WindowsAPI


さてさて、ウインドウを作れて喜んでる場合ではありません。
前回作ったのは STATICっていうクラスのウインドウでしたよね?覚えてる?CreateWindow関数の引数の1個目。
もともと用意されていたSTATICってのを選んで「じゃあこれで」と頼んだわけだけど
今日はそれを自分で作ってみよう。そしたらもっといろんなウインドウを作れるもんね

〜ウインドウクラス〜

例えばウインドウの中にはサイズ変更ができないものがある。
ウインドウの中だけマウスの形が変わるのや ウインドウのデザインがそもそも違うものがある。
そういうクラスがなんでもかんでも用意されてるわけじゃありません。自分で作るんです。
そういうのを「ここはこうで、ここはこうね」って設定する設定集みたいなのがウインドウクラス構造体です。
そういう設定をして名前をつけて「こういうクラス作りました!Windowsさん! そんでこのクラスでウインドウを作りますね!」
とすれば、自分で作ったクラスを自分のウインドウに使えるわけです。
どんな設定がクラスで出来るのか見てみましょうか。

〜WNDCLASS構造体〜

ウインドウクラス用のWNDCLASSっていう構造体が用意されています。
これの一つ一つのメンバーを書き換えてウインドウズに登録すれば このクラスを使ったウインドウを作れるわけです。
やってるところを見ながら解説。

#include <windows.h>

int WINAPI WinMain(HINSTANCE hInstance,
			HINSTANCE hPrevInstance,
			PSTR lpCmdLine,
			int nCmdShow){

	HWND hwnd;
	WNDCLASS windowclass;

	windowclass.style		= CS_HREDRAW | CS_VREDRAW;
	windowclass.lpfnWndProc	= DefWindowProc;
	windowclass.cbClsExtra	= 0;
	windowclass.cbWndExtra	= 0;
	windowclass.hInstance	= hInstance;
	windowclass.hIcon		= LoadIcon(NULL , IDI_APPLICATION);
	windowclass.hCursor		= LoadCursor(NULL , IDC_ARROW);
	windowclass.hbrBackground	= (HBRUSH)GetStockObject(WHITE_BRUSH);
	windowclass.lpszMenuName	= NULL;
	windowclass.lpszClassName	= TEXT("oyabunn");

	if(!RegisterClass(&windowclass))return -1;

	hwnd = CreateWindow(TEXT("oyabunn") , TEXT("こんちは世界!") ,
						WS_OVERLAPPEDWINDOW |WS_VISIBLE ,
						200 , 200 , 200 , 200 , NULL , NULL ,hInstance , NULL);
	
	MessageBox(hwnd,TEXT("OK?"),TEXT("OK?"),MB_OK);

	return 0;
}

やってることはこうです。
1、ウインドウクラス構造体の変数windowclassを作る
2、そのwindowclassの中身をつめていく。要するに欲しいウインドウの設定をしていく
3、それをウインドウズに登録する。

1は問題ないですよね。普通に変数を作ってるだけです。
問題は2ですね。どういう設定があって何を書かなければならないのか。
詳細を書くと

style ウインドウのスタイル
lpfnWndPrc ウインドウに使うウインドウプロシージャ
cbClsExtra 補助メモリ
cbWndExtra 補助メモリ
hInstance インスタンスハンドル
hIcon アイコン
hCursor カーソル
hbrBackground 背景
lpszMenuName メニュー
lpszClassName クラス

こうなるんですが。いきなり今日これを理解するのは難しいです。
なので、今日覚えて欲しいところだけ。

 

style ウインドウのスタイル
lpfnWndPrc ウインドウに使うウインドウプロシージャ
cbClsExtra 補助メモリ
cbWndExtra 補助メモリ
hInstance インスタンスハンドル
hIcon アイコン
hCursor カーソル
hbrBackground 背景
lpszMenuName メニュー
lpszClassName クラス

まずstyleですが、これはウインドウのスタイルです。サイズ変更ができるのかどうかや、その他どういうウインドウにしたいのかっていう部分です。
一番僕らが興味あるところですよね。
ここではCS_HREDRAW CS_VREDRAWを指定しました。これは水平にサイズ変更可能 と 垂直にサイズ変更可能 の2つです。
ORで結べばたくさん設定できるので このウインドウクラスで作ったウインドウは どっちにもサイズ変更できるってことです。

インスタンスハンドルはもうしってるよね?ここでも使います。

そしてlpszClassNameがこのクラスの名前。このプログラムではTEXT(”oyabunn”)ってなってますね。
oyabunnって名前にしてみました。

さて、oyabunnって名前の縦横サイズ変更可能なウインドウクラスを用意しました。
でもこのままではCreateWindow関数では使えません。
Windowsに登録する必要があるんです。
それをするのがRegisterClass関数


	if(!RegisterClass(&windowclass))return -1;

情報を詰め込んだこの変数のアドレス(&がついてるでしょ?)を渡します。
クラスの登録ができたら1が返ってきます、だめなら0です。
このif文では RegisterClass なので返り値が0のときreturn -1でプログラムを終了するってことになってますね。
登録に失敗したらしつこくせがまないいいプログラムです。うん。

そして登録したプログラムをCreateWindow で使用するように設定する。
もう1度プログラムを見てみましょう

#include <windows.h>

int WINAPI WinMain(HINSTANCE hInstance,
			HINSTANCE hPrevInstance,
			PSTR lpCmdLine,
			int nCmdShow){

	HWND hwnd;
	WNDCLASS windowclass;		//変数を作る

	windowclass.style		= CS_HREDRAW | CS_VREDRAW;	//作りたいウインドウクラスを設定していく
	windowclass.lpfnWndProc	= DefWindowProc;
	windowclass.cbClsExtra	= 0;
	windowclass.cbWndExtra	= 0;
	windowclass.hInstance	= hInstance;
	windowclass.hIcon		= LoadIcon(NULL , IDI_APPLICATION);
	windowclass.hCursor		= LoadCursor(NULL , IDC_ARROW);
	windowclass.hbrBackground	= (HBRUSH)GetStockObject(WHITE_BRUSH);
	windowclass.lpszMenuName	= NULL;
	windowclass.lpszClassName	= TEXT("oyabunn");

	if(!RegisterClass(&windowclass))return -1;			//ウインドウズに登録

	hwnd = CreateWindow(TEXT("oyabunn") , TEXT("こんちは世界!") ,		//さっき登録したのを使う
						WS_OVERLAPPEDWINDOW |WS_VISIBLE ,
						200 , 200 , 200 , 200 , NULL , NULL ,hInstance , NULL);
	
	MessageBox(hwnd,TEXT("OK?"),TEXT("OK?"),MB_OK);

	return 0;
}

ほらっ。こんなに簡単でしょ?
構造体の他のメンバーは追々解説するとして 今日はこんなところで。

 

まとめ

WNDCLASS・・・ウインドウクラス用の構造体。

RegisterClass・・・構造体のアドレスを渡してウインドウズに新しいウインドウクラスを登録する

 

ホームへ