编辑 - 添加了与m_hWndClient和最初未包含的WndProc有关的代码。为了简短起见,我错误地认为它是无关的。
运行以下内容后
HWND m_hWndFrame;
HWND m_hWndClient; // added in Edit2
...
m_hWndFrame = CreateWindowEx(...)
m_hWndFrame
为NULL,GetLastError
给出“错误1400 - 无效窗口句柄”,但这样可以正常工作:
HWND m_hWndFrame = NULL;
HWND m_hWndClient = NULL; // added in Edit2
...
m_hWndFrame = CreateWindowEx(...)
我的WndProc
看起来像这样:
LRESULT CALLBACK ProgramManager::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
CLIENTCREATESTRUCT clientCreate;
HINSTANCE hInstance = GetModuleHandle(NULL);
RECT clientRect;
switch (uMsg)
{
case WM_CREATE:
clientCreate.hWindowMenu = NULL;
clientCreate.idFirstChild = IDM_FIRSTCHILD ;
GetClientRect(hwnd,&clientRect);
s_instance->m_hWndClient = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT ("MDICLIENT"), NULL,
WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0, 0, clientRect.right,
clientRect.bottom, hwnd, (HMENU)ID_MDI_CLIENT, hInstance,
(LPVOID)&clientCreate);
return 0 ;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefFrameProc(hwnd,m_hWndClient,uMsg,wParam,lParam);
}
我的项目现在有效(经过多次撕裂)但我不明白为什么初始化一个仅用于保存返回值的变量应该很重要。
显然假设变量为NULL或0而没有初始化然后使用或测试内容(例如if (!m_unitialisedVariable)
)将在灾难中结束但是为什么在这种情况下它是否重要?在调用'CreateWindowEx'之前,没有要求m_hWndFrame
特别包含任何内容(至少根据VS2010中的帮助),为什么它会影响'CreateWindowEx'的结果?
答案 0 :(得分:1)
问题不在于m_hWndFrame是否为NULL,而是m_hWndClient是否为NULL。
在WM_CREATE
中的WndProc
处理程序中,创建了一个MDI客户端窗口,其句柄存储在m_hWndClient
中。任何未处理的消息都会转到WndProc
:
return DefFrameProc(hwnd,m_hWndClient,uMsg,wParam,lParam);
但是WM_CREATE
不是发送到窗口的第一条消息(WM_NCCREATE
之前发送WM_CREATE
)。因此,当在 WM_CREATE
之前收到消息时,m_hWndClient
仍然未初始化,并且是错误消息所指示的无效窗口句柄。
因此,在这种情况下,初始化m_hWndFrame在技术上并不是必需的,但初始化m_hWndClient是否会导致客户端窗口句柄的DefFrameProc调用变为垃圾。