Jump to content
Mingre

String to icon

Recommended Posts

Mingre

Hello,

Few weeks ago, I found this UDF in the Example Scripts forums which allows text to be displayed on the trayicon. I failed to save the script though so I had to search the forum but without success. The demo script shows a countdown from 99 on the trayicon.

I created this thread so to ask anyone who happens to know anything relevant to what I'm looking for (e.g., if you have the copy of the said UDF, or have an alternative method.)

I searched the forums with the combination of the following strings: trayicon, icon, countdown, _WinAPI_DrawIconEx, draw icon. (What other terms should I search for?)

Thank you!

Share this post


Link to post
Share on other sites
Melba23

Mingre,

Do you mean this one? :huh:

Unfortunately the code has been corrupted by the forum software - perhaps someone else can help correct the errors. :)

M23

Fixed it:

#include <WindowsConstants.au3>
#include <GDIPlus.au3>
#include <WinAPI.au3>

Global Const $tagNOTIFYICONDATA = "dword Size;" & _
        "hwnd Wnd;" & _
        "uint ID;" & _
        "uint Flags;" & _
        "uint CallbackMessage;" & _
        "ptr Icon;" & _
        "wchar Tip[128];" & _
        "dword State;" & _
        "dword StateMask;" & _
        "wchar Info[256];" & _
        "uint Timeout;" & _
        "wchar InfoTitle[64];" & _
        "dword InfoFlags;" & _
        "dword Data1;word Data2;word Data3;byte Data4[8];" & _
        "ptr BalloonIcon"

Global Const $NIM_ADD = 0
Global Const $NIM_MODIFY = 1

Global Const $NIF_MESSAGE = 1
Global Const $NIF_ICON = 2

Global Const $AUT_WM_NOTIFYICON = $WM_USER + 1 ; Application.h
Global Const $AUT_NOTIFY_ICON_ID = 1 ; Application.h

AutoItWinSetTitle("this is a test 123")
Global $TRAY_ICON_GUI = WinGetHandle(AutoItWinGetTitle()) ; Internal AutoIt GUI

;;;

_GDIPlus_Startup()

Local $hBitmap, $hImage, $hGraphic, $hIcon

$hBitmap = _WinAPI_CreateSolidBitmap(0, 0xFFFFFF, 16, 16)
$hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)
$hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage)

For $i = 99 To 1 Step -1
    _GDIPlus_GraphicsClear($hGraphic, 0xFFFFFFFF)
    _GDIPlus_GraphicsDrawString($hGraphic, $i, (StringLen($i) - 2) * - 3, 2, "Arial", 8)

    $hIcon = _GDIPlus_BitmapCreateHICONFromBitmap($hImage)
    _Tray_SetHIcon($hIcon)
    _WinAPI_DestroyIcon($hIcon)

    Sleep(200)
Next

_GDIPlus_ImageDispose($hImage)
_GDIPlus_GraphicsDispose($hGraphic)
_WinAPI_DeleteObject($hBitmap)

_GDIPlus_Shutdown()

;;;

Func _Tray_SetHIcon($hIcon)
    Local $tNOTIFY = DllStructCreate($tagNOTIFYICONDATA)
    DllStructSetData($tNOTIFY, "Size", DllStructGetSize($tNOTIFY))
    DllStructSetData($tNOTIFY, "Wnd", $TRAY_ICON_GUI)
    DllStructSetData($tNOTIFY, "ID", $AUT_NOTIFY_ICON_ID)
    DllStructSetData($tNOTIFY, "Icon", $hIcon)
    DllStructSetData($tNOTIFY, "Flags", BitOR($NIF_ICON, $NIF_MESSAGE))
    DllStructSetData($tNOTIFY, "CallbackMessage", $AUT_WM_NOTIFYICON)

    Local $aRet = DllCall("shell32.dll", "int", "Shell_NotifyIconW", "dword", $NIM_MODIFY, "ptr", DllStructGetPtr($tNOTIFY))
    If (@error) Then Return SetError(1, 0, 0)

    Return $aRet[0] <> 0
EndFunc   ;==>_Tray_SetHIcon

Func _GDIPlus_BitmapCreateHICONFromBitmap($hBitmap)
    Local $hIcon = DllCall($ghGDIPDll, "int", "GdipCreateHICONFromBitmap", "hwnd", $hBitmap, "int*", 0)
    If @error Or Not $hIcon[0] Then Return SetError(@error, @extended, $hIcon[2])

    Return $hIcon[2]
EndFunc   ;==>_GDIPlus_BitmapCreateHICONFromBitmap
Edited by Melba23
  • Like 1

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites
water

The code from post #1 works fine here - no corrupted code. Should I post the code here?


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2018-06-01 - Version 1.4.9.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-01-27 - Version 1.3.3.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
Mingre

Melba23,

Yes, thank you so much! (I wonder how you found it? Haha.)

water,

The code from the original thread also works here.

Share this post


Link to post
Share on other sites
kisstom

 

 

Fixed it:

Hi Melba23,

I try this code but i get error message :'$ghGDIPDll  variable used without being declared'

Can you help me?

Thx

Share this post


Link to post
Share on other sites
UEZ

Use $__g_hGDIPDll or even better use _GDIPlus_HICONCreateFromBitmap instead.

Edited by UEZ
  • Like 1

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites
kisstom

Use $__g_hGDIPDll or even better use _GDIPlus_HICONCreateFromBitmap instead.

Thnx, how can i use _GDIPlus_HICONCreateFromBitmap ?

I used

Local $hIcon = DllCall($__g_hGDIPDll, "int", "GdipCreateHICONFromBitmap", "hwnd", $hBitmap, "int*", 0)

and it's working.

Share this post


Link to post
Share on other sites
UEZ

As far as I can remember "int*" will crash when running as x64.

Why don't you use simply?

Local $hIcon = _GDIPlus_HICONCreateFromBitmap($hBitmap)

 

Otherwise I would suggest to use (no error check!):

Local $aIcon = DllCall($__g_hGDIPDll, "int", "GdipCreateHICONFromBitmap", "handle", $hBitmap, "handle*", 0)
Local $hIcon = $aIcon[2]

 

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites
kisstom

Is there a way to transparent background instead of white?

Edit:

_GDIPlus_GraphicsClear($hGraphic, 0xFFFFFFFF)

As far as i know the 1st 2 FF is the alpha channel so 0x00FFFFFF means full transparency but the icon goes black then.

Edit 2:

SOLVED: here is an example if someone interested:

#include <WindowsConstants.au3>
#include <GDIPlus.au3>
#include <WinAPI.au3>

Global Const $tagNOTIFYICONDATA = "dword Size;" & _
        "hwnd Wnd;" & _
        "uint ID;" & _
        "uint Flags;" & _
        "uint CallbackMessage;" & _
        "ptr Icon;" & _
        "wchar Tip[128];" & _
        "dword State;" & _
        "dword StateMask;" & _
        "wchar Info[256];" & _
        "uint Timeout;" & _
        "wchar InfoTitle[64];" & _
        "dword InfoFlags;" & _
        "dword Data1;word Data2;word Data3;byte Data4[8];" & _
        "ptr BalloonIcon"

Global Const $NIM_ADD = 0
Global Const $NIM_MODIFY = 1

Global Const $NIF_MESSAGE = 1
Global Const $NIF_ICON = 2

Global Const $AUT_WM_NOTIFYICON = $WM_USER + 1 ; Application.h
Global Const $AUT_NOTIFY_ICON_ID = 1 ; Application.h

Global $iW = 32, $iH = 32, $hBitmap, $hBMP, $tBitmapData, $tPixels

AutoItWinSetTitle("this is a test 123")
Global $TRAY_ICON_GUI = WinGetHandle(AutoItWinGetTitle()) ; Internal AutoIt GUI

;;; START EXAMPLE

_GDIPlus_Startup()

$i = "59"
$hImageCleanPNG = _CreatePNG()                                      ;create clean PNG
$hImageTXT = _ImageDrawText($hImageCleanPNG, $i)
$hIcon = _GDIPlus_BitmapCreateHICONFromBitmap($hImageTXT)
_Tray_SetHIcon($hIcon)
_WinAPI_DestroyIcon($hIcon)

Sleep(2000)

$i = "22"
$hImageTXT = _ImageDrawText($hImageCleanPNG, $i,Default,Default, 0xFFFFFF); white
$hIcon = _GDIPlus_BitmapCreateHICONFromBitmap($hImageTXT)
_Tray_SetHIcon($hIcon)

Sleep(2000)

_WinAPI_DestroyIcon($hIcon)
_GDIPlus_ImageDispose($hImageCleanPNG)
_GDIPlus_ImageDispose($hImageTXT)
_GDIPlus_Shutdown()

;;; END EXAMPLE

