4

I implemented the code in the first answer to this question and it works great except that it doesn't include the title bar, which is a must for my needs. Does anybody have any idea what I'm doing wrong?

I've updated my example to show all the other commented out attempts that failed. Here's my code:

Window shellView = Application.Current.MainWindow;

Rect bounds = VisualTreeHelper.GetDescendantBounds(shellView);
//Rect bounds = new Rect(new Size(shellView.ActualWidth, shellView.ActualHeight));
//Rect bounds = shellView.RestoreBounds;
//Rect bounds = VisualTreeHelper.GetContentBounds(shellView);
//Rect bounds = new Rect(new Size(VisualTreeHelperEx.FindDescendantByType<Window>(shellView).ActualWidth,
//    VisualTreeHelperEx.FindDescendantByType<Window>(shellView).ActualHeight));

RenderTargetBitmap renderTarget = new RenderTargetBitmap((int)bounds.Width, (int)bounds.Height, 96, 96, PixelFormats.Pbgra32);
DrawingVisual visual = new DrawingVisual();

string fileName = $@"{Environment.GetFolderPath(Environment.SpecialFolder.Desktop)}\Screen_Capture.png";
if (_dialogService.ShowSaveFileDialog(ref fileName, "PNG Files | *.png"))
{
    using (DrawingContext context = visual.RenderOpen())
    {
        VisualBrush visualBrush = new VisualBrush(shellView);
        context.DrawRectangle(visualBrush, null, new Rect(new Point(), bounds.Size));
    }

    renderTarget.Render(visual);
    PngBitmapEncoder bitmapEncoder = new PngBitmapEncoder();
    bitmapEncoder.Frames.Add(BitmapFrame.Create(renderTarget));

    using (Stream stm = File.Create(fileName))
    {
        bitmapEncoder.Save(stm);
    }
}

And at XAMIMAX's request, what I can share of the XAML with names changed:

<Window x:Class="MyProject.Shell.Views.Shell.ShellView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:ap="clr-namespace:MyProject.Common.Support.AttachedProperties;assembly=MyProject.Common.Support"
        xmlns:controls="clr-namespace:MyProject.Common.Support.Controls;assembly=MyProject.Common.Support"
        xmlns:converters="clr-namespace:MyProject.Common.Support.Converters;assembly=MyProject.Common.Support"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:dts="clr-namespace:MyProject.Common.Support.DataTemplateSelectors;assembly=MyProject.Common.Support"
        xmlns:enums="clr-namespace:MyProject.Shell.Enums"
        xmlns:enums1="clr-namespace:MyProject.Common.Support.Enums;assembly=MyProject.Common.Support"
        xmlns:ikriv="clr-namespace:MyProject.Common.Support.AttachedProperties;assembly=MyProject.Common.Support"
        xmlns:intr="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
        xmlns:m="clr-namespace:MyProject.Common.Support.MarkupExtensions;assembly=MyProject.Common.Support"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:resources="clr-namespace:MyProject.Shell.Views.Shell.Resources"
        xmlns:ss="clr-namespace:MyProject.Common.Support.StyleSelectors;assembly=MyProject.Common.Support"
        xmlns:system="clr-namespace:System;assembly=mscorlib"
        xmlns:views="clr-namespace:MyProject.NotificationModule.Client.Views;assembly=MyProject.NotificationModule.Client"
        xmlns:constants="clr-namespace:MyProject.Shell"
        x:Name="shell"
        Title="{Binding MyProjectApplicationTitle}"
        Width="1024"
        Height="768"
        MinWidth="800"
        MinHeight="600"
        Background="{DynamicResource PrimarySolidColorBrush}"
        Icon="/Resources/Embedded/MyProject.ico"
        mc:Ignorable="d">

        <controls:LocalizationScope.Content>
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="*" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>

                <Grid.Children>

                    <Grid Grid.Row="1">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="{Binding NavigationBarWidth, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                              MinWidth="38"
                                              MaxWidth="400" />
                    </Grid>

                </Grid.Children>
            </Grid>
        </controls:LocalizationScope.Content>
</Window>

I hope that's enough of the XAML to help. I also tried the example at this link Generating a screenshot of a WPF window, but got the same results: no title bar.

Phil N DeBlanc
  • 398
  • 1
  • 13
  • On my side the title bar is also displayed, can i see code of your Window to understand what's different between mine and yours? – nalka Dec 11 '19 at 13:27
  • Thanks, @nalka, but it's huge and there's a lot of proprietary stuff in there that I don't feel comfortable posting. What I can say is that the application main window, the ShellView's class' code behind is declared like this: _public partial class ShellView : Window, IShell, IVisibleShell _ So it's definitely inheriting from the Window class. – Phil N DeBlanc Dec 11 '19 at 13:36
  • Have you modifed the window to have a custom title bar? (this is achieved by using `WindowStyle="None"` and `AllowsTransparency="True"`) – nalka Dec 11 '19 at 13:38
  • Nope. Uses a standard title bar: _Title="{Binding MyApplicationTitle}"_ – Phil N DeBlanc Dec 11 '19 at 13:41
  • Have you tried using actualWidth and ActualHeight from window? And shellView only causes concerns. This is probably mashup of winforms and wpf with no practise whatsoever and hacks all over the place – XAMlMAX Dec 11 '19 at 17:37
  • @XAMlMAX, did you see the link in my post? This is pretty much the exact same code with the addition of a SaveFileDialog for the user to be able to choose where to save the screen shot. So no, it's not a mashup. I did try this: Rect bounds = new Rect(new Size(shellView.Width, shellView.Height)); and still no title bar. – Phil N DeBlanc Dec 12 '19 at 05:53
  • I meant the property called `ActualWidth`, which can have different values than `Width` [SO answer](https://stackoverflow.com/a/607849/2029607) and yes I saw question that you have linked, hence the the suggestion to try another property. BTW xaml for your window can be posted here, just remove the stuff that we don't need, which I think is all inside of the root Grid. – XAMlMAX Dec 12 '19 at 09:19
  • @XAMlMAX ActualWidth doesn't work either. I've added my Window's XAML header info and trimmed code. I hope it's enough for you. – Phil N DeBlanc Dec 13 '19 at 08:53
  • The window decorations like frame and title bar are not part of the visual tree of a WPF application. Hence RenderTargetBitmap won't work. You'll need something like this: https://stackoverflow.com/q/1163761/1136211 – Clemens Dec 17 '19 at 09:07
  • @Clemens I looked at that link and was able to bastardize some code from it that works. Thank you! Post an answer and you can collect the bounty! – Phil N DeBlanc Dec 17 '19 at 10:19

1 Answers1

1

Thanks to the link that @Clemens sent me to, I was able to use some of the code on that page to come up with this working method. It grabs a few pixels more that the active window, but that works for me!

    private void TakeScreenshot()
    {
        var rect = new Rect();
        GetWindowRect(GetForegroundWindow(), 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 System.Drawing.Point(bounds.Left, bounds.Top), System.Drawing.Point.Empty, bounds.Size);
        }

        string fileName = $@"{Environment.GetFolderPath(Environment.SpecialFolder.Desktop)}\Screen_Capture.png";
        if (_dialogService.ShowSaveFileDialog(ref fileName, "PNG Files | *.png"))
        {

            result.Save(fileName, ImageFormat.Png);

            _dialogService.ShowInfoDialog(_localizationService["Shell.Views.Shell.HelpMenu.ScreenshotSaved"] + $"{fileName}");
        }
    }
Phil N DeBlanc
  • 398
  • 1
  • 13