Wooltown Posted November 8, 2007 Posted November 8, 2007 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
Zedna Posted November 8, 2007 Posted November 8, 2007 Look here Resources UDF ResourcesEx UDF AutoIt Forum Search
Zedna Posted November 8, 2007 Posted November 8, 2007 (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_PenCreateI'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) EndFuncEDIT: fixed header of Func MY_WM_PAINT($hwnd, $msg, $wparam, $lparam) Edited November 8, 2007 by Zedna Resources UDF ResourcesEx UDF AutoIt Forum Search
Zedna Posted November 8, 2007 Posted November 8, 2007 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 Resources UDF ResourcesEx UDF AutoIt Forum Search
Zedna Posted November 8, 2007 Posted November 8, 2007 (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 EndFuncEDIT: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 November 8, 2007 by Zedna Resources UDF ResourcesEx UDF AutoIt Forum Search
Siao Posted November 8, 2007 Posted November 8, 2007 expandcollapse popup#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 ExitAdd 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"
Zedna Posted November 8, 2007 Posted November 8, 2007 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! Resources UDF ResourcesEx UDF AutoIt Forum Search
Zedna Posted November 8, 2007 Posted November 8, 2007 Little note: WinGetHandle() is not needed because GUICreate returns window handle Resources UDF ResourcesEx UDF AutoIt Forum Search
Zedna Posted November 8, 2007 Posted November 8, 2007 (edited) One BIG note:When you need painting over some other controls in GUI (for example picture control) then this will not workbecause 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 andin 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 November 8, 2007 by Zedna Resources UDF ResourcesEx UDF AutoIt Forum Search
Siao Posted November 8, 2007 Posted November 8, 2007 (edited) I would be happy If there is some more elegant way.The easiest way probably would be this: expandcollapse popup#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 November 8, 2007 by Siao "be smart, drink your wine"
Zedna Posted November 8, 2007 Posted November 8, 2007 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@ë-+mç(®·¶*'~*ì´`È>[¬¶©',¶° êï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 Resources UDF ResourcesEx UDF AutoIt Forum Search
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now