2009-04-10 24 views
6

Zajmuję się rozszerzeniem do PsychToolbox firmy MATLAB, która pozwala na lepszą kontrolę myszy podczas eksperymentów psychofizycznych (w szczególności, zapobieganie ograniczeniom ekranów przez przeciąganie ... powinno być odczuwalne jak możesz przesuwać mysz "nieskończenie" we wszystkich kierunkach). Ponieważ MATLAB nie obsługuje tworzenia dodatkowych wątków (i tak byłoby to niepotrzebnie skomplikowane w tej sytuacji), nie mogę korzystać z menedżerów zdarzeń Carbon lub Cocoa.Mac OS X: CGGetLastMouseDelta i programowanie myszy

CGGetLastMouseDelta jest niemal idealne do tego co trzeba zrobić (robi mi kwotę mysz została przeniesiona „od ostatniego zdarzenia ruch myszy otrzymanej przez zastosowanie” ignorując granice ekranu), jednak jest jeden mały problem. Podczas przenoszenia myszy programowo (przy użyciu CGWarpMouseCursorPosition lub CGDisplayMoveCursorToPoint), żadne zdarzenia nie są generowane. Dlatego CGGetLastMouseDelta wydaje się nie mieć świadomości, że mysz w ogóle się poruszyła. Innymi słowy, jeśli przesuniemy mysz o 50 pikseli i 50 pikseli w dół programowo, CGGetLastMouseDelta zwróci (0, 0) później dla delty myszy. Jest to niepożądane zachowanie w moim kontekście i wymaga brzydkich obejść. Próbowałem poruszając myszą zamieszczając wydarzenia za pośrednictwem systemu konferencyjnego, w następujący sposób (jest to „mexFunction” sposobem Matlaba wywołania kodu 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); 
} 

ten szczęśliwie przesuwa kursor myszy, ale nie wydaje się w ogóle zmienić zachowanie CGGetLastMouseDelta. Czy ktokolwiek zna dokładne specyfikacje dotyczące zwracanych przez CGGetLastMouseDelta (i kiedy?). Dokumentacja Apple na ten temat (odniesienie do kwarcu) jest jak zwykle prawie bezużyteczna (a przynajmniej brakuje w niej niezbędnych szczegółów).

Dzięki!

Odpowiedz

2

Dobrym pomysłem może być użycie CGAssociateMouseAndMouseCursorPosition(0), aby odłączyć ruch myszy od kursora. Wtedy nie dostaniesz problemu z granicami ekranu.

0

Opcja (1) Wygeneruj własne wydarzenie, które określa ruch myszy.
Opcja (2) Zadzwoń do funkcji obsługi zdarzeń przeniesionej myszą z . Przenieśliśmy procedurę rutowania myszy.