2009-04-10 9 views
6

Je développe une extension de PsychToolbox de MATLAB qui permet un meilleur contrôle de la souris pendant les expériences psychophysiques (en particulier, en empêchant les limites de l'écran de limiter les opérations de traînée ... comme vous pouvez déplacer la souris "infiniment" dans toutes les directions). Puisque MATLAB ne supporte pas la création de threads supplémentaires (ce qui serait inutilement compliqué pour cette situation de toute façon), je ne peux pas utiliser les gestionnaires d'événements Carbon ou Cocoa.Mac OS X: CGGetLastMouseDelta et déplacement de la souris par programme

CGGetLastMouseDelta est presque parfait pour ce que je dois faire (il me reçoit le montant de la souris est déplacé « depuis le dernier événement de mouvement de la souris reçue par l'application » en ignorant les limites de l'écran), mais il y a un léger problème. Lorsque vous déplacez la souris par programmation (en utilisant CGWarpMouseCursorPosition ou CGDisplayMoveCursorToPoint), aucun événement n'est généré. Par conséquent, CGGetLastMouseDelta ne semble pas être conscient que la souris a bougé du tout. En d'autres termes, si je déplace la souris de 50 pixels par dessus et de 50 pixels par programmation, CGGetLastMouseDelta renvoie (0, 0) après pour le delta de la souris. C'est un comportement indésirable dans mon contexte, et nécessite des solutions de contournement laids. J'ai essayé de déplacer la souris en affichant des événements à travers le système d'événements, comme suit (ce qui est un « mexFunction », la manière de Matlab d'appeler du code 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); 
} 

Cela déplace joyeusement la souris, mais qui ne fonctionne pas semblent changer le comportement de CGGetLastMouseDelta du tout. Est-ce que quelqu'un connaît les spécifications exactes concernant ce qui est retourné par CGGetLastMouseDelta (et quand?). La documentation d'Apple sur ce sujet (la référence Quartz) est comme d'habitude proche de l'inutile (ou du moins, manque de détails nécessaires).

Merci!

Répondre

2

Une bonne idée pourrait être d'utiliser CGAssociateMouseAndMouseCursorPosition(0) pour déconnecter le mouvement de la souris du curseur. Ensuite, vous n'obtenez pas le problème avec les limites de l'écran.

0

Option (1) Générez votre propre événement qui spécifie que vous avez provoqué le déplacement de la souris.
Option (2) Appelez votre souris déplacé la fonction de gestionnaire d'événements du J'ai déplacé la souris routine.