プログラムの修正は以上です。ビルドして実行すれば、ウィンドウの左上にアイコンが表示されます。メニュー等、他のリソースを使う場合も同じようにしましょう。他のウィンドウのウィンドウクラスウィンドウクラスをMFCで登録する場合について説明する前に、「他のウィンドウ」がどのようなウィンドウクラスなのかということを紹介しておきます。実は、他のアプリケーションが作成した各ウィンドウの情報や、そのウィンドウクラスの情報を取得することができます(ちなみにそういうプログラムを作ることもできます)。C++に付属しています。「Spy++」といって、各アプリケーションや各ウィンドウの情報を取得したり、特定のウィンドウに送られる「メッセージ」を見ることができます(「メッセージ」については「ウィンドウプロシージャ」で説明します)。このSpy++を実行してみましょう。ウィンドウを調べる対象用に、フォルダを4つほど開いておいてください。C++のメニューの「ツール」-「Spy++」を選択してください。Spy++が起動します。Spy++起動直後、Spy++にはウィンドウ一覧がツリー形式で表示されています。各行は、左から「ウィンドウハンドル(ウィンドウのポインタ)」「ウィンドウ名」「ウィンドウクラス名」となります。このウィンドウ一覧から「フォルダのウィンドウ」を探してみてください。「フォルダのウィンドウ」は、ウィンドウタイトルが「フォルダ名」になっているので、それを手がかりにして探してみてください。そのウィンドウのウィンドウクラス名には「CabinetWClass」と書かれていることがわかると思います。このウィンドウクラス名は、どのフォルダも同じ名前になっています。「フォルダ」というアプリケーション(つまり「C:\WinNT\explorer.exe」)のウィンドウは、全て同じ「CabinetWClass」という名前のウィンドウクラスを使用しているということです。このツリーを開いていくと、色々なウィンドウが出てくると思います。実は、ウィンドウは「入れ子」になっています。「フォルダのウィンドウ」の場合、一番外枠のウィンドウの中に、ツールバーを表示するウィンドウや、ファイル一覧を表示するウィンドウなど、様々なウィンドウが重なっています。ツリーを展開していくと、「Edit」というウィンドウクラスのウィンドウがあると思います。このウィンドウは、「アドレス」の右にある「フォルダのパスを入力する入力欄」のウィンドウです。実は、Windowsの標準的な画面パーツ――エディットボックス、コンボボックス、ボタン、リスト等――は、全て「ウィンドウの一種」です。ただのパーツのように見えますが、実はちゃんとしたウィンドウです。ダイアログであれば「ダイアログのウィンドウの上に、ボタンやエディットボックスのウィンドウが乗せてある」ということになります。これらのウィンドウはWindowsがあらかじめウィンドウクラスを登録してあります。アドレスの右側にあるエディットボックスは、「Edit」というウィンドウクラス名で登録されています。エディットボックスのようなものを「プログラムで一から作る必要はない」ということです。これらはWindowsがあらかじめ用意してくれているので簡単に表示できるわけです。このように、ウィンドウクラスには自分で登録するものだけではなく、あらかじめ登録されているものもあるということを憶えておいてください。MFCのウィンドウクラスMFCの場合、ウィンドウクラスの登録は複雑な仕組みになっています。MFCは「ドキュメント・ビュー・アーキテクチャー」というシステムを使用しています。このシステムは、「ファイル形式を元にビュー(ウィンドウ)を作製する」という方法を採っています。テキストファイルを読み込めばテキストを表示し、画像を読み込めば画像を表示し、といったことができる仕組みになっています。具体的な流れを追ってみましょう。各アプリケーションのCWinApp派生クラス(たとえばCTest01Appクラスとか)のInitInstance()メンバ関数がまず呼び出されます。その中でCWinAppクラスのProcessShellCommand()メンバ関数を呼び出し、そこから流れ流れてウィンドウを作成します。このProcessShellCommand()メンバ関数は、アプリケーションが実行されたときのコマンドライン引数をチェックし、何も指定されていなかったら空のビューとドキュメントを、ファイルが指定されていたらそのファイルを読み込んでドキュメントとビューを表示します。いった状況に合わせてウィンドウを作製するため、MFCがウィンドウを作成するときには、その場の状況に合わせてウィンドウクラスを登録します。そのため、実はウィンドウクラス名がかなり特殊なものになっています。MFCのウィンドウクラス図5をご覧ください。これはMDIアプリケーションのウィンドウをSpy++で見たものです。ウィンドウクラス名が「Afx:400000:8:10013:0:950e07」となっています。なんだかかなりへんてこなウィンドウクラス名になっています。MFCは、何度も新しいウィンドウクラスを登録しなければいけません。そのたびに「何か意味のあるウィンドウクラス名」を付けると面倒だと思ったのか、このようなへんてこなウィンドウクラス名を付けています。ちなみにこのウィンドウクラス名は、WNDCLASS構造体の各メンバ変数の値を元に作られています。このウィンドウクラス名の作成は、MFCのAfxRegisterWndClass()関数で行っています。(UINT)hIcon);このようにアイコンやカーソルのハンドルを元に作成しています。ハンドルはポインタの一種ですから、実行するたびに値が変わるため、実質ランダムな値を元にウィンドウクラス名が作られると言っていいでしょう。ドキュメント・ビュー・アーキテクチャーを使用した場合、CWinAppクラスのProcessShellCommand()メンバ関数から様々なメンバ関数を経由して、やがてこのAfxRegisterWndClass()関数が呼び出されます。ここでウィンドウクラス名が生成されたあと、さらにAfxRegisterClass()関数が呼び出されます。このAfxRegisterClass()関数の中で、APIのRegisterClass()関数が呼び出され、ウィンドウクラスが登録されます。略}つまり「MFCを使用している場合でも、ウィンドウクラスの登録はRegisterClass()関数で行う」ということです。これはMFCの大原則です。MFCが「Windowsで動くプログラム」である以上、Windowsの操作には必ずAPIを呼び出す必要があります。そのため、最初はWinMain()関数から始まり、ウィンドウクラスの登録にはRegisterClass()関数を呼び出し、さらにウィンドウの表示にはそのためのAPIを、画面の描画にはそのためのAPIを使用するわけです。MFCはAPIの呼び出しを隠しているだけです。やっていることは、この解説のサンプルプロジェクトで行っていることが複雑になっただけです。このことはしっかり憶えておいてください。この点について、次ページ以降も見ていくことになります。ちなみに、MFCを使用する場合、このドキュメント・ビュー・アーキテクチャーを必ず使用しなければいけないわけではありません。MFCにはこれを使用せずにウィンドウを構築する方法も用意してくれています。クラスの登録」と、このCodianの「MFCチップス」にある「常駐型アプリケーション」のページをお読みください。この方法を使用すると、自分の好きなウィンドウクラス名を使用できるため、ウィンドウクラス名が重要という場合にはこちらの方法がいいでしょう。逆に言うと、MFCのドキュメント・ビュー・アーキテクチャーを使用する場合には、ウィンドウクラス名は変更できないと考えた方がいいでしょう。まとめまず「ウィンドウを作製する前にウィンドウクラスをWindowsに登録する必要がある」ということを必ず憶えておいてください。その際には、WNDCLASS構造体に各設定を渡して、RegisterClass()関数を使って登録します。こちらは忘れても構いません。実際に使うことはあまりないでしょうから。MFCの部分については、「MFCだって、結局APIを使っているんだ」ということを必ず憶えておいてください。この講座の核心は、まさにここにあります。C++言語プログラミングの解説を行うCodianの一コンテンツです。詳しい説明はCodianのトップページをご覧ください。