Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi DeviceChange mit SD-Card (https://www.delphipraxis.net/100944-devicechange-mit-sd-card.html)

gabneo 5. Okt 2007 19:07


DeviceChange mit SD-Card
 
Hallo DP-Community,
ich wende mich an euch mit nem fetten Problem.
Leider konnten mir einschlägige Themen nicht weiterhelfen.

Die Windows Message "WM_DEVICECHANGE" wird an alle Programme gesendet, wenn sich ein Device-Change ereignet. Jetzt ist ein SD-Reader das Device. Das heißt die SD-Card ist das Medium.
Das Problem das ich habe ist, wenn ich nun das Medium Tausche (andere sd-card einlege), soll die gleiche Prozedur durchgeführt werden wie bei einem Devicechange. Welche Windowsmessage wird nun gesendet wenn man eine SD-Card einlegt?

Hier mein Code für das Devicechange:
Delphi-Quellcode:
public
    procedure WMDeviceChange(var Msg: TMessage); message WM_DEVICECHANGE;

procedure TForm1.WMDeviceChange(var Msg: TMessage);
const DBT_DEVICEARRIVAL = $8000; DBT_DEVICEREMOVECOMPLETE = $8004;
begin
 if checkbox1.checked then
  begin
   button1.Click;
  end;
end;
greez....und vielen Dank
gabneo

BUG 5. Okt 2007 19:42

Re: DeviceChange mit SD-Card
 
Hi gabneo,

soweit ich weiß wird in einem Parameter der Message angezeigt, ob das Medium eingelegt oder entfernt wurde (interessanter Artikel).

Eine SD-Karte austauschen bedeutet ja:
- alte Karte entfernen
- neue Karte einlegen

dabei wird dann mindestens 2 mal WM_DEVICECHANGE gesendet...

MfG,
Bug

PS:
Zitat:

Zitat von Artikel
Beispielprogramm von Robert Marquardt.

Der ist imho doch auch hier in DP.

gabneo 5. Okt 2007 23:29

Re: DeviceChange mit SD-Card
 
Hi,
genau diesen Artikel habe ich auch verschlungen, doch wird leider die WM_DeviceChange nicht einmal aufgerufen. Da ich die Prozedur Parameter-unabhängig Programmiert habe müsste folglich bei jedem WM_DeviceChange der Button1.click ausgeführt werden. Aus der Realität sehe ich aber, das WM_DeviceChange nie (!) ausgeführt wird wenn ein SD-Card-Medium oder auch eine Diskette eingelegt werden sich also nicht der Device ändert sondern der Devicetype!
D.h. Windows sendet dazu eine andere Message und nicht nur verschiedene Parameter, wieso auch immer... müsste also eine WM_DeviceTypeChange oder so sein?!

greez
gabneo

PS: vielen Dank...für jede Hilfestellung.


[Edit]
Ich lese gerade das die Speichermedien für Card-Reader und USB-HID Geräte als wParam=$0007 zu erkennen sein sollen, doch ich kann zumindest von den Speichermedien sagen, das keine WM auch nicht mit wParam=$0007 abgesetzt wird. Desweiteren soll dieser Parameter beim Hinzufügen und beim entfernen der Hardware gesetzt werden woraus resultiert, das man nicht wie bei WM_DeviceArrival und WM_DeviceRemoveComplete konkret (ohne Umwege) unterscheiden kann was gerade passiert ist.
Da muss es doch was viel einfacheres geben...WinAPI hat garantiert dafür eine eigene Message (änderungen bei CD/DVD Medien werden übrigens unlogischerweise bei WM_DeviceChange mit abgehandelt...aber das nur nebenbei.)
[/Edit]

Mackhack 5. Okt 2007 23:48

Re: DeviceChange mit SD-Card
 
Vielleicht hilft dir dieser Beitrag von Olli noch weiter!

gabneo 6. Okt 2007 01:16

Re: DeviceChange mit SD-Card
 
danke Mackhack, doch leider verläuft sich der Thread im Sande gerade dann wenn es Interessant wird. Deswegen habe ich mal einen neuen Thread aufgemacht um der WM auf die schliche zu kommen^^

greez

gabneo 9. Okt 2007 13:00

Re: DeviceChange mit SD-Card
 
- push -

:pale:

RWarnecke 9. Okt 2007 13:37

Re: DeviceChange mit SD-Card
 
Also, soweit ich das aus den Beiträge verstehe, wird nur dann eine Message abgesetzt bei Cardreader, wenn auch etwas beim USB-Port ein Singnal ankommt. Dazu gibt es nun unterschiedliche CardReader, wo ich die Karten so reinstecken und auch wieder rausziehen kann, ohne das ein neues Laufwerk erstellt wird. Deshalb bin ich der Meinung, dass es schwierig wird, das wechseln einer Karte in so einem Cardreader festzustellen. Bei Cardreadern, die wie ein USB-Stick funktionieren, hast Du ja schon eine fertige Lösung in diesem Beitrag.

Hast Du denn das Beispielprogramm von Olli schonmal ausprobiert ?

gabneo 9. Okt 2007 18:17

Re: DeviceChange mit SD-Card
 
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 :gruebel:
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]

hathor 9. Okt 2007 23:24

Re: DeviceChange mit SD-Card
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hier ist ein interessanter Artikel:

whiteF 19. Aug 2012 21:03

AW: DeviceChange mit SD-Card
 
ich push den Thread auch nochmal, da ich momentan auch vor diesem Problem stehe und anderweitig nichts gefunden habe.

Weiß mittlerweile jmd mehr?

mfg


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:29 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz