views:

354

answers:

2

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.

+3  A: 

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).

AshleysBrain
+1  A: 

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.

Hans Passant