簡體   English   中英

如何處理鼠標事件

[英]How to handle mouse event

我想在一個正方形內單擊,然后應該會出現一個“X”,但我不確定在Form1_MouseDownForm1_PaintForm1_MouseUp事件中放什么。 我該如何實現這是 C#?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace VTest
{
    public partial class Form1 : Form
    {
        Rectangle rect; // single rect
        int sqsize, n;
        int margin;

        public Form1()
        {
            n = 3;
            margin = 25;
            sqsize = 50;
            rect = new Rectangle(10, 10, 150, 150);
            InitializeComponent();
        }

        private void Form1_MouseDown(object sender, MouseEventArgs e)
        {
            // what goes here?
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            // what goes here?
        }

        private void Form1_MouseUp(object sender, MouseEventArgs e)
        {
            // what goes here?
        }

        // ...

在您的 MouseDown 事件中,確定單擊是否發生在您的矩形內很容易:

if (rect.Contains(e.Location))
{
    // the user has clicked inside your rectangle
}

在表單上繪制“X”也很容易:

Graphics g = this.CreateGraphics();
g.DrawString("X", this.Font, SystemBrushes.WindowText,
    (float)e.X, (float)e.Y);

但是,在這種情況下,“X”不會是持久的,這意味着如果您將另一個表單拖到表單上然后將其移開,“X”將不再存在。 要繪制持久的“X”,請創建一個表單級 Point 變量,如下所示:

private Point? _Xlocation = null;

如果用戶在您的矩形中單擊,請使用您的 MouseDown 事件設置此變量:

if (rect.Contains(e.Location))
{
    _Xlocation = e.Location;
    this.Invalidate(); // this will fire the Paint event
}

然后,在表單的 Paint 事件中,繪制“X”:

if (_Xlocation != null)
{
    e.Graphics.DrawString("X", this.Font, SystemBrushes.WindowText,
        (float)e.X, (float)e.Y);
}
else
{
    e.Graphics.Clear(this.BackColor);
}

如果您希望“X”在用戶松開鼠標按鈕時消失,只需將此代碼放在 MouseUp 事件中:

_Xlocation = null;
this.Invalidate();

您可以根據需要將其設置得更復雜。 使用此代碼,“X”將在您單擊表單的任何位置的下方和右側繪制。 如果您希望“X”以單擊位置為中心,您可以使用 Graphics 對象的 MeasureString 方法來確定“X”的高度和寬度,並相應地偏移 DrawString 位置。

您不需要 mousedown 和 mouseup 事件處理程序。

選擇一個做出反應,我傾向於對 MouseDown 事件做出反應。

但是,當您想要查看 MouseEventArgs 屬性時,您應該能夠確定您是否在方塊內。

您可能想致電:

System.Diagnostics.Debug.WriteLine(...)

使用 MouseEventArgs 中的 x 和 y 屬性,這樣您就可以看到鼠標點擊的位置,並確定您何時在方塊中。

到達那里后,您就可以繪制 X。

您可能想要編寫一個函數來繪制一個 X,並通過讓它在 300,300 處繪制一個 X 來測試它,這樣您就可以確保它在您試驗 MouseDown 時看起來如您所願。

更新:我喜歡 MusiGenesis 演示的 Rectangle.contains(location) 方法。

public partial class formDemo : Form
{
    Rectangle rec;
    public formDemo() => InitializeComponent();

    private void formDemo_Load(object sender, EventArgs e) =>
        rec = new Rectangle(150,100,100,100);

    private void frmDemo_Paint(object sender, PaintEventArgs e)
    {   
        var p = new Pen(Color.Blue);
        var g = e.Graphics;

        g.DrawRectangle(p, rec);
    }

    private void formDemo_MouseMove(object sender, MouseEventArgs e) =>
        Cursor = rec.Contains(e.Location) ? Cursors.Cross : Cursors.Default;

    private void formDemo_MouseDown(object sender, MouseEventArgs e)
    {   
        if (rec.Contains(e.Location))
        {
            // Mouse position adjust for window postion and border size.
            // You may have to adjust the borders depending your
            // Windows theme
            int x = MousePosition.X - this.Left -  4;
            int y = MousePosition.Y - this.Top  - 29;

            var g  = this.CreateGraphics();
            var p  = new Pen(Color.Black);
            var p1 = new Point(x - 10, y - 10);
            var p2 = new Point(x + 10, y + 10);
            var p3 = new Point(x - 10, y + 10);
            var p4 = new Point(x + 10, y - 10);

            g.DrawLines(p, new Point[] { p1, p2 });
            g.DrawLines(p, new Point[] { p3, p4 });
        }
    }
}

請參閱此處的代碼:

using System; 
using System.Drawing; 
using System.Windows.Forms; 
using System.Runtime.InteropServices; 

namespace Demo_mousehook_csdn
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        MouseHook mh;

        private void Form1_Load(object sender, EventArgs e)
        {
            mh = new MouseHook();
            mh.SetHook();
            mh.MouseMoveEvent += mh_MouseMoveEvent;
            mh.MouseClickEvent += mh_MouseClickEvent;
            mh.MouseDownEvent += mh_MouseDownEvent;
            mh.MouseUpEvent += mh_MouseUpEvent;
        }
        private void mh_MouseDownEvent(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                richTextBox1.AppendText("Left Button Press\n");
            }
            if (e.Button == MouseButtons.Right)
            {
                richTextBox1.AppendText("Right Button Press\n");
            }
        }

        private void mh_MouseUpEvent(object sender, MouseEventArgs e)
        {

            if (e.Button == MouseButtons.Left)
            {
                richTextBox1.AppendText("Left Button Release\n");
            }
            if (e.Button == MouseButtons.Right)
            {
                richTextBox1.AppendText("Right Button Release\n");
            }

        }
        private void mh_MouseClickEvent(object sender, MouseEventArgs e)
        {
            //MessageBox.Show(e.X + "-" + e.Y);
            if (e.Button == MouseButtons.Left)
            {
                string sText = "(" + e.X.ToString() + "," + e.Y.ToString() + ")";
                label1.Text = sText;
            }
        }

        private void mh_MouseMoveEvent(object sender, MouseEventArgs e)
        {
            int x = e.Location.X;
            int y = e.Location.Y;
            textBox1.Text = x + "";
            textBox2.Text = y + "";
        }
        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            mh.UnHook();
        }

        private void Form1_FormClosed_1(object sender, FormClosedEventArgs e)
        {
            mh.UnHook();
        }

        private void richTextBox1_TextChanged(object sender, EventArgs e)
        {

        }
    }

    public class Win32Api
    {
        [StructLayout(LayoutKind.Sequential)]
        public class POINT
        {
            public int x;
            public int y;
        }
        [StructLayout(LayoutKind.Sequential)]
        public class MouseHookStruct
        {
            public POINT pt;
            public int hwnd;
            public int wHitTestCode;
            public int dwExtraInfo;
        }
        public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern bool UnhookWindowsHookEx(int idHook);
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam);
    }

    public class MouseHook
    {
        private Point point;
        private Point Point
        {
            get { return point; }
            set
            {
                if (point != value)
                {
                    point = value;
                    if (MouseMoveEvent != null)
                    {
                        var e = new MouseEventArgs(MouseButtons.None, 0, point.X, point.Y, 0);
                        MouseMoveEvent(this, e);
                    }
                }
            }
        }
        private int hHook;
        private const int WM_MOUSEMOVE = 0x200;
        private const int WM_LBUTTONDOWN = 0x201;
        private const int WM_RBUTTONDOWN = 0x204;
        private const int WM_MBUTTONDOWN = 0x207;
        private const int WM_LBUTTONUP = 0x202;
        private const int WM_RBUTTONUP = 0x205;
        private const int WM_MBUTTONUP = 0x208;
        private const int WM_LBUTTONDBLCLK = 0x203;
        private const int WM_RBUTTONDBLCLK = 0x206;
        private const int WM_MBUTTONDBLCLK = 0x209;
        public const int WH_MOUSE_LL = 14;
        public Win32Api.HookProc hProc;
        public MouseHook()
        {
            this.Point = new Point();
        }
        public int SetHook()
        {
            hProc = new Win32Api.HookProc(MouseHookProc);
            hHook = Win32Api.SetWindowsHookEx(WH_MOUSE_LL, hProc, IntPtr.Zero, 0);
            return hHook;
        }
        public void UnHook()
        {
            Win32Api.UnhookWindowsHookEx(hHook);
        }
        private int MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam)
        {
            Win32Api.MouseHookStruct MyMouseHookStruct = (Win32Api.MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(Win32Api.MouseHookStruct));
            if (nCode < 0)
            {
                return Win32Api.CallNextHookEx(hHook, nCode, wParam, lParam);
            }
            else
            {
                if (MouseClickEvent != null)
                {
                    MouseButtons button = MouseButtons.None;
                    int clickCount = 0;
                    switch ((Int32)wParam)
                    {
                        case WM_LBUTTONDOWN:
                            button = MouseButtons.Left;
                            clickCount = 1;
                            MouseDownEvent(this, new MouseEventArgs(button, clickCount, point.X, point.Y, 0));
                            break;
                        case WM_RBUTTONDOWN:
                            button = MouseButtons.Right;
                            clickCount = 1;
                            MouseDownEvent(this, new MouseEventArgs(button, clickCount, point.X, point.Y, 0));
                            break;
                        case WM_MBUTTONDOWN:
                            button = MouseButtons.Middle;
                            clickCount = 1;
                            MouseDownEvent(this, new MouseEventArgs(button, clickCount, point.X, point.Y, 0));
                            break;
                        case WM_LBUTTONUP:
                            button = MouseButtons.Left;
                            clickCount = 1;
                            MouseUpEvent(this, new MouseEventArgs(button, clickCount, point.X, point.Y, 0));
                            break;
                        case WM_RBUTTONUP:
                            button = MouseButtons.Right;
                            clickCount = 1;
                            MouseUpEvent(this, new MouseEventArgs(button, clickCount, point.X, point.Y, 0));
                            break;
                        case WM_MBUTTONUP:
                            button = MouseButtons.Middle;
                            clickCount = 1;
                            MouseUpEvent(this, new MouseEventArgs(button, clickCount, point.X, point.Y, 0));
                            break;
                    }

                    var e = new MouseEventArgs(button, clickCount, point.X, point.Y, 0);
                    MouseClickEvent(this, e);
                }
                this.Point = new Point(MyMouseHookStruct.pt.x, MyMouseHookStruct.pt.y);
                return Win32Api.CallNextHookEx(hHook, nCode, wParam, lParam);
            }
        }

        public delegate void MouseMoveHandler(object sender, MouseEventArgs e);
        public event MouseMoveHandler MouseMoveEvent;

        public delegate void MouseClickHandler(object sender, MouseEventArgs e);
        public event MouseClickHandler MouseClickEvent;

        public delegate void MouseDownHandler(object sender, MouseEventArgs e);
        public event MouseDownHandler MouseDownEvent;

        public delegate void MouseUpHandler(object sender, MouseEventArgs e);
        public event MouseUpHandler MouseUpEvent;

    }
}

在這個演示中,您可以檢測鼠標實時位置,並檢測 mouseup/domn 事件。 它將顯示在此演示中的 Richtextbox 上。

更多關於鼠標事件的教程或下載這個演示,你可以在這里看到。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM