forked from AutoHotkey/Ahk2Exe
-
Notifications
You must be signed in to change notification settings - Fork 11
/
IconChanger.ahk
99 lines (76 loc) · 2.46 KB
/
IconChanger.ahk
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
; This code is based on Ahk2Exe's changeicon.cpp
ReplaceAhkIcon(re, IcoFile, ExeFile)
{
global _EI_HighestIconID
static iconID := 159
ids := EnumIcons(ExeFile, iconID)
if !IsObject(ids)
return false
f := FileOpen(IcoFile, "r")
if !IsObject(f)
return false
VarSetCapacity(igh, 8), f.RawRead(igh, 6)
if NumGet(igh, 0, "UShort") != 0 || NumGet(igh, 2, "UShort") != 1
return false
wCount := NumGet(igh, 4, "UShort")
VarSetCapacity(rsrcIconGroup, rsrcIconGroupSize := 6 + wCount*14)
NumPut(NumGet(igh, "Int64"), rsrcIconGroup, "Int64") ; fast copy
ige := &rsrcIconGroup + 6
; Delete all the images
Loop, % ids.MaxIndex()
DllCall("UpdateResource", "ptr", re, "ptr", 3, "ptr", ids[A_Index], "ushort", 0x409, "ptr", 0, "uint", 0, "uint")
Loop, %wCount%
{
thisID := ids[A_Index]
if !thisID
thisID := ++ _EI_HighestIconID
f.RawRead(ige+0, 12) ; read all but the offset
NumPut(thisID, ige+12, "UShort")
imgOffset := f.ReadUInt()
oldPos := f.Pos
f.Pos := imgOffset
VarSetCapacity(iconData, iconDataSize := NumGet(ige+8, "UInt"))
f.RawRead(iconData, iconDataSize)
f.Pos := oldPos
DllCall("UpdateResource", "ptr", re, "ptr", 3, "ptr", thisID, "ushort", 0x409, "ptr", &iconData, "uint", iconDataSize, "uint")
ige += 14
}
DllCall("UpdateResource", "ptr", re, "ptr", 14, "ptr", iconID, "ushort", 0x409, "ptr", &rsrcIconGroup, "uint", rsrcIconGroupSize, "uint")
return true
}
EnumIcons(ExeFile, iconID)
{
; RT_GROUP_ICON = 14
; RT_ICON = 3
global _EI_HighestIconID
static pEnumFunc := RegisterCallback("EnumIcons_Enum")
hModule := DllCall("LoadLibraryEx", "str", ExeFile, "ptr", 0, "ptr", 2, "ptr")
if !hModule
return
_EI_HighestIconID := 0
if DllCall("EnumResourceNames", "ptr", hModule, "ptr", 3, "ptr", pEnumFunc, "uint", 0) = 0
{
DllCall("FreeLibrary", "ptr", hModule)
return
}
hRsrc := DllCall("FindResource", "ptr", hModule, "ptr", iconID, "ptr", 14, "ptr")
hMem := DllCall("LoadResource", "ptr", hModule, "ptr", hRsrc, "ptr")
pDirHeader := DllCall("LockResource", "ptr", hMem, "ptr")
pResDir := pDirHeader + 6
wCount := NumGet(pDirHeader+4, "UShort")
iconIDs := []
Loop, %wCount%
{
pResDirEntry := pResDir + (A_Index-1)*14
iconIDs[A_Index] := NumGet(pResDirEntry+12, "UShort")
}
DllCall("FreeLibrary", "ptr", hModule)
return iconIDs
}
EnumIcons_Enum(hModule, type, name, lParam)
{
global _EI_HighestIconID
if (name < 0x10000) && name > _EI_HighestIconID
_EI_HighestIconID := name
return 1
}