Reputation: 557
My problem is, I suppose, reasonably common: opening a file in the first instance of my app when a second instance is run (e.g. by opening an asociated file in the explorer).
The way I implemented this on Windows is by using the SendMessage
Win API and receiving the message by reimplementing winEvent in a Qt window. This worked well enough on Qt4. But for some reason, it stopped working completely after I had updated my app to Qt 5.
I have written a minimal test (see below) that reproduces the behaviour: also fine on Qt 4, but not working on Qt 5 (the message is not received). I am using mingw32
(gcc
) in case it makes any difference. I am very unfamiliar with the Windows API so would be delighted if someone could explain the odd behaviour.
Thanks a lot!
server.c:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winuser.h>
#include <windef.h>
#include <QApplication>
#include <QLabel>
#include <QDialog>
#include "winmessagelistener.h"
bool WinMessageListener::winEvent( MSG* message, long* result ) {
if( message->message == WM_COPYDATA ) {
label->setText( "Message!" );
// We process the event here
*result = 0;
return true;
}
else {
// Give the event to qt
return false;
}
}
WinMessageListener::WinMessageListener() : QDialog() {
setWindowTitle( "blah" );
label = new QLabel( this );
label->setText("no message");
}
int main(int argc, char **argv) {
QApplication app (argc, argv);
WinMessageListener listener;
listener.show();
return app.exec();
}
winmessagelistener.h:
#include <QDialog>
#include <QLabel>
class WinMessageListener : public QDialog {
Q_OBJECT
public:
WinMessageListener();
private:
// Override the default event message
bool winEvent( MSG* message, long* result );
QLabel* label;
};
client.c:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winuser.h>
#include <windef.h>
#include <iostream>
#include <QString>
const QString WINDOW_TITLE = "blah";
int main(int argc, char **argv) {
LPCWSTR window_title = (LPCWSTR) WINDOW_TITLE.utf16();
HWND window_handle_ = FindWindow( NULL, window_title );
std::cerr << "Window handle = " << window_handle_ << std::endl;
COPYDATASTRUCT data = { 0, 0, 0 };
SendMessage( window_handle_, WM_COPYDATA, 0, (LPARAM) &data );
}
Upvotes: 0
Views: 2108
Reputation: 4125
Since an answer can help others better than comments, here it is. The problem is that in Qt5, the function bool QWidget::winEvent(MSG * message, long * result)
is no longer available. It has been replaced by the function bool QWidget::nativeEvent(const QByteArray &eventType, void *message, long *result)
, as it is stated in the documentation:
Note: This function superseedes the event filter functions x11Event(), winEvent() and macEvent() of Qt 4.
Note that in a more general way, and as @Paul R. said that in the comments, don't forget to use the macro Q_DECL_OVERRIDE in order to allow the compiler to generate an error if your overriding of the virtual function does nothing. In that case, it could have been used like this :
bool WinMessageListener::winEvent(MSG * message, long * result) Q_DECL_OVERRIDE;
Note : this is a C++11 contextual keyword, and thus your compiler needs to support C++11 if you want to use it. If you are not using a compiler supporting C++11, you won't get any diagnostics.
Upvotes: 1