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



我有一个从注册设备通知中获取的代码示例,用于检测 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 设置操作输入目标用户32 0x7709d2b3 3 调度消息W 用户32 0x7707e88a 4 调度消息W 用户32 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 主.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)

你不需要重新实现任何原生消息泵送:Qt已经为你做到了。

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

要使用过滤器,请使用qApp->installNativeEventFilter进行安装。

WinApi本质上不是C++意识。 QT将抽象出将正确消息传递到正确窗口所涉及的所有艰苦工作。 您似乎试图绕过所有这些事情并自己创建窗口和消息,这导致了您的问题。

为什么不遵循一个简单的QT示例并将您的更改插入其中,而不是重新发明轮子。

最新更新