Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

How to get the Icon Group Number ?


  • Please log in to reply
26 replies to this topic
ladiko
  • Members
  • 290 posts
  • Last active: Jan 16 2012 11:46 PM
  • Joined: 13 Jul 2006
Does anybody know how to get the IconGroup number if i have the IndexNumber that MS Windows uses?

f.e. explorer.exe,0 is the explorer's default icon for windows, but to extract it with reshacker, i need the icongroup number that is 100 for the explorer.exe

reshacker.exe -extract "c:\windows\explorer.exe, "d:\explorer_main.ico" , icongroup,100,1033


Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
Try this:
MsgBox % ResourceIdOfIcon(A_WinDir "\explorer.exe", 0)

ResourceIdOfIcon(Filename, IconIndex)
{
    hmod := DllCall("GetModuleHandle", "str", Filename)
    ; If the DLL isn't already loaded, load it as a data file.
    loaded := !hmod
        && hmod := DllCall("LoadLibraryEx", "str", Filename, "uint", 0, "uint", 0x2)
    
    if !hmod
        return
    
    enumproc := RegisterCallback("ResourceIdOfIcon_EnumIconResources","F")
    VarSetCapacity(param,12,0), NumPut(IconIndex,param,0)
    ; Enumerate the icon group resources. (RT_GROUP_ICON=14)
    DllCall("EnumResourceNames", "uint", hmod, "uint", 14, "uint", enumproc, "uint", ¶m)
    DllCall("GlobalFree", "uint", enumproc)
    
    ; If we loaded the DLL, free it now.
    if loaded
        DllCall("FreeLibrary", "uint", hmod)
    
    return NumGet(param,8) ? NumGet(param,4) : ""
}

ResourceIdOfIcon_EnumIconResources(hModule, lpszType, lpszName, lParam)
{
    index := NumGet(lParam+4)
    if (index = NumGet(lParam+0))
    {   ; for named resources, lpszName might not be valid once we return (?)
        ; if (lpszName >> 16 == 0), lpszName is an integer resource ID.
        NumPut(lpszName, lParam+4)
        NumPut(1, lParam+8)
        return false    ; break
    }
    NumPut(index+1, lParam+4)
    return true
}
It is based on IndexOfIconResource, which I posted in this thread.

(Edit: ResourceIdOfIcon now returns blank if the icon at the specified index doesn't exist, in case 0 is a valid resource ID.)

ladiko
  • Members
  • 290 posts
  • Last active: Jan 16 2012 11:46 PM
  • Joined: 13 Jul 2006
i tested this: <!-- m -->http://phpfi.com/306605<!-- m --> cause you have ResourceIdOfIcon() and IndexOfIconResource() but both msgboxes show me 0 =(

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

MsgBox % ResourceIdOfIcon(A_WinDir "\explorer.exe", 100)

This attempts to get the resource ID of the 101st icon in explorer.exe (0 is the first icon). Since there are less then 101 icons, it returns 0. You wanted to get the "IconGroup number", given the "IndexNumber", right?
IconGroup := ResourceIdOfIcon(A_WinDir "\explorer.exe", IndexNumber)
If IndexNumber is 0, it should set IconGroup to 100...

MsgBox % IndexOfIconResource(A_WinDir "\shell32.dll", 324)

Shell32.dll is in %A_WinDir%\System32, not %A_WinDir%.

ladiko
  • Members
  • 290 posts
  • Last active: Jan 16 2012 11:46 PM
  • Joined: 13 Jul 2006
ahh ok yes that's right, now it works!

thank you very much! i wanna use it for the Compile_AHK script. :-)

ExplExe := A_WinDir . "\explorer.exe"
Shell32dll := A_WinDir "\System32\shell32.dll"

IfExist , %ExplExe%
	IconIDList = %ExplExe% has following Icons:`n
IfExist , %Shell32dll%
	IconIDList2 = %Shell32dll% has following Icons:`n

Loop , 100
{
	TempIcon := ResourceIdOfIcon( ExplExe , A_Index - 1)
	If TempIcon != 0
		IconIDList .= (A_Index - 1) . " = " . TempIcon . "`t"
	
	TempIcon := ResourceIdOfIcon( Shell32dll , A_Index - 1)
	If TempIcon != 0
		IconIDList2 .= (A_Index - 1) . " = " . TempIcon . "`t"
	
	If Mod(A_Index,10) = 0
	{
		IconIDList .= "`n"
		IconIDList2 .= "`n"
	}
}
Msgbox , %IconIDList%`n`n%IconIDList2%
results in:
C:\WINDOWS\explorer.exe has following Icons:
0 = 100	1 = 101	2 = 102	3 = 103	4 = 104	5 = 107	6 = 108	7 = 109	8 = 110	9 = 111	
10 = 205	11 = 250	12 = 251	13 = 252	14 = 253	15 = 254	16 = 256	17 = 257	

C:\WINDOWS\System32\shell32.dll has following Icons:
0 = 1	1 = 2	2 = 3	3 = 4	4 = 5	5 = 6	6 = 7	7 = 8	8 = 9	9 = 10	
10 = 11	11 = 12	12 = 13	13 = 14	14 = 15	15 = 16	16 = 17	17 = 18	18 = 19	19 = 20	
20 = 21	21 = 22	22 = 23	23 = 24	24 = 25	25 = 26	26 = 27	27 = 28	28 = 29	29 = 30	
30 = 31	31 = 32	32 = 33	33 = 34	34 = 35	35 = 36	36 = 37	37 = 38	38 = 39	39 = 40	
40 = 41	41 = 42	42 = 43	43 = 44	44 = 45	45 = 46	46 = 47	47 = 48	48 = 49	49 = 50	
50 = 51	51 = 52	52 = 53	53 = 54	54 = 133	55 = 134	56 = 135	57 = 137	58 = 138	59 = 139	
60 = 140	61 = 141	62 = 142	63 = 143	64 = 144	65 = 145	66 = 146	67 = 147	68 = 148	69 = 151	
70 = 152	71 = 153	72 = 154	73 = 155	74 = 156	75 = 157	76 = 160	77 = 161	78 = 165	79 = 166	
80 = 167	81 = 168	82 = 169	83 = 170	84 = 171	85 = 172	86 = 173	87 = 174	88 = 175	89 = 176	
90 = 177	91 = 178	92 = 179	93 = 180	94 = 181	95 = 182	96 = 183	97 = 184	98 = 185	99 = 186

what does the IndexOfIconResource() in the other thread do?

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
The opposite. :lol: IndexOfIconResource(File, ResourceIdOfIcon(File, Index)) should return Index+1 as long as File and Index are valid. IndexOfIconResource is intended to convert a resource ID (the "IconGroup number" as you referred to it) to a one-based icon index usable with AutoHotkey's various icon-loading commands. Windows uses zero-based icon indices, hence the +1.

Btw, *_EnumIconResources is called once for each icon group up to the icon group identified by the index or resource ID. If you intend to enumerate all icon groups, it would be more efficient to use EnumResourceNames than to use ResourceIdOfIcon in a loop. You may adapt either function for this...

ladiko
  • Members
  • 290 posts
  • Last active: Jan 16 2012 11:46 PM
  • Joined: 13 Jul 2006
no, it was just a test, i dont want to enumerate them all. like i wrote, i want to get the IconGroupNumber to use it with reshacker. the linked script compile_ahk is for compiling ahk-scripts with changed versioninfo, changed icons etc. and now i added an PickIconDlg to choose an icon. so i get windows' zero-based index, but i need the icongroup cause reshacker uses icongroup numbers to replace icons. your code is a great help! if it wouldnt exist i had to use another program to get the icon.

ladiko
  • Members
  • 290 posts
  • Last active: Jan 16 2012 11:46 PM
  • Joined: 13 Jul 2006
on my winows vista machine i get
C:\Windows\explorer.exe has following Icons:
0 = 	1 = 	2 = 	3 = 	4 = 	5 = 	6 = 	7 = 	8 = 	9 = 	
10 = 	11 = 	12 = 	13 = 	14 = 	15 = 	16 = 	17 = 	18 = 	19 = 	
20 = 	21 = 	22 = 	23 = 	24 = 	25 = 	26 = 	27 = 	28 = 	29 = 	
30 = 	31 = 	32 = 	33 = 	34 = 	35 = 	36 = 	37 = 	38 = 	39 = 	
40 = 	41 = 	42 = 	43 = 	44 = 	45 = 	46 = 	47 = 	48 = 	49 = 	
50 = 	51 = 	52 = 	53 = 	54 = 	55 = 	56 = 	57 = 	58 = 	59 = 	
60 = 	61 = 	62 = 	63 = 	64 = 	65 = 	66 = 	67 = 	68 = 	69 = 	
70 = 	71 = 	72 = 	73 = 	74 = 	75 = 	76 = 	77 = 	78 = 	79 = 	
80 = 	81 = 	82 = 	83 = 	84 = 	85 = 	86 = 	87 = 	88 = 	89 = 	
90 = 	91 = 	92 = 	93 = 	94 = 	95 = 	96 = 	97 = 	98 = 	99 = 	


C:\Windows\System32\shell32.dll has following Icons:
0 = 	1 = 	2 = 	3 = 	4 = 	5 = 	6 = 	7 = 	8 = 	9 = 	
10 = 	11 = 	12 = 	13 = 	14 = 	15 = 	16 = 	17 = 	18 = 	19 = 	
20 = 	21 = 	22 = 	23 = 	24 = 	25 = 	26 = 	27 = 	28 = 	29 = 	
30 = 	31 = 	32 = 	33 = 	34 = 	35 = 	36 = 	37 = 	38 = 	39 = 	
40 = 	41 = 	42 = 	43 = 	44 = 	45 = 	46 = 	47 = 	48 = 	49 = 	
50 = 	51 = 	52 = 	53 = 	54 = 	55 = 	56 = 	57 = 	58 = 	59 = 	
60 = 	61 = 	62 = 	63 = 	64 = 	65 = 	66 = 	67 = 	68 = 	69 = 	
70 = 	71 = 	72 = 	73 = 	74 = 	75 = 	76 = 	77 = 	78 = 	79 = 	
80 = 	81 = 	82 = 	83 = 	84 = 	85 = 	86 = 	87 = 	88 = 	89 = 	
90 = 	91 = 	92 = 	93 = 	94 = 	95 = 	96 = 	97 = 	98 = 	99 =

hmm =(

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
Are you talking about the script in your previous post? It works fine for me on Vista. Actually, I developed both functions while on a rather typical Vista install.

ladiko
  • Members
  • 290 posts
  • Last active: Jan 16 2012 11:46 PM
  • Joined: 13 Jul 2006
hmm interesting oO

so here is the full script: <!-- m -->http://phpfi.com/306855<!-- m -->

maybe there is an mistake in the script? do you have sp1 installed? i do and got an problem with another script that uses DllCall with RegisterCallback that also works fine on xp, but not vista business sp1.

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
Yes, I have SP1 installed. I am on 32-bit Vista Business. UAC is enabled and the script works with or without elevated privileges. If you're using a more limited account or are joined to a domain, perhaps that would make a difference. Anti-virus software or DEP (data execution prevention) might conceivably cause problems.

What's with
MsgBox %hmod%
? Does it show 0? If so, check %A_LastError%. If not, replace the DllCall("EnumResourceNames"...) line with the following and let me know the output:
r := DllCall("EnumResourceNames", "uint", hmod, "uint", 14, "uint", enumproc, "uint", ¶m)
MsgBox return: %r%`nErrorLevel: %ErrorLevel%`nlast error: %A_LastError%
Btw, there is an AutoHotkey Pastebin.

ladiko
  • Members
  • 290 posts
  • Last active: Jan 16 2012 11:46 PM
  • Joined: 13 Jul 2006
i will test it if i'm back home. great to know that there is a special ahk pastebin :-) but the not switchable auto-expire feature is a reason to not use it - i often use pastebins to "store" code snipets /old revisions of scripts for me (and others). who is the owner of the site?

ladiko
  • Members
  • 290 posts
  • Last active: Jan 16 2012 11:46 PM
  • Joined: 13 Jul 2006
i hope i inserted your code correct: <!-- m -->http://phpfi.com/307022?lang=ada<!-- m -->
the result is: <!-- m -->http://phpfi.com/307023?lang=cpp<!-- m -->

why is only the first adress different from the others? could you imagine whats wrong?

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

who is the owner of the site?

I think Titan manages it. <!-- m -->https://ahknet.autohotkey.com/paste<!-- m --> also redirects to there. (It is in the topic of the AutoHotkey IRC channel.)

why is only the first adress different from the others? could you imagine whats wrong?

That is strange. Since they all get the same result, perhaps it is incorrect for all of them. I'm not sure how that could happen.

Error code 998 is ERROR_NOACCESS: Invalid access to memory location.

I get 15106 (ERROR_RESOURCE_ENUM_USER_STOP, meaning the script stopped enumeration) if the icon was found and 0 if all icons were enumerated without finding the right one.

ladiko
  • Members
  • 290 posts
  • Last active: Jan 16 2012 11:46 PM
  • Joined: 13 Jul 2006
thank you again lexikos! now it works and i could finish my update for compile_ahk --> <!-- m -->http://www.autohotke...ic.php?p=146598<!-- m -->