• 締切済み

メッセージループ

while(true) { if(PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)) { if(msg.message==WM_QUIT) break; DispatchMessage(&msg); if(!GetMessage(&msg,NULL,0,0)) { return (int)msg.wParam; } } } else { } このソースで実行して消したら終了しませんでした。 なぜ終了できなかったのでしょうか?

  • 79562
  • お礼率68% (164/239)

みんなの回答

  • php504
  • ベストアンサー率42% (926/2160)
回答No.3

WM_DESTROYでPostQuitMessage(0);を処理しないとウィンドウだけ消えてプログラムは終了しないですがどうでしょうか。

79562
質問者

お礼

回答ありがとうございます。WM_DESTROYでPostQuitMessage(0);はちゃんと出来てます。 それとソースが違っていました。 while(true) { if(PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)) { if(msg.message==WM_QUIT) break; DispatchMessage(&msg); if(!GetMessage(&msg,NULL,0,0)) { } } } else { } です。

  • php504
  • ベストアンサー率42% (926/2160)
回答No.2

質問と補足で内容が違うようですがとりあえず質問のほうで DispatchMessage( )をGetMessage( )の後ろに移動しましょう WM_QUITのチェックも不要でしょう if(PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)) { if(!GetMessage(&msg,NULL,0,0)) { return (int)msg.wParam; } DispatchMessage(&msg);

79562
質問者

お礼

回答ありがとうございます。質問の件なのですが、なぜ if(PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)) { if(msg.message==WM_QUIT) break; DispatchMessage(&msg); if(!GetMessage(&msg,NULL,0,0)) { } } なぜウィンドウが消えたのに実行中なのかということです。説明不足ですいません。

  • asuncion
  • ベストアンサー率33% (2126/6287)
回答No.1

>このソースで せっかくそこまでソースを載せたのですから、 どうせなら全部載せた方がいいとはお思いになりませんか? 回答しようとする人のところでも同じ現象を再現できる方が、 問題解決への早道だと思いますが、いかがでしょうか? >消したら 何を消したのでしょうか?

79562
質問者

お礼

