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.

image\btncmd.gif 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.