#4098 new Bug

_GDIPlus — at Version 4

Reported by: jak_piotr@… Owned by:
Milestone: Component: AutoIt
Version: Other Severity: None
Keywords: Cc:

Description (last modified by mLipok)

GDIPlus example in this module that all examples that are not animated disappear when minimized e.g. _GDIPlus_ColorMatrixCreate()

Change History (4)

comment:1 by Jpm, on May 29, 2026 at 4:27:16 PM

Perhaps UEZ can help on the subject

comment:2 by pixelsearch, on May 29, 2026 at 7:10:47 PM

Hello everybody,
OP jak_piotr indicates function _GDIPlus_ColorMatrixCreate in his description above.
If not mistaken, all 3 examples in help file using _GDIPlus_ColorMatrixCreate also use _GDIPlus_GraphicsDrawImageRectRect

So let's go to function _GDIPlus_GraphicsDrawImageRectRect and have a look at its 2 examples :

  • Example 2 of _GDIPlus_GraphicsDrawImageRectRect is the animated example :

jak_piotr indicates that everything is ok with this example, probably because the graghic is drawn every 20 ms during the main loop, with new coords, so far so good.

  • Example 1 of _GDIPlus_GraphicsDrawImageRectRect is the non-animated example :

No graphic redraw within the main loop, so the graphics disappear in the 3 following cases (at least) :

1) Minimizing / Restoring the Gui (as indicated by OP)
2) Dragging the GUI a bit outside the screen (all the hidden part of the gui loses its graphic)
3) Covering the GUI (totally or partially) with another window.

To solve these 3 cases, I tried what follows in the script below (example 1, reworked) :
1) $GUI_EVENT_RESTORE to take care of a restored GUI
2) $WM_MOVE to take care of a moved GUI
3) WinActive($hGUI) to take care of another window covering the GUI

All 3 cases use the same global variable $g_bRedraw : when this variable is True, then the graphics is redrawn (and the variable goes to False)

#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <ScreenCapture.au3>
#include <WinAPIHObj.au3>

Global $g_bRedraw

Example()

Func Example()
        _GDIPlus_Startup() ;initialize GDI+
        Local Const $iWidth = 600, $iHeight = 600

        Local $hGUI = GUICreate("GDI+ Example (" & @ScriptName & ")", $iWidth, $iHeight) ;create a test GUI
        GUISetState(@SW_SHOW)

        Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI) ;create a graphics object from a window handle
        Local $pIA = _GDIPlus_ImageAttributesCreate() ;create an ImageAttribute object

        ;create the color matrix used to adjust the colors of the image
        Local $tColorMatrix = _GDIPlus_ColorMatrixCreateTranslate(-1, -1, 0) ;use translation color matrix to create a blue scaled image

        _GDIPlus_ImageAttributesSetColorMatrix($pIA, 0, True, $tColorMatrix) ;adjust the ImageAttribute color-key color matrix

        Local $hHBmp = _ScreenCapture_Capture("", 0, 0, $iWidth, $iHeight) ;create a GDI bitmap by capturing an area on desktop
        Local $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hHBmp) ;convert GDI to GDI+ bitmap
        _WinAPI_DeleteObject($hHBmp) ;release GDI bitmap resource because not needed anymore
        _GDIPlus_GraphicsDrawImageRectRect($hGraphics, $hBitmap, 0, 0, $iWidth, $iHeight, 0, 0, $iWidth, $iHeight, $pIA) ;draw the bitmap while applying the color adjustment

        GUIRegisterMsg($WM_MOVE, "WM_MOVE")

        While 1
                Switch GUIGetMsg()
                        Case $GUI_EVENT_CLOSE
                                ExitLoop
                        Case $GUI_EVENT_RESTORE
                                $g_bRedraw = True
                EndSwitch
                If Not WinActive($hGUI) Then $g_bRedraw = True
                If $g_bRedraw And WinActive($hGUI) Then
                        _GDIPlus_GraphicsDrawImageRectRect($hGraphics, $hBitmap, 0, 0, $iWidth, $iHeight, 0, 0, $iWidth, $iHeight, $pIA)
                        $g_bRedraw = False
                EndIf
        WEnd

        ;cleanup GDI+ resources
        _GDIPlus_ImageAttributesDispose($pIA)
        _GDIPlus_GraphicsDispose($hGraphics)
        _GDIPlus_BitmapDispose($hBitmap)
        _GDIPlus_Shutdown()
        GUIDelete($hGUI)
