テクニカル ノート 1: ウィンドウ クラスの登録

更新 : 2007 年 11 月

このノートでは、Microsoft Windows に必要な専用 WNDCLASS を登録する MFC ルーチンについて説明します。MFC および Windows で使用する WNDCLASS の属性について説明します。

問題

CWnd オブジェクトの属性 (Windows の HWND ハンドルなど) は、ウィンドウ オブジェクトと WNDCLASS の 2 か所に格納されます。WNDCLASS の名前は、ウィンドウ作成用の一般関数 (CWnd::CreateCFrameWnd::Create など) に lpszClassName パラメータとして渡されます。

WNDCLASS は、次の 4 つの方法のいずれかで登録します。

  • MFC 提供の WNDCLASS を使用して暗黙に登録

  • Windows コントロールなどのコントロールをサブクラス化することによって暗黙に登録

  • MFC の AfxRegisterWndClass または AfxRegisterClass を呼び出して明示的に登録

  • Windows ルーチン RegisterClass を呼び出して明示的に登録

WNDCLASS フィールド

WNDCLASS 構造体は、ウィンドウ クラスを記述する各種のフィールドで構成されます。次の表は、それぞれのフィールド名と、MFC アプリケーションでの使い方を示しています。

フィールド

説明

lpfnWndProc

ウィンドウ プロシージャ。AfxWndProc にする。

cbClsExtra

使用しない。0 にする。

cbWndExtra

使用しない。0 にする。

hInstance

自動的に AfxGetInstanceHandle が入る。

hIcon

フレーム ウィンドウのアイコン。下記参照。

hCursor

マウスがウィンドウ上にあるときのカーソル。下記参照。

hbrBackground

背景色。下記参照。

lpszMenuName

使用しない。NULL にする。

lpszClassName

クラス名。下記参照。

提供される WNDCLASS

以前のバージョンの MFC (MFC 4.0 より前) では、定義済みの Window クラスがいくつか提供されていました。これらの Window クラスは、既定では提供されないことになりました。アプリケーションでは、適切なパラメータと共にAfxRegisterWndClass を使用する必要があります。

アプリケーションで特定のリソース ID (AFX_IDI_STD_FRAME など) のリソースを用意すると、MFC はそのリソースを使うようになります。それ以外の場合は、既定のリソースを使います。アイコンの場合は標準のアプリケーション アイコンを使い、カーソルの場合は標準の矢印カーソルを使います。

単一文書型の MDI アプリケーションをサポートするアイコンは 2 つあります。1 つはメイン アプリケーション用のアイコンで、もう 1 つは文書や MDIChild ウィンドウ用のアイコンです。各種のアイコンを使う複数文書型の場合は、追加の WNDCLASS を登録するか、CFrameWnd::LoadFrame 関数を使用する必要があります。

CFrameWnd::LoadFrame は、第 1 パラメータとして指定したアイコン ID と、以下に示す標準属性を使用して、 WNDCLASS を登録します。

  • クラス スタイル : CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;

  • アイコン AFX_IDI_STD_FRAME

  • 矢印カーソル

  • COLOR_WINDOW 背景色

CMDIFrameWnd では、背景色とカーソルの値は使用されません。これは、CMDIFrameWnd のクライアント領域が MDICLIENT ウィンドウに完全に隠れるためです。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, ...);
...

ウィンドウ クラスの登録に失敗すると、AfxRegisterWndClassCResourceException をスローします。原因として、パラメータが正しくないか、Windows メモリが不足している可能性があります。

RegisterClass 関数および AfxRegisterClass 関数

AfxRegisterWndClass で行われる処理よりも高度な操作を行うには、Windows API 関数の RegisterClass または MFC 関数の AfxRegisterClass を呼び出します。CWndCFrameWnd、および CMDIChildWnd の Create 関数は、ウィンドウ クラスの lpszClassName 文字列名を第 1 パラメータとして受け取ります。登録済みのウィンドウ クラス名であれば、登録時に使用したメソッドに関係なく、どれでも使用できます。

Win32 上の DLL では、AfxRegisterClass (または AfxRegisterWndClass) を使用することが重要です。Win32 では、DLL から登録されたクラスは自動的には登録解除されないため、DLL の終了時に明示的に登録を解除する必要があります。ただし、RegisterClass の代わりに AfxRegisterClass を使用すると、この処理が自動的に行われます。AfxRegisterClass は、DLL から登録された一意のクラスのリストを保持し、DLL の終了時に自動的に登録を解除します。DLL で RegisterClass を使用する場合は、DLL の終了時に (DllMain 関数で) すべてのクラスを登録解除する必要があります。これを行わないと、別のクライアント アプリケーションが同じ DLL を使おうとしたとき、RegisterClass が予期せず失敗することがあります。

参照

その他の技術情報

番号順テクニカル ノート

カテゴリ別テクニカル ノート