BranchViewExtended wfx-plugin
Moderators: Hacker, petermad, Stefan2, white
- ghisler(Author)
- Site Admin
- Posts: 50386
- Joined: 2003-02-04, 09:46 UTC
- Location: Switzerland
- Contact:
Indeed if you do not call ExtractImage with parameter LR_SHARED, you must tell TC to delete the icon after using it! Otherwise you will get a memory leak. See
http://msdn.microsoft.com/en-us/library/ms648045%28VS.85%29.aspx
http://msdn.microsoft.com/en-us/library/ms648045%28VS.85%29.aspx
Author of Total Commander
https://www.ghisler.com
https://www.ghisler.com
I think this note is only for calling LoadImage in each FsExtractCustomIcon? If I extract icon only once during plugin initialization and tell to TC its handle every time, I do not create new resource and TC should not delete it.ghisler(Author) wrote:Indeed if you do not call ExtractImage with parameter LR_SHARED, you must tell TC to delete the icon after using it! Otherwise you will get a memory leak. See
http://msdn.microsoft.com/en-us/library/ms648045%28VS.85%29.aspx
Same here:kotlomoy wrote: -- When there is a LOT of directories (thousands) TC doesn't draw all my icons. More importantly that TC itself gets problems with redrawing of windows, buttons, menu...
Code: Select all
HINSTANCE theDll = NULL;
HICON hIcon16, hIcon32;
BOOL APIENTRY DllMain( HINSTANCE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
theDll = hModule;
hIcon16 = (HICON)LoadImage(theDll,MAKEINTRESOURCE(IDI_ICON_FOLDER16),IMAGE_ICON,16,16,0);
hIcon32 = (HICON)LoadImage(theDll,MAKEINTRESOURCE(IDI_ICON_FOLDER32),IMAGE_ICON,32,32,0);
return TRUE;
}
int __stdcall FsExtractCustomIcon(char* RemoteName,int ExtractFlags,HICON* TheIcon)
{
if ('/' == RemoteName[ strlen( RemoteName ) - 1 ])
{
if(ExtractFlags&FS_ICONFLAG_SMALL)
*TheIcon = hIcon16;
else
*TheIcon = hIcon32;
return FS_ICON_EXTRACTED;
}
return FS_ICON_USEDEFAULT;
}
Code: Select all
int __stdcall FsExtractCustomIcon(char* RemoteName,int ExtractFlags,HICON* TheIcon)
{
if ('/' == RemoteName[ strlen( RemoteName ) - 1 ])
{
if(ExtractFlags&FS_ICONFLAG_SMALL)
*TheIcon=(HICON)LoadImage(theDll,MAKEINTRESOURCE(IDI_ICON_FOLDER16),IMAGE_ICON,16,16,0);
else
*TheIcon=(HICON)LoadImage(theDll,MAKEINTRESOURCE(IDI_ICON_FOLDER32),IMAGE_ICON,32,32,0);
return FS_ICON_EXTRACTED_DESTROY;
}
return FS_ICON_USEDEFAULT;
}

#213083 Single user license
BranchViewExtended
BranchViewExtended
2MVV
Yes, I did.
Also I tried LoadIcon.
The result is same - after 9000-10000 dirs TC stops drawing my icons. TC draws 2-4 black squares then draws default icons. Then TC itself gets problems with redrawing.
Yes, I did.
Also I tried LoadIcon.
The result is same - after 9000-10000 dirs TC stops drawing my icons. TC draws 2-4 black squares then draws default icons. Then TC itself gets problems with redrawing.
#213083 Single user license
BranchViewExtended
BranchViewExtended
- ghisler(Author)
- Site Admin
- Posts: 50386
- Joined: 2003-02-04, 09:46 UTC
- Location: Switzerland
- Contact:
You can watch the number used GDI and USER objects in Task Manager (Ctrl+Shift+ESC), you need to switch on additional columns to see them. This will show you that the icons aren't freed...
Author of Total Commander
https://www.ghisler.com
https://www.ghisler.com
The problem is how to free icons. Where to free.ghisler(Author) wrote:You can watch the number used GDI and USER objects in Task Manager (Ctrl+Shift+ESC), you need to switch on additional columns to see them. This will show you that the icons aren't freed...
I've tried different ways but nothing works for me.
Can somebody give me a working example of FsExtractCustomIcon?

