首页  编辑  

同时打印到多台打印机

Tags: /超级猛料/Print.打印/   Date Created:

同时打印到多台打印机

Yes! The following example demonstrates how to print to more than

one printer at a given time. The exmple does not use TPrinter, since

TPrinter does not support printing to multiple printers at a given

time.

Example:

unit multiprn;

interface

{$IFDEF WIN32}

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls,

Forms, Dialogs, StdCtrls;

{$ELSE}

uses

SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics,

Controls, Forms, Dialogs, StdCtrls;

{$ENDIF}

type

TForm1 = class(TForm)

Button1: TButton;

ListBox1: TListBox;

ListBox2: TListBox;

ListBox3: TListBox;

procedure FormCreate(Sender: TObject);

procedure ListBox1Click(Sender: TObject);

procedure ListBox2Click(Sender: TObject);

procedure ListBox3Click(Sender: TObject);

procedure Button1Click(Sender: TObject);

private

{ Private declarations }

procedure GetTheListOfPrinters;

public

{ Public declarations }

end;

var

Form1: TForm1;

implementation

{$R *.DFM}

type

PdcArray = ^TdcArray;

TdcArray = array[0..0] of hdc;

procedure TForm1.GetTheListOfPrinters;

var

p : pChar;

p2 : pChar;

i : integer;

sDriver : string;

sPort : string;

begin

GetMem(p, 32767);

p2 := p;

{Get a list of the printer names from the win.ini file.}

{The list will be a buffer filled with strings, each seperated}

{by a null character, with the final string terminated with}

{a two null characters}

if GetProfileString('devices', nil, '',p, 32767) <> 0 then begin

{loop though the null terminated strings. We know we}

{have reached the end when p2 equals a null character}

while p2^ <> #0 do begin

ListBox1.Items.Add(StrPas(p2));

{increment the pointer past the null to get the next string}

p2 := @p2[lStrLen(p2) + 1];

end;

end;

GetMem(p2, 32767);

{Get the driver and port names for each printer found}

for i := 0 to (ListBox1.Items.Count - 1) do begin

StrPCopy(p2, ListBox1.Items[i]);

if GetProfileString('devices', p2, '',p, 32767) <> 0 then begin

sDriver := StrPas(p);

sPort := sDriver;

{The driver is the portion of the string before the comma}

Delete(sDriver, Pos(',', sDriver), Length(sDriver));

{The port is the portion of the string after the comma}

Delete(sPort, 1, Pos(',', sPort));

ListBox2.Items.Add(sDriver);

ListBox3.Items.Add(sPort);

end;

end;

FreeMem(p2, 32767);

FreeMem(p, 32767);

end;

procedure TForm1.FormCreate(Sender: TObject);

begin

GetTheListOfPrinters;

{Allow the user to select multiple printers}

ListBox1.MultiSelect := true;

ListBox2.MultiSelect := true;

ListBox3.MultiSelect := true;

end;

procedure TForm1.ListBox1Click(Sender: TObject);

var

i : integer;

begin

{Select same indexes in ListBoxs 2 and 3 as are selected in Listbox1}

for i := 0 to ListBox1.Items.Count - 1 do begin

ListBox2.Selected[i] := ListBox1.Selected[i];

ListBox3.Selected[i] := ListBox1.Selected[i]

end;

end;

procedure TForm1.ListBox2Click(Sender: TObject);

var

i : integer;

begin

{Select same indexes in ListBoxs 1 and 3 as are selected in Listbox2}

for i := 0 to ListBox2.Items.Count - 1 do begin

ListBox1.Selected[i] := ListBox2.Selected[i];

ListBox3.Selected[i] := ListBox2.Selected[i]

end;

end;

procedure TForm1.ListBox3Click(Sender: TObject);

var

i : integer;

begin

{Select same indexes in ListBoxs 1 and 2 as are selected in Listbox3}

for i := 0 to ListBox3.Items.Count - 1 do begin

ListBox1.Selected[i] := ListBox3.Selected[i];

ListBox2.Selected[i] := ListBox3.Selected[i]

end;

end;

procedure TForm1.Button1Click(Sender: TObject);

var

