Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2004.07.18;
Скачать: [xml.tar.bz2];

Вниз

Вопрос по WM_DEVICECHANGE   Найти похожие ветки 

 
Ruslan   (2004-06-04 16:39) [0]

Для определения изменения состава оборудования использую

procedure TForm1.WMDeviceChange(var Message: TMessage);

 var

   s : string;

 begin

 {Do Something here}

   case Message.wParam of

     DBT_DEVICEARRIVAL :

       s := "A device has been inserted and is now available";

     DBT_DEVICEQUERYREMOVE: begin

       s := "Permission to remove a device is requested";

       ShowMessage(s);

      {True grants premission}

       Message.Result := integer(true);

       exit;

     end;

     DBT_DEVICEQUERYREMOVEFAILED :

       s := "Request to remove a device has been canceled";

     DBT_DEVICEREMOVEPENDING :

       s := "Device is about to be removed";

     DBT_DEVICEREMOVECOMPLETE :

       s := "Device has been removed";

     DBT_DEVICETYPESPECIFIC :

       s := "Device-specific event";

     DBT_CONFIGCHANGED :

       s:= "Current configuration has changed"

     else s := "Unknown Device Message";

   end;

   ShowMessage(s);

   inherited;

 end;

Подключаю USB устройство и получаю  WParam = 7, причем сообщение приходит дважды! Не могу понять почему. Может надо как то ответить на него?
проверяю с компакт диском при установке  WParam = 8000, при выгрузке 8004. Сообщения приходят по одному разу.


 
Игорь Шевченко ©   (2004-06-04 17:12) [1]


> Подключаю USB устройство и получаю  WParam = 7


Один раз на устройство, один раз на диск ?


 
han_malign ©   (2004-06-04 17:28) [2]

The system broadcasts the DBT_DEVNODES_CHANGED device event when a device has been added to or removed from the system. Applications that maintain lists of devices in the system should refresh their lists.

To broadcast this device event, the system uses the WM_DEVICECHANGE message with wParam set to DBT_DEVNODES_CHANGED and lParam set to zero.

Насколько я понимаю, одно сообщение для собого устройства, второе для группы устройств.
DevNodes:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\Vid_XXXX&Pid_XXXX\
в последнем лежат дескрипторы конкретных устройств (64-bit, 16-тиричная строка), как раз в нем можно посмотреть ClassGUID устройства.
Обрати внимание на подчеркнутое выше - при получении этих сообщений нужно проверить список интересующих тебя устройств с помощь функций SetupAPI(SetupDiXXX), примерно так:
unit uWinPnP;

interface

{$IFDEF VER150}
{$WARN UNSAFE_TYPE OFF}
{$WARN UNSAFE_CAST OFF}
{$WARN UNSAFE_CODE OFF}
{$ENDIF}

uses Windows;

function GetPnpDeviceName(AGuid : TGUID; ADeviceId : Integer) : String;
function GetPnpDeviceList(AHeader : String; AGuid : TGuid) : String;

implementation

uses Utils;

const
  DIGCF_DEFAULT  = LongWord($00000001);
  DIGCF_PRESENT                = LongWord($00000002);
  DIGCF_ALLCLASSES             = LongWord($00000004);
  DIGCF_PROFILE                = LongWord($00000008);
  DIGCF_DEVICEINTERFACE        = LongWord($00000010);

type
  HDEVINFO = Pointer;

  SP_DEVICE_INTERFACE_DETAIL_DATA_A = packed record
     cbSize  : LongWord;
     DevicePath        : array [0..0] of char;
  end;
  PSP_DEVICE_INTERFACE_DETAIL_DATA_A = ^SP_DEVICE_INTERFACE_DETAIL_DATA_A;

  SP_DEVINFO_DATA = packed record
     cbSize  : LongWord;
     ClassGuid         : TGUID;
     DevInst           : LongWord;
     Reserved          : LongWord;
  end;
  PSP_DEVINFO_DATA = ^SP_DEVINFO_DATA;

  SP_DEVICE_INTERFACE_DATA = packed record
     cbSize   : LongWord;
     InterfaceClassGuid        : TGUID;
     Flags                     : LongWord;
     Reserved                  : LongWord;
  end;
  PSP_DEVICE_INTERFACE_DATA = ^SP_DEVICE_INTERFACE_DATA;

