Я пишу классы-оболочки для win32, в основном, чтобы больше узнать о программировании на win32.
Чтобы обойти проблему обратных вызовов в стиле c, следующий метод сохраняет / извлекает указатель с помощью SetWindowLong / GetWindowLong и передает его фактическому winproc.
LRESULT CALLBACK WinClass::WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
// On window creation, WindowProc receives lParam as a LPCREATESTRUCT
// Store *this* pointer as long in GWL_USERDATA
if (msg == WM_NCCREATE)
::SetWindowLong(hwnd, GWL_USERDATA, reinterpret_cast<long>(reinterpret_cast<LPCREATESTRUCT>(lParam)->lpCreateParams));
// Retrieve the pointer
WinClass *wnd = reinterpret_cast<WinClass*>(::GetWindowLongPtr(hwnd, GWL_USERDATA));
// Call the actual winproc function
if (wnd)
return wnd->WndProc(hwnd, msg, wParam, lParam);
// Default to DefWindowProc message handler function
return ::DefWindowProc(hwnd, msg, wParam, lParam);
}
Winclass - это класс, обертывающий главное окно, созданное CreateWindowEx. Та же самая функция WindowProc является частью MDlgClass, заключающего модальное диалоговое окно. Я вызываю диалог, как это
DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(id), hwnd, DialogProc);
Если я передаю NULL как hWndParent, диалоговое окно нормально работает как немодальное диалоговое окно, но если я передаю hwnd, дескриптор главного окна как hWndParent, диалоговое окно работает правильно как модальное диалоговое окно. Однако, когда я закрываю диалог, он не передает управление обратно в главное родительское окно? Отладка в Visual Studio показывает зависание в насосе сообщений в WinMain.
Я думал об использовании хэш-карты для отображения указателей, но я бы предпочел сделать это с помощью GetWindowLong и т. Д. Возможно ли это? Я пытался сохранить указатель диалога в DWL_USER, но это не помогает.
Буду признателен за любую помощь, я все еще думаю о Win32.
РЕДАКТИРОВАТЬ: я уничтожаю диалог с помощью EndDialog
РЕДАКТИРОВАТЬ: я храню указатель в области GWL_USERDATA главного окна, которая не используется окнами, и я изменяю его только в WinClass :: WindowProc, когда окно создается впервые. Если я не создаю экземпляр класса диалога, я знаю, что к указателю обращаются правильно, поскольку приложение отвечает на команды меню, обработанные с помощью WindowProc и WM_COMMAND.