Delphi 2 - Moving from VB to Delphi

By: Borland Staff

Abstract: This document is designed to facilitate an understanding of Delphi 2.0 among those with existing knowledge in Visual Basic 4.0.

Moving From VB to Delphi: Graphics

Canvases
Image Manipulation
Graphics in Delphi is a larger topic than this chapter allows but it is important to touch on a few of the fundamental graphics concepts in Delphi and how they compare to Visual Basic.

Canvases
The TCanvas object is an abstraction that Delphi provides as a drawing surface in a number of components including the form, image, printer and listbox! Essentially a wrapper around a device context, this object allows you to write routines which operate on any of a number of different component types rather than just one as in VB.

All of the graphic methods you have for a Picturebox or Form in Visual Basic have equivalent methods in a Delphi TCanvas:

VB Delphi
Circle Elipse, Arc, Pie
Line LineTo, Rectangle
Print TextOut

In addition, the TCanvas represents a fairly complete wrapper around the graphics API of Windows so there are methods to support functionality that would otherwise require the use of the Windows API in VB. Examples are: CopyRect, FloodFill, and Polygon. The key portion of VBSAMPLESCALLDLLSCALLDLLS.MAK code in VB looks like this:

temp = BitBlt(hDC, X, Y, PicWidth, PicHeight, picCopy.hDC, 0, 0, SRCCOPY)

temp = BitBlt(picCopy.hDC, 0, 0, PicWidth, PicHeight, hDC, NewX, NewY, SRCCOPY)

temp = BitBlt(hDC, NewX, NewY, PicWidth, PicHeight, picMask.hDC, 0, 0, SRCAND)

temp = BitBlt(hDC, NewX, NewY, PicWidth, PicHeight, picSprite.hDC, 0, 0, SRCINVERT)

the same functionality in the Delphi example looks like this:

C.CopyMode := cmSrcAnd;

C.CopyRect (Dest, imgMask.Canvas, Src);

C.CopyMode := cmSrcInvert;

C.CopyRect (Dest, imgSprite.Canvas, Src);

C.CopyMode := cmSrcCopy;

where C refers to the canvas property of an image control. Furthermore, it is possible to create a canvas and assign an hDC into that canvas, thereby minimizing the amount of Windows API functionality required. In the Sprite sample, the code checks whether to act on the form or the desktop and assigns a different value to the local canvas variable:

if chkDesk.State = cbChecked then begin

C := TCanvas.Create;

C.Handle := GetDC(GetDesktopWindow);

RightEdge := GetSystemMetrics(SM_CXSCREEN);

BottomEdge := GetSystemMetrics(SM_CYSCREEN);

end

else begin

C := Canvas; {the Canvas property of the form}

RightEdge := ClientWidth;

BottomEdge := ClientHeight;

end;

Therefore, the canvas is an extremely important aspect of graphics programming in Delphi, especially from the perspective of hiding the complexity of manipulating the drawing surface of different objects.

Image Manipulation
Similarly, image manipulation in Delphi is designed around the concept of a picture object such as TBitmap. This object too has a canvas which can be manipulated the same way that of a picture box or form can be.

Suppose you wanted to mimic the functionality of the PICCLIP.OCX control which ships with Visual Basic Professional. This control allows you to extract portions of a matrix of pictures and assign the "cell picture" to another picture control.

To accomplish this, you might create a subroutine which extracted a portion of a picture like this and assigned it to another picture property:

procedure GetCell (Index:Integer; Dest, Source:TPicture);

var

BWidth, BHeight:Integer;

SrcR, DestR:TRect;

begin

BWidth := Source.Picture.Width div FCols;

BHeight := Source.Picture.Height div FRows;

DestR.Left := 0;

DestR.Top := 0;

DestR.Right := BWidth;

DestR.Bottom := BHeight;

SrcR.Left := (Index mod Cols) * BWidth;

SrcR.Top := (Index div Cols) * BHeight;

SrcR.Right := SrcR.Left + BWidth;

SrcR.Bottom := SrcR.Top + BHeight;

Dest.Bitmap.Width := BWidth;

Dest.Bitmap.Height := BHeight;

Dest.Bitmap.Canvas.CopyRect (DestR, Source.Canvas, SrcR);

end;

This is a pretty clean routine which doesn't use any API calls. Although it might be "showing off," you can take this a step further. What if you actually wanted to create a PICCLIP component for Delphi? Where would you begin? You want a control that is prepared to take a picture property, so why not begin with a TImage component and work from there. That's exactly what was done in the following unit, which represents an implementation of PicClip for Delphi. You need only install PRCCLIP.PAS into the IDE and you'll have a PicClip component! Here is the complete source code for the PicClip component for Delphi:

unit PicClip;

interface

uses Classes, Controls, WinTypes, Graphics, StdCtrls;

type

TPicClip = class(TImage)

private

FRows:Integer;

FCols:Integer;

FPicture:TPicture;

function GetCell (Index:Integer):TPicture;

public

constructor Create(AOwner: TComponent); override;

destructor Destroy;override;

property GraphicCell[Index:Integer]:TPicture read GetCell;

published

property Rows:Integer read FRows write FRows;

property Cols:Integer read FCols write FCols;

end;

procedure Register;

implementation

constructor TPicClip.Create(AOwner: TComponent);

begin

inherited Create(AOwner);

FPicture := TPicture.Create;

Visible := False;

end;

destructor TPicClip.Destroy;

begin

FPicture.Destroy;

inherited Destroy;

end;

function TPicClip.GetCell (Index:Integer):TPicture;

var

BWidth, BHeight:Integer;

SrcR, DestR:TRect;

begin

BWidth := Picture.Width div FCols;

BHeight := Picture.Height div FRows;

DestR.Left := 0;

DestR.Top := 0;

DestR.Right := BWidth;

DestR.Bottom := BHeight;

SrcR.Left := (Index mod Cols) * BWidth;

SrcR.Top := (Index div Cols) * BHeight;

SrcR.Right := SrcR.Left + BWidth;

SrcR.Bottom := SrcR.Top + BHeight;

FPicture.Bitmap.Width := BWidth;

FPicture.Bitmap.Height := BHeight;

FPicture.Bitmap.Canvas.CopyRect (DestR, Canvas, SrcR);

GetCell := FPicture;

end;

procedure Register;

begin

RegisterComponents('Foxhall', [TPicClip] );

end;

end.

It is intended that the examples provided in this document have helped highlight some of the key differences between programming with the interpreter-based Visual Basic Pro and Borland's next-generation Delphi, built around a state of that art optimising native code compiler. Furthermore, the sample code also makes clear the differences between the script-language style of Visual Basic versus the more structured, object-oriented approach made possible by Delphi's Object Pascal language. You should now be able to begin applying your programming skills productively in Delphi. You can also use a variety of third party tools and components to facilitate creation of Delphi or Delphi Client/Server applications including tools that help convert existing code into Delphi code.

As you become familiar with Delphi programming you will find that Delphi and Delphi Client/Server are able to take you further in your application development with greater performance, reuse and scalability than Visual Basic Pro.


Server Response from: ETNASC03