2009-04-10 8 views
6

Ich entwickle eine Erweiterung zu MATLABs PsychToolbox, die eine bessere Kontrolle der Maus während psychophysikalischer Experimente erlaubt (insbesondere verhindert man, dass die Bildschirmgrenzen den Ziehvorgang einschränken, sollte es sich anfühlen) wie Sie können die Maus "unendlich" in alle Richtungen bewegen. Da MATLAB die Erstellung zusätzlicher Threads nicht unterstützt (und das wäre ohnehin unnötig kompliziert), kann ich weder die Carbon- noch die Cocoa-Event-Manager verwenden.Mac OS X: CGGetLastMouseDelta und Bewegen der Maus programmatisch

CGGetLastMouseDelta ist fast perfekt für das, was ich tun muss (es wird mir die Menge der Maus „seit der letzten Mausbewegung Ereignis empfangen durch die Anwendung“ ignoriert Bildschirm Grenzen bewegt hat), jedoch gibt es ein kleines Problem. Wenn Sie die Maus programmgesteuert (mit CGWarpMouseCursorPosition oder CGDisplayMoveCursorToPoint) bewegen, werden keine Ereignisse generiert. Daher scheint CGGetLastMouseDelta nicht bewusst zu sein, dass sich die Maus überhaupt bewegt hat. Mit anderen Worten: Wenn ich die Maus programmgesteuert 50 Pixel über und 50 Pixel nach unten bewege, gibt CGGetLastMouseDelta danach (0, 0) für das Maus-Delta zurück. Dies ist unerwünschtes Verhalten in meinem Kontext und erfordert hässliche Problemumgehungen. Ich habe versucht, die Maus zu bewegen, indem Ereignisse durch das Ereignissystem veröffentlichen, wie folgt (dies ist eine „mexFunction“, MATLAB Weg C-Code des Anrufers):

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { 
    CGEventRef event; 
    CGPoint offset; 
    CGPoint currentLocation; 
    CGPoint newLocation; 

    if (nrhs != 2) 
     mexErrMsgTxt("The global x and y coordinates (and only those) must be supplied."); 

    event = CGEventCreate(NULL); 
    currentLocation = CGEventGetLocation(event); 
    CFRelease(event); 

    offset = CGPointMake((CGFloat) mxGetScalar(prhs[0]), (CGFloat) mxGetScalar(prhs[1])); 
    newLocation = CGPointMake(currentLocation.x + offset.x, currentLocation.y + offset.y); 

    event = CGEventCreateMouseEvent(NULL, kCGEventMouseMoved, newLocation, kCGMouseButtonLeft); 
    CGEventPost(kCGHIDEventTap, event); 
    CFRelease(event); 
} 

Dies bewegt glücklich die Maus, aber nicht scheinen das Verhalten von CGGetLastMouseDelta überhaupt zu verändern. Kennt jemand die genauen Spezifikationen, was von CGGetLastMouseDelta (und wann?) Zurückgegeben wird. Apples Dokumentation zu diesem Thema (die Quarz-Referenz) ist wie üblich fast nutzlos (oder zumindest fehlt es an notwendigen Details).

Danke!

Antwort

2

Eine gute Idee könnte sein, CGAssociateMouseAndMouseCursorPosition(0) zu verwenden, um die Mausbewegung vom Cursor zu trennen. Dann bekommst du das Problem mit Bildschirmgrenzen nicht.

0

Option (1) Generieren Sie Ihr eigenes Ereignis, das angibt, dass Sie die Maus bewegt haben.
Option (2) Rufen Sie Ihre Maus bewegte Event-Handler-Funktion von der Ich bewegte die Maus Routine.