2010-12-19 10 views
5

Aktualizuję (powtarza?) Aplikację napisaną dla 10.6+ do pracy w 10.5+. Mam problem z przechwytywaniem aktualnie wciśniętego przycisku myszy w selektorze -(void)menuWillOpen:(NSMenu *);.Naciśnięty przycisk myszy NSMenu w 10.5

Dla 10.6+ Korzystam z [NSEvent pressedMouseButtons], która pozwala mi uzyskać wciśnięty przycisk poza strumieniem zdarzeń. Jednak ten nie istnieje w 10.5+ (wydaje się, że trzeba zadzwonić [theEvent buttonNumber]

Jak przechwycić wciśnięty przycisk myszy (prawy lub lewy).

  1. Wewnątrz mojego delegata NSMenu
  2. Korzystnie wewnątrz selektora
  3. w dworku, który działa zarówno 10.5+ i 10.6+
  4. -(void)menuWillOpen:(NSMenu *)menu

naprawdę doceniam pomoc i wiem, StackOverflow pomoże nowego programatora Objective-C!

Dzięki Dustin

+0

to jest najlepszy sposób to zrobić, ale można po prostu użyć [[NSApp currentEvent] buttonNumber].NSApp to globalna zmienna wskazująca obiekt aplikacji. – ughoavgfhw

+0

Dustin Senos: Powinieneś opublikować to jako odpowiedź na własne pytanie. Załatwię to. –

Odpowiedz

6

W końcu udało mi się bieżący przycisk myszy poprzez wywołanie (dzięki Nick Paulson za pomoc):

[[[NSApplication sharedApplication] currentEvent] buttonNumber]

Jak ughoavgfhw wskazał krótszą drogę ściągam to samo wydarzenie jest jednak:

[[NSApp currentEvent] buttonNumber]

+1

Chciałbym dodać do tej odpowiedzi dla tych, którzy dodają wsparcie dla starszych maszyn. Upewnij się, że nie sprawdzasz tylko prawego przycisku myszy (który może, ale nie musi istnieć na starszej maszynie), ale sprawdzasz, czy użytkownik trzyma klawisz kontrolny podczas klikania (często używany na starszych komputerach do przełączania menu kontekstowego): 'if ([[NSApp currentEvent] modifierFlags] & NSControlKeyMask) {... wykonaj kod}' –

2

Innym sposobem byłoby stworzenie CGEventTap który przechwytuje myszy wydarzenia.
Następnie wystarczy pamiętać o ostatnim typie zdarzenia i sprawdzić, czy w jednej z metod delegowania NSMenu.
Oto przykładowy kod:

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 docs stwierdzają, że:

zawory imprez otrzymać w góre i klucz dół wydarzeń, jeśli jeden z następujących warunków jest spełniony:

  • Bieżący proces działa jako użytkownik root .
  • Dostęp do urządzeń pomocniczych jest włączony. W systemie Mac OS X 10.4, można włączyć tę funkcję, korzystając z opcji Preferencje systemowe, Uniwersalny dostęp , Widok uniwersalny , Widok klawiatury.

dwukrotnym sprawdzeniu, i wydaje się, że naprawdę nie trzeba włączyć urządzeń wspomagających do odbierania zdarzeń myszy.

Ale jeśli [[[NSApplication sharedApplication] currentEvent] buttonNumber] robi to, co chcesz, zdecydowanie bym z tym. Jest to wyższy poziom, a zatem mniej kodu.

+0

Naprawdę doceniam pomoc/kod weichsel, zawsze dobrze jest zobaczyć różne podejścia do tego samego problemu. Tak jak powiedziałeś, podejście '[NSApplication sharedApplication]' robi to, co chcę, i jest na wyższym poziomie, więc na razie będę z nim pracował. –

+0

To bardzo pomogło. Dzięki! –

Powiązane problemy