0

I am currently migrating an old Winforms project to WPF with the MVVM pattern, so I have been strugling with a lot of things. One on the last things I need to understand is how to do a screen capture of the application Window after a SaveDialog Close. On Winforms is easy and I have the following code that does the job:

Form frm = Form.ActiveForm;
if (frm != null)
{
    using (Bitmap bmp = new Bitmap(frm.Width, frm.Height))
    {
        frm.DrawToBitmap(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height));
        bmp.Save(saveFileDialog.FileName, ImageFormat.Png);
    }
}

I have been struggling a lot with this and I have found something equivalent on WPF:

double screenLeft = SystemParameters.VirtualScreenLeft;
double screenTop = SystemParameters.VirtualScreenTop;
double screenWidth = SystemParameters.VirtualScreenWidth;
double screenHeight = SystemParameters.VirtualScreenHeight;

using (Bitmap bmp = new Bitmap((int)screenWidth, (int)screenHeight))
{
    using (Graphics g = Graphics.FromImage(bmp))
    {
        g.CopyFromScreen((int)screenLeft, (int)screenTop, 0, 0, bmp.Size);
        bmp.Save(nombreArchivo);
    }
}

The problem with the past code is the following: -First it creates a picture of the Whole screen. -Second it give me ghosting results as soon as the SaveDialog close.

I just ask a way of how to do it as simple as Winforms using Form.ActiveForm; or the equivalent on WPF which I can't find.

Thanks in advance.

EDIT: Even if is marked as duplicated, none of the "duplicated" questions satisfied my needs, but I finally realized how to do it in a similar way of Winforms (simple), in case anyone needs it.

Window? window = Application.Current.Windows.OfType<Window>().SingleOrDefault(x => x.IsActive);
if (window != null)
{
    //Render Bitmap for Width and Height of window
    RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap((int)window.ActualWidth, (int)window.ActualHeight, 96, 96, Pixelwindowats.Pbgra32);
    renderTargetBitmap.Render(window);

    //Define encoder png
    PngBitmapEncoder png = new PngBitmapEncoder();
    png.Frames.Add(BitmapFrame.Create(renderTargetBitmap));
    using (Stream stm = File.Create(nombreArchivo))
    {
        png.Save(stm);
    }
}
  • 1
    What do you mean by _ghosting results_? – emoacht Jan 04 '23 at 04:45
  • have you tried this https://www.codeproject.com/Articles/91487/Screen-Capture-in-WPF-WinForms-Application – Noorul Jan 04 '23 at 04:52
  • there are some duplicates also available https://www.codeproject.com/Articles/91487/Screen-Capture-in-WPF-WinForms-Application – Noorul Jan 04 '23 at 04:53
  • @emoacht as soon as I close the SaveDialog it take the screenshot but the SaveDialog is still dissapearing leaving a Ghosting effect, is still not the desire solution that I want because I only need the APP area and ignore everything else. – Andres Diaz De Valdes Jan 04 '23 at 12:48
  • @Noorul thanks, but is not what I want, I just the equivalent result on WPF from Winforms code, which is only the APP screenshot – Andres Diaz De Valdes Jan 04 '23 at 12:50
  • @AndresDiazDeValdes You can insert `Task.Delay` to wait SaveDialog disappeared. – emoacht Jan 04 '23 at 14:35
  • @emoacht yep, It came across to my mind too, but I refused to fix the problem like that, luckily after a lot of trial and error the answer on my EDIT was a success. Thanks for the advices. – Andres Diaz De Valdes Jan 04 '23 at 18:16
  • @AndresDiazDeValdes Your WinForms code produces an image with window chrome while your revised WPF code produces an image of only client area. If your original intention is the latter, your question can be read as misleading. – emoacht Jan 05 '23 at 00:17
  • @Andres if none of the duplicates answer your question you should post your answer there, not create a new question. That way all the answers are in one place instead of spread all over SO. – Dour High Arch Jan 07 '23 at 23:02
  • @DourHighArch I found it myself after the questions was created. – Andres Diaz De Valdes Jan 08 '23 at 16:54

0 Answers0