【问题标题】:Optimizing Tab Control With AutoIT使用 AutoIT 优化选项卡控制
【发布时间】:2019-04-03 15:25:26
【问题描述】:

所以我写了这个来模拟一个有启动和停止功能的程序,并且有一个tab design。现在有一个标签,其中有一个 RichEdit 对象,旨在成为一个运行日志。

如您所见,在我们“启动”程序后,我只输入了几毫秒的 sleep 来模拟运行指令。我创建了一个函数来检查将在整个代码中以更大规模随机调用的请求来 ping GUI

#include <GUIConstantsEx.au3>
#include <GuiRichEdit.au3>
#include <WindowsConstants.au3>

Global Const $h_numOfTabs = 2
Global Enum $H_TAB_1, $H_TAB_2, $H_TAB_END
Global $hGui, $h_logRichEdit, $iMsg,  $h_tabs, $h_startButton, $h_stopButton

Example()

Func Example()
    $hGui = GUICreate("Example (" & StringTrimRight(@ScriptName, StringLen(".exe")) & ")", 400, 550, -1, -1)

    ; ADD START AND STOP BUTTONS
    $h_startButton = GUICtrlCreateButton( "Start", 50, 450 )
    $h_stopButton = GUICtrlCreateButton( "Stop", 150, 450 )

    $h_tabs = GUICtrlCreateTab( 5, 5, 390,375 )

    ; LOG TAB
    GUICtrlCreateTabItem( "Log" )
    $h_logRichEdit = _GUICtrlRichEdit_Create ( $hGui, "", 8, 30, 384, 347, BitOR( $ES_MULTILINE, $WS_VSCROLL, $ES_AUTOVSCROLL, $ES_READONLY ) )

    ; STATS TAB
    GUICtrlCreateTabItem( "Stats" )

    ; Close TABS
    GUICtrlCreateTabItem( "" )

    GUISetState( @SW_SHOW ) ; initialize the gui

    While True
        CheckRequests()
    WEnd
EndFunc   ;==>Example

Func Start()
    while true
        Sleep(100)
        CheckRequests()
    WEnd
EndFunc

Func Stop()

EndFunc

Func CheckRequests()
    $iMsg = GUIGetMsg()
    while $iMsg <> 0
        Select
            Case $iMsg = $GUI_EVENT_CLOSE
                _GUICtrlRichEdit_Destroy($h_logRichEdit) ; needed unless script crashes
                ; GUIDelete()   ; is OK too
                Exit
            Case $iMsg = $h_tabs
                Switch GUICtrlRead( $h_tabs )
                    Case $H_TAB_1
                        ControlShow( $hGui, "", $h_logRichEdit )
                    Case Else
                        ControlHide( $hGui, "", $h_logRichEdit )
                EndSwitch
            Case $iMsg = $h_startButton
                Start()
            Case $iMsg = $h_stopButton
                Stop()
        EndSelect
        $iMsg = GUIGetMsg()
    WEnd
EndFunc

在大约 500 毫秒睡眠时,可以看到切换标签时的延迟。

我的问题:在更大的范围内,这是我们在运行更大的程序时如何处理/更新特定于选项卡的内容的方式吗?如果不是,那么在运行更大的整体程序时更新选项卡特定属性的更有效方法是什么。

我最近还看到了一个设计,其中所有选项卡和相关组件都是它们自己的GUI's,但我不确定所有东西都是它自己的GUI 的相关性以及它是否与这个问题有关。

非常感谢任何帮助或澄清,我是 AutoIT 的新手,并试图弄清楚一些该做什么和不该做什么以及效率。

【问题讨论】:

  • 我正在查看GUICtrlCreateTab 的参考资料,看起来他们正在创建一个选项卡控件,可以在不使用 gui 消息的情况下在 GUI 元素之间切换,因此您可能想尝试这样做以避免滞后。但是,我使用 _GUICtrlRichEdit_Create() 进行了尝试,但它似乎不起作用......无论单击哪个选项卡,富编辑似乎都会出现。它适用于其他 GUI 元素,例如标签、按钮等......

