2
votes

I need to do the following. I have USB-UART converter and when it's plugged in it's recognized as serial port. I need to read this serial port's name and add it to combobox, where user can choose it and open for data transfer.

Getting available serial ports is not a problem in Qt. But I want to do it only when device is inserted or removed. I did this in Linux by listening to corresponding DBus signals. Is there something similar in Windows? What I need exactly is to receive messages in my application from system each time when new serial port is connected or disconnected.

I've found some solutions for .NET C#, but have no idea how to reproduce them in Qt. Thanks!

1
@kunif thank you! But it's not really helpful. I write my app in qml and don't know how it's possible to process nativeEvent for qml main window...Herman
@kunif thank you again! I've managed to solve my problem with first link. It gave me event's name I should have caught and by this name I've found information I needed. Some of your other links describe the solution. I'll post solution on my behalf, but it's truly your merit! Thanks again!Herman

1 Answers

1
votes

Thanks to @kunif I've found solution. So to listen to Windows messages you need to add your own EventFilter by inheriting QAbstractNativeEventFilter like this:

#include <QAbstractNativeEventFilter>
#include <QObject>

class DeviceEventFilter : public QObject, public QAbstractNativeEventFilter
{
    Q_OBJECT

public:
    DeviceEventFilter();
    bool nativeEventFilter(const QByteArray &eventType, void *message, long *) override;

signals:
    void serialDeviceChanged();
};

And filter the message you need WM_DEVICECHANGE:

#include <windows.h>
#include <dbt.h>

bool DeviceEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *) {
    if (eventType == "windows_generic_MSG") {
        MSG *msg = static_cast<MSG *>(message);

        if (msg->message == WM_DEVICECHANGE) {
            if (msg->wParam == DBT_DEVICEARRIVAL || msg->wParam == DBT_DEVICEREMOVECOMPLETE) {
                // connect to this signal to reread available ports or devices etc
                emit serialDeviceChanged();        
            }
        }
    }
    return false;
}

And somewhere in your code, where you have access to DeviceEventFilter object add this line:

qApp->installNativeEventFilter(&devEventFilterObj);

Or in main.cpp :

QApplication app(argc, argv);
app.installNativeEventFilter(&devEventFilterObj);

All gratitude to @kunif !