Jump to content

Clearing a graphic drawn over a background image


AndyK
 Share

Recommended Posts

I'm trying to develop an application that draws a graphic when a spot on a background image is clicked. Unfortunately, when I try to clear the previously drawn graphic, it also clears the background image to black. I believe I understand this is happening because my graphic object is derived from the actual window, but so how would i fix this? I also need to be able to capture the coordinates of the mouse click relative to the image, which works fine as I have implemented it but might influence a fix for my problem. Im still trying to understand some of the features of AutoIt, so if you could explain what I'm doing wrong so that I understand, that would be great. Maybe this has been answered in another topic, but everything I have found so far was too complex for me to understand currently (I am a contractor who specializes in things that go bang).

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <AVIConstants.au3>
#include <TreeViewConstants.au3>
#include <GDIPlus.au3>
Opt("MouseCoordMode",2)

$settingsFile="c:\RHCV\IMS\settings.ini"
Local $settingsData[3][2] = [ ["LocationImage",""], ["LocationX",0], ["LocationY",0] ]
IniWriteSection($settingsFile,"Settings",$settingsData,0)

$file = FileOpenDialog("Please select a BMP, GIF or JPG...","C:\Users\user\Pictures\", "Images (*.jpg;*.bmp;*.gif)", 1+4+8)
IniWrite($settingsFile,"Settings","LocationImage",$file)

_GDIPlus_Startup()
$hImage = _GDIPlus_ImageLoadFromFile($file)
$iX = _GDIPlus_ImageGetWidth($hImage)
$iY = _GDIPlus_ImageGetHeight($hImage)
_GDIPlus_ImageDispose($hImage)


$looping = True
While $looping
    If @DesktopHeight < $iY Then
        $iX *= 0.75
        $iY *= 0.75
    ElseIf @DesktopWidth < $iX Then
        $iX *= 0.75
        $iY *= 0.75
    Else
        $looping = False
    EndIf
WEnd

$hWnd = GUICreate("TEST TEST TEST", $iX, $iY)
$pic = GUICtrlCreatePic("",0,0,$iX,$iY,$WS_CLIPSIBLINGS)
GUICtrlSetState(-1,$GUI_DISABLE)
GUICtrlSetImage($pic,$file)

$oGraphic = _GDIPlus_GraphicsCreateFromHWND($hWnd)
$hBrush = _GDIPlus_BrushCreateSolid(0xFF00FF00)

GUISetState(@SW_SHOW, $hWnd)

While 1
    $msg = GUIGetMsg(1)

    If $msg[0] = $GUI_EVENT_CLOSE Then ExitLoop

    If $msg[0] = $GUI_EVENT_PRIMARYDOWN Then
        If ($msg[3] >= 0) AND ($msg[3] <= $iX) AND ($msg[4] >= 0) AND ($msg[4] <= $iY) Then
            MsgBox(0,"","X: " & $msg[3] & "; Y: " & $msg[4])
            ;Really just need to update the original array with these values
            ;IniWrite($settingsFile,"Settings","LocationX",$msg[3])
            ;IniWrite($settingsFile,"Settings","LocationY",$msg[4])
            _GDIPlus_GraphicsClear($oGraphic,0x00FFFFFF)
            _GDIPlus_GraphicsFillRect($oGraphic, $msg[3]-4, $msg[4]-4, 9, 9, $hBrush)
        Else
            MsgBox(0,"","Please select a location on the actual picture.")
        EndIf
    EndIf

    ;$mouse = MouseGetPos()
    ;GUICtrlSetData($label,"X: " & $mouse[0] &"; Y: " & $mouse[1])
WEnd

_GDIPlus_BrushDispose($hBrush)
_GDIPlus_GraphicsDispose($oGraphic)
_GDIPlus_Shutdown()

Any help is appreciated...

Edited by AndyK
Link to comment
Share on other sites

Try this:

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <AVIConstants.au3>
#include <TreeViewConstants.au3>
#include <GDIPlus.au3>
Opt("MouseCoordMode",2)

$settingsFile="c:\RHCV\IMS\settings.ini"
Local $settingsData[3][2] = [ ["LocationImage",""], ["LocationX",0], ["LocationY",0] ]
IniWriteSection($settingsFile,"Settings",$settingsData,0)

$file = FileOpenDialog("Please select a BMP, GIF or JPG...","C:\Users\user\Pictures\", "Images (*.jpg;*.bmp;*.gif)", 1+4+8)
IniWrite($settingsFile,"Settings","LocationImage",$file)

_GDIPlus_Startup()
$hImage = _GDIPlus_ImageLoadFromFile($file)
$iX = _GDIPlus_ImageGetWidth($hImage)
$iY = _GDIPlus_ImageGetHeight($hImage)

$looping = True
While $looping
    If @DesktopHeight < $iY Then
        $iX *= 0.75
        $iY *= 0.75
    ElseIf @DesktopWidth < $iX Then
        $iX *= 0.75
        $iY *= 0.75
    Else
        $looping = False
    EndIf
WEnd

$hWnd = GUICreate("TEST TEST TEST", $iX, $iY)
$pic = GUICtrlCreatePic("",0,0,$iX,$iY,$WS_CLIPSIBLINGS)
GUICtrlSetState(-1,$GUI_DISABLE)
GUICtrlSetImage($pic,$file)

$oGraphic = _GDIPlus_GraphicsCreateFromHWND($hWnd)
$hBrush = _GDIPlus_BrushCreateSolid(0xFF00FF00)
GUISetState(@SW_SHOW, $hWnd)
_GDIPlus_GraphicsDrawImageRect($oGraphic, $hImage, 0, 0, $iX, $iY)

While 1
    $msg = GUIGetMsg(1)

    If $msg[0] = $GUI_EVENT_CLOSE Then ExitLoop

    If $msg[0] = $GUI_EVENT_PRIMARYDOWN Then
        If ($msg[3] >= 0) AND ($msg[3] <= $iX) AND ($msg[4] >= 0) AND ($msg[4] <= $iY) Then
            MsgBox(0,"","X: " & $msg[3] & "; Y: " & $msg[4])
            ;Really just need to update the original array with these values
            ;IniWrite($settingsFile,"Settings","LocationX",$msg[3])
            ;IniWrite($settingsFile,"Settings","LocationY",$msg[4])
;~             _GDIPlus_GraphicsClear($oGraphic,0xFF000000) ;not needed in this case
            _GDIPlus_GraphicsDrawImageRect($oGraphic, $hImage, 0, 0, $iX, $iY) ;comment this out if the drawn green squares shouldn't be cleaned
            _GDIPlus_GraphicsFillRect($oGraphic, $msg[3]-4, $msg[4]-4, 9, 9, $hBrush)
        Else
            MsgBox(0,"","Please select a location on the actual picture.")
        EndIf
    EndIf

    ;$mouse = MouseGetPos()
    ;GUICtrlSetData($label,"X: " & $mouse[0] &"; Y: " & $mouse[1])
WEnd
_GDIPlus_ImageDispose($hImage)
_GDIPlus_BrushDispose($hBrush)
_GDIPlus_GraphicsDispose($oGraphic)
_GDIPlus_Shutdown()

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

You can also replace GDIPlus_GraphicsClear() with _WinAPI_InvalidateRect($hPic, 0, False)

add this include

#include <WinAPI.au3>

and add this line below $pic = GUICtrlCreatePic()

Global $hPic = GUICtrlGetHandle($pic)

InvalidateRect() will force the pic control to be redrawn

Edited by rover

I see fascists...

Link to comment
Share on other sites

It was too late yesterday evening to see that you display the picture in pic control.

However, disadvantage using pic control is that you cannot use png images.

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

Thank you both for the help...

@ UEZ

_GDIPlus_GraphicsDrawImageRect($oGraphic,$hImage, 0, 0, $iX, $iY) ;comment this out if the drawn green squares shouldn't be cleaned

Just so I understand, is this line basically just printing the image on top of everything that was previously drawn, thereby 'erasing' it?

Edited by AndyK
Link to comment
Share on other sites

With _GDIPlus_GraphicsDrawImageRect($oGraphic,$hImage, 0, 0, $iX, $iY) you are copying the image to the graphic handle again. That means it will erase previous screen. If you disable this line you will paint over that background image.

I hope I've explained it well.

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

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