English 中文(简体)
Delphi TListview Scroll 累进[复制]
原标题:Delphi TListview Scroll While dragging [duplicate]

我的通话可以有许多节点,许多节点被扩大后,树群使用许多屏幕空间。

现在,我 su想把树View底附近的一个 no子拖到顶上,因为我选择的 no子处于底层,我可以实际看到树冠的顶端。 当把 no子拖到树冠上时,我希望树的话在拖拉时与我一起自动 s,否则似乎不会发生。

视窗探索者就是这一行为的完美例子。 如果你试图拖拉文件或文件夹,如果你把被拖出的物品(node)上 h,则根据 cur的头寸,自动 s。

希望是有意义的。

PS,我已经知道如何拖走 no子,如果在树木的顶部或底部附近 h,我就想用树木在拖拉时与我roll。

感谢。

最佳回答

这是我使用的法典。 它将针对任何<条码>TWinControl:名单箱、树木观点、名单观点等。

type
  TAutoScrollTimer = class(TTimer)
  private
    FControl: TWinControl;
    FScrollCount: Integer;
    procedure InitialiseTimer;
    procedure Timer(Sender: TObject);
  public
    constructor Create(Control: TWinControl);
  end;

{ TAutoScrollTimer }

constructor TAutoScrollTimer.Create(Control: TWinControl);
begin
  inherited Create(Control);
  FControl := Control;
  InitialiseTimer;
end;

procedure TAutoScrollTimer.InitialiseTimer;
begin
  FScrollCount := 0;
  Interval := 250;
  Enabled := True;
  OnTimer := Timer;
end;

procedure TAutoScrollTimer.Timer(Sender: TObject);

  procedure DoScroll;
  var
    WindowEdgeTolerance: Integer;
    Pos: TPoint;
  begin
    WindowEdgeTolerance := Min(25, FControl.Height div 4);
    GetCursorPos(Pos);
    Pos := FControl.ScreenToClient(Pos);
    if not InRange(Pos.X, 0, FControl.Width) then begin
      exit;
    end;
    if Pos.Y<WindowEdgeTolerance then begin
      SendMessage(FControl.Handle, WM_VSCROLL, SB_LINEUP, 0);
    end else if Pos.Y>FControl.Height-WindowEdgeTolerance then begin
      SendMessage(FControl.Handle, WM_VSCROLL, SB_LINEDOWN, 0);
    end else begin
      InitialiseTimer;
      exit;
    end;

    if FScrollCount<50 then begin
      inc(FScrollCount);
      if FScrollCount mod 5=0 then begin
        //speed up the scrolling by reducing the timer interval
        Interval := MulDiv(Interval, 3, 4);
      end;
    end;

    if Win32MajorVersion<6 then begin
      //in XP we need to clear up transient "fluff"; results in flickering so only do it in XP where it is needed
      FControl.Invalidate;
    end;
  end;

begin
  if Mouse.IsDragging then begin
    DoScroll;
  end else begin
    Free;
  end;
end;

然后使用<代码>。 • 用于控制和实施《标准的活动手册》:

procedure TMyForm.SomeControlStartDrag(Sender: TObject; var DragObject: TDragObject);
begin
  TAutoScrollTimer.Create(Sender as TWinControl);
end;
问题回答

这里的另一种选择是,所选的节点总会自动浏览。

type
  TForm1 = class(TForm)
    TreeView1: TTreeView;
    TreeView2: TTreeView;
    procedure TreeViewDragOver(Sender, Source: TObject; X, Y: Integer;
      State: TDragState; var Accept: Boolean);
    procedure TreeViewEndDrag(Sender, Target: TObject; X, Y: Integer);
    procedure TreeViewMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
    FDragNode: TTreeNode;
    FNodeHeight: Integer;
  end;

...

procedure TForm1.TreeViewMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  with TTreeView(Sender) do
  begin
    FDragNode := GetNodeAt(X, Y);
    if FDragNode <> nil then
    begin
      Selected := FDragNode;
      with FDragNode.DisplayRect(False) do
        FNodeHeight := Bottom - Top;
      BeginDrag(False, Mouse.DragThreshold);
    end;
  end;
end;

procedure TForm1.TreeViewDragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
var
  Pt: TPoint;
  DropNode: TTreeNode;
begin
  Accept := Source is TTreeView;
  if Accept then
    with TTreeView(Source) do
    begin
      if Sender <> Source then
        Pt := ScreenToClient(Mouse.CursorPos)
      else
        Pt := Point(X, Y);
      if Pt.Y < FNodeHeight then
        DropNode := Selected.GetPrevVisible
      else if Pt.Y > (ClientHeight - FNodeHeight) then
        DropNode := Selected.GetNextVisible
      else
        DropNode := GetNodeAt(Pt.X, Pt.Y);
      if DropNode <> nil then
        Selected := DropNode;
    end;
end;

procedure TForm1.TreeViewEndDrag(Sender, Target: TObject; X, Y: Integer);
var
  DropNode: TTreeNode;
begin
  with TTreeView(Sender) do
    if Target <> nil then
    begin
      DropNode := Selected;
      DropNode := Items.Insert(DropNode,   );
      DropNode.Assign(FDragNode);
      Selected := DropNode;
      Items.Delete(FDragNode);
    end
    else
      Selected := FDragNode;
end;

<may> >希望将OnDragOver活动手稿也与树木的母体联系起来,结果导致当 mo树不在树木电文中时 dropping死。 如果你想要roll,但当 mo在树木电文之外时不会退缩,那么就在OnEndDrag活动手里检查if Target = Sender

仅仅完成,其他答复中的工作就不再需要。 以后的版本可以选择:

TreeOptions.AutoOptions.toAutoScroll := 真实





相关问题
determining the character set to use

my delphi 2009 app has a basic translation system that uses GNUGetText. i had used some win API calls to prepare the fonts. i thought it was working correctly until recently when someone from Malta ...

Help with strange Delphi 5 IDE problems

Ok, I m going nuts here. For the last (almost) four years, I ve been putting up with some extremely bad behavior from my Delphi 5 IDE. Problems include: Seemingly random errors in coride50.bpl ...

How to write a Remote DataModule to run on a linux server?

i would like to know if there are any solution to do this. Does anyone? The big picture: I want to access data over the web, using my delphi thin clients. But i´would like to keep my server/service ...

How convert string to integer in Oxygene

In Delphi, there is a function StrToInt() that converts a string to an integer value; there is also IntToStr(), which does the reverse. These functions doesn t appear to be part of Oxygene, and I can ...

Quick padding of a string in Delphi

I was trying to speed up a certain routine in an application, and my profiler, AQTime, identified one method in particular as a bottleneck. The method has been with us for years, and is part of a "...

热门标签