标签: performance autoit


【解决方案1】:
#include <GUIConstantsEx.au3>
#include <GuiRichEdit.au3>
#include <WindowsConstants.au3>

Global Const $h_numOfTabs = 2
Global Enum $H_TAB_1, $H_TAB_2, $H_TAB_END
Global $hGui, $h_logRichEdit, $iMsg,  $h_tabs, $h_startButton, $h_stopButton

Example()

Func Example()
    $hGui = GUICreate("Example (" & StringTrimRight(@ScriptName, StringLen(".exe")) & ")", 400, 550, -1, -1)

    ; ADD START AND STOP BUTTONS
    $h_startButton = GUICtrlCreateButton( "Start", 50, 450 )
    $h_stopButton = GUICtrlCreateButton( "Stop", 150, 450 )

    $h_tabs = GUICtrlCreateTab( 5, 5, 390,375 )

    ; LOG TAB
    GUICtrlCreateTabItem( "Log" )
    $h_logRichEdit = _GUICtrlRichEdit_Create ( $hGui, "", 8, 30, 384, 347, BitOR( $ES_MULTILINE, $WS_VSCROLL, $ES_AUTOVSCROLL, $ES_READONLY ) )
    _GUICtrlRichEdit_AppendText($h_logRichEdit, "{\rtf {Showing \b1 Rich Text \b0}")

    ; STATS TAB
    GUICtrlCreateTabItem( "Stats" )

    ; Close TABS
    GUICtrlCreateTabItem( "" )

    ; Register Windows message.
    GUIRegisterMsg($WM_NOTIFY, 'WM_NOTIFY')

    GUISetState( @SW_SHOW ) ; initialize the gui

    GuiMessageLoop()
EndFunc

Func GuiMessageLoop()
    While 1
        $iMsg = GUIGetMsg()

        Switch $iMsg
            Case $GUI_EVENT_CLOSE
                _GUICtrlRichEdit_Destroy($h_logRichEdit) ; needed unless script crashes
                ; GUIDelete()   ; is OK too
                Exit

            Case $h_startButton
                Start()

            Case $h_stopButton
                Stop()
        EndSwitch
    WEnd
EndFunc

Func Start()
    ConsoleWrite('# Sleep' & @CRLF)
    Sleep(5000)
    ConsoleWrite('# Awake' & @CRLF)
EndFunc

Func Stop()

EndFunc

Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
    Local $iLoWord = _WinAPI_LoWord($lParam)
    Local $iHiWord = _WinAPI_HiWord($lParam)
    ConsoleWrite('- WM_NOTIFY' & ' ' & $iLoWord & ' ' & $iHiWord & @CRLF)

    Switch GUICtrlRead( $h_tabs )
        Case $H_TAB_1
            ControlShow( $hGui, "", $h_logRichEdit )
        Case Else
            ControlHide( $hGui, "", $h_logRichEdit )
    EndSwitch

    Return $GUI_RUNDEFMSG
EndFunc

试试这个例子。它使用GuiRegisterMessage 来捕获 WM_NOTIFY Windows 消息。 WM_NOTIFY 不理想 消息代码,虽然还没有找到 更适合只换Tabs。

隐藏和显示 Rich Edit 控件的代码已 移动到WM_NOTIFY 函数中,这样每次 收到消息后,执行 Tab 隐藏和显示代码。

ConsoleWrite 用于显示感兴趣的事件 在测试期间正在做。如果您的编辑器有输出 控制台窗格,然后您可能能够查看写入 控制台窗格。

如果函数Start等事件需要很长时间, 那么多处理可能有助于让 Gui 对消息循环保持响应。

想要一个do不要,避免(cyclic)递归函数 调用并避免陷入循环。


其他参考资料:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-10
    • 2011-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多