Using a screen capture tool these days is second nature to most computer users. So much so, that it's likely that your customers may expect to find screen capture features in your application. How much work is required to add this feature to a WPF application? It turns out that it's not that hard to add if you aren't afraid to make some PInvoke calls out to native Win32 libraries and interop with Windows Forms. Perhaps the next version of WPF will contain a screen capture API, but for now you need to roll your own.
First up, let's look at the basic XAML for the interface.
This XAML creates a simple UI with an Image control embedded within a ScrollViewer. The Image control is where the captured UI will be shown.
I'm going to use the System.Drawing.Graphics class to grab the screen shot. More specifically, I will call the CopyFromScreen method to do the work. This method does a Bit Block (BitBlt) transfer from the screen into our graphics context. I'll need to add a reference to System.Drawing.dll to our project before continuing.
Setting up the DeleteObject native call
It's important to release native resources correctly. As you will see in a minute at one point in the code, I am getting an unmanaged pointer to the native image. In order to prevent memory leaks I have to call the GDI DeleteObject function. Since this is a PInvoke call I'll add this DllImport attribute to my code.
Finally, here is the commented code that captures the screenshot. Note this captures the whole screen. If you want to capture a portion of the window, use a different rectangle for the capture size.
This was first published in June 2010