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

Mik*_*son 15 gtk macos mono cocoa macos-carbon

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

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

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

或者,一种方式来发送Cmd-?对Carbon的命令处理进行击键或直接合成命令事件会很好,但我在那方面没有运气.

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

关于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);
Run Code Online (Sandbox Code Playgroud)

密钥代码是从GTK密钥映射确定为44.我使用普通的MonoMac(Cocoa)应用程序确认密钥代码是正确的,但是InterpretKeyEvents也不适用于该应用程序中的事件.我找不到与该命令相关的任何选择器.

Geo*_*rge 1

您可以使用辅助功能 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];
Run Code Online (Sandbox Code Playgroud)