Jump to content

Recommended Posts

Posted

@UEZ hello :)


I would like to expose an issue I got when a pic control is resided with GUICtrlSetResizing($idPic, $GUI_DOCKAUTO) , maybe you could be so kind to indicate if something is doable or not. Though the images below don't show it, all what follows has also been tested right now on Windows 11, but the issue (if it's an issue) is still there.

1) Grid.png (3KB, downloadable at the end of this post)
This is a png image 600x600 pixels, white background, with a grid composed of squares of 20x20 pixels :

image.png.c63fe2dbd604870ee4455eca58db1ae1.png

2) I create a pic control with this png, in a script having a gui which client size is also 600x600 pixels
The gui is resizable and contains controls (all movable and resizable) as shown in the pic below. The grid helps a lot to align the controls :

image.png.db98fc6c7348c0ab61b0a15919e1614a.png

3) When the yellow checkbox control is checked, then the pic control (containing grid.png) is hidden, the gui grey background reappears and all other controls react correctly (by design) as shown in the pic below :

image.png.487244fdf8861d21d62bd1bd0a2aeb6e.png

When the script ends, all coords are saved, so all controls will be correctly placed when the script is run again, so far so good

4) Now please have a look at this simpler script that will indicate the issue :

#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

Opt("MustDeclareVars", 1)

Example()

Func Example()
    Local $sImagePath = @ScriptDir & "\Grid.png"

    _GDIPlus_Startup()
    Local $hImage = _GDIPlus_ImageLoadFromFile($sImagePath)
    Local $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
    Local $iX = _GDIPlus_ImageGetWidth($hImage)
    Local $iY = _GDIPlus_ImageGetHeight($hImage)

    Local $hGUI = GUICreate("Grid Test", $iX, $iY, -1, -1, $WS_OVERLAPPEDWINDOW)
    GUISetBkColor(0x808080) ; grey

    Local $idPic = GUICtrlCreatePic("", 0, 0, $iX, $iY)
    _WinAPI_DeleteObject(GUICtrlSendMsg($idPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hBitmap))
    GUICtrlSetResizing($idPic, $GUI_DOCKAUTO)
    GUICtrlSetState($idPic, $GUI_DISABLE)
    GUISetState(@SW_SHOW)

    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    _WinAPI_DeleteObject($hBitmap)
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_Shutdown()
EndFunc   ;==>Example

5) When you run the script in 4) the pic 600x600 showing the grid is displayed in the gui. Now if you resize the gui horizontally (dragging its right border to the left) then the gui client width becomes < 600 pixels . In this case, the vertical lines only becomes messy, as shown in the pic below :

image.png.295b4743284ad6063cbfe0a4537ee884.png

6) When you run the script in 4) the pic 600x600 showing the grid is displayed in the gui. Now if you resize the gui vertically (dragging its bottom border to the top) then the gui client height becomes < 600 pixels . In this case, the horizontal lines only becomes messy, as shown in the pic below :

image.png.626ec2f6729e1baa88fe926e1724f430.png

7) If you resize both width and height (both being < 600 pixels) then all lines are messy : this is 5) + 6) as shown in the pic below :

image.png.7a890165b7967e4ca98df7e105bf21dd.png

8 ) Applied to 2) you will end up with this bad display, after you resize the gui to width & height < 600 pixels :

image.png.b7db248ed8b113cc10f97541a66275f6.png

Please note that width and height > 600 pixels behave correctly, the problem occurs only when < 600 pixels.
For the record, I tried also a jpg image (instead of a png) with the same bad display.

I thought that GUICtrlSetResizing() was enough to fix this, but apparently not. Do you think there is an easy solution to avoid this, or should I update the pic control constantly during the resize phase, with a resized or scaled image, or maybe another solution ?

Thanks for reading

Grid.png

 

"I think you are searching a bug where there is no bug... don't listen to bad advice."

Posted (edited)

Is the grid just for demonstration purposes, or is that really the background you want to use?

Should the grid resize when the GUI is resized?

 

Here the version without resizing the grid on GUI resize (modified one of my old scripts):

;Coded by UEZ build 2026-05-31

#include <Constants.au3>
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Global Const $STM_SETIMAGE = 0x0172
Global $sImage = "Grid.png"

