Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Отслеживание подключения USB устройств на WinApi


Автор: maloicds 28.1.2011, 22:45
Доброго времени суток. Пишу программу для отслеживания подключения USB устройств на WinApi. Вот код:
Код

program usb;

uses
  windows, messages,
  dialogs, sysutils;  // для тестов

var WClass:TWndClass;
     hWnd:THandle;
     mMsg:TMsg;

function WndProc(hWn:Thandle;mMsg,wParam,lParam:integer):integer; stdcall; 
begin 
   Case mMsg of
     WM_DESTROY:halt(0);
     WM_DEVICECHANGE: ShowMessage(inttostr(wparam)+' '+inttostr(lparam));
   end;
 result:=DefWindowProc(hWn,mMsg,wParam,lParam);
end;

begin
 with WClass do
  begin 
   lpfnWndProc:=@WndProc;
   lpszClassName:='My';
  end;
  RegisterClass(WClass);
  hWnd:=CreateWindow('My','',WS_OVERLAPPEDWINDOW,0,0,0,0,0,0,hInstance,nil);
 while GetMessage(mMsg, hWnd , 0, 0) do
  begin 
   TranslateMessage(mMsg);
   DispatchMessage(mMsg);
  end; 
 
end.


Проблема в том, что сообщение WM_DEVICECHANGE отлавливает все события от устройств (значения wParam и lParam всегда одинаковы) , а мне надо только от флешек.
На форуме много примеров с компонентами и с формами, но вот заставить это работать на WinApi не получается!

Автор: alexnef 14.2.2011, 20:31
Код

type
  pdev_broadcast_hdr = {^DEV_BROADCAST_DEVICEINTERFACE;
  DEV_BROADCAST_DEVICEINTERFACE =} record
     dbch_size: dword;
     dbch_devicetype: dword;
     dbch_reserved: dword;
     handle: thandle;
     hnotif: pointer;
     guid: tguid;
     name: ulong;
     data: byte;     
  end;

var
pt:dword;
i,sz: integer;
mask: dword;
ch: char;
begin
  //
if (Msg.wParam = DBT_DEVICEARRIVAL) then //
   begin
      if msg.LParam<>0 then
      if integer(pointer(msg.LParam+4)^)=DBT_DEVTYP_VOLUME then
      begin           // съемный диск или флешка
         i:=1 ;
         mask:=cardinal(pointer(msg.LParam+12)^);
         for ch:='A' to 'Z' do
         begin
           if mask and i<>0 then
           begin
              //
              sz:=sizeof(pdev_broadcast_hdr{DEV_BROADCAST_DEVICEINTERFACE});
              zeromemory(@pdev_hdr,sz);
              pdev_hdr.dbch_size:=sz;        //     DBT_DEVTYP_VOLUME
              pdev_hdr.dbch_devicetype:=DBT_DEVTYP_HANDLE;
              pdev_hdr.dbch_reserved:=0;
              pdev_hdr.handle:=createfile(pchar(ch+':\'),
                               GENERIC_READ,
                               FILE_SHARE_READ or FILE_SHARE_WRITE,
                               nil,
                               OPEN_EXISTING,
                               FILE_FLAG_BACKUP_SEMANTICS,
                               0);
              if pdev_hdr.handle<>$ffffffff then
              hdevnot[ch]:=registerdevicenotification(mainform.Handle,@pdev_hdr,0);{ сообщаем системе , что мы хотим принимать все    сообщения связаные с этим устройством}
              if hdevnot[ch]=nil then
                 begin
                 messagebox(application.handle,
                      pchar('Can not watch for device '+ch+':\ notifications'),
                      pchar('Error!'),mb_iconexclamation);
                 end;
              closehandle(pdev_hdr.handle);
              break;
           end;
         i:=I*2;
         end;
      end;
   end;


собственно тебе нужно только

Код

if (Msg.wParam = DBT_DEVICEARRIVAL) then //
   begin
      if msg.LParam<>0 then
      if integer(pointer(msg.LParam+4)^)=DBT_DEVTYP_VOLUME then
      begin           // съемный диск или флешка
      
      End;


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)