MFC和Win32技術應用分析
MDI子窗口類似于上述MDI主窗口的處理。
在MFC創建控制窗口時,如工具欄窗口,如果“AfxControlBar”類還沒有注冊,則注冊它。注冊過程很簡單,就是調用::InitCommonControl加載通用控制動態連接庫。
調用::RegisterWndClass。
直接調用Win32的窗口注冊函數::RegisterWndClass注冊“窗口類”,這樣做有一個缺點:如果是DLL模塊,這樣注冊的“窗口類”在程序退出時不會自動的被取消注冊(Unregister)。所以必須記得在DLL模塊退出時取消它所注冊的窗口類。
子類化
子類化(Subclass)一個“窗口類”,可自動地得到它的“窗口類”屬性。
MFC窗口類CWnd
在Windows系統里,一個窗口的屬性分兩個地方存放:一部分放在“窗口類”里頭,如上所述的在注冊窗口時指定;另一部分放在Windows Object本身,如:窗口的尺寸,窗口的位置(X,Y軸),窗口的Z軸順序,窗口的狀態(ACTIVE,MINIMIZED,MAXMIZED,RESTORED…),和其他窗口的關系(父窗口,子窗口…),窗口是否可以接收鍵盤或鼠標消息,等等。
為了表達所有這些窗口的共性,MFC設計了一個窗口基類CWnd。有一點非常重要,那就是CWnd提供了一個標準而通用的MFC窗口過程,MFC下所有的窗口都使用這個窗口過程。至于通用的窗口過程卻能為各個窗口實現不同的操作,那就是MFC消息映射機制的奧秘和作用了。這些,將在后面有關章節詳細論述。
CWnd提供了一系列成員函數,或者是對Win32相關函數的封裝,或者是CWnd新設計的一些函數。這些函數大致如下。
(1)窗口創建函數
這里主要討論函數Create和CreateEx。它們封裝了Win32窗口創建函數::CreateWindowEx。Create的原型如下:
BOOL CWnd::Create(LPCTSTR lpszClassName,
LPCTSTR lpszWindowName, DWORD dwStyle,
const RECT rect,
CWnd* pParentWnd, UINT nID,
CCreateContext* pContext)
Create是一個虛擬函數,用來創建子窗口(不能創建桌面窗口和POP UP窗口)。CWnd的基類可以覆蓋該函數,例如邊框窗口類等覆蓋了該函數以實現邊框窗口的創建,視類則使用它來創建視窗口。
Create調用了成員函數CreateEx。CWnd::CreateEx的原型如下:
BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName,
LPCTSTR lpszWindowName, DWORD dwStyle,
int x, int y, int nWidth, int nHeight,
HWND hWndParent, HMENU nIDorHMenu, LPVOID lpParam)
CreateEx有11個參數,它將調用::CreateWindowEx完成窗口的創建,這11個參數對應地傳遞給::CreateWindowEx。參數指定了窗口擴展風格、“窗口類”、窗口名、窗口大小和位置、父窗口句柄、窗口菜單和窗口創建參數。
CreateEx的處理流程將在后面4.4.1節討論窗口過程時分析。
窗口創建時發送WM_CREATE消息,消息參數lParam指向一個CreateStruct結構的變量,該結構有11個域,其描述見后面4.4.1節對窗口過程的分析,Windows使用和CreateEx參數一樣的內容填充該變量。
(2)窗口銷毀函數
例如:
DestroyWindow函數 銷毀窗口
PostNcDestroy( ),銷毀窗口后調用,虛擬函數
(3)用于設定、獲取、改變窗口屬性的函數,例如:
SetWindowText(CString tiltle) 設置窗口標題
GetWindowText() 得到窗口標題
SetIcon(HICON hIcon, BOOL bBigIcon);設置窗口像標
GetIcon( BOOL bBigIcon ) ;得到窗口像標
GetDlgItem( int nID);得到窗口類指定ID的控制子窗口
GetDC(); 得到窗口的設備上下文
SetMenu(CMenu *pMenu); 設置窗口菜單
GetMenu();得到窗口菜單
…
(4)用于完成窗口動作的函數
用于更新窗口,滾動窗口,等等。一部分成員函數設計成或可重載(Overloaded)函數,或虛擬(Overridden)函數,或MFC消息處理函數。這些函數或者實現了一部分功能,或者僅僅是一個空函數。如:
有關消息發送的函數:
SendMessage( UINT message,WPARAM wParam = 0, LPARAM lParam = 0 );
給窗口發送發送消息,立即調用方式
PostMessage(( UINT message,WPARAM wParam = 0, LPARAM lParam = 0 );
給窗口發送消息,放進消息隊列
…
有關改變窗口狀態的函數
MoveWindow( LPCRECT lpRect, BOOL bRepaint = TRUE );
移動窗口到指定位置
ShowWindow(BOOL );顯示窗口,使之可見或不可見
….
實現MFC消息處理機制的函數:
virtual LRESULT WindowProc( UINT message, WPARAM wParam, LPARAM lParam ); 窗口過程,虛擬函數
virtual BOOL OnCommand( WPARAM wParam, LPARAM lParam );處理命令消息
…
消息處理函數:
OnCreate( LPCREATESTRUCT lpCreateStruct );MFC窗口消息處理函數,窗口創建時由MFC框架調用
OnClose();MFC窗口消息處理函數,窗口創建時由MFC框架調用
…
其他功能的函數
CWnd的導出類是類型更具體、功能更完善的窗口類,它們繼承了CWnd的屬性和方法,并提供了新的成員函數(消息處理函數、虛擬函數、等等)。
常用的窗口類及其層次關系見圖1-1。
在MFC下創建一個窗口對象
MFC下創建一個窗口對象分兩步,首先創建MFC窗口對象,然后創建對應的Windows窗口。在內存使用上,MFC窗口對象可以在棧或者堆(使用new創建)中創建。具體表述如下:
創建MFC窗口對象。通過定義一個CWnd或其派生類的實例變量或者動態創建一個MFC窗口的實例,前者在棧空間創建一個MFC窗口對象,后者在堆空間創建一個MFC窗口對象。
調用相應的窗口創建函數,創建Windows窗口對象。
例如:在前面提到的AppWizard產生的源碼中,有CMainFrame(派生于CMDIFrame(SDI)或者CMDIFrameWnd(MDI))類。它有兩個成員變量定義如下:











評論