Mega Code Archive

 
Categories / Delphi / Examples
 

Graphictnt

GRAPHICS -best ways to set up components for drawing. 1. declare a bitmap in FormCreate and immediately assign that to the Picture.Graphic property of a TImage component placed on the main drawing form. Note that here we also set the bitmap's extents to be the same as the extents of the form's image component: procedure TFormLab3D.FormCreate(Sender: TObject); var Bitmap: TBitmap; begin Bitmap := TBitmap.Create; Bitmap.Width := Image.Width; Bitmap.Height := Image.Height; Image.Picture.Graphic := Bitmap; ShowFigure; //also interesting; see below end; note how next we declare a variable of type TPantograph within the function, and then we call it's constructor WITH A PARAMETER OF THE IMAGE CANVAS PROCEDURE TFormLab3D.ShowFigure; VAR pantograph: TPantoGraph; BEGIN Image.Canvas.FillRect( Rect(0,0, Width, Height) ); pantograph := TPantoGraph.Create(Image.Canvas); {Use whole canvas as viewport} {although you can do more in terms of viewports using the pantograph's viewport method [elsewhere]...} pantograph.ViewPort(0.00,1.00, 0.00,1.00); TRY {do stuff...} FINALLY pantograph.free END END; In the example program from which the code above is taken, the pantograph object is declared in another unit, and 'A pantoGraph object maps "World Coordinates" to a Delphi Canvas'. This to is interesting in that it brings to mind what Ed Yourdon said once about how a non-trivial graphics app coded with good object-orientation should haver three main layers of objects: 1. a 'screen' layer 2. a 'functional code' layer, and 3. a 'data' layer ************************************************************ beware of rounding down in complex calculations, as this may well result in significant alterations to x,y coordinates for instance. So always do the calculations with floating point type variables until the very last moment, converting to Integer types a necessary. ************************************************************ Tip: Use the initialization section to initaialise variables and/or executer program startup code as the initialization section 'contains statements that are executed, in the order in which they appear, on program start-up'. ************************************************************ EXCEPTIONS declare your new user-defined exceptions as CLASSES in the Interface/Type section at the top of a unit, like so INTERFACE TYPE EVectorError = CLASS(Exception); EMatrixError = CLASS(Exception); and then (when appropriate conditions hold true) 'RAISE' the exception as follows: raise EMatrixError.Create('Matrix multiplication error') ************************************************************ alternatively (probably not as good) we can declare a bitmap variable as an attribute of a draw object, creating it in the object's constructor, and freeing it in the object's destructor: Note also how we do operations on the bitmap (in FillTBitMapDrawArea), copying the bitmap to the canvas passed in at the end of the function type TCNSVDraw = class(TObject) constructor Create; destructor Destroy; override; procedure FillTBitMapDrawArea(thisCanvas: TCanvas; cWidth, cHeight: Integer); {et cetera} private memBitMap: Graphics.TBitMap; public end; var CNSVDraw: TCNSVDraw; implementation constructor TCNSVDraw.Create; begin memBitMap := Graphics.TBitmap.Create; memBitMap.Width := Screen.Width; memBitMap.Height := Screen.Height; end; destructor TCNSVDraw.Destroy; begin memBitMap.Free; end; procedure TCNSVDraw.FillTBitMapDrawArea(thisCanvas: TCanvas; cWidth, cHeight: Integer); {set up the drawing area to be white not grey...} var imageRect: TRect; begin with memBitMap.Canvas do begin Brush.Color := clWhite; imageRect.Left := 0; imageRect.Top := 0; //imageRect.Right := cWidth; //imageRect.Bottom := cHeight; imageRect.Right := Screen.Width; imageRect.Bottom := Screen.Height; FillRect(imageRect); end; thisCanvas.Draw(0, 0, memBitMap); end; *************************************************************** When sizing, say, a TImage to the form on which it sits, be careful of using the WIDTH of the form as in MainForm.Width. The borders of forms (ie the borders of windows) are user-configurable so the width of the border of the form will vary unpredictably. But if you use clientWidth and clientHeight instead this avoids the problem, since clientWidth is formWidth minus border. *************************************************************** ************************************** If you want to maintain a LARGE LIST OF IMAGES, then consider using an Image List component. From the Delphi Help: The TImageList component is a collection of same-sized images, each of which can be referred to by its index. Unit Controls Description Image lists are used to efficiently manage large sets of icons or bitmaps. All images in an image list are contained in a single, wide bitmap in screen device format. An image list may also include a monochrome bitmap that contains masks used to draw images transparently (icon style). The image list is capable of holding a large number of same sized images and retrieving them via their index within the range 0 to n - 1. The image list also has methods to facilitate storing, retrieving, and drawing of the stored images. The TImageList is derived from TCustomImageList and exposes many of the protected properties and methods of the TCustomImageList.