【问题标题】:How to accept a mouse click for one portion and let click-though the rest of an NSWindow如何接受鼠标单击一部分并让单击其余的 NSWindow
【发布时间】:2013-10-24 04:46:06
【问题描述】:

我有下面的子类 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;
    }
}

【问题讨论】:

    标签: cocoa nswindow nsevent


    【解决方案1】:

    在 Cocoa 中,您有两个基本选择:1) 您可以使用 [window setIgnoresMouseEvents:YES] 使整个窗口通过点击,或者 2) 您可以使部分窗口透明并且默认情况下点击通过。

    限制是窗口服务器决定将事件传递给哪个应用程序一次。将事件传递到您的应用程序后,无法让它取回事件并将其传递到另一个应用程序。

    一种可能的解决方案是使用Quartz Event Taps。这个想法是让你的窗口忽略鼠标事件,但设置一个事件点击,它将查看登录会话的所有事件。如果你想让一个正在通过你的窗口的事件实际上停止在你的窗口,你手动处理它然后丢弃它。你不要让事件继续到它本来可以到达的应用程序上。我希望这将是非常棘手的正确做法。例如,您不想拦截您前面的另一个应用程序窗口的事件。

    如果可能,我建议您使用 Cocoa 支持的技术。我认为您只希望点击通过透明的窗口,否则用户怎么知道他们在点击什么?

    【讨论】:

    • 不幸的是,没有什么能像我预期的那样工作。当我用基本动画缩放窗口视图时,它会产生很多透明部分,但这些部分仍然接受鼠标点击,因为原始透明度与动画层无关。它还必须对 App Store 友好,因此事件陷阱并不好。我已经按原样提交了应用程序,如果我收到很多抱怨,可能会出现“错误”,如果我只是将封闭窗口的大小调整为与缩放视图相同的大小。还是谢谢你。
    • 我不知道在动画期间,但肯定在动画调整大小完成后尝试调用-[NSWindow invalidateShadow]。这应该确保窗口服务器更新其窗口形状的概念。
    【解决方案2】:

    请调用透明覆盖 CHILD WINDOW 以接受控制,并按照 Ken 的指示设置主窗口 -setIgnoresMouseEvents:YES。

    我在名为“Overlay”的应用上使用了这个技巧。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多