_GDIPlus_Startup()
Global $hBmp = _GDIPlus_BitmapCreateFromFile($sImage), $hTexture = _GDIPlus_TextureCreate($hBmp, 0)
Global $iW = _GDIPlus_ImageGetWidth($hBmp), $iH = _GDIPlus_ImageGetHeight($hBmp)

Global $hGUI = GUICreate("Test", $iW, $iH, -1, -1, BitOR($GUI_SS_DEFAULT_GUI, $WS_SIZEBOX, $WS_THICKFRAME), $WS_EX_COMPOSITED)
Global $idPic = GUICtrlCreatePic("", 0, 0, $iW, $iH)
GUICtrlSetResizing(-1, $GUI_DOCKAUTO)

Global $hHBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBmp)
Global $hB = GUICtrlSendMsg($idPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hHBitmap)
If $hB Then _WinAPI_DeleteObject($hB)
GUISetState(@SW_SHOW)

GUIRegisterMsg($WM_SIZE, "WM_SIZE")

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            GUIRegisterMsg($WM_SIZE, "")
            _WinAPI_DeleteObject($hHBitmap)
            _GDIPlus_BrushDispose($hTexture)
            _GDIPlus_BitmapDispose($hBmp)
            _GDIPlus_Shutdown()
            GUIDelete()
            Exit
    EndSwitch
WEnd

Func WM_SIZE($hWnd, $Msg, $wParam, $lParam)
    #forceref $Msg, $wParam, $lParam
    Local $aSize = ControlGetPos($hWnd, "", $idPic)
    Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($aSize[2], $aSize[3])
    Local $hContext = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    _GDIPlus_GraphicsSetInterpolationMode($hContext, 0)
    _GDIPlus_GraphicsFillRect($hContext, 0, 0, $aSize[2], $aSize[3], $hTexture)
    _GDIPlus_GraphicsDispose($hContext)
    Local $hHBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
    Local $hB = GUICtrlSendMsg($idPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hHBitmap)
    If $hB Then _WinAPI_DeleteObject($hB)
    _WinAPI_DeleteObject($hHBitmap)
    _GDIPlus_BitmapDispose($hBitmap)
    Return "GUI_RUNDEFMSG"
EndFunc

 

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

Posted

Thanks for your script, very informative.

52 minutes ago, UEZ said:

Is the grid just for demonstration purposes, or is that really the background you want to use?

Yes it is the background I want to use.
 

52 minutes ago, UEZ said:

Should the grid resize when the GUI is resized?

 

Definitely, the grid should resize when the GUI is resized, as you can see in my preceding post, when comparing image in 2) with image in 8 )

By the way, bravo for your super comment in trac ticket 4098, it explains nicely why graphics context disappear and how to fix that. I wish your code to fix the disappearing of graphics context was found in all help file examples related to that !
You did well adding the fixing lines preceded with a Tab so it was easy to detect them :thumbsup:

"I think you are searching a bug where there is no bug... don't listen to bad advice."

Posted
7 minutes ago, pixelsearch said:

Definitely, the grid should resize when the GUI is resized, as you can see in my preceding post, when comparing image in 2) with image in 8 )

With resize I mean really resize of the grid. My example above fills only the grid but doesn't resize it. You can also resize the grid when GUI resizes. That means the grid becomes smaller / bigger on GUI resize.

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
;Coded by UEZ build 2026-05-31

#include <Constants.au3>
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Global Const $STM_SETIMAGE = 0x0172
Global $sImage = "image.png"

_GDIPlus_Startup()
Global $hBmp = _GDIPlus_BitmapCreateFromFile($sImage), $hTexture = _GDIPlus_TextureCreate($hBmp, 0)
Global $iW = _GDIPlus_ImageGetWidth($hBmp), $iH = _GDIPlus_ImageGetHeight($hBmp)

Global $g_hWnd, $hGUI = GUICreate("Test", $iW, $iH, -1, -1, BitOR($GUI_SS_DEFAULT_GUI, $WS_SIZEBOX, $WS_THICKFRAME), $WS_EX_COMPOSITED)
Global $idPic = GUICtrlCreatePic("", 0, 0, $iW, $iH)
GUICtrlSetResizing(-1, $GUI_DOCKAUTO)

Global $hHBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBmp)
Global $hB = GUICtrlSendMsg($idPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hHBitmap)
If $hB Then _WinAPI_DeleteObject($hB)
GUISetState(@SW_SHOW)

