TN001:窗口類註冊
本說明描述了註冊Microsoft Windows所需的特殊wnd類的MFC例程。討論MFC和Windows使用的特定WNDCLASS屬性。
問題是
像Windows中的HWND壹樣,CWnd對象的屬性存儲在兩個地方:window對象和WNDCLASS。WNDCLASS不同於C++類。WNDCLASS的名稱被傳遞給常規窗口創建函數,如lpszClassName參數中的CWnd::Create和CFrameWnd::Create。
此WNDCLASS必須通過以下四種方式之壹註冊:
由MFC隱式提供的WNDCLASSes
隱式地通過子類化壹個窗口控件(或壹些其他控件)
顯式調用MFC AfxRegisterWndClass或AfxRegisterClass
顯式調用Windows例程RegisterClass
WNDCLASSes和MFC
WNDCLASS結構由描述窗口類的各種字段組成。下面是這些字段以及它們在MFC應用程序中的用法。
窗的樣式樣式:見下圖
LpfnWndProc窗口過程,必須是AfxWndProc
未使用CbClsExtra(應該為零)
未使用CbWndExtra(應該為零)
HInstance自動填充AfxGetInstanceHandle
框架窗口的圖標,見下圖
鼠標在窗口上時的光標,見下圖
HbrBackground背景色,見下圖
未使用LpszMenuName(應為NULL)
LpszClassName類名,見下文
提供了WNDCLASSes
在MFC的早期版本(MFC 4.0之前)中,提供了許多預定義的窗口類。由於與版本控制(在壹個地址空間中加載多個版本的MFC)相關的技術問題,以及與MFC應用程序和OLE控件都可能使用MFC DLLs相關的問題,默認情況下不再提供這些窗口類。
下面提供的參考有助於遷移使用這些以前提供的WNDCLASSes的代碼。應用程序應該使用AfxRegisterWndClass(帶有適當的參數)來代替這些類。
下面顯示了這些類及其屬性:
“AfxWnd”用於所有用CWnd::Create創建的子窗口。
類樣式:CS _ DBLCLKS | CS _ HREDRAW | CS _ VREDRAW
沒有圖標
箭頭光標
沒有背景顏色
“AfxFrameOrView”用於框架窗口和視圖(包括獨立的CFrameWnds和CMDIChildWnds)。
類樣式:CS _ DBLCLKS | CS _ HREDRAW | CS _ VREDRAW;
圖標AFX _ IDI _標準_框架
箭頭光標
顏色_窗口背景色
“AfxMDIFrame”用於用CMDIFrameWnd::Create創建的MDI框架窗口(即父窗口)。
class style : CS_DBLCLKS [調整大小時減少閃光]
圖標AFX _ IDI _標準_MDIFRAME
箭頭光標
沒有背景顏色
“AfxControlBar”用於標準控制條實現。
類別樣式:0 [調整大小時減少閃爍,無雙擊]
沒有圖標
箭頭光標
灰色背景色(COLOR_BTNFACE)
如果應用程序提供具有指定資源ID(例如,AFX_IDI_STD_FRAME) ID的資源,MFC將使用該資源。否則,使用默認資源。對於圖標,使用標準應用程序圖標,對於光標,使用標準箭頭光標。
有兩個圖標支持具有單壹文檔類型的MDI應用程序(壹個圖標用於主應用程序,另壹個圖標用於圖標文檔/MDI chid窗口)。對於具有不同圖標的多種文檔類型,必須註冊額外的Wnd類或使用CFrameWnd::LoadFrame函數。
CFrameWnd::LoadFrame將使用標準的“AfxFrameOrView”屬性自動註冊壹個WNDCLASS,但是使用您指定的圖標ID作為LoadFrame的第壹個參數。
不使用MDIFrameWnd的背景顏色和光標的值,因為MDIFrameWnd的客戶區完全被“MDIC客戶端”窗口覆蓋。Microsoft不鼓勵對“MDICLIENT”窗口進行子類化,因此盡可能使用標準顏色和光標類型。
子類化控件
如果妳是壹個Windows控件的子類或超類(例如,CButton ),那麽妳的類會自動獲得該控件的Windows實現中提供的WNDCLASS屬性。
AfxRegisterWndClass函數
MFC為註冊窗口類提供了壹個助手例程。給定壹組屬性(窗口類樣式、光標、背景畫筆和圖標),生成壹個合成名稱,並註冊生成的窗口類。舉個例子,
const char * AfxRegisterWndClass(UINT nclasstyle,HCURSOR hCursor,HBRUSH hbrBackground,HICON HICON);
這個函數返回生成的註冊窗口類名的臨時字符串。有關更多詳細信息,請參見類庫參考。
返回的字符串是指向靜態字符串緩沖區的臨時指針,該指針在下壹次調用AfxRegisterWndClass之前壹直有效。如果妳想保留這個字符串,把它存儲在壹個CString變量中。舉個例子,
CS string strwnd class = AfxRegisterWndClass(CS _ dbl clk,...);
...
CWnd* pWnd =新CWnd;
pWnd-& gt;創建(strWndClass,...);
...
如果窗口類註冊失敗(由於錯誤的參數或Windows內存不足),AfxRegisterWndClass將引發CResourceException。
RegisterClass和AfxRegisterClass函數
如果想做比AfxRegisterWndClass提供的更復雜的事情,可以調用Windows API RegisterClass或MFC函數AfxRegisterClass。CWnd、CFrameWnd和CMDIChildWnd Create函數將窗口類的lpszClassName字符串名稱作為第壹個參數。可以使用任何窗口類名,不管它是如何註冊的。
在Win32上的DLL中使用AfxRegisterClass(或AfxRegisterWndClass)很重要。Win32不會自動註銷由DLL註冊的類,因此必須在DLL終止時顯式註銷。通過使用AfxRegisterClass而不是RegisterClass,這是自動為您完成的。Afx RegisterClass維護壹個由您的DLL註冊的唯壹類的列表,並在DLL終止時自動取消註冊。在DLL中使用Regi sterClass時,必須確保當DLL終止時(在DllMain函數中)所有的類都被取消註冊。否則,當您的DLL被另壹個客戶端應用程序使用時,可能會導致RegisterClass意外失敗。
按編號列出的技術說明|按類別列出的技術說明