2

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!

Herman
  • 155
  • 4
  • 13
  • 1
    For example, is this article helpful? [WM_DEVICECHANGE received but not DBT_DEVICEARRIVAL in my Qt app](https://stackoverflow.com/q/30399992/9014308) – kunif Oct 01 '19 at 23:36
  • @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 Oct 02 '19 at 11:15
  • 1
    Perhaps one of these may be helpful. [Qt's nativeEvent() is never called](https://stackoverflow.com/q/30384037/9014308), [Qt::nativeEvent calls](https://stackoverflow.com/q/26652783/9014308), [Process native events of a window created by QQmlApplicationEngine](https://stackoverflow.com/q/50900006/9014308), [How can I intercept and cancel the minimizing of a Window?](https://stackoverflow.com/q/51509507/9014308) – kunif Oct 02 '19 at 11:32
  • @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 Oct 02 '19 at 17:30

1 Answers1

1

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 !

Herman
  • 155
  • 4
  • 13
  • This didn't work for me. The `nativeEventFilter` event was called several times when I did various things on my computer (like launching programs and stuff), but it wasn't called when I connected or disconnected my Android phone through USB. – Donald Duck Oct 24 '21 at 13:17
  • @DonaldDuck maybe because android phone is not registered in the system as USB device? I used this method with USB flash stick and it worked. – Herman Nov 01 '21 at 12:54
  • @​Herman So do you mean it only works with USB flash sticks? I need a solution that works when anything is plugged into a USB port, including phones, USB mouse, etc. – Donald Duck Nov 01 '21 at 16:28
  • @DonaldDuck I mean that I needed this functionality to detect USB stick plug in and out. I didn't try this with other devices. Try to check all incoming messages types when you connect target devices. I'm sorry, but I'm not Windows expert. By the way, check links in the comments under original question. – Herman Nov 03 '21 at 15:17