次の方法で共有


TN001: ウィンドウ クラスの登録

このノートでは、Microsoft Windows で必要な特別な WNDCLASSを登録する MFC ルーチンについて説明します。 MFC と Windows で使用される特定の WNDCLASS 属性について説明します。

問題

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

この WNDCLASS は、次の 4 つの方法のいずれかを使用して登録する必要があります。

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を呼び出すことができます。 CWndCFrameWndCMDIChildWndCreate 関数は、最初のパラメーターとしてウィンドウ クラスの lpszClassName 文字列名を受け取ります。 登録に使用したメソッドに関係なく、登録済みのウィンドウ クラス名を使用できます。

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

こちらも参照ください

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