anythinging 发表于 2022-2-8 22:49:14

【已解决】点击菜单后程序会停止运行(while与计时器的调用)

本帖最后由 anythinging 于 2022-2-10 10:34 编辑

遇到个小问题,当打开菜单后,程序会暂停,类似于msgbox的中断效果,想请教在点击打开菜单时,是否可以让程序继续运行?
借用帮助中的例子,加了一个更新数字

#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <StaticConstants.au3>


Global $i = 0
Example()

Func Example()
    GUICreate("菜单项目控件 GUI", 300, 200)

    Local $sStatus = "准备就绪"

    Local $idFileMenu = GUICtrlCreateMenu("文件 &F")
    Local $idFileItem = GUICtrlCreateMenuItem("打开", $idFileMenu)
    GUICtrlSetState(-1, $GUI_DEFBUTTON)
    Local $idHelpMenu = GUICtrlCreateMenu("?")
    GUICtrlCreateMenuItem("保存", $idFileMenu)
    GUICtrlSetState(-1, $GUI_DISABLE)
    Local $idInfoItem = GUICtrlCreateMenuItem("信息", $idHelpMenu)
    Local $idExit = GUICtrlCreateMenuItem("退出", $idFileMenu)
    Local $idRecentFilesMenu = GUICtrlCreateMenu("最近的文件", $idFileMenu, 1)

    GUICtrlCreateMenuItem("", $idFileMenu, 2) ; 创建分隔线

    Local $idViewMenu = GUICtrlCreateMenu("查看", -1, 1) ; 创建在 "?" 之前的菜单
    Local $idViewStatusItem = GUICtrlCreateMenuItem("状态栏", $idViewMenu)
    GUICtrlSetState(-1, $GUI_CHECKED)

      $text = GUICtrlCreateLabel('0',20,50,50,10)

      GUICtrlCreateButton("确定", 50, 130, 70, 20)
    GUICtrlSetState(-1, $GUI_FOCUS)
    Local $idCancel = GUICtrlCreateButton("取消", 180, 130, 70, 20)

    Local $idStatusLabel = GUICtrlCreateLabel($sStatus, 0, 165, 300, 16, BitOR($SS_SIMPLE, $SS_SUNKEN))

    GUISetState(@SW_SHOW)

    Local $sFilePath
    ; 循环到用户退出.
    While 1
      Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE, $idCancel, $idExit
                Exit

            Case $idInfoItem
                MsgBox($MB_SYSTEMMODAL, "信息", "只是一个测试...")

            Case $idFileItem
                $sFilePath = FileOpenDialog("选择一个文件...", @TempDir, "所有文件 (*.*)")
                If @error Then
                  ContinueLoop
                EndIf
                GUICtrlCreateMenuItem($sFilePath, $idRecentFilesMenu)

            Case $idViewStatusItem
                If BitAND(GUICtrlRead($idViewStatusItem), $GUI_CHECKED) = $GUI_CHECKED Then
                  GUICtrlSetState($idViewStatusItem, $GUI_UNCHECKED)
                  GUICtrlSetState($idStatusLabel, $GUI_HIDE)
                Else
                  GUICtrlSetState($idViewStatusItem, $GUI_CHECKED)
                  GUICtrlSetState($idStatusLabel, $GUI_SHOW)
                EndIf
      EndSwitch
      $i += 1
      GUICtrlSetData($text,$i)
      Sleep(500)
    WEnd
EndFunc   ;==>Example


anythinging 发表于 2022-2-10 10:32:21

感谢A版指点,将While与多个定时器代码最终整理如下,有需要的朋友可以拿去参考:
#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <StaticConstants.au3>
#include <Timers.au3>


Global $i = 0,$ii = 0,$ix = 0
Global $text1,$text2,$text3
Example()