#213083 Single user license
BranchViewExtended
BranchViewExtended
- ghisler(Author)
- Site Admin
- Posts: 50386
- Joined: 2003-02-04, 09:46 UTC
- Location: Switzerland
- Contact:
Did you try to return
FS_ICON_EXTRACTED_DESTROY
TC will then delete the icon. You must NOT use LR_SHARED in LoadImage then.
FS_ICON_EXTRACTED_DESTROY
TC will then delete the icon. You must NOT use LR_SHARED in LoadImage then.
Author of Total Commander
https://www.ghisler.com
https://www.ghisler.com
After some testing I've found out that TC deletes icons on changing current path of file panel.ghisler(Author) wrote:Did you try to return
FS_ICON_EXTRACTED_DESTROY
TC will then delete the icon. You must NOT use LR_SHARED in LoadImage then.
If current path doesn't change TC DOES NOT DELETE ICONS.
So TC cannot show more than 9999 custom icons in file panel
#213083 Single user license
BranchViewExtended
BranchViewExtended
- ghisler(Author)
- Site Admin
- Posts: 50386
- Joined: 2003-02-04, 09:46 UTC
- Location: Switzerland
- Contact:
Indeed the icons are cached in the file list, so TC doesn't need to re-request them from the plugin all the time...
Author of Total Commander
https://www.ghisler.com
https://www.ghisler.com
MVV wrote:I suggest to return special folder icon instead of default icon. This will help to distinguish folders and files.
Unfortunately, my plugin cannot use custom iconskotlomoy wrote:If current path doesn't change TC DOES NOT DELETE ICONS.
So TC cannot show more than 9999 custom icons in file panel

#213083 Single user license
BranchViewExtended
BranchViewExtended
I do not understand why TC with your plugin can't show icons if you use one pre-extracted icon for all cases.kotlomoy wrote:Unfortunately, my plugin cannot use custom icons
Hm-m, you're right, when I return same icon handle for 15k of folders, TC uses 10k of GDI objects... LR_SHARED does not matter, ExtractIcon or LoadImage - also doesn't matter!!!



Hm-m, how icons are being cached? Does TC keep icon handles or draws icon into internal icons array? I think in first case TC will not use 10k of GDI objects for 10k calls of FsExtractCustomIcon because if you draw same GDI object 10k times, system will not create 10k objects. In the second case it is obvious that TC will have 10k of images in memory.
- ghisler(Author)
- Site Admin
- Posts: 50386
- Joined: 2003-02-04, 09:46 UTC
- Location: Switzerland
- Contact:
TC converts each icon to a bitmap with the needed foreground and background colors, and scaled to the correct size.
If all the icons are identical, or many of them, you need to tell TC about it!
From the description of FsExtractCustomIcon():
RemoteName
This is the full path to the file or directory whose icon is to be retrieved. When extracting an icon, you can return an icon name here - this ensures that the icon is only cached once in the calling program. The returned icon name must not be longer than MAX_PATH characters (including terminating 0!). The icon handle must still be returned in TheIcon!
So TC caches a separate bitmap for each different RemoteName. It's best to return the path,filename and icon Nr. of the file from which the icon was extracted.
If all the icons are identical, or many of them, you need to tell TC about it!
From the description of FsExtractCustomIcon():
RemoteName
This is the full path to the file or directory whose icon is to be retrieved. When extracting an icon, you can return an icon name here - this ensures that the icon is only cached once in the calling program. The returned icon name must not be longer than MAX_PATH characters (including terminating 0!). The icon handle must still be returned in TheIcon!
So TC caches a separate bitmap for each different RemoteName. It's best to return the path,filename and icon Nr. of the file from which the icon was extracted.
Author of Total Commander
https://www.ghisler.com
https://www.ghisler.com
Indeed, now icons are OKghisler(Author) wrote: RemoteName
When extracting an icon, you can return an icon name here - this ensures that the icon is only cached once in the calling program.

Version with icons:
http://cid-9a15473c9a985119.skydrive.live.com/self.aspx/!work/BranchViewEx%5E_icons.wfx
This version is slower than previuos (w/o icons) though

#213083 Single user license
BranchViewExtended
BranchViewExtended
- ghisler(Author)
- Site Admin
- Posts: 50386
- Joined: 2003-02-04, 09:46 UTC
- Location: Switzerland
- Contact:
How about returning FS_ICON_DELAYED immediately, and extracting the icon in background? Or are you doing that already?
This way TC will request the icons in a background thread only when needed, as it does for exe/lnk icons in the foreground.
This way TC will request the icons in a background thread only when needed, as it does for exe/lnk icons in the foreground.
Author of Total Commander
https://www.ghisler.com
https://www.ghisler.com