Func _ImageDrawText($hImage, $sText, $iX = 0, $iY = 0, $iRGB = 0x000000, $iSize = 20, $iStyle = 0, $sFont = "Arial")
    Local $w, $h, $hGraphic1, $hBitmap, $hGraphic2, $hBrush, $hFormat, $hFamily, $hFont, $tLayout, $aInfo
    $w = _GDIPlus_ImageGetWidth($hImage)
    $h = _GDIPlus_ImageGetHeight($hImage)

    ;Create a new bitmap, this way the original opened png is left unchanged
    $hGraphic1 = _GDIPlus_GraphicsCreateFromHWND(_WinAPI_GetDesktopWindow())
    $hBitmap = _GDIPlus_BitmapCreateFromGraphics($w, $h, $hGraphic1)
    $hGraphic2 = _GDIPlus_ImageGetGraphicsContext($hBitmap)

    ; Draw the original opened png into my newly created bitmap
    _GDIPlus_GraphicsDrawImageRect($hGraphic2, $hImage, 0, 0, $w, $h)

    ;Create the font
    $hBrush = _GDIPlus_BrushCreateSolid ("0xFF" & Hex($iRGB, 6))
    $hFormat = _GDIPlus_StringFormatCreate()
    $hFamily = _GDIPlus_FontFamilyCreate ($sFont)
    $hFont = _GDIPlus_FontCreate ($hFamily, $iSize, $iStyle)
    $tLayout = _GDIPlus_RectFCreate ($iX, $iY, 0, 0)
    $aInfo = _GDIPlus_GraphicsMeasureString ($hGraphic2, $sText, $hFont, $tLayout, $hFormat)

    ;Draw the font onto the new bitmap
    _GDIPlus_GraphicsDrawStringEx ($hGraphic2, $sText, $hFont, $aInfo[0], $hFormat, $hBrush)

    ;Cleanup the no longer needed resources
    _GDIPlus_FontDispose ($hFont)
    _GDIPlus_FontFamilyDispose ($hFamily)
    _GDIPlus_StringFormatDispose ($hFormat)
    _GDIPlus_BrushDispose ($hBrush)
    _GDIPlus_GraphicsDispose ($hGraphic2)
    _GDIPlus_GraphicsDispose ($hGraphic1)

    ;Return the new bitmap
    Return $hBitmap
EndFunc

Func _Tray_SetHIcon($hIcon)
    Local $tNOTIFY = DllStructCreate($tagNOTIFYICONDATA)
    DllStructSetData($tNOTIFY, "Size", DllStructGetSize($tNOTIFY))
    DllStructSetData($tNOTIFY, "Wnd", $TRAY_ICON_GUI)
    DllStructSetData($tNOTIFY, "ID", $AUT_NOTIFY_ICON_ID)
    DllStructSetData($tNOTIFY, "Icon", $hIcon)
    DllStructSetData($tNOTIFY, "Flags", BitOR($NIF_ICON, $NIF_MESSAGE))
    DllStructSetData($tNOTIFY, "CallbackMessage", $AUT_WM_NOTIFYICON)

    Local $aRet = DllCall("shell32.dll", "int", "Shell_NotifyIconW", "dword", $NIM_MODIFY, "ptr", DllStructGetPtr($tNOTIFY))
    If (@error) Then Return SetError(1, 0, 0)

    Return $aRet[0] <> 0
EndFunc   ;==>_Tray_SetHIcon

Func _GDIPlus_BitmapCreateHICONFromBitmap($hBitmap)
    Local $hIcon = DllCall($__g_hGDIPDll, "int", "GdipCreateHICONFromBitmap", "hwnd", $hBitmap, "int*", 0)
    If @error Or Not $hIcon[0] Then Return SetError(@error, @extended, $hIcon[2])

    Return $hIcon[2]
EndFunc   ;==>_GDIPlus_BitmapCreateHICONFromBitmap


