代码之家  ›  专栏  ›  技术社区  ›  John B

屏幕捕获程序复制多个选定区域

  •  0
  • John B  · 技术社区  · 7 年前

    我遵循Huw Collingbourne程序,用C#创建了一个屏幕捕获程序。然而,我注意到了几个奇怪的项目,无论我使用他创建的程序还是我修改的程序都是如此。具体来说,我创建了一个程序,可以打开一个窗口,让您捕获该区域。 我认为这与我的电脑上的坐姿有关,但如果其他人要使用我的屏幕捕获程序,我需要知道如何预测和解决这个问题! 如果我的windows 10显示设置为100%,我会得到比所选窗口多一点的内容,如果我将显示设置为125%文本,那么我会得到很多所选区域。保留默认大小时,我的大小应为555484。但我捕获的要大得多。

    public partial class Form1 : Form
    {
        //https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getwindowrect
        [DllImport("user32.dll")]
        private static extern IntPtr GetForegroundWindow();
        [DllImport("user32.dll")]
        private static extern IntPtr GetDesktopWindow();
        [DllImport("user32.dll")]
        private static extern bool GetWindowRect(IntPtr hWnd, ref Rectangle lpRect);
    
        //ICON info
        //https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getcursorinfo
        [DllImport("user32.dll")]
        private static extern bool GetIconInfo(IntPtr hIcon, out ICONINFO piconinfo);
        [DllImport("user32.dll")]
        private static extern bool GetCursorInfo(out CURSORINFO pci);
    
    
        public struct POINT
        {
            public Int32 x;
            public Int32 y;
        }
    
        public struct ICONINFO
        {
            public bool fIcon;
            public Int32 xHotspot;
            public Int32 yHotspot;
            public IntPtr hbmMask;
            public IntPtr hbmColor;
        }
    
        public struct CURSORINFO
        {
            public Int32 cbSize;
            public Int32 flags;
            public IntPtr hCursor;
            public Point ptScreenPos;
        }
    
        GrabRegionForm grabForm;
    
        public void GrabRect(Rectangle rect)
        {
            int rectWidth = rect.Width - rect.Left;
            int rectHeight = rect.Height - rect.Top;
            Bitmap bm = new Bitmap(rectWidth, rectHeight);
            Graphics g = Graphics.FromImage(bm);
            g.CopyFromScreen(rect.Left, rect.Top, 0, 0, new Size(rectWidth, rectHeight));
            DrawMousePointer(g, Cursor.Position.X - rect.Left, Cursor.Position.Y - rect.Top);
            this.pb_screengrab.Image = bm;
            Clipboard.SetImage(bm);
        }
    }
    
    public partial class GrabRegionForm : Form
    {
        public Rectangle formRect;
        private Form1 mainForm;
        [DllImport("user32.dll")]
        public static extern bool ReleaseCapture();
        [DllImport("user32.dll")]
        public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
        private void buttonOK_Click(object sender, EventArgs e)
        {
            formRect = new Rectangle(this.Left, this.Top, this.Left + this.Width, this.Top + this.Height);
            this.Hide();
            mainForm.GrabRect(formRect);
            Close();
        }
    }
    

    ScreenGrab with Display at 100%

    ScreenGrab with Display at 125%

    Area showing capture window

    Area Actually Captured

    1 回复  |  直到 7 年前
        1
  •  0
  •   John B    7 年前

    来自吉米 https://stackoverflow.com/users/7444103/jimi 如何配置应用程序以在具有高DPI设置的计算机上正确运行 How to configure an app to run correctly on a machine with a high DPI setting (e.g. 150%)?

    来自吉米 https://stackoverflow.com/users/7444103/jimi 将SetWindowPos与多个监视器一起使用 Using SetWindowPos with multiple monitors

    如果我的应用程序只针对windows 10,那么现在就非常简单了。 如果使用Windows 10,则使用4.7可以更轻松地更改DPI设置。

    https://docs.microsoft.com/en-us/dotnet/framework/winforms/high-dpi-support-in-windows-forms

    然后将以下内容添加到Windows 10兼容性推荐下XML中的app.manifest文件中。

    supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"
    

    在app.config文件中启用每监视器DPI感知。 Windows窗体引入了一个新元素,以支持从.NET Framework 4.7开始添加的新功能和自定义。要利用支持高DPI的新功能,请将以下内容添加到应用程序配置文件中。

    转到System.Windows.Forms.ApplicationConfiguration部分的XML行

    add key="DpiAwareness" value="PerMonitorV2"
    
    推荐文章