テクニカル ノート


MFC ライブラリ リファレンス
テクニカル ノート 1: ウィンドウ クラスの登録

Noteメモ :

次のテクニカル ノートは、最初にオンライン ドキュメントの一部とされてから更新されていません。結果として、一部のプロシージャおよびトピックが最新でないか、不正になります。最新の情報について、オンライン ドキュメントのキーワードで関係のあるトピックを検索することをお勧めします。

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

問題

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

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

  • MFC 提供の WNDCLASS で暗黙に登録

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

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

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

WNDCLASS と MFC

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

スタイル ウィンドウのスタイル

LpfnWndProc

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

CbClsExtra

使用しない。0 にする。

CbWndExtra

使用しない。0 にする。

HInstance

自動的に AfxGetInstanceHandle が入る。

HIcon

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

HCursor

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

HbrBackground

背景色。下記参照。

LpszMenuName

使用しない。NULL にする。

LpszClassName

クラス名。下記参照。

提供される WNDCLASS

MFC 4.0 より前の MFC では、定義済みの Window クラスが多数提供されていました。これらの Window クラスは、技術上の問題により、既定では提供されないことになりました。この技術上の問題とは、1 つはバージョン管理上の問題であり複数の MFC バージョンを同一アドレス空間に読み込んだ場合に問題になります。もう 1 つの問題は、MFC アプリケーションと OLE コントロールの両方が MFC DLL を使う場合があるという点です。

次に、以前提供されていたこれらの WNDCLASS を使っているコードを移行させる方法について説明します。アプリケーションでは、これらのクラスの代わりに AfxRegisterWndClass を使い、該当するパラメータを指定してください。

次に、クラスとその属性を示します。

  • "AfxWnd" は、CWnd::Create で作成したすべての子ウィンドウに対して使います。

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

    • アイコンなし

    • 矢印カーソル

    • 背景色なし

  • "AfxFrameOrView" は、スタンドアロンの CFrameWndCMDIChildWnd など、ビューおよびフレーム ウィンドウに対して使います。

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

    • アイコン AFX_IDI_STD_FRAME

    • 矢印カーソル

    • COLOR_WINDOW 背景色

  • "AfxMDIFrame" は、CMDIFrameWnd::Create で作成した MDI フレーム ウィンドウ、つまり親ウィンドウに対して使います。

    • クラス スタイル : CS_DBLCLKS サイズ変更中のフラッシュ回数が減ります。

    • アイコン AFX_IDI_STD_MDIFRAME

    • 矢印カーソル

    • 背景色なし

  • "AfxControlBar" は、標準実装のコントロール バーに対して使います。

    • クラス スタイル : 0 サイズ変更中のフラッシュ回数が減ります。ダブルクリックは使えません。

    • アイコンなし

    • 矢印カーソル

    • 背景色は灰色 (COLOR_BTNFACE)

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

単一文書型の MDI アプリケーションをサポートするアイコンは 2 つあります。メイン アプリケーション用のアイコンとアイコン化文書/MDI 子ウィンドウ用のアイコンです。各種のアイコンを使う複数文書型の場合は、さらに WNDCLASS を登録するか、CFrameWnd::LoadFrame 関数を使ってください。

CFrameWnd::LoadFrameWNDCLASS を自動的に登録します。このとき "AfxFrameOrView" の標準属性を使いますが、アイコン ID は LoadFrame の第 1 パラメータのものを使います。

MDIFrameWnd の背景色およびカーソルの値は使いません。MDIFrameWnd のクライアント領域が "MDICLIENT" ウィンドウに完全に隠れるからです。"MDICLIENT" ウィンドウのサブクラス化はお勧めしません。できるだけ、標準の色とカーソル タイプを使ってください。

コントロールのサブクラス化

Windows コントロール (CButton など) のサブクラスまたはスーパークラスを作成すると、作成したクラスはこのコントロールの Windows 版で提供される WNDCLASS 属性を自動的に取得します。

AfxRegisterWndClass 関数

MFC にはウィンドウ クラスを登録するための補助ルーチンが用意されています。一連の属性 (ウィンドウ クラスのスタイル、カーソル、背景ブラシ、アイコン) を指定すると、合成名が生成され、そのウィンドウ クラスが登録されます。次に例を示します。

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

この関数は生成され登録されたウィンドウ クラスの名前の一時的な文字列を返します。詳細については、『MFC リファレンス』を参照してください。

返された文字列は、静的な文字列バッファを指す一時的なポインタであり、次に AfxRegisterWndClass を呼び出すまで有効です。この文字列を長期間保持するには、CString 変数に保存します。次に例を示します。

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

このウィンドウ クラスの登録に失敗すると、AfxRegisterWndClassCResourceException をスローします。原因は、パラメータが不正値であるか Windows メモリの不足です。

RegisterClass 関数および AfxRegisterClass 関数

AfxRegisterWndClass で提供される機能より高度な操作を行うには、Windows API 関数の RegisterClass または MFC 関数の AfxRegisterClass を呼び出します。関数 CWndCFrameWndCMDIChildWndCreate はどれも第 1 パラメータとしてウィンドウ クラスの lpszClassName 文字列名を受け取ります。このパラメータとして、登録方法に関係なく、どのウィンドウ クラス名でも使えます。

Win32 で DLL で AfxRegisterClass (または AfxRegisterWndClass) を使うと便利です。Win32 では DLL で登録したクラスを自動的に登録解除しないので、DLL の終了時に明示的に登録を解除する必要があります。しかし、RegisterClass の代わりに AfxRegisterClass を使うと、この登録解除を自動的に行ってくれます。AfxRegisterClass は DLL で登録した一連の一意なクラスを保持し、DLL の終了時に自動的にこれらのクラスを登録解除します。DLL で RegisterClass を使うと、DLL を DllMain 関数で終了するときに、自分ですべてのクラスを登録解除する必要があります。この登録解除を忘れると、DLL を別のクライアント アプリケーションで使ったときに、RegisterClass が異常終了することがあります。

参照

その他の技術情報

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

タグ :


Page view tracker