Jump to content
Sign in to follow this  
fisofo

SOLVED: GDI+: Clearing graphics makes GUI background black?

Recommended Posts

fisofo

EDIT 2, SOLVED update: for those that may come searching, I refined this a bit more by using the $tagRECT structure. I have again updated the code block and cleaned up this post a bit to make it easy to understand. The reason $tagRECT is nice is that by using the it, just the area that you changed can get redrawn, rather than the entire GUI window (which tends to be noticeable if the GUI is the entire screen, as I found out ;) ). See code for details and comments!

Previous: EDIT, SOLVED: now working, thanks Malkey! Just needed:

_WinAPI_RedrawWindow($hGUI,"","",BitOR($RDW_ERASE,$RDW_INVALIDATE,$RDW_UPDATENOW,$RDW_FRAME,$RDW_ALLCHILDREN))

See code box for the working stuff.

Original Issue: Okay, so this should be a pretty easy one, but I could use some help. I'm trying to update some GDI graphics in a GUI I created, but when I use _GDIPlus_GraphicsClear, it makes the background of the GUI black. What am I doing wrong?

To clarify a bit more... any "GUICtrlCreate..." items in the GUI can no longer be seen after _GDIPlus_GraphicsClear is called.

Here is some quick and easy code to demonstrate my dilemma, notice that "Test Label" is no longer visible after the msgbox:

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

_Main()

Func _Main()
    Local $sString = "GDI+ Test Text"
    
    ; Create GUI
    $hGUI = GUICreate("GDI+", 400, 300)
    $Label1 = GUICtrlCreateLabel("Test Label that needs to stay visible!", 5, 50)
    GUISetState()
    
    _GDIPlus_Startup ()

; ------------------ First Drawing ------------------ 
    ; Define variables for drawing a string
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND ($hGUI)
    $hBrush = _GDIPlus_BrushCreateSolid (0xFFFFFFFF)
    $hFormat = _GDIPlus_StringFormatCreate ()
    $hFamily = _GDIPlus_FontFamilyCreate ("Calibri")
    $hFont = _GDIPlus_FontCreate ($hFamily, 18, 1)
    $tLayout = _GDIPlus_RectFCreate (5, 5, 400, 300)
    $aInfo = _GDIPlus_GraphicsMeasureString ($hGraphic, $sString, $hFont, $tLayout, $hFormat)
    
    ; Retrieve height and width of the string
    $hWidth = DllStructGetData($aInfo[0], 3)
    $hHeight = DllStructGetData($aInfo[0], 4)
    
    ; create a struct for later redrawing this area
    $tRect = DllStructCreate($tagRECT)
    DllStructSetData($tRect, "Left", 5)
    DllStructSetData($tRect, "Top", 5)
    DllStructSetData($tRect, "Right", 5 + $hWidth)
    DllStructSetData($tRect, "Bottom", 5 + $hHeight)
    
    ; Draw a rectangle to fit the String rectangle we found
    $hBrushRect = _GDIPlus_BrushCreateSolid(0xFF0000FF)
    _GDIPlus_GraphicsFillRect($hGraphic, 5, 5, $hWidth, $hHeight, $hBrushRect)
    
    ; Draw the string!  Done last so that it is on top of the drawn rectangle
    _GDIPlus_GraphicsDrawStringEx ($hGraphic, $sString, $hFont, $aInfo[0], $hFormat, $hBrush)

; ------------------ Clear Drawing ------------------ 
    MsgBox(0, "", "Now we will redraw the GUI")
    
;~     _GDIPlus_GraphicsClear($hGraphic) ; This will blank out the entire GUI window, losing any controls you had.  Not good for this purpose.
;~     _WinAPI_RedrawWindow($hGUI,0,0,BitOR($RDW_ERASE,$RDW_INVALIDATE,$RDW_UPDATENOW,$RDW_FRAME,$RDW_ALLCHILDREN)) ; works, but redraws entire screen.
;~     _WinAPI_RedrawWindow($hGUI,$tRect,0,BitOR($RDW_ERASE,$RDW_INVALIDATE)) ; Does the same as _WinAPI_InvalidateRect shown below.
    _WinAPI_InvalidateRect($hGUI, $tRect, True) ; Redraws just the defined text rectangle $tRect structure!

