microsoft / Windows.UI.Composition-Win32-Samples

Windows.UI.Composition Win32 Samples
MIT License
459 stars 186 forks source link

Bug in `IsWindowValidForCapture` method/logic.. How to get it right? #99

Closed gileli121 closed 2 years ago

gileli121 commented 2 years ago

Hello, I noticed that in the example you have a helper method called IsWindowValidForCapture(). I found it useful But unfortunately, I found a case when it does not work right. Your example ignores any explorer.exe windows.

If run the example, I can't see explorer.exe windows. However, If I modify it and add the following lines in Window_Loaded while 0x0000000000020A1E is the handle to explorer window:

var targetHwnd = new IntPtr(0x0000000000020A1E);
StartHwndCapture(targetHwnd);

Then it will be able to capture it: image

It just doesn't suggest selecting this window for some reason.

This is how your example check whatever the window is valid for capture: WindowEnumerationHelper.IsWindowValidForCapture(p.MainWindowHandle) While p is the window process.

I found out that this line will return false. To isolate it and reproduce it directly, run this code:

var p = Process.GetProcessesByName("explorer").First();
var valid = WindowEnumerationHelper.IsWindowValidForCapture(p.MainWindowHandle);

As you will see, it will return false image

After more investigation, I found out that it is because the code using MainWindowHandle of the process instead of the actual window handle (eg: 0x0000000000020A1E in my case)

Changing the handle to the direct window handle will solve the problem. However, unfortunately, this will create another problem that for some other windows the method will return true while capturing will always fail.

An example of such a window is the following Git Extensions window image

Using MainWindowHandle here will return the correct result (false and indeed the capture will fail) but once I will use here the direct window handle, it will return true. And again, if I use the direct handle it will work wrong with explorer windows.

So it looks like something is not working fine with the logic here. I don't know what is the correct way to do it.

Anyway, it looks like the native picker provided by the API is working fine: image

It doesn't show to pick the "Git Extensions" window that I showed earlier while it still shows the explorer window. So this native picker got it right in both cases.

So there must be a way to do it without the picker.

robmikh commented 2 years ago

The sample is just one example implementation. Each application will have different needs and you can tailor yours to your specific requirements. The ScreenCaptureforHWND sample might have a different behavior that you're looking for, it doesn't depend on the MainWindowHandle property.