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;
    

  • Mod

    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!


  • Mod

    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.


Anmelden zum Antworten