Printer files are definded using the PFILE instruction. This is anologous to the FILE, IFILE and AFILE definitions for disk files. You'll open and close the printer file, much like a disk file.PRTOPEN STATEMENT
Here is how we usually define a printer object (or file). Note that we also set up a couple of our own work areas.PRINTER_FILE PFILE ;you MUST define the printer PRINTER_NAME DIM 31 ;we use this for optional name SPOOL_ERROR DIM 1 ;this is our own error flag
Before using the printer it must be opened with the PRTOPEN statement.PRTOPEN: CANCEL button
There are a number of parameters that you can use with the PRTOPEN. The minimum statement is:PRTOPEN {pfile name}, {windows printer name}, {job name}The windows printer name and the job name can both be null strings, but you must have SOMETHING in those positions. It can be a literal or a string variable name. For example you could code:PRINTER_FILE PFILE PRTOPEN PRINTER_FILE, "", ""You could also code it like this:PRTOPEN PRINTER_FILE, "HP Laserjet 4", ""Or code it like this:PRTOPEN PRINTER_FILE, PRINTER_NAME, ""The printer name is very significant. If the name is a null string, or a null literal, then the windows printer selection dialog box will open and the user can select the printer.
The printer name string can also contain the name of an active and valid printer on the computer. If you do this, you have to be sure that you use a valid name of a printer that's actually installed on the computer where the program is running.
The generally accepted method is to leave the printer string NULL. This let's the user select the printer at run time.
In summary, the data in the windows printer name does these things:
- "-" Tells the system to use the currently selected printer. (see PAGESETUP below).
- "@" or "@printer name" or Does a "print preview" after you do a PRTCLOSE.
- "@?" or "@?printer name" or You can tell the system to do a print preview, AFTER the print selection dialog, upon the PRTCLOSE
- Of course you can also explicitly name the printer.
The standard Windows printer selection dialog includes a cancel button. If the user clicks that it will cause a runtime error unless you trap for it. The Sunbelt manual says you get an S22 but experience has shown that you actually get an S10. (At one time we had a note that you get an S18... can't prove that now.)PAGESETUP STATEMENT
The trap to use for this is "SPOOL". Here's how we handled it:MOVE NO,SPOOL_ERROR ;this will be our flag TRAP PRINTER_ERROR IF SPOOL ;watch for an error PRTOPEN PRINTER_FILE, "", "" ;let user specify printer TRAPCLR SPOOL ;clear the trap if not taken . IF (SPOOL_ERROR != NO) ;see if there was an error ..... could do something ... RETURN ;in our case we return ENDIF ..... more program.... . printer_error ;routine for the TRAP MOVE YES,SPOOL_ERROR ;just note error RETURN ;S$ERROR$ would have full data
The PAGESETUP statement provides another method for controlling the PRTOPENPRTCLOSE STATEMENT
Normally the PRTOPEN with a null printer name will cause the Windows printer dialog to open, thus allowing the user to select the printer.
When you already KNOW the printer name, you can just provide it in the PRTOPEN and skip the dialog.
Sometimes the second open of the printer causes strange problems. For example, we've seen examples where the second PRTOPEN leaves Windows not knowing what type of printer is selected. After that, things like setting landscape orientation on a laser just won't work.
PAGESETUP selects a printer, and remembers what that printer is, without actually doing an open to the printer. Later you can do as many PRTOPENs as you want using the printer defined by the PAGESETUP.
We don't know where the PAGESETUP information is stored. One way to think about is that PAGESETUP puts the printer information onto the clipboard and PRTOPEN uses whatever is stored there.
PAGESETUP has no parameters. It's a standalone statement.
PAGESETUP opens the printer selection dialog on the options side, not on the printer selection side where you normally land. The user can set options, but your program can override them with "*" parameters in the PRTPAGE instruction.
Here's an example:Suppose you want to provide a button for printing envelopes when the user selects a customer from a DATALIST.
On the button click you'd retreive the customer information then CALL a routine that does something like this:envelope_routine IF (FIRST_TIME = YES) MOVE NO,FIRST_TIME PAGESETUP ENDIF PRTOPEN PRINTER_FILE, "-", "" ... do the envelope print.... PRTCLOSE PRINTER_FILE RETURN
The first time the routine is called, it does the PAGESETUP which establishes the printer. This only happens once.
Each time the routine is called it will open the printer file using the "-" printer name parameter which say to use the currently defined printer. The envelope is printed and the printer is closed which causes it to print immediately.
The user selects the printer only once then just gets an envelope each time the button is clicked.
Once a printer is opened, all output is sent to the Windows print handler. Nothing prints until you close the print file with PRTCLOSE. The format is simply:PRTPAGE (print) STATEMENTSPRTCLOSE PRINTER_FILE ;close the printerYou can have multiple printer files open at any time. They can be opened and closed independently.
In the envelope example above, you could open a summary report printer file when the job starts and you'd print a single line to that report each time an envelope is printed.
The envelopes would print one at a time, with their printer file opening and closing each time.
At the end of the run, you'd close the summary report and it would produce a list of all the envelopes which had been printed.
The summary report job would be a good example of a place to use the "@" printer name option in the PRTOPEN. That option tells the printer select dialog to open after the CLOSE, not after the OPEN. It delays the printer selection to the END of the run.
PRTPAGE PRINTER_FILE;"This is data": *N,"Here's the next line": *FThat prints two lines and "formfeeds" to the next page. Note that, like a file I/O routine, the printer file is named at the beginning and is followed by a semi-colon.
PRTPAGE PRINTER_FILE;*P10:10,*BOLDON,"position 10, line 10": *BOLDOFF: *P01:01,"back to top of page": *P50:20,"farther down page"There are numerous other commands including line and box drawing, font control, line control and the like.
GETFILE {printer file}, PRTNAME=Printer_fullname, HDC=Printer_Handle, etc.
For most cases, you would use GETINFO for printers. It gives the most information. One drawback is that it does not provide the full printer name. GETINFO gives just the first 31 bytes of the printer name. Many printers have much longer names!
GETFILE is supposed to give the full printer name. This requires PL/B version 9.x and above. Before that you still got the 31 byte name
The GETINFO instruction can be used to retreive a lot of information about printers. There are several variations:GETINFO PRINTERS,{string} returns the DEFAULT printer name string. It doesn't matter what printer you have opened, this is the current DEFAULT printer name.
- GETINFO PRINTERS,{string} (gets default printer name)
- GETINFO PRINTERS,{datalist} (gets list of all printers)
- GETINFO TYPE={printer object}, {string} (gets open printer specs)
Note that the printer name which is returned may be more than you want, need or can use. For example you may get:
HP LaserJet 4,HPPCL5MS,\\Gateway\1
If that occurrs, you want only the bytes up to the first comma:
HP LaserJet 4
See special note in printer management section dealing with network printers and printer name lengths.
GETINFO PRINTERS,{datalist} populates the {datalist} with a list of all the printers defined on the computer. This allows you to do your own printer selection dialog without actually opening a printer file.
Unlike the default printer format shown above, this format gives you only the printer name. You can use that name directly.
GETINFO TYPE={printer object}, {string} returns a predefined string defining the currently opened printer and just about everything about it.
The layout of the returned string is defined in the on-line help. We cut that table and pasted it into a file which we INCLUDE in our programs when we need the information. You can cut the table from this page if you want it. (Our include file is Z:PRT-INFO.PLS.)
WHERE in the on-line PL/B manual from Sunbelt? Go to the GETINFO index entry and click it. Then look for "PFILE Information" in the topic list. Click on it. You get:................................................... . This was extracted from the Sunbelt ON-LINE MANUAL 12/6/2000. . That was PLBWIN version 8.4 . . The GETINFO instruction retrieves the following information . when the TYPE keyword specifies a PFILE: . . For example: . GETINFO TYPE={printer file}, PRINTER_INFO_DATA . . 1.0 millimeter = 0.039370078740157 inches . 25.4 millimeters = 1 inch . . Column Size Value . 1 8 Current Printer Driver version . 9 8 Page width in pixels . 17 8 Page height in pixels . 25 8 Page width in millimeters . 33 8 Page height in millimeters . 41 8 Number of color bits per pixel . 49 8 Number of device specific fonts . 57 1 Can Print Pictures ? (Y or N) . 58 4 User specified copies specified by user (future) . 62 1 Print All Pages (Y or N) . 63 1 Print Selection Only (Y or N) . 64 8 Print dialog start page value . . 72 8 Print dialog end page value . 80 1 Print Alignment Right (Y or N) . 81 1 Print Alignment Decimal (Y or ) . 82 1 Fill On Enabled (Y or N) . 83 1 Pict Rectangle Enabled (Y or N) . 84 1 Overlay Enabled (Y or N) . 85 4 Number of characters in Printer Name . 89 31 Printer name . 120 10 Print orientation as follows . 1 = Portrait . 2 = Landscape . . 130 10 Paper size as follows: . 1 = Letter, 8 1/2- by 11-inch . 2 = Letter Small, 8 1/2- by 11-inch . 3 = Tabloid, 11- by 17-inch . 4 = Ledger, 17- by 11-inch . 5 = Legal, 8 1/2- by 14-inch . 6 = Statement, 5 1/2- by 8 1/2-inch . 7 = Executive, 7 1/4- by 10 1/2-inch . 8 = A3 sheet, 297- by 420-mm . 9 = A4 Sheet, 210- by 297-mm . 10 = A4 small sheet, 210- by 297-mm . 11 = A5 sheet, 148- by 210-mm . 12 = B4 sheet, 250- by 354-mm . 13 = B5 sheet, 182- by 257-mm . 14 = Folio, 8 1/2- by 13-inch . 15 = Quarto, 215- by 275-mm . 16 = 10- by 14-inch . 17 = 11- by 17-inch . 18 = Note, 8 1/2- by 11-inch . 19 = #9 Envelope, 3 7/8- by 8 7/8-inch . 20 = #10 Envelope, 4 1/8- by 9 1/2-inch . 21 = #11 Envelope, 4 1/2- by 10 3/8-inch . 22 = #12 Envelope, 4 3/4- by 11-inch . 23 = #14 Envelope, 5- by 11 1/2-inch . 24 = C Sheet, 17- by 22-inch . 25 = D Sheet, 22- by 34-inch . 26 = E Sheet, 34- by 44-inch . 27 = DL Envelope, 110- by 220-mm . 28 = C5 Envelope, 162- by 229-mm . 29 = C3 Envelope, 324- by 458-mm . 30 = C4 Envelope, 229- by 324-mm . 31 = C6 Envelope, 114- by 162-mm . 32 = C65 Envelope, 114- by 229-mm . 33 = B4 Envelope, 250- by 353-mm . 34 = B5 Envelope, 176- by 250-mm . 35 = B6 Envelope, 176- by 125-mm . 36 = Italy Envelope, 110- by 230-mm . 37 = Monarch Envelope, 3 7/8- by 7 1/2-inch . 38 = 6 3/4 Envelope, 3 5/8- by 6 1/2-inch . 39 = US Standard Fanfold, 14 7/8- by 11-inch . 40 = German Standard Fanfold, 8 1/2- by 12-inch . 41 = German Legal Fanfold, 8 1/2 by 13-inch . 256= Custom user defined . . 140 10 Custom paper length in 10ths of mm . 150 10 Custom paper width in 10ths of mm . 160 10 Printed output scaling factor . 170 10 Num of copies printed if multi-page copies supported . 180 10 Paper feed source as follows: . 1 = Upper tray or only one . 2 = Lower tray . 3 = Middle tray . 4 = Manual . 5 = Envelope . 6 = Envelope Manual . 7 = Auto . 8 = Tractor feed . 9 = Small FMT . 10 = Large FMT . 11 = Large Capacity . 14 = Cassette . 15 = Form source . . 190 10 Print quality as follows: . -1 = Draft . -2 = Low . -3 = Medium . -4 = High . nnn = Dots per inch when positive . . 200 10 Color usage as follows: . 1 = Monochrome . 2 = Color . . 210 10 Type of double sided print as follows: . 1 = Simplex . 2 = Vertical . 3 = Horizontal . . 220 10 Copies being collated as follows . 0 = No . 1 = Yes . 230 8 Current vertical print position . 238 8 Current horizontal print position . .................................. . INCH_PER_MM FORM "0.03937" ;conversion factor for MM to inches . 0.039370078740157 = full factor PID_PG_I_WIDE FORM 8.8 ;use for conversions PID_PG_I_HIGH FORM 8.8 ;use for conversions . PRINTER_INFO_DATA LIST PID_DRV_VER DIM 8 Current Printer Driver version . PID_PG_P_WIDE DIM 8 Page width in pixels PID_PG_P_HIGH DIM 8 Page height in pixels PID_PG_M_WIDE DIM 8 Page width in millimeters PID_PG_M_HIGH DIM 8 Page height in millimeters . PID_COLOR_BITS DIM 8 Number of color bits per pixel PID_NUM_OF_FONTS DIM 8 Number of device specific fonts PID_PIC_OK DIM 1 Can Print Pictures ? (Y or N) PID_USER_COPIES DIM 4 Copies specified by user (future) PID_PRINT_ALL DIM 1 Print All Pages (Y or N) PID_PRINT_SEL DIM 1 Print Selection Only (Y or N) . PID_START_PAGE DIM 8 Print dialog start page value PID_END_PAGE DIM 8 Print dialog end page value PID_ALIGN_RIGHT DIM 1 Print Alignment Right (Y or N) PID_ALIGN_DEC DIM 1 Print Alignment Decimal (Y or ) PID_FILL_ON DIM 1 Fill On Enabled (Y or N) PID_PICT_RECT DIM 1 Pict Rectangle Enabled (Y or N) PID_OVERLAY DIM 1 Overlay Enabled (Y or N) . PID_NAME_SIZE DIM 4 Number of characters in Printer Name PID_NAME DIM 31 Printer name . PID_ORIENTATION DIM 10 Print orientation CODE PID_PAPER_SIZE DIM 10 Paper size CODE . PID_PGLEN_MM DIM 10 Custom paper length in 10ths of mm PID_PGWIDTH_MM DIM 10 Custom paper width in 10ths of mm PID_SCALING DIM 10 Printed output scaling factor PID_COPIES DIM 10 Copies printed if multi-page copies supported PID_FEED_SOURCE DIM 10 Paper feed source CODE PID_QUALITY DIM 10 Print quality CODE PID_COLOR_USAGE DIM 10 Color usage CODE . PID_DOUBLE_SIDE DIM 10 Type of double sided print CODE PID_COPYCOLLATE DIM 10 Copies being collated CODE PID_V_POS DIM 8 Current vertical print position PID_H_POS DIM 8 Current horizontal print position LISTEND
There are a number of things to keep in mind with printers. I'll note some here as they come up.
SCAN " on ", PRINTER_NAME IF EQUAL SPLICE " ON ", PRINTER_NAME, 4 RESET PRINTER_NAME ENDIF PRTOPEN PRINTER_FILE,PRINTER_NAME....
This instruction allows you to get all the information that you need to justify print lines. It returns the width in pixels for any line when given the FONT and the PRINTER.
MMCC has a generalized loadmod called MMCCJUST which will do all of this for you. Give it the string, font and printer and it will return a table of lines to fit the width that you define. (In the UTIL-PLB folder.)
GETINFO TYPE={font object}, {string}, PRINTER={printer object} returns a predefined string defining information about the string as it would apply if tinted on the named printer object.
The fields for this info string are defined in the COMMONWK.PLS include unit..... . You can get this with: 4/04/2001 . MOVE INPUT_DATA, STRING . GETINFO TYPE={font},STRING,PRINTER_FILE . UNPACK STRING, FONT_INFO . . The GETINFO will read the contents of STRING based on . the FONT OBJECT and return, in STRING, the following . string of information: . FONT_INFO LIST FI_ASCENT FORM 4 Pixels above baseline for a character FI_DESCENT FORM 4 Pixels below baseline for a character FI_HEIGHT FORM 4 Height of a character (ascent + descent) FI_FULLHEIGHT FORM 4 Full height character (height + external L/S) FI_AVG_CHAR FORM 4 Average character width - generally letter "X" FI_MAX_CHAR FORM 4 Maximum character width - wides in font FI_FONT_S_W FORM 4 Font string width truncated to 4 bytes FI_FIRST_CHAR DIM 1 First character in the font FI_LAST_CHAR DIM 1 Last character in the font FI_PIXELS FORM 8 Last character in the font LISTEND
ONE FORM "1" Just a constant "1" PAGENUM FORM 3 Page number MAXLINES FORM "55" Max lines we can get on a page LINECNT FORM " 1" Line we're at on the page LH FORM 5 Calculated HORIZONTAL position LV FORM 5 Calculated VERTICAL position LINE_HEIGHT FORM "10" Height in 1/100th inches . print_data CALC LV = LINECNT * LINE_HEIGHT CALC LH = 10 PRTPAGE PRINTER_FILE;*UNITS=*LOENGLISH: *PLH:LV,"Here is the data" CALL LINECHEK RETURN . ............................... . Central page overflow tester . Count the line just printed and see if room for more. . linechek ADD ONE,LINECNT IF (LINECNT < MAXLINES) RETURN ENDIF . pagehead ADD ONE,PAGENUM MOVE ONE,LINECNT . PRTPAGE PRINTER_FILE;*F: "HEADING STUFF": "Page:",PAGENUM ADD FIVE,LINECNT RETURN
Top Margin 15 Line size 12 Middle column 250 Footer position 800
PICT_DEF PICT PICT_NAME DIM 30 MOVE "MMCCLOGO.JPG",PICTURE_NAME CREATE PICTURE_THING=20:60:20:60,PICTURE_NAME PRTPAGE PRINTER_FILE;*P20:10,"HERE IS THE PICTURE": *PICT=21:30:10:20:PICT_DEF;
PRTPAGE PRINTER_FILE;*P20:10,"HERE IS THE PICTURE": *PICTRECT=*OFF: *PICT=21:30:10:20:PICT_DEF;
{window-name}.FormToPict GIVING {pict object}You must define the pict object in your program, but the method will take care of the CREATE for you. Once you have the picture, you print it just like any other picture with any of the controls, and sizing that you want.
FORM_PICTURE PICT F1_Window.FormToPict GIVING FORM_PICTURE PRTPAGE PRINTER_FILE;*P=10:01,"Here's the screen print:": *PICTRECT=*ON: *PICT=02:30:10:100:FORM_PICTURE;
![]() v1.10 |
Send e-mail to MMCC. |