Draw Command Architecture

TECH TIP: Draw Command Architecture

Page Objects

When a report prints it generates Page objects. Each Page object contains an array of DrawCommand objects (Page.DrawCommands[]) that describe what needs to be rendered for the page.

Report --> Pages.DrawCommands[] ---> Device (Printer, Screen, ..) --> final output

DrawCommands Objects
Component --> DrawCommand

Each TppComponent generates a DrawCommand object each time
it prints on a page. For example if the component is a TppLabel and prints at the top of the page – one draw command object will be created for each page. If the Label is in the detail band, many draw commands will be created for each page.

A DrawCommand contains a complete description of the location and content to draw. See ppDrwCmd.pas for the existing DrawCommand class descendants (DrawText, DrawImage, etc.)

Some of the basic DrawCommand classes such as DrawImage and DrawText, rely on the ScreenDevice and PrinterDevice classes to render their content. Other DrawCommand classes such as TppDrawBarCode and TppDrawRichText render themselves to the appropriate device canvas directly.

Creating Custom Components

Each component has an associated DrawCommand class that is is the value of its DrawCommandClass property. For a Label, the DrawCommandClass is TppDrawText. This value is normally set in the constructor. Examples of the common components are located in ppCtrls.pas.

constructor TmyComponent.Create(AOwner: TComponent);
begin

  inherited Create(AOwner);

  DrawCommandClass := TppDrawText;

end;

Each time the component prints, a DrawCommand object of the designated DrawCommand class will automatically be created and the components PropertiesToDrawCommand method will be called. You override this method to transfer the appropriate property values from the component to the drawcommand object.

{------------------------------------------------------------------------}
{ TmyComponent.PropertiesToDrawCommand }

procedure TmyComponent.PropertiesToDrawCommand(aDrawCommand: TppDrawCommand);
var
  lWrappedText: TStrings;
  lTextBuf: PChar;
  lPrinter: TObject;
  lDrawText: TppDrawText;
  llCharPos: Longint;
begin

  inherited PropertiesToDrawCommand(aDrawCommand);

  if not(aDrawCommand is TppDrawText) then Exit;

  lDrawText := TppDrawText(aDrawCommand);

  {set properties here}

  lDrawText.Alignment    := Alignment;
  lDrawText.AutoSize     := AutoSize;
  lDrawText.Color        := Color;
  lDrawText.Left         := PrintPosRect.Left;
  lDrawText.Top          := PrintPosRect.Top;
  lDrawText.Height       := PrintPosRect.Bottom - PrintPosRect.Top;
  lDrawText.Width        := PrintPosRect.Right - PrintPosRect.Left;
  lDrawText.Text         := Text;
  lDrawText.Transparent  := Transparent;
  lDrawText.WordWrap     := WordWrap;
  lDrawText.Font         := Font;


end;