このたびもよろしくお願いいたします。
とある本を参考にVC++プログラミングを勉強していますが、
いくつか目の例題をやってみたとき、ウインドウが表示されない事態になりました。
ウインドウクラスの設定、登録、ウインドウハンドルの設定、ShowWindow()、
UpdateWindow()すべてWinMain()で行い、WndProc()のプロトタイプも併せて別ファイル
に保存して、例題では逐次ワークスペースに追加する方法でやっていますが、ほかの例
題ではウインドウが表示されています。
デバッガでWM_CREATEメッセージがswitch~case文で参照されているか見たところ、素通
りしていました。
なにぶん初心者なもので、事態がよく飲み込めていないところが多々あると思います
が、解決のご助力をお願いします。
環境:
WindowsXP SP1
VC++6.0
MFCを使用しないでプログラムしています。
> デバッガでWM_CREATEメッセージがswitch~case文で参照されているか見たところ、
> 素通りしていました。
これを信じる限り、Createされてないんでしょう。
> なにぶん初心者なもので、事態がよく飲み込めていないところが多々あると
> 思いますが、解決のご助力をお願いします。
これ以上の情報がないなら、コメントできるのもこれだけ。
episteme様ご返答ありがとうございます。
例題の内容なのですが、主にマウスからのメッセージに関するもので
1.ウインドウ内に文字列を表示
2.文字列をクリックすると反転表示
3.ドラッグすると文字列を移動
4.ダブルクリックするとメッセージボックスに文字列を表示
というテストです。
長くなって申し訳ないのですが、WinMain載せてみます。
#include windows.h
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd )
{
WNDCLASSEX wcex;
HWND hWnd;
MSG msg;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = Skelton;
wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wcex)){
return FALSE;
}
hWnd = CreateWindow(wcex.lpszClassName,
hoge, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL,
hInstance,
NULL );
ShowWindow(hWnd, nShowCmd);
UpdateWindow(hWnd);
while( GetMessage(&msg, NULL, 0, 0) ){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
> 例題の内容なのですが、主にマウスからのメッセージに関するもので
> 1.ウインドウ内に文字列を表示
> 2.文字列をクリックすると反転表示
> 3.ドラッグすると文字列を移動
> 4.ダブルクリックするとメッセージボックスに文字列を表示
> というテストです。
いや、それ以前の問題なんでしょ? ウィンドウが現れんのでしょ?
上記の機能を一切取っ払って'真っ白なウィンドウを表示する'ことすらできないのですか?
以前のサンプルではちゃんと表示されており、そのときのWinMainがこれと同じなら、
WinMainを提示しても意味ねぇです。
episteme様ありがとうございます。
ご指摘の通り、まっさらなウインドウすら表示されない状態です…というより、でし
た。
ワークスペースとかそのあたりの問題なのかと思い、WinMainまるごとコピーして新しい
ワークスペース作成してそこにペーストしてビルドしたら表示されました。
ワークスペースとか外部依存とかの問題であれば、まだまだ浅学で全然わからないのが
現状です。
もしそうだとすれば、「出直してきます」…。
結果オーライみたいになってるようですが・・・。
こういうケースの場合、まずCreateWindowが正常に終わっているのか、
戻り値をチェックすべきだと思います。
正常終了していない場合、GetLastErrorがエラーの原因を教えてくれると、
MSDNに書いてありますよ。
sugar様ありがとうございます。
GetLastError()の戻り値ですが、CreateWindow()直後は0でした。
SetLastErrorで0かNULLか-1を設定している場合は関数が失敗しているようですね。
CreateWindow()が失敗するというケースはどういったものが考えられるのでしょうか?
自レスです。
>SetLastErrorで0かNULLか-1を設定している場合は関数が失敗しているようですね。
すみません読み違いでした。そんなことどこにも書いてなかったです…。
関数が失敗したときは0か-1かNULLが返されるということで、
if(hWnd) exit(1);
を追加してみたところ、exitで終了していました。
やっぱりCreateWindow()が失敗しているようです。
何度もすみません。
if(!hWnd) exit(1);
の誤りです。
episteme様、sugar様ありがとうございました。
無事解決いたしました。
で、何が原因だったのよ?
最悪な終わり方ですね。
騒ぐだけ騒いで、自分だけ納得して帰って行くなんて。
これは失礼いたしました…。
CreateWindow()がWM_CREATEをウインドウプロシージャに送ったあと、
WM_GETMINMAXINFO、WM_NCCREATEをDefWindowProc()で処理してreturnするつもりが、
switch(msg){
・
・
・
default:
DefWindowProc(...);
break;
}
return 0;
と記述してしまっていたため、この二つのメッセージに対して0が返されCreateWindow()
が結果的に失敗したためでした。
こんなミスで引っ張ってすみません…。
訂正です。
WM_GETMINMAXINFO = 36
WM_NCCREATE = 129
WM_NCCALCSIZE = 131
はWM_CREATEが送られるの前でした。