在表格外使用放大镜

榻榻米

下午好!有一种形式(镜片),可以用作放大镜(在形式内部)。我需要摆脱TargetForm属性,以使窗体(镜头)无需绑定到窗体即可作为独立控件工作。用什么代码替换它,请告诉我。

在此处输入图片说明

在此处输入图片说明

Main_Form的代码

private void button1_Click(object sender, EventArgs e) {
    new Lens_Form() { TargetForm = this }.Show(this);
    Cursor.Hide();
}

Lens_Form的代码

public partial class Lens_Form : Form {
    public Form TargetForm { get; set; }
    public new float Scale { get; set; }

    private Bitmap tmpBmp;

    public Lens_Form() {
        InitializeComponent();

        // Drawing the Ellipse
        GraphicsPath path = new GraphicsPath();
        path.AddEllipse(ClientRectangle);
        Region = new Region(path);

        // Set Scale
        Scale = 2; // 2-4-6-8
    }

    protected override void OnPaint(PaintEventArgs e) {
        Point pos = TargetForm.PointToClient(Cursor.Position);
        Location = new Point(Cursor.Position.X - Width / 2, Cursor.Position.Y - Height / 2);

        Rectangle screenRectangle = TargetForm.RectangleToScreen(TargetForm.ClientRectangle);
        int dY = screenRectangle.Top - TargetForm.Top;
        int dX = screenRectangle.Left - TargetForm.Left;

        e.Graphics.TranslateTransform(Width / 2, Height / 2);
        e.Graphics.ScaleTransform(Scale, Scale);
        e.Graphics.TranslateTransform(-pos.X - dX, -pos.Y - dY);

        if (tmpBmp != null) e.Graphics.DrawImage(tmpBmp, 0, 0);
    }

    // Timer
    private void Main_Timer_Tick(object sender, EventArgs e) {
        tmpBmp = new Bitmap(TargetForm.Size.Width, TargetForm.Size.Height);
        TargetForm.DrawToBitmap(tmpBmp, new Rectangle(0, 0, TargetForm.Width, TargetForm.Height));
        Invalidate();
    }
}
空博士

您需要扩大规模并使用更大的边界,而不是屏幕的边界。通过该Graphics.CopyFromScreen方法捕获屏幕而不是Form

这是一个使用相同方法的工作示例,其中包括一些其他功能。

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

public class Lens_Form : Form
{
    private readonly Timer timer;
    private Bitmap scrBmp;
    private Graphics scrGrp;
    private bool mouseDown;

    public Lens_Form() : base()
    {
        SetStyle(
            ControlStyles.OptimizedDoubleBuffer |
            ControlStyles.Opaque |
            ControlStyles.UserPaint |
            ControlStyles.AllPaintingInWmPaint, true);
        UpdateStyles();

        FormBorderStyle = FormBorderStyle.None;
        ShowInTaskbar = false;
        TopMost = true;
        Width = 150;
        Height = 150;

        timer = new Timer() { Interval = 55, Enabled = true };
        timer.Tick += (s, e) => Invalidate();
    }

    public int ZoomFactor { get; set; } = 2;
    public bool HideCursor { get; set; } = true;
    public bool AutoClose { get; set; } = true;
    public bool NearestNeighborInterpolation { get; set; }

    protected override void OnShown(EventArgs e)
    {
        base.OnShown(e);

        var gp = new GraphicsPath();
        gp.AddEllipse(0, 0, Width, Height);
        Region = new Region(gp);

        CopyScreen();
        SetLocation();

        Capture = true;
        mouseDown = true;
        if (HideCursor) Cursor.Hide();
    }

    protected override void OnMouseDown(MouseEventArgs e)
    {
        base.OnMouseDown(e);

        if (e.Button == MouseButtons.Left)
        {
            mouseDown = true;
            if (HideCursor) Cursor.Hide();
        }
    }

    protected override void OnMouseMove(MouseEventArgs e)
    {
        base.OnMouseMove(e);
        Invalidate();
    }

    protected override void OnMouseUp(MouseEventArgs e)
    {
        base.OnMouseUp(e);

        mouseDown = false;
        if (HideCursor) Cursor.Show();
        if (AutoClose) Dispose();
    }

