Sign in to follow this  
Followers 0
Spiff59

Why the huge performance hit?

12 posts in this topic

#1 ·  Posted (edited)

Is interesting, you can click on the left button in the demo below as quickly as you like and all runs smoothly.

Click on the right one and the response is slow and jerky.

#include <GuiConstants.au3>
$Main_GUI = GuiCreate("", 160, 80)
GUISetFont (9, 600, 0)
$Button_Left = GUICtrlCreateButton("<", 20, 20)
$Label = GUICtrlCreateLabel("", 60, 25, 20, 20)
$Button_Right = GUICtrlCreateButton(">", 100, 20)
GuiCtrlSetColor(-1, 0x0000FF); blue
;GuiCtrlSetBkColor(-1, 0xFFFFFF); white
GUISetState()

;---------------------------------------------------------------------------------------------------------------------------
$x = 1
While 1
    $msg = GUIGetMsg()  
    Switch $msg
        Case $Button_Left
            $x -= 1
            GUICtrlSetData($label, $x)
        Case $Button_Right
            $x += 1
            GUICtrlSetData($label, $x)
        Case $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
Wend
Exit

Why such a performance hit by changing the text color of the button control?

This can't be inherent in the OS?

Thanks.

Edited by Spiff59

Share this post


Link to post
Share on other sites



that's really strange to me. i see the same strange results by clicking LMB on right button (control with style).

Right Button control is getting messages from mouse clicks twice longer than control with no style. lol.

interesting is everything works fine and fast if you use ENTER key instead of Left Mouse Button to hit control.

check this code

#include <GuiConstants.au3>
#include <Misc.au3>
Global $tLeft, $tRight, $check, $key, $sMsg

$Main_GUI = GuiCreate("", 160, 80)
$Button_Left = GUICtrlCreateButton("<", 20, 20)
$Label = GUICtrlCreateLabel("", 60, 25, 20, 20)
$Button_Right = GUICtrlCreateButton(">", 100, 20)
GuiCtrlSetColor(-1, 0x0000FF); blue
GUISetState()

;---------------------------------------------------------------------------------------------------------------------------
$x = 1
While 1
    If _IsPressed('01') Then 
        $check = TimerInit()
        $key = 'Mouse LMB:  '
    EndIf
    
    If _IsPressed('0D') Then 
        $check = TimerInit()
        $key = 'ENTER key:  '
    EndIf
    
    $msg = GUIGetMsg()    
    Switch $msg
        Case $Button_Left
            $sMsg &= $key &Round(TimerDiff($check),3)
            $sMsg &= @CRLF &"Last click:     " &Round(TimerDiff($tLeft),3)
            $x -= 1
            GUICtrlSetData($label, $x)
            ToolTip($sMsg, 0, 0, 'Button Left')
            $sMsg = ""
            $tLeft = TimerInit()
        Case $Button_Right
            $sMsg &= $key &Round(TimerDiff($check),3)
            $sMsg &= @CRLF & "Last click:     " &Round(TimerDiff($tRight),3)
            $x += 1
            GUICtrlSetData($label, $x)
            ToolTip($sMsg, 0, 0, 'Button Right')
            $sMsg = ""
            $tRight = TimerInit()
        Case $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
Wend
Exit

Share this post


Link to post
Share on other sites

that's really strange to me. i see the same strange results by clicking LMB on right button (control with style).

Right Button control is getting messages from mouse clicks twice longer than control with no style. lol.

interesting is everything works fine and fast if you use ENTER key instead of Left Mouse Button to hit control.

The fact that this behavior occurs only with mouse clicks, and not the {ENTER} key, seems useful information if someone were trying to figure out what causes this...

Share this post


Link to post
Share on other sites

Indeed a wired one!

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

WELL.... i agree... maybe i dont know maybe its the GUIctrlsetcolor() or -----BkColor() because its usefull to always specify (not sure if this is problem)

EDIT

#Include <ButtonConstants.au3>

#Include <WindowsConstants.au3>

???? i dont know

Edited by CodyBarrett

Share this post


Link to post
Share on other sites

