jimg Posted August 6, 2008 Share Posted August 6, 2008 I have a simple GUI application where I have a little "speedometer" with some extra text, and despite calling GUICtrlDelete of the control that is the actual "dial", the individual GUICtrlSetGraphic commands seem to accumulate over time. I assume I just skipped an important chapter in the manual. Here's the essence of the code: #include <INet.au3> #include <GuiConstantsEx.au3> #include <GDIPlus.au3> #include <WindowsConstants.au3> #Include <WinAPI.au3> #include <StaticConstants.au3> Opt("GUIOnEventMode", 1) $meter=0 $dir=0 $label_speed = 0 $pi = 3.14159 $font = "Tahoma" ; Create GUI & label controls $hGUI = GUICreate("GUIone", 100, 120,-1,-1,$WS_CAPTION,$WS_EX_TOOLWINDOW) $label_date = GUICtrlCreateLabel ( "", 10, 0 ,80,14,$SS_Center) $label_time = GUICtrlCreateLabel ( "", 10, 15 ,80,14,$SS_Center) GUIRegisterMsg($WM_PAINT, "Paint") GUISetOnEvent($GUI_EVENT_RESTORE, "Paint") GUISetOnEvent($GUI_EVENT_CLOSE, "Finish") while 1 paint() ; run every ten minutes ; sleep(10*60*1000) sleep(1000) WEnd Func Paint() $radius = 40 ; stuff to generate data goes here, but isn't included $date = "Aug 8, 2008" $time = "17:30pm" $speed = 13.7 $dir = $dir+1 if $dir = 360 then $dir = 0 ; delete controls if they exist if $meter <> 0 then GUICtrlDelete($meter) if $label_speed <> 0 then GUICtrlDelete($label_speed) $meter = GUICtrlCreateGraphic(5, 30, 90, 90) GUICtrlSetGraphic(-1, $GUI_GR_PENSIZE,2) GUICtrlSetGraphic(-1, $GUI_GR_COLOR, 0x000000, 0x888888) GUICtrlSetGraphic(-1, $GUI_GR_ELLIPSE, 5, 5, 80, 80) GUICtrlSetGraphic(-1, $GUI_GR_COLOR, 0x000000, 0xcccccc) ; tick marks on dial for $index = 0 to 16 $xsp = $radius*sin($pi*$index/8) $ysp = -1*$radius*cos($pi*$index/8) $xep = 1.15*$radius*sin($pi*$index/8) $yep = -1.15*$radius*cos($pi*$index/8) GUICtrlSetGraphic(-1, $GUI_GR_MOVE, $xsp+45, $ysp+45) GUICtrlSetGraphic(-1, $GUI_GR_LINE, $xep+45, $yep+45) Next $xpos = 35*sin($pi*$dir/180) $ypos = -35*cos($pi*$dir/180) GUICtrlSetGraphic(-1, $GUI_GR_MOVE, 45, 45) GUICtrlSetGraphic(-1, $GUI_GR_LINE, $xpos+45, $ypos+45) $label_speed = GUICtrlCreateLabel("", 35,67,30,16,$SS_RIGHT) GUICtrlSetData ( $label_date, $date) GUICtrlSetData ( $label_time, $time) GUICtrlSetFont ($label_speed, 10,800) GUICtrlSetData ( $label_speed, $speed) GUISetState(@SW_SHOW) EndFunc Func Finish() Exit EndFunc Link to comment Share on other sites More sharing options...
martin Posted August 6, 2008 Share Posted August 6, 2008 What do you mean by the commands seeming to accumulate? Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script. Link to comment Share on other sites More sharing options...
jimg Posted August 6, 2008 Author Share Posted August 6, 2008 If you run the script, you'll find that "old" needle positions are visible during the update. I thought that the elements were children of the control, but deleting the control doesn't seem to delete the elements. As time goes by, the update takes longer and longer, and the Task Manager shows more and more memory being used. You can see pixels flashing by of the prior needle positions dueing the redraw.I've added msgbox's in the delete control conditional, and they seem to be happening.What do you mean by the commands seeming to accumulate? Link to comment Share on other sites More sharing options...
martin Posted August 6, 2008 Share Posted August 6, 2008 (edited) If you run the script, you'll find that "old" needle positions are visible during the update. I thought that the elements were children of the control, but deleting the control doesn't seem to delete the elements. As time goes by, the update takes longer and longer, and the Task Manager shows more and more memory being used. You can see pixels flashing by of the prior needle positions dueing the redraw. I've added msgbox's in the delete control conditional, and they seem to be happening. Maybe this is better expandcollapse popup#include <INet.au3> #include <GuiConstantsEx.au3> #include <GDIPlus.au3> #include <WindowsConstants.au3> #Include <WinAPI.au3> #include <StaticConstants.au3> Global Const $WS_EX_COMPOSITED = 0x2000000 Opt("GUIOnEventMode", 1) global $meter = 0,$lock = false $dir = 0 global $label_speed = 0 $pi = 3.14159 $font = "Tahoma" ; Create GUI & label controls $hGUI = GUICreate("GUIone", 100, 120, -1, -1, $WS_CAPTION, BitOr($WS_EX_COMPOSITED,$WS_EX_TOOLWINDOW)) $label_date = GUICtrlCreateLabel("", 10, 0, 80, 14, $SS_Center) $label_time = GUICtrlCreateLabel("", 10, 15, 80, 14, $SS_Center) Global $inpaint = false GUIRegisterMsg($WM_PAINT, "Paint") GUISetOnEvent($GUI_EVENT_RESTORE, "Paint") GUISetOnEvent($GUI_EVENT_CLOSE, "Finish") GUISetState() paint() adlibenable("paint1",1000);allow clock to keep going when gui is being moved While 1 Sleep(100) WEnd Func paint1() $dir += 2;increment here otherwise if paint is called by WM_PAINT then the value ;of dir is incremented when it shouldn't be and causes the flickering lines in wrong place paint() EndFunc Func Paint() $radius = 40 ; stuff to generate data goes here, but isn't included $date = "Aug 8, 2008" $time = "17:30pm" $speed = 13.7 ; delete controls if they exist If $meter <> 0 Then GUICtrlDelete($meter) If $label_speed <> 0 Then GUICtrlDelete($label_speed) $meter = GUICtrlCreateGraphic(5, 30, 90, 90) GUICtrlSetGraphic(-1, $GUI_GR_PENSIZE, 2) GUICtrlSetGraphic(-1, $GUI_GR_COLOR, 0x000000, 0x888888) GUICtrlSetGraphic(-1, $GUI_GR_ELLIPSE, 5, 5, 80, 80) GUICtrlSetGraphic(-1, $GUI_GR_COLOR, 0x000000, 0xcccccc) ; tick marks on dial For $index = 0 To 16 $xsp = $radius * Sin($pi * $index / 8) $ysp = -1 * $radius * Cos($pi * $index / 8) $xep = 1.15 * $radius * Sin($pi * $index / 8) $yep = -1.15 * $radius * Cos($pi * $index / 8) GUICtrlSetGraphic(-1, $GUI_GR_MOVE, $xsp + 45, $ysp + 45) GUICtrlSetGraphic(-1, $GUI_GR_LINE, $xep + 45, $yep + 45) Next $xpos = 35 * Sin($pi * $dir / 180) $ypos = -35 * Cos($pi * $dir / 180) GUICtrlSetGraphic(-1, $GUI_GR_MOVE, 45, 45) GUICtrlSetGraphic(-1, $GUI_GR_LINE, $xpos + 45, $ypos + 45) $label_speed = GUICtrlCreateLabel("", 35, 67, 30, 16, $SS_RIGHT) GUICtrlSetData($label_date, $date) GUICtrlSetData($label_time, $time) GUICtrlSetFont($label_speed, 10, 800) GUICtrlSetData($label_speed, $speed) ;GUISetState(@SW_SHOW) EndFunc ;==>Paint Func Finish() Exit EndFunc ;==>Finish Edited August 6, 2008 by martin Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script. Link to comment Share on other sites More sharing options...
jimg Posted August 6, 2008 Author Share Posted August 6, 2008 It does work better. It's not the paint1() issue, though, since my $dir value is actually extracted from an RSS feed, and isn't very dynamic. The "accumulation" only shows up after days of execution. It must have to do with the other changes you made, which I'll scratch my head over. Maybe this is better expandcollapse popup#include <INet.au3> #include <GuiConstantsEx.au3> #include <GDIPlus.au3> #include <WindowsConstants.au3> #Include <WinAPI.au3> #include <StaticConstants.au3> Global Const $WS_EX_COMPOSITED = 0x2000000 Opt("GUIOnEventMode", 1) global $meter = 0,$lock = false $dir = 0 global $label_speed = 0 $pi = 3.14159 $font = "Tahoma" ; Create GUI & label controls $hGUI = GUICreate("GUIone", 100, 120, -1, -1, $WS_CAPTION, BitOr($WS_EX_COMPOSITED,$WS_EX_TOOLWINDOW)) $label_date = GUICtrlCreateLabel("", 10, 0, 80, 14, $SS_Center) $label_time = GUICtrlCreateLabel("", 10, 15, 80, 14, $SS_Center) Global $inpaint = false GUIRegisterMsg($WM_PAINT, "Paint") GUISetOnEvent($GUI_EVENT_RESTORE, "Paint") GUISetOnEvent($GUI_EVENT_CLOSE, "Finish") GUISetState() paint() adlibenable("paint1",1000);allow clock to keep going when gui is being moved While 1 Sleep(100) WEnd Func paint1() $dir += 2;increment here otherwise if paint is called by WM_PAINT then the value ;of dir is incremented when it shouldn't be and causes the flickering lines in wrong place paint() EndFunc Func Paint() $radius = 40 ; stuff to generate data goes here, but isn't included $date = "Aug 8, 2008" $time = "17:30pm" $speed = 13.7 ; delete controls if they exist If $meter <> 0 Then GUICtrlDelete($meter) If $label_speed <> 0 Then GUICtrlDelete($label_speed) $meter = GUICtrlCreateGraphic(5, 30, 90, 90) GUICtrlSetGraphic(-1, $GUI_GR_PENSIZE, 2) GUICtrlSetGraphic(-1, $GUI_GR_COLOR, 0x000000, 0x888888) GUICtrlSetGraphic(-1, $GUI_GR_ELLIPSE, 5, 5, 80, 80) GUICtrlSetGraphic(-1, $GUI_GR_COLOR, 0x000000, 0xcccccc) ; tick marks on dial For $index = 0 To 16 $xsp = $radius * Sin($pi * $index / 8) $ysp = -1 * $radius * Cos($pi * $index / 8) $xep = 1.15 * $radius * Sin($pi * $index / 8) $yep = -1.15 * $radius * Cos($pi * $index / 8) GUICtrlSetGraphic(-1, $GUI_GR_MOVE, $xsp + 45, $ysp + 45) GUICtrlSetGraphic(-1, $GUI_GR_LINE, $xep + 45, $yep + 45) Next $xpos = 35 * Sin($pi * $dir / 180) $ypos = -35 * Cos($pi * $dir / 180) GUICtrlSetGraphic(-1, $GUI_GR_MOVE, 45, 45) GUICtrlSetGraphic(-1, $GUI_GR_LINE, $xpos + 45, $ypos + 45) $label_speed = GUICtrlCreateLabel("", 35, 67, 30, 16, $SS_RIGHT) GUICtrlSetData($label_date, $date) GUICtrlSetData($label_time, $time) GUICtrlSetFont($label_speed, 10, 800) GUICtrlSetData($label_speed, $speed) ;GUISetState(@SW_SHOW) EndFunc ;==>Paint Func Finish() Exit EndFunc ;==>Finish Link to comment Share on other sites More sharing options...
jimg Posted August 6, 2008 Author Share Posted August 6, 2008 I'm still confused. The "fix" for the appearance seems to be the $WS_EX_COMPOSITED = 0x2000000 parameter, but it also causes a constant update, burning 20% of one of my processors. I looked in WindowsConstants.au3 and that bit appears to be $WS_CLIPCHILDREN, which makes no sense to me at all (neither the fixing the problem part nor the constant refresh).It does work better. It's not the paint1() issue, though, since my $dir value is actually extracted from an RSS feed, and isn't very dynamic. The "accumulation" only shows up after days of execution. It must have to do with the other changes you made, which I'll scratch my head over. Link to comment Share on other sites More sharing options...
jimg Posted August 6, 2008 Author Share Posted August 6, 2008 I see I confused Styles with Extended_Styles. Regardless, the $WS_EX_COMPOSITED forces constant redraws (and a constant increase in memory usage), so I'm thinking the orphaned stuff is still around, but just not being seen due to the double buffering.I'm still confused. The "fix" for the appearance seems to be the $WS_EX_COMPOSITED = 0x2000000 parameter, but it also causes a constant update, burning 20% of one of my processors. I looked in WindowsConstants.au3 and that bit appears to be $WS_CLIPCHILDREN, which makes no sense to me at all (neither the fixing the problem part nor the constant refresh). Link to comment Share on other sites More sharing options...
martin Posted August 7, 2008 Share Posted August 7, 2008 (edited) I see I confused Styles with Extended_Styles. Regardless, the $WS_EX_COMPOSITED forces constant redraws (and a constant increase in memory usage), so I'm thinking the orphaned stuff is still around, but just not being seen due to the double buffering. I think the problem is having controls created and destroyed in the function called by WM_PAINT. When a visible control is created or destroyed inside a function called by WM_PAINT I imagine it causes problems with the function being called again while the function is still being executed. If you make 2 separate functions so that WM_PAINT doesn't destroy or create controls which have to be drawn then I think the problem will go away, something like this expandcollapse popup#include <INet.au3> #include <GuiConstantsEx.au3> #include <GDIPlus.au3> #include <WindowsConstants.au3> #Include <WinAPI.au3> #include <StaticConstants.au3> Global Const $WS_EX_COMPOSITED = 0x2000000 Opt("GUIOnEventMode", 1) Global $label_speed = 0, $meter = 0, $dir = 0, $radius = 40 ; stuff to generate data goes here, but isn't included Global $date = "Aug 8, 2008", $time = "17:30pm", $speed = 13.7, $pi = 3.14159, $font = "Tahoma" ; Create GUI & label controls $hGUI = GUICreate("GUIone", 100, 120, -1, -1, $WS_CAPTION, $WS_EX_TOOLWINDOW); BitOr($WS_EX_COMPOSITED,$WS_EX_TOOLWINDOW)) $label_date = GUICtrlCreateLabel("", 10, 0, 80, 14, $SS_Center) $label_time = GUICtrlCreateLabel("", 10, 15, 80, 14, $SS_Center) GUIRegisterMsg($WM_PAINT, "RePaint") GUISetOnEvent($GUI_EVENT_RESTORE, "RePaint") GUISetOnEvent($GUI_EVENT_CLOSE, "Finish") GUISetState() $label_speed = GUICtrlCreateLabel("", 35, 67, 30, 16, $SS_RIGHT) Paint() AdlibEnable("paint", 1000) While 1 Sleep(100) WEnd Func RePaint() GUICtrlSetGraphic($meter, $GUI_GR_PENSIZE, 2) GUICtrlSetGraphic($meter, $GUI_GR_COLOR, 0x000000, 0x888888) GUICtrlSetGraphic($meter, $GUI_GR_ELLIPSE, 5, 5, 80, 80) GUICtrlSetGraphic($meter, $GUI_GR_COLOR, 0x000000, 0xcccccc) ; tick marks on dial For $index = 0 To 16 $xsp = $radius * Sin($pi * $index / 8) $ysp = -1 * $radius * Cos($pi * $index / 8) $xep = 1.15 * $radius * Sin($pi * $index / 8) $yep = -1.15 * $radius * Cos($pi * $index / 8) GUICtrlSetGraphic($meter, $GUI_GR_MOVE, $xsp + 45, $ysp + 45) GUICtrlSetGraphic($meter, $GUI_GR_LINE, $xep + 45, $yep + 45) Next $xpos = 35 * Sin($pi * $dir / 180) $ypos = -35 * Cos($pi * $dir / 180) GUICtrlSetGraphic($meter, $GUI_GR_MOVE, 45, 45) GUICtrlSetGraphic($meter, $GUI_GR_LINE, $xpos + 45, $ypos + 45) GUICtrlSetData($label_date, $date) GUICtrlSetData($label_time, $time) If $label_speed <> 0 Then GUICtrlSetFont($label_speed, 10, 800) GUICtrlSetData($label_speed, $speed) EndFunc ;==>RePaint Func Paint() $dir += 2 ; delete control if it exists If $meter <> 0 Then GUICtrlDelete($meter) $meter = 0 EndIf $meter = GUICtrlCreateGraphic(5, 30, 90, 90) repaint() EndFunc ;==>Paint Func Finish() Exit EndFunc ;==>Finish Edited August 7, 2008 by martin Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script. Link to comment Share on other sites More sharing options...
jimg Posted August 7, 2008 Author Share Posted August 7, 2008 Thanks a heap! That seems to do just what I was looking for - good diagnosis! I think the problem is having controls created and destroyed in the function called by WM_PAINT. When a visible control is created or destroyed inside a function called by WM_PAINT I imagine it causes problems with the function being called again while the function is still being executed. If you make 2 separate functions so that WM_PAINT doesn't destroy or create controls which have to be drawn then I think the problem will go away, something like this expandcollapse popup#include <INet.au3> #include <GuiConstantsEx.au3> #include <GDIPlus.au3> #include <WindowsConstants.au3> #Include <WinAPI.au3> #include <StaticConstants.au3> Global Const $WS_EX_COMPOSITED = 0x2000000 Opt("GUIOnEventMode", 1) Global $label_speed = 0, $meter = 0, $dir = 0, $radius = 40 ; stuff to generate data goes here, but isn't included Global $date = "Aug 8, 2008", $time = "17:30pm", $speed = 13.7, $pi = 3.14159, $font = "Tahoma" ; Create GUI & label controls $hGUI = GUICreate("GUIone", 100, 120, -1, -1, $WS_CAPTION, $WS_EX_TOOLWINDOW); BitOr($WS_EX_COMPOSITED,$WS_EX_TOOLWINDOW)) $label_date = GUICtrlCreateLabel("", 10, 0, 80, 14, $SS_Center) $label_time = GUICtrlCreateLabel("", 10, 15, 80, 14, $SS_Center) GUIRegisterMsg($WM_PAINT, "RePaint") GUISetOnEvent($GUI_EVENT_RESTORE, "RePaint") GUISetOnEvent($GUI_EVENT_CLOSE, "Finish") GUISetState() $label_speed = GUICtrlCreateLabel("", 35, 67, 30, 16, $SS_RIGHT) Paint() AdlibEnable("paint", 1000) While 1 Sleep(100) WEnd Func RePaint() GUICtrlSetGraphic($meter, $GUI_GR_PENSIZE, 2) GUICtrlSetGraphic($meter, $GUI_GR_COLOR, 0x000000, 0x888888) GUICtrlSetGraphic($meter, $GUI_GR_ELLIPSE, 5, 5, 80, 80) GUICtrlSetGraphic($meter, $GUI_GR_COLOR, 0x000000, 0xcccccc) ; tick marks on dial For $index = 0 To 16 $xsp = $radius * Sin($pi * $index / 8) $ysp = -1 * $radius * Cos($pi * $index / 8) $xep = 1.15 * $radius * Sin($pi * $index / 8) $yep = -1.15 * $radius * Cos($pi * $index / 8) GUICtrlSetGraphic($meter, $GUI_GR_MOVE, $xsp + 45, $ysp + 45) GUICtrlSetGraphic($meter, $GUI_GR_LINE, $xep + 45, $yep + 45) Next $xpos = 35 * Sin($pi * $dir / 180) $ypos = -35 * Cos($pi * $dir / 180) GUICtrlSetGraphic($meter, $GUI_GR_MOVE, 45, 45) GUICtrlSetGraphic($meter, $GUI_GR_LINE, $xpos + 45, $ypos + 45) GUICtrlSetData($label_date, $date) GUICtrlSetData($label_time, $time) If $label_speed <> 0 Then GUICtrlSetFont($label_speed, 10, 800) GUICtrlSetData($label_speed, $speed) EndFunc ;==>RePaint Func Paint() $dir += 2 ; delete control if it exists If $meter <> 0 Then GUICtrlDelete($meter) $meter = 0 EndIf $meter = GUICtrlCreateGraphic(5, 30, 90, 90) repaint() EndFunc ;==>Paint Func Finish() Exit EndFunc ;==>Finish Link to comment Share on other sites More sharing options...
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