Перетаскиваем ноды в TTreeView

15:11
unit Unit1;
 
interface
 
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls;
 
type
TForm1 = class(TForm)
TreeView1: TTreeView;
procedure TreeView1DragDrop(Sender, Source: TObject; X, Y: Integer);
procedure TreeView1StartDrag(Sender: TObject;
var DragObject: TDragObject);
procedure TreeView1DragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
procedure FormCreate(Sender: TObject);
private
FDraggedItem: TTreeNode;
 
{ Private declarations }
public
{ Public declarations }
end;
 
var
Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
procedure TForm1.TreeView1DragDrop(Sender, Source: TObject; X, Y: Integer);
var
FTargetItem: TTreeNode;
begin
FTargetItem := treeview1.GetNodeAt(x, y);
if Assigned(FTargetItem) then begin
if GetKeyState(VK_SHIFT) < 0 then
// If Shift is down make dragged node a child of the target node
FDraggedItem.MoveTo(FTargetItem, naAddChildFirst)
else
// Make dragged node a sibling of the target node
if FTargetItem.getNextSibling <> nil then
FDraggedItem.MoveTo(FTargetItem.getNextSibling, naInsert)
else
FDraggedItem.MoveTo(FTargetItem, naAdd);
end
else begin
if y < 5 then begin
// Make dragged node the first root node
if treeview1.Items[0] <> FDraggedItem then
FDraggedItem.MoveTo(treeview1.Items[0], naInsert);
end
else
// Make dragged node the last root node
FDraggedItem.MoveTo(treeview1.Items[0], naAdd);
end;
FDraggedItem := nil;
 
end;
 
procedure TForm1.TreeView1StartDrag(Sender: TObject;
var DragObject: TDragObject);
var
pt: TPoint;
begin
pt := treeview1.ScreenToClient(mouse.cursorpos);
FDraggedItem := treeview1.GetNodeAt(pt.x, pt.y);
if not Assigned(FDraggedItem) then
CancelDrag;
end;
 
 
procedure TForm1.TreeView1DragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
begin
Accept := (sender = source) and
(FDraggedItem <> treeview1.GetNodeAt(x, y));
end;
 
procedure TForm1.FormCreate(Sender: TObject);
var
node: TTreenode;
i, j: integer;
begin
for i := 1 to 10 do begin
node := TreeView1.Items.Add(nil, inttostr(i));
for j := 1 to 3 do
node := TreeView1.Items.AddChild(node, inttostr(i) + '->sub' + inttostr(j));
end;
end;
 
end.