2017-04-24 71 views
0

我試圖圍繞Win32 API進行打包,創建窗口時出現不一致的結果。對CreateWindowEx的調用將失敗,GetLastError()的結果產生ERROR_NOT_ENOUGH_MEMORY錯誤代碼。但有時應用程序成功創建窗口並運行良好。這讓我頗爲困惑。Win32不一致的CreateWindowEx調用

// Standard Includes 
#include <windows.h> 
#include <iostream> 

#ifndef UNICODE 
    #define UNICODE 
#endif 
#ifndef _UNICODE 
    #define _UNICODE 
#endif 

#define UNUSED_PARAM(x) (void)(x) 

const char szWindowClass[] = "Program"; 
const char szTitle[] = "Program Desc"; 
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); 

int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
        LPSTR lpCmdLine, int nCmdShow) { 

    UNUSED_PARAM(hPrevInstance); 
    UNUSED_PARAM(lpCmdLine); 

    WNDCLASSEX wcex; 
    HWND hWnd; 

    wcex.cbSize =   sizeof(WNDCLASSEX); 
    wcex.style =   CS_HREDRAW | CS_VREDRAW; 
    wcex.lpfnWndProc =  WndProc; 
    wcex.cbClsExtra =  0; 
    wcex.hInstance =  hInstance; 
    wcex.hIcon =   LoadIcon(hInstance, IDI_APPLICATION); 
    wcex.hCursor =   LoadCursor(NULL, IDC_ARROW); 
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); 
    wcex.lpszMenuName =  NULL; 
    wcex.lpszClassName = szWindowClass; 
    wcex.hIconSm =   LoadIcon(wcex.hInstance, IDI_APPLICATION); 

    if(!RegisterClassEx(&wcex)) { 
     MessageBox(NULL, "Call to RegisterClassEx failed!", szWindowClass, MB_ICONEXCLAMATION | MB_OK); 
     return 1; 
    } 

    hWnd = CreateWindowEx(WS_EX_CLIENTEDGE,    // dwExStyle 
          szWindowClass,    // lpClassName 
          szTitle,      // lpWindowName 
          WS_OVERLAPPEDWINDOW,   // dwStyle 
          CW_USEDEFAULT, CW_USEDEFAULT, // x, y 
          240, 120,      // width, height 
          NULL, NULL,     // hWndParent, hMenu 
          hInstance, NULL);    // hInstance, lpParam 
    std::cout << GetLastError(); 
    if(hWnd == NULL) { 
     MessageBox(NULL, "Call to CreateWindow failed!", szWindowClass, MB_ICONEXCLAMATION | MB_OK); 
     return 1; 
    } 

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

    // Main message loop 
    MSG msg; 
    while (GetMessage(&msg, NULL, 0, 0)) { 
     TranslateMessage(&msg); 
     DispatchMessage(&msg); 
    } 

    return (int) msg.wParam; 
} 

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

回答

7

你沒有初始化WNDCLASSEX.cbWndExtra定義如何存儲的許多額外字節的窗口類的需求。

您應該添加:

wcex.cbWndExtra = 0; 

您的來電RegisterClassEx之前。另外,您可以用此啓動:

WNDCLASSEX wcex = { sizeof(wcex) }; 

這將在cbSize成員初始化爲結構的大小和所有其他成員爲0(或NULL)爲您服務。

+0

工作,只是我在閱讀時錯過的東西。謝謝! –

+1

甚至更​​好的IMO:'WNDCLASSEX wcex = {sizeof(wcex)};'它會初始化'cbSize'成員到struct的大小並且零初始化其餘成員。 – zett42

+0

@ zett42,同意。更新。 –

相關問題