• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 403
  • Last Modified:

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
0
yc
Asked:
yc
  • 9
  • 3
1 Solution
 
viktornetCommented:
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
0
 
viktornetCommented:
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
0
 
viktornetCommented:
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
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
ycAuthor Commented:
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

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

//Vik
0
 
viktornetCommented:
Ok, here is the new one that works...I just tried it...
-----------------------------
var          pt : TPoint;
procedure TForm1.TreeView1DragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
begin
  Accept := Sender is TTreeView;
  GetCursorPos(PT);
            pt := ScreenToClient(pt);
            if pt.y >= TreeView1.Height + 40 then//Just fix this
            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 + 20 then//and also fix this
            begin
              if not(treeview1.Selected.Index <= 4)then
                SendMessage(treeview1.handle, WM_VSCROLL, -1, 0);
            end;
end;

procedure TForm1.TreeView1DragDrop(Sender, Source: TObject; X, Y: Integer);
var
  s : tpoint;
begin
  s := point(x,y);
  treeview1.Items.Insert(Treeview1.GetNodeAt(s.x,s.y + 10),'COOL');;
  treeview1.items.delete(treeview1.selected);
end;
--------------------------
Hope this helps =)

Regards,
Viktor Ivanov
0
 
viktornetCommented:
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
0
 
viktornetCommented:
You actually asked about scrolling not how to insert them so I think I answered your question......

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

Regards,
Viktor Ivanov
0
 
ycAuthor Commented:
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
0
 
rickpetCommented:
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
0
 
ycAuthor Commented:
Hi viktornet,

Would you give me some code using perform?

Thanks.

Ye Chen
0
 
viktornetCommented:
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~
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

  • 9
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now