EndFunc   ;==>Example

Func WM_MOVE($hWnd, $iMsg, $wParam, $lParam)
        $g_bRedraw = True
        Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_MOVE

Hope it helps a bit, until UEZ indicates his solution, which will certainly be more accurate.

Last edited on Jun 9, 2026 at 7:17:51 PM by mLipok (previous) (diff)

comment:3 by UEZ, on May 29, 2026 at 8:02:12 PM

This behavior is by design and not a bug. When a window is minimized, hidden, or moved out of the visible screen area, Windows invalidates the graphics context, causing static GDI+ drawings to disappear. Since non-animated examples lack a continuous redraw loop, the image is not repainted when the window is restored.

To resolve this without the need for a complex $WM_PAINT message handler, the updated example separates the source and target canvas by creating a new blank bitmap via _GDIPlus_BitmapCreateFromScan0. The original capture is drawn onto this new bitmap while applying the ColorMatrix attributes, preventing any GDI+ source-target conflicts. Finally, the processed image is converted to a GDI handle and assigned to a native AutoIt Picture control (GUICtrlCreatePic) via $STM_SETIMAGE. This solves both issues at once: it ensures clean GDI+ rendering and relies entirely on native Windows OS routines to keep the image persistent during minimization or restoration.

#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <ScreenCapture.au3>
#include <StaticConstants.au3>
#include <WinAPIHObj.au3>

Example()

Func Example()
    _GDIPlus_Startup() ;initialize GDI+

    Local Const $iWidth = 600, $iHeight = 600

    Local $hHBmp = _ScreenCapture_Capture("", 0, 0, $iWidth, $iHeight) ;create a GDI bitmap by capturing an area on desktop
    Local $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hHBmp) ;convert GDI to GDI+ bitmap
    _WinAPI_DeleteObject($hHBmp) ;release GDI bitmap resource because not needed anymore
        Local $hImage = _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight)
        Local $hGraphics = _GDIPlus_ImageGetGraphicsContext($hImage)
    Local $hGUI = GUICreate("GDI+ Example (" & @ScriptName & ")", $iWidth, $iHeight) ;create a test GUI
        Local $iPic = GUICtrlCreatePic("", 0, 0, $iWidth, $iHeight)
    GUISetState(@SW_SHOW)
        
    Local $hIA = _GDIPlus_ImageAttributesCreate() ;create an ImageAttribute object
    Local $tColorMatrix = _GDIPlus_ColorMatrixCreate() ;create color matrix

    Local $iX, $iY
    For $iX = 0 To 3 ;manipulate some values in the color matrix
        For $iY = 0 To 3
            DllStructSetData($tColorMatrix, "m", Random(0, 0.5), $iY * 5 + $iX + 1)
        Next
    Next

    _GDIPlus_ImageAttributesSetColorMatrix($hIA, 0, True, $tColorMatrix) ;adapt the modified color matrix
    _GDIPlus_GraphicsDrawImageRectRect($hGraphics, $hBitmap, 0, 0, $iWidth, $iHeight, 0, 0, $iWidth, $iHeight, $hIA) ;draw the bitmap while applying the color adjustment
        Local $hBitmap_GDI = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
        _WinAPI_DeleteObject(GUICtrlSendMsg($iPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hBitmap_GDI))
        
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    ;cleanup GDI+ resources
        _WinAPI_DeleteObject($hBitmap_GDI)
        _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_ImageAttributesDispose($hIA)
    _GDIPlus_BitmapDispose($hBitmap)
        _GDIPlus_ImageDispose($hImage)
    _GDIPlus_Shutdown()
    GUIDelete($hGUI)
EndFunc   ;==>Example

Last edited on Jun 9, 2026 at 7:18:23 PM by mLipok (previous) (diff)

comment:4 by mLipok, on Jun 9, 2026 at 7:16:42 PM

Description: modified (diff)
Note: See TracTickets for help on using tickets.