>> WINAPI入門トップに戻る

ウィンドウの作成

今回はウィンドウの作成について説明します。
前回説明したとおり、ウィンドウの作成でしなければならないのは

①ウィンドウクラスの登録
②ウィンドウの作成

の二つです。
まずはウィンドウクラスの登録から説明します。

ウィンドウクラスを登録するには、WNDCLASS構造体を定義し、
RegisterClass関数にそのアドレスを渡します。
下記のコードをごらん下さい。

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
	WNDCLASS wc;

	wc.style=CS_HREDRAW | CS_VREDRAW;//縦横の再描画をする
	wc.lpfnWndProc=WinProc;//ウィンドウプロシージャの名前
	wc.cbClsExtra=wc.cbWndExtra=0;//使わないから0かNULL
	wc.hInstance=hInstance;//インスタンスハンドル
	wc.hCursor=wc.hIcon=NULL;//NULLで問題なし
	wc.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);//背景を黒に設定
	wc.lpszClassName="test";//クラス登録名は「test」に設定
	wc.lpszMenuName=NULL;//メニューは使用しないのでNULL
	
	if(!RegisterClass(&wc)){
		return -1;
	}

まずWNDCLASS構造体を宣言して、色々なメンバに値を代入しています。
WNDCLASS構造体は以下のように定義されています。

typedef struct _WNDCLASS {
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HANDLE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCTSTR lpszMenuName;
LPCTSTR lpszClassName;
} WNDCLASS;

styleメンバはウィンドウクラスのスタイルを指定します。
lpfnWndProcメンバはウィンドプロシージャの関数を指定します。
hInstanceメンバはインスタンスハンドルを指定します。
hCursorはカーソルのハンドルを指定します。
hIconはアイコンのハンドルを指定します。
hbrBackgroundメンバは背景色を設定します。
lpszClassNameメンバは登録するクラスの名前を指定します。
lpszMenuNameメンバはメニューのハンドルを指定します。

ただの平凡なwindowアプリケーションであれば、上記のメンバを設定するだけで十分です。
hIcon,hCursor,lpszMenuName,cbClsExtra,cbWndExtraメンバーは
NULLを指定しても問題なく動作します。

styleメンバに指定してる、CS_HREDRAWとCS_VREDRAWはウィンドウのリサイズ時に
縦横を再描画するかしないかの設定です。
基本はこの二つを指定しておけばokです。

hbrBackgroundメンバで、GetStockObject関数を使っています。
この関数は引数に指定した定数のGDIオブジェクトを取得する関数です。
描画専用のオブジェクトだと思ってもらえれば問題ありません。
それを取得し、HBRUSH型にキャストしてます。
hbrBackgroundメンバはHBRUSH型なので、これをする必要があります。
その他のメンバについては、コード内に記述している通りです。

これでウィンドウクラスの定義が出来ました。
これを、RegisterClass関数に渡して、登録を行います。

RegisterClass関数にはWNDCLASS構造体のアドレスを渡します。
関数が成功すれば、0以外の値が返ります。失敗すれば0が返ります。
上記のコードでは失敗した場合はプログラムを終了するようにしています。
ここまでが、ウィンドウクラスの登録になります。
また、プログラム終了時には、UnregisterClass関数で、
ウィンドウクラスを破棄する必要があります。
この関数の第一引数にはクラス名、第二引数にはインスタンスハンドルを指定して下さい。

次にウィンドウの作成を説明します。
ウィンドウの作成には、CreateWindow関数を使います。
引数は以下のようになっています。

HWND CreateWindow(
LPCTSTR lpClassName, // RegisterClass関数で登録したクラス名
LPCTSTR lpWindowName, // ウィンドウの名前
DWORD dwStyle, // ウィンドウスタイル
int x, // ウィンドウの横方向の位置
int y, // ウィンドウの縦方向の位置
int nWidth, // ウィンドウの幅
int nHeight, // ウィンドウの高さ
HWND hWndParent, // 親ウィンドウまたはオーナーウィンドウのハンドル
HMENU hMenu, // メニューハンドルまたは子ウィンドウ ID
HINSTANCE hInstance, // アプリケーションインスタンスのハンドル
LPVOID lpParam // ウィンドウ作成データ
);

