我使用 CGEventTapCreateForPSN
捕获并过滤我的应用程序的按键事件。我不希望拦截其他应用程序的事件。我相信事件监听对于我的目的来说有些过于笨重,但我一直找不到更好的方法,所以还是使用事件监听的方式。
具体而言,这段代码实现了我的需求。
GetCurrentProcess(&psn);
CFMachPortRef eventTap = CGEventTapCreateForPSN(
&psn,
kCGHeadInsertEventTap,
kCGEventTapOptionDefault,
CGEventMaskBit(kCGEventKeyDown)
| CGEventMaskBit(kCGEventKeyUp),
eventCallback,
userInfo);
我的回调函数被很好地处理了,只拦截当前应用程序的事件。
不幸的是,所有获取当前ProcessSerialNumber
的方法在10.9版本后均已弃用。有一种旧的标准方法可以获取ProcessSerialNumber
并将其传递给同一进程中的其他例程,初始化方法如下...
ProcessSerialNumber psn = { 0, kCurrentProcess };
但是当调用CGEventTapCreateForPSN
时,这种方法不起作用。头文件文档也指出了这一点,下面的代码片段返回NULL
作为确认。
ProcessSerialNumber psn = { 0, kCurrentProcess };
CFMachPortRef eventTap = CGEventTapCreateForPSN(
&psn,
kCGHeadInsertEventTap,
kCGEventTapOptionDefault,
CGEventMaskBit(kCGEventKeyDown)
| CGEventMaskBit(kCGEventKeyUp),
eventCallback,
userInfo);
我可以使用 CGEventTapCreate
,但它会捕捉整个主机,因此我需要过滤掉任何不针对我的应用程序的内容,而 CGEventTapProxy
是不透明的,我不知道如何使用它来确定是否是我的应用程序。
我已验证过时的代码仍然有效,但苹果公司可以随时决定将其移除。那么,有没有人有想法应该如何在 Mavericks 及更高版本中调用 CGEventTapCreateForPSN
?
谢谢!
更新
在 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);
因此,由于PID可以用作第一个参数,因此不需要使用已弃用的函数。
+[NSEvent addLocalMonitorForEventsMatchingMask:handler:]
? - JWWalker[NSEvent addLocalMonitorForEventsMatchingMask:handler:]
不会监视嵌套事件循环中的事件。 - Jody HaginsGetEventDispatcherTarget()
)上安装Carbon事件处理程序。从10.10 SDK头文件中可以看出,必要的API未被弃用,并且可在64位中使用。 - JWWalkeraddLocalMonitor..
不适用于非主线程,它需要主线程,这就是为什么我不能使用addLocal的原因:( - Noitidart