2014-04-26 120 views
-2

我做了這個GUI應用程序使用C++和WINAPI,只是當我完成我的教程,但永遠不會奏效無論我嘗試...WINAPI窗口不起作用。

這裏是代碼:

#include <windows.h> 

LRESULT CALLBACK WinProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam); 

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

WNDCLASS window; 
window.cbClsExtra = NULL; 
window.cbWndExtra = NULL; 
window.hbrBackground = (HBRUSH)COLOR_BACKGROUND; 
window.hCursor = LoadCursor (hInst, IDC_ARROW); 
window.hIcon = NULL; 
window.hInstance = hInst; 
window.lpfnWndProc = WinProc; 
window.lpszClassName = "WINDOW"; 
window.lpszMenuName = NULL; 
window.style = CS_HREDRAW | CS_VREDRAW; 

RegisterClass(&window); 

HWND hwnd = CreateWindow("WINDOW", "Win32 Window Application", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 50, 50, 200, 200, NULL, NULL, hInst, NULL); 

ShowWindow(hwnd, SW_SHOW); 

MSG message; 

while (GetMessage(&message, hwnd, 0, 0)){ 

TranslateMessage(&message); 
DispatchMessage(&message); 

} 

} 

LRESULT CALLBACK WinProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam){ 

switch(message){ 

case WM_DESTROY: 
{ 

PostQuitMessage(0); 
return 0; 
break; 

} 
} 

} 

我試圖改變幾乎所有到不同的值,並添加頭文件,但從來沒有工作。

+1

當你說「不工作」,你是什麼意思與?窗戶不要打開?你在某處遇到錯誤嗎?程序崩潰了嗎?請詳細說明。 –

+6

非常標準的錯誤,除了從不檢查錯誤,因此永遠無法診斷失敗。你的窗口過程**必須調用DefWindowProc()來處理它自己不處理的消息。現在WM_NCCREATE消息沒有得到處理,這是任何嘗試獲取窗口創建的結束。 –

+0

您應該做的第一件事是檢查函數的結果,確定是否通過文檔中陳述的任何錯誤發生,並獲得更多信息(如果可用),如文檔中所述。 – chris

回答

0

添加以下你的窗口過程的末尾:

return DefWindowProc(window, message, wParam, lParam);

現在你不處理,除了WM_DESTROY任何消息。也沒有從程序中返回任何東西,這意味着未定義的行爲。

+0

我在窗口過程的默認情況下添加了行,它的工作原理,但是當我點擊x按鈕時,它只隱藏但不關閉,什麼可以在這個問題? – user3407319

+0

這是因爲你的GetMessage只接受窗口消息,而WM_QUIT是一個線程消息。您還需要更改爲'GetMessage(&message,NULL,0,0)'。 IInspectable的答案也已經解釋了這一點。 – Kirinyale

4

您需要應用以下更改源代碼:

  1. 指導窗口,以更新其內容:

    ShowWindow(hwnd, SW_SHOW); 
    UpdateWindow(hwnd); 
    
  2. 初始化MSG結構,不過濾的郵件,並適當使用返回值GetMessage

    MSG message = {0}; 
    
    while (GetMessage(&message, NULL, 0, 0) > 0){ 
        TranslateMessage(&message); 
        DispatchMessage(&message); 
    
    } 
    

    使用參數hwnd過濾消息只會從該窗口的消息隊列中檢索消息。 WM_QUIT將會丟失,並且由於您沒有檢查GetMessage的返回值> 0,您的消息循環將繼續無限旋轉。

  3. 將你不處理的所有信息傳遞給DefWindowProc。不這樣做會阻止窗戶甚至起飛。正如Hans Passant在上面做出的迴應,WM_NCCREATE未處理,致使CreateWindow失敗(請檢查返回值爲NULL)。另外,不要忽略編譯器警告(如你的代碼張貼生產):

    LRESULT CALLBACK WinProc(HWND window, 
             UINT message, 
             WPARAM wParam, 
             LPARAM lParam){ 
        switch(message){ 
    
        case WM_DESTROY: 
         PostQuitMessage(0); 
         return 0; 
    
        default: 
         break; 
        } 
    
        return DefWindowProc(window, message, wParam, lParam); 
    } 
    
  4. 務必檢查錯誤。任何可能失敗的API調用(請參閱文檔)應該檢查其返回值。特別是您需要檢查RegisterClassCreateWindow的呼叫。後者就會給你線索,什麼是錯的:

    if(RegisterClass(&window) == 0) 
        return -1; 
    
    // ... 
    
    if(hwnd == NULL) 
        return -1;