下午好!有一种形式(镜片),可以用作放大镜(在形式内部)。我需要摆脱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.Position
Form的当前坐标和屏幕坐标(而不是主From)进行数学运算。
Dispose
方法进行清理。演示版
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句