    protected override void OnKeyDown(KeyEventArgs e)
    {
        base.OnKeyDown(e);

        if (e.KeyCode == Keys.Escape) Dispose();
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        if (mouseDown) SetLocation();
        else CopyScreen();

        var pos = Cursor.Position;
        var cr = RectangleToScreen(ClientRectangle);
        var dY = cr.Top - Top;
        var dX = cr.Left - Left;

        e.Graphics.TranslateTransform(Width / 2, Height / 2);
        e.Graphics.ScaleTransform(ZoomFactor, ZoomFactor);
        e.Graphics.TranslateTransform(-pos.X - dX, -pos.Y - dY);
        e.Graphics.Clear(BackColor);

        if (NearestNeighborInterpolation)
        {
            e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
            e.Graphics.PixelOffsetMode = PixelOffsetMode.Half;
        }

        if (scrBmp != null) e.Graphics.DrawImage(scrBmp, 0, 0);
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            timer.Dispose();
            scrBmp?.Dispose();
            scrGrp?.Dispose();
        }
        base.Dispose(disposing);
    }

    private void CopyScreen()
    {
        if (scrBmp == null)
        {
            var sz = Screen.FromControl(this).Bounds.Size;

            scrBmp = new Bitmap(sz.Width, sz.Height);
            scrGrp = Graphics.FromImage(scrBmp);
        }

        scrGrp.CopyFromScreen(Point.Empty, Point.Empty, scrBmp.Size);
    }

    private void SetLocation()
    {
        var p = Cursor.Position;

        Left = p.X - Width / 2;
        Top = p.Y - Height / 2;
    }
}

主窗体中的呼叫者:

private void SomeButton_MouseDown(object sender, MouseEventArgs e)
{
    var f = new Lens_Form()
    {
        Size = new Size(150, 150),
        AutoClose = true,
        HideCursor = true,
        ZoomFactor = 2,
        NearestNeighborInterpolation = false
    };
    f.Show();
}

笔记

  • The SetStyle method is called in the constructor to apply some useful styles in this context to the control. To takeover the painting routine, reduce the flickering, and prevent painting the background.

  • Override the OnShown method to get the size set by the caller and set the region, take a screenshot, and set the Form's location.

  • Override the mouse methods to apply the properties and refresh the view.

  • 覆盖在OnPaint按下鼠标左键时移动窗体方法,否则重新复制屏幕。这是给您两个选项,如果禁用该AutoClose属性,则在拖动窗体时或在不按任何按钮的情况下移动鼠标时进行放大对于转换部分,使用Cursor.PositionForm的当前坐标和屏幕坐标(而不是主From)进行数学运算。

  • 最后,重写该Dispose方法进行清理。

演示版

SOQ66321638

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

WPF中的放大镜

来自分类Dev

iOS黑色放大镜

来自分类Dev

默认屏幕放大镜?

来自分类Dev

默认屏幕放大镜?

来自分类Dev

自动启动放大镜

来自分类Dev

使用CSS使放大镜遵循椭圆形路径

来自分类Dev

如何在Qualtrics中使用放大镜?

来自分类Dev

新的 Windows 10 放大镜使用什么算法?

来自分类Dev

当使用nextjs放大时,React图像放大镜不起作用

来自分类Dev

jQuery放大镜不在图像外

来自分类Dev

跟随光标在画布上的放大镜

来自分类Dev

屏幕放大镜也显示鼠标指针

来自分类Dev

如何使用userChrome.css从现代版本的Firefox / Iceweasel中删除放大镜?

来自分类Dev

当我使用AVPlayerLayer时,放大镜以错误的方式出现

来自分类Dev

当使用放大镜js更改src时,如何刷新img src?

来自分类Dev

放大镜悬停后iOS屏幕闪烁

来自分类Dev

撤消Google Chrome检查器的放大镜工具?

来自分类Dev

放大镜显示UIWindow在后面

来自分类Dev

跟随画布光标的放大镜

来自分类Dev

为什么我的搜寻按钮没有放大镜?

来自分类Dev

HTML5搜索输入放大镜替代?

来自分类Dev

Facebook Feed对话框中的神秘放大镜

来自分类Dev

如何隐藏Windows 10的放大镜(缩放)?

来自分类Dev

如何在羽毛灯灯箱中取出放大镜?

来自分类Dev

在输入type =“ search”元素内增加放大镜图标

来自分类Dev

更改放大镜和灯箱图像 woocommerce

来自分类Dev

如何显示与放大镜一样大的文本

来自分类Dev

使用预制的javascript放大镜时,如何在水平方向上对齐图像并以CSS为中心?

来自分类Dev

如何在一个子图中显示图像的放大(图上放大镜)