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

Cocoa 以编程方式打开Mac帮助菜单,cocoa,macos,mono,gtk,macos-carbon,Cocoa,Macos,Mono,Gtk,Macos Carbon,我正在将一个GTK应用程序集成到Mac OS X中。Mac OS X上的GTK是一些可可和碳基础的包装。我们有一些直接使用碳全球菜单API的特定于平台的东西(它比Cocoa更低级、更灵活,我们不需要64位) 似乎GTK在Carbon将所有键盘事件作为命令发送之前就已经将它们吞没了。这是有道理的,因为没有碳指令映射到GTK世界。一般来说,这不是一个问题,因为我们有一个全局键事件处理程序,并通过我们自己的命令系统分派所有内容。然而,这似乎阻止了Cmd-?从打开“帮助搜索”菜单,我找不到一种以编程方式

我正在将一个GTK应用程序集成到Mac OS X中。Mac OS X上的GTK是一些可可和碳基础的包装。我们有一些直接使用碳全球菜单API的特定于平台的东西(它比Cocoa更低级、更灵活,我们不需要64位)

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

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

或者,一种发送Cmd-?按一下Carbon的命令处理或直接合成命令事件会很好,但我在这方面没有任何运气

Carbon的ProcessHICommand没有命令ID是没有任何用处的,我也不知道它是什么(如果有)

关于Cocoa,我可以控制NSWindow并调用InterpretatKeyEvents,但我没有成功合成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 keymap确定为44。我用一个普通的MonoMac(Cocoa)应用程序确认了keycode是正确的,但解释器KeyEvents也不能与该应用程序中的事件一起工作。我找不到任何与该命令相关联的选择器。

您可以通过从C/Objective-C调用来执行此操作,这基本上可以像用户一样对用户进行指向和单击,以自动打开“帮助”菜单程序。

您可以使用辅助功能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];

用户一直在要求Cmd转换-?按键绑定以打开“帮助搜索”菜单。不知何故,GTK的事件循环阻止了内置处理的工作。对于cocoa事件,您是否尝试过使用“/”而不是“?”。另一方面,您关于碳“比cocoa更低级、更灵活”的说法是错误的。Carbon是一个完全独立的API,旨在与Mac OS 8/9兼容。它已被弃用,维护不善,并没有以任何方式“隐藏”在可可之下。可可实际上比碳更古老,尽管乍一看它更现代。你真的应该使用Cocoa而不是Carbon。那么为什么我会在Cocoa菜单调用堆栈中看到HIToolbox调用呢?很有趣。我猜他们一定是认为碳纤维的菜单比可可粉的要好,所以他们用了它。不过,我不会在一个你将要花很长时间开发的应用程序中使用任何碳API。苹果在Mac OS X的上一个版本中开始认真地远离碳,今天编写碳代码的任何人都应该预料到,在不久的将来,碳代码将需要用Cocoa重新编写。我们实际上找到了另一个解决方案,其中包括修复GTK工具包,这样它就不会拦截键盘,而是让Cocoa来处理。然而,我接受这个答案,因为对于任何愿意依赖可访问性框架的人来说,这是一个很好的解决方案。由于硬编码的"帮助"标题,这将在除英语以外的任何语言中失败。您需要为应用程序主菜单中的“帮助”菜单指定一个标记值,然后获取菜单的实际标题并使用它。