Thema: Delphi DeviceChange mit SD-Card

Einzelnen Beitrag anzeigen

gabneo

Registriert seit: 15. Okt 2006
Ort: Deutsche Toskana :)
93 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#8

Re: DeviceChange mit SD-Card

  Alt 9. Okt 2007, 19:17
Ja den Code von Olli habe ich schon ausprobiert. Dieser bemerkt einen DeviceChange zuverlässig. Doch für einen "DeviceMediumStateChange" (whatever, Wortschöpfung die gerade am besten passt) einer SD-Card langts nicht.

Ich habe es auch schon folgendermassen probiert, habe mir mit TApplicationEvents alle Messages die von windows an meine Application gesandt werden aufgefangen. Dabei habe ich bemerkt, das Windows mir gar keine Message zusendet. Nun zum Hintergrund, windows geht nicht davon aus, das mein Programm "Interesse" an solch einer Nachricht hat, was muss ich demnach tun? mich bei Windows Anmelden um diese Message zu empfangen.
Nach einer Vorlage für USB-Devices, die bei Windows Registriert, dass meine Applikation nähere Informationen zum Status eines Devices bei "DeviceMediumStateChange" (vorsicht wortschöpfung^^) benötigt, als beim reinen DeviceChange (wparam=$0007). Nun hoffte ich, dass da ich überhaupt keinen DeviceChange bekomme, ich über RegisterDeviceNotification mich bei Windows für die Messages eines bestimmten GUID_devicetype registrieren könnte, doch fehlanzeige...ich poste folgenden Code zum nachvollziehen was ich gemacht habe:

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type

  PDevBroadcastHdr = ^DEV_BROADCAST_HDR;
  DEV_BROADCAST_HDR = packed record
    dbch_size: DWORD;
    dbch_devicetype: DWORD;
    dbch_reserved: DWORD;
  end;

  PDevBroadcastDeviceInterface = ^DEV_BROADCAST_DEVICEINTERFACE;
  DEV_BROADCAST_DEVICEINTERFACE = record
    dbcc_size: DWORD;
    dbcc_devicetype: DWORD;
    dbcc_reserved: DWORD;
    dbcc_classguid: TGUID;
    dbcc_name: short;
  end;

const
   GUID_DEVCLASS_SMARTCARDREADER: TGUID = '{50dd5230-ba8a-11d1-bf5d-0000f805f530}';
   //GUID_DEVINTERFACE_USB_DEVICE: TGUID = '{A5DCBF10-6530-11D2-901F-00C04FB951ED}';
   DBT_DEVICEARRIVAL = $8000; // system detected a new device
   DBT_DEVICEREMOVECOMPLETE = $8004; // device is gone
   DBT_DEVTYP_DEVICEINTERFACE = $00000005; // device interface class


type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Memo2: TMemo;
    procedure ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean);
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    procedure WMDeviceChange(var Msg: TMessage); message WM_DeviceChange;
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function deviceregister: Boolean;
var dbi: DEV_BROADCAST_DEVICEINTERFACE; Size: Integer; r: Pointer;
begin
  Result := False;
  Size := SizeOf(DEV_BROADCAST_DEVICEINTERFACE);
  ZeroMemory(@dbi, Size);
  dbi.dbcc_size := Size;
  dbi.dbcc_devicetype := DBT_DEVTYP_DEVICEINTERFACE;
  dbi.dbcc_reserved := 0;
  dbi.dbcc_classguid := GUID_DEVCLASS_SMARTCARDREADER;//GUID_DEVINTERFACE_USB_DEVICE;
  dbi.dbcc_name := 0;

  r := RegisterDeviceNotification(Form1.Handle, @dbi, DEVICE_NOTIFY_WINDOW_HANDLE );
  if Assigned(r) then Result := True;
end;

procedure TForm1.WMDeviceChange(var Msg: TMessage);
var devType: Integer; Datos: PDevBroadcastHdr;
begin
 //if (Msg.wParam = DBT_DEVICEARRIVAL) or (Msg.wParam = DBT_DEVICEREMOVECOMPLETE) then
 // begin
   Datos := PDevBroadcastHdr(Msg.lParam);
   devType := Datos^.dbch_devicetype;
   if devType = DBT_DEVTYP_DEVICEINTERFACE then
    begin
     if Msg.wParam = DBT_DEVICEARRIVAL then
      begin
       showmessage('income');
      end
     else
      begin
       showmessage('outgoing');
      end;
    end;
 // end;
end

procedure TForm1.FormCreate(Sender: TObject);
begin
 deviceregister;
end;

end.
Also, entweder habe ich hier einen fetten Logikfehler drinnen...oder ich bin mit meinem latein am ende
Und ja es geht nur um die Art von Cardreadern die nicht selbstständig ein Device anmelden wenn man eine SD-Card oder CF MMC etc. reinsteckt, sondern die 99% aller Cardreader die per USB eingebunden sind und die Laufwerke/Devices automatisch von Windows schon registriert werden.

[Edit]
Irgendeine Message wird garantiert gesendet, da auch der Autostart ausgeführt wird wenn man eine SD-Card (oder CF MMC....) in das entsprechende Laufwerk steckt.
Vielleicht wäre ja ein "Messageauffangtool" das sich bei Windows für "alle" Messages registriert eine Möglichkeit auf die hierfür zuständige Message zu schließen...falls es sowas überhaupt gibt/jemand sowas schon mal gemacht hat.
[/Edit]
  Mit Zitat antworten Zitat