2

我正在使用 addGlobalMonitorForEventsMatchingMask 来监听 Co​​coa 中的事件:

[NSEvent addGlobalMonitorForEventsMatchingMask:NSLeftMouseDraggedMask 
                                       handler:^(NSEvent *event) {
    NSLog(@"Dragged...");
}];

虽然我想知道我是否正在拖动/移动一个窗口(以及哪个窗口,我可以找到焦点窗口,但在按住命令并拖动窗口时,据我所知它并没有获得焦点。)

那么,我可以检测我是否在拖动窗口吗?

更新:

我现在有一个类:“ SATest : NSObject <NSWindowDelegate>”,我在其中实现了 windowDidMove 方法(稍后可能还有 windowWillMove。)不过,现在下一步是将其附加到一个窗口,对吗?所以我现在的问题是:如何将代理附加到所有应用程序的所有窗口?

更新 2:

我现在可以在屏幕上找到所有打开窗口的列表:

AXUIElementRef _systemWideElement;
_systemWideElement = AXUIElementCreateSystemWide();

CFArrayRef _windows;
AXUIElementCopyAttributeValues(_systemWideElement, kAXWindowsAttribute, 0, 100, &_windows);

现在我必须遍历窗口,并且每个得到它的 NSWindow 以便我可以将我的委托添加到它:[window setDelegate:self];

更新3:要清楚,这个问题是关于检测所有应用程序的所有窗口的拖动。不仅是我自己的应用程序的窗口。

另外,我对这个事件和窗口管理的东西很陌生,所以不需要让你的答案简短我很高兴阅读了很多:P

谢谢!-P

4

2 回答 2

5

要确定是否正在拖动窗口,您需要通过响应NSWindowDelegate协议的以下消息来拥有一个充当窗口委托的对象:

  1. windowWillMove - 这告诉代理窗口即将移动。
  2. windowDidMove - 这告诉代理窗口已经移动。

您可以通过将对象发送到发送到这些方法的通知参数来检索有问题的 NSWindow 对象:

例如

NSWindow draggedWindow = [notification object];

更多信息可以在这里找到。

更新:

为了响应您关于获取所有窗口的此信息的请求,NSApplication类提供了一个方法,该方法返回应用程序拥有的所有窗口的数组。获取此信息的典型方法是使用NSApplicationDelegate方法之一来获取对应用程序对象的引用。

例如,在您的应用委托(伪代码)中:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    NSApplication * app = [aNotification object];
    // you now have a reference to your application.
    // and can iterate over the collection of windows and call
    // [window setDelegate:self]; for each window.
}

请注意,在添加和删除窗口时,您需要添加/删除您的代表。执行此操作的最佳方法是– applicationDidUpdate:

这应该足以让您开始解决问题。

于 2012-06-09T18:43:10.323 回答
1

正如 Benjamin 所建议的,答案在于可访问性 API。甚至在我问这个问题之前,我就在这方面环顾了一段时间,但从来没有让它做我想做的事。我现在找到了一个很好的解决方案。

在高层次上,我执行以下操作:

  1. 聆听鼠标按下事件并记住您单击的窗口及其位置。
  2. 侦听鼠标向上事件并检查位置是否已更改,如果是,您知道您移动了一个窗口

如果您还想知道是否调整了大小,您可以对大小执行类似的操作。可能有更好的解决方案,但经过几天的尝试,这是我让它按照我想要的方式工作的唯一方法。

希望这可以帮助任何正在寻找类似东西的人。

-巴勃罗

于 2012-06-20T08:59:18.800 回答