How to reliably find a foreground window when it has no focus

So, I thought it would be simple and, well, I was wrong. Here is a simplified description of the problem:

I am writing a small application for our production specialists, which will capture a screenshot of the entire desktop, as well as the foreground window, when they click the application icon on the taskbar. I am currently using the Win32 method "GetforegroundWindow" in the MouseMove NotifyIcon event to save a handle to the foreground window and take a screenshot in the Click event.

This sometimes works, but if I quickly click on the icon, I will actually grab the taskbar instead of the foreground window. I'm not sure why this is happening (I understand that the taskbar is a window, I don’t understand why sometimes it seems like I have focus in MouseMove before I clicked), and I was not lucky using the EnumWindows method as well. probably because I do not quite understand how this works.

It would seem that if I could get the z position of each window using only the window handle, this would be an easy problem to solve with EnumWindows. However, I did not find a way to do this.

So, I ask you guys; how would you write a method for reliably defining a foreground window, given that it may not have focus at the time? Either my google-fu fails, or information about it is sparse. Thanks in advance.

+6
c # interop
source share
2 answers

The taskbar is a faithful foreground window like any other. When you click on it, it will temporarily be a foreground window. And if you click "Start" and, for example, click "Escape", it will be a foreground window until you release it.

You can probably use GetWindow with HWND_NEXT passing in the window handle of the taskbar. Strike>

Nevermind, since the taskbar is the topmost window, GetWindow (or GetNextWindow, etc.) will work differently. I suggest revising the EnumWindows solution, which is likely to be your best bet.

+1
source share

If the form you want has a snapshot that is the same as the form associated with the taskbar, you really don't need to use GetforegroundWindow. Just use Form.hWnd and pass this to the snapshot function. You may need to do this in the top window by calling

[DllImport( "user32.dll" )] public static extern IntPtr SetForegroundWindow( IntPtr hWnd ); 

or

 [DllImport( "user32.dll" )] public static extern bool BringWindowToTop( HandleRef hWnd ); 

If you need an entire desktop, then you probably just need to insert Thread.Sleep to make sure that the foreground is enough to go to the beginning before taking a screenshot of the desktop.

putting src from my comment here for a better print

 [DllImport( "user32.dll" )] public static extern IntPtr GetForegroundWindow(); [DllImport( "user32.dll" )] public static extern IntPtr GetActiveWindow(); // this or the next line not both IntPtr curWindow = GetActiveWindow(); IntPtr curWindow = GetForegroundWindow(); BringWindowToTop( window ); System.Threading.Thread.Sleep( 500 ); 

If the sleeping stream gives the window enough time to come to the beginning of order Z.

0
source share

All Articles