And it doesn't seem to be easy, specially when it comes to folders icons and shortcuts with shortcut overlay.
Here is what I have so far:
#NoEnv #Persistent #SingleInstance force SetWorkingDir %A_ScriptDir% Gui, +LastFound Gui, Add, Text, x25 y25 w150 h150 0x1203 HWNDhPreviewPic Gui, Show,w200 h200,PathIcon Return GuiDropFiles: STM_SETIMAGE(hPreviewPic, A_GuiEvent) Return GuiClose: ExitApp STM_SETIMAGE(hControl, p_ImageFile) { global ImagePath,IconIndex static h_icon DefaultFolderIdx:= 1 DefaultFileIdx:= 3 DefaultExecutableIdx:= 2 SendMessage, ( STM_SETIMAGE:=0x172 ), 0x1, 0,, ahk_id %hControl% ImagePath:= Instr(FileExist(p_ImageFile), "D") ? A_ScriptFullPath : p_ImageFile IconIndex:= Instr(FileExist(p_ImageFile), "D") ? 1 : 0 DLLCall("DestroyIcon", "Int", h_icon) If Instr(FileExist(p_ImageFile), "D") GetFolderIcon(p_ImageFile, ImagePath, IconIndex) If (DllCall("PrivateExtractIcons", "str", ImagePath, "int", IconIndex, "int", 128, "int", 128, "uint*", h_icon, "uint*", 0, "uint", 1, "uint", 0, "int") <= 0) { If Instr(FileExist(p_ImageFile), "D") ImagePath:= A_ScriptFullPath, IconIndex:= DefaultFolderIdx ; default Else { SplitPath, ImagePath,,, OutExtension If OutExtension { ; EXE with no icon If (OutExtension = "exe") ImagePath:= A_ScriptFullPath, IconIndex:= DefaultExecutableIdx ; Shortcut, look for target Else If (OutExtension = "lnk") { FileGetShortcut, %ImagePath%, OutTarget SplitPath, OutTarget,,, OutExtension If Instr(FileExist(OutTarget), "D") { ;Folder shortcut GetFolderIcon(OutTarget, ImagePath, IconIndex) If !ImagePath ImagePath:= A_ScriptFullPath, IconIndex:= DefaultFolderIdx } Else getExtIcon(OutExtension, ImagePath, IconIndex) } ; File type Else { getExtIcon(OutExtension, ImagePath, IconIndex) If !ImagePath ImagePath:= A_ScriptFullPath, IconIndex:= DefaultFileIdx } } ; File type that has no icon Else ImagePath:= A_ScriptFullPath, IconIndex:= DefaultFileIdx } ; MsgBox, % ImagePath "`n`n" IconIndex DllCall("PrivateExtractIcons", "str", ImagePath, "int", IconIndex, "int", 128, "int", 128, "uint*", h_icon, "uint*", 0, "uint", 1, "uint", 0, "int") ; If (DllCall("PrivateExtractIcons", "str", ImagePath, "int", IconIndex, "int", 128, "int", 128, "uint*", h_icon, "uint*", 0, "uint", 1, "uint", 0, "int") <= 0) { ; Everything above failed :/ ; } } SendMessage, ( STM_SETIMAGE:=0x172 ), 0x1, h_icon,, ahk_id %hControl% } GetFolderIcon(Folder, ByRef IconFile, ByRef IconIndex) { IniRead, IconFile, %Folder%\desktop.ini, .ShellClassInfo, IconFile, %A_Space% IniRead, IconIndex, %Folder%\desktop.ini, .ShellClassInfo, IconIndex, %A_Space% If !IconFile { IniRead, IconResource, %Folder%\desktop.ini, .ShellClassInfo, IconResource, %A_Space% If !IconResource Return StringSplit, I, IconResource, `, IconFile:= I1, IconIndex:= I2 } StringReplace,IconFile, IconFile, `%ProgramFiles`%, %A_ProgramFiles%, All StringReplace,IconFile, IconFile, `%windir`%, %A_WinDir%, All If Instr(IconFile, "\") IconFile:= GetFullPath(Folder, IconFile) IconFile:= !FileExist(IconFile) && !FileExist(A_WinDir "\System32\" IconFile) ? "" : IconFile } getExtIcon(Ext, ByRef ImagePath, ByRef IconIndex) { RegRead, from, HKEY_CLASSES_ROOT, .%Ext% RegRead, DefaultIcon, HKEY_CLASSES_ROOT, %from%\DefaultIcon StringReplace, DefaultIcon, DefaultIcon, `",,all ;" StringReplace, DefaultIcon, DefaultIcon, `%SystemRoot`%, %A_WinDir%,all StringReplace, DefaultIcon, DefaultIcon, `%ProgramFiles`%, %A_ProgramFiles%,all StringReplace, DefaultIcon, DefaultIcon, `%windir`%, %A_WinDir%,all I1 := I2:= "" StringSplit, I, DefaultIcon, `, StringReplace,I1, I1, `%ProgramFiles`%, %A_ProgramFiles%, All StringReplace,ImagePath, I1, `%windir`%, %A_WinDir%, All ImagePath:= !FileExist(ImagePath) && !FileExist(A_WinDir "\System32\" ImagePath) ? "" : ImagePath IconIndex:= (I2 < 0) ? IndexOfIconResource( I1, RegExReplace(I2, "[^\d]+"))-1 : I2 IconIndex:= IconIndex < 0 ? 0 : IconIndex } IndexOfIconResource(Filename, ID) { 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) enumproc := RegisterCallback("IndexOfIconResource_EnumIconResources","F") VarSetCapacity(param,12,0), NumPut(ID,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) : 0 } ;http://www.autohotkey.com/forum/viewtopic.php?p=168951#168951 IndexOfIconResource_EnumIconResources(hModule, lpszType, lpszName, lParam) { NumPut(NumGet(lParam+4)+1, lParam+4) if (lpszName = NumGet(lParam+0)) { NumPut(1, lParam+8) return false ; break } return true }
Use compiled script for included icons.
But I believe there must be a better way using DllCall to do the job.
If anyone got an idea I appreciate that.
Thanks