2009-09-05 8 views
11

DokunmalarınBeganWithEvent, touchEndedWithEvent, vb kullanılarak, dokunma verilerini çok dokunuşlu izleme panelinden alabilirsiniz, ancak bu dokunma verilerinin fareyi hareket ettirmesini/sistem genelindeki hareketleri etkinleştirmesini engellemenin bir yolu var mı? Çince metin girişinde ne yapılır?Tüm çok dokunuşlu izleme paneli girişini Cocoa'da yakalama

+1

Kabul edilen yanıtı güncellemeyi öneriyorum. – ArtOfWarfare

cevap

6

:

Bu gibi bazı kod gerekiyordu. Tarmes ayrıca Rob Keniger'in cevabının artık çalışmadığını not ediyor (OS X> = 10.8). Neyse ki, Apple kCGEventMaskForAllEvents kullanarak ve geri arama içinde NSEvent için CGEventRef dönüştürerek oldukça kolay bunu yapmanın bir yolunu sağlamıştır:

NSEventMask eventMask = NSEventMaskGesture|NSEventMaskMagnify|NSEventMaskSwipe|NSEventMaskRotate|NSEventMaskBeginGesture|NSEventMaskEndGesture; 

CGEventRef eventTapCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef eventRef, void *refcon) { 
    // convert the CGEventRef to an NSEvent 
    NSEvent *event = [NSEvent eventWithCGEvent:eventRef]; 

    // filter out events which do not match the mask 
    if (!(eventMask & NSEventMaskFromType([event type]))) { return [event CGEvent]; } 

    // do stuff 
    NSLog(@"eventTapCallback: [event type] = %d", [event type]); 

    // return the CGEventRef 
    return [event CGEvent]; 
} 

void initCGEventTap() { 
    CFMachPortRef eventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, kCGEventTapOptionListenOnly, kCGEventMaskForAllEvents, eventTapCallback, nil); 
    CFRunLoopAddSource(CFRunLoopGetCurrent(), CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0), kCFRunLoopCommonModes); 
    CGEventTapEnable(eventTap, true); 
    CFRunLoopRun(); 
} 

Not bu pasajı, bir projeden alındıktan sonra CFRunLoopRun() çağrısı dahil olduğunu hangi NSApplication kullanamadı, ancak bir çıplak kemikleri CFRunLoop vardı. NSApplication kullanırsanız atlayın.

2

GÜNCELLEME: aşağıda yanıtım artık çalışmıyor. Cevap here'a bakın.

Genellikle bunu yapmak için, Dokunmatik Olaylar CGEvent API'si tarafından "resmi olarak" desteklenmiyor gibi görünmekle birlikte, bir Quartz Etkinlik Dokunuşu kullanmanız gerekir. NSEvent.h'deki multitouch olmayan olay türleri, CGEventTypes.h'deki CGEvent türleriyle eşleşiyor gibi görünüyor, bu nedenle çok dokunuşlu olanlar muhtemelen belgelenmemiş olsalar bile çalışır. ilerleyen olayları engellemek amacıyla

, olay musluk geri çağırma gelen NULL dönmek gerekir. CGEventTap için yazarlardan NSEventMask kullanılarak, valexa tarafından belirtildiği gibi

#import <ApplicationServices/ApplicationServices.h> 

//assume CGEventTap eventTap is an ivar or other global 

void createEventTap(void) 
{ 
CFRunLoopSourceRef runLoopSource; 

//listen for touch events 
//this is officially unsupported/undocumented 
//but the NSEvent masks seem to map to the CGEvent types 
//for all other events, so it should work. 
CGEventMask eventMask = (
    NSEventMaskGesture  | 
    NSEventMaskMagnify  | 
    NSEventMaskSwipe   | 
    NSEventMaskRotate  | 
    NSEventMaskBeginGesture | 
    NSEventMaskEndGesture 
); 

// Keyboard event taps need Universal Access enabled, 
// I'm not sure about multi-touch. If necessary, this code needs to 
// be here to check whether we're allowed to attach an event tap 
if (!AXAPIEnabled()&&!AXIsProcessTrusted()) { 
    // error dialog here 
    NSAlert *alert = [[[NSAlert alloc] init] autorelease]; 
    [alert addButtonWithTitle:@"OK"]; 
    [alert setMessageText:@"Could not start event monitoring."]; 
    [alert setInformativeText:@"Please enable \"access for assistive devices\" in the Universal Access pane of System Preferences."]; 
    [alert runModal]; 
    return; 
} 


//create the event tap 
eventTap = CGEventTapCreate(kCGHIDEventTap, //this intercepts events at the lowest level, where they enter the window server 
     kCGHeadInsertEventTap, 
     kCGEventTapOptionDefault, 
     eventMask, 
     myCGEventCallback, //this is the callback that we receive when the event fires 
     nil); 

// Create a run loop source. 
runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0); 

// Add to the current run loop. 
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes); 

// Enable the event tap. 
CGEventTapEnable(eventTap, true); 
} 


//the CGEvent callback that does the heavy lifting 
CGEventRef myCGEventCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef theEvent, void *refcon) 
{ 
//handle the event here 
//if you want to capture the event and prevent it propagating as normal, return NULL. 

//if you want to let the event process as normal, return theEvent. 
return theEvent; 
} 
+0

aslında ne CGEventMasks için NSEventMasks haritası olanlara maske ayarı kCGEventMaskForAllEvents için maske ayarı ile aynı olduğunu olduğunu yanlıştır ve sonuç trackpad üzerinde her dokunuş için NSEventTypeGesture sadece olayların bir buhar oluyor baskılanması var NULL'ı geri döndürerek gerçekten herhangi bir hareketi engeller. – valexa

+0

Bu çalışmayı 10.8'nin altında çalıştırmayı denedim ve işe yaramıyor gibi görünüyor - hareketler artık EventTap üzerinden geçmiyor. Başka bir çözüm buldunuz sanmıyorum? – tarmes

+0

-1: 10.8'in altında çalışmıyor. Bunun yerine şu cevabı kullanmanızı öneriyorum: http://stackoverflow.com/a/13755292/901641 – ArtOfWarfare

İlgili konular