如何动态添加删除热键(hotkey)

maomao85 2014-05-09 03:03:02
最新我需要做一个热键模组,希望能够动态的增加删除热键。
1.我需要提供一个AddHotKey函数,该函数有3个参数(1.需要添加的hotkey list; 2.需要添加热键的窗口handle; 3.热键发生时具体触发的动作,即一个函数指针)
2.一个RemoveHotKey函数该函数有3个参数(1.需要删除的hotkey list; 2.需要删除热键的窗口handle; 3.热键发生时具体触发的动作,即一个函数指针)


如上图,我的tab control有3个分页,然后每个分页用AddHotKey注册不同的热键,每个分页也可以用RemoveHotKey删除不同的热键

我的问题是:
我在每个分页的OnInitDialog函数里用RegisterHotKey注册热键。这样导致
1.RegisterHotKey注册的是系统热键(全局热键),我切换到分页2后,分页2页可以相应分页1添加的热键,我不希望这样。我要切换到每个分页后,每个分页仅仅只响应本分页注册的热键
2.希望我注册的这个热键不要对其他有程序有影响,比如我注册CTRL+S,office word也有这个热键,这样如果我的程序开office word的CTRL+S就会失去作用

请问怎么解决?难道需要我监测3个分页分别是否有焦点,然后一有焦点就RegisterHotKey,一失去焦点就UnRegisterHotKey?
...全文
580 46 打赏 收藏 转发到动态 举报
写回复
用AI写文章
46 条回复
切换为时间正序
请发表友善的回复…
发表回复
maomao85 2014-05-13
  • 打赏
  • 举报
回复
引用 45 楼 dingxz105090 的回复:
我也不清楚钩子的使用 http://hi.baidu.com/hammer_2011/item/7aec4c25407d4ac70f37f9da
好吧,这个帖子结了,需求我算是初步完成了
maomao85 2014-05-12
  • 打赏
  • 举报
回复
引用 42 楼 dingxz105090 的回复:
那就用非全局钩子吧
不用局部钩子,重载WM_HELPINFO消息,可以屏蔽MFC自带的F1热键
凌乱哥 2014-05-12
  • 打赏
  • 举报
回复
那就用非全局钩子吧
凌乱哥 2014-05-12
  • 打赏
  • 举报
回复
maomao85 2014-05-12
  • 打赏
  • 举报