type
  Tf_SetupDiGetClassDevsA  = function(ClassGuid : PGUID; Enumerator : PCHAR; hwndParent : HWND; Flags : LongWord): HDEVINFO; stdcall;
  Tf_SetupDiDestroyDeviceInfoList = function(DeviceInfoSet : HDEVINFO): boolean; stdcall;
  Tf_SetupDiEnumDeviceInterfaces = function(DeviceInfoSet : HDEVINFO; DeviceInfoData : PSP_DEVINFO_DATA; InterfaceClassGuid : PGUID; MemberIndex : LongWord; DeviceInterfaceData : PSP_DEVICE_INTERFACE_DATA) : boolean; stdcall;
  Tf_SetupDiGetDeviceInterfaceDetailA = function(DeviceInfoSet : HDEVINFO; DeviceInterfaceData : PSP_DEVICE_INTERFACE_DATA; DeviceInterfaceDetailData : PSP_DEVICE_INTERFACE_DETAIL_DATA_A; DeviceInterfaceDetailDataSize : LongWord; var RequiredSize : LongWord; DeviceInfoData : PSP_DEVINFO_DATA) : boolean; stdcall;
  Tf_SetupDiGetClassDescriptionA = function(ClassGuid : PGUID; ClassDescription : PChar; ClassDescriptionSize : LongWord; var RequiredSize : LongWord) : Boolean; stdcall;

function GetPnpDeviceName(AGuid : TGUID; ADeviceId : Integer) : String;
var
  i, cnt   : integer;
  len, need    : LongWord;
  HwDevInfo    : HDEVINFO;
  DevInfoData    : SP_DEVICE_INTERFACE_DATA;
  functionClassDeviceData  : PSP_DEVICE_INTERFACE_DETAIL_DATA_A;
  S    : String;

  hLib    : THandle;
  pf_SetupDiGetClassDevsA  : Tf_SetupDiGetClassDevsA;
  pf_SetupDiDestroyDeviceInfoList : Tf_SetupDiDestroyDeviceInfoList;
  pf_SetupDiEnumDeviceInterfaces : Tf_SetupDiEnumDeviceInterfaces;
  pf_SetupDiGetDeviceInterfaceDetailA : Tf_SetupDiGetDeviceInterfaceDetailA;
  pf_SetupDiGetClassDescriptionA : Tf_SetupDiGetClassDescriptionA;

begin
  result := "";

  hLib := LoadLibrary("setupapi.dll");
  if hLib <> 0 then begin

     @pf_SetupDiGetClassDescriptionA := GetProcAddress(hLib, "SetupDiGetClassDescriptionA");
     if @pf_SetupDiGetClassDescriptionA <> nil then begin
        need := 0;
        if not pf_SetupDiGetClassDescriptionA(@AGuid, nil, 0, need)
        then S := WinErrMsg(GetLastError);
        if need > 0 then begin
           SetLength(S, need);
           if not pf_SetupDiGetClassDescriptionA(@AGuid, @S[1], Length(S), need)
           then S := "";
        end;
     end else S := "SetupDiGetClassDescriptionA not found";

     @pf_SetupDiGetClassDevsA   := GetProcAddress(hLib, "SetupDiGetClassDevsA");
     @pf_SetupDiEnumDeviceInterfaces  := GetProcAddress(hLib, "SetupDiEnumDeviceInterfaces");
     @pf_SetupDiGetDeviceInterfaceDetailA := GetProcAddress(hLib, "SetupDiGetDeviceInterfaceDetailA");
     @pf_SetupDiDestroyDeviceInfoList  := GetProcAddress(hLib, "SetupDiDestroyDeviceInfoList");

     if (@pf_SetupDiGetClassDevsA <> nil) and (@pf_SetupDiEnumDeviceInterfaces <> nil) and
        (@pf_SetupDiGetDeviceInterfaceDetailA <> nil) and (@pf_SetupDiDestroyDeviceInfoList <> nil)
     then begin
        HwDevInfo := pf_SetupDiGetClassDevsA(@AGuid, nil, 0, DIGCF_PRESENT or DIGCF_DEVICEINTERFACE);

        DevInfoData.cbSize := sizeof(SP_DEVICE_INTERFACE_DATA);
        i := 0; cnt := 0;
        while cnt <= ADeviceId do begin
           if pf_SetupDiEnumDeviceInterfaces(HwDevInfo, nil, @AGuid, i, @DevInfoData) then begin
              need := 0;
              pf_SetupDiGetDeviceInterfaceDetailA(HwDevInfo, @DevInfoData, nil, 0, need, nil);
              len := need;
              GetMem(functionClassDeviceData, len);
              functionClassDeviceData.cbSize := sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);

              if pf_SetupDiGetDeviceInterfaceDetailA(HwDevInfo, @DevInfoData, functionClassDeviceData, len, need, nil) then begin
                 S := PChar(@functionClassDeviceData^.DevicePath[0]);
                 S := Trim(S);

                 if S <> "\" then begin
                    if cnt = ADeviceId then begin result := S; FreeMem(functionClassDeviceData, len); Break; end
                    else Inc(cnt);
                 end;
              end;
              FreeMem(functionClassDeviceData, len);
           end else if GetLastError = ERROR_NO_MORE_ITEMS then Break;
           inc(i);
        end;

        pf_SetupDiDestroyDeviceInfoList(HwDevInfo);
     end;

     FreeLibrary(hLib);
  end;
end;


 
han_malign ©   (2004-06-04 17:29) [3]

