橫秋掃盲系列(3): CPropertySheet 屬性對話框 -- 2005-8-21 17:48:23

首先要了解的是CPropertySheet實際上是由一個TabCtrl加多個Page和多個按鈕組成
這裏強調一點,DoModal的時候並沒有把所有的PAGE都創建出來,只有在SetActivePage的時候才創建
所以如果你初始化的代碼在OnInitDialog,那麼剛開始最好先用SetActivePage切換一下

在講述之前,大家可以先看看《深入淺出CPropertySheet》(翻譯的不錯)
http://www.vckbase.com/document/viewdoc/?id=427
其實原文後面還有一個例子,不過原理上帖中也表現出來了,就是窗口的移動MoveWindow和HeaderCtrl的創建等
參見 http://www.codeguru.com/Cpp/controls/propertysheet/article.php/c3973/
所以在此一些簡單按鈕的隱藏和移動及其Enable使能就不多說了

一、佈局修改
a.修改字體
重載OnInitDialog,CreateFont創建字體pFont
SendMessageToDescendants(WM_SETFONT, (WPARAM)pFont->GetSafeHandle(), TRUE);
如果字體的改變(如高度、寬度)可能需要改變控件的位置,這樣看起來才和諧一點,參見
Prpfont.exe sample demonstrates how to set the desired font for your CPropertyPages in Visual C++
http://support.microsoft.com/default.aspx?scid=kb;en-us;142170

b.設置初始的焦點
GetPage(0)->SetModified ();//使應用按鈕有效
SendMessage(DM_SETDEFID,ID_APPLY_NOW); //也可設置到自己添加的按鈕中

c.改變大小Resizable(這類文章和發問比較多,所以主要帖URL,見諒)
使用ResizableLib(適用於幾乎所有窗口,Dialog,PropSheet,SDI,MDI等)
http://www.codeproject.com/dialog/ResizableLib.asp
也可參看Resizable CPropertySheet
http://www.codeproject.com/property/resizableproperties.asp
http://www.codeguru.com/Cpp/controls/propertysheet/sizing/article.php/c599/
運行期間動態進行調整大小,避免切換後又恢復原來大小,參見
http://support.microsoft.com/default.aspx?scid=kb;en-us;143291

注:如果自己在OnInitDialog做MoveWindow的時候要記住代碼放到CPropertySheet::OnInitDialog();後

d.嚮導方式
最簡單的就是設置模式 SetWizardMode //注意最前和最後頁的SetWizardButtons
後來添加了Wizard97 風格,主要有兩塊地方填充的,左邊的叫WATERMARK和上部的叫HEADER
注:左邊和上部一般不能同時顯示,所以要想顯示WATERMARK,需要在PAGE中設置PSP_HIDEHEADER風格(VC7默認才設了)

添加WIZARD97風格,同時設置對應的位圖
psh.dwFlags =  PSH_WIZARD97|PSH_WATERMARK|PSH_HEADER;
psh.pszbmWatermark = MAKEINTRESOURCE(IDB_WATERMARK);
psh.pszbmHeader =    MAKEINTRESOURCE(IDB_BANNER);

如果要HEADER中顯示文本TITLE也可設置PSP_USEHEADERTITLE和PSP_USEHEADERSUBTITLE,如
psp.dwFlags =           PSP_DEFAULT|PSP_USEHEADERTITLE|PSP_USEHEADERSUBTITLE;
psp.pszHeaderTitle =    MAKEINTRESOURCE(IDS_TITLE1);
psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_SUBTITLE1);

更多的詳情有興趣的可自行搜索,如6.0版本中PROPSHEETPAGE新添的hActCtx等,在此點到爲止

e.內嵌入對話框中和Modeless
ps.Create(this);//如果要內嵌添加,WS_CHILD|WS_VISIBLE
ps.ShowWindow(SW_SHOW);
但這時候出來的是沒有標準按鈕,想要添加可重載OnInitDialog
BOOL CMySheet::OnInitDialog()
{
   m_bModeless = FALSE;
   m_nFlags |= WF_CONTINUEMODAL;

   BOOL bResult = CPropertySheet::OnInitDialog();

   m_bModeless = TRUE;
   m_nFlags &= ~WF_CONTINUEMODAL;
   return bResult;
}
P.S.焦點切換後子屬性框(modeless)僵死,請在OnInitDialog中添加
ModifyStyleEx(0,WS_EX_CONTROLPARENT);

二、標籤TabCtrl的操作
a.修改Text
有三種方法
m_pPage1=newCPage1(IDS_MYCAPTION);//idofstringresource

m_pPage1->m_psp.dwFlags|=PSP_USETITLE;
m_pPage1->m_psp.pszTitle=_T("MyCaption");

運行時也可修改標籤
TC_ITEM ti;
ti.mask=TCIF_TEXT;
ti.pszText=pszText;
VERIFY(GetTabControl()->SetItem(nPage,&ti));

b.Tab使用Scrollbar而不是用多行
EnableStackedTabs(FALSE);即可,原理就是GetTabControl()->ModifyStyle(TCS_MULTILINE, TCS_SINGLELINE)


c.如何調整標籤位置(下面或者左右)一般自畫,參考:
http://www.codeguru.com/Cpp/controls/controls/tabcontrols/article.php/c6385/

d.Disable Tab中如果要重畫TabItem使其看起來灰化,也可以看Paul的CTabCtrlWithDisable
http://www.microsoft.com/msj/0398/c0398.aspx

e.CPropertySheet頁中的標題欄中顯示指定數量的屬性頁,如:標題欄要求每行顯示5個屬性頁
可使用 MutliRowTabView 參見 http://www.codeguru.com/Cpp/controls/propertysheet/article.php/c623/

三、消息的響應
a.獲得CPropertySheet的WM_CLOSE消息
http://dev.csdn.net/develop/article/35/35982.shtm比較簡便地實現了此功能,
但需要覆蓋每個屬性頁的OnApply函數,且不利於宏觀同步未完成的任務.
現提供一個通過覆蓋CMyPropertySheet類的OnCommand函數實現此功能的方法.
OnCommand的實現代碼如下:
BOOL CMyPropertySheet::OnCommand(WPARA MwParam,LPARAM lParam)

b.NOTIFY的響應 如:Disable 某個TAB
BOOL CMySheet::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
   {
       NMHDR* pnmh = (NMHDR*)lParam;
       // tab is about to change
       if (TCN_SELCHANGING == pnmh->code)
           // save the current page index
           m_nLastActive = GetActiveIndex ();
       // tab has been changed
       else if (TCN_SELCHANGE == pnmh->code)
       {
           // get the current page index
           int nCurrentPage = GetActiveIndex ();
           // if current page is in our map of disabled pages
           if (m_DisabledPages.Lookup (nCurrentPage, nCurrentPage))
           // activate the previous page
           PostMessage (PSM_SETCURSEL, m_nLastActive);
       }
       return CPropertySheet::OnNotify(wParam, lParam, pResult);
   }

c.如何響應上下文幫助  
Title Bar添加問號(?)按鈕的響應:添加WN_HELP響應
ON_WM_HELPINFO()//添加函數BOOL OnHelpInfo(HELPINFO*)
如果響應底部的幫助按鈕(原理:一般按鈕的點擊映射)
ON_COMMAND(IDHELP, OnHelp)//添加函數BOOL OnHelp()

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章