VC++技術內幕(第四版)筆記(第12章)

/***************************************/

第十二章:菜單、鍵盤加速鍵、覆文本編輯控件和屬性表


1,主框架窗口包含標題欄和菜單欄,而各種各樣的子窗口(包括工具欄窗口、狀態欄窗口和視圖窗口)覆蓋着主框架窗口的客戶區域。應用程序通過框架和視圖之間的消息傳遞來控制框架和視圖之間的相互作用。

2,MFC應用程序框架提供了一個非常複雜的命令消息傳遞系統,這些消息來自菜單的選擇、鍵盤加速、以及工具欄和對話框按鈕,另外,命令消息也可以通過調用CWnd::SendMessage或PostMessage函數來發送。
1)大多數命令消息都來自主框架窗口,但應用程序框架並沒有對其一一的響應處理,需要我們自己在適當的地方添加響應函數加以響應處理。
2)當應用程序框架接收到框架窗口的命令,它將按下列次序來尋找其消息控制函數:
SDI程序(單文檔):視圖(VIEW類)-》文檔(DOC類)-》SDI主框架窗口(FRAME類)-》應用程序(APP類)。
MDI程序(多文檔):視圖--》文檔--》MDI子框架窗口--》MDI主框架窗口--》應用程序。
說明:
當框架接收到框架窗口命令,安上敘的次序尋找其消息控制函數的時候,一旦找到,就停止繼續往下尋找,這樣當路徑中有多個該消息控制函數的時候,只執行先找到的那個。

3,命令傳遞系統反映對命令消息控制的一個方面,類的層次結構反映了對命令消息進行控制處理的另一個方面。
1)一般,派生類會繼承基類所有的消息映射函數,其中包括命令消息函數。
2)如果想對基類的消息映射函數進行重載,就必須在派生類中加入相應的消息映射函數和相應的消息映射入口(及函數聲明)。

4,所有的彈出式菜單都屬於主框架窗口。
1)彈出式菜單上按鈕(及資源編輯器中菜單項)的ID必須在0x8000-0xDFFF範圍內,纔可以產生可被傳遞的命令消息。
2)使用符號編輯器來輸入ID,可以保證ID範圍落在0x8000-0xDFFF範圍內。
(注:書中是彈出式對話框,不過應該是彈出式菜單纔對。)

5,CFrameWnd::m_bAutoMenuEnable
//Controls automatic enable and disable functionality for menu items.
//CFrameWnd類中的BOOL型數據成員,默認爲TRUE。
//如果m_bAutoMenuEnable設爲TRUE,則如果某菜單項在當前命令路徑中無法找到相應的命令消息控制函數,則此時應用程序框架便禁用該菜單項,並將該菜單項設爲灰色。
//如果m_bAutoMenuEnable設爲FALSE,便可以禁止上敘自動禁用無控制函數菜單項的特性。
(試一試:自己在框架類構造函數CMainFrame::CMainFrame()中添加this->m_bAutoMenuEnable=TRUE語句,然後看看菜單裏菜單項裏看看有什麼變化哦)


6,MFC文本編輯選擇
1)CEditView類:文本大小限制在64K以內,不能設混合字體,實現了基本的編制功能。
2)CRichEditView類:使用了富文本編輯控件,支持混合字體和大數據量文本。
3)CRichEditCtrl類:封裝了富文本編輯控件。
//CRichEditCtrl   A window in which the user can enter and edit text with character and paragraph formatting. The control can include embedded OLE objects.


7,示例事例說明:
事例EX12A(未優化前的)中使用CRichEditCtrl類來在基類爲CView類的項目中設計編輯功能:
1)方法:構造CRichEditCtrl類對象,併爲之創建控件窗口與之關聯,設置控件窗口爲當前視圖客戶區大小,使CRichEditCtrl類控件窗口覆蓋當前視圖客戶區,CRichEditCtrl類控件窗口具有富文本編輯功能,從而完成設計。
2)實現細節:
CRichEditCtrl m_rich;//構造CRichEditCtrl對象
m_rich.Create(ES_AUTOVSCROLL | ES_MULTILINE | ES_WANTRETURN | WS_CHILD | WS_VISIBLE | WS_VSCROLL,rect,this,1);//創建控件窗口用以初始化CRichEditCtrl對象
m_rich.SetWindowPos(&wndTop,0,0,rect.right-rect.left,rect.bottom-rect.top,SWP_SHOWWINDOW);
//設置CRichEditCtrl控件窗口大小(使用GetClientRect(rect)獲得視圖客戶區大小)和位置,即覆蓋視圖客戶區域。
3)獲取和保存控件文本技巧:
在VIEW類中獲取對應DOC類對象指針:CEX12aDoc *pDoc=GetDocument();
獲取控件窗口文本:m_rich.SetWindowText(pDoc->m_strText);
設置控件窗口文本:m_rich.GetWindowText(pDoc->m_strText);
技巧說明:在視圖類中利用GetDocument()函數獲取其對應文檔類對象指針,從而可將m_rich控件窗口文本保持到文檔類數據成員m_strText中。
4)CRichEditCtrl::SetModify
void SetModify( BOOL bModified = TRUE );
bModified》》A value of TRUE indicates(象徵,預示) that the text has been modified, and a value of FALSE indicates it is unmodified. By default, the modified flag is set.
5)關於加速鍵的添加:在在資源管理器Accelerator中添加(如:ID_GETDATA   VK_F2)。

