texan

_GDIPlus_GraphicsDrawImageRect image disappears

8 posts in this topic

I am creating a GUi that displays an image from a PNG file. I am using _GDIPlus_GraphicsDrawImageRect to display the image and this works fine. The problem I am having is that the image disappears if you minimize the window then restore it. It also disappears if you drag the window off screen and then back.

The code below demonstrates my issue.

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

Global $BaseFilePath, $GUI, $h, $w
Opt("GUIOnEventMode", 1)  ; Change to OnEvent mode
OnAutoItExitRegister("OnExit")

_GDIPlus_Startup()

$BaseFilePath = "S:\AutoIt\ImageFailure\med.base.png"
$Base = _GDIPlus_ImageLoadFromFile($BaseFilePath)
$h = _GDIPlus_ImageGetHeight($Base)
$w = _GDIPlus_ImageGetWidth($Base)

;Create the Window based on the size of the Baseline file
$GUI = GUICreate("Test",$w,$h,-1,-1,-1,$WS_EX_APPWINDOW)
GUISetOnEvent($GUI_EVENT_CLOSE, "OnExitScript")
$hwndGraphic = _GDIPlus_GraphicsCreateFromHWND($GUI)   ;Create a Graphics object from a Window Handle
GUISetState()
_GDIPlus_GraphicsDrawImageRect($hwndGraphic, $Base, 0, 0, $w, $h)

While 1
    Sleep(100)
WEnd

Func OnExitScript()
    Exit
EndFunc
Func OnExit()
    _GDIPlus_ImageDispose($Base)
    _GDIPlus_GraphicsDispose($hwndGraphic)
    _GDIPlus_Shutdown()
EndFunc

 

Share this post


Link to post
Share on other sites



A suggestion is to repaint the picture from a GUI event so you would replace the consolewrites in the WM_SYSCOMMAND function with the repaint functionality: Link 

 

 


Snips & Scripts


My Snips: graphCPUTemp ~ getENVvars
My Scripts: Short-Order Encrypter - message and file encryption V1.6.1 ~ AuPad - Notepad written entirely in AutoIt V1.9.4

Feel free to use any of my code for your own use.                                                                                                                                                           Forum FAQ

 

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Either this way:

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

Global $BaseFilePath, $GUI, $h, $w
Opt("GUIOnEventMode", 1)  ; Change to OnEvent mode
OnAutoItExitRegister("OnExit")

_GDIPlus_Startup()

$BaseFilePath = "S:\AutoIt\ImageFailure\med.base.png"
$Base = _GDIPlus_ImageLoadFromFile($BaseFilePath)
$h = _GDIPlus_ImageGetHeight($Base)
$w = _GDIPlus_ImageGetWidth($Base)

;Create the Window based on the size of the Baseline file
$GUI = GUICreate("Test",$w,$h,-1,-1,-1,$WS_EX_APPWINDOW)
GUISetOnEvent($GUI_EVENT_CLOSE, "OnExit")
GUISetOnEvent($GUI_EVENT_RESTORE, "Repaint")
$hwndGraphic = _GDIPlus_GraphicsCreateFromHWND($GUI)   ;Create a Graphics object from a Window Handle
GUISetState()
Repaint()

GUIRegisterMsg($WM_PAINT, "WM_PAINT")

While 1
    Sleep(100)
WEnd

Func Repaint()
    _GDIPlus_GraphicsDrawImageRect($hwndGraphic, $Base, 0, 0, $w, $h)
EndFunc


Func WM_PAINT()
    Repaint()
    Return "GUI_RUNDEFMSG"
EndFunc

Func OnExit()
    GUIRegisterMsg($WM_PAINT, "")
    _GDIPlus_ImageDispose($Base)
    _GDIPlus_GraphicsDispose($hwndGraphic)
    _GDIPlus_Shutdown()
    GUIDelete()
    Exit
EndFunc

 

or this:

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

Global $BaseFilePath, $GUI, $h, $w
Opt("GUIOnEventMode", 1)  ; Change to OnEvent mode
OnAutoItExitRegister("OnExit")

_GDIPlus_Startup()

Global Const $STM_SETIMAGE = 0x0172
$BaseFilePath = "S:\AutoIt\ImageFailure\med.base.png"
$Base = _GDIPlus_ImageLoadFromFile($BaseFilePath)
$h = _GDIPlus_ImageGetHeight($Base)
$w = _GDIPlus_ImageGetWidth($Base)
$hBmp_GDI = _GDIPlus_BitmapCreateHBITMAPFromBitmap($Base)

