RegisterDeviceNotification liefert nie Gerätetyp DBT_DEVTYP_VOLUME Benachrichtigungen
-
Hallo,
um unter Windows den Laufwerksbuchstaben eines neu eingesteckten USB-Sticks zu erhalten, möchte ich die WM_DEVICECHANGE Nachricht benutzen. Da meine Applikation kein Top-Level Fenster besitzt, verwende ich dazu RegisterDeviceNotification mit der GUID für Disk-Devices. Lasse ich die Applikation laufen, erhalte ich jedoch beim Einstecken eines USB-Sticks keine Broadcast-Medlung mit dem Gerätetyp DBT_DEVTYP_VOLUME sondern stets nur DBT_DEVTYP_DEVICEINTERFACE (0x5) Nachrichten.
Was mache ich falsch?Anbei Auszüge aus meiner WndProc.
Vielen Dank für eure Hilfe!
static DEV_BROADCAST_DEVICEINTERFACE NotificationFilter; static HDEVNOTIFY hDeviceNotify = NULL; static const GUID GuidDevInterfaceDisk = {0x53f56307, 0xb6bf, 0x11d0, { 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b }}; PDEV_BROADCAST_HDR pHdr; static char cDriveLetter;
in WM_CREATE:
ZeroMemory(&NotificationFilter, sizeof(NotificationFilter)); NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE); NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; hDeviceNotify = RegisterDeviceNotification(hwnd, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);
case WM_DEVICECHANGE: printf("WM_DEVICECHANGE\n"); pHdr = (PDEV_BROADCAST_HDR) lParam; if(wParam == DBT_DEVICEARRIVAL) { printf("devicetype: %x\n", (unsigned int)pHdr->dbch_devicetype); if(pHdr->dbch_devicetype == DBT_DEVTYP_VOLUME) { PDEV_BROADCAST_VOLUME pVol = (PDEV_BROADCAST_VOLUME) pHdr; DWORD unitmask; unitmask = pVol->dbcv_unitmask; for(cDriveLetter='A'; cDriveLetter<='Z'; cDriveLetter++) { if(unitmask & 0x1) break; unitmask = unitmask >> 1; } printf("drive: %c\n", cDriveLetter); // tue etwas... } } break;
-
rand_max schrieb:
in WM_CREATE:
ZeroMemory(&NotificationFilter, sizeof(NotificationFilter)); NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE); NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; hDeviceNotify = RegisterDeviceNotification(hwnd, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);
Du bekommst was Du verlangst.
Du willst DBT_DEVTYP_DEVICEINTERFACE und bekomst diese, wenn Du Volume Nachrichten willst musst Du auch DBT_DEVTYP_VOLUME registrieren-
-
Laut MSDN Darf man nur DBT_DEVTYP_DEVICEINTERFACE oder DBT_DEVTYP_HANDLE registrieren. Wenn man damit tatsächlich nur DBT_DEVTYP_DEVICEINTERFACE Nachrichten erhalten würde wozu dann überhaupt die anderen?
-
rand_max schrieb:
wozu dann überhaupt die anderen?
Die Applikationen, die einen Top-Level Fenster besitzen, bekommen auch alle anderen Notifikationen frei Haus geliefert.
Das kannst auch Du für Deine Applikation erreichen, indem Du einfach ein unsichtbares Top-Level Fenster erzeugst.
Und bekommst in Deiner Nachrichtenschleife alle Device-Nachrichten eingetrudelt, ohne daß Du vorher irgendwas per RegisterDeviceNotification() registrieren mußt!Just my 5 cents,
Martin
-
Ach so ist das. Vielen Dank euch beiden für die Klarstellung!
Wie realisiert man am besten ein unsichtbares Hauptfenster?
-
Ich hatte ein "message-only window" verwendet. Nachdem ich nun HWND_MESSAGE als Elter des Fenster entfernt habe, klappt alles wie erwartet. Vielen Dank noch einmal!
-
rand_max schrieb:
Ach so ist das. Vielen Dank euch beiden für die Klarstellung!
Wie realisiert man am besten ein unsichtbares Hauptfenster?Man erzeugt das Fenster einfach ohne den Stil WS_VISIBLE.
In jedem Fall benötigt man eine Message-Loop in dem Thread der das Fenster erzeugt hat.