Outlining, Dragging, and Pasting a Region (Delphi 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 Main Form’s private declarations section. In online help, you can use the Edit pull-down menu to copy the block of code. |
{ Private declarations }
ReadyToDrag: boolean ; //The state after marking the region but before dragging
Dragging: boolean; //The state when the mouse is used for dragging the floater
StartX: Single; //Starting X position in screen twips
StartY: Single; //Starting Y position in screen twips
FloaterX: Single; //Floater X position in screen twips
FloaterY: Single; //Floater Y position in screen twips
ZoomFactorX: Single; //Used for translating positioning information
ZoomFactorY: Single; //Used for translating positioning information
4. |
At the top of your main form, add two command 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. |
procedure TForm1.SelRgnBtnClick(Sender: TObject);
begin
LEADRasterView1.RgnFrameType := RGNFRAME_ANIMATED;
LEADRasterView1.Raster.RefBitmap:= False ;
LEADRasterView1.RgnMarkingMode:= RGNMARK_FREEHAND;
ShowMessage ( 'Draw a freehand region' ) ;
end;
6. |
Code the PasteFloaterBtn control's Click procedure: |
procedure TForm1.PasteFloaterBtnClick(Sender: TObject);
var
RasterProc: ILEADRasterProcess;
LCRgnX:Single;
LCRgnY:Single;
LCRgnWidth: Single;
LCRgnHeight: Single;
LBRgnX: Single;
LBRgnY: Single;
LBRgnWidth: Single;
LBRgnHeight:Single;
MyOp: CombineConstants;
Ret : Smallint;
begin
//Do nothing if there is no floater.
if (LEADRasterView1.Floater = 0 ) then
Exit;
RasterProc := CreateComObject ( CLASS_LEADRasterProcess ) as ILEADRasterProcess;
//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 := CB_OP_ADD + CB_DST_0 ; //Operation flags for a simple paste.
RasterProc.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, Ret ) ;
//Free the region.
LEADRasterView1.Raster.FreeRgn ( ) ;
end;
7. |
Handle the LEADRasterView1 control's OnMouseDown2 event, and code LEADRasterView1MouseDown2 as follows. This code selects a different drawing object each time the event occurs. |
procedure TForm1.LEADRasterView1MouseDown2 (Sender: TObject; Button,
Shift: Smallint; x, y: Integer);
var
BitmapX: Single;
BitmapY: Single;
NewX: Single;
NewY:Single;
NewWidth: Single;
NewHeight: Single;
Ret: Smallint ;
begin
//Do nothing if we are drawing a region.
if LEADRasterView1.RgnMarkingMode <> RGNMARK_NONE then
Exit;
//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 = True ) then
begin
//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) )then
begin
//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, Ret ) ;
//Set form-level variables.
FloaterY := LEADRasterView1.FloaterDstTop;
FloaterX := LEADRasterView1.FloaterDstLeft;
LEADRasterView1.FloaterVisible := True;
Dragging := True;
ReadyToDrag := False;
end;
end;
end;
8. |
Handle the LEADRasterView1 control's OnMouseMove2 event, and code LEADRasterView1MouseMove2 as follows: |
procedure TForm1.LEADRasterView1MouseMove2(Sender: TObject; Button,
Shift: Smallint; x, y: Integer);
var
xDelta: Single;
yDelta: Single;
NewX: Single;
NewY: Single;
NewWidth: Single;
NewHeight: Single;
sRet: smallint;
bRet: WordBool ;
begin
//Do nothing if we are drawing a region.
if LEADRasterView1.RgnMarkingMode <> RGNMARK_NONE then
Exit ;
//Reposition the floater if we are dragging it.
if ((Dragging = True) And (Button = 1) And (LEADRasterView1.Floater <> 0)) then
begin
if ( LEADRasterView1.IsPtInFloater ( x, y, bRet)) then
begin
//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, sRet ) ;
//Save the form-level position variables.
FloaterY := NewY;
FloaterX := NewX;
StartY := y;
StartX := x;
end;
end;
end;
9. |
Handle the LEADRasterView1 control's OnMouseUp2 event, and code LEADRasterView1MouseUp2 as follows: |
procedure TForm1.LEADRasterView1MouseUp2(Sender: TObject; Button,
Shift: Smallint; x, y: Integer);
begin
//if we were drawing a region, set up for the next operation.
if ( LEADRasterView1.RgnMarkingMode <> RGNMARK_NONE ) then
begin
LEADRasterView1.RgnMarkingMode := RGNMARK_NONE;
LEADRasterView1.RgnFrameType := RGNFRAME_STATIC;
ReadyToDrag := True;
ShowMessage ( 'Now, drag the selection to another place.' ) ;
end;
end;
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 file, add LTRASTERPROCLib_TLB to the uses section. For example: |
Uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, LTRASTERPROCLib_TLB;
12. |
Run your program to test it. |