4

我有这个事件:

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 中,我只是为表单创建一个新实例,然后我可以移动它。为什么在没有按下鼠标键的情况下快速移动鼠标时会失去焦点?

4

2 回答 2

2

在你的 MouseDown 你应该把this.Capture = true;和在你的 MouseUp 放this.Capture.false;

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

于 2013-04-15T17:29:12.537 回答
2

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

对继承者的说明:

在派生类中重写 OnMouseDown 时,请务必调用基类的 OnMouseDown 方法,以便注册的委托接收事件。

好吧,以及基类方法所做的其他事情。就像抓老鼠一样。仅当您真正知道自己在做什么时才跳过调用基类方法。这很难弄清楚,你真的需要知道基类方法的作用。它并不总是像触发事件一样简单。通常,类越精细,它就越有可能在基本方法中隐藏一些代码。DataGridView 是松鼠王。您可以从参考源获取该信息。

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

   base.OnMouseDown(e);

并在 OnMouseMove() 覆盖中执行相同操作。不是因为这对于解决这个特定问题是必要的,因为文档说你应该这样做。

于 2013-04-15T18:03:08.840 回答