matrix200 Posted December 7, 2006 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
Zedna Posted December 7, 2006 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
matrix200 Posted December 7, 2006 Author 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?
Zedna Posted December 7, 2006 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
matrix200 Posted December 8, 2006 Author 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
matrix200 Posted December 9, 2006 Author 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
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