关于C#:为什么错误1400窗口句柄无效?

Why error 1400 Invalid window handle?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <stdio.h>
#include <stdbool.h>
#include <Windows.h>

HWND WindowHandle;
HINSTANCE Instance;
const wchar_t WindowClassName[] = L"Temp Projcet";

LRESULT CALLBACK WindowProc(HWND _windowHandle, UINT _msg, WPARAM _param, LPARAM _param1) {
    switch (_msg) {
    case WM_PAINT: {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(WindowHandle, &ps);
        FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
        EndPaint(WindowHandle, &ps);
    } break;
    case WM_CLOSE: {
        if (IDOK == MessageBoxW(WindowHandle, L"Quit?", L"My application", MB_OKCANCEL)) {
            DestroyWindow(WindowHandle);
        }
        return false;
    } break;
    case WM_DESTROY: {
        PostQuitMessage(0);
    } break;
    default:
        break;
    }
    return DefWindowProcW(WindowHandle, _msg, _param, _param1);
}

ATOM RegisterWindowClass(void) {
    WNDCLASS wc = { 0 };
    wc.lpfnWndProc = WindowProc;
    wc.hInstance = Instance;
    wc.lpszClassName = WindowClassName;
    return RegisterClassW(&wc);
}

int APIENTRY wWinMain(HINSTANCE _instance, HINSTANCE _prevInstance, PWSTR _cmdLine, int _cmdShow) {
    Instance = _instance;
    RegisterWindowClass();

    WindowHandle = CreateWindowExW(
        0,
        WindowClassName,
        L"This a window",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
        NULL,
        NULL,
        Instance,
        NULL
    );

    DWORD err = GetLastError();
    // Why error 1400 Invalid window handle?

    MSG msg = { 0 };
    while (GetMessageW(&msg, WindowHandle, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessageW(&msg);
    }

    return 0;
}

为什么在创建窗口时它会返回1400个无效的句柄?不是吗?创建窗口函数中没有窗口句柄,好吗?怎么可能是无效的句柄?我已经在搜索引擎中搜索了很长时间,但是仍然无法解决此问题?
为什么CreateWindowExW()返回1400?
第44行中的代码。


在将其设置为返回值CreateWindowEx之前,您正在窗口过程中使用WindowHandleCreateWindowEx调用的一部分是使用WM_NCCREATEWM_CREATE调用窗口过程。此时,您的窗口过程将调用带有空句柄的DefWindowProc

这里的简单解决方案是使用_windowHandle参数而不是全局WindowHandle

还请注意,为了使您的窗口可见,您需要调用ShowWindow。此外,您发布的退出消息不是特定于该窗口的,因此您的GetMessage调用将不会检索它,并且应用程序也不会结束。


仅在失败的CreateWindow(即,如果CreateWindow返回NULL)之后调用GetLastError。

在绝大多数成功的Windows API调用之后,未指定最后一个错误值,必须在调用GetLastError之前检查返回值。


这里

1
DWORD err = GetLastError();

您尚未测试是否确实存在错误。您需要测试从CreateWindowEx返回的句柄,然后再调用GetLastError。否则,它将返回一些先前的,不相关的错误或某个随机值。