GUIRegisterMsg($WM_SIZE, "WM_SIZE")

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            GUIRegisterMsg($WM_SIZE, "")
            _WinAPI_DeleteObject($hHBitmap)
            _GDIPlus_BrushDispose($hTexture)
            _GDIPlus_BitmapDispose($hBmp)
            _GDIPlus_Shutdown()
            GUIDelete()
            Exit
    EndSwitch
WEnd

Func WM_SIZE($hWnd, $Msg, $wParam, $lParam)
    #forceref $Msg, $wParam, $lParam
    $g_hWnd = $hWnd
    doit()
    AdlibRegister(doit, 100)
    Return "GUI_RUNDEFMSG"
EndFunc

Func doit()
    AdlibUnRegister(doit)
    Local $aSize = ControlGetPos($g_hWnd, "", $idPic)
    Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($aSize[2], $aSize[3])
    Local $hContext = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    _GDIPlus_GraphicsSetInterpolationMode($hContext, 0)
    _GDIPlus_GraphicsFillRect($hContext, 0, 0, $aSize[2], $aSize[3], $hTexture)
    _GDIPlus_GraphicsDispose($hContext)
    Local $hHBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
    Local $hB = GUICtrlSendMsg($idPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hHBitmap)
    If $hB Then _WinAPI_DeleteObject($hB)
    _WinAPI_DeleteObject($hHBitmap)
    _GDIPlus_BitmapDispose($hBitmap)
EndFunc

..to give it a last pass. Looks better on mouse release :) 

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting  image.gif.922e3a93535f431de08b31ee669cc446.gif
autoit_scripter_blue_userbar.png

Posted (edited)
On 5/31/2026 at 6:30 PM, UEZ said:

You can also resize the grid when GUI resizes. That means the grid becomes smaller / bigger on GUI resize.

Hello UEZ :)
Yes that's why I want, so I just scripted what follows, to have the grid image shrink harmoniously with the GUI : no more artefacts as shown in my 1st post. Please be kind to indicate if something needs to be improved, thank you.

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

Opt("MustDeclareVars", 1)

Global $g_hImage, $g_idPic
Example()

Func Example()
    Local $sFileName  = @ScriptDir & "\Grid.png"

    _GDIPlus_Startup()
    $g_hImage = _GDIPlus_ImageLoadFromFile($sFileName) ; note that file is locked on disk until _GDIPlus_ImageDispose()
    Local $iW = _GDIPlus_ImageGetWidth($g_hImage), $iH = _GDIPlus_ImageGetHeight($g_hImage)

    Local $hGUI = GUICreate("Test Grid", $iW, $iH, -1, -1, $WS_OVERLAPPEDWINDOW, $WS_EX_COMPOSITED)
    $g_idPic = GUICtrlCreatePic("", 0, 0, $iW, $iH)
    GUICtrlSetResizing(-1, $GUI_DOCKAUTO) ; or $GUI_DOCKBORDERS ?
    Update_Pic($g_hImage)

    GUISetState(@SW_SHOW)
    GUIRegisterMsg($WM_SIZE, "WM_SIZE")

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                _GDIPlus_ImageDispose($g_hImage)
                _GDIPlus_Shutdown()
                GUIDelete()
                Exit
        EndSwitch
    WEnd
EndFunc   ;==>Example

Func Update_Pic($hHandle)
    Local $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hHandle)
    Local $hPrevImage = GUICtrlSendMsg($g_idPic, 0x0172, 0, $hBitmap) ; $STM_SETIMAGE = 0x0172, $IMAGE_BITMAP = 0
    If $hPrevImage Then _WinAPI_DeleteObject($hPrevImage); delete prev image if any (help file)
    _WinAPI_DeleteObject($hBitmap)
EndFunc   ;==>Update_Pic

Func WM_SIZE($hWnd, $iMsg, $wParam, $lParam)
    Local $hImage_resized = _GDIPlus_ImageResize($g_hImage, BitAND($lParam, 0xFFFF), BitShift($lParam, 16))
    Update_Pic($hImage_resized)
    _GDIPlus_ImageDispose($hImage_resized)
    Return "GUI_RUNDEFMSG"
EndFunc   ;==>WM_SIZE

