Jump to content

GDI+ Animation start/stop issue


MaxG
 Share

Go to solution Solved by UEZ,

Recommended Posts

Hello All,

I modified one of UEZ's loading animations to start and stop when requested.  Problem is, in my main script it stops executing after starting the animation, yet when I tried it in a simple notepad test script it works fine....

This code works fine....

#include <_LoadingAnimation.au3>
BlockInput(1)

    _StartLoadingAnimation()                 ;<--------  Animation Start
    Run("notepad.exe")

    WinWaitActive("Untitled - Notepad")
    Sleep(2000)
    _StopLoadingAnimation()                  ;<-------- Animation Stop

    Send("This is some text." & @CRLF & '"This is on a new line!"')

    WinClose("Untitled - Notepad")

    WinWaitActive("Notepad", "&Save")

    send("!n")

BlockInput(0)

....while this block of code starts the animation (_StartLoadingAnimation) but never reaches the MsgBox.

;Handles the saved BATCH index screen
WinWaitActive("[CLASS:#32770]", "The following index is saved")
ControlClick("[CLASS:#32770]", "The following index is saved", "[CLASS:Button; INSTANCE:1]")

;Could use progress display here
_StartLoadingAnimation()               ;<-------- Animation Start

MsgBox(0,"Test", "Right after animation starts")
;Clicks the save button on the layout screen just prior to DBF creation
WinWaitActive("BCC Mail Manager FS Network - ADMIN", "")
WinWait($listName, "")
Sleep($mediumDelay)
_StopLoadingAnimation()                ;<-------- Animation Start
WinActivate($listName, "")
;MsgBox(0,"Test","Before Click")
ControlClick($listName, "No Records", "[CLASS:TPanel; INSTANCE:2]", "left", 1, 45, 10)

I'm about to leave work for the day, just thought I'd post and see if I'm missing something obvious.  I know I'm not giving a lot of code, but I just can't see a reason why it would work in my notepad example and not the main script.

In the "not working" example, the WinWaitActive and WinWait statements refer to windows that do exist and ARE appearing/activating but the statements do not react as normal.

Thanks in advance for any input!

~MaxG

Link to comment
Share on other sites

The interesting part here is the _StartLoadingAnimation() function.

Can you post it?

Br,

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

Link to comment
Share on other sites

I'm sorry, I was in a rush to get out of work....  It didn't occur to me until later how useless this post would be without the #include code.

Below is the code...  hopefully I didn't butcher your work too badly.   :)

;coded by UEZ build 2014-02-25, idea taken from http://codepen.io/alextebbs/pen/tHhrz
;AutoIt v3.3.9.21 or higher needed!
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

; #FUNCTION# ============================================================================================================================
; Name...........: _StartLoadingAnimation
;
; Description ...: Starts the rotating gears loading animation.
;
; Syntax.........: _StartLoadingAnimation()
;
; Parameters ....: None
;
; Return values .: None
;
; Author.........: UEZ
; Modified By........: MaxG
; Date ..........: 03/27/2014
; Remarks .......: Starts the rotating gears loading animation.
; =======================================================================================================================================
Func _StartLoadingAnimation()
    _GDIPlus_Startup()
    Global Const $STM_SETIMAGE = 0x0172; $IMAGE_BITMAP = 0
    Global $iW = 500, $iH = 250
    Global Const $hGUI = GUICreate("Gears Animation", $iW, $iH, -1, -1, $WS_POPUP, $WS_EX_TOPMOST)
    Global Const $iPic = GUICtrlCreatePic("", 0, 0, $iW, $iH)
    GUICtrlSetState(-1, $GUI_DISABLE)
    GUISetState()

    Global $hHBmp_BG, $hB, $iSleep = 40

    GUIRegisterMsg($WM_TIMER, "PlayAnim")
    DllCall("user32.dll", "int", "SetTimer", "hwnd", $hGUI, "int", 0, "int", $iSleep, "int", 0)
EndFunc

; #FUNCTION# ============================================================================================================================
; Name...........: _StopLoadingAnimation
;
; Description ...: Stops the rotating gears loading animation.
;
; Syntax.........: _StopLoadingAnimation()
;
; Parameters ....: None
;
; Return values .: None
;
; Author.........: UEZ
; Modified By........: MaxG
; Date ..........: 03/27/2014
; Remarks .......: Stops the rotating gears loading animation.
; =======================================================================================================================================
Func _StopLoadingAnimation()
    GUIRegisterMsg($WM_TIMER, "")
    _WinAPI_DeleteObject($hHBmp_BG)
    _GDIPlus_Shutdown()
    GUIDelete()
