为什么当快速移动鼠标时,新窗体不粘在鼠标移动位置上

本文关键字:鼠标 移动 窗体 位置 新窗体 为什么 | 更新日期: 2023-09-27 18:09:11

我有这个事件:

protected override void OnMouseDown(MouseEventArgs e)
{
    mOffset = new Point(Width / 2 - e.X, Height / 2 - e.Y);
    mCurrentPoint = PointToScreen(new Point(e.X + mOffset.X, e.Y + mOffset.Y));
    mTargetPoint = mCurrentPoint;
    mTimer.Enabled = true;
}

和这个事件:

protected override void OnMouseMove(MouseEventArgs e)
{
    mTargetPoint = PointToScreen(new Point(e.X + mOffset.X, e.Y + mOffset.Y));
    mTimer.Enabled = true;
}

如果我只是快速移动鼠标,我就会失去对窗体的关注,我正在移动的窗体只有鼠标移动。

但是如果我点击鼠标向下键,然后快速移动鼠标,表单就会一直聚焦。

所以我试图从OnMouseDown事件复制两行到OnMouseMove事件:

mOffset = new Point(Width / 2 - e.X, Height / 2 - e.Y);
mTargetPoint = mCurrentPoint;

但是,一旦我将这两行移动到Move事件,什么也没有发生。无论我做什么,这个表格都不动。

如果需要,下面是完整的表单代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.IO;
using System.Drawing.Imaging;
namespace Magnifier20070401
{
    public partial class MagnifierForm : Form
    {
        public MagnifierForm()//Configuration configuration, Point startPoint)
        {
            InitializeComponent();
            //--- My Init ---
            //mConfiguration = configuration;
            FormBorderStyle = FormBorderStyle.None;
            ShowInTaskbar = false;//mConfiguration.ShowInTaskbar;
            TopMost = true;//mConfiguration.TopMostWindow;
            Width = 150;// mConfiguration.MagnifierWidth;
            Height = 150;// mConfiguration.MagnifierHeight;
            // Make the window (the form) circular
            GraphicsPath gp = new GraphicsPath();
            gp.AddEllipse(ClientRectangle);
            Region = new Region(gp);
            mImageMagnifier = ScreenVideoRecorder.Properties.Resources.magnifierGlass;
            mTimer = new Timer();
            mTimer.Enabled = true;
            mTimer.Interval = 20;
            mTimer.Tick += new EventHandler(HandleTimer);
            mScreenImage = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
                                     Screen.PrimaryScreen.Bounds.Height);
            mStartPoint = new Point(500, 500);// startPoint;
            mTargetPoint = new Point(500, 500); // startPoint;
            /*if (mConfiguration.ShowInTaskbar)
                ShowInTaskbar = true;
            else
                ShowInTaskbar = false;*/
        }
        protected override void OnShown(EventArgs e)
        {
            RepositionAndShow();
        }
        private delegate void RepositionAndShowDelegate();
        private void RepositionAndShow()
        {
            if (InvokeRequired)
            {
                Invoke(new RepositionAndShowDelegate(RepositionAndShow));
            }
            else
            {
                // Capture the screen image now!
                Graphics g = Graphics.FromImage(mScreenImage);
                g.CopyFromScreen(0, 0, 0, 0, new Size(mScreenImage.Width, mScreenImage.Height));
                g.Dispose();                
                //if (mConfiguration.HideMouseCursor)
                  //  Cursor.Hide();
                //else
                    Cursor = Cursors.Cross;
                Capture = true;
                /*if (mConfiguration.RememberLastPoint)
                {
                    mCurrentPoint = mLastMagnifierPosition;
                    Cursor.Position = mLastMagnifierPosition;
                    Left = (int)mCurrentPoint.X - Width / 2;
                    Top = (int)mCurrentPoint.Y - Height / 2;
                }
                else
                {*/
                    mCurrentPoint = Cursor.Position;
                //}
                Show();
            }
        }
        void HandleTimer(object sender, EventArgs e)
        {
            float dx = /*mConfiguration.SpeedFactor*/ (float)0.35 * (mTargetPoint.X - mCurrentPoint.X);
            float dy = /*mConfiguration.SpeedFactor*/ (float)0.35 * (mTargetPoint.Y - mCurrentPoint.Y);
            if (mFirstTime)
            {
                mFirstTime = false;
                mCurrentPoint.X = mTargetPoint.X;
                mCurrentPoint.Y = mTargetPoint.Y;
                Left = (int)mCurrentPoint.X - Width / 2;
                Top = (int)mCurrentPoint.Y - Height / 2;
                return;
            }
            mCurrentPoint.X += dx;
            mCurrentPoint.Y += dy;
            if (Math.Abs(dx) < 1 && Math.Abs(dy) < 1)
            {
                mTimer.Enabled = false;
            }
            else
            {
                // Update location
                Left = (int)mCurrentPoint.X - Width / 2;
                Top = (int)mCurrentPoint.Y - Height / 2;
                mLastMagnifierPosition = new Point((int)mCurrentPoint.X, (int)mCurrentPoint.Y);
            }
            Refresh();
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            mOffset = new Point(Width / 2 - e.X, Height / 2 - e.Y);
            mCurrentPoint = PointToScreen(new Point(e.X + mOffset.X, e.Y + mOffset.Y));
            mTargetPoint = mCurrentPoint;
            mTimer.Enabled = true;
        }
        protected override void OnMouseUp(MouseEventArgs e)
        {
            //if (mConfiguration.CloseOnMouseUp)
            //{
             /*   Close();
                mScreenImage.Dispose();
            //}
            Cursor.Show();
            Cursor.Position = mStartPoint;   */         
        }
        protected override void OnMouseMove(MouseEventArgs e)
        {
            //if (e.Button == MouseButtons.Left)
            //{
                mOffset = new Point(Width / 2 - e.X, Height / 2 - e.Y);
                mTargetPoint = PointToScreen(new Point(e.X + mOffset.X, e.Y + mOffset.Y));
                //mTargetPoint = mCurrentPoint;
                mTimer.Enabled = true;
            //} 
        }
        protected override void OnPaintBackground(PaintEventArgs e)
        {
            /*if (mConfiguration.DoubleBuffered)
            {
                // Do not paint background (required for double buffering)!
            }
            else
            {
                base.OnPaintBackground(e);
            }*/
            base.OnPaintBackground(e);
        }
        protected override void  OnPaint(PaintEventArgs e)
        {
            if (mBufferImage == null)
            {
                mBufferImage = new Bitmap(Width, Height);
            }
            Graphics bufferGrf = Graphics.FromImage(mBufferImage);
            Graphics g;
            /*if (mConfiguration.DoubleBuffered)
            {
                g = bufferGrf;
            }
            else
            {*/
                g = e.Graphics;
            //}
            if (mScreenImage != null)
            {
                Rectangle dest = new Rectangle(0, 0, Width, Height);
                int w = (int)(Width / 3.0);//mConfiguration.ZoomFactor);
                int h = (int)(Height / 3.0);//mConfiguration.ZoomFactor);
                int x = Left - w / 2 + Width / 2;
                int y = Top - h / 2 + Height / 2;
                g.DrawImage(
                    mScreenImage,
                    dest,
                    x, y,
                    w, h,
                    GraphicsUnit.Pixel);
            }
            if (mImageMagnifier != null)
            {
                g.DrawImage(mImageMagnifier, 0, 0, Width, Height);
            }
           //if (mConfiguration.DoubleBuffered)
            //{
                e.Graphics.DrawImage(mBufferImage, 0, 0, Width, Height);
            //}      
        }

