Hello, Using Delphi 7 with RB 10 Is there any way to draw directly to the report canvas using RAP - i want to draw custom shapes like triangles and hexagons that TppShape does not support. Regards, Gilbert
- one option is to create a new myShape component that can draw triangles and hexagons. The source code the TppShape resides in ppCtrls.pas and can be used as a starting point. Also see TppDrawShape in ppDrwCmds.pas. Creating a custom component would allow you to easily re-use the myShape in many reports. (For an example of a custom component, see RBuilder\Demos\RCL)
- another option is to use a metafile and draw to a metafile canvas, then assign the metafile to the TppImage.Picture.Graphics property. To draw from RAP you would need to create one or more pass-thru functions.
-- Nard Moseley Digital Metaphors www.digital-metaphors.com
Best regards,
Nard Moseley Digital Metaphors www.digital-metaphors.com
OK, i created a new component, everythings cool in design mode, but the thing does not render in preview. I am rendering the shape in my TppCustomComponentControl desecendent which i have a feeling is only applicable to design mode:
Looking at the code for TppShape, the only place i can see that could render the shape in preview is procedure TppScreenDevice.DrawShape(aDrawShape: TppDrawShape); in ppViewr.pas
How do i get my shape to render in preview & print?
You will need to create a custom TppDrawCommand descendant and override the DrawCommand.Draw method to render to the screen and to printer. See the following article.
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.
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.
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.
When you create a descendant component you can either use an existing draw command class or create a new one. For the TeeChart wrapper components, we chose to use the existing DrawImage class to specify the TeeChart as a metafile image. So it is not always necessary to create a draw command class.
Examples of DrawCommand classes are located in ppDrwCmd.pas. A drawcommand will contain published properties that contain a complete description of the location and content to be rendered.
DrawCommand classes must be registered - see the initization and finalization sections at the bottom of the ppDrwCmd.pas unit for an example.
DrawCommand classes should publish all properties used to describe the object.
DrawCommand classes must implment the Assign method to assign the values of all published properties from one draw command to another.
When asking a question, please start a new thread. This help us track down your questions and answer them more quickly.
I'm a bit unclear about what you would like to do. If you would like full justified text, you can use the TppMemo object which provides this feature. If you would like to space dynamic components across a page equally, you will need to do so manually before the components are generated. Let me know exactly what you are trying to accomplish and I can give you some direction.
Comments
- one option is to create a new myShape component that can draw triangles
and hexagons. The source code the TppShape resides in ppCtrls.pas and can be
used as a starting point. Also see TppDrawShape in ppDrwCmds.pas. Creating a
custom component would allow you to easily re-use the myShape in many
reports. (For an example of a custom component, see RBuilder\Demos\RCL)
- another option is to use a metafile and draw to a metafile canvas, then
assign the metafile to the TppImage.Picture.Graphics property. To draw from
RAP you would need to create one or more pass-thru functions.
--
Nard Moseley
Digital Metaphors
www.digital-metaphors.com
Best regards,
Nard Moseley
Digital Metaphors
www.digital-metaphors.com
thing does not render in preview. I am rendering the shape in my
TppCustomComponentControl desecendent which i have a feeling is only
applicable to design mode:
TppDesignControlFactory.RegisterDesignControlClass(TmyShape,
TmyShapeControl);
Looking at the code for TppShape, the only place i can see that could render
the shape in preview is
procedure TppScreenDevice.DrawShape(aDrawShape: TppDrawShape);
in ppViewr.pas
How do i get my shape to render in preview & print?
Regards,
Gilbert
You will need to create a custom TppDrawCommand descendant and override the
DrawCommand.Draw method to render to the screen and to printer. See the
following article.
---------------------------------------
Article: 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;
Creating Custom DrawCommands
----------------------------
When you create a descendant component you can either
use an existing draw command class or create a new one.
For the TeeChart wrapper components, we chose to use
the existing DrawImage class to specify the TeeChart
as a metafile image. So it is not always necessary to
create a draw command class.
Examples of DrawCommand classes are located in ppDrwCmd.pas.
A drawcommand will contain published properties that
contain a complete description of the location and
content to be rendered.
DrawCommand classes must be registered - see the
initization and finalization sections at the bottom
of the ppDrwCmd.pas unit for an example.
DrawCommand classes should publish all properties
used to describe the object.
DrawCommand classes must implment the Assign
method to assign the values of all published
properties from one draw command to another.
--
Tech Support mailto:support@digital-metaphors.com
Digital Metaphors http://www.digital-metaphors.com
--
Nard Moseley
Digital Metaphors
www.digital-metaphors.com
Best regards,
Nard Moseley
Digital Metaphors
www.digital-metaphors.com
simetrics margins
i use report bulder 10.02 and delphi 7
When asking a question, please start a new thread. This help us track down
your questions and answer them more quickly.
I'm a bit unclear about what you would like to do. If you would like full
justified text, you can use the TppMemo object which provides this feature.
If you would like to space dynamic components across a page equally, you
will need to do so manually before the components are generated. Let me
know exactly what you are trying to accomplish and I can give you some
direction.
--
Regards,
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com