【问题标题】:How do I show the new form at the current position of the mouse cursor?如何在鼠标光标的当前位置显示新表单?
【发布时间】:2013-05-26 22:38:41
【问题描述】:

这是代码:

private void hsMagnfier_OnMouseDown(object sender)
{
    int x = mLastCursorPosition.X;
    int y = mLastCursorPosition.Y;
    MagnifierForm magnifier = new MagnifierForm(mConfiguration, System.Windows.Forms.Cursor.Position);//mLastCursorPosition);
    magnifier.Show();
}

上面的代码在Form 中,我可以将其拖到屏幕上。

然后,当我点击一个图标时,它正在执行magnifier.Show(); 并且放大镜形式显示在鼠标当前位置的位置。

但是如果我再次点击它,那么现在新表格的位置就在我的Form1 中心。而不是第一次鼠标当前位置在哪里。

这是MagnifierForm 代码,可能第一次它位于当前鼠标位置,但下一次它位于Form1 的中心?

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 ScreenVideoRecorder
{
    public partial class MagnifierForm : Form
    {

        public MagnifierForm(Configuration configuration, Point startPoint)
        {
            InitializeComponent();

            //--- My Init ---
            mConfiguration = configuration;
            FormBorderStyle = FormBorderStyle.None;

            ShowInTaskbar = mConfiguration.ShowInTaskbar;
            TopMost = mConfiguration.TopMostWindow;
            Width = mConfiguration.MagnifierWidth;
            Height = mConfiguration.MagnifierHeight;

            // Make the window (the form) circular
            GraphicsPath gp = new GraphicsPath();
            gp.AddEllipse(ClientRectangle);
            Region = new Region(gp);

            mImageMagnifier = 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 = startPoint;
            mTargetPoint = 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 * (mTargetPoint.X - mCurrentPoint.X);
            float dy = mConfiguration.SpeedFactor * (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)
            {
                mTargetPoint = PointToScreen(new Point(e.X + mOffset.X, e.Y + mOffset.Y));
                mTimer.Enabled = true;
            } 
        }

        protected override void OnPaintBackground(PaintEventArgs e)
        {
            if (mConfiguration.DoubleBuffered)
            {
                // Do not paint background (required for double buffering)!
            }
            else
            {
                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 / mConfiguration.ZoomFactor);
                int h = (int)(Height / 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
    }
}

第一次放大镜出现在我的鼠标光标所在的位置。 下次我点击它时,它会在 Form1 的中心显示放大镜窗体,而不是鼠标光标所在的位置。

这是为什么呢?当我再次点击图标时,它仍然在做

System.Windows.Forms.Cursor.Position

再次。奇怪。

【问题讨论】:

  • 第一次在鼠标光标的当前位置显示放大镜窗体时再次检查,但下一次它在上次放大镜窗体的位置显示新的放大镜窗体。如果我在屏幕周围移动放大镜表格并将其留在某个地方,下次我将再次显示放大镜,它将在我离开它的最后一个位置,而不是鼠标光标所在的位置。每次单击以显示放大镜窗体时,我都会再次检查它正在执行 System.Windows.Forms.Cursor.Position 但将其显示在最后一个位置而不是鼠标光标所在的位置。
  • 有些东西阻止了放大镜表格显示鼠标光标当前所在的位置,并使其显示上次放大镜所在的位置。有些东西需要重置,也许是配置的问题。

标签: c# winforms


【解决方案1】:

假设您有两种形式 - Master 和 Child

如果你在MouseUp事件(例如)上从Master调用Child,请在Master表单的MouseUp事件中编写代码

ChildForm obj=new ChildForm();
obj.pntLocation = new Point(Cursor.Position.X, Cursor.Position.Y);
obj.ShowDialog();

在 Child 内部声明一个变量作为 location

public Point pntLocation;

现在在Child 的Form_Load 内设置位置

this.Location = pntLocation;

【讨论】:

    【解决方案2】:

    好的发现做这件事的部分在放大镜形式:

    mConfiguration.RememberLastPoint = false;
    if (mConfiguration.RememberLastPoint)
    {
        mCurrentPoint = mLastMagnifierPosition;
        Cursor.Position = mLastMagnifierPosition;
        Left = (int)mCurrentPoint.X - Width / 2;
        Top = (int)mCurrentPoint.Y - Height / 2;
    }
    else
    {
        mCurrentPoint = Cursor.Position;
    }
    

    所以我现在添加了以下行:mConfiguration.RememberLastPoint = false;,它现在完成了这项工作。

    【讨论】:

      猜你喜欢
      • 2019-06-14
      • 2013-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-24
      • 1970-01-01
      相关资源
      最近更新 更多