関数が成功すると、作成したウィンドウのウィンドウハンドルが返ります。
失敗するとNULLが返ります。
ウィンドウハンドルとはどのウィンドウなのかを識別するための番号です。
CreateWindow関数は実は、CreateWindowA関数とCreateWindowW関数の二つのどちらかが実行されています。
実はプロジェクトの文字コードの設定によって、都合の良い方にtypedefで名前が変えられています。
プロジェクトアイコンをクリックしてプロパティを見てみてください。

この文字セットの設定が「マルチバイト文字セットを使用する」になっていれば、CreateWindowA関数が、
「Unicode文字セットを使用する」になっていれば、CreateWindowW関数が実行されます。
これによって影響してくるものは、第一引数と第二引数です。
ここは文字列を指定しますが、マルチバイトの文字セットは単純に
「"test"」とダブルクオテーションで指定すれば良いのに対し、
Unicode文字セットを使用する場合は文字の前に大文字のLを置いて、
「L"test"」と書かなければなりません。
もっと詳しく言うと、マルチバイト文字セットの場合は、第一、二引数の方がLPCSTR(const char)型なのに対し、
Unicode文字セットだとLPCWSTR(const w_char)型になります。
ですので引数の指定方法が違うんですね。
この仕組みは他にも沢山ある関数についても言えることです。
何か文字列関連のコンパイルエラーが出たらまずコレを疑いましょう。

さて話がそれましたが、実際のCreateWindow関数のコードを見てください。
関数はCreateWindowA関数を使っていますが、CreateWindow関数を使っても、
文字セットをマルチバイト文字セットに指定してれば、自動的にCreateWindowA関数が実行されます。

	hwnd=CreateWindowA("test","テストウィンドウ",WS_VISIBLE | WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX,
		0,0,WIDTH,HEIGHT,NULL,NULL,hinst,NULL);

	if(hwnd==NULL){
		return -1;
	}

第一引数には先程ウィンドウクラスを登録する際に指定したクラス名を指定しています。
第二引数にはウィンドウの名前を指定しています。
第三引数はウィンドウスタイルを指定しています。
上記のコードだと、システムメニュー、システムメニュー、タイトルがあり、
ウィンドウを表示する、という指定になります。
ウィンドウスタイルは他にも沢山ありますので、コチラを参照して下さい。
親ウィンドウハンドル、メニューハンドル、ウィンドウ作成データは今回は必要ないので、
NULLを指定しています。
その他のメンバは関数の説明とコードの通りです。

ここまでがウィンドウの登録になります。
引数が非常に多くて覚えるが大変ですが、
まずは絶対使う必要のあるメンバや引数だけ覚えてください。

次回はメッセージループについて説明します。


