home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / prnt3.zip / PrnAPI.C < prev    next >
C/C++ Source or Header  |  1995-05-09  |  27KB  |  798 lines

  1. #pragma    title("Printer Driver  --  Version 3  --  (PrnAPI.C)")
  2. #pragma    subtitle("   Printer API's - 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_GPI           /* Include OS/2 PM GPI Interface    */
  9. #define    INCL_SPL           /* Include OS/2 PM Spooler Interface    */
  10. #define    INCL_SPLDOSPRINT
  11. #define    INCL_WIN           /* Include OS/2 PM Windows Interface    */
  12.  
  13. #include <malloc.h>
  14. #include <os2.h>
  15. #include <string.h>
  16.  
  17. #include "appdefs.h"
  18. #include "prnsetup.h"
  19.  
  20. /* This    file contains the printer support functions that can be    used    */
  21. /* to select a printer,    manipulate job properties, and open a DC    */
  22. /* for printing.                            */
  23.  
  24. /* Filename:   PrnAPI.C                            */
  25.  
  26. /*  Version:   3                            */
  27. /*  Created:   1995-02-09                        */
  28. /*  Revised:   1995-03-10                        */
  29.  
  30. /* Routines:   BOOL PrnCreatePrinterList(PPRN pprn);            */
  31. /*           BOOL PrnDestroyPrinterList(PPRN pprn);            */
  32. /*           HDC PrnOpenDC(PPRN pprn,    PSZ pszDataType);        */
  33. /*           HDC PrnOpenInfoDC(PPRN pprn, PSZ    pszDataType);        */
  34. /*           BOOL PrnQueryJobProperties(PPRN pprn, INT iQueue);    */
  35. /*           PSZ PrnQueryPrinterName(PPRN pprn);            */
  36. /*           MRESULT EXPENTRY    PrnSetupDlgProc(HWND hWnd, ULONG msg,    */
  37. /*                        MPARAM mp1, MPARAM mp2);*/
  38. /*           LONG SelectFont(HDC hDC,    HPS hPS, CHAR *pszFacename,    */
  39. /*                   LONG lPoints);                */
  40. /*           LONG SelectScalableFont(HPS hPS,    CHAR *pszFacename);    */
  41. /*           LONG ScaleFont(HPS hPS, CHAR *pszFacename, LONG lSize);    */
  42.  
  43. /************************************************************************/
  44. /************************************************************************/
  45. /************************************************************************/
  46. /* DISCLAIMER OF WARRANTIES:                        */
  47. /* -------------------------                        */
  48. /* The following [enclosed] code is sample code    created    by IBM        */
  49. /* Corporation and Prominare Inc.  This    sample code is not part    of any    */
  50. /* standard IBM    product    and is provided    to you solely for the purpose    */
  51. /* of assisting    you in the development of your applications.  The code    */
  52. /* is provided "AS IS",    without    warranty of any    kind.  Neither IBM nor    */
  53. /* Prominare shall be liable for any damages arising out of your    */
  54. /* use of the sample code, even    if they    have been advised of the    */
  55. /* possibility of such damages.                        */
  56. /************************************************************************/
  57. /************************************************************************/
  58. /************************************************************************/
  59. /*               D I S C L A I M E R                */
  60. /* This    code is    provided on an as is basis with    no implied support.    */
  61. /* It should be    considered freeware that cannot    be rebundled as        */
  62. /* part    of a larger "*ware" offering without our consent.        */
  63. /************************************************************************/
  64. /************************************************************************/
  65. /************************************************************************/
  66.  
  67. /* Copyright ╕ International Business Machines Corp., 1995.        */
  68. /* Copyright ╕ 1995  Prominare Inc.  All Rights    Reserved.        */
  69.  
  70. /* --------------------------------------------------------------------    */
  71.  
  72. #pragma    subtitle("   Printer Control - Create Printer List Function")
  73. #pragma    page( )
  74.  
  75. /* --- PrnCreatePrinterList ---------------------------- [ Public ] ---    */
  76. /*                                    */
  77. /*     This function is    construct a list of printers.            */
  78. /*                                    */
  79. /*     Upon Entry:                            */
  80. /*                                    */
  81. /*     PPRN pprn; = Printer Control Structure Pointer            */
  82. /*                                    */
  83. /*     Upon Exit:                            */
  84. /*                                    */
  85. /*     PrnCreatePrinterList =  TRUE : Queue List Retrieved        */
  86. /*                = FALSE : No Queue List Retrieved        */
  87. /*                                    */
  88. /* --------------------------------------------------------------------    */
  89.  
  90. BOOL PrnCreatePrinterList(PPRN pprn)
  91.  
  92. {
  93. PCHAR      pch;               /* String Character Pointer        */
  94. PPRQINFO3 pQueueInfo;           /* Queue Information            */
  95. ULONG      aulVersion[2];       /* Version Number Holder        */
  96. ULONG      cReturned;           /* Returned Queue Count        */
  97. ULONG      cTotal;           /* Total Count            */
  98. ULONG      cbNeeded;           /* Buffer Size            */
  99. register INT i;               /* Loop Counter            */
  100. register UINT n;           /* Loop Counter            */
  101.  
  102. DosQuerySysInfo(QSV_VERSION_MAJOR, QSV_VERSION_REVISION, aulVersion,
  103.         2UL * sizeof(ULONG));
  104.  
  105.                /* Determine the    amount of memory required for    */
  106.                /* queue    information                */
  107.  
  108. SplEnumQueue((PSZ)NULL,    3UL, (PVOID)NULL, 0UL, &cReturned, &cTotal,
  109.          &cbNeeded,    NULL);
  110.  
  111.                /* Check    to see if any printers were detected    */
  112.                /* and if none were found, return with the no    */
  113.                /* no queue list    retrieved flag            */
  114. if ( cTotal == 0L )
  115.    {
  116.    pprn->hAB     = 0UL;
  117.    pprn->cQueues = 0;
  118.    return(FALSE);
  119.    }
  120.                /* Allocate memory for the queue    list        */
  121.  
  122. if ( DosAllocMem((PPVOID)(PVOID)&pQueueInfo, cbNeeded, PAG_READ    | PAG_WRITE | PAG_COMMIT) )
  123.    {
  124.    pprn->hAB     = 0UL;
  125.    pprn->cQueues = 0;
  126.    return(FALSE);
  127.    }
  128.                /* Retrieve the queue list from the system    */
  129.  
  130. SplEnumQueue((PSZ)NULL,    3UL, (PVOID)pQueueInfo,    cbNeeded, &cReturned,
  131.          &cTotal, &cbNeeded, NULL);
  132.  
  133. pprn->pquei = (PQUEINFO)malloc(sizeof(QUEINFO) * cTotal);
  134.  
  135.                /* Scan the queue list looking for the entry    */
  136.                /* that contains    the default queue and when    */
  137.                /* found, save the queue    index entry        */
  138.  
  139. for ( i    = 0; i < cReturned; i++    )
  140.    {
  141.    if (    pQueueInfo[i].pszName )
  142.        {
  143.        pprn->pquei[i].pszName =    (PSZ)malloc((n = strlen(pQueueInfo[i].pszName) + 1));
  144.        memcpy(pprn->pquei[i].pszName, pQueueInfo[i].pszName, n);
  145.        }
  146.    else
  147.        pprn->pquei[i].pszName =    NULL;
  148.  
  149.    if (    pQueueInfo[i].pszDriverName )
  150.        {
  151.        pprn->pquei[i].pszDriverName = (PSZ)malloc((n = strlen(pQueueInfo[i].pszDriverName) + 1));
  152.        memcpy(pprn->pquei[i].pszDriverName, pQueueInfo[i].pszDriverName, n);
  153.        }
  154.    else
  155.        pprn->pquei[i].pszDriverName = NULL;
  156.  
  157.    if (    pQueueInfo[i].pszPrinters )
  158.        {
  159.        pprn->pquei[i].pszPrinters = (PSZ)malloc((n = strlen(pQueueInfo[i].pszPrinters) + 1));
  160.        memcpy(pprn->pquei[i].pszPrinters, pQueueInfo[i].pszPrinters, n);
  161.        }
  162.    else
  163.        pprn->pquei[i].pszPrinters = NULL;
  164.  
  165.    pprn->pquei[i].pDriverData =    (PSZ)malloc((ULONG)pQueueInfo[i].pDriverData->cb);
  166.    memcpy(pprn->pquei[i].pDriverData, pQueueInfo[i].pDriverData, (ULONG)pQueueInfo[i].pDriverData->cb);
  167.  
  168.                /* Check    for the    default    queue            */
  169.  
  170.    if (    ((aulVersion[0]    == 20UL) && (aulVersion[1] >= 10UL)) ||    (aulVersion[0] > 20UL) )
  171.        if ( pQueueInfo[i].fsType & PRQ3_TYPE_APPDEFAULT    )
  172.        pprn->iQueue    = i;
  173.    }
  174.  
  175. if ( (aulVersion[0] == 20UL) &&    (aulVersion[1] < 10UL) )
  176.    {
  177.                /* Get the default queue    to use            */
  178.  
  179.    if (    PrfQueryProfileString(HINI_PROFILE, "PM_SPOOLER", "QUEUE", NULL,
  180.                   pprn->szQueue, 256UL) )
  181.        {
  182.                /* Truncate the semicolon delimiter in the queue    */
  183.                /* name                        */
  184.  
  185.        pch = strchr(pprn->szQueue, ';');
  186.        *pch = 0;
  187.        }
  188.    else
  189.                /* No default queue name    found, use the first    */
  190.                /* printer from the list                */
  191.  
  192.        strcpy(pprn->szQueue, pQueueInfo->pszName);
  193.  
  194.                /* Scan the queue list looking for the entry    */
  195.                /* that contains    the default queue and when    */
  196.                /* found, save the queue    index entry        */
  197.  
  198.    for ( i = 0;    i < cReturned; i++ )
  199.        if ( !strcmp(pprn->szQueue, pQueueInfo[i].pszName) )
  200.        {
  201.        pprn->iQueue    = i;
  202.        break;
  203.        }
  204.    }
  205.                /* Save the queue information within the    printer    */
  206.                /* information structure    and save the number of    */
  207.                /* queues found within the system as well and    */
  208.                /* return the queues found flag            */
  209.  
  210. pprn->cQueues =    (INT)cReturned;
  211.  
  212. DosFreeMem((PVOID)pQueueInfo);
  213.  
  214. return(TRUE);
  215. }
  216. #pragma    subtitle("   Printer Control - Destroy Printer List Function")
  217. #pragma    page( )
  218.  
  219. /* --- PrnDestroyPrinterList --------------------------- [ Public ] ---    */
  220. /*                                    */
  221. /*     This function is    used to    destroy    a constructed printer list.    */
  222. /*                                    */
  223. /*     Upon Entry:                            */
  224. /*                                    */
  225. /*     PPRN pprn; = Printer Control Structure Pointer            */
  226. /*                                    */
  227. /*     Upon Exit:                            */
  228. /*                                    */
  229. /*     PrnDestroyPrinterList =    TRUE : List Destroyed            */
  230. /*                 = FALSE : Error                */
  231. /*                                    */
  232. /* --------------------------------------------------------------------    */
  233.  
  234. BOOL PrnDestroyPrinterList(PPRN    pprn)
  235.  
  236. {
  237. register INT i;               /* Loop Counter            */
  238.  
  239.                /* Check    to make    sure that memory was allocated    */
  240.                /* for the list and if the case,    release    it    */
  241. if ( pprn->hAB )
  242.    {
  243.    for ( i = 0;    i < pprn->cQueues; i++ )
  244.        {
  245.        if ( pprn->pquei[i].pszName )
  246.        free(pprn->pquei[i].pszName);
  247.  
  248.        if ( pprn->pquei[i].pszDriverName )
  249.        free(pprn->pquei[i].pszDriverName);
  250.  
  251.        if ( pprn->pquei[i].pszPrinters )
  252.        free(pprn->pquei[i].pszPrinters);
  253.  
  254.        free(pprn->pquei[i].pDriverData);
  255.        }
  256.  
  257.    pprn->hAB = 0;
  258.    pprn->cQueues = 0;
  259.    return(TRUE);
  260.    }
  261.                /* No memory allocated for the list, return    */
  262.                /* error    flag                    */
  263. return(FALSE);
  264. }
  265. #pragma    subtitle("   Printer Control - Printer DC Open Function")
  266. #pragma    page( )
  267.  
  268. /* --- PrnOpenDC --------------------------------------- [ Public ] ---    */
  269. /*                                    */
  270. /*     This function is    used to    open a device context on a specified    */
  271. /*     printer.                                */
  272. /*                                    */
  273. /*     Upon Entry:                            */
  274. /*                                    */
  275. /*     PPRN pprn;     = Printer Control Structure Pointer        */
  276. /*     PSZ  pszDataType; = Data    Type (PM_Q_STD or PM_Q_RAW)        */
  277. /*                                    */
  278. /*     Upon Exit:                            */
  279. /*                                    */
  280. /*     PrnOpenDC = Printer Device Context                */
  281. /*                                    */
  282. /* --------------------------------------------------------------------    */
  283.  
  284. HDC PrnOpenDC(PPRN pprn, PSZ pszDataType)
  285.  
  286. {
  287. CHAR         achDriverName[256];   /* Driver Name            */
  288. DEVOPENSTRUC dop;           /* Device Open Structure        */
  289. register INT i;               /* Loop Counter            */
  290.  
  291. if ( !pprn->cQueues )
  292.    return((HDC)NULL);
  293.                /* Initialize the driver    data structure        */
  294.  
  295. memset(&dop, 0,    sizeof(DEVOPENSTRUC));
  296.  
  297.                /* Set the logical address            */
  298.  
  299. dop.pszLogAddress = pprn->pquei[pprn->iQueue].pszName;
  300.  
  301.                /* Set the driver name (ie. PSCRIPT)        */
  302.  
  303. if ( (i    = (INT)strcspn(pprn->pquei[pprn->iQueue].pszDriverName,    ".")) != 0 )
  304.    {
  305.    dop.pszDriverName = memcpy(achDriverName, pprn->pquei[pprn->iQueue].pszDriverName, (UINT)i);
  306.    achDriverName[i] = 0;
  307.    }
  308. else
  309.    dop.pszDriverName = strcpy(achDriverName, pprn->pquei[pprn->iQueue].pszDriverName);
  310.  
  311. dop.pdriv  = (PVOID)pprn->pquei[pprn->iQueue].pDriverData;
  312.  
  313.                /* Set data type    (ie. PM_Q_STD or PM_Q_RAW)    */
  314.  
  315. dop.pszDataType    = pszDataType;
  316.  
  317. /* Other data values include:                        */
  318. /*                                    */
  319. /*  dop.pszComment    =    "comments"; // Comment for OD_Q            */
  320. /*  dop.pszQueueProcName   = NULL;  // queue processor;            */
  321. /*                    //    NULL =>    use default        */
  322. /*  dop.pszQueueProcParams = NULL;  // parms for queue processor    */
  323. /*  dop.pszSpoolerParams   = NULL;  // spooler parms (use NULL!)    */
  324. /*  dop.pszNetworkParams   = NULL;  // network parms (use NULL!)    */
  325.  
  326. return(DevOpenDC(pprn->hAB, OD_QUEUED, "*", 9L,    (PDEVOPENDATA)(PVOID)&dop, (HDC)0L));
  327. }
  328. #pragma    subtitle("   Printer Control - Printer DC Open Function")
  329. #pragma    page( )
  330.  
  331. /* --- PrnOpenInfoDC ----------------------------------- [ Public ] ---    */
  332. /*                                    */
  333. /*     This function is    used to    open a device context on a specified    */
  334. /*     printer.     The type of device context opened is an information    */
  335. /*     type where no printing is to occur.                */
  336. /*                                    */
  337. /*     Upon Entry:                            */
  338. /*                                    */
  339. /*     PPRN pprn;     = Printer Control Structure Pointer        */
  340. /*     PSZ  pszDataType; = Data    Type (PM_Q_STD or PM_Q_RAW)        */
  341. /*                                    */
  342. /*     Upon Exit:                            */
  343. /*                                    */
  344. /*     PrnOpenInfoDC = Printer Device Context                */
  345. /*                                    */
  346. /* --------------------------------------------------------------------    */
  347.  
  348. HDC PrnOpenInfoDC(PPRN pprn, PSZ pszDataType)
  349.  
  350. {
  351. CHAR         achDriverName[256];   /* Driver Name            */
  352. DEVOPENSTRUC dop;           /* Device Open Structure        */
  353. register INT i;               /* Loop Counter            */
  354.  
  355. if ( !pprn->cQueues )
  356.    return((HDC)NULL);
  357.                /* Initialize the driver    data structure        */
  358.  
  359. memset(&dop, 0,    sizeof(DEVOPENSTRUC));
  360.  
  361.                /* Set the logical address            */
  362.  
  363. dop.pszLogAddress = pprn->pquei[pprn->iQueue].pszName;
  364.  
  365.                /* Set the driver name (ie. PSCRIPT)        */
  366.  
  367. if ( (i    = (INT)strcspn(pprn->pquei[pprn->iQueue].pszDriverName,    ".")) != 0 )
  368.    {
  369.    dop.pszDriverName = memcpy(achDriverName, pprn->pquei[pprn->iQueue].pszDriverName, (UINT)i);
  370.    achDriverName[i] = 0;
  371.    }
  372. else
  373.    dop.pszDriverName = strcpy(achDriverName, pprn->pquei[pprn->iQueue].pszDriverName);
  374.  
  375. dop.pdriv  = (PVOID)pprn->pquei[pprn->iQueue].pDriverData;
  376.  
  377.                /* Set data type    (ie. PM_Q_STD or PM_Q_RAW)    */
  378.  
  379. dop.pszDataType    = pszDataType;
  380.  
  381. /* Other data values include:                        */
  382. /*                                    */
  383. /*  dop.pszComment    =    "comments"; // Comment for OD_Q            */
  384. /*  dop.pszQueueProcName   = NULL;  // queue processor;            */
  385. /*                    //    NULL =>    use default        */
  386. /*  dop.pszQueueProcParams = NULL;  // parms for queue processor    */
  387. /*  dop.pszSpoolerParams   = NULL;  // spooler parms (use NULL!)    */
  388. /*  dop.pszNetworkParams   = NULL;  // network parms (use NULL!)    */
  389.  
  390. return(DevOpenDC(pprn->hAB, OD_INFO, "*", 9L, (PDEVOPENDATA)(PVOID)&dop, (HDC)0L));
  391. }
  392. #pragma    subtitle("   Printer Control - Job Properies Query Function")
  393. #pragma    page( )
  394.  
  395. /* --- PrnQueryJobProperties --------------------------- [ Public ] ---    */
  396. /*                                    */
  397. /*     This function is    used to    get printer job    properties.  It    is    */
  398. /*     valid for a printer to require no job properties.  In this    */
  399. /*     case, *pcb == 0.                            */
  400. /*                                    */
  401. /*     Upon Entry:                            */
  402. /*                                    */
  403. /*     PPRN pprn;   = Printer Control Structure    Pointer            */
  404. /*     INT  iQueue; = Selected Queue Index                */
  405. /*                                    */
  406. /*     Upon Exit:                            */
  407. /*                                    */
  408. /*     PrnQueryJobProperties =    TRUE : Properties Retrieved        */
  409. /*                 = FALSE : Buffer to Small            */
  410. /*                                    */
  411. /* --------------------------------------------------------------------    */
  412.  
  413. BOOL PrnQueryJobProperties(PPRN    pprn, INT iQueue)
  414.  
  415. {
  416. CHAR      achDeviceName[256];       /* Device Name            */
  417. CHAR      achDriverName[256];       /* Driver Name            */
  418. PCHAR      pch;               /* Character    Pointer            */
  419. register INT i;               /* Index                */
  420.  
  421. if ( !pprn->cQueues )
  422.    return(FALSE);
  423.                /* Find the driver/device delimiter and parse    */
  424.                /* out the driver name and the device name    */
  425.  
  426. if ( (i    = (INT)strcspn(pprn->pquei[iQueue].pszDriverName, "."))    != 0 )
  427.    {
  428.    memcpy(achDriverName, pprn->pquei[iQueue].pszDriverName, (UINT)i);
  429.    achDriverName[i] = 0;
  430.                /* Set the device name                */
  431.  
  432.    strcpy(achDeviceName, &pprn->pquei[iQueue].pszDriverName[i +    1]);
  433.    }
  434. else
  435.    {
  436.    strcpy(achDriverName, pprn->pquei[iQueue].pszDriverName);
  437.    achDeviceName[0] = 0;
  438.    }
  439.                /* Get terminate    properly the printer name    */
  440.  
  441. if ( (pch = strchr(pprn->pquei[iQueue].pszPrinters, ',')) != NULL )
  442.    *pch    = 0;
  443.  
  444. return((BOOL)(DevPostDeviceModes(pprn->hAB, (PVOID)pprn->pquei[iQueue].pDriverData, achDriverName,
  445.                  achDeviceName,    pprn->pquei[iQueue].pszPrinters,
  446.                  DPDM_POSTJOBPROP) == DEV_OK));
  447. }
  448. #pragma    subtitle("   Printer Control - Printer Information Query Function")
  449. #pragma    page( )
  450.  
  451. /* --- PdsPrintQueryPrinterName    ------------------------ [ Public ] ---    */
  452. /*                                    */
  453. /*     This function is    used to    get information    on a printer.        */
  454. /*                                    */
  455. /*     Upon Entry:                            */
  456. /*                                    */
  457. /*     PPRN pprn; = Printer Control Structure Pointer            */
  458. /*                                    */
  459. /*     Upon Exit:                            */
  460. /*                                    */
  461. /*     PrnQueryPrinterName = Address of    Printer    Name            */
  462. /*                                    */
  463. /* --------------------------------------------------------------------    */
  464.  
  465. PSZ PrnQueryPrinterName(PPRN pprn)
  466.  
  467. {
  468.  
  469. if ( !pprn->cQueues )
  470.    return((PSZ)NULL);
  471.                /* Return the address of    the printer name    */
  472.  
  473. return(pprn->pquei[pprn->iQueue].pszName);
  474. }
  475. #pragma    subtitle("   Printer Control - Printer Setup Dialogue Procedure")
  476. #pragma    page( )
  477.  
  478. /* --- PrnSetupDlgProc --------------------------------- [ Public ] ---    */
  479. /*                                    */
  480. /*     This function is    used to    process    the Printer Setup dialogue    */
  481. /*     procedure.                            */
  482. /*                                    */
  483. /*     Upon Entry:                            */
  484. /*                                    */
  485. /*     HWND   hWnd; = Dialogue Window Handle                */
  486. /*     ULONG  msg;  = PM Message                    */
  487. /*     MPARAM mp1;  = Message Parameter    1                */
  488. /*     MPARAM mp2;  = Message Parameter    2                */
  489. /*                                    */
  490. /*     Upon Exit:                            */
  491. /*                                    */
  492. /*     PrnSetupDlgProc = Message Handling Result            */
  493. /*                                    */
  494. /* --------------------------------------------------------------------    */
  495.  
  496. MRESULT    EXPENTRY PrnSetupDlgProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  497.  
  498. {
  499. CHAR szPrinter[CCHMAXPATH];       /* Printer Name Holder        */
  500. PPRN pprn;               /* Printer List Pointer        */
  501. register INT i,    n;           /* Loop Counters            */
  502.  
  503. switch ( msg )
  504.    {
  505.    case    WM_INITDLG :
  506.                /* Save the pointer to user style information    */
  507.                /* within the dialog's reserved memory           */
  508.  
  509.        WinSetWindowPtr(hWnd, QWL_USER, (PVOID)(pprn = (PPRN)mp2));
  510.  
  511.                /* Go through the queue list and    add each of the    */
  512.                /* queue    entries    to the list box    from which the    */
  513.                /* user can select a printer to use and/or    */
  514.                /* configure                    */
  515.  
  516.        for ( i = 0; i <    pprn->cQueues; i++ )
  517.        {
  518.                /* Insert item and store    index            */
  519.  
  520.        WinSendDlgItemMsg(hWnd, LB_PRINTERS,    LM_SETITEMHANDLE,
  521.                  MPFROMSHORT(n = (INT)LONGFROMMR(WinSendDlgItemMsg(hWnd, LB_PRINTERS, LM_INSERTITEM,
  522.                                            MPFROMSHORT(LIT_SORTASCENDING),
  523.                                            MPFROMP(strcat(strcat(strcpy(szPrinter,
  524.                                                pprn->pquei[i].pszName),    ": "),
  525.                                                pprn->pquei[i].pszDriverName))))),
  526.                  MPFROMP(i));
  527.  
  528.                /* If the default printer, save the name    to set    */
  529.                /* selection                    */
  530.  
  531.        if (    i == pprn->iQueue )
  532.            WinSendDlgItemMsg(hWnd, LB_PRINTERS, LM_SELECTITEM, MPFROMSHORT(n),
  533.                  MPFROMSHORT(TRUE));
  534.        }
  535.        break;
  536.                /* Process list box selections            */
  537.    case    WM_CONTROL :
  538.        switch (    SHORT2FROMMP(mp1) )
  539.        {
  540.                /* Printer entry    selected            */
  541.  
  542.        case    LN_SELECT :
  543.            WinEnableWindow(WinWindowFromID(hWnd, DID_SETUP), TRUE);
  544.            WinEnableWindow(WinWindowFromID(hWnd, DID_OK),     TRUE);
  545.            break;
  546.        }
  547.        break;
  548.  
  549.    case    WM_COMMAND :
  550.        switch (    SHORT1FROMMP(mp1) )
  551.        {
  552.        case    DID_OK :
  553.                /* Get selection    from the list box        */
  554.  
  555.            pprn = (PPRN)WinQueryWindowPtr(hWnd, QWL_USER);
  556.  
  557.                /* Get printer handle                */
  558.  
  559.            pprn->iQueue = (INT)LONGFROMMR(WinSendDlgItemMsg(hWnd, LB_PRINTERS, LM_QUERYITEMHANDLE,
  560.                                 MPFROMLONG(WinSendDlgItemMsg(hWnd, LB_PRINTERS,
  561.                                                  LM_QUERYSELECTION,
  562.                                                  0L, 0L)),
  563.                                 0L));
  564.            WinDismissDlg(hWnd, TRUE);
  565.            break;
  566.  
  567.        case    DID_SETUP :
  568.  
  569.                /* Get printer handle                */
  570.  
  571.            PrnQueryJobProperties((PPRN)WinQueryWindowPtr(hWnd, QWL_USER),
  572.                      (INT)LONGFROMMR(WinSendDlgItemMsg(hWnd,
  573.                                        LB_PRINTERS,
  574.                                        LM_QUERYITEMHANDLE,
  575.                                        MPFROMLONG(WinSendDlgItemMsg(hWnd,
  576.                                                     LB_PRINTERS,
  577.                                                     LM_QUERYSELECTION,
  578.                                                     0L,    0L)),
  579.                                        0L)));
  580.            break;
  581.  
  582.        case    DID_CANCEL :
  583.            WinDismissDlg(hWnd, FALSE);
  584.            break;
  585.        }
  586.        break;
  587.                /* Close    received, exit dialog            */
  588.    case    WM_CLOSE :
  589.        WinDismissDlg(hWnd, FALSE);
  590.        break;
  591.  
  592.    default :
  593.        return(WinDefDlgProc(hWnd, msg, mp1, mp2));
  594.    }
  595.                /* Pass through unhandled messages        */
  596. return(0L);
  597. }
  598. #pragma    subtitle("   Font Functions - Image Font Selection Function")
  599. #pragma    page( )
  600.  
  601. /* --- SelectFont -------------------------------------- [ Public ] ---    */
  602. /*                                    */
  603. /*     This function is    used to    determine the lMatch component for    */
  604. /*     a requested image font.                        */
  605. /*                                    */
  606. /*     Upon Entry:                            */
  607. /*                                    */
  608. /*     HDC   hDC;       = Device Context                */
  609. /*     HPS   hPS;       = Presentation Space                */
  610. /*     CHAR  *pszFacename; = Font Face Name                */
  611. /*     LONG  lPoints;       = Points Size Requested            */
  612. /*                                    */
  613. /*     Upon Exit:                            */
  614. /*                                    */
  615. /*     SelectFont = lMatch Number for Requested    Font            */
  616. /*                                    */
  617. /* --------------------------------------------------------------------    */
  618.  
  619. LONG SelectFont(HDC hDC, HPS hPS, CHAR *pszFacename, LONG lPoints)
  620.  
  621. {
  622. LONG         cFonts;           /* Fonts Count            */
  623. LONG         lFontsTotal = 0L;       /* Fonts Total Count            */
  624. LONG         lMatch = 1L;       /* Font Match Value            */
  625. LONG         lXDeviceRes;       /* x    Device Resolution        */
  626. LONG         lYDeviceRes;       /* y    Device Resolution        */
  627. PFONTMETRICS pfm;           /* Font Metrics Pointer        */
  628. register INT i;               /* Loop Counter            */
  629.  
  630.                /* Get the height of the    screen in pels        */
  631.  
  632. DevQueryCaps(hDC, CAPS_HORIZONTAL_FONT_RES, 1L,    &lXDeviceRes);
  633. DevQueryCaps(hDC, CAPS_VERTICAL_FONT_RES,   1L,    &lYDeviceRes);
  634.  
  635.                /* Get the number of fonts for the face name    */
  636.                /* provided                    */
  637.  
  638. cFonts = GpiQueryFonts(hPS, QF_PUBLIC, pszFacename, &lFontsTotal,
  639.                sizeof(FONTMETRICS), (PFONTMETRICS)NULL);
  640.  
  641.                /* Allocate space for the font metrics for the    */
  642.                /* different font sizes and devices of the font    */
  643.  
  644. DosAllocMem((PPVOID)(PVOID)&pfm, (ULONG)(sizeof(FONTMETRICS) * cFonts),
  645.         PAG_READ | PAG_WRITE | PAG_COMMIT);
  646.  
  647.                /* Make a pointer for the memory    allocated for    */
  648.                /* the font metrics and get the font metrics for    */
  649.                /* the number of    fonts for the face name        */
  650.                /* provided                    */
  651.  
  652. GpiQueryFonts(hPS, QF_PUBLIC, pszFacename, &cFonts,
  653.           sizeof(FONTMETRICS), pfm);
  654.  
  655.                /* Adjust the point size    to correspond to the    */
  656.                /* the nominal point size that is contained    */
  657.                /* within the font metrics structure        */
  658. lPoints    *= 10;
  659.                /* Loop through the font    metrics    returned to    */
  660.                /* locate the desired font by matching the x and    */
  661.                /* y device resolution of the font and the point    */
  662.                /* size                        */
  663.  
  664. for ( i    = 0; i < (INT)cFonts; i++ )
  665.    if (    (pfm[i].sXDeviceRes == (SHORT)lXDeviceRes) &&
  666.     (pfm[i].sYDeviceRes == (SHORT)lYDeviceRes) &&
  667.     ((LONG)pfm[i].sNominalPointSize    == lPoints) )
  668.        {
  669.                /* Font found, get the match value to allow the    */
  670.                /* exact    font to    be selected by the calling    */
  671.                /* application                    */
  672.  
  673.        lMatch =    pfm[i].lMatch;
  674.        break;
  675.        }
  676.                /* Release the memory allocated for the font    */
  677.                /* metrics array                    */
  678. DosFreeMem(pfm);
  679.                /* Return the match value to the    calling        */
  680.                /* application                    */
  681. return(lMatch);
  682. }
  683. #pragma    subtitle("   Font Functions - Select Scalable Font Function")
  684. #pragma    page( )
  685.  
  686. /* --- SelectScalableFont ------------------------------ [ Public ] ---    */
  687. /*                                    */
  688. /*     This function is    used to    determine the lMatch component for    */
  689. /*     a requested vector font.                        */
  690. /*                                    */
  691. /*     Upon Entry:                            */
  692. /*                                    */
  693. /*     HPS   hPS;      = Presentation Space                */
  694. /*     CHAR *pszFacename; = Font Face Name                */
  695. /*                                    */
  696. /*     Upon Exit:                            */
  697. /*                                    */
  698. /*     SelectScalableFont = lMatch Number for Requested    Font        */
  699. /*                                    */
  700. /* --------------------------------------------------------------------    */
  701.  
  702. LONG SelectScalableFont(HPS hPS, CHAR *pszFacename)
  703.  
  704. {
  705. LONG         cFonts;           /* Fonts Count            */
  706. LONG         lFontsTotal = 0L;       /* Fonts Total Count            */
  707. LONG         lMatch = 1L;       /* Font Match Value            */
  708. PFONTMETRICS pfm;           /* Font Metrics Pointer        */
  709. register INT i;               /* Loop Counter            */
  710.  
  711.                /* Get the number of fonts for the face name    */
  712.                /* provided                    */
  713.  
  714. DosAllocMem((PPVOID)(PVOID)&pfm, (ULONG)(sizeof(FONTMETRICS) *
  715.          (cFonts = GpiQueryFonts(hPS, QF_PUBLIC, pszFacename, &lFontsTotal,
  716.          sizeof(FONTMETRICS), (PFONTMETRICS)NULL))), PAG_READ | PAG_WRITE |    PAG_COMMIT);
  717.  
  718.                /* Make a pointer for the memory    allocated for    */
  719.                /* the font metrics and get the font metrics for    */
  720.                /* the number of    fonts for the face name        */
  721.                /* provided                    */
  722.  
  723. GpiQueryFonts(hPS, QF_PUBLIC, pszFacename, &cFonts,
  724.           sizeof(FONTMETRICS), pfm);
  725.  
  726.                /* Loop through the font    metrics    returned to    */
  727.                /* locate the desired font by matching the x and    */
  728.                /* y device resolution of the font and the point    */
  729.                /* size                        */
  730.  
  731. for ( i    = 0; i < (INT)cFonts; i++ )
  732.    if (    (pfm[i].sXDeviceRes == 1000) &&    (pfm[i].sYDeviceRes == 1000) )
  733.        {
  734.                /* Font found, get the match value to allow the    */
  735.                /* exact    font to    be selected by the calling    */
  736.                /* application                    */
  737.  
  738.        lMatch =    pfm[i].lMatch;
  739.        break;
  740.        }
  741.                /* Release the memory allocated for the font    */
  742.                /* metrics array                    */
  743. DosFreeMem(pfm);
  744.                /* Return the match value to the    calling        */
  745.                /* application                    */
  746. return(lMatch);
  747. }
  748. #pragma    subtitle("   Font Functions -  Scale Font Function")
  749. #pragma    page( )
  750.  
  751. /* --- ScaleFont --------------------------------------- [ Public ] ---    */
  752. /*                                    */
  753. /*     This function is    used to    select and scale the font requested    */
  754. /*     to the size required for    printing.  The PS is assumed to    be    */
  755. /*     in TWIPS.                            */
  756. /*                                    */
  757. /*     Upon Entry:                            */
  758. /*                                    */
  759. /*     HPS   hPS;      = Presentation Space                */
  760. /*     CHAR *pszFacename; = Font Face Name                */
  761. /*     LONG lSize;      = Font Size in Decipoints (ie    10 pt =    100)    */
  762. /*                                    */
  763. /*     Upon Exit:                            */
  764. /*                                    */
  765. /*     ScaleFont = Logical Font    ID                    */
  766. /*                                    */
  767. /* --------------------------------------------------------------------    */
  768.  
  769. LONG ScaleFont(HPS hPS,    CHAR *pszFacename, LONG    lSize)
  770.  
  771. {
  772. FATTRS fat;               /* Font Attributes            */
  773. SIZEF  sizfxBox;           /* Character    Size Holder        */
  774.  
  775.                /* Complete the font attributes structure to    */
  776.                /* allow    the selection of the font requested    */
  777.                /* within the print file    dialogue box        */
  778.  
  779. memset(&fat, 0,    sizeof(FATTRS));
  780. fat.usRecordLength  = sizeof(FATTRS);
  781. fat.lMatch        = SelectScalableFont(hPS, strcpy(fat.szFacename, pszFacename));
  782. fat.usCodePage        = 850;
  783.  
  784.                /* Create the required font and set the        */
  785.                /* character size by changing the character box    */
  786.                /* size.     The sizing in TWIPS for a 12 pt font    */
  787.                /* is 240, therefore a 10 pt font would be 200.    */
  788.  
  789. GpiCreateLogFont(hPS, (PSTR8)NULL, 2L, &fat);
  790. GpiSetCharSet(hPS, 2L);
  791.  
  792. sizfxBox.cx = sizfxBox.cy = MAKEFIXED(lSize * 2, 0);
  793.  
  794. GpiSetCharBox(hPS, &sizfxBox);
  795.  
  796. return(2L);
  797. }
  798.