matrix200 Posted December 7, 2006 Share Posted December 7, 2006 Hi allI am writing ups monitoring application which is going to be knutclient windows clonehttp://www.alo.cz/knutclient/My problem is that when i try to refresh the analogue clocks state by moving the needle sometimes (usually after a while) I am getting a flicker.When I was using $GUI_GR_REFRESH it was flickering the whole window.Now I have limited that only to the area of the clock itself.Still it is very annoying.Here is a snippet of my code to show the problemexpandcollapse popup#include <GUIConstants.au3> Global $gui = 0 Global $num = 265 Global $needle1 = 0 Global $inputv = 0 Global $gray = "0xD4D0C8" Func Update() $num = $num + 1 if $num = 271 Then $num = 210 EndIf UpdateValue(136 , 70 , $needle1 , String($num) , $inputv ) EndFunc Func ForceRefresh($hWnd, $rRect=0, $bErase=0) Local $pRect, $aResult if $rRect <> 0 then $pRect = DllStructGetPtr($rRect) $aResult = DllCall("User32.dll", "int", "InvalidateRect", "hwnd", $hWnd, "ptr", $pRect, "int", 0) Return ($aResult[0] <> 0) EndFunc Func UpdateValue($left , $top , byref $needle , $value , $label , $min = 170, $max = 270) ;GUICtrlSendMsg($gui,0x000F,FALSE , 0) $oldval = Round (GuiCtrlRead($label)) ;ConsoleWrite($oldval) if $oldval == Round($value) Then Return EndIf ;GuiCtrlDelete($needle) GuiCtrlSetData($label , $value ) $value = Round($value ) if $value < $min Then $value = $min EndIf if $value > $max Then $value = $max EndIf $oldneedle = ($oldval - $min) / ( ($max - $min ) / 100 ) ;ConsoleWrite($oldneedle) GUICtrlSetGraphic($needle,$GUI_GR_MOVE, 10 + $oldneedle , 10 ) GUICtrlSetGraphic($needle,$GUI_GR_PENSIZE, 2) GUICtrlSetGraphic($needle,$GUI_GR_COLOR, 0x00ffff) GUICtrlSetGraphic($needle, $GUI_GR_LINE, 60 , 70 ) GUICtrlSetGraphic($needle,$GUI_GR_CLOSE) ;$needle = GUICtrlCreateGraphic(10 + $left ,35 + $top , 120 , 80 ) $setneedle =($value - $min)/ ( ($max - $min ) / 100 ) GUICtrlSetGraphic($needle,$GUI_GR_MOVE, 10 + $setneedle , 10 ) GUICtrlSetGraphic($needle,$GUI_GR_PENSIZE, 2) GUICtrlSetGraphic($needle,$GUI_GR_COLOR, 0x000000) GUICtrlSetGraphic($needle, $GUI_GR_LINE, 60 , 70 ) GUICtrlSetGraphic($needle,$GUI_GR_CLOSE) $struct = DllStructCreate("long;long;long;long") DllStructSetData($struct , 1 , 10 ) DllStructSetData($struct , 2 , 10) DllStructSetData($struct , 3 , 110 ) DllStructSetData($struct , 4 , 70 ) ;GUICtrlSendMsg( $gui,0x000F,TRUE , 0) DllStructSetData($struct , 1 , Int($left)+ 10 ) DllStructSetData($struct , 2 , Int($top) + 40 ) DllStructSetData($struct , 3 , Int($left) + 110 ) DllStructSetData($struct , 4 , Int($top) + 80 ) ForceRefresh($gui , $struct , false ) EndFunc Func DrawDial($left , $top , $basescale , $title , $units , ByRef $value , ByRef $needle , $scale = 1 , $leftG = 20, $rightG = 70 , $bkColor = 0xD4D0C8) $group = GUICtrlCreateGroup( $title , $left , $top , 150 ,120 ,Bitor( 0,$BS_CENTER) ) GUICtrlSetBkColor(-1,0x00ffff) GuiCtrlCreateGraphic($left , $top , 150 , 120 ) GUICtrlSetBkColor(-1,0x00ffff) for $x = 0 to 100 step 10 if $x > 0 Then $y = 1 Else $y = 0 endif if StringinStr($x / 20,".") = 0 Then GUICtrlCreateLabel("",$x * 1.2 + $left + 10 , 15 + $top , 1 , 15 , $SS_BLACKRECT) GUICtrlSetBkColor(-1, 0x00ffff) if $x < 100 Then $test = GUICtrlCreateLabel("",$x * 1.2 +$left + 11,15 + $top , 11 , 5 , 0 ) GUICtrlSetBkColor(-1, 0x00ffff) if $x < $rightG and $x > $leftG then GUICtrlSetBkColor($test , 0x00ff00) Else GUICtrlSetBkColor($test , 0xff0000) EndIf EndIf $scalevalue = $basescale + $x / $scale if ($x == 0 and $scalevalue > 99 ) or ( $scalevalue <100 and $scalevalue > 9 ) then GUICtrlCreateLabel( $scalevalue , $x * 1.2+ $left + 5, 25 + $top ) GUICtrlSetBkColor(-1, 0x00ffff) Else if $scalevalue < 10 Then GUICtrlCreateLabel($scalevalue , $x * 1.2 + $left + 8, 25 + $top ) GUICtrlSetBkColor(-1, 0x00ffff) Else GUICtrlCreateLabel($scalevalue , $x * 1.2 + $left, 25 + $top ) GUICtrlSetBkColor(-1, 0x00ffff) EndIf EndIf GUICtrlSetFont(-1,7) Else GUICtrlCreateLabel("",$x * 1.2 + $left + 10 , 15 + $top , 1 , 5 , $SS_BLACKRECT ) GUICtrlSetBkColor(-1, 0x00ffff) $test = GUICtrlCreateLabel("", $x *1.2 +$left + 11 ,15 + $top , 11 , 5 , 0 ) GUICtrlSetBkColor(-1, 0x00ffff) if $x < $rightG and $x > $leftG then GUICtrlSetBkColor($test , 0x00ff00) Else GUICtrlSetBkColor($test , 0xff0000) EndIf EndIf Next $value = GUICtrlCreateLabel($value, 10 + $left ,100 + $top , 40 , 15 ) GUICtrlSetBkColor(-1, 0x00ffff) $label2 = GUICtrlCreateLabel($units , 125 + $left ,100 + $top , 20 , 15 ) GUICtrlSetBkColor(-1, 0x00ffff) $needle = GUICtrlCreateGraphic(10 + $left ,35 + $top , 115 , 80 ) GUICtrlSetBkColor(-1, 0x00ffff) EndFunc Func skipBg($hWndGUI, $MsgID) Return EndFunc $inputv ="265" $needle1 = 0 $voltage ="V" $gui = GUICreate("UPS Monitor", 608 + 25, 338, -1 , -1) DrawDial(136 , 70 , 170 , "Input Voltage" , $voltage , $inputv , $needle1 , 1) ;GUIRegisterMsg ( 0x0014, "skipBg" ) AdlibEnable("Update",1000) GUISetState(@SW_SHOW) While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd Link to comment Share on other sites More sharing options...
Zedna Posted December 7, 2006 Share Posted December 7, 2006 (edited) try to use in your function UpdateValue():GuiSetState(@SW_LOCK, $gui) ; at begining ; your drawing here ... GuiSetState(@SW_UNLOCK, $gui) ; at end Edited December 7, 2006 by Zedna Resources UDF ResourcesEx UDF AutoIt Forum Search Link to comment Share on other sites More sharing options...
matrix200 Posted December 7, 2006 Author Share Posted December 7, 2006 Thanks for advice Zedna , but I have already tried that and sure enough the second the UNLOCK is executed the gui is redrawn and I get my flicker again. The thing is it is not flickering on every refresh , only from time to time . The longer the program runs the more flickering it gets and I start seeing remnants of the older arrows that were supposed to be deleted a long time ago. I also tried earlier to delete/recreate the graphic control , but that causes flicker all the time. Could I somehow force the application to redraw only certain regions on the screen and NEVER redraw anything else? Or maybe there is a way not to use the graphic at all to draw the arrow pointing to a value at my clocks? Link to comment Share on other sites More sharing options...
Zedna Posted December 7, 2006 Share Posted December 7, 2006 Or maybe there is a way not to use the graphic at all to draw the arrow pointing to a value at my clocks? You can use Window API: LineTo, MoveTo, ... and then use GUIRegisterMsg($WM_PAINT, 'MY_WM_PAINT') look at BlackJack antiflicker methods also look at my Radar.au3 - function MalujKriz() it's in my signature. Resources UDF ResourcesEx UDF AutoIt Forum Search Link to comment Share on other sites More sharing options...
matrix200 Posted December 8, 2006 Author Share Posted December 8, 2006 (edited) Regarding BlackJack , Is that right that the main problem there was redrawing images? I see what he did is simply inject some code to repaint the cards before calling to default WM_PAINT handler. I don't see how that can help me since I am not using anything like card.dll in my program. Regarding your code in Radar I tried to make it work with my program , but wasn't able to see any arrows at all (nothing is redrawn at all). Here is the code I put instead of my update $handle = ControlGetHandle($gui,"",$needle1) $user_dll = DllOpen("user32.dll") $gdi_dll = DllOpen("gdi32.dll") $l_hdc = DLLCall($user_dll,"int","GetDC","hwnd",$needle1) $pen = DLLCall($gdi_dll,"int","CreatePen","int",0,"int",2,"int",0xFF) $obj_orig = DLLCall($gdi_dll,"int","SelectObject","int",$l_hdc[0],"int",$pen[0]) DLLCall($gdi_dll,"int","MoveToEx","int",$l_hdc[0],"int",10 + $oldneedle,"int",10,"int",0) DLLCall($gdi_dll,"int","LineTo","int",$l_hdc[0],"int",60,"int",70) DLLCall($gdi_dll,"int","SelectObject","int",$l_hdc[0],"int",$obj_orig[0]) DLLCall($gdi_dll,"int","DeleteObject","int",$pen[0]) $l_hdc = DLLCall($user_dll,"int","ReleaseDC","hwnd",$handle,"int",$l_hdc[0]) DllClose($gdi_dll) DllClose($user_dll) What am I doing wrong here? Another interesting thing I noticed , when I added back the invalidate_rectangle call I saw occasional flicker again. I am still using guictrlcreategraphic even though without its drawing functions , could it be the reason for the flicker? In that case what kind of control I should choose? Edited December 8, 2006 by matrix200 Link to comment Share on other sites More sharing options...
matrix200 Posted December 9, 2006 Author Share Posted December 9, 2006 (edited) Just an update Zedna. I would like to thank you for the great help. Your idea of using windows api works great! The flicker is pretty much gone now. Again thanks a lot for your help. I am going to publish the whole program as I perfect it a little bit. As far as I know it is first NUT ups windows gui client so I hope people are going to be interested Edited December 9, 2006 by matrix200 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