Pracuję nad aplikacją pisania na klawiaturze dla systemu Mac OSX, która musi mieć przekierowane do niej klawisze, nawet gdy aplikacja nie jest aktywna.OSX: wykrywanie zdarzeń keyDown obejmujących cały system?
Czy istnieje sposób, aby system przesuwał do przodu sekwencje klawiszy, prawdopodobnie poprzez NSDistributedNotificationCenter? Mam google sobie głupie, i nie były w stanie znaleźć odpowiedź ...
EDIT:Przykładowy kod poniżej.
Dzięki @NSGod za skierowanie mnie we właściwym kierunku - skończyło się na dodaniu global events monitor przy użyciu metody addGlobalMonitorForEventsMatchingMask: handler :, która działa pięknie. Dla kompletności, moja realizacja wygląda następująco:
// register for keys throughout the device...
[NSEvent addGlobalMonitorForEventsMatchingMask:NSKeyDownMask
handler:^(NSEvent *event){
NSString *chars = [[event characters] lowercaseString];
unichar character = [chars characterAtIndex:0];
NSLog(@"keydown globally! Which key? This key: %c", character);
}];
Dla mnie najtrudniejsza część została przy użyciu bloków, więc dam trochę opis w przypadku, gdy ktoś pomaga:
Rzeczą godną uwagi o powyższy kod jest taki, że to wszystko pojedyncza metoda wywołania na NSEvent. Blok jest dostarczany jako argument, bezpośrednio do funkcji. Można by pomyśleć, że jest to metoda inline delegate. Tylko dlatego, że to trwało długo zatopić się za mnie, idę do pracy przez to krok po kroku tutaj:
[NSEvent addGlobalMonitorForEventsMatchingMask:NSKeyDownMask
Ten pierwszy bit nie jest problemem. Nazywasz metodę klasy w NSEvent i mówisz, które zdarzenie chcesz monitorować, w tym przypadku NSKeyDownMask. A list of masks for supported event types można znaleźć here.
Teraz dochodzimy do skomplikowanej części: obsługi, która spodziewa się blok:
handler:^(NSEvent *event){
zajęło mi kilka kompilacji błędów, aby uzyskać to prawo, ale (dziękuję Apple) były bardzo konstruktywne błąd wiadomości. Pierwszą rzeczą, którą należy zauważyć, jest karat ^. To sygnalizuje początek bloku. Następnie w nawiasach podano deklarację zmiennej, która będzie używana w bloku do przechwytywania zdarzenia. Można to nazwać, nie ma znaczenia, po prostu użyjesz tej nazwy w bloku. W takim razie wszystko jest w porządku. Pamiętaj, aby zamknąć nawias klamrowy i wspornik, aby zakończyć wywołanie metody:
}];
I gotowe! To naprawdę jest rodzaj "jednego liniowca". Nie ma znaczenia, gdzie wykonasz połączenie wewnątrz aplikacji - robię to w aplikacji AppDelegate applicationDidFinishLaunching. Następnie w ramach bloku możesz wywoływać inne metody z poziomu swojej aplikacji.
Hej @Pirripli dzięki bardzo za wyjaśnienie blok składnia dla mnie. NAPRAWDĘ pomaga tym, którzy się uczą! Świetnie spisuje się przy okazji :) – lab12
Bez problemu. ;) Zawsze jestem wdzięczny, gdy inni robią to dla mnie, więc staram się pomóc, kiedy mogę. –
Kiedy próbuję tego bloku kodu, pojawia się błąd: "Niezgodne typy wskaźnika bloku wysyłającego" void (^) (struct NSEvent *) "do parametru typu void (^) (NSEvent *)" w deklaracji - @Pirripli , Czy zapomniałem coś dodać? Czy musisz dodać coś specjalnego do obsługi składni blokowej? [Screenshot] (https://img.skitch.com/20111024-tnmnka59j9fqn6u145g2jppk5d.png) – Tronathan