Unit UFileCatcher.pas
64 Bit Für höhere Compiler Versionen mit Bilder laden :
unit UFileCatcher;
interface
uses
Windows, ShellAPI;
type
TFileCatcher = class(TObject)
private
fDropHandle: HDROP;
function GetFile(Idx: Integer): string;
function GetFileCount: Integer;
function GetPoint: TPoint;
public
constructor Create(DropHandle: HDROP);
destructor Destroy; override;
property FileCount: Integer read GetFileCount;
property Files[Idx: Integer]: string read GetFile;
property DropPoint: TPoint read GetPoint;
end;
implementation
{ TFileCatcher }
constructor TFileCatcher.Create(DropHandle: HDROP);
begin
inherited Create;
fDropHandle := DropHandle;
end;
destructor TFileCatcher.Destroy;
begin
DragFinish(fDropHandle);
inherited;
end;
function TFileCatcher.GetFile(Idx: Integer): string;
var
FileNameLength: Integer;
begin
FileNameLength := DragQueryFile(fDropHandle, Idx, nil, 0);
SetLength(Result, FileNameLength);
DragQueryFile(fDropHandle, Idx, PChar(Result), FileNameLength + 1);
end;
function TFileCatcher.GetFileCount: Integer;
begin
Result := DragQueryFile(fDropHandle, $FFFFFFFF, nil, 0);
end;
function TFileCatcher.GetPoint: TPoint;
begin
DragQueryPoint(fDropHandle, Result);
end;
end.
Unit 1 :
ExtCtrls, ShellAPI, ComCtrls, UFileCatcher
private
function IsSupportedFileType(const FileName: string): Boolean;
procedure AddFile(const FileName: string);
procedure DisplayFile(Idx: Integer);
procedure WMDropFiles(var Msg: TWMDropFiles); message WM_DROPFILES;
const
cSupportedExts = '*.txt;*.html;*.htm;*.pas;*.inc;*.dpr;';
//
procedure TForm1.FormCreate(Sender: TObject);
begin
DragAcceptFiles(Self.Handle, True);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
DragAcceptFiles(Self.Handle, False);
end;
procedure TForm1.WMDropFiles(var Msg: TWMDropFiles);
var
I: Integer;
DropPoint: TPoint;
Catcher: TFileCatcher;
begin
inherited;
Catcher := TFileCatcher.Create(Msg.Drop);
try
for I := 0 to Pred(Catcher.FileCount) do
AddFile(Catcher.Files[I]);
DropPoint := Catcher.DropPoint;
ShowMessageFmt('%d file(s) dropped at (%d,%d)',
[Catcher.FileCount, DropPoint.X, DropPoint.Y]);
finally
Catcher.Free;
end;
Msg.Result := 0;
end;
procedure TForm1.AddFile(const FileName: string);
begin
if IsSupportedFileType(FileName) then
DisplayFile(ListBox1.Items.Add(FileName))
else
ShowMessageFmt('File %s is not a supported type', [FileName]);
end;
procedure TForm1.DisplayFile(Idx: Integer);
var
FileName: string;
begin
if Idx >= 0 then
begin
FileName := ListBox1.Items[Idx];
ListBox1.ItemIndex := Idx;
Memo1.Lines.LoadFromFile(FileName);
StatusBar1.SimpleText := FileName;
end
else
begin
Memo1.Clear;
StatusBar1.SimpleText := 'N0 FILE SELECTED';
end;
end;
function TForm1.IsSupportedFileType(const FileName: string): Boolean;
begin
Result := AnsiPos('*' + ExtractFileExt(FileName) + ';', cSupportedExts) > 0;
end;
procedure TForm1.ListBox1Click(Sender: TObject);
begin
DisplayFile(ListBox1.ItemIndex);
end;
Unit DropTargetFilesPicture.pas
unit DropTargetFilesPicture;
interface
Uses
ActiveX, Classes, Windows;
type
TDropTargetFilesPicture = class;
TDropTargetFilesPictureAccept = (dtfpaFiles, dtfpaPictures);
TDropTargetFilesPictureAccepts = set of TDropTargetFilesPictureAccept;
TDropTargetFilesPictureFileNamesCallback = procedure (Sender: TDropTargetFilesPicture; MousePosition: TPoint; FileNames: TStrings) of object;
TDropTargetFilesPicturePictureCallback = procedure (Sender: TDropTargetFilesPicture; MousePosition: TPoint; FileName: String; Stream: TStream) of object;
TDropTargetFilesPictureAcceptCallback = procedure (Sender: TDropTargetFilesPicture; const DataObj: IDataObject; MousePosition: TPoint; AcceptType: TDropTargetFilesPictureAccept; var Accept: Boolean) of object;
TDropTargetFilesPictureDragOverCallback = procedure(Sender: TDropTargetFilesPicture; grfKeyState: Longint; MousePosition: TPoint; var dwEffect: Longint) of object;
TDropTargetFilesPictureDragLeaveCallback = procedure(Sender: TDropTargetFilesPicture) of object;
TDropTargetFilesPicture = class(TComponent, IDropTarget)
private
CF_FileGroupDescriptor: TClipFormat;
CF_FileContents: TClipFormat;
FAccept: Boolean;
FAccepts: TDropTargetFilesPictureAccepts;
FOnDropFileNames: TDropTargetFilesPictureFileNamesCallback;
FOnDropPicture: TDropTargetFilesPicturePictureCallback;
FOnDropAccept: TDropTargetFilesPictureAcceptCallback;
FOnDragOver: TDropTargetFilesPictureDragOverCallback;
FOnDragLeave: TDropTargetFilesPictureDragLeaveCallback;
protected
function DragEnter(const dataObj: IDataObject; grfKeyState: Longint; pt: TPoint; var dwEffect: Longint): HResult; stdcall;
function DragOver(grfKeyState: Longint; pt: TPoint; var dwEffect: Longint): HResult; stdcall;
function DragLeave: HResult; stdcall;
function Drop(const dataObj: IDataObject; grfKeyState: Longint; pt: TPoint; var dwEffect: Longint): HResult; stdcall;
public
Handles: Array of THandle;
Constructor Create(AOwner: TComponent); override;
Destructor Destroy; override;
function AddDropTargetHandle(AHandle: THandle): Boolean;
function GetFileListFromObj(const DataObj: IDataObject; const FileList: TStrings): Boolean;
function GetPictureFileNameFromObj(const DataObj: IDataObject; const FileList: TStrings): Boolean;
function GetPictureFromObj(const DataObj: IDataObject; Stream: TStream): Boolean;
function GetBitmapFromObj(const DataObj: IDataObject; Stream: TStream): Boolean;
published
property Accepts: TDropTargetFilesPictureAccepts read FAccepts write FAccepts;
property OnDropFileNames: TDropTargetFilesPictureFileNamesCallback read FOnDropFileNames write FOnDropFileNames;
property OnDropPicture: TDropTargetFilesPicturePictureCallback read FOnDropPicture write FOnDropPicture;
property OnDropAccept: TDropTargetFilesPictureAcceptCallback read FOnDropAccept write FOnDropAccept;
property OnDragOver: TDropTargetFilesPictureDragOverCallback read FOnDragOver write FOnDragOver;
property OnDragLeave: TDropTargetFilesPictureDragLeaveCallback read FOnDragLeave write FOnDragLeave;
end;
procedure Register;
implementation
Uses
SysUtils, Graphics, ShlObj, ShellAPI, Controls;
procedure Register;
begin
RegisterComponents('3delite', [TDropTargetFilesPicture]);
end;
function TDropTargetFilesPicture.AddDropTargetHandle(AHandle: THandle): Boolean;
begin
Result := RegisterDragDrop(AHandle, Self) = S_OK;
if Result then begin
SetLength(Handles, Length(Handles) + 1);
Handles[Length(Handles) - 1] := AHandle;
end;
end;
constructor TDropTargetFilesPicture.Create(AOwner: TComponent);
begin
inherited;
FAccepts := [dtfpaFiles, dtfpaPictures];
CF_FileGroupDescriptor := RegisterClipboardFormat('FileGroupDescriptorW');
CF_FileContents := RegisterClipboardFormat('FileContents');
//CF_DC := RegisterClipboardFormat('DragContext');
end;
destructor TDropTargetFilesPicture.Destroy;
var
i: Integer;
begin
for i := Low(Handles) to High(Handles) do begin
RevokeDragDrop(Handles[i]);
end;
inherited;
end;
function TDropTargetFilesPicture.DragEnter(const dataObj: IDataObject; grfKeyState: Longint; pt: TPoint; var dwEffect: Longint): HResult;
var
FmtEtc: TFormatEtc;
Medium: TStgMedium;
begin
FAccept := False;
dwEffect := DROPEFFECT_NONE;
if dtfpaFiles in FAccepts then begin
FmtEtc.cfFormat := CF_HDROP;
FmtEtc.ptd := nil;
FmtEtc.dwAspect := DVASPECT_CONTENT;
FmtEtc.lindex := -1;
FmtEtc.tymed := TYMED_HGLOBAL;
if DataObj.GetData(FmtEtc, Medium) = S_OK then begin
FAccept := True;
if Assigned(FOnDropAccept) then begin
FOnDropAccept(Self, DataObj, pt, dtfpaFiles, FAccept);
end;
if FAccept then begin
dwEffect := DROPEFFECT_COPY;
end;
ReleaseStgMedium(Medium);
end;
end;
if dtfpaPictures in FAccepts then begin
FmtEtc.cfFormat := CF_FileContents;
FmtEtc.ptd := nil;
FmtEtc.dwAspect := DVASPECT_CONTENT;
FmtEtc.lindex := 0;
FmtEtc.tymed := TYMED_HGLOBAL;
if DataObj.GetData(FmtEtc, Medium) = S_OK then begin
FAccept := True;
if Assigned(FOnDropAccept) then begin
FOnDropAccept(Self, DataObj, pt, dtfpaPictures, FAccept);
end;
if FAccept then begin
dwEffect := DROPEFFECT_COPY;
end;
ReleaseStgMedium(Medium);
end;
end;
Result := S_OK;
end;
function TDropTargetFilesPicture.DragLeave: HResult;
begin
if Assigned(FOnDragLeave) then begin
FOnDragLeave(Self);
end;
Result := S_OK;
end;
function TDropTargetFilesPicture.DragOver(grfKeyState: Longint; pt: TPoint; var dwEffect: Longint): HResult;
begin
dwEffect := DROPEFFECT_COPY;
if Assigned(FOnDragOver) then begin
FOnDragOver(Self, grfKeyState, pt, dwEffect);
end;
Result := S_OK;
end;
function TDropTargetFilesPicture.Drop(const dataObj: IDataObject; grfKeyState: Longint; pt: TPoint; var dwEffect: Longint): HResult;
var
Enum: IEnumFormatEtc;
FileNameList: TStrings;
PictureStream: TMemoryStream;
FileName: String;
begin
dwEffect := DROPEFFECT_COPY;
if DataObj.EnumFormatEtc(DATADIR_GET, Enum) = S_OK then begin
FileNameList := TStringList.Create;
PictureStream := TMemoryStream.Create;
try
if dtfpaFiles in FAccepts then begin
if GetFileListFromObj(dataObj, FileNameList) then begin
if Assigned(FOnDropFileNames) then begin
FOnDropFileNames(Self, pt {Mouse.CursorPos}, FileNameList);
end;
end;
end;
if dtfpaPictures in FAccepts then begin
GetPictureFileNameFromObj(dataObj, FileNameList);
if GetPictureFromObj(dataObj, PictureStream) then begin
if Assigned(FOnDropPicture) then begin
if FileNameList.Count > 0 then begin
FileName := FileNameList[0];
end;
FOnDropPicture(Self, pt {Mouse.CursorPos}, FileName, PictureStream);
end;
end;
if GetBitmapFromObj(dataObj, PictureStream) then begin
if Assigned(FOnDropPicture) then begin
FOnDropPicture(Self, pt {Mouse.CursorPos}, FileName, PictureStream);
end;
end;
end;
finally
FreeAndNil(PictureStream);
FreeAndNil(FileNameList);
end;
end;
Result := S_OK;
end;
function TDropTargetFilesPicture.GetFileListFromObj(const DataObj: IDataObject; const FileList: TStrings): Boolean;
var
FmtEtc: TFormatEtc;
Medium: TStgMedium;
DroppedFileCount: Integer;
i: Integer;
FileNameLength: Integer;
FileName: string;
begin
Result := False;
FmtEtc.cfFormat := CF_HDROP;
FmtEtc.ptd := nil;
FmtEtc.dwAspect := DVASPECT_CONTENT;
FmtEtc.lindex := -1;
FmtEtc.tymed := TYMED_HGLOBAL;
if DataObj.GetData(FmtEtc, Medium) = S_OK then begin
try
try
DroppedFileCount := DragQueryFile(Medium.hGlobal, $FFFFFFFF, nil, 0);
for i := 0 to Pred(DroppedFileCount) do begin
FileNameLength := DragQueryFile(Medium.hGlobal, i, nil, 0);
SetLength(FileName, FileNameLength);
DragQueryFile(Medium.hGlobal, i, PChar(FileName), FileNameLength + 1);
FileList.Add(FileName);
Result := True;
end;
finally
DragFinish(Medium.hGlobal);
end;
finally
ReleaseStgMedium(Medium);
end;
end;
end;
function TDropTargetFilesPicture.GetPictureFileNameFromObj(const DataObj: IDataObject; const FileList: TStrings): Boolean;
var
FmtEtc: TFormatEtc;
Medium: TStgMedium;
PData: PChar;
begin
Result := False;
FmtEtc.cfFormat := CF_FileGroupDescriptor;
FmtEtc.ptd := nil;
FmtEtc.dwAspect := DVASPECT_CONTENT;
FmtEtc.lindex := - 1;
FmtEtc.tymed := TYMED_HGLOBAL;
if DataObj.GetData(FmtEtc, Medium) = S_OK then begin
try
PData := GlobalLock(Medium.hGlobal);
try
FileList.Append(PFileGroupDescriptorW(PData).fgd[0].cFileName);
Result := True;
finally
GlobalUnlock(Medium.hGlobal);
end;
finally
ReleaseStgMedium(Medium);
end;
end;
end;
function TDropTargetFilesPicture.GetPictureFromObj(const DataObj: IDataObject; Stream: TStream): Boolean;
var
FmtEtc: TFormatEtc;
Medium: TStgMedium;
PData: PChar;
MemSize: NativeUInt;
begin
Result := False;
FmtEtc.cfFormat := CF_FileContents;
FmtEtc.ptd := nil;
FmtEtc.dwAspect := DVASPECT_CONTENT;
FmtEtc.lindex := 0;
FmtEtc.tymed := TYMED_HGLOBAL;
if DataObj.GetData(FmtEtc, Medium) = S_OK then begin
try
PData := GlobalLock(Medium.hGlobal);
try
MemSize := GlobalSize(Medium.hGlobal);
Stream.Write(PData^, MemSize);
Stream.Seek(0, soBeginning);
Result := True;
finally
GlobalUnlock(Medium.hGlobal);
end;
finally
ReleaseStgMedium(Medium);
end;
end;
end;
function DIBGetData(const ADataObject: IDataObject; const AMedium: TStgMedium; Stream: TMemoryStream): Boolean;
var
BitmapInfo: PBitmapInfo;
BitmapFileHeader: TBitmapFileHeader;
DIBSize: integer;
FileSize: integer;
InfoSize: integer;
begin
Result := False;
BitmapInfo := GlobalLock(AMedium.HGlobal);
try
if (BitmapInfo = nil) then begin
Exit;
end;
DIBSize := GlobalSize(AMedium.HGlobal);
FileSize := SizeOf(TBitmapFileHeader) + DIBSize;
InfoSize := SizeOf(TBitmapInfoHeader);
if (BitmapInfo^.bmiHeader.biBitCount > 8) then begin
if ((BitmapInfo^.bmiHeader.biCompression and BI_BITFIELDS) <> 0) then begin
Inc(InfoSize, 12);
end else begin
Inc(InfoSize, SizeOf(TRGBQuad) * (1 shl BitmapInfo^.bmiHeader.biBitCount));
end;
end;
Stream.SetSize(FileSize);
FillChar(BitmapFileHeader, SizeOf(TBitmapFileHeader), 0);
with BitmapFileHeader do begin
bfType := $4D42;
bfSize := FileSize;
bfOffBits := SizeOf(TBitmapFileHeader) + InfoSize;
end;
Stream.Write(BitmapFileHeader, SizeOf(TBitmapFileHeader));
Stream.Write(BitmapInfo^, DIBSize);
Stream.Seek(0, soBeginning);
Result := True;
finally
GlobalUnlock(AMedium.HGlobal);
end;
end;
function TDropTargetFilesPicture.GetBitmapFromObj(const DataObj: IDataObject; Stream: TStream): Boolean;
var
FmtEtc: TFormatEtc;
Medium: TStgMedium;
begin
Result := False;
FmtEtc.cfFormat := CF_DIB;
FmtEtc.ptd := nil;
FmtEtc.dwAspect := DVASPECT_CONTENT;
FmtEtc.lindex := - 1;
FmtEtc.tymed := TYMED_HGLOBAL;
if DataObj.GetData(FmtEtc, Medium) = S_OK then begin
try
Result := DIBGetData(DataObj, Medium, Stream as TMemoryStream);
finally
ReleaseStgMedium(Medium);
end;
end;
end;
Initialization
OleInitialize(nil);
Finalization
OleUninitialize;
end.
Unit1 :
uses uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
Vcl.ExtCtrls, Vcl.StdCtrls, DropTargetFilesPicture, JPEG, PNGImage;
private
{ Private declarations }
DropTargetFilesPicture: TDropTargetFilesPicture;
protected
procedure DropFileNamesCallback(Sender: TDropTargetFilesPicture; MousePosition: TPoint; FileNames: TStrings);
procedure DropPictureCallback(Sender: TDropTargetFilesPicture; MousePosition: TPoint; FileName: String; Stream: TStream);
//
procedure TForm1.FormCreate(Sender: TObject);
begin
DropTargetFilesPicture := TDropTargetFilesPicture.Create(Self);
DropTargetFilesPicture.OnDropFileNames := DropFileNamesCallback;
DropTargetFilesPicture.OnDropPicture := DropPictureCallback;
DropTargetFilesPicture.AddDropTargetHandle(Handle);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
FreeAndNil(DropTargetFilesPicture);
end;
procedure TForm1.DropFileNamesCallback(Sender: TDropTargetFilesPicture; MousePosition: TPoint; FileNames: TStrings);
begin
Memo1.Lines.Clear;
Image1.Picture.Assign(nil);
Memo1.Lines.Assign(FileNames);
Memo2.Lines.LoadFromFile(Memo1.Lines[0]);
Image1.Picture.LoadFromFile(Memo1.Lines[0]);
end;
procedure TForm1.DropPictureCallback(Sender: TDropTargetFilesPicture; MousePosition: TPoint; FileName: String; Stream: TStream);
begin
Memo1.Lines.Clear;
Image1.Picture.Assign(nil);
Memo1.Lines.Append(FileName);
Image1.Picture.LoadFromStream(Stream);
end;
Keine Kommentare:
Kommentar veröffentlichen