c++ - Win32 : Modal dialog not returning focus

标签 c++ c windows winapi

我正在写一个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/

相关文章:

C++成员初始化、复制初始化和默认初始化

c++ - 文件流和控制台流之间的区别

c - 如何使我的递归 C 程序更有效率?

C 线程变量在从另一个线程声明后具有值

windows - QtService 应用程序作为服务运行时无法连接到系统总线

c++ - 安装了全局 Hook 后,我如何知道窗口何时开始移动以及何时停止移动?

windows - 有没有办法确定命名对象的 CloseHandle() 是否是最后一个?

c++ - 如何一一检查 const char* 值

你能为条件编译定义一个函数风格的宏吗?

c++ - 在 C++ 中重载命名空间 std 中的数学函数是一种好习惯吗