Drag & Drop mit Dateien
Eine Datei von Windows auf eine Komponente ziehen, dieses Anliegen wird von den Delphi-Komponenten nicht direkt unterstützt. In 3 Schritten ist es möglich, diesen Mechanismus nachzubilden:
1. Komponente für Drag & Drop anmelden (DragAcceptFiles)
2. Eine Prozedur für die Windowsbotschaft WM_DROPFILES schreiben
3. Mit der Prozedur DragQueryFile alle Drag-Dateien erfragen
Beispiel: TListView (Delphi 4)
unit DspListView;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls,
Forms, Dialogs, ComCtrls, ShellApi;
type
TDragFileEvent = procedure(Sender: TObject; const aDragFile: string) of object;
TDspListView = class(TListView)
private
FAcceptFiles: boolean;
FOnDragFile: TDragFileEvent;
procedure SetAcceptFiles(const Value: boolean);
procedure WMDropFiles(var Msg: TWMDropFiles); message WM_DROPFILES;
protected
procedure CreateHandle; override;
procedure DestroyWindowHandle; override;
procedure DragFile(aDragFile: string); virtual;
public
published
property AcceptFiles: boolean read FAcceptFiles write SetAcceptFiles default false;
property OnDragFile: TDragFileEvent read FOnDragFile write FOnDragFile;
end;
implementation
{ TDspListView }
procedure TDspListView.CreateHandle;
begin
inherited CreateHandle;
if AcceptFiles then
DragAcceptFiles(Handle, true);
end;
procedure TDspListView.DestroyWindowHandle;
begin
if AcceptFiles then
DragAcceptFiles(Handle, False);
inherited Destroyhandle;
end;
procedure TDspListView.DragFile(aDragFile: string);
begin
if assigned(FOnDragFile) then
OnDragFile(self, aDragFile);
end;
procedure TDspListView.SetAcceptFiles(const Value: boolean);
begin
if AcceptFiles <> Value then begin
FAcceptFiles := Value;
// Falls schon aktiv, DragAcceptFiles aufrufen
if not (csDesigning in ComponentState) and HandleAllocated then
DragAcceptFiles(Handle, Value);
end;
end;
procedure TDspListView.WMDropFiles(var Msg: TWMDropFiles);
var
c : array[0..255] of char;
Anz, z : cardinal;
begin
Msg.Result := 0;
try
// Anzahl der Dragdateien erfragen
Anz := DragQueryFile(Msg.Drop, $FFFFFFFF, nil, 0);
for z := 1 to Anz do begin
// Dateinamen holen
DragQueryFile(Msg.Drop, z - 1, @c, SizeOf(c) - 1);
// und verarbeiten
DragFile(StrPas(c));
end;
finally
// Speicher freigeben
DragFinish(Msg.Drop);
end;
end;
end.
|