2016-07-22 8 views
0

新しいUSBデバイスが接続または切断されたときに通知を受けたい(デバイスhid)。私は、USBデバイスの変更があったときに通知を受けることに成功しましたが、デバイスが接続されているか切断されているかわかりません。 (USBは着脱時に)私が受け取るメッセージは同じです: メッセージ:537(VM_DEVICECHANGE) のwParam:7 のlParam:0新しいusbデバイスが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:なぜあなたはカスタムウィンドウが必要なのでしょうか?単に 'qApp-> eventDispatcher() - > installNativeEventFilter(yourEventFilter);'を使用してください。 'yourEventFilter'は' QAbstractNativeEventFilter'の子でなければなりません –

+0

@DmitrySazonovトリックをありがとうございますが、私はいつも同じ問題を抱えています(私の投稿を編集しました) – helene

答えて

0

WM_DEVICECHANGE messageは本当にあなたのデバイスがあったかどうかを教えてくれありません接続または切断される。そのメッセージを受信した後、アプリケーションはSetupAPIを使用して、接続されているすべてのUSBデバイスを調べ、適切な処置をとる必要があります。ここで

+0

'WM_DEVICECHANGE'メッセージを受け取ったら' wParam'を確認できます'DBT_DEVICEARRIVAL'または' DBT_DEVICEREMOVECOMPLETE'です。 –

+0

しかしOPはDBT_DEVNODES_CHANGEDを​​取得しているため、これらのチェックは両方とも失敗します。 –

+1

wParamは7(DBT_DEVNODES_CHANGED。)です。私が理解すれば、接続か削除かどうか簡単に知ることは不可能です。私は、hidデバイス(hidapi)を見るためにAPIを使用しています。接続または削除の場合は、それを使用してベストを見つけるのが良いと思います。 – helene

0

は、私はUSB接続/ deconnectionsのために通知を得るために私のプロジェクトの一つに使用するものです。

/** 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は、USBキーを差し込む(または取り外した)場合のみDBT_DEVICEARRIVALまたはDBT_DEVICEREMOVECOMPLETEと同じです。私がマウスのようなものを接続した場合、それはうまくいきません。 – helene

+0

'DBT_DEVNODES_CHANGED'だけを受信することはよくある問題です。 次のような興味深いものがあります:http://stackoverflow.com/questions/28998625/c-win32-not-receiving-dbt-devicearrival-or-dbt-deviceremovecomplete-on-wm-devi –

関連する問題