Author: Jonas Bilinkevicius
How to print a file directly to a printer
Answer:
Solve 1:
1 uses
2 WinSpool;
3
4 procedure PrintFile(const sFileName: string);
5 const
6 BufSize = 16384;
7 type
8 TDoc_Info_1 = record
9 pDocName: pChar;
10 pOutputFile: pChar;
11 pDataType: pChar;
12 end;
13 var
14 Count, BytesWritten: integer;
15 hPrinter: THandle;
16 Device: array[0..255] of char;
17 Driver: array[0..255] of char;
18 Port: array[0..255] of char;
19 hDeviceMode: THandle;
20 DocInfo: TDoc_Info_1;
21 f: file;
22 Buffer: Pointer;
23 begin
24 Printer.PrinterIndex := -1;
25 Printer.GetPrinter(Device, Driver, Port, hDeviceMode);
26 if not WinSpool.OpenPrinter(@Device, hPrinter, nil) then
27 exit;
28 DocInfo.pDocName := 'MyDocument';
29 DocInfo.pOutputFile := nil;
30 DocInfo.pDatatype := 'RAW';
31 if StartDocPrinter(hPrinter, 1, @DocInfo) = 0 then
32 begin
33 WinSpool.ClosePrinter(hPrinter);
34 exit;
35 end;
36 if not StartPagePrinter(hPrinter) then
37 begin
38 EndDocPrinter(hPrinter);
39 WinSpool.ClosePrinter(hPrinter);
40 exit;
41 end;
42 System.Assign(f, sFileName);
43 try
44 Reset(f, 1);
45 GetMem(Buffer, BufSize);
46 while not eof(f) do
47 begin
48 Blockread(f, Buffer^, BufSize, Count);
49 if Count > 0 then
50 begin
51 if not WritePrinter(hPrinter, Buffer, Count, BytesWritten) then
52 begin
53 EndPagePrinter(hPrinter);
54 EndDocPrinter(hPrinter);
55 WinSpool.ClosePrinter(hPrinter);
56 FreeMem(Buffer, BufSize);
57 exit;
58 end;
59 end;
60 end;
61 FreeMem(Buffer, BufSize);
62 EndDocPrinter(hPrinter);
63 WinSpool.ClosePrinter(hPrinter);
64 finally
65 System.Closefile(f);
66 end;
67 end;
68
69 procedure WriteRawStringToPrinter(PrinterName: string; S: string);
70 var
71 Handle: THandle;
72 N: DWORD;
73 DocInfo1: TDocInfo1;
74 begin
75 if not OpenPrinter(PChar(PrinterName), Handle, nil) then
76 begin
77 ShowMessage('error ' + IntToStr(GetLastError));
78 Exit;
79 end;
80 with DocInfo do
81 begin
82 pDocName := PChar('test doc');
83 pOutputFile := nil;
84 pDataType := 'RAW';
85 end;
86 StartDocPrinter(Handle, 1, ocInfo);
87 StartPagePrinter(Handle);
88 WritePrinter(Handle, PChar(S), Length(S), N);
89 EndPagePrinter(Handle);
90 EndDocPrinter(Handle);
91 ClosePrinter(Handle);
92 end;
The PrinterName parameter must be the name of the printer as it is installed. For
example, if the name of the printer is "HP LaserJet 5MP" then that is what you
should pass.
Solve 2:
The procedure below spools a RAW PCL file to the printer. Mainly you need to use
the WritePrinter API call along with OpenPrinter.
93 procedure PrintPCL;
94 var
95 Handle: THandle;
96 numwrite: DWORD;
97 Docinfo1: TDocInfo1;
98 PrintFile, InFile, SampForm: TMemoryStream;
99 buffer: array[0..4096] of char;
100 HPLetter, HPLegal, NC: array[0..15] of char;
101 temp: array[0..3] of char;
102 FF: char;
103 numread: longint;
104 x: integer;
105 FileName: string;
106 begin
107 if (OpenPrinter(PrinterName, Handle, nil)) then
108 begin
109 FF := Chr(12);
110 strcopy(HPLetter, chr(27));
111 strcat(HPLetter, '&l6d66p1h2A');
112 strcopy(HPLegal, chr(27));
113 strcat(HPLegal, '&l6d84p4h3A');
114 strcopy(NC, chr(27));
115 strcat(NC, '&l');
116 strcat(NC, StrPCopy(temp, InttoStr(NumCopies)));
117 strcat(NC, 'X');
118 try
119 PrintFile := TMemoryStream.Create;
120 for x := 0 to Printlist.Count - 1 do
121 begin
122 FileName := Copy(PrintList[x], 1, pos(',', printlist[x]) - 1);
123 InFile := TMemoryStream.Create;
124 InFile.LoadFromFile(FileName);
125 if (Integer(filename[Length(FileName) - 1]) = 49) then
126 PrintFile.write(HPLetter, Strlen(HPLetter))
127 else
128 PrintFile.write(HPLegal, Strlen(HPLegal));
129 PrintFile.write(NC, strlen(NC));
130 PrintFile.CopyFrom(InFile, 0);
131 InFile.Free;
132 if Sample then
133 begin
134 try
135 SampForm := TMemoryStream.Create;
136 SampForm.LoadFromFile(AppPath + 'SAMPLE.PRN');
137 PrintFile.Copyfrom(SampForm, 0);
138 finally
139 SampForm.Free;
140 end;
141 end;
142 PrintFile.write(FF, SizeOf(FF));
143 end;
144 DocInfo1.pDocName := PChar('PCLPrinter');
145 DocInfo1.pOutputFile := nil;
146 DocInfo1.pDataType := 'RAW';
147 PrintFile.Seek(0, 0);
148 StartDocPrinter(Handle, 1, @DocInfo1);
149 StartPagePrinter(Handle);
150 numread := 0;
151 numwrite := 0;
152 while (numread = numwrite) and (PrintFile.Position <> PrintFile.Size) do
153 begin
154 numread := PrintFile.read(buffer, sizeof(buffer));
155 WritePrinter(Handle, @buffer, numread, numwrite);
156 UpdateProgress(round((PrintFile.Position / PrintFile.Size) * 100));
157 end;
158 EndPagePrinter(Handle);
159 EndDocPrinter(Handle);
160 ClosePrinter(Handle);
161 finally
162 PrintFile.Free;
163 end;
164 end;
165 end;
|