Skip to content

Instantly share code, notes, and snippets.

@AHK-just-me
Last active July 9, 2023 16:29
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save AHK-just-me/5518511 to your computer and use it in GitHub Desktop.
Save AHK-just-me/5518511 to your computer and use it in GitHub Desktop.
/* _______________________________________________________________________________________
_____ ______ __ _
|_ _| | ____| /_ || | _ _ _ SKAN (Suresh Kumar A N)
| | ___ ___ _ __ | |__ __ __ | || |_| | | | | | arian.suresh@gmail.com
| | / __/ _ \| '_ \| __| \ \/ / | ||___| | | ' | |
_| || (_| (_) | | | | |____ > < | | | | | |__| | Created on : 13-May-2008
|_____\___\___/|_| |_|______/_/\_\ |_|(_) |_| \.___/ Last Modified : 10-Aug-2012
[ I C O N E X P L O R E R A N D E X T R A C T O R ] Version : 1.4u
_______________________________________________________________________________________
*/
#NoEnv
#SingleInstance, Force
SetWorkingDir, %A_ScriptDir%
SetBatchLines, -1
Process, Priority, , High
; ======================================================================================================================
SaveButton := 0x79 -1 ; (VK code for F9) Note: modify -1 to -2 for F8 and so on...
KeyName := "F9" ; depends on the VK code you use above
Deff := A_ScriptDir ; Default ICON save folder
CallB := RegisterCallback("EnumResNameProc")
tFolder := A_WinDir . "\System32\shell32.dll" ; default folder in address bar
AhkVersion := A_AhkVersion . (A_IsUnicode ? (A_PtrSize = 8 ? " (U64)" : " (U32)") : " (ANSI)")
GuiTitle := "IconEx - v1.4u [ AutoHotkey v" . AhkVersion . " ]"
RT_GROUP_ICON := 14
RT_ICON := 3
STM_SETIMAGE := 0x172
If FileExist(A_Temp . "\IconEx.tmp") {
FileRead, tFolder, %A_Temp%\IconEx.tmp
FileDelete, %A_Temp%\IconEx.tmp
}
; ======================================================================================================================
Gui, Font, s10 Normal, Tahoma
Gui, Add, Combobox, x7 y7 w550 h21 Choose1 -Theme hwndhSHAC vtFolder, %tFolder%
ControlGet, hMyEdit, hWnd,, Edit1, ahk_id %hSHAC%
; SHAutoComplete(): Sean - http://www.autohotkey.com/forum/viewtopic.php?p=121621#121621
; For constants : http://www.codeproject.com/KB/edit/autocomp.aspx
DllCall("Shlwapi.dll\SHAutoComplete", "Ptr", hMyEdit, "UInt", 0x1|0x10000000)
Gui, Font, s8 Normal, Tahoma
Gui, Add, Button, x+2 w33 h24 +Default gUpdateResourceList, &Go
Gui, Add, Button, x+2 w52 h24 gSelectFolder, &Browse
Gui, Add, ListView
, x7 y+5 h280 w235 -Theme -E0x200 +0x4 +0x8 +Border vLVR gLVR +BackGroundFFFFFA c444466 AltSubmit
, Resource File|Icons|IconGroup
LV_ModifyCol(1 ,"170")
LV_ModifyCol(2, "42 Integer")
LV_ModifyCol(3, "0")
Gui, Add, ListView
, x+0 yp h280 w405 -Theme +Icon -E0x200 +0x100 +BackGroundFFFFFC cBB2222 Border AltSubmit vLVI gLVI hwndLVC2
Gui, Add, Hotkey, x2 y+79 w1 h1 +Disabled vHotkey gCreateSimpleIcon
Loop 8 {
Ix += 1
Gui, Add, Text, x+10 yp-70 0x1203 w70 h70 vI%Ix% hWndIcon%Ix% gSelectSimpleIcon
Gui, Add, Text, xp yp+70 0x201 w70 h16 vIconT%Ix%, -
}
Gui, Add, Text, x2 y+79 w1 h1
Loop 8 {
Ix += 1
Gui, Add, Text, x+10 yp-70 0x1203 w70 h70 vI%Ix% hWndIcon%Ix% gSelectSimpleIcon
Gui, Add, Text, xp yp+70 0x201 w70 h16 vIconT%Ix%, -
}
Gui, Add, Button, x7 y+30 gAccelerator, &File
Gui, Add, Button, x+5 gAccelerator, &Icon
Gui, Add, Button, x+5 gAccelerator, A&ddress Bar
Gui, Add, Button, x+5 gAccelerator, &Reload
Gui, Font
Gui, Add, StatusBar, vSB gFindTarget
SB_SetParts(40, 425)
GoSub, UpdateResourceList
SB_SetText("Type the path to a folder/file. Auto complete enabled", 2)
Gui, Show, w655 h535, %GuiTitle%
Return ; // end of auto-execute section //
; ======================================================================================================================
UpdateResourceList:
SendInput, {Escape}
ControlGetText,tFolder,, ahk_id %hSHAC%
If ! InStr(FileExist(tFolder), "D")
Folder := tFolder
Else Folder := tFolder . "\*.*"
GoSub, SetFolder
Gui, ListView, LVI
LV_Delete()
Gui, ListView, LVR
LV_Delete()
SB_SetText(" Loading files.. Please wait" , 2)
FileCount := 0
Loop, %Folder%
{
If A_LoopFileExt Not in EXE,DLL,CPL,SCR
Continue
hModule := LoadLibraryEx(A_LoopFileLongPath)
If (hModule = 0)
Continue
IGCount := 0
IconGroups := ""
DllCall("Kernel32.dll\EnumResourceNames", "Ptr", hModule, "Ptr", 14, "Ptr", CallB, "Ptr", 0)
DllCall("Kernel32.dll\FreeLibrary", "Ptr", hModule)
If (IGCount = 0)
Continue
FileCount++
StringUpper, FileName, A_LoopFileName
Gui, ListView, LVR
LV_ADD("", FileName, IGCount, IconGroups)
SB_SetText("`t" . FileCount, 1)
}
SB_SetText("`t" . FileCount, 1)
SB_SetText(" Done!" , 2)
GuiControl, Focus, LVR
RowNo := 1
GoSub, LVRSUB
Gui, ListView, LVI
LV_Modify(1, "Select")
Gui, ListView, LVR
GuiControl, Focus, LVR
LV_Modify(1, "Select")
GuiControl, Focus, tFolder
Return
; ======================================================================================================================
LVR:
If (A_GuiEvent = "k") {
If (A_EventInfo = 40 || A_EventInfo = 38) {
RowNo := LV_GetNext(0, "Focused")
GoTo, LVRSUB
Return
}
If (A_EventInfo = SaveButton) {
RowNo := LV_GetNext(0, "Focused")
If (RowNo <> 0)
GoSub, ExtractIconRes
Return
}
}
If (A_GuiEvent <> "Normal")
Return
RowNo := A_EventInfo
If (RowNo = 0) {
Loop, 16 {
GuiControl, , IconT%A_Index%, -
SendMessage, %STM_SETIMAGE%, 0x1, 0, , % "ahk_id " . Icon%A_Index%
}
Gui, ListView, LVI
LV_Delete()
If (ImageListID)
IL_Destroy(ImageListID)
ImageListID := 0
SB_SetText("", 2)
SB_SetText("", 3)
Return
}
LVRSUB:
Gui, ListView, LVR
LV_GetText(File, RowNo,1)
LV_GetText(IGC, RowNo,2)
LV_GetText(IG, RowNo,3)
SB_SetText("Press <" . KeyName . "> to save all icons in " . File , 2)
Gui, ListView, LVI
LV_Delete()
If (ImageListID)
IL_Destroy(ImageListID)
ImageListID := IL_Create(10, 10, 1)
LV_SetImageList(ImageListID)
Loop, %IGC%
IL_Add(ImageListID, tFolder . "\" . File, A_Index)
Loop, Parse, IG, |
{
Gui, ListView, LVI
LV_Add("Icon" . A_Index, A_LoopField)
}
RowNo := 1
GoSub, LVISUB
Gui, ListView, LVR
Return
; ======================================================================================================================
LVI:
Gui, ListView, LVI
If (A_GuiEvent = "k") {
If (A_EventInfo >= 37) && (A_EventInfo <= 40) {
RowNo := LV_GetNext(0, "Focused")
LV_GetText(IconGroup, RowNo, 1)
SB_SetText("Press <" . KeyName . "> to save the Icon Group " . IconGroup, 2)
GoTo, LVISUB
Return
}
If (A_EventInfo = SaveButton) {
RowNo := LV_GetNext(0, "Focused")
If (RowNo <> 0)
GoSub, ExtractIcon
Return
}
If (A_EventInfo = 0x79) {
GoSub, ApplyIconToFolder
Return
}
}
If (A_GuiEvent <> "Normal")
Return
RowNo := A_EventInfo
LV_GetText(IconGroup, RowNo, 1)
SB_SetText("Press <" . KeyName . "> to save the Icon Group " . IconGroup, 2)
LVISUB:
Gui, ListView, LVI
LV_GetText(IconGroup, RowNo,1)
hMod := LoadLibraryEx(tFolder . "\" . File)
Buff := GetResource(hMod, IconGroup, RT_GROUP_ICON, nSize, hResData)
Icos := NumGet(Buff + 4, 0, "UShort")
Buff += 6
SB_SetText("`t" . Icos . " Icons in < Group " . IconGroup . " >", 3)
Loop, %Icos% {
W := NumGet(Buff + 0, 0, "UChar")
H := NumGet(Buff + 0, 1, "UChar")
BPP := NumGet(Buff + 0, 6, "UShort")
nID := NumGet(Buff + 0, 12, "UShort")
Buff += 14
If ((W + H) = 0) {
SendMessage, %STM_SETIMAGE%, 0x1, 0, , % "ahk_id " . Icon%A_Index%
DllCall("Kernel32.dll\FreeResource", "Ptr", hResData)
GuiControl, ,IconT%A_Index%, PNG ICON
Continue
}
IconD := GetResource(hMod, nID, RT_ICON, nSize, hResData)
Wi := (W > 64) ? 64 : W
Hi := (H > 64) ? 64 : H
hIcon := DllCall("User32.dll\CreateIconFromResourceEx", "Ptr", IconD, "UInt", nSize, "Int", 1
, "UInt", 0x00030000, "Int", Wi, "Int", Hi, "UInt",(LR_SHARED := 0x8000), "UPtr")
SendMessage, %STM_SETIMAGE%, 0x1, 0, , % "ahk_id " . Icon%A_Index%
SendMessage, %STM_SETIMAGE%, 0x1, hIcon, , % "ahk_id " . Icon%A_Index%
DllCall("Kernel32.dll\FreeResource", "Ptr", hResData)
GuiControl, , IconT%A_Index%, %W%x%H%-%BPP%b
}
Loop % (16 - Icos) {
Ix := Icos + A_Index
GuiControl, , IconT%Ix%, -
SendMessage, %STM_SETIMAGE%, 0x1, 0, , % "ahk_id " . Icon%Ix%
}
DllCall("Kernel32.dll\FreeResource", "Ptr", hResData)
DllCall("Kernel32.dll\FreeLibrary", "Ptr", hModule)
Return
; ======================================================================================================================
ExtractIconRes:
FileSelectFolder, TargetFolder, *%DEFF%, 3, Extract Icons! Where to?
If (TargetFolder = "")
Return
GoSub, SetFolder
hModule := LoadLibraryEx(tFolder . "\" . File)
Loop, Parse, IG, |
{
FileN := SubStr("000" . A_Index, -3) . "-" . SubStr("00000" . A_LoopField, -4) . ".ico"
SB_SetText((FileN := TargetFolder . "\" . FileN), 2)
IconGroup := A_LoopField
GoSub, WriteIcon
}
DllCall("Kernel32.dll\FreeLibrary", "Ptr", hModule)
SB_SetText(IGC . " Icons extracted!", 2)
DllCall("Kernel32.dll\Sleep", "UInt", 1000)
SB_SetText(TargetFolder, 2)
Return
; ======================================================================================================================
ExtractIcon:
LV_GetText(IconGroup, RowNo, 1)
FileN := SaveIcon(Deff . "\" . File . "_IG" . SubStr("_00000" . IconGroup, -4) . ".ico")
If (FileN = "")
Return
hModule := LoadLibraryEx(tFolder . "\" . File)
GoSub, WriteIcon
DllCall("Kernel32.dll\FreeLibrary", "Ptr", hModule)
SB_SetText(FileN, 2)
Return
; ======================================================================================================================
WriteIcon:
hFile := FileOpen(FileN, "rw", "CP0")
sBuff := GetResource(hModule, IconGroup, RT_GROUP_ICON, nSize, hResData)
Icons := NumGet(sBuff + 0, 4, "UShort")
hFile.RawWrite(sBuff + 0, 6)
sBuff += 6
Loop, %Icons% {
hFile.RawWrite(sBuff + 0, 14)
hFile.WriteUShort(0)
sBuff += 14
}
DllCall("Kernel32.dll\FreeResource", "Ptr", hResData)
EOF := hFile.Pos
hFile.Pos := 18
Loop %Icons% {
nID := hFile.ReadUShort()
hFile.Seek(-2, 1)
hFile.WriteUInt(EOF)
DataOffSet := hFile.Pos
sBuff := GetResource(hModule, nID, RT_ICON, nSize, hResData)
hFile.Seek(-0, 2)
hFile.RawWrite(sBuff + 0, nSize)
DllCall("Kernel32.dll\FreeResource", "Ptr", hResData)
EOF := hFile.Pos
hFile.Pos := DataOffset + 12
}
hFile.CLose()
Return
; ======================================================================================================================
SelectSimpleIcon:
StringTrimLeft, FNo ,A_GuiControl, 1
GuiControlGet, IconT%fNo%
If ((IconT := IconT%fNo%) = "-")
Return
SB_SetText("Press <" . KeyName . "> to save Icon " . IconT . " from Icon Group " . IconGroup , 2)
GuiControl, Enable, Hotkey
GuiControl, Focus, Hotkey
GuiControl, ,Hotkey
SetTimer, DisableHotkey, -5000
Return
; ======================================================================================================================
DisableHotkey:
GuiControlGet, Hotkey, Enabled
If (Hotkey) {
GuiControl, ,Hotkey
GuiControl, Disable, Hotkey
GuiControl, Focus, LVI
StatusBarGetText, SbTxt, 2, IconEx
InStr(SbTxt, "to save Icon") ? SB_SetText("", 2) :
}
Return
; ======================================================================================================================
CreateSimpleIcon:
SB_SetText("", 2)
GuiControlGet, Hotkey
GuiControl, Disable, Hotkey
IfNotEqual, Hotkey, %KeyName%, Return
FileN := SaveIcon(Deff . "\" . File . "_" . SubStr("0000" IconGroup, -4) . "_"
. SubStr("0" . FNo, -1) . "_" . IconT . ".ico")
If (FileN = "")
Return
hModule := LoadLibraryEx(tFolder . "\" . File)
Buffer := GetResource(hModule, IconGroup, RT_GROUP_ICON, nSize, hResData)
tBuff := Buffer + 6 + ((Fno - 1) * 14)
nID := Numget(tBuff + 0, 12, "Ushort")
hFile := FileOpen(FileN, "w", "CP0")
hFile.WriteUShort(0)
hFile.WriteUShort(1)
hFile.WriteUShort(1)
hFile.RawWrite(tBuff + 0, 12)
hFile.WriteUInt(22)
DllCall("Kernel32.dll\FreeResource", "Ptr", hResData)
Buff := GetResource(hModule, nID, RT_ICON, nSize, hResData)
hFile.RawWrite(Buff + 0, nSize)
hFile.Close()
DllCall("Kernel32.dll\FreeResource", "Ptr", hResData)
DllCall("Kernel32.dll\FreeLibrary", "Ptr", hModule)
SB_SetText(FileN, 2)
Return
; ======================================================================================================================
FindTarget:
StatusBarGetText, SB, 2, A
If FileExist(SB)
Run, %COMSPEC% /c "Explorer /select`, %SB%", ,Hide
Return
; ======================================================================================================================
SetFolder:
ControlGetText, tFolder, , ahk_id %hSHAC%
If !InStr(FileExist(tFolder), "D") {
SplitPath, tFolder, , tFolder
StringUpper, tFolder, tFolder
ControlSetText, , %tFolder%, ahk_id %hSHAC%
}
Return
; ======================================================================================================================
SelectFolder:
GoSub, SetFolder
FileSelectFolder, nFolder, *%tFolder%, , Select a Resource Folder
If (nFolder = "")
Return
ControlSetText, ,%nFolder%, ahk_id %hSHAC%
GoSub, SetFolder
GoSub, UpdateResourceList
Return
; ======================================================================================================================
Accelerator:
If (A_GuiControl = "&File")
GuiControl, Focus, LVR
Else If (A_GuiControl = "&Icon")
GuiControl, Focus, LVI
ELse If (A_GuiControl = "A&ddress Bar")
GuiControl,Focus,tFolder
Else If (A_GuiControl = "&Reload") && FileExist(tFolder . "\" . File) {
FileAppend, %tFolder%\%File%, %A_Temp%\IconEx.tmp
Reload
}
Return
; ======================================================================================================================
ApplyIconToFolder:
FileSelectFolder, applyFolder, ::{20d04fe0-3aea-1069-a2d8-08002b30309d}, 0, Apply FolderIcon
If (applyFolder= "" || ErrorLevel)
Return
DesktopIni := applyFolder . "\Desktop.ini"
IniRead, iconFile, %DesktopIni%, .ShellClassInfo, IconFile, %A_Space%
If (SubStr(iconFile, 1, 7) == "IconEx_")
FileDelete, %applyFolder%\%iconFile%
iconFile := ("IconEx_" . HashStr(A_Now) . ".ico")
FileN := applyFolder . "\" . iconFile
hModule := LoadLibraryEx(tFolder . "\" . File)
LV_GetText(IconGroup, RowNo, 1)
GoSub, WriteIcon
DllCall("Kernel32.dll\FreeLibrary", "Ptr", hModule)
SB_SetText(FileN, 2)
IniWrite, %IconFile%, %DesktopIni%, .ShellClassInfo, IconFile
IniWrite, 0 , %DesktopIni%, .ShellClassInfo, IconIndex
FileSetAttrib, +S, %applyFolder%
FileSetAttrib, +SH, %DesktopIni%
FileSetAttrib, +SH, %FileN%
; SHCNE_ASSOCCHANGED := 0x8000000
DllCall("Shell32.dll\SHChangeNotify", "Int", 0x8000000, "UInt", 0x0, "Ptr", 0, "Ptr" ,0)
Run, Properties "%applyFolder%"
Return
; ======================================================================================================================
GuiContextMenu:
StatusBarGetText, SbTxt, 2, IconEx
StringTrimLeft, SbTxt, SbTxt, 14
If (SubStr(SbTxt, 1, 4) = "save")
SendInput, {%KeyName%}
Return
; ======================================================================================================================
GuiClose:
ExitApp
; ======================================================================================================================
EnumResNameProc(hModule, lpszType, lpszName, lParam) {
Global IconGroups, IGCount
If (lpszName > 0xFFFF)
lpszName := StrGet(lpszName)
IconGroups .= (IconGroups <> "" ? "|" : "") . lpszName
IGCount++
Return True
}
; ======================================================================================================================
GetResource(hModule, rName, rType, ByRef nSize, ByRef hResData) {
Arg := (rName + 0 = "") ? &rName : rName
hResource := DllCall("Kernel32.dll\FindResource", "Ptr", hModule, "Ptr", Arg, "Ptr", rType, "UPtr")
nSize := DllCall("Kernel32.dll\SizeofResource", "Ptr", hModule, "Ptr", hResource, "UInt")
hResData := DllCall("Kernel32.dll\LoadResource", "Ptr", hModule, "Ptr" , hResource, "UPtr")
Return DllCall("Kernel32.dll\LockResource", "Ptr", hResData, "UPtr")
}
; ======================================================================================================================
SaveIcon(Filename, Prompt := "Save Icon As") {
FileSelectFile, File, 16, %Filename%, %Prompt%, Icon (*.ico)
Return ((File <> "" && SubStr(File, -3) <> ".ico") ? File . ".ico" : File)
}
; ======================================================================================================================
LoadLibraryEx(File) {
Return DllCall("Kernel32.dll\LoadLibraryEx", "Str", File, "Ptr", 0, "UInt", 0x02, "UPtr")
}
; ======================================================================================================================
HashStr(sStr) {
VarSetCapacity(hHash, 16, 0)
DllCall("Shlwapi.dll\UrlHash", "Str", sStr, "UIntP", dHash, "UInt", 4)
If (A_IsUnicode)
DllCall("msvcrt.dll\swprintf", "Str", hHash, "Str", "%08X", "UInt", dHash)
Else
DllCall("msvcrt.dll\sprintf", "Str", hHash, "Str", "%08X", "UInt", dHash)
Return hHash
}
@Jonw82
Copy link

Jonw82 commented Aug 12, 2021

Is it possible to do something like this, but for bitmap image strips? Like toolbar icons (bitmaps) etc? This is really great for working with icons, thanks for sharing it. It makes it so much easier to find obscure icons deep inside of Window or another programs folder.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment