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. |