Reputation: 3739
I'm using System.Drawing.Graphics.CopyFromScreen to grab a partial screenshot of the desktop. I've noticed some curious behaviour. On some machines, when the application (WPF) window has AllowsTransparency="True", calling CopyFromScreen will capture whats 'under' the window. But on other machines, it captures the calling window too.
I've tried it on a number of machines, and operating systems, and haven't found a pattern. On XP and Windows 7 laptops it captures under the transparent window. On one windows 7 desktop we have, it captures the window itself. Aero, or other Windows 7 display features seem make no difference.
Could it be a graphics card issue? Is there any way to get consistent behaviour across all machines, or to predict or detect when this issue will occur?
EDIT Thanks to the link provided by Hans Passant below, and some further testing, I now understand that this issue connected to window transparency only. On some machines, CopyFromScreen captures all windows, on other machines it only captures non-transparent windows.
Upvotes: 4
Views: 1939
Reputation: 942109
Not so sure about the sometimes-not behavior. Layered windows have been behaving oddish since Aero. What is definite is that Graphics.CopyFromScreen() will not capture layered windows by default unless you use the overload that specifies the CopyPixelOperation. The required option is CaptureBlt, described as:
Windows that are layered on top of your window are included in the resulting image. By default, the image contains only your window.
Which is not accurate, "your window" won't be captured if it is a layered window. What's worse is that the method has a bug. You don't only need CaptureBlt, you also need SourceCopy. And the argument validation code doesn't permit that combination, you'll get an InvalidEnumArgumentException when you try to use it.
Well, GDI+ is a bag 'o bugs. You'll find the ugly pinvoke code you'll need to work around this in this answer.
Upvotes: 4