找回密码
 加入
搜索
查看: 3967|回复: 3

[AU3基础] 关于如何“中止”一个循环?的一些个人看法

[复制链接]
发表于 2014-12-30 13:33:01 | 显示全部楼层 |阅读模式
大家都知道autoit是单线程,不管是消息模式还是事件模式,同一时间它只能进行一项操作.当脚本执行一个包含长时间循环的函数时,此时按其它按钮是不会响应的.详见http://www.autoitx.com/forum.php ... hlight=%D6%D0%D6%B9

有人已提出了思路,加入一个中止的flag,在循环体中检测这个flag,当满足条件,即退出循环,那么,问题来了,如何正确及时的设置这个flag,成为问题所在.

经过测试,注册系统消息wm_command是可行的
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <ProgressConstants.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>
$flag = False
$Form1 = GUICreate("Form1", 487, 98)
$Progress1 = GUICtrlCreateProgress(8, 72, 465, 17)
GUICtrlSetData(-1, 0)
$Button1 = GUICtrlCreateButton("开始", 48, 16, 105, 33)
$Button2 = GUICtrlCreateButton("中止", 168, 16, 105, 33)
GUICtrlSetState(-1, $gui_disable)
$Button3 = GUICtrlCreateButton("退出", 288, 16, 97, 33)
GUISetState(@SW_SHOW)
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
                Case $GUI_EVENT_CLOSE
                        Exit
                Case $Button1
                        gogo()
                Case $Button2
                        $flag = True
                Case $Button3
                        Exit
        EndSwitch
WEnd

Func gogo()
        $flag = False
        GUICtrlSetState($Button1, $gui_disable)
        GUICtrlSetState($Button2, $gui_enable)
        GUICtrlSetState($Button3, $gui_disable)
        GUICtrlSetData($Progress1, 0)
        Local $i, $j = 30
        For $i = 1 To $j
                        ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $flag = ' & $flag & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
                If $flag Then
                        GUICtrlSetState($Button1, $gui_enable)
                        GUICtrlSetState($Button2, $gui_disable)
                        GUICtrlSetState($Button3, $gui_enable)
                        Return SetError(1, 0, 0)
                EndIf
                GUICtrlSetData($Progress1, $i * 100 / $j)
                Sleep(200)
                ; 这里要加什么命令才能中止循环, 并得到当前的 $i
                ; MsgBox(0,"操作被中止","操作被中止, 最后的 $i 是:" & $i)
        Next
        GUICtrlSetState($Button1, $gui_enable)
        GUICtrlSetState($Button2, $gui_disable)
        GUICtrlSetState($Button3, $gui_enable)
EndFunc   ;==>gogo

Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
        Local $wID = _WinAPI_LoWord($iwParam)
        Local $iIDFrom = BitAND($iwParam, 0xFFFF)
        Local $iCode = BitShift($iwParam, 16)
        Switch $wID
                Case $Button2
                        $flag = True
        EndSwitch
EndFunc   ;==>WM_COMMAND
发表于 2014-12-30 13:46:39 | 显示全部楼层
回复 1# tubaba

试试:
    47 行 If $flag = True Then MsgBox(0,"操作被中止","操作被中止, 最后的 $i 是:" & $i)
 楼主| 发表于 2014-12-30 14:23:14 | 显示全部楼层
本帖最后由 tubaba 于 2014-12-30 14:24 编辑

回复 2# 131738


    好吧,被你吓到了,重贴,只是提供思路,试试下面的
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <ProgressConstants.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>
$flag = False
$Form1 = GUICreate("Form1", 487, 98)
$Progress1 = GUICtrlCreateProgress(8, 72, 465, 17)
GUICtrlSetData(-1, 0)
$Button1 = GUICtrlCreateButton("开始", 48, 16, 105, 33)
$Button2 = GUICtrlCreateButton("中止", 168, 16, 105, 33)
GUICtrlSetState(-1, $gui_disable)
$Button3 = GUICtrlCreateButton("退出", 288, 16, 97, 33)
GUISetState(@SW_SHOW)
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
                Case $GUI_EVENT_CLOSE
                        Exit
                Case $Button1
                        gogo()
                Case $Button2
                        $flag = True
                Case $Button3
                        Exit
        EndSwitch
WEnd

Func gogo()
        $flag = False
        GUICtrlSetState($Button1, $gui_disable)
        GUICtrlSetState($Button2, $gui_enable)
        GUICtrlSetState($Button3, $gui_disable)
        GUICtrlSetData($Progress1, 0)
        Local $i, $j = 30
        For $i = 1 To $j
                 If $flag Then
                        GUICtrlSetState($Button1, $gui_enable)
                        GUICtrlSetState($Button2, $gui_disable)
                        GUICtrlSetState($Button3, $gui_enable)
                                                MsgBox(0,"操作被中止","操作被中止, 最后的 $i 是:" & $i)
                        Return SetError(1, 0, $i)
                EndIf
                GUICtrlSetData($Progress1, $i * 100 / $j)
                Sleep(200)
                ; 这里要加什么命令才能中止循环, 并得到当前的 $i
                ; MsgBox(0,"操作被中止","操作被中止, 最后的 $i 是:" & $i)
        Next
        GUICtrlSetState($Button1, $gui_enable)
        GUICtrlSetState($Button2, $gui_disable)
        GUICtrlSetState($Button3, $gui_enable)
EndFunc   ;==>gogo

Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
        Local $wID = _WinAPI_LoWord($iwParam)
        Local $iIDFrom = BitAND($iwParam, 0xFFFF)
        Local $iCode = BitShift($iwParam, 16)
        Switch $wID
                Case $Button2
                        $flag = True
        EndSwitch
EndFunc   ;==>WM_COMMAND
发表于 2014-12-30 14:57:33 | 显示全部楼层
本帖最后由 131738 于 2014-12-30 15:00 编辑

回复 3# tubaba
不懂................你什么意思................算我没说.................
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-5-17 14:07 , Processed in 0.091483 second(s), 24 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表