Func _ImageToTransPNG($sInFile, $iXPixel = 0, $iYPixel = 0)
    Local $hImage, $iW, $iH, $iFirstPixel, $iTransPixel, $tBitmapData, $iStride, $iScan0, $iX, $iY, $tPixel, $iPixel
    Local $v_BufferA, $AllPixels, $sREResult1, $sPix

    $hImage = _GDIPlus_ImageLoadFromFile($sInFile)

    $iW = _GDIPlus_ImageGetWidth($hImage)
    $iH = _GDIPlus_ImageGetHeight($hImage)

    ;=> Start Work araound For XP, GDIPBitmapLockBits() seem to hard crash autoit When using images that are less then 24bpp
    ; If your using Vista or Newer OS then this won't be called or needed.
    If StringInStr('"WIN_2003","WIN_XP","WIN_2000"', @OSVersion) Then
        Local $aRet, $hBmp, $hBitmap, $hGraphic
        $aRet = _GDIPlus_ImageGetPixelFormat($hImage)
        If Int(StringRegExpReplace($aRet[1], "\D+", "")) < 24 Then
            $hBmp = _WinAPI_CreateBitmap($iW, $iH, 1, 32)
            $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBmp)
            _WinAPI_DeleteObject($hBmp)
            $hGraphic = _GDIPlus_ImageGetGraphicsContext($hBitmap)
            _GDIPlus_GraphicsDrawImage($hGraphic, $hImage, 0, 0)
            _GDIPlus_GraphicsDispose($hGraphic)
            _GDIPlus_ImageDispose($hImage)
            $hImage = _GDIPlus_BitmapCloneArea($hBitmap, 0, 0, $iW, $iH, $GDIP_PXF32ARGB)
            _GDIPlus_BitmapDispose($hBitmap)
        EndIf
    EndIf
    ;=> End Work around

    $tBitmapData = _GDIPlus_BitmapLockBits($hImage, 0, 0, $iW, $iH, $GDIP_ILMWRITE, $GDIP_PXF32ARGB)
    $iStride = DllStructGetData($tBitmapData, "stride")
    $iScan0 = DllStructGetData($tBitmapData, "Scan0")

    ; Get Pixel colour to be transparent at coordinates ($iXPixel, $iYPixel).
    $tPixel = DllStructCreate("int", $iScan0 + ($iYPixel * $iStride) + ($iXPixel * 4))
    $iFirstPixel = DllStructGetData($tPixel, 1)
    $iTransPixel = BitAND($iFirstPixel, 0x00FFFFFF)


    $iFirstPixel = StringRegExpReplace(Hex($iFirstPixel, 8), "(.{2})(.{2})(.{2})(.{2})", "\4\3\2\1")
    ConsoleWrite($iFirstPixel & @LF)
    $iTransPixel = StringTrimRight($iFirstPixel, 2) & "00"
    $v_BufferA = DllStructCreate("byte[" & $iH * $iW * 4 & "]", $iScan0) ; Create DLL structure for all pixels
    $AllPixels = DllStructGetData($v_BufferA, 1)
    $sREResult1 = StringRegExpReplace(StringTrimLeft($AllPixels, 2), "(.{8})", "\1 ")
    $sPix = "0x" & StringStripWS(StringRegExpReplace($sREResult1, "(" & $iFirstPixel & ")", $iTransPixel), 8)
    $AllPixels = DllStructSetData($v_BufferA, 1, $sPix)

    _GDIPlus_BitmapUnlockBits($hImage, $tBitmapData)
  ;  _GDIPlus_ImageSaveToFileEx($hImage, $sOutFile, _GDIPlus_EncodersGetCLSID("PNG"))
 ;   _GDIPlus_ImageDispose($hImage)

    Return $hImage
EndFunc   ;==>_ImageToTransPNG

Func _CreatePNG()

    ;Local $iW = 32, $iH = 32, $hBitmap, $hBMP, $tBitmapData, $tPixels

    _GDIPlus_Startup()
$hBitmap = _WinAPI_CreateBitmap($iW, $iH , 1 , 32)
$hBMP = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)
_WinAPI_DeleteObject($hBitmap)
$hBitmap = _GDIPlus_BitmapCloneArea($hBMP, 0, 0, $iW, $iH, $GDIP_PXF32ARGB)
_GDIPlus_BitmapDispose($hBMP)
$tBitmapData = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $iW, $iH, $GDIP_ILMWRITE, $GDIP_PXF32ARGB)
$tPixels = DllStructCreate("byte[" & $iH * $iW * 4 & "]", DllStructGetData($tBitmapData, "Scan0")) ; Create DLL structure for all pixels
DllStructSetData($tPixels, 1, StringReplace(DllStructGetData($tPixels, 1), "000000FF", "00000000"))
_GDIPlus_BitmapUnlockBits($hBitmap, $tBitmapData)
$tPixels = 0
$tBitmapData = 0
Return ($hBitmap)

EndFunc

 

Edited by kisstom
Solved

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

×