説明不足ですみません。ウィンドウを消してもという意味でした。 ソースはこれです。 int WINAPI _tWinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR lpCmdLine,int nCmdShow) { // ミューテックスオブジェクトによる多重起動の防止 HANDLE hMutex=CreateMutex(NULL,TRUE,_T(__FILE__)); if(GetLastError()==ERROR_ALREADY_EXISTS) { MessageBox(NULL,_T("既に起動しています"),_T("起動できません"),MB_OK); return 0; } HRESULT hr=InitApp(hInst); if(FAILED(hr)) { DXTRACE_ERR_MSGBOX(_T("_tWinMain InitApp"),hr); return 0; } hr=InitDXGraphics(); if(FAILED(hr)) { DXTRACE_ERR_MSGBOX(_T("_tWinMain InitDXGraphics"),hr); DestroyWindow(g_hWnd); } else { hr=InitD3DObject(); if(FAILED(hr)) { DXTRACE_ERR_MSGBOX(_T("_tWinMain InitD3DObject"),hr); DestroyWindow(g_hWnd); } } if(g_bWndMode==false) // フルスクリーンモードで起動 { g_bWndMode=true; ChangeDisplayMode(); } MSG msg; timeBeginPeriod(1); // 最小分解能を1[ms]に設定する while(true) { if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { if(msg.message==WM_QUIT) break; DispatchMessage(&msg); if(!GetMessage(&msg,NULL,0,0)) { } } else { } } timeEndPeriod(1); CloseHandle(hMutex); return (int)msg.wParam; }

関連するQ&A

  • メッセージループについて

    while(true) { if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { if(msg.message==WM_QUIT) break; DispatchMessage(&msg); if(!GetMessage(&msg,NULL,0,0)) { } } else { } これはpeekMessageがメッセージを取り出してメッセージがあったら if(msg.message==WM_QUIT) break; DispatchMessage(&msg); if(!GetMessage(&msg,NULL,0,0)) を実行して、GetMessage()で待機してもし、メッセージがWM_QUITならGetMessageにWM_QUITのメッセージを渡してメッセージが消えてPeekMessageはメッセージキューがないため、0を返し永遠にelseを繰り返すという認識でよろしいのですか? あと、while(true) { if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { if(!GetMessage(&msg,NULL,0,0)) { } if(msg.message==WM_QUIT) break; DispatchMessage(&msg); } else { } if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))がWM_QUITのメッセージで そしてメッセージが消えてGetMessageで待機状態になるということでよろしいのでしょうか?ご教授お願いします。

  • PeekMessageについて

    確認したいのですが、 MSG msg; while(TRUE) { if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { if(msg.message==WM_QUIT) { return (int) msg.wParam; } TranslateMessage(&msg); DispatchMessage(&msg); } else { } } このPeekMessageというものですがキューに溜めているということでいいのでしょうか。 後、 MSG msg; while(TRUE) { if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { if(!GetMessage(&msg,NULL,0,0)) { return (int) msg.wParam; } if(msg.message==WM_QUIT) { return (int) msg.wParam; } TranslateMessage(&msg); DispatchMessage(&msg); } else { } } の if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { if(!GetMessage(&msg,NULL,0,0)) { return (int) msg.wParam; } はキューから出してGetMessageは待機してるということでいいのでしょか? if(PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)) { if(!GetMessage(&msg,NULL,0,0)) { return (int) msg.wParam; } これはキューの中は出さないで、GetMessageでPeekMessageからのキューを出しているということでいいのでしょか?

  • 質問なのですが・・・

    while(true) { if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { if(msg.message==WM_QUIT) break; DispatchMessage(&msg); } else { if(FAILED(Render(g_pD3DDevice))) DestroyWindow(hWindow); } } でRenderが通らないのですがどうしたら通るようになるのでしょうか。

  • APIのメッセージループの流れとTranslateMessage

    while(GetMessage(&msg, NULL, 0, 0) > 0){ TranslateMessage(&msg); DispatchMessage(&msg); } もしも「a」が押されたときは、 GetMessageで受け取って TranslateMessageでWM_CHARに変換され DispatchMessageでWM_CHARとしてのメッセージが送られる という流れになるはずです。 けど、実際には一度プロシージャにWM_KEYDOWNが送られます。 TranslateMessageが先にメッセージを変換してるので、WM_KEYDOWNが送られることはありえないと思うのですが、なぜでしょうか。 何か重大な思い違いをしているのでしょうか・・?

  • ウィンドウ内でマウスが乗ると更新が止まります・・

    ウィンドウプロシージャ周りを触っているのですが、  ・ウィンドウにマウスが乗っていつつ、マウスが動いている時  ・キーボードーを押した瞬間 にメインループに処理が回らず 全体の処理が止まってしまいます。 上の問題を解決するには、どうすれば良いでしょうか? ※以下コード ---------------------------------------------- while(TRUE) { if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if(msg.message == WM_QUIT) { break; } else { TranslateMessage(&msg); DispatchMessage(&msg); } } else { // 処理メッセージが無いとき WINDOWPLACEMENT wndpl; GetWindowPlacement(hWnd, &wndpl); if((wndpl.showCmd != SW_HIDE) && (wndpl.showCmd != SW_MINIMIZE) && (wndpl.showCmd != SW_SHOWMINIMIZED) && (wndpl.showCmd != SW_SHOWMINNOACTIVE)) { ... ゲームのような、常時更新が必要なループ処理 ... } } Sleep(1); // 最小化等でフリーズしないため } ---------------------------------------------- //以下メッセージ処理側の一部 case WM_KEYDOWN: if (wParam == VK_ESCAPE) { PostQuitMessage(0); } break; case WM_MOUSEMOVE: return DefWindowProc(hWnd, msg, wParam, lParam); default: return DefWindowProc(hWnd, msg, wParam, lParam); ---------------------------------------------- また、ゲームなどのリアルタイム更新に向いた ウィンドウプロシージャの作り方などの説明サイト等ご存知でしたら そちらも教えて頂けると幸いです。

  • メッセージループについて

    確認したいのですが、AとBのプロセスがあるとしたら、 AとB while(GetMessage(&msg,NULL,0,0,PM_REMODE)) { TranslateMessage(&msg); DispatchMessage(&msg); } でAを実行中のときはBのプロセスはGetMessageによって処理を行わず待機、Bに移った場合、AはGetMessageによって待機というのでいいのでしょうか?

  • Sleep(1)が1msでもどってこない。

    Sleep(1)が1msでもどってこない。 ゲームのループ処理を作っていまして、 空いている時間をシステムに返すためにSleep(1)を呼んで いるのですが、 while( msg.message != WM_QUIT ) { if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } else { //ゲーム的な処理 //時間があまればSleep() } } といった定番なことをしているのですが、 30FPSで固定されません。 調べてみるとSleep(1)が2msくらいして戻ってきています。 なにかよいアイディアを持っている方がいらっしゃいましたら教えてください。 よろしくお願いします。

  • LinuxでDoEvents()同等機能

    Linux初心者です。 2.6-18-at9 Debianで及ばずながらマルチスレッドのプログラムを書いています。 VBにはOSにコントロールを戻すDoEventsという機能があります。 Windows/VC++ではこれと同等機能の関数を使っています: DWORD DoEvents(VOID) { MSG msg; while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ){ if ( msg.message == WM_QUIT ){ return( msg.message ); } TranslateMessage( &msg ); DispatchMessage( &msg ); } return( 0 ); } どなたかの示唆によるもので内容はよく理解していませんが、Windows下ではこれで長年つかえてきました。 Linux-gccで同等の関数は定義できるのでしょうか?。

  • ウィンドウハンドルがメッセージ処理ループの後おかしくなる(?)

    下のコードをコンパイルしても、 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; }

  • C++ GUIのメッセージループ。

    初心者です。 よろしくお願いします。 とても重く時間の掛かる処理を色んなサイトを参考にスレッドにしてみたんですけど、書き方が悪いのか、再描写がワンテンポ遅れたり、アプリケーションを複数起動したりするとフリーズしてしまったりします。 原因はメッセージループにあるような気がしてるんですが、この書き方はおかしいですか?? どのサイトから引用したのかわからなくなってしまいました。 気付いたことなどあったら何でもいいので教えて貰えたら嬉しいです!よろしくお願いします!! thread01に重い処理が書かれてます。 int thread_call() {   unsigned int dwThreadId[1];   HANDLE hThread[0] = (HANDLE)_beginthreadex(     NULL,     0,     ( unsigned int (__stdcall*)(void*) )thread01,     NULL,     0,     &dwThreadId[0] );   MSG msg;   DWORD dwRet = WAIT_TIMEOUT;   while ( 1 ) {     dwRet = ::MsgWaitForMultipleObjects( sL, hThread, FALSE, INFINITE, QS_ALLEVENTS );     if ( dwRet == WAIT_OBJECT_0 + sL ) {       if ( ::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) {         ::TranslateMessage( &msg );         ::DispatchMessage( &msg );       }     } else if ( dwRet >= WAIT_OBJECT_0 && dwRet < WAIT_OBJECT_0 + sL )       break;   }   CloseHandle( hThread[0] );   hThread[0] = NULL; }

専門家に質問してみよう