Delphi 以对象作为参数调用过程

Delphi 以对象作为参数调用过程,delphi,Delphi,试图保存代码。我想在OnActivate的表单上的图像上显示文本等,然后单击按钮打印相同的文本。真正的程序更复杂。为了两次保存编写代码,我尝试了附带的代码,但在Obj.Canvas行无法编译。如果我注释掉这一行和封闭的行,程序将运行,但Obj值为 我尝试过其他几种方法,但都不管用。谁能告诉我哪里出了问题 獾 unit Unit7; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variant

试图保存代码。我想在OnActivate的表单上的图像上显示文本等,然后单击按钮打印相同的文本。真正的程序更复杂。为了两次保存编写代码,我尝试了附带的代码,但在Obj.Canvas行无法编译。如果我注释掉这一行和封闭的行,程序将运行,但Obj值为

我尝试过其他几种方法,但都不管用。谁能告诉我哪里出了问题

unit Unit7;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls, printers;

type
  TForm7 = class(TForm)
    Print: TButton;
    Image1: TImage;
    PrintDialog1: TPrintDialog;
    procedure FormActivate(Sender: TObject);
    procedure PrintClick(Sender: TObject);
  private
    { Private declarations }
  public
    DH,DW:Extended;
    Procedure DoLayout(Obj:TObject);
    { Public declarations }
  end;

var
  Form7: TForm7;

implementation

{$R *.dfm}

procedure TForm7.FormActivate(Sender: TObject);
begin
DoLayout(Image1);
end;

procedure TForm7.PrintClick(Sender: TObject);
begin
  if PrintDialog1.Execute then
  begin
    printer.BeginDoc;
      DoLayout(Printer);
    Printer.EndDoc;
  end;
end;

procedure TForm7.DoLayout(Obj:TObject);
begin
  if  Obj =Printer then         //when you run the program Obj is ()
  begin
    DW:=Printer.PageWidth/Image1.Width;
    DH:=Printer.PageHeight/Image1.Height;
  end
  else
  begin
    DH:=1;
    DW:=1;
  end;
  With Obj.canvas do          //Error here when compiled   - tried commenting it out
  begin
    TextOut(Int(DH*50),Int(DW*30),'This is the text');    //commented this out too
  end;
end;

end.
tpinter类和TImage类除了TObject之外不共享一个共同的祖先类,因此这就是您要传递的

一个建议的重构是更改DoLayout代码以接受您想要使用的画布,以及一个确定您正在传递的是打印机还是图像的参数,例如

procedure TForm7.DoLayout(aCanvas : TCanvas; bPrinter : boolean);
begin
  if bPrinter then         //when you run the program Obj is ()
  begin
    DW:=Printer.PageWidth/Image1.Width;
    DH:=Printer.PageHeight/Image1.Height;
  end
  else
  begin
    DH:=1;
    DW:=1;
  end;
  With aCanvas do
  begin
    TextOut(Int(DH*50),Int(DW*30),'This is the text');
  end;
end;
然后在调用时,显式使用打印机画布或图像画布:

DoLayout(Printer.canvas, true);


这只是基于代码的粗略估计;我手头没有delphi编译器来验证它。

TObject的实例没有canvas属性,这解释了错误;你需要选择正确的画布对象,而不是你在做什么。我向你的智慧低头,因为这个对象没有画布。然而,这并不能解决我的问题。我需要在Image1和Printer上使用DoLayout过程,否则我会将DoLayout作为打印过程的一部分。您的问题是传入一个TObject,因为Tprint和TImage没有共同的祖先。对象没有画布,并且编译器不知道您实际传入的内容,因此这不起作用。但是它们有一个共同的画布,所以传递,连同执行布局所需的数据,按Petesh的回答去做。FWIW,注释只是注释,它们并不意味着包含问题的解决方案。对此,有答案。
DoLayout(Image1.canvas, false);