;Create the Window based on the size of the Baseline file
$GUI = GUICreate("Test",$w,$h,-1,-1,-1,$WS_EX_APPWINDOW)
$PIC = GUICtrlCreatePic("", 0, 0, $w, $h)
_WinAPI_DeleteObject(GUICtrlSendMsg($PIC, $STM_SETIMAGE, $IMAGE_BITMAP, $hBmp_GDI))
GUISetOnEvent($GUI_EVENT_CLOSE, "OnExit")
GUISetState()

While 1
    Sleep(100)
WEnd


Func OnExit()
    _WinAPI_DeleteObject($hBmp_GDI)
    _GDIPlus_ImageDispose($Base)
    _GDIPlus_Shutdown()
    GUIDelete()
    Exit
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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

UEZ, both of those work, thanks! Now I need to see how to implement it on my actual larger script that has multiple images.

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

One followup question. I used UEZ option #1 and applied it to my larger script. In my larger script I actually have multiple Rect drawn on top of each other using _GDIPlus_GraphicsDrawImageRect. Each of these RECT are built from different PNG images and each of the PNG images have transparent areas so that the images can display on top of each other.

The problem I have now is that the screen flickers when it calls the Repaint function because the Repaint function actually makes multiple calls to _GDIPlus_GraphicsDrawImageRect.

Is there any way to avoid this? I was wondering if there might be a way to combine these mulitple PNG images into one Graphic before making a single call to _GDIPlus_GraphicsDrawImageRect? I assume this would stop the flickering affect.

Edited by texan

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Yes, you have to use the backbuffer technique. Draw everything to a bitmap and when finished copy it to the visible graphic.

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

Yes, you have to use the backbuffer technique. Draw everything to a bitmap and when finished copy it to the visible graphic.

Is this what you mean by using backbuffer technique? It seems to work, is there anything I am leaving out?

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

Global $BaseFilePath, $GUI, $h, $w, $Base, $MaskFilePath, $Mask, $hwndGraphic, $backbuffer, $bitmap
Opt("GUIOnEventMode", 1)  ; Change to OnEvent mode
OnAutoItExitRegister("OnExit")

_GDIPlus_Startup()

$BaseFilePath = "S:\AutoIt\ImageFailure\med.base.png"
$MaskFilePath = "S:\AutoIt\ImageFailure\med.mask.png"
$Base = _GDIPlus_ImageLoadFromFile($BaseFilePath)
$Mask = _GDIPlus_ImageLoadFromFile($MaskFilePath)
$h = _GDIPlus_ImageGetHeight($Base)
$w = _GDIPlus_ImageGetWidth($Base)
$WhiteBrush = _GDIPlus_BrushCreateSolid(0xffffffff)

;Create the Window based on the size of the Baseline file
$GUI = GUICreate("Test",$w,$h,-1,-1,-1,$WS_EX_APPWINDOW)
GUISetOnEvent($GUI_EVENT_CLOSE, "OnExit")
GUISetOnEvent($GUI_EVENT_RESTORE, "Repaint")
$hwndGraphic = _GDIPlus_GraphicsCreateFromHWND($GUI)   ;Create a Graphics object from a Window Handle
$bitmap = _GDIPlus_BitmapCreateFromGraphics($w,$h,$hwndGraphic)
$backbuffer = _GDIPlus_ImageGetGraphicsContext($bitmap)
GUISetState()
Repaint()

GUIRegisterMsg($WM_PAINT, "WM_PAINT")

While 1
    Sleep(100)
WEnd

Func Repaint()
;~     _GDIPlus_GraphicsDrawImageRect($hwndGraphic, $Base, 0, 0, $w, $h)
    _GDIPlus_GraphicsFillRect($BackBuffer, 0, 0, $w, $h, $WhiteBrush)  ;clear the left side
    _GDIPlus_GraphicsDrawImageRect($BackBuffer, $Base, 0, 0, $w, $h)
    _GDIPlus_GraphicsDrawImageRect($BackBuffer, $Mask, 0, 0, $w, $h)
    _GDIPlus_GraphicsDrawImageRect($hwndGraphic, $bitmap, 0, 0, $w, $h)
EndFunc


Func WM_PAINT()
    Repaint()
    Return "GUI_RUNDEFMSG"
EndFunc

Func OnExit()
    GUIRegisterMsg($WM_PAINT, "")
    _GDIPlus_ImageDispose($Base)
    _GDIPlus_GraphicsDispose($hwndGraphic)
    _GDIPlus_Shutdown()
    GUIDelete()
    Exit
EndFunc

 

Share this post


Link to post
Share on other sites

It looks good (not tested) but the in exit function some resource cleanups are missing.


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

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