        //--- Data Members ---
        #region Data Members
        private Timer mTimer;
        private Configuration mConfiguration;
        private Image mImageMagnifier;
        private Image mBufferImage = null;
        private Image mScreenImage = null;
        private Point mStartPoint;
        private PointF mTargetPoint;
        private PointF mCurrentPoint;
        private Point mOffset;
        private bool mFirstTime = true;
        private static Point mLastMagnifierPosition = Cursor.Position;
        #endregion
        private void MagnifierForm_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Control && e.KeyCode.ToString() == "M")
            {
                this.Close();
            }
        }
    }
}

在Form1中,我只是为表单创建了一个新实例,然后我可以移动它。为什么当快速移动鼠标而不按下鼠标键时,它会失去焦点?

为什么当快速移动鼠标时,新窗体不粘在鼠标移动位置上

这不是一个事件,它是一个方法。你没有获得默认行为(捕获鼠标),因为你忘记调用base.OnMouseDown()。MSDN库对此发出严厉警告:



当在派生类中重写OnMouseDown时,一定要调用基类的OnMouseDown方法以便注册委托接收事件。

以及基类方法所做的其他事情。比如抓老鼠。只有当你真正知道你在做什么时,才会跳过调用基类方法。这很难弄清楚,你需要知道基类的方法是做什么的。它是而不是,总是像触发事件一样简单。通常,类越复杂,它就越有可能在基方法中隐藏一些代码。DataGridView是松鼠之王。你可以从参考源中获得这些信息。

只需在方法的底部添加这一行就可以解决您的问题:

   base.OnMouseDown(e);

在OnMouseMove()重写中做同样的事情。不是因为这是解决这个特定问题所必需的,因为文档说您应该这样做。

在MouseDown中输入this.Capture = true;,在MouseUp中输入this.Capture.false;

如果你快速移动鼠标,它可能会移动到窗口外,默认情况下,只有鼠标所在的窗口才会收到鼠标消息。使用Control.Capture可以解决这个问题。