【问题标题】:Win32 Inconsistent CreateWindowEx CallWin32 不一致的 CreateWindowEx 调用
【发布时间】:2017-04-24 21:10:03
【问题描述】:

我正试图围绕 Win32 API 进行思考,但在创建窗口时我得到了不一致的结果。对 CreateWindowEx 的调用将失败,来自GetLastError() 的结果会产生ERROR_NOT_ENOUGH_MEMORY 错误代码。但有时应用程序会成功创建窗口并运行良好。这让我很困惑。

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

【问题讨论】:

    标签: c++ windows winapi


    【解决方案1】:

    您没有初始化 WNDCLASSEX.cbWndExtra,它定义了您的窗口类需要多少额外的存储字节。

    你应该添加:

    wcex.cbWndExtra = 0;
    

    在您致电RegisterClassEx 之前。或者你可以从这个开始:

    WNDCLASSEX wcex = { sizeof(wcex) };
    

    这会将 cbSize 成员初始化为结构的大小,并将所有其他成员初始化为 0(或 NULL)。

    【讨论】:

    • 更好的 IMO:WNDCLASSEX wcex = { sizeof(wcex) }; 会将 cbSize 成员初始化为结构的大小并将剩余成员初始化为零。
    • @zett42,同意。已更新。
    猜你喜欢
    • 1970-01-01
    • 2011-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多