回复
引用 42 楼 dingxz105090 的回复:
那就用非全局钩子吧
键盘钩子函数: LRESULT CALLBACK WINProc( int nCode, // hook code WPARAM wParam, // message identifier LPARAM lParam // mouse coordinates ) nCode的值可以是0,HC_ACTION,HC_NOREMOVE 我想问HC_ACTION,HC_NOREMOVE有什么作用呢?我百度看很多人都是这么写的:

LRESULT CALLBACK KeyHookProc(int nCode, WPARAM wParam, LPARAM lParam)// 键盘钩子函数消息过程
{
     if(nCode < 0 || nCode == HC_NOREMOVE)
return ::CallNextHookEx(g_hHook, nCode, wParam, lParam);

     if(lParam & 0x40000000) // 消息重复就交给下一个hook链
{
   return ::CallNextHookEx(g_hHook, nCode, wParam, lParam);
} 
我不太明白 if(nCode < 0 || nCode == HC_NOREMOVE)这个判断的作用
maomao85 2014-05-11
  • 打赏
  • 举报
回复
引用 32 楼 dingxz105090 的回复:
不过我找到办法可以实现你最初的需求了,注册热键和取消热键,你试试

//比如我注册CTRL+D是显示窗口,CTRL+F是隐藏窗口
#define HOTKEY_HIDE		0xB0FF
#define HOTKEY_RESTORE	0xB100
#define VK_D			'D'   
#define VK_F			'F'

//初始化时注册热键
BOOL result=RegisterHotKey(this->GetSafeHwnd(),HOTKEY_HIDE,MOD_CONTROL,VK_D);
result=RegisterHotKey(this->GetSafeHwnd(),HOTKEY_RESTORE,MOD_CONTROL,VK_F);

//添加WM_HOTKEY消息响应热键
afx_msg void OnHotKey(WPARAM wParam,LPARAM lParam);
ON_MESSAGE(WM_HOTKEY,OnHotKey)
void CXXXDlg::OnHotKey(WPARAM wParam,LPARAM lParam)
{
	if(HOTKEY_HIDE==(int) wParam)
		ShowWindow(SW_HIDE);
	if(HOTKEY_RESTORE==(int) wParam)
		ShowWindow(SW_SHOW);
}

//卸载热键
::UnregisterHotKey(this->GetSafeHwnd(),HOTKEY_HIDE);
::UnregisterHotKey(this->GetSafeHwnd(),HOTKEY_RESTORE);
我发现我还是需要用钩子,因为热键有F1,按F1会弹出windows的热键,然后才是我的messagebox

BOOL CHotKeysAppDlg::PreTranslateMessage(MSG* pMsg)
{
	// TODO: Add your specialized code here and/or call the base class

	if (pMsg->message==WM_KEYDOWN)
	{
		
		 if(pMsg->wParam>=VK_F1 )
		{
			MessageBox(_T("F1"),_T("MessageBox"),MB_OK);
		}
	}

	return CDialogEx::PreTranslateMessage(pMsg);
}
summer_insects 2014-05-11
  • 打赏
  • 举报
回复
引用 36 楼 maomao85 的回复:
[quote=引用 35 楼 wohaaitinciu 的回复:] 楼主的“热键”是指的“加速键”吗?如果是,参考下面这几个函数 CreateAcceleratorTable TranslateAccelerator DestroyAcceleratorTable
这个我有想过,可是我的需求是要和窗口句柄相关啊,CreateAcceleratorTable和窗口句柄联系不上[/quote] 是的 可以创建多套加速键,然后在PreTranslateMessage里面根据不同的情况,传合适的参数传给TranslateAccelerator 我曾经这样弄过
maomao85 2014-05-11
  • 打赏
  • 举报
回复
引用 38 楼 lis2012 的回复:
page切换的时候控制热键的注册与反注册
RegisterHotKey注册的是全局热键,组长说不要注册全局热键,要做成App内部的热键。
lis2012 2014-05-11
  • 打赏
  • 举报
回复
page切换的时候控制热键的注册与反注册
maomao85 2014-05-11
  • 打赏
  • 举报
回复
引用 32 楼 dingxz105090 的回复:
不过我找到办法可以实现你最初的需求了,注册热键和取消热键,你试试

//比如我注册CTRL+D是显示窗口,CTRL+F是隐藏窗口
#define HOTKEY_HIDE		0xB0FF
#define HOTKEY_RESTORE	0xB100
#define VK_D			'D'   
#define VK_F			'F'

//初始化时注册热键
BOOL result=RegisterHotKey(this->GetSafeHwnd(),HOTKEY_HIDE,MOD_CONTROL,VK_D);
result=RegisterHotKey(this->GetSafeHwnd(),HOTKEY_RESTORE,MOD_CONTROL,VK_F);

//添加WM_HOTKEY消息响应热键
afx_msg void OnHotKey(WPARAM wParam,LPARAM lParam);
ON_MESSAGE(WM_HOTKEY,OnHotKey)
void CXXXDlg::OnHotKey(WPARAM wParam,LPARAM lParam)
{
	if(HOTKEY_HIDE==(int) wParam)
		ShowWindow(SW_HIDE);
	if(HOTKEY_RESTORE==(int) wParam)
		ShowWindow(SW_SHOW);
}

//卸载热键
::UnregisterHotKey(this->GetSafeHwnd(),HOTKEY_HIDE);
::UnregisterHotKey(this->GetSafeHwnd(),HOTKEY_RESTORE);
RegisterHotKey注册的是全局热键,组长说不要注册全局热键,要做成App内部的热键。
maomao85 2014-05-11
  • 打赏
  • 举报
回复
引用 35 楼 wohaaitinciu 的回复:
楼主的“热键”是指的“加速键”吗?如果是,参考下面这几个函数 CreateAcceleratorTable TranslateAccelerator DestroyAcceleratorTable
这个我有想过,可是我的需求是要和窗口句柄相关啊,CreateAcceleratorTable和窗口句柄联系不上
summer_insects 2014-05-10
  • 打赏
  • 举报
回复
楼主的“热键”是指的“加速键”吗?如果是,参考下面这几个函数 CreateAcceleratorTable TranslateAccelerator DestroyAcceleratorTable
maomao85 2014-05-10
  • 打赏
  • 举报
回复
引用 4 楼 dingxz105090 的回复:
PreTranslateMsg里拦截WM_KEYDOWN按键消息,并判断CTRL、ALT是否按下
可是我的快捷键还有可能是一个按钮,比如F1
凌乱哥 2014-05-10
  • 打赏
  • 举报
回复
引用 33 楼 maomao85 的回复:
[quote=引用 31 楼 dingxz105090 的回复:] 可是我有测试过,你按下ctrl松开后,立即按下A,是满足条件的,前提是松开ctrl后立即按下A,不信你测试
这个你就不用这么仔细了,如果按照系统一定是正确的话,我就可以说是你松的太快或者太慢 上限的问题好奇怪,有时候又能按6个,好像跟不同的键有关 [/quote] 你能通时按6键啊。。。一般”同时“按下3个键就不错了[/quote] 手脚并用
maomao85 2014-05-10
  • 打赏
  • 举报
回复
引用 31 楼 dingxz105090 的回复:
可是我有测试过,你按下ctrl松开后,立即按下A,是满足条件的,前提是松开ctrl后立即按下A,不信你测试
这个你就不用这么仔细了,如果按照系统一定是正确的话,我就可以说是你松的太快或者太慢 上限的问题好奇怪,有时候又能按6个,好像跟不同的键有关 [/quote] 你能通时按6键啊。。。一般”同时“按下3个键就不错了
凌乱哥 2014-05-10
  • 打赏
  • 举报
回复
不过我找到办法可以实现你最初的需求了,注册热键和取消热键,你试试

//比如我注册CTRL+D是显示窗口,CTRL+F是隐藏窗口
#define HOTKEY_HIDE		0xB0FF
#define HOTKEY_RESTORE	0xB100
#define VK_D			'D'   
#define VK_F			'F'

//初始化时注册热键
BOOL result=RegisterHotKey(this->GetSafeHwnd(),HOTKEY_HIDE,MOD_CONTROL,VK_D);
result=RegisterHotKey(this->GetSafeHwnd(),HOTKEY_RESTORE,MOD_CONTROL,VK_F);

//添加WM_HOTKEY消息响应热键
afx_msg void OnHotKey(WPARAM wParam,LPARAM lParam);
ON_MESSAGE(WM_HOTKEY,OnHotKey)
void CXXXDlg::OnHotKey(WPARAM wParam,LPARAM lParam)
{
	if(HOTKEY_HIDE==(int) wParam)
		ShowWindow(SW_HIDE);
	if(HOTKEY_RESTORE==(int) wParam)
		ShowWindow(SW_SHOW);
}

//卸载热键
::UnregisterHotKey(this->GetSafeHwnd(),HOTKEY_HIDE);
::UnregisterHotKey(this->GetSafeHwnd(),HOTKEY_RESTORE);
凌乱哥 2014-05-10
  • 打赏
  • 举报
回复
引用 25 楼 maomao85 的回复:
[quote=引用 23 楼 dingxz105090 的回复:] 那肯定不弹出了啊,你还是没理解啊,要弹出是要满足2个条件的,你CTRL都松开了,不就不满足条件了吗
可是我有测试过,你按下ctrl松开后,立即按下A,是满足条件的,前提是松开ctrl后立即按下A,不信你测试[/quote] 这个你就不用这么仔细了,如果按照系统一定是正确的话,我就可以说是你松的太快或者太慢 上限的问题好奇怪,有时候又能按6个,好像跟不同的键有关
maomao85 2014-05-10
  • 打赏
  • 举报
回复
引用 29 楼 dingxz105090 的回复:
[quote=引用 28 楼 dingxz105090 的回复:] 你拖一个编辑框IDC_EDIT1,试试效果,还不错
好像按键的上限是5个,多了就不行了,5个也足够了[/quote] 多谢,一会我研究研究。
凌乱哥 2014-05-10
  • 打赏
  • 举报
回复
引用 28 楼 dingxz105090 的回复:
你拖一个编辑框IDC_EDIT1,试试效果,还不错
好像按键的上限是5个,多了就不行了,5个也足够了
凌乱哥 2014-05-10
  • 打赏
  • 举报
回复
你拖一个编辑框IDC_EDIT1,试试效果,还不错
加载更多回复(26)

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