home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / prnt2.zip / FilePrn.C < prev    next >
C/C++ Source or Header  |  1995-05-04  |  53KB  |  1,565 lines

  1. #pragma    title("Printer Driver  --  Version 2  --  (PrnWnd.C)")
  2. #pragma    subtitle("   Application Window - Interface Definitions")
  3.  
  4. #define    INCL_DEV           /* Include OS/2 Device Interface    */
  5. #define    INCL_DOS           /* Include OS/2 DOS Kernal        */
  6. #define    INCL_DOSERRORS           /* Include OS/2 DOS Errors        */
  7. #define    INCL_GPI           /* Include OS/2 PM GPI Interface    */
  8. #define    INCL_WIN           /* Include OS/2 PM Windows Interface    */
  9.  
  10. #pragma    info(noext)
  11.  
  12. #include <malloc.h>
  13. #include <os2.h>
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17.  
  18. #include "appdefs.h"
  19. #include "prnsetup.h"
  20.  
  21. /* This    module contains    the routines to    handle the font    selection,    */
  22. /* file    selection and printing.                        */
  23.  
  24. /* Filename:   FilePrn.C                        */
  25.  
  26. /*  Version:   2                            */
  27. /*  Created:   1995-03-07                        */
  28. /*  Revised:   1995-05-04                        */
  29.  
  30. /* Routines:   MRESULT EXPENTRY    FilePrintDlgProc(HWND hWnd,        */
  31. /*                         ULONG msg,        */
  32. /*                         MPARAM    mp1,        */
  33. /*                         MPARAM    mp2);        */
  34. /*           static LONG lSetFonts(HWND hwndFontNames);        */
  35. /*           static VOID ShowDirInfo(HWND hWnd, ULONG    idPath,        */
  36. /*                       ULONG idVol, ULONG idRoom);    */
  37. /*           static VOID DiskVolDrive(ULONG ulDrive,            */
  38. /*                    CHAR *pszDiskName);        */
  39. /*           static VOID QueryDriveList( );                */
  40. /*           static ULONG ulGetDirList(HWND hwndDrives, HWND hwndDirs,*/
  41. /*                     HWND hwndFiles);        */
  42. /*           static BOOL fPrnLine(HPS    hpsPrinter, HDC    hdcPrinter,    */
  43. /*                    PSZ    pszStr,    PPOINTL    pptl,        */
  44. /*                    PPOINTL pptlFooter,            */
  45. /*                    PSIZEL psizlPage, LONG yShift,    */
  46. /*                    BOOL fDateFooter, PSZ pszFooter,    */
  47. /*                    PULONG pcPages);            */
  48. /*           VOID _System PrnFile(PPRNDATA pprni);            */
  49.  
  50. /************************************************************************/
  51. /************************************************************************/
  52. /************************************************************************/
  53. /* DISCLAIMER OF WARRANTIES:                        */
  54. /* -------------------------                        */
  55. /* The following [enclosed] code is sample code    created    by IBM        */
  56. /* Corporation and Prominare Inc.  This    sample code is not part    of any    */
  57. /* standard IBM    product    and is provided    to you solely for the purpose    */
  58. /* of assisting    you in the development of your applications.  The code    */
  59. /* is provided "AS IS",    without    warranty of any    kind.  Neither IBM nor    */
  60. /* Prominare shall be liable for any damages arising out of your    */
  61. /* use of the sample code, even    if they    have been advised of the    */
  62. /* possibility of such damages.                        */
  63. /************************************************************************/
  64. /************************************************************************/
  65. /************************************************************************/
  66. /*               D I S C L A I M E R                */
  67. /* This    code is    provided on an as is basis with    no implied support.    */
  68. /* It should be    considered freeware that cannot    be rebundled as        */
  69. /* part    of a larger "*ware" offering without our consent.        */
  70. /************************************************************************/
  71. /************************************************************************/
  72. /************************************************************************/
  73.  
  74. /* Copyright ╕ International Business Machines Corp., 1995.        */
  75. /* Copyright ╕ 1995  Prominare Inc.  All Rights    Reserved.        */
  76.  
  77. /* --------------------------------------------------------------------    */
  78.  
  79. /************************************************************************/
  80. /*                                    */
  81. /*     Module Prototype    Definitions                    */
  82. /*                                    */
  83. /************************************************************************/
  84.  
  85. static VOID  QueryDriveList(VOID);
  86. static ULONG ulGetDirList(HWND hwndDrives, HWND    hwndDirs, HWND hwndFiles);
  87. static VOID  DiskVolDrive(ULONG    ulDrive, CHAR *pszDiskName);
  88. static VOID  ShowDirInfo(HWND hWnd, ULONG idPath, ULONG    idVol, ULONG idRoom);
  89. static LONG  lSetFonts(HWND hwndFontNames);
  90. static BOOL  fPrnLine(HPS hpsPrinter, HDC hdcPrinter, PSZ pszStr,
  91.            PPOINTL pptl, PPOINTL pptlFooter, PSIZEL    psizlPage, LONG    yShift,
  92.            BOOL fDateFooter, PSZ pszFooter,    PULONG pcPages);
  93. VOID _System PrnFile(PPRNDATA pprni);
  94.  
  95. /************************************************************************/
  96. /*                                    */
  97. /*     Module Data Definitions                        */
  98. /*                                    */
  99. /************************************************************************/
  100.  
  101. BOOL  fLineNumbers = FALSE;       /* Line Numbers Flag            */
  102. INT   iFileSel = LIT_NONE;       /* File Selected            */
  103. BOOL  fDrivesFilled;           /* Drives Filled Flag        */
  104. ULONG ulDriveMap;           /* Drive Bit    Map Holder        */
  105. LONG  cDrives;
  106. CHAR  aszDrives[26][20];
  107. BOOL  afRemoveable[26] = { FALSE, FALSE, FALSE,    FALSE, FALSE, FALSE, FALSE, FALSE,
  108.                FALSE, FALSE, FALSE,    FALSE, FALSE, FALSE, FALSE, FALSE,
  109.                FALSE, FALSE, FALSE,    FALSE, FALSE, FALSE, FALSE, FALSE,
  110.                FALSE, FALSE    };
  111.  
  112. FONTSIZE afsiz[    ] = { {     "6",  6 },
  113.               {     "8",  8 },
  114.               {    "10", 10 },
  115.               {    "12", 12 },
  116.               {    "14", 14 },
  117.               {    "16", 16 },
  118.               {    "18", 18 },
  119.               {    "20", 20 },
  120.               {    "24", 24 },
  121.               {    "32", 32 },
  122.               {    "40", 40 },
  123.               {    "48", 48 } };
  124.  
  125. CHAR szDayNames[ ]   = { "SunMonTueWedThuFriSat" };
  126. CHAR szMonthNames[ ] = { "JanFebMarAprMayJunJulAugSepOctNovDec"    };
  127.  
  128. PFONTMETRICS pfm;           /* Font Metrics Pointer        */
  129. LONG         cFonts;           /* Font Count            */
  130. FONTSEL         fsel;           /* Font Selection            */
  131.  
  132. #pragma    subtitle("   File Print -  File Print Dialogue Procedure")
  133. #pragma    page( )
  134.  
  135. /* --- FilePrintDlgProc    -------------------------------- [ Public ] ---    */
  136. /*                                    */
  137. /*     This function is    used to    process    the messages for the file    */
  138. /*     print dialogue procedure.                    */
  139. /*                                    */
  140. /*     Upon Entry:                            */
  141. /*                                    */
  142. /*     HWND   hWnd; = Dialog Window Handle                */
  143. /*     ULONG  msg;  = PM Message                    */
  144. /*     MPARAM mp1;  = Message Parameter    1                */
  145. /*     MPARAM mp2;  = Message Parameter    2                */
  146. /*                                    */
  147. /*     Upon Exit:                            */
  148. /*                                    */
  149. /*     FilePrintDlgProc    = Message Handling Result            */
  150. /*                                    */
  151. /* --------------------------------------------------------------------    */
  152.  
  153. MRESULT    EXPENTRY FilePrintDlgProc(HWND hWnd, ULONG msg,    MPARAM mp1, MPARAM mp2)
  154.  
  155. {
  156. CHAR     szFileName[CCHMAXPATH];   /* Filename Holder            */
  157. CHAR     szStrBuf[CCHMAXPATH];       /* String Buffer            */
  158. LONG     lMatch;           /* Font Match            */
  159. PPRNDATA pprni;               /* Print Data Pointer        */
  160. TID     tid;               /* Thread ID                */
  161. register INT i,    k, n;           /* Loop Counters            */
  162.  
  163. switch ( msg )
  164.    {
  165.                /* Perform dialog initialization            */
  166.    case    WM_INITDLG :
  167.        WinSetPointer(HWND_DESKTOP, hptrWait);
  168.  
  169.                /* Clear    the drives filled flag            */
  170.  
  171.        fDrivesFilled = FALSE;
  172.  
  173.                /* Show the selected print name            */
  174.  
  175.        WinSetDlgItemText(hWnd, IT_PRINTER, PrnQueryPrinterName(&prn));
  176.  
  177.                /* Set the fonts    for the    printer    selected    */
  178.  
  179.        switch (    lSetFonts(WinWindowFromID(hWnd,    CBX_FONT)) )
  180.        {
  181.                /* Error    return:    bad HDC    for printer        */
  182.        case    1L :
  183.            WinMessageBox(HWND_DESKTOP, hWnd, "Printer Device Context could not be opened.",
  184.                  "Print Font Example", 0UL,    MB_OK |    MB_ICONHAND | MB_MOVEABLE);
  185.            WinDismissDlg(hWnd, FALSE);
  186.            return(0L);
  187.  
  188.                /* Error    return:    bad HPS    for printer        */
  189.        case    2L :
  190.            WinMessageBox(HWND_DESKTOP, hWnd, "Printer Presentation Space could not be created.",
  191.                  "Print Font Example", 0UL,    MB_OK |    MB_ICONHAND | MB_MOVEABLE);
  192.            WinDismissDlg(hWnd, FALSE);
  193.            return(0L);
  194.  
  195.                /* Error    return:    no error, fonts    set in combo    */
  196.        default :
  197.            break;
  198.        }
  199.                /* Set the check    box for    the inclusion of the    */
  200.                /* line numbers                    */
  201.  
  202.        WinSendDlgItemMsg(hWnd, CB_INCLUDELINENUMS, BM_SETCHECK,
  203.              MPFROMSHORT(fLineNumbers), 0L);
  204.  
  205.                /* Get directory/file list and display in list    */
  206.                /* boxes                        */
  207.  
  208.        ShowDirInfo(hWnd, IT_DIRECTORY, IT_VOLUMELABEL, IT_DISKFREE);
  209.  
  210.                /* Get a    list of    the drives, directories    and    */
  211.                /* files    for the    list boxes and show the    number    */
  212.                /* of files within the directory            */
  213.  
  214.        sprintf(szStrBuf, "%d", ulGetDirList(WinWindowFromID(hWnd, CBX_DRIVES),
  215.                         WinWindowFromID(hWnd, LB_DIRECTORIES),
  216.                         WinWindowFromID(hWnd, LB_FILES)));
  217.        WinSetDlgItemText(hWnd, IT_FILECOUNT, szStrBuf);
  218.  
  219.                /* Select the last file printed            */
  220.  
  221.        if ( iFileSel !=    LIT_NONE )
  222.        WinSendDlgItemMsg(hWnd, LB_DIRECTORIES, LM_SELECTITEM, MPFROMSHORT(iFileSel),
  223.                  MPFROMSHORT(TRUE));
  224.        WinSetPointer(HWND_DESKTOP, hptrArrow);
  225.        break;
  226.             /* Process control selections            */
  227.    case    WM_CONTROL :
  228.        switch (    SHORT2FROMMP(mp1) )
  229.        {
  230.                /* Enter    or selection made within error combo    */
  231.                /* box                        */
  232.        case    CBN_ENTER :
  233.            switch (    SHORT1FROMMP(mp1) )
  234.            {
  235.            case    CBX_DRIVES :
  236.  
  237.                /* Get item selected from the list box        */
  238.  
  239.                WinSendDlgItemMsg(hWnd, CBX_DRIVES, LM_QUERYITEMTEXT,
  240.                   MPFROM2SHORT(LONGFROMMR(WinSendDlgItemMsg(hWnd, CBX_DRIVES,
  241.                                         LM_QUERYSELECTION,
  242.                                         0L,    0L)),
  243.                            CCHMAXPATH),
  244.                   MPFROMP(szFileName));
  245.  
  246.                /* Change drives                    */
  247.  
  248.                DosSetDefaultDisk((ULONG)((szFileName[0]    & 223) - '@'));
  249.  
  250.                /* Refresh the directory    files list and show the    */
  251.                /* number of files within the directory        */
  252.  
  253.                sprintf(szStrBuf, "%d", ulGetDirList(WinWindowFromID(hWnd, CBX_DRIVES),
  254.                     WinWindowFromID(hWnd, LB_DIRECTORIES),
  255.                     WinWindowFromID(hWnd, LB_FILES)));
  256.                WinSetDlgItemText(hWnd, IT_FILECOUNT, szStrBuf);
  257.  
  258.                /* Display the directory    path, volume label and    */
  259.                /* total    disk space free                */
  260.  
  261.                ShowDirInfo(hWnd, IT_DIRECTORY, IT_VOLUMELABEL, IT_DISKFREE);
  262.                break;
  263.  
  264.            default :
  265.                break;
  266.            }
  267.            break;
  268.                /* Process message combo    box entry selections    */
  269.  
  270.        case    CBN_LBSELECT :
  271.            switch (    SHORT1FROMMP(mp1) )
  272.            {
  273.            case    CBX_FONT :
  274.  
  275.                /* Check    to see that a valid entry has been    */
  276.                /* selected within the combo box            */
  277.  
  278.                if ( (i = (INT)LONGFROMMR(WinSendDlgItemMsg(hWnd, CBX_FONT,
  279.                        LM_QUERYSELECTION,
  280.                        0L, 0L))) !=    LIT_NONE )
  281.                {
  282.                WinSetPointer(HWND_DESKTOP, hptrWait);
  283.  
  284.                /* Get the font match number for    the font    */
  285.                /* selected from    the selected item handle    */
  286.  
  287.                lMatch = (LONG)LONGFROMMR(WinSendDlgItemMsg(hWnd, CBX_FONT,
  288.                                        LM_QUERYITEMHANDLE,
  289.                                        MPFROMSHORT(i), 0L));
  290.  
  291.                /* Clear    the entries within the font sizes box    */
  292.  
  293.                WinSendDlgItemMsg(hWnd, CBX_FONTSIZE, LM_DELETEALL, 0L, 0L);
  294.  
  295.                /* Find the font    metric for the selected    font    */
  296.  
  297.                for ( i = 0;    i < (INT)cFonts; i++ )
  298.                    if ( pfm[i].lMatch == lMatch )
  299.                    break;
  300.  
  301.                /* Check    to see if the font is an outline font    */
  302.                /* and if the case, place the outline font sizes    */
  303.                /* within the font sizes    combo box        */
  304.  
  305.                if (    pfm[i].fsDefn &    FM_DEFN_OUTLINE    )
  306.                    for ( n = 0; n <    12; n++    )
  307.                    WinSendDlgItemMsg(hWnd, CBX_FONTSIZE,
  308.                           LM_INSERTITEM,
  309.                           MPFROMSHORT(LIT_END),
  310.                           MPFROMP(afsiz[n].pszSize));
  311.                else
  312.  
  313.                /* Device font selected,    locate all the fonts    */
  314.                /* that match the selected font within the    */
  315.                /* font metrics array for each of the different    */
  316.                /* sizes    supported by the printer and place each    */
  317.                /* size within the combo    box            */
  318.  
  319.                    for ( n = k = 0;    n < (INT)cFonts; n++ )
  320.                    if (    (pfm[n].lMatch < 0) &&
  321.                     !strcmp(pfm[i].szFacename,
  322.                         pfm[n].szFacename) &&
  323.                     !(pfm[n].fsDefn    & FM_DEFN_OUTLINE) )
  324.                        {
  325.  
  326.                /* Check    to see if the device font is the HP    */
  327.                /* line printer font size which is a half size    */
  328.  
  329.                        if ( pfm[n].sNominalPointSize ==    85 )
  330.                        memcpy(szStrBuf, "8.5", 4);
  331.                        else
  332.                        _ltoa(pfm[n].sNominalPointSize / 10,
  333.                          szStrBuf, 10);
  334.  
  335.                /* Place    the font size within the combo box    */
  336.  
  337.                        if ( (INT)LONGFROMMR(WinSendDlgItemMsg(hWnd, CBX_FONTSIZE,
  338.                               LM_SEARCHSTRING,
  339.                               MPFROM2SHORT(LSS_CASESENSITIVE, LIT_FIRST),
  340.                               MPFROMP(szStrBuf))) ==
  341.                               LIT_NONE )
  342.                        {
  343.                        WinSendDlgItemMsg(hWnd, CBX_FONTSIZE,
  344.                               LM_INSERTITEM,
  345.                               MPFROMSHORT(LIT_END),
  346.                               MPFROMP(szStrBuf));
  347.                        WinSendDlgItemMsg(hWnd, CBX_FONTSIZE,
  348.                               LM_SETITEMHANDLE,
  349.                               MPFROMSHORT(k++),
  350.                               MPFROMLONG(pfm[n].lMatch));
  351.                        }
  352.                        }
  353.  
  354.                /* Search the list of font sizes    for the    font    */
  355.                /* size last selected and select    the size    */
  356.  
  357.                if (    (i = (INT)LONGFROMMR(WinSendDlgItemMsg(hWnd, CBX_FONTSIZE,
  358.                               LM_SEARCHSTRING,
  359.                               MPFROM2SHORT(LSS_CASESENSITIVE, LIT_FIRST),
  360.                               MPFROMP(_ltoa(fsel.lPointSize, szStrBuf, 10))))) ==
  361.                               LIT_NONE )
  362.                    i = 0;
  363.  
  364.                WinSendDlgItemMsg(hWnd, CBX_FONTSIZE, LM_SELECTITEM,
  365.                       MPFROMSHORT(i),
  366.                       MPFROMSHORT(TRUE));
  367.                WinSetPointer(HWND_DESKTOP, hptrArrow);
  368.                }
  369.  
  370.                break;
  371.            }
  372.            break;
  373.                /* Drive/directory selected, get    entry selected    */
  374.                /* and change to    drive or directory selected    */
  375.  
  376.        case    LN_ENTER :
  377.            switch (    SHORT1FROMMP(mp1) )
  378.            {
  379.            case    LB_DIRECTORIES :
  380.  
  381.                /* Get item selected from the directories list    */
  382.                /* box                        */
  383.  
  384.                WinSendDlgItemMsg(hWnd, LB_DIRECTORIES, LM_QUERYITEMTEXT,
  385.                   MPFROM2SHORT(LONGFROMMR(WinSendDlgItemMsg(hWnd, LB_DIRECTORIES,
  386.                                         LM_QUERYSELECTION, 0L, 0L)),
  387.                            sizeof(szFileName)),
  388.                   MPFROMP(szFileName));
  389.  
  390.                /* Change to the    selected directory        */
  391.  
  392.                DosSetCurrentDir(szFileName);
  393.  
  394.                /* Refresh the directory    files list and show the    */
  395.                /* number of files within the directory        */
  396.  
  397.                sprintf(szStrBuf, "%d", ulGetDirList(WinWindowFromID(hWnd, CBX_DRIVES),
  398.                     WinWindowFromID(hWnd, LB_DIRECTORIES),
  399.                     WinWindowFromID(hWnd, LB_FILES)));
  400.                WinSetDlgItemText(hWnd, IT_FILECOUNT, szStrBuf);
  401.  
  402.                /* Display the directory    path, volume label and    */
  403.                /* total    disk space free                */
  404.  
  405.                ShowDirInfo(hWnd, IT_DIRECTORY, IT_VOLUMELABEL, IT_DISKFREE);
  406.                break;
  407.  
  408.            case    LB_FILES :
  409.  
  410.                /* Item within the files    list box double    clicked    */
  411.                /* on, user indicating that the file selected    */
  412.                /* should be printed, therefore,    force the    */
  413.                /* simulation of    the Print push button        */
  414.  
  415.                WinSendMsg(hWnd,    WM_COMMAND, MPFROMSHORT(DID_OK), 0L);
  416.                break;
  417.            }
  418.            break;
  419.        }
  420.        break;
  421.             /* Process push    button selections        */
  422.    case    WM_COMMAND :
  423.     switch ( SHORT1FROMMP(mp1) )
  424.         {
  425.                /* Print    push button clicked            */
  426.        case    DID_OK :
  427.                /* Get the file selected                */
  428.  
  429.            if ( (iFileSel =    (i = (INT)LONGFROMMR(WinSendDlgItemMsg(hWnd, LB_FILES,
  430.                                        LM_QUERYSELECTION,
  431.                                        0L, 0L)))) == LIT_NONE )
  432.            break;
  433.            else
  434.                /* Get item selected from the list box and    */
  435.                /* determine which file selected            */
  436.  
  437.            WinSendDlgItemMsg(hWnd, LB_FILES, LM_QUERYITEMTEXT,
  438.                      MPFROM2SHORT(i, sizeof(szFileName)),
  439.                      MPFROMP(szFileName));
  440.  
  441.                /* Get the font selected                */
  442.  
  443.            if ( (i = (INT)LONGFROMMR(WinSendDlgItemMsg(hWnd, CBX_FONT,
  444.                                LM_QUERYSELECTION,
  445.                                0L, 0L))) !=    LIT_NONE )
  446.            {
  447.                /* Get the font match number of the font        */
  448.                /* selected                    */
  449.  
  450.            fsel.lMatch = (LONG)LONGFROMMR(WinSendDlgItemMsg(hWnd, CBX_FONT,
  451.                                     LM_QUERYITEMHANDLE,
  452.                                     MPFROMSHORT(i), 0L));
  453.  
  454.                /* Locate the font metrics for the font selected    */
  455.  
  456.            for ( i = 0;    i < (INT)cFonts; i++ )
  457.                if ( pfm[i].lMatch == fsel.lMatch )
  458.                break;
  459.  
  460.                /* Check    to see if the font selected is a    */
  461.                /* scalable font                    */
  462.  
  463.            if (    pfm[i].fsDefn &    FM_DEFN_OUTLINE    )
  464.                {
  465.                /* Scalable font, get the index of the font size    */
  466.                /* selected                    */
  467.  
  468.                n = (INT)LONGFROMMR(WinSendDlgItemMsg(hWnd, CBX_FONTSIZE,
  469.                         LM_QUERYSELECTION,
  470.                         0L, 0L));
  471.                fsel.fFixed = FALSE;
  472.  
  473.                /* Save the point size and facename        */
  474.  
  475.                fsel.lPointSize = afsiz[n].lPointSize;
  476.                fsel.lNominalPointSize =    afsiz[n].lPointSize * 10;
  477.                strcpy(fsel.szFacename, pfm[i].szFacename);
  478.                }
  479.            else
  480.                {
  481.                /* Get the font match number for    the size    */
  482.                /* selected                    */
  483.  
  484.                fsel.lMatch = (LONG)LONGFROMMR(WinSendDlgItemMsg(hWnd, CBX_FONTSIZE,
  485.                                     LM_QUERYITEMHANDLE,
  486.                                     MPFROMSHORT(WinSendDlgItemMsg(hWnd, CBX_FONTSIZE,
  487.                                                       LM_QUERYSELECTION,
  488.                                                       0L, 0L)),
  489.                                     0L));
  490.                fsel.fFixed = TRUE;
  491.  
  492.                /* Locate the font metrics for the font selected    */
  493.  
  494.                for ( i = 0; i <    (INT)cFonts; i++ )
  495.                if (    pfm[i].lMatch == fsel.lMatch )
  496.                    break;
  497.  
  498.                /* Save the point size and facename        */
  499.  
  500.                fsel.lNominalPointSize =    pfm[i].sNominalPointSize;
  501.                strcpy(fsel.szFacename, pfm[i].szFacename);
  502.                }
  503.            }
  504.            else
  505.            break;
  506.  
  507.                /* Get the line number include option        */
  508.  
  509.            fLineNumbers = (BOOL)SHORT1FROMMR(WinSendDlgItemMsg(hWnd,
  510.                                    CB_INCLUDELINENUMS,
  511.                                    BM_QUERYCHECK,
  512.                                    0L, 0L));
  513.  
  514.                /* Allocate memory for the printer information    */
  515.                /* and save the printer information from    the    */
  516.                /* dialogue in the memory            */
  517.  
  518.            DosAllocMem((PPVOID)(PVOID)&pprni, PRNDATASIZE +    CCHMAXPATH,
  519.                PAG_READ | PAG_WRITE    | PAG_COMMIT);
  520.  
  521.            pprni->prn       = prn;
  522.            pprni->fsel       = fsel;
  523.            pprni->cPrnFiles       = 1;
  524.            pprni->fLineNumbers = fLineNumbers;
  525.            pprni->fDateFooter  = TRUE;
  526.            memcpy(pprni->szTitle, "Print Font Example - ", 22);
  527.            strcat(pprni->szTitle, strcpy(pprni->aszFiles[0], szFileName));
  528.  
  529.                /* Create a separate thread from    which the    */
  530.                /* printing is performed                */
  531.  
  532.            DosCreateThread(&tid, (PFNTHREAD)PrnFile, (ULONG)pprni,
  533.                    STACK_COMMITTED,    16384UL);
  534.  
  535.            WinDismissDlg(hWnd, TRUE);
  536.            break;
  537.                /* Cancel push button selected            */
  538.        case    DID_CANCEL :
  539.            WinDismissDlg(hWnd, FALSE);
  540.            break;
  541.                /* Setup    push button selected            */
  542.  
  543.        case    DID_SETUP :
  544.            if ( WinDlgBox(HWND_DESKTOP, hwndPrnSetupFrame, (PFNWP)PrnSetupDlgProc,
  545.                   (HMODULE)NULL, DLG_PRNSETUP, (PVOID)&prn)    )
  546.  
  547.                /* Set the fonts    for the    printer    selected    */
  548.  
  549.            switch ( lSetFonts(WinWindowFromID(hWnd, CBX_FONT)) )
  550.                {
  551.                /* Error    return:    bad HDC    for printer        */
  552.  
  553.                case 1L :
  554.                WinMessageBox(HWND_DESKTOP, hWnd, "Printer Device Context could not be opened.",
  555.                      "Print Font Example", 0UL, MB_OK | MB_ICONHAND    | MB_MOVEABLE);
  556.                WinDismissDlg(hWnd, FALSE);
  557.                return(0L);
  558.  
  559.                /* Error    return:    bad HPS    for printer        */
  560.  
  561.                case 2L :
  562.                WinMessageBox(HWND_DESKTOP, hWnd, "Printer Presentation Space could not be created.",
  563.                      "Print Font Example", 0UL, MB_OK | MB_ICONHAND    | MB_MOVEABLE);
  564.                WinDismissDlg(hWnd, FALSE);
  565.                return(0L);
  566.  
  567.                /* Error    return:    no error, fonts    set in combo    */
  568.  
  569.                default :
  570.                WinSetDlgItemText(hWnd, IT_PRINTER, PrnQueryPrinterName(&prn));
  571.                break;
  572.                }
  573.            break;
  574.         }
  575.     break;
  576.             /* Close requested, exit dialogue        */
  577.    case    WM_CLOSE :
  578.     WinDismissDlg(hWnd, FALSE);
  579.     break;
  580.             /* Pass    through    unhandled messages        */
  581.    default :
  582.        return(WinDefDlgProc(hWnd, msg, mp1, mp2));
  583.    }
  584. return(0L);
  585. }
  586. #pragma    subtitle("   File Print - Font Selection Function")
  587. #pragma    page( )
  588.  
  589. /* --- SetFonts    ---------------------------------------    [ Private ] ---    */
  590. /*                                    */
  591. /*     This function is    enumerate the fonts for    the selected printer    */
  592. /*     and fill    the fonts combo    box with the font names.        */
  593. /*                                    */
  594. /*     Upon Entry:                            */
  595. /*                                    */
  596. /*     HWND hWnd;       = Dialogue Window Handle            */
  597. /*     HWND hwndFontNames; = Font Names    Combo Box Handle        */
  598. /*                                    */
  599. /*     Upon Exit:                            */
  600. /*                                    */
  601. /*     Nothing                                */
  602. /*                                    */
  603. /* --------------------------------------------------------------------    */
  604.  
  605. static LONG lSetFonts(HWND hwndFontNames)
  606.  
  607. {
  608. BOOL  fFonts = FALSE;           /* Fonts Found Flag            */
  609. BOOL  fSelected;           /* Font Selected Flag        */
  610. HDC   hdcPrinter;           /* Device Context Handle        */
  611. HPS   hPS;               /* Presentation Space Handle        */
  612. LONG  lFonts = 0L;           /* Fonts Count            */
  613. SIZEL sizlPage;               /* Size Holder            */
  614. register INT i,    n;           /* Loop Counter            */
  615.  
  616. sizlPage.cx = sizlPage.cy = 0L;
  617. if ( !(hdcPrinter = PrnOpenDC(&prn, "PM_Q_STD")) )
  618.    return(1L);
  619. else
  620.    if (    !(hPS =    GpiCreatePS(hAB, hdcPrinter, &sizlPage,    PU_TWIPS |
  621.                 GPIF_DEFAULT | GPIT_NORMAL | GPIA_ASSOC)) )
  622.        {
  623.        DevCloseDC(hdcPrinter);
  624.        return(2L);
  625.        }
  626.                /* Get the number of fonts for the face name    */
  627.                /* provided                    */
  628.  
  629. cFonts = GpiQueryFonts(hPS, QF_PUBLIC, NULL, &lFonts,
  630.                sizeof(FONTMETRICS), (PFONTMETRICS)NULL);
  631.  
  632.                /* Allocate space for the font metrics for the    */
  633.                /* different font sizes and devices of the font    */
  634. if ( pfm )
  635.    DosFreeMem((PVOID)pfm);
  636. DosAllocMem((PVOID)&pfm, (ULONG)(sizeof(FONTMETRICS) * cFonts),
  637.         PAG_READ | PAG_WRITE | PAG_COMMIT);
  638.  
  639.                /* Get the font metrics for the number of fonts    */
  640.                /* for the face name provided            */
  641.  
  642. GpiQueryFonts(hPS, QF_PUBLIC, NULL, &cFonts,
  643.           sizeof(FONTMETRICS), pfm);
  644.  
  645. WinSendMsg(hwndFontNames, LM_DELETEALL,    0L, 0L);
  646.  
  647.                /* Loop through the font    metrics    returned to    */
  648.                /* and place each of the    different font names    */
  649.                /* within the fonts combo box            */
  650.  
  651. for ( i    = 0, fSelected = fFonts    = FALSE; i < (INT)cFonts; i++ )
  652.    if (    pfm[i].lMatch <    0 )
  653.        if ( (INT)LONGFROMMR(WinSendMsg(hwndFontNames,
  654.                        LM_SEARCHSTRING,
  655.                        MPFROM2SHORT(LSS_CASESENSITIVE, LIT_FIRST),
  656.                        MPFROMP(pfm[i].szFacename))) == LIT_NONE    )
  657.        {
  658.        fFonts = TRUE;
  659.  
  660.                /* Place    the font within    the combo box and set    */
  661.                /* the item handle as the font match number    */
  662.  
  663.        WinSendMsg(hwndFontNames, LM_SETITEMHANDLE,
  664.               MPFROMSHORT(n = (INT)LONGFROMMR(WinSendMsg(hwndFontNames,
  665.                                  LM_INSERTITEM,
  666.                                  MPFROMSHORT(LIT_SORTASCENDING),
  667.                                  MPFROMP(pfm[i].szFacename)))),
  668.               MPFROMLONG(pfm[i].lMatch));
  669.  
  670.                /* Check    to see if the last font    used is    the    */
  671.                /* font placed in the combo box and if so,    */
  672.                /* select it                    */
  673.  
  674.        if (    !strcmp(fsel.szFacename, pfm[i].szFacename) )
  675.            {
  676.            WinSendMsg(hwndFontNames, LM_SELECTITEM,
  677.               MPFROMSHORT(n), MPFROMSHORT(TRUE));
  678.            fSelected = TRUE;
  679.            }
  680.        }
  681.                /* Check    to see if any fonts selected and if    */
  682.                /* none were, get the default font for the    */
  683.                /* printer                    */
  684. if ( !fFonts )
  685.     {
  686.     GpiQueryFontMetrics(hPS, sizeof(FONTMETRICS), pfm);
  687.  
  688.                /* Place    the font within    the combo box and set    */
  689.                /* the item handle as the font match number    */
  690.  
  691.     WinSendMsg(hwndFontNames, LM_SETITEMHANDLE,
  692.            MPFROMSHORT(n = (INT)LONGFROMMR(WinSendMsg(hwndFontNames,
  693.                               LM_INSERTITEM,
  694.                               MPFROMSHORT(LIT_SORTASCENDING),
  695.                               MPFROMP(pfm[0].szFacename)))),
  696.            MPFROMLONG(pfm[0].lMatch));
  697.  
  698.     WinSendMsg(hwndFontNames, LM_SELECTITEM,
  699.            MPFROMSHORT(n), MPFROMSHORT(TRUE));
  700.     fSelected =    TRUE;
  701.     cFonts = 1L;
  702.     }
  703.  
  704. if ( !fSelected    )
  705.     WinSendMsg(hwndFontNames, LM_SELECTITEM,
  706.            MPFROMSHORT(0), MPFROMSHORT(TRUE));
  707.  
  708. GpiAssociate(hPS, (HDC)NULL);
  709. GpiDestroyPS(hPS);
  710. DevCloseDC(hdcPrinter);
  711.  
  712. return(0L);
  713. }
  714. #pragma    subtitle("   File Print - Directory Information Display Function")
  715. #pragma    page( )
  716.  
  717. /* --- ShowDirInfo ------------------------------------    [ Private ] ---    */
  718. /*                                    */
  719. /*     This function is    used to    display    information regarding the    */
  720. /*     path, volume label and room remaining.                */
  721. /*                                    */
  722. /*     Upon Entry:                            */
  723. /*                                    */
  724. /*     HWND  hWnd;   = Dialog Dialogue Window Handle            */
  725. /*     ULONG idPath; = Path ID                        */
  726. /*     ULONG idVol;  = Volume Label ID                    */
  727. /*     ULONG idRoom; = Room Remaining ID                */
  728. /*                                    */
  729. /*     Upon Exit:                            */
  730. /*                                    */
  731. /*     Nothing                                */
  732. /*                                    */
  733. /* --------------------------------------------------------------------    */
  734.  
  735. static VOID ShowDirInfo(HWND hWnd, ULONG idPath, ULONG idVol, ULONG idRoom)
  736.  
  737. {
  738. CHAR       szStrBuf[CCHMAXPATH];   /* String Buffer            */
  739. FSALLOCATE diskinfo;           /* Disk Information Structure    */
  740. FSINFO       fsinf;           /* Disk Volume Information Structure    */
  741. ULONG       cbBuf;           /* Directory    Buffer Size Count    */
  742. ULONG       ulCurDrive;           /* Current Drive Designation        */
  743. ULONG       ulDrives;           /* Drive Map                */
  744.  
  745.                /* Form the current drive/path and display    */
  746.                /* within the Path display field            */
  747.  
  748. DosQueryCurrentDisk(&ulCurDrive, &ulDriveMap);
  749.  
  750.                /* Get the current drive    and path being used and    */
  751.                /* display with Path display field        */
  752.  
  753. DosQueryCurrentDisk(&ulCurDrive, &ulDrives);
  754. memcpy(&szStrBuf[1], ":\\", 3);
  755. szStrBuf[0] = (CHAR)(ulCurDrive    + '@');
  756. cbBuf =    CCHMAXPATH - 3;
  757.                /* Get information on the current directory    */
  758.  
  759. if ( !DosQueryCurrentDir(ulCurDrive, &szStrBuf[3], &cbBuf) )
  760.    {
  761.                /* Show the full    path information        */
  762.  
  763.    WinSetDlgItemText(hWnd, idPath, szStrBuf);
  764.  
  765.                /* Get the volume information and display it    */
  766.  
  767.    if (    !DosQueryFSInfo(0UL, FSIL_VOLSER, (PBYTE)(&fsinf), sizeof(FSINFO)) )
  768.        if ( fsinf.vol.szVolLabel[0] )
  769.        WinSetDlgItemText(hWnd, idVol, fsinf.vol.szVolLabel);
  770.        else
  771.        WinSetDlgItemText(hWnd, idVol, "");
  772.  
  773.                /* Get the remaining space of the drive and    */
  774.                /* display                    */
  775.  
  776.    if (    !DosQueryFSInfo(ulCurDrive, FSIL_ALLOC,    (PVOID)&diskinfo,
  777.             sizeof(FSALLOCATE)) )
  778.        WinSetDlgItemText(hWnd, idRoom,
  779.              strcat(_ltoa((LONG)(diskinfo.cbSector * diskinfo.cSectorUnit *    diskinfo.cUnitAvail),
  780.                 szStrBuf, 10), " Bytes"));
  781.    }
  782. }
  783. #pragma    subtitle("   File Print - Get Disk Volume Label Function")
  784. #pragma    page( )
  785.  
  786. /* --- DiskVolDrive -----------------------------------    [ Private ] ---    */
  787. /*                                    */
  788. /*     This function is    used to    retrieve the volume label of the    */
  789. /*     default disk drive.                        */
  790. /*                                    */
  791. /*     Upon Entry:                            */
  792. /*                                    */
  793. /*     ULONG ulDrive;       = Drive Number                */
  794. /*     CHAR  *pszDiskName; = Holder for    Volume Label            */
  795. /*                                    */
  796. /*     Upon Exit:                            */
  797. /*                                    */
  798. /*     Nothing                                */
  799. /*                                    */
  800. /* --------------------------------------------------------------------    */
  801.  
  802. static VOID DiskVolDrive(ULONG ulDrive,    CHAR *pszDiskName)
  803.  
  804. {
  805. FSINFO fsinf;              /* Disk Volume Information Structure */
  806.  
  807.                /* Get the disk volume label            */
  808.  
  809. if ( !DosQueryFSInfo(ulDrive, FSIL_VOLSER, (PBYTE)(&fsinf), sizeof(FSINFO)) )
  810.    if (    fsinf.vol.szVolLabel[0]    )
  811.        strcat(strcat(memcpy(pszDiskName, "[ ", 3), fsinf.vol.szVolLabel), " ]");
  812.    else
  813.        pszDiskName[0] =    0;
  814. }
  815. #pragma    subtitle("   File Print - Drive List Query Procedure")
  816. #pragma    page( )
  817.  
  818. /* --- QueryDriveList ---------------------------------- [ Public ] ---    */
  819. /*                                    */
  820. /*     This function is    used to    build a    list of    valid drives.        */
  821. /*                                    */
  822. /*     Upon Entry:                            */
  823. /*                                    */
  824. /*     Nothing                                */
  825. /*                                    */
  826. /*     Upon Exit:                            */
  827. /*                                    */
  828. /*     Nothing                                */
  829. /*                                    */
  830. /* --------------------------------------------------------------------    */
  831.  
  832. static VOID QueryDriveList( )
  833.  
  834. {
  835. CHAR        szDrive[4];           /* Drive Designation    Holder        */
  836. PFSQBUFFER2 psqbf;           /* File System Query    Buffer Pointer    */
  837. ULONG        cbDrvi;           /* Buffer Count            */
  838. ULONG        ulError;           /* OS/2 Error            */
  839. ULONG        ulCurDrive;           /* Current Drive Designation        */
  840. ULONG        ulDriveMask    = 1;       /* Drive Bit    Map Mask        */
  841. register INT i;               /* Loop Counter            */
  842.  
  843.                /* Perform general initialization        */
  844.  
  845. DosQueryCurrentDisk(&ulCurDrive, &ulDriveMap);
  846.  
  847.                /* Allocate space for the file system query    */
  848.                /* buffer                    */
  849.  
  850. psqbf =    (PFSQBUFFER2)malloc(1024UL);
  851. memcpy(&szDrive[1], ":", 2);
  852. DosError(FERR_DISABLEHARDERR);
  853.  
  854. for ( i    = cDrives = 0; i < 26; i++ )
  855.    {
  856.                /* Determine if a disk drive present by masking    */
  857.                /* out the drive    present    bit            */
  858.  
  859.    if (    ulDriveMap & ulDriveMask )
  860.        {
  861.                /* Save the drive designation for the drive    */
  862.                /* that is present                */
  863.  
  864.        aszDrives[cDrives][0] = szDrive[0] = (CHAR)(i + 'A');
  865.        memcpy(&aszDrives[cDrives][1], ":\\ ", 4);
  866.  
  867.                /* Start    with hard disk drives, check to    see if    */
  868.                /* the drive is local or    remote.     Remote    drives    */
  869.                /* are generally    networked drives.  Prominare    */
  870.                /* Builder denotes diskette, local and remote    */
  871.                /* drives within    the Drives/Directories window.    */
  872.        if ( i >    1 )
  873.        {
  874.                /* Initialize the buffer    count before the file    */
  875.                /* system is queried otherwise the call may fail    */
  876.  
  877.        cbDrvi = 1024UL;
  878.  
  879.        if (    (ulError = DosQueryFSAttach(szDrive, 1UL, FSAIL_QUERYNAME,
  880.                         (PFSQBUFFER2)psqbf,
  881.                         &cbDrvi)) == ERROR_NOT_READY )
  882.            afRemoveable[cDrives++] = TRUE;
  883.        else
  884.            if ( !ulError )
  885.            if (    !memcmp(&psqbf->rgFSAData[1], "CDFS", 5) )
  886.                afRemoveable[cDrives++] = TRUE;
  887.            else
  888.                ++cDrives;
  889.        }
  890.        else
  891.        afRemoveable[cDrives++] = TRUE;
  892.        }
  893.                /* Shift    the drive designation bitmap mask    */
  894.    ulDriveMask <<= 1;
  895.    }
  896. DosError(FERR_ENABLEHARDERR);
  897.  
  898.                /* Release the memory allocated for the query    */
  899.                /* buffer                    */
  900. free(psqbf);
  901. }
  902. #pragma    subtitle("   File Print - Directory Retrieval/Display Function")
  903. #pragma    page( )
  904.  
  905. /* --- ulGetDirList -----------------------------------    [ Private ] ---    */
  906. /*                                    */
  907. /*     This function is    used to    search for sub-directories and files    */
  908. /*     within the current sub-directory/drive and place    the entries    */
  909. /*     within two list boxes.                        */
  910. /*                                    */
  911. /*     Upon Entry:                            */
  912. /*                                    */
  913. /*     HWND hwndDrives;    = Drives Combo Box Handle            */
  914. /*     HWND hwndDirs;    = Directories List Box Handle            */
  915. /*     HWND hwndFiles;    = Files    List Box Handle                */
  916. /*                                    */
  917. /*     Upon Exit:                            */
  918. /*                                    */
  919. /*     ulGetDirList = Number of    Files in Files List Box            */
  920. /*                                    */
  921. /* --------------------------------------------------------------------    */
  922.  
  923. static ULONG ulGetDirList(HWND hwndDrives, HWND    hwndDirs, HWND hwndFiles)
  924.  
  925. {
  926. HDIR          hDir = (HDIR)HDIR_CREATE;/* Directory Handle        */
  927. HPOINTER      hptr;           /* Mouse Pointer Handle        */
  928. PFILEFINDBUF3 pfindbuf3;       /* File Find    Buffer            */
  929. PFILEFINDBUF3 pfindbuf;           /* File Find    Buffer            */
  930. ULONG          cFiles = 0UL;       /* Files Count            */
  931. ULONG          ulCurDrive;       /* Current Drive Designation        */
  932. ULONG          ulDrives;           /* Drive Bit    Map Holder        */
  933. ULONG          ulErr;           /* OS/2 Error Value            */
  934. ULONG          ulFileCnt    = 71UL;       /* File Counter Holder        */
  935. register INT i,    n;           /* Loop Counters            */
  936.  
  937. hptr = WinQueryPointer(HWND_DESKTOP);
  938.  
  939.                /* Set the mouse    pointer    to hourglass shape    */
  940.                /* while    directory search taking    place        */
  941.  
  942. WinSetPointer(HWND_DESKTOP,
  943.           WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, FALSE));
  944.  
  945.                /* Allocate memory for a    large directory    search    */
  946.                /* buffer                    */
  947.  
  948. pfindbuf3 = (PFILEFINDBUF3)malloc(71UL * sizeof(FILEFINDBUF3));
  949.  
  950.                /* Get the handles of the list boxes and    disable    */
  951.                /* updating of them while inserting the data    */
  952.                /* into them and    delete the contents within them    */
  953.  
  954. WinEnableWindowUpdate(hwndDirs,     FALSE);
  955. WinEnableWindowUpdate(hwndFiles, FALSE);
  956. WinSendMsg(hwndDirs,  LM_DELETEALL, 0L,    0L);
  957. WinSendMsg(hwndFiles, LM_DELETEALL, 0L,    0L);
  958.  
  959.                /* Start    directory search            */
  960.  
  961. if ( !(ulErr = DosFindFirst("*.*", &hDir, MUST_HAVE_DIRECTORY |    FILE_DIRECTORY,
  962.                 (PVOID)pfindbuf3, 71UL * sizeof(FILEFINDBUF3),
  963.                 &ulFileCnt,    FIL_STANDARD)) )
  964.    {
  965.    do
  966.        for ( i = 0, pfindbuf = pfindbuf3; i < ulFileCnt; i++ )
  967.        {
  968.                /* If file found    a sub-directory, place into the    */
  969.                /* Directories list box                */
  970.  
  971.        if (    (pfindbuf->attrFile & FILE_DIRECTORY) && memcmp(pfindbuf->achName, ".",    2) )
  972.            WinSendMsg(hwndDirs, LM_INSERTITEM,
  973.               MPFROMSHORT(LIT_SORTASCENDING),
  974.               MPFROMP(pfindbuf->achName));
  975.        pfindbuf = (PFILEFINDBUF3)((PBYTE)pfindbuf +    pfindbuf->oNextEntryOffset);
  976.        }
  977.        while ( (ulFileCnt == 71UL) &&
  978.            !DosFindNext(hDir, pfindbuf3, 71UL * sizeof(FILEFINDBUF3), &ulFileCnt) );
  979.  
  980.                /* Close    directory search handle            */
  981.    DosFindClose(hDir);
  982.    }
  983. else
  984.    if (    ulErr != ERROR_NO_MORE_FILES )
  985.        {
  986.                /* Release the memory allocated for the search    */
  987.                /* buffer                    */
  988.  
  989.        free((PVOID)pfindbuf3);
  990.        return(0);
  991.        }
  992.  
  993. if ( !fDrivesFilled )
  994.    {
  995.                /* Form the current drive/path and display    */
  996.                /* within the Path display field            */
  997.  
  998.    DosQueryCurrentDisk(&ulCurDrive, &ulDrives);
  999.    if (    ulDriveMap != ulDrives )
  1000.        QueryDriveList( );
  1001.    for ( i = 0;    i < cDrives; i++ )
  1002.        {
  1003.        if ( !afRemoveable[i] )
  1004.        DiskVolDrive((ULONG)(i + 1),    &aszDrives[i][4]);
  1005.        else
  1006.        aszDrives[i][4] = 0;
  1007.        n = (INT)LONGFROMMR(WinSendMsg(hwndDrives, LM_INSERTITEM, MPFROMSHORT(LIT_END),
  1008.                 MPFROMP(aszDrives[i])));
  1009.        if ( i == (ulCurDrive - 1) )
  1010.        WinSendMsg(hwndDrives, LM_SELECTITEM,
  1011.               MPFROMLONG(n), MPFROMLONG(TRUE));
  1012.        }
  1013.    fDrivesFilled = TRUE;
  1014.    }
  1015.                /* Reset    directory handle and file counter    */
  1016. hDir = (HDIR)HDIR_CREATE;
  1017. ulFileCnt = 71UL;
  1018.                /* Start    file search                */
  1019.  
  1020. if ( !(ulErr = DosFindFirst("*.*", &hDir, FILE_NORMAL,
  1021.                 (PVOID)pfindbuf3, 71UL * sizeof(FILEFINDBUF3),
  1022.                 &ulFileCnt,    FIL_STANDARD)) )
  1023.    {
  1024.    do
  1025.        for ( i = 0, pfindbuf = pfindbuf3; i < ulFileCnt; i++ )
  1026.        {
  1027.                /* If file found    not a sub-directory, place    */
  1028.                /* filename in list box                */
  1029.  
  1030.        if (    (pfindbuf->attrFile & FILE_DIRECTORY) != FILE_DIRECTORY    )
  1031.            {
  1032.            ++cFiles;
  1033.            WinSendMsg(hwndFiles, LM_INSERTITEM,
  1034.               MPFROMSHORT(LIT_SORTASCENDING),
  1035.               MPFROMP(pfindbuf->achName));
  1036.            }
  1037.        pfindbuf = (PFILEFINDBUF3)((PBYTE)pfindbuf +    pfindbuf->oNextEntryOffset);
  1038.        }
  1039.                /* Search for remaining entries and place valid    */
  1040.                /* entries in list box                */
  1041.  
  1042.        while ( (ulFileCnt == 71UL) &&
  1043.         !DosFindNext(hDir, pfindbuf3, 71UL * sizeof(FILEFINDBUF3), &ulFileCnt) );
  1044.  
  1045.                /* Close    directory search handle            */
  1046.    DosFindClose(hDir);
  1047.    }
  1048. else
  1049.    if (    ulErr != ERROR_NO_MORE_FILES )
  1050.        {
  1051.                /* Release the memory allocated for the search    */
  1052.                /* buffer                    */
  1053.  
  1054.        free((PVOID)pfindbuf3);
  1055.        return(0);
  1056.        }
  1057.                /* Release the memory allocated for the search    */
  1058.                /* buffer                    */
  1059. free((PVOID)pfindbuf3);
  1060.                /* Re-enable updating to    the list boxes and    */
  1061.                /* force    the displaying of the new contents    */
  1062.  
  1063. WinShowWindow(hwndDirs,    TRUE);
  1064. WinShowWindow(hwndFiles, TRUE);
  1065.  
  1066.                /* Reset    edit field text    in case    invalid    search    */
  1067.                /* spec entered and reset mouse pointer back to    */
  1068.                /* arrow    shape                    */
  1069.  
  1070. WinSetPointer(HWND_DESKTOP, hptr);
  1071. return(cFiles);
  1072. }
  1073. #pragma    subtitle("   File Print - File Line Printing Routine")
  1074. #pragma    page( )
  1075.  
  1076. /* --- PrnLine ----------------------------------------    [ Private ] ---    */
  1077. /*                                    */
  1078. /*     This function is    used to    print a    multiple line entry such that    */
  1079. /*     when the    string is wider    than the printable area    it is properly    */
  1080. /*     truncated and the remainder printed on the next line or lines.    */
  1081. /*                                    */
  1082. /*     This routine is recursive.                    */
  1083. /*                                    */
  1084. /*     Upon Entry:                            */
  1085. /*                                    */
  1086. /*     HPS     hpsPrinter;  = Presentation Space Handle            */
  1087. /*     HDC     hdcPrinter;  = Device Context Handle            */
  1088. /*     PSZ     pszStr;        = String to    Print                */
  1089. /*     PPOINTL pptl;        = Display Point                */
  1090. /*     PPOINTL pptlFooter;  = Footer Display Point            */
  1091. /*     PSIZEL  psizlPage;   = Page Size                    */
  1092. /*     LONG    yShift;        = Vertical Line Shift            */
  1093. /*     BOOL    fDateFooter; = Print Footer Flag                */
  1094. /*     PSZ     pszFooter;   = Footer String                */
  1095. /*     PULONG  pcPages;        = Page Counter Pointer            */
  1096. /*                                    */
  1097. /*     Upon Exit:                            */
  1098. /*                                    */
  1099. /*     fPrnLine    =  TRUE    : New Page Started                */
  1100. /*        = FALSE    : Normal Line Printed                */
  1101. /*                                    */
  1102. /* --------------------------------------------------------------------    */
  1103.  
  1104. static BOOL fPrnLine(HPS hpsPrinter, HDC hdcPrinter, PSZ pszStr,
  1105.              PPOINTL pptl, PPOINTL pptlFooter, PSIZEL psizlPage, LONG yShift,
  1106.              BOOL fDateFooter, PSZ pszFooter, PULONG pcPages)
  1107.  
  1108. {
  1109. PPOINTL    aptlLimits;           /* Limits Point Array Pointer    */
  1110. POINTL    aptl[TXTBOX_COUNT];       /* Character    Text Box Array        */
  1111. register INT i,    n;           /* Index                */
  1112.  
  1113.                /* Check    to see if the length of    the string is    */
  1114.                /* greater than 512 characters.    Present    GPI    */
  1115.                /* functions cannot handle greater than 512    */
  1116.                /* characters.                    */
  1117.  
  1118. if ( (n    = (INT)strlen(pszStr)) > 512 )
  1119.    n = 512;
  1120.                /* Determine the    width of the line        */
  1121.  
  1122. GpiQueryTextBox(hpsPrinter, n, pszStr, TXTBOX_COUNT, aptl);
  1123.  
  1124.                /* Check    to see if the width is less than the    */
  1125.                /* width    of the page                */
  1126.  
  1127. if ( aptl[TXTBOX_CONCAT].x < (psizlPage->cx - 720L) )
  1128.    GpiCharStringAt(hpsPrinter, pptl, n,    pszStr);
  1129. else
  1130.    {
  1131.                /* Allocate memory for the point    array to allow    */
  1132.                /* the proper break to be found            */
  1133.  
  1134.    DosAllocMem((PPVOID)(PVOID)&aptlLimits, (ULONG)(n * sizeof(POINTL)),
  1135.            PAG_READ    | PAG_WRITE | PAG_COMMIT);
  1136.  
  1137.                /* Get the point    position of each character    */
  1138.                /* within the string                */
  1139.  
  1140.    GpiQueryCharStringPosAt(hpsPrinter, pptl, 0UL, n, pszStr, (PLONG)NULL, aptlLimits);
  1141.  
  1142.                /* Search for a break character            */
  1143.  
  1144.    if (    strchr(pszStr, ' ') )
  1145.        {
  1146.        for ( i = n - 1;    i > 0; i-- )
  1147.        if (    aptlLimits[i].x    < (pptl->x + (psizlPage->cx - 720L)) )
  1148.            {
  1149.            while ( pszStr[i] && (pszStr[i] != ' ') )
  1150.            --i;
  1151.            ++i;
  1152.            break;
  1153.            }
  1154.        }
  1155.    else
  1156.                /* No break character found, look for a clean    */
  1157.                /* location where the forced break can occur    */
  1158.  
  1159.        for ( i = 0; i <    n; i++ )
  1160.        if (    aptlLimits[i].x    > (pptl->x + (psizlPage->cx - 720L)) )
  1161.            break;
  1162.                /* Release the memory allocated for the point    */
  1163.                /* array                        */
  1164.  
  1165.    DosFreeMem((PVOID)aptlLimits);
  1166.  
  1167.                /* Display the string                */
  1168.  
  1169.    GpiCharStringAt(hpsPrinter, pptl, i,    pszStr);
  1170.  
  1171.                /* Update the string pointer and    check to see    */
  1172.                /* if any more characters should    be displayed    */
  1173.    pszStr += i;
  1174.    if (    *pszStr    )
  1175.        {
  1176.                /* Update the position on the page        */
  1177.  
  1178.        if ( (pptl->y -=    yShift)    < 720L )
  1179.        {
  1180.                /* Have reached the bottom of the page, display    */
  1181.                /* the footer for the page            */
  1182.  
  1183.        if (    fDateFooter )
  1184.            GpiCharStringAt(hpsPrinter, pptlFooter, 37L, pszFooter);
  1185.  
  1186.                /* Force    the ejection of    the page        */
  1187.  
  1188.        DevEscape(hdcPrinter, DEVESC_NEWFRAME, 0L, NULL, NULL, NULL);
  1189.  
  1190.                /* Reset    the pointer to the top of the page    */
  1191.  
  1192.        pptl->y = psizlPage->cy - yShift * TOP_MARGIN;
  1193.        ++(*pcPages);
  1194.        }
  1195.                /* Print    the remaining portion of the string    */
  1196.  
  1197.        return(fPrnLine(hpsPrinter, hdcPrinter, pszStr,
  1198.                pptl, pptlFooter, psizlPage, yShift,
  1199.                fDateFooter, pszFooter, pcPages));
  1200.        }
  1201.    }
  1202.                /* Update the position on the page        */
  1203.  
  1204. if ( (pptl->y -= yShift) < 720L    )
  1205.    {
  1206.                /* Have reached the bottom of the page, display    */
  1207.                /* the footer for the page            */
  1208.  
  1209.    if (    fDateFooter )
  1210.        GpiCharStringAt(hpsPrinter, pptlFooter, 37L, pszFooter);
  1211.  
  1212.                /* Force    the ejection of    the page        */
  1213.  
  1214.    DevEscape(hdcPrinter, DEVESC_NEWFRAME, 0L, NULL, NULL, NULL);
  1215.  
  1216.                /* Reset    the pointer to the top of the page    */
  1217.  
  1218.    pptl->y = psizlPage->cy - yShift * TOP_MARGIN;
  1219.    ++(*pcPages);
  1220.    return(TRUE);
  1221.    }
  1222. else
  1223.    return(FALSE);
  1224. }
  1225. #pragma    subtitle("   File Print - File Printing Routine")
  1226. #pragma    page( )
  1227.  
  1228. /* --- PrnFile ----------------------------------------    [ Private ] ---    */
  1229. /*                                    */
  1230. /*     This function is    used to    read in    the file selected and        */
  1231. /*     provide the appropriate decoding    for printing the file.        */
  1232. /*     The function constructs a line from the file and    then        */
  1233. /*     determines if further decoding is required or to    print        */
  1234. /*     constructed line.                        */
  1235. /*                                    */
  1236. /*     Upon Entry:                            */
  1237. /*                                    */
  1238. /*     PPRNDATA    pprni; = Print Information Pointer            */
  1239. /*                                    */
  1240. /*     Upon Exit:                            */
  1241. /*                                    */
  1242. /*     Nothing                                */
  1243. /*                                    */
  1244. /* --------------------------------------------------------------------    */
  1245.  
  1246. VOID _System PrnFile(PPRNDATA pprni)
  1247.  
  1248. {
  1249. BOOL        fEndOfFile;           /* End of File Flag            */
  1250. BOOL        fNewPage;           /* New Page Flag            */
  1251. BYTE        bCh;           /* Input Character            */
  1252. BYTE        szLineBuf[8];       /* Line Number Buffer        */
  1253. BYTE        szFooter[48];       /* Footer Buffer            */
  1254. DATETIME    dt;               /* Date and Time Holder        */
  1255. FILESTATUS3 fs;               /* File Status            */
  1256. FONTMETRICS fmPrn;           /* Font Metrics Info            */
  1257. HAB        habThread;           /* Thread Anchor Block Handle    */
  1258. HCINFO        hci;           /* Hard Copy    Information Structure    */
  1259. HDC        hdcPrinter;           /* Printer Device Context Handle    */
  1260. HFILE        hFile;           /* Input File Handle            */
  1261. HPS        hpsPrinter;           /* Printer Presentation Space Handle    */
  1262. INT        cLineNum;           /* Line Number Character Counter    */
  1263. INT        cLines;           /* Line Number Counter        */
  1264. LONG        lOut;           /* Output Count            */
  1265. LONG        lcid;           /* Logical Font ID            */
  1266. LONG        sPos;           /* Current Buffer Position        */
  1267. PBYTE        pbInputBuffer;       /* File Input Buffer            */
  1268. PBYTE        pszOutPutLine;       /* Formatted    Output Buffer        */
  1269. POINTL        ptl;           /* Display Point            */
  1270. POINTL        ptlFooter;           /* Display Point            */
  1271. SIZEL        sizlPage;           /* Page Size    Holder            */
  1272. ULONG        cPages;           /* Page Count            */
  1273. ULONG        cbRead;           /* Bytes Read            */
  1274. ULONG        ulAction;           /* Action Taken            */
  1275. USHORT        usJobID;           /* Spooler Job ID            */
  1276. register INT i;               /* Loop Counter            */
  1277. register UINT sPointer;           /* Input Buffer Pointer        */
  1278.  
  1279.                /* Get an anchor    block handle to    allow proper    */
  1280.                /* thread initialization    of stack space and    */
  1281.                /* usage    of some    PM calls.  Create a message    */
  1282.                /* queue    as well    to make    sure that everything    */
  1283.                /* works    properly in terms of error message    */
  1284.                /* display.                    */
  1285.  
  1286. habThread = WinInitialize(0UL);
  1287.  
  1288.                /* Open a device    context    for the    printer        */
  1289.                /* selected                    */
  1290.  
  1291. if ( (hdcPrinter = PrnOpenDC(&pprni->prn, "PM_Q_STD")) != (HDC)NULL )
  1292.    {
  1293.                /* Create a presentation    space into which the    */
  1294.                /* printing will    occur using TWIPS as the unit    */
  1295.                /* of measure                    */
  1296.  
  1297.    sizlPage.cx = sizlPage.cy = 0L;
  1298.    hpsPrinter =    GpiCreatePS(habThread, hdcPrinter, &sizlPage, PU_TWIPS |
  1299.                 GPIF_DEFAULT | GPIT_NORMAL | GPIA_ASSOC);
  1300.  
  1301.                /* Start    the printing of    the selected file by    */
  1302.                /* indicating the start of the document within    */
  1303.                /* device context                */
  1304.  
  1305.    if (    DevEscape(hdcPrinter, DEVESC_STARTDOC, (LONG)strlen(pprni->szTitle),
  1306.           pprni->szTitle, NULL,    NULL) != DEVESC_ERROR )
  1307.        {
  1308.                /* Determine the    size of    the output area        */
  1309.  
  1310.        GpiQueryPS(hpsPrinter, &sizlPage);
  1311.  
  1312.                /* Select and scale the font for    the printer    */
  1313.  
  1314.        lcid = ScaleFont(hpsPrinter, pprni->fsel.szFacename,
  1315.             pprni->fsel.lNominalPointSize);
  1316.  
  1317.                /* Get the new font metrics for the scaled font    */
  1318.                /* and determine    the number of lines that can be    */
  1319.                /* contained within the page            */
  1320.  
  1321.        GpiQueryFontMetrics(hpsPrinter, sizeof(FONTMETRICS), &fmPrn);
  1322.  
  1323.                /* Determine the    hard copy capabilities for the    */
  1324.                /* form selected.  Note that all    values returned    */
  1325.                /* are in millimetres except for    the xPels and    */
  1326.                /* yPels    elements.                */
  1327.  
  1328.        DevQueryHardcopyCaps(hdcPrinter,    0L, 1L,    &hci);
  1329.  
  1330.        DosAllocMem((PPVOID)(PVOID)&pszOutPutLine, 4096UL, PAG_READ | PAG_WRITE | PAG_COMMIT);
  1331.  
  1332.                /* Provide a 1/2    inch left margin including any    */
  1333.                /* device provided margin.  There are 57    twips    */
  1334.                /* per millimetre.                */
  1335.  
  1336.        ptl.x = 1080L - hci.xLeftClip * 57L;
  1337.  
  1338.        if ( pprni->fDateFooter )
  1339.        {
  1340.        DosGetDateTime(&dt);
  1341.  
  1342.                /* Copy the masking string into the buffer and    */
  1343.                /* copy the day and month strings into the    */
  1344.                /* buffer                    */
  1345.  
  1346.        memcpy(szFooter, "Printed:  Tue Jan 01 00:00:00.00 1970", 38);
  1347.        memcpy(&szFooter[10], (PCHAR)(szDayNames + (dt.weekday * 3)), 3);
  1348.        memcpy(&szFooter[14], (PCHAR)(szMonthNames +    ((dt.month - 1)    * 3)), 3);
  1349.  
  1350.                /* Point    to the day of the month    within the    */
  1351.                /* buffer and store the day of the month    within    */
  1352.                /* the buffer (1    - 31)                */
  1353.  
  1354.        szFooter[18]    = (CHAR)('0' + (dt.day / 10));
  1355.        szFooter[19]    = (CHAR)('0' + (dt.day % 10));
  1356.  
  1357.                /* Store    the hours within the buffer (0 - 23)    */
  1358.  
  1359.        szFooter[21]    = (CHAR)('0' + (dt.hours / 10));
  1360.        szFooter[22]    = (CHAR)('0' + (dt.hours % 10));
  1361.  
  1362.                /* Store    the minutes within the buffer (0 - 59)    */
  1363.         
  1364.        szFooter[24]    = (CHAR)('0' + (dt.minutes / 10));
  1365.        szFooter[25]    = (CHAR)('0' + (dt.minutes % 10));
  1366.  
  1367.                /* Store    the seconds within the buffer (0 - 59)    */
  1368.  
  1369.        szFooter[27]    = (CHAR)('0' + (dt.seconds / 10));
  1370.        szFooter[28]    = (CHAR)('0' + (dt.seconds % 10));
  1371.  
  1372.                /* Store    the hundredths within the buffer    */
  1373.                /* (0 - 100)                    */
  1374.  
  1375.        szFooter[30]    = (CHAR)('0' + (dt.hundredths /    10));
  1376.        szFooter[31]    = (CHAR)('0' + (dt.hundredths %    10));
  1377.  
  1378.                /* Store    the year within    the buffer        */
  1379.  
  1380.        szFooter[33]    = (CHAR)('0' + ((dt.year / 100)    / 10));
  1381.        szFooter[34]    = (CHAR)('0' + ((dt.year / 100)    % 10));
  1382.        szFooter[35]    = (CHAR)('0' + ((dt.year % 100)    / 10));
  1383.        szFooter[36]    = (CHAR)('0' + ((dt.year % 100)    % 10));
  1384.        ptlFooter.x = 1080L - hci.xLeftClip * 57L;
  1385.        ptlFooter.y = TOP_MARGIN / 2L;
  1386.        }
  1387.  
  1388.                /* Open the requested file for printing        */
  1389.  
  1390.        for ( i = 0; i <    pprni->cPrnFiles; i++ )
  1391.        {
  1392.        if (    DosOpen(pprni->aszFiles[i], &hFile, &ulAction, 0UL, FILE_NORMAL,
  1393.             OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW,
  1394.             OPEN_ACCESS_READONLY | OPEN_SHARE_DENYWRITE, NULL) )
  1395.            continue;
  1396.        else
  1397.            {
  1398.                /* Get the file information for the file    which    */
  1399.                /* will allow the size of the file to be        */
  1400.                /* determined and allow the entire file to be    */
  1401.                /* read in in one read                */
  1402.  
  1403.            DosQueryFileInfo(hFile, FIL_STANDARD, (PVOID)&fs, sizeof(FILESTATUS3));
  1404.            DosAllocMem((PPVOID)(PVOID)&pbInputBuffer, fs.cbFile + 1UL, PAG_READ | PAG_WRITE    | PAG_COMMIT);
  1405.            DosRead(hFile, (PVOID)pbInputBuffer, fs.cbFile, &cbRead);
  1406.  
  1407.                /* Close    the file opened    for printing and clear    */
  1408.                /* the printing active flag            */
  1409.  
  1410.            DosClose(hFile);
  1411.  
  1412.            cLines     = 1;
  1413.            cPages     = 1;
  1414.            fNewPage     = TRUE;
  1415.            sPointer    = 0;
  1416.            fEndOfFile = FALSE;
  1417.  
  1418.                /* Check    to see if line numbers requested and if    */
  1419.                /* required form    the start of the line        */
  1420.  
  1421.            if ( pprni->fLineNumbers    )
  1422.            {
  1423.            memcpy(pszOutPutLine, " 00000: ", 9);
  1424.            sPos    = 8;
  1425.            }
  1426.            else
  1427.            {
  1428.            pszOutPutLine[0] = 0;
  1429.            sPos    = 0;
  1430.            }
  1431.                /* Enter    the loop that reads in the requested    */
  1432.                /* file,    and sends it to    the printing context    */
  1433.            do
  1434.            {
  1435.            if (    sPointer >= cbRead )
  1436.  
  1437.                /* Logical End-of-File encountered, set        */
  1438.                /* character to End-of-File value        */
  1439.  
  1440.                bCh = 26;
  1441.            else
  1442.                /* Get a    character from the file    input buffer    */
  1443.  
  1444.                bCh = pbInputBuffer[sPointer++];
  1445.  
  1446.                /* Decode character to line demarcation values    */
  1447.            switch ( bCh    )
  1448.                {
  1449.                case CR :
  1450.                continue;
  1451.  
  1452.                case TAB    :
  1453.                do pszOutPutLine[sPos] = ' ';
  1454.                    while ( ++sPos %    8 );
  1455.                break;
  1456.  
  1457.                case TOF    :
  1458.  
  1459.                /* Complete the printing    of the page and    set    */
  1460.                /* new page flag    before returning        */
  1461.  
  1462.                if (    pprni->fDateFooter )
  1463.                    GpiCharStringAt(hpsPrinter, &ptlFooter, 37L, szFooter);
  1464.                DevEscape(hdcPrinter, DEVESC_NEWFRAME, 0L, NULL, NULL, NULL);
  1465.                fNewPage = TRUE;
  1466.                break;
  1467.  
  1468.                case LF :
  1469.  
  1470.                /* Line feed signifying end-of-line encountered    */
  1471.                /* complete the line and    send for processing    */
  1472.                /* and printing                    */
  1473.  
  1474.                pszOutPutLine[sPos] = 0;
  1475.                if (    fNewPage )
  1476.                    {
  1477.                /* Form top margin co-ordinates            */
  1478.  
  1479.                    ptl.y = sizlPage.cy - fmPrn.lMaxBaselineExt * TOP_MARGIN;
  1480.  
  1481.                /* Reset    new page flag                */
  1482.  
  1483.                    fNewPage    = FALSE;
  1484.                    }
  1485.                if (    pprni->fLineNumbers )
  1486.                    {
  1487.                    cLineNum    = (INT)strlen(itoa(cLines++, szLineBuf,    10));
  1488.  
  1489.                    memcpy(&pszOutPutLine[6 - cLineNum], szLineBuf, (UINT)cLineNum);
  1490.                    }
  1491.  
  1492.                /* Print    out formatted line            */
  1493.  
  1494.                fNewPage = fPrnLine(hpsPrinter, hdcPrinter, pszOutPutLine,
  1495.                            &ptl, &ptlFooter, &sizlPage, fmPrn.lMaxBaselineExt,
  1496.                            pprni->fDateFooter, szFooter, &cPages);
  1497.                if (    pprni->fLineNumbers )
  1498.                    sPos = 8;
  1499.                else
  1500.                    sPos = 0;
  1501.                break;
  1502.  
  1503.                case 26 :
  1504.  
  1505.                /* End-of-File mark encounted, set end-of-file    */
  1506.                /* file to stop input processing            */
  1507.  
  1508.                fEndOfFile =    TRUE;
  1509.                break;
  1510.  
  1511.                /* Normal character, save in output buffer    */
  1512.  
  1513.                default :
  1514.                pszOutPutLine[sPos++] = bCh;
  1515.                }
  1516.            } while ( !fEndOfFile );
  1517.  
  1518.            if ( !fNewPage && ((i + 1) != pprni->cPrnFiles) )
  1519.            {
  1520.            if (    pprni->fDateFooter )
  1521.                GpiCharStringAt(hpsPrinter, &ptlFooter, 37L, szFooter);
  1522.            DevEscape(hdcPrinter, DEVESC_NEWFRAME, 0L, NULL, NULL, NULL);
  1523.            if (    cPages % 2 )
  1524.                {
  1525.                if ( pprni->fDateFooter )
  1526.                GpiCharStringAt(hpsPrinter, &ptlFooter, 37L,    szFooter);
  1527.                DevEscape(hdcPrinter, DEVESC_NEWFRAME, 0L, NULL,    NULL, NULL);
  1528.                }
  1529.            }
  1530.            }
  1531.        DosFreeMem((PVOID)pbInputBuffer);
  1532.        }
  1533.        if ( pprni->fDateFooter )
  1534.        GpiCharStringAt(hpsPrinter, &ptlFooter, 37L,    szFooter);
  1535.        DosFreeMem((PVOID)pszOutPutLine);
  1536.  
  1537.                /* Reset    the character set back to the default    */
  1538.  
  1539.        GpiSetCharSet(hpsPrinter, 0L);
  1540.        GpiDeleteSetId(hpsPrinter, lcid);
  1541.  
  1542.                /* Inform the device context printing complete    */
  1543.                /* to allow the correct spooling    and final    */
  1544.                /* printing to occur                */
  1545.        lOut = 2L;
  1546.        DevEscape(hdcPrinter, DEVESC_ENDDOC, 0L,    NULL, &lOut, (PBYTE)&usJobID);
  1547.  
  1548.                /* Release and destroy both the printing        */
  1549.                /* presentation space and device    context    handles    */
  1550.  
  1551.        GpiAssociate(hpsPrinter,    (HDC)NULL);
  1552.        GpiDestroyPS(hpsPrinter);
  1553.        DevCloseDC(hdcPrinter);
  1554.        }
  1555.    }
  1556. DosFreeMem((PVOID)pprni);
  1557.  
  1558.                /* Destroy the message queue used by the    thread    */
  1559.                /* and destroy the anchor block before exiting    */
  1560.                /* the thread                    */
  1561. WinTerminate(habThread);
  1562.  
  1563. DosExit(EXIT_THREAD, 0UL);
  1564. }
  1565.