Jump to content

Recommended Posts

Posted

Hi. Can you help me please? I have a little script to draw and redraw a tray icon, even animate it. But there is a little problem with it. After a while (several hours), it stops drawing, it shows the default Autoit icon instead. Since it really takes hours, it’s hard to debug it. But maybe you guys can find what did I miss. First, here is the script. It has three functions. You have to call prepareicon first, then draw the contents on $img, then seticon will display it. Now, dispose everything defined for drawing, and you can call finishicon to close the process. For changing or animated icons, you have to repeat these steps.
 

#include <GDIPlus.au3>
#include <WinAPIGdi.au3>

Global $img, $bmp, $isize=1000, $count=0

Func prepareicon()
    _GDIPlus_Startup()
    $bmp = _GDIPlus_BitmapCreateFromScan0($isize, $isize)
    $img= _GDIPlus_ImageGetGraphicsContext($bmp)
EndFunc
Func seticon()
    _WinAPI_SaveHICONToFile(@ScriptFullPath&'.ico', _GDIPlus_HICONCreateFromBitmap($bmp))
    TraySetIcon(@ScriptFullPath&'.ico')
    FileDelete(@Scriptfullpath&'.ico')
EndFunc
Func finishicon()
    _GDIPlus_GraphicsDispose($img)
    _GDIPlus_ImageDispose($bmp)
    _GDIPlus_Shutdown()
EndFunc

Now, one of my scripts that uses it.

#include <ispressed.au3>
#include "animateudf.au3"

Global $img, $bmp, $isize=100

$prev='x'

While True
    Sleep(10)
    $r='3b'
    $g='1b'
    $b='0d'
    If _ispressed('10') Then $r='ff'
    If _ispressed('11') Then $g='ff'
    If _ispressed('12') Then $b='ff'
    If _ispressed('5B') Then
        $r='ff'
        $g='c0'
        $b='ff'
    EndIf

    If $r&$g&$b<>$prev Then
        showcolor($r&$g&$b)
        $prev=$r&$g&$b
    EndIf
WEnd

Func showcolor($t)
    prepareicon()
    $fillbrush=_GDIPlus_BrushCreateSolid('0xff'&$t)
    _GDIPlus_GraphicsFillRect($img, 0, 0, 100, 100, $fillbrush)
    $rectpen=_GDIPlus_PenCreate(0xffffffff, 5, 2)
    _GDIPlus_GraphicsDrawRect($img, 1, 1, 95, 95, $rectpen)
    seticon()
    _GDIPlus_BrushDispose($fillbrush)
    _GDIPlus_PenDispose($rectpen)
    finishicon()
EndFunc
Func _IsAnyKeyPressed()
    For $i = 8 To 127
        if (_IsPressed(Hex($i))) Then return true
    Next
    return False
EndFunc

It shows a brown icon with a white border (my taskbar is brown, so it appears as an empty square). Then, when either modifier key is pressed, the inside of the square turns to a different color: red for Shift, green for Ctrl, blue for Alt and pink for Win key.

It’s cute and works properly – as I said, for several hours. Then it turns back to the default Autoit icon. Quitting and restarting the script helps.

Thanks for any idea.

Posted

Sounds like something isnt cleared from memory, have you watched memory usage in taskmanager?

Maybe try using _GDIPlus_BitmapDispose($bmp) instead of _GDIPlus_ImageDispose($bmp).

Some guy's script + some other guy's script = my script!

Posted
10 minutes ago, Werty said:

Sounds like something isnt cleared from memory, have you watched memory usage in taskmanager?

Maybe try using _GDIPlus_BitmapDispose($bmp) instead of _GDIPlus_ImageDispose($bmp).

No, I didn’t try watching it – actually, I didn’t even know I can or should. Thank you for the hint, I’m going to check it if your second hint won’t work. Now I applied it, changed it to _GDIPlus_BitmapDispose, restarted all scripts which are using it, and let’s see what happens. Since it usually takes hours for the bug to appear, and it’s evening here, it’ll be tomorrow earliest. I’ll let you know what happens. Thank you.

Posted

This creates a memory leak

_WinAPI_SaveHICONToFile(@ScriptFullPath&'.ico', _GDIPlus_HICONCreateFromBitmap($bmp))

_GDIPlus_HICONCreateFromBitmap($bmp) creates HICON without being released.

Suggestion:

Func seticon()
    Local $hIcon = _GDIPlus_HICONCreateFromBitmap($bmp)
    _WinAPI_SaveHICONToFile(@ScriptFullPath&'.ico', $hIcon)
    _WinAPI_DestroyIcon($hIcon)
    TraySetIcon(@ScriptFullPath&'.ico')
    FileDelete(@Scriptfullpath&'.ico')
EndFunc

You should create your animation frames in the memory rather than writing it permanetly to disk and loading it from there again.

PS:
I didn't test your code - only visual checked.

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Posted
28 minutes ago, UEZ said:

This creates a memory leak

You should create your animation frames in the memory rather than writing it permanetly to disk and loading it from there again.

Okay, I’ve replaced seticon with the code you gave, thank you very much. Now again, waiting for enough hours to elapse to see the result.
How can I create them in memory and use them? TraySetIcon, AFAIK, accepts only a file name. Is there a function anywhere which can set the tray icon from a frame in the memory?

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
×
×
  • Create New...