242上位机VC MFC利用TAB或回车键切换焦点
键盘上系统功能键是指shift,ctrl,win等一些具有特定系统功能的键盘按键,有时我们自己开发的程序并不想让系 ...
242上位机VC MFC实现键盘指定系统功能键屏 功能展示 键盘上系统功能键是指shift,ctrl,win等一些具有特定系统功能的键盘按键,有时我们自己开发的程序并不想让系统响应用户触发的这些键盘系统功能键,我们就得对这些功能键进行屏蔽,当前例程实现特定的功能键屏蔽功能,效果如图,点击屏蔽按钮ESC,WIN,CTRL,等功能键会失效,点击取消可恢复;大家也可根据自身程序开发需要,对更多系统功能键屏蔽; 要点提示 例程对键盘功能键屏蔽的方法是通过挂接键盘钩子,在键盘钩子函数内实现对功能键的屏蔽;挂接键盘钩子可以通过函数SetWindowsHookEx()实现。
1.函数SetWindowsHookEx()把一个应用程序定义的钩子子程安装到钩子链表中。 此函数总是在Hook链的开头安装Hook回调函数。当指定类型的Hook监视的事件发生时,系统就调用与这个Hook关联的Hook链的开头的Hook回调函数。每一个Hook链中的Hook回调函数都决定是否把这个事件传递到下一个Hook回调函数。Hook回调函数传递事件到下一个 Hook回调函数需要调用CallNextHookEx函数。
2.函数说明HHOOK SetWindowsHookEx(int idHook, //钩子的类型,即它处理的消息类型 HOOKPROC lpfn, // 钩子子程的地址指针。如果dwThreadId参数为0或是一个由别的进程创建的线程的标识lpfn必须指向DLL中的钩子子程。除此以外,lpfn可以指向当前进程的一段钩子子程代码。 钩子函数的入口地址,当钩子钩到任何消息后便调用这个函数。 HINSTANCE hMod, // 应用程序实例的句柄。标识包含lpfn所指的子程的DLL。如果dwThreadId标识当前进程创建的一个线程,而且子程代码位于当前进程,hMod必须为NULL。可以很简单的设定其为本应用程序的实例句柄。 DWORD dwThreadId ); // 与安装的钩子子程相关联的线程的标识符。如果为0,钩子子程与所有的线程关联,即为全局钩子。 实现功能 1.新建基于对话框的应用程序 2.拖拽两按钮<屏蔽系统键盘功能键><取消屏蔽>关联函数,并在程序退出也调用一次取消屏蔽按钮所关联的函数 - void CGkbc8Dlg::OnButton1()
- {
- g_Hook=::SetWindowsHookEx(WH_KEYBOARD_LL,LowLevelKeyboardProc,::AfxGetApp()->m_hInstance,0);
- }
- void CGkbc8Dlg::OnButton2()
- {
- ::UnhookWindowsHookEx(g_Hook);
- }
- void CGkbc8Dlg::OnDestroy()
- {
- OnButton2() ;
- CDialog::OnDestroy();
- }
复制代码3.在代码段前添加回调函数及一全局变量 - HHOOK g_Hook=NULL;
- LRESULT CALLBACK LowLevelKeyboardProc(int nCode,WPARAM wParam,LPARAM lParam)
- {
- if(nCode<0)//如nCode<0必须返回 CallNextHookEx
- return CallNextHookEx(0,nCode,wParam,lParam);
- LPKBDLLHOOKSTRUCT p=(LPKBDLLHOOKSTRUCT)lParam;
复制代码- if(nCode==HC_ACTION)// 当nCode为HC_ACTION时,wParam,lParam 带有鼠标信息
- {
- if(p->vkCode==VK_LWIN||p->vkCode==VK_RWIN)
- return 1;
- if(p->vkCode==VK_LSHIFT||p->vkCode==VK_RSHIFT)
- return 1;
- if(p->vkCode==VK_LCONTROL||p->vkCode==VK_RCONTROL)
- return 1;
- if(p->vkCode==VK_ESCAPE)
- return 1;
- }
- CallNextHookEx(0,nCode,wParam,lParam);
- return 0;
- }
复制代码4.在stdafc.h头文件顶部添加代码#define _WIN32_WINNT 0x0500 定义WIN32版本使用程序使用的宏能够被编译器正确识别; 我们来演示下功能实现的整个过程
|