Author: Embarcadero USA
Technical Information Database TI1497D.txt - Direct Commands to Printer - Passthrough/Escape Category :Printing Platform :All-32Bit Product :All32Bit, Description: Although Delphi's TPrinter unit makes it easy to interface to a given printer, there are times when you may need to drop down to the printers level and send device specific escape sequences. Under 16-bit versions of Windows, this was as easy as opening the printer port, but under Windows NT, directly accessing the hardware is is illegal. One solution is to use the Windows "PASSTHROUGH" escape to send an escape sequence directly to the printer. In order to use the "PASSTHROUGH" escape, it must be supported by the printer driver. Be forwarned that not all printer drivers will support this feature. It's worth noting that the "PASSTHROUGH" escape is documented as obsolete for thirty-two bit applications. It should be a number of years before this escape goes by the way, since it is used in many commercial applications. The example code presented is not targeted to any specific printer model. You will need to know the correct escape sequences to send to the printer you are interfacing to. Note that you must still call the BeginDoc and EndDoc methods of TPrinter. During the BeginDoc call, the printer driver initializes the printer as necessary, and during the EndDoc call, the printer driver will uninitialize the printer and eject the page. When you do make your escape call, the printer may be set for the current windows mapping mode if the printer supports scaling internaly. Technically, you should not do anything that would cause the printer memory to be reset, or eject a page with an escape sequence. In other words, try to leave the printer in the same state it was in when you made your escape. This is more important on intellegent printers (Postscript printers), and not important at all on a standard TTY line printer, where you can do just about anything you like, including ejecting pages. Code Example: You will need to declare a structure to hold the buffer you are sending. The structure of the buffer is defined as a word containing the length of the buffer, followed by the buffer containing the data. Before making the escape call to pass the data, we will use the escape "QUERYESCSUPPORT" to determine if the "PASSTHROUGH" escape is supported by the print driver. Finally, be aware that your data will be inserted directly into the printers data stream. On some printer models (Postscript), you may need to add a space to the start and end of your data to separate your data from the printer drivers data. (Postscript is a Registered Trademark of Adobe Systems Incorporated) unit Esc1; interface uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation { add the printers unit } uses Printers; {$R *.DFM} { declare the "PASSTHROUGH" structure } type TPrnBuffRec = record BuffLength : word; Buffer : array [0..255] of char; end; procedure TForm1.Button1Click(Sender: TObject); var Buff : TPrnBuffRec; TestInt : integer; s : string; begin { Test to see if the "PASSTHROUGH" escape is supported } TestInt := PASSTHROUGH; if Escape(Printer.Handle, QUERYESCSUPPORT, sizeof(TestInt), @TestInt, nil) > 0 then begin { Start the printout } Printer.BeginDoc; { Make a string to passthrough } s := ' A Test String '; { Copy the string to the buffer } StrPCopy(Buff.Buffer, s); { Set the buffer length } Buff.BuffLength := StrLen(Buff.Buffer); { Make the escape} Escape(Printer.Canvas.Handle, PASSTHROUGH, 0, @Buff, nil); { End the printout } Printer.EndDoc; end; end; end. Reference: 4/22/99 12:48:27 PM
Article originally contributed by