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");
在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");