So i did raise the quesetion, whether it is expected to work or not, and, if not, what should be the recommended strategy.In lazarus TListView is rendered entirely via a widget, but TTreeView images are rendered using LCL.
GetMem, can I ask you to complete the example with code for the TShellListView. It's an excellent sample for reference.
The link mentioned by Ally (above) gives a good starting point. As well as that one:Why don't you use Getmem's demo and merge it with ASerge's code? Did you check that?
https://forum.lazarus.freepascal.org/index.php/topic,35669.msg236441.html#msg236441
Here, see routine TShellListView1FileAdded (although it is not needed and i would not do a call of SHGetFileInfoW for each file added; better do it only once for a folder).
ASerge, did you mean TListView is entirely built by LCL? if it is able to allow Listview_SetImagelist, the more it would be desirable that the treeview allows such similar.Actually, I said that only TreeView renders the icons itself, but ListView uses the system. Therefore, it is useless for TreeView to set a non-LCL ImageList. But for ListView, it works.
Thanks a lot. Very helpful. Where to put it? wiki? CCR/applications? Lazarus/examples/?You're welcome. I don't have any preference, it's up to you.
many thanks for the sample!You're welcome!
Will this trunk needed be part of the next release?The next release(2.0.12) is a bugfix release. After that, what is now trunk will become Lazarus 2.2. Anyways in my previous post I attached two demo versions, one for 2.0.10 and one for trunk. Unfortunately the VirtualTreeView shipped with 2.0.10, it's slightly old and buggy. The fix is easy, just install "VirtualTreeView V5" with OPM(Menu->Package->Online Package Manager).
I think i can see the idea behind it i(it is based on VirtualTreeview control, and so i believe by my own usage of this control that it will be really fast enough).Yes. I believe it will be fast enough, but please run a few test.
Abut the icon access within: same question i had but cannot answer fo rmyself: will the continuous usage of Imagelist IconAdd, when iterating maybe the same directory multiple times, let the imagelist grow and grow and grow??Each icon is loaded only once. When you do a lot of drawing(scrolling the tree for example), the icons are re-used. The imagelist won't grow, it's cleared before the tree is populated.
Each icon is loaded only once. When you do a lot of drawing(scrolling the tree for example), the icons are re-used. The imagelist won't grow, it's cleared before the tree is populated.Could you please explain a little bit where (for to avoid to store the same object again and again) this clear is done when coming back to a previously visited folder again?
I think d7_2_laz's argument is valid. I took the demo of reply #12 (which does add icons to the image list) and added the line Caption := SLV.SmallImages.Count.ToString; at the end of the SLVFileAdded event handler -- it simply displays in the form caption the current count of icons of the ListView's imagelist. When I run the program and open the c:\Windows\System32 folder the icon count increases by about 100 on my system. Then I click some other folder, and the count increases again by some value. But when I return to C:\Windows\System32 the icon count increases by aonther 100 icons. This is a clear proof that the icons are re-added, otherwise the icon count should stay constant when a previously opened folder is revisited.QuoteEach icon is loaded only once. When you do a lot of drawing(scrolling the tree for example), the icons are re-used. The imagelist won't grow, it's cleared before the tree is populated.Could you please explain a little bit where (for to avoid to store the same object again and again) this clear is done when coming back to a previously visited folder again?
wp, yes of course, but it is still a construction zone and the icon is still a pure placeholderSorry, you did say that you work on the treeview but I did not get it... I am struggling with the ListView, and this is even worse.
Currently i'm stuck with mouse click will not respect the changed offsets.
The procedure (only this procedure) is attached.
Could you please explain a little bit where (for to avoid to store the same object again and again) this clear is done when coming back to a previously visited folder again?
I think d7_2_laz's argument is valid. I took the demo of reply #12 (which does add icons to the image list) and added the line Caption := SLV.SmallImages.Count.ToString; at the end of the SLVFileAdded event handler -- it simply displays in the form caption the current count of icons of the ListView's imagelist. When I run the program and open the c:\Windows\System32 folder the icon count increases by about 100 on my system. Then I click some other folder, and the count increases again by some value. But when I return to C:\Windows\System32 the icon count increases by aonther 100 icons. This is a clear proof that the icons are re-added, otherwise the icon count should stay constant when a previously opened folder is revisited.
How should I define ImageList in TTreeView ?You can't assign FImageList to a TImageList, unfortunately the Handle property is readonly in lazarus:
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.
@wpI believe the code we are interested in may be in this unit: https://github.com/double-commander/doublecmd/blob/master/src/platform/upixmapmanager.pasQuoteNote 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.pasThanks! I really appreciate your effort. The final decision belongs to @wp.
Thanks. Another hint is given by Anton Kavalenka in an attachment to bugreport https://bugs.freepascal.org/view.php?id=18247.Maybe I could look at it myself, but I don't guarantee anything (and in a short time).
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.
You see the overlay icons in the listview / Windows 64bitThe 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.
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.
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:
procedure TForm1.GetFileIcon(FilePath: String; var fIcon: TIcon); var FileName: WideString; FileInfo: TSHFileInfoW; ImageHandle: DWORD; begin FileName := UTF8ToUTF16(FilePath); ImageHandle := SHGetFileInfoW(PWideChar(FileName), 0, {%H-}FileInfo, SizeOf(FileInfo), SHGFI_USEFILEATTRIBUTES Or SHGFI_ICON or SHGFI_SMALLICON or SHGFI_SYSICONINDEX); if ImageHandle = 0 then Exit; fIcon.Handle := FileInfo.hIcon; end;
And it works fine.
Some progress in QT5. See attached image.Looks good!
Can you post a patch?I'm still working on it. For now I am adapting the GetMem demo for QT5. Then I'll move on to integrate the changes into Lazarus.
El Salvador, applied your patch.Thank you very much. These days I'll probably do a small patch (about executable files), but if someone were to test the code on the various distros in the meantime it would be great. Thank you everybody!