My project is C++ Windows Desktop Wizard AKA Win32 API project.
In function WinMain(...) I'm creating my window:
hWnd = CreateWindowEx(NULL, _T("DesktopApp"), _T("Hi, I'm window"), WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, NULL, NULL, hInstance, NULL);
And after that for some reason my window has status "unable to read memory" (therefore I can't create GUIs without this issue). I checked even 2nd page of Google to find a resolve of this problem. Microsoft's documentation didn't help: I checked the implementation and it fits with mine. I can't fix it for a long time, mb I'm blind and I wrote smth wrong before, despite I've created 2 working projects before (comparison didn't give any results).
Here goes the whole code:
#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;
}
Thanks in advance for help.
When
STRICT Type Checkingis enabled during compiling,HWNDis a typedef forHWND__*, whereHWND__is a struct with anunuseddata member (only because astructcan't legally be empty in C, but it can in C++), eg:winnt.h:
windef:
So, when
STRICTis defined,HWNDis an alias forstruct HWND__*, otherwise it is an alias forPVOID(void*). Same with MANY other handle types (HHOOK,HEVENT,HGDIOBJ,HBITMAP, etc).For your debugger to be showing you the
unusedmember when viewing anHWND, that means you are compiling withSTRICTdefined (which is a good thing, you should be). The debugger sees a pointer to a type, and tries to display the data that type contains.However, an
HWNDis not REALLY a pointer to astruct HWND__in memory. It is actually just an opaque value provided by the kernel. What anHWNDactually refers to is private to the kernel, a user-mode debugger has no way of knowing what that really is.STRICThandling is merely provided for compile-time type safety, so that user code can't accidentally pass other handle types where anHWNDis expected, and vice versa.In your case, your
HWNDhas a value of0x00170344, which meansCreateWindowEx()is not failing, theHWNDitself is valid. But0x00170344is not a valid memory address in your app's address space, so when the debugger tries to access theunusedmember at that address, it fails with "unable to read memory". Theunusedmember will NEVER be valid in a user-mode debugger (that is why it is "unused"). The only thing that is important is whether the value of theHWNDitself is0or not.