2016-07-22 216 views
0

我想在新USB設備連接或斷開時連接(設備隱藏)。當有USB設備更改時,我已成功通知,但我不知道設備是連接還是斷開連接。 我收到(USB連接或分離時)的信息是相同的: 消息:537(VM_DEVICECHANGE) 的wParam:7 的lParam:0檢測到在Qt上連接/斷開連接的新USB設備

#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。)。如果我明白這是不可能很容易地知道,如果它是一個連接或刪除。我使用API​​來查看隱藏設備(hidapi),我認爲最好的方法是使用它來知道它是連接還是刪除 – 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->僅當我插入(或拔下)USB密鑰時,wParam等於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 –