Annotation of os232sdk/toolkt20/c/samples/style/sty_prnt.c, revision 1.1

1.1     ! root        1: /*==============================================================*\
        !             2:  *  Prnt.c - routines for printing of a document
        !             3:  *      Created 1990, Microsoft, IBM  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:  *           CalcPrintArea(hpsPrinter,
        !            22:  *                         hdcPrinter,
        !            23:  *                         prclPrintArea,
        !            24:  *                         pfm);
        !            25:  *           PrintDoc(hdc);
        !            26:  *           QueryMaxPages();
        !            27:  *
        !            28:  *
        !            29: \*==============================================================*/
        !            30: 
        !            31: /*--------------------------------------------------------------*\
        !            32:  *  Include files, macros, defined constants, and externs
        !            33: \*--------------------------------------------------------------*/
        !            34: 
        !            35: #define INCL_WINMLE
        !            36: #define INCL_GPICONTROL
        !            37: #define INCL_GPITRANSFORMS
        !            38: #define INCL_GPIPRIMITIVES
        !            39: #define INCL_GPILCIDS
        !            40: #define INCL_DEV
        !            41: 
        !            42: #include <os2.h>
        !            43: #include "sty_main.h"
        !            44: #include "sty_xtrn.h"
        !            45: 
        !            46: #if 0
        !            47: #include "pmkitp.h"
        !            48: #define PRINT_DLGS_ENABLED
        !            49: #endif
        !            50: 
        !            51: #define MAXHEADERLEN    100     /* maximum length of header */
        !            52: #define MAXFOOTERLEN    100     /* maximum length of footer */
        !            53: #define DLGTITLELEN      30     /* length of dialog title string */
        !            54: 
        !            55: #define DEVDATACOUNT    7L      /* # fields of DEVOPENSTRUCT used */
        !            56: 
        !            57: #define FONTLCID        1L      /* LCID for printer font */
        !            58: 
        !            59: #define QMP_ERROR       -1      /* error return from QueryMaxPages() */
        !            60: 
        !            61: /* constants used in InitPrintingDlgs() for initial and maximum margins */
        !            62: #define ONEINCH         (MAKEFIXED(1, 0))
        !            63: #define EIGHTINCHES     (MAKEFIXED(8, 0))
        !            64: #define ELEVENINCHES    (MAKEFIXED(11, 0))
        !            65: 
        !            66: /* Macro for converting a FIXED integer value into LO_ENGLISH
        !            67:     world coordinates */
        !            68: #define FIXEDTOWORLD(x)   ((FIXEDINT(x) * 100L) +  \
        !            69:                            ((FIXEDFRAC(x) * 100L) / 65536L))
        !            70: 
        !            71: 
        !            72: /*--------------------------------------------------------------*\
        !            73:  *  Global variables
        !            74: \*--------------------------------------------------------------*/
        !            75: #ifdef PRINT_DLGS_ENABLED
        !            76: 
        !            77: static PAGESETUPDLG pgsd;
        !            78: static PRINTSETUPDLG psd;
        !            79: static PRINTDLG prtd;
        !            80: static CHAR szHeader[MAXHEADERLEN], szFooter[MAXFOOTERLEN];
        !            81: static CHAR szPgsdTitle[DLGTITLELEN];
        !            82: static CHAR szPsdtitle[DLGTITLELEN];
        !            83: static CHAR szPrtdTitle[DLGTITLELEN];
        !            84: 
        !            85: #endif
        !            86: 
        !            87: /*--------------------------------------------------------------*\
        !            88:  *  Entry point declarations
        !            89: \*--------------------------------------------------------------*/
        !            90: SHORT QueryMaxPages(VOID);
        !            91: BOOL PrintDoc(HDC hdc);
        !            92: BOOL CalcPrintArea(HPS hpsPrinter,
        !            93:                    PRECTL prclPrintArea,
        !            94:                    PFONTMETRICS pfm);
        !            95: 
        !            96: 
        !            97: /****************************************************************\
        !            98:  *  Initalizes the print dialog structures
        !            99:  *--------------------------------------------------------------
        !           100:  *
        !           101:  *  Name:   InitPrintDialogs()
        !           102:  *
        !           103:  *  Purpose: Places defaults in the global info structures
        !           104:  *          used by the standard print dialogs
        !           105:  *
        !           106:  *  Usage:  called once from the initialization routine
        !           107:  *
        !           108:  *  Method: places standard defaults into each of the fields
        !           109:  *          of the Page Setup, Print Setup, and Print Dialog
        !           110:  *          structures.  The values used are standard defaults,
        !           111:  *          such as inches for the page units, which can be
        !           112:  *          easily changed by changing the default values in
        !           113:  *          the routine.  The application developer should
        !           114:  *          modify these values if he wishes to have the
        !           115:  *          default printer and page setup use different values.
        !           116:  *
        !           117:  *  Returns:
        !           118:  *
        !           119: \****************************************************************/
        !           120:  VOID InitPrintingDialogs(VOID)
        !           121:  {
        !           122: 
        !           123: #ifdef PRINT_DLGS_ENABLED
        !           124: 
        !           125:     fPrintEnabled = TRUE;
        !           126:                                                           
        !           127:     /*--------------------------------------------------------------*\
        !           128:      *  Initialize the Page Setup structure
        !           129:     \*--------------------------------------------------------------*/
        !           130:     pgsd.kgd.cbSize      = sizeof(PAGESETUPDLG);
        !           131:     pgsd.kgd.flStyle     = PGSS_CENTER;
        !           132: 
        !           133:     if(!WinLoadString(hab,
        !           134:                       NULL,
        !           135:                       IDS_PAGESETUPTITLE,
        !           136:                       DLGTITLELEN,
        !           137:                       (PSZ)szPgsdTitle))  {
        !           138: 
        !           139:         MessageBox(hwndMain, IDMSG_CANNOTLOADSTRING, FALSE);
        !           140:         fPrintEnabled = FALSE;
        !           141:         return;
        !           142:     }
        !           143: 
        !           144:     pgsd.kgd.pszDlgTitle = szPgsdTitle;
        !           145:     pgsd.kgd.pfnDlgProc  = NULL;
        !           146:     pgsd.kgd.hmod        = NULL;
        !           147:     pgsd.kgd.idDlg       = 0;
        !           148:     pgsd.kgd.lReturn     = 0L;
        !           149:     pgsd.kgd.x           = 0;
        !           150:     pgsd.kgd.y           = 0;
        !           151: 
        !           152:     pgsd.flFlags     = PGSF_INCHES;
        !           153: 
        !           154:     /* Setup the header and footer fields.  */
        !           155:     pgsd.cchHeader = MAXFOOTERLEN;
        !           156:     pgsd.cchFooter = MAXHEADERLEN;
        !           157:     pgsd.pszHeader = szHeader;
        !           158:     pgsd.pszFooter = szFooter;
        !           159: 
        !           160:     /* Setup the margin fields to one inch top and side margins */
        !           161:     pgsd.fxLeftMargin   = ONEINCH;
        !           162:     pgsd.fxRightMargin  = ONEINCH;
        !           163:     pgsd.fxTopMargin    = ONEINCH;
        !           164:     pgsd.fxBottomMargin = ONEINCH;
        !           165: 
        !           166:     /* maximum margins are 8 inch left and right, 11 inch bottom.  We
        !           167:        are assuming the default page size is 8 1/2" x 11 " */
        !           168:     pgsd.fxLeftMarginMax   = EIGHTINCHES;
        !           169:     pgsd.fxRightMarginMax  = EIGHTINCHES;
        !           170:     pgsd.fxTopMarginMax    = ELEVENINCHES;
        !           171:     pgsd.fxBottomMarginMax = ELEVENINCHES;
        !           172: 
        !           173:     pgsd.lUser = 0L;
        !           174: 
        !           175: 
        !           176:     /*--------------------------------------------------------------*\
        !           177:      *  Initialize the Print Setup structure
        !           178:     \*--------------------------------------------------------------*/
        !           179:     psd.kgd.cbSize      = sizeof(PRINTSETUPDLG);
        !           180:     psd.kgd.flStyle     = PGSS_CENTER;
        !           181: 
        !           182:     if(!WinLoadString(hab,
        !           183:                       NULL,
        !           184:                       IDS_PRINTSETUPTITLE,
        !           185:                       DLGTITLELEN,
        !           186:                       (PSZ)szPsdTitle))  {
        !           187: 
        !           188:         MessageBox(hwndMain, IDMSG_CANNOTLOADSTRING, FALSE);
        !           189:         fPrintEnabled = FALSE;
        !           190:         return;
        !           191:     }
        !           192: 
        !           193:     psd.kgd.pszDlgTitle = szPsdTitle;
        !           194:     psd.kgd.pfnDlgProc  = NULL;
        !           195:     psd.kgd.hmod        = NULL;
        !           196:     psd.kgd.idDlg       = 0;
        !           197:     psd.kgd.lReturn     = 0L;
        !           198:     psd.kgd.x           = 0;
        !           199:     psd.kgd.y           = 0;
        !           200: 
        !           201:     psd.pszAppName      = szAppName;
        !           202:     psd.lUser           = 0L;
        !           203: 
        !           204:     /*--------------------------------------------------------------*\
        !           205:      *  Initialize the Print Dialog structure
        !           206:     \*--------------------------------------------------------------*/
        !           207:     prtd.kgd.cbSize      = sizeof(PRINTDLG);
        !           208:     prtd.kgd.flStyle     = PGSS_CENTER;
        !           209: 
        !           210:     if(!WinLoadString(hab,
        !           211:                       NULL,
        !           212:                       IDS_PRINTTITLE,
        !           213:                       DLGTITLELEN,
        !           214:                       (PSZ)szPrtdTitle))  {
        !           215: 
        !           216:         MessageBox(hwndMain, IDMSG_CANNOTLOADSTRING, FALSE);
        !           217:         fPrintEnabled = FALSE;
        !           218:         return;
        !           219:     }
        !           220: 
        !           221: 
        !           222:     prtd.kgd.pszDlgTitle = szPrtdTitle;
        !           223:     prtd.kgd.pfnDlgProc  = NULL;
        !           224:     prtd.kgd.hmod        = NULL;
        !           225:     prtd.kgd.idDlg       = 0;
        !           226:     prtd.kgd.lReturn     = 0L;
        !           227:     prtd.kgd.x           = 0;
        !           228:     prtd.kgd.y           = 0;
        !           229: 
        !           230:     prtd.flFlags    = PRTF_ALLPAGES;
        !           231:     prtd.cPages     = 0;
        !           232:     prtd.cCopies    = 1;
        !           233: 
        !           234:     prtd.iFrom      = 0;
        !           235:     prtd.iTo        = 0;
        !           236: 
        !           237:     prtd.cchFileName = 0;
        !           238:     prtd.pszFileName = NULL;
        !           239: 
        !           240:     prtd.lUser       = 0L;
        !           241: 
        !           242: 
        !           243:     /*--------------------------------------------------------------*\
        !           244:      *  Associate all of the dialog structures with each other so
        !           245:      *  that the dialogs can be called from one another
        !           246:     \*--------------------------------------------------------------*/
        !           247:     pgsd.ppsd  = &psd;
        !           248:     pgsd.pprtd = &prtd;
        !           249:     psd.ppgsd  = &pgsd;
        !           250:     psd.pprtd  = &prtd;
        !           251:     prtd.ppsd  = &psd;
        !           252:     prtd.ppgsd = &pgsd;
        !           253: 
        !           254: 
        !           255:     /*--------------------------------------------------------------*\
        !           256:      *  Initialize the DEVOPENSTRUC in psd and prtd with the data
        !           257:      *  from the default printer in os2.ini
        !           258:     \*--------------------------------------------------------------*/
        !           259:     psd.kgd.flStyle |= PSS_INITDEVOPENSTRUC;
        !           260:     if(!KitPrintSetupDlg(NULL, &psd))
        !           261:        fPrintEnabled = FALSE;
        !           262: 
        !           263:     prtd.kgd.flStyle |= PSS_INITDEVOPENSTRUC;
        !           264:     if(!KitPrintDlg(NULL, &prtd))
        !           265:        fPrintEnabled = FALSE;
        !           266: 
        !           267:     if(!fPrintEnabled)
        !           268:         MessageBox(HWND_DESKTOP,
        !           269:                    IDMSG_PRINTINITFAILED,
        !           270:                    MB_OK | MB_ERROR,
        !           271:                    FALSE);
        !           272: 
        !           273: #else
        !           274:     fPrintEnabled = FALSE;
        !           275: #endif
        !           276: 
        !           277:  }  /* InitPrintDialogs() */
        !           278: 
        !           279: #ifdef PRINT_DLGS_ENABLED
        !           280: 
        !           281: 
        !           282: /****************************************************************\
        !           283:  *  Calls the page setup dialog
        !           284:  *--------------------------------------------------------------
        !           285:  *
        !           286:  *  Name:   PageSetup(hwndOwner)
        !           287:  *
        !           288:  *  Purpose: Changes the page setup options by calling the
        !           289:  *          standard page setup dialog
        !           290:  *
        !           291:  *  Usage:  called whenever the user wants to update his
        !           292:  *          page setup.
        !           293:  *
        !           294:  *  Method: Calls the standard Page Setup dialog with the
        !           295:  *          global PAGESETUPDLG structure which currently
        !           296:  *          holds the user's choices.
        !           297:  *
        !           298:  *  Returns:
        !           299:  *
        !           300: \****************************************************************/
        !           301: VOID PageSetup(hwndOwner)
        !           302: HWND hwndOwner;        /* Owner of the dialog */
        !           303: {
        !           304:     if(!KitPageSetupDlg(hwndOwner, &pgsd))
        !           305:        MessageBox(hwndOwner,
        !           306:                   IDMSG_CANNOTRUNPAGESETUP,
        !           307:                   MB_OK | MB_ERROR,
        !           308:                   TRUE);
        !           309: 
        !           310: }  /* PageSetup() */
        !           311:    
        !           312: 
        !           313: /****************************************************************\
        !           314:  *  Calls the print setup dialog
        !           315:  *--------------------------------------------------------------
        !           316:  *
        !           317:  *  Name:   PrintSetup(hwndOwner)
        !           318:  *
        !           319:  *  Purpose: Changes the printer setup by calling the standard
        !           320:  *          print setup dialog
        !           321:  *
        !           322:  *  Usage:  called whenever the user wants to update his
        !           323:  *          printer set up.
        !           324:  *
        !           325:  *  Method: Calls the standard Print Setup dialog with the
        !           326:  *          global PRINTSETUPDLG structure which currently
        !           327:  *          holds the user's choices.
        !           328:  *
        !           329:  *  Returns:
        !           330:  *
        !           331: \****************************************************************/
        !           332: VOID PrintSetup(hwndOwner)
        !           333: HWND hwndOwner;        /* Owner of the dialog */
        !           334: {
        !           335: 
        !           336:     if(!KitPrintSetupDlg(hwndOwner, &psd))
        !           337:        MessageBox(hwndOwner,
        !           338:                   IDMSG_CANNOTRUNPRINTSETUP,
        !           339:                   MB_OK | MB_ERROR,
        !           340:                   TRUE);
        !           341: 
        !           342: }  /* PrintSetup() */
        !           343:    
        !           344: 
        !           345: /****************************************************************\
        !           346:  *  Begins the printing of a document
        !           347:  *--------------------------------------------------------------
        !           348:  *
        !           349:  *  Name:   Print()
        !           350:  *
        !           351:  *  Purpose: Does the groundwork necessary when printing a file
        !           352:  *
        !           353:  *  Usage:  called whenever the user wants to print his file
        !           354:  *
        !           355:  *  Method: - determines the number of pages in the document
        !           356:  *          - calls the standard print dialog to get the user's
        !           357:  *            printing options
        !           358:  *          - opens the DC for the selected printer
        !           359:  *          - calls the application's printing routine, passing
        !           360:  *            it the handle to the DC of the printer
        !           361:  *
        !           362:  *  Returns:
        !           363:  *
        !           364: \****************************************************************/
        !           365: VOID Print(hwndOwner)
        !           366: HWND hwndOwner;        /* Owner of the dialog */
        !           367: {
        !           368:     HDC hdcPrinter;
        !           369: 
        !           370:     /* Determine number of pages available to print */
        !           371:     prtd.cPages = QueryMaxPages();
        !           372:     if(prtd.cPages == QMP_ERROR)  {
        !           373:         MessageBox(hwndOwner, IDMSG_CANNOTGETPAGEINFO, MB_OK | MB_ERROR, FALSE);
        !           374:         return;
        !           375:     }
        !           376: 
        !           377:     prtd.cCopies = 1;      /* initialize the number of copies to one */
        !           378: 
        !           379:     /* Bring up the Print Dialog */
        !           380:     if(!KitPrintDlg(hwndOwner, &prtd))  {
        !           381:        MessageBox(hwndOwner, IDMSG_CANNOTRUNPRINT, MB_OK | MB_ERROR,  TRUE);
        !           382:        return;
        !           383:     }
        !           384: 
        !           385:    /* if user cancelled the dialog, cancel the printing */
        !           386:    if(prtd.kgd.lReturn == ID_CANCEL)
        !           387:        return;
        !           388: 
        !           389: 
        !           390:    /*--------------------------------------------------------------*\
        !           391:     *  Open the DC for the default printer.  The default printer
        !           392:     *  DEVOPENDATA is stored in the prtd structure
        !           393:    \*--------------------------------------------------------------*/
        !           394:    hdcPrinter = DevOpenDC(hab,
        !           395:                           OD_QUEUED,
        !           396:                           "*",
        !           397:                           DEVDATACOUNT,
        !           398:                           (PDEVOPENDATA)&prtd.ppsd->dop,
        !           399:                           (HDC)NULL);
        !           400: 
        !           401:    if(!hdcPrinter)  {
        !           402:        MessageBox(hwndMain, IDMSG_CANNOTOPENPRINTER, MB_OK | MB_ERROR,  FALSE);
        !           403:        return;
        !           404:    }
        !           405: 
        !           406:    /*--------------------------------------------------------------*\
        !           407:     *  Call the application's printing function
        !           408:    \*--------------------------------------------------------------*/
        !           409: 
        !           410:     if(!PrintDoc(hdcPrinter))
        !           411:         MessageBox(hwndOwner, IDMSG_PRINTERROR, MB_OK | MB_ERROR, FALSE);
        !           412: 
        !           413:     DevCloseDC(hdcPrinter);
        !           414: 
        !           415: }  /* Print() */
        !           416: 
        !           417: 
        !           418: /****************************************************************\
        !           419:  *  Calculates the print area of the printer page
        !           420:  *--------------------------------------------------------------
        !           421:  *
        !           422:  *  Name:   CalcPrintArea(hpsPrinter, prclPrintArea, pfm)
        !           423:  *
        !           424:  *  Purpose: Sets up the print HPS by installing the font,
        !           425:  *              calculating the print rectangle, and returning
        !           426:  *              the metrics of the chosen font
        !           427:  *
        !           428:  *  Usage:  called by PrintDoc() and QueryMaxPages() to set
        !           429:  *          up the printer HPS for printing.
        !           430:  *
        !           431:  *          Note: HPS must be associated with the printer HDC
        !           432:  *
        !           433:  *  Method:  Routine creates an HPS for the printer DC that
        !           434:  *          uses LOENGLISH for page units.  A similar HPS is
        !           435:  *          created for the MLE through which the current MLE
        !           436:  *          font is translated from device metrics to LOENGLISH
        !           437:  *          metrics.  The print rectangle is determined by
        !           438:  *          finding the printer page size and then subtracting
        !           439:  *          the margins and the headers and footers, if any.
        !           440:  *          The new font is selected into the printer PS and
        !           441:  *          the metrics are returned for the font.  The HPS
        !           442:  *          is returned with the printer font selected.
        !           443:  *
        !           444:  *  Returns: TRUE if successfull, FALSE if not
        !           445:  *
        !           446: \****************************************************************/
        !           447: BOOL CalcPrintArea(hpsPrinter, prclPrintArea, pfm)
        !           448: HPS hpsPrinter;         /* INPUT: HPS associated with the printer DC */
        !           449: PRECTL prclPrintArea;   /* OUTPUT: buffer for the print rectangle */
        !           450: PFONTMETRICS pfm;       /* OUTPUT: pointer to buffer for fontmetrics of
        !           451:                                    printer font */
        !           452: {
        !           453:     HPS hpsMLE;
        !           454:     SIZEL szl;
        !           455:     FATTRS fattr;
        !           456:     FONTMETRICS fm;
        !           457:     HDC hdcPrinter;
        !           458: 
        !           459:     szl.cx = szl.cy = 0L;
        !           460: 
        !           461:     /* get the handle to the HDC of the printer */
        !           462:     hdcPrinter = GpiQueryDevice(hpsPrinter);
        !           463:     if(!hdcPrinter)
        !           464:         return FALSE;
        !           465: 
        !           466:     /* get width and height of paper and convert those points to page units */
        !           467:     if(!DevQueryCaps(hdcPrinter, CAPS_WIDTH, 2L, (PLONG)&szl))
        !           468:         return FALSE;
        !           469: 
        !           470:     if(GpiConvert(hpsPrinter, CVTC_DEVICE, CVTC_WORLD, 2L, (PPOINTL)&szl) ==
        !           471:                 GPI_ERROR)
        !           472:         return FALSE;
        !           473: 
        !           474: 
        !           475: 
        !           476:     /*--------------------------------------------------------------*\
        !           477:      *  prclPrintArea will be set to the rectangle that encompasses
        !           478:      *  the area of the page where the text will be printed.  The
        !           479:      *  rectangle is defined to be the rectangle of the page minus
        !           480:      *  the margins on each side.  For example, the print area
        !           481:      *  on a page using the default margins will be the rectangle
        !           482:      *  that is one inch from the left, bottom, right, and top
        !           483:      *  edges of the papaer.
        !           484:      *
        !           485:      *  This routine creates the print area rectangle in world
        !           486:      *  coordinates.  Since the printer HPS was created in LOENGLISH
        !           487:      *  page units, each point of world coordinate space equals
        !           488:      *  .01 inch, or 100 points equals one inch.  The left and
        !           489:      *  bottom sides of the print area rectangle are equal to the
        !           490:      *  the number of inches of the left and bottom margins times
        !           491:      *  100.  The top and right margins can also be calculated by
        !           492:      *  multiplying the margin size * 100, but then that distance
        !           493:      *  must be subtracted from the width and height of the paper.
        !           494:      *
        !           495:      *  The FIXEDTOWORLD() macro, as defined above, converts a
        !           496:      *  FIXED integer value into LOENGLISH world coordinates.  If
        !           497:      *  you change either the page units of the printer HPS or the
        !           498:      *  scale of the margins, you must changed FIXEDTOWORLD() to
        !           499:      *  translate the margin dimensions to fit the new parameters.
        !           500:      *
        !           501:     \*--------------------------------------------------------------*/
        !           502:     prclPrintArea->xLeft = FIXEDTOWORLD(pgsd.fxLeftMargin);
        !           503: 
        !           504:     prclPrintArea->yBottom = FIXEDTOWORLD(pgsd.fxBottomMargin);
        !           505: 
        !           506:     prclPrintArea->xRight = szl.cx - FIXEDTOWORLD(pgsd.fxRightMargin);
        !           507: 
        !           508:     prclPrintArea->yTop = szl.cy - FIXEDTOWORLD(pgsd.fxTopMargin);
        !           509: 
        !           510: 
        !           511: 
        !           512:     /* get a PS for the MLE and set it to be LOENGLISH also.
        !           513:      *
        !           514:      * Note: only GpiSetPS is checked for an error return.  That is
        !           515:      *  because if the WinGetPS() function returns an error, hpsMLE
        !           516:      *  will be NULL.  If hpsMLE is NULL, then GpiSetPS() will fail.
        !           517:      *  So, GpiSetPS() will fail if WinGetPS() fails, so we only need
        !           518:      *  to check the return code from GpiSetPS()
        !           519:      */
        !           520: 
        !           521:     hpsMLE = WinGetPS(hwndMLE);
        !           522:     if(GpiSetPS(hpsMLE, &szl, PU_LOENGLISH) == GPI_ERROR)
        !           523:         return FALSE;
        !           524: 
        !           525:     /* get font information from MLE and create similar font on printer */
        !           526:     WinSendMsg(hwndMLE, MLM_QUERYFONT, MPFROMP(&fattr), NULL);
        !           527: 
        !           528:     /* convert font information to LOENGLISH by setting the font into
        !           529:      *  the LOENGLISH PS we created for the MLE, getting the
        !           530:      *  fontmetrics, and then updating the fattr structure.
        !           531:      *
        !           532:      *  Note: only GpiSetCharSet's return value is checked, because if
        !           533:      *  the GpiCreateLogFont call fails, the LCID passed to GpiSetCharSet
        !           534:      *  will be invalid and GpiSetCharSet will fail as well.
        !           535:      */
        !           536: 
        !           537:     GpiCreateLogFont(hpsMLE, (PSTR8)fattr.szFacename, FONTLCID, &fattr);
        !           538:     if(GpiSetCharSet(hpsMLE, FONTLCID) == GPI_ERROR)
        !           539:         return FALSE;
        !           540: 
        !           541:     if(GpiQueryFontMetrics(hpsMLE,
        !           542:                            (ULONG)sizeof(FONTMETRICS),
        !           543:                            (PFONTMETRICS)&fm) == GPI_ERROR)
        !           544:         return FALSE;
        !           545: 
        !           546:     /* delete font and release MLE HPS.  Return values are not checked for
        !           547:      *  error because a failure in the clean up of the HPS will not
        !           548:      *  adversely affect this routine
        !           549:      */
        !           550:     GpiSetCharSet(hpsMLE, 0);
        !           551:     GpiDeleteSetId(hpsMLE, FONTLCID);
        !           552:     WinReleasePS(hpsMLE);
        !           553: 
        !           554:     /* The FATTRS structure was filled with the information for the font
        !           555:      * of the MLE.  The height and width of the font is in device
        !           556:      * coordinates, however.  Since we created the same font on a
        !           557:      * PU_LOENGLISH HPS, we now can get the height and width in
        !           558:      * PU_LOENGLISH page units.  These values are contained in the
        !           559:      * fm structure.  We replace the height and width of the font with
        !           560:      * the PU_LOENGLISH equavalents and set the lMatch to 0, so that
        !           561:      * GPI will look through all printer fonts for the font that most
        !           562:      * closely matches the size of the font used on the screen.
        !           563:      */
        !           564: 
        !           565:     fattr.lMaxBaselineExt = fm.lMaxBaselineExt;
        !           566:     fattr.lAveCharWidth   = fm.lAveCharWidth;
        !           567:     fattr.lMatch = 0L;
        !           568: 
        !           569:     /* Create the font on the printer HPS.
        !           570:      *
        !           571:      * Note:  if GpiCreateLogFont() returns 1, then an exact match for
        !           572:      *  the font desired was not found.  This application does not care
        !           573:      *  if the font matches exactly or not, but your application might.
        !           574:      *  If GpiCreateLogFont() returns 0, and error occurred, which will
        !           575:      *  be caught when we attempt GpiSetCharSet() with this font's LCID
        !           576:      */
        !           577:     GpiCreateLogFont(hpsPrinter, (PSTR8)fattr.szFacename, FONTLCID, &fattr);
        !           578: 
        !           579:     if(GpiSetCharSet(hpsPrinter, FONTLCID) == GPI_ERROR)
        !           580:         return FALSE;
        !           581: 
        !           582:     /* get printer font information for return in pfm */
        !           583:     if(GpiQueryFontMetrics(hpsPrinter,
        !           584:                           (LONG)sizeof(FONTMETRICS),
        !           585:                           pfm) == GPI_ERROR)
        !           586:         return FALSE;
        !           587: 
        !           588: 
        !           589:     /*--------------------------------------------------------------*\
        !           590:      *  If a header or footer is present, it will take two lines -
        !           591:      *  one for the text and one blank line.  Since rclPrintArea
        !           592:      *  is the rectangle where the document text is to be printed,
        !           593:      *  the two lines of the header or footer are removed from
        !           594:      *  the current print area.  The top and bottom side are
        !           595:      *  adjusted accordingly.
        !           596:      *
        !           597:      *  When the header and footer are printed, they are printed
        !           598:      *  two lines above and below the print area.
        !           599:      *
        !           600:     \*--------------------------------------------------------------*/
        !           601: 
        !           602:     /* if header is present, adjust top for it */
        !           603:     if(pgsd.pszHeader[0])
        !           604:         prclPrintArea->yTop -= (pfm->lMaxBaselineExt +
        !           605:                                    pfm->lExternalLeading) * 2L;
        !           606: 
        !           607:     /* if footer is present, adjust bottom for it */
        !           608:     if(pgsd.pszFooter[0])
        !           609:         /*--------------------------------------------------------------*\
        !           610:          *  A line of text has a height equal to the MaxBaselineExt
        !           611:          *  followed by the ExternalLeading.  Since the footer is
        !           612:          *  printed on the bottom of the page, the ExternalLeading
        !           613:          *  following the footer is not necessary.  The height of the
        !           614:          *  footer, then, is calculated as the sum of the heights
        !           615:          *  of the text line, the blank line, and the External Leading  *
        !           616:          *  between them.
        !           617:          *
        !           618:         \*--------------------------------------------------------------*/
        !           619:         prclPrintArea->yBottom += (pfm->lMaxBaselineExt * 2L) +
        !           620:                                    pfm->lExternalLeading;
        !           621: 
        !           622:     return TRUE;
        !           623: 
        !           624: }   /* CalcPrintArea() */
        !           625: 
        !           626: 
        !           627: /****************************************************************\
        !           628:  *  Determines the maximum number of pages in the document
        !           629:  *--------------------------------------------------------------
        !           630:  *
        !           631:  *  Name:   QueryMaxPages()
        !           632:  *
        !           633:  *  Purpose: returns the maximum number of pages in a file
        !           634:  *
        !           635:  *  Usage:  called by Print() to initialize the prtd.cPages
        !           636:  *          field
        !           637:  *
        !           638:  *  Method:
        !           639:  *
        !           640:  *  Returns: Number of pages in the document or QMP_ERROR if an error
        !           641:  *
        !           642: \****************************************************************/
        !           643: SHORT QueryMaxPages(VOID)
        !           644: {
        !           645:     HDC hdcPrinter;
        !           646:     FONTMETRICS fm;
        !           647:     RECTL rclPrintArea;
        !           648:     HPS hpsPrinter;
        !           649:     SIZEL szl;
        !           650:     LONG lLines, lLinesPerPage;
        !           651: 
        !           652:     /*--------------------------------------------------------------*\
        !           653:      *  Code to determine the number of pages in the document
        !           654:      *  to be printed
        !           655:     \*--------------------------------------------------------------*/
        !           656: 
        !           657:     /* create an info dc for the printer */
        !           658:     hdcPrinter = DevOpenDC(hab,
        !           659:                            OD_INFO,
        !           660:                            "*",
        !           661:                            DEVDATACOUNT,
        !           662:                            (PDEVOPENDATA)&prtd.ppsd->dop,
        !           663:                            (HDC)NULL);
        !           664:     if(!hdcPrinter)
        !           665:         return QMP_ERROR;
        !           666: 
        !           667:     /* create a ps for the DC.  Use english page units so we can
        !           668:        measure the margins easily */
        !           669:     szl.cx = szl.cy = 0L;
        !           670:     hpsPrinter = GpiCreatePS(hab,
        !           671:                         hdcPrinter,
        !           672:                         &szl,
        !           673:                         PU_LOENGLISH | GPIT_NORMAL | GPIF_DEFAULT | GPIA_ASSOC);
        !           674:     if(!hpsPrinter)
        !           675:         return QMP_ERROR;
        !           676: 
        !           677:     if(!CalcPrintArea(hpsPrinter, &rclPrintArea, &fm))
        !           678:         return QMP_ERROR;
        !           679: 
        !           680:     /* get number of lines in the document */
        !           681:     lLines = (LONG)WinSendMsg(hwndMLE, MLM_QUERYLINECOUNT, NULL, NULL);
        !           682: 
        !           683:     /* calculate the number of lines per page */
        !           684:     lLinesPerPage = (rclPrintArea.yTop - rclPrintArea.yBottom) /
        !           685:                     (fm.lMaxBaselineExt + fm.lExternalLeading);
        !           686: 
        !           687:     GpiAssociate(hpsPrinter, NULL);
        !           688:     GpiDestroyPS(hpsPrinter);
        !           689:     DevCloseDC(hdcPrinter);
        !           690: 
        !           691:     return(SHORT)(lLines / lLinesPerPage) + 1;
        !           692: 
        !           693: }   /* QueryMaxPages() */
        !           694: 
        !           695: 
        !           696: /****************************************************************\
        !           697:  *  Performs the actual printing of a document
        !           698:  *--------------------------------------------------------------
        !           699:  *
        !           700:  *  Name:   PrintDoc(hdc)
        !           701:  *
        !           702:  *  Purpose: Performs the printing of a file
        !           703:  *
        !           704:  *  Usage:  called by Print() to actually print the file
        !           705:  *
        !           706:  *  Method:  This routine prints each line of the MLE.  If a
        !           707:  *           line is longer than the page width, then the line
        !           708:  *           is clipped to the margin;  it is not wrapped to
        !           709:  *           the next line.
        !           710:  *
        !           711:  *          Note: this routine should NOT close the printer DC
        !           712:  *
        !           713:  *  Returns:    TRUE if successfull, FALSE if not
        !           714:  *
        !           715: \****************************************************************/
        !           716: BOOL PrintDoc(hdc)
        !           717: HDC hdc;               /* hdc of the printer */
        !           718: {
        !           719:     USHORT usSpoolId, usNumCopies;
        !           720:     LONG   lOutData, lOffset = 0L, lFileEnd, lLine, lT, lPageLines;
        !           721:     LONG   lLinesPerPage, lLineHeight, lStartOffset, lTotalLines;
        !           722:     RECTL  rclPrintArea, rclText;
        !           723:     HPS    hpsPrinter;
        !           724:     SIZEL  szl;
        !           725:     PVOID  pvBuf;
        !           726:     FONTMETRICS fm;
        !           727:     POINTL ptl;
        !           728:     BOOL   fRet = TRUE;
        !           729: 
        !           730:     /*--------------------------------------------------------------*\
        !           731:      *  Creates a PS for the DC.  Note that you can associate an
        !           732:      *  existing HPS to the DC here instead if you are using
        !           733:      *  retained graphics in the HPS.  The PS must use PU_LOENGLISH
        !           734:      *  page units since the CalcPrintArea() routine expects the
        !           735:      *  the PS to use them.
        !           736:     \*--------------------------------------------------------------*/
        !           737:     szl.cx = szl.cy = 0L;
        !           738:     hpsPrinter = GpiCreatePS(hab,
        !           739:                     hdc,
        !           740:                     &szl,
        !           741:                     PU_LOENGLISH | GPIT_NORMAL | GPIF_DEFAULT | GPIA_ASSOC);
        !           742:     if(!hpsPrinter)
        !           743:         return FALSE;
        !           744: 
        !           745:     if(!CalcPrintArea(hpsPrinter, &rclPrintArea, &fm))  {
        !           746:         fRet = FALSE;
        !           747:         goto PrintDocExit;
        !           748:     }
        !           749: 
        !           750:     /*--------------------------------------------------------------*\
        !           751:      *  Note:  CalcPrintArea() has created the printer font on
        !           752:      *  hpsPrinter and selected the font.  It has also returned
        !           753:      *  the metrics for the font in fm.  rclPrintArea is the
        !           754:      *  rectangle bounding the print area of the page, excluding
        !           755:      *  the header and footer.
        !           756:     \*--------------------------------------------------------------*/
        !           757: 
        !           758:     /*--------------------------------------------------------------*\
        !           759:      *  rclText is set to the rectangle that will encompass one
        !           760:      *  line of output.  Its left and right sides are set to the
        !           761:      *  margins of the paper, namely the left and right sides of
        !           762:      *  the print area as represented by rclPrintArea.  Its top
        !           763:      *  will be repositioned for each line of output and its
        !           764:      *  bottom will always be set to one line's height below the
        !           765:      *  top.  All text output will be clipped to this rectangle.
        !           766:     \*--------------------------------------------------------------*/
        !           767: 
        !           768:     /* set rectangle for each text line to have its left and right sides
        !           769:         equal to the left and right margin of the print area */
        !           770:     rclText.xLeft = rclPrintArea.xLeft;
        !           771:     rclText.xRight = rclPrintArea.xRight;
        !           772: 
        !           773:     /* calculate the height of each printed line, including any space
        !           774:         (leading) between the lines */
        !           775:     lLineHeight = fm.lMaxBaselineExt + fm.lExternalLeading;
        !           776: 
        !           777:     /* calculate the number of lines that fit on a page */
        !           778:     lLinesPerPage =  (rclPrintArea.yTop - rclPrintArea.yBottom) /
        !           779:                       lLineHeight;
        !           780: 
        !           781:     /* If our page size is too small to print even one line, then
        !           782:         abort the print job */
        !           783:     if(lLinesPerPage < 0L)  {
        !           784:         MessageBox(hwndMLE, IDMSG_PRINTAREATOOSMALL, MB_OK | MB_ERROR,  FALSE);
        !           785:         goto PrintDocExit;
        !           786:     }
        !           787: 
        !           788: 
        !           789:     /* get the length of the output file */
        !           790:     lFileEnd = (LONG)WinSendMsg(hwndMLE, MLM_QUERYTEXTLENGTH, NULL, NULL);
        !           791: 
        !           792:     /* create a buffer to hold the file */
        !           793:     DosAllocMem((PPVOID) &pvBuf, lFileEnd, fALLOC);
        !           794: 
        !           795:     /* set up the buffer for the MLE text */
        !           796:     WinSendMsg(hwndMLE,
        !           797:                MLM_SETIMPORTEXPORT,
        !           798:                MPFROMP(pvBuf),
        !           799:                MPFROMLONG(lFileEnd));
        !           800: 
        !           801: 
        !           802:     /* if printing all pages, set file offset to beginning of file  *\
        !           803:      *  and set the last line to the end of the file.  If printing
        !           804:      *  only certain pages, calculate the beginning and ending line
        !           805:     \*  based on the pages                                          */
        !           806: 
        !           807:     if(prtd.flFlags & PRTF_ALLPAGES) {
        !           808:         lStartOffset = 0L;
        !           809:         lTotalLines = (LONG)WinSendMsg(hwndMLE,
        !           810:                                       MLM_QUERYLINECOUNT,
        !           811:                                       NULL,
        !           812:                                       NULL);
        !           813:     }  else  {
        !           814:         /* set lStartOffset to the beginning of the first line of the
        !           815:             first page set to print */
        !           816:         lT = (LONG)(prtd.iFrom - 1L) * lLinesPerPage;
        !           817: 
        !           818:         if(lT < 0L);    /* lT should never be less than 0, so this is */
        !           819:             lT = 0L;    /* purely defensive programming */
        !           820: 
        !           821:         /* lT is the number of lines in all pages from the beginning
        !           822:             of the document to the first page printed */
        !           823: 
        !           824:         lStartOffset = (LONG)WinSendMsg(hwndMLE,
        !           825:                                         MLM_CHARFROMLINE,
        !           826:                                         MPFROMLONG(lT),
        !           827:                                         NULL);
        !           828: 
        !           829:         /* set lTotalLines to the number of lines in the pages between the
        !           830:             starting and ending */
        !           831:         lTotalLines = (LONG)(prtd.iTo - prtd.iFrom + 1) * lLinesPerPage;
        !           832:         lFileEnd = (LONG)WinSendMsg(hwndMLE,
        !           833:                                     MLM_QUERYLINECOUNT,
        !           834:                                     NULL,
        !           835:                                     NULL);
        !           836: 
        !           837:         /* if last line is beyond end of file, set the last line to
        !           838:             be the end of file */
        !           839:         if(lTotalLines + lT > lFileEnd)
        !           840:             lTotalLines = lFileEnd - lT;
        !           841:     }
        !           842: 
        !           843: 
        !           844: 
        !           845:     /* print one document for each number of copies */
        !           846:     usNumCopies = (USHORT)prtd.cCopies;
        !           847:     while(usNumCopies--)  {
        !           848: 
        !           849:         /* set file offset variable to the beginning of the lines
        !           850:            being printed; set line variable to the number of lines
        !           851:            to be printed */
        !           852:         lLine = lTotalLines;
        !           853:         lOffset = lStartOffset;
        !           854: 
        !           855:         /* send a DEVESC_STARTDOC to start the printing */
        !           856:         if(DevEscape(hdc,
        !           857:                      DEVESC_STARTDOC,
        !           858:                      (LONG)MAXNAMEL,
        !           859:                      (PBYTE)szAppName,
        !           860:                      (PLONG)NULL,
        !           861:                      (PBYTE)NULL) != DEV_OK)  {
        !           862: 
        !           863:             MessageBox(hwndMain,
        !           864:                        IDMSG_CANNOTOPENPRINTER,
        !           865:                        MB_OK | MB_ERROR,
        !           866:                        FALSE);
        !           867: 
        !           868:             fRet = FALSE;
        !           869:             goto PrintDocExit;
        !           870:         }
        !           871: 
        !           872:         while(lLine)  {
        !           873: 
        !           874:             /* if we have header text, print the header at the top of the page */
        !           875:             if(pgsd.pszHeader[0])  {
        !           876: 
        !           877:                 /* set text rectangle to two lines above print area since
        !           878:                    we reserved two lines for it in CalcPrintArea() */
        !           879: 
        !           880:                 rclText.yTop = rclPrintArea.yTop + (lLineHeight * 2L);
        !           881:                 rclText.yBottom = rclText.yTop - fm.lMaxBaselineExt;
        !           882: 
        !           883:                 ptl.x = rclText.xLeft;
        !           884:                 ptl.y = rclText.yTop - fm.lMaxAscender;
        !           885: 
        !           886:                 GpiMove(hpsPrinter, &ptl);
        !           887: 
        !           888:                 GpiCharStringPos(hpsPrinter,
        !           889:                                  &rclText,
        !           890:                                  CHS_CLIP,
        !           891:                                  pgsd.cchHeader,
        !           892:                                  pgsd.pszHeader,
        !           893:                                  NULL);
        !           894: 
        !           895:             }
        !           896: 
        !           897:             /*==============================================================*\
        !           898:              * Now print each line of text in the print area
        !           899:             \*==============================================================*/
        !           900: 
        !           901:             /*--------------------------------------------------------------*\
        !           902:              *  The top of rclText is set here to the top of the print
        !           903:              *  area while the bottom is set to the height of one line
        !           904:              *  below the top.  The measurement used to position the
        !           905:              *  bottom is not the lLineHeight variable, but rather the
        !           906:              *  actual height of the characters in the font as given by
        !           907:              *  the lMaxBaselineExt field of the fontmetrics structure.
        !           908:              *  Thus, rclText will be the height of the characters in the
        !           909:              *  line and will not include any external leading.
        !           910:             \*--------------------------------------------------------------*/
        !           911:             rclText.yTop = rclPrintArea.yTop;
        !           912:             rclText.yBottom = rclText.yTop - fm.lMaxBaselineExt;
        !           913: 
        !           914:             /*--------------------------------------------------------------*\
        !           915:              *  ptl will be the beginning point of the text string.  The
        !           916:              *  x coordinate of the point will always be on the left side
        !           917:              *  of the print line, as given the rclText.xLeft.  The y
        !           918:              *  coordinate is set to the baseline of the font.  The
        !           919:              *  baseline is the line at the bottom of all characters,
        !           920:              *  excluding any descenders.  The baseline is determined by
        !           921:              *  taking the top of the text line and subtracting the height
        !           922:              *  of the ascender of the font.  Thus:
        !           923:              *
        !           924:              *                  ****       ===            ===
        !           925:              *                 *    *        |              |
        !           926:              *                 *    *        |  ascender    |
        !           927:              *                 *    *        |              | MaxBaselineExt
        !           928:              *     baseline --- *****------===              |
        !           929:              *                      *        |              |
        !           930:              *                 *    *        |  descender   |
        !           931:              *                  ****       ===            ===
        !           932:              *
        !           933:              *  ptl.y is set to the baseline coordinate by subracting the
        !           934:              *  Ascender of the font (fm.lMaxAscender) from the top of
        !           935:              *  the text rectangle (rclText.yTop).
        !           936:              *
        !           937:             \*--------------------------------------------------------------*/
        !           938: 
        !           939:             ptl.x = rclText.xLeft;
        !           940:             ptl.y = rclText.yTop - fm.lMaxAscender;
        !           941: 
        !           942:             /* set lPageLines to the number of lines on the page.  If
        !           943:                there are fewer lines left in the document, then set
        !           944:                it to the number of lines left */
        !           945:             lPageLines = min(lLinesPerPage, lLine);
        !           946: 
        !           947:             while(lPageLines--)  {
        !           948:                 ptl.y = rclText.yTop - fm.lMaxAscender;  /* re-set baseline */
        !           949: 
        !           950:                 /* get current line from MLE */
        !           951:                 lT = WinSendMsg(hwndMLE,
        !           952:                                 MLM_QUERYFORMATLINELENGTH,
        !           953:                                 MPFROMLONG(lOffset),
        !           954:                                 NULL);
        !           955:                 /* lT is the length of the current line, including the
        !           956:                     CR/LF pair at the end */
        !           957: 
        !           958:                 lOutData = lT - 2L;     /* length of line minus CR/LF pair */
        !           959: 
        !           960:                 /* get the text from the MLE */
        !           961:                 WinSendMsg(hwndMLE,
        !           962:                            MLM_EXPORT,
        !           963:                            MPFROMP(&lOffset),
        !           964:                            MPFROMP(&lT));
        !           965: 
        !           966:                 /* print the string */
        !           967:                 if(GpiMove(hpsPrinter, &ptl) == GPI_ERROR)  {
        !           968:                     fRet = FALSE;
        !           969:                     goto PrintDocExit;
        !           970:                 }
        !           971: 
        !           972: 
        !           973:                 if(GpiCharStringPos(hpsPrinter,
        !           974:                                     &rclText,
        !           975:                                     CHS_CLIP,
        !           976:                                     lOutData,
        !           977:                                     pvBuf,
        !           978:                                     NULL) == GPI_ERROR)  {
        !           979:                     fRet = FALSE;
        !           980:                     goto PrintDocExit;
        !           981:                 }
        !           982: 
        !           983:                 /* subtract one from the lines remaining */
        !           984:                 lLine--;
        !           985: 
        !           986:                 /* move offset pointer to the beginning of next line */
        !           987:                 lOffset += lT;
        !           988: 
        !           989:                 /* set the top of the text rectangle to the top of the
        !           990:                     next line.  Set the bottom to a character's height
        !           991:                     below the top */
        !           992:                 rclText.yTop = rclText.yBottom - fm.lExternalLeading;
        !           993:                 rclText.yBottom = rclText.yTop - fm.lMaxBaselineExt;
        !           994: 
        !           995:             }   /* while(lPageLines) */
        !           996: 
        !           997: 
        !           998:             /* add footer if necessary */
        !           999:             if(pgsd.pszFooter[0])  {
        !          1000: 
        !          1001:                 /* set text rectangle to two lines below print area since
        !          1002:                    we reserved two lines for it in CalcPrintArea().  Refer
        !          1003:                    to the CalcPrintArea() function for an explanation of
        !          1004:                    the height of the footer */
        !          1005: 
        !          1006:                 rclText.yBottom = rclPrintArea.yBottom -
        !          1007:                                   ((fm.lMaxBaselineExt * 2L) +
        !          1008:                                   fm.lExternalLeading);
        !          1009: 
        !          1010:                 rclText.yTop = rclText.yBottom + fm.lMaxBaselineExt;
        !          1011: 
        !          1012:                 /* set ptl to baseline */
        !          1013:                 ptl.y = rclText.yTop - fm.lMaxAscender;
        !          1014: 
        !          1015:                 /* print the footer text */
        !          1016:                 if(GpiMove(hpsPrinter, &ptl) == GPI_ERROR)  {
        !          1017:                     fRet = FALSE;
        !          1018:                     goto PrintDocExit;
        !          1019:                 }
        !          1020: 
        !          1021:                 if(GpiCharStringPos(hpsPrinter,
        !          1022:                                     &rclText,
        !          1023:                                     CHS_CLIP,
        !          1024:                                     pgsd.cchFooter,
        !          1025:                                     pgsd.pszFooter,
        !          1026:                                     NULL) == GPI_ERROR)  {
        !          1027:                     fRet = FALSE;
        !          1028:                     goto PrintDocExit;
        !          1029:                 }
        !          1030: 
        !          1031:             }
        !          1032: 
        !          1033:             /* send a DEVESC_NEWFRAME to end this page */
        !          1034:             if(DevEscape(hdc,
        !          1035:                          DEVESC_NEWFRAME,
        !          1036:                          0L,
        !          1037:                          (PBYTE)NULL,
        !          1038:                          (PLONG)NULL,
        !          1039:                          (PBYTE)NULL) != DEV_OK)  {
        !          1040: 
        !          1041:                 fRet = FALSE;
        !          1042:                 goto PrintDocExit;
        !          1043:             }
        !          1044: 
        !          1045:         }   /* while(lLine) */
        !          1046: 
        !          1047: 
        !          1048: 
        !          1049:         /* send a DEVESC_ENDDOC to end the printing */
        !          1050:         if(DevEscape(hdc,
        !          1051:                      DEVESC_ENDDOC,
        !          1052:                      0L,
        !          1053:                      (PBYTE)NULL,
        !          1054:                      (PLONG)&lOutData,
        !          1055:                      (PBYTE)&usSpoolId) != DEV_OK)  {
        !          1056: 
        !          1057:             fRet = FALSE;
        !          1058:             goto PrintDocExit;
        !          1059:         }
        !          1060: 
        !          1061:     }   /* while(usNumCopies) */
        !          1062: 
        !          1063: PrintDocExit:
        !          1064: 
        !          1065:     /* free the text buffer and destroy the PS */
        !          1066:     GpiFreeMem((PVOID)pvBuf);
        !          1067: 
        !          1068:     GpiAssociate(hpsPrinter, NULL);
        !          1069:     GpiDestroyPS(hpsPrinter);
        !          1070: 
        !          1071:     return fRet;
        !          1072: 
        !          1073: }   /* PrintDoc() */
        !          1074: 
        !          1075: 
        !          1076: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.