返回介绍

GUI Reference - MessageLoop Mode

发布于 2020-03-05 18:21:26 字数 4311 浏览 1138 评论 0 收藏 0

在消息循环模式下,脚本大部分时间都在执行一个周期非常短的循环,这个循环通知GUI使用 GUIGetMsg (截获消息)函数。当某个事件发生时 GUIGetMsg 函数把消息作为返回数值返回(比如某个按钮被按下、GUI被关闭,等等)。

这一模式最适合用于那些以 GUI 为重点的脚本中,并且您最关心的就是等待用户事件。

消息循环模式是AutoIt GUI 默认的模式。另外还有一种模式是 OnEvent 模式。

在此模式下,只有当我们频繁地使用 GUIGetMsg 函数时才有可能接收到事件,因此您必须确保在每一秒内都有数次调用该函数,否则您的 GUI 将无法响应事件。

基本的 消息循环 结构

下面是 消息循环 的基本结构:

While 1
$msg = GUIGetMsg() ; 截获消息
... ; 处理消息
...
WEnd

像上面这种循环周期非常短的脚本通常会把CPU占用推到高达 100%,幸运的是 GUIGetMsg 函数可在无事件等待时自动闲置CPU。另外千万 不要 因为怕增加CPU压力而自己添加休眠语句(Sleep)到脚本中,这么做只会让GUI响应迟钝。

GUI 事件

GUIGetMsg 返回的事件消息有以下三种:

  • 无事件
  • 控件事件
  • 系统事件
  • 无事件

    没有截获任何事件时 GUIGetMsg 的返回值为 0。这也是 最常发生的事件

    控件事件

    当某个控件被点击或该控件有其它变化时将发送控件事件。这些事件代码都是正数并且关联发送事件消息的 控件ID(也即使用 GUICtrlCreate... 函数创建该控件时的返回值)。

    系统事件

    系统事件包括GUI(窗口)被关闭等在内,它们的值都是 负数。下面列出了各种系统事件(在 GUIConstants.au3 中有定义):

    $GUI_EVENT_CLOSE
    $GUI_EVENT_MINIMIZE
    $GUI_EVENT_RESTORE
    $GUI_EVENT_MAXIMIZE
    $GUI_EVENT_PRIMARYDOWN
    $GUI_EVENT_PRIMARYUP
    $GUI_EVENT_SECONDARYDOWN
    $GUI_EVENT_SECONDARYUP
    $GUI_EVENT_MOUSEMOVE

    GUI 示例

    GUI 相关 的页面上我们曾编写过一个简单的窗口:

    #include <GUIConstants.au3>

    GUICreate("您好", 200, 100)
    GUICtrlCreateLabel("最近过得怎样?", 30, 10)
    GUICtrlCreateButton("还OK吧", 70, 50, 60)
    GUISetState(@SW_SHOW)
    Sleep(2000)

    现在我们来尝试使用 消息循环 以及上面描述的事件消息来完成全部代码。为了脚本的可读性考虑我们使用条件选择语句。

    #include <GUIConstants.au3>

    GUICreate("您好", 200, 100)
    GUICtrlCreateLabel("最近过得怎样?", 30, 10)
    $okbutton = GUICtrlCreateButton("还OK吧", 70, 50, 60)
    GUISetState(@SW_SHOW)

    While 1
    $msg = GUIGetMsg()

    Select
    Case $msg = $okbutton
    MsgBox(0, "GUI 事件", "您按下了“还OK吧”按钮!")

    Case $msg = $GUI_EVENT_CLOSE
    MsgBox(0, "GUI 事件", "您选择了关闭!正在退出...")
    ExitLoop
    EndSelect
    WEnd

    很简单,对吧?很明显创建的窗口及控件越多则脚本越复杂,但基本结构都是类似上面的这个示例。

    高级操作及多窗口

    即使有很多窗口存在,控件 ID 也是唯一的,因此上面的脚本可以正常工作。但是在处理如 $GUI_EVENT_CLOSE 或 $GUI_MOUSEMOVE 等消息时您还必须知道究竟是哪个窗口引发的事件。为了解决这个问题,您可以参考下面这个语句来调用 GUIGetMsg 函数:

    $msg = GUIGetMsg(1)

    在函数 GUIGetMsg 中指定1作为参数调用时它将返回一个数组。这个数组不仅包括被截获的事件(保存在$array[0]中),还包括其它信息如窗口句柄等(保存在$array[1]中)。假设我们要创建两个窗口,则相应的脚本代码如下:

    #include <GUIConstants.au3>

    $mainwindow = GUICreate("您好", 200, 100)
    GUICtrlCreateLabel("最近过得怎样?", 30, 10)
    $okbutton = GUICtrlCreateButton("还OK吧", 70, 50, 60)

    $dummywindow = GUICreate(" 这只是测试用的虚设窗口,并不会被显示 ", 200, 100)

    GUISwitch($mainwindow)
    GUISetState(@SW_SHOW)

    While 1
    $msg = GUIGetMsg(1)

    Select
    Case $msg[0] = $okbutton ; 注意这里的$msg[0]和后面的$msg[1]
    MsgBox(0, "GUI 事件", "您按下了“还OK吧”按钮!")

    Case $msg[0] = $GUI_EVENT_CLOSE And $msg[1] = $mainwindow
    MsgBox(0, "GUI 事件", "您选择了关闭主窗口!正在退出...")
    ExitLoop
    EndSelect
    WEnd

    第一个需要注意的变动是上面的脚本增加了一个 GUISwitch 函数的调用,当新的窗口被创建之后该窗口即变成后面所有GUI操作(包括创建控件在内)的“默认”窗口,也就是说这些GUI操作的对象都会是这个默认窗口。但我们希望显示的是主窗口(首先被创建的窗口)而不是那个测试窗口,这时就要使用 GUISwitch 函数来切换操作对象。某些GUI函数允许您在调用它们时使用窗口句柄(参数)来指定操作目标,同时也将自动切换该目标窗口为“默认窗口”。所以在这个示例中,我们还可以改用这样的语句:

    GUISetState(@SW_SHOW, $mainwindow)

    另外要注意的就是 GUIGetMsg 函数的用法以及事件是如何被截获并处理的,注意 $msg[0] 和 $msg[1] 的用法,现在我们就可以确保在窗口的关闭按钮被点击 而且 消息是从主窗口发送的时候才退出GUI了。

    如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

    扫码二维码加入Web技术交流群

    发布评论

    需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
    列表为空,暂无数据
      我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
      原文