c# - mouseposition - Ajustar a la rejilla del mouse bloqueando
mousemove visual basic (4)
Estoy de acuerdo con ruijoel, no te metas con la posición del cursor. Es mejor tener una cruz o un anillo que se dibuja en el punto de inicio para mostrar al usuario qué punto es el que se ajustará en un evento de clic.
Para que esto funcione bien, es posible que desee ver xor-drawing para que ese elemento se borre una vez que se mueva a un nuevo punto de ajuste.
Estoy trabajando en una aplicación que dibuja una cuadrícula de puntos simple. Me gustaría que el mouse se ajuste entre los puntos de la grilla, eventualmente para dibujar líneas en la grilla.
Tengo un método que toma la ubicación actual del mouse (X, Y) y calcula la coordenada de la cuadrícula más cercana.
Cuando creo un evento e intento mover el mouse a la nueva coordenada, todo el sistema se vuelve desigual. El mouse no se ajusta sin problemas entre los puntos de la grilla.
He copiado un ejemplo de código a continuación para ilustrar lo que intento hacer. ¿Alguien tiene algún consejo que puedan ofrecerme sobre cómo puedo eliminar el nerviosismo dentro del movimiento del mouse?
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 GridTest
{
public partial class Form1 : Form
{
Graphics g;
const int gridsize = 20;
public Form1()
{
InitializeComponent();
g = splitContainer1.Panel2.CreateGraphics();
splitContainer1.Panel2.Invalidate();
}
private void splitContainer1_Panel2_Paint(object sender, PaintEventArgs e)
{
Drawgrid();
}
private void Drawgrid()
{
for (int x = 0; x < splitContainer1.Panel2.ClientSize.Width; x += gridsize)
{
for (int y = 0; y < splitContainer1.Panel2.ClientSize.Height; y += gridsize)
{ g.DrawLine(Pens.Black, new Point(x, y), new Point(x + 1, y)); }
}
}
private void splitContainer1_Panel2_MouseMove(object sender, MouseEventArgs e)
{
Point newPosition = new Point();
newPosition = RoundToNearest(gridsize, e.Location);
Cursor.Position = splitContainer1.Panel2.PointToScreen(newPosition);
}
private Point RoundToNearest(int nearestRoundValue, Point currentPoint)
{
Point newPoint = new Point();
int lastDigit;
lastDigit = currentPoint.X % nearestRoundValue;
if (lastDigit >= (nearestRoundValue/2))
{ newPoint.X = currentPoint.X - lastDigit + nearestRoundValue; }
else
{ newPoint.X = currentPoint.X - lastDigit; }
lastDigit = currentPoint.Y % nearestRoundValue;
if (lastDigit >= (nearestRoundValue / 2))
{ newPoint.Y = currentPoint.Y - lastDigit + nearestRoundValue; }
else
{ newPoint.Y = currentPoint.Y - lastDigit; }
return newPoint;
}
}
}
El mouse sigue moviéndose al mismo punto si intenta moverlo, porque aún está más cerca de ese punto ... Si mueve el mouse hacia la izquierda, mueva el cursor al punto a la izquierda del actual en lugar de volver a calcular la corriente. Solicite las otras 3 direcciones ...
Sin embargo, no recomendaría este comportamiento, causará mucha irritación. Ajuste sus controles a la cuadrícula, no al mouse.
Creo que entiendo de dónde vienes. Simplemente necesita estar fuera del punto de referencia original (el clic izquierdo del mouse) antes de ajustar al nuevo punto.
Aquí hay 50 líneas de código que ilustran lo que quiero decir: (Inicie un nuevo proyecto VB.NET, agregue un nuevo módulo, copie y pegue el código, agregue una referencia, a System, System.drawing y System.Windows.Forms)
Imports System
Imports System.Drawing
Imports System.Windows.Forms
Module modSnap
Public Const strApplicationTitle As String = "Snap Demo"
Public frmSnap As SnapForm
Public ptSnap, ptStart, ptEnd As Point
Public Class SnapForm
Inherits Form
Public Sub New()
Me.Text = "Snap Demo"
Me.ClientSize = New Size(800, 600)
Me.FormBorderStyle = Windows.Forms.FormBorderStyle.FixedSingle
Me.MaximizeBox = False
Me.StartPosition = FormStartPosition.CenterScreen
Me.DoubleBuffered = True
End Sub
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
MyBase.OnPaint(e)
e.Graphics.Clear(Color.Black)
For row As Integer = 20 To 780 Step 20
For col As Integer = 20 To 580 Step 20
e.Graphics.DrawEllipse(Pens.Blue, New Rectangle(row - 2, col - 2, 4, 4))
Next
Next
e.Graphics.DrawLine(Pens.Red, ptStart, ptEnd)
End Sub
Protected Overrides Sub OnMouseDown(ByVal e As System.Windows.Forms.MouseEventArgs)
MyBase.OnMouseDown(e)
Dim x As Integer = CInt(e.X / 20) * 20
Dim y As Integer = CInt(e.Y / 20) * 20
ptStart = New Point(x, y)
ptSnap = New Point(x, y)
Windows.Forms.Cursor.Position = Me.PointToScreen(ptSnap)
End Sub
Protected Overrides Sub OnMouseMove(ByVal e As System.Windows.Forms.MouseEventArgs)
MyBase.OnMouseMove(e)
If e.Button = Windows.Forms.MouseButtons.Left Then
Dim x As Integer = CInt(e.X / 20) * 20
Dim y As Integer = CInt(e.Y / 20) * 20
'' must be some delta away from original snap point
If (x < ptSnap.X - 15 Or x > ptSnap.X + 15) Or (y < ptSnap.Y - 15 Or y > ptSnap.Y + 15) Then
ptSnap = New Point(x, y)
ptEnd = New Point(x, y)
Me.Invalidate(False)
Windows.Forms.Cursor.Position = Me.PointToScreen(ptSnap)
End If
End If
End Sub
End Class
Public Sub main()
Try
frmSnap = New SnapForm
Application.Run(frmSnap)
Catch ex As Exception
MessageBox.Show(ex.Message, strApplicationTitle, MessageBoxButtons.OK, MessageBoxIcon.Error)
Finally
frmSnap.Dispose()
End Try
End Sub
End Module
No modifique la posición del cursor. No es necesario.
En cambio, dibuja como si estuviera enganchado a la cuadrícula. Cuando el usuario hace clic en algún lugar, simplemente dibuje la línea desde los puntos de cuadrícula más cercanos.
Por ejemplo, si el usuario hace clic en (197,198), pero usted sabe que el punto más cercano en realidad es (200,200), simplemente trace una línea a (200,200) en lugar de (197,198).
Y por favor, no te metas con la posición actual del cursor.
No sé si hay alguna forma de ocultar el cursor del mouse. Si lo hay, puedes ocultarlo y dibujarlo tú mismo, sin modificar la posición real .