Code : Tout sélectionner
#include <Constants.au3>
#include <StructureConstants.au3>
#include <WinAPI.au3>
$hIcon = LoadIconFromDLL(@SystemDir & "\shell32.dll",2)
_CreateIconFileFromHICON($hIcon, @ScriptDir & "\testtt.ico")
_WinAPI_DestroyIcon($hIcon)
Func LoadIconFromDLL($file, $resource)
Local Const $IMAGE_ICON = 1
Local $DLLinst
Local $hIcon
$DLLinst = DLLCall("kernel32.dll","hwnd","LoadLibrary","str",$file)
$DLLinst = $DLLinst[0]
$hIcon = DLLCall("user32.dll","hwnd","LoadImage","hwnd",$DLLinst,"int",$resource, _
"int",$IMAGE_ICON,"int",0,"int",0,"int",0)
$hIcon = $hIcon[0]
DLLCall("kernel32.dll","int","FreeLibrary","hwnd",$DLLinst)
Return $hIcon
EndFunc
Func DeleteObject($hObj)
Local $bResult = DllCall('gdi32.dll', 'int', 'DeleteObject', _
'hwnd', $hObj)
Return $bResult[0]
EndFunc ;==>DeleteObject
Func _CreateIconFileFromHICON($hIcon, $sOutIcon)
$sIco = _GetIconFromHICON($hIcon)
; Write the icon to a file.
$FO = FileOpen($sOutIcon, 18)
FileWrite($sOutIcon, Binary($sIco))
FileClose($FO)
; Clear the structs
$tBits = 0
$tBI = 0
EndFunc ;==>_CreateIconFileFromHICON
Func _GetIconFromHICON($hIcon)
Local $aInfo, $sIco, $sBmp, $hCDC, $tBI, $tBits, $iSz, $sBD, $FO
; Start of single Icon Header 3 x 2 bytes = 6 bytes: 0000 Reserved / 0100 Icon / 0100 Numer of icons, total length will be 22 bytes for a single icon when finished
$sIco = "0x000001000100"
; Start of the Bitmap data header 1 x 4bytes: length of the header will be 40 bytes when finished. Will be appended to the end of the icon header when finished
$sBmp = "28000000"
; Get info about the HICON, this is mainly to get the pointers to the Color/Mask bitmaps data
$aInfo = _WinAPI_GetIconInfo($hIcon)
; Create a memory Compatable DC
$hCDC = _WinAPI_CreateCompatibleDC(0)
; Create a BITMAPINFO Struct to store the Bitmap Info, it needs to be inilialized by setting the struct size.
$tBI = DllStructCreate($tagBITMAPINFO)
DllStructSetData($tBI, "Size", DllStructGetSize($tBI))
; Pass a bitmap data pointer to the BITMAPINFO struct so we can recieve the details of the color bitmap data, we use it to write the headers
_WinAPI_GetDIBits($hCDC, $aInfo[5], 0, 0, 0, DllStructGetPtr($tBI), 0)
; Now we have some the basic info to add to the Icon & Bitmap header so we'll add that to the headers.
$sIco &= Hex(DllStructGetData($tBI, "Width"), 2) & Hex(DllStructGetData($tBI, "Height"), 2) & "00000100" & _RB(Hex(DllStructGetData($tBI, "BitCount"), 4))
$sBmp &= _RB(Hex(DllStructGetData($tBI, "Width"))) & _RB(Hex(DllStructGetData($tBI, "Height") * 2)) & "0100" & _RB(Hex(DllStructGetData($tBI, "BitCount"), 4)) & "00000000"
; Get the size of the Bitmap data from the BITMAPINFO Struct, we'll use this in the headers further on.
$iSz = DllStructGetData($tBI, "SizeImage")
; Create a struct to store the Bitmap data Bits of the first bitmap, reset the BITMAPINFO struct
$tBits = DllStructCreate("byte[" & DllStructGetData($tBI, "SizeImage") & "]")
; Get the color bitmap dib bits into the $tBits struct.
DllCall('gdi32.dll', 'int', 'GetBitmapBits', 'ptr', $aInfo[5], 'int', $iSz, 'ptr', DllStructGetPtr($tBits))
; Get GetBitmapBits returns Bottom to Top dib, so I turn it to Top to Bottom dib ;)
; ATM I'm only assuming that GetBitmapBits returns a Bottom to Top dib, maybe the bitmap bits you use could be Top Down already?.
For $i = DllStructGetData($tBI, "SizeImage") + 1 To 0 Step -(DllStructGetData($tBI, "SizeImage") / DllStructGetData($tBI, "Height"))
$sBD &= StringTrimLeft(BinaryMid(DllStructGetData($tBits, 1), $i, (DllStructGetData($tBI, "SizeImage") / DllStructGetData($tBI, "Height"))), 2)
Next
;Clear the BITMAPINFO & $tBits Struct as we'll use the same variables again for the mask bitmap data
$tBits = 0
$tBI = 0
; Create a BITMAPINFO Struct to store the Bitmap Info again, it needs to be inilialized by setting the struct size.
$tBI = DllStructCreate($tagBITMAPINFO)
DllStructSetData($tBI, "Size", DllStructGetSize($tBI))
; Pass a bitmap data pointer to the BITMAPINFO struct so we can recieve the details of the bitmask bitmap data
_WinAPI_GetDIBits($hCDC, $aInfo[4], 0, 0, 0, DllStructGetPtr($tBI), 0)
; We've finished with the Compatable DC, delete it.
_WinAPI_DeleteDC($hCDC)
; Add the size of the of the color + bitmask bitmap data as we need this for both the Icon & Bitmap header
$iSz += DllStructGetData($tBI, "SizeImage")
; combine the bitmap data size with the bitmap header, I'm padding the rest of the 40 byte bitmap header with 0's., that's the Bitmap header done
$sBmp &= _RB(Hex($iSz)) & "00000000000000000000000000000000"
; Now add the size of the Bitmap data + bitmap header size and combine the icon header together with the bitmap header and color bitmap data
$sIco &= _RB(Hex($iSz + 40)) & _RB(Hex("22")) & $sBmp & $sBD
; Create a struct to store the Bitmap dib Bits of the mask bitmap
$tBits = DllStructCreate("byte[" & DllStructGetData($tBI, "SizeImage") & "]")
; Get the mask bitmap dib bits into the $tBits struct.
DllCall('gdi32.dll', 'int', 'GetBitmapBits', 'ptr', $aInfo[4], 'int', DllStructGetData($tBI, "SizeImage"), 'ptr', DllStructGetPtr($tBits))
; Get GetBitmapBits returns Bottom to Top dib, so I turn it to a Top to Bottom dib and append the mask bitmap data to the icon
For $i = DllStructGetData($tBI, "SizeImage") + 1 To 0 Step -(DllStructGetData($tBI, "SizeImage") / DllStructGetData($tBI, "Height"))
$sIco &= StringTrimLeft(BinaryMid(DllStructGetData($tBits, 1), $i, (DllStructGetData($tBI, "SizeImage") / DllStructGetData($tBI, "Height"))), 2)
Next
Return $sIco
EndFunc
; Reverse Byte String
Func _RB($sByte)
Local $aX = StringRegExp($sByte, "(.{2})", 3), $sX = ''
For $i = UBound($aX) - 1 To 0 Step -1
$sX &= $aX[$i]
Next
Return $sX
EndFunc ;==>_RB