8,學用屬性表
這裏提供一種利用資源管理器創建屬性表的方法:
第一步:利用資源管理器添加幾個對話框作爲屬性頁(這樣可方便往屬性頁上添加控件並處理了)。
第二步:分別爲作爲屬性頁的對話框創建類,基類採用CPropertyPage。
第三步:利用類嚮導創建用戶屬性表類,基類採用CPropertySheet。
第四步:在剛創建的用戶屬性表類中添加需要屬性頁類數據成員,並在屬性表類構造函數中調用CPropertySheet::AddPage函數將所需要的屬性頁一一添加到屬性表中去。目前爲止屬性表類創建結束。
第五步: 在需要創建和顯示屬性表的地方構造用戶屬性表對象,並調用CPropertySheet::DoModal顯示。
說明:
1)CPropertySheet
Objects of class CPropertySheet represent property sheets, otherwise known as tab dialog boxes. A property sheet consists of a CPropertySheet object and one or more CPropertyPage objects. A property sheet is displayed by the framework as a window with a set of tab indices, with which the user selects the current page, and an area for the currently selected page.

Even though CPropertySheet is not derived from CDialog, managing a CPropertySheet object is similar to managing a CDialog object.

Exchanging data between a CPropertySheet object and some external object is similar to exchanging data with a CDialog object.

2)CPropertyPage
Objects of class CPropertyPage represent individual pages of a property sheet, otherwise known as a tab dialog box. As with standard dialog boxes, you derive a class from CPropertyPage for each page in your property sheet. To use CPropertyPage-derived objects, first create a CPropertySheet object, and then create an object for each page that goes in the property sheet. Call CPropertySheet::AddPage for each page in the sheet, and then display the property sheet by calling CPropertySheet::DoModal for a modal property sheet, or CPropertySheet::Create for a modeless property sheet.

3)Apply按鈕的處理:
在所有的屬性表類中,只要控件給屬性頁發送一個消息(如:點擊或選擇屬性頁上的控件,框架便調用該屬性頁OnCommand函數來響應這些控件所發出的通告消息,OnCommand函數是虛函數),在每個屬性頁中重載OnCommand函數設置SetModified(TRUE)可使Apply按鈕有效。
當用戶點擊Apply按鈕,框架自動調用OnApply函數,可以在重載它來完成一些重要的任務。
CWnd::OnCommand 
virtual BOOL OnCommand( WPARAM wParam, LPARAM lParam );
//The framework calls this member function when the user selects an item from a menu, when a child control sends a notification message, or when an accelerator keystroke is translated.

CPropertyPage::OnApply
virtual BOOL OnApply( );
//This member function is called by the framework when the user chooses the OK or the Apply Now button. When the framework calls this function, changes made on all property pages in the property sheet are accepted, the property sheet retains focus, and OnApply returns TRUE (the value 1). Before OnApply can be called by the framework, you must have called SetModified and set its parameter to TRUE. This will activate the Apply Now button as soon as the user makes a change on the property page.

Override this member function to specify what action your program takes when the user clicks the Apply Now button. When overriding, the function should return TRUE to accept changes and FALSE to prevent changes from taking effect.

The default implementation of OnApply calls OnOK.


9,CMenu類
CMenu類對象可以用來表示各種Windows菜單,包括頂層菜單項及相應的彈出式菜單。
添加菜單方法:
程序添加法:1)定義菜單資源;2)構造菜單對象;3)調用CMenu::LoadMenu函數將菜單將菜單資源載入;4)調用CWnd::SetMenu函數將菜單連接到框架窗口中;5)調用CMenu::Detach函數把對象HMENU句柄獨立出來(這樣當CMenu對象銷燬時候,菜單不隨之銷燬)
/////////////////////////////////
/////////////////////////////////

另一中簡便的添加菜單方法:如果想爲某對話框添加菜單,可從話框屬性中Menu項中選擇資源管理器中的需要的菜單完成添加工作。

10,創建浮動式彈出菜單
步驟:
1)用資源編輯器添加菜單資源
2)在視圖類或其他接收鼠標右鍵單擊的窗口類中添加WM_CONTEXTMENU消息控制函數,編輯代碼如下:
void CAboutDlg::OnContextMenu(CWnd* pWnd, CPoint point)
{
 CMenu menu;
 menu.LoadMenu(IDR_MENU1);
 menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,point.x,point.y,this);
 
}
說明:
GetSubMenu函數得到指向彈出式菜單的CMenu指針。
TrackPopupMenu在指定位置顯示浮動菜單,並跟蹤彈出菜單的選擇項。

11,關於擴展命令的處理:
擴展命令無法使用嚮導添加,需要自己添加,添加的方法如普通的命令處理類似。具體參看書P256-257頁。

////////////////////////
/////////////////////
後續章節筆記待續

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