1

サブクラス化された NSWindow のコードを以下に示します。スケーリング可能なアニメーション ビューがあり、適切な場所でクリックされたときにクリックを受け入れ、外側にある場合は拒否 (クリック スルー) したいと考えています。

以下のコードは、ウィンドウがクリックスルーしないことを除いてうまく機能します。

- (void)mouseDragged:(NSEvent *)theEvent {
  if (allowDrag) {
    NSRect screenVisibleFrame = [[NSScreen mainScreen] visibleFrame];
    NSRect windowFrame = [self frame];
    NSPoint newOrigin = windowFrame.origin;

    // Get the mouse location in window coordinates.
    NSPoint currentLocation = [theEvent locationInWindow];
    // Update the origin with the difference between the new mouse location and the old mouse location.
    newOrigin.x += (currentLocation.x - initialMouseLocation.x);
    newOrigin.y += (currentLocation.y - initialMouseLocation.y);

    if ((newOrigin.y + windowFrame.size.height) > (screenVisibleFrame.origin.y + screenVisibleFrame.size.height)) {
        newOrigin.y = screenVisibleFrame.origin.y + (screenVisibleFrame.size.height - windowFrame.size.height);
    }

    // Move the window to the new location
    [self setFrameOrigin:newOrigin];
  }
}



- (void)mouseDown:(NSEvent *)theEvent
{
    screenResolution = [[NSScreen mainScreen] frame];

   initialMouseLocation = [theEvent locationInWindow];

    float scale = [[NSUserDefaults standardUserDefaults] floatForKey:@"widgetScale"]/100;

    float pX = initialMouseLocation.x;
    float pY = initialMouseLocation.y;
    float fX = self.frame.size.width;
    float fY = self.frame.size.height;

    if (pX>(fX-fX*scale)/2 && pX<(fX+fX*scale)/2 && pY>(fY+fY*scale)/2) {
        allowDrag = YES;
    } else {
        allowDrag = NO;
    }
}
4

2 に答える 2

1

Cocoa では、2 つの基本的な選択肢があります。1) でウィンドウ全体をクリックを通過させる[window setIgnoresMouseEvents:YES]か、2) ウィンドウの一部を透明にしてクリックをデフォルトで通過させるかです。

制限は、ウィンドウ サーバーがイベントを配信するアプリを 1 回決定することです。イベントをアプリに配信した後、イベントを元に戻して別のアプリに配信する方法はありません。

考えられる解決策の 1 つは、Quartz Event Tapsを使用することです。ウィンドウがマウス イベントを無視するようにしますが、ログイン セッションのすべてのイベントを表示するイベント タップを設定します。ウィンドウを通過するイベントを実際にウィンドウで停止させたい場合は、手動で処理してから破棄します。イベントが他の方法で到達するアプリに継続することはできません。これを正しく行うのは非常に難しいと思います。たとえば、自分のウィンドウの前にある別のアプリのウィンドウのイベントをインターセプトしたくありません。

可能であれば、Cocoa がサポートする手法を使用することをお勧めします。とにかく透明なウィンドウを通過するだけのクリックが必要だと思います。そうしないと、ユーザーは自分が何をクリックしているのかをどうやって知るのでしょうか?

于 2013-03-03T06:07:39.487 に答える
0

コントロールを受け入れるために透明なオーバーレイ CHILD WINDOW を呼び出し、Ken の指示に従ってメイン ウィンドウを -setIgnoresMouseEvents:YES にしてください。

「Overlay」という名前のアプリでこのトリッキーを使用しました。

于 2013-10-23T20:46:06.520 に答える