Программно открыть меню справки Mac

Я интегрирую приложение GTK # в Mac OS X. GTK на Mac OS X является оберткой над некоторыми Cocoa и углеродными принципами. У нас есть некоторые специфичные для платформы вещи, непосредственно использующие глобальные API-интерфейсы Carbon (он более низкоуровневый и гибкий, чем Cocoa, и нам не нужно быть 64-битным).

Кажется, что GTK поглощает все события клавиатуры, прежде чем Carbon отправит их в виде команд. Это имеет смысл, потому что в GTK нет отображения команд Carbon. В общем, это не проблема, потому что у нас есть глобальный обработчик ключевых событий и отправка всего через нашу собственную систему команд. Однако это, по-видимому, предотвращает Cmd-? от открытия меню поиска справки, и я не могу найти способ сделать это программно.

Функция меню MenuSelect многообещающая, но я не выяснил способ автоматического определения координат, и по какой-то причине он работает только, когда я дважды нажимаю комбинацию...

Альтернативно, способ отправки Cmd-? нажатие клавиши на команду Carbon или синтезирование командного события было бы неплохо, но мне не повезло в этой области.

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);

Keycode определяется из карты ключей GTK как 44. Я подтвердил, что код ключа был прав с использованием простого приложения MonoMac (Cocoa), но InterpretKeyEvents также не работали с событием в этом приложении. И я не могу найти какой-либо селектор, связанный с командой.

Ответы

Ответ 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];

Ответ 2

Вы можете сделать это, вызвав из C/ Objective-C a AppleScript (GUI) script, который будет по существу выполнять указания и щелкнув пользователя так же, как пользователь, чтобы открыть программу меню справки.