首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Win32 API CreateWindow 失敗返回 NULL 但 GetLastError 為 0 的真兇:DefWindowProc 參數順序顛倒

     編輯:程式設計疑難解答

現象

Win32 程式註冊窗口類成功,`CreateWindow` 返回 `NULL`,`GetLastError()` 返回 `0` (ERROR_SUCCESS),無法定位錯誤。

代碼定位

窗口過程函數 `WndProc` 末尾:


// 錯誤代碼
return DefWindowProc(hWnd, message, lParam, wParam); // 參數順序錯誤!

根本原因

  • `DefWindowProc` 簽名:`LRESULT DefWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)`。
  • 代碼將 `wParam` 和 `lParam` 顛倒傳遞,導致默認消息處理邏輯錯亂(如 `WM_CREATE` 返回值錯誤),間接導致窗口創建失敗。
  • 系統未設置錯誤碼,因為 `CreateWindow` 內部調用失敗非因資源不足等可報錯原因,而是窗口過程邏輯錯誤導致創建流程中斷。

修正代碼


// 正確順序
return DefWindowProc(hWnd, message, wParam, lParam);

調試建議

  1. 窗口過程**必須**正確轉發未處理消息給 `DefWindowProc`,參數順序、類型不可出錯。
  2. `WM_CREATE` 處理中若返回 `-1` 會導致創建失敗,檢查是否有非預期返回值。
  3. 使用 `GetLastError` 輔助調試時,應在 **緊跟** 失敗的 API 調用後立即調用,中間不可插入其他 API(可能重置錯誤碼)。
  4. 啟用「調試版用戶模式」或使用 `SetLastError(0)` 前置清零再調用 API 驗證。

完整最小化正確框架


LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    switch (msg) {
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        case WM_PAINT: {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            TextOut(hdc, 10, 10, L"Hello", 5);
            EndPaint(hWnd, &ps);
            return 0;
        }
    }
    return DefWindowProc(hWnd, msg, wParam, lParam); // 參數順序正確
}

總結

Win32 窗口創建失敗且 `GetLastError=0` 多為窗口過程邏輯錯誤(參數顛倒、返回值錯誤、未處理關鍵消息),而非系統資源問題。優先檢查 `WndProc` 中 `DefWindowProc` 調用正確性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved