【问题标题】:How can i pop up NSMenu at mouse cursor position?如何在鼠标光标位置弹出 NSMenu?
【发布时间】:2012-01-27 12:55:31
【问题描述】:

我想通过在鼠标光标位置显示NSMenu 来响应热键按下。

我的应用程序是UIElement,没有自己的窗口。

我知道有NSMenu的方法:

-(void)popUpContextMenu:(NSMenu *)menu
              withEvent:(NSEvent *)event
                forView:(NSView *)view;

但是在没有视图的情况下似乎不起作用:(。

我应该在鼠标光标位置创建一个假的透明视图,然后在那里显示NSMenu,还是有更好的方法?

可以用 Carbon 实现吗?

【问题讨论】:

  • 你试过创建一个假的透明视图吗?会发生什么?
  • @RobKeniger - 我已经发布了解决方案。它有效。

标签: cocoa nsview nsmenu


【解决方案1】:

改用这个:

  [theMenu popUpMenuPositioningItem:nil atLocation:[NSEvent mouseLocation] inView:nil];

【讨论】:

    【解决方案2】:

    这是使用透明窗口的解决方案:

    + (NSMenu *)defaultMenu {
        NSMenu *theMenu = [[[NSMenu alloc] initWithTitle:@"Contextual Menu"] autorelease];
        [theMenu insertItemWithTitle:@"Beep" action:@selector(beep:) keyEquivalent:@"" atIndex:0];
        [theMenu insertItemWithTitle:@"Honk" action:@selector(honk:) keyEquivalent:@"" atIndex:1];
        return theMenu;
    }
    
    - (void) hotkeyWithEvent:(NSEvent *)hkEvent 
    {
        NSPoint mouseLocation = [NSEvent mouseLocation];
    
        // 1. Create transparent window programmatically.
    
        NSRect frame = NSMakeRect(mouseLocation.x, mouseLocation.y, 200, 200);
        NSWindow* newWindow  = [[NSWindow alloc] initWithContentRect:frame
                                                         styleMask:NSBorderlessWindowMask
                                                           backing:NSBackingStoreBuffered
                                                             defer:NO];
        [newWindow setAlphaValue:0];
        [newWindow makeKeyAndOrderFront:NSApp];
    
        NSPoint locationInWindow = [newWindow convertScreenToBase: mouseLocation];
    
        // 2. Construct fake event.
    
        int eventType = NSLeftMouseDown;
    
        NSEvent *fakeMouseEvent = [NSEvent mouseEventWithType:eventType 
                                                     location:locationInWindow
                                                modifierFlags:0
                                                    timestamp:0
                                                 windowNumber:[newWindow windowNumber]
                                                      context:nil
                                                  eventNumber:0
                                                   clickCount:0
                                                     pressure:0];
        // 3. Pop up menu
        [NSMenu popUpContextMenu:[[self class]defaultMenu] withEvent:fakeMouseEvent forView:[newWindow contentView]];
    

    }

    它有效,但我仍在寻找更优雅的解决方案。

    【讨论】:

    • 您找到更好的解决方案了吗?
    • @Wesley 不幸的是没有。在许多项目中仍在使用它:(
    • 这似乎更好一些? [theMenu popUpMenuPositioningItem:nil atLocation:[NSEvent mouseLocation] inView:nil];
    • 哇 :) 在方法描述中看起来不错且正确。 “如果 view 为 nil,则在屏幕坐标系中解释位置。这允许您弹出与任何窗口断开连接的菜单。”谢谢。
    • @Wesley 太棒了的回答!你为我节省了很多时间... :-)
    猜你喜欢
    • 2017-03-28
    • 2012-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多