Почему CreateWindowEx возвращает NULL при использовании WNDCLASSEX и RegisterClassEx? - PullRequest
0 голосов
/ 24 апреля 2020

Так что это похоже на код из docs.microsoft, но я решил вместо этого использовать WNDCLASSEX и RegisterClassEx. При запуске приложение сразу закрывается и окно не отображается. При отладке я обнаружил, что функция CreateWindowEx возвращает значение NULL. Обратите внимание, что если я использую WNDCLASS и RegisterClass, CreateWindowEx возвращает нормальное значение и отображает окно, как задумано.

Что делают WNDCLASSEX и RegisterClassEx по сравнению с WNDCLASS и RegisterClass и как это влияет на CreateWindowEx? Я хотел бы понять причину такого поведения.

Это код. Большое спасибо в продвинутом!

#ifndef UNICODE
#define UNICODE
#endif

#include <Windows.h>

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int WINAPI wWinMain(
    HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    PWSTR pCmdLine,
    int nCmdShow)
{
    // Register the windows class.
    const wchar_t CLASS_NAME[] = L"Sample Window Class";

    WNDCLASSEX wc = {};

    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hInstance;
    wc.lpszClassName = CLASS_NAME;

    RegisterClassEx(&wc);

    // Create the window.

    HWND hwnd = CreateWindowEx(
        0,                                                  // Optional window styles.                  
        CLASS_NAME,                                         // Window class
        L"Sorting Algorithm Simulator",                     // Window name
        WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU,           // Window style

        // position and size
        400, 200, 640, 480,

        NULL,       // Parent window                
        NULL,       // Menu
        hInstance,  // Instance handle
        NULL        // Additional application data
    );

    if (hwnd == NULL)
    {
        return 0;
    }

    ShowWindow(hwnd, nCmdShow);

    // Run the message loop.

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

    return 0;
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM  lParam)
{
    switch (uMsg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;

    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hwnd, &ps);



        FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW + 1));

        EndPaint(hwnd, &ps);
    }
    return 0;
    }
    return DefWindowProc(hwnd,uMsg,wParam,lParam);
}

Ответы [ 3 ]

4 голосов
/ 24 апреля 2020

RegisterClassEx() необходимо знать размер используемой структуры, поэтому вы должны инициализировать элемент w c .cbSize с sizeof(wc):

wc.cbSize = sizeof(wc);

или эквивалентно:

wc.cbSize = sizeof(WNDCLASSEX) ;
4 голосов
/ 24 апреля 2020

Добавьте

wc.cbSize = sizeof wc;

и обнулите остальную часть структуры.

2 голосов
/ 24 апреля 2020

Ответ в документации для WNDCLASSEX :

Структура WNDCLASSEX аналогична структуре WNDCLASS . Есть два отличия. WNDCLASSEX включает элемент cbSize, который определяет размер структуры [...]

Документация для cbSize содержит эту информацию:

Размер в байтах этой структуры. Установите для этого участника значение sizeof(WNDCLASSEX). [...]

При отсутствии кода проверки ошибок вам нужно обязательно написать идеальный код. Шаг к этой цели - правильно инициализировать структуру WNDCLASSEX. Член cbSize является первым членом в структурах, если он присутствует. Следующий ноль инициализирует структуру и соответственно устанавливает член cbSize:

WNDCLASSEX wc = { sizeof(wc) };

, хотя я бы предпочел

WNDCLASSEXW wc = { sizeof(wc) };

Важные уроки:

  • Внимательно прочитайте документацию.
  • Реализуйте сообщения об ошибках / обработку.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...