Also, I compared both functions _GDIPlus_ImageResize() and _GDIPlus_ImageScale() to make sure which one was more convenient in my case. Both functions are nearly the same, but as I natively got new width & height in $lParam of WM_SIZE, then I choosed _GDIPlus_ImageResize() in the script.

One question if you don't mind : is it normal that _GDIPlus_ImageAttributesDispose($hIA) is found only in _GDIPlus_ImageScale() but not in _GDIPlus_ImageResize() ?

Edited by pixelsearch
typo

"I think you are searching a bug where there is no bug... don't listen to bad advice."

Posted
Func _GDIPlus_ImageResize($hImage, $iNewWidth, $iNewHeight, $iInterpolationMode = $GDIP_INTERPOLATIONMODE_HIGHQUALITYBICUBIC)
    Local $iWidth = _GDIPlus_ImageGetWidth($hImage)
    If @error Then Return SetError(1, 0, 0)
    Local $iHeight = _GDIPlus_ImageGetHeight($hImage)
    If @error Then Return SetError(2, 0, 0)
    Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($iNewWidth, $iNewHeight)
    If @error Then Return SetError(3, 0, 0)
    Local $hBmpCtxt = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    _GDIPlus_GraphicsSetInterpolationMode($hBmpCtxt, $iInterpolationMode)
    _GDIPlus_GraphicsSetPixelOffsetMode($hBmpCtxt, $GDIP_PIXELOFFSETMODE_HIGHQUALITY)
    Local $hIA = _GDIPlus_ImageAttributesCreate()
    __GDIPlus_ImageAttributesSetImageWrapMode($hIA)
    If @error Then
        _GDIPlus_ImageAttributesDispose($hIA)
        _GDIPlus_GraphicsDispose($hBmpCtxt)
        _GDIPlus_BitmapDispose($hBitmap)
        Return SetError(4, 0, 0)
    EndIf
    _GDIPlus_GraphicsDrawImageRectRect($hBmpCtxt, $hImage, 0, 0, $iWidth, $iHeight, 0, 0, $iNewWidth, $iNewHeight, $hIA)
    _GDIPlus_GraphicsDispose($hBmpCtxt)
    Return $hBitmap
EndFunc   ;==>_GDIPlus_ImageResize

Func _GDIPlus_ImageScale($hImage, $iScaleW, $iScaleH, $iInterpolationMode = $GDIP_INTERPOLATIONMODE_HIGHQUALITYBICUBIC)
    Local $iWidth = _GDIPlus_ImageGetWidth($hImage)
    If @error Then Return SetError(1, 0, 0)
    Local $iHeight = _GDIPlus_ImageGetHeight($hImage)
    If @error Then Return SetError(2, 0, 0)
    Local $iNewWidth = $iWidth * $iScaleW
    Local $iNewHeight = $iHeight * $iScaleH
    Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($iNewWidth, $iNewHeight)
    If @error Then Return SetError(3, 0, 0)
    Local $hBmpCtxt = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    _GDIPlus_GraphicsSetInterpolationMode($hBmpCtxt, $iInterpolationMode)
    _GDIPlus_GraphicsSetPixelOffsetMode($hBmpCtxt, $GDIP_PIXELOFFSETMODE_HIGHQUALITY)
    Local $hIA = _GDIPlus_ImageAttributesCreate()
    __GDIPlus_ImageAttributesSetImageWrapMode($hIA)
    If @error Then
        _GDIPlus_ImageAttributesDispose($hIA)
        _GDIPlus_GraphicsDispose($hBmpCtxt)
        _GDIPlus_BitmapDispose($hBitmap)
        Return SetError(4, 0, 0)
    EndIf
    _GDIPlus_GraphicsDrawImageRectRect($hBmpCtxt, $hImage, 0, 0, $iWidth, $iHeight, 0, 0, $iNewWidth, $iNewHeight, $hIA)
    _GDIPlus_ImageAttributesDispose($hIA)
    _GDIPlus_GraphicsDispose($hBmpCtxt)
    Return $hBitmap
EndFunc   ;==>_GDIPlus_ImageScale

I can see it in both functions. 😉

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
13 minutes ago, UEZ said:

I can see it in both functions. 😉

Yes in the @error part, both functions are ok :

If @error Then
    _GDIPlus_ImageAttributesDispose($hIA)
    _GDIPlus_GraphicsDispose($hBmpCtxt)
    _GDIPlus_BitmapDispose($hBitmap)
    Return SetError(4, 0, 0)
