2012-12-03 67 views
1

我想通過一些教程學習win32 API。
(雖然我做了非常小的調整來創建一個無邊框固定窗口。)

但是,我最簡單的窗口應用程序正在退出時帶有一些隨機代碼。
我不知道爲什麼它不會退出代碼'0'。

有關更多信息,請使用Visual Studio 2012 Pro。
源代碼的文件擴展名是.c,編譯器設置可能是默認的。
我創建了一個空的win32應用程序(不是控制檯)的項目。

請一定幫助,將不勝感激。
謝謝。隨機win32退出代碼

#include <Windows.h> 
#include <windowsx.h> 

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

int __stdcall WinMain(HINSTANCE hInstance, 
         HINSTANCE hPrevInstance, 
         LPSTR lpCmdLine, 
         INT nCmdShow) { 
    HWND hWnd; 
    WNDCLASSEX wcex; 
    MSG msg; 

    ZeroMemory(&wcex, sizeof(WNDCLASSEX)); 

    wcex.cbSize = sizeof(WNDCLASSEX); 
    wcex.style = CS_HREDRAW | CS_VREDRAW; 
    wcex.lpfnWndProc = 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 = L"WindowClass1"; 
    wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION); 

    if (!RegisterClassEx(&wcex)) 
    { 
     MessageBox(
      NULL, 
      L"Failed to register window!", 
      L"ERROR", 
      MB_OK | MB_ICONEXCLAMATION); 
     return EXIT_FAILURE; 
    } 

    hWnd = CreateWindowEx(
     0, 
     L"WindowClass1", 
     L"Application", 
     WS_POPUP, 
     0, 0, 
     GetSystemMetrics(SM_CXSCREEN), 
     GetSystemMetrics(SM_CYSCREEN), 
     NULL, NULL, hInstance, NULL); 


    if (hWnd == NULL) 
    { 
     MessageBox(
      NULL, 
      L"Failed to create window!", 
      L"ERROR", 
      MB_OK | MB_ICONEXCLAMATION); 
     return EXIT_FAILURE; 
    } 

    ShowWindow(hWnd, nCmdShow); 
    UpdateWindow(hWnd); 

    while (GetMessage(&msg, hWnd, 0, 0) > 0) 
    { 
     TranslateMessage(&msg); 
     DispatchMessage(&msg); 
    } 

    return msg.wParam; 
} 

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

    return 0; 
} 
+0

你能告訴你如何讀取退出代碼? –

+0

使用alt + f4關閉窗口後,Visual Studio中的輸出窗口告訴我我的應用程序終止的退出代碼。 – HTK

回答

3

在你的程序中,GetMessage其實是在迴歸-1這是一個錯誤。當GetMessage返回值< = 0時,您的消息循環終止,因此當GetMessage返回-1時,它將終止。

現在,由於最終致電GetMessage失敗並顯示錯誤,因此msg.wParam的值未明確定義。您不應該將它作爲退出代碼返回。當最終致電GetMessage返回0時,您只應返回msg.wParam作爲退出代碼。這在documentation中已清楚表明。

你可以看到這一切,如果你改變你的消息循環是這樣的:

while((bRet = GetMessage(&msg, hWnd, 0, 0)) != 0) 
{ 
    if (bRet == -1) 
    { 
     return GetLastError(); 
    } 
    else 
    { 
     TranslateMessage(&msg); 
     DispatchMessage(&msg); 
    } 
} 

return msg.wParam; 

在我的機器,該bRet == -1路由選擇和錯誤代碼是1400。這是ERROR_INVALID_WINDOW_HANDLE。我不太清楚爲什麼你的應用會以這種方式行事,但我滿足於我已經回答了你詢問關於退出代碼的問題!

+0

非常感謝! – HTK

+0

這是非常晚,但不是GetMessage假設爲 GetMessage(&msg,0,0,0)?如果我使用了HWND,我會遇到問題。 –

2

除了覆蓋整個屏幕,一個空白窗口,需要使用ALT-F4的退出你的應用程序,事情看起來不錯,除了一兩件事:

的GetMessage,儘管聲稱要返回「BOOL」實際上返回int:成功時爲正值,接收到WM_QUIT時爲0,出現錯誤時爲-1。微軟從GetMessage(以及其他函數)返回「BOOL plus lil'東西」的策略是愚蠢且危險的,因此它們應該被抨擊。

如果GetMessage返回-1,則msg的內容可能有效也可能不會有效;換句話說,wParam可以是零,也可以是potato。這可能會轉化爲您所看到的「隨機」退出代碼。

我建議是這樣的:

int nRet; 

do 
{ 
    nRet = GetMessage(&msg, hWnd, 0, 0); 

    if(nRet == -1) 
     return GetLastError(); 

    if(nRet != 0) 
    { 
     TranslateMessage(&msg); 
     DispatchMessage(&msg); 
    } 
} while(nRet != 0); 

return msg.wParam; 
+0

謝謝!但我相信大衛先回答了它。 – HTK

+1

不客氣。第一或第二無關緊要 - 重要的是你得到了你需要的答案。 –

+0

Nik是對的。你應該接受最好的答案,而不是最快的答案。在這種情況下,它們看起來非常相似! –