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