Recent

Author Topic: ShellTreeView and system icons  (Read 18830 times)

El Salvador

  • Full Member
  • ***
  • Posts: 134
Re: ShellTreeView and system icons
« Reply #45 on: March 15, 2021, 07:41:02 pm »
Thanks. Another hint is given by Anton Kavalenka in an attachment to bugreport https://bugs.freepascal.org/view.php?id=18247.

So, if somebody wants to spend some time on this topic, I'd be glad to accept related patches. Ideally such a patch should take advantage of the current widgetset solution. In case of gtk2, for example, it must provide a unit lcl/interfaces/gtk2/gtk2wsshellctrls with a class TGtk2WSCustomShellTreeView implementing the class functions DrawBuiltInIcon and GetBuiltinIconSize, as well as a class TGtk2WSCustomShellListView implementing a class function GetBuiltInImageIndex. And ideally the code should use the gtk2 functions available rather than relying on a given folder structure to find the images. And of course the same must be repeated for qt, qt5, gtk3, gtk, cocoa, carbon...

So, knowing how somebody else solved the issue is just one (important) step on some long trail.
Maybe I could look at it myself, but I don't guarantee anything (and in a short time).

Another small thing for win32: you can improve icon recovery times by adding the SHGFI_USEFILEATTRIBUTES flag when using the method SHGetFileInfoW(). See https://web.archive.org/web/20101125055232/https://www.codeguru.com/cpp/com-tech/shell/article.php/c4511 and https://devblogs.microsoft.com/oldnewthing/20040601-00/?p=39073
« Last Edit: March 16, 2021, 12:55:13 pm by El Salvador »

wp

  • Hero Member
  • *****
  • Posts: 11912
Re: ShellTreeView and system icons
« Reply #46 on: March 15, 2021, 10:56:42 pm »
Thanks for the hint, I modified the win32 widgetset code to take advantage of the SHGFI_USEFILEATTRIBUTES flag. I do see a factor 2 speed improvement when the c:\windows\system32 folder is opened in the ShellListView (from about 2 sec down to about 1 sec)

d7_2_laz

  • Hero Member
  • *****
  • Posts: 512
Re: ShellTreeView and system icons
« Reply #47 on: March 16, 2021, 12:35:11 am »
But please keep in mind that imo for win64 it does not make much sense,
because it might have inaccurate results (see image 1, left side "old"/correct behaviour, right side when using the changed attribute and flag).  The evaluation by registry type might be to rough sometimes.

And imo it's not faster here, (sometimes even slower, varies depending on the os cache). On x64 the existing settiing is excellent fast, in my test (intel i5) it needs ca. 100ms for 18000 objects. -See image 2 left/"old" vs. right/"new".
Lazarus 3.2  FPC 3.2.2 Win10 64bit

wp

  • Hero Member
  • *****
  • Posts: 11912
Re: ShellTreeView and system icons
« Reply #48 on: March 16, 2021, 10:37:25 am »
I can confirm the issue with the missing link overlay icons. Speed is difficult to reproduce for the treeview because it varies strongly between runs. I do not expect much impact of the new version on ShellTreeView because it needs the icons only for painting, unlike the TShellListview for which I confirmed the earlier observation of a factor 2 speed improvement.

Because of the overlay icon issues I reverted the change for the ShellTreeView, but kept it for the ShellListView.

d7_2_laz

  • Hero Member
  • *****
  • Posts: 512
