Свои компоненты + внутренние данные
Народ спасайте, как заполнить данными свой компонент, обнуляет все при вызове
frxReport1.ShowReport;
И как сделать доступными функции компонента из скрипта всегда, не хватает ума
как их зарегистрировать в RTTI.
Написал компонент frxChartMMView;
по тексту далее
procedure TForm2.Button1Click(Sender: TObject);
var img: TfrxChartMMView;
i, j: integer;
begin
из базовой программы задолняю массив, все ок все заполняется
img := frxReport1.FindObject('ChartMM1') as TfrxChartMMView;
for i:=0 to 100 do img.AddY(i*10,11,11,'');
а после этого вызова, массив пустой
frxReport1.ShowReport;
end;
сам модуль
unit frxChartMMView;
interface
{$I frx.inc}
uses
Windows, Messages, SysUtils, Classes, Graphics, frxClass
type
TfrxChartMMObject = class(TComponent); // fake component
TfrxChartMMView = class(TfrxView)
private
...
aPoint: array of integer;
procedure WallpaperMillimeter(X, Y, X1, Y1: integer);
public
constructor Create(AOwner: TComponent); override;
procedure Draw(Canvas: TCanvas; ScaleX, ScaleY, OffsetX, OffsetY: Extended); override;
class function GetDescription: String; override;
// процедура заполнения
procedure AddY(Y: Extended; cycle, code: integer; name: string);
published
property Frame;
end;
procedure Register;
implementation
uses frxChartMMViewRTTI, frxDsgnIntf, frxRes;
constructor TfrxChartMMView.Create(AOwner: TComponent);
begin
inherited;
BackColor:=clWhite;
...
end;
class function TfrxChartMMView.GetDescription: String;
begin
Result := 'ChartMMView';
end;
procedure TfrxChartMMView.WallpaperMillimeter(X, Y, X1, Y1: integer);
begin
....
тут что то рисую, все рисуется
дальше хочу нарисовать из массива, а он пустой
j:=high(aPoint);
for i:=0 to j do
begin
FCanvas.MoveTo(Trunc(i*tPixelInMM)+x,0);
FCanvas.LineTo(Trunc(i*tPixelInMM)+x,round(aPoint*tPixelInMM));//aPoint^.y
end;
end;
procedure TfrxChartMMView.Draw(Canvas: TCanvas; ScaleX, ScaleY, OffsetX,
OffsetY: Extended);
var i: double;
begin
BeginDraw(Canvas, ScaleX, ScaleY, OffsetX, OffsetY);
WallpaperMillimeter(FX, FY, FX1, FY1);
DrawFrame;
end;
procedure TfrxChartMMView.AddY(Y: Extended; cycle, code: integer; name: string);
var i: integer;
begin
i:=length(aPoint);
setlength(aPoint,i+1);
aPoint:=round(y);
end;
procedure Register;
begin
RegisterComponents('My', [TfrxChartMMObject]);
end;
initialization
frxObjects.RegisterObject1(TfrxChartMMView, nil, '', '', 0, 50);
finalization
frxObjects.UnRegister(TfrxChartMMView);
end.
его RTTI
type
TFunctions = class(TfsRTTIModule)
public
constructor Create(AScript: TfsScript); override;
end;
{ TFunctions }
constructor TFunctions.Create(AScript: TfsScript);
begin
inherited Create(AScript);
with AScript do
begin
AddClass(TfrxChartMMView, 'TfrxView');
end;
end;
initialization
fsRTTIModules.Add(TFunctions);
finalization
if fsRTTIModules <> nil then
fsRTTIModules.Remove(TFunctions);
end.
frxReport1.ShowReport;
И как сделать доступными функции компонента из скрипта всегда, не хватает ума
как их зарегистрировать в RTTI.
Написал компонент frxChartMMView;
по тексту далее
procedure TForm2.Button1Click(Sender: TObject);
var img: TfrxChartMMView;
i, j: integer;
begin
из базовой программы задолняю массив, все ок все заполняется
img := frxReport1.FindObject('ChartMM1') as TfrxChartMMView;
for i:=0 to 100 do img.AddY(i*10,11,11,'');
а после этого вызова, массив пустой
frxReport1.ShowReport;
end;
сам модуль
unit frxChartMMView;
interface
{$I frx.inc}
uses
Windows, Messages, SysUtils, Classes, Graphics, frxClass
type
TfrxChartMMObject = class(TComponent); // fake component
TfrxChartMMView = class(TfrxView)
private
...
aPoint: array of integer;
procedure WallpaperMillimeter(X, Y, X1, Y1: integer);
public
constructor Create(AOwner: TComponent); override;
procedure Draw(Canvas: TCanvas; ScaleX, ScaleY, OffsetX, OffsetY: Extended); override;
class function GetDescription: String; override;
// процедура заполнения
procedure AddY(Y: Extended; cycle, code: integer; name: string);
published
property Frame;
end;
procedure Register;
implementation
uses frxChartMMViewRTTI, frxDsgnIntf, frxRes;
constructor TfrxChartMMView.Create(AOwner: TComponent);
begin
inherited;
BackColor:=clWhite;
...
end;
class function TfrxChartMMView.GetDescription: String;
begin
Result := 'ChartMMView';
end;
procedure TfrxChartMMView.WallpaperMillimeter(X, Y, X1, Y1: integer);
begin
....
тут что то рисую, все рисуется
дальше хочу нарисовать из массива, а он пустой
j:=high(aPoint);
for i:=0 to j do
begin
FCanvas.MoveTo(Trunc(i*tPixelInMM)+x,0);
FCanvas.LineTo(Trunc(i*tPixelInMM)+x,round(aPoint*tPixelInMM));//aPoint^.y
end;
end;
procedure TfrxChartMMView.Draw(Canvas: TCanvas; ScaleX, ScaleY, OffsetX,
OffsetY: Extended);
var i: double;
begin
BeginDraw(Canvas, ScaleX, ScaleY, OffsetX, OffsetY);
WallpaperMillimeter(FX, FY, FX1, FY1);
DrawFrame;
end;
procedure TfrxChartMMView.AddY(Y: Extended; cycle, code: integer; name: string);
var i: integer;
begin
i:=length(aPoint);
setlength(aPoint,i+1);
aPoint:=round(y);
end;
procedure Register;
begin
RegisterComponents('My', [TfrxChartMMObject]);
end;
initialization
frxObjects.RegisterObject1(TfrxChartMMView, nil, '', '', 0, 50);
finalization
frxObjects.UnRegister(TfrxChartMMView);
end.
его RTTI
type
TFunctions = class(TfsRTTIModule)
public
constructor Create(AScript: TfsScript); override;
end;
{ TFunctions }
constructor TFunctions.Create(AScript: TfsScript);
begin
inherited Create(AScript);
with AScript do
begin
AddClass(TfrxChartMMView, 'TfrxView');
end;
end;
initialization
fsRTTIModules.Add(TFunctions);
finalization
if fsRTTIModules <> nil then
fsRTTIModules.Remove(TFunctions);
end.
Комментарии
В базовой программе
img := frxReport1.FindObject('ChartMM1') as TfrxChartMMView;
for i:=0 to 5 do img.AddY(i*10,11,11,'');
frxReport1.ShowReport;
работает. Проверяю BeforePrint, данные есть, AfterPrint есть, а внутри нет. Похоже создается новый экземпляр объекта со своими переменными, отробатывает ривование и вовзращает предыдущему экземпляру. Когдато читал о подобном но не могу найти. ПОМОЖИТЕ ЛЮДИ ДОБРЫ!
Проще говоря, Вам нужно записывать и считывать aPoint через DefineProperties.
Да спасибо. Так и сделал. Но хотел добиться классического решения. Рассматривал вариант нескольких наследуемых классов, но так и не разобрался, как создать независимый класс данных от класса наследуемого TfrxView.
Проблема в том, что класс наследуемый от TfrxView, создается при запуске окна где лежит компонет, но при отработке Draw, порождается новый объект, естественно со своими переменными. Т.е. в onBeforePrint написанного компонента я еще обращаюсь к основному компоненту, могу его заполнять и т.д. затем отрабатывается новый экземпляр (внутри программно я могу изменять новые данные), но в onAfterPrint это не отразится, данные будут для объекта Before.
Как написанно в ответе 2 проще всего передавать данные через Property