The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: Custos on May 21, 2011, 10:34:13 AM

Title: Displaying icons in a listview.
Post by: Custos on May 21, 2011, 10:34:13 AM
Hello everyone,

I am looking for the fastest way to display icons in my listview that displays files and folders in a directory.  So far I have been using SHGetFileInfo and the system image list.  My problem is that the SHGetFileInfo is quite slow.  I notice in other programs and explorer that they load much faster.  I have read other suggestions on the net but they vary wildly.  Some suggest creating another thread to load the icons after you have displayed everything else.  I also read in the windows sdk that:
Quote"There are two ways to retrieve an object's icon. The simplest way is to call SHGetFileInfo. However, this approach is inflexible and may be slow. A more flexible and efficient way to retrieve an item's icon is to use IExtractIcon."
  I have played around with the IShellFolder and IExtractIcon interfaces to do just that but haven't had much luck with them.  I am new to COM programming but have been trying to wrap my head around it. 

Anyway, what method can I use that will be faster?  Should I not even bother with the COM stuff?  Any hints?

Thanks
Title: Re: Displaying icons in a listview.
Post by: Tedd on May 21, 2011, 11:14:35 AM
Write your own function which, given a filename, extracts the extension and uses that to reference an 'icon cache' and return the handle of the icon to be drawn (taking in to account no extension and folders.) If it's not found in the cache, use SHGetFileInfo to get the icon and add it to the list. Build up an image-list of the icons as you go.
And it's not a bad idea to seed the cache before you begin, with a few of the more common file types (folder, none, exe, txt, ...)
Title: Re: Displaying icons in a listview.
Post by: hfheatherfox07 on May 21, 2011, 04:25:19 PM
Quote from: Custos on May 21, 2011, 10:34:13 AM
Hello everyone,

I am looking for the fastest way to display icons in my listview that displays files and folders in a directory.  So far I have been using SHGetFileInfo and the system image list.  My problem is that the SHGetFileInfo is quite slow.  I notice in other programs and explorer that they load much faster.  I have read other suggestions on the net but they vary wildly.  Some suggest creating another thread to load the icons after you have displayed everything else.  I also read in the windows sdk that:
Quote"There are two ways to retrieve an object's icon. The simplest way is to call SHGetFileInfo. However, this approach is inflexible and may be slow. A more flexible and efficient way to retrieve an item's icon is to use IExtractIcon."
  I have played around with the IShellFolder and IExtractIcon interfaces to do just that but haven't had much luck with them.  I am new to COM programming but have been trying to wrap my head around it. 

Anyway, what method can I use that will be faster?  Should I not even bother with the COM stuff?  Any hints?

Thanks

Hi,
I saw your post and I have an example of that... here is "Listview #2 displaying icons"   :U there are more example there....

Originally I downloaded the file from Here:

http://members.a1.net/ranmasaotome/projects.html


Title: Re: Displaying icons in a listview.
Post by: Custos on May 21, 2011, 10:35:31 PM
Thanks for the replies. 

Tedd: I understand what you're getting at.  That method would probably be a lot faster but I would be missing out on the "real" icons for lots of files (exe files for example will probably all have their own icons).  I would like to be able to display the real icons for all files and folders and not a default icon dependent on the extension.

hfheatherfox07: I took a look at the example.  They create their own image list and add two icons to it and use those.  Unfortunately that's not what I'm looking for.  I want to be able to display the actual icons for every file and folder and I don't think creating an imagelist will help me do that.  If I didn't care about having default icons I could use it but in this case I want the real icons.

Explorer can do what I want nicely.  How can I do the same?
Title: Re: Displaying icons in a listview.
Post by: hfheatherfox07 on May 22, 2011, 01:54:31 AM
What you are describing I only saw done with a "loader"  - A loader is a little standalone program that is used to load another program:

here is an example of a loader ( wont do what you want, but will show you how to load, and you should be able to just load the icons)

http://www.reversing.be/article.php?story=20050305202101960


more examples on that site....
Title: Re: Displaying icons in a listview.
Post by: qWord on May 22, 2011, 02:05:28 AM
hfheatherfox07,
are you an programmer or an reserve engineer?
Title: Re: Displaying icons in a listview.
Post by: hfheatherfox07 on May 22, 2011, 02:11:00 AM
Quote from: qWord on May 22, 2011, 02:05:28 AM
hfheatherfox07,
are you an programmer or an reserve engineer?

LOL,

NO I am not a  reserve engineer LOL

Those guys have nice codes for stuff .... sometimes I Google a question and at the end I put "ASM" or "MASM" ... that is how I found this place

I don't really care were I learn from as long as it helps me....

by the way ,
Email me at lois must die (all one word) at yahoo.com

sorry ,I had too.... big family guy fan
Title: Re: Displaying icons in a listview.
Post by: qWord on May 22, 2011, 02:16:54 AM
sry,
I'm only sensitive when seeing the word loader in combination with commercial Software like 'Warcraft III 1.18 '.
Title: Re: Displaying icons in a listview.
Post by: hfheatherfox07 on May 22, 2011, 02:22:05 AM
Quote from: qWord on May 22, 2011, 02:16:54 AM
sry,
I'm only sensitive when seeing the word loader in combination with ......

