NSMenu нажал кнопку мыши в 10.5

Я обновляю (удаляю?) приложение, написанное для версии 10.6+, чтобы оно работало в версии 10.5+. Я изо всех сил пытаюсь захватить текущую нажатую кнопку мыши в селекторе -(void)menuWillOpen:(NSMenu *);.

Для версии 10.6+ я использую преимущества [NSEvent pressedMouseButtons]. что позволяет мне получить нажатую кнопку вне потока событий. Однако этого нет в 10.5+ (кажется, мне нужно вызвать [theEvent buttonNumber].

Как зафиксировать нажатую кнопку мыши (правую или левую):

  1. Внутри моего делегата NSMenu
  2. Желательно внутри селектора -(void)menuWillOpen:(NSMenu *)menu
  3. В поместье, которое работает как в 10.5+, так и в 10.6+

Я очень ценю помощь и знаю, что StackOverflow поможет новому программисту на Objective-C!

Спасибо, Дастин


person Dustin Senos    schedule 19.12.2010    source источник
comment
Это лучший способ сделать это, но вы можете просто использовать [[NSApp currentEvent] buttonNumber]. NSApp — это глобальная переменная, указывающая на объект приложения.   -  person ughoavgfhw    schedule 19.12.2010
comment
Дастин Сенос: Вы должны опубликовать это как ответ на свой вопрос. Я бы проголосовал за это.   -  person Peter Hosey    schedule 19.12.2010


Ответы (2)


В конце концов я смог получить текущую кнопку мыши, позвонив (спасибо Nick Paulson за помощь):

[[[NSApplication sharedApplication] currentEvent] buttonNumber]

Как указал ughoavgfhw, более короткий способ получения того же события:

[[NSApp currentEvent] buttonNumber]

person Dustin Senos    schedule 19.12.2010
comment
Хотел добавить к этому ответу тех, кто добавляет поддержку старых машин. Убедитесь, что вы не просто проверяете правую кнопку мыши (которая может существовать, а может и не существовать на более старой машине), но проверяете, держит ли пользователь клавишу управления при нажатии (часто используется на старых машинах для переключения контекстного меню). ): if ([[NSApp currentEvent] modifierFlags] & NSControlKeyMask) { … do code } - person Dustin Senos; 21.12.2010

Другой способ — создать CGEventTap, который фиксирует события нажатия мыши.
Затем вам просто нужно запомнить последний тип события и проверить его в одном из ваших методов делегата NSMenu.
Вот пример кода:

CGEventRef MouseClickedEventCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void* refcon)
{
    CGPoint location = CGEventGetLocation(event);   
    switch (type) 
    {
        case kCGEventLeftMouseDown:
        {
            NSLog(@"Left Mouse pressed at %@", NSStringFromPoint(NSPointFromCGPoint(location)));
            break;
        }           
        case kCGEventRightMouseDown:
        {
            NSLog(@"Right Mouse pressed at %@", NSStringFromPoint(NSPointFromCGPoint(location)));
            break;
        }   
        case kCGEventOtherMouseDown:
        {
            NSLog(@"Other Mouse pressed at %@", NSStringFromPoint(NSPointFromCGPoint(location)));
            break;          
        }
        default:
            break;
    }
    return event;
}

- (void)applicationDidFinishLaunching:(NSNotification*)aNotification
{
    CGEventMask eventMask = CGEventMaskBit(kCGEventLeftMouseDown)|CGEventMaskBit(kCGEventRightMouseDown)|CGEventMaskBit(kCGEventOtherMouseDown);
    CFMachPortRef eventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, 0, eventMask, MouseClickedEventCallback, NULL);
    CFRunLoopSourceRef runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);
    CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);
    CGEventTapEnable(eventTap, true);
}

Состояние Quartz Event Services тот:

Отводы событий получают события нажатия и нажатия клавиши, если выполняется одно из следующих условий:

  • Текущий процесс выполняется от имени пользователя root.
  • Доступ для вспомогательных устройств включен. В Mac OS X v10.4 вы можете включить эту функцию, используя Системные настройки, панель универсального доступа, режим клавиатуры.

Я дважды проверил это, и кажется, что вам действительно не нужно разрешать вспомогательным устройствам получать события мыши.

Но если [[[NSApplication sharedApplication] currentEvent] buttonNumber] делает то, что вы хотите, я бы точно согласился. Это более высокий уровень и, следовательно, меньше кода.

person Thomas Zoechling    schedule 19.12.2010
comment
Очень ценю помощь/код, всегда приятно видеть разные подходы к одной и той же проблеме. Как вы сказали, подход [NSApplication sharedApplication] делает то, что я хочу, и является более высоким уровнем, поэтому я пока буду использовать его. - person Dustin Senos; 19.12.2010
comment
Это очень помогло. Спасибо! - person Ian Bytchek; 17.03.2017