AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Alternative way to load small icon from exe into listview?

 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Ask for Help
View previous topic :: View next topic  
Author Message
Serenity



Joined: 08 Nov 2004
Posts: 839

PostPosted: Thu Apr 13, 2006 1:49 pm    Post subject: Alternative way to load small icon from exe into listview? Reply with quote

On 2k I notice that 16x16 icons look degraded when loaded into a listview with ExtractIconA. I get this with the main listview example in the help file, and with ExtractAssociatedIconA, yet the same icons look fine in Explorer in list/detail mode. I'm not sure exactly why this is. I saw this thread and tried CopyImage but icons still look degraded, only slightly different to without CopyImage. Is it possible to load only the small icons instead of relying on the system to resize icons to fit?
_________________
"Anything worth doing is worth doing slowly." - Mae West
Back to top
View user's profile Send private message Visit poster's website
Chris
Site Admin


Joined: 02 Mar 2004
Posts: 10467

PostPosted: Thu Apr 13, 2006 2:37 pm    Post subject: Reply with quote

You could try using ExtractAssociatedIconEx(), but it requires Windows 2000 or later. Furthermore, I'm not sure if it's the method Explorer uses to get better quality icons.

If you find out more, please post here.
Back to top
View user's profile Send private message Send e-mail
Serenity



Joined: 08 Nov 2004
Posts: 839

PostPosted: Thu Apr 13, 2006 3:31 pm    Post subject: Reply with quote

Thanks Chris. I tried ExtractAssociatedIconEx() and for some reason DllCall returns -4, The specified function could not be found inside the DLL. I have version 5.0.3700.6705 of shell32.dll.
_________________
"Anything worth doing is worth doing slowly." - Mae West
Back to top
View user's profile Send private message Visit poster's website
PhiLho



Joined: 27 Dec 2005
Posts: 6721
Location: France (near Paris)

PostPosted: Thu Apr 13, 2006 3:35 pm    Post subject: Reply with quote

You can use Dependency Walker to check the list of functions exported by a given DLL.
_________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")
Back to top
View user's profile Send private message Visit poster's website
Serenity



Joined: 08 Nov 2004
Posts: 839

PostPosted: Thu Apr 13, 2006 3:45 pm    Post subject: Reply with quote

I tried this instead and it returns 0xc0000005, so the function was called, but something is wrong:

Code:
VarSetCapacity(this, 260)
this := array4
hIcon := DllCall("Shell32\ExtractAssociatedIconExA", UInt, 0, Str, this, UShortP, 0)
msgbox, % errorlevel


PhiLho wrote:
You can use Dependency Walker to check the list of functions exported by a given DLL.


Thanks, this confirmed the function exists. In my version of shell32.dll, there are four variations of this:

ExtractAssociatedIconA
ExtractAssociatedIconExA
ExtractAssociatedIconExW
ExtractAssociatedIconW
_________________
"Anything worth doing is worth doing slowly." - Mae West
Back to top
View user's profile Send private message Visit poster's website
Chris
Site Admin


Joined: 02 Mar 2004
Posts: 10467

PostPosted: Fri Apr 14, 2006 2:42 pm    Post subject: Reply with quote

Quote:
hIcon := DllCall("Shell32\ExtractAssociatedIconExA", UInt, 0, Str, this, UShortP, 0)
ExtractAssociatedIconEx seems to require 4 parameters but you're only passing 3. Also, you're passing zero for the third parameter, which might not be acceptable to the function (MSDN doesn't say for sure). The following seems to work:

VarSetCapacity(this, 260)
this := array4
hIcon := DllCall("Shell32\ExtractAssociatedIconExA", UInt, 0, Str, this, UShortP, IconIndex, UShortP, IconID)
Back to top
View user's profile Send private message Send e-mail
Serenity



Joined: 08 Nov 2004
Posts: 839

PostPosted: Fri Apr 14, 2006 3:02 pm    Post subject: Reply with quote

Thanks Chris, the following works for me, but if I change the third parameter to IconIndex, the wrong icons are loaded for some programs. In either case, the icons are still appear degraded.

hIcon := DllCall("Shell32\ExtractAssociatedIconExA", UInt, 0, Str, this, UShortP, 0, UShortP, IconID)
_________________
"Anything worth doing is worth doing slowly." - Mae West
Back to top
View user's profile Send private message Visit poster's website
Chris
Site Admin


Joined: 02 Mar 2004
Posts: 10467

PostPosted: Fri Apr 14, 2006 5:29 pm    Post subject: Reply with quote

Thanks for the follow-up. I've researched this some more and it appears that SHGetFileInfo() is the recommended way to get the high-quality small-icon associated with a file type. The following is a working example:
Code:
sfi_size = 352  ; Structure size of SHFILEINFO.
VarSetCapacity(sfi, sfi_size)
FileName := A_ScriptFullPath

if not DllCall("Shell32\SHGetFileInfoA", "str", FileName, "uint", 0, "str", sfi
   , "uint", sfi_size, "uint", 0x101)  ; 0x101 is SHGFI_ICON+SHGFI_SMALLICO
   MsgBox SHGetFileInfoA() indicated a failure.
else ; Icon successfully loaded.
{
   ; Extract the hIcon member from the structure:
   hIcon = 0
   Loop 4
      hIcon += *(&sfi + A_Index-1) << 8*(A_Index-1)
}
MsgBox %hIcon%
In the hopes that the above improves icon quality, I've applied it to the large example at the bottom of the ListView page. Please post here if you can determine whether the quality is in fact better, or if you have any problems with it.

Also note that a script should call DestroyIcon on the hIcon when it no longer needs it (though this will happen automatically when the script exits, so sometimes it's not necessary).

Thanks.

Edit: Fixed to include SHGFI_SMALLICO.


Last edited by Chris on Tue Jul 18, 2006 5:41 am; edited 1 time in total
Back to top
View user's profile Send private message Send e-mail
Lemming



Joined: 20 Dec 2005
Posts: 150
Location: Malaysia

PostPosted: Fri Apr 14, 2006 7:48 pm    Post subject: extract first? Reply with quote

Is it absolutely necessary for the script to load icons from an EXE? If not, you can extract the required icon beforehand using an icon editor, then save it to an .ico file. Ahk can then load the .ico file without any dllcalls.
Back to top
View user's profile Send private message
Tekl



Joined: 24 Sep 2004
Posts: 813
Location: Germany

PostPosted: Mon Jul 17, 2006 12:23 pm    Post subject: Reply with quote

Hi,

the example on the listview-page does not show high-quality small icons on my XP SP2 with AHK 1.0.44.7. Is it broken or what could be the reason?
_________________
Tekl
Back to top
View user's profile Send private message Visit poster's website
Tekl



Joined: 24 Sep 2004
Posts: 813
Location: Germany

PostPosted: Mon Jul 17, 2006 12:26 pm    Post subject: Reply with quote

Ahh... I tried 0x101 instead of 0x100 (SHGFI_ICON) to get the right small icon and it works.
_________________
Tekl
Back to top
View user's profile Send private message Visit poster's website
Chris
Site Admin


Joined: 02 Mar 2004
Posts: 10467

PostPosted: Tue Jul 18, 2006 5:40 am    Post subject: Reply with quote

Thanks for the tip; I've updated the example on the Listview page.
Back to top
View user's profile Send private message Send e-mail
skrommel



Joined: 30 Jul 2004
Posts: 175

PostPosted: Mon Jan 08, 2007 12:15 am    Post subject: Multiple icons Reply with quote

Smile Works great for the first icon in the file, but how about files with multiple icons?

I can't see any option to specify what icon to access in SHGetFileInfoA. The only thing I have found is FindResource.

There's a working sample with sourcecode at
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwui/html/msdn_icons.asp

Look for ReadIconFromEXEFile.

Skrommel
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Ask for Help All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group