Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I'm trying to capture desktop windows in C# based on Window handles. I'm using .NET and using PInvoke to GetWindowRect() to capture the window rectangle. I've got the Window selection and rectangle capture working fine.

However, the window rectangles captured include not just the actual window size but also the Window's adornments like the shadow around it. When I try to clip the window to a bitmap the bitmap contains the area and shadow. On Windows 10 I get the transparent shadow area including any content that might be visible below the active window:

enter image description here

The code I use is simple enough capturing the Window using Win32 GetWindowRect() via PInvoke call:

var rect = new Rect();
GetWindowRect(handle, ref rect);
var bounds = new Rectangle(rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top);
var result = new Bitmap(bounds.Width, bounds.Height);

using (var graphics = Graphics.FromImage(result))
{
    graphics.CopyFromScreen(new Point(bounds.Left, bounds.Top), Point.Empty, bounds.Size);
}

return result;

I then capture the image and assign it into a picture box.

In addition it looks like there's some variation between windows - some windows have shadows others do not. Most do, but some like Visual Studio and Chrome do not, so it's not even a simple matter of stripping out the extraneous pixels.

I've tried using GetClientRect() but that gets me just the client area which is not what I've after. What I'd like to get is the actual Window rectangle with borders but without the shadows.

Is there anyway to do this?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
378 views
Welcome To Ask or Share your Answers For Others

1 Answer

I'm running Windows 10 and came across the same issue when writing an app to snap windows to the top or bottom of the screen. I've found DwmGetWindowAttribute() to work. It returns a RECT with slightly different values than GetWindowRect()...

Results from a sample window:

GetWindowRect(): {X=88,Y=26,Width=871,Height=363}

DwmGetWindowAttribute(): {X=95,Y=26,Width=857,Height=356}

My testing showed that GetWindowRect() included the adornments, while DwmGetWindowAttribute() did not.

If you're getting identical results from both methods on a window with adornments, it might be that that particular window is drawing its own adornments, or that there is some other attribute or property set to the window that needs to be taken into account.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...