none
Dibujar un rectángulo dentro de un PictureBox C++ Forms RRS feed

  • Pregunta

  • Hola,

    necesito dibujar un rectángulo sobre un PictureBox. Muestro varias imágenes en el PictureBox, según le voy dando a un botón Siguiente, las imágenes van cambiando.

    El problema es que dibuja un rectángulo, pero sobre la siguiente imagen. Es decir, en la imagen actual parece que no haga nada, y cuando le doy al botón Siguiente para que aparezca otra imagen, sale el rectángulo dibujado en la siguiente imagen.

    He utilizado el siguiente código:

    private: System::Void pbImagenes_MouseDown(System::Object^  /*sender*/, System::Windows::Forms::MouseEventArgs^  e) {
       
        // Determine the initial rectangle coordinates...
        RcDraw.X = e->X;
        RcDraw.Y = e->Y;
      }
    private: System::Void pbImagenes_MouseUp(System::Object^  /*sender*/, System::Windows::Forms::MouseEventArgs^  e) {
        // Determine the width and height of the rectangle...
         if ( e->X < RcDraw.X )
         {
         RcDraw.Width = RcDraw.X - e->X;
         RcDraw.X = e->X;
         }
         else
         {
         RcDraw.Width = e->X - RcDraw.X;
         }

         if ( e->Y < RcDraw.Y )
         {
         RcDraw.Height = RcDraw.Y - e->Y;
         RcDraw.Y = e->Y;
         }
         else
         {
         RcDraw.Height = e->Y - RcDraw.Y;
         }

         // Force a repaint of the region occupied by the rectangle...
         this->Invalidate( RcDraw );

       }

    private: System::Void pbImagenes_Paint(System::Object^  sender, System::Windows::Forms::PaintEventArgs^  e) {
        // Draw the rectangle...
       float PenWidth = 5;
       e->Graphics->DrawRectangle( gcnew Pen( Color::White,PenWidth ), RcDraw );

       }

    ¿Cómo puedo hacer para que me aparezca el rectángulo en la imagen actual?

    Gracias.

    domingo, 10 de noviembre de 2013 13:21

