|
|
1.1 root 1: /*==============================================================*\
2: * Prnt.c - routines for printing of a document
3: * Created 1989, 1990 Microsoft Corp.
4: *--------------------------------------------------------------
5: *
6: * This module contains the routines for the printing of a
7: * a document. Included are the routines for calling the
8: * standard dialogs for obtaining the user's printer and
9: * page setup preferences. Also included is the routine to
10: * determine the number of pages in a document as well as the
11: * routine to obtain the printer DC and print the document.
12: *
13: *--------------------------------------------------------------
14: *
15: * This source file contains the following functions:
16: *
17: * InitPrinting();
18: * PageSetup(hwndOwner);
19: * PrintSetup(hwndOwner);
20: * Print();
21: * PrintDoc(hdc);
22: * QueryMaxPages();
23: *
24: \*==============================================================*/
25:
26: /*--------------------------------------------------------------*\
27: * Include files, macros, defined constants, and externs
28: \*--------------------------------------------------------------*/
29:
30: #define INCL_DEV
31:
32: #include <os2.h>
33: #include "main.h"
34: #include "xtrn.h"
35:
36: #define MAXHEADERLEN 100 /* maximum length of header */
37: #define MAXFOOTERLEN 100 /* maximum length of footer */
38: #define DLGTITLELEN 30 /* length of dialog title string */
39:
40: #define DEVDATACOUNT 7L /* # fields of DEVOPENSTRUCT used */
41:
42: #define FONTLCID 1L /* LCID for printer font */
43:
44: #define QMP_ERROR -1 /* error return from QueryMaxPages() */
45:
46: /* constants used in InitPrintingDlgs() for initial and maximum margins */
47: #define ONEINCH (MAKEFIXED(1, 0))
48: #define EIGHTINCHES (MAKEFIXED(8, 0))
49: #define ELEVENINCHES (MAKEFIXED(11, 0))
50:
51: /* Macro for converting a FIXED integer value into LO_ENGLISH
52: world coordinates */
53: #define FIXEDTOWORLD(x) ((FIXEDINT(x) * 100L) + \
54: ((FIXEDFRAC(x) * 100L) / 65536L))
55:
56:
57: /*--------------------------------------------------------------*\
58: * Global variables
59: \*--------------------------------------------------------------*/
60: #ifdef PRINT_DLGS_ENABLED
61:
62: static PAGESETUPDLG pgsd;
63: static PRINTSETUPDLG psd;
64: static PRINTDLG prtd;
65: static CHAR szHeader[MAXHEADERLEN], szFooter[MAXFOOTERLEN];
66: static CHAR szPgsdTitle[DLGTITLELEN];
67: static CHAR szPsdtitle[DLGTITLELEN];
68: static CHAR szPrtdTitle[DLGTITLELEN];
69:
70: #endif
71:
72: /*--------------------------------------------------------------*\
73: * Entry point declarations
74: \*--------------------------------------------------------------*/
75: SHORT QueryMaxPages(VOID);
76: BOOL PrintDoc(HDC hdc);
77:
78:
79: /****************************************************************\
80: * Initializes the print dialog structures
81: *--------------------------------------------------------------
82: *
83: * Name: InitPrintDialogs()
84: *
85: * Purpose: Places defaults in the global info structures
86: * used by the standard print dialogs
87: *
88: * Usage: called once from the initialization routine
89: *
90: * Method: places standard defaults into each of the fields
91: * of the Page Setup, Print Setup, and Print Dialog
92: * structures. The values used are standard defaults,
93: * such as inches for the page units, which can be
94: * easily changed by changing the default values in
95: * the routine. The application developer should
96: * modify these values if he wishes to have the
97: * default printer and page setup use different values.
98: *
99: * Returns:
100: *
101: \****************************************************************/
102: VOID InitPrintingDialogs(VOID)
103: {
104:
105: #ifdef PRINT_DLGS_ENABLED
106:
107: fPrintEnabled = TRUE;
108:
109: /*--------------------------------------------------------------*\
110: * Initialize the Page Setup structure
111: \*--------------------------------------------------------------*/
112: pgsd.kgd.cbSize = sizeof(PAGESETUPDLG);
113: pgsd.kgd.flStyle = PGSS_CENTER;
114:
115: if(!WinLoadString(hab,
116: NULL,
117: IDS_PAGESETUPTITLE,
118: DLGTITLELEN,
119: (PSZ)szPgsdTitle)) {
120:
121: MessageBox(hwndMain, IDMSG_CANNOTLOADSTRING, MB_OK | MB_ERROR, FALSE);
122: fPrintEnabled = FALSE;
123: return;
124: }
125:
126: pgsd.kgd.pszDlgTitle = szPgsdTitle;
127: pgsd.kgd.pfnDlgProc = NULL;
128: pgsd.kgd.hmod = NULL;
129: pgsd.kgd.idDlg = 0;
130: pgsd.kgd.lReturn = 0L;
131: pgsd.kgd.x = 0;
132: pgsd.kgd.y = 0;
133:
134: pgsd.flFlags = PGSF_INCHES;
135:
136: /* Setup the header and footer fields. */
137: pgsd.cchHeader = MAXFOOTERLEN;
138: pgsd.cchFooter = MAXHEADERLEN;
139: pgsd.pszHeader = szHeader;
140: pgsd.pszFooter = szFooter;
141:
142: /* Setup the margin fields to one inch top and side margins */
143: pgsd.fxLeftMargin = ONEINCH;
144: pgsd.fxRightMargin = ONEINCH;
145: pgsd.fxTopMargin = ONEINCH;
146: pgsd.fxBottomMargin = ONEINCH;
147:
148: /* maximum margins are 8 inch left and right, 11 inch bottom. We
149: are assuming the default page size is 8 1/2" x 11 " */
150: pgsd.fxLeftMarginMax = EIGHTINCHES;
151: pgsd.fxRightMarginMax = EIGHTINCHES;
152: pgsd.fxTopMarginMax = ELEVENINCHES;
153: pgsd.fxBottomMarginMax = ELEVENINCHES;
154:
155: pgsd.lUser = 0L;
156:
157:
158: /*--------------------------------------------------------------*\
159: * Initialize the Print Setup structure
160: \*--------------------------------------------------------------*/
161: psd.kgd.cbSize = sizeof(PRINTSETUPDLG);
162: psd.kgd.flStyle = PGSS_CENTER;
163:
164: if(!WinLoadString(hab,
165: NULL,
166: IDS_PRINTSETUPTITLE,
167: DLGTITLELEN,
168: (PSZ)szPsdTitle)) {
169:
170: MessageBox(hwndMain, IDMSG_CANNOTLOADSTRING, MB_OK | MB_ERROR, FALSE);
171: fPrintEnabled = FALSE;
172: return;
173: }
174:
175: psd.kgd.pszDlgTitle = szPsdTitle;
176: psd.kgd.pfnDlgProc = NULL;
177: psd.kgd.hmod = NULL;
178: psd.kgd.idDlg = 0;
179: psd.kgd.lReturn = 0L;
180: psd.kgd.x = 0;
181: psd.kgd.y = 0;
182:
183: psd.pszAppName = szAppName;
184: psd.lUser = 0L;
185:
186: /*--------------------------------------------------------------*\
187: * Initialize the Print Dialog structure
188: \*--------------------------------------------------------------*/
189: prtd.kgd.cbSize = sizeof(PRINTDLG);
190: prtd.kgd.flStyle = PGSS_CENTER;
191:
192: if(!WinLoadString(hab,
193: NULL,
194: IDS_PRINTTITLE,
195: DLGTITLELEN,
196: (PSZ)szPrtdTitle)) {
197:
198: MessageBox(hwndMain, IDMSG_CANNOTLOADSTRING, MB_OK | MB_ERROR, FALSE);
199: fPrintEnabled = FALSE;
200: return;
201: }
202:
203:
204: prtd.kgd.pszDlgTitle = szPrtdTitle;
205: prtd.kgd.pfnDlgProc = NULL;
206: prtd.kgd.hmod = NULL;
207: prtd.kgd.idDlg = 0;
208: prtd.kgd.lReturn = 0L;
209: prtd.kgd.x = 0;
210: prtd.kgd.y = 0;
211:
212: prtd.flFlags = PRTF_ALLPAGES;
213: prtd.cPages = 0;
214: prtd.cCopies = 1;
215:
216: prtd.iFrom = 0;
217: prtd.iTo = 0;
218:
219: prtd.cchFileName = 0;
220: prtd.pszFileName = NULL;
221:
222: prtd.lUser = 0L;
223:
224:
225:
226: /*--------------------------------------------------------------*\
227: * Associate all of the dialog structures with each other so
228: * that the dialogs can be called from one another
229: \*--------------------------------------------------------------*/
230: pgsd.ppsd = &psd;
231: pgsd.pprtd = &prtd;
232: psd.ppgsd = &pgsd;
233: psd.pprtd = &prtd;
234: prtd.ppsd = &psd;
235: prtd.ppgsd = &pgsd;
236:
237:
238: /*--------------------------------------------------------------*\
239: * Initialize the DEVOPENSTRUC in psd and prtd with the data
240: * from the default printer in os2.ini
241: \*--------------------------------------------------------------*/
242: psd.kgd.flStyle |= PSS_INITDEVOPENSTRUC;
243: if(!KitPrintSetupDlg(NULL, &psd))
244: fPrintEnabled = FALSE;
245:
246: prtd.kgd.flStyle |= PSS_INITDEVOPENSTRUC;
247: if(!KitPrintDlg(NULL, &prtd))
248: fPrintEnabled = FALSE;
249:
250: if(!fPrintEnabled)
251: MessageBox(HWND_DESKTOP,
252: IDMSG_PRINTINITFAILED,
253: MB_OK | MB_ERROR,
254: FALSE);
255:
256: #else
257: fPrintEnabled = FALSE;
258: #endif
259:
260:
261: } /* InitPrintDialogs() */
262:
263:
264: #ifdef PRINT_DLGS_ENABLED
265:
266: /****************************************************************\
267: * Calls the page setup dialog
268: *--------------------------------------------------------------
269: *
270: * Name: PageSetup(hwndOwner)
271: *
272: * Purpose: Changes the page setup options by calling the
273: * standard page setup dialog
274: *
275: * Usage: called whenever the user wants to update his
276: * page setup.
277: *
278: * Method: Calls the standard Page Setup dialog with the
279: * global PAGESETUPDLG structure which currently
280: * holds the user's choices.
281: *
282: * Returns:
283: *
284: \****************************************************************/
285: VOID PageSetup(hwndOwner)
286: HWND hwndOwner; /* Owner of the dialog */
287: {
288: if(!KitPageSetupDlg(hwndOwner, &pgsd))
289: MessageBox(hwndOwner,
290: IDMSG_CANNOTRUNPAGESETUP,
291: MB_OK | MB_ERROR,
292: TRUE);
293:
294: } /* PageSetup() */
295:
296:
297: /****************************************************************\
298: * Calls the print setup dialog
299: *--------------------------------------------------------------
300: *
301: * Name: PrintSetup(hwndOwner)
302: *
303: * Purpose: Changes the printer setup by calling the standard
304: * print setup dialog
305: *
306: * Usage: called whenever the user wants to update his
307: * printer set up.
308: *
309: * Method: Calls the standard Print Setup dialog with the
310: * global PRINTSETUPDLG structure which currently
311: * holds the user's choices.
312: *
313: * Returns:
314: *
315: \****************************************************************/
316: VOID PrintSetup(hwndOwner)
317: HWND hwndOwner; /* Owner of the dialog */
318: {
319:
320: if(!KitPrintSetupDlg(hwndOwner, &psd))
321: MessageBox(hwndOwner,
322: IDMSG_CANNOTRUNPRINTSETUP,
323: MB_OK | MB_ERROR,
324: TRUE);
325:
326: } /* PrintSetup() */
327:
328:
329: /****************************************************************\
330: * Begins the printing of a document
331: *--------------------------------------------------------------
332: *
333: * Name: Print()
334: *
335: * Purpose: Does the groundwork necessary when printing a file
336: *
337: * Usage: called whenever the user wants to print his file
338: *
339: * Method: - determines the number of pages in the document
340: * - calls the standard print dialog to get the user's
341: * printing options
342: * - opens the DC for the selected printer
343: * - calls the application's printing routine, passing
344: * it the handle to the DC of the printer
345: *
346: * Returns:
347: *
348: \****************************************************************/
349: VOID Print(hwndOwner)
350: HWND hwndOwner; /* owner of the print dialog */
351: {
352: HDC hdcPrinter;
353:
354: /* Determine number of pages available to print */
355: prtd.cPages = QueryMaxPages();
356: if(prtd.cPages == QMP_ERROR) {
357: MessageBox(hwndOwner, IDMSG_CANNOTGETPAGEINFO, MB_OK | MB_ERROR, FALSE);
358: return;
359: }
360:
361: prtd.cCopies = 1; /* initialize the number of copies to one */
362:
363: /* Bring up the Print Dialog */
364: if(!KitPrintDlg(hwndOwner, &prtd)) {
365: MessageBox(hwndOwner, IDMSG_CANNOTRUNPRINT, MB_OK | MB_ERROR, TRUE);
366: return;
367: }
368:
369: /* if user cancelled the dialog, cancel the printing */
370: if(prtd.kgd.lReturn == ID_CANCEL)
371: return;
372:
373:
374: /*--------------------------------------------------------------*\
375: * Open the DC for the default printer. The default printer
376: * DEVOPENDATA is stored in the prtd structure
377: \*--------------------------------------------------------------*/
378: hdcPrinter = DevOpenDC(hab,
379: OD_QUEUED,
380: "*",
381: DEVDATACOUNT,
382: (PDEVOPENDATA)&prtd.ppsd->dop,
383: (HDC)NULL);
384:
385: if(!hdcPrinter) {
386: MessageBox(hwndMain,
387: IDMSG_CANNOTOPENPRINTER,
388: MB_OK | MB_ERROR,
389: FALSE);
390:
391: return;
392: }
393:
394: /*--------------------------------------------------------------*\
395: * Call the application's printing function
396: \*--------------------------------------------------------------*/
397:
398: if(!PrintDoc(hdcPrinter)) {
399: MessageBox(hwndOwner, IDMSG_PRINTERROR, MB_OK | MB_ERROR, FALSE);
400: }
401:
402: DevCloseDC(hdcPrinter);
403:
404: } /* Print() */
405:
406: /****************************************************************\
407: * Determines the maximum number of pages in the document
408: *--------------------------------------------------------------
409: *
410: * Name: QueryMaxPages()
411: *
412: * Purpose: returns the maximum number of pages in a file
413: *
414: * Usage: called by Print() to initialize the prtd.cPages
415: * field
416: *
417: * Method:
418: *
419: * Returns: Number of pages in the document, QMP_ERROR if an error
420: * occurred
421: *
422: \****************************************************************/
423: SHORT QueryMaxPages(VOID)
424: {
425:
426: /*--------------------------------------------------------------*\
427: * Add code to determine the number of pages in the document
428: * to be printed and return that value
429: \*--------------------------------------------------------------*/
430:
431: return 1;
432:
433: } /* QueryMaxPages() */
434:
435:
436: /****************************************************************\
437: * Performs the actual printing of a document
438: *--------------------------------------------------------------
439: *
440: * Name: PrintDoc(hdc)
441: *
442: * Purpose: Performs the printing of a file
443: *
444: * Usage: called by Print() to actually print the file
445: *
446: * Method: Application specific print routines
447: *
448: * Note: this routine should NOT close the printer DC
449: *
450: * Returns: TRUE if successful, FALSE if not
451: *
452: \****************************************************************/
453: BOOL PrintDoc(hdc)
454: HDC hdc; /* hdc of the printer */
455: {
456: SIZEL szl;
457: HPS hpsPrinter;
458: USHORT usNumCopies;
459: BOOL fRet = TRUE;
460:
461: /*--------------------------------------------------------------*\
462: * Create a PS for the DC. Note that you can associate an
463: * existing HPS to the DC here instead if you are using
464: * retained graphics in the HPS. The PS should use any page units
465: * that are convenient. This PS uses LOENGLISH since the margins
466: * returned by the page setup dialog are in inches
467: \*--------------------------------------------------------------*/
468: szl.cx = szl.cy = 0L;
469: hpsPrinter = GpiCreatePS(hab,
470: hdc,
471: &szl,
472: PU_LOENGLISH | GPIT_NORMAL | GPIF_DEFAULT | GPIA_ASSOC);
473: if(hpsPrinter == NULL)
474: return FALSE;
475:
476:
477: /* print one document for each number of copies */
478: usNumCopies = (USHORT)prtd.cCopies;
479: while(usNumCopies--) {
480:
481: /* send a DEVESC_STARTDOC to start the printing */
482: if(DevEscape(hdc,
483: DEVESC_STARTDOC,
484: (LONG)MAXNAMEL,
485: (PBYTE)szAppName,
486: (PLONG)NULL,
487: (PBYTE)NULL) != DEV_OK) {
488:
489: MessageBox(hwndMain,
490: IDMSG_CANNOTOPENPRINTER,
491: MB_OK | MB_ERROR,
492: FALSE);
493:
494: fRet = FALSE;
495: goto PrintDocExit;
496: }
497:
498: /*--------------------------------------------------------------*\
499: * Include any code necessary for printing here. Note that
500: * all page and printer setup information can be found in
501: * the pgsd, psd, and prtd global variables. Remember to
502: * send a DEVESC_NEWFRAME escape code to the hdc after each
503: * page.
504: \*--------------------------------------------------------------*/
505:
506:
507:
508: /* send a DEVESC_ENDDOC to end the printing */
509: if(DevEscape(hdc,
510: DEVESC_ENDDOC,
511: 0L,
512: (PBYTE)NULL,
513: (PLONG)&lOutData,
514: (PBYTE)&usSpoolId) != DEV_OK) {
515:
516: MessageBox(hwndMain,
517: IDMSG_CANNOTOPENPRINTER,
518: MB_OK | MB_ERROR,
519: FALSE);
520:
521: fRet = FALSE;
522: goto PrintDocExit;
523: }
524:
525: } /* while(usNumCopies) */
526:
527: PrintDocExit:
528:
529: /* Destroy the printer PS */
530: GpiAssociate(hpsPrinter, NULL);
531: GpiDestroyPS(hpsPrinter);
532:
533: return fRet;
534:
535: } /* PrintDoc() */
536:
537: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.