avlec
avlec

Reputation: 394

Win32 Inconsistent CreateWindowEx Call

I'm trying to wrap my head around the Win32 API, and when creating the window I get inconsistent results. The call to CreateWindowEx will fail and the result from GetLastError() yields the ERROR_NOT_ENOUGH_MEMORY error code. But sometimes the application successfully creates the window and runs fine. This has left me rather confused.

// 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;
}

Upvotes: 0

Views: 501

Answers (1)

Sean Bright
Sean Bright

Reputation: 120704

You're not initializing WNDCLASSEX.cbWndExtra which defines how many extra bytes of storage your window class needs.

You should add:

wcex.cbWndExtra = 0;

Before your call to RegisterClassEx. Alternatively you could start with this:

WNDCLASSEX wcex = { sizeof(wcex) };

Which will initialize the cbSize member to the size of the structure and all other members to 0 (or NULL) for you.

Upvotes: 7

Related Questions