; ------------------ Second Drawing ------------------ 
    ; Define variables for drawing a new string
    $sString = "GDI+ Text Changed!"
    $hBrush = _GDIPlus_BrushCreateSolid (0xFF0000FF)
    $hFormat = _GDIPlus_StringFormatCreate ()
    $hFamily = _GDIPlus_FontFamilyCreate ("Calibri")
    $hFont = _GDIPlus_FontCreate ($hFamily, 18, 1)
    $tLayout = _GDIPlus_RectFCreate (5, 5, 400, 300)
    $aInfo = _GDIPlus_GraphicsMeasureString ($hGraphic, $sString, $hFont, $tLayout, $hFormat)
    
    ; Retrieve height and width of the new string
    $hWidth = DllStructGetData($aInfo[0], 3)
    $hHeight = DllStructGetData($aInfo[0], 4)
    
    ; Draw a rectangle to fit the new String rectangle we found
    $hBrushRect = _GDIPlus_BrushCreateSolid(0xFFFFFFFF)
    _GDIPlus_GraphicsFillRect($hGraphic, 5, 5, $hWidth, $hHeight, $hBrushRect)
    
    ; Draw the new string!
    _GDIPlus_GraphicsDrawStringEx ($hGraphic, $sString, $hFont, $aInfo[0], $hFormat, $hBrush)

; ------------------ Clean up resources ------------------
    _GDIPlus_FontDispose ($hFont)
    _GDIPlus_FontFamilyDispose ($hFamily)
    _GDIPlus_StringFormatDispose ($hFormat)
    _GDIPlus_BrushDispose ($hBrush)
    _GDIPlus_GraphicsDispose ($hGraphic)
    _GDIPlus_Shutdown ()

; ------------------ Loop until user exits ------------------
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
EndFunc   ;==>_Main
Edited by fisofo

Share this post


Link to post
Share on other sites
Andreik

Now work fine:

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

_Main()

Func _Main()
    Local $hGUI, $hWnd, $hGraphic, $hBrush, $hBrushRect, $hFormat, $hFamily, $hFont, $tLayout, $aInfo
    Local $sString = "GDI+ Test Text"
   
   ; Create GUI
    $hGUI = GUICreate("GDI+", 400, 300)
    $Label1 = GUICtrlCreateLabel("Test Label", 5, 50)
    GUISetState()

   ; Draw a string
    _GDIPlus_Startup ()
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND ($hGUI)
    $hBrush = _GDIPlus_BrushCreateSolid (0xFF000000)
    $hFormat = _GDIPlus_StringFormatCreate ()
    $hFamily = _GDIPlus_FontFamilyCreate ("Calibri")
    $hFont = _GDIPlus_FontCreate ($hFamily, 18, 1)
    $tLayout = _GDIPlus_RectFCreate (5, 5, 400, 300)
    $aInfo = _GDIPlus_GraphicsMeasureString ($hGraphic, $sString, $hFont, $tLayout, $hFormat)
   
    $hWdith = DllStructGetData($aInfo[0], 3)
    $hHeight = DllStructGetData($aInfo[0], 4)
    $hBrushRect = _GDIPlus_BrushCreateSolid(0x66FFFFFF)
    _GDIPlus_GraphicsFillRect($hGraphic, 5, 5, $hWdith, $hHeight, $hBrushRect)
   
    _GDIPlus_GraphicsDrawStringEx ($hGraphic, $sString, $hFont, $aInfo[0], $hFormat, $hBrush)

   
    MsgBox(0, "", "Now we will change the GDI Text")
   
    _GDIPlus_GraphicsClear($hGraphic,0xFFECE8D7)
    $sString = "GDI+ Test Changed!"
    $hBrush = _GDIPlus_BrushCreateSolid (0xFF000000)
    $hFormat = _GDIPlus_StringFormatCreate ()
    $hFamily = _GDIPlus_FontFamilyCreate ("Calibri")
    $hFont = _GDIPlus_FontCreate ($hFamily, 18, 1)
    $tLayout = _GDIPlus_RectFCreate (5, 5, 400, 300)
    $aInfo = _GDIPlus_GraphicsMeasureString ($hGraphic, $sString, $hFont, $tLayout, $hFormat)
   
    $hWdith = DllStructGetData($aInfo[0], 3)
    $hHeight = DllStructGetData($aInfo[0], 4)
    $hBrushRect = _GDIPlus_BrushCreateSolid(0x66FFFFFF)
    _GDIPlus_GraphicsFillRect($hGraphic, 5, 5, $hWdith, $hHeight, $hBrushRect)
   
    _GDIPlus_GraphicsDrawStringEx ($hGraphic, $sString, $hFont, $aInfo[0], $hFormat, $hBrush)


   ; Clean up resources
    _GDIPlus_FontDispose ($hFont)
    _GDIPlus_FontFamilyDispose ($hFamily)
    _GDIPlus_StringFormatDispose ($hFormat)
    _GDIPlus_BrushDispose ($hBrush)
    _GDIPlus_GraphicsDispose ($hGraphic)
    _GDIPlus_Shutdown ()

   ; Loop until user exits
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
EndFunc  ;==>_Main