EndFunc

Func PlayAnim()
    $hHBmp_BG = GearsAnim($iW, $iH)
    $hB = GUICtrlSendMsg($iPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hHBmp_BG)
    If $hB Then _WinAPI_DeleteObject($hB)
    _WinAPI_DeleteObject($hHBmp_BG)
EndFunc   ;==>PlayAnim


Func GearsAnim($iW, $iH, $sText = "Loading...", $fSpeed = 2, $bHBitmap = True)
    Local Const $hBitmap = _GDIPlus_BitmapCreateFromScan0($iW, $iH)
    Local Const $hGfx = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    _GDIPlus_GraphicsSetSmoothingMode($hGfx, $GDIP_SMOOTHINGMODE_ANTIALIAS8X4 + (@OSBuild > 5999))
    _GDIPlus_GraphicsSetTextRenderingHint($hGfx, $GDIP_TEXTRENDERINGHINT_ANTIALIAS)
    _GDIPlus_GraphicsSetPixelOffsetMode($hGfx, $GDIP_PIXELOFFSETMODE_HIGHQUALITY)
    Local Const $hBrush_Bg = _GDIPlus_LineBrushCreate(0,0, $iW / 2, $iH / 2, 0xFF080808, 0xFF606060, 1)
    _GDIPlus_GraphicsFillRect($hGfx, 0, 0, $iW, $iH, $hBrush_Bg)

    Local Const $iW2 = $iW / 2, $iH2 = $iH / 2
    Local Const $hBrush = _GDIPlus_BrushCreateSolid(0)
    Local Static $f1 = 0, $f2 = 0, $f3 = 0, $f4 = 0, $c = 0
    Local $aGears[4], $i, $iW_Gear = 220, $iH_Gear = 150, $iW2_Gear = $iW_Gear / 2, $iH2_Gear = $iH_Gear / 2
    Local Const $hBitmap_Gear = _GDIPlus_BitmapCreateFromScan0($iW_Gear, $iH_Gear)
    Local Const $hCtxt = _GDIPlus_ImageGetGraphicsContext($hBitmap_Gear)
    _GDIPlus_GraphicsSetSmoothingMode($hCtxt, $GDIP_SMOOTHINGMODE_ANTIALIAS8X4 + (@OSBuild > 5999))
    _GDIPlus_GraphicsSetPixelOffsetMode($hCtxt, $GDIP_PIXELOFFSETMODE_HIGHQUALITY)
    _GDIPlus_GraphicsClear($hCtxt, 0xFF121212)

    $aGears[0] = _GDIPlus_BitmapCreateGear($f1)
    _GDIPlus_GraphicsDrawImage($hCtxt, $aGears[0], 0, 1)
    $aGears[1] = _GDIPlus_BitmapCreateGear($f2)
    _GDIPlus_GraphicsDrawImage($hCtxt, $aGears[1], 51, 51)
    $aGears[2] = _GDIPlus_BitmapCreateGear($f3)
    _GDIPlus_GraphicsDrawImage($hCtxt, $aGears[2], 0, 101)
    $aGears[3] = _GDIPlus_BitmapCreateGear($f4, 12, 60, 48)
    _GDIPlus_GraphicsDrawImage($hCtxt, $aGears[3], 120, 4)

    _GDIPlus_GraphicsDrawImageRect($hGfx, $hBitmap_Gear, $iW2 - $iW2_Gear, $iH2 - $iH2_Gear, $iW_Gear, $iH_Gear)

    $f1 -= $fSpeed
    $f2 += $fSpeed
    $f3 -= $fSpeed
    $f4 -= $fSpeed / 2

    Local $iC = Hex(Int(0x80 - Sin($c) * 0x7F), 2)
    $c += 0.025

    _GDIPlus_BrushSetSolidColor($hBrush, "0x9F" & $iC & $iC & $iC)
    $hPath = _GDIPlus_PathCreate()
    Local Const $hFamily = _GDIPlus_FontFamilyCreate("Arial Black"), $hFormat = _GDIPlus_StringFormatCreate()
    _GDIPlus_StringFormatSetAlign($hFormat, 1)
