Lately, I had remote users testing one of my application. These users were not SnagIt users. They asked me to add a button to the application that will automatically create an email and attach the snapshot just taken.
So that was my inspiration for this month article.
Downloadable demo
This month downloadable solution has been created using Visual Studio 2015 but you can reuse the exact same code in older versions as well.
The solution contains both VB and C# code.
Creating a test UI
For the needs of the demo application, I have created a very sample form containing a grid showing dummy content coming from a previous article. The form also contains a button that when clicked will take a snapshot of the current form.
Figure 1: The demo application in action
Filling the datagrid is not the interesting part. So let’s jump right to the capture button!
Capturing the current UI Element
I have created an extension method that extends UIElement object type. This way, you could pass just a control instead of the whole form if you need a more specific capture.
This is the method that does the hard stuff:
<Runtime.CompilerServices.Extension> Public Function CaptureUiElement(source As UIElement) As Byte() Dim height As Double = source.RenderSize.Height Dim width As Double = source.RenderSize.Width Dim dpi As Double = 96 Dim renderTarget As New RenderTargetBitmap(CInt(width), CInt(height), dpi, dpi, PixelFormats.Pbgra32) Dim drawingVisual As New DrawingVisual() Dim drawingContext As DrawingContext = drawingVisual.RenderOpen() Using drawingContext drawingContext.DrawRectangle(New VisualBrush(source), Nothing, New Rect(New Point(0, 0), New Point(width, height))) End Using renderTarget.Render(drawingVisual) Dim jpgEncoder As New JpegBitmapEncoder() jpgEncoder.QualityLevel = 90 jpgEncoder.Frames.Add(BitmapFrame.Create(renderTarget)) Dim imageArray As Byte() Using outputStream As New MemoryStream() jpgEncoder.Save(outputStream) imageArray = outputStream.ToArray() End Using Return imageArray End Function
This method extends a UIElement (available in the source parameter). Using the size of this element, a jpeg (using the JpegBitmapEncoder from the System.Windows.Media.Imaging library) is created in a byte array and returned to the caller.
Using that method
Now that we have this method in place, it is quite easy to use.
The first thing you need to do is to call the CaptureUiElement method. As shown in the following code snippet, it is currently called on Me (for VB or this for C#) meaning that we want the whole form.
Once you have the byte array, you can for example save it using a BinaryWriter.
The complete code to capture the screen and save the file reads like this:
Private Sub ButtonCapture_Click(sender As Object, e As RoutedEventArgs) 'get a byte array containing the screen shot Dim screenshot As Byte() = Me.CaptureUiElement() 'save the byte array in a file in the current folder Using fileStream As New FileStream(String.Format("Screenshot_{0}.jpg", DateTime.Now.ToString("yyyyMMdd_HHmmss")), FileMode.Create, FileAccess.ReadWrite) Using binaryWriter As New BinaryWriter(fileStream) binaryWriter.Write(screenshot) binaryWriter.Close() End Using End Using End Sub
As explained earlier, I could have use “GridData.CaptureUiElement()” as well to only get the image of the grid.
Emailing the image
I haven’t included the code here to attach the image to an email. I will refer you to a previous article from “Sending e-mails with attachments (a different method)”.
Conclusion
This feature is not very complex and can be very helpful for many users not using tools like SnagIt and don’t want to learn to use the free snipping tool.