【发布时间】:2022-05-09 21:02:08
【问题描述】:
对于脚本实用程序,我需要能够记录应用程序获得焦点时发生的一系列键盘和鼠标事件。第二部分是能够稍后将这些事件发送到活动窗口。
我不需要担心菜单或跟踪哪个窗口接收输入的标识符。
我知道如何在 Windows 下执行此操作,但不知道 Mac OS X。
【问题讨论】:
对于脚本实用程序,我需要能够记录应用程序获得焦点时发生的一系列键盘和鼠标事件。第二部分是能够稍后将这些事件发送到活动窗口。
我不需要担心菜单或跟踪哪个窗口接收输入的标识符。
我知道如何在 Windows 下执行此操作,但不知道 Mac OS X。
【问题讨论】:
我要告诉你的第一件事是,如果用户在可访问性控制面板中启用对辅助设备的支持,你不能这样做。这是 OSX 内置的某种安全机制。
这是我在我的一个应用程序中使用的代码片段:
//this method calls a carbon method to attach a global event handler
- (void)attachEventHandlers
{
//create our event type spec for the keyup
EventTypeSpec eventType;
eventType.eventClass = kEventClassKeyboard;
eventType.eventKind = kEventRawKeyUp;
//create a callback for our event to fire in
EventHandlerUPP handlerFunction = NewEventHandlerUPP(globalKeyPress);
//install the event handler
OSStatus err = InstallEventHandler(GetEventMonitorTarget(), handlerFunction, 1, &eventType, self, NULL);
//error checking
if( err )
{
//TODO: need an alert sheet here
NSLog(@"Error registering keyboard handler...%d", err);
}
//create our event type spec for the mouse events
EventTypeSpec eventTypeM;
eventTypeM.eventClass = kEventClassMouse;
eventTypeM.eventKind = kEventMouseUp;
//create a callback for our event to fire in
EventHandlerUPP handlerFunctionM = NewEventHandlerUPP(globalMousePress);
//install the event handler
OSStatus errM = InstallEventHandler(GetEventMonitorTarget(), handlerFunctionM, 1, &eventTypeM, self, NULL);
//error checking
if( errM )
{
//TODO: need an alert sheet here
NSLog(@"Error registering mouse handler...%d", err);
}
}
这是我正在使用的回调方法的示例:
OSStatus globalKeyPress(EventHandlerCallRef nextHandler, EventRef theEvent, void *userData)
{
NSEvent *anEvent = [NSEvent eventWithEventRef:theEvent];
NSEventType type = [anEvent type];
WarStrokerApplication *application = (WarStrokerApplication*)userData;
//is it a key up event?
if( type == NSKeyUp)
{
//which key is it?
switch( [anEvent keyCode] )
{
case NUMERIC_KEYPAD_PLUS:
//this is the character we are using for our toggle
//call the handler function
[application toggleKeyPressed];
break;
//Comment this line back in to figure out the keykode for a particular character
default:
NSLog(@"Keypressed: %d, **%@**", [anEvent keyCode], [anEvent characters]);
break;
}
}
return CallNextEventHandler(nextHandler, theEvent);
}
【讨论】:
后半部分,发布事件,使用ApplicationServices/ApplicationServices.h中提供的CGEvent方法
这是一个将鼠标移动到指定绝对位置的示例函数:
#include <ApplicationServices/ApplicationServices.h>
int to(int x, int y)
{
CGPoint newloc;
CGEventRef eventRef;
newloc.x = x;
newloc.y = y;
eventRef = CGEventCreateMouseEvent(NULL, kCGEventMouseMoved, newloc,
kCGMouseButtonCenter);
//Apparently, a bug in xcode requires this next line
CGEventSetType(eventRef, kCGEventMouseMoved);
CGEventPost(kCGSessionEventTap, eventRef);
CFRelease(eventRef);
return 0;
}
【讨论】:
点击鼠标事件见Link
我没有在 10.5 Leopard 下检查过这个,但在 10.4 上它可以工作。
【讨论】: