Link to home
Start Free TrialLog in
Avatar of yc
yc

asked on

AutoScroll when drag node in treeview

In a treeview component, when i try to move a node to
another node's position by draging, I found the treeview's
view area can not scrolling automaticly.

How to make any solution for the problem?

Thanks.

Ye Chen
Avatar of viktornet
viktornet
Flag of United States of America image

Here is something that will work...

var
  Down : Boolean;
  PT : TPoint;
procedure TForm1.TreeView1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  Down := True;
end;

procedure TForm1.TreeView1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  Down := False;
end;

procedure TForm1.TreeView1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
var
  pt : TPoint;
begin
  if Down then
  begin
    GetCursorPos(PT);
    if pt.y >= TreeView1.Height - 3 then
      if not(treeview1.Selected.Index >= treeview1.items.count - 4)then
        TreeView1.Selected :=TreeView1.Selected.GetNext;
  end;
end;

Talk to you later..

Regards,
Viktor Ivanov
Here is a better version.... =)
---------------------------------------
var
     Down : Boolean;
     PT : TPoint;

procedure TForm1.TreeView1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
    Down := True;
end;

procedure TForm1.TreeView1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
   Down := False;
end;

procedure TForm1.TreeView1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
var
     pt : TPoint;
   begin
     if Down then
     begin
       GetCursorPos(PT);
       pt := ScreenToClient(pt);
       if pt.y >= TreeView1.Height + 40 then
       begin
         if not(treeview1.Selected.Index >= treeview1.items.count - 4)then
           SendMessage(treeview1.handle, WM_VSCROLL, 1, 0);
       end
       else if pt.y <= TreeView1.Top + 5then
       begin
         if not(treeview1.Selected.Index <= 4)then
           SendMessage(treeview1.handle, WM_VSCROLL, -1, 0);
       end;
     end;
end;
----------------------

I hope this helps!

Regards,
Viktor Ivanov
Here is a better version.... =)
---------------------------------------
var
     Down : Boolean;
     PT : TPoint;

procedure TForm1.TreeView1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
    Down := True;
end;

procedure TForm1.TreeView1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
   Down := False;
end;

procedure TForm1.TreeView1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
var
     pt : TPoint;
   begin
     if Down then
     begin
       GetCursorPos(PT);
       pt := ScreenToClient(pt);
       if pt.y >= TreeView1.Height + 40 then
       begin
         if not(treeview1.Selected.Index >= treeview1.items.count - 4)then
           SendMessage(treeview1.handle, WM_VSCROLL, 1, 0);
       end
       else if pt.y <= TreeView1.Top + 5then
       begin
         if not(treeview1.Selected.Index <= 4)then
           SendMessage(treeview1.handle, WM_VSCROLL, -1, 0);
       end;
     end;
end;
----------------------

I hope this helps!

Regards,
Viktor Ivanov
Avatar of yc
yc

ASKER

Hi, viktornet

Thanks for your answer.

But when in drag-drop mode, i want not to change the current selected treenode, i think through autoscrolling the tree to find
the droptarget i need to drop to. So, use mouseup, mousedown, mousemove is not a very well idea i think.

How do you think about this?

Regards
Ye Chen

Let me try it and I'll tell you. OK?

//Vik
ASKER CERTIFIED SOLUTION
Avatar of viktornet
viktornet
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
You may use this in dragdrop...

procedure TForm1.TreeView1DragDrop(Sender, Source: TObject; X, Y: Integer);
var
  Noder : TTreeNode;
begin
  Noder := TreeView1.Selected;
  treeview1.Items.Insert(treeview1.GetNodeAt(x,y),Noder.Text);
  treeview1.items.delete(Noder);
end;

/vvik
You actually asked about scrolling not how to insert them so I think I answered your question......

//Viktor
Well, what do you think??? Does it work now???

Regards,
Viktor Ivanov
Avatar of yc

ASKER

Hi, Viktor Ivanov

Now, My Code is the following, and it works very well.
Please take attentions to the different with your coding. :)

procedure TForm1.TreeView1DragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
begin
  Accept := Sender is TTreeView;

            if Y >= TreeView1.Height - 40 then
                SendMessage(treeview1.handle, WM_VSCROLL, SB_LINEDOWN, 0)
            else if Y <= 40 then
                SendMessage(treeview1.handle, WM_VSCROLL, SB_LINEUP, 0);
end;


But, there are two questions:

1. In Micrisoft Win95's Explorer, when you draging a file or directionary on the bottom
 and stop moving, Explorer 's tree scrollup automaticly until to the last.
I found if when i stop moving on then tree bottom, the treeview also stop scrollup automaticly.
It seems Explorer use a timer behind. How can i do as Explorer?

2. When dragover a node,  How to expand or collaps it after a little time automaticly ?


Regards

Ye Chen
Yes...I'm sure MS uses a timer to kick off scrolls...once you leave the explorer...

Instead of SendMessage, have you tried Perform?  This is faster as it goes straight to the control and doesn't have to go through the message handling system...

Rick
Avatar of yc

ASKER

Hi viktornet,

Would you give me some code using perform?

Thanks.

Ye Chen
Here is some code.....

In OnMouseMove() of a Button for example....
begin
  if ssLeft in Shift then
  begin
    ReleaseCapture;
    Button1.Perform(WM_SYSCOMMAND, $F012, 0);
//Button1.Perform(WM_SYSCOMMAND, $F012, 0); is same as
//SendMessage(Button1.Handle, WM_SYSCOMMAND, $F012, 0);
  end;
end;

BTW, I'd like to know if you are going to accept my answer or reject it . o O???

ThanQ~