首页 > 解决方案 > 为什么它不在新的透明表单上用鼠标绘制矩形?

问题描述

它到达了F_Paint事件,但没有到达F_MouseDown事件。我希望能够在F表单上绘制矩形。

也许因为F表格是透明的,所以不能在上面画画?但它永远不会到达F_MouseDown我在事件内部使用断点的F_MouseDown事件。

不知道为什么它没有参加MouseDown活动。

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 System.Windows.Forms;

namespace Tester
{
    public partial class Form1 : Form
    {
        Ffmpeg ffmpeg = new Ffmpeg();

        private bool _canDraw;
        private int _startX, _startY;
        private Rectangle _rect;

        public Form1()
        {
            InitializeComponent();

            BackColor = Color.Blue;
            TransparencyKey = BackColor;
            Opacity = 1;
            var f = new HelperForm { Opacity = 0, ShowInTaskbar = false, FormBorderStyle = FormBorderStyle.None };
            f.MouseDown += F_MouseDown;
            f.MouseMove += F_MouseMove;
            f.MouseUp += F_MouseUp;
            f.Paint += F_Paint;
            f.Show();
            Visible = false;
            Owner = f;
            Visible = true;
            Move += (o, a) => f.Bounds = Bounds;
            Resize += (o, a) => f.Bounds = Bounds;
            f.Bounds = Bounds;
            ffmpeg.Start(@"d:\ffmpegx86\test.mp4", 24);
        }

        private void F_Paint(object sender, PaintEventArgs e)
        {
            //Create a new 'pen' to draw our rectangle with, give it the color red and a width of 2
            using (Pen pen = new Pen(Color.Red, 2))
            {
                //Draw the rectangle on our form with the pen
                e.Graphics.DrawRectangle(pen, _rect);
            }
        }

        private void F_MouseUp(object sender, MouseEventArgs e)
        {
            //The system is no longer allowed to draw rectangles
            _canDraw = false;
        }

        private void F_MouseMove(object sender, MouseEventArgs e)
        {
            //If we are not allowed to draw, simply return and disregard the rest of the code
            if (!_canDraw) return;

            //The x-value of our rectangle should be the minimum between the start x-value and the current x-position
            int x = Math.Min(_startX, e.X);
            //The y-value of our rectangle should also be the minimum between the start y-value and current y-value
            int y = Math.Min(_startY, e.Y);

            //The width of our rectangle should be the maximum between the start x-position and current x-position minus
            //the minimum of start x-position and current x-position
            int width = Math.Max(_startX, e.X) - Math.Min(_startX, e.X);

            //For the hight value, it's basically the same thing as above, but now with the y-values:
            int height = Math.Max(_startY, e.Y) - Math.Min(_startY, e.Y);
            _rect = new Rectangle(x, y, width, height);
            //Refresh the form and draw the rectangle
            Refresh();
        }

        private void F_MouseDown(object sender, MouseEventArgs e)
        {
            //The system is now allowed to draw rectangles
            _canDraw = true;
            //Initialize and keep track of the start position
            _startX = e.X;
            _startY = e.Y;
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            ffmpeg.Close();
        }
    }

    class HelperForm : Form
    {
        protected override CreateParams CreateParams
        {
            get
            {
                const int WS_EX_TOOLWINDOW = 0x80;
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= WS_EX_TOOLWINDOW;
                return cp;
            }
        }
    }
}

标签: c#winforms

解决方案


阻止绘制矩形和触发鼠标事件的原因有很多。首先,您将设置Opacity0; 这意味着您尝试绘制的任何内容都永远不可见。相反,您应该将 设置为TransparencyKey中的颜色BackColor

f.TransparencyKey = f.BackColor;

然后,您尝试使用_rect从未初始化的对象绘制一个矩形;因此,您尝试绘制的矩形将以 0 宽度和 0 高度的大小绘制,这意味着它不会被绘制,因此,在初始化期间,您应该为_rect例如提供默认值:

_rect = new Rectangle(Point.Empty, this.Size);

绘制的矩形现在应该是可见的;但是,事件不会触发,因为您正在反转表单所有权,所以,而不是

Owner = f;

利用:

f.Owner = this;

推荐阅读