|
 
- 帖子
- 415
- 威望
- 75
- 金钱
- 226
- 贡献
- 2317
|
1行
发表于 2011-10-25 21:36
| 只看该作者
一些新人对系统消息比较陌生,实际上,消息是 Windows 发出的一个通知,告诉应用程序某个事情发生了。例如, 单击鼠标、改变窗口尺寸、按下键盘上的一个键都会使Windows发送一个消息给应用程序. 消息本身是作为一个记录传递给应用程序的, 这个记录中包含了消息的类型以及其他相关信息。在 AutoHotkey 中我们可以使用 OnMessage() 捕捉系统消息, 这样可以实现对右击、双击、获取焦点等行为的判断, 从而进行进一步的响应.
本文将探讨如何监视系统消息并根据需要进行处理. 我们先来看看下面这个例子, 这里实现了当编辑控件取得焦点 (可以通过点击鼠标或键盘导航) 时清除提示, 若失去焦点前没有输入新内容则恢复提示.- SetFormat, integer, hex
- WM_COMMAND := 0x111 ; http://msdn.microsoft.com/en-us/library/ms647591.aspx
- TestStr := "请输入测试字符串!"
- Gui, +Border +LastFound +AlwaysOnTop +ToolWindow
- hWin := WinExist()
- Gui, Add, Edit
- Gui, Font, italic s15
- Gui, Add, Edit, vEditVar HwndhEdit, %TestStr%
- Gui, Font, norm
- Gui, Add, Button, Default, 确定
- Gui, Show, AutoSize, 测试 GUI
- OnMessage(WM_COMMAND,"MsgHandler")
- Return
- GuiClose:
- ExitApp
- MsgHandler(wParam, lParam, msg, hwnd)
- {
- global hEdit, TestStr, EditVar
- EN_SETFOCUS := 0x100 ; http://msdn.microsoft.com/en-us/library/bb761685
- EN_KILLFOCUS := 0x200
- ;~ xn := NumGet(wParam, 0, "short")
- ;~ yn := NumGet(wParam, 2, "short")
- Transform, loword, BitAnd, wParam, 0xffff
- Transform, hiword, BitShiftRight, wParam, 16
- if (hEdit <> lParam) ; 发送此通告的不是目标编辑控件
- {
- return
- }
- ControlGetText, EditContent, , ahk_id %hEdit% ; 获取控件现在的内容
- if (EditContent <> "" and EditContent <> TestStr) ; 控件的内容不为空, 说明已经输入了新内容或者为第一次获取焦点前的原始内容.
- {
- return
- }
-
- if (hiword = EN_SETFOCUS) ; 编辑控件获得焦点
- {
- Gui, Font, norm
- GuiControl, Font, EditVar
- GuiControl, , EditVar
- }
- if (hiword = EN_KILLFOCUS) ; 编辑控件失去焦点
- {
- Gui, Font, italic
- GuiControl, Font, EditVar
- GuiControl, , EditVar, %TestStr%
- }
- return, 0
- }
复制代码 这里是赋值我们需要监视的系统消息, 与许多高级语言可以通过加载头文件从而包含常量值 WM_COMMAND 不同, 在 AutoHotkey 中并没有, 所以要使用消息前需要先赋值 (或者直接在后面使用相应的数值).- OnMessage(WM_COMMAND,"MsgHandler")
复制代码 监视 WM_COMMAND 消息, 接收到后使用 MsgHandler() 函数处理. 如果我们这里没有监视系统消息, 那么应用程序接收到消息后会进行默认的处理. 除了 WM_COMMAND, 还有许多其他的消息, 例如 WM_NOTIFY, 更多的请参阅帮助中 "Windows 消息列表" 页面.- MsgHandler(wParam, lParam, msg, hwnd){}
复制代码 这个是消息处理函数, 四个参数的值都是数字, 这里简要说明它们的含义:
wParam: 消息的首个参数, 表示的含义与具体的系统消息有关.
lParam: 消息的第二个参数, 表示的含义与具体的系统消息有关.
msg: 接收到的消息号, 如果我们使用一个函数监视多种系统消息例如 WM_COMMAND 和 WM_NOTIFY, 在函数中可以根据这个判断接收到的是哪种消息.
hwnd: 接收到消息的窗口句柄, 当我们写的脚本中含有多个窗口时可以根据此参数判断接收到消息的是哪个窗口.- EN_SETFOCUS := 0x100
- EN_KILLFOCUS := 0x200
复制代码 赋值控件定义的通告码, 这些通告码包含在消息的参数中, 我们需要分解参数判断控件发生了什么.- Transform, loword, BitAnd, wParam, 0xffff
- Transform, hiword, BitShiftRight, wParam, 16
复制代码 在这个例子中, 我们监视的是目标编辑控件取得和失去焦点时的系统消息, 根据 MSDN 中 WM_COMMAND 消息页面可以看到, wParam 中的低字表示控件标识符, 高字表示控件定义的通告码, lParam 表示发送此消息的控件句柄. 这里摘取 MSDN 中 EN_SETFOCUS notification code 页面的关于 wParam 描述部分:wParam
The LOWORD contains the identifier of the edit control. The HIWORD specifies the notification code. 所以, 这个例子中如果完整的判断时 (例如在含有多窗口的脚本中使用一个函数监视多种系统消息时), 首先根据 hwnd 判断是否是我们需要监视的目标窗口, 使用 msg 知道接收到的消息号, 使用 lParam 判断发送消息的控件, 然后检查 wParam 中的高字, 如果高字的内容为 EN_SETFOCUS, 说明目标编辑控件取得了焦点. 这里有两个地方要小心, 一是从 wParam 中分离高字和低字时使用 NumGet() 得到的结果是错误的, 二是应该使用 lParam 判断发送消息的控件而不用 wParam 中的低字, 因为控件标识符不是唯一的. (在函数中还可以使用 AutoHotkey 的一些内置变量进行辅助判断, 例如 A_Gui 等)
这里还有一个例子: 请问怎样实现点击Edit框那些字就消失的效果?
|

适用环境: 如果未特别指明, 默认环境为 AutoHotkey_L 1.1.00.00+ Unicode 在 WinXP SP3 系统上, 脚本编码 UTF-8 with BOM
如果提到 AutoHotkey Basic, 默认指 1.0.48.05 版本.
适用版权: 如果未特别指明, 我所发布的代码都使用CC0 1.0许可, 包括但不限于AutoHotkey 中文论坛中的部分. 建议在发到其他地方时加上我的发布链接, 因为我会不时地进行补充/完善. 此外, 对于转载内容的适用许可, 请到原网址了解详情. |
|