Редактировать - Добавлен код для использования m_hWndClient и WndProc, которые изначально не были включены. В попытке быть краткими я неправильно предположил, что это не связано.Почему неинициализированное возвращаемое значение вызывает недопустимую ошибку дескриптора окна в CreateWindowEx?
После следующих запускается
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)
) закончится катастрофой, но почему это имеет значение в этом случае? Для m_hWndFrame
нет необходимости содержать что-либо, прежде чем вызывать «CreateWindowEx» (по крайней мере, согласно справкой в VS2010), так почему это должно повлиять на результат «CreateWindowEx»?
Невозможно знать наверняка, не видя полного кода, но я предполагаю, что вы передаете другой неинициализированный дескриптор в качестве родительского окна. И, случается, имеет место NULL тогда и только тогда, когда предыдущее предложение является заданием «NULL». – rodrigo
Я предполагаю, что оконная процедура пытается использовать 'm_hWndFrame' внутри своего обработчика' WM_CREATE'. Поскольку это выполняется до того, как 'CreateWindowEx' вернется, он использует неинициализированную переменную. 'CreateWindowEx' не заботится о' m_hWndFrame', но может потребоваться и другие части вашего кода, которые выполняются как часть создания окна. –
@RaymondChen: Но даже если он это сделает, 'CreateWindowEx' не будет терпеть неудачу, если он не вернет что-то'! = 0' из 'WM_CREATE' ... – rodrigo