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]