ウィンドウ生成拒否


キューを使わないメッセージ

メッセージは、全てがメッセージキューにポストされるわけではありません
キューに入るメッセージのほとんどは、ユーザーからの入力によるメッセージです
WM_RBUTTONDOWN などのメッセージがそうです

しかし、それ以外に関数などからダイレクトに送られるメッセージもあります
メッセージは、メッセージキューに入ることなくウィンドウプロシージャに送られます
例えば、CreateWindow() 関数はウィンドウを生成する前に WM_CREATEを送ります
//もちろん、CreateWindowEx() 関数もこれと同じである
これは、メッセージキューではなく適切なウィンドウプロシージャに直接送られます

このメッセージは、パラメータ lParam にCREATESTRUCT構造体へのポインタを含みます
この構造体は次のように定義されています
typedef struct tagCREATESTRUCT {
   LPVOID    lpCreateParams;
   HANDLE    hInstance;
   HMENU     hMenu;
   HWND      hwndParent;
   int       cy;
   int       cx;
   int       y;
   int       x;
   LONG      style;
   LPCSTR    lpszName;
   LPCSTR    lpszClass;
   DWORD     dwExStyle;
} CREATESTRUCT;
dwExStyle から、上に向かって CreateWindowEx() 関数の引数と同じです
この構造体のポインタ型ですから、頭に LP プレフィックスを付加した
LPCREATESTRUCT 型をプロシージャで受け取ることができます

さらに、WM_CREATE メッセージは戻り値でウィンドウの生成を制御できます
このメッセージを処理した時に 0 を返すとウィンドウを生成します
ウィンドウを生成しない場合は -1 を返します
-1 を返した場合、ウィンドウは生成されないので CreateWindow() は NULL を返します
#include<windows.h>

LRESULT CALLBACK WndProc(HWND hwnd , UINT msg , WPARAM wp , LPARAM lp) {
	int nYesNo;
	LPCREATESTRUCT lpcsWnd;

	switch(msg) {
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	case WM_CREATE:
		lpcsWnd = (LPCREATESTRUCT)lp;
		nYesNo = MessageBox(hwnd , TEXT("ウィンドウを生成しますか?") ,
				TEXT(lpcsWnd->lpszName) , MB_YESNO | MB_ICONQUESTION);
		if (nYesNo == IDYES) return 0;
		else return -1;
	}
	return DefWindowProc(hwnd , msg , wp , lp);
}

int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance ,
		 PSTR lpCmdLine , int nCmdShow ) {
	HWND hwnd;
	WNDCLASS winc;
	MSG msg;

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

	if (!RegisterClass(&winc)) return 0;

	hwnd = CreateWindow(
			TEXT("KITTY") , TEXT("Kitty on your lap") ,
			WS_OVERLAPPEDWINDOW  | WS_VISIBLE ,
			100 , 100 , 200 , 200 , NULL , NULL ,
			hInstance , NULL
	);

	if (hwnd == NULL) return 0;

	while (GetMessage(&msg , NULL , 0 , 0)) DispatchMessage(&msg);
	return msg.wParam;
}
このプログラムでは、ウィンドウの生成時にメッセージボックスを出現させ
ユーザーにウィンドウを生成するかどうかを尋ねています
ウィンドウを生成しない場合は、-1を返します
CreateWindow() 関数は NULL を返すので、何もしないままプログラムは終了します

メッセージボックスのタイトルバーには、生成するウィンドウの名前が入ります
これは、LPCREATESTRUCT型変数から生成するウィンドウの名前を参照しています

CreateWindow() 関数の最後の引数で WM_CREATE メッセージの lParam に渡す
CREATESTRUCT 構造体へのポインタを指定することもできます

このプログラムを見てもわかるように WM_CREATE メッセージは
ウィンドウ生成時の初期化処理などにも用いることができます



前のページへ戻る次のページへ