メモ : |
|---|
| 次のテクニカル ノートは、最初にオンライン ドキュメントの一部とされてから更新されていません。結果として、一部のプロシージャおよびトピックが最新でないか、不正になります。最新の情報について、オンライン ドキュメントのキーワードで関係のあるトピックを検索することをお勧めします。 |
このノートでは、Microsoft Windows に必要な専用 WNDCLASS を登録する MFC ルーチンについて説明します。MFC および Windows で使う WNDCLASS の属性について説明します。
問題
CWnd オブジェクトの属性 (Windows の HWND など) はウィンドウ オブジェクトと WNDCLASS の 2 か所に格納されます。WNDCLASS は、C++ のクラスとは異なります。WNDCLASS の名前が lpszClassName パラメータでウィンドウ作成用の一般関数 (CWnd::Create、CFrameWnd::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 | クラス名。下記参照。 |
MFC 4.0 より前の MFC では、定義済みの Window クラスが多数提供されていました。これらの Window クラスは、技術上の問題により、既定では提供されないことになりました。この技術上の問題とは、1 つはバージョン管理上の問題であり複数の MFC バージョンを同一アドレス空間に読み込んだ場合に問題になります。もう 1 つの問題は、MFC アプリケーションと OLE コントロールの両方が MFC DLL を使う場合があるという点です。
次に、以前提供されていたこれらの WNDCLASS を使っているコードを移行させる方法について説明します。アプリケーションでは、これらのクラスの代わりに AfxRegisterWndClass を使い、該当するパラメータを指定してください。
次に、クラスとその属性を示します。
-
"AfxWnd" は、CWnd::Create で作成したすべての子ウィンドウに対して使います。
-
"AfxFrameOrView" は、スタンドアロンの CFrameWnd、CMDIChildWnd など、ビューおよびフレーム ウィンドウに対して使います。
-
"AfxMDIFrame" は、CMDIFrameWnd::Create で作成した MDI フレーム ウィンドウ、つまり親ウィンドウに対して使います。
-
"AfxControlBar" は、標準実装のコントロール バーに対して使います。
アプリケーションで AFX_IDI_STD_FRAME などのリソース ID のリソースを用意すると、MFC はこのリソースを使います。それ以外の場合は、既定のリソースを使います。アイコンの場合は標準のアプリケーション アイコンを使い、カーソルの場合は標準の矢印カーソルを使います。
単一文書型の MDI アプリケーションをサポートするアイコンは 2 つあります。メイン アプリケーション用のアイコンとアイコン化文書/MDI 子ウィンドウ用のアイコンです。各種のアイコンを使う複数文書型の場合は、さらに WNDCLASS を登録するか、CFrameWnd::LoadFrame 関数を使ってください。
CFrameWnd::LoadFrame は WNDCLASS を自動的に登録します。このとき "AfxFrameOrView" の標準属性を使いますが、アイコン ID は LoadFrame の第 1 パラメータのものを使います。
MDIFrameWnd の背景色およびカーソルの値は使いません。MDIFrameWnd のクライアント領域が "MDICLIENT" ウィンドウに完全に隠れるからです。"MDICLIENT" ウィンドウのサブクラス化はお勧めしません。できるだけ、標準の色とカーソル タイプを使ってください。
Windows コントロール (CButton など) のサブクラスまたはスーパークラスを作成すると、作成したクラスはこのコントロールの Windows 版で提供される WNDCLASS 属性を自動的に取得します。
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, ...);
...
このウィンドウ クラスの登録に失敗すると、AfxRegisterWndClass は CResourceException をスローします。原因は、パラメータが不正値であるか Windows メモリの不足です。
RegisterClass 関数および AfxRegisterClass 関数
AfxRegisterWndClass で提供される機能より高度な操作を行うには、Windows API 関数の RegisterClass または MFC 関数の AfxRegisterClass を呼び出します。関数 CWnd、CFrameWnd、CMDIChildWnd、Create はどれも第 1 パラメータとしてウィンドウ クラスの lpszClassName 文字列名を受け取ります。このパラメータとして、登録方法に関係なく、どのウィンドウ クラス名でも使えます。
Win32 で DLL で AfxRegisterClass (または AfxRegisterWndClass) を使うと便利です。Win32 では DLL で登録したクラスを自動的に登録解除しないので、DLL の終了時に明示的に登録を解除する必要があります。しかし、RegisterClass の代わりに AfxRegisterClass を使うと、この登録解除を自動的に行ってくれます。AfxRegisterClass は DLL で登録した一連の一意なクラスを保持し、DLL の終了時に自動的にこれらのクラスを登録解除します。DLL で RegisterClass を使うと、DLL を DllMain 関数で終了するときに、自分ですべてのクラスを登録解除する必要があります。この登録解除を忘れると、DLL を別のクライアント アプリケーションで使ったときに、RegisterClass が異常終了することがあります。
その他の技術情報
番号順テクニカル ノート
カテゴリ別テクニカル ノート