简体   繁体   English

没有活动窗口的屏幕截图

[英]Screen capture without active window

I'm trying to write a magnifier application using a winform or wpf windows. 我正在尝试使用Winform或WPF Windows编写放大镜应用程序。 The idea is to drag the window over a spot on the screen and magnify it. 想法是将窗口拖到屏幕上的某个位置上并放大。 I know it exists commercially but need to build a customized version. 我知道它在商业上存在,但需要构建定制版本。 The challenge I'm having is to capture the screen image behind the active application. 我面临的挑战是捕获活动应用程序后面的屏幕图像。 I have found code to capture a screen image below. 我在下面找到了捕获屏幕图像的代码。 But it includes the active window 但它包含活动窗口

    {
        Rectangle bounds = new Rectangle(this.Location, this.Size);
        Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height);
        Graphics g = Graphics.FromImage(bitmap);
        g.CopyFromScreen(this.Location, Point.Empty, bounds.Size);
        Bitmap bp2 = new Bitmap(bitmap); //  local copy of image...
        pictureBox1.Image = bp2;
    }

Adding statements to hide the active application correct the image capture, but introduce a screen flicker which I'd like to avoid. 添加语句以隐藏活动的应用程序可以纠正图像捕获,但是会引起屏幕闪烁,我想避免这种情况。 (modified code below) (下面的修改代码)

    {
        this.StartPosition = FormStartPosition.Manual;  // get current window location
        Point cur = this.Location;
        this.Location = new Point(-500, -500);  //  hide the active app off screen.

        Rectangle bounds = new Rectangle(cur, this.Size);
        Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height);
        Graphics g = Graphics.FromImage(bitmap);
        g.CopyFromScreen(cur, Point.Empty, bounds.Size);
        Bitmap bp2 = new Bitmap(bitmap); //  local copy of image...
        pictureBox1.Image = bp2;

        this.Location = cur;  // restore application location
    }

Can someone suggest an alternative to capture a screen region, behind an active windows? 有人可以建议在活动窗口后面捕获屏幕区域的替代方法吗?

Thx. 谢谢。

Wrapping the Magnification API is pretty useful. 包装放大API非常有用。 I created a Winforms control that does this. 我创建了一个Winforms控件来执行此操作。 Add a new class to your project and paste the code shown below. 将新类添加到您的项目中,然后粘贴以下代码。 Compile. 编译。 Drop the new control from the top of the toolbox onto a form. 将新控件从工具箱的顶部拖放到窗体上。

The TrackMouse property controls which part of the screen is shown magnified. TrackMouse属性控制屏幕的哪个部分被放大显示。 Set to False, it magnifies the area covered by the control, making it act like a magnifying glass. 设置为False时,它将放大控件覆盖的区域,使其像放大镜一样起作用。 Set to True, it will operate like Windows' Magnifier, following the mouse. 设置为True,跟随鼠标,它将像Windows的放大镜一样操作。

The Magnification property controls the amount of magnification. 放大倍数属性控制放大倍数。 You can already adjust it by using the mouse wheel. 您已经可以使用鼠标滚轮对其进行调整。

The form you drop it should have its TopMost property set to True. 放置的表单应将其TopMost属性设置为True。 You might want to tinker with its Region property to make it resemble a spyglass. 您可能需要修改其Region属性,使其类似于望远镜。

using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;

class Magnifier : Control {
    public Magnifier() {
        if (!MagInitialize()) throw new NotSupportedException();
        timer = new Timer { Interval = 45 };
        timer.Tick += (o, ea) => { if (trackMouse) setSource(false); else Invalidate(); };
    }
    [DefaultValue(false)]
    public bool TrackMouse {
        get { return trackMouse; }
        set { trackMouse = value; setSource(false); }
    }
    [DefaultValue(2.0f)]
    public float Magnification {
        get { return magnification; }
        set { magnification = Math.Max(1, value); setSource(true); }
    }

    protected override CreateParams CreateParams {
        get {
            var cp = base.CreateParams;
            if (!this.DesignMode) {
                cp.ClassName = "Magnifier";
                //cp.Style |= MS_SHOWMAGNIFIEDCURSOR;
                this.SetStyle(ControlStyles.UserPaint, true);
            }
            return cp;
        }
    }

    protected override void OnHandleCreated(EventArgs e) {
        base.OnHandleCreated(e);
        if (!this.DesignMode) {
            setSource(true);
            this.FindForm().LocationChanged += ParentLocationChanged;
            timer.Start();
        }
    }
    protected override void Dispose(bool disposing) {
        if (disposing) {
            var frm = this.FindForm();
            if (frm != null) frm.LocationChanged -= ParentLocationChanged;
            timer.Dispose();
            MagUninitialize();
        }
        base.Dispose(disposing);
    }

    private void ParentLocationChanged(object sender, EventArgs e) {
        if (!trackMouse) setSource(false);
    }
    protected override void OnSizeChanged(EventArgs e) {
        setSource(false);
        base.OnSizeChanged(e);
    }
    protected override void OnMouseWheel(MouseEventArgs e) {
        this.Magnification += e.Delta / 100f;
        ((HandledMouseEventArgs)e).Handled = true;
    }

    private void setSource(bool newmag) {
        if (!this.IsHandleCreated || this.DesignMode) return;
        if (newmag) {
            var xform = new MAGTRANSFORM();
            xform.v11 = xform.v22 = magnification;
            xform.v33 = 1.0f;
            MagSetWindowTransform(this.Handle, ref xform);
        }
        Point center;
        if (trackMouse) center = Cursor.Position;
        else {
            var rc = this.RectangleToScreen(this.Bounds);
            center = new Point(rc.Left + rc.Width / 2, rc.Top + rc.Height / 2);
        }
        var scr = Screen.FromPoint(center);
        var rect = new RECT();
        rect.left = Math.Max(scr.Bounds.Left, center.X - (int)(this.Width / magnification / 2));
        rect.top = Math.Max(scr.Bounds.Top, center.Y - (int)(this.Height / magnification / 2));
        rect.right = rect.left + (int)(this.Width / magnification);
        if (rect.right > scr.Bounds.Right) {
            rect.right = scr.Bounds.Right;
            rect.left = rect.right - (int)(this.Width / magnification);
        }
        rect.bottom = center.Y + (int)(this.Height / magnification);
        if (rect.bottom > scr.Bounds.Bottom) {
            rect.bottom = scr.Bounds.Bottom;
            rect.top = rect.bottom - (int)(this.Height / magnification);
        }
        MagSetWindowSource(this.Handle, ref rect);
        this.Invalidate();
    }

    private Timer timer;
    private bool trackMouse;
    private float magnification = 2.0f;

    private struct RECT {
        public int left, top, right, bottom;
    }
    private struct MAGTRANSFORM {
        public float v11, v12, v13;
        public float v21, v22, v23;
        public float v31, v32, v33;
    }
    [DllImport("magnification.dll")]
    private static extern bool MagInitialize();
    [DllImport("magnification.dll")]
    private static extern bool MagUninitialize();
    [DllImport("magnification.dll")]
    private static extern bool MagSetWindowSource(IntPtr hWnd, ref RECT rc);
    [DllImport("magnification.dll")]
    private static extern bool MagSetWindowTransform(IntPtr hWnd, ref MAGTRANSFORM xform);
    private const int MS_SHOWMAGNIFIEDCURSOR = 1;
    private const int MS_CLIPAROUNDCURSOR = 2;
    private const int MS_INVERTCOLORS = 4;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM