Sign in to follow this  
Followers 0
atomman

Loops and CPU cycles

14 posts in this topic

#1 ·  Posted (edited)

Scenario: 2 edit controls, side by side, and want to scroll 1 and synchronize the 2nd with the 1st.

I'm not understanding either how to nest loops properly, or just not using the right syntax. Here's an example that i have nested within a While() loop that uses too much CPU whenever the GUI containing this code is focused AND the mouse is moved around (either on or off the GUI):

If WinActive($Form1) Then
        If _GUICtrlEdit_GetFirstVisibleLine($Edit1) > _GUICtrlEdit_GetFirstVisibleLine($Edit2) Then
            _GUICtrlEdit_Scroll($Edit2, $SB_LINEDOWN)
            Sleep(5)
        ElseIf _GUICtrlEdit_GetFirstVisibleLine($Edit1) < _GUICtrlEdit_GetFirstVisibleLine($Edit2) Then
            _GUICtrlEdit_Scroll($Edit2, $SB_LINEUP)
            Sleep(5)
        EndIf
    EndIf

I've substituted and or added Do - Until, While - WEnd, If - EndIf statements/loops everywhere throughout the above code, with Sleep() added within the loops, but the end result is either the code works and CPU remains high, or i break it. Here's another example i tried...

If WinActive($Form1) And _GUICtrlEdit_GetFirstVisibleLine($Edit1) > _GUICtrlEdit_GetFirstVisibleLine($Edit2) Then
    While _GUICtrlEdit_GetFirstVisibleLine($Edit1) > _GUICtrlEdit_GetFirstVisibleLine($Edit2)
        _GUICtrlEdit_Scroll($Edit2, $SB_LINEDOWN)
        Sleep(5)
    WEnd
ElseIf WinActive($Form1) And _GUICtrlEdit_GetFirstVisibleLine($Edit1) < _GUICtrlEdit_GetFirstVisibleLine($Edit2) Then
    While _GUICtrlEdit_GetFirstVisibleLine($Edit1) < _GUICtrlEdit_GetFirstVisibleLine($Edit2)
        _GUICtrlEdit_Scroll($Edit2, $SB_LINEUP)
        Sleep(5)
    WEnd
EndIf

What i really don't understand is why CPU usage remains high only when the mouse is moved. The lines in the edit controls remain in whatever state they're in, regardless of mouse movement. I can understand why CPU would spike if the number of lines in the edit's were not equal AND a Sleep() wasn't used, but how does mouse movement come in to play?

Edited by atomman

Share this post


Link to post
Share on other sites



don't have to because as i was trimming the code to make the example, the CPU usage problem quit. :)

so it's not that snippet by itself that's causing the problem.

are there any general rules i need to be following that are not covered in the manual when nesting multiple loops within a loop?

such as...

while 1

  while(this)
  wend

 while(that)
   do
   until
 wend

wend

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

now i will, because i'm having the same problem again and i need to use this code.

problem is high CPU activity only when the GUI is given focus and the mouse is moved (on or off the GUI).

#include <GUIConstants.au3>
;#include <GUIConstantsEx.au3>
;#include <GUIDefaultConstants.au3>
;#include <ButtonConstants.au3>
#include <GuiEdit.au3>

Opt("TrayIconDebug", 1)

Dim $Line
Dim $Win
Dim $Text2Html_HlCst
Dim $Text2Html_Cmt
Dim $Text2Html_Div

$Form1 = GUICreate("", 487, 152, -1, -1, BitOR($WS_SIZEBOX, $WS_THICKFRAME, $WS_POPUP), 0)
$Edit1 = GUICtrlCreateEdit("", 0, 20, 250, 131, BitOR($ES_AUTOVSCROLL, $ES_AUTOHSCROLL, $ES_NOHIDESEL, $ES_WANTRETURN, $WS_HSCROLL, $WS_VSCROLL), $WS_EX_STATICEDGE)
GUICtrlSetData(-1, StringFormat("1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20"))
GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKTOP + $GUI_DOCKBOTTOM)
$Edit2 = GUICtrlCreateEdit("", 252, 20, 234, 131, BitOR($ES_AUTOVSCROLL, $ES_AUTOHSCROLL, $ES_NOHIDESEL, $ES_WANTRETURN, $WS_HSCROLL), $WS_EX_STATICEDGE)
GUICtrlSetData(-1, StringFormat("1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20"))
GUICtrlSetResizing(-1, $GUI_DOCKRIGHT + $GUI_DOCKTOP + $GUI_DOCKBOTTOM)
$Label_Drag = GUICtrlCreateLabel("", 76, 2, 299, 17, BitOR($SS_BLACKRECT, $SS_GRAYFRAME, $SS_LEFTNOWORDWRAP, $SS_NOPREFIX), $GUI_WS_EX_PARENTDRAG)
GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKRIGHT + $GUI_DOCKTOP + $GUI_DOCKHEIGHT)
GUICtrlSetCursor(-1, 9)
$Button_Exit = GUICtrlCreateButton("X", 467, 2, 16, 16, 0)
GUICtrlSetResizing(-1, $GUI_DOCKRIGHT + $GUI_DOCKTOP + $GUI_DOCKWIDTH + $GUI_DOCKHEIGHT)
GUICtrlSetTip(-1, "Exit")
GUISetState(@SW_SHOW)

