редактировать— Добавлен код для 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)
) закончится катастрофой, но почему это должно иметь значение в этом случае? Там нет никаких требований для m_hWndFrame
содержать что-либо, в частности, перед вызовом CreateWindowEx (по крайней мере, согласно справке в VS2010), так почему это должно влиять на результат CreateWindowEx?
Проблема не в том, что 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 получает мусор для дескриптора окна клиента.
Других решений пока нет …