一个关于向 TreeView 拖放文件的问题。(100分)

  • 主题发起人 主题发起人 乖乖兔
  • 开始时间 开始时间

乖乖兔

Unregistered / Unconfirmed
GUEST, unregistred user!
我建立了一个顶层窗口,在当中放了一个 TreeView,
我想从系统的“资源管理器”或其它的窗口中拖放一些文件过来放下。
现在的情况是,这个窗口是接收了这些文件,但是我只想让这个 TreeView 接收,
别的地方无效,怎么样做!
 
判断 接受窗口中是不是treeview控件,是的化,就接受。用DragDrop控件实现你的要求很简单
 
在ondragover 事件里用

accept := dest is TTreeView
 
用我这个控件就OK了,可以指定一个TWinControl来接收文件,不指定的话就是
整个From都可接收,你在OnDropFile事件中写代码就行了:

{***************************************************************
*
* Project Name: IRIMS -- NSFileDrop
* Typist: XJG(xianjun@163.net)
* Purpose: 从Explorer中拖放文件到目标控件
* Comment Time: 2002-6-2 21:35:02
* History: Create by xjg. 2002-6-2 21:35:02
*
****************************************************************}

unit NSFileDrop;

interface

uses
Windows, Messages, SysUtils, Classes, Controls, ActiveX, ShellAPI;

type
TDropFileEvent = procedure(APoint: TPoint; AKeyState: Longint;
AFiles: array of string) of object;

TNSFileDrop = class(TComponent, IDropTarget)
private
FOnDropFile: TDropFileEvent;
FHandledTarget: TWinControl;
FRegisteredHwnd: THandle;
FOldWndProc: TWndMethod;
procedure NewWndProc(var Msg: TMessage);
procedure SetHandledTarget(const Value: TWinControl);

{ IDropTarget }
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;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
protected
procedure Loaded; override;
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
published
property HandledTarget: TWinControl read FHandledTarget write SetHandledTarget;
property OnDropFile: TDropFileEvent read FOnDropFile write FOnDropFile;
end;

implementation

{ TNSFileDrop }

function TNSFileDrop._AddRef: Integer;
begin
Result := S_OK;
end;

function TNSFileDrop._Release: Integer;
begin
Result := S_OK;
end;

function TNSFileDrop.DragEnter(const dataObj: IDataObject;
grfKeyState: Integer; pt: TPoint; var dwEffect: Integer): HRESULT;
begin
dwEffect := DROPEFFECT_COPY;
Result := S_OK;
end;

function TNSFileDrop.DragLeave: HRESULT;
begin
Result := S_OK;
end;

function TNSFileDrop.DragOver(grfKeyState: Integer; pt: TPoint;
var dwEffect: Integer): HRESULT;
begin
dwEffect := DROPEFFECT_COPY;
Result := S_OK;
end;

function TNSFileDrop.Drop(const dataObj: IDataObject; grfKeyState: Integer;
pt: TPoint; var dwEffect: Integer): HRESULT;
var
Buffer: string;
Files: array of string;
Count, I: Integer;
formatEtc: TFormatEtc;
medium: TStgMedium;
const
MAX_PATH = 255;
CF_HDROP = 15;
begin
with formatEtc do
begin
cfFormat := CF_HDROP;
ptd := nil;
dwAspect := DVASPECT_CONTENT;
lindex := -1;
tymed := TYMED_HGLOBAL;
end;
dataObj.GetData(formatEtc, medium);

try
Count := DragQueryFile(medium.HGLOBAL, $FFFFFFFF, @Buffer[1], MAX_PATH);
SetLength(Files, Count);
for I := 0 to Count - 1 do
begin
SetLength(Buffer, MAX_PATH);
SetLength(Buffer, DragQueryFile(medium.HGLOBAL, I, PChar(Buffer), MAX_PATH) + 1);
Files := Buffer;
end;
if (Length(Files) > 0) and Assigned(FOnDropFile) then
FOnDropFile(pt, grfKeyState, Files);
finally
ReleaseStgMedium(medium);
end;
Result := S_OK;
end;

procedure TNSFileDrop.SetHandledTarget(const Value: TWinControl);
begin
if FHandledTarget <> Value then
begin
if not (csDesigning in ComponentState) then
if Assigned(FHandledTarget) then
begin
if Assigned(FOldWndProc) then
begin
FHandledTarget.WindowProc := FOldWndProc;
FOldWndProc := nil;
end;
if (FRegisteredHwnd > 0) and Failed(RevokeDragDrop(FRegisteredHwnd)) then
RaiseLastOSError;
FRegisteredHwnd := 0;
end;
FHandledTarget := Value;
if not (csDesigning in ComponentState) then
if Value <> nil then
begin
FOldWndProc := FHandledTarget.WindowProc;
FHandledTarget.WindowProc := NewWndProc;
Value.FreeNotification(Self);
if Failed(RegisterDragDrop(FHandledTarget.Handle, Self)) then
RaiseLastOSError;
FRegisteredHwnd := FHandledTarget.Handle;
end;
end;
end;

procedure TNSFileDrop.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited;
if (Operation = opRemove) and (AComponent = FHandledTarget) then
begin
FHandledTarget.WindowProc := FOldWndProc;
FOldWndProc := nil;
if FRegisteredHwnd > 0 then
begin
if Failed(RevokeDragDrop(FRegisteredHwnd)) then
RaiseLastOSError;
FRegisteredHwnd := 0;
end;
FHandledTarget := nil;
end;
end;

procedure TNSFileDrop.NewWndProc(var Msg: TMessage);
begin
if Msg.Msg = WM_DESTROY then
begin
if Assigned(FHandledTarget) then
FHandledTarget.WindowProc := FOldWndProc;
FHandledTarget := nil;
FOldWndProc := nil;
if (FRegisteredHwnd > 0) and Failed(RevokeDragDrop(FRegisteredHwnd)) then
RaiseLastOSError;
FRegisteredHwnd := 0;
end
else if Assigned(FOldWndProc) then
FOldWndProc(Msg);
end;

procedure TNSFileDrop.Loaded;
begin
inherited;
if not (csDesigning in ComponentState) then
if (Owner is TWinControl) and (HandledTarget = nil) then
HandledTarget := TWinControl(Owner);
end;

initialization
OleInitialize(nil);
finalization
OleUninitialize;

end.

 
后退
顶部