I have a sample of code taken from Registering for Device Notification to detect if a USB device is removed. This code uses the Win32 API and I have built and test it with success.
When I try to integrate this functionality into a QObject
-derived class, I'm getting a crash in the MessagePump()
method:
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);
}
}
}
As you can imagine, I have to modify the WndProc()
callback in the example to use a static member for this class and satisfy WNDCLASS
object as follow:
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;
}
The call stack when the application crashes is:
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
Any idea how to solve this crash?
EDIT: Posted standard output:
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)
You don't need to reimplement any of the native message pumping: Qt already does it for you.
Instead, react to Windows messages in your reimplementation of nativeEventFilter
in a concrete QAbstractNativeEventFilter . The reimplementation can also inherit QObject
- make sure the QObject
is the first base class as that's the only supported way to inherit QObject
.
To use the filter, install it using qApp->installNativeEventFilter
.
WinApi is inherently not C++ aware. QT will abstract away all the hard work involved with passing the correct messages to the correct window. You seem to be attempting to bypass all of these things and do window creation and message pumping yourself, which is causing your problems.
Why not follow a simple QT example and insert your changes into that, rather than re-inventing the wheel.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.