2017-05-17 63 views
1

任何人都可以解释这应该如何工作(在Windows10上运行的Delphi XE2)?德尔福TPrinter和错误217

简约的应用程序 - 包含两个按钮的形式 - 用下面的代码:

procedure TForm2.Button1Click(Sender: TObject); 
begin 
    Printer.BeginDoc; 
    Printer.Canvas.TextOut(10,10,'Hello World'); 
    Printer.EndDoc; 
end; 

procedure TForm2.Button2Click(Sender: TObject); 
var 
    MyPrinter : TPrinter; 
begin 
    MyPrinter := Printer; 
    MyPrinter.BeginDoc; 
    MyPrinter.Canvas.TextOut(10,10,'Hello World'); 
    MyPrinter.EndDoc; 
    MyPrinter.Free; 
end; 

如果我单击Button1,该程序在我的默认打印机打印的“Hello World”,通常当我关闭关闭它(用关闭按钮)。相反,如果我单击Button2,程序将打印一个相同的页面,但现在当我用关闭按钮关闭时,我会收到错误217消息。

我无法在Delphi文档中找到有关如何使用打印机功能和TPrinter变量的说明。我很高兴使用Button1技术的派生物进行打印 - 如果确认这是“防弹”方式,但想了解为什么Button2方法不起作用。我是否应该假设它不是我的负责释放任何我实例化的TPrinter对象,还是有更清晰的解释?

回答

5

当您运行此代码:

MyPrinter := Printer; 
    MyPrinter.BeginDoc; 
    MyPrinter.Canvas.TextOut(10,10,'Hello World'); 
    MyPrinter.EndDoc; 
    MyPrinter.Free; 

Printer是在函数退出删除。所以当应用程序终止时,它会尝试再次删除它,并且出现错误。更重要的是,如果你尝试第二次运行这个代码,它也会增加。 MyPrinter只是指向由Printer函数返回的全局对象TPrinter的指针。你不应该删除你没有创建的东西。

Printer功能的文档:

返回TPrinter的全局实例来管理与 打印机的交互。

打印机第一次创建一个全局TPrinter对象的实例,它被调用时第一次调用 。使用打印机功能使用TPrinter 对象进行打印。

注意:当 应用程序关闭时,全局TPrinter对象会自动释放。打电话给SetPrinter后, 返回的打印机不会自动释放。致电者的责任是释放返回值,或者使用 对SetPrinter的另一个呼叫替换它,并释放 第二个SetPrinter调用返回的替代打印机。

+0

因此,如果我理解正确,Printer函数只是返回一个预先创建的TPrinter对象,该对象设置为与默认打印机相匹配。可以这么说,它不应该被认为是一个TPrinter工厂。那么我是否正确,如果我只是使用打印机,就好像它是一个TPrinter类型的全局变量(而不是Delphi帮助中描述的函数)? – Penguino

+2

是的。打印机函数返回全局“TPrinter”对象的实例,该实例在第一次使用时创建。只要你没有使用'SetPrinter'函数,它就会在应用程序退出时自动释放。 – Ari0nhh

+2

@Penguino'Printer()'函数返回一个RTL为你拥有的'TPrinter'单例对象。根据需要使用'TPrinter'。而且,您也不仅限于默认的打印机。您可以将TPrinter.PrinterIndex属性设置为与其他打印机一起使用。 –