Outlining, Dragging, and Pasting a Region (C++ Builder)
Take the following steps to add code that lets you outline an area with a mouse, drag a copy of the selected area, and paste the copy into another part of the bitmap:
| 1. | Start with the project that you created in Loading and Displaying an Image. | 
| 2. | Add a second LEAD control, name it Lead2, and set its Visible property to False. | 
| 3. | Add the following declarations to the private section of the Unit1.h file. In online help, you can copy the block of code and paste it into your application. | 
    bool ReadyToDrag; /*The state after marking the region but before dragging */
    bool Dragging; /*The state when the mouse is used for dragging the floater */
    int StartX; /*Starting X position in screen pixels */
    int StartY; /*Starting Y position in screen pixels */
    int FloaterX; /*Floater X position in screen pixels */
    int FloaterY; /*Floater Y position in screen pixels */
    float ZoomFactorX; /*Used for translating positioning information */
    float ZoomFactorY; /*Used for translating positioning information */
| 4. | 
 | 
| Name | Caption | 
| SelectRgn | Select Region | 
| PasteFloater | Paste Floater | 
| 5. | Code the SelectRgn control's Click procedure as follows: | 
void __fastcall TForm1::SelectRgnClick(TObject *Sender)
{
   Lead1->RgnMarkingMode = mmFreeHand;
   ShowMessage("Draw a freehand region");
}
| 6. | Code the PasteFloaterBtn control's Click procedure as follows: | 
void __fastcall TForm1::PasteFloaterClick(TObject *Sender)
{
   /*Declare the variable for the Combine operation. */
   int MyOp;
   /*Declare variables for the client area coordinates. */
   int LCRgnX, LCRgnY , LCRgnWidth, LCRgnHeight;
   /*Declare variables for the bitmap coordinates. */
   int LBRgnX, LBRgnY , LBRgnWidth, LBRgnHeight;
   /*Do nothing if( there is no floater. */
   if(!Lead1->Floater)
      return;
   /*Get the floater into another bitmap */
   Lead2->Bitmap = Lead1->Floater;
   /*Get the floater's client coordinates into local variables. */
   LCRgnX = Lead1->FloaterDstLeft;
   LCRgnY = Lead1->FloaterDstTop;
   LCRgnWidth = Lead1->FloaterDstWidth;
   LCRgnHeight = Lead1->FloaterDstHeight;
   /*Delete the floater. */
   Lead1->FloaterVisible = false;
   Lead1->Floater = 0;
   /*Translate the client coordinates to bitmap coordinates. */
   LBRgnX = (LCRgnX-Lead1->DstLeft) / ZoomFactorX + Lead1->SrcLeft;
   LBRgnY = (LCRgnY-Lead1->DstTop) / ZoomFactorY + Lead1->SrcTop;
   LBRgnWidth = LCRgnWidth / ZoomFactorX;
   LBRgnHeight = LCRgnHeight / ZoomFactorY;
   /*Reposition the region to use it as a mask for the Combine method*/
   Lead1->OffsetRgn(LBRgnX-Lead1->RgnLeft, LBRgnY-Lead1->RgnTop);
   /*Use the Combine method to paste the Lead2 bitmap into the Lead1 bitmap*/
   MyOp = CB_OP_ADD | CB_DST_0; /*Operation flags for a simple paste.*/
   Lead1->Combine(LBRgnX, LBRgnY, LBRgnWidth, LBRgnHeight, Lead2 
 >Bitmap, 0, 0, MyOp);
   /*Repaint the part of the client area that has changed. */
   Lead1->RepaintRect(LCRgnX, LCRgnY, LCRgnWidth, LCRgnHeight, false);
   /*Free the region. */
   Lead1->FreeRgn();
}
| 7. | In the LEAD1 control's OnMouseDown procedure, add the following code. | 
void __fastcall TForm1::Lead1MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y)
{
   /*Declare local variables. */
   int BitmapX, BitmapY;
   int NewX, NewY, NewWidth, NewHeight;
   /*Do nothing if we are drawing a region. */
   if(Lead1->RgnMarkingMode != mmNone)
      return;
   /* Save the starting position, in case we need it. */
   StartY = Y;
   StartX = X;
   /*if we are ready to drag the selection, get a floater. */
   if(ReadyToDrag)
   {
      /*Translate the current mouse coordinates. */
      /*These coordinates account for the zoom factor and offset. */
      ZoomFactorX = (float)Lead1->DstWidth / (float)Lead1->SrcWidth;
      ZoomFactorY = (float)Lead1->DstHeight / (float)Lead1 
 >SrcHeight;
      BitmapX = (X / ZoomFactorX) - (Lead1->DstLeft / ZoomFactorX) + Lead1->SrcLeft;
      BitmapY = (Y / ZoomFactorY) - (Lead1->DstTop / ZoomFactorY) + Lead1->SrcTop;
      /*Continue to create the floater if( the mouse is pointing to the region we marked*/
      if(Lead1->IsPtInRgn(BitmapX, BitmapY))
      {
         /*Hide the region frame. */
         Lead1->RgnFrameType = ftNone;
         /*Create the floater bitmap, which will be the part of the*/
         /* main bitmap that is in the region's bounding rectangle */
         Lead1->Floater = Lead1->Bitmap;
         /*Translate the bitmap region coordinates to client area coordinates. */
         NewY = (Lead1->RgnTop - Lead1->SrcTop) * ZoomFactorY + Lead1->DstTop;
         NewX = (Lead1->RgnLeft - Lead1->SrcLeft) * ZoomFactorX + Lead1->DstLeft;
         NewWidth = Lead1->RgnWidth * ZoomFactorX;
         NewHeight = Lead1->RgnHeight * ZoomFactorY;
         /*Set the initial display position of the floater. */
         Lead1->SetFloaterDstRect(NewX, NewY, NewWidth, NewHeight);
         /*Set form-level variables. */
         FloaterY = Lead1->FloaterDstTop;
         FloaterX = Lead1->FloaterDstLeft;
         Lead1->FloaterVisible = true;
         Dragging = true;
         ReadyToDrag = false;
      }
   }
}
| 8. | In the LEAD1 control's MouseMove procedure, add the following code. | 
void __fastcall TForm1::Lead1MouseMove(TObject *Sender, TShiftState Shift, int X, int Y)
{
   /*Declare variables for repositioning the floater. */
   int NewX, NewY, NewWidth, NewHeight, XDelta, YDelta;
   /*Do nothing if( we are drawing a region. */
   if(Lead1->RgnMarkingMode != mmNone)
      return;
   /*Reposition the floater if we are dragging it. */
   if(Dragging && Shift==(TShiftState() << ssLeft) && (Lead1 
 >Floater))
      if(Lead1->IsPtInFloater(X, Y))
      {
         /*Update the position variables. */
         XDelta = X - StartX;
         YDelta = Y - StartY;
         NewX = FloaterX + XDelta;
         NewY = FloaterY + YDelta;
         NewWidth = Lead1->FloaterDstWidth;
         NewHeight = Lead1->FloaterDstHeight;
         /*Reposition the floater. */
         Lead1->SetFloaterDstRect(NewX, NewY, NewWidth, NewHeight);
         /*Save the form-level position variables. */
         FloaterY = NewY;
         FloaterX = NewX;
         StartY = Y;
         StartX = X;
      }
}
| 9. | In the LEAD1 control's MouseUp procedure, add the following code. | 
void __fastcall TForm1::Lead1MouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y)
{
   /*if we were drawing a region, set up for the next operation*/
   if(Lead1->RgnMarkingMode != mmNone)
   {
      Lead1->RgnMarkingMode = mmNone;
      Lead1->RgnFrameType = ftStatic;
      ReadyToDrag = true;
      ShowMessage("Now, drag the selection to another place.");
   }
}
| 10. | Run your program to test it. |