如何获取窗口的Aero Snap状态?

3
当使用 Aero Snapping 调整窗口大小时,User32.GetWindowPlacement(hWnd).rcNormalPosition 仍会存储其原始矩形,而 User32.GetWindowRect 则会受到影响。
由于 Aero Snapping 似乎与 WINDOWPLACEMENT 无关,因此现在我们无法仅使用 user32.dll 收集实际放置的 完整 信息。因此我想知道是否有一种方法可以获取窗口的 Aero Snapping 状态,指示窗口是否被停靠以及窗口停靠在哪一侧
2个回答

1
"Aero Snap是Shell的一个功能,而不是窗口系统的功能。因此,窗口系统无法提供该信息,因为它不知道这些状态。Shell也没有公开此信息。因此,从本质上讲,系统不通过公共API提供任何给定窗口的Aero Snap状态。"

真遗憾。你有没有想过为什么微软不从Shell提供这样的API? - 0x269
1
@true_mogician:因为开发人员通常不需要那些信息。(另外:需要更多的工作来记录和支持它,也有更多的东西可以被滥用。) - Andreas Rejbrand
1
这是系统的一个不透明特性,客户端代码无需知道。它与从WM_GETMINMAXINFO报告的窗口信息协作。它遵守窗口调整请求的其他限制。总之,甚至没有理由知道Aero Sanp的存在。如果您确实有合理的用例,Microsoft接受“设计更改请求”。不过,您需要解释清楚。 - IInspectable
1
请记住,人们已经在12年前就要求公开API了。虽然我不知道是否有任何正式请求发布API,但看起来它不会得到太高的优先级处理。 - IInspectable
1
@IInspectable 感谢您提供的信息。我只是想更准确地恢复一些窗口的位置,如果忽略此功能并使用user32.dll,那也没关系。 - 0x269
@IInspectable:“总的来说,没有理由知道Aero Snap的存在。”考虑像Outlook这样的应用程序,它会不时地关闭并重新创建其主窗口。您可以将Outlook的主窗口捕捉到监视器边框上,但在不可预测的时刻它可能会看似自发地“解除捕捉”。如果捕捉状态可以通过编程访问,则可以将替换窗口放回原始位置。 - Adrian McCarthy

1
我喜欢让我的主窗口记住它们的所有位置信息,这样当它们重新启动时可以恢复。过去,保存窗口放置结构的副本并在重新创建窗口时将其设置回来就足够了。
引入“捕捉”需要保留一些额外的信息。我通过比较窗口矩形和包含窗口的监视器的工作区矩形来检测窗口是否被捕捉。如果它似乎被捕捉到了其中一个边缘,我记录下来以及放置信息。在创建窗口时,我首先恢复窗口位置,然后,如果我有记录的捕捉状态,我会相应地更改窗口的大小和位置。
您可以区分已捕捉到监视器边缘的窗口和已经仔细调整大小和放置的窗口,因为捕捉窗口的矩形不会与窗口放置中的矩形匹配。
这种方法在Windows 7中非常有效。我最近发现Windows 10增加了更多灵活性来捕捉位置和大小,并玩更多的游戏来实现令人恼人的看不见的调整边框。因此,我的检测代码并不总是能识别出已捕捉的窗口,但这是可以修复的。
一些流行的软件(如主要浏览器)似乎记得它们被捕捉了,我认为它们使用相同的方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接