>> 【メッセージループ】に進む
>> WINAPI入門トップに戻る
●更新履歴
2016/08/16 Java入門ページにページを幾つか追加
2016/04/08 Java入門ページ作成
2016/03/09 メニューレイアウト変更。ブラウザキャッシュのクリアをお願い致します。
2016/03/09 PDOトランザクション、自動コミットモードをオフ追加
2016/03/09 PDO 例外処理 try catch追加
2016/03/09 PDO update文実行追加
2016/03/09 PDO delete文実行追加
2016/03/09 PDO insert文実行追加
2016/03/09 PDO selectでデータを取得、fetchAll、queryメソッド追加
2016/03/09 PDO bindValueとbindParamの違い追加
2016/03/09 PDO prepare プリペアドステートメントの使い方追加
2016/03/04 ソースコードをクリップボードにコピーする機能を追加
2016/03/04 C言語、C++のページのソースコードを一部修正
2014/01/31 C言語関数一覧ページに11ページほど追加
2014/01/31 C言語関数一覧ページに30ページほど追加
2014/01/30 C言語関数一覧ページ作成中
2013/07/01 レイアウト変更に伴いブラウザキャッシュのクリアをお願いします。
2013/07/01 MySQL入門ページ作成
2013/07/01 PHP入門ページにSQLite学習項目追加
2013/06/25 ドメイン変更、レイアウトを一部変更
2013/03/14 レイアウトを一部変更
2012/08/13 C言語よくある課題・宿題ページ開設!
2012/08/13 シューティングゲーム作成第33章追加!
2012/08/11 ドメイン変更&サーバ移設完了
2012/04/21 シューティングゲームプログラミング第2,3章の内容を修正
2012/04/19 シューティングゲームプログラミング第2章の内容を修正
2012/04/03 Googleカスタム検索を設置!
2012/04/03 シューティングゲームプログラミング第32章追加!
2012/04/03 シューティングゲームプログラミング第31章追加!
2012/03/31 サイトをリニューアルしました!
2012/03/25 シューティングゲームプログラミング第30章追加!
2012/03/19 シューティングゲームプログラミング第29章追加!
2012/03/16 シューティングゲームプログラミング第28章追加!
2012/02/27 シューティングゲームプログラミング第27章追加!
2012/02/03 シューティングゲームプログラミング第26章追加!
2012/01/31 シューティングゲームプログラミング第25章追加!
2012/01/20 シューティングゲームプログラミング第23,24章追加!
2012/01/11 シューティングゲームプログラミング第22章追加!
2012/01/05 トップページ、ゲームプログラミング関連のトップページのデザインを変更
2012/01/04 シューティングゲームプログラミング第21章追加!
2012/01/01 シューティングゲームプログラミング第20章追加!
2011/12/25 シューティングゲームプログラミング第19章追加!
2011/12/22 シューティングゲームプログラミング第18章追加!
2011/12/18 シューティングゲームプログラミング第17章追加!
2011/12/17 シューティングゲームプログラミングページOPEN!
2011/11/21 ゲームプログラミングページOPEN!
2011/11/21 サイトデザインを大幅に変更
2011/11/17 TOPページのデザインを変更。相互リンクページに、複数サイト追加。
2011/11/06 WINAPI学習ページ(33~36章)追加
2011/11/05 WINAPI学習ページ(20~32章)追加
2011/10/27 WINAPI学習ページ(14~19章)追加
2011/10/21 WINAPI学習ページ(13章)追加
2011/10/21 サイトマップ、連絡ページ追加
2011/10/17 WINAPI学習ページ(6~11章)追加
2011/10/16 WINAPI学習ページ(1~5章)追加
2011/10/13 全体のレイアウト変更
2011/10/07 PHP学習ページ(8~11章)追加
2011/10/06 PHP学習ページ(1~7章)作成
2011/10/06 JavaScriptリファレンスページ作成
2011/10/05 C言語学習ページ発展編(10~14章)追加
2011/10/04 C言語学習ページ発展編(1~9章)追加。
2011/10/03 HTML/CSSリファレンスのページ追加。(個々の詳細ページは作成中)
2011/09/30 HTML学習ページ(8章)追加
2011/09/29 JavaScript学習ページ(12~17章)追加
2011/09/28 JavaScript学習ページ(1~11章)追加
2011/09/27 HTML学習ページ(4~7章)追加
2011/09/26 C言語学習ページ(27章)追加、C++学習ページ(17章)、HTML学習ページ(1~3章)追加
2011/09/25 C言語学習ページ(23~26章)を追加
2011/09/24 C++学習ページ(9~16章)追加
2011/09/23 C++学習ページ(3~8章)追加
2011/09/22 C言語の学習ページ(22章)とC++学習ページ(1~2章)追加
2011/09/21 C言語の学習ページ(15章~21章)を追加
2011/09/20 C言語の学習ページ(10章~14章)を追加
2011/09/19 サイト作成(随時更新予定)