forked from Ixiko/AHK-libs-and-classes-collection
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSaveHICONtoFile.ahk
89 lines (74 loc) · 5.24 KB
/
SaveHICONtoFile.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
SaveHICONtoFile( hicon, iconFile ) { ; By SKAN | 06-Sep-2017 | goo.gl/8NqmgJ
Static CI_FLAGS:=0x2008 ; LR_CREATEDIBSECTION | LR_COPYDELETEORG
Local File, Var, mDC, sizeofRGBQUAD, ICONINFO:=[], BITMAP:=[], BITMAPINFOHEADER:=[]
File := FileOpen( iconFile,"rw" )
If ( ! IsObject(File) )
Return 0
Else File.Length := 0 ; Delete (any existing) file contents
VarSetCapacity(Var,32,0) ; ICONINFO Structure
If ! DllCall( "GetIconInfo", "Ptr",hicon, "Ptr",&Var )
Return ( File.Close() >> 64 )
ICONINFO.fIcon := NumGet(Var, 0,"UInt")
ICONINFO.xHotspot := NumGet(Var, 4,"UInt")
ICONINFO.yHotspot := NumGet(Var, 8,"UInt")
ICONINFO.hbmMask := NumGet(Var, A_PtrSize=8 ? 16:12, "UPtr")
ICONINFO.hbmMask := DllCall( "CopyImage" ; Create a DIBSECTION for hbmMask
, "Ptr",ICONINFO.hbmMask
, "UInt",0 ; IMAGE_BITMAP
, "Int",0, "Int",0, "UInt",CI_FLAGS, "Ptr" )
ICONINFO.hbmColor := NumGet(Var, A_PtrSize=8 ? 24:16, "UPtr")
ICONINFO.hbmColor := DllCall( "CopyImage" ; Create a DIBSECTION for hbmColor
, "Ptr",ICONINFO.hbmColor
, "UInt",0 ; IMAGE_BITMAP
, "Int",0, "Int",0, "UInt",CI_FLAGS, "Ptr" )
VarSetCapacity(Var,A_PtrSize=8 ? 104:84,0) ; DIBSECTION of hbmColor
DllCall( "GetObject", "Ptr",ICONINFO.hbmColor, "Int",A_PtrSize=8 ? 104:84, "Ptr",&Var )
BITMAP.bmType := NumGet(Var, 0,"UInt")
BITMAP.bmWidth := NumGet(Var, 4,"UInt")
BITMAP.bmHeight := NumGet(Var, 8,"UInt")
BITMAP.bmWidthBytes := NumGet(Var,12,"UInt")
BITMAP.bmPlanes := NumGet(Var,16,"UShort")
BITMAP.bmBitsPixel := NumGet(Var,18,"UShort")
BITMAP.bmBits := NumGet(Var,A_PtrSize=8 ? 24:20,"Ptr")
BITMAPINFOHEADER.biClrUsed := NumGet(Var,32+(A_PtrSize=8 ? 32:24),"UInt")
File.WriteUINT(0x00010000) ; ICONDIR.idReserved and ICONDIR.idType
File.WriteUSHORT(1) ; ICONDIR.idCount (No. of images)
File.WriteUCHAR(BITMAP.bmWidth < 256 ? BITMAP.bmWidth : 0) ; ICONDIRENTRY.bWidth
File.WriteUCHAR(BITMAP.bmHeight < 256 ? BITMAP.bmHeight : 0) ; ICONDIRENTRY.bHeight
File.WriteUCHAR(BITMAPINFOHEADER.biClrUsed < 256 ; ICONDIRENTRY.bColorCount
? BITMAPINFOHEADER.biClrUsed : 0)
File.WriteUCHAR(0) ; ICONDIRENTRY.bReserved
File.WriteUShort(BITMAP.bmPlanes) ; ICONDIRENTRY.wPlanes
File.WriteUSHORT(BITMAP.bmBitsPixel) ; ICONDIRENTRY.wBitCount
File.WriteUINT(0) ; ICONDIRENTRY.dwBytesInRes (filled later)
File.WriteUINT(22) ; ICONDIRENTRY.dwImageOffset
NumPut( BITMAP.bmHeight*2, Var, 8+(A_PtrSize=8 ? 32:24),"UInt") ; BITMAPINFOHEADER.biHeight should be
; modified to double the BITMAP.bmHeight
File.RawWrite( &Var + (A_PtrSize=8 ? 32:24), 40) ; Writing BITMAPINFOHEADER (40 bytes)
If ( BITMAP.bmBitsPixel <= 8 ) ; Bitmap uses a Color table!
{
mDC := DllCall( "CreateCompatibleDC", "Ptr",0, "Ptr" )
DllCall( "SaveDC", "Ptr",mDC )
DllCall( "SelectObject", "Ptr",mDC, "Ptr",ICONINFO.hbmColor )
sizeofRGBQUAD := ( BITMAPINFOHEADER.biClrUsed * 4 ) ; Colors used x UINT (0x00bbggrr)
VarSetCapacity( Var,sizeofRGBQUAD,0 ) ; Array of RGBQUAD structures
DllCall( "GetDIBColorTable", "Ptr",mDC, "UInt",0, "UInt",BITMAPINFOHEADER.biClrUsed, "Ptr",&Var )
DllCall( "RestoreDC", "Ptr",mDC, "Int",-1 )
DllCall( "DeleteDC", "Ptr",mDC )
File.RawWrite(Var, sizeofRGBQUAD) ; Writing Color table
}
File.RawWrite(BITMAP.bmBits, BITMAP.bmWidthBytes*BITMAP.bmHeight) ; Writing BITMAP bits (hbmColor)
VarSetCapacity(Var,A_PtrSize=8 ? 104:84,0) ; DIBSECTION of hbmMask
DllCall( "GetObject", "Ptr",ICONINFO.hbmMask, "Int",A_PtrSize=8 ? 104:84, "Ptr",&Var )
BITMAP := []
BITMAP.bmHeight := NumGet(Var, 8,"UInt")
BITMAP.bmWidthBytes := NumGet(Var,12,"UInt")
BITMAP.bmBits := NumGet(Var,A_PtrSize=8 ? 24:20,"Ptr")
File.RawWrite(BITMAP.bmBits, BITMAP.bmWidthBytes*BITMAP.bmHeight) ; Writing BITMAP bits (hbmMask)
File.Seek(14,0) ; Seeking ICONDIRENTRY.dwBytesInRes
File.WriteUINT(File.Length()-22) ; Updating ICONDIRENTRY.dwBytesInRes
File.Close()
DllCall( "DeleteObject", "Ptr",ICONINFO.hbmMask )
DllCall( "DeleteObject", "Ptr",ICONINFO.hbmColor )
Return True
}