c++ - winapi - 从 QObject 派生类调用时 GetMessage() 崩溃

标签 c++ qt winapi

我有一个代码示例来自 Registering for Device Notification检测 USB 设备是否被移除。此代码使用 Win32 API,我已经构建并成功测试了它。

当我尝试将此功能集成到 QObject 派生类中时,我在 MessagePump() 方法中遇到崩溃:

void QObjectDerivedClass::MessagePump() {
    MSG message;
    int retVal;

    if (!m_hWnd) {
        return;
    }

    qDebug() << Q_FUNC_INFO;

    // Get all messages for any window that belongs to this thread,
    // without any filtering. Potential optimization could be
    // obtained via use of filter values if desired.

    while ((retVal = GetMessage(&message, m_hWnd,
                             MSG_FILTER_MIN, MSG_FILTER_MAX)) != 0) {
        if (retVal == -1) {
            break;
        } else {
            TranslateMessage(&message);
            DispatchMessage(&message);
        }
    }
}

如您所想,我必须修改示例中的 WndProc() 回调,以便为此类使用静态成员并满足 WNDCLASS 对象,如下所示:

BOOL QObjectDerivedClass::InitWindowClass() {
    WNDCLASSEX wndClass;/* = {0};*/

    wndClass.cbSize = sizeof(WNDCLASSEX);
    wndClass.style = 0;
    wndClass.hInstance = reinterpret_cast<HINSTANCE>(GetModuleHandle(0));
    // WndProcThunk is an static member of QObjectDerivedClass
    wndClass.lpfnWndProc = reinterpret_cast<WNDPROC>(WndProcThunk);
    wndClass.cbClsExtra = 0;
    wndClass.cbWndExtra = 0;
    wndClass.hIcon = NULL;
    wndClass.hIconSm = NULL;
    wndClass.hbrBackground = NULL;
    wndClass.hCursor = NULL;
    wndClass.lpszClassName = WND_CLASS_NAME;
    wndClass.lpszMenuName = NULL;

    if (!RegisterClassEx(&wndClass)) {
        qDebug() << Q_FUNC_INFO << "Unable to register window class. Error:"
             << QString::number(GetLastError());

        return FALSE;
    }

    m_instance = wndClass.hInstance;

    return TRUE;
}

应用崩溃时的调用栈是:

1                                                                0xd26128   
2  SetManipulationInputTarget             USER32                 0x7709d2b3 
3  DispatchMessageW                       USER32                 0x7707e88a 
4  DispatchMessageW                       USER32                 0x7707e4c0 
5  RealGetWindowClassW                    USER32                 0x7708a64f 
6  KiUserCallbackDispatcher               ntdll                  0x772e08c6 
7  QObjectDerivedClass::MessagePump       qobjectderived.cpp 165 0xa52e88   
8  QObjectDerivedClass::Start             qobjectderived.cpp 346 0xa52bc2   
9  wWinMain                               main.cpp           259 0xa525ff   
10 invoke_main                            exe_common.inl     118 0xa5516e   
11 __scrt_common_main_seh                 exe_common.inl     253 0xa54fd0   
12 __scrt_common_main                     exe_common.inl     296 0xa54e6d   
13 wWinMainCRTStartup                     exe_wwinmain.cpp   17  0xa55188   
14 BaseThreadInitThunk                    KERNEL32               0x73d862c4 
15 RtlSubscribeWnfStateChangeNotification ntdll                  0x772d0fd9 
16 RtlSubscribeWnfStateChangeNotification ntdll                  0x772d0fa4

知道如何解决这个崩溃吗?


编辑:发布的标准输出:

int __stdcall wWinMain(struct HINSTANCE__ *,struct HINSTANCE__ *,wchar_t *,int)
int __stdcall QObjectDerivedClass::WndProcThunk(struct HWND__ *,unsigned int,unsigned int,long)
int __stdcall QObjectDerivedClass::WndProcThunk(struct HWND__ *,unsigned int,unsigned int,long)
int __stdcall QObjectDerivedClass::WndProcThunk(struct HWND__ *,unsigned int,unsigned int,long)
int __stdcall QObjectDerivedClass::WndProcThunk(struct HWND__ *,unsigned int,unsigned int,long)
void __thiscall QObjectDerivedClass::MessagePump(void)

最佳答案

您不需要重新实现任何 native 消息泵:Qt 已经为您完成了。

相反,在具体的 nativeEventFilter 实现中对 Windows 消息使用react QAbstractNativeEventFilter .重新实现也可以继承 QObject - 确保 QObject 是第一个基类,因为这是继承 QObject 的唯一支持方式。

要使用过滤器,请使用 qApp->installNativeEventFilter 安装它.

关于c++ - winapi - 从 QObject 派生类调用时 GetMessage() 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43230755/

相关文章:

c++ - 不要真正理解 std::atomic::compare_exchange_weak 和 compare_exchange_strong 的逻辑

c++ - 抽象基类的抽象子类

c++ - Qt 断开连接后连接到服务器时客户端程序崩溃

c++ - 我的函数操作 std::string 产生了意想不到的结果

c# - 在 C# 中更改辅助监视器屏幕分辨率

c++ - 包括 stdafx.h winsock2 重新定义错误

c++ - Eigen 矩阵库系数明智的操作

c++ - Qt 小部件在某些情况下无法重新绘制

c++ - qapps运行良好但断点有时会产生段错误

c++ - VBA 无法找到我的 DLL,尽管对位置进行了硬编码。