Func Example()
    $hGUI = GUICreate("下拉菜单导致While中断", 300, 200)

    Local $idViewMenu = GUICtrlCreateMenu("查看", -1, 1)
    Local $idViewStatusItem = GUICtrlCreateMenuItem("状态栏", $idViewMenu)

        GUICtrlCreateLabel('While',20,50)
        $text1 = GUICtrlCreateLabel('0',120,50,50,10)
        GUICtrlCreateLabel('计时器1',20,70)
        $text2 = GUICtrlCreateLabel('0',120,70,50,10)
        GUICtrlCreateLabel('计时器2',20,90)
        $text3 = GUICtrlCreateLabel('0',120,90,50,10)

    GUISetState(@SW_SHOW)

        $start1 = GUICtrlCreateButton('启动计时器1',20,120,100,20)
        $kill1 = GUICtrlCreateButton('停止计时器1',120,120,100,20)
        $start2 = GUICtrlCreateButton('启动计时器2',20,140,100,20)
        $kill2 = GUICtrlCreateButton('停止计时器2',120,140,100,20)


        $iIDtimer1 = _Timer_SetTimer($hGUI, 500, "_Time1") ; 创建计时器1
        $iIDtimer2 = _Timer_SetTimer($hGUI, 500, "_Time2") ; 创建计时器2


        ;AdlibRegister('time',1000)

    While 1
      Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                Exit
                        Case $start1
                                $ii = 0
                                _Timer_KillTimer($hGUI, $iIDtimer1)
                                $iIDtimer1 = _Timer_SetTimer($hGUI, 1000, "_Time1") ; 创建计时器
                               
                        Case $kill1
                                _Timer_KillTimer($hGUI, $iIDtimer1)

                        Case $start2
                                $ix = 0
                                _Timer_KillTimer($hGUI, $iIDtimer2)
                                $iIDtimer2 = _Timer_SetTimer($hGUI, 1000, "_Time2") ; 创建计时器
                               
                        Case $kill2
                                _Timer_KillTimer($hGUI, $iIDtimer2)


                EndSwitch

                $i += 1
                GUICtrlSetData($text1,$i)


                Sleep(50)
    WEnd
EndFunc   ;==>Example

Func time()
                $ii += 0.5
                GUICtrlSetData($text2,$ii)
EndFunc

Func _Time1($hWnd, $iMsg, $iIDTimer, $iTime)
    #forceref $hWnd, $iMsg, $iIDTimer, $iTime

        $ii += 0.5
        GUICtrlSetData($text2,$ii)

EndFunc

Func _Time2($hWnd, $iMsg, $iIDTimer, $iTime)
    #forceref $hWnd, $iMsg, $iIDTimer, $iTime
        $ix += 0.2
        GUICtrlSetData($text3,$ix)

EndFunc

afan 发表于 2022-2-9 21:10:21

anythinging 发表于 2022-2-9 19:51
感谢指点!

之前看帮助文档的时个确实看到了有第四个参数,但当时加了后计时器不能工作。


$iIDtimer1 = _Timer_SetTimer($hGUI, 1000, "_Time1")
计算器创建成功后,返回新计时器的整数标识,就是$iIDtimer1,是否就是之后要用到的第四个参数?
是的,初始已经创建成功了,之后可以直接代入使用,如:$iIDtimer1 = _Timer_SetTimer($hGUI, 1000, "_Time1", $iIDtimer1)
随意指定当然不行,该ID必须已存在

afan 发表于 2022-2-9 13:30:00

anythinging 发表于 2022-2-9 11:34
还是没明白,能否进一步指点?
情况是点击菜单查看出现‘状态’下拉菜单后,while中语句,和AdlibRegist ...

_Timer_SetTimer

afan 发表于 2022-2-8 23:08:20

轻量级的任务可用定时器,不会中断。非轻量可多进程

anythinging 发表于 2022-2-9 11:34:36

afan 发表于 2022-2-8 23:08
轻量级的任务可用定时器,不会中断。非轻量可多进程

还是没明白,能否进一步指点?
情况是点击菜单查看出现‘状态’下拉菜单后,while中语句,和AdlibRegister中的都会停止运行。

#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <StaticConstants.au3>


Global $i = 0,$ii = 0
Global $text,$text2
Example()

Func Example()
    GUICreate("出现下拉菜单程序停止运行", 300, 200)

    Local $idViewMenu = GUICtrlCreateMenu("查看", -1, 1)
    Local $idViewStatusItem = GUICtrlCreateMenuItem("状态栏", $idViewMenu)

        $text = GUICtrlCreateLabel('0',20,50,50,10)
        $text2 = GUICtrlCreateLabel('0',20,70,50,10)

    GUISetState(@SW_SHOW)

        AdlibRegister('time',1000)

    While 1
      Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                Exit
      EndSwitch

                $i += 1
                GUICtrlSetData($text,$i)
                Sleep(50)
    WEnd
EndFunc   ;==>Example

Func time()
                $ii += 0.5
                GUICtrlSetData($text2,$ii)
EndFunc

anythinging 发表于 2022-2-9 15:22:05

本帖最后由 anythinging 于 2022-2-9 15:51 编辑

afan 发表于 2022-2-9 13:30
_Timer_SetTimer
感谢a版指点,已解决。附正常运行代码供各位朋友参考


#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <StaticConstants.au3>
#include <Timers.au3>