;~  _GDIPlus_StringFormatSetLineAlign($hFormat, 1)
    Local $tLayout = _GDIPlus_RectFCreate(0, 0, $iW, $iH)
    $tLayout.Y = $iH2 + $iH2_Gear + 4
    _GDIPlus_PathAddString($hPath, $sText, $tLayout, $hFamily, 0, $iH / 10, $hFormat)
    _GDIPlus_GraphicsFillPath($hGfx, $hPath, $hBrush)

    _GDIPlus_PathReset($hPath)
    Local Const $iPenSize = 2

    Local $tRect = DllStructCreate("float X; float Y; float W; float H;")
    $tRect.W = $iW_Gear * 1.5
    $tRect.H = $iH_Gear
    Local $hBrush_outline = _GDIPlus_LineBrushCreateFromRectWithAngle($tRect, 0xFF202020, 0xFFA0A0A0, -210, True, 1)
    _GDIPlus_LineBrushSetSigmaBlend($hBrush_outline, 0, 1)

    Local Const $hPen = _GDIPlus_PenCreate2($hBrush_outline, $iPenSize)
    $iW2_Gear += $iPenSize / 2
    $iH2_Gear += $iPenSize / 2
    Local $aPoints[9][2] = [[8]], $iCorner = 5
    $aPoints[1][0] = $iW2 - $iW2_Gear + $iCorner
    $aPoints[1][1] = $iH2 - $iH2_Gear
    $aPoints[2][0] = $iW2 + $iW2_Gear - $iCorner
    $aPoints[2][1] = $iH2 - $iH2_Gear
    $aPoints[3][0] = $iW2 + $iW2_Gear
    $aPoints[3][1] = $iH2 - $iH2_Gear + $iCorner
    $aPoints[4][0] = $iW2 + $iW2_Gear
    $aPoints[4][1] = $iH2 + $iH2_Gear - $iCorner

    $aPoints[5][0] = $iW2 + $iW2_Gear - $iCorner
    $aPoints[5][1] = $iH2 + $iH2_Gear
    $aPoints[6][0] = $iW2 - $iW2_Gear + $iCorner
    $aPoints[6][1] = $iH2 + $iH2_Gear
    $aPoints[7][0] = $iW2 - $iW2_Gear
    $aPoints[7][1] = $iH2 + $iH2_Gear - $iCorner
    $aPoints[8][0] = $iW2 - $iW2_Gear
    $aPoints[8][1] = $iH2 - $iH2_Gear + $iCorner

    _GDIPlus_PathAddClosedCurve2($hPath, $aPoints, 0.025)
    _GDIPlus_GraphicsDrawPath($hGfx, $hPath, $hPen)

    _GDIPlus_PenDispose($hPen)
    _GDIPlus_PathDispose($hPath)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_BrushDispose($hBrush_Bg)
    _GDIPlus_BrushDispose($hBrush_outline)
    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_StringFormatDispose($hFormat)
    For $i = 0 to 3
        _GDIPlus_BitmapDispose($aGears[$i])
    Next
    _GDIPlus_GraphicsDispose($hCtxt)
    _GDIPlus_BitmapDispose($hBitmap_Gear)
    _GDIPlus_GraphicsDispose($hGfx)

    If $bHBitmap Then
        Local $hHBITMAP = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
        _GDIPlus_BitmapDispose($hBitmap)
        Return $hHBITMAP
    EndIf
    Return $hBitmap
EndFunc   ;==>GearsAnim

