home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / prnt3.zip / DrawPage.C < prev    next >
Text File  |  1995-06-29  |  24KB  |  550 lines

  1. #pragma title("Printer Driver  --  Version 3  --  (PrnPage.C)")
  2. #pragma subtitle("   Application Window - Interface Definitions")
  3.  
  4. #pragma info(noext)
  5.  
  6. #define INCL_DEV                   /* Include OS/2 Device Interface     */
  7. #define INCL_DOS                   /* Include OS/2 DOS Kernal           */
  8. #define INCL_DOSERRORS             /* Include OS/2 DOS Errors           */
  9. #define INCL_GPI                   /* Include OS/2 PM GPI Interface     */
  10. #define INCL_WIN                   /* Include OS/2 PM Windows Interface */
  11.  
  12. #include <os2.h>
  13. #include <string.h>
  14.  
  15. #include "appdefs.h"
  16. #include "prnsetup.h"
  17.  
  18. /* This module contains the various drawing routines for the example    */
  19. /* printing.                                                            */
  20.  
  21. /* Filename:   PrnWnd.C                                                 */
  22.  
  23. /*  Version:   2                                                        */
  24. /*  Created:   1995-03-08                                               */
  25. /*  Revised:   1995-03-12                                               */
  26.  
  27. /* Routines:   MRESULT EXPENTRY PrintDriverWndProc(HWND hWnd,           */
  28. /*                                                 ULONG msg,           */
  29. /*                                                 MPARAM mp1,          */
  30. /*                                                 MPARAM mp2);         */
  31.  
  32. /************************************************************************/
  33. /************************************************************************/
  34. /************************************************************************/
  35. /* DISCLAIMER OF WARRANTIES:                                            */
  36. /* -------------------------                                            */
  37. /* The following [enclosed] code is sample code created by IBM          */
  38. /* Corporation and Prominare Inc.  This sample code is not part of any  */
  39. /* standard IBM product and is provided to you solely for the purpose   */
  40. /* of assisting you in the development of your applications.  The code  */
  41. /* is provided "AS IS", without warranty of any kind.  Neither IBM nor  */
  42. /* Prominare shall be liable for any damages arising out of your        */
  43. /* use of the sample code, even if they have been advised of the        */
  44. /* possibility of such damages.                                         */
  45. /************************************************************************/
  46. /************************************************************************/
  47. /************************************************************************/
  48. /*                     D I S C L A I M E R                              */
  49. /* This code is provided on an as is basis with no implied support.     */
  50. /* It should be considered freeware that cannot be rebundled as         */
  51. /* part of a larger "*ware" offering without our consent.               */
  52. /************************************************************************/
  53. /************************************************************************/
  54. /************************************************************************/
  55.  
  56. /* Copyright ╕ International Business Machines Corp., 1995.             */
  57. /* Copyright ╕ 1995  Prominare Inc.  All Rights Reserved.               */
  58.  
  59. /* -------------------------------------------------------------------- */
  60.  
  61. /************************************************************************/
  62. /*                                                                      */
  63. /*     Module Data Definitions                                          */
  64. /*                                                                      */
  65. /************************************************************************/
  66.  
  67. HPS hpsPrint;                      /* Print Window Presentation Handle  */
  68.  
  69. PSZ pszString1 = "This is an example of ";
  70. #define CSTRING1 22L
  71. PSZ pszString2 = "italic";
  72. #define CSTRING2 6L
  73. PSZ pszString3 = " and ";
  74. #define CSTRING3 5L
  75. PSZ pszString4 = "bold";
  76. #define CSTRING4 4L
  77. PSZ pszString5 = " text displayed on same line.";
  78. #define CSTRING5 29L
  79.  
  80. PSZ apszScale[6] = { "0", "1", "2", "3", "4", "5" };
  81.  
  82. /************************************************************************/
  83. /*                                                                      */
  84. /*     Module Prototype Definitions                                     */
  85. /*                                                                      */
  86. /************************************************************************/
  87.  
  88. static VOID DrawFormattedText(HPS hpsTarget, HPS hpsPrinter,
  89.                               LONG cString, PSZ pszString, ULONG fl, PFONTCACHE pfcache);
  90.  
  91. #pragma subtitle("   Client Window - Client Window Procedure")
  92. #pragma page( )
  93.  
  94. /* --- DrawCommon -------------------------------------- [ Public ] --- */
  95. /*                                                                      */
  96. /*     This function is used to perform the drawing of the graphics     */
  97. /*     and text within the presentation space.  It is assumed by the    */
  98. /*     function that the units of the presentation space are TWIPS.     */
  99. /*                                                                      */
  100. /*     Upon Entry:                                                      */
  101. /*                                                                      */
  102. /*     HPS hPS; = Presentation Space Handle                             */
  103. /*                                                                      */
  104. /*     Upon Exit:                                                       */
  105. /*                                                                      */
  106. /*     Nothing                                                          */
  107. /*                                                                      */
  108. /* -------------------------------------------------------------------- */
  109.  
  110. VOID DrawCommon(HPS hPS, HPS hpsPrinter, PFONTCACHE pfcache,
  111.                 LONG lLeftMargin, LONG lBottomMargin,
  112.                 LONG lRightMargin, LONG lTopMargin,
  113.                 PSZ pszHeader, PSZ pszFooter, BOOL fDrawHeader)
  114.  
  115. {
  116. POINTL ptl;                        /* Display Point                     */
  117. POINTL ptlTickStart;               /* Tick Start Display Point          */
  118. POINTL ptlTickEnd;                 /* Tick End Display Point            */
  119. POINTL ptlScale;                   /* Tick End Display Point            */
  120. POINTL rgptl[TXTBOX_COUNT];        /* Text Box Point Array              */
  121. union {
  122. LONG   clr;                        /* RGB Colour                        */
  123. RGB2   rgb2;                       /* RGB Colour                        */
  124.  } lClr;
  125. POINTL aptl[4];                    /* Gray Scale Display Points         */
  126. SIZEL  sizl;                       /* Page Size                         */
  127. register INT i, n;                 /* Loop Counter                      */
  128.  
  129. GpiQueryPS(hPS, &sizl);
  130. aptl[0].x = lLeftMargin;
  131. aptl[0].y = lBottomMargin;
  132. aptl[1].x = lLeftMargin;
  133. aptl[1].y = sizl.cy - lTopMargin;
  134. aptl[2].x = sizl.cx - lRightMargin;
  135. aptl[2].y = sizl.cy - lTopMargin;
  136. aptl[3].x = sizl.cx - lRightMargin;
  137. aptl[3].y = lBottomMargin;
  138.  
  139. GpiBeginPath(hPS, 1L);
  140. GpiMove(hPS, &aptl[3]);
  141. GpiPolyLine(hPS, 4L, aptl);
  142. GpiEndPath(hPS);
  143.                        /* Circle complete, convert the normal path to a */
  144.                        /* clip path to allow the determination of the   */
  145.                        /* mouse button click within the colour wheel or */
  146.                        /* outside the edge of the wheel but still       */
  147.                        /* within the limits of the control itself       */
  148.  
  149. GpiSetClipPath(hPS, 1L, SCP_ALTERNATE | SCP_AND);
  150.  
  151.                        /* Set the colour table to RGB mode              */
  152.  
  153. GpiCreateLogColorTable(hPS, 0UL, LCOLF_RGB, 0L, 0L, (PLONG)NULL);
  154.  
  155. ptl.x = ptlTickStart.x = ptlTickEnd.x = ptlScale.x = lLeftMargin;
  156. ptl.y = ptlTickStart.y = lBottomMargin + 720L;
  157.  
  158. GpiMove(hPS, &ptl);
  159. ptl.x = 9360L + lLeftMargin;
  160. GpiLine(hPS, &ptl);
  161.  
  162. ptlScale.y = lBottomMargin + 540L;
  163.  
  164. for ( i = 0; i < 6; i++, ptlScale.x += 1440L )
  165.    for ( n = 0; n < 16; n++, ptlTickEnd.x = (ptlTickStart.x += 90L) )
  166.        {
  167.        switch ( n )
  168.            {
  169.            case 1 :        /* 1/16 */
  170.            case 3 :        /* 3/16 */
  171.            case 5 :        /* 5/16  */
  172.            case 7 :        /* 7/16 */
  173.            case 9 :        /* 9/16 */
  174.            case 11 :       /* 11/16 */
  175.            case 13 :       /* 13/16 */
  176.            case 15 :       /* 15/16 */
  177.                ptlTickEnd.y = lBottomMargin + 720L + 90L;
  178.                break;
  179.  
  180.            case 2 :        /* 1/8  */
  181.            case 6 :        /* 3/8  */
  182.            case 10 :       /* 5/8  */
  183.            case 14 :       /* 7/8  */
  184.                ptlTickEnd.y = lBottomMargin + 720L + 180L;
  185.                break;
  186.  
  187.            case 4 :        /* 1/4  */
  188.            case 12 :       /* 3/4  */
  189.                ptlTickEnd.y = lBottomMargin + 720L + 270L;
  190.                break;
  191.  
  192.            case 0 :        /* 0  */
  193.                GpiMove(hPS, &ptlScale);
  194.                DrawFormattedText(hPS, hpsPrinter, 1, apszScale[i], 0UL, &fcacheScale);
  195.  
  196.            case 8 :        /* 1/2  */
  197.                ptlTickEnd.y = lBottomMargin + 720L + 450L;
  198.                break;
  199.            }
  200.        GpiMove(hPS, &ptlTickStart);
  201.        GpiLine(hPS, &ptlTickEnd);
  202.        }
  203.  
  204. lClr.rgb2.fcOptions = 0;
  205.  
  206. aptl[0].x = lLeftMargin   + 720L;
  207. aptl[0].y = lBottomMargin + 360L;
  208. aptl[1].x = lLeftMargin   + 900L;
  209. aptl[1].y = lBottomMargin + 360L;
  210. aptl[2].x = lLeftMargin   + 900L;
  211. aptl[2].y = lBottomMargin + 180L;
  212. aptl[3].x = lLeftMargin   + 720L;
  213. aptl[3].y = lBottomMargin + 180L;
  214.  
  215. for ( i = 0; i < 100; i += 10 )
  216.    {
  217.    lClr.rgb2.bGreen =
  218.    lClr.rgb2.bBlue  =
  219.    lClr.rgb2.bRed   = (BYTE)((i * 255L) / 100L);
  220.  
  221.    GpiSetColor(hPS, (LONG)lClr.clr);
  222.  
  223.    GpiBeginArea(hPS, BA_NOBOUNDARY | BA_ALTERNATE);
  224.  
  225.    GpiMove(hPS, &aptl[3]);
  226.    GpiPolyLine(hPS, 4L, aptl);
  227.    GpiEndArea(hPS);
  228.    aptl[0].x = (aptl[3].x += 180L);
  229.    aptl[1].x = (aptl[2].x += 180L);
  230.    }
  231.  
  232. aptl[0].x = (aptl[3].x += 360L);
  233. aptl[1].x = (aptl[2].x += 360L);
  234.  
  235. for ( i = 0; i < 7; i++ )
  236.    {
  237.    switch ( i )
  238.        {
  239.        case 0 :
  240.            lClr.rgb2.bGreen = 0L;
  241.            lClr.rgb2.bBlue  = 0L;
  242.            lClr.rgb2.bRed   = 0L;
  243.            break;
  244.  
  245.        case 1 :
  246.            lClr.rgb2.bGreen = 255L;
  247.            lClr.rgb2.bBlue  = 0L;
  248.            lClr.rgb2.bRed   = 0L;
  249.            break;
  250.  
  251.        case 2 :
  252.            lClr.rgb2.bGreen = 0L;
  253.            lClr.rgb2.bBlue  = 255L;
  254.            lClr.rgb2.bRed   = 0L;
  255.            break;
  256.  
  257.        case 3 :
  258.            lClr.rgb2.bGreen = 0L;
  259.            lClr.rgb2.bBlue  = 0L;
  260.            lClr.rgb2.bRed   = 255L;
  261.            break;
  262.  
  263.        case 4 :
  264.            lClr.rgb2.bGreen = 255L;
  265.            lClr.rgb2.bBlue  = 255L;
  266.            lClr.rgb2.bRed   = 0L;
  267.            break;
  268.  
  269.        case 5 :
  270.            lClr.rgb2.bGreen = 255L;
  271.            lClr.rgb2.bBlue  = 0L;
  272.            lClr.rgb2.bRed   = 255L;
  273.            break;
  274.  
  275.        case 6 :
  276.            lClr.rgb2.bGreen = 0L;
  277.            lClr.rgb2.bBlue  = 255L;
  278.            lClr.rgb2.bRed   = 255L;
  279.            break;
  280.        }
  281.    GpiSetColor(hPS, (LONG)lClr.clr);
  282.  
  283.    GpiBeginArea(hPS, BA_NOBOUNDARY | BA_ALTERNATE);
  284.  
  285.    GpiMove(hPS, &aptl[3]);
  286.    GpiPolyLine(hPS, 4L, aptl);
  287.    GpiEndArea(hPS);
  288.    aptl[0].x = (aptl[3].x += 180L);
  289.    aptl[1].x = (aptl[2].x += 180L);
  290.    }
  291.  
  292. ptl.x = lLeftMargin   + 720L;
  293. ptl.y = lBottomMargin + 1440L;
  294. GpiMove(hPS, &ptl);
  295. GpiSetColor(hPS, RGB_BLACK);
  296.  
  297. DrawFormattedText(hPS, hpsPrinter, CSTRING1, pszString1, 0UL,              pfcache);
  298. DrawFormattedText(hPS, hpsPrinter, CSTRING2, pszString2, FATTR_SEL_ITALIC, pfcache);
  299. DrawFormattedText(hPS, hpsPrinter, CSTRING3, pszString3, 0UL,              pfcache);
  300. DrawFormattedText(hPS, hpsPrinter, CSTRING4, pszString4, FATTR_SEL_BOLD,   pfcache);
  301. DrawFormattedText(hPS, hpsPrinter, CSTRING5, pszString5, 0UL,              pfcache);
  302.  
  303.                        /* Draw the header and footer if necessary       */
  304. if ( fDrawHeader )
  305.    {
  306.                        /* Determine the size of the output area         */
  307.  
  308.    if ( pszHeader && pszHeader[0] )
  309.        {
  310.        GpiSetCharSet(hPS, pfcache->lfontBold.lcid);
  311.        GpiQueryTextBox(hPS, (LONG)strlen(pszHeader), pszHeader, 5L, rgptl);
  312.        ptl.x = (sizl.cx - lLeftMargin - lRightMargin - rgptl[TXTBOX_CONCAT].x) / 2L +
  313.                lLeftMargin;
  314.        ptl.y = sizl.cy - lTopMargin / 2L;
  315.        GpiMove(hPS, &ptl);
  316.        DrawFormattedText(hPS, hpsPrinter, (LONG)strlen(pszHeader), pszHeader, FATTR_SEL_BOLD, pfcache);
  317.        }
  318.  
  319.    if ( pszFooter && pszFooter[0] )
  320.        {
  321.        GpiSetCharSet(hPS, pfcache->lfontBold.lcid);
  322.        GpiQueryTextBox(hPS, (LONG)strlen(pszFooter), pszFooter, 5L, rgptl);
  323.        ptl.x = (sizl.cx - lLeftMargin - lRightMargin - rgptl[TXTBOX_CONCAT].x) / 2L +
  324.                lLeftMargin;
  325.        ptl.y = lBottomMargin / 2L;
  326.        GpiMove(hPS, &ptl);
  327.        DrawFormattedText(hPS, hpsPrinter, (LONG)strlen(pszFooter), pszFooter, FATTR_SEL_BOLD, pfcache);
  328.        }
  329.    }
  330. }
  331. #pragma subtitle("   Client Window - Client Window Procedure")
  332. #pragma page( )
  333.  
  334. /* --- DrawFormattedText ------------------------------- [ Public ] --- */
  335. /*                                                                      */
  336. /*     This function is used to perform the drawing of the graphics     */
  337. /*     and text within the presentation space.  It is assumed by the    */
  338. /*     function that the units of the presentation space are TWIPS.     */
  339. /*                                                                      */
  340. /*     Upon Entry:                                                      */
  341. /*                                                                      */
  342. /*     HPS hPS; = Presentation Space Handle                             */
  343. /*                                                                      */
  344. /*     Upon Exit:                                                       */
  345. /*                                                                      */
  346. /*     Nothing                                                          */
  347. /*                                                                      */
  348. /* -------------------------------------------------------------------- */
  349.  
  350. static VOID DrawFormattedText(HPS hpsTarget, HPS hpsPrinter,
  351.                               LONG cString, PSZ pszString, ULONG fl,
  352.                               PFONTCACHE pfcache)
  353.  
  354. {
  355. PLONG  alVector;                   /* Vector Array                      */
  356. register INT i;                    /* Loop Counter                      */
  357.  
  358. if ( hpsPrinter )
  359.    {
  360.    DosAllocMem((PPVOID)(PVOID)&alVector, (ULONG)(cString * sizeof(LONG)), PAG_READ | PAG_WRITE | PAG_COMMIT);
  361.    if ( fl == 0UL )
  362.        {
  363.        GpiSetCharSet(hpsTarget, pfcache->lfontNormal.lcid);
  364.        if ( pfcache->lfontNormal.fScalable )
  365.            GpiSetCharBox(hpsTarget, &pfcache->lfontNormal.sizfxBox);
  366.  
  367.        for ( i = 0; i < cString; i++ )
  368.            alVector[i] = pfcache->lfontNormal.alWidths[pszString[i]];
  369.        }
  370.    else
  371.        if ( fl == FATTR_SEL_ITALIC )
  372.            {
  373.            GpiSetCharSet(hpsTarget, pfcache->lfontItalic.lcid);
  374.            if ( pfcache->lfontItalic.fScalable )
  375.                GpiSetCharBox(hpsTarget, &pfcache->lfontItalic.sizfxBox);
  376.  
  377.            for ( i = 0; i < cString; i++ )
  378.                alVector[i] = pfcache->lfontItalic.alWidths[pszString[i]];
  379.            }
  380.        else
  381.            {
  382.            GpiSetCharSet(hpsTarget, pfcache->lfontBold.lcid);
  383.            if ( pfcache->lfontBold.fScalable )
  384.                GpiSetCharBox(hpsTarget, &pfcache->lfontBold.sizfxBox);
  385.  
  386.            for ( i = 0; i < cString; i++ )
  387.                alVector[i] = pfcache->lfontBold.alWidths[pszString[i]];
  388.            }
  389.  
  390.    GpiCharStringPos(hpsTarget, (PRECTL)NULL, CHS_VECTOR, cString, pszString, alVector);
  391.    DosFreeMem((PVOID)alVector);
  392.    }
  393. else
  394.    {
  395.    if ( fl == 0UL )
  396.        {
  397.        GpiSetCharSet(hpsTarget, pfcache->lfontNormal.lcid);
  398.        if ( pfcache->lfontNormal.fScalable )
  399.            GpiSetCharBox(hpsTarget, &pfcache->lfontNormal.sizfxBox);
  400.        }
  401.    else
  402.        if ( fl == FATTR_SEL_ITALIC )
  403.            {
  404.            GpiSetCharSet(hpsTarget, pfcache->lfontItalic.lcid);
  405.            if ( pfcache->lfontItalic.fScalable )
  406.                GpiSetCharBox(hpsTarget, &pfcache->lfontItalic.sizfxBox);
  407.  
  408.            }
  409.        else
  410.            {
  411.            GpiSetCharSet(hpsTarget, pfcache->lfontBold.lcid);
  412.            if ( pfcache->lfontNormal.fScalable )
  413.                GpiSetCharBox(hpsTarget, &pfcache->lfontBold.sizfxBox);
  414.            }
  415.  
  416.    GpiCharStringPos(hpsTarget, (PRECTL)NULL, 0UL, cString, pszString, (PLONG)NULL);
  417.    }
  418. }
  419. #pragma subtitle("   Client Window - Client Window Procedure")
  420. #pragma page( )
  421.  
  422. /* --- DrawText ---------------------------------------- [ Public ] --- */
  423. /*                                                                      */
  424. /*     This function is used to draw the control text within the main   */
  425. /*     application window to show the spacing differences.  This text   */
  426. /*     does not use the vector spacing.                                 */
  427. /*                                                                      */
  428. /*     Upon Entry:                                                      */
  429. /*                                                                      */
  430. /*     HPS hpsTarget; = Presentation Space Handle                       */
  431. /*                                                                      */
  432. /*     Upon Exit:                                                       */
  433. /*                                                                      */
  434. /*     Nothing                                                          */
  435. /*                                                                      */
  436. /* -------------------------------------------------------------------- */
  437.  
  438. VOID DrawText(HPS hpsTarget)
  439.  
  440. {
  441. POINTL ptl;                        /* Display Point                     */
  442.  
  443. ptl.x = 810L;
  444. ptl.y = 2160L;
  445. GpiMove(hpsTarget, &ptl);
  446. GpiSetColor(hpsTarget, RGB_BLACK);
  447.  
  448. DrawFormattedText(hpsTarget, (HPS)NULL, CSTRING1, pszString1, 0UL,              &fcache);
  449. DrawFormattedText(hpsTarget, (HPS)NULL, CSTRING2, pszString2, FATTR_SEL_ITALIC, &fcache);
  450. DrawFormattedText(hpsTarget, (HPS)NULL, CSTRING3, pszString3, 0UL,              &fcache);
  451. DrawFormattedText(hpsTarget, (HPS)NULL, CSTRING4, pszString4, FATTR_SEL_BOLD,   &fcache);
  452. DrawFormattedText(hpsTarget, (HPS)NULL, CSTRING5, pszString5, 0UL,              &fcache);
  453.  
  454. }
  455. #pragma subtitle("   File Print - File Printing Routine")
  456. #pragma page( )
  457.  
  458. /* --- PrnDisplay ------------------------------------- [ Private ] --- */
  459. /*                                                                      */
  460. /*     This function is used to print the constructed display           */
  461. /*     image within a separate thread.  The routine uses the common     */
  462. /*     display function.                                                */
  463. /*                                                                      */
  464. /*     Upon Entry:                                                      */
  465. /*                                                                      */
  466. /*     PPRNDATA pprni; = Print Information Pointer                      */
  467. /*                                                                      */
  468. /*     Upon Exit:                                                       */
  469. /*                                                                      */
  470. /*     Nothing                                                          */
  471. /*                                                                      */
  472. /* -------------------------------------------------------------------- */
  473.  
  474. VOID _System PrnDisplay(PPRNDATA pprni)
  475.  
  476. {
  477. HAB         habThread;             /* Thread Anchor Block Handle        */
  478. HDC         hdcPrinter;            /* Printer Device Context Handle     */
  479. HPS         hpsPrinter;            /* Printer Presentation Space Handle */
  480. LONG        lOut;                  /* Output Count                      */
  481. SIZEL       sizlPage;              /* Page Size Holder                  */
  482. USHORT      usJobID;               /* Spooler Job ID                    */
  483. FONTCACHE   fcachePrn;             /* Font Cache                        */
  484.  
  485.                        /* Get an anchor block handle to allow proper    */
  486.                        /* thread initialization of stack space and      */
  487.                        /* usage of some PM calls.  Create a message     */
  488.                        /* queue as well to make sure that everything    */
  489.                        /* works properly in terms of error message      */
  490.                        /* display.                                      */
  491.  
  492. habThread = WinInitialize(0UL);
  493.  
  494.                        /* Open a device context for the printer         */
  495.                        /* selected                                      */
  496.  
  497. if ( (hdcPrinter = PrnOpenDC(&pprni->prn, "PM_Q_STD")) != (HDC)NULL )
  498.    {
  499.                        /* Create a presentation space into which the    */
  500.                        /* printing will occur using TWIPS as the unit   */
  501.                        /* of measure                                    */
  502.  
  503.    sizlPage.cx = sizlPage.cy = 0L;
  504.    hpsPrinter = GpiCreatePS(habThread, hdcPrinter, &sizlPage, PU_TWIPS |
  505.                             GPIF_DEFAULT | GPIT_NORMAL | GPIA_ASSOC);
  506.  
  507.                        /* Start the printing of the selected file by    */
  508.                        /* indicating the start of the document within   */
  509.                        /* device context                                */
  510.  
  511.    if ( DevEscape(hdcPrinter, DEVESC_STARTDOC, (LONG)strlen(pprni->szTitle),
  512.                   pprni->szTitle, NULL, NULL) != DEVESC_ERROR )
  513.        {
  514.        BuildFontCache((HPS)NULL, hpsPrinter, hdcPrinter,
  515.                       pprni->fsel.szFacename, pprni->fsel.lNominalPointSize,
  516.                       &fcachePrn);
  517.  
  518.        DrawCommon(hpsPrinter, (HPS)NULL, &fcachePrn,
  519.                   (LONG)(1440 * pprni->pags.rdLeftMargin),
  520.                   (LONG)(1440 * pprni->pags.rdBottomMargin),
  521.                   (LONG)(1440.0 * pprni->pags.rdRightMargin),
  522.                   (LONG)(1440.0 * pprni->pags.rdTopMargin),
  523.                   pprni->pags.szHeader, pprni->pags.szFooter,
  524.                   TRUE);
  525.  
  526.                        /* Inform the device context printing complete   */
  527.                        /* to allow the correct spooling and final       */
  528.                        /* printing to occur                             */
  529.        lOut = 2L;
  530.        DevEscape(hdcPrinter, DEVESC_ENDDOC, 0L, NULL, &lOut, (PBYTE)&usJobID);
  531.  
  532.                        /* Release and destroy both the printing         */
  533.                        /* presentation space and device context handles */
  534.  
  535.        GpiAssociate(hpsPrinter, (HDC)NULL);
  536.        GpiDestroyPS(hpsPrinter);
  537.        DevCloseDC(hdcPrinter);
  538.        }
  539.    DeleteFontCache(hpsPrinter, &fcachePrn);
  540.    }
  541. DosFreeMem((PVOID)pprni);
  542.  
  543.                        /* Destroy the message queue used by the thread  */
  544.                        /* and destroy the anchor block before exiting   */
  545.                        /* the thread                                    */
  546. WinTerminate(habThread);
  547.  
  548. DosExit(EXIT_THREAD, 0UL);
  549. }
  550.