Re: ShellTreeView and system icons
« Reply #49 on: March 16, 2021, 02:03:26 pm »
You see the overlay icons in the listview / Windows 64bit
having replaced the flag SHGFI_TYPENAME by SHGFI_USEFILEATTRIBUTES as the article explains to be the driver to gain the speed benefit?
If i use SHGFI_TYPENAME i'll see the overlays, but it is described as to be slower.
If i use SHGFI_USEFILEATTRIBUTES (which is described to be faster), i'll see them not.

    ImageHandle := SHGetFileInfoW(PWideChar(FileName),
                   //FILE_ATTRIBUTE_NORMAL,      // for non-folder items
                   FILE_ATTRIBUTE_DIRECTORY,     // for folders only
                  {%H-}FileInfo, SizeOf(FileInfo),
                   //SHGFI_USEFILEATTRIBUTES or   // ** is described to be faster --- but overlay icons are lost!
                  //SHGFI_TYPENAME or   // ** is described to be slower --- but the overlay icons are preserved!
                  SHGFI_USEFILEATTRIBUTES or
                  SHGFI_ICON or SHGFI_SMALLICON or SHGFI_SYSICONINDEX);

In the listview in virtual mode imo one shouldn't recognize much speed difference though as the SHGetFileInfoW should be executed only for the few lines one sees on the screen at a time, not for the 18000 items the folder might contain.

But maybe i did misunderstand something basically. But what?
Lazarus 3.2  FPC 3.2.2 Win10 64bit

wp

  • Hero Member
  • *****
  • Posts: 11912
Re: ShellTreeView and system icons
« Reply #50 on: March 16, 2021, 02:38:01 pm »
You see the overlay icons in the listview / Windows 64bit
having replaced the flag SHGFI_TYPENAME by SHGFI_USEFILEATTRIBUTES as the article explains to be the driver to gain the speed benefit?
If i use SHGFI_TYPENAME i'll see the overlays, but it is described as to be slower.
If i use SHGFI_USEFILEATTRIBUTES (which is described to be faster), i'll see them not.
The same for me. The current implementation of the ShellListView in Laz trunk does NOT operate in virtual mode - I think this would be a fundamental change, and doing this would probably affect the base component, not just the win32 widgetset, and I am not sure that virtual mode works correctly in all widget sets. Such a fundamental change should not be done before the new release v2.2 is tagged. Therefore I decided to focus on the speed argument and accept the incorrectly drawn overlay icons. Maybe in a later version we can try to implement virtual mode for the ShellListView, and since speed will not be an issue then we can remove the SHGFI_USEFILEATTRIBUTES again.

d7_2_laz

  • Hero Member
  • *****
  • Posts: 512
Re: ShellTreeView and system icons
« Reply #51 on: March 16, 2021, 03:17:53 pm »
Ok wp ... understood.  Thanks for the information!
Lazarus 3.2  FPC 3.2.2 Win10 64bit

jcmontherock

  • Full Member
  • ***
  • Posts: 236
Re: ShellTreeView and system icons
« Reply #52 on: March 16, 2021, 04:48:55 pm »
Strange: I do not have that problem with *.lnk files and SHGFI_USEFILEATTRIBUTES
« Last Edit: March 16, 2021, 04:51:44 pm by jcmontherock »
Windows 11 UTF8-64 - Lazarus 3.2-64 - FPC 3.2.2

wp

  • Hero Member
  • *****
  • Posts: 11912
Re: ShellTreeView and system icons
« Reply #53 on: March 16, 2021, 04:57:10 pm »
What are you doing? At which time did you pull your Laz-trunk, what is the revision that you work with? The version with SHGFI_USEFILEATTRIBUTES in TShellTreeView was online only for about 12 hours.

jcmontherock

  • Full Member
  • ***
  • Posts: 236
Re: ShellTreeView and system icons
« Reply #54 on: March 16, 2021, 05:50:27 pm »
I do not use ShellTreeView. Only a simple StringGrid to get icons.
I am on Windows 10 (19042.867) 64 bits. I am using the Lazarus 2.012, SVN 64642 downloaded from the official site.
The function I'm using is:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.GetFileIcon(FilePath: String; var fIcon: TIcon);
  2. var
  3.   FileName:     WideString;
  4.   FileInfo:     TSHFileInfoW;
  5.   ImageHandle:  DWORD;
  6. begin
  7.   FileName := UTF8ToUTF16(FilePath);
  8.   ImageHandle := SHGetFileInfoW(PWideChar(FileName), 0, {%H-}FileInfo, SizeOf(FileInfo),
  9.                  SHGFI_USEFILEATTRIBUTES Or SHGFI_ICON or SHGFI_SMALLICON or SHGFI_SYSICONINDEX);
  10.   if ImageHandle = 0 then Exit;
  11.   fIcon.Handle := FileInfo.hIcon;
  12.  
  13. end;
  14.  
  15.  

