tags:

views:

429

answers:

4

Anyone know of an efficient way of detecting movement of any windows currently open on a windows system? I need to detect a window's movement, determine if it collides with my applications Form, and bump it out from underneath if necessary.

I know I can scan through an enumerated list and check each window -- but that is way to intensive to perform constantly.

Background:

I have a taskbar-esque application that docks on the side of a user's screen. When the "Always on Top" feature is on, maximized windows will take up the remaining available space without covering the toolbar, as expected.

However, if you drag a non-maximized window over the toolbar, the application goes behind the toolbar (also expected), but you can no longer grab onto the title bar to move it back -- the window is stuck unless you disable "Always on Top" and then move it. So, I want to bump the window out from underneath.

A: 

Try checking your PaintEventArgs ClipRectangle ..

(edit: and/or WindowFromPoint shooting match)

rama-jka toti
I think he wants to move a window he doesn't own, not one he does.
jeffamaphone
Jeffamaphone is correct -- I am looking to detect overlapping windows that are external to my application.
Matt
ah, ok.. edited with a further suggestion.. have a hack :)
rama-jka toti
+1  A: 

Although not a direct answer, one possible solution to this is to create your application as an application desktop toolbar rather than a regular window. From the docs:

An application desktop toolbar(also called an appbar) is a window that is similar to the Microsoft Windows taskbar. It is anchored to an edge of the screen... The system prevents other applications from using the desktop area occupied by an appbar. (emphasis added)

This may not be a great fit for your scenario because it is oriented towards COM and unmanaged code rather than managed apps: however see this CodeProject article for info about using this feature from C#.

Failing that, you could try installing a hook (see SetWindowsHookEx) and listening for move messages but this is pretty low-level...

itowlson
Thank you for the suggestion. The application is already currently registered as an application desktop toolbar, which is why maximizing windows will abide by the rules. The windows task bar (another application desktop toolbar) actually has the same issue as mine - move your taskbar to the top of your screen and set it to "Always on Top". Then drag another window over it so the entire title bar is over the taskbar, and you can no longer move the window. The exception to this is in Windows 7 where the Windows Taskbar has the behavior I desire, and will bump out windows.
Matt
I will try the SetWindowsHookEx idea and see if it does the trick. I am not worried about going low-level, as long as it works without hogging too many resources.
Matt
A: 

You can get notification of window movements using a CBT Hook: http://msdn.microsoft.com/en-us/library/ms644977%28VS.85%29.aspx

danbystrom
I have this hooked up and it looks like it should work -- but currently I can only get it to give me feedback for window movements that are owned by my application. If I can get this to give me callbacks for any windows on the system, we are in business!
Matt
According to http://support.microsoft.com/default.aspx/kb/318804, and various other sources, you cannot create global windows hooks from a .NET application (aside from those watching the keyboard/mouse movements), without implementing them in a C++ DLL.. I guess I will start looking into that, as it seems to be my only option.
Matt
A: 

http://www.codeproject.com/KB/dialog/FindWindow.aspx?msg=3262771

"FindWindow By Jörg Bausch"

Will get you the external (not your app's) window ID (IntPtr) the mouse went up over from within your C# application. For the desktop, and everything else on the desktop, it will return the same pointer (you can't distinguish, using this code, between as mouse-up on a folder, the desktop, the Recycle Bin).

http://www.codeproject.com/KB/cs/globalhook.aspx

"Processing Global Mouse and Keyboard Hooks in C# By George Mamaladze"

Will allow you to create GlobalHook for keyboard and mouse-events in C#. I've used it recently in VS 2010 beta 2 : it is NOT USABLE compiled against FrameWork 4.0, but does compile and work okay against FrameWork 3.5 and lower. If you download only George's demo app, be aware the download doesn't include the required dll, and will fail when you launch the .exe file (which I have brought to George's attention).

I've never worked with a "desktop application toolbar;" I hope this is relevant.

best,

BillW