EndIf

But I was concerned by what happens after, when there is no @error :

_GDIPlus_GraphicsDrawImageRectRect($hBmpCtxt, $hImage, 0, 0, $iWidth, $iHeight, 0, 0, $iNewWidth, $iNewHeight, $hIA)
_GDIPlus_GraphicsDispose($hBmpCtxt)
Return $hBitmap

versus

_GDIPlus_GraphicsDrawImageRectRect($hBmpCtxt, $hImage, 0, 0, $iWidth, $iHeight, 0, 0, $iNewWidth, $iNewHeight, $hIA)
_GDIPlus_ImageAttributesDispose($hIA)
_GDIPlus_GraphicsDispose($hBmpCtxt)
Return $hBitmap

 

"I think you are searching a bug where there is no bug... don't listen to bad advice."

Posted (edited)

Indeed

_GDIPlus_ImageAttributesDispose($hIA)

is missing in _GDIPlus_ImageResize() after / before _GDIPlus_GraphicsDispose($hBmpCtxt), which can lead to memory leaks when called multible times.

@jpm can you fix it please?

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

Posted (edited)

Thanks for your confirmation concerning the missing line, it will surely be fixed in next release.

By the way, I'm actually trying all possible values of the 4th parameter in _GDIPlus_ImageResize, which is $iInterpolationMode (default is $GDIP_INTERPOLATIONMODE_HIGHQUALITYBICUBIC)

I guess it accepts all values found in _GDIPlus_GraphicsSetInterpolationMode, which are :

$GDIP_INTERPOLATIONMODE_DEFAULT (0) - Default interpolation mode
$GDIP_INTERPOLATIONMODE_LOWQUALITY (1) - Low-quality mode
$GDIP_INTERPOLATIONMODE_HIGHQUALITY (2) - High-quality mode
$GDIP_INTERPOLATIONMODE_BILINEAR (3) - Bilinear interpolation. No prefiltering is done
$GDIP_INTERPOLATIONMODE_BICUBIC (4) - Bicubic interpolation. No prefiltering is done
$GDIP_INTERPOLATIONMODE_NEARESTNEIGHBOR (5) - Nearest-neighbor interpolation
$GDIP_INTERPOLATIONMODE_HIGHQUALITYBILINEAR (6) - High-quality, bilinear interpolation. Prefiltering is performed to ensure high-quality shrinking
$GDIP_INTERPOLATIONMODE_HIGHQUALITYBICUBIC (7) - High-quality, bicubic interpolation. Prefiltering is performed to ensure high-quality shrinking

This is what happens when I apply different values in this line of my last script :

Local $hImage_resized = _GDIPlus_ImageResize($g_hImage, BitAND($lParam, 0xFFFF), BitShift($lParam, 16), 0 to 7)
2, 6, 7 : shrink is ok
0, 1, 3, 4, 5 : shrink is bad

"Bad" means if I shrink the GUI, then all artefacts found in my 1st post [ chapters 5) 6) 7) ] are shown again.
There was no _GDIPlus_ImageResize() in my very first script [ 1st post, chapter 4) ] so maybe AutoIt's GUICtrlSetResizing(-1, $GUI_DOCKAUTO) creates the problem in my 1st script, by shrinking the pic with a "low quality" parameter etc...

Anyway, I hoped that GUICtrlSetResizing(-1, $GUI_DOCKAUTO) would be enough to shrink correctly the pic in all cases but it's not enough, gladly _GDIPlus_ImageResize() with a 4th parameter = 2|6|7 does the job correctly.

One more thing : I'm gonna create a bigger Grid.png, which will be suitable to plenty of GUI's width and height, for example a grid of 1920x1080 pixels. That grid will be immediately cloned in the script (using probably _GDIPlus_BitmapCloneArea) to have the exact client size of the initial GUI. In theory it should work and be more user friendly, especially this Grid.png is only a few Kb's

For the record, I create the grid image through Paint Shop Pro => new image, size 1920x1080, white background.
Then from the paintshop menu, add a temporary grid (black color) of 20x20 pixels, no need of adding rulers or guides. Finally take a snapshot of the image and save it as Grid.png

 

Edited by pixelsearch
typo

"I think you are searching a bug where there is no bug... don't listen to bad advice."

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...