ウィンドウ生成拒否
キューを使わないメッセージ
メッセージは、全てがメッセージキューにポストされるわけではありません
キューに入るメッセージのほとんどは、ユーザーからの入力によるメッセージです
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 メッセージは
ウィンドウ生成時の初期化処理などにも用いることができます