简体   繁体   中英

winapi - GetMessage() crashing when is called from QObject derived class

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM