なぜかWM_CREATEが届かない・・・ – プログラミング – Home

なぜかWM_CREATEが届かない・・...
 
通知
すべてクリア

[解決済] なぜかWM_CREATEが届かない・・・


ねこまんじゅう
 ねこまんじゅう
(@ねこまんじゅう)
ゲスト
結合: 19年前
投稿: 10
Topic starter  

WinXP VisualStudio 2005 Win32

はじめて質問させて頂きます。
初心者ですが、よろしくお願いいたします。

1.
下のスケルトンプログラムにて、プロシージャ内でcase WM_CREATEがあります。
私はWM_CREATEは「ウインドウが作成されたときに送られてくる」と思っています。
下記のプログラムを実行すればウインドウが表示されますが、
case WM_CREATE: の中にMessageBox(NULL,OK, タイトル, MB_OK); というように
書いても、メッセージボックスが表示されません。
これはつまり、WM_CREATEが送られてきていないということですよね。
なぜ送られてこないのか、わかりません・・・。

2.
そもそも、ウインドウとダイアログの違いがよくわかりません。
このスケルトンプログラムは、ダイアログを表示していますが、
ウインドウが表示されたときに送られてくるWM_CREATEを使用しているのが、謎です。
ダイアログを表示しているわけだから、WM_INITDIALOGを使用するはずだと思い、
WM_CREATEをWM_INITDIALOGに書き換えると、コンパイルは通りますが、実行すると強制終
了します。

よろしくお願いいたします・・・・

#include windows.h
#include resource.h

HWND hDlgWnd;
static TCHAR szAppName[] = TEXT (Dialog1) ;

LRESULT CALLBACK MainDlgProc(HWND, UINT, WPARAM, LPARAM);

int APIENTRY WinMain (HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PSTR szCmdLine,
int nCmdShow)
{

MSG msg ;

WNDCLASS wndclass ;

wndclass.style = 0;
wndclass.lpfnWndProc = MainDlgProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = DLGWINDOWEXTRA;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon (hInstance, szAppName);
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;

if (!RegisterClass (&wndclass))
{
MessageBox (NULL,
TEXT (ウインドウクラスを登録できませんでした。),
szAppName,
MB_ICONERROR);
return 0;
}

//メインウインドウの生成
if((hDlgWnd=CreateDialog(hInstance,
MAKEINTRESOURCE(IDD_DIALOG1),
0,
(DLGPROC)MainDlgProc)) == NULL) {
MessageBox(NULL,
メインウインドウを作成できませんでした。,
szAppName,
MB_APPLMODAL | MB_ICONSTOP);
return FALSE;
}

ShowWindow (hDlgWnd, nCmdShow);
UpdateWindow (hDlgWnd);

while (GetMessage (&msg, NULL, 0, 0)) {
if(IsDialogMessage(hDlgWnd,&msg) == FALSE) {
TranslateMessage (&msg);
DispatchMessage (&msg);
}
}

return (int)msg.wParam;
}

LRESULT CALLBACK MainDlgProc (HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
static HINSTANCE hInstance;

switch (message) {
case WM_CREATE :
hInstance = ((LPCREATESTRUCT) lParam)->hInstance;
return TRUE;

case WM_COMMAND :
switch (LOWORD (wParam)) {
case IDOK :
MessageBox(NULL,OK, 実行, MB_OK);
break;
case IDCANCEL :
DestroyWindow(hWnd);
break;
}
return TRUE;

//[X]ボタン
case WM_CLOSE:
PostMessage(hWnd,WM_COMMAND,IDCANCEL,0);
return TRUE;

case WM_DESTROY :
PostQuitMessage (0);
return TRUE;
}
return FALSE;
}


引用未解決
トピックタグ
Kerry
 Kerry
(@Kerry)
ゲスト
結合: 20年前
投稿: 192
 

1.
ダイアログボックスの場合、メッセージはWindows内部のプロシージャで
処理されてから、ダイアログプロシージャに渡されます。
WM_CREATEメッセージは内部のプロシージャで処理されてしまって、
ダイアログプロシージャには渡されないようになっています。
そのため、ダイアログには初期化のためのWM_INITDIALOGメッセージが用意
されています。

それから、ダイアログプロシージャの戻り値がLRESULT型になっていますが、
正しくはBOOL型です。

また、このコードではウィンドウクラスを登録していますが、ダイアログ
ボックスの場合は通常定義済みのダイアログボックスクラスを使用するので
不要です。(カスタムダイアログクラスを作成するのであれば別ですが)

2.
WM_CREATEメッセージとWM_INITDIALOGメッセージでは、WPARAM・LPARAM
パラメータの解釈が異なります。
WM_INITDIALOGメッセージに対して、LPARAMをLPCREATESTRUCT型にキャスト
して使っているのでおかしくなります。
詳細はヘルプを参照してください。

インスタンスハンドルが必要ならば、グローバル変数で保持するか、
以下のようにして取得してください。

hInstance = (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE);


返信引用
Ban
 Ban
(@ban)
Prominent Member
結合: 5年前
投稿: 776
 

ちなみに、CreateDialog で作成するのは「モードレスダイアログ」です。
一般的な、いわゆるダイアログは「モーダルダイアログ」ですので、
区別して考えると分かりやすいかと思います。


返信引用
PATIO
(@patio)
Famed Member
結合: 3年前
投稿: 2660
 

蛇足ですが、

各メッセージに関してはMSDNできちんと調べてから使用する様にした方がいいです。
メッセージによって各パラメータの解釈は違ってくるのでうろ覚えで使わずに
確認する習慣をつけたほうがいいです。


返信引用
ねこまんじゅう
 ねこまんじゅう
(@ねこまんじゅう)
ゲスト
結合: 19年前
投稿: 10
Topic starter  

Kerryさま Banさま PATIOさま
とても丁寧なご説明、アドバイス、どうもありがとうございました。
なるほど・・・ という感じです。
これからもっと勉強したいと思います。

ここはやさしい方が多くて、いいところですね。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました