Sign in to follow this  
Followers 0
pcjames

How to get icon for FileCreateShortcut from shell32.dll

14 posts in this topic

I'm trying to get a shortcut "Add and Remove Programs" on my desktop. Can someone help/show/explain to me how to get a icon for a shortcut which I believe is in the shell32.dll. The code below creates but I can't figure out how to get the icon for it or am I going in the right direction?

FileCreateShortcut(@SystemDir & "\appwiz.cpl", @DesktopCommonDir & "\Add and Remove Programs.lnk", "", "", @SystemDir & "\shell32.dll")

Thanks in advance for any help!

Share this post


Link to post
Share on other sites



FileCreateShortcut ( "file", "lnk" [, "workdir" [, "args" [, "desc" [, "icon" [, "hotkey" [, icon number [, state]]]]]]] )

8)


NEWHeader1.png

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

I did read the functions page but for a newbie it's hard to know exactly what to do. Do I need all the [] in there? I'm not trying to create a hotkey and how do find out what Number to put in for the icon?

FileCreateShortcut(@SystemDir & "\appwiz.cpl", @DesktopCommonDir & "\Add and Remove Programs.lnk", "", "", @SystemDir & "\shell32.dll", "", "", "8", @SW_SHOWNORMAL)
Edited by pcjames

Share this post


Link to post
Share on other sites

I did read the functions page but for a newbie it's hard to know exactly what to do. Do I need all the [] in there? I'm not trying to create a hotkey and how do find out what Number to put in for the icon?

FileCreateShortcut(@SystemDir & "\appwiz.cpl", @DesktopCommonDir & "\Add and Remove Programs.lnk", "", "", @SystemDir & "\shell32.dll", "", "", "8", @SW_SHOWNORMAL)
Do I need all the [] in there? ... No

how do find out what Number to put in for the icon? ... use this

look for: C:\Program Files\AutoIt3\Examples\GUI\Advanced\enumicons.au3

8)


NEWHeader1.png

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Thank You for the heads up on how to find icon numbers, but now I have my "Icon Number" and I think I have everything in it's right place but when I run the script it still doesn't show a Icon.

FileCreateShortcut(@SystemDir & "\appwiz.cpl", @DesktopCommonDir & "\Add and Remove Programs.lnk", "", "", @SystemDir & "\shell32.dll", "", "", "-163", @SW_SHOWNORMAL)

So what am I doing wrong now?

Edited by pcjames

Share this post


Link to post
Share on other sites

FileCreateShortcut(@SystemDir & "\appwiz.cpl", @DesktopCommonDir & "\Add and Remove Programs.lnk", "", "", @SystemDir & "\shell32.dll", "", "", "-163", @SW_SHOWNORMAL)

FileCreateShortcut ( "file" , "lnk" , "workdir" , "args" [, "desc" [, "icon" [, "hotkey" [, icon number [, state]]]]]]] )

I think you need to re-align the correct parameters

8)


NEWHeader1.png

Share this post


Link to post
Share on other sites

FileCreateShortcut(@SystemDir & "\appwiz.cpl", @DesktopCommonDir & "\Add and Remove Programs.lnk", "", "", "Add and Remove Programs", @SystemDir & "\shell32.dll", "", "-163", @SW_SHOWNORMAL)

File = @SystemDir & "\appwiz.cpl"

lnk = @DesktopCommonDir & "\Add and Remove Programs.lnk"

workdir = ""

args = ""

desc = "Add and Remove Programs"

Icon = @SystemDir & "\shell32.dll"

hotkey = ""

Icon Number = "-163"

state = @SW_SHOWNORMAL

FileCreateShortcut( "file", "lnk"  ,"workdir","args"[,"desc" [,"icon"[, "hotkey" [, icon number [, state]]]]]]] )

I think I see what you was talking about, I was treating workdir & args @WindowsDir,"/e,c:\" as one " " instead of two " ", " " but it still doesn't work, do I have to put in anything for workdir? and args? according to the functions page it's says it's optional.

Confused! (of coarse I stay confused)

Share this post


Link to post
Share on other sites

Ok I got it working... when I ran the enumicons.au3 script (Icon Selector) the number it gave me was -163 and that was not giving me a icon then I changed it to 163 and it gave me a icon but the wrong one which was -164 on the Icon Selector, so I guess u have to subtract 1 from whatever number it gives you which in this case was 162

I'll post the correct code for others

FileCreateShortcut(@SystemDir & "\appwiz.cpl", @DesktopCommonDir & "\Add and Remove Programs.lnk", "", "", "Add and Remove Programs", @SystemDir & "\shell32.dll", "", "162", @SW_SHOWNORMAL)

Thanks for the lesson Valuater!

Share this post


Link to post
Share on other sites

If you can work out the icon index or ordinal your doing well...lol

When looking at shell32.dll in a resource viewer you can see the icon group name and the individual icon ordinal name..

But it doesn't help when using autoit...

For example when windows creates a shortcut and the number of the icon the shortcut uses does not equal the ordinal or group name or index in the resource.

emuicons.au3 does not show the ordinal or name that is in a resource.

The reason I say this is it doesn't actually check the ordinal or names in the resource which make getting the correct icon hit and miss or a fluke imho.

As for windows shortcuts and it's method of icon number that's also another kettle of fish..

From reading some threads on other forums windows translates a shortcuts icon index to a low order word..

So trying to use an index or ordinal number to get the correct icon also makes it harder to consistently get the correct icon you want.

Then autoit also uses a different method when using GuiCtrlSetImage() when setting icons..

Over all getting the icon wanted for a trivial task is not always as easy as it seems..lol

Example of icons in shell32.dll

the first icon groups names in shell32.dll start at 1 and go upto 54

then 133 upto 200

then 210

then 220 upto 338

then 512

then 1001 upto 1011

then 8240

then 16710

then 16715

then 16717 upto 16718

then 16721

Each icon group name contains multiple icons of different sizes and bit color which each icon has an ordinal name.

Ordinal name of an icon in a group isn't always in consecutive order.

icon group name 1 contains 6 icons each containing an ordinal name

ordinal names in the first group go from: 6 upto 11

So looking in emuicon.au3 to get a true ordinal or name and your bound to fail at some point.

Lazycat modded emicons.au3 to actually generate true ordinal and names by reading the resource...

But for some reason the example was replaced with the inferior emuicons.au3 that's included in autoit now.

Share this post


Link to post
Share on other sites

Thanks for the explanation lol... I thought I was doing something wrong (as usual). I'm quickly learning that trying to find the default icons is a chore, now I'm trying to get the Date and Time icon and found it in emuicons.au3 in the timedate.cpl and by name it says it's -1 and I've tried several numbers both ways with no luck :) Is there another way to try and find these?

Thanks James

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

.....

I'm trying to get the Date and Time icon and found it in emuicons.au3 in the timedate.cpl and by name it says it's -1 and I've tried several numbers both ways with no luck :) Is there another way to try and find these?

Thanks James

Hi,

Yep the timedate.cpl icon group name is 200 so in the shortcut index Parameter use "-200"

Group icon names are not always numbers, they can be a string..

For example "twunk_32.exe (found in the windows directory) group icon name is "TWUNK_ICO"

For using autoit's FileCreateShortcut() function you can use a name or index..

To be truthfull I'd use the icon group name.

Take the FileCreateShortcut() example and it uses index "15"

The icon the shortcut uses is the icon group name 16 when viewed in the shell32.dll.

So instead of using 15 try using "-16" and you get the same icon.

When it uses 15 it's actually basing 0 as the first icon, so 15 would be the 16th icon group based on a counting from 1 in shell32.dll...bahhh

Yet using the minus in front of the number makes the shortcut use the group icon name it appears.

If a group icon name isn't a number and there's no minus then it uses the name.

Say the Add and Remove icon you said about earlier.. The group icon name is actually 271 when you open shell32.dll in a resource viewer..

In your shortcut index use "-271" and you get the correct icon with no guessing involved...lol

Here's some code that shows the true icon group name, drop your file on the listview and it'll show the icon with it's true name.

Unlike enumicons.au3 with it's assuming that a icon group name is a number which isn't always the case

(twunk_32.exe shows exactly what I mean)

;Supported dropfiles: cpl, dll, exe, ocx

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
#include <WinAPI.au3>


Opt("GUIOnEventMode", 1)

Global $Default = @SystemDir & "\shell32.dll"
Global $hGui, $LV, $Extract, $LHT, $IHM
Global $aEN[1]

$hGui = GUICreate("", 500, 400, -1, -1, -1, BitOR($WS_EX_TOPMOST, $WS_EX_ACCEPTFILES))
GUISetOnEvent($GUI_EVENT_DROPPED, "GuiEvent", $hGui)
GUISetOnEvent($GUI_EVENT_CLOSE, "GuiEvent", $hGui)
$LV = GUICtrlCreateListView("", 5, 5, 490, 390, $LVS_ICON)
GUICtrlSetState(-1, $GUI_DROPACCEPTED)
GUICtrlSetTip(-1, "Drop a supported file here to view it's icons.")
_GUICtrlListView_SetView($LV, 1)
Update($Default)
GUISetState(@SW_SHOW, $hGui)


While 1
    Sleep(100)
WEnd

Func GuiEvent()
    Switch @GUI_CtrlId
        Case $GUI_EVENT_CLOSE
            Exit
        Case $GUI_EVENT_DROPPED
            If StringRegExp(@GUI_DragFile, "(?i)\.(cpl|dll|exe|ocx)", 0) Then
                _GUICtrlListView_DeleteAllItems($LV)
                $Default = @GUI_DragFile
                Update($Default)
            EndIf
    EndSwitch
EndFunc   ;==>GuiEvent

Func Update($sFile)
    Local Const $RT_GROUP_ICON = 14
    Local Const $LOAD_LIBRARY_AS_DATAFILE = 0x2
    Local $hModule, $hIcon, $iState = 0, $iGN = "?" 
    Switch $sFile
        Case "shell32.dll", "0"
            $hModule = _WinAPI_GetModuleHandle($sFile)
        Case Else
            Switch StringRight($sFile, 3)
                Case "exe","cpl", "dll", "ocx"
                    $hModule = _WinAPI_LoadLibraryEx($sFile, $LOAD_LIBRARY_AS_DATAFILE)
                    $State = 1
            EndSwitch       
    EndSwitch   
    _ResourceEnumNames($hModule, $RT_GROUP_ICON)
    If $State Then _WinAPI_FreeLibrary($hModule)
    WinSetTitle($hGui, "", "Icons found in file: " & $aEN[0])
    For $i = 1 To Ubound($aEN) -1
        GUICtrlCreateListViewItem("-" & $aEN[$i], $LV)
        GUICtrlSetImage(-1, $Default, -$i, 1)
    Next
    Dim $aEN[1]
EndFunc   ;==>Update

Func _ResourceEnumNames($hModule, $iType)
    Local $aRet, $xCB
    If Not $hModule Then Return SetError(1, 0, 0)
    $xCB = DllCallbackRegister('___EnumResNameProc', 'int', 'int_ptr;int_ptr;int_ptr;int_ptr')
    $aRet = DllCall('kernel32.dll', 'int', 'EnumResourceNamesW', 'ptr', $hModule, 'int', $iType, 'ptr', DllCallbackGetPtr($xCB), 'ptr', 0)
    DllCallbackFree($xCB)
    If $aRet[0] <> 1 Then Return SetError(2, 0, 0)
    Return SetError(0, 0, 1)
EndFunc   ;==>_ResourceEnumNames

Func ___EnumResNameProc($hModule, $pType, $pName, $lParam)
    Local $aSize = DllCall('kernel32.dll', 'int', 'GlobalSize', 'ptr', $pName), $tBuf
    If $aSize[0] Then
        $tBuf = DllStructCreate('wchar[' & $aSize[0] & ']', $pName)
        ReDim $aEN[UBound($aEN) + 1]
        $aEN[0] += 1
        $aEN[UBound($aEN) - 1] = DllStructGetData($tBuf, 1)
    Else
        ReDim $aEN[UBound($aEN) + 1]
        $aEN[0] += 1
        $aEN[UBound($aEN) - 1] = $pName
    EndIf
    Return 1
EndFunc   ;==>___EnumResNameProc

Edit:

This example will only work with 32bit modules.

Edited by smashly

Share this post


Link to post
Share on other sites

Hey Smashly, I'm sure you know I'm sorta new to Autoit, so Thanks for taking your time to explain this information to me, as a newbie it can be hard to just read the documentation i.e. functions page and to know what all their talking about and when your trying to learn, sometimes when you ask for help in forums (in general) some treat you as if you haven't read the documentation or searched the forums or even searched the internet about your problem. I'm sure there are a lot of peeps who are just lazy and want a quick answer, But I want to learn. I've been working with autoit for about a year now and have most of my unattended setup after windows installation 80% complete and I've read and read documentation, searched forums and the internet learning how to do this and in all that time I have never asked for any help up until last week when I just couldn't figure out how to go past something.

I own a computer repair business and 50% of my customers barely know how to do common task on a computer so I know how it is when someone ask for help and I'm thinking this is like "computer 101 1st grade material", doesn't everyone know this stuff! So with that being said I've come to know that everyone learns things differently and I'm not saying that I've had any problems with anyone here on the forums but I'm sure like myself with my customers, some do think or make you feel that you should know this stuff.

Sorry for being so long winded but I wanted to take my hat off to you and commend you on your explanation about icons and to Thank You for taking your time explaining this to where I can somewhat understand it and not treating me "like I should know this stuff" or should of read it in the documentation somewhere. Actually I think Autoit should have a forum named "Tutorials" and this information being a part of it! I know they have "Examples" and Valuater has an excellent tutorial, but it doesn't cover everything.

Now back to the topic... Oh man twunk_32.exe is a life saver! Thank You, Thank You! And now that I got your head swollen... is there a twunk_64.exe? I'll be working on 64-Bit after I get all my 32-bit stuff done...lol

Anyways I don't completely understand all about the groups yet or how they came to be but I do understand everything in your last post, it makes sense now.

Thanks Again, James

Share this post


Link to post
Share on other sites

This example will only work with 32bit modules.

Does anyone know a solution so that this will work with Win 7 64bit?

Share this post


Link to post
Share on other sites

Not an 'autoit' reply, but if you google 'extract icons' you'll find apps that will trawl your dlls etc and show the icons, convert them to other formats etc. then you can use them as you wish.

William

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0