wops , removed that link...
Title: Re: Displaying icons in a listview.
Post by: qWord on May 22, 2011, 02:23:30 AM
Quote from: hfheatherfox07 on May 22, 2011, 02:22:05 AM
wops , removed that link...
:thumbu
Title: Re: Displaying icons in a listview.
Post by: Custos on May 22, 2011, 02:26:44 AM
hfheatherfox07:  I appreciate the thought.  I am familiar with a loader however it will not do what I want (as you said).

qWord:  Any thoughts on my problem?  I've seen your responses to other posts around here and it seems like there is no question you can't answer.  :bg
Title: Re: Displaying icons in a listview.
Post by: qWord on May 22, 2011, 02:27:59 AM
Quote from: Custos on May 22, 2011, 02:26:44 AM... and it seems like there is no question you can't answer.  :bg
I can live with this  :bg
Title: Re: Displaying icons in a listview.
Post by: hfheatherfox07 on May 22, 2011, 02:36:10 AM
Sorry VB....

http://www.buygold.net/v06n09/v06n09.html
Title: Re: Displaying icons in a listview.
Post by: qWord on May 22, 2011, 02:37:44 AM
Custos ,
as an addition: IMO c# is the best solution for what are you trying to do . The code is easy to read and it is quick in execution for most common applications. However, it is your decision to whether use c#, c++ or what ever - as long as the speed is ok  :U
Title: Re: Displaying icons in a listview.
Post by: Custos on May 22, 2011, 03:01:40 AM
Thanks for the replies!

hfheatherfox07:  I have seen that page.  That code uses SHGetFileInfo which I have been using.  The only difference is that they create their own imagelist.  I can't see how that would be any faster than just asking SHGetFileInfo for SHGFI_SYSICONINDEX which is what I have been doing.  I've probably seen most of the pages like that, I've been searching for a solution for a while now.

qWord: I forgot to mention that I am programming in assembly...  I'm not concerned with how much code it takes I just want it to work.  For me assembly code is not too hard to read.  :bg  I'm thinking about just running a background thread to get the icons after all the text is loaded into the listview but I would rather not have to create a thread to solve this problem.
Title: Re: Displaying icons in a listview.
Post by: Gunner on May 22, 2011, 03:28:11 AM
How are you getting the system image list?  How are you calling SHGetFileInfo?  You explain a problem but no sample source?


use SHGFI_USEFILEATTRIBUTES so SHGetFileInfo does not "access" the file so it will be faster
invoke  SHGetFileInfo, PATHTOFILETOGETICONFOR, NULL, addr sfi, sizeof sfi,  SHGFI_SYSICONINDEX or SHGFI_USEFILEATTRIBUTES or SHGFI_LARGEICON or SHGFI_ICON
Title: Re: Displaying icons in a listview.
Post by: Custos on May 22, 2011, 04:05:16 AM
I am getting the system image list like this:

invoke SHGetFileInfo, NULL, 0, addr sfi, sizeof SHFILEINFO, SHGFI_SYSICONINDEX or SHGFI_SMALLICON
mov hImageListSmall, eax

After that I set the imagelist for the listview:
invoke SendMessage, hListview, LVM_SETIMAGELIST, LVSIL_SMALL, hImageListSmall

and have been calling SHGetFileInfo like this:

invoke SHGetFileInfo, addr filename, NULL,addr sfi,SIZEOF SHFILEINFO,SHGFI_SYSICONINDEX

I tried your suggestion but it did not make any noticeable improvement in speed.  Also, it only displays default program icons for executable files and I want display the actual program icons.

I did not post any sample source because I do not have a problem with my code.  The problem is that I am looking for a faster way to display the icons.

Thanks for your suggestion.
Title: Re: Displaying icons in a listview.
Post by: jj2007 on May 22, 2011, 07:14:34 AM
Quote from: Custos on May 22, 2011, 04:05:16 AM
The problem is that I am looking for a faster way to display the icons.

Don't ask for impossible things. Either your code, or the system, has to extract the icons from all executables. That is a lot of work for the hard disk.

The only way to speed this up is to carefully select the number of executables to those that are really being displayed - i.e. those 20-30 that actually show up in your listview.
Title: Re: Displaying icons in a listview.
Post by: dedndave on May 22, 2011, 11:17:56 AM
.... or, it may be that Windows Explorer has cached them someplace   :P

C:\Documents and Settings\Dave\Local Settings\Application Data\IconCache.db
Title: Re: Displaying icons in a listview.
Post by: Tedd on May 22, 2011, 01:46:23 PM
1. Do as I originally said
2. Treat .exes specially and extract their icons individually
3. Use I_IMAGECALLBACK for the image index when you add new items, and handle LVN_GETDISPINFO to find and set the real icon when requested (which is only when they're drawn)
3b. Add LVIF_DI_SETITEM to the mask when responding to LVN_GETDISPINFO, so you don't extract the same icons repeatedly.