0

Suppose I have the following winform interface: enter image description hereI try to get a screenshot of the whole interface, but I don't need to include the window information in the upper left corner.

I try to take a screenshot with CopyFromScreen:

Graphics myGraphics = this.CreateGraphics();
Size s = this.Size;
Bitmap bit = new Bitmap(s.Width, s.Height, myGraphics);
Graphics g = Graphics.FromImage(bit);
g.CompositingQuality = CompositingQuality.HighQuality;
Point screenPoint = this.PointToScreen(this.Location);
g.CopyFromScreen(screenPoint, new Point(0, 0), s);
bit.Save("temp.png", System.Drawing.Imaging.ImageFormat.Png);

The result I get looks like this: enter image description hereI know it might be because of screen scaling issues, mine is 150%. I tried adjusting the screen zoom to 100%, but that didn't work. If you have any comments, comments are welcome, I'm very grateful for that!

According to How to configure an app to run correctly on a machine with a high DPI setting (e.g. 150%)?, I made the following changes: My app.manifest file:

<application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings>
      <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
      <longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
    </windowsSettings>
</application>

My App.config file:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/>
    </startup>
</configuration>

My Program.cs file:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Diploma
{
    internal static class Program
    {
        /// <summary>
        ///
        /// </summary>
        [STAThread]
        static void Main()
        {
            if (Environment.OSVersion.Version.Major >= 6) {
                SetProcessDPIAware();
            }

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new PhD_CN_B());
        }

        [System.Runtime.InteropServices.DllImport("user32.dll")]
        private static extern bool SetProcessDPIAware();
    }
}

My Form file:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PdfSharp;
using PdfSharp.Drawing;
using PdfSharp.Pdf;
using PdfSharp.Pdf.IO;
using System.Windows.Forms;
using System.Diagnostics;
using System.Drawing.Drawing2D;

namespace Diploma {
    public partial class PhD_CN_B : Form {
        public PhD_CN_B() {
            InitializeComponent();
        }

        private void textBox1_TextChanged(object sender, EventArgs e) {

        }

        private void CaptureScreen() {

            Graphics myGraphics = this.CreateGraphics();
            Size s = this.Size;
            Bitmap bit = new Bitmap(s.Width, s.Height, myGraphics);
            Graphics g = Graphics.FromImage(bit);
            g.CompositingQuality = CompositingQuality.HighQuality;
            Point screenPoint = this.PointToScreen(this.Location);
            //Console.WriteLine(screenPoint);
            g.CopyFromScreen(screenPoint, new Point(0, 0), s);
            bit.Save("temp.png", System.Drawing.Imaging.ImageFormat.Png);


        }

        private void button1_Click(object sender, EventArgs e) {

            CaptureScreen();
        }

        private void PhD_CN_B_Load(object sender, EventArgs e) {

        }
    }
}

But I still can't get a full screenshot!

ki-ljl
  • 499
  • 2
  • 9
  • This question got marked as a duplicate but the linked question is different and does not answer it. – Dan Ling Apr 04 '22 at 04:15
  • @DanLing Why do you think the marked duplicate doesn't answer the question? In the sense that *fixes the problem* (since it's a DpiAwareness problem, or lack thereof). – Jimi Apr 04 '22 at 04:19
  • @Jimi Are you the one the closed this? If so, how about you explain how that other one addresses this? It's not even the same question and if it somehow helps there is no obvious relation. – Dan Ling Apr 04 '22 at 04:23
  • For the OP, here is a code sample that actually answers the question: https://gist.github.com/dotnetdan/8025e380d6f1c803f9057b3f0f20d495 – Dan Ling Apr 04 '22 at 04:24
  • I tried using SetProcessDPIAware to solve the problem, but it didn't work. – ki-ljl Apr 04 '22 at 04:24
  • You don't need to call a Win32 function. Make your app DpiAware by following one of the suggested methods in that question. That's all there's is to it. Your application is clearly not DpiAware. The logic used to make your app DpiAware depends on the .Net version in use. .Net 5+ apps already set this in Programs.cs using the new Template. In .Net Framework 4.8, you either use the `app.manifest` or `App.Config`. The latter is preferred. -- When the application is not DpiAware, you receive *virtualized* measures and coordinates. -- Remember to design at 100% scale. – Jimi Apr 04 '22 at 04:29
  • @DanLing I tried your method and it didn't work, maybe it's because my OS is win11? – ki-ljl Apr 04 '22 at 04:30
  • @ki-ljl based on the comment from Jimi, you're better off going that route. the solution I provided is appropriate for screen shotting a non-dpi aware application that you can't change. And yes, it's possible that it doesn't work for you due to registry changes in win 11 – Dan Ling Apr 04 '22 at 05:06
  • @Jimi ok i'm trying it, thanks for your comment. – ki-ljl Apr 04 '22 at 05:07
  • As mentioned, remove the call to `SetProcessDPIAware()`, this was used in Windows 7, pre-.Net FX 4.7.1. If you're targeting .Net Framework 4.8, use `app.config` to select `PerMonitorV2` DpiAwareness mode. -- Note that PdfShap may introduce automatic DpiAwareness (`SystemAware`) when you don't target the `[package]-gdi` libraries explicitly (since it imports WPF / PresentationFramework libraries). But probably even if you do. That doesn't work well with WinForms in Window 11. -- Also remove this: `Graphics myGraphics = this.CreateGraphics();` + `this.Location` is already a Screen coordinate etc – Jimi Apr 04 '22 at 16:16
  • When you use `app.config` to set DpiAwareness mode, you don't also set it in `app.manifest`, since the latter overrides the former's settings. -- A couple of references: [High DPI Desktop Application Development on Windows](https://learn.microsoft.com/en-us/windows/win32/hidpi/high-dpi-desktop-application-development-on-windows) - [Setting the default DPI awareness for a process](https://learn.microsoft.com/en-us/windows/win32/hidpi/setting-the-default-dpi-awareness-for-a-process) – Jimi Apr 04 '22 at 16:21
  • @Jimi I will try to revise it again based on your suggestion, thank you very much. – ki-ljl Apr 04 '22 at 16:52

0 Answers0