为什么未初始化的返回值会导致createwindowwex的无效窗口句柄错误



Edit-添加了与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"的结果呢?

问题不在于m_hWndFrame是否为NULL,而在于m_hWndClient是否为NULL。

WndProcWM_CREATE处理程序中创建了一个MDI客户端窗口,并将其句柄存储在m_hWndClient中。任何未处理的消息都将通过WndProc末尾的行:

return DefFrameProc(hwnd,m_hWndClient,uMsg,wParam,lParam);

然而WM_CREATE不是发送到窗口的第一个消息(WM_NCCREATEWM_CREATE之前发送)。因此,当 WM_CREATE之前收到消息时,m_hWndClient仍然未初始化,并且是错误消息所指示的无效窗口句柄。

所以在这个实例中初始化m_hWndFrame在技术上是没有必要的,但是初始化m_hWndClient否则DefFrameProc调用会为客户端窗口的句柄获取垃圾。

相关内容

  • 没有找到相关文章

最新更新