MxA04_VC6.zip今回はウィンドウクラスの登録について見ていきます。前回紹介したWinMain()関数内からは、まず最初にRegisterWindowClass()関数を呼び出していました。RegisterWindowClass()関数は同じプロジェクト内の関数です。ウィンドウクラスを登録します。ウィンドウクラスの情報を格納する構造体です。どんなウィンドウクラスを作るのか、設定をセットします。ウィンドウクラスを登録します。ウィンドウクラスを登録します。ウィンドウクラスの情報を格納する構造体です。どんなウィンドウクラスを作るのか、設定をセットします。ウィンドウクラスを登録します。TRUE;}この関数では、「ウィンドウクラスの登録」というとても重要なことを行っています。ウィンドウクラスの登録ウィンドウを表示するためには、必ず「ウィンドウクラスの登録」が必要になります。この「ウィンドウクラス」というものについて見ていきましょう。「ウィンドウクラス」と、「クラス」という名前が付いていますが、C++言語の「クラス」とは全くの別物です。何の関連もありません。この「クラス」という言葉には特に意味はありません。この用語は「ウィンドウクラス」というひとつの単語として覚えておきましょう。「ウィンドウクラス」とは何なのかというと、「これこれこういう形のウィンドウですよ」という、Windowsに登録されたウィンドウの形状のことです。ウィンドウを作成する際には、まず大まかな形状をWindowsに登録します。これが「ウィンドウクラス」です。登録後、それを元にウィンドウを表示します。ウィンドウクラスはウィンドウにおけるテンプレートのようなものということです。ウィンドウクラスただし、ウィンドウクラスで登録する設定はわずかです。簡単な形状と、アイコンやカーソル、後で説明する「ウィンドウプロシージャ」の設定を行うだけです。そのため、ウィンドウの細かい形状はウィンドウの表示時に設定しますので、ウィンドウクラスで行う設定は、ウィンドウの設定全体の内のごく一部ということになります。ウィンドウクラスの登録方法ウィンドウクラスの登録は、RegisterClass()関数というAPIで行います。WNDCLASS構造体に、ウィンドウクラスの情報を設定します。この構造体はウィンドウクラスの情報を格納する構造体で、この中に設定をセットして、RegisterClass()関数に渡すことでウィンドウクラスを登録します。WNDCLASS構造体WNDCLASS構造体のメンバ変数は以下の通りです。・style:ウィンドウのスタイルを渡します。本当におおまかな形状しか決めないため、サンプルプログラム1の通りにして構いません。・lpfnWndProc:「ウィンドウプロシージャ」のアドレスを渡します。詳しくは「ウィンドウプロシージャ」のページで説明します。・cbClsExtra:ウィンドウクラスの「拡張領域」のサイズ(バイト数)を渡します。通常は0を設定します。・cbWndExtra:ウィンドウの「拡張領域」のサイズ(バイト数)を渡します。通常は0を設定します。・hInstance:インスタンスハンドルを渡します。「インスタンスハンドル」についてはすべてはWinMain()から」をご覧ください。・hIcon:アイコンのハンドルを渡します。詳しくは次項で説明します。・hCursor:カーソルのハンドルを渡します。詳しくは次項で説明します。・hbrBackground:背景を塗りつぶすブラシのハンドルを渡します。詳しくは「デバイスコンテキストとハンドル」で説明します。・lpszMenuName:メニューのハンドルを渡します。詳しくは次項で説明します。・lpszClassName:ウィンドウクラス名を渡します。あとでウィンドウを作成するときに、この名前を指定します。ウィンドウクラスの設定は、他のページで説明している部分が多いのでそちらもご覧ください。正直なところ、ウィンドウクラスはアプリケーションごとにあまり変える必要はありません。ウィンドウがひとつだけの場合には、これをそのまま使用しても問題ないでしょう。アイコンの設定等はウィンドウの作成後も変えられるからです。さまざまな種類のウィンドウを表示する場合には、その数だけウィンドウクラスの登録が必要かもしれません。ウィンドウプロシージャやメニューが異なるウィンドウを作る場合には、ウィンドウクラスをそれぞれのウィンドウ用に登録する必要があります。その場合には、lpfnWndProcメンバ変数やlpszMenuName、そしてlpszClassNameメンバ変数をそれぞれ変えて登録すればいいでしょう。WNDCLASS構造体の準備ができたら、RegisterClass()関数でウィンドウクラスを登録します。RegisterClass()関数にはWNDCLASS構造体のアドレスを渡します。戻り値は、登録に成功したら0以外、失敗したら0が返されます。登録したウィンドウクラスは、「ウィンドウクラス名」で区別されます。これはWNDCLASS構造体のlpszClassNameメンバ変数で指定した文字列です。サンプルプログラム1では「CLASS_NAME」を指定していますが、これは「すべてはWinMain()から」で説明した「CLASS_NAMEグローバル変数」で、"MxA02WndClass"という文字列を指定しています。このウィンドウクラス名は、後でウィンドウを作成する際に「どのウィンドウクラスを元にウィンドウを作成するのか」を指定する時に使用します。そのため、複数のウィンドウクラスを登録する場合、それぞれのウィンドウクラス名はアプリケーション内で重複しないようにする必要があります。複数のウィンドウクラスを登録する場合にはウィンドウクラス名をそれぞれ別にしましょう。ウィンドウクラス名は「アプリケーション内」で重複しなければ問題ありません。普通に登録したウィンドウクラスは「ローカル」なものなので、他のアプリケーションで登録したウィンドウクラス名と重複しても大丈夫です(ただし、ユーティリティアプリケーションの中には「ウィンドウクラス名を見てアプリケーションを識別する」ものとかもあるので、他になさそうなウィンドウクラス名にした方が無難でしょう)。リソースとはWNDCLASS構造体で指定するメンバ変数のうち、hIcon、hCursor、lpszMenuNameで指定するアイコン、カーソル、メニューは「リソース」というものです。「リソース(resource)」というと、一般的には「資源」という意味ですが、Windowsアプリケーションでは、アプリケーション内に埋め込まれた、アイコンやメニュー、ダイアログといった画面表示用データの事を指します。ウィンドウの左上に表示されるアイコン、ウィンドウ上部に表示されるメニュー、ダイアログ内のボタンやエディットボックスのサイズと位置は、アプリケーション内に「リソース」という形で保存されています。これらは「画面の表示」を行う部分のため、プログラム内で直接記述せず、専用のエディタを使用して作成します。「ダイアログ上のボタンの位置は(2,3)の位置で(100,20)のサイズ」のような指定をプログラム上で行うのは面倒なので、分かりやすいエディタで修正し、それをリソースという形で埋め込めるようになっているわけです。今回の解説では、本筋とは少し異なるため、リソースは作成していません。ウィンドウクラスで指定しているアイコンは、Windowsシステムが持っている「ビックリマークアイコン」です。);LoadIcon()関数は、アイコンを読み込むAPIです。第1引数にはインスタンスハンドル、第2引数にはアイコンの「ID」を指定します。リソースには「ID」という番号が割り振られていて、読み込むアイコンをその番号で指定します。ここでは、Windowsシステムのアイコンを使うため、第1引数にはNULLを指定します。リファレンスに書かれているものから選択します。戻り値には「アイコンのハンドル」という、ポインタの一種が返されます。「ハンドル」については「デバイスコンテキストとハンドル」で解説します。リソースはそれぞれハンドルで管理し、アイコンはアイコンのハンドル、メニューはメニューのハンドルを使用することになります。脱線して、リソースのうち、アイコンを作ってみましょう(今回の本筋とは異なるものですのでおまけ扱いです。ここに書かれていることはしなくても構いません。実際に修正を行ったサンプルプロジェクトを用意しましたのでそちらもご利用ください)。リソースを作るためには、まず「リソーススクリプト」を作ります。リソーススクリプトは「アイコンにどのファイルを使うか」「メニューの構造はどうするか」「ダイアログの中身はどうするか」といったことが書かれたテキストファイルです。C++のメニューから「ファイル」-「新規作製」を選択します。「新規作成」ダイアログ(図3)が表示されるので、そのダイアログの上部にあるタブから「ファイル」を選びます(おそらく初めから表示されています)。スクリプト」を選択し、「ファイル名」に「Script.rc」を入力してください。OKボタンを押すと、フォルダ表示のような形式でScript.rcが開きますのでこれを閉じてください。これでリソーススクリプトが作成されました。次にアイコンを作成しましょう。C++のメニューから「挿入」-「リソース」を選択します。「リソースの挿入」ダイアログが表示されるので、「リソースのタイプ」から「Icon」を選択して「新規作成」を押してください。アイコンが作成され、アイコンエディタでそのアイコンが開きます。適当に描いて保存するとアイコンの完成です。このアイコンのIDは「IDI_ICON1」となります。このIDを分かりやすく変えたい場合には、アイコンエディタで開いた状態で、メニューの「表示」-「プロパティ」を選択して、表示されたプロパティダイアログで変更することができます(今回の例では変更しません)。このIDは、前述したとおり「整数値」です。「IDI_ICON1」と整数値との結びつけは、「resource.h」というヘッダーファイルで定義されています。このファイルはリソーススクリプトを作ると自動的に作成され、リソースを修正すると自動的に修正されます。基本的にresource.hの中身は見る必要はありません。修正する必要がありませんし、修正してはいけないわけですから。そのため、基本的に開くことはありませんが、一応ここで見ておきましょう。101#endif#endif#defineマクロで、「IDI_ICON1」が「101」という整数値に結びつけられていることが分かると思います。このアイコンをウィンドウの左上で表示してみましょう。前述したとおり、アイコンはウィンドウクラスを登録する際にWNDCLASS構造体のhIconメンバ変数で指定します。);同じようにLoadIcon()関数を使用しますが、引数が異なります。第1引数にはインスタンスハンドルを渡します。リソースはアプリケーション内に格納されているので、このアプリケーションのインスタンスハンドルを渡す必要があります。第2引数には、表示するアイコンのIDを指定します。渡すのではなくMAKEINTRESOURCEマクロを通して渡します。このようにして、先ほど作成したIDI_ICON1アイコンを読み込み、ウィンドウクラスにセットします。このウィンドウクラスを元に作成したウィンドウは、左上のアイコンがこのIDI_ICON1アイコンになります。この「IDI_ICON1」という名称をプログラム中で使うためには、resource.hヘッダーファイルに書かれた定義を読み込んでおく必要があります。そのため、WinMain.cソースファイルの先頭でresource.hヘッダーファイルをインクルードしておきます。