Win32 API - HWND "{unused = ???} Unable to read memory"错误



我的项目是C++Windows Desktop Wizard AKA Win32 API项目。

在函数中 WinMain(...(我正在创建我的窗口:

hWnd = CreateWindowEx(NULL, _T("DesktopApp"), _T("Hi, I'm window"), WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, NULL, NULL, hInstance, NULL);

之后,由于某种原因,我的窗口状态为"无法读取内存"(因此如果没有此问题,我无法创建 GUI(。我甚至检查了谷歌的第二页,以找到这个问题的解决方案。Microsoft的文档没有帮助:我检查了实现,它适合我的。我很长一段时间都无法修复它,mb 我是盲人,我之前写错了 smth,尽管我之前创建了 2 个工作项目(比较没有给出任何结果(。

整个代码如下:

#include <windows.h>
#include <stdlib.h>
#include <string>
#include <tchar.h>
#include <shellapi.h>
#include <ctime>
HWND hWnd;
HINSTANCE hInst;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int CALLBACK WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow)
{
WNDCLASSEX wcex;
ZeroMemory(&wcex, sizeof(wcex));
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 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,
_T("Call to RegisterClassEx failed!"),
_T("Windows Desktop Guided Tour"),
NULL);
return 1;
}
hInst = hInstance;
hWnd = CreateWindowEx(NULL, _T("DesktopApp"), _T("Hi, I'm window"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
MessageBox(NULL,
_T("Call to CreateWindow failed!"),
_T("Windows Desktop Guided Tour"),
NULL);
return 1;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}

>它在调试器中的外观<</p>

提前感谢您的帮助。

在编译过程中启用STRICT Type Checking时,HWNDHWND__*的 typedef,其中HWND__是具有unused数据成员的结构(只是因为struct在 C 中不能合法地为空,但在 C++ 中可以(,例如:

温特·

#ifdef STRICT
typedef void *HANDLE;
#if 0 && (_MSC_VER > 1000)
#define DECLARE_HANDLE(name) struct name##__; typedef struct name##__ *name
#else
#define DECLARE_HANDLE(name) struct name##__{int unused;}; typedef struct name##__ *name
#endif
#else
typedef PVOID HANDLE;
#define DECLARE_HANDLE(name) typedef HANDLE name
#endif

赢德:

DECLARE_HANDLE            (HWND);

所以,当定义STRICT时,HWNDstruct HWND__*的别名,否则是PVOID的别名(void*(。 与许多其他手柄类型(HHOOKHEVENTHGDIOBJHBITMAP等(相同。

为了使调试器在查看HWND时向您显示unused成员,这意味着您正在使用定义的STRICT进行编译(这是一件好事,您应该这样做(。 调试器看到指向类型的指针,并尝试显示该类型包含的数据。

但是,HWND并不是真正指向内存中struct HWND__的指针。 它实际上只是内核提供的一个不透明值HWND实际引用的内容是内核专用的,用户模式调试器无法知道它到底是什么。

STRICT处理只是为了编译时类型安全而提供的,因此用户代码不会意外地将其他句柄类型传递到需要HWND的地方,反之亦然。

在您的情况下,您的HWND的值为0x00170344,这意味着CreateWindowEx()没有失败,则HWND本身是有效的。 但0x00170344不是应用地址空间中的有效内存地址,因此当调试器尝试访问该地址的unused成员时,它会失败并显示"无法读取内存"。unused成员在用户模式调试器中永远不会有效(这就是它"未使用"的原因(。 唯一重要的是HWND本身的价值是否0

相关内容

  • 没有找到相关文章

最新更新