Global $i = 0,$ii = 0,$ix = 0
Global $text1,$text2,$text3
Example()

Func Example()
    $hGUI = GUICreate("下拉菜单导致While中断", 300, 200)

    Local $idViewMenu = GUICtrlCreateMenu("查看", -1, 1)
    Local $idViewStatusItem = GUICtrlCreateMenuItem("状态栏", $idViewMenu)

      GUICtrlCreateLabel('While',20,50)
      $text1 = GUICtrlCreateLabel('0',120,50,50,10)
      GUICtrlCreateLabel('计时器1',20,70)
      $text2 = GUICtrlCreateLabel('0',120,70,50,10)
      GUICtrlCreateLabel('计时器2',20,90)
      $text3 = GUICtrlCreateLabel('0',120,90,50,10)

    GUISetState(@SW_SHOW)

      $start1 = GUICtrlCreateButton('启动计时器1',20,120,100,20)
      $kill1 = GUICtrlCreateButton('停止计时器1',120,120,100,20)
      $start2 = GUICtrlCreateButton('启动计时器2',20,140,100,20)
      $kill2 = GUICtrlCreateButton('停止计时器2',120,140,100,20)


      $iIDtimer1 = _Timer_SetTimer($hGUI, 500, "_Time1") ; 创建计时器1
      $iIDtimer2 = _Timer_SetTimer($hGUI, 500, "_Time2") ; 创建计时器2


      ;AdlibRegister('time',1000)

    While 1
      Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                Exit
                        Case $start1
                              $iIDtimer1 = _Timer_SetTimer($hGUI, 1000, "_Time1") ; 创建计时器
                        Case $kill1
                              _Timer_KillTimer($hGUI, $iIDtimer1)

                        Case $start2
                              $iIDtimer2 = _Timer_SetTimer($hGUI, 1000, "_Time2") ; 创建计时器
                        Case $kill2
                              _Timer_KillTimer($hGUI, $iIDtimer2)


                EndSwitch

                $i += 1
                GUICtrlSetData($text1,$i)


                Sleep(50)
    WEnd
EndFunc   ;==>Example

Func time()
                $ii += 0.5
                GUICtrlSetData($text2,$ii)
EndFunc

Func _Time1($hWnd, $iMsg, $iIDTimer, $iTime)
    #forceref $hWnd, $iMsg, $iIDTimer, $iTime

      $ii += 0.5
      GUICtrlSetData($text2,$ii)

EndFunc   ;==>_UpdateStatusBarClock

Func _Time2($hWnd, $iMsg, $iIDTimer, $iTime)
    #forceref $hWnd, $iMsg, $iIDTimer, $iTime
      $ix += 0.2
      GUICtrlSetData($text3,$ix)

EndFunc   ;==>_UpdateStatusBarClock


另外还请a版帮看下对2个计时器操作:分别开始、停止2个计时器的方法是否正确?
我打算把tcp接收发送(约200多个客户端配置信息、在线时间统计,服务端发送控制命令等)的代码通过计时器的方式运行,不知是否可以?




afan 发表于 2022-2-9 16:00:51

anythinging 发表于 2022-2-9 15:22
感谢a版指点,已解决。附正常运行代码供各位朋友参考




                        Case $start1
                              $iIDtimer1 = _Timer_SetTimer($hGUI, 1000, "_Time1") ; 创建计时器
以上示例代码若持续点击会持续创建新的定时器,这样停止将会失效,因此,创建前应先 _Timer_KillTimer($hGUI, $iIDtimer1),或使用_Timer_SetTimer的第4个参数更替。

上面说了,轻量级的任务可用定时器,其它用多进程,可根据实际需求自行选择。

anythinging 发表于 2022-2-9 19:51:24

本帖最后由 anythinging 于 2022-2-9 19:54 编辑

afan 发表于 2022-2-9 16:00
Case $start1
                              $iIDtimer1 = _Timer_SetTimer ...
感谢指点!

之前看帮助文档的时个确实看到了有第四个参数,但当时加了后计时器不能工作。


您说的第四个参数,不知我理解的对不?:

$iIDtimer1 = _Timer_SetTimer($hGUI, 1000, "_Time1")
计算器创建成功后,返回新计时器的整数标识,就是$iIDtimer1,是否就是之后要用到的第四个参数?

另外我发现,好象创建计时器时,如随意指定第四个参数(如1234567),则计时器无法调用设置的函数,不知原因?(是否可以理解为第四个参数$iTimerID,必需是已存在的?)
页: [1]
查看完整版本: 【已解决】点击菜单后程序会停止运行(while与计时器的调用)