That's... uhh, really weird. I first thought it was a drawing issue but using the spacebar to activate the control works fine (which is really what's analogous to clicking, not hitting Enter). I don't know what to say other than owner-drawn buttons should have never been added to the native controls in the first place. Try it with a UDF owner-drawn button and see how that performs.

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

Hmm... very interesting...

I've found something that might lead to a cure?

Try the demo below, it has wide buttons and kicks out a timer of milliseconds between hits.

#include <GuiConstants.au3>
$Main_GUI = GuiCreate("", 300, 80)
$Button_Left = GUICtrlCreateButton("default color", 20, 20, 120, 24)
$Label_Left = GUICtrlCreateLabel("", 70, 50, 22, 20)
$Button_Right = GUICtrlCreateButton("modified color", 150, 20, 120, 24)
GuiCtrlSetColor(-1, 0xFF0000)
GuiCtrlSetBkColor(-1, 0xFFFFFF)
$Label_Right = GUICtrlCreateLabel("", 200, 50, 22, 20)
GUISetState()

;---------------------------------------------------------------------------------------------------------------------------
$timer = TimerInit()
While 1
    $msg = GUIGetMsg()  
    Switch $msg
        Case $Button_Left
            GUICtrlSetData($Label_Left, TimerDiff($timer))
;           beep(500,1)
            $timer = TimerInit()
        Case $Button_Right
            GUICtrlSetData($Label_Right, TimerDiff($timer))
;           beep(500,1)
            $timer = TimerInit()
        Case $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
Wend
Exit

Playing the "mouse-click game", I can "score" a 93 pretty easily while beating up on the button with the default text color.

I saw a 64 go by once and a few 72's as well. Pounding on the button with the user-assigned color, 296 milliseconds seems to be about the average "best time" I can get, with a 265 going by on once or twice as my "lucky click". So, changing the text color results in around a 300% hit on button performance.

Here's the kicker!!! 296 is about the best score I can get if I hold the mouse steady while clicking on the pretty button. BUT... If subsequent mouse-clicks on the modified button occur at different coordinates, the response time is close to normal! I skipped my bottle of vodka for breakfast this morning, to intentionally induce tremors, and find it's not too tough for a shaky hand to score a near-normal 124 milliseconds on the bastardized button. If I spasm over the standard button, I get the same scores.

So, the performance hit only occurs when you click repeatedly on the same coordinate of the user-modified button.

Might that fact help narrow the scope of tracking down the cause for this issue?

Edited by Spiff59

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

I don't know enough about the internals of Windows to go any further with this.

This, my final little demo program on the topic, demonstrates the initial odd behavior, and the even more freakish method of alleviating it...

I've added a checkbox for "wiggle mode" that cuts the performance decrease from 250-300% to close to nothing.

Give 'er a try.

Can Anyone explain what's taking place here???

$Main_GUI = GuiCreate("", 290, 80)
$Label_Wiggle = GUICtrlCreateCheckbox("Wiggle Mouse", 110, 5, 90, 20)
$Button_Left = GUICtrlCreateButton("default color", 20, 30, 120, 24)
$Label_Left = GUICtrlCreateLabel("", 20, 60, 120, 20)
$Button_Right = GUICtrlCreateButton("modified color", 150, 30, 120, 24)
GuiCtrlSetColor(-1, 0xFF0000)
GuiCtrlSetBkColor(-1, 0xF0F0F0)
$Label_Right = GUICtrlCreateLabel("", 155, 60, 120, 20)
GUISetState()

$wiggle_mouse = 0
$offset = 2
$lspeed = 999
$rspeed = 999
$timer = TimerInit()
;-----------------------------------------------------
While 1
    $msg = GUIGetMsg()  
    Switch $msg
        Case $Button_Left
            $timer = Int(TimerDiff($timer))
            If $timer < $lspeed Then
                $lspeed = $timer
                beep(500,1)
            EndIf
            GUICtrlSetData($Label_Left, "Last: " & $timer & "   Best: " & $lspeed)
            If $wiggle_mouse Then
                $x = MouseGetPos()
                $offset *= -1
                MouseMove($x[0] + $offset, $x[1], 0)
            EndIf
            $timer = TimerInit()
        Case $Button_Right
            $timer = Int(TimerDiff($timer))
            If $timer < $rspeed Then
                $rspeed = $timer
                beep(500,1)
            EndIf
            GUICtrlSetData($Label_Right, "Last: " & $timer & "  Best: " & $rspeed)
            If $wiggle_mouse Then
                $x = MouseGetPos()
                $offset *= -1
                MouseMove($x[0] + $offset, $x[1], 0)
            EndIf
            $timer = TimerInit()
        Case $Label_Wiggle
            $wiggle_mouse = Not $wiggle_mouse
            $lspeed = 999
            $rspeed = 999
            GUICtrlSetData($Label_Left, "")
            GUICtrlSetData($Label_Right, "")
        Case -3; $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
Wend
Exit

Let's just say, at this point, I've given up any intention of coloring the text or background of a button control.

Edit: PS - To anyone whom I've helped wear out their mouse: I apologize :P

Edited by Spiff59
Removed text that was too long.

Share this post


Link to post
Share on other sites

Is interesting, you can click on the left button in the demo below as quickly as you like and all runs smoothly.

Click on the right one and the response is slow and jerky.

#include <GuiConstants.au3>
$Main_GUI = GuiCreate("", 160, 80)
GUISetFont (9, 600, 0)
$Button_Left = GUICtrlCreateButton("<", 20, 20)
$Label = GUICtrlCreateLabel("", 60, 25, 20, 20)
$Button_Right = GUICtrlCreateButton(">", 100, 20)
GuiCtrlSetColor(-1, 0x0000FF); blue
;GuiCtrlSetBkColor(-1, 0xFFFFFF); white
GUISetState()

;---------------------------------------------------------------------------------------------------------------------------
$x = 1
While 1
    $msg = GUIGetMsg()  
    Switch $msg
        Case $Button_Left
            $x -= 1
            GUICtrlSetData($label, $x)
        Case $Button_Right
            $x += 1
            GUICtrlSetData($label, $x)
        Case $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
Wend
Exit

Why such a performance hit by changing the text color of the button control?

This can't be inherent in the OS?

Thanks.

A recent post reminded me of this post. And, had to test this resultant script.

Using _WinAPI_PtInRectEx() from

http://www.autoitscript.com/forum/index.ph...st&p=639786

The coloured button appears to be performing as well as the other button.

#include <GuiConstants.au3>

Opt("MouseCoordMode", 2);1=absolute, 0=relative, 2=client
$Main_GUI = GUICreate("", 160, 80)
GUISetFont(9, 600, 0)
$Button_Left = GUICtrlCreateButton("<", 20, 20)
$Label = GUICtrlCreateLabel("", 60, 25, 20, 20)
$Button_Right = GUICtrlCreateButton(">", 100, 20)
GUICtrlSetColor(-1, 0x0000FF); blue
;GuiCtrlSetBkColor(-1, 0xFFFFFF); white
GUISetState()

;---------------------------------------------------------------------------------------------------------------------------
$x = 1
While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $Button_Left
            $x -= 1
            GUICtrlSetData($Label, $x)
        Case $GUI_EVENT_PRIMARYUP ;Case $Button_Right
            $aPos = MouseGetPos()
            If _WinAPI_PtInRectEx($aPos[0], $aPos[1], 100, 20, 16, 27) Then
                $x += 1
                GUICtrlSetData($Label, $x)
            EndIf
        Case $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
WEnd
Exit

Func _WinAPI_PtInRectEx($iX, $iY, $iLeft, $iTop, $iWidth, $iHeight)
    Local $aResult, $tagREC = "int Left;int Top;int Right;int Bottom"
    Local $tRect = DllStructCreate($tagREC)
    DllStructSetData($tRect, "Left", $iLeft)
    DllStructSetData($tRect, "Top", $iTop)
    DllStructSetData($tRect, "Right", $iLeft + $iWidth)
    DllStructSetData($tRect, "Bottom", $iTop + $iHeight)
    $aResult = DllCall("User32.dll", "int", "PtInRect", "ptr", DllStructGetPtr($tRect), "int", $iX, "int", $iY)
    If @error Then Return SetError(@error, 0, False)
    Return $aResult[0] <> 0
EndFunc   ;==>_WinAPI_PtInRectEx

Share this post


Link to post
Share on other sites

@Spiff59, All

I came across the answer to this while Googling for something else

my ownerdrawn button doesnt respond well to clicks

comp.os.ms-windows.programmer.win32

http://groups.google.ca/group/comp.os.ms-w...c6835b0f41b7bab

#include <GuiConstants.au3>

Global Const $GCL_STYLE = -26
Global Const $CS_DBLCLKS = 0x8

$Main_GUI = GUICreate("", 160, 80)
GUISetFont(9, 600, 0)
$Label = GUICtrlCreateLabel("", 60, 25, 20, 20)

$Button_Left = GUICtrlCreateButton("<", 20, 20)

$Button_Right = GUICtrlCreateButton(">", 100, 20)
GUICtrlSetColor(-1, 0x0000FF); blue
$hButton = GUICtrlGetHandle(-1)

;when GuiCtrlSetColor() changes a button style to ownerdrawn for colouring, the Button class style CS_DBLCLKS causes this effect
;GUICtrlSetStyle($nButton, BitOR($WS_TABSTOP, $BS_NOTIFY, $BS_OWNERDRAW))
;help file - Push Button Styles: $BS_NOTIFY - 'To get BN_DBLCLK notification messages, the button must have the BS_RADIOBUTTON or BS_OWNERDRAW style'

;An alternative I haven't tried, is to create a new button class
;WM_DRAWITEM - Bitmap buttons missing mouse clicks
;http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/8889b33c-c54b-4fd8-b58f-9d66b9aa2f77/

;remove CS_DBLCLKS style from Button class
;NOTE: all subsequently created buttons for current process will not have CS_DBLCLKS style
$aResult = DllCall("User32.dll", "dword", "GetClassLong", "hwnd", $hButton, "int", $GCL_STYLE)
ConsoleWrite('+ GCL_STYLE = ' & $aResult[0] & @CRLF & '>Error code: ' & @error & @CRLF)
$iStyle = BitAND($aResult[0], BitNOT($CS_DBLCLKS))
$aResult = DllCall("User32.dll", "dword", "SetClassLong", "hwnd", $hButton, "int", $GCL_STYLE, "long", $iStyle)
$aResult = DllCall("User32.dll", "dword", "GetClassLong", "hwnd", $hButton, "int", $GCL_STYLE)
ConsoleWrite('+ GCL_STYLE = ' & $aResult[0] & @CRLF & '>Error code: ' & @error & @CRLF)

GUISetState()

$x = 1
While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $Button_Left
            $x -= 1
            GUICtrlSetData($Label, $x)
        Case $Button_Right
            $x += 1
            GUICtrlSetData($Label, $x)
        Case $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
WEnd
Exit

I see fascists...

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

The first effective work-around, nice job!

Smooth as butter. This seems to be the root of the problem! Way to go.

Think there is a Bug Trac in this???

Edited by Spiff59

Share this post


Link to post
Share on other sites

Smooth as butter. This seems to be the root of the problem! Way to go.

Think there is a Bug Trac in this???

Hi Spiff59

If it can be considered a bug its an MS bug, or a feature ^_^

This is intended behaviour from the button control when ownerdrawn

haven't found any MS explanation yet on this.

Re: CButton with no CS_DBLCLKS style (I don't want BN_DOUBLECLICKED messages)

http://www.tech-archive.net/Archive/Develo...04-11/0198.html

Owner-draw icon buttons in plain C (no MFC)

http://www.codeproject.com/KB/buttons/odib.aspx

for reference another MS link suggesting creating a custom button class

WM_DRAWITEM - Bitmap buttons missing mouse clicks

http://social.msdn.microsoft.com/Forums/en...f-9d66b9aa2f77/


I see fascists...

Share this post


Link to post
Share on other sites

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
Sign in to follow this  
Followers 0