uses
Windows,
ActiveX, ShellAPI, StrUtils, Forms, ComObj, SysUtils, Messages;
type
PDropTarget =
class(TInterfacedObject, IDropTarget)
private
m_DropHandle: HWND;
m_DropAllowed: Boolean;
private
procedure SetDropAllowed(_DropAllowed: Boolean);
private
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
constructor Create(_DropHandle: HWND; _DropAllowed: boolean);
destructor Destroy;
override;
public
property DropHandle: HWND
read m_DropHandle;
property DropAllowed: Boolean
read m_DropAllowed
write SetDropAllowed;
end;
implementation
{$REGION 'PDropTarget'}
constructor PDropTarget.Create(_DropHandle: HWND; _DropAllowed: boolean);
begin
inherited Create;
m_DropHandle := _DropHandle;
m_DropAllowed := _DropAllowed;
if _DropAllowed
then
begin
OleInitialize(
nil);
OleCheck(RegisterDragDrop(m_DropHandle, Self));
end;
end;
destructor PDropTarget.Destroy;
begin
RevokeDragDrop(DropHandle);
OleUninitialize;
inherited;
end;
procedure PDropTarget.SetDropAllowed(_DropAllowed: Boolean);
begin
if _DropAllowed
and (
not m_DropAllowed)
then
begin
OleInitialize(
nil);
OleCheck(RegisterDragDrop(m_DropHandle, Self));
end else if (
not _DropAllowed)
and m_DropAllowed
then
begin
RevokeDragDrop(DropHandle);
OleUninitialize;
end;
m_DropAllowed := _DropAllowed;
end;
function PDropTarget.DragEnter(
const dataObj: IDataObject; grfKeyState: Integer; pt: TPoint;
var dwEffect: Integer): HResult;
begin
dwEffect := DROPEFFECT_COPY;
Result := S_OK;
end;
function PDropTarget.DragLeave: HResult;
begin
Result := S_OK;
end;
function PDropTarget.DragOver(grfKeyState: Integer; pt: TPoint;
var dwEffect: Integer): HResult;
begin
dwEffect := DROPEFFECT_COPY;
Result := S_OK;
end;
function PDropTarget.Drop(
const dataObj: IDataObject; grfKeyState: Integer; pt: TPoint;
var dwEffect: Integer): HResult;
var
l_Format : TFormatEtc;
l_StgMed : TStgMedium;
begin
if (dataObj =
nil)
then
raise Exception.Create('
IDataObject-Zeiger ist ungültig!');
with l_Format
do
begin
cfFormat := CF_HDROP;
ptd :=
nil;
dwAspect := DVASPECT_CONTENT;
lindex := -1;
tymed := TYMED_HGLOBAL;
end;
OleCheck(dataObj.GetData(l_Format, l_StgMed));
try
SendMessage(DropHandle, WM_DROPFILES, l_StgMed.hGlobal, -1);
//Message wird in abgeleiteten Controls abgefangen und behandelt.
finally
ReleaseStgMedium(l_StgMed);
end;
Result := S_OK;
end;
{$ENDREGION}