6 Stimmen

Mac OS X: CGGetLastMouseDelta und programmgesteuertes Bewegen der Maus

Ich entwickle eine Erweiterung für die PsychToolbox von MATLAB, die eine bessere Steuerung der Maus bei psychophysikalischen Experimenten ermöglicht (insbesondere soll verhindert werden, dass die Bildschirmgrenzen die Ziehoperationen einschränken... es soll sich so anfühlen, als könne man die Maus "unendlich" in alle Richtungen bewegen). Da MATLAB die Erstellung zusätzlicher Threads nicht unterstützt (und das wäre in dieser Situation ohnehin unnötig kompliziert), kann ich weder den Carbon noch den Cocoa Event Manager nutzen.

CGGetLastMouseDelta ist fast perfekt für das, was ich tun muss (es bekommt mir die Menge der Maus bewegt hat " seit dem letzten von der Anwendung empfangenen Mausbewegungsereignis " ohne Berücksichtigung der Bildschirmgrenzen), jedoch gibt es ein kleines Problem. Wenn Sie die Maus programmatisch bewegen (entweder mit CGWarpMouseCursorPosition oder CGDisplayMoveCursorToPoint), werden keine Ereignisse erzeugt. Daher scheint CGGetLastMouseDelta nicht zu wissen, dass sich die Maus überhaupt bewegt hat. Mit anderen Worten, wenn ich die Maus programmatisch 50 Pixel nach oben und 50 Pixel nach unten bewege, gibt CGGetLastMouseDelta anschließend (0, 0) für das Mausdelta zurück. Dies ist ein unerwünschtes Verhalten in meinem Kontext und erfordert hässliche Workarounds. Ich habe versucht, die Maus durch das Senden von Ereignissen über das Ereignissystem zu bewegen, und zwar wie folgt (dies ist eine "mexFunction", MATLABs Art, C-Code aufzurufen):

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

Dadurch wird die Maus fröhlich bewegt, aber das Verhalten von CGGetLastMouseDelta scheint sich überhaupt nicht zu ändern. Kennt jemand die genauen Spezifikationen bezüglich dessen, was von CGGetLastMouseDelta zurückgegeben wird (und wann?). Apples Dokumentation zu diesem Thema (die Quartz-Referenz) ist wie üblich nahezu unbrauchbar (oder lässt zumindest die notwendigen Details vermissen).

Gracias.

2voto

Johan Kotlinski Punkte 24241

Eine gute Idee wäre die Verwendung von CGAssociateMouseAndMouseCursorPosition(0) um die Mausbewegung vom Cursor zu trennen. Dann haben Sie das Problem mit den Bildschirmgrenzen nicht.

0voto

codeDr Punkte 1397

Option (1) Erzeugen Sie ein eigenes Ereignis, das angibt, dass Sie die Bewegung der Maus verursacht haben.
Option (2) Rufen Sie Ihre Mausbewegungs-Ereignishandlerfunktion von der Ich bewegte die Maus Routine.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X