Sign in to follow this  
Followers 0
picea892

Set current date as tray icon

2 posts in this topic

#1 ·  Posted (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.

#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 by picea892

Share this post


Link to post
Share on other sites



Very Nice!! That may come in handy, adding to my tidbits.. Thank you!

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0