picea892 Posted October 17, 2009 Share Posted October 17, 2009 (edited) Hi I can't take credit for this script. I simply merged two scripts together to create this example of how to set the day as the tray icon (think of rainlendar) Credit goes to smashly http://www.autoitscript.com/forum/index.php?showtopic=101305&st=0&p=720443&hl=create%20ico&fromsearch=1&#entry720443 and whoever created the gradient script I'm using. expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <GDIPlus.au3> #include <WinAPI.au3> Global $ApW = 32, $ApH = 32 Global $hImage, $hIcon PicSetGraphics($ApW, $ApH); <-- Draw GDIPlus graphics on Picture control. While 1 Sleep(10) WEnd Func PicSetGraphics($iW, $iH) Local Const $STM_SETIMAGE = 0x0172 Local Const $IMAGE_BITMAP = 0 Local $hWnd, $hBitmap, $hImage, $hGraphic, $hBrush, $hBrush1, $hbmp, $aBmp _GDIPlus_Startup() ;Buffer $hBitmap = _WinAPI_CreateSolidBitmap(0, 0xFFFFFF, $iW, $iH) $hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap) $hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage) ;Gradient Background - At the top Maroon 50% transparency to fully opaque black at bottom Global $a_Factors[4] = [0.0, 0.4, 0.8, 1.0] Global $a_Positions[4] = [0.0, 0.3, 0.6, 1.0] $hBrushLin = _GDIPlus_CreateLineBrushFromRect( 0, 0, $iW, $iH, $a_Factors, $a_Positions, 0x80800040, 0xFF000000,1,0) GDIPlus_SetLineGammaCorrection($hBrushLin);, $bGammaCorrection) _GDIPlus_GraphicsFillRect($hGraphic, 0, 0, $iW, $iH, $hBrushLin) ; Draw text $sText = @MDAY $hBrush1 = _GDIPlus_BrushCreateSolid(0xFFBBBBBB) $hFormat = _GDIPlus_StringFormatCreate(0) $hFamily = _GDIPlus_FontFamilyCreate("Arial") $hFont = _GDIPlus_FontCreate($hFamily, 16, 1, 3) $tLayout = _GDIPlus_RectFCreate(0, 4, 32,32) ; increase 300 to 380 for one line of text $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, $sText, $hFont, $tLayout, $hFormat) _GDIPlus_GraphicsDrawStringEx($hGraphic, $sText, $hFont, $tLayout, $hFormat, $hBrush1) $hIcon = _GDIPlus_BitmapCreateHICONFromBitmap($hImage) ; Create an ico file from the image _CreateIconFileFromHICON($hIcon, @DesktopDir & "\TestWrite1.ico") ; Destroy the HICON now I've finished with it. _WinAPI_DestroyIcon($hIcon) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; TraySetIcon(@DesktopDir & "\TestWrite1.ico") _GDIPlus_ImageDispose($hImage) _GDIPlus_BrushDispose($hBrush) _GDIPlus_BrushDispose($hBrush1) _GDIPlus_BrushDispose($hBrushLin) _GDIPlus_FontDispose($hFont) _GDIPlus_FontFamilyDispose($hFamily) _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_GraphicsDispose($hGraphic) _WinAPI_DeleteObject($hbmp) _WinAPI_DeleteObject($hBitmap) _GDIPlus_Shutdown() EndFunc ;==>PicSetGraphics Func _GDIPlus_CreateLineBrushFromRect($iX, $iY, $iWidth, $iHeight, $aFactors, $aPositions, _ $iArgb1 = 0xFFFFFFFF, $iArgb2 = 0xFF000000, $LinearGradientMode = 0x00000001, $WrapMode = 0) Local $tRect, $pRect, $aRet, $tFactors, $pFactors, $tPositions, $pPositions, $iCount, $iI, $hStatus If $iArgb1 = Default Then $iArgb1 = 0xFF0000FF If $iArgb2 = Default Then $iArgb2 = 0xFFFF0000 If $LinearGradientMode = -1 Or $LinearGradientMode = Default Then $LinearGradientMode = 0x00000001 If $WrapMode = -1 Or $LinearGradientMode = Default Then $WrapMode = 1 $tRect = DllStructCreate("float X;float Y;float Width;float Height") $pRect = DllStructGetPtr($tRect) DllStructSetData($tRect, "X", $iX) DllStructSetData($tRect, "Y", $iY) DllStructSetData($tRect, "Width", $iWidth) DllStructSetData($tRect, "Height", $iHeight) ;Note: Withn _GDIPlus_Startup(), $ghGDIPDll is defined $aRet = DllCall($ghGDIPDll, "int", "GdipCreateLineBrushFromRect", "ptr", $pRect, "int", $iArgb1, _ "int", $iArgb2, "int", $LinearGradientMode, "int", $WrapMode, "int*", 0) If IsArray($aFactors) = 0 Then Dim $aFactors[4] = [0.0, 0.4, 0.6, 1.0] If IsArray($aPositions) = 0 Then Dim $aPositions[4] = [0.0, 0.3, 0.7, 1.0] $iCount = UBound($aPositions) $tFactors = DllStructCreate("float[" & $iCount & "]") $pFactors = DllStructGetPtr($tFactors) For $iI = 0 To $iCount - 1 DllStructSetData($tFactors, 1, $aFactors[$iI], $iI + 1) Next $tPositions = DllStructCreate("float[" & $iCount & "]") $pPositions = DllStructGetPtr($tPositions) For $iI = 0 To $iCount - 1 DllStructSetData($tPositions, 1, $aPositions[$iI], $iI + 1) Next $hStatus = DllCall($ghGDIPDll, "int", "GdipSetLineBlend", "hwnd", $aRet[6], _ "ptr", $pFactors, "ptr", $pPositions, "int", $iCount) Return $aRet[6] ; Handle of Line Brush EndFunc ;==>_GDIPlus_CreateLineBrushFromRect Func GDIPlus_SetLineGammaCorrection($hBrush, $useGammaCorrection = True) Local $aResult $aResult = DllCall($ghGDIPDll, "int", "GdipSetLineGammaCorrection", "hwnd", $hBrush, "int", $useGammaCorrection) Return $aResult[0] EndFunc ;==>GDIPlus_SetLineGammaCorrection Func _CreateIconFileFromHICON($hIcon, $sOutIcon) 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 ; 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 ; 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 Func _GDIPlus_BitmapCreateHICONFromBitmap($hBitmap) Local $hIcon $hIcon = DllCall($ghGDIPDll, "int", "GdipCreateHICONFromBitmap", "hwnd", $hBitmap, "int*", 0) If @error Then Return SetError(@error, 0, -1) Return SetError($hIcon[0], 0, $hIcon[2]) EndFunc ;==>_GDIPlus_BitmapCreateHICONFromBitmap Edited October 17, 2009 by picea892 Link to comment Share on other sites More sharing options...
gseller Posted October 17, 2009 Share Posted October 17, 2009 Very Nice!! That may come in handy, adding to my tidbits.. Thank you! Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now