基于对话框的程序的全局按键设置的注意事项

  • 最近在写一个后台小程序,需要在焦点在其他窗口的时候也能够响应,因此就想到了为这个小程序注册全局的按键。其实一开始想用全局钩子来实现的,但是微软官方的编程文档上指出全局钩子会严重消耗系统资源,而且全局钩子的设置还是稍微麻烦一些的,因此杀鸡焉用牛刀,单单实现一个全局热键就不用全局钩子了,如果想看全局钩子如何实现全局热键,可以参考微软官方的文档,地址在下面:

https://docs.microsoft.com/zh-cn/windows/win32/winmsg/hooks

  • 然后呢我就打算用MFC中的RegisterHotKey来实现,但是我发现RegisterHotKey函数还是充满坑的,因此特意记录一下,当然关于如何使用RegisterHotKey函数来设置按键我就不提了,可以自行查阅微软官方文档,也很简单。
  • 首先,当你使用RegisterHotKey设置了一对组合键之后,你在系统任何位置按下这对组合键应该就会产生WM_HOTKEY消息才对,但是事实上一开始我怎么调试都没有收到WM_HOTKEY消息,我一直在网上查了很久,微软官方的文档页反复看了很多次才发现问题。
  • 问题有两个,第一个在于WM_HOTKEY消息在基于对话框程序中的传递机制问题,具体是什么原因我有点忘了,反正WM_HOTKEY消息并不会被转发。解决这个问题需要修改代码,重载对话框类PreTranslateMessage()函数,比如下面是我写的代码
BOOL CGujianOLDlg::PreTranslateMessage(MSG* pMsg)
{
	// TODO: 在此添加专用代码和/或调用基类
	if(pMsg->message==WM_HOTKEY){
		OnHotKey(pMsg->wParam,pMsg->lParam);
	}
	return CDialogEx::PreTranslateMessage(pMsg);
}
  • 需要在原来的return之前拦截WM_HOTKEY消息自己处理,还有需要注意的是自己拦截处理之后就可以不用使用ON_MESSAGE宏进行消息路由了,不然消息处理函数可能会被调用两次。
  • 第二个问题在于我使用了CHotKeyCtrl,就是热键输入的控件,因为我想要用户可以自定义快捷键。HotKey控件可以很方便的获取用户输入的快捷键,在用户输入之后,我们可以使用GetHotKey()方法来获取用户输入了什么组合键,但是这个GetHotKey()非常坑的是他获取到的值并不能直接传递给RegisterHotKey()来进行注册,原因是微软的文档中写了

Note that the shift state flags used in the call to RegisterHotKey are not the same as those returned by the GetHotKey member function; you'll have to translate these flags before calling RegisterHotKey.

  •  意思就是GetHotKey()方法获取到的辅助键的标志位与RegisterHotKey所用的标志位不一样,你自己必须得写个函数来处理一下,我看到的是不一样的就是他们两个的shift和alt键的标志位恰好是反的,在使用GetHotKey获取到用户的输入之后自己转换之下再交给RegisterHotKey注册就行了。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值