GetWindowPlacement返回的窗口位置不正确

8
如何判断窗口是否使用Aero Snap 功能调整大小?GetWindowPlacement 函数返回最新的“恢复”窗口大小。我将其用于以下方式:
WINDOWPLACEMENT wp = {};
wp.length = sizeof(WINDOWPLACEMENT);
::GetWindowPlacement( hWnd, &wp );

例如,它给出了 wp.rcNormalPosition = {top=208 bottom=520 left=152 right=510},但实际上应该是 {top=0 bottom=1920 left=152 right=510}
请注意,GetWindowRect(获取窗口大小和位置)提供完全相同的错误结果。那是我的错,GetWindowRect 提供正确的结果。
我需要在程序退出时保存窗口状态,并在启动时加载它,因此我需要知道窗口的实际位置。如何找到实际的窗口坐标?
嗯,我用 notepad.exe(以及其他一些标准的 Windows 组件)进行了几次测试,它以相同的方式保存其状态,不记得它是否被“吸附”。因此,我认为这是 Windows 程序的意图行为。

2
GetClientRect 是什么意思?如果客户端大小大于窗口大小,那就说明有问题了。DWMWA_EXTENDED_FRAME_BOUNDS 又是什么呢?在 GetWindowRect 的注释中提到它有助于获取 Aero 窗口的边界。 - Ben Voigt
看起来这可能是 GetWindowRect too small on Windows 7 的重复问题。 - Ben Voigt
@ben 我的经验是 GetWindowRect 返回正确的值,但 GetWindowPlacement 存在问题。 - David Heffernan
1个回答

7
AeroSnap 是窗口管理器发送给应用程序的另一种调整大小方式。因此,您无法知道它是“捕捉”而不是其他任何类型的调整大小。
您能做的最好的事情就是在调整大小事件中检测相对的边缘已经移动。您需要检查高度或宽度是否也发生了变化,以便将其与移动事件区分开来。
之所以不会告诉您这是一个捕捉操作,是因为很难想象应用程序会关心调整大小的机制。
评论揭示了更多有关问题的信息。您正在尝试在应用程序关闭时保留其位置和大小,以便在重新启动时恢复它。您正在使用 GetWindowPlacement() 来实现,并发现当窗口的最后一次调整大小是 AeroSnap 时返回的位置不正确。
我的应用程序完全相同,我也遇到了完全相同的问题。我使用的解决方法是调用 GetWindowRect() 代替 GetWindowPlacement() 来获取窗口位置和大小。您表示这对您无效,对此我无能为力。我必须说,我有点难以相信 GetWindowRect() 不会返回正确的窗口矩形。

我不在乎用什么机制调整窗口大小,我只想知道它当前的位置。 - Kirill V. Lyadvinsky
2
@Kirill,我认为如果您将问题从“如何找出窗口是否被‘捕捉’?”改为“为什么GetWindowRect、GetWindowPlacement等在AeroSnap后报告我的应用程序的位置不正确”,那么您的问题会得到改善。 - David Heffernan
2
哦,内置应用程序(资源管理器、记事本等)由于Aero Snap而不“记住”它们的位置。我认为这是因为它是一种方便的功能,可以暂时将窗口放置在某个位置。用户可能不希望记住窗口的捕捉大小/位置。就像您不会记住已最大化或最小化的窗口的大小/位置一样。您可以调用GetWindowPlacement来获取窗口在最大化或最小化之前的最后位置。对于Aero Snap,我会做同样的事情,而不是尝试编写绕过它的代码。 - Cody Gray
2
@cody 不确定我同意。我喜欢程序记住。 - David Heffernan
5
@David,"Snap" 和 "正常" 调整大小之间有一个重大区别 - 当你“Snap”时,你可以双击标题栏,它会还原到原始位置。在这个意义上,它更像是最大化。问题是,与最大化不同,WINDOWPLACEMENT 不会给你任何指示它处于这个 Snap 状态。 - Maurice Flanagan
显示剩余2条评论

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