Recent

Author Topic: TShellTreeView TopItem  (Read 291 times)

Paolo

  • Hero Member
  • *****
  • Posts: 726
TShellTreeView TopItem
« on: May 16, 2026, 06:54:11 pm »
Hello (win64, fpc 324rc1, laz 4.6)

by this code (is it the correct one ?) I was able to put on top of ShellTreeView the selected item

Code: Pascal  [Select][+][-]
  1. procedure TFForm1.ShlTrVwFoldersClick(Sender: TObject);
  2. var
  3.   HT : THitTests;
  4.   P : TPoint;
  5. begin
  6.   GetCursorPos(P);
  7.   P:=ShlTrVwFolders.ScreenToClient(P);
  8.   HT:=ShlTrVwFolders.GetHitTestInfoAt(P.X, P.Y);
  9.   if (htOnItem in HT) then
  10.     ShlTrVwFolders.TopItem:=ShlTrVwFolders.GetNodeAt(P.X, P.Y);
  11.  

I want to be able to have the same result when "click" happens on the "folding simbol" (I don't know the correct name) but it seems that no value in THintTests catches such area.

How can I do that ?

Thank you.
« Last Edit: May 16, 2026, 06:56:33 pm by Paolo »

jamie

  • Hero Member
  • *****
  • Posts: 7774
Re: TShellTreeView TopItem
« Reply #1 on: May 16, 2026, 07:49:32 pm »
offset the X value you get when doing a Mouse Location point after you convert it to ScreenToClient area.

X := Max(IconWidth,X);

That will pick the smallest X location and when you query the node with the new value you will get that info while hovering over the icon.

Jamie
The only true wisdom is knowing you know nothing

wp

  • Hero Member
  • *****
  • Posts: 13583
Re: TShellTreeView TopItem
« Reply #2 on: May 16, 2026, 11:43:13 pm »
The hit test for the expand/collapse button is "htOnButton". But that itself would be too easy...

One problem is that the public method GetNodeAt ignores clicks left of the node text. Fortunately there is another "GetNode*" method, GetNodeAtY, which does not do this; however, it is protected... To access it nevertheless, write a class helper:
Code: Pascal  [Select][+][-]
  1. type
  2.   TShellTreeViewHelper = class helper for TShellTreeView
  3.   public
  4.     function MyGetNodeAtY(Y: Integer): TTreeNode;
  5.   end;
  6.  
  7. function TShellTreeViewHelper.MyGetNodeAtY(Y: Integer): TTreeNode;
  8. begin
  9.   Result := GetNodeAtY(Y);
  10. end;

The other problem is that the OnClick event removes HitTest results again, so that the "htOnButton" cannot be detected here. Therefore, put the code into the OnMouseDown or OnMouseUp events. It turned out that OnMouseDown is too early because the regular click is still handled later and this causes some confusion. I got the best results when I put your code into the OnMouseUp event:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.ShellTreeView1MouseUp(Sender: TObject; Button: TMouseButton;
  2.   Shift: TShiftState; X, Y: Integer);
  3. var
  4.   HT : THitTests;
  5. begin
  6.   HT:=ShellTreeView1.GetHitTestInfoAt(X, Y);
  7.   //Caption := SetToString(PTypeInfo(TypeInfo(HT)), Integer(HT), True);    // Activate this line to see which hit tests were detected. Requires "TypInfo" in "uses".
  8.   if (HT * [htOnButton, htOnIcon, htOnLabel] <> []) then       // React on clicks on expand/collapse, icon or label
  9.     ShellTreeView1.TopItem:=ShellTreeView1.MyGetNodeAtY(Y);    // this accesses the protected GetNoteAtY via the class helper
  10. end;

Side-note: I personally consider automatic scrolling the clicked node to the top a very annoying user interface because I always have to move the mouse for quite some distance when I want to open child nodes. And when the text click even moves the focused node to the top I cannot see the nodes above the focused node any more.

Paolo

  • Hero Member
  • *****
  • Posts: 726
Re: TShellTreeView TopItem
« Reply #3 on: May 17, 2026, 10:07:58 am »
@jamie: click is not fired at all if I click on the "expand" symbol

@wp:

Quote
I personally consider automatic scrolling the clicked node to the top a very annoying user interface because I always have to move the mouse for quite some distance when I want to open child nodes. And when the text click even moves the focused node to the top I cannot see the nodes above the focused node any more.

the opposite here. I have many sub-direcotry and I want to see as much as possible sub-directories once I click on the father directory.
at the begin I tried OnMouseDown, but probably I did something wrong, I'll try to follow your suggestion, and I'll come back with the findings.

Paolo

  • Hero Member
  • *****
  • Posts: 726
Re: TShellTreeView TopItem
« Reply #4 on: May 18, 2026, 06:53:15 pm »
perfect ! it works as I want.

thanks wp.

 

TinyPortal © 2005-2018