home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / dbcs.zip / DRAWPAGE.C < prev    next >
C/C++ Source or Header  |  1996-01-19  |  19KB  |  562 lines

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