如何把资源管理器中的文件拖放到treeview中的字节点下面?(100分)

A

amourz

Unregistered / Unconfirmed
GUEST, unregistred user!
我用下面的代码,发现只能把文件拖放到根下,好像根本无法取得子节点,哪位大侠能解决这个
问题?100分送上.

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls,shellapi;

type
TForm1 = class(TForm)
TreeView1: TTreeView;
procedure FormCreate(Sender: TObject);
procedure TreeView1DragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
private
{ Private declarations }
procedure WMDropFiles(VAR Msg: TWMDropFiles);message WM_DROPFILES;
procedure AppOnMessage(VAR Msg: TMsg;VAR Handled : Boolean);
public
{ Public declarations }
end;

var
Form1: TForm1;
s:string;
CurrentNode:TTreeNode;
implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
DragAcceptFiles(Handle, True);
DragAcceptFiles(Application.Handle, True);
Application.OnMessage := AppOnMessage;
end;

procedure TForm1.WMDropFiles(VAR Msg: TWMDropFiles);
VAR
N : Word;
buffer : ARRAY[0..180] OF Char;

BEGIN

WITH Msg DO
BEGIN
FOR N := 0 TO DragQueryFile(Drop, $FFFFFFFF, buffer,1)-1 DO
BEGIN
DragQueryFile(Drop, N, Buffer, 80);
s:=StrPas(Buffer);
TreeView1.Items.AddChild(CurrentNode,s);
END;
DragFinish(Drop);
END;
END;

procedure TForm1.AppOnMessage(VAR Msg: TMsg;
VAR Handled : Boolean);
VAR WMD : TWMDropFiles;
BEGIN
IF Msg.message = WM_DROPFILES then
BEGIN
WMD.Msg := Msg.message;
WMD.Drop := Msg.wParam;
WMD.Unused := Msg.lParam;
WMD.Result := 0;
WMDropFiles(WMD);
Handled := TRUE;
END;
END;

procedure TForm1.TreeView1DragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
begin
CurrentNode:=TreeView1.GetNodeAt(x,y);
end;

end.
 
TreeView1.GetNodeAt(x,y);
var
P: Point;
...
WITH Msg DO
BEGIN
FOR N := 0 TO DragQueryFile(Drop, $FFFFFFFF, buffer,1)-1 DO
BEGIN
DragQueryFile(Drop, N, Buffer, 80);
s:=StrPas(Buffer);
DragQueryPoint(Drop, P); // 或者是 DragQueryPoint(Drop, @P); 你试一试
P := TreeView1.ScreenToClient(P);
TreeView1.Items.AddChild(TreeView1.GetNodeAt(P.X, P.Y), s);
END;
DragFinish(Drop);
END;
 
[red]to beta:[/red]
point是个什么东东?这个好像通不过语法检查阿
 
文中:TreeView1.Items.AddChild(CurrentNode,s)的CurrentNode 在使用时实际是 NULL
值,为什么?你别问我,看帮助。
TreeView1.Items.AddChild 只能给 Treeview 加一个 Label 的值(也就是 Treeview 的标签)
你不会和我一样,傻乎乎地给 Treeview 加一个文件路径+文件名做标签文字吧。
 
to小雨哥:标签不标签不是讨论的问题,问题是如何取得子节点的焦点.如果在同一FORM内拖放,
TREEVIEW是可以取得子节点的.当鼠标DRAGOVER时会高亮变兰.可是从FORM外拖放文件却只能
到根,也就是你说的CurrentNode 在使用时实际是 NULL值,我想肯定有办法取得子节点的吧.
不然我从外拖放文件不就和LISTBOX效果一样了,文件都是处于同一层次?期盼哪位高人出现.
 
其实 beta 一眼就看出了你的问题所在,他试图通过鼠标光标的位置来定位节点,我想
你应该看得出他的意图,试着去做到这一点。我所谓的标签,是根据你的程序片段看到
的,你使用的函数只能得到一个标签被写上 'String' 的节点,如果你觉得够用了,就
不需要理会,而更常用的是 AddChildObject 函数。
 
Sorry, 手误,重写一次:

var
P: TPoint; // 呵呵,这里是 TPoint,一个有两个成员的 record,通常用于保存二维坐标等
...
WITH Msg DO
BEGIN
FOR N := 0 TO DragQueryFile(Drop, $FFFFFFFF, buffer,1)-1 DO
BEGIN
DragQueryFile(Drop, N, Buffer, 80);
s:=StrPas(Buffer);
DragQueryPoint(Drop, P); // 或者是 DragQueryPoint(Drop, @P); 你试一试
P := TreeView1.ScreenToClient(P);
TreeView1.Items.AddChild(TreeView1.GetNodeAt(P.X, P.Y), s);
END;
DragFinish(Drop);
END;

你再试一试?
 
to beta:还是不行
 
谢谢BETA和小雨哥,我已经自己解决问题了。
用treeview.items.addchild(treeview1.selected,s);
就可以拖放进字节点里去。而且我注意到了。资源管理器也是如此,必须先
选中一个节点,才可以拖放进。
 
多人接受答案了。
 
顶部