Outlining, Dragging, and Pasting a Region (C++ Builder 4.0)

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 RasterView control, name it LEADRasterView2, and set its Visible property to False.

 

Note: for simplicity, this example uses 2 controls. In order to save memory, your application could use a dynamically created ILEADRaster object instead of the 2nd LEAD Raster View control.

3.

Add the following form-level variables to the Unit1.h file private declarations section. In online help, you can use the Edit pull-down menu to copy the block of code.

 bool ReadyToDrag; //The state after marking the region but before dragging
 bool Dragging; //The state when the mouse is used for dragging the floater
 float StartX; //Starting X position in screen twips
 float StartY; //Starting Y position in screen twips
 float FloaterX; //Floater X position in screen twips
 float FloaterY; //Floater Y position in screen twips
 float ZoomFactorX; //Used for translating positioning information
 float ZoomFactorY; //Used for translating positioning information

4.

image\btncmd.gif At the top of your main form, add two buttons and name them as follows:

 

Name

Caption

 

SelRgnBtn

Select Region

 

PasteFloaterBtn

Paste Floater

5.

Code SelRgnBtn control's Click procedure as the following. In online help, you can use the Edit pull-down menu to copy the block of code.

void __fastcall TForm1::SelRgnBtnClick(TObject *Sender)
{
 LEADRasterView1->RgnFrameType = RGNFRAME_ANIMATED;
LEADRasterView1->Raster->RefBitmap = false ;
LEADRasterView1->RgnMarkingMode = RGNMARK_FREEHAND;
ShowMessage ( "Draw a freehand region" ) ;
}

6.

Code the PasteFloaterBtn control's Click procedure:

void __fastcall TForm1::PasteFloaterBtnClick(TObject *Sender)
{
LEADRasterProcess* pRasterProc= NULL;;
float LCRgnX;
float LCRgnY;
float LCRgnWidth;
float LCRgnHeight;
float LBRgnX;
float LBRgnY;
float LBRgnWidth;
float LBRgnHeight;
CombineConstants MyOp ;

//Do nothing if there is no floater
if (LEADRasterView1->Floater == 0 )
 return;
CoCreateInstance(CLSID_LEADRasterProcess, NULL, CLSCTX_ALL, IID_ILEADRasterProcess, (void**)&pRasterProc);
//Get the floater into another bitmap
LEADRasterView2->Raster->RefBitmap = false;
LEADRasterView2->ScaleMode = LEADRasterView1->ScaleMode;
LEADRasterView2->Raster->Bitmap = LEADRasterView1->Floater;
//Get the floater's client coordinates into local variables
LCRgnX = LEADRasterView1->FloaterDstLeft;
LCRgnY = LEADRasterView1->FloaterDstTop;
LCRgnWidth = LEADRasterView1->FloaterDstWidth;
LCRgnHeight = LEADRasterView1->FloaterDstHeight;
//Delete the floater->
LEADRasterView1->FloaterVisible = false;
LEADRasterView1->Floater = 0;
//Translate the client coordinates to bitmap coordinates
LBRgnX = ((LCRgnX - LEADRasterView1->DstLeft) / ZoomFactorX) + LEADRasterView1->SrcLeft;
LBRgnY = ((LCRgnY - LEADRasterView1->DstTop) / ZoomFactorY) + LEADRasterView1->SrcTop;
LBRgnWidth = LCRgnWidth / ZoomFactorX;
LBRgnHeight = LCRgnHeight / ZoomFactorY;
//Reposition the region to use as a mask for the Combine method
LEADRasterView1->Raster->OffsetRgn ( LBRgnX - LEADRasterView1->Raster->Rgnleft, LBRgnY - LEADRasterView1->Raster->Rgntop ) ;
//Use the Combine method to paste the Lead2 bitmap into the Lead1 bitmap
MyOp = (CombineConstants)(CB_OP_ADD + CB_DST_0) ; //Operation flags for a simple paste
pRasterProc->Combine ( LEADRasterView1->Raster, LBRgnX, LBRgnY, LBRgnWidth, LBRgnHeight, LEADRasterView2->Raster, 0, 0, MyOp ) ;
//Repaint the part of the client area that has changed
LEADRasterView1->RepaintRect (LCRgnX, LCRgnY, LCRgnWidth, LCRgnHeight, false);
//Free the region
LEADRasterView1->Raster->FreeRgn ( ) ;
pRasterProc->Release();
}

7.

Handle the LEADRasterView1 control's OnMouseDown2 event, and code LEADRasterView1MouseDown2 as follows:

