Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macos NSEvent`subtype`等同于CGEvent?_Macos_Cocoa_Macos Carbon_Nsevent_Cgeventtap - Fatal编程技术网

Macos NSEvent`subtype`等同于CGEvent?

Macos NSEvent`subtype`等同于CGEvent?,macos,cocoa,macos-carbon,nsevent,cgeventtap,Macos,Cocoa,Macos Carbon,Nsevent,Cgeventtap,具有获取事件的子类型的方法: 获取自定义事件信息 –数据1 –数据2 –子类型 在不首先将CGEvent转换为NSEvent的情况下,是否可以从CGEvent访问相同的子类型 CGEventRef eventCG = ...; NSEvent *eventNS = [NSEvent eventWithCGEvent:eventCG]; short subtypeNS = eventNS.subtype; short subtypeCG = ???; 提到鼠标事件子类型,似乎与IOLLEven

具有获取事件的
子类型的方法

获取自定义事件信息
–数据1
–数据2
–子类型

在不首先将CGEvent转换为NSEvent的情况下,是否可以从CGEvent访问相同的
子类型

CGEventRef eventCG = ...;
NSEvent *eventNS = [NSEvent eventWithCGEvent:eventCG];

short subtypeNS = eventNS.subtype;
short subtypeCG = ???;
提到鼠标事件子类型,似乎与
IOLLEvent.h
中的鼠标子类型相对应。但是,我对查找系统定义的CGEvents的子类型特别感兴趣

这些将是下面或CG备选方案中的NX子类型辅助控制按钮等

/* 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

对于鼠标事件,可以使用
CGEventGetIntegerValueField
获取事件的
kCGMouseEventSubtype
属性

系统定义的事件更复杂。CGEvents似乎并没有真正暴露这一点


简单的部分是匹配事件。只要CGEvent使用与NSEvent和Iolevent相同的事件类型编号,只要事件掩码是
1的简单组合,那么我对此做了一些研究,看起来子类型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);
更新:这里是获取上述信息的正确方法。它需要与-frameworkappkit链接

#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"));
#包括
#包括
静态id自动释放池;
...
类NSAutoreleasePool_Class=(类)objc_getClass(“NSAutoreleasePool”);
id pool=class\u createInstance(NSAutoreleasePool\u class,0);
id(*无CGEVENT的事件)(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(*event without cgevent)(id,SEL)=(long(*)(id,SEL))objc_msgSend;
int subtype=(int)没有CGevent的事件(事件数据,选择注册表名(“subtype”);
long data1=没有CGEVENT的事件(事件数据,选择寄存器名称(“数据1”));
long data2=没有CGEVENT的事件(事件数据,选择寄存器名称(“数据2”));
...
没有CGEvent的事件(自动释放池、选择注册名称(“释放”);

谢谢。我更喜欢NSEvent监视器,但不幸的是CGEvents是运行全局钩子的唯一方法。其想法是在创建NSEvent之前过滤相当常见的
NX\u子类型\u AUX\u鼠标按钮
事件。他们中的许多人被我的NSSystemDefined事件(特别是Power key)钩子抓住了。这不是世界上最糟糕的事情,但这会有点优化。@pkamb:NSEvent的全局事件监视API在哪些方面不能满足您的需要?您是否希望修改或删除某些事件?标记为已接受的答案(谢谢!),“可能无法获得系统定义的事件的子类型”。但如果有人找到办法,情况就会改变。