2012-03-05 19 views
4

私はWin32 APIの初心者ですが、私は中間的にC++を経験しています。学習目的のために、私は参考文献、チュートリアル、および例に基づいて非常に単純なWin32アプリケーションを作成しました。メインウィンドウが閉じられた後、Win32アプリケーションがバックグラウンドで実行されないようにするにはどうすればよいですか?

メインウィンドウを閉じた後も、そのプロセスはバックグラウンドで実行されるという問題があります。どうすればこれを防ぐことができますか?私のWndProc関数では、私はDestroyWindowでWM_DESTROYのケースを持っていますが、それはトリックをやっているようではありません。コードは次のとおりです。

#include <cstdio> 
#include <cstdlib> 

#ifdef UNICODE 
#include <tchar.h> 
#endif 

#include <Windows.h> 

HINSTANCE hinst; 
HWND hwnd; 

LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); 

#ifdef UNICODE 
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) 
#else 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) 
#endif 
{ 
    MSG msg; 
    WNDCLASSEX mainclass; 
    BOOL bRet; 
    UNREFERENCED_PARAMETER(lpCmdLine); 

    mainclass.cbSize =   sizeof(WNDCLASSEX); 
    mainclass.style =   CS_VREDRAW | CS_HREDRAW; 
    mainclass.lpfnWndProc =  (WNDPROC) WndProc; 
    mainclass.cbClsExtra =  NULL; 
    mainclass.cbWndExtra =  NULL; 
    mainclass.hInstance =  hInstance; 
    mainclass.hIcon =   NULL; 
    mainclass.hCursor =   LoadCursor(NULL, IDC_ARROW); 
    mainclass.hbrBackground = (HBRUSH) COLOR_WINDOW; 
    mainclass.lpszMenuName = NULL; 
    mainclass.lpszClassName = TEXT("MainWindowClass"); 
    mainclass.hIconSm =   NULL; 

    if (!RegisterClassEx(&mainclass)) 
     return FALSE; 

    hinst = hInstance; 

    hwnd = CreateWindowEx(
     WS_EX_WINDOWEDGE, 
     TEXT("MainWindowClass"), 
     TEXT("Test Window"), 
     WS_CAPTION | WS_VISIBLE | WS_SIZEBOX | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, 
     CW_USEDEFAULT, 
     CW_USEDEFAULT, 
     CW_USEDEFAULT, 
     CW_USEDEFAULT, 
     NULL, 
     NULL, 
     hinst, 
     NULL); 

    ShowWindow(hwnd, nCmdShow); 
    UpdateWindow(hwnd); 

    while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0) 
    { 
     if (bRet != -1) 
     { 
      TranslateMessage(&msg); 
      DispatchMessage(&msg); 
     } 
    } 
    return (int) msg.wParam; 
} 

LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
{ 
    PAINTSTRUCT ps; 
    switch(uMsg) 
    { 
    case WM_DESTROY: 
     DestroyWindow(hwnd); 
     break; 
    case WM_PAINT: 
     BeginPaint(hwnd, &ps); 
     EndPaint(hwnd, &ps); 
     break; 
    default: 
     return DefWindowProc(hwnd, uMsg, wParam, lParam); 
    } 
    return 0; 
} 
+1

デバッガを使用して手助けをすることができます。メインウィンドウを閉じてプログラムが実行されているときは、実行を一時停止し、呼び出しスタックを調べて、プログラムがまだビジー状態であることを確認します。これは、あなたのプログラムが実行を止めるためにあなたが期待していることについての手がかりを与えることができます。たとえば、プログラムでメッセージループが実行されていることが判明した場合は、ループの終了条件が満たされるように調整できます。 –

+0

[Raymond ChenのC++スクラッチプログラム](http://blogs.msdn.com/b/oldnewthing/archive/2005/04/22/410773.aspx)のリファレンス/チュートリアル/例がここにあります。そしてここに[C scratchプログラムへのリンク](http://blogs.msdn.com/b/oldnewthing/archive/2003/07/23/54576.aspx)もあります。 –

答えて

9

DestroyWindow()に電話をかけないでください。メッセージはあなたのウィンドウが既に破壊されていることを伝えています。アプリケーションを終了するにはPostQuitMessage(0)に電話してください。

+1

実際には、 'DestroyWindow(hwnd)'を起動するには 'WM_CLOSE'が必要です。しかしそれはデフォルトかもしれません。 –

+0

ああ、ありがとう!私はWM_DESTROYメッセージの使用を誤解しました。 PostQuitMessage(0)はそれを修正しました。 – Archimaredes

+0

@BenVoigtデフォルトのようです。明らかな自動DestroyWindowのためにそのケースを追加する必要はありませんでした。 – Archimaredes

2

あなたのWndProcにWM_CLOSEのケースを追加し、PostQuitMessageを呼び出します。

LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
{ 
    case WM_CLOSE: 
    PostQuitMessage(0); 
    break; 
    // other cases 
} 

ユーザーが閉じるボタン(またはsysメニューから)をクリックすると、WindowsはWM_CLOSEメッセージを送信します。これにより、メインのWindowsメッセージハンドラが終了します。これにより、アプリケーションが適切に終了することが保証されます。

関連する問題