共用方式為


TN001:視窗類別註冊

此備忘錄描述 Microsoft Windows 所需的特殊 WNDCLASS 的 MFC 例程註冊。 會討論 MFC 和 Windows 所使用的特定 WNDCLASS 屬性。

問題

CWnd 物件的屬性,就像 Windows 中的句柄一樣,會儲存在兩個HWND位置:視窗物件和 WNDCLASS。 的名稱WNDCLASS會傳遞至一般視窗建立函式,例如 CWnd::CreatelpszClassName 參數中的 CFrameWnd::Create

WNDCLASS 必須透過四種方法之一進行註冊:

WNDCLASS 欄位

結構 WNDCLASS 是由描述視窗類別的各種欄位所組成。 下表顯示欄位,並指定它們如何在 MFC 應用程式中使用:

領域 說明
lpfnWndProc 視窗工作程序,必須是 AfxWndProc
cbClsExtra 未使用 (應為零)
cbWndExtra 未使用 (應為零)
hInstance 自動填入 AfxGetInstanceHandle
hIcon 框架視窗的圖示,請參閱下方
hCursor 滑鼠停留在視窗上方時的游標,請參閱下方
hbrBackground 背景色彩,請參閱下方
lpszMenuName 未使用 (應為 NULL)
lpszClassName 類別名稱,請參閱下方

提供的 WNDCLASSes

舊版 MFC (在 MFC 4.0 之前),提供了數個預先定義的 Window 類別。 預設不會再提供這些 Window 類別。 應用程式應該搭配適當的參數使用 AfxRegisterWndClass

如果應用程式提供具有指定資源標識符的資源(例如,AFX_IDI_STD_FRAME),MFC 會使用該資源。 否則會使用預設資源。 針對圖示,會使用標準應用程式圖示,而針對游標,則會使用標準箭號游標。

兩個圖示支援具有單一檔類型的 MDI 應用程式:主要應用程式的一個圖示,另一個圖示用於圖示檔/MDIChild 視窗。 對於具有不同圖示的多個文件類型,您必須註冊其他 WNDCLASSes 或使用 CFrameWnd::LoadFrame 函式。

CFrameWnd::LoadFrame 將會使用您指定做為第一個參數與下列標準屬性的圖示識別碼來註冊 WNDCLASS

  • 類別樣式: CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;

  • 圖標:AFX_IDI_STD_FRAME

  • 箭頭游標

  • COLOR_WINDOW背景色彩

CMDIFrameWnd 的背景色彩和游標不會使用,因為 CMDIFrameWnd 视窗完全覆蓋工作區。 Microsoft不鼓勵子類別 化 MDICLIENT 視窗,因此請盡可能使用標準色彩和游標類型。

子類別化和超類別化控件

如果您繼承或覆蓋 Windows 控制元件(例如 CButton),則您的類別會自動取得 Windows 實作中提供給該控制元件的 WNDCLASS 屬性。

AfxRegisterWndClass 函式

MFC 提供協助程式函式來註冊窗口類別。 假設有一組屬性(視窗類別樣式、游標、背景筆刷和圖示),會產生綜合名稱,並註冊產生的窗口類別。 例如,

const char* AfxRegisterWndClass(UINT nClassStyle,
    HCURSOR hCursor,
    HBRUSH hbrBackground,
    HICON hIcon);

此函式會傳回所產生已註冊視窗類別名稱的暫存字串。 如需此函式的詳細資訊,請參閱 AfxRegisterWndClass

傳回的字串是靜態字串緩衝區的暫存指標。 這有效,直到下一次呼叫 AfxRegisterWndClass。 如果您想要保留此字串,請將它儲存在 CString 變數中,如下列範例所示:

CString strWndClass = AfxRegisterWndClass(CS_DBLCLK, ...);

...
CWnd* pWnd = new CWnd;
pWnd->Create(strWndClass, ...);

...

AfxRegisterWndClass 如果窗口類別無法註冊,則會擲回 CResourceException (因為參數不正確或 Windows 記憶體不足)。

RegisterClass 和 AfxRegisterClass 這兩個函式

如果您要執行比提供更 AfxRegisterWndClass 複雜的事情,您可以呼叫 Windows API RegisterClass 或 MFC 函式 AfxRegisterClassCWndCFrameWndCMDIChildWndCreate 函式會採用視窗類別的 lpszClassName 字串名稱做為第一個參數。 不論您用來註冊它的方法為何,您都可以使用任何已註冊的窗口類別名稱。

請務必在 Win32 上的 DLL 中使用 AfxRegisterClass (或 AfxRegisterWndClass)。 Win32 不會自動取消註冊 DLL 所註冊的類別,因此您必須在 DLL 終止時明確取消註冊類別。 藉由使用 AfxRegisterClass 而非 RegisterClass ,系統會自動為您處理。 AfxRegisterClass 會維護 DLL 註冊的唯一類別清單,並在 DLL 終止時自動取消註冊。 當您在 DLL 中使用 RegisterClass 時,您必須確定當 DLL 終止時,所有類別都會取消註冊(在 DllMain 函式中)。 未能做到這一點可能會在另一個用戶端應用程式嘗試使用您的 DLL 時導致 RegisterClass 意外故障。

另請參閱

依編號的技術注意事項
依類別排序的技術注意事項