Aero Snap 不适用于我的应用程序
我遇到了 Aero Snap 无法与我正在处理的应用程序(Windows 桌面、本机 C++ 应用程序)一起工作的问题,并且我对发生的情况有点困惑,因为它似乎应该可以正常工作,在盒子。
我在最小的 win32 应用程序上使用了 Spy++,当我按 Win-Left 时收到以下消息:
<00070> 00030D1C P WM_KEYDOWN nVirtKey:VK_LWIN cRepeat:1 扫描码:5B fRepeat:0 fUp:0 <00071> 00030D1C P WM_KEYDOWN nVirtKey:VK_LWIN cRepeat:1 扫描码:5B fRepeat:1 fUp:0 <00072> 00030D1C P WM_KEYDOWN nVirtKey:VK_LWIN cRepeat:1 扫描码:5B fRepeat:1 fUp:0 <00088> 00030D1C S WM_GETMINMAXINFO lpmmi:0043FCBC
<00089> 00030D1C R WM_GETMINMAXINFO lpmmi:0043FCBC
<00090> 00030D1C S WM_WINDOWPOSCHANGING lpwp:0043FCC4
<00091> 00030D1C S WM_GETMINMAXINFO lpmmi:0043F8E8
<00092> 00030D1C R WM_GETMINMAXINFO lpmmi:0043F8E8
<00093> 00030D1C R WM_WINDOWPOSCHANGING
..等等
所以我可以看到左键的 WM_KEYDOWN 没有到达应用程序,但我得到了航空快照“调整窗口大小”的东西。
当我监视我的应用程序时,我可以看到左键没有被“拦截”,而是被传递到应用程序,所以我没有得到任何捕捉的好处。
<00043> 000F0F12 P WM_KEYDOWN nVirtKey:VK_LWIN cRepeat:1 扫描码:5B fRepeat:0 fUp:0
<00044> 000F0F12 P WM_KEYDOWN nVirtKey:VK_LWIN cRepeat:1 扫描码:5B fRepeat:1 fUp:0
<00045> 000F0F12 P WM_KEYDOWN nVirtKey:VK_LWIN cRepeat:1 扫描码:5B fRepeat:1 fUp:0
<00060> 000F0F12 P WM_KEYUP nVirtKey:VK_LEFT cRepeat:1 ScanCode:4B fRepeat:0 fUp:1
我将深入研究消息处理的核心,看看发生了什么,但我会采取所有我能想到的技巧get :)
编辑 我注意到 Win-Up 和 Win-Shift-Left/Right 实际上工作正常,所以只是 Win-Down 和 Win-Left/Right 没有被“气动捕捉”到正确的位置/尺寸。
编辑 好的,问题似乎是我的窗口不是使用 WS_THICKFRAME 标志创建的。如果我添加标志,快照就可以工作。现在,我实际上一开始并不想要边框,但至少我知道是什么导致了奇怪的行为。
希望最终编辑摆脱边框就像响应一样简单为WM_NCCALCSIZE,并使客户端占据整个窗口。
I have a problem with Aero Snap not working with the application I'm working on (Windows desktop, native C++ application), and I'm a bit confused as to what's happening, as it seems like it should just work, out of the box.
I've used Spy++ on a mininal win32 application, and get the following messages when I press Win-Left:
<00070> 00030D1C P WM_KEYDOWN nVirtKey:VK_LWIN cRepeat:1 ScanCode:5B fRepeat:0 fUp:0
<00071> 00030D1C P WM_KEYDOWN nVirtKey:VK_LWIN cRepeat:1 ScanCode:5B fRepeat:1 fUp:0
<00072> 00030D1C P WM_KEYDOWN nVirtKey:VK_LWIN cRepeat:1 ScanCode:5B fRepeat:1 fUp:0
<00088> 00030D1C S WM_GETMINMAXINFO lpmmi:0043FCBC
<00089> 00030D1C R WM_GETMINMAXINFO lpmmi:0043FCBC
<00090> 00030D1C S WM_WINDOWPOSCHANGING lpwp:0043FCC4
<00091> 00030D1C S WM_GETMINMAXINFO lpmmi:0043F8E8
<00092> 00030D1C R WM_GETMINMAXINFO lpmmi:0043F8E8
<00093> 00030D1C R WM_WINDOWPOSCHANGING
.. and so on
So I can see that the WM_KEYDOWN for the left key isn't reaching the application, but I'm getting the aero snap "resize window" stuff instead.
When I Spy++ my application, I can see that the left key isn't being "intercepted", but instead being passed on to the application, so I don't get any snapping goodness.
<00043> 000F0F12 P WM_KEYDOWN nVirtKey:VK_LWIN cRepeat:1 ScanCode:5B fRepeat:0 fUp:0
<00044> 000F0F12 P WM_KEYDOWN nVirtKey:VK_LWIN cRepeat:1 ScanCode:5B fRepeat:1 fUp:0
<00045> 000F0F12 P WM_KEYDOWN nVirtKey:VK_LWIN cRepeat:1 ScanCode:5B fRepeat:1 fUp:0
<00060> 000F0F12 P WM_KEYUP nVirtKey:VK_LEFT cRepeat:1 ScanCode:4B fRepeat:0 fUp:1
I'm going to dig into the cores of our message handling and see what's going on, but I'll take all the tips I can get :)
Edit I noticed that Win-Up and Win-Shift-Left/Right actually work correctly, so it's just Win-Down and Win-Left/Right that aren't being "aero snapped" into the correct position/size.
Edit Ok, the problem seems to be that my window wasn't been created with the WS_THICKFRAME flag. If I add the flag, snap works. Now, I don't actually want the border there in the first place, but at least I know what was causing the weird behavior..
Hopefully a final edit Getting rid of the border was as simple as responding to WM_NCCALCSIZE, and making the client occupy the whole window.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我不记得具体的消息,但是如果您处理主窗口的 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 的东西。也许您的应用程序会执行类似的操作(如果有人有更好的方法让应用程序在拖动期间保持运行,我很想听听)。I can't remember the specific messages, but Aero Snap is disabled if you process the WM_MOVING/WM_MOVE and/or WM_SIZING/WM_SIZE messages for the main window. If these do not reach
DefWindowProc
Aero Snap won't work. I guess DefWindowProc is responsible for implementing Aero Snap, so if you make sure those messages reach it, that might help.I discovered this implementing custom window dragging code so the application continues to execute and update the screen while the window is dragged, which meant processing these messages, but it disabled Aero Snap.
Edit: On further inspection, the application I mentioned handles WM_SYSCOMMAND and checks
(wParam & 0xFFF0) == SC_MOVE
to indicate a window move beginning. It then returns 0 and simulates the window dragging by updating the window position periodically whilst still running the application, drawing etc. This causes Windows to think the window is unmovable and that the user cannot drag it, but my application is updating the position to make it look like it's still being dragged, until WM_LBUTTONUP. Obviously Windows won't try any Aero Snap stuff if it doesn't think the window is being dragged. Maybe your application does something similar (if anyone has a better way to keep the app running during a drag, I'd be interested to hear).我怀疑这是消息处理,消息循环从未看到 WM_KEYDOWN 消息。在尝试了各种方法均未成功之后,我只能猜测 Windows 认为您的应用程序以某种方式不兼容。例如,在程序中使用 SetWindowsHookEx()。
I doubt it is message handling, the message loop never sees the WM_KEYDOWN message. After trying various things unsuccessfully, I can only guess at Windows thinking your app is incompatible somehow. Using SetWindowsHookEx() in your program for example.