このノートでは、Microsoft Windows で必要な特別な WNDCLASSを登録する MFC ルーチンについて説明します。 MFC と Windows で使用される特定の WNDCLASS
属性について説明します。
問題
Windows のHWND
ハンドルのような CWnd オブジェクトの属性は、ウィンドウ オブジェクトとWNDCLASS
の 2 つの場所に格納されます。
WNDCLASS
の名前は、lpszClassName パラメーターの CWnd::Create や CFrameWnd::Create などの一般的なウィンドウ作成関数に渡されます。
この WNDCLASS
は、次の 4 つの方法のいずれかを使用して登録する必要があります。
MFC 提供の
WNDCLASS
を使用して暗黙的に。Windows コントロール (またはその他のコントロール) をサブクラス化することによって暗黙的に。
MFC AfxRegisterWndClass または AfxRegisterClass を 呼び出して明示的 に指定します。
Windows ルーチン RegisterClass を呼び出して明示的に指定します。
WNDCLASS フィールド
WNDCLASS
構造体は、ウィンドウ クラスを記述するさまざまなフィールドで構成されます。 次の表に、フィールドを示し、MFC アプリケーションでのフィールドの使用方法を指定します。
フィールド | 説明 |
---|---|
lpfnWndProc | ウィンドウ プロシージャは、〘〘 AfxWndProc |
cbClsExtra | 使用しない (ゼロにする必要があります) |
cbWndExtra | 使用しない (ゼロにする必要があります) |
hInstance | AfxGetInstanceHandle で自動的に入力される |
hIcon | フレーム ウィンドウのアイコン(下を参照) |
hCursor | マウスがウィンドウの上にある場合のカーソル(以下を参照) |
hbrBackground | 背景色(下記参照) |
lpszMenuName | 使用されません (NULL にする必要があります) |
lpszClassName | クラス名(以下を参照) |
提供された WNDCLASSes
MFC の以前のバージョン (MFC 4.0 より前) には、いくつかの定義済みの Window クラスが用意されていました。 これらの Window クラスは、既定では提供されなくなりました。 アプリケーションでは、適切なパラメーターで AfxRegisterWndClass
を使用する必要があります。
アプリケーションが指定したリソース ID (AFX_IDI_STD_FRAME など) を持つリソースを提供する場合、MFC はそのリソースを使用します。 それ以外の場合は、既定のリソースが使用されます。 アイコンには標準のアプリケーション アイコンが使用され、カーソルには標準の矢印カーソルが使用されます。
2 つのアイコンは、1 つのドキュメントの種類を持つ MDI アプリケーションをサポートします。1 つはメイン アプリケーションのアイコン、もう 1 つは象徴的なドキュメント/MDIChild ウィンドウのアイコンです。 アイコンが異なる複数のドキュメントの種類の場合は、追加の WNDCLASS
を登録するか、 CFrameWnd::LoadFrame 関数を使用する必要があります。
CFrameWnd::LoadFrame
は、最初のパラメーターとして指定したアイコン ID と次の標準属性を使用して、 WNDCLASS
を登録します。
クラススタイル:
CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
アイコン AFX_IDI_STD_FRAME
矢印カーソル
COLOR_WINDOW背景色
CMDIFrameWnd
のクライアント領域は MDICLIENT ウィンドウで完全にカバーされるため、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
は、ウィンドウ クラスの登録に失敗した場合 (パラメーターが正しくないか、Windows メモリ不足のため) に CResourceException をスローします。
RegisterClass 関数と AfxRegisterClass 関数
AfxRegisterWndClass
が提供するよりも高度な操作を行う場合は、Windows API RegisterClass
または MFC 関数AfxRegisterClass
を呼び出すことができます。
CWnd
、CFrameWnd、CMDIChildWndCreate
関数は、最初のパラメーターとしてウィンドウ クラスの lpszClassName 文字列名を受け取ります。 登録に使用したメソッドに関係なく、登録済みのウィンドウ クラス名を使用できます。
Win32 の DLL で AfxRegisterClass
(または AfxRegisterWndClass
) を使用することが重要です。 Win32 は DLL によって登録されたクラスの登録を自動的に解除しないため、DLL が終了したときにクラスの登録を明示的に解除する必要があります。
RegisterClass
の代わりにAfxRegisterClass
を使用すると、自動的に処理されます。
AfxRegisterClass
は、DLL によって登録された一意のクラスの一覧を保持し、DLL が終了すると自動的に登録解除されます。 DLL で RegisterClass
を使用する場合は、DLL が終了したときに ( DllMain 関数で) すべてのクラスが登録解除されるようにする必要があります。 これを行わないと、別のクライアント アプリケーションが DLL を使用しようとしたときに、 RegisterClass
が予期せず失敗する可能性があります。