NSEvent有一个获取事件的subtype的方法
获取自定义事件信息 - data1 - data2 -亚型
如果不首先将同一个subtype转换成NSEvent,就可以从CGEvent访问它吗?
CGEventRef eventCG = ...;
NSEvent *eventNS = [NSEvent eventWithCGEvent:eventCG];
short subtypeNS = eventNS.subtype;
short subtypeCG = ???;CGEvent文档提到鼠标事件子类型,似乎与来自IOLLEvent.h的鼠标子类型相对应。但是,我特别感兴趣的是查找系统定义的CGEvents的子类型。
这些将是NX_SUBTYPE_AUX_CONTROL_BUTTONS等,以下或CG的替代方案。
/* sub types for mouse and move events */
#define NX_SUBTYPE_DEFAULT 0
#define NX_SUBTYPE_TABLET_POINT 1
#define NX_SUBTYPE_TABLET_PROXIMITY 2
#define NX_SUBTYPE_MOUSE_TOUCH 3
/* sub types for system defined events */
#define NX_SUBTYPE_POWER_KEY 1
#define NX_SUBTYPE_AUX_MOUSE_BUTTONS 7
/*
* NX_SUBTYPE_AUX_CONTROL_BUTTONS usage
*
* The incoming NXEvent for other mouse button down/up has event.type
* NX_SYSDEFINED and event.data.compound.subtype NX_SUBTYPE_AUX_MOUSE_BUTTONS.
* Within the event.data.compound.misc.L[0] contains bits for all the buttons
* that have changed state, and event.data.compound.misc.L[1] contains the
* current button state as a bitmask, with 1 representing down, and 0
* representing up. Bit 0 is the left button, bit one is the right button,
* bit 2 is the center button and so forth.
*/
#define NX_SUBTYPE_AUX_CONTROL_BUTTONS 8
#define NX_SUBTYPE_EJECT_KEY 10
#define NX_SUBTYPE_SLEEP_EVENT 11
#define NX_SUBTYPE_RESTART_EVENT 12
#define NX_SUBTYPE_SHUTDOWN_EVENT 13
#define NX_SUBTYPE_STICKYKEYS_ON 100
#define NX_SUBTYPE_STICKYKEYS_OFF 101
#define NX_SUBTYPE_STICKYKEYS_SHIFT 102
#define NX_SUBTYPE_STICKYKEYS_CONTROL 103
#define NX_SUBTYPE_STICKYKEYS_ALTERNATE 104
#define NX_SUBTYPE_STICKYKEYS_COMMAND 105
#define NX_SUBTYPE_STICKYKEYS_RELEASE 106
#define NX_SUBTYPE_STICKYKEYS_TOGGLEMOUSEDRIVING 107发布于 2014-01-02 01:24:07
对于鼠标事件,可以使用CGEventGetIntegerValueField获取事件的kCGMouseEventSubtype属性。
系统定义的事件更棘手。CGEvents似乎并没有真正暴露这一点。
最简单的部分是匹配事件。只要CGEvent使用与NSEvent和IOLLEvent相同的事件类型编号,只要事件掩码只是1 << eventType的组合,您就应该能够在CGEventMaskBit(NSSystemDefined)上使用一些变化来进行注册和测试CGEventGetType(event) == NSSystemDefined。
最难的部分是告诉系统定义的事件的子类型是什么,而不经过NSEvent。
一种可能是对鼠标事件(使用kCGMouseEventSubtype)做同样的操作,但是由于鼠标事件和“复合”事件(其中包括系统定义的)事件的NXEventData布局不同,所以我不指望这种工作。
很可能,无法从CGEvent获得系统定义的事件的子类型,因此您必须创建一个NSEvent。
您考虑过使用NSEvent的事件监视器API吗?如果您需要10.6或更高版本,您可以以这种方式捕获事件,并且已经将它们作为NSEvents,准备询问它们的子类型。
发布于 2015-07-03 17:38:45
因此,我对此做了一些研究,看起来这是可能的子类型,data1和data2。您可能不应该这样做,请参阅下面的更新.
CFDataRef data_ref = CGEventCreateData(kCFAllocatorDefault, event_ref);
if (data_ref == NULL) {
return;
}
CFIndex len = CFDataGetLength(data_ref);
UInt8 *buffer = malloc(20);
if (buffer == NULL) {
return;
}
CFDataGetBytes(data_ref, CFRangeMake(len - 68, 20), buffer);
...
int subtype = CFSwapInt32BigToHost(*((UInt32 *) buffer));
#ifdef __LP64__
long data1 = CFSwapInt64BigToHost(*((UInt64 *) (buffer + 4)));
#else
long data1 = CFSwapInt32BigToHost(*((UInt32 *) (buffer + 4)));
#endif
#ifdef __LP64__
long data2 = CFSwapInt64BigToHost(*((UInt64 *) (buffer + 12)));
#else
long data2 = CFSwapInt32BigToHost(*((UInt32 *) (buffer + 8)));
#endif
...
CFRelease(data_ref);
free(buffer);更新:,所以这里是获取上述信息的正确方法。它将需要与-framework AppKit链接。
#include <objc/objc.h>
#include <objc/objc-runtime.h>
static id auto_release_pool;
...
Class NSAutoreleasePool_class = (Class) objc_getClass("NSAutoreleasePool");
id pool = class_createInstance(NSAutoreleasePool_class, 0);
id (*eventWithoutCGEvent)(id, SEL) = (id (*)(id, SEL)) objc_msgSend;
auto_release_pool = eventWithoutCGEvent(pool, sel_registerName("init"));
...
id (*eventWithCGEvent)(id, SEL, CGEventRef) = (id (*)(id, SEL, CGEventRef)) objc_msgSend;
id event_data = eventWithCGEvent((id) objc_getClass("NSEvent"), sel_registerName("eventWithCGEvent:"), event_ref);
long (*eventWithoutCGEvent)(id, SEL) = (long (*)(id, SEL)) objc_msgSend;
int subtype = (int) eventWithoutCGEvent(event_data, sel_registerName("subtype"));
long data1 = eventWithoutCGEvent(event_data, sel_registerName("data1"));
long data2 = eventWithoutCGEvent(event_data, sel_registerName("data2"));
...
eventWithoutCGEvent(auto_release_pool, sel_registerName("release"));https://stackoverflow.com/questions/20864608
复制相似问题