And it works fine.
Windows 11 UTF8-64 - Lazarus 3.2-64 - FPC 3.2.2

wp

  • Hero Member
  • *****
  • Posts: 11912
Re: ShellTreeView and system icons
« Reply #55 on: March 16, 2021, 06:52:35 pm »
I do not use ShellTreeView. Only a simple StringGrid to get icons.
I am on Windows 10 (19042.867) 64 bits. I am using the Lazarus 2.012, SVN 64642 downloaded from the official site.
The function I'm using is:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.GetFileIcon(FilePath: String; var fIcon: TIcon);
  2. var
  3.   FileName:     WideString;
  4.   FileInfo:     TSHFileInfoW;
  5.   ImageHandle:  DWORD;
  6. begin
  7.   FileName := UTF8ToUTF16(FilePath);
  8.   ImageHandle := SHGetFileInfoW(PWideChar(FileName), 0, {%H-}FileInfo, SizeOf(FileInfo),
  9.                  SHGFI_USEFILEATTRIBUTES Or SHGFI_ICON or SHGFI_SMALLICON or SHGFI_SYSICONINDEX);
  10.   if ImageHandle = 0 then Exit;
  11.   fIcon.Handle := FileInfo.hIcon;
  12.  
  13. end;
  14.  
  15.  

And it works fine.

Really? When the flag SHGFI_USEFILEATTRIBUTES is used then the second parameter must contain the attributes of the file for which the icon is to be determined. With your value 0, I never get the folder icons.

d7_2_laz

  • Hero Member
  • *****
  • Posts: 512
Re: ShellTreeView and system icons
« Reply #56 on: March 16, 2021, 07:29:51 pm »
Yes. but however he sees the overlay icons for files ,, (0  matches FILE_ATTRIBUTE_NORMAL) and, so, the icon information for the .LNK file in speech.

I think the difference is by principle, as apparently the windows registry stores icon information for files and folders differently.  More individually resp. respecting file extension too ... like type .LNK, vs. more generic/general for the type "folder".
"c:\ Documents and Settings"  is no .LNK file.
jcmontherock, if you try that one and use attribute FILE_ATTRIBUTE_DIRECTORY instead of "0", i would guess you see no overlay icon either.
 
Lazarus 3.2  FPC 3.2.2 Win10 64bit

jcmontherock

  • Full Member
  • ***
  • Posts: 236
Re: ShellTreeView and system icons
« Reply #57 on: March 17, 2021, 05:15:23 pm »
With C:\Document And Setting I get the following:
Windows 11 UTF8-64 - Lazarus 3.2-64 - FPC 3.2.2

jcmontherock

  • Full Member
  • ***
  • Posts: 236
Re: ShellTreeView and system icons
« Reply #58 on: March 17, 2021, 05:30:31 pm »
I give you the program. You only have to change the files.
« Last Edit: March 17, 2021, 05:32:57 pm by jcmontherock »
Windows 11 UTF8-64 - Lazarus 3.2-64 - FPC 3.2.2

d7_2_laz

  • Hero Member
  • *****
  • Posts: 512
Re: ShellTreeView and system icons
« Reply #59 on: March 17, 2021, 05:54:20 pm »
Thar's resulting from the second parameter of the shgetfileinfo, the attribute. It surely contains still 0 (resp. FILE_ATTRIBUTE_NORMAL)  - for files -, but not FILE_ATTRIBUTE_DIRECTORY, which is needed to be used for folders.
With FILE_ATTRIBUTE_DIRECTORY you'll see the folder icon, but without the link overlay.
Lazarus 3.2  FPC 3.2.2 Win10 64bit

 

TinyPortal © 2005-2018