プロが教える店舗&オフィスのセキュリティ対策術

下のコードをコンパイルしても、
WinMain KillTimer hr=ERROR_INVALID_WINDOW_HANDLE (0x00000578)
というエラーメッセージが出てうまく通りません。
エラーを無視する意味でKillTimerをせずにやってしまえば、特に問題ないのですが、後々問題が出てきても怖いので、直したいです。
メッセージ処理ループの手前でKillTimerを行うと、エラーは出ませんし、
メッセージ処理ループのすぐ後でSetTimerを行うと、SetTimerでエラーが出るので、
ループでおかしくなるのかな、と思いました。
プログラムをシェイプアップしてもエラーがとれませんし、
もしかして根本的な間違いがあるのでしょうか・・・?

#include <windows.h>
#include <dxerr9.h>

#define kWCLASS_NAME "WndClass" // ウィンドウクラス名
#define kWINDOW_NAME "Wnd" // ウィンドウ名

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}

int WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow )
{

WNDCLASSEX wcex;

wcex.cbSize = sizeof(WNDCLASSEX);

wcex.style= CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc= WndProc;
wcex.cbClsExtra= 0;
wcex.cbWndExtra= 0;
wcex.hInstance= hInst;
wcex.hIcon= NULL;
wcex.hCursor= LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground= (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName=NULL;
wcex.lpszClassName= kWCLASS_NAME;
wcex.hIconSm= NULL;

RegisterClassEx(&wcex);

/* --- メイン・ウィンドウの作成 --- */
HWND hWnd;
hWnd = CreateWindow(kWCLASS_NAME, kWINDOW_NAME, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInst, NULL);

/* --- ウィンドウの表示 --- */
ShowWindow( hWnd, SW_SHOWDEFAULT );
UpdateWindow( hWnd );

/* --- タイマのセット --- */
if ( SetTimer( hWnd, 1, 1000, NULL ) == 0 ) // WM_TIMERはWndProcで処理
{ DXTRACE_ERR( "WinMain SetTimer", GetLastError() ); return -1; }

/* --- メッセージ処理ループ --- */
MSG msg;
ZeroMemory( &msg, sizeof( msg ) );

while ( msg.message != WM_QUIT ) // PostQuitMessage()が呼ばれたら終了
{
if ( !GetMessage( &msg, NULL, 0, 0 ) )
{ msg.message = WM_QUIT; }
else
{ TranslateMessage( &msg ); DispatchMessage( &msg ); }
}

/* --- タイマの破棄 --- */
if ( KillTimer( hWnd, 1 ) == 0 )
{ DXTRACE_ERR( "WinMain KillTimer", GetLastError() ); return -1; }

/* --- 終了処理 --- */
// ウィンドウクラスの登録解除
if ( UnregisterClass( kWCLASS_NAME, hInst ) == 0 )
{ DXTRACE_ERR( "WinMain UnregisterClass", GetLastError() ); return -1; }

return 0;
}

A 回答 (1件)

メッセージループ抜けた後では、ウィンドウは破棄済みなのでは?


となると、そのウィンドウハンドルは無効なのでエラーになるものと思われます。

WM_CREATEでSetTimerして、WM_DESTROYでKillTimerすればよろしいのでは?

この回答への補足

めちゃ早い回答ありがとうございますw
確かにWM_CREATEでSetTimerやってるコードをよく見かけますが、そういう意味があったんですかね?
納得なので今すぐやってみようと思うのですが、
違うプログラムでメッセージループの後にKillTimerを実行してもエラーにならなかったので、
それについてはどうなのかな、とか思ったりします。

補足日時:2007/11/25 14:18
    • good
    • 0
この回答へのお礼

有難う御座いました。うまくできました。
正直1日費やしてわからなかったです・・・
言い訳としては、書籍についていたコードがその通りに間違ってて、
他にも自分と同じように勘違いする人がいないか多少心配です。
(DirectXの最近出た本です、心当たりのある人は間違えないで!!)
はたまた、こんな誤りに気づかない人はDirectXに手を出していないという話でしょうか。汗

あと、補足に書いた話ですが、今自分で試すとエラーとして出たので、
聞かなかったことにして下さい。汗汗

有難う御座いました。

お礼日時:2007/11/25 14:57

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!