替代击键

时间:2014-11-11 20:20:38

标签: objective-c objective-c-blocks keyboard-events

我试图拦截击键,并用不同的角色替换它。我已经能够拦截被按下的键,以及执行一些额外的操作。现在我需要按住键,如果它与我正在观看的那个匹配,并插入一个不同的字符。这是我现在的代码:

#import "AppDelegate.h"
#import <AppKit/AppKit.h>
#import <CoreGraphics/CoreGraphics.h>
#include <ApplicationServices/ApplicationServices.h>

@interface AppDelegate ()

@property (weak) IBOutlet NSWindow *window;
@end

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    //Keys that are being watched to be switched out
    NSArray *keysToWatch = [[NSArray alloc] initWithObjects:@"c",@".", nil];


    // register for keys throughout the device...
    [NSEvent addGlobalMonitorForEventsMatchingMask:NSKeyDownMask
                                           handler:^(NSEvent *event){
                                               //Get characters
                                               NSString *chars = [[event characters] lowercaseString];
                                               //Get the actual character being pressed
                                               unichar character = [chars characterAtIndex:0];
                                               //Transform it to a string
                                               NSString *aString = [NSString stringWithCharacters:&character length:1];
                                               //If it is in the list, start looking if Keynote is active
                                               if ([keysToWatch containsObject:[NSString stringWithString:aString]]) {
                                                   //DEBUG: Print a message
                                                   NSLog(@"Key being watched has been pressed");
                                                   //Get a list of all running apps
                                                   for (NSRunningApplication *currApp in [[NSWorkspace sharedWorkspace] runningApplications]) {
                                                       //Get current active app
                                                       if ([currApp isActive]) {
                                                           //Check if it is Keynote, if yes perform remap
                                                           if ([[currApp localizedName] isEqualToString:@"Keynote"]){
                                                               //DEBUG: Print a small message
                                                               NSLog(@"Current app is Keynote");


                                                               if (character=='.') {
                                                                   NSLog(@"Pressed a dot");
                                                                   //I want to post a different character here
                                                                   PostKeyWithModifiers((CGKeyCode)11, FALSE);
                                                               }
                                                               else if ([aString isEqualToString:@"c"]) {
                                                                   NSLog(@"Pressed c");
                                                               }




                                                           }
                                                           else if ([[currApp localizedName] isEqualToString:@"Microsoft PowerPoint"]){

                                                           }
                                                       }
                                                   }
                                               }




                                               }
                                               ];
}
- (void)applicationWillTerminate:(NSNotification *)aNotification {
    // Insert code here to tear down your application
}

- (BOOL)acceptsFirstResponder {
    return YES;
}

void PostKeyWithModifiers(CGKeyCode key, CGEventFlags modifiers)
{
    CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateCombinedSessionState);

    CGEventRef keyDown = CGEventCreateKeyboardEvent(source, key, TRUE);
    CGEventSetFlags(keyDown, modifiers);
    CGEventRef keyUp = CGEventCreateKeyboardEvent(source, key, FALSE);

    CGEventPost(kCGAnnotatedSessionEventTap, keyDown);
    CGEventPost(kCGAnnotatedSessionEventTap, keyUp);

    CFRelease(keyUp);
    CFRelease(keyDown);
    CFRelease(source);
}
@end

我的问题是我无法停止原来的击键。请记住,我在Obj C是全新的,所以让我知道是否有什么我可以做得更好。谢谢!

2 个答案:

答案 0 :(得分:0)

来自docs for +[NSEvent addGlobalMonitorForEventsMatchingMask:handler:]

  

事件以异步方式发送到您的应用,您只能这样做   观察事件;您无法修改或以其他方式阻止该事件   从交付到其原始目标应用程序。

你必须使用Quartz Event Tap

答案 1 :(得分:0)

所以,在经过大量挖掘之后,我找到了一种方法,使用Quartz Event Taps here来实现这一目标。感谢@Ken Thomases指出我正确的方向。然后我将我的代码与本文中解释的代码结合起来,并且它有效。