2016-07-22 14 views
0

Ich möchte benachrichtigt werden, wenn ein neues USB-Gerät angeschlossen oder getrennt (Gerät hid). Es ist mir gelungen, benachrichtigt zu werden, wenn ein USB-Gerät geändert wird, aber ich weiß nicht, ob das Gerät verbunden oder getrennt ist. Die Botschaft, die ich erhalten (wenn usb oder frei stehende Anlage) ist das gleiche: Nachricht: 537 (VM_DEVICECHANGE) wParam: 7 lParam: 0Ermittelte neue USB-Gerät verbunden/getrennt auf Qt

#include <QGuiApplication> 
#include <QQmlApplicationEngine> 
#include <QAbstractEventDispatcher> 
#include <QAbstractNativeEventFilter> 
#include <QDebug> 
#include <windows.h> 
#include <dbt.h> 
#include <QObject> 

class MyNativeEventFilter : public QAbstractNativeEventFilter { 
public : 
    virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) 
    Q_DECL_OVERRIDE 
    { 
     if (eventType == "windows_generic_MSG") 
     { 
      MSG *msg = static_cast<MSG *>(message); 
      static int i = 0; 

       msg = (MSG*)message; 
        qDebug() << "message: " << msg->message << " wParam: " << msg->wParam 
         << " lParam: " << msg->lParam; 
       if (msg->message == WM_DEVICECHANGE) 
       { 
        qDebug() << "WM_DEVICECHANGE"; 
       } 
      } 
     return false; 
    } 
}; 

int main(int argc, char *argv[]) 
{ 
    QGuiApplication app(argc, argv); 
    MyNativeEventFilter myEventfilter; 
    app.eventDispatcher()->installNativeEventFilter(&myEventfilter); 
    QQmlApplicationEngine engine; 
    engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); 

    return app.exec(); 
} 
+0

Offtopic: warum Sie ein eigenes Fenster brauchen? Verwenden Sie einfach 'qApp-> eventDispatcher() -> installNativeEventFilter (yourEventFilter);'. 'yourEventFilter' sollte ein Kind von' QAbstractNativeEventFilter' sein. –

+0

@DmitrySazonov Danke für den Trick, aber ich habe immer das gleiche "Problem" (Ich habe meinen Beitrag bearbeitet) – helene

Antwort

0

Die WM_DEVICECHANGE message nicht wirklich Sie nicht sagen, ob ein Gerät war verbunden oder getrennt. Nach dem Empfang dieser Nachricht sollte Ihre Anwendung mithilfe von SetupAPI alle angeschlossenen USB-Geräte überprüfen und entsprechende Maßnahmen ergreifen.

+0

Wenn Sie eine 'WM_DEVICECHANGE' Nachricht erhalten, können Sie' wParam' gegen überprüfen 'DBT_DEVICEARRIVAL' oder' DBT_DEVICEREMOVECPLETE'. –

+0

Aber das OP erhält DBT_DEVNODES_CHANGED, so dass beide Prüfungen fehlschlagen würden. –

+1

wParam ist gleich 7 (DBT_DEVNODES_CHANGED.). Wenn ich verstehe, ist es nicht möglich, leicht zu wissen, ob es eine Verbindung oder ein Entfernen ist. Ich benutze eine API, um versteckte Gerät (Hidapi) zu sehen, ich denke, das beste ist, es zu verwenden, um zu wissen, ob es eine Verbindung ist oder entfernen – helene

0

Hier ist, was ich in einem meiner Projekte verwenden für USB-Verbindungen/deconnections, um informiert:

/** deviceeventfilter.h **/ 
class DeviceEventFilter: public QObject, public QAbstractNativeEventFilter 
{ 
    Q_OBJECT 
public: 
    explicit DeviceEventFilter(QObject *parent = 0); 
    virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *result); 

signals: 
    void newUSBDevice(); 
    void lostUSBDevice(); 

public slots: 
    void registerEvent(QWindow *window); 
}; 

/** deviceeventfilter.cpp **/ 
DeviceEventFilter::DeviceEventFilter(QObject *parent) : 
    QObject(parent) 
{ 

} 

bool DeviceEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *result) 
{ 
    Q_UNUSED(eventType); 
    Q_UNUSED(result); 
#ifdef Q_OS_WIN32 
    MSG *msg = (MSG *)message; 
    if(WM_DEVICECHANGE == msg->message && DBT_DEVICEARRIVAL == msg->wParam) 
    { 
     qDebug("USB arrival detected!"); 
     emit newUSBDevice(); 
    } 
    else if(WM_DEVICECHANGE == msg->message && DBT_DEVICEREMOVECOMPLETE == msg->wParam) 
    { 
     qDebug("USB departure detected!"); 
     emit lostUSBDevice(); 
    } 
#endif 
    // Return false so that the event is propagated 
    return false; 
} 


void DeviceEventFilter::registerEvent(QWindow *window) 
{ 
    if(window != nullptr) 
    { 
#ifdef Q_OS_WIN32 
     GUID guid = ...; 

     DEV_BROADCAST_DEVICEINTERFACE NotificationFilter; 

     ZeroMemory(&NotificationFilter, sizeof(NotificationFilter)); 
     NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE); 
     NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; 
     NotificationFilter.dbcc_classguid = guid; 
     HDEVNOTIFY hDevNotify = RegisterDeviceNotification((HANDLE)window->winId(), &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE); 
     if(NULL == hDevNotify) 
     { 
      // Print error 
     } 
#endif 
    } 

} 

/** main.cpp **/ 
int main() 
{ 
    ... 
    DeviceEventFilter event_filter; 
    QWindow *w = qApp->allWindows().first(); 
    event_filter.registerEvent(w); 
    app.installNativeEventFilter(&event_filter); 
    ... 
} 
+0

msg-> wParam ist gleich DBT_DEVICEARRIVAL oder DBT_DEVICEREMOVECOMPLETE nur, wenn ich den USB-Schlüssel einstecken (oder entfernen). Wenn ich die Maus zum Beispiel stecke funktioniert es nicht – helene

+0

Es scheint, dass das Empfangen nur 'DBT_DEVNODES_CHANGED' ein häufiges Problem ist. Sie könnten das folgende interessant finden: http://stackoverflow.com/questions/28998625/c-win32-not-receiving-dbt-devicearrival-or-dbt-deviceremovecomplete-on-wm-devi –