【问题标题】:How to implement shortcut key input in Mac Cocoa App?Mac Cocoa App中如何实现快捷键输入?
【发布时间】:2011-11-20 11:59:16
【问题描述】:

我需要在我的 Cocoa 应用程序中创建一个全局热键输入框。

我知道 Shortcut Recorder,但它是一个非常古老的解决方案。它有部分使用已弃用的 Carbon 实现,如果我使用它,我无法将我的应用发布到 Mac App Store。

有现成的现代解决方案吗?谁能给我自己做这个的方法(我不知道从哪里开始)?

【问题讨论】:

  • 并非所有 Carbon 都被弃用,只是 GUI 部分。

标签: objective-c macos cocoa shortcuts


【解决方案1】:

有一个名为 MASShortcut 的现代框架用于在 OS X 10.7+ 中实现全局快捷方式。

【讨论】:

  • (他建造的)
  • 这仅适用于其他应用程序中不存在的快捷方式吗?我在注册快捷方式时遇到问题,我看到其中一个在另一个应用程序中实现。此外,如果我更改默认快捷方式,它不起作用,并且不是修饰键的键在我的运行时在任何应用程序中都不起作用。我想抓住 cmd+c 和 alt+cmd+v
【解决方案2】:

并非所有 Carbon 都已弃用。您不能再制作纯 Carbon 应用程序了,但一些 API 仍然存在,其中一些仍然是完成某些事情的最简单方法。

其中之一是 Carbon Events 热键 API。您当然可以使用 NSEvent 的事件监视器方法筛选所有事件,但这是不必要的工作。 Carbon Events 热键 API 仍然受支持并且更简单——您只需告诉它您想要匹配哪个键以及按下该键时要调用什么函数。还有一些 Cocoa 包装器,例如 DDHotKey,使其更加简单。

【讨论】:

  • 谢谢,彼得!但我知道如何注册热键。这对我来说很简单。我想记录用户的键,所以我需要在我的首选项窗口中实现“热键 NSTextField”之类的东西。
  • @VictorShcherbakov:据我所知,ShortcutRecorder 仍然是最好的方法。它应该是 64 位兼容的,至少在主干版本中是这样。 code.google.com/p/shortcutrecorder
  • shortcutrecorder(演示应用程序)在 lion + xcode4 上没有为我工作。所以我仍然很高兴听到除了快捷方式记录器之外的其他输入字段选项
【解决方案3】:

在 Mac OS X 10.6 及更高版本中,您可以使用从 NSEvent 类定义的方法 +addGlobalMonitorForEventsMatchingMask:handler:+addLocalMonitorForEventsMatchingMask:handler:Monitoring Events 报告以下信息:

本地和全局事件监视器是互斥的。例如,全局监视器不会观察安装它的应用程序的事件流。本地事件监视器只观察其应用程序的事件流。要监视来自所有应用程序(包括“当前”应用程序)的事件,您必须安装两个事件监视器。

该页面中显示的代码用于本地事件监视器,但全局事件监视器的代码类似;调用NSEvent的方法有什么变化。

_eventMonitor = [NSEvent addLocalMonitorForEventsMatchingMask:
        (NSLeftMouseDownMask | NSRightMouseDownMask | NSOtherMouseDownMask | NSKeyDownMask)
        handler:^(NSEvent *incomingEvent) {
    NSEvent *result = incomingEvent;
    NSWindow *targetWindowForEvent = [incomingEvent window];
    if (targetWindowForEvent != _window) {
        [self _closeAndSendAction:NO];
    } else if ([incomingEvent type] == NSKeyDown) {
        if ([incomingEvent keyCode] == 53) {
            // Escape
            [self _closeAndSendAction:NO];
            result = nil; // Don't process the event
        } else if ([incomingEvent keyCode] == 36) {
            // Enter
            [self _closeAndSendAction:YES];
            result = nil;
        }
    }
    return result;
}];

一旦不再需要监视器,您可以使用以下代码将其删除:

[NSEvent removeMonitor:_eventMonitor];

【讨论】:

  • 虽然这行得通,但这是一个艰难的道路。 Carbon 事件管理器的 API 仍然受支持,并且更简单、更容易,并且它的两个第三方 Cocoa 包装器使它更容易。
  • 这不适用于关键事件,除非应用程序的可访问性受信任
  • 全局监视器不起作用,但我在本地可以监听按键。但我会假设人们正在寻找全局热键:)。
  • 另外一个需要注意的问题是使用这种方法的一些按键命令仍然会触发“Funk”错误声音。有谁知道阻止这种情况的方法?
  • @kiamlaluno 感谢您的明确回答。它有效。
猜你喜欢
  • 1970-01-01
  • 2010-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-23
  • 1970-01-01
  • 2010-09-26
  • 2021-06-05
相关资源
最近更新 更多