views:

902

answers:

3

Anyone know of a way to reliably take a snapshot of a WPF window? The PrintWindow api works well for "standard" win32 windows but since WPF uses DirectX, PrintWindow fails to capture an image. I think that one would need to grab the front buffer for the DirectX object associated with the window, but I am not sure how to do that.

Thanks!

+2  A: 

I'm not sure if this is what you mean, and I'm not sure I'm allowed to link to my blog or not, but is this any use? It basically uses a RenderTargetBitmap to generate a JPG. You can use it to "screenshot" an entire window then print that.

If this is against the rules, someone feel free to delete :)

Steven Robbins
Thanks Steve. This won't work for my case - I will update my question because it wasn't clear. Basically, I want to be able to capture this image with access to just the Hwnd and from another process.
Mo Flanagan
Ah, sorry, no idea then. I've done DirecX screenshots from within the app, but never remotely. That code was originally written for remote screenshots, but it used a self hosted WCF service, which I guess is no good for you?
Steven Robbins
A: 

You can use the PrintDialog.PrintVisual() method.

MSDN Link: http://msdn.microsoft.com/en-us/library/system.windows.controls.printdialog.printvisual.aspx

A sample: http://www.thejoyofcode.com/Reason_9._Printing.aspx

A: 

This Method should help you print the entire WPF / XAML Window

private void PrintWindow(PrintDialog pdPrint, System.Windows.Window wWin, string sTitle, System.Windows.Thickness? thMargin) { Grid drawing_area = new Grid(); drawing_area.Width = pdPrint.PrintableAreaWidth; drawing_area.Height = pdPrint.PrintableAreaHeight;

        Viewbox view_box = new Viewbox();
        drawing_area.Children.Add(view_box);
        view_box.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
        view_box.VerticalAlignment = System.Windows.VerticalAlignment.Center;

        if (thMargin == null)
        {
            view_box.Stretch = System.Windows.Media.Stretch.None;
        }
        else
        {

            view_box.Margin = thMargin.Value;
            view_box.Stretch = System.Windows.Media.Stretch.Uniform;
        }


        VisualBrush vis_br = new VisualBrush(wWin);


        System.Windows.Shapes.Rectangle win_rect = new System.Windows.Shapes.Rectangle();
        view_box.Child = win_rect;
        win_rect.Width = wWin.Width;
        win_rect.Height = wWin.Height;
        win_rect.Fill = vis_br;
        win_rect.Stroke = System.Windows.Media.Brushes.Black;
        win_rect.BitmapEffect = new System.Windows.Media.Effects.DropShadowBitmapEffect();

        // Arrange to produce output.
        Rect rect = new Rect(0, 0, pdPrint.PrintableAreaWidth, pdPrint.PrintableAreaHeight);
        drawing_area.Arrange(rect);

        // Print it.
        pdPrint.PrintVisual(drawing_area, sTitle);

    }

Regards Sean Campbell

Sean Campbell
Thanks Sean but this won't work, I need to be able to capture the image from another process using only the HWND, I don't have access to the "wWin" in this case
Mo Flanagan