2009-04-10 7 views
6

Sto sviluppando un'estensione di PsychToolbox di MATLAB che consente un migliore controllo del mouse durante esperimenti psicofisici (in particolare, impedendo ai limiti dello schermo di limitare le operazioni di trascinamento ... dovrebbe come se tu potessi muovere il mouse "infinitamente" in tutte le direzioni). Dato che MATLAB non supporta la creazione di thread aggiuntivi (e che sarebbe comunque inutilmente complicato per questa situazione), non posso utilizzare i gestori di eventi Carbon o Cocoa.Mac OS X: CGGetLastMouseDelta e spostamento del mouse programmaticamente

CGGetLastMouseDelta è quasi perfetto per quello che ho bisogno di fare (mi viene l'importo che il mouse si è spostato "dall'ultimo evento movimento del mouse ricevuto dall'applicazione" ignorando limiti dello schermo), tuttavia c'è un piccolo problema. Quando si sposta il mouse in modo programmatico (utilizzando CGWarpMouseCursorPosition o CGDisplayMoveCursorToPoint), non viene generato alcun evento. Pertanto, CGGetLastMouseDelta non sembra essere consapevole del fatto che il mouse si è spostato del tutto. In altre parole, se sposto il mouse 50 pixel sopra e 50 pixel verso il basso in modo programmatico, CGGetLastMouseDelta restituisce (0, 0) in seguito per il delta del mouse. Questo è un comportamento indesiderato nel mio contesto e richiede brutte soluzioni. Ho provato a spostare il mouse con la pubblicazione di eventi attraverso il sistema di eventi, come segue (si tratta di una "mexFunction", modo di MATLAB di chiamare codice C):

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); 
} 

Questo sposta felicemente il mouse, ma non lo fa sembra cambiare il comportamento di CGGetLastMouseDelta a tutti. Qualcuno conosce le specifiche esatte di ciò che viene restituito da CGGetLastMouseDelta (e quando?). La documentazione di Apple su questa roba (il riferimento al quarzo) è come al solito quasi inutile (o almeno, manca di dettagli necessari).

Grazie!

risposta

2

Una buona idea potrebbe essere quella di utilizzare CGAssociateMouseAndMouseCursorPosition(0) per scollegare il movimento del mouse dal cursore. Quindi non si ottiene il problema con i limiti dello schermo.

0

Opzione (1) Genera il tuo evento che specifica che hai causato il movimento del mouse.
Opzione (2) Chiamare la funzione del gestore di eventi spostata del mouse da Ho spostato la routine del mouse.