Why doesn't the new shape stick to the mouse move position when the mouse moves fast?

I have this event:

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

And this event:

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

If I just move the mouse quickly, I lose focus on the shape that I am moving, and the shape remains in place only when the mouse moves.

But if I press the mouse button down, then move the mouse and quickly the shape is in focus completely.

So, I tried to copy two lines from the OnMouseDown event to the OnMouseMove event:

 mOffset = new Point(Width / 2 - eX, Height / 2 - eY); mTargetPoint = mCurrentPoint; 

But as soon as I moved these two lines to the Move event, nothing will happen. The form does not move at all, no matter what it does.

If necessary, this is the full form code:

 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 - eX, Height / 2 - eY); mCurrentPoint = PointToScreen(new Point(eX + mOffset.X, eY + 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 - eX, Height / 2 - eY); mTargetPoint = PointToScreen(new Point(eX + mOffset.X, eY + 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(); } } } } 

In Form1, I just create a new instance for the form, then I can move it. Just why does it lose focus when you quickly move the mouse if you do not press the mouse button?

+4
source share
2 answers

This is not an event, this is a method. And you will not get the default behavior (mouse capture) because you forgot to call base.OnMouseDown (). The MSDN library strictly warns about this:

Notes for Inheritors:

When overriding OnMouseDown in a derived class, be sure to call the base class's OnMouseDown method so that registered delegates receive the event.

Well and other things that the base class method does. Like a mouse capture. Just skip calling the base class method when you really know what you are doing. What is hard to understand, you really need to know what the base class methods do. It is not always as easy as shooting from events. As a rule, the more complex the class, the more likely it is to hold some code together in the base method. DataGridView is the king of squirrels. You can get this information from a reference source.

Just add this line at the bottom of the method to solve your problem:

  base.OnMouseDown(e); 

And do the same in overriding OnMouseMove (). Not because it is necessary to solve this particular problem, because the documents say that you should.

+2
source

In your MouseDown you should put this.Capture = true; and put this.Capture.false; in your this.Capture.false;

If you quickly move the mouse, it probably moves outside the window, and by default only the window in which the mouse is located will receive mouse messages. Using Control.Capture fixes this problem.

+2
source

All Articles