【问题标题】:Aero Snap not working for my applicationAero Snap 不适用于我的应用程序
【发布时间】:2011-02-24 14:45:08
【问题描述】:

我遇到了 Aero Snap 无法与我正在使用的应用程序(Windows 桌面、本机 C++ 应用程序)一起使用的问题,我对正在发生的事情有点困惑,因为它似乎应该可以正常工作,开箱即用。

我在一个最小的 win32 应用程序上使用了 Spy++,当我按下 Win-Left 时收到以下消息:

00030D1C P WM_KEYDOWN nVirtKey:VK_LWIN cRepeat:1 ScanCode:5B fRepeat:0 fUp:0 00030D1C P WM_KEYDOWN nVirtKey:VK_LWIN cRepeat:1 ScanCode:5B fRepeat:1 fUp:0 00030D1C P WM_KEYDOWN nVirtKey:VK_LWIN cRepeat:1 ScanCode:5B fRepeat:1 fUp:0 00030D1C S WM_GETMINMAXINFO lpmmi:0043FCBC
00030D1C R WM_GETMINMAXINFO lpmmi:0043FCBC
00030D1C S WM_WINDOWPOSCHANGING lpwp:0043FCC4
00030D1C S WM_GETMINMAXINFO lpmmi:0043F8E8
00030D1C R WM_GETMINMAXINFO lpmmi:0043F8E8
00030D1C R WM_WINDOWPOSCHANGING
..等等

所以我可以看到左键的 WM_KEYDOWN 没有到达应用程序,但我得到的是 aero snap“调整窗口大小”的东西。

当我窥探 ++ 我的应用程序时,我可以看到左键没有被“拦截”,而是被传递给应用程序,所以我没有得到任何捕捉好处。

000F0F12 P WM_KEYDOWN nVirtKey:VK_LWIN cRepeat:1 ScanCode:5B fRepeat:0 fUp:0
000F0F12 P WM_KEYDOWN nVirtKey:VK_LWIN cRepeat:1 ScanCode:5B fRepeat:1 fUp:0
000F0F12 P WM_KEYDOWN nVirtKey:VK_LWIN cRepeat:1 ScanCode:5B fRepeat:1 fUp:0
000F0F12 P WM_KEYUP nVirtKey:VK_LEFT cRepeat:1 ScanCode:4B fRepeat:0 fUp:1

我将深入研究消息处理的核心,看看发生了什么,但我会尽我所能:)

编辑我注意到 Win-Up 和 Win-Shift-Left/Right 实际上工作正常,所以只是 Win-Down 和 Win-Left-Left/Right 没有被“aero snapped”到正确的位置/大小。

编辑好的,问题似乎是我的窗口不是使用 WS_THICKFRAME 标志创建的。如果我添加标志,snap 工作。现在,我实际上并不想要那里的边界,但至少我知道是什么导致了奇怪的行为..

希望最后的编辑摆脱边框就像响应 WM_NCCALCSIZE 一样简单,让客户端占据整个窗口。

【问题讨论】:

  • 你能发布你的代码来处理 NCCALCSIZE 吗?
  • 代码就像从消息处理程序返回 0 一样简单。有关实际情况的详细描述,请参阅 WM_NCCALCSIZE 的 MSDN 文档,但简而言之,当调用 NCCALCSIZE 时,lParam 拥有一个指向 3 个矩形数组的指针,其中第一个是窗口矩形。当您从 NCCALCSIZE 返回时,Windows 期望第一个矩形是您的客户端矩形,因此只需不做任何事情,您就可以使客户端矩形等于窗口矩形。
  • 我的情况是最大化窗口。所以我打开了 WS_THICKFRAME,我关闭了 WS_CAPTION(因为我正在绘制我自己的),并且我在我的 windowproc 中为 WM_NCCALCSIZE 返回 0,但我仍然看到边框。 :p
  • 我能够通过在我的 WM_NCCALCSIZE 处理程序中返回一个对应于框架厚度的膨胀矩形来“移除”厚框架。

标签: c++ winapi windows-7 aero aero-snap


【解决方案1】:

我不记得具体的消息,但是如果您处理主窗口的 WM_MOVING/WM_MOVE 和/或 WM_SIZING/WM_SIZE 消息,Aero Snap 将被禁用。如果这些没有达到DefWindowProc Aero Snap 将无法工作。我猜 DefWindowProc 负责实现 Aero Snap,所以如果你确保这些消息到达它,那可能会有所帮助。

我发现了这个实现自定义窗口拖动代码,因此应用程序在拖动窗口时继续执行和更新屏幕,这意味着处理这些消息,但它禁用了 Aero Snap。

编辑:进一步检查,我提到的应用程序处理 WM_SYSCOMMAND 并检查 (wParam & 0xFFF0) == SC_MOVE 以指示窗口移动开始。然后它返回 0 并通过定期更新窗口位置来模拟窗口拖动,同时仍在运行应用程序、绘图等。这导致 Windows 认为窗口是不可移动的并且用户无法拖动它,但我的应用程序正在更新要制作的位置看起来它仍在被拖动,直到 WM_LBUTTONUP。显然,如果 Windows 认为窗口没有被拖动,它就不会尝试任何 Aero Snap 的东西。也许您的应用程序做了类似的事情(如果有人有更好的方法让应用程序在拖动过程中保持运行,我很想听听)。

【讨论】:

    【解决方案2】:

    我怀疑它是消息处理,消息循环从来没有看到 WM_KEYDOWN 消息。在尝试了各种失败后,我只能猜测 Windows 认为您的应用程序在某种程度上不兼容。例如在你的程序中使用 SetWindowsHookEx()。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-14
      • 2019-07-14
      • 1970-01-01
      • 2014-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多