dcs : PdcArray; {a pointer to an array of hdc's}

dcsCount : integer; {count of valad hdc's}

dc : hdc; {test hdc}

i : integer; {couning variable}

pPrinter : pChar; {pointer to a printer name}

pDriver : pChar; {pointer to a printer driver filename}

pPort : pChar; {pointer to a port}

DocInfo: TDocInfo; {document information for the spooler}

{$IFDEF WIN32}

osv : TOSVERSIONINFO; {to test for Windows NT}

{$ENDIF}

begin

{If there are no printers selected then exit}

if ListBox1.SelCount = 0 then exit;

{If Range Checking is on then rember the setting and turn it off}

{This will allow use to access the dcs[i] array past element zero}

{without a compiler or runtime error}

{$IFOPT R+}

{$DEFINE CKRANGE}

{$R-}

{$ENDIF}

{Allocate the array of dcs}

GetMem(dcs, sizeof(hdc) * ListBox1.SelCount);

dcsCount := 0;

{Loop though the printers that are selected and create dc's for each}

for i := 0 to (ListBox1.Items.Count - 1) do begin

{Loop through the list box to find the selected printers}

if ListBox1.Selected[i] then begin

{Allocate and get the Printer, Driver and port from the listboxs}

{in the form of a null terminated string}

GetMem(pPrinter, Length(ListBox1.Items[i]) + 1);

GetMem(pDriver, Length(ListBox2.Items[i]) + 1);

GetMem(pPort, Length(ListBox3.Items[i]) + 1);

StrPCopy(pPrinter, ListBox1.Items[i]);

StrPCopy(pDriver, ListBox2.Items[i]);

StrPCopy(pPort, ListBox3.Items[i]);

{Attempt to create a dc - notes 1) Not all printers can}

{support multiple dc's at one time. 2) CreateDc requires}

{different parameters if Win32 andor Win32 under NT.}

{Sixteen bit win apps get standard handling}

{$IFDEF WIN32}

GetVersionEx(osv);

if osv.dwPlatformId = VER_PLATFORM_WIN32_NT then

dc := CreateDc(pDriver, pPrinter, nil, nil) else

dc := CreateDc(nil, pPrinter, nil, nil);

{$ELSE}

dc := CreateDc(pDriver, pPrinter, pPort, nil);

{$ENDIF}

FreeMem(pPrinter, Length(ListBox1.Items[i]));

FreeMem(pDriver, Length(ListBox2.Items[i]));

FreeMem(pPort, Length(ListBox3.Items[i]));

{If the dc is valid, then lets save it to our array}

{and increment our count}

if dc <> 0 then begin

dcs^[dcsCount] := dc;

inc(dcsCOunt);

end;

end;

end;

{If we ended up with a valid array of dc's then let's print}

if dcsCount > 0 then begin

{Fill Out the DocInfo structure for the spooler}

{and start a document for each printer}

GetMem(DocInfo.lpszDocName, 32);

for i := 0 to (dcsCount - 1) do begin

FillChar(DocInfo, sizeof(DocInfo), #0);

DocInfo.cbSize := SizeOf(DocInfo);

StrPCopy(DocInfo.lpszDocName, 'Test Doc' + IntToStr(i));

StartDoc(dcs^[i], DocInfo);

end;

FreeMem(DocInfo.lpszDocName, 32);

{Start a page for each printer}

for i := 0 to (dcsCount - 1) do

StartPage(dcs^[i]);

{Print something}

for i := 0 to (dcsCount - 1) do

TextOut(dcs^[i], 200, 200, 'Test', 4);

{End a page for each printer}

for i := 0 to (dcsCount - 1) do

EndPage(dcs^[i]);

{End the document for each printer}

for i := 0 to (dcsCount - 1) do

EndDoc(dcs^[i]);

{Delete the dc for each printer}

for i := 0 to (dcsCount - 1) do

DeleteDc(dcs^[i]);

end; {dcsCount}

{Free our array of printers}

FreeMem(dcs, sizeof(hdc) * ListBox1.SelCount);

{If range checking was on when we started then turn it back on}

{$IFDEF CKRANGE}

{$UNDEF CKRANGE}

{$R+}

{$ENDIF}

end;

end.