#include #include #include Func LoadIcon($file, $Index) Local $hIcon Switch(StringRight($file, 4)) Case ".dll" $hIcon = LoadIconFromDLL($file, $Index) Case ".exe" $hIcon = LoadIconFromEXE($file, $Index) EndSwitch Return $hIcon EndFunc Func LoadIconFromEXE($file, $Index) $DLLinst = GetModuleHandle(Ptr(0)) Local $aResult = DllCall("shell32.dll", "ptr", "ExtractIcon", "ptr", $DLLinst, "str", $file, "int", $Index) If @error Then Return SetError(@error, @extended, 0) Return $aResult[0] EndFunc ;==>_WinAPI_ExtractIconEx Func LoadIconFromDLL($file, $Index) 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",$Index, _ "int",$IMAGE_ICON,"int",0,"int",0,"int",0) $hIcon = $hIcon[0] DLLCall("kernel32.dll","int","FreeLibrary","hwnd",$DLLinst) Return $hIcon EndFunc Func GetModuleHandle($sModuleName) Local $tText, $aResult If $sModuleName <> "" Then $tText = DllStructCreate("char Text[4096]") DllStructSetData($tText, "Text", $sModuleName) $aResult = DllCall("kernel32.dll", "hwnd", "GetModuleHandle", "ptr", DllStructGetPtr($tText)) Else $aResult = DllCall("kernel32.dll", "hwnd", "GetModuleHandle", "ptr", Ptr(0)) EndIf Return $aResult[0] EndFunc 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