void __fastcall TForm1::LEADRasterView1MouseDown2 (TObject *Sender,
short Button, short Shift, long x, long y)
{
 float BitmapX;
float BitmapY;
float NewX;
float NewY;
float NewWidth;
float NewHeight;

//Do nothing if we are drawing a region.
if (LEADRasterView1->RgnMarkingMode != RGNMARK_NONE)
 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 = LEADRasterView1->DstWidth / LEADRasterView1->SrcWidth;
ZoomFactorY = LEADRasterView1->DstHeight / LEADRasterView1->SrcHeight;
BitmapX = (x / ZoomFactorX) - (LEADRasterView1->DstLeft / ZoomFactorX)
+ LEADRasterView1->SrcLeft;
BitmapY = (y / ZoomFactorY) - (LEADRasterView1->DstTop / ZoomFactorY)
+ LEADRasterView1->SrcTop;
//Continue to create the floater if the mouse is pointing to the region we marked

if ( LEADRasterView1->Raster->IsPtInRgn (BitmapX, BitmapY) )
{
//Hide the region frame->
LEADRasterView1->RgnFrameType = RGNFRAME_NONE;
//Create the floater bitmap, which will be the part of the main bitmap that is
//in the region's bounding rectangle
LEADRasterView1->Floater = LEADRasterView1->Raster->Bitmap;
//Translate the bitmap region coordinates to client area coordinates
NewY = ((LEADRasterView1->Raster->Rgntop - LEADRasterView1->SrcTop) * ZoomFactorY)
+ LEADRasterView1->DstTop;
NewX = ((LEADRasterView1->Raster->Rgnleft - LEADRasterView1->SrcLeft) * ZoomFactorX)
+ LEADRasterView1->DstLeft;
NewWidth = LEADRasterView1->Raster->RgnWidth * ZoomFactorX;
NewHeight = LEADRasterView1->Raster->RgnHeight * ZoomFactorY;
//Set the initial display position of the floater
LEADRasterView1->SetFloaterDstRect ( NewX, NewY, NewWidth, NewHeight) ;
//Set form-level variables
FloaterY = LEADRasterView1->FloaterDstTop;
FloaterX = LEADRasterView1->FloaterDstLeft;
LEADRasterView1->FloaterVisible = True;
Dragging = True;
ReadyToDrag = False;
 }
 }
}

8.

Handle the LEADRasterView1 control's OnMouseMove2 event, and code LEADRasterView1MouseMove2 as follows:

void __fastcall TForm1::LEADRasterView1MouseMove2(TObject *Sender,
short Button, short Shift, long x, long y)
{
 float xDelta;
float yDelta;
float NewX;
float NewY;
float NewWidth;
float NewHeight;

//Do nothing if we are drawing a region.
if (LEADRasterView1->RgnMarkingMode !=RGNMARK_NONE)
 return;
//Reposition the floater if we are dragging it.
if ((Dragging) && (Button == 1) && (LEADRasterView1->Floater != 0))
{
 if ( LEADRasterView1->IsPtInFloater (x, y))
{
 //Update the position variables->
xDelta = x - StartX;
yDelta = y - StartY;
NewX = FloaterX + xDelta;
NewY = FloaterY + yDelta;
NewWidth = LEADRasterView1->FloaterDstWidth ;
NewHeight = LEADRasterView1->FloaterDstHeight;
//Reposition the floater
LEADRasterView1->SetFloaterDstRect (NewX, NewY, NewWidth, NewHeight) ;
//Save the form-level position variables->
FloaterY = NewY;
FloaterX = NewX;
StartY = y;
StartX = x;
}
 }
}

9.

Handle the LEADRasterView1 control's OnMouseUp2 event, and code LEADRasterView1MouseUp2 as follows:

void __fastcall TForm1::LEADRasterView1MouseUp2(TObject *Sender,
short Button, short Shift, long x, long y)
{
 //if we were drawing a region, set up for the next operation.
if ( LEADRasterView1->RgnMarkingMode != RGNMARK_NONE )
{
 LEADRasterView1->RgnMarkingMode = RGNMARK_NONE;
LEADRasterView1->RgnFrameType = RGNFRAME_STATIC;
ReadyToDrag = True;
ShowMessage ( "Now, drag the selection to another place." ) ;
}
}

10.

On the Project pull-down menu, use the Import Type library… and select the LEAD Raster Process object library (14.5).

11.

At the beginning of the Unit1.cpp file, include this file:

#include "LTRASTERPROCLib_TLB.h"

12.

Run your program to test it.