Ich hab damit auch mal rumgespielt.
Ich poste mal den Testcode, ist aber wirklich nur ein Testcode zum Weiterentwickeln / ordnen / abstrahieren / schöner machen:
1) Neues Projekt anlegen, ein Memo auf die Form klatschen und dann
unit folgendermaßen anpassen:
Delphi-Quellcode:
unit devicechange_test;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 =
class(TForm)
Memo1: TMemo;
private
function GetVolumeName(FDrive: Char):
string;
procedure WMDeviceChange(
var Msg: TMessage);
message WM_DEVICECHANGE;
public
{ Public-Deklarationen }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
// Volume-Name herausfinden
function TForm1.GetVolumeName(FDrive: Char):
string;
var
max, Flags: DWORD;
Buf:
array [0..MAX_PATH]
of Char;
begin
try
GetVolumeInformation(PChar(
string(FDrive + '
:')), Buf, sizeof(Buf),
nil, max, Flags,
nil, 0);
Result := StrPas(buf);
except
result := '
';
end;
end;
// Event beim mounten oder entfernen eines Laufwerks oder Medium
procedure TForm1.WMDeviceChange(
var Msg: TMessage);
type
PDevBroadcastHdr = ^TDevBroadcastHdr;
TDevBroadcastHdr =
packed record
dbcd_size, dbcd_devicetype, dbcd_reserved: DWORD;
end;
PDevBroadcastVolume = ^TDevBroadcastVolume;
TDevBroadcastVolume =
packed record
dbcv_size, dbcv_devicetype, dbcv_reserved, dbcv_unitmask: DWORD;
dbcv_flags: Word;
end;
function GetDrive(pDBVol: PDevBroadcastVolume):
string;
var i: Byte; Maske: DWORD;
begin
case (pDBVol^.dbcv_flags)
of
// es ist ein entfernbares MEDIUM (CD /DVD)
0:
begin
end;
// es ist ein entfernbares LAUFWERK (Platte)
1:
begin
end;
end;
Maske := pDBVol^.dbcv_unitmask;
for i := 0
to 25
do
begin
if (Maske
and 1) = 1
then Result := Char(i + Ord('
A')) + '
: ';
Maske := Maske
shr 1;
end;
end;
var Drive,DriveName:
String;
begin
case Msg.wParam
of
// laufwerk eingelegt
$8000:
if PDevBroadcastHdr(Msg.lParam)^.dbcd_devicetype = $0002
then
begin
Drive := GetDrive(PDevBroadcastVolume(Msg.lParam));
DriveName := GetVolumeName(Drive[1]) ;
memo1.lines.add('
Datenträger in Laufwerk '+Drive+'
eingelegt ("'+DriveName+'
")');
end;
// laufwerk entfernt
$8004:
if PDevBroadcastHdr(Msg.lParam)^.dbcd_devicetype = $0002
then
begin
Drive := GetDrive(PDevBroadcastVolume(Msg.lParam));
// DriveName ist hier nach dem entfernen nicht mehr verfügbar, also am besten vorher beim einlegen speichern :)
memo1.lines.add('
Datenträger aus Laufwerk '+Drive+'
entfernt.');
end;
end;
end;
end.
dann das Programm mal laufen lassen und einen usb stick einstecken und / oder entfernen.
Zu beachten ist dabei, wie auch schon im Code kommentiert ist, dass ein Laufwerks-Name dann nicht mehr ausgelesen werden kann, wenn der Event "Laufwerk wurde entfernt" zuschlägt, da das Laufwerk ja zu diesem Zeitpunkt schon nicht mehr verfügbar ist.
Also sollte man beim Programmstart die derzeit verfügbaren Laufwerke durchgehen und die Namen den Driveletters zuordnen und speichern, damit man nach dem Entfernen auch den zugehörigen Namen des entfernten Laufwerks hat.
Bei einem "Laufwerk wurde gemountet"-Event ist diese Liste / das Mapping natürlich zu erweitern.
Mit dem Code kannst du das gewünschte grundlegend schon erreichen, du musst ihn halt noch an deine Bedürfnisse anpassen.