When the words fail... music speaks

Share this post


Link to post
Share on other sites
fisofo

While I appreciate your help, all you did was change the color used by _GDIPlus_GraphicsClear to 0xFFECE8D7. Sorry, that doesn't help ;)

You'll notice that the Label named "Test Label" still disappears on the GUI! That is the main issue I am having... everything else gets "blanked" on the GUI. Same thing happens If I have a button that was in the window.

Share this post


Link to post
Share on other sites
Andreik

While I appreciate your help, all you did was change the color used by _GDIPlus_GraphicsClear to 0xFFECE8D7. Sorry, that doesn't help ;)

You'll notice that the Label named "Test Label" still disappears on the GUI! That is the main issue I am having... everything else gets "blanked" on the GUI. Same thing happens If I have a button that was in the window.

What do you expect to do function _GDIPlus_GraphicsClear()?

_GDIPlus_GraphicsClear clears a Graphics object to a specified color. What color only you know that... I suppose that you want to be same color like your GUI.


When the words fail... music speaks

Share this post


Link to post
Share on other sites
fisofo

What do you expect to do function _GDIPlus_GraphicsClear()?

_GDIPlus_GraphicsClear clears a Graphics object to a specified color. What color only you know that... I suppose that you want to be same color like your GUI.

I'm trying to update the graphics without losing the gui controls! it has nothing to do with color. I would expect the function to just clear the gdi+ graphics, not the entire gui... doesn't this make sense? anyone else know how to get what i'm looking for?

Share this post


Link to post
Share on other sites
Malkey

I'm trying to update the graphics without losing the gui controls! it has nothing to do with color. I would expect the function to just clear the gdi+ graphics, not the entire gui... doesn't this make sense? anyone else know how to get what i'm looking for?

From here

http://www.autoitscript.com/forum/index.ph...st&p=560052

try

_WinAPI_RedrawWindow(_WinAPI_GetDesktopWindow(),"","",BitOR($RDW_INVALIDATE,$RDW_UPDATENOW,$RDW_FRAME,$RDW_ALLCHILDREN))

after

MsgBox(0, "", "Now we will change the GDI Text")

in your script.

Edit: And delete _GDIPlus_GraphicsClear($hGraphic)

Edited by Malkey

Share this post


Link to post
Share on other sites
fisofo

Awesome thank you, that fixed it! I've updated the first post with the working code. I actually didn't need the "_WinAPI_GetDesktopWindow", I just used the GUI handle, and I had to add a "$RDW_ERASE" to the BitOr otherwise the previously drawn items weren't removed.

Thanks Malkey!

Share this post


Link to post
Share on other sites
fisofo

One more update: refined code a bit more now that I understand it better and have updated the first post. $tagRECT is a magical thing!

quick and dirty, these just redraw the area you need:

_WinAPI_RedrawWindow($hGUI,$tRect,0,BitOR($RDW_ERASE,$RDW_INVALIDATE))

_WinAPI_InvalidateRect($hGUI, $tRect, True)

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
Sign in to follow this  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.