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

时间:2013-05-21 23:44:29

标签: c++ windows winapi createwindowex

编辑 - 添加了与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'的结果?

1 个答案:

答案 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调用变为垃圾。