Respuestas

  • this->pbImagenes->Invalidate( RcDraw );

    • Marcado como respuesta maria_dp domingo, 10 de noviembre de 2013 22:51
    domingo, 10 de noviembre de 2013 13:39
  • Podría ser

    private:
    Rectangle RcDraw;
    Point pos;
    
    System::Void pbImagenes_MouseDown(System::Object^  sender, System::Windows::Forms::MouseEventArgs^  e) 
    {
    	if (e->Button == System::Windows::Forms::MouseButtons::Left)
    	{
    		pos = e->Location;
    	}
    }
    
    System::Void pbImagenes_MouseMove(System::Object^  sender, System::Windows::Forms::MouseEventArgs^  e) 
    {
    	if (e->Button == System::Windows::Forms::MouseButtons::Left)
    	{
    		RcDraw.Width = e->X - pos.X;
    		RcDraw.Height = e->Y - pos.Y;
    
    		if (RcDraw.Width < 0)
    		{
    			RcDraw.Width *= -1;
    			RcDraw.X = pos.X - RcDraw.Width;
    		}
    		else
    		{
    			RcDraw.X = pos.X;
    		}
    
    		if (RcDraw.Height < 0)
    		{
    			RcDraw.Height *= -1;
    			RcDraw.Y = pos.Y - RcDraw.Height;
    		}
    		else
    		{
    			RcDraw.Y = pos.Y;
    		}
    
    		pbImagenes->Invalidate();
    	}
    }
    
    System::Void pbImagenes_Paint(System::Object^  sender, System::Windows::Forms::PaintEventArgs^  e) 
    {
    	// Draw the rectangle...
    	float PenWidth = 5;
    	e->Graphics->DrawRectangle( gcnew Pen( Color::White,PenWidth ), RcDraw );
    }
    

    • Marcado como respuesta maria_dp lunes, 11 de noviembre de 2013 13:53
    lunes, 11 de noviembre de 2013 0:17
  • Entonces necesitas seleccionar una "herramienta" de tu "toolbox".

    Cuando la herramienta está seleccionada, puedes seleccionar la imagen. Digamos

    mousedown:

    if (!herramienta) return;

    if (e->Button etc., etc.

    mousemove:

    if (!herramienta) return;

    if (e->Button etc., etc.

    y talvez agregar mouseup para desafectar la herramienta automáticamente,

    mouseup:

    herramienta = false

    Otra cosa. Puedes usar el RcDraw con el Invalidate, de la siguiente manera

    RcDraw.Inflate(3, 3);
    pbImagenes->Invalidate(RcDraw);
    
    RcDraw.Width = e->X - pos.X;
    RcDraw.Height = e->Y - pos.Y;
    ...
    
    RcDraw.Inflate(3, 3);
    pbImagenes->Invalidate(RcDraw);
    RcDraw.Inflate(-3, -3);
    Si en vez de un Rectangle fuese un Path rectangular, vos podrías en el DrawPath establecer que el trazo sea interior. Aquí la "mitad" del trazo queda fuera del rectángulo.



    • Editado sopita lunes, 11 de noviembre de 2013 14:20
    • Marcado como respuesta maria_dp lunes, 11 de noviembre de 2013 16:09
    lunes, 11 de noviembre de 2013 14:09

Todas las respuestas

  • this->pbImagenes->Invalidate( RcDraw );

    • Marcado como respuesta maria_dp domingo, 10 de noviembre de 2013 22:51
    domingo, 10 de noviembre de 2013 13:39
  • Gracias! ya va!

    Y otra cosa... ¿para qué se vea el rectángulo según lo estoy dibujando? ¿En lugar de que aparezca ya cuando has soltado el ratón?

    domingo, 10 de noviembre de 2013 22:44
  • Podría ser

    private:
    Rectangle RcDraw;
    Point pos;
    
    System::Void pbImagenes_MouseDown(System::Object^  sender, System::Windows::Forms::MouseEventArgs^  e) 
    {
    	if (e->Button == System::Windows::Forms::MouseButtons::Left)
    	{
    		pos = e->Location;
    	}
    }
    
    System::Void pbImagenes_MouseMove(System::Object^  sender, System::Windows::Forms::MouseEventArgs^  e) 
    {
    	if (e->Button == System::Windows::Forms::MouseButtons::Left)
    	{
    		RcDraw.Width = e->X - pos.X;
    		RcDraw.Height = e->Y - pos.Y;
    
    		if (RcDraw.Width < 0)
    		{
    			RcDraw.Width *= -1;
    			RcDraw.X = pos.X - RcDraw.Width;
    		}
    		else
    		{
    			RcDraw.X = pos.X;
    		}
    
    		if (RcDraw.Height < 0)
    		{
    			RcDraw.Height *= -1;
    			RcDraw.Y = pos.Y - RcDraw.Height;
    		}
    		else
    		{
    			RcDraw.Y = pos.Y;
    		}
    
    		pbImagenes->Invalidate();
    	}
    }
    
    System::Void pbImagenes_Paint(System::Object^  sender, System::Windows::Forms::PaintEventArgs^  e) 
    {
    	// Draw the rectangle...
    	float PenWidth = 5;
    	e->Graphics->DrawRectangle( gcnew Pen( Color::White,PenWidth ), RcDraw );
    }
    

    • Marcado como respuesta maria_dp lunes, 11 de noviembre de 2013 13:53
    lunes, 11 de noviembre de 2013 0:17
  • Si, perfecto! muchas gracias!

    La única pega es que al dibujar un segundo rectángulo, me borra el anterior y quiero que se mantenga.

    Se borra cuando vuelvo a pinchar con el ratón en la imagen, por tanto creo que habría que modificar el evento MouseDown, no sé si creando un new pos, para que no sobreescriba el que ya hay...

    lunes, 11 de noviembre de 2013 13:53
  • Entonces necesitas seleccionar una "herramienta" de tu "toolbox".

    Cuando la herramienta está seleccionada, puedes seleccionar la imagen. Digamos

    mousedown:

    if (!herramienta) return;

    if (e->Button etc., etc.

    mousemove:

    if (!herramienta) return;

    if (e->Button etc., etc.

    y talvez agregar mouseup para desafectar la herramienta automáticamente,

    mouseup:

    herramienta = false

    Otra cosa. Puedes usar el RcDraw con el Invalidate, de la siguiente manera

    RcDraw.Inflate(3, 3);
    pbImagenes->Invalidate(RcDraw);
    
    RcDraw.Width = e->X - pos.X;
    RcDraw.Height = e->Y - pos.Y;
    ...
    
    RcDraw.Inflate(3, 3);
    pbImagenes->Invalidate(RcDraw);
    RcDraw.Inflate(-3, -3);
    Si en vez de un Rectangle fuese un Path rectangular, vos podrías en el DrawPath establecer que el trazo sea interior. Aquí la "mitad" del trazo queda fuera del rectángulo.



    • Editado sopita lunes, 11 de noviembre de 2013 14:20
    • Marcado como respuesta maria_dp lunes, 11 de noviembre de 2013 16:09
    lunes, 11 de noviembre de 2013 14:09