我正在写一个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 的消息泵中。
我想过使用 HashMap 来映射指针,但我更愿意使用 GetWindowLong 等来实现。这可能吗?我试过将对话框指针存储在 DWL_USER 中,但没有帮助。
任何帮助将不胜感激,我仍在思考 Win32。
编辑:我正在使用 EndDialog 破坏对话框
编辑:我将指针存储在主窗口的 GWL_USERDATA 区域中,Windows 不使用该区域,我只是在首次创建窗口时在 WinClass::WindowProc 中修改它。如果我不实例化对话框类,我知道指针被正确访问,因为应用程序响应通过 WindowProc 和 WM_COMMAND 处理的菜单命令。
最佳答案
您不能将 WindowProc 用作 DialogProc。窗口过程在不处理消息时调用 DefWindowProc,并在处理时返回有意义的结果。
对话过程在不处理消息时返回 FALSE,在处理消息时返回 TRUE(处理 WM_INITDIALOG
时除外),如果它们有需要从外部窗口返回的有意义的结果过程,放在 DWL_MSGRESULT
中。
当您调用模态对话框函数 DialogBox 时,它会进入一个消息泵循环 - 它会向线程中的所有窗口发送消息,以便所有窗口继续绘制和处理输入 - 当对话框关闭时(使用 EndDialog) , DialogBox 过程应该返回。
当制作一个类来包装对话框时,通常的方法是将“this”指针传递给 DialogBoxParam 函数之一 - 可以直接从 WM_INITDIALOG
消息中提取。
关于c++ - Win32 : Modal dialog not returning focus,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/923631/