漫漫开发路|技法:对你的应用添加键盘加速键

对IsDialogMessage的误解
有一个API函数可能经常容易造成误解 , 它就是IsDialogMessage 。 IsDialogMessage将会判断一个消息是否是针对指定对话框的消息 , 如果是的话 , 则会处理这个消息 。 所以 , 我们不能从API名字上简单的将它看作是一个判断函数 , 实际上 , 它的内部实现代码中还会附带一系列的处理流程 。 参数
它的第一个参数是指向一个对话框的窗口句柄 , 第二个参数是指向一个MSG结构的指针 , 这个MSG结构中包含了即将被检查的消息本身 。 返回值
如果MSG结构中的消息被处理 , 则返回非零值 , 如果未被处理 , 则返回零 。 使用方法
尽管IsDialogMessage主要被用来处理非模态对话框 , 但是我们完全可以将它用在任何带有控件的一般窗口里 , 实现类似于对话框的键盘按键处理 。
当IsDialogMessage处理一个消息的时候 , 它会特别检查键盘消息 , 并将它们转换为对话框中对应的选择操作 。 举个例子 , 对于TAB按键 , 当我们按下它的时候 , 我们将会发现下一个控件或者控件组被选中了 , 如果按下的是向下的箭头按键 , 则会选择控件组中的下一个控件 。
因为IsDialogMessage内部会执行所有必要的消息翻译(Translating)和分发(Dispatching) , 所以 , 一个被IsDialogMessage处理过的消息不能再被传递到TranslateMessage和DispatchMessage这两个API函数中 。
IsDialogMessage会向对话框窗口过程发送WM_GETDLGCODE消息来决定哪一个按键需要被处理 。
IsDialogMessage会发送DM_GETDEFID和DM_SETDEFID这两个消息给窗口 。 这两个消息在Winuser.h头文件中分别被定义为WM_USER和WM_USER+1 , 所以 , 如果应用程序使用到了相同的自定义消息值 , 则可能会发生冲突 。 基于这个原因 , 应用程序不应使用这两个消息值作为自定义消息 。
IsDialogMessage虽然为对话框而生(从它的名字也可以看出来) , 但是实际上它可以工作在任何一个窗口上 。 只要窗口的控件启用了WS_TABSTOP或WS_GROUP风格 , 则它们都可以在父窗口里导航 , 就像对话框里的控件一样 。
下面是一个示例代码 , 演示了如何在一个普通窗口(非对话框)中使用Tab按键来切换控件焦点 。
漫漫开发路|技法:对你的应用添加键盘加速键
文章图片
漫漫开发路|技法:对你的应用添加键盘加速键
文章图片
漫漫开发路|技法:对你的应用添加键盘加速键
文章图片
在上面的代码中 , 需要注意一个比较微妙的地方:为了在用户切换到其他窗口并切换回来时保持焦点 , 我们对WM_ACTIVATE和WM_SETFOCUS这两消息进行了处理 。 另外 , 还需要注意的是 , 通过设置第一个按钮的BS_DEFPUSHBUTTON风格 , 我们选择了第一个按钮作为默认按钮 , 在窗口初次显示的时候 , 它将拥有初始焦点 。
我们可以观察到 , 所有对话框里使用的标准键盘加速键都能如预期般的工作 。 包括TAB按键切换输入焦点 , ALT+1和ALT+2在两个按钮之间的切换 , 按下回车键会触发默认按钮的点击以及按下ESC将会触发取消按钮(因为它的ID是IDCANCEL)的点击等 。 总结
【漫漫开发路|技法:对你的应用添加键盘加速键】现代用户主要都会使用鼠标进行日常操作 , 但是添加对键盘按键的处理 , 将会成为你的应用的一个”惊喜的”亮点 , 这将是你开发的应用与别人的应用的一个”差异化”优势 。
漫漫开发路|技法:对你的应用添加键盘加速键
文章图片