Cómo dibujar un rectángulo de goma o un rectángulo de foco en Visual C#

Para una versión de Microsoft Visual Basic .NET de este artículo, consulte
317479 .
Este artículo hace referencia a los siguientes espacios de nombres de biblioteca de clases de.NET Framework:
  • System.Drawing
  • System.Drawing.Imaging
  • System.Windows.Forms

EN ESTA TAREA

Resumen

Un rectángulo de goma o de foco es un rectángulo que realiza un seguimiento con el puntero del mouse mientras mantiene presionado el botón primario del mouse. Esta técnica se utiliza comúnmente para delimitar una selección en respuesta a la entrada de usuario del puntero del mouse. En la interfaz de dispositivo gráfico (GDI), estos rectángulos se implementan normalmente mediante operaciones de trama (ROPs). Sin embargo, el método System.Drawing se basa en GDI+ (la sucesora de GDI), que no tiene soporte para ROPs. Este artículo explica otro enfoque para implementar los rectángulos de foco en el.NET Framework.

En el GDI, rectángulos de foco comúnmente se dibujan mediante códigos ROP. En particular, los códigos ROP2 R2_XORPEN y R2_NOT se utilizan con frecuencia. Cuando se utiliza cualquiera de estos códigos ROP2, puede borrar una línea anterior dibujando la línea otra vez en la misma posición. Esto se conoce a veces como un efecto de OR exclusiva (XOR).

Código de ejemplo

Porque no están disponibles en GDI+ y System.DrawingROPs, otro enfoque es necesario para dibujar líneas reversibles con estas herramientas. Por ejemplo, puede utilizar servicios de invocación de plataforma (PInvoke) para interoperar con el GDI. Sin embargo, una solución que utiliza código administrado sólo está disponible mediante el miembro estático ControlPaint::DrawReversibleFrame(). El código de ejemplo siguiente, escrito en C# y listo para pegar en la clase de formulario en una aplicación Microsoft Visual C# predeterminada, muestra este enfoque:
Boolean bHaveMouse;PointptOriginal = new Point();
PointptLast = new Point();

// Called when the left mouse button is pressed.
public void MyMouseDown( Object sender, MouseEventArgs e )
{
// Make a note that we "have the mouse".
bHaveMouse = true;
// Store the "starting point" for this rubber-band rectangle.
ptOriginal.X = e.X;
ptOriginal.Y = e.Y;
// Special value lets us know that no previous
// rectangle needs to be erased.
ptLast.X = -1;
ptLast.Y = -1;
}
// Convert and normalize the points and draw the reversible frame.
private void MyDrawReversibleRectangle( Point p1, Point p2 )
{
Rectangle rc = new Rectangle();

// Convert the points to screen coordinates.
p1 = PointToScreen( p1 );
p2 = PointToScreen( p2 );
// Normalize the rectangle.
if( p1.X < p2.X )
{
rc.X = p1.X;
rc.Width = p2.X - p1.X;
}
else
{
rc.X = p2.X;
rc.Width = p1.X - p2.X;
}
if( p1.Y < p2.Y )
{
rc.Y = p1.Y;
rc.Height = p2.Y - p1.Y;
}
else
{
rc.Y = p2.Y;
rc.Height = p1.Y - p2.Y;
}
// Draw the reversible frame.
ControlPaint.DrawReversibleFrame( rc,
Color.Red, FrameStyle.Dashed );
}
// Called when the left mouse button is released.
public void MyMouseUp( Object sender, MouseEventArgs e )
{
// Set internal flag to know we no longer "have the mouse".
bHaveMouse = false;
// If we have drawn previously, draw again in that spot
// to remove the lines.
if( ptLast.X != -1 )
{
Point ptCurrent = new Point( e.X, e.Y );
MyDrawReversibleRectangle( ptOriginal, ptLast );
}
// Set flags to know that there is no "previous" line to reverse.
ptLast.X = -1;
ptLast.Y = -1;
ptOriginal.X = -1;
ptOriginal.Y = -1;
}
// Called when the mouse is moved.
public void MyMouseMove( Object sender, MouseEventArgs e )
{
Point ptCurrent = new Point( e.X, e.Y );
// If we "have the mouse", then we draw our lines.
if( bHaveMouse )
{
// If we have drawn previously, draw again in
// that spot to remove the lines.
if( ptLast.X != -1 )
{
MyDrawReversibleRectangle( ptOriginal, ptLast );
}
// Update last point.
ptLast = ptCurrent;
// Draw new lines.
MyDrawReversibleRectangle( ptOriginal, ptCurrent );
}
}
// Set up delegates for mouse events.
protected override void OnLoad(System.EventArgs e)
{
MouseDown += new MouseEventHandler( MyMouseDown );
MouseUp += new MouseEventHandler( MyMouseUp );
MouseMove += new MouseEventHandler( MyMouseMove );
bHaveMouse = false;
}

Nota: El código se debe cambiar en Visual Studio 2005. Cuando crea un proyecto de formularios Windows Forms, Visual C# agrega un formulario al proyecto de forma predeterminada. Este formulario se denomina Form1. Los dos archivos que lo representan se denominan Form1.cs y Form1.designer.cs. Escriba el código en Form1.cs. El archivo designer.cs es donde el Diseñador de Windows Forms escribe el código que implementa todas las acciones que realizó arrastrando y colocando controles desde el cuadro de herramientas. Para obtener más información acerca de cómo el Diseñador de Windows Forms en Visual C# 2005, visite el siguiente sitio Web de Microsoft:

Tenga en cuenta que esta solución está disponible sólo para la salida en la pantalla. Para dibujar líneas reversibles en un objeto graphics, debe interoperar con GDI o llamar a Bitmap:: LockBits() y manipular directamente los bits de imagen.

Propiedades

Id. de artículo: 314945 - Última revisión: 22 ene. 2017 - Revisión: 1

Comentarios