Recent

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

d7_2_laz

  • Hero Member
  • *****
  • Posts: 512
Re: ShellTreeView and system icons
« Reply #30 on: February 12, 2021, 07:18:20 pm »
You both are just doing milestones on improvements of the shell controls, are you aware?  :D

@wp: the icon thing within  the SLVCustomDrawSubItem basically works fine  :D
I still need to adapt the ShellCtrls.pas as mentioned, but if the BeginUpdate/EndUpdtes is not implemented here yet, i don't doubt about the effect.

First back to the treeview (my first pain), topic "AddIcon" only for the moment:
meanwhile i thought about, what would be effect if we query on the initial value (-1) before doing the AddIcon.
@GetMen: Then i tried again the VDT sample and verified (display of listimage count in the caption) that indeed it behaved correctly.  After some srolling up and down (all getData done) the counter did reach the maxium number of objects within the folder ...... but no longer increased above..
I looked inside the source and saw that you did exactly that (query on -1 as condition for the AddIcon steps).  The clue is not the clear of the listview. It is this if-condition.

@wp, would you like to verify within your last sample? 
At the beginning of STVGetImageIndex add:
Code: Pascal  [Select][+][-]
  1.   fMain.Caption := ilSTV.Count.ToString;
  2.   if Node.ImageIndex > -1 then exit;     // Probably: -1 seems to be the initial value of the node (no need to set i explicitely?
  3.  

Try it with and without this if-condition and iterate along folders. Look at the results.

So we have for now at least a working version of the treeview with icons, and without havng 5 million entries in the imagelist after an hour  8-)



Lazarus 3.2  FPC 3.2.2 Win10 64bit

balazsszekely

  • Guest
Re: ShellTreeView and system icons
« Reply #31 on: February 13, 2021, 04:29:01 pm »
With Delphi we can do something like this:
Code: Pascal  [Select][+][-]
  1. ImageList.Handle := SHGetFileInfoW('', 0, FileInfo, SizeOf(FileInfo), SHGFI_SMALLICON or SHGFI_SYSICONINDEX);
  2. ImageList.ShareIcons := True;

After the assigment, ImageList has access to system icons. Unfortunately the Handle property is readonly in Lazarus, so we must resort to hacks like ImageList.Add.
To completely remove the need of ImageList, I wrote a unit which gets the icons faster then the previously used methods and supports different icon size(ShellView_GetIcons.zip) .
I also attach the VirtualDrawTree demo, where TImageList is not used anymore. A directory with 10000 items can be loaded in less then 100 ms(ShellView_VDT_Trunk.zip). The same idea also works with custom drawn TShellListView, though  VDT is much faster.
« Last Edit: February 13, 2021, 04:32:40 pm by GetMem »

balazsszekely

  • Guest
Re: ShellTreeView and system icons
« Reply #32 on: February 13, 2021, 10:01:07 pm »
Finally the super fast TShellTreeView/TShellListView combination has arrived. :D  Please run the application outside the IDE. Unfortunately I had to switch back to ImageLists, because owner drawing is not working in TShellListView or at least not working properly.

PS: I deatach myself from this thread, enough shell programming for a year. :)
« Last Edit: February 13, 2021, 10:12:21 pm by GetMem »

wp

  • Hero Member
  • *****
  • Posts: 11923
Re: ShellTreeView and system icons
« Reply #33 on: February 13, 2021, 11:30:29 pm »
Now I uploaded a new version of TShellTreeView to Lazarus trunk in which the shell icons are automatically displayed when no imagelist is attached to the tree. This means no more user code is required to show the icons. Of course, it works only on Windows...

The feature can be turned off by setting the public property UseBultinIcons to false. Or when an ImageList with special icons is attached to the tree then these images have priority.

Unfortunately customdrawing in T(Shell)ListView is much more complicated, but I try to get a similar solution also for the ShellListview.

d7_2_laz

  • Hero Member
  • *****
  • Posts: 512
Re: ShellTreeView and system icons
« Reply #34 on: February 14, 2021, 10:54:47 am »
@you_both,

i cannot unerline anough how impressed i am about your contributios.
Are your aware that there had been threads around this topic since long time ago, eg. since 2009(!) in a long thread in the german forum?
Your contribution changes all. Modern speaking: 10000 likes from my side!

I meanwhile had integrated the OnGetImageIndex paradigm (for treeview) in my own context and the listview_setimage list approach in my virtual listview
and was very happy to have the icons for the treeview and in general the speed back i was used to have with the previous D7 handle assignment.
The new versiom for the listview is even faster and i try to adapt accordingly. Great!

About the listview ownerdraw a little remark: occasionally i noticed that with this version leaving a heavy populated folder took nearly the same time as entering it:
I wondered where the time was eaten, maybe in intensive internal graphical cleanup things, don't know. Might be considered for such an approach.
However the new version does not shou up this, it is simply excellent and it is great to hear that such will be part of the shell controls later.
 8-) :) ;D
Lazarus 3.2  FPC 3.2.2 Win10 64bit

jcmontherock

  • Full Member
  • ***
  • Posts: 236
Re: ShellTreeView and system icons
« Reply #35 on: February 15, 2021, 11:10:41 am »
@you both,

