Delphi 列印對象 Tprinter 介紹
Delphi 簡化了列印時使用者所必須了解的大部分内容。使用者可以很輕松地寫出簡單的列印程式來輸出文本和位圖化了的圖像。
對于更為複雜的列印,僅需了解幾個要領和技術,使用者就可以實作任何類型的自定義列印。
Delphi 的TPrinter對象封裝了 Windows 的列印引擎,為程式員做了大量原本需要親自做的工作。
本章告訴使用者怎樣用TPrinter來完成各種列印作業。使用者可以看到一個簡單的例子,
從中可以了解到建立進階列印程式的技術,而這些技術正是使用者成為列印高手的起點。
1 TPrinter 對象
Delphi 中的 TPrinter類可以友善地實作通常的列印任務。通過Printer 全局函數可以傳回TPrinter類的一個對象,該對象在Printers單元中定義。
可以把Printer 全局函數看作一個全局變量,并利用這個全局變量來與列印機進行列印操作。
利用 Printer 來實作列印的一般過程如下:
(1)調用BeginDoc 過程向列印機發送一個列印作業(此時還沒有在列印機上開始列印)。
(2)通過一個 Text 變量或調用 Canvas 對象方法建立列印輸出。
(3)調用 EndDoc過程結束目前的列印作業,該列印作業開始在列印機上列印。
(4)如果出現問題,調用 Abort過程取消目前列印的作業。
1.1 TPrinter對象的常用屬性
屬性 作用
Aborted 判斷是否中止列印作業
Canvas 畫布屬性
Capabilities 目前列印機驅動裝置的設定資訊
Copies 列印的份數
Fonts 字型屬性
Handle 列印機句柄
Orientation 紙張的方向:橫向或縱向
PageHeight 紙張的高度
PageNumber 目前列印的頁數
PageWidth 紙張的寬度
Printers 系統中安裝的所有列印機
Printing 辨別是否正在進行一個列印作業
PrinterIndex 列印機屬性中目前列印機的索引值
1.2 TPrinter對象的幾個常用方法 :
方法 作用
Abort 中止正在列印的列印作業
BeginDoc 向列印機發送一個列印作業
EndDoc 結束目前的列印作業并關閉文本檔案變量
GetPrinter 獲得目前列印機序号
NewPage 開始新的一頁并增加 PageNumber屬性
Refresh 更新字型和列印機的屬性
通常,在列印前要進行列印預覽。在列印預覽的時候,往往要将列印的結果在螢幕上顯示出來。
這時,就要注意螢幕的分辨率和列印機的分辨率的差别了。讀取螢幕資訊可以通過全局變量 Screen 來實作,Screen 為TScreen類的一個執行個體,在建立工程的時候就自動建立了,并在程式開始運作時讀取了螢幕的一些設定資訊。
值得注意的一點是 TPrinter.Canvas。TPrinter.Canvas 對于窗體來說像一個畫布,在它上面可以顯示文本和圖形。
不同的是, TPrinter.Canvas 表示的是列印輸出的畫布,而非顯示用的畫布。大多數用來顯示文本、圖像和畫圖的程式可以用同一種方式來列印輸出。
但是,在列印時必須考慮到其中的不同之處:
¾ 在螢幕上繪畫是動态的,可以擦去在螢幕上輸出的内容。而向列印機中輸出則不那麼靈活,凡是向 TPrinter.Canvas 輸出的内容将被列印機列印出來。
¾ 在螢幕上顯示文本和圖是很快的,而向列印機輸出,即使是高性能的雷射列印機,也是較慢的。是以,必須允許使用者能夠終止列印作業或者采用其他辦法來放棄列印作業。
¾ 由于使用者運作的是 Windows,可以假定支援圖形顯示。但是,不能對他們的列印機做同樣的假定。一些列印機也許具有非常低的分辨率,或者根本不支援圖形列印。在列印程式中必須考慮到這些問題。
¾ 使用者從來沒有看到過諸如“顯示超出螢幕空間”、“請插入更多的螢幕空間”此類的資訊,但是肯定見過“列印紙不夠”的資訊。當這些錯誤發生時, Windows NT/2000 和Windows 95/98能夠處理這些錯誤,但程式員應該向使用者提供在發生這些問題時取消列印的辦法。
¾ 對于螢幕上的文本和圖形來說,硬拷貝操作看起來是不同的。列印機和顯示器具有非常不同的分辨率。300×300 的位圖在 640×480 的顯示器中顯得很漂亮。但是在300dpi 的雷射列印機上,它僅僅是一個1×1 inch 的小方塊。程式員必須負責調整列印程式,使使用者不必用放大鏡就可以看清他們的列印輸出。
2 列印操作常用函數 (Windows API)
函數 說明
AbortPrinter 在假脫機的情況下删除列印緩沖檔案
AbortProc 當列印作業取消時調用的一個應用程式定義的回調函數
AddForm 為指定的列印機從有效窗體清單中新增一個窗體
AddJob 擷取一個檔案名用來儲存列印緩沖工作
AddMonitor 新安裝一個列印機管理器
AddPort 新增一個列印機端口
AddPrinter 在指定的伺服器上新安裝一個列印機
AddPrinterConnection 在目前使用者和指定的列印機之間建立一個聯系
AddPrinterDriver 為本地或網絡列印機安裝列印機驅動程式
AddPrintProcessor 在指定的列印伺服器上安裝一個列印處理器
AddPrintProvidor 新增一個列印機支援器
AdvancedDocumentProperties 設定列印機的進階屬性
ClosePrinter 關閉指定的列印機
ConfigurePort 通過端口設定對話框來設定指定伺服器上的端口
ConnectToPrinterDlg 顯示一個浏覽對話并與網絡列印機連接配接
DeleteForm 從窗體清單中删除一個窗體名稱
DeleteMonitor 删除列印機螢幕
DeletePort 删除列印機端口
DeletePrinter 删除指定的列印機對象
DeletePrinterConnection 删除一個列印機連接配接
DeletePrinterData 删除列印機的配置資料
DeletePrinterDriver 删除指定列印機的驅動程式
DeletePrintProcessor 删除一個列印機的處理器
DeletePrintProvidor 删除一個列印機的支援器
DocumentProperties 取得或設定列印機的初始化資訊或顯示列印機配置對話框
EndDocPrinter 結束指定列印機上的列印作業
EndPagePrinter 在指定列印機上結束一頁并開始新的一頁
EnumForms 列舉列印機支援的窗體資訊
EnumJobs 擷取列印機的作業資訊
EnumMonitors 擷取指定伺服器上的列印螢幕資訊
EnumPorts 列舉指定伺服器上支援的端口資訊
GetPrinter 擷取指定列印機的資訊
GetPrinterData 擷取指定列印機的配置資訊
GetPrinterDriver 擷取指定列印機驅動程式的資料資訊
GetPrinterDriverDirectory 擷取指定列印機驅動程式所在的目錄
GetPrintProcessorDirectory 擷取指定伺服器上列印處理器所在的目錄
OpenPrinter 擷取指定列印機或伺服器的句柄
PrinterMessageBox 顯示列印異常資訊對話框
PrinterProperties 顯示指定列印機的屬性對話框
ReadPrinter 從指定的列印機讀取資料
ResetPrinter 設定列印機的資料類型和裝置模式等
ScheduleJob 擷取指定列印作業的列印緩沖時間表
SetForm 設定指定列印機的窗體資訊
SetJob 暫停、繼續、取消和重新開始指定列印機上的列印作業
SetPort 設定列印機端口的狀态
SetPrinter 設定列印機的狀态資訊
SetPrinterData 設定列印機的配置資訊
StartDocPrinter 通知列印緩沖器一個列印作業将被送往列印
StartPagePrinter 通知列印緩沖器一個頁面将送往列印
WritePrinter 通知列印緩沖器資料将被寫到指定的列印機
3 列印操作 (實作列印輸出的方法 )
3.1 列印文本
在Delphi 中實作文本的列印功能需要做的隻是取得列印參數,打開列印機,然後發送文本的每一行内容。
在 Delphi 中提供了一個 Printers程式單元,它說明了一個 TPrint 對象,封裝了Windows 列印工作和輸出列印機之間的接口,并提供常用的屬性和方法,其中畫布Canvas 是一個非常有用的屬性,它代表了目前列印檔案的表面,是以圖形方式來工作的,整個的列印輸出工作僅僅是将使用者列印的内容輸出到TPrinter的屬性 Canvas 上,當全部的輸出工作完成之後,列印對象(TPrinter)把 Canvas 的屬性值送到列印機上。
一個例子:在 Form中加入 Memo,PrintDialog,PrintSetupDialog 和兩個 Button 控件,兩個Button 的Caption分别為“列印設定”和“列印”。然後編寫Button 的事件驅動程式如下:
[delphi]
implement
uses printers;
{$R *.DFM}
procedure TForm1.BitBtn1Click(Sender:TObject);
begin
PrinterSetupDialog1.Execute;//選擇輸出的列印機以及其他列印控制選項
end;
procedure TForm1.BitBtn2Click(Sender:TObject);
var
lines:integer;
prntext:system.text;
// 将prntext 聲明為一個在system 程式單元中定義的文本檔案
begin
if PrintDialog1.Execute then assignprn(prntext);// 将prnsetup配置設定給列印機
rewrite(prntext);// 調用rewrite 函數,為輸出打開已配置設定的檔案
printer.Canvas.font:=memo1.font; // 把目前Memo1的字型指定給列印對象的Canvas 的字型屬性
for lines:=0 to memo1.lines.count-1 do
writeln(prntext,memo1.lines[lines]); // 把Memo的内容寫到列印機對象
System.close(prntext);
end;
procedure Tform1.FormCreate(Sender:TObject);
begin
memo1.lines.loadfromfile(‘C:\dos\os2.txt’); // 在Form建立時讀入檔案C:\dos\os2.txt
end;
3.2 列印位圖
列印位圖也很簡單。下面列出了相應代碼。
procedure TBMPForm.mmiPrintClick(Sender:TObject)
begin
inherited;
with ImgMain.Picture.BitMap do
begin
Printer.BeginDoc;
Printer.Cavas.StretchDraw(Cavas.ClipRect,ImgMain.Picture.Bitmap);
Printer.EndCode;
end;
end;
調用 TCanvas.StretchDraw()來列印位圖僅需三行代碼。
在Delphi 中,位圖的預設格式是DIB 格式,而 DIB 格式正是列印機驅動程式所需要的,這就大大簡化了列印位圖的工作。
如果遇到一個非DIB 格式的位圖,可以把它複制給一個臨時的TBitmap 對象,然後把TBitmap.HandleType 特性設為 bmDIB ,以強制把位圖臨時轉化為 DIB 格式,這樣就可以列印出DIB 格式的位圖。 注意列印的關鍵之一是列印圖像時能夠以其與在螢幕上近似相同的尺寸列印。
例如,一個3×3inch的圖像在 640×480 的螢幕上要比在 300dpi 的列印機上需要較少的像素。是以,在調用 StretchDIBits()時,把位圖位伸以便與 TPrinter.Canvas 比對。
3.3 列印 TMemo元件中的内容
事實上,用 AssignPrn()來列印文本行相當簡單。AssignPrn() 可以為目前列印機配置設定一個文本檔案變量,它與 Rewrite() 和CloseFile()等過程一起使用。下面幾行代碼說明了用法:
var
f:TextFile;
begin
AssignPrn(f);
try
Rewrite(f);
Writeln(f, 'Print the output');
finally
CloseFile(f);
end;
end;
向列印輸出一行文字與向檔案中輸出一行文字一樣,可以使用下面的語句:
Writeln(f,'This is my line of text');
下面的一段程式示範了如何從 TMdiEditForm 列印窗體上的内容。使用者可以用同樣的技術來列印任何文本。
procedure TForm1.mmiPrintClick(Sender:TObject)
var
i:integer;
PText:TextFile;
begin
inherited;
if PrintDialog.Execute then
begin
AssignPrn(PText);
Rewrite(PText);
try
Printer.Cavas.Font:=memMainMemo.Font;
for i:=0 to memMainMemo.Lines.Count-1 do
writeln(PText,memMainMemo.Line[i]);
finally
CloseFile(PText);
end;
end;
end;
注意列印機的字型被指定為TMemo元件的字型,導緻列印輸出的字型與memMainMemo的字型一樣。隻有指定列印機所支援的字型,列印機才能以指定的字型列印。否則列印機以與指定字型特征最接近的字型列印。
3.4 列印 RTF 格式的文本
RTF 格式文本的列印同樣簡單,隻要調用一個方法就行了。相應代碼如下所示:
procedure TMdiRtfForm.mmiPrintClick(Sender:TObject);
begin
inherited;
reMain.Print(Caption);
end;
4 列印技巧
4.1 擷取顯示目前列印機的分辨率
Windows 下的列印分辨率對列印程式有至關重要的作用,利用函數 GetDeviceCaps() 可以得到列印分辨率。
例如:
var
iHorizontal,iVertical:integer;
iHorizontal:=GetDeviceCap s(printer.handle,LOGPIXELSX);
iVertical:= GetDeviceCaps(printer.handle,LOGPIXELSY);
begin
ShowMessage( '水準分辨率:'+inttostr(iHorizontal)+chr(12)+ ' 垂直分辨率:'+Inttostr(iVertical));
end;
4.2 盡量不要使用 AssignPrn
盡管 AssignPrn簡化了文本列印操作,是輸出到列印機像輸出到檔案一樣簡單。但簡單帶來的是一系列不友善:使用者無法知道目前列印的行數,無法準确控制行距,也無法靈活改變字型字型,是以最好使用 Canvas 屬性。
4.3 用列印機的點數做度量機關
如果要讓列印程式在任何列印機上都能正常列印,就必須改變使用者的度量機關。如果采用固定度量,不同分辨率列印效果是不同的。舉例來說:printer.Canvas.rectangle(0,0,360,720)
在佳能 4200SP上能打出一個 1 inch 寬,2 inch 高的矩形,但在 600×600de HP6L上隻能打出0.6 inch 寬,1.2inch 高的矩形。使用列印機的點數作為度量機關是一個明智的選擇。具
體做法如下:
var
PointX:integer;
PointY:integer;
Begin
PointX := GetDeviceCap s(printer.Handle,LOGPIXELSX);
PointY := GetDeviceCap s(printer.Handle,LOGPIXELSY);
Printer.Canvas.rectangle(0,0,PointX*1,PointY*2);
End;
這樣,無論使用什麼列印機,都能得到一個1 inch 寬,2 inch 高的矩形。
4.4 将列印結果直接送到列印機
Delphi 提供了兩種列印方式:
一種将結果輸出到Form,再調試 Form的Print 方法将結果輸送給列印機。如果使用者采用第一種方式,則無論使用者怎樣調整Form的PrintScal 屬性,列印出來的東西也不能讓使用者滿意,是以建議使用第二種方式。