Delphi 如何将特定树视图节点的位置居中?

Delphi 如何将特定树视图节点的位置居中?,delphi,treeview,Delphi,Treeview,当我用TTreeView打开表单时,我用一些数据填充表单并选择一些节点。但我需要使所选节点在控制中心可见(当然,在可能的情况下)。我找不到如何使用标准的TTreeView组件。 有什么想法吗?我能找到的滚动树状视图的唯一方法是发送一个WM\u VSCROLL,值为SB\u LINEDOWN/SB\u LINEUP。由于某些原因,控件似乎不响应滚动值SB_THUMBPOSITION,例如富编辑。出于这个原因,下面的try通过向控件发送一组行滚动消息,或多或少地使节点居中。试着自己看看它是否适合你的

当我用TTreeView打开表单时,我用一些数据填充表单并选择一些节点。但我需要使所选节点在控制中心可见(当然,在可能的情况下)。我找不到如何使用标准的TTreeView组件。
有什么想法吗?

我能找到的滚动树状视图的唯一方法是发送一个
WM\u VSCROLL
,值为
SB\u LINEDOWN
/
SB\u LINEUP
。由于某些原因,控件似乎不响应滚动值
SB_THUMBPOSITION
,例如富编辑。出于这个原因,下面的try通过向控件发送一组行滚动消息,或多或少地使节点居中。试着自己看看它是否适合你的需要

var
  DR, CR: TRect;
  ScrollPx, ScrollLines, i: Integer;
begin
  if Assigned(TreeView1.Selected) then begin

    // calculate how many *pixels* should we scroll
    DR := TreeView1.Selected.DisplayRect(False);
    CR := TreeView1.ClientRect;
    ScrollPx := - Round((CR.Bottom / 2) - DR.Top - ((DR.Bottom - DR.Top) / 2));

    // how many lines does it correspond to
    ScrollLines := ScrollPx div TreeView_GetItemHeight(TreeView1.Handle);

    // scroll that many lines
    if ScrollLines > 0 then
      for i := 1 to ScrollLines do
        TreeView1.Perform(WM_VSCROLL, MakeWParam(SB_LINEDOWN, 0), 0)
    else if ScrollLines < 0 then
      for i := ScrollLines to -1 do
        TreeView1.Perform(WM_VSCROLL, MakeWParam(SB_LINEUP, 0), 0);
  end;
var
DR,CR:TRect;
滚动px,滚动线,i:整数;
开始
如果已分配(TreeView.1.选中),则开始
//计算我们应该滚动多少像素
DR:=TreeView1.Selected.DisplayRect(False);
CR:=TreeView1.ClientRect;
ScrollPx:=-圆形((CR.Bottom/2)-DR.Top-((DR.Bottom-DR.Top)/2));
//它对应多少行
ScrollLines:=ScrollPx div TreeView_GetItemHeight(TreeView1.Handle);
//滚动那么多行
如果ScrollLines>0,则
对于i:=1的滚动行
树视图1.执行(WM_VSCROLL,MakeWParam(SB_LINEDOWN,0),0)
否则,如果滚动线<0,则
对于i:=滚动行到-1 do
树视图1.执行(WM_VSCROLL,MakeWParam(SB_LINEUP,0),0);
结束;

这还不足以让您确保它在任何时候都可见吗?您需要自己计算滚动和滚动的距离。@TLama-我使用Delphi XE3,当我选择node时,它变得可见,但它看起来不是很好,因为用户需要查看一些上下文(所选内容的上面和下面的项目)。那么,请获取节点边界(
DisplayRect(False)
),计算其到要居中位置的距离并滚动控件。这是我能想到的唯一方法。@TLama-这似乎是我所需要的(我在寻找解决方案时错过了DisplayRect)。我明天会查的。谢谢我仍然在想,对于如何按像素滚动任何窗口控件(具有滚动条),是否有一个明确的答案。我最多只能移动一个窗口的内容(通过
ScrollWindowEx
函数),但它从来都不是持久的。当控件无效时,窗口内容向后移动,我永远也不知道如何相应地移动scrolbars。也许我应该多花点时间。[+1]@TLama-我从来都不太明白
ScrollWindow[Ex]
有什么好处。我一直认为它不会真正滚动任何东西,但它是绘制自己滚动控件的偏移区域的快捷方式,绘制无效部分的负担仍然落在您身上。它不适用于现成的控件,因为它们一有机会就绘制原始外观。不过我可能大错特错了。。谢谢你的投票。:)我无法在Delphi7中编译上面的代码。TreeView_GetItemHeight与TreeView w1.GetItemHeight一样未定义。任何建议,@SertacAkyuz?@Tom-在uses子句中包含'commctrl'。