PRINTING
Under DOS, programs send printer commandsè
Each DOS program must have drivers for each type of printer
Under WINDOWS, programs invoke standard GDI functionsè
These draw on a DC
Could be a DC compatible with a printer
Drivers stored in Windows system DLLs translate to printer commands
Windows environment supports different types of printers
User selects a printer from the Control Panel Application
Driver for that printer used for printing from ALL running apps
Printer DC--
Must be compatible with:
Printing device
Its driver
Must use correct output port
Printer and screen are differentè
Printer DC is different from screen DC
Some unique printer issues:
Is printer on line?
Does printer have paper?
Is there color support?
How much graphics support is there?
Printers are slower than video displays
Programs reuse video display surface
Printer must eject completed pages and go on to others
Printers can jam
Lots of others
Issues should be addressed without having to use printer-specific commands
Selecting a Printer from Control Panel--
User selects "Start | Printers" or
"Start | Control Panel | Printers"
Chooses a printer, and from "File" menu selects: "Set as Default"è
Windows updates WIN.INI file in Windows directory
Or in the System Registry
WIN.INI / Registry contains information on current devices/drivers
Windows reads WIN.INI / Registry when information required
[windows]:
Section of WIN.INI containing information on printers
Example--
[windows]
...
device=Panasonic KX-P2130/2135,PAN24_15,LPT1:
…
Here Windows is informed:
A device named Panasonic KX-P2130/2135 is installed
It uses device driver file named PAN24_15.DRV
Output will go to port LPT1
PRINTER DEVICE CONTEXTS--
To print, program must get a DC compatible with the current printer
Use CreateDC()--
hDC = CreateDC (drvName, devName, outPort, initData);
CDC:: CreateDC (drvName, devName, outPort, initData);
Each parameter is a pointer to a character string--
drvName: printer driver file name (e.g., "PAN24_15")
devName: device name (e.g., "KX-P2130/2135")
outPort: output device port name (e.g., "LPT1")
initData: initialization data, usually set to NULL
The Info contained in "device=" line of [windows] section of WIN.INI
Can use GetProfileString() to read an entry in a section of WIN.INI
(Mapped to Registry under NT, 98, 2000, XP)
n = GetProfileString(section, entry, default, cBuf, maxcnt);
First four parameters--pointers to strings:
section: section of WIN.INI containing entry (e.g., "windows")
entry: entry name (e.g., "device")
default: default entry name, if not found (e.g., "")
cBuf: buffer to hold string read from WIN.INI
maxcnt: maximum number of characters to be read
Returns number of characters actually read into buffer
Example--
n = GetProfileString("windows", "device", "", lpszPrinter, 64);
Under MFC--
CWinApp:: GetProfileString(section, entry, default, maxcnt);
Returns a CString
Program then must extract individual fields from the buffer--
Use C library function strtok():
char * strtok (char * s1, const char * s2);
Parses string s1
Breaks into tokens separated by string s2
First call:
Returns pointer to first character in first token of s1
Inserts NULL after token
Subsequent calls (first parameter = NULL):
Work way through string s1
Return pointers to first character in each subsequent token
Sample Code to Create a DC for the Default Printer--
HDC hDC;
char szPrt[64], *szDrv, *szDev, *szPort;
GetProfileString ("windows","device","",szPrt,64);
szDev = strtok (szPrt, ","); // parsing for commas
szDrv = strtok (NULL, ",");
szPort = strtok (NULL, ",");
// Now each pointer points to correct section of szPrt
hDC = CreateDC (szDrv, szDev, szPort, NULL);
// Now output to printer using standard GDI functions
Getting rid of printer DC--
DeleteDC (hDC);
Special Printing Functions (most important ones)--
StartDoc (hDC, lpDocinfo);
CDC::StartDoc(lpDocinfo);
Starts a print job
Returns a positive integer if successful
Parameter: pointer to a DOCINFO structure:
Size in bytes of DOCINFO structure
Name of document (lpsz)
Name of output file (lpsz):
Could be a file for redirected output
NULLèuse the printer specified in DC
StartPage (hDC);
CDC::StartPage();
Prepares printer driver to accept data
Returns positive integer if successful
EndPage (hDC);
CDC::EndPage();
Signals printer that writing to page is done
Directs driver to advance printer to new page
Returns positive integer if successful
EndDoc (hDC);
CDC::EndDoc();
Ends print job
Returns positive integer if successful
PRINT1 Example Program--
Outputs a line of text and a rectangle to default printer and to screen
Uses a helper function, OutputStuff()--
Loads a string from a string table stored in the program resources
Outputs it to location (0,0) on device context specified in first parameter
Draws rectangle between (0,40) and (200,100) on specified device context
But printed output looks different from screen output
Reason: Default mapping mode (MM_TEXT) used--
Size of printer device unit (dot) screen device unit (pixel) differentè
Different size rectangles
Text not affected by mapping mode in place, only by font
Windows keeps default system font about same size on both
To get the Printer Output "Right"--
Use mapping mode with fixed unit size
e.g., MM_LOMETRIC, MM_LOENGLISH, etc.
Output to screen and printed page will be very similar
PRINT2 Example Program--
Uses MM_LOMETRIC mapping mode
Draws some text enclosed in a rectangle
Draws a black circle
Output goes to both printer and screen
Change helper function OutputStuff()--
Set mapping mode to MM_LOMETRIC & move paper/screen up 15 mm
Uses GetTextExtentPoint() to get size of text string
x,y extent of text returned in SIZE structure pointed to by last param
Paper and screen output are very similar
Getting Information about a Physical Device (e.g., PRINTER)--
Can query device context of a device for associated data
Stored there by Windows when DC created
CapValue = GetDeviceCaps (hDC, capability_index);
CDC::GetDeviceCaps(capability_index);
Accesses specified DC
Returns requested capability value
(See online help on GetDeviceCaps() for possible capabilities)
DEVCAPS Example Program--
Displays several capabilities of video display and default printer
Uses a string table to store various capability entries
Two helper functions do display--
1. OutStringTable(hDC, hInst, nStringID, nx, ny);
Retrieves string whose ID is nStringID from string table resource
Displays it at (nx,ny) on device context whose handle is hDC
2. OutDevCapValue(hDCOut, hDCData, nCapIndex, nx, ny);
Gets and displays capability value from device context--
HDCOut: handle to DC where result displayed
hDCData: handle to DC being queried
nCapIndex: index of capability
nx,ny: where to display
Gets capability value with:
nValue = GetDeviceCaps (hDCdata, nIndex) ;
Formats and displays value with:
TextOut (hDCout, nX, nY, cBuf, wsprintf (cBuf, "%d", nValue)) ;
Here wsprintf() formats the string and returns its length