如何在Mac OS X下捕获/发布系统范围的键盘/鼠标事件? [英] How to Capture / Post system-wide Keyboard / Mouse events under Mac OS X?

查看:157
本文介绍了如何在Mac OS X下捕获/发布系统范围的键盘/鼠标事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于脚本实用程序,我需要能够记录在应用程序具有焦点时发生的一系列键盘和鼠标事件。第二部分是能够稍后将这些事件发送到活动窗口。



我不需要担心菜单或跟踪哪个窗口的标识符接收输入。 / p>

我知道如何在Windows下执行此操作,但不知道Mac OS X。

解决方案

我会告诉你的第一件事是,你不能在没有用户在可访问性控制面板中启用支持设备的情况下这样做。



这是一个我在我的应用程序中使用的代码片段:

  //此方法调用一个碳方法附加一个全局事件处理程序
- (void)attachEventHandlers
{
// create我们的keyup的事件类型规范
EventTypeSpec eventType;
eventType.eventClass = kEventClassKeyboard;
eventType.eventKind = kEventRawKeyUp;

//为我们的事件创建回调函数
EventHandlerUPP handlerFunction = NewEventHandlerUPP(globalKeyPress);

//安装事件处理程序
OSStatus err = InstallEventHandler(GetEventMonitorTarget(),handlerFunction,1,& eventType,self,NULL);

//错误检查
if(err)
{
// TODO:需要一个警告表
NSLog ...%d,err);
}

//为鼠标事件创建事件类型规范
EventTypeSpec eventTypeM;
eventTypeM.eventClass = kEventClassMouse;
eventTypeM.eventKind = kEventMouseUp;

//为我们的事件创建回调函数
EventHandlerUPP handlerFunctionM = NewEventHandlerUPP(globalMousePress);

//安装事件处理程序
OSStatus errM = InstallEventHandler(GetEventMonitorTarget(),handlerFunctionM,1,& eventTypeM,self,NULL);

//错误检查
if(errM)
{
// TODO:需要一个警告表
NSLog ...%d,err);
}
}

这里是一个回调方法的例子我使用:

  OSStatus globalKeyPress(EventHandlerCallRef nextHandler,EventRef theEvent,void * userData)
{
NSEvent * anEvent = [NSEvent eventWithEventRef:theEvent];
NSEventType type = [anEvent type];
WarStrokerApplication * application =(WarStrokerApplication *)userData;

//是一个key up事件吗?
if(type == NSKeyUp)
{
//这是什么键?
switch([anEvent keyCode])
{
case NUMERIC_KEYPAD_PLUS:
//这是我们用于切换的字符
//调用处理函数
[application toggleKeyPressed];
break;

//注释这行回到特定字符的keykode
默认值:
NSLog(@Keypressed:%d,**%@ ** ,[anEvent keyCode],[anEvent characters]);
break;
}
}

return CallNextEventHandler(nextHandler,theEvent);
}


For a scripting utility I need to be able to record a series of keyboard and mouse events that occur when an application has focus. The second part is being able to later send those events to the active window.

I do not need to worry about menus or tracking the identifier of which window receives input.

I know how to do this under Windows but have no idea about Mac OS X.

解决方案

The first thing i will tell you is that you CAN'T do this without the user enabling support for assitive devices in the accessability control panel. It's some kind of security built into OSX.

Here is a code snippit I am using in one of my applications to do this:

//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);
    }
}

Here is an example of the callback method i am using:

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);
}

这篇关于如何在Mac OS X下捕获/发布系统范围的键盘/鼠标事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