CreateWindow 失败时 GetLastError returns 998 和 returns 0

GetLastError returns 998 when CreateWindow failed and returns 0

main.cpp:

#include "window.h"

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    Window main_window(hInstance, nCmdShow);
    main_window.Intitialize(CS_HREDRAW, NULL, LoadCursor(NULL, IDC_ARROW), (HBRUSH)(COLOR_WINDOW), (WIDE_CHAR) "Application", (WIDE_CHAR) "WindowName");
    return main_window.Show();
}

window.h:

#include <stdio.h>

#ifndef _WINDOW_H_
    #define _WINDOW_H_

#include <windows.h>

typedef wchar_t* WIDE_CHAR;
typedef HINSTANCE INSTANCE;
typedef HWND HANDLE_WINDOW;
typedef tagWNDCLASSEXW WINDOW_CLASS;

LRESULT Procedure(HANDLE_WINDOW, UINT, WPARAM, LPARAM);

class Window {
  private:
    INSTANCE instance;
    int show_command;
    WINDOW_CLASS window_object;
    HANDLE_WINDOW handle;

  public:
    Window(INSTANCE instance, int show_command) {
        this->instance = instance;
        this->show_command = show_command;
    }

    void Intitialize(UINT style, HICON icon, HCURSOR cursor, HBRUSH background, WIDE_CHAR class_name, WIDE_CHAR title) {
        window_object.cbSize = sizeof(WINDOW_CLASS);
        window_object.cbClsExtra = 0;
        window_object.cbWndExtra = 0;
        window_object.hInstance = instance;
        window_object.lpfnWndProc = Procedure;

        window_object.style = style;
        window_object.hIcon = icon;
        window_object.hCursor = cursor;
        window_object.hbrBackground = background;
        window_object.lpszMenuName = NULL;
        window_object.lpszClassName = class_name;
        window_object.hIconSm = NULL;

        RegisterClassExW(&window_object);
        printf("%lld", GetLastError());

        handle = CreateWindowExW(WS_EX_CLIENTEDGE, class_name, title, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 1080, 720, NULL, NULL, instance, NULL);
    }

    int Show() {
        ShowWindow(handle, show_command);
        UpdateWindow(handle);

        MSG message;
        while (GetMessageW(&message, NULL, 0, 0)) {
            TranslateMessage(&message);
            DispatchMessageW(&message);
        }

        return message.wParam;
    }
};

LRESULT Procedure(HANDLE_WINDOW handle, UINT message, WPARAM wParam, LPARAM lParam) {
    switch (message) {
        case WM_CLOSE:
            DestroyWindow(handle);
            break;

        case WM_DESTROY:
            PostQuitMessage(0);
            break;

        default:
            return DefWindowProc(handle, message, wParam, lParam);
            break;
    }
    return 0;
}

#endif

我试图包装 Win32 接口并尝试制作一个 window,但我总是卡在一些奇怪的地方,比如 Unicode...

首先,我对宽字符的使用和转换还不能完全理解。我觉得window注册和window创建失败的很大一部分原因是使用了宽字符和普通字符。 其次,我不明白为什么我不能使用命名空间“std”,一旦使用它,甚至window注册失败。

您正在将 (WIDE_CHAR) "Application"(WIDE_CHAR) "WindowName" 传递给 Intitialize

如您所定义

typedef wchar_t* WIDE_CHAR;

参数是 NARROW 个字符转换为 WIDE 个字符。当 CreateWindowExW 尝试访问它们时,它变为 out-of-bounds (因为宽字符串的长度是窄字符串的两倍),导致错误:

ERROR_NOACCESS

998 (0x3E6)

Invalid access to memory location.

根据https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes--500-999-

改为这样做:

main_window.Intitialize(CS_HREDRAW, NULL, LoadCursor(NULL, IDC_ARROW), 
    (HBRUSH)(COLOR_WINDOW), L"Application", L "WindowName");