以编程方式打开 Mac 帮助菜单

发布于 2024-10-02 19:48:51 字数 1026 浏览 7 评论 0原文

我正在将 GTK# 应用程序集成到 Mac OS X 中。Mac OS X 上的 GTK 是一些 Cocoa 和 Carbon 基础知识的包装。我们直接使用 Carbon 全局菜单 API 有一些特定于平台的东西(它比 Cocoa 更底层、更灵活,而且我们不需要是 64 位)。

看来 GTK 在 Carbon 将键盘事件作为命令调度之前就吞噬了所有键盘事件。这是有道理的,因为 Carbon 命令没有映射到 GTK 世界。一般来说,这不是问题,因为我们有一个全局按键事件处理程序,并通过我们自己的命令系统调度所有内容。然而,这似乎阻止了 Cmd-?打开帮助搜索菜单,我找不到以编程方式执行此操作的方法。

菜单管理器的 MenuSelect 功能很有前途,但我还没有找到一种自动确定坐标的方法,并且由于某种原因,它只有在我按两次组合键时才起作用......

或者,一种调度 Cmd- 的方法?击键到 Carbon 的命令处理或直接合成命令事件会很好,但我在该领域没有任何运气。

Carbon的ProcessHICommand在没有命令ID的情况下没有任何用处,我无法弄清楚它是什么(如果有的话)

关于Cocoa,我可以掌握NSWindow并调用InterpretKeyEvents,但我还没有成功合成 NSEvent - 它只是发出蜂鸣声。我使用的事件是

var evt = NSEvent.KeyEvent (NSEventType.KeyDown, System.Drawing.PointF.Empty,
    NSEventModifierMask.CommandKeyMask | NSEventModifierMask.ShiftKeyMask,
    0, win.WindowNumber, NSGraphicsContext.CurrentContext, "?", "?",
    false, (ushort) keycode);

Keycode 根据 GTK 键映射确定为 44。我使用普通的 MonoMac (Cocoa) 应用程序确认键码是正确的,但 InterpretKeyEvents 也不适用于该应用程序中的事件。我找不到与该命令关联的任何选择器。

I'm integrating a GTK# application into Mac OS X. GTK on Mac OS X is a wrapper over some Cocoa and Carbon fundamentals. We have some platform-specific stuff directly using Carbon global menu APIs (it's more low-level and flexible than Cocoa, and we don't need to be 64-bit).

It seems that GTK swallows up all the keyboard events before Carbon dispatches them as commands. This makes sense, because there is no mapping of Carbon commands into the GTK world. In general, this isn't a problem, because we have a global key event handler and dispatch everything via our own command system. However, this seems to be preventing Cmd-? from opening the Help search menu, and I cannot find a way to do this programmatically.

Menu Manager's MenuSelect function is promising, but I haven't figured out a way to determine the coordinate automatically, and for some reason it only works when I hit the combination twice...

Alternatively, a way to dispatch the Cmd-? keystroke to Carbon's command handling or synthesize the command event directly would be good, but I haven't had any luck in that area.

Carbon's ProcessHICommand isn't any use without a command ID and I can't figure out what it is (if there is one)

Regarding Cocoa, I can get hold of the NSWindow and call InterpretKeyEvents, but I haven't had any luck success synthesizing the NSEvent - it just beeps. The event I'm using is

var evt = NSEvent.KeyEvent (NSEventType.KeyDown, System.Drawing.PointF.Empty,
    NSEventModifierMask.CommandKeyMask | NSEventModifierMask.ShiftKeyMask,
    0, win.WindowNumber, NSGraphicsContext.CurrentContext, "?", "?",
    false, (ushort) keycode);

Keycode is determined from a GTK keymap to be 44. I confirmed that the keycode was correct using a plain MonoMac (Cocoa) app but InterpretKeyEvents did not work with the event in that app either. And I can't find any selector associated with the command.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

甜宝宝 2024-10-09 19:48:51

您可以使用辅助功能 API 来假装按下菜单项。

NSString *helpMenuTitle = [[[[NSApplication sharedApplication] mainMenu] itemWithTag:HELP_MENU_TAG] title];
AXUIElementRef appElement = AXUIElementCreateApplication(getpid());
AXUIElementRef menuBar;
AXError error = AXUIElementCopyAttributeValue(appElement,
                                              kAXMenuBarAttribute,
                                              (CFTypeRef *)&menuBar);
if (error) {
    return;
}

CFIndex count = -1;
error = AXUIElementGetAttributeValueCount(menuBar, kAXChildrenAttribute, &count);
if (error) {
    CFRelease(menuBar);
    return;
}

NSArray *children = nil;
error = AXUIElementCopyAttributeValues(menuBar, kAXChildrenAttribute, 0, count, (CFArrayRef *)&children);
if (error) {
    CFRelease(menuBar);
    return;
}

for (id child in children) {
    AXUIElementRef element = (AXUIElementRef)child;
    id title;
    AXError error = AXUIElementCopyAttributeValue(element,
                                                  kAXTitleAttribute,
                                                  (CFTypeRef *)&title);
    if ([title isEqualToString:helpMenuTitle]) {
        AXUIElementPerformAction(element, kAXPressAction);
        CFRelease(title);
        break;
    }
    CFRelease(title);
}
CFRelease(menuBar);
[children release];

You can use accessibility APIs to fake a press on the menu item.

NSString *helpMenuTitle = [[[[NSApplication sharedApplication] mainMenu] itemWithTag:HELP_MENU_TAG] title];
AXUIElementRef appElement = AXUIElementCreateApplication(getpid());
AXUIElementRef menuBar;
AXError error = AXUIElementCopyAttributeValue(appElement,
                                              kAXMenuBarAttribute,
                                              (CFTypeRef *)&menuBar);
if (error) {
    return;
}

CFIndex count = -1;
error = AXUIElementGetAttributeValueCount(menuBar, kAXChildrenAttribute, &count);
if (error) {
    CFRelease(menuBar);
    return;
}

NSArray *children = nil;
error = AXUIElementCopyAttributeValues(menuBar, kAXChildrenAttribute, 0, count, (CFArrayRef *)&children);
if (error) {
    CFRelease(menuBar);
    return;
}

for (id child in children) {
    AXUIElementRef element = (AXUIElementRef)child;
    id title;
    AXError error = AXUIElementCopyAttributeValue(element,
                                                  kAXTitleAttribute,
                                                  (CFTypeRef *)&title);
    if ([title isEqualToString:helpMenuTitle]) {
        AXUIElementPerformAction(element, kAXPressAction);
        CFRelease(title);
        break;
    }
    CFRelease(title);
}
CFRelease(menuBar);
[children release];
尾戒 2024-10-09 19:48:51

您可以通过从 C / Objective-C 调用 AppleScript (GUI) 脚本 ,这本质上就像用户所做的那样,通过用户的指向和单击来以编程方式打开帮助菜单。

You could do this via calling from C / Objective-C a AppleScript (GUI) script , that would essentially do the pointing and clicking of a user just as a user would do, to open the help menu program-matically.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文