WPCubed Product Support

Adding wprichtext to Tchart - little help needed

Hi Support,

today I got an example how to integrate a normal RichEdit into a Tchart. They use this code to draw the richedit to the Tchart Canvas:

unit RichText_Drawing;{$I TeeDefs.inc}interfaceuses  {$IFNDEF LINUX}  Windows, Messages,  {$ENDIF}  SysUtils, Classes,  {$IFDEF CLX}  QGraphics, QControls, QForms, QDialogs, QExtCtrls, QComCtrls, QStdCtrls,  {$ELSE}  Graphics, Controls, Forms, Dialogs, ExtCtrls, ComCtrls, StdCtrls, RichEdit,  {$ENDIF}  {$IFDEF CLR}  Types,  {$ENDIF}  Base, TeeProcs, TeEngine, Chart;type  TRichTextDrawing = class(TBaseForm)    procedure Chart1AfterDraw(Sender: TObject);  private    { Private declarations }  public    { Public declarations }  end;Procedure DrawRichText(Chart:TCustomTeePanel; RichEdit:TRichEdit; R:TRect); overload;Procedure DrawRichText(Chart:TCustomTeePanel; const RichText:String; R:TRect); overload;implementation{$IFNDEF CLX}{$R *.dfm}{$ELSE}{$R *.xfm}{$ENDIF}procedure TRichTextDrawing.Chart1AfterDraw(Sender: TObject);var RichText : String;begin  RichText:= '{\rtf1\ansi\ansicpg1252\deff0\deflang1033'+             '{\fonttbl{\f0\fswiss\fcharset0 Arial;}'+             '{\f1\fmodern\fprq1\fcharset0 Courier New;}'+             '{\f2\fnil\fcharset2 Symbol;}}'+             '{SuperScript}{\super 2} {+ SubScript}{\sub 2}  =  a^2 + a2}';  DrawRichText(Chart1,RichText,Rect(60,60,360,90));  RichText:= '{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fswiss'+      '\fcharset0 Arial;}{\f1\fmodern\fprq1\fcharset0 Courier New;}{\f2' +      '\fnil\fcharset2 Symbol;}}'+      '\viewkind4\uc1\pard\f0\fs20 Normal\par'+      '\b Bold  \ul\b0 Underline\ulnone   \i Itallic\par'+      '}';  DrawRichText(Chart1,RichText,Rect(60,100,360,140));end;{$IFDEF CLR}{$IF Defined(UnsafeCode)}{$DEFINE ACCEPTDRAW}{$IFEND}{$ELSE}{$DEFINE ACCEPTDRAW}{$ENDIF}Procedure DrawRichText(Chart:TCustomTeePanel; RichEdit:TRichEdit; R:TRect); overload; {$IFDEF CLR}{$IFDEF ACCEPTDRAW}unsafe;{$ENDIF}{$ENDIF}{$IFDEF ACCEPTDRAW}const TwipsPerPixel=1440.0/96.0;var fr : FORMATRANGE;{$ENDIF}begin  {$IFDEF ACCEPTDRAW}  fr.hdc := Chart.Canvas.Handle;  fr.hdcTarget := fr.hdc;  r.left :=Round(r.Left*twipsPerPixel);  r.top :=Round(r.Top*twipsPerPixel);  r.right :=Round(r.Right*twipsPerPixel);  r.bottom := Round(r.Bottom*twipsPerPixel);  fr.rc := r;  fr.rcPage := r;  fr.chrg.cpMin :=0;  fr.chrg.cpMax :=-1;  RichEdit.Perform(EM_FORMATRANGE,1,{$IFNDEF CLR}Integer{$ENDIF}(@fr));  {$ENDIF}end;Procedure DrawRichText(Chart:TCustomTeePanel; const RichText:String; R:TRect); overload;var RichEdit : TRichEdit;begin  RichEdit:=TRichEdit.Create(nil);  try    RichEdit.Parent:=Chart.Parent; // set Parent before text and color    RichEdit.Text:=RichText;    RichEdit.Color:=Chart.Color;    DrawRichText(Chart,RichEdit,R);  finally    RichEdit.Free;  end;end;initialization  RegisterClass(TRichTextDrawing);end.