I tried to reuse your example, GetMem in your post #31 (unit usystemicons) with TTreeView. For that I changed FImageList and function GetIconIndex to public. How should I define ImageList in TTreeView ? I tried
"TreeView1.Images := TImageList(@SysIcons.FImageList)" or
"TreeView1.Images := TImageList(SysIcons.FImageList^)" but nothing works. Have you any idea ?
Windows 11 UTF8-64 - Lazarus 3.2-64 - FPC 3.2.2

balazsszekely

  • Guest
Re: ShellTreeView and system icons
« Reply #36 on: February 15, 2021, 11:31:39 am »
@jcmontherock
Quote
How should I define ImageList in TTreeView ?
You can't assign FImageList to a TImageList, unfortunately the Handle property is readonly in lazarus:
Code: Pascal  [Select][+][-]
  1. TreeView1.Images.Handle := SystemIcons.FImageList; //won't work
More over AFAIK TTreeView does not support virutal mode, so your code will be slow. The best solution is to switch to VirtualDrawTree.


jcmontherock

  • Full Member
  • ***
  • Posts: 236
Re: ShellTreeView and system icons
« Reply #37 on: February 16, 2021, 05:47:45 pm »
Thanks for your infos et your examples.
Windows 11 UTF8-64 - Lazarus 3.2-64 - FPC 3.2.2

wp

  • Hero Member
  • *****
  • Posts: 11923
Re: ShellTreeView and system icons
« Reply #38 on: March 09, 2021, 07:41:40 pm »
In current Lazarus trunk there is now a version of TShellTreeView and TShellListView in which the system icons are displayed automatically when no image list is attached. It does not utilize the last improvments which GetMem has brought up, but should be good for a start - see screenshot.

Note that this works only on Windows, for other widgetsets still no icons are displayed.

Note also that the code now has been moved into the widgetset. In the non-Windows widgetsets, "dummy" code makes sure that the widgetset architecture works. There is a potential risk that there are typos in the registration code of other widgetsets which could crash the application and/or the IDE when TShellTreeView and/or TShellListView are used. I tested gtk2, gtk3, qt4, qt5, and cocoa, but I could not test the other widgetsets supported by the LCL. Therefore I ask users of Laz trunk and these other widgetsets to test the ShellTreeView and ShellListView in a simple application, such as the attached one.

balazsszekely

  • Guest
Re: ShellTreeView and system icons
« Reply #39 on: March 09, 2021, 08:05:48 pm »
@wp

Quote
Note that this works only on Windows, for other widgetsets still no icons are displayed.
Double Commander does a pretty good job getting the icons on Linux and macOS. It's not perfect, but so far is the best from what I saw. I attach two screenshots with DC and the native file managers side by side. Unfortunately DC is a very large application, hopefully somebody has patience to extract the relevant part.

Donwload link: https://sourceforge.net/projects/doublecmd/
License: GNU Library or Lesser General Public License version 2.0 (LGPLv2)
              GNU General Public License version 2.0 (GPLv2)

El Salvador

  • Full Member
  • ***
  • Posts: 134
Re: ShellTreeView and system icons
« Reply #40 on: March 10, 2021, 11:04:11 am »
@wp

Quote
Note that this works only on Windows, for other widgetsets still no icons are displayed.
Double Commander does a pretty good job getting the icons on Linux and macOS. It's not perfect, but so far is the best from what I saw. I attach two screenshots with DC and the native file managers side by side. Unfortunately DC is a very large application, hopefully somebody has patience to extract the relevant part.

Donwload link: https://sourceforge.net/projects/doublecmd/
License: GNU Library or Lesser General Public License version 2.0 (LGPLv2)
              GNU General Public License version 2.0 (GPLv2)
I believe the code we are interested in may be in this unit: https://github.com/double-commander/doublecmd/blob/master/src/platform/upixmapmanager.pas

balazsszekely

  • Guest
Re: ShellTreeView and system icons
« Reply #41 on: March 10, 2021, 11:37:19 am »
@El Salvador
Quote
I believe the code we are interested in may be in this unit: https://github.com/double-commander/doublecmd/blob/master/src/platform/upixmapmanager.pas
Thanks! I really appreciate your effort. The final decision belongs to @wp.

wp

  • Hero Member
  • *****
  • Posts: 11923
Re: ShellTreeView and system icons
« Reply #42 on: March 10, 2021, 02:41:19 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.

d7_2_laz

  • Hero Member
  • *****
  • Posts: 512
Re: ShellTreeView and system icons
« Reply #43 on: March 15, 2021, 03:01:26 pm »
Hello wp,
small q. - is there any timeline when your changes / winx64 might be delivered officially?
(i'm not using the shellctrls  yet / not yet for the recent app, but would be very interested to try them out for other projects, and appreciate your efforts very much).
Lazarus 3.2  FPC 3.2.2 Win10 64bit

wp

  • Hero Member
  • *****
  • Posts: 11923
Re: ShellTreeView and system icons
« Reply #44 on: March 15, 2021, 03:25:46 pm »
Since it is a new feature it will be contained in Laz 2.2. Releasing 2.2 has recently been discussed in the devs mailing list, but no specific date has been mentioned.

 

TinyPortal © 2005-2018