如果当焦点处于其他应用程序时,如何拦截键盘事件?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如果当焦点处于其他应用程序时,如何拦截键盘事件?相关的知识,希望对你有一定的参考价值。

WINDOW下可进行挂接的过滤函数一共有哪几种?

WINDOWS的消息处理机制为了能在应用程序中监控系统的各种事件消息,提供了挂接 各种反调函数(HOOK)的功能。这种挂钩函数(HOOK)类似扩充中断驱动程序,挂钩上 可以挂接多个反调函数构成一个挂接函数链。系统产生的各种消息首先被送到各种 挂接函数,挂接函数根据各自的功能对消息进行监视、修改和控制等,然后交还控 制权或将消息传递给下一个挂接函数以致最终达到窗口函数。WINDOW系统的这种反 调函数挂接方法虽然会略加影响到系统的运行效率,但在很多场合下是非常有用 的,通过合理有效地利用键盘事件的挂钩函数监控机制可以达到预想不到的良好效 果。
一、在WINDOWS键盘事件上挂接监控函数的方法
WINDOW下可进行挂接的过滤函数包括11种:
WH_CALLWNDPROC 窗口函数的过滤函数
WH_CBT 计算机培训过滤函数
WH_DEBUG 调试过滤函数
WH_GETMESSAGE 获取消息过滤函数
WH_HARDWARE 硬件消息过滤函数
WH_JOURNALPLAYBACK 消息重放过滤函数
WH_JOURNALRECORD 消息记录过滤函数
WH_MOUSE 鼠标过滤函数
WH_MSGFILTER 消息过滤函数
WH_SYSMSGFILTER 系统消息过滤函数
WH_KEYBOARD 键盘过滤函数
其中键盘过滤函数是最常用最有用的过滤函数类型,不管是哪一种类型的过滤函 数,其挂接的基本方法都是相同的。 WINDOW调用挂接的反调函数时总是先调用挂接链首的那个函数,因此必须将键盘挂 钩函数利用函数SetWindowsHookEx()将其挂接在函数链首。至于消息是否传递给函 数链的下一个函数是由每个具体函数功能确定的,如果消息需要传统给下一个函 数,可调用API函数的CallNextHookEx()来实现,如果不传递直接返回即可。 挂接函数可以是用来监控所有线程消息的全局性函数,也可以是单独监控某一线程 的局部性函数。如果挂接函数是局部函数,可以将它放到一个.DLL动态链接库中, 也可以放在一个局部模块中;如果挂接函数是全局的,那么必须将其放在一个.DLL 动态链接库中。挂接函数必须严格按照下述格式进行声明,以键盘挂钩函数为例:
int FAR PASCAL KeyboardProc( int nCode,WORD wParam,DWORD lParam) 其中KeyboardProc为定义挂接函数名,该函数必须在模块定义文件中利用EXPORTS命 令进行说明;nCode决定挂接函数是否对当前消息进行处理;wParam和lParam为具体 的消息内容。

二、键盘事件挂接函数的安装与下载 在程序中可以利用函数SetWindowsHookEx()来挂接过滤函数,在挂接函数时必须指 出该挂接函数的类型、函数的入口地址以及函数是全局性的还是局部性的,挂接函 数的具体调用格式如下:
SetWindowsHookEx(iType,iProc,hInst,iCode) 其中iType为挂接函数类型,键盘类型为WH_KEYBOARD,iProc为挂接函数地址,hInst 为挂接函数链接库实例句柄,iCode为监控代码-0表示全局性函数。 如果挂接函数需要将消息传递给下一个过滤函数,则在该挂接函数返回前还需要调 用一次CallNextHookEx()函数,当需要下载挂接函数时,只要调用一次 UnhookWindowsHookEx(iProc)函数即可实现。 如果函数是全局性的,那么它必须放在一个.DLL动态链接库中,这时该函数调用方 法可以和其它普通.DLL函数一样有三种:
1.在DEF定义文件中直接用函数名或序号说明: EXPORTS WEP @1 RESIDENTNAME InitHooksDll @2 InstallFilter @3 KeyboardProc @4 用序号说明格式为:链接库名.函数名(如本例中说明方法为KEYDLL.KeyboardProc)。
2.在应用程序中利用函数直接调用: 首先在应用程序中利用LoadLibrary(LPSTR "链接库名")将动态链接库装入,并取得 装载库模块句柄hInst,然后直接利用GetProcAddress(HINSTANCE hInst,LPSTR "函 数过程名")获取函数地址,然后直接调用该地址即可,程序结束前利用函数 FreeLibrary( )释放装入的动态链接库即可。
3.利用输入库.LIB方法 利用IMPLIB.EXE程序在建立动态链接库的同时建立相应的输入库.LIB,然后直接在 项目文件中增加该输入库。
参考技术A 按键功能处理 break; 5、当应用程序退出时应注意下载键盘监控函数,即调用InstallFilter(FALSE)函 数一次。 6、利用本文提供的方法设置自己的应用程序功能按键,在保证程序功能按键不会 与其它系统发生冲突的同时,有效地利用了系统中现有资源,而且在实现应用程序 功能的同时灵活应用了系统中提 参考技术B INDOWS 键盘事件驱动程序 并不将这两个按键的消息进行正常解释,这就必须利用键盘事件的挂钩监控函数来 实现其特定的功能。其方法如下:
答案补充
1、首先编制如下一个简单动态链接库程序,并编译成DLL文件。 #include "windows.h" int FAR PASCAL LibMain(HANDLE hModule,UINT wDataSeg, UINT cbHeapSize,
sd

当 textview 处于焦点时,SDK 安全的方法来隐藏 iPad 键盘

【中文标题】当 textview 处于焦点时,SDK 安全的方法来隐藏 iPad 键盘【英文标题】:SDK safe way to hide iPad keyboard when textview is in focus 【发布时间】:2012-05-25 20:08:40 【问题描述】:

我有一些 iPad 应用程序,用户可以在其中使用触摸屏或蓝牙键盘进行导航。 我有一些隐藏的 textView 处于焦点位置(第一响应者),在这里我检测到从键盘输入的内容。

但是,当我断开键盘时,我遇到了问题,出现了虚拟键盘。

我可以检查蓝牙键盘是否连接,并在 viewDidLoad 中设置或退出第一响应者吗?

我有通知:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillAppear:) name:UIKeyboardWillShowNotification object:nil];

当keyboardWillAppear被触发时,我可以以某种方式隐藏键盘吗? 我试过 [textView resignFirstResponder],但没有成功:|

【问题讨论】:

【参考方案1】:

您可以将 inputView 设置为透明视图:

UIView *emptyView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
emptyView.backgroundColor = [UIColor clearColor];
textView.inputView = emptyView;

理论上,这会将屏幕键盘设置为空视图,使其不可见。如果它不接受没有框架的视图,则尝试将宽度和高度设置为 1。它不会影响外部键盘;它只是不会显示在设备上。

【讨论】:

【参考方案2】:

您可以为此使用 performSelector:。

- (void)hideKeyboard:(UITextView *)textView 
    [textView resignFirstResponder];


- (void)keyboardWillAppear:(NSNotification *)notification  
    UITextView *textView = (UITextView *)[self.view viewWithTag:TEXTVIEW_TAG];

    [self performSelector:@selector(hideKeyboard:) withObject:textView];


- (void)viewDidLoad 
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillAppear:) name:UIKeyboardWillShowNotification object:nil];

【讨论】:

我也一样。还有一个更正,它是 TextView,而不是 TextField。【参考方案3】:

您必须安排 textView 的第一响应者辞职到调度队列,因为成为第一响应者的过程可能还没有完成。使用 XCode 的调度模板的简单解决方案:

int64_t delayInSeconds = 0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void)
    [self.textView resignFirstResponder];
);

【讨论】:

以上是关于如果当焦点处于其他应用程序时,如何拦截键盘事件?的主要内容,如果未能解决你的问题,请参考以下文章

当uitextView处于焦点时如何隐藏键盘~~

当 textview 处于焦点时,SDK 安全的方法来隐藏 iPad 键盘

如何在 UITextField 子类中拦截来自键盘的文本输入事件

从其他应用程序进入时应用程序没有获得键盘焦点

如何在颤动中取消焦点文本字段?

winform中键盘和鼠标事件的捕捉和重写