I can translate this to work with TWPRichText instead of RichEdit, but it wont work fpr me and I think it is a problem within this routine:

Procedure DrawRichText(Chart:TCustomTeePanel; RichEdit:TRichEdit; R:TRect); overload; {$IFDEF CLR}{$IFDEF ACCEPTDRAW}unsafe;{$ENDIF}{$ENDIF}{$IFDEF ACCEPTDRAW}const TwipsPerPixel=1440.0/96.0;var fr : FORMATRANGE;{$ENDIF}begin  {$IFDEF ACCEPTDRAW}  fr.hdc := Chart.Canvas.Handle;  fr.hdcTarget := fr.hdc;  r.left :=Round(r.Left*twipsPerPixel);  r.top :=Round(r.Top*twipsPerPixel);  r.right :=Round(r.Right*twipsPerPixel);  r.bottom := Round(r.Bottom*twipsPerPixel);  fr.rc := r;  fr.rcPage := r;  fr.chrg.cpMin :=0;  fr.chrg.cpMax :=-1;  RichEdit.Perform(EM_FORMATRANGE,1,{$IFNDEF CLR}Integer{$ENDIF}(@fr));  {$ENDIF}end;

I changed it to this:

Procedure DrawRichText(Chart:TCustomTeePanel; RichEdit:TWPRichText; R:TRect); overload;   //    RichEdit:TRichEdit; R:TRect); overload;{$IFDEF CLR}{$IFDEF ACCEPTDRAW}unsafe;{$ENDIF}{$ENDIF}{$IFDEF ACCEPTDRAW}const TwipsPerPixel=1440.0/96.0;var fr : FORMATRANGE;{$ENDIF}begin  {$IFDEF ACCEPTDRAW}  fr.hdc := Chart.Canvas.Handle;  fr.hdcTarget := fr.hdc;  r.left :=Round(r.Left*twipsPerPixel);  r.top :=Round(r.Top*twipsPerPixel);  r.right :=Round(r.Right*twipsPerPixel);  r.bottom := Round(r.Bottom*twipsPerPixel);  fr.rc := r;  fr.rcPage := r;  fr.chrg.cpMin :=0;  fr.chrg.cpMax :=-1;  RichEdit.Perform(EM_FORMATRANGE,1,{$IFNDEF CLR}Integer{$ENDIF}(@fr));  {$ENDIF}end;

I can compile it, but I see nothing. Could you please help me to get it working? I think there are two main problems:

  1. var fr : FORMATRANGE;

This is defined in the unit RichEdit:

{$EXTERNALSYM _formatrange}  _formatrange = record    hdc: HDC;    hdcTarget: HDC;    rc: TRect;    rcPage: TRect;    chrg: TCharRange;  end;  TFormatRange = _formatrange;  {$EXTERNALSYM FORMATRANGE}  FORMATRANGE = _formatrange;
type  _charrange = record    cpMin: Longint;    cpMax: LongInt;  end;  {$EXTERNALSYM _charrange}  TCharRange = _charrange;
  1. RichEdit.Perform(EM_FORMATRANGE,1,{$IFNDEF CLR}Integer{$ENDIF}(@fr));

I really don´t know if ths could work with WpRichText.

So can you give me some tips what I have to change in addition?

This is the code I tested ...

unit MainUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, TeeProcs, TeEngine, Chart,
  ComCtrls, StdCtrls, RichEdit, Series, TeeComma, TeeEdit, WPRTEDefs,
  WPRTEPaint, WPCTRLabel, WPCTRMemo, WPCTRRich;

