Catch Win+Left (Aero-Snap)?
-
I'm writing a WPF app with a custom window frame (not a specific WPF question though). Due to the necessary "macgyverising" of the window and window frame to get things to work correctly (i.e. hidden transparent window borders, etc.), it kind of messed up the aero-snapping a little bit. I want to catch the Win+Left, etc. hot keys so I can "fix" my window. All the usual suspects don't work for this. Keydown, PreviewKeydown, custom window proc, etc. Only thing I've found that works for this (so far) is a low level keyboard hook. I'm not thrilled about the low level keyboard hook, as its a global hook and if my EXE is running, the system will call my app for ALL keys in ALL apps. That's not really an acceptable solution in my book. Any other options?
-
I'm writing a WPF app with a custom window frame (not a specific WPF question though). Due to the necessary "macgyverising" of the window and window frame to get things to work correctly (i.e. hidden transparent window borders, etc.), it kind of messed up the aero-snapping a little bit. I want to catch the Win+Left, etc. hot keys so I can "fix" my window. All the usual suspects don't work for this. Keydown, PreviewKeydown, custom window proc, etc. Only thing I've found that works for this (so far) is a low level keyboard hook. I'm not thrilled about the low level keyboard hook, as its a global hook and if my EXE is running, the system will call my app for ALL keys in ALL apps. That's not really an acceptable solution in my book. Any other options?
Well, it takes a low-level keyboard hook because your app never sees the key combination. Windows handles it. Well, more specifically, Explorer does. Your app window gets a ton of WM_ messages that tell it to resize itself to whatever size the screen height and 1/2 the width is and to move itself over to the top left corner of the desktop window. The messages are essentially no different than if the user told the window to do then same thing using the mouse. I've never tried to doing this, but you might be able to prevent this by handling the Resize event or setting the forms MaxSize property.
A guide to posting questions on CodeProject
Click this: Asking questions is a skill. Seriously, do it.
Dave Kreskowiak -
Well, it takes a low-level keyboard hook because your app never sees the key combination. Windows handles it. Well, more specifically, Explorer does. Your app window gets a ton of WM_ messages that tell it to resize itself to whatever size the screen height and 1/2 the width is and to move itself over to the top left corner of the desktop window. The messages are essentially no different than if the user told the window to do then same thing using the mouse. I've never tried to doing this, but you might be able to prevent this by handling the Resize event or setting the forms MaxSize property.
A guide to posting questions on CodeProject
Click this: Asking questions is a skill. Seriously, do it.
Dave KreskowiakI did discover that setting ResizeMode=None blocks the Aero-snap commands just for the specific window, but there still wasn't any way to catch the Win+Left that I could find. The regular keyboard hook would only catch it on the release. I tried catching WM_GETMINMAXINFO, but the samples I saw used Marshal.PtrToStructure, so I guess that makes a copy of the struct and you can't modify the original data? Regardless, I also tried catching the various sizing messages, and yeah, I guess I was able to kind of trap Height = 100% / Width = 50%, but there was no way to tell if that was from the user mouse or from Aero-snap and that would kind of be the same situation if I got the WM_GETMINMAXINFO message working. So, I guess the only solution is to use the low level keyboard hook -- with a twist :). I only need it to catch Win+Left, Win+Right and Win+Up... so I can catch the Win down in my app and then I install the system wide hook so I can catch the 3 Win+XXX combinations and when the Win button is released, or my app loses focus I remove it. Rinse. Repeat. Still don't like installing a system wide hook, but I'm only keeping it installed when they press the Win key, so I guess its not too bad. Better then leaving it installed the whole time my app is up.
-
I did discover that setting ResizeMode=None blocks the Aero-snap commands just for the specific window, but there still wasn't any way to catch the Win+Left that I could find. The regular keyboard hook would only catch it on the release. I tried catching WM_GETMINMAXINFO, but the samples I saw used Marshal.PtrToStructure, so I guess that makes a copy of the struct and you can't modify the original data? Regardless, I also tried catching the various sizing messages, and yeah, I guess I was able to kind of trap Height = 100% / Width = 50%, but there was no way to tell if that was from the user mouse or from Aero-snap and that would kind of be the same situation if I got the WM_GETMINMAXINFO message working. So, I guess the only solution is to use the low level keyboard hook -- with a twist :). I only need it to catch Win+Left, Win+Right and Win+Up... so I can catch the Win down in my app and then I install the system wide hook so I can catch the 3 Win+XXX combinations and when the Win button is released, or my app loses focus I remove it. Rinse. Repeat. Still don't like installing a system wide hook, but I'm only keeping it installed when they press the Win key, so I guess its not too bad. Better then leaving it installed the whole time my app is up.
Don't forget that the keyboard isn't the only way that Aero-snap can be invoked. Dragging the window to the edge of the screen will also invoke it. :)
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer