Jod*_*ins 15 macos cocoa cgeventtap osx-mavericks osx-yosemite
我正在使用CGEventTapCreateForPSN
陷阱和过滤我的应用程序的键.我对拦截其他应用程序的事件不感兴趣.我很确定一个事件水龙头太重了我的目的,但我一直无法找到更好的方法,并使用事件水龙头工作.
具体来说,这段代码可以满足我的需求.
GetCurrentProcess(&psn);
CFMachPortRef eventTap = CGEventTapCreateForPSN(
&psn,
kCGHeadInsertEventTap,
kCGEventTapOptionDefault,
CGEventMaskBit(kCGEventKeyDown)
| CGEventMaskBit(kCGEventKeyUp),
eventCallback,
userInfo);
Run Code Online (Sandbox Code Playgroud)
并且我的回调处理得很好,事件只从当前应用程序中截获.
不幸的是,ProcessSerialNumber
从10.9开始,所有获得当前的方法都已被弃用.有一种旧的标准方法可以ProcessSerialNumber
在同一个进程中传递给其他例程,这个初始化...
ProcessSerialNumber psn = { 0, kCurrentProcess };
Run Code Online (Sandbox Code Playgroud)
但是在打电话时这不起作用CGEventTapCreateForPSN
.头文件docs表示尽可能多,并且以下代码段NULL
作为确认返回.
ProcessSerialNumber psn = { 0, kCurrentProcess };
CFMachPortRef eventTap = CGEventTapCreateForPSN(
&psn,
kCGHeadInsertEventTap,
kCGEventTapOptionDefault,
CGEventMaskBit(kCGEventKeyDown)
| CGEventMaskBit(kCGEventKeyUp),
eventCallback,
userInfo);
Run Code Online (Sandbox Code Playgroud)
我可以使用,CGEventTapCreate
但它点击整个主机,然后我需要过滤任何不指向我的应用程序的东西,并且CGEventTapProxy
是不透明的,我不知道如何使用它来确定它是否是我的应用程序.
我已经验证了已弃用的代码仍然有效,但Apple可以随时决定将其删除.那么,有没有人知道我应该怎样继续CGEventTapCreateForPSN
在小牛队以及其他地方打电话?
谢谢!
UPDATE
在10.11(我认为那是El Capitan),增加了一个新功能.虽然它没有文档,但它的签名几乎完全相同CGEventTapCreateForPSN
.
CFMachPortRef CGEventTapCreateForPSN(
void *processSerialNumber,
CGEventTapPlacement place,
CGEventTapOptions options,
CGEventMask eventsOfInterest,
CGEventTapCallBack callback,
void *userInfo);
CFMachPortRef CGEventTapCreateForPid(
pid_t pid,
CGEventTapPlacement place,
CGEventTapOptions options,
CGEventMask eventsOfInterest,
CGEventTapCallBack callback,
void *userInfo);
Run Code Online (Sandbox Code Playgroud)
因此,不需要不推荐使用的功能,因为PID可以用作第一个参数.
我认为你应该- (void)sendEvent:(NSEvent *)theEvent
为此目的子类化 NSApplication 并重写方法。来自文档:
您很少会发现真正需要创建自定义 NSApplication 子类。与一些面向对象的库不同,Cocoa 不需要您子类化 NSApplication 来自定义应用程序行为。相反,它为您提供了许多其他方式来自定义应用程序。
还:
重要的
许多 AppKit 类依赖于 NSApplication 类,并且在该类完全初始化之前可能无法正常工作。因此,您不应该尝试从 NSApplication 子类的初始化方法调用其他 AppKit 类的方法。
因此,您可以拦截通过应用程序传递的所有事件并调用自定义 NSApplicationDelegate 继承的协议方法。
// in SubApplication.h
@protocol ExtendedApplicationDelegate : NSApplicationDelegate
- (void)applicationDidTrapSomeInterestingEvent:(NSEvent *)event;
@end
// in SubApplication.m
- (void)sendEvent:(NSEvent *)event
{
if ([event type] == NSKeyDown && [event keyCode]==_someCode)
{
// call application delegate method
}
[super sendEvent:event];
}
Run Code Online (Sandbox Code Playgroud)
我不确定这种方法是否能解决问题,但你仍然可以尝试一下。
归档时间: |
|
查看次数: |
758 次 |
最近记录: |