hnfeng 发表于 2014-11-7 10:04:47

[已解决] 如何“中止”一个循环?

本帖最后由 hnfeng 于 2014-11-7 14:22 编辑

当进行一个比较耗时的操作时,如何能中止这个操作呢?请教高手,谢谢

#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <ProgressConstants.au3>
#include <WindowsConstants.au3>

$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)

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

Func gogo()
        GUICtrlSetState($Button1, $gui_disable)
        GUICtrlSetState($Button2, $gui_enable)
        GUICtrlSetState($Button3, $gui_disable)
        GUICtrlSetData($Progress1, 0)
        Local $i, $j=30
        For $i = 1 To $j
                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

austere 发表于 2014-11-7 11:28:58

回复 1# hnfeng


    这个问题也要问啊....

hnfeng 发表于 2014-11-7 11:30:46

回复 2# austere


    对于高手也许很简单。能否指点一下呢?谢谢

seniors 发表于 2014-11-7 11:56:06

; 这里要加什么命令才能中止循环, 并得到当前的 $i
; MsgBox(0,"操作被中止","操作被中止, 最后的 $i 是:" & $i)
加一个全局变量$stop
if $stop then
MsgBox(0,"操作被中止","操作被中止, 最后的 $i 是:" & $i)
$stop = false
exitloop
endif

中止按钮的操作是 $stop=true

hnfeng 发表于 2014-11-7 12:14:57

回复 4# seniors


    这样应该不行吧?
因为点击了“开始”以后,就进入了 for循环,此时“中止”按钮是不会响应点击的,直到循环结束。

131738 发表于 2014-11-7 13:01:29

4 楼应该正解, 在 While 1 循环中添加 $Button2 的点击操作函数, 然后....

austere 发表于 2014-11-7 13:08:24

回复 5# hnfeng


    你的意思是进入了for循环, while 就不起作用了?   for是满足了条件就结束的,while 1 你不结束,他会一直循环的~~

hnfeng 发表于 2014-11-7 13:17:43

回复 4# seniors


这样改了还是不行,请指教是哪里的问题,谢谢了:#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <ProgressConstants.au3>
#include <WindowsConstants.au3>

$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)
Global $stop ;加了全局函数
GUISetState(@SW_SHOW)

While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
                Case $GUI_EVENT_CLOSE
                        Exit
                Case $Button1
                        gogo()
                Case $Button2
                        $stop = True ;加了点击后变量赋值
                Case $Button3
                        Exit
        EndSwitch
WEnd

Func gogo()
        GUICtrlSetState($Button1, $gui_disable)
        GUICtrlSetState($Button2, $gui_enable)
        GUICtrlSetState($Button3, $gui_disable)
        GUICtrlSetData($Progress1, 0)
        Local $i, $j = 30
        For $i = 1 To $j
                GUICtrlSetData($Progress1, $i * 100 / $j)
                Sleep(200)
                If $stop Then
                        MsgBox(0, "操作被中止", "操作被中止, 最后的 $i 是:" & $i)
                        $stop = False
                        ExitLoop
                EndIf
        Next
        GUICtrlSetState($Button1, $gui_enable)
        GUICtrlSetState($Button2, $gui_disable)
        GUICtrlSetState($Button3, $gui_enable)
EndFunc   ;==>gogo

veket_linux 发表于 2014-11-7 13:17:55

这个是要玩线程的节奏         去找人写dll吧

hnfeng 发表于 2014-11-7 13:19:20

回复 6# 131738


    麻烦看看8楼代码的问题,谢谢了

131738 发表于 2014-11-7 13:28:29

回复 10# hnfeng

GUICtrlCreateProgress() 函数示例脚本就有暂停(中止)功能,不妨看看

hnfeng 发表于 2014-11-7 13:31:38

回复 9# veket_linux


我开始猜想可能要用到AdlibRegister 或者“事件”模式(我一点不懂这个)或其他技术了,看了前面几位的回复感觉解决起来要简单一些,看了你的回复又感觉好难的样子

131738 发表于 2014-11-7 13:56:12

回复 12# hnfeng

刚才看了天空 S 的回复,明白了你脚本结构不符你的要求, au3 是单线程,
第 22 行后, 脚本被 gogo 函数独占了, While 停止循环, 因此无法监视到 $Button2 的点击...
而 GUICtrlCreateProgress() 函数示例脚本的进度是在 Do (While) 循环中,没有独立另外的函数...

用 AdlibRegister() 我也不知是否可行...., 修改 GUICtrlCreateProgress() 函数示例脚本不会很难吧...

131738 发表于 2014-11-7 13:58:15

9 楼的回复视乎有道理.....

hnfeng 发表于 2014-11-7 14:12:14

本帖最后由 hnfeng 于 2014-11-7 14:23 编辑

回复 13# 131738


在您的提醒下,在 GUICtrlCreateProgress() 函数示例脚本中找到办法,搞掂了。
谢谢上面有心帮忙的朋友。
代码公布一下, 以备需要的网友使用:#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <ProgressConstants.au3>
#include <WindowsConstants.au3>

$Form1 = GUICreate("Form1", 487, 98)
$Progress1 = GUICtrlCreateProgress(8, 72, 465, 17)
GUICtrlSetData(-1, 0)
$Button1 = GUICtrlCreateButton("开始", 48, 16, 105, 33)
$Button3 = GUICtrlCreateButton("退出", 288, 16, 97, 33)
GUISetState(@SW_SHOW)

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

Func gogo()
        GUICtrlSetData($Button1, "中止")
        GUICtrlSetState($Button3, $gui_disable)
        GUICtrlSetData($Progress1, 0)
        Local $i, $j = 30
        For $i = 1 To $j
                GUICtrlSetData($Progress1, $i * 100 / $j)
                Sleep(200)
                $idM = GUIGetMsg()
                If $idM = $Button1 Then
                        MsgBox(0, "操作被中止", "操作被中止, 最后的 $i 是:" & $i)
                        GUICtrlSetData($Button1, "开始")
                        ExitLoop
                EndIf
        Next
        GUICtrlSetState($Button3, $gui_enable)
EndFunc   ;==>gogo
页: [1] 2
查看完整版本: [已解决] 如何“中止”一个循环?