6

私はMATLABのPsychToolboxの拡張機能を開発しており、精神物理学的実験中にマウスをより適切に制御できるようにしています(具体的には、画面の境界がドラッグ操作を制限するのを防ぎます...マウスをすべての方向に「無限に」動かすことができるように感じるはずです) 。MATLABは追加のスレッドの作成をサポートしていないため(とにかくこの状況では不必要に複雑になります)、CarbonまたはCocoaのイベントマネージャーを使用することはできません。

CGGetLastMouseDeltaは、私が行う必要のあることにはほぼ完璧です(アプリケーションが最後にマウスを動かしたイベントを受け取ってから、マウスが動いた量を取得します)「画面の境界を無視します)、ただし、わずかな問題が1つあります。プログラムでマウスを移動すると(CGWarpMouseCursorPositionまたはCGDisplayMoveCursorToPointのいずれかを使用)、イベントは生成されません。したがって、CGGetLastMouseDeltaは、マウスが移動したことをまったく認識していないようです。つまり、プログラムでマウスを50ピクセル上、50ピクセル下に移動すると、CGGetLastMouseDeltaはマウスデルタに対して後で(0、0)を返します。これは私のコンテキストでは望ましくない動作であり、醜い回避策が必要です。マウスを動かしてみました。次のように、イベントシステムを介してイベントを投稿します(これは「mexFunction」、MATLABの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);
}

これはマウスをうまく動かしますが、CGGetLastMouseDeltaの動作をまったく変更しないようです。CGGetLastMouseDeltaによって返されるもの(およびいつ)に関する正確な仕様を知っている人はいますか?このようなものに関するAppleのドキュメント(Quartzリファレンス)は、いつものようにほとんど役に立たない(または少なくとも、必要な詳細が不足している)。

ありがとう!

4

2 に答える 2

2

CGAssociateMouseAndMouseCursorPosition(0)マウスの動きをカーソルから切断するために使用することをお勧めします。そうすれば、画面の境界に関する問題は発生しません。

于 2009-05-12T16:38:34.423 に答える
0

オプション (1) マウスを動かしたことを指定する独自のイベントを生成します。
オプション (2) マウスを動かしたイベント ハンドラ関数を、マウスを動かしたルーチンから呼び出します。

于 2009-05-17T11:32:46.153 に答える