продолжение
function GetPnpDeviceList(AHeader : String; AGuid : TGuid) : String;
var
  i       : integer;
  len, need    : LongWord;
  HwDevInfo    : HDEVINFO;
  DevInfoData    : SP_DEVICE_INTERFACE_DATA;
  functionClassDeviceData  : PSP_DEVICE_INTERFACE_DETAIL_DATA_A;
  S, GuidStr   : String;

  hLib    : THandle;
  pf_SetupDiGetClassDevsA  : Tf_SetupDiGetClassDevsA;
  pf_SetupDiDestroyDeviceInfoList : Tf_SetupDiDestroyDeviceInfoList;
  pf_SetupDiEnumDeviceInterfaces : Tf_SetupDiEnumDeviceInterfaces;
  pf_SetupDiGetDeviceInterfaceDetailA : Tf_SetupDiGetDeviceInterfaceDetailA;
  pf_SetupDiGetClassDescriptionA : Tf_SetupDiGetClassDescriptionA;

begin
  result := "";

  AHeader := UpperCase(AHeader);

  hLib := LoadLibrary("setupapi.dll");
  if hLib <> 0 then begin

     @pf_SetupDiGetClassDescriptionA := GetProcAddress(hLib, "SetupDiGetClassDescriptionA");
     if @pf_SetupDiGetClassDescriptionA <> nil then begin
        need := 0;
        if not pf_SetupDiGetClassDescriptionA(@AGuid, nil, 0, need)
        then S := WinErrMsg(GetLastError);
        if need > 0 then begin
           SetLength(S, need);
           if not pf_SetupDiGetClassDescriptionA(@AGuid, @S[1], Length(S), need)
           then S := "";
        end;
     end else S := "SetupDiGetClassDescriptionA not found";

     @pf_SetupDiGetClassDevsA   := GetProcAddress(hLib, "SetupDiGetClassDevsA");
     @pf_SetupDiEnumDeviceInterfaces  := GetProcAddress(hLib, "SetupDiEnumDeviceInterfaces");
     @pf_SetupDiGetDeviceInterfaceDetailA := GetProcAddress(hLib, "SetupDiGetDeviceInterfaceDetailA");
     @pf_SetupDiDestroyDeviceInfoList  := GetProcAddress(hLib, "SetupDiDestroyDeviceInfoList");

     if (@pf_SetupDiGetClassDevsA <> nil) and (@pf_SetupDiEnumDeviceInterfaces <> nil) and
        (@pf_SetupDiGetDeviceInterfaceDetailA <> nil) and (@pf_SetupDiDestroyDeviceInfoList <> nil)
     then begin
        HwDevInfo := pf_SetupDiGetClassDevsA(@AGuid, nil, 0, DIGCF_PRESENT or DIGCF_DEVICEINTERFACE);

        DevInfoData.cbSize := sizeof(SP_DEVICE_INTERFACE_DATA);
        i := 0;
        GuidStr := GuidToStr(AGuid);
        while True do begin
           if pf_SetupDiEnumDeviceInterfaces(HwDevInfo, nil, @AGuid, i, @DevInfoData) then begin
              need := 0;
              pf_SetupDiGetDeviceInterfaceDetailA(HwDevInfo, @DevInfoData, nil, 0, need, nil);
              len := need;
              GetMem(functionClassDeviceData, len);
              functionClassDeviceData.cbSize := sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);

              if pf_SetupDiGetDeviceInterfaceDetailA(HwDevInfo, @DevInfoData, functionClassDeviceData, len, need, nil) then begin
                 S := PChar(@functionClassDeviceData^.DevicePath[0]);
                 S := Trim(S);

                 if (S <> "\") and
                    (Pos(AHeader, UpperCase(S)) = 1) and
                    (Pos(GuidStr, UpperCase(S)) = Length(S)-Length(GuidStr)+1)
                 then begin
                    if result <> "" then result := result + ",";
                    result := result + """ + Copy(S, Length(AHeader)+1, Length(S)-Length(AHeader)-Length(GuidStr)-1) + """;
                 end;
              end;
              FreeMem(functionClassDeviceData, len);
           end else if GetLastError = ERROR_NO_MORE_ITEMS then Break;
           inc(i);
        end;

        pf_SetupDiDestroyDeviceInfoList(HwDevInfo);
     end;

     FreeLibrary(hLib);
  end;
end;

end.



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2004.07.18;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.036 c
3-1087845103
zokzok
2004-06-21 23:11
2004.07.18
изменение таблицы через Query


1-1088752340
Mc'SIMM
2004-07-02 11:12
2004.07.18
Моргание в панели задач


1-1088765919
Popovich A.
2004-07-02 14:58
2004.07.18
Вопросик по TImage


14-1088560114
Думкин
2004-06-30 05:48
2004.07.18
С днем рождения! 30 июня


1-1088459789
Sonnik
2004-06-29 01:56
2004.07.18
Несколько модулей





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский