关于OLE拖拽(原创)(参考了MSDN上一些信息)
[OLE拖拽]
与OLE拖拽相关的接口有很多如下:
IDataObject:此接口主要负责数据处理行为,在OLE拖拽的源实现该接口以定义数据传输格式。在OLE拖拽的目的对象中,可以获取IDataObject接口,并且通过该接口的GetData方法获取数据。具体信息下面介绍。
IDropSource:此接口定义了一些方法来处理拖拽的界面显示。(是否如此还有待考证)
IDropTarget:此接口定义了接收OLE拖拽将要实现的方法。接收OLE拖拽的对象必须实现该接口。
--------------------------------------------------------------------------------
我现在主要是要响应OLE拖拽,所以先从IDropTarget说起。
要能够响应OLE拖拽首先要实现IDropTarget接口,并把该接口注册到要响应OLE拖拽的窗口。例如有对象如下:
TDropManager = class(TInterfacedObject, IDropTarget)
private
FOwner: TWinControl;
FHandle: HWND;
FTarget: Pointer;
public
constructor Create(AOwner: TWinControl);
destructor Destroy; override;
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;
end;
该对象实现了IDropTarget,就可以创建该对象了。在Create方法中写入如下代码:
constructor TpsDragDropManager.Create(AOwner: TWinControl);
begin
inherited Create;
FOwner := AOwner;
FHandle := AOwner.Handle;
OleCheck(RegisterDragDrop(FHandle, Self));
end;
其中RegisterDragDrop就是把支持IDropTarget接口的对象注册为FHandle所指的窗口的用于处理OLE拖拽的对象。由程序可知,此对象的父窗口就可以获取OLE拖拽事件了,这些事件是在DragEnter,DragOver,DragLeave和Drop中触发的。理所当然的,你还需要在该对象释放的时候取消注册。也就是在析构函数中调用RevokeDragDrop(FHandle);注意, RegisterDragDrop和RevokeDragDrop不一定要放在构造函数中,它们可以放在任何地方。
[重要说明:这里进行OLE调用,因此必须初始化,使用OleInitialize(nil)和OleUninitialize函数。我是在此单元的initialization和finalization部分分别使用这两个函数(注意,我指Delphi中)]
<另一点说明,在DragEnter中,Result := S_OK事件才会继续传递到DragOver,DragLeave等>
在DragEnter,DragOver和Drop函数中都有const dataObj: IDataObject参数,这个接口就是把数据传递进来的接口。可以调用该接口的GetData方法获取OLE拖拽的数据。GetData的声明如下:function GetData(const formatetcIn: TFormatEtc; out medium: TStgMedium): HResult; stdcall; 它需要2个参数。其中formatetcIn函数指明了能够响应的拖拽数据类型。medium参数存放有具体数据信息。
如:
const
HDropFormatEtc: TFormatEtc = (cfFormat: CF_HDROP; ptd: nil; dwAspect: DVASPECT_CONTENT;
lindex: - 1; tymed: $FFFFFFFF);
HDropFormatEtc1: TFormatEtc = (cfFormat: CF_TEXT; ptd: nil; dwAspect: DVASPECT_CONTENT;
lindex: - 1; tymed: $FFFFFFFF);