C ++ Win32 empfängt DBT_DEVICEARRIVAL oder DBT_DEVICEREMOVECOMPLETE nicht auf WM_DEVICECHANGE

8

Ich habe daran gearbeitet, das Einsetzen / Entfernen von USB zu erkennen. Ich habe Code mit CreateWindowEx () implementiert und übergebe eine WNCLASSEX mit meinem Fensterprozessrückruf. Wenn ich meinen USB einfüge und entferne, erhalte ich erfolgreich die WM_DEVICECHANGE Nachricht, aber der wParam wird immer auf DBT_DEVNODES_CHANGED festgelegt.

Ich bekomme weder DBT_DEVICEARRIVAL noch DBT_DEVICEREMOVECPLETE. Ich habe verwendet, was ich bekomme, aber ich muss wirklich in der Lage sein, den Unterschied zwischen Gerätankunft und -entfernung zu unterscheiden, so dass ich je nachdem, was ich bekomme, verschiedene Aktionen ausführen kann.

Im Moment muss ich einen Timer setzen, nachdem ich DBT_DEVNODES_CHANGED erhalten habe, und dann testen, ob es neue entfernbare Objekte auf dem System gibt oder ob irgendwelche in meiner Liste nicht mehr vorhanden sind. Ich bin mir sicher, dass das nicht stimmt, also dachte ich, ich würde fragen. Ich würde viel lieber den Timer loswerden und nur diese zwei Nachrichten erhalten. Das würde mir sehr dabei helfen, was ich tun muss. Irgendwelche Vorschläge?

Hier ist der Code, den ich für die Registrierung des Callbacks habe, sowie den Callback selbst:

HINWEIS: 3/12/2015: Code aktualisiert, um tatsächliche GUID und die Definition der DoRegisterDeviceInterfaceToHwnd () - Funktion anzuzeigen.):

%Vor%     
bmahf 11.03.2015, 22:30
quelle

1 Antwort

10

Wenn Sie die MSDN-Dokumentation lesen, heißt es:

Medieneinfügung oder -entfernung erkennen

  

Windows sendet alle übergeordneten Fenster eine Reihe von Standardmeldungen WM_DEVICECHANGE, wenn neue Geräte oder Medien (z. B. eine CD oder DVD) hinzugefügt und verfügbar werden und wenn vorhandene Geräte oder Medien entfernt werden . Sie müssen sich nicht registrieren, um diese Standard -Nachrichten zu erhalten. Weitere Informationen darüber, welche Nachrichten standardmäßig gesendet werden, finden Sie im Abschnitt "Hinweise" in RegisterDeviceNotification. .

RegisterDeviceNotification-Funktion

  

Jede Anwendung mit einem Fenster der obersten Ebene kann grundlegende Benachrichtigungen empfangen, indem sie die WM_DEVICECHANGE-Nachricht verarbeitet. Anwendungen können die RegisterDeviceNotification-Funktion verwenden, um sich für den Empfang von Gerätebenachrichtigungen zu registrieren.
  ...
  Die Ereignisse DBT_DEVICEARRIVAL und DBT_DEVICEREMOVECOMPLETE werden automatisch an alle Fenster der obersten Ebene für Portgeräte gesendet . Daher ist es nicht erforderlich, RegisterDeviceNotification für ports aufzurufen, und die Funktion schlägt fehl, wenn das Member dbch_devicetype DBT_DEVTYP_PORT ist.

DEV_BROADCAST_HDR Struktur

  

DBT_DEVTYP_PORT
  0x00000003

     

Port-Gerät (seriell oder parallel) . Diese Struktur ist eine DEV_BROADCAST_PORT-Struktur.

Ein USB-Gerät ist kein serieller / paralleler Anschluss. Es ist stattdessen eine Geräteschnittstelle ( DBT_DEVTYP_DEVICEINTERFACE ). Und DBT_DEVICEARRIVAL / DBT_DEVICEREMOVECOMPLETE werden standardmäßig nicht für DBT_DEVTYP_DEVICEINTERFACE devices gesendet . Wenn Sie sie wollen, müssen Sie RegisterDeviceNotification() verwenden, um sie anzufordern.

Es sieht so aus, als ob Ihr Code auf diesem MSDN-Beispiel basiert:

Registrierung für Gerätebenachrichtigung

In diesem Code ist WceusbshGUID als {25dbce51-6c8f-4a72-8a6d-b54c2b4fc835} definiert, was als Klassenleitfaden für USB serial host PnP-Treiber kommentiert wird. Laut dieser MSDN-Seite:

Systemdefinierte Geräte-Setup-Klassen, die für Hersteller verfügbar sind

Diese GUID ist die Klassenanleitung für Windows CE USB ActiveSync-Geräte (die konsistenter mit dem im Code verwendeten Wceusb... -Präfix ist). Auf dieser Seite ist auch {88BAE032-5A81-49f0-BC3D-A4FF138216D6} für USB-Gerät ( alle USB-Geräte, die keiner anderen Klasse angehören ).

Der folgende CodeProject Artikel:

Hardwareeinfügung und / oder Entfernung erkennen

Erwähnungen {a5dcbf10-6530-11d2-901f-00c04fb951ed} für USB Raw Device . Die gleiche GUID ist auf MSDN als GUID_DEVINTERFACE_USB_DEVICE dokumentiert (deren Benennung) geht wahrscheinlich auf Pre-XP-Tage zurück, als die Benennung von Klassen-Guids und Interface-Guides war nicht gut getrennt ).

Wenn Sie also RegisterDeviceNotification() mit einer spezifischen Klassen-Guid aufrufen, stellen Sie sicher, dass es sich um die korrekte Klassen-Guid handelt, da Sie Geräteereignisse nur dafür erhalten spezifischer Gerätetyp. Wahrscheinlich verwendet Ihr USB-Gerät eine andere Klassen-Guid als die, die Sie registrieren, und deshalb erhalten Sie nicht die Geräteereignisse, die Sie erwarten.

Wenn Sie beliebiges USB-Gerät unabhängig von seiner Klassen-Guid erkennen möchten (und mehrere USB-Klassen-Guids definiert sind), können Sie das DEVICE_NOTIFY_ALL_INTERFACE_CLASSES Flag verwenden, wenn Sie RegisterDeviceNotification() aufrufen Klassen-GUID wird ignoriert. In den Nachrichten " DBT_DEVICEARRIVAL " und " DBT_DEVICEREMOVECOMPLETE " (vorausgesetzt, Sie können sie jetzt abrufen) wird Ihnen die gemeldete dbcc_classguid die tatsächliche Klassen-GUID mitteilen, und die gemeldete dbcc_name beginnt mit dem \?\USB: Präfix.

Eine letzte Sache - Sie erhalten nur DBT_DEVICE... -Nachrichten, wenn ein USB-Gerät eingelegt / entfernt wird, während Ihre App bereits läuft. Um festzustellen, ob ein USB-Gerät beim Starten der App bereits angeschlossen ist, müssen Sie SetupAPI Funktionen ( SetupDiGetClassDevs() , SetupDiEnumDeviceInterfaces() , SetupDiGetDeviceInterfaceDetail() usw.), um die verfügbaren Geräte aufzulisten.

    
Remy Lebeau 12.03.2015, 02:18
quelle

Tags und Links