Jump to content

Recommended Posts

Posted

When I change to another window and back again, the graphics is gone, for example I used the example in the helpfile.

_GDIPlus_GraphicsDrawCurve

Got a tip to use WM_PAINT and GUIRegisterMsg to redraw the graphics, but no success, I have searched the helpfile and on MSDN, anyone that can help me ?

Look at attached file.

Running Beta 3.2.9.8 on Windows 2000 SP4

Posted (edited)

I have not latest beta instaled so I can't test it.

I have installed latest beta now and there are problems with this my script:

It shows Fatal Error: AVector: []: Out of bounds. (Subscript used with non-Array variable.<_< at Return in:

Func _GDIPlus_PenCreate($iARGB = 0xFF000000, $nWidth = 1, $iUnit = 2)
    Local $iWidth, $aResult

    $iWidth = _WinAPI_FloatToInt ($nWidth)
    $aResult = DllCall($ghGDIPDll, "int", "GdipCreatePen1", "int", $iARGB, "int", $iWidth, "int", $iUnit, "int*", 0)
    Return SetError($aResult[0], 0, $aResult[4])
EndFunc  ;==>_GDIPlus_PenCreate

I'm running 3.2.9.8 on WINXP.

#include <GuiConstants.au3>
#include <GDIPlus.au3>

Local $hGUI, $hWnd, $hGraphic, $aPoints[5][2]

$hGUI = GUICreate("GDI+", 400, 300)
GUIRegisterMsg($WM_PAINT, "MY_WM_PAINT")
GUISetState()

_GDIPlus_Startup ()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND ($hGUI)

$aPoints[0][0] = 4
$aPoints[1][0] = 0
$aPoints[1][1] = 100
$aPoints[2][0] = 50
$aPoints[2][1] = 50
$aPoints[3][0] = 100
$aPoints[3][1] = 100
$aPoints[4][0] = 150
$aPoints[4][1] = 50

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

; Clean up resources
_GDIPlus_GraphicsDispose ($hGraphic)
_GDIPlus_Shutdown ()

Func MY_WM_PAINT($hwnd, $msg, $wparam, $lparam)
    _GDIPlus_GraphicsDrawCurve ($hGraphic, $aPoints)
EndFunc

EDIT: fixed header of Func MY_WM_PAINT($hwnd, $msg, $wparam, $lparam)

Edited by Zedna
Posted

I made modification but with no success too:

This runs without errors but curve is not painted and form couldn't be closed.

#include <GuiConstants.au3>
#include <GDIPlus.au3>

Local $hGUI, $hWnd, $hGraphic, $aPoints[5][2]

$hGUI = GUICreate("GDI+", 400, 300)
GUIRegisterMsg($WM_PAINT, "MY_WM_PAINT")
GUISetState()

$aPoints[0][0] = 4
$aPoints[1][0] = 0
$aPoints[1][1] = 100
$aPoints[2][0] = 50
$aPoints[2][1] = 50
$aPoints[3][0] = 100
$aPoints[3][1] = 100
$aPoints[4][0] = 150
$aPoints[4][1] = 50

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

Func MY_WM_PAINT()
    _GDIPlus_Startup ()
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND ($hGUI)

    _GDIPlus_GraphicsDrawCurve ($hGraphic, $aPoints)

    ; Clean up resources
    _GDIPlus_GraphicsDispose ($hGraphic)
    _GDIPlus_Shutdown ()
EndFunc
Posted (edited)

Here is third version which works.

But form can't be closed.

EDIT:

I forgot "Return $GUI_RUNDEFMSG"

Now it's fully working

#include <GuiConstants.au3>
#include <GDIPlus.au3>

Local  $hGUI,  $hWnd,  $hGraphic,  $aPoints[5][2]

$aPoints[0][0] =  4
$aPoints[1][0] =  0
$aPoints[1][1] =  100
$aPoints[2][0] =  50
$aPoints[2][1] =  50
$aPoints[3][0] =  100
$aPoints[3][1] =  100
$aPoints[4][0] =  150
$aPoints[4][1] =  50

$hGUI =  GUICreate("GDI+",  400,  300)

_GDIPlus_Startup  ()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND  ($hGUI)

GUIRegisterMsg($WM_PAINT,  "MY_WM_PAINT")
GUISetState()

While 1
    $msg = GuiGetMsg()
    If $msg = $GUI_EVENT_CLOSE Then ExitLoop
WEnd

; Clean up resources
_GDIPlus_GraphicsDispose  ($hGraphic)
_GDIPlus_Shutdown  ()

Func MY_WM_PAINT($hwnd,  $msg,  $wparam,  $lparam)
    _GDIPlus_GraphicsDrawCurve  ($hGraphic,  $aPoints)
        Return $GUI_RUNDEFMSG
EndFunc

EDIT:

I noticed that Do Until has 100% CPU usage, so optimized version of main loop is here

;~ Do
;~ Until  GUIGetMsg() =  $GUI_EVENT_CLOSE

While 1
    $msg = GuiGetMsg()
    If $msg = $GUI_EVENT_CLOSE Then ExitLoop
WEnd
Edited by Zedna
Posted

#include <GuiConstants.au3>
#include <GDIPlus.au3>
Opt('MustDeclareVars', 1)


Global $hGUI, $hWnd, $hGraphic, $aPoints[5][2]

; Create GUI
$hGUI = GUICreate("GDI+", 400, 300)
$hWnd = WinGetHandle("GDI+")
; Draw a cardinal spline
_GDIPlus_Startup ()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND($hWnd)
$aPoints[0][0] = 4
$aPoints[1][0] = 0
$aPoints[1][1] = 100
$aPoints[2][0] = 50
$aPoints[2][1] = 50
$aPoints[3][0] = 100
$aPoints[3][1] = 100
$aPoints[4][0] = 150
$aPoints[4][1] = 50
;~ _GDIPlus_GraphicsDrawCurve ($hGraphic, $aPoints)

GUIRegisterMsg($WM_PAINT, "MY_WM_PAINT")
GUISetState()
; Loop until user exits
While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
WEnd

; Clean up resources
_GDIPlus_GraphicsDispose ($hGraphic)
_GDIPlus_Shutdown ()

Func MY_WM_PAINT($hwnd, $msg, $wparam, $lparam)
    _GDIPlus_GraphicsDrawCurve($hGraphic, $aPoints)
    Return $GUI_RUNDEFMSG
EndFunc

Exit

Add a "Return $GUI_RUNDEFMSG" to GuiRegisterMsg function. There is a bug with using functions inside msg handler function, which makes it not to return properly, and it's still not fixed. So it's a good idea to explicitly state the default return when you want so.

This will solve high CPU usage and GUI not responding issue.

"be smart, drink your wine"

Posted

Add a "Return $GUI_RUNDEFMSG" to GuiRegisterMsg function. There is a bug with using functions inside msg handler function, which makes it not to return properly, and it's still not fixed. So it's a good idea to explicitly state the default return when you want so.

This will solve high CPU usage and GUI not responding issue.

You are right. I forgot "Return $GUI_RUNDEFMSG"

Thanks siao!

Posted (edited)

One BIG note:

When you need painting over some other controls in GUI (for example picture control) then this will not work

because code in WM_PAINT is executed before internal WM_PAINT (and not after).

If somebody know how to do such painting in WM_PAINT over picture control in GUI, please tell me.

In mentioned BlackJack I did it by copying whole content of GUI into memory bitmap then painted my graphic at memory bitmap and

in the end BitBlt from memory bitmap onto visible GUI.

I would be happy If there is some more elegant way.

EDIT: Here is link to BlackJack

Edited by Zedna
Posted (edited)

I would be happy If there is some more elegant way.

The easiest way probably would be this:

#include <GuiConstants.au3>
#include <GDIPlus.au3>
Opt('MustDeclareVars', 0)
Global $hGUI, $hWnd, $hGraphic, $aPoints[5][2]

; Create GUI
$hGUI = GUICreate("GDI+", 400, 300)
$cPic = GUICtrlCreatePic(@Systemdir & "\oobe\images\mslogo.jpg", 200,150, 200,150)
$hPic = GUICtrlGetHandle($cPic)
; Draw a cardinal spline
_GDIPlus_Startup()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
$hGraphic2 = _GDIPlus_GraphicsCreateFromHWND($hPic)
;~ cw(Hex($hGraphic2))

$aPoints[0][0] = 4
$aPoints[1][0] = 0
$aPoints[1][1] = 100
$aPoints[2][0] = 50
$aPoints[2][1] = 50
$aPoints[3][0] = 100
$aPoints[3][1] = 100
$aPoints[4][0] = 150
$aPoints[4][1] = 50
;~ _GDIPlus_GraphicsDrawCurve ($hGraphic, $aPoints)

GUIRegisterMsg($WM_PAINT, "MY_WM_PAINT")
GUISetState()
; Loop until user exits
While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
WEnd

; Clean up resources
_GDIPlus_GraphicsDispose($hGraphic)
_GDIPlus_GraphicsDispose($hGraphic2)
_GDIPlus_Shutdown()

Func MY_WM_PAINT($hWnd, $Msg, $wParam, $lParam)
    _GDIPlus_GraphicsDrawCurve($hGraphic, $aPoints)
    _WinAPI_RedrawWindow($hPic, 0, 0, $RDW_UPDATENOW) ;force redraw of pic
    _GDIPlus_GraphicsDrawCurve($hGraphic2, $aPoints) ;then draw your stuff on top
    _WinAPI_RedrawWindow($hPic, 0, 0, $RDW_VALIDATE) ;then force no-redraw of pic
    Return $GUI_RUNDEFMSG
EndFunc

Exit
Edited by Siao

"be smart, drink your wine"

Posted

The easiest way probably would be this:

Func MY_WM_PAINT($hWnd, $Msg, $wParam, $lParam)
    _GDIPlus_GraphicsDrawCurve($hGraphic, $aPoints)
    _WinAPI_RedrawWindow($hPic, 0, 0, $RDW_UPDATENOW) ;force redraw of pic
    _GDIPlus_GraphicsDrawCurve($hGraphic2, $aPoints) ;then draw your stuff on top
    _WinAPI_RedrawWindow($hPic, 0, 0, $RDW_VALIDATE) ;then force no-redraw of pic
    Return $GUI_RUNDEFMSG
EndFuncoÝ÷ Ûú®¢×©ä³}÷ß}÷Ý8b²+D@ë-+(®·¶*'~*ì´`È>[¬¶©',¶°
êïz+'¢ÙÞy×jëh×6Func MY_WM_PAINT($hWnd, $Msg, $wParam, $lParam)
;    _GDIPlus_GraphicsDrawCurve($hGraphic, $aPoints)
    _WinAPI_RedrawWindow($hPic, 0, 0, $RDW_UPDATENOW) ;force redraw of pic
    _GDIPlus_GraphicsDrawCurve($hGraphic2, $aPoints) ;then draw your stuff on top
    _WinAPI_RedrawWindow($hPic, 0, 0, $RDW_VALIDATE) ;then force no-redraw of pic
    Return $GUI_RUNDEFMSG
EndFunc

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
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...