type
  TForm12 = class(TForm)
    Chart1: TChart;
    ChartEditor1: TChartEditor;
    TeeCommander1: TTeeCommander;
    RichEdit1: TRichEdit;
    Button1: TButton;
    WPRichTextLabel1: TWPRichTextLabel;
    WPRichText1: TWPRichText;
    procedure Chart1AfterDraw(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form12: TForm12;

Procedure DrawRichText(Chart:TCustomTeePanel; RichEdit:TWPRichText; R:TRect); overload;
Procedure DrawRichText(Chart:TCustomTeePanel; const RichText:String; R:TRect); overload;

implementation

{$R *.dfm}

procedure TForm12.Chart1AfterDraw(Sender: TObject);
var RichText : String;
begin
  RichText:= '{\rtf1\ansi\ansicpg1252\deff0\deflang1033'+
             '{\fonttbl{\f0\fswiss\fcharset0 Arial;}'+
             '{\f1\fmodern\fprq1\fcharset0 Courier New;}'+
             '{\f2\fnil\fcharset2 Symbol;}}'+

             '{SuperScript}{\super 2} {+ SubScript}{\sub 2}  =  a^2 + a2}';

  //RichText := RichEdit1.;

  DrawRichText(Chart1,RichText,Rect(60,60,360,90));

// RichText:= '{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fswiss'+
//      '\fcharset0 Arial;}{\f1\fmodern\fprq1\fcharset0 Courier New;}{\f2' +
//      '\fnil\fcharset2 Symbol;}}'+
//      '\viewkind4\uc1\pard\f0\fs20 Normal\par'+
//      '\b Bold  \ul\b0 Underline\ulnone   \i Itallic\par'+
//      '}';

//  DrawRichText(Chart1,RichText,Rect(60,100,360,140));
end;

{$IFDEF CLR}
{$IF Defined(UnsafeCode)}
{$DEFINE ACCEPTDRAW}
{$IFEND}
{$ELSE}
{$DEFINE ACCEPTDRAW}
{$ENDIF}

Procedure DrawRichText(Chart:TCustomTeePanel; RichEdit:TWPRichText; R:TRect); overload;   //    RichEdit:TRichEdit; R:TRect); overload;
{$IFDEF CLR}{$IFDEF ACCEPTDRAW}unsafe;{$ENDIF}{$ENDIF}
{$IFDEF ACCEPTDRAW}
const TwipsPerPixel=1440.0/96.0;
var fr : FORMATRANGE;
{$ENDIF}
begin
  {$IFDEF ACCEPTDRAW}
  fr.hdc := Chart.Canvas.Handle;
  fr.hdcTarget := fr.hdc;
  r.left :=Round(r.Left*twipsPerPixel);
  r.top :=Round(r.Top*twipsPerPixel);
  r.right :=Round(r.Right*twipsPerPixel);
  r.bottom := Round(r.Bottom*twipsPerPixel);
  fr.rc := r;
  fr.rcPage := r;
  fr.chrg.cpMin :=0;
  fr.chrg.cpMax :=-1;

  RichEdit.Perform(EM_FORMATRANGE,1,{$IFNDEF CLR}Integer{$ENDIF}(@fr));
  {$ENDIF}
end;

Procedure DrawRichText(Chart:TCustomTeePanel; const RichText:String; R:TRect); overload;
var RichEdit : TWPRichText;         // var RichEdit : TRichEdit;
begin
  RichEdit:=TWPRichText.Create(nil);  //  TWPRichTextLabel
  try
    RichEdit.Parent:=Chart.Parent; // set Parent before text and color
    RichEdit.Lines.Add('Hallo Welt');
    RichEdit.LayoutMode := wplayNormal;
    RichEdit.PaperColor := $ABCDEF;
    DrawRichText(Chart,RichEdit,R);
  finally
    RichEdit.Free;
  end;
end;

end.
#1 ♥ 0
3.3k Views 2 users read 6 min
support

Hi,

check out the component TWPPrintEngine. That handles virtual page sizes (actual rectangles) which can then be printed on a Canvas surface. Do not try to convert the EM_FORMATRANGE call, the principle is different. You tell the component the size of the rectangles and it formats it for you. Then you can paint every "page"

Julian

#2 ♥ 0
This category is archived. No new posts are possible.