While 1

    $Msg = GUIGetMsg()
    
    If WinActive($Form1) And _GUICtrlEdit_GetFirstVisibleLine($Edit1) > _GUICtrlEdit_GetFirstVisibleLine($Edit2) Then
        Do
            _GUICtrlEdit_Scroll($Edit2, $SB_LINEDOWN)
            Sleep(5)
        Until _GUICtrlEdit_GetFirstVisibleLine($Edit1) = _GUICtrlEdit_GetFirstVisibleLine($Edit2)
    ElseIf WinActive($Form1) And _GUICtrlEdit_GetFirstVisibleLine($Edit1) < _GUICtrlEdit_GetFirstVisibleLine($Edit2) Then
        Do
            _GUICtrlEdit_Scroll($Edit2, $SB_LINEUP)
            Sleep(5)
        Until _GUICtrlEdit_GetFirstVisibleLine($Edit1) = _GUICtrlEdit_GetFirstVisibleLine($Edit2)
    EndIf
    
    Switch $Msg

        Case $Button_Exit
            GUIDelete($Form1)
            Exit

    EndSwitch

WEnd
Edited by atomman

Share this post


Link to post
Share on other sites

has anyone verified this?

Share this post


Link to post
Share on other sites

can someone confirm this please?

Share this post


Link to post
Share on other sites

still looking for help on this one.

wondering why CPU rises to ~35% when mouse is moved around when this GUI is active.

here's the latest example...

#include <GUIConstants.au3>
#include <GuiEdit.au3>

$Form1 = GUICreate("Form1", 195, 134, -1, -1)
$Edit1 = GUICtrlCreateEdit("", 8, 4, 85, 121)
GUICtrlSetData(-1, StringFormat("1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20"))
$Edit2 = GUICtrlCreateEdit("", 100, 4, 85, 121)
GUICtrlSetData(-1, StringFormat("1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20"))
GUISetState(@SW_SHOW)


While 1
    
    If _GUICtrlEdit_GetFirstVisibleLine($Edit1) > _GUICtrlEdit_GetFirstVisibleLine($Edit2) Then
        _GUICtrlEdit_Scroll($Edit2, $SB_LINEDOWN)
    ElseIf _GUICtrlEdit_GetFirstVisibleLine($Edit2) > _GUICtrlEdit_GetFirstVisibleLine($Edit1) Then
        _GUICtrlEdit_Scroll($Edit2, $SB_LINEUP)
    EndIf
    
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit

    EndSwitch
WEnd

Share this post


Link to post
Share on other sites

not the best way to do it, but give it a try

#include <GUIConstants.au3>
#include <GuiEdit.au3>

$Form1 = GUICreate("Form1", 195, 134, -1, -1)
$Edit1 = GUICtrlCreateEdit("", 8, 4, 85, 121)
GUICtrlSetData(-1, StringFormat("1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20"))
$Edit2 = GUICtrlCreateEdit("", 100, 4, 85, 121)
GUICtrlSetData(-1, StringFormat("1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20"))
GUISetState(@SW_SHOW)
AdlibEnable("_Control", 50)

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

Func _Control()
    Select
        Case _GUICtrlEdit_GetFirstVisibleLine($Edit1) > _GUICtrlEdit_GetFirstVisibleLine($Edit2)
        _GUICtrlEdit_Scroll($Edit2, $SB_LINEDOWN)
        Case _GUICtrlEdit_GetFirstVisibleLine($Edit2) > _GUICtrlEdit_GetFirstVisibleLine($Edit1)
        _GUICtrlEdit_Scroll($Edit2, $SB_LINEUP)
    EndSelect
EndFunc

Share this post


Link to post
Share on other sites

If you use a different method for the scroll, instead of the built in scroll bars, you could try something like this, but as it is now the IsPressed function doesn't like to pick up the mouse click when you are using it to scroll.

#include <GUIConstants.au3>
#include <GuiEdit.au3>
#Include <Misc.au3>

$Form1 = GUICreate("Form1", 195, 134, -1, -1)
$Edit1 = GUICtrlCreateEdit("", 8, 4, 85, 121)
GUICtrlSetData(-1, StringFormat("1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20"))
$Edit2 = GUICtrlCreateEdit("", 100, 4, 85, 121)
GUICtrlSetData(-1, StringFormat("1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20"))
GUISetState(@SW_SHOW)
While 1
    If _IsPressed( 01 ) Then
        While _IsPressed( 01 )
            Sleep(10)
        WEnd
        cpuhog()
    EndIf
    Sleep(10)
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd
Func cpuhog()
    If _GUICtrlEdit_GetFirstVisibleLine($Edit1) > _GUICtrlEdit_GetFirstVisibleLine($Edit2) Then
        For $avar = _GUICtrlEdit_GetFirstVisibleLine($Edit2) To _GUICtrlEdit_GetFirstVisibleLine($Edit1) - 1
            _GUICtrlEdit_Scroll($Edit2, $SB_LINEDOWN)
        Next
    ElseIf _GUICtrlEdit_GetFirstVisibleLine($Edit2) > _GUICtrlEdit_GetFirstVisibleLine($Edit1) Then
        For $avar = _GUICtrlEdit_GetFirstVisibleLine($Edit1) To _GUICtrlEdit_GetFirstVisibleLine($Edit2) - 1
            _GUICtrlEdit_Scroll($Edit2, $SB_LINEUP)
        Next
    EndIf
EndFunc   ;==>cpuhog

Share this post


Link to post
Share on other sites

not the best way to do it, but give it a try

well, it works, but it is dirty :)

AdlibEnable is new to me. I missed that one entirely. Thanks for the enlightenment.

If you use a different method for the scroll, instead of the built in scroll bars, you could try something like this, but as it is now the IsPressed function doesn't like to pick up the mouse click when you are using it to scroll.

I went a similar route before, but with Case $GUI_EVENT_PRIMARYDOWN. It works fine, but of course only when the L-button is down and the scroll wheel obviously has no effect on the second edit control.

This would be yours and mine combined..

#include <GUIConstants.au3>
#include <GuiEdit.au3>
#Include <Misc.au3>

$Form1 = GUICreate("Form1", 195, 134, -1, -1)
$Edit1 = GUICtrlCreateEdit("", 8, 4, 85, 121)
GUICtrlSetData(-1, StringFormat("1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20"))
$Edit2 = GUICtrlCreateEdit("", 100, 4, 85, 121)
GUICtrlSetData(-1, StringFormat("1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20"))
GUISetState(@SW_SHOW)
While 1

    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
            
        Case $GUI_EVENT_PRIMARYDOWN
            If _GUICtrlEdit_GetFirstVisibleLine($Edit1) > _GUICtrlEdit_GetFirstVisibleLine($Edit2) Then
                For $avar = _GUICtrlEdit_GetFirstVisibleLine($Edit2) To _GUICtrlEdit_GetFirstVisibleLine($Edit1) - 1
                    _GUICtrlEdit_Scroll($Edit2, $SB_LINEDOWN)
                Next
            ElseIf _GUICtrlEdit_GetFirstVisibleLine($Edit2) > _GUICtrlEdit_GetFirstVisibleLine($Edit1) Then
                For $avar = _GUICtrlEdit_GetFirstVisibleLine($Edit1) To _GUICtrlEdit_GetFirstVisibleLine($Edit2) - 1
                    _GUICtrlEdit_Scroll($Edit2, $SB_LINEUP)
                Next
            EndIf

    EndSwitch
WEnd

I guess that's what i may be stuck with since i don't want to get in to the mouse hook stuff at this point.

Share this post


Link to post
Share on other sites

Hey, good work atomman, here is ours combined to equal a nice script:

#include <GUIConstants.au3>
#include <GuiEdit.au3>
#Include <Misc.au3>

$Form1 = GUICreate("Form1", 195, 134, -1, -1)
$Edit1 = GUICtrlCreateEdit("", 8, 4, 85, 121)
GUICtrlSetData(-1, StringFormat("1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20"))
$Edit2 = GUICtrlCreateEdit("", 100, 4, 85, 121)
GUICtrlSetData(-1, StringFormat("1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20"))
GUISetState(@SW_SHOW)
While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
           
       Case $GUI_EVENT_PRIMARYDOWN
           While _IsPressed( 01 )
               Sleep(10)
           WEnd
            If _GUICtrlEdit_GetFirstVisibleLine($Edit1) > _GUICtrlEdit_GetFirstVisibleLine($Edit2) Then
                For $avar = _GUICtrlEdit_GetFirstVisibleLine($Edit2) To _GUICtrlEdit_GetFirstVisibleLine($Edit1) - 1
                    _GUICtrlEdit_Scroll($Edit2, $SB_LINEDOWN)
                Next
            ElseIf _GUICtrlEdit_GetFirstVisibleLine($Edit2) > _GUICtrlEdit_GetFirstVisibleLine($Edit1) Then
                For $avar = _GUICtrlEdit_GetFirstVisibleLine($Edit1) To _GUICtrlEdit_GetFirstVisibleLine($Edit2) - 1
                    _GUICtrlEdit_Scroll($Edit2, $SB_LINEUP)
                Next
            EndIf
    EndSwitch
    Sleep(10)
WEnd

Share this post


Link to post
Share on other sites

What is the thinking behind adding the _IsPressed and Sleep's in there?

I = nOOb, so i don't understand. CPU stays low either way.

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

So that the action takes place after the mouse button is released, instead of when it is pressed.

EDIT: if you clicked and dragged to highlight stuff, it would only goto the point of initial click not release.

Edited by danwilli

Share this post


Link to post
Share on other sites

ah... didn't test that yet.

thanks!

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