属性单和属性页

属性单和属性页

   利用属性单和属性页的组合,能很好的解决单个对话框显示很多控件的问题。主要使用了CPropertySheet类和CproperPage类,CpropertyPage类代表每个单独的选项卡,CPropertySheet类代表显示这些选项卡的窗口。CPropertySheet类是从CWnd派生而来的,选项卡(CPropertyPage)则是从CDialog派生而来的。
   
   模态属性单实例程序主要讲解CPropertySheet和CPropertyPage类的不同方面。
1)创建程序的框架
   常见一个名为ModalDemo的MFC SDI项目。再添加两个对话框,ID分别为IDD_FINDBOOK_FIND和IDD_FINDBOOK_RESULTS,并为两个对话框创建派生于CPropertyPage类的CFindPage类和CResultsPage类。添加一个ID为IDS_FIND,Caption为FindBook的字符串资源,它将被传递给CPropertySheet构造函数。最后,在IDR_MAINFRAME菜单栏添加Books,并添加子项FindBook,ID为ID_FINDBOOK。
2)单击ID_FINDBOOK事件
   创建有IDD_FINDBOOK_FIND和IDD_FINDBOOK_RESULTS为属性页和IDS_FIND为属性单的组合。在这里创建CPropertySheet的派生类CFindSheet。

void  CMainFrame::OnFindbook() 
{
    CFindSheet sheet(IDS_FIND);
    CFindPage pageFind;
    CResultsPage pageResults;

    sheet.AddPage(
& pageFind);///////////////////////////////////////////////////////////////////////////////////
    sheet.AddPage(
& pageResults);
    sheet.DoModal();
}

3)去除标准按钮
   标准按钮有OK(IDOK)、Cancel(IDCANCEL)、Help(IDHELP)和Apply(ID_APPLY_NOW)。这里去除掉Cancel和Apply两个按钮。

BOOL CFindSheet::OnInitDialog() 
{
    BOOL bResult 
=  CPropertySheet::OnInitDialog();

    
int  ids[] = {ID_APPLY_NOW,IDCANCEL};
    
for ( int  i = 0 ;i < sizeof (ids) / sizeof (ids[ 0 ]);i ++ )
    {
        CWnd
*  pWnd = GetDlgItem(ids[i]);
        
if (pWnd)
            pWnd
-> ShowWindow(FALSE);
    }

    
return  bResult;
}

4)重定位标准按钮
   默认情况下,标准按钮是在属性页的下方,这里把OK按钮移到沿属性页右对齐。

BOOL CFindSheet::OnInitDialog() 
{
    BOOL bResult 
=  CPropertySheet::OnInitDialog();

    CWnd
*  pbtnOk = GetDlgItem(IDOK);

    CRect rectSheet;
    GetWindowRect(rectSheet);

    CRect rectOkBtn;
    pbtnOk
-> GetWindowRect(rectOkBtn);

    
int  iBorder = rectSheet.bottom - rectOkBtn.bottom;

    rectSheet.right
+= rectOkBtn.Width() + iBorder;
    rectSheet.bottom
= rectOkBtn.top;
    MoveWindow(rectSheet);/////////////////////////////////////////////////////////////////////////////

    CPropertyPage
*  page = GetPage( 0 );//////////////////////////////////////////////////////////////////
    CRect rectPage;
    page
-> GetWindowRect(rectPage);

    
int  cxOk = rectOkBtn.Width();
    
int  cyOk = rectOkBtn.Height();

    rectOkBtn.top
= rectPage.top;
    rectOkBtn.bottom
= rectOkBtn.top + cyOk;
    rectOkBtn.left
= rectSheet.right - (cxOk + iBorder);
    rectOkBtn.right
= rectOkBtn.left + cxOk;
    ScreenToClient(rectOkBtn);
    pbtnOk
-> MoveWindow(rectOkBtn);

    
return  bResult;
}

5)更改标准按钮的标题

BOOL CFindSheet::OnInitDialog() 
{
    BOOL bResult 
=  CPropertySheet::OnInitDialog();

    pbtnOk
-> SetWindowText(_T( " Cl&ose " ));////////////////////////////////////////////////////////////////

    
return  bResult;
}

6)禁用选项卡
   创建一个存储当前选项卡索引的成员变量和一个容纳当前被禁用的选项卡的成员变量

     int  m_iLastActivePage; // 当前选项卡索引
    CUIntArray m_arrDisabledPages; // 被禁用的选项卡索引

   添加禁用指定的选项卡的成员函数和设置已禁用选项卡的标题的成员函数

#define DISABLED_TEXT "-Disabled"
void
 CFindSheet::DisablePage( int  iFirstPage,)
{
    
int  iPage = iFirstPage;

    va_list marker;)////////////////////////////////////////////////
    va_start (marker,iFirstPage);)////////////////////////////////////////////////
    
int  nArgs = 0 ;

    
whil