Func _GDIPlus_BitmapCreateGear($fAngle = 0, $iTeeth = 6, $fRadius_outer = 30, $fRadius_inner = 18, $fTeethHeight = 10.5, $iColor1 = 0xFF606060, $iColor2 = 0xFF404040)
    Local Const $iW = 2 * $fRadius_outer + $fTeethHeight * 2, $iH = $iW, $iW2 = $iW / 2, $iH2 = $iW2, $fDeltaAngle = 360 / $iTeeth, $fDeg = 3.14159265358979 / 180
    Local Const $hBitmap = _GDIPlus_BitmapCreateFromScan0($iW, $iH)
    Local Const $hGfx = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    _GDIPlus_GraphicsSetSmoothingMode($hGfx, $GDIP_SMOOTHINGMODE_ANTIALIAS8X4 + (@OSBuild > 5999))

    Local $tRect = DllStructCreate("float X; float Y; float W; float H;")
    $tRect.W = $iW
    $tRect.H = $iH / 2
    Local $hBrush_outline = _GDIPlus_LineBrushCreateFromRectWithAngle($tRect, 0x44000000 + BitAND(0x00FFFFFF, $iColor2), 0, -90, True, 1)
    _GDIPlus_LineBrushSetSigmaBlend($hBrush_outline, 1, 0.95)
    _GDIPlus_LineBrushSetColors($hBrush_outline, 0, 0xAA989898)

    Local Const $hPen = _GDIPlus_PenCreate2($hBrush_outline, 2)
    Local Const $hBrush = _GDIPlus_BrushCreateSolid($iColor1)
    Local Const $hPath = _GDIPlus_PathCreate()
    _GDIPlus_PathAddEllipse($hPath, $iW2 - $fRadius_outer, $iH2 - $fRadius_outer, $fRadius_outer * 2, $fRadius_outer * 2)
    Local $aPoints[5][2] = [[4]], $iX, $iY, $i, $j
    For $i = 1 To $iTeeth
        $iX = $iW2 + Cos(($fAngle + 0) * $fDeg) * $fRadius_outer
        $iY = $iH2 + Sin(($fAngle + 0) * $fDeg) * $fRadius_outer
        For $j = 0 To $aPoints[0][0]
            $aPoints[1][0] = $iX + Cos(($fAngle + 45) * $fDeg) * $fTeethHeight
            $aPoints[1][1] = $iY + Sin(($fAngle + 45) * $fDeg) * $fTeethHeight
            $aPoints[2][0] = $iX + Cos(($fAngle + 135) * $fDeg) * $fTeethHeight
            $aPoints[2][1] = $iY + Sin(($fAngle + 135) * $fDeg) * $fTeethHeight
            $aPoints[3][0] = $iX + Cos(($fAngle + 225) * $fDeg) * $fTeethHeight
            $aPoints[3][1] = $iY + Sin(($fAngle + 225) * $fDeg) * $fTeethHeight
            $aPoints[4][0] = $iX + Cos(($fAngle + 315) * $fDeg) * $fTeethHeight
            $aPoints[4][1] = $iY + Sin(($fAngle + 315) * $fDeg) * $fTeethHeight
        Next
        _GDIPlus_PathAddPolygon($hPath, $aPoints)
        $fAngle += $fDeltaAngle
    Next
    _GDIPlus_PathWindingModeOutline($hPath)
    _GDIPlus_PathAddEllipse($hPath, $iW2 - $fRadius_inner, $iH2 - $fRadius_inner, $fRadius_inner * 2, $fRadius_inner * 2)
    _GDIPlus_GraphicsFillPath($hGfx, $hPath, $hBrush)
    _GDIPlus_GraphicsDrawPath($hGfx, $hPath, $hPen)
    _GDIPlus_PathDispose($hPath)
    _GDIPlus_PenDispose($hPen)
    _GDIPlus_BrushDispose($hBrush_outline)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_GraphicsDispose($hGfx)
    Return $hBitmap
EndFunc
Link to comment
Share on other sites

  • Solution

 

....while this block of code starts the animation (_StartLoadingAnimation) but never reaches the MsgBox.

 

That's not true ;)

The animation has the topmost style set and the MsgBox is behind the animation.

You have to set either the MsgBox also topmost or set it as a child of the GUI.

Here both together:

...
_StartLoadingAnimation()
MsgBox(262144,"Test", "Right after animation starts", 0, $hGUI)
...

Br,

UEZ

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

Link to comment
Share on other sites

That's interesting.  It never occurred to me that the MsgBox would be behind the animation but it makes perfect sense.

I tested the MsgBox code you posted and, sure enough, it popped up just fine...  so the code is executing after _StartLoadingAnimation()

However, I added the MsgBox as part of debugging.  The original issue was that without the MsgBox it seemed like _StopLoadingAnimation() never gets called after the WinWaitActive, WinWait, and Sleep statements.

Thanks to you I at least knew for sure that script execution was continuing after _StartLoadingAnimation()... so moving down the script I tested my WinWaitActive statement.  Turns out the loading animation was changing the way in which focus was being transferred.

I reconsidered my code logic and realized that my WinWaitActive statement was unnecessary anyway.  Removing it made the animation start and stop as expected and made that section a little more reliable overall.

Thanks again UEZ, marking this one solved!

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...