选择popUpContextMenu中的第一项

时间:2010-07-07 17:35:04

标签: cocoa contextmenu macos-carbon nsmenu nsmenuitem

我在一个非常键盘密集的应用程序上工作。双手放在键盘上。没有手放在鼠标上。

用户可以通过键盘弹出上下文菜单,选择一个项目,最后点击回车。

[NSMenu popUpContextMenu]显示菜单而不突出显示任何项目。用户必须按一次arrow_down才能突出显示第一个项目。

我的一位朋友发现,每次使用此菜单时都必须按arrow_down 建议我删除此步骤,以便在弹出菜单时始终突出显示第一个项目。

我怀疑它需要碳黑?

如何以编程方式突出显示第一项?


我使用此代码弹出菜单。

NSEvent* event = [NSEvent otherEventWithType:NSApplicationDefined
    location:location 
    modifierFlags:0 
    timestamp:0
    windowNumber:[[self window] windowNumber]
    context:[[self window] graphicsContext]
    subtype:100
    data1:0
    data2:0
];
[NSMenu popUpContextMenu:menu withEvent:event forView:self];

更新:我尝试在popUpContextMenu之后立即向我的应用发送一个arrow_down事件,但是当菜单可见时不会执行该事件。 (事件在菜单消失后执行)。

unichar code = NSDownArrowFunctionKey;
NSString* chars = [NSString stringWithFormat: @"%C", code];
NSEvent* event = [NSEvent keyEventWithType:NSKeyDown location:location modifierFlags:0 timestamp:0 windowNumber:[[self window] windowNumber] context:[[self window] graphicsContext] characters:chars charactersIgnoringModifiers:chars isARepeat:NO keyCode:code];
[NSApp sendEvent:event];

2 个答案:

答案 0 :(得分:0)

我找到了原始问题的答案。但它有问题,我认为_NSGetCarbonMenu()是解决它们所必需的。

  1. 问题:如何绘制菜单 item它看起来像一个原生菜单 项目?
  2. 问题:如何制作 自定义视图表现为普通 menuitem ..现在你必须 按两次arrow_down得到 选择下一个项目。
  3. 如何解决这些问题?

    @interface MyMenuItem : NSView {
        BOOL m_active;
    }
    @end
    
    @implementation MyMenuItem
    - (BOOL)acceptsFirstResponder { return YES; }
    - (BOOL)becomeFirstResponder { m_active = YES; return YES; }
    - (BOOL)resignFirstResponder { m_active = NO; return YES; }
    
    - (void)viewDidMoveToWindow { [[self window] makeFirstResponder:self]; }
    
    - (void)drawRect:(NSRect)rect {
        if(m_active) {
            [[NSColor blueColor] set];
        } else {
            [[NSColor blackColor] set];
        }
        NSRectFill(rect);
    }
    @end
    
    
    // this makes sure the first item gets selected when the menu popups
    MyMenuItem* view = [[[MyMenuItem alloc] initWithFrame:NSMakeRect(0, 0, 100, 20)] autorelease];
    [view setAutoresizingMask:NSViewWidthSizable];
    NSMenuItem* item = [menu itemAtIndex:0];
    [item setView:view];
    [NSMenu popUpContextMenu:menu withEvent:event forView:self];
    

    解决了!忘了上面的所有东西。我刚刚找到了一个不需要碳的优雅解决方案。

    // simulate a key press of the arrow-down key
    CGKeyCode key_code = 125;  // kVK_DownArrow = 125
    CGEventRef event1, event2;
    event1 = CGEventCreateKeyboardEvent(NULL, key_code, YES);
    event2 = CGEventCreateKeyboardEvent(NULL, key_code, NO);
    CGEventPost(kCGSessionEventTap, event1);
    CGEventPost(kCGSessionEventTap, event2);
    CFRelease(event1);
    CFRelease(event2);
    
    [NSMenu popUpContextMenu:menu withEvent:event forView:self];
    

答案 1 :(得分:0)

对于记录,如果您的目标是10.6及更高版本,请不要使用类方法popUpContextMenu,请使用实例的popUpMenuPositioningItem:atLocation:inView:。 如果您指定positioningItem,则会自动选择它。当然,您需要重新计算相对于所选项目的位置。