home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / PRESPM.ZIP / FNTDEMO.C < prev    next >
Text File  |  1991-04-15  |  31KB  |  786 lines

  1. /*\ FntDemo.C
  2. |*|         
  3. |*| See the Read.Me file for details.
  4. \*/         
  5.  
  6. #define INCL_WINERRORS
  7. #define INCL_WINSYS
  8. #define INCL_WINWINDOWMGR
  9. #define INCL_WINLISTBOXES
  10. #define INCL_GPILCIDS  
  11. #define INCL_GPICONTROL
  12. #define INCL_GPIPRIMITIVES
  13. #define INCL_DEV  
  14. #include <os2.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <ctype.h>   
  18. #include <limits.h>   
  19. #include "esllib.h"
  20. #define NR_ENTRIES(a) (sizeof(a)/sizeof(a[0]))
  21. #define ERRMSG1FROMERRI(erri) (PSZ)((*erri).offaoffszMsg + (PSZ)erri)
  22.     /*\                                                         
  23.     |*| erri is PERRINFO obtained from WinGetErrorInfo ( hab ) ;
  24.     \*/                                                         
  25.  
  26. /*\                                                         
  27. |*| Miscellaneous Named Constants
  28. \*/                                                         
  29. #define LISTBOX_CLASSNAME  "#7"
  30. #define CLASSNAMEMAXLTH    256
  31. #define POINTFACE_MAXCHARS 255
  32. #define CLASSNAME_MAXCHARS 255     
  33.  
  34. /*\
  35. |*| Return codes for ChangeHANDLE_FontToPOINTS_FACE_  (CHFTPF)
  36. \*/
  37. #define CHFTPF_OK               0
  38. #define CHFTPF_NOSIZE           1
  39. #define CHFTPF_NOTNUMSIZE       2
  40. #define CHFTPF_NOTVALIDSIZE     3
  41. #define CHFTPF_NOFACE           4
  42. #define CHFTPF_NOFACEMATCH      5     
  43. #define CHFTPF_NOPOINTSIZEMATCH 6    
  44. #define CHFTPF_PRESPARAMSETERR  7  
  45. #define CHFTPF_NOSTGAVAIL       8  
  46. PSZ     CHFTPFErrorMessage [] =
  47.     { "OK"
  48.     , "No font size was specified."
  49.     , "Font size is not numeric."
  50.     , "Font size is not valid."
  51.     , "No font face name was specified."
  52.     , "No fonts are available for this face."
  53.     , "Font is not available in requested size."
  54.     , "supplied by WinGetErrorInfo"
  55.     , "No storage available for font metrics."
  56.     } ;                                               
  57.  
  58. /*\
  59. |*| Return codes for MakeHANDLE_COLOR   (MHC)
  60. \*/
  61. #define MHC_OK               0
  62. #define MHC_NOTVALIDCOLOR    1
  63. #define MHC_PRESPARAMSETERR  2
  64. PSZ     MHCErrorMessage [] =
  65.     { "OK"
  66.     , "Not a valid EASEL color number."
  67.     , "supplied by WinGetErrorInfo"
  68.     } ;                        
  69.  
  70. HAB habError = NULL ;         /*  Saved hab for error message processing */
  71.  
  72. int_acrtused = 1 ;            /*  std for C DLL                          */
  73.  
  74. /*\
  75. |*| Function Headers
  76. \*/
  77. LONG ParseFontSpec
  78.     ( PSZ      pszFont        /*  Font in format pp.FFFF                 */
  79.     , PSZ      pszPointFace   /*  Standardized version of pszFont        */
  80.     , PSZ      pszFaceName    /*  Face name from pszFont                 */
  81.     , PSHORT   sPoints        /*  Point size from pszFont in decipoints  */
  82.     ) ;                       
  83.  
  84. UCHAR * StrSpace 
  85.     ( UCHAR * pszSource
  86.     , USHORT  NrCopiesPadChar
  87.     , UCHAR * pPadChar  
  88.     , UCHAR * pszTarget 
  89.     ) ;     
  90.  
  91. LONG APIENTRY MakeHANDLE_PP_COLOR_
  92.     ( LONG *  phwndControl    /*  handle of Easel dialog control         */
  93.     , LONG *  plColorIndex    /*  desired color index                    */
  94.     , LONG *  lpp             /*  presentation param for color index     */
  95.     ) ;                        
  96.  
  97. /*\=========================================================================
  98. |*|                                                                         
  99. |*| ChangeHANDLE_FontToDefault
  100. |*|                                                                         
  101. |*| Removes the PP_FONTNAMESIZE presentation parameter from the control.    
  102. |*|_________________________________________________________________________
  103. \*/
  104. LONG APIENTRY ChangeHANDLE_FontToDefault
  105.     ( LONG *  phwndControl    /*  handle of Easel dialog control         */
  106.     )                         /*      pp.FFFF  pp=points FFFF=Face name  */
  107.     {  
  108.     LONG        rc = 0;   
  109.     PERRINFO    erri ;
  110.     HAB         hab ;    
  111.     HPS         hps ;    
  112.     FONTMETRICS Metrics ;
  113.     UCHAR       szClassName [ CLASSNAMEMAXLTH ] ;
  114.     SHORT       sClassNameLth ;
  115.     SHORT       sClassNameBufLth = NR_ENTRIES( szClassName ) ; 
  116.  
  117.     /*\
  118.     |*| Remove the presentation parameter for the font from the control.
  119.     \*/    
  120.     WinRemovePresParam ( (HWND) *phwndControl, PP_FONTNAMESIZE ) ; 
  121.                                      
  122.     /*\
  123.     |*| If the control is a listbox, send an LM_SETITEMHEIGHT to it.
  124.     \*/    
  125.     sClassNameLth = WinQueryClassName 
  126.         ( (HWND) *phwndControl
  127.         , sClassNameBufLth
  128.         , szClassName
  129.         ) ;     
  130.  
  131.     if  ( !strcmp ( LISTBOX_CLASSNAME, szClassName ) ) /* if a listbox     */
  132.         {
  133.         hps = WinGetPS ( (HWND) *phwndControl ) ;  /* Cached micro ps      */
  134.         GpiQueryFontMetrics ( hps, (LONG)sizeof(FONTMETRICS), &Metrics ) ;
  135.         WinReleasePS ( hps ) ;  
  136.         WinSendMsg                        /* tell listbox how to draw font */
  137.             ( (HWND) *phwndControl  
  138.             , LM_SETITEMHEIGHT 
  139.             , (MPARAM) Metrics.lMaxBaselineExt
  140.             , NULL 
  141.             ) ;   
  142.        }
  143.     return 0L ;
  144.     }                                               
  145.  
  146. /*\=========================================================================
  147. |*|                                                                         
  148. |*| ChangeHANDLE_FontToPOINTSFACE_                                        
  149. |*|                                                                         
  150. |*|_________________________________________________________________________
  151. \*/
  152. LONG APIENTRY ChangeHANDLE_FontToPOINTSFACE_
  153.     ( LONG *  phwndControl    /*  handle of Easel dialog control         */
  154.     , PHSTRING phsFont        /*  name of font face desired              */
  155.     )                         /*      pp.FFFF  pp=points FFFF=Face name  */
  156.     {  
  157.     PSZ         pszFont ; 
  158.     PSZ         pszErrMsg ;
  159.     UCHAR       szPointFace [ POINTFACE_MAXCHARS + 1 ] ;
  160.     UCHAR       szFaceName  [ POINTFACE_MAXCHARS + 1 ] ;
  161.     SHORT       sPoints ;  
  162.     LONG        lFontLength ;  
  163.     LONG        rc = 0;   
  164.     HPS         hps ;    
  165.     HDC         hdc ;    
  166.     FONTMETRICS Metrics ;
  167.     FONTMETRICS *pfmMetrics ;
  168.     LONG        lReqFonts ;
  169.     LONG        lAvailFonts ;
  170.     UCHAR       szClassName [ CLASSNAME_MAXCHARS + 1 ] ;
  171.     SHORT       sClassNameLth ;
  172.     SHORT       sClassNameBufLth = NR_ENTRIES(szClassName) ;
  173.     LONG  alDevCapsFontRes [ 2 ] ;           
  174.  
  175.     /*\
  176.     |*| Initialize habError for error processing.  
  177.     |*|     (see ErrMsgFromChangeHANDLEFont() ).   
  178.     \*/
  179.     habError = WinQueryAnchorBlock ( (HWND) *phwndControl ) ;    
  180.  
  181.     /*\
  182.     |*| First, get the name of the requested font.
  183.     \*/
  184.     pszFont = EslQueryStringAddr ( *phsFont ) ;         
  185.  
  186.     /*\
  187.     |*| Next, parse the font specification into its component face name
  188.     |*|     (szFaceName) and point size (sPoints).  Also create a 
  189.     |*|     standardized form of the specification (szPointFace).
  190.     \*/
  191.     if  ( rc = ParseFontSpec ( pszFont, szPointFace, szFaceName, &sPoints ) ) 
  192.         /*\
  193.         |*| A non-zero return code indicates an invalid font specification.
  194.         |*| Return to the caller.
  195.         \*/
  196.         return rc ;     
  197.  
  198.     /*\ 
  199.     |*| assert: Face name is a valid non-null string.
  200.     |*| Validate szFaceName as an available one.
  201.     |*| Find out how many fonts there are with this face name.
  202.     \*/            
  203.     hps = WinGetPS ( HWND_DESKTOP ) ; /* Cached micro ps for display       */
  204.     lReqFonts = 0 ;                /* 0 says return how many fonts match.  */
  205.     lAvailFonts = GpiQueryFonts 
  206.         ( hps                      
  207.         , QF_PUBLIC | QF_PRIVATE   /* check both                           */
  208.         , szFaceName               /* facename from font request           */
  209.         , &lReqFonts               /* 0 input means return nr that exist   */
  210.         , (LONG) (NULL)            
  211.         , (PFONTMETRICS) NULL      /* where fontmetrics info is returned   */
  212.         ) ;
  213.     if ( GPI_ALTERROR == lAvailFonts || 0L == lAvailFonts )
  214.         return CHFTPF_NOFACEMATCH ; /* no match on face name               */
  215.  
  216.     /*\ 
  217.     |*| Allocate storage for and retrieve FONTMETRICS info on all fonts with
  218.     |*|     the specified face name.
  219.     \*/
  220.     pfmMetrics = malloc /* use DosAllocSeg if you want ... */
  221.         ( (UINT) ( lAvailFonts * sizeof(FONTMETRICS) )
  222.         ) ;   
  223.     if (pfmMetrics == NULL) 
  224.         {
  225.         free ( pfmMetrics ) ;      /* free storage for array of FONTMETRICS*/
  226.         return CHFTPF_NOSTGAVAIL ; /* no match on face name                */
  227.         }                     
  228.  
  229.     lReqFonts = GpiQueryFonts      /* Get fontmetrics for all of this face */
  230.         ( hps
  231.         , QF_PUBLIC | QF_PRIVATE
  232.         , szFaceName
  233.         , &lAvailFonts             /* ask for as many as it said there are */
  234.         , (LONG) sizeof (FONTMETRICS)
  235.         , pfmMetrics               /* returned info in allocated area      */
  236.         )  ;                 
  237.  
  238.     /*\
  239.     |*| Query the device's font resolution;  these X and Y values will
  240.     |*| be used to select matching fonts.
  241.     \*/                
  242.     hdc = GpiQueryDevice ( hps ) ; 
  243.     DevQueryCaps ( hdc, CAPS_HORIZONTAL_FONT_RES, 2L, alDevCapsFontRes ) ;
  244.     WinReleasePS ( hps ) ;            
  245.  
  246.     /*\
  247.     |*| Inspect array of available font sizes for the requested face.
  248.     |*| Validate that the requested point size is available.
  249.     \*/                
  250.     for ( 
  251.         ; lAvailFonts 
  252.         ; pfmMetrics++ , --lAvailFonts 
  253.         ) 
  254.         if  (  pfmMetrics[0].sNominalPointSize == sPoints 
  255.             && pfmMetrics[0].sXDeviceRes == (SHORT) alDevCapsFontRes[0] 
  256.             && pfmMetrics[0].sYDeviceRes == (SHORT) alDevCapsFontRes[1]
  257.             ) 
  258.             break ;   
  259.  
  260.     if ( !lAvailFonts )            /* no match found on point size         */
  261.         {
  262.         free ( pfmMetrics ) ;      /* free storage for array of FONTMETRICS*/
  263.         return CHFTPF_NOPOINTSIZEMATCH ;
  264.         }                
  265.  
  266.     Metrics = *pfmMetrics ;        /* save FONTMETRICS for matched font.   */
  267.     free ( pfmMetrics ) ;          /* free storage for array of FONTMETRICS*/
  268.  
  269.     /*\
  270.     |*| Change the presentation parameters for the control to use the
  271.     |*|     validated font.
  272.     \*/ 
  273.     sClassNameLth = WinQueryClassName 
  274.         ( (HWND) *phwndControl
  275.         , sClassNameBufLth
  276.         , szClassName
  277.         ) ;                  
  278.  
  279.     if  ( !strcmp ( LISTBOX_CLASSNAME, szClassName ) ) /* if a listbox     */
  280.         {
  281.         /*\
  282.         |*| This appears to be necessary to get the proper behaviour from
  283.         |*| the listbox and its vertical scrollbar.  There is an APAR open
  284.         |*| on this;  search on PP_FONTNAMESIZE.  You have to change the
  285.         |*| size twice; the first ever change does NOT result in a proper
  286.         |*| redraw.
  287.         \*/
  288.         ChangeHANDLE_FontToDefault ( phwndControl ) ; 
  289.         }           
  290.  
  291.     lFontLength = strlen ( szPointFace ) + 1;       
  292.     if  (!WinSetPresParam
  293.         ( (HWND) *phwndControl                                       
  294.         , PP_FONTNAMESIZE                                          
  295.         , lFontLength 
  296.         , (PVOID) szPointFace
  297.         ) )
  298.         return CHFTPF_PRESPARAMSETERR ;   
  299.  
  300.     if  ( !strcmp ( LISTBOX_CLASSNAME, szClassName ) ) /* if a listbox     */
  301.         {
  302.         WinSendMsg                        /* tell listbox size of new font */
  303.             ( (HWND) *phwndControl  
  304.             , LM_SETITEMHEIGHT 
  305.             , (MPARAM) Metrics.lMaxBaselineExt
  306.             , NULL 
  307.             ) ;  
  308.         }
  309.     return CHFTPF_OK ;
  310.     }                                                
  311.  
  312. /*\=========================================================================
  313. |*|                                                                         
  314. |*| ErrMsgFromChangeHANDLEFont
  315. |*|                                                                         
  316. |*| Return an error message associated with the given errorlevel number
  317. |*| passed from EASEL.  It is assumed that:
  318. |*|                                                                         
  319. |*|     (1) the errorlevel represents an errorlevel due to the              
  320. |*|         ChangeHANDLE_FontToPOINTSFACE_  call.                           
  321. |*|     (2) no other PM Winxxx errors have occurred between the             
  322. |*|         ChangeHANDLE_FontToPOINTSFACE_  call and this call.             
  323. |*|                                                                         
  324. |*|_________________________________________________________________________
  325. \*/
  326. HSTRING APIENTRY ErrMsgFromChangeHANDLEFont
  327.     ( LONG     errorlevel /*  errorlevel from EASEL                      */
  328.     )                         
  329.     {  
  330.     HSTRING hsErrMsg ;    /*  EASEL string handle                        */
  331.     PSZ     pszErrMsg ;   /*  pointer to error message for errorlevel    */
  332.     PERRINFO erri ;       /*  WinGetErrorInfo()'s returned structure     */ 
  333.  
  334.     if  ( errorlevel == CHFTPF_PRESPARAMSETERR )
  335.         /*\
  336.         |*| If errorlevel indicates last error was due to an error in the
  337.         |*|     WinSetPresParams() API call, then return the text from the
  338.         |*|     WinGetErrorInfo() API.
  339.         \*/
  340.         {
  341.         erri = WinGetErrorInfo ( habError ) ; 
  342.         pszErrMsg = ERRMSG1FROMERRI(erri) ; 
  343.         hsErrMsg = EslCreateString ( strlen ( pszErrMsg ), pszErrMsg ) ;
  344.         WinFreeErrorInfo ( erri ) ; 
  345.         } 
  346.     else if  ( errorlevel >= 0 && errorlevel < NR_ENTRIES(CHFTPFErrorMessage) )
  347.         /*\
  348.         |*| Else if valid subscript, pull errmsg from array of messages.
  349.         \*/
  350.         hsErrMsg = EslCreateString 
  351.             ( strlen ( CHFTPFErrorMessage [errorlevel] )
  352.             , CHFTPFErrorMessage [errorlevel]
  353.             ) ;
  354.     else
  355.         /*\
  356.         |*| Else substitute dummy error message.
  357.         \*/
  358.         hsErrMsg = EslCreateString 
  359.             ( sizeof("*Bad errorlevel*") - 1
  360.             , "*Bad errorlevel*"
  361.             ) ;
  362.     return hsErrMsg ;
  363.     }              
  364.  
  365. /*\=========================================================================
  366. |*|                                                                         
  367. |*| ErrMsgFromMakeHANDLECOLOR
  368. |*|                                                                         
  369. |*| Return an error message associated with the given errorlevel number
  370. |*| passed from EASEL.  It is assumed that:
  371. |*|                                                                         
  372. |*|     (1) the errorlevel represents an errorlevel due to one of the       
  373. |*|         MakeHANDLE<xxx>COLOR_ calls.
  374. |*|     (2) no other PM Winxxx errors have occurred between the             
  375. |*|         MakeHANDLE<xxx>COLOR_  call and this call.             
  376. |*|                                                                         
  377. |*|_________________________________________________________________________
  378. \*/
  379. HSTRING APIENTRY ErrMsgFromMakeHANDLECOLOR
  380.     ( LONG     errorlevel /*  errorlevel from EASEL                      */
  381.     )                         
  382.     {  
  383.     HSTRING hsErrMsg ;    /*  EASEL string handle                        */
  384.     PSZ     pszErrMsg ;   /*  pointer to error message for errorlevel    */
  385.     PERRINFO erri ;       /*  WinGetErrorInfo()'s returned structure     */ 
  386.  
  387.     if  ( errorlevel == MHC_PRESPARAMSETERR )
  388.         /*\
  389.         |*| If errorlevel indicates last error was due to an error in the
  390.         |*|     WinSetPresParams() API call, then return the text from the
  391.         |*|     WinGetErrorInfo() API.
  392.         \*/
  393.         {
  394.         erri = WinGetErrorInfo ( habError ) ; 
  395.         pszErrMsg = ERRMSG1FROMERRI(erri) ; 
  396.         hsErrMsg = EslCreateString ( strlen ( pszErrMsg ), pszErrMsg ) ;
  397.         WinFreeErrorInfo ( erri ) ; 
  398.         } 
  399.     else if  ( errorlevel >= 0 && errorlevel < NR_ENTRIES(MHCErrorMessage) )
  400.         /*\
  401.         |*| Else if valid subscript, pull errmsg from array of messages.
  402.         \*/
  403.         hsErrMsg = EslCreateString 
  404.             ( strlen ( MHCErrorMessage [errorlevel] )
  405.             , MHCErrorMessage [errorlevel]
  406.             ) ;
  407.     else
  408.         /*\
  409.         |*| Else substitute dummy error message.
  410.         \*/
  411.         hsErrMsg = EslCreateString 
  412.             ( sizeof("*Bad errorlevel*") - 1
  413.             , "*Bad errorlevel*"
  414.             ) ;
  415.     return hsErrMsg ;
  416.     }       
  417.  
  418. /*\=========================================================================
  419. |*|                                                                         
  420. |*| MakeHANDLE_ForeCOLOR_
  421. |*|                                                                         
  422. |*| Changes the PP_FOREGROUNDCOLORINDEX presentation parameter 
  423. |*| of the control.    
  424. |*|_________________________________________________________________________
  425. \*/
  426. LONG APIENTRY MakeHANDLE_ForeCOLOR_
  427.     ( LONG *  phwndControl    /*  handle of Easel dialog control         */
  428.     , LONG *  plColorIndex    /*  desired color index                    */
  429.     )                         
  430.     {  
  431.     LONG lpp = PP_FOREGROUNDCOLORINDEX ; 
  432.  
  433.     return MakeHANDLE_PP_COLOR_ 
  434.         ( phwndControl
  435.         , plColorIndex
  436.         , &lpp
  437.         ) ;
  438.     }                            
  439.  
  440. /*\=========================================================================
  441. |*|                                                                         
  442. |*| MakeHANDLE_BackCOLOR_
  443. |*|                                                                         
  444. |*| Changes the PP_BACKGROUNDCOLORINDEX presentation parameter 
  445. |*| of the control.    
  446. |*|_________________________________________________________________________
  447. \*/
  448. LONG APIENTRY MakeHANDLE_BackCOLOR_
  449.     ( LONG *  phwndControl    /*  handle of Easel dialog control         */
  450.     , LONG *  plColorIndex    /*  desired color index                    */
  451.     )                         
  452.     {  
  453.     LONG lpp = PP_BACKGROUNDCOLORINDEX ;
  454.  
  455.     return MakeHANDLE_PP_COLOR_ 
  456.         ( phwndControl
  457.         , plColorIndex
  458.         , &lpp
  459.         ) ;
  460.     }      
  461.  
  462. /*\=========================================================================
  463. |*|                                                                         
  464. |*| MakeHANDLE_HiliteForeCOLOR_
  465. |*|                                                                         
  466. |*| Changes the PP_HILITEFOREGROUNDCOLORINDEX presentation parameter 
  467. |*| of the control.    
  468. |*|_________________________________________________________________________
  469. \*/
  470. LONG APIENTRY MakeHANDLE_HiliteForeCOLOR_
  471.     ( LONG *  phwndControl    /*  handle of Easel dialog control         */
  472.     , LONG *  plColorIndex    /*  desired color index                    */
  473.     )                         
  474.     {  
  475.     LONG lpp = PP_HILITEFOREGROUNDCOLORINDEX ;  
  476.  
  477.     return MakeHANDLE_PP_COLOR_ 
  478.         ( phwndControl
  479.         , plColorIndex
  480.         , &lpp
  481.         ) ;
  482.     }                                                           
  483.  
  484. /*\=========================================================================
  485. |*|                                                                         
  486. |*| MakeHANDLE_HiliteBackCOLOR_
  487. |*|                                                                         
  488. |*| Changes the PP_HILITEBACKGROUNDCOLORINDEX presentation parameter 
  489. |*| of the control.    
  490. |*|_________________________________________________________________________
  491. \*/
  492. LONG APIENTRY MakeHANDLE_HiliteBackCOLOR_
  493.     ( LONG *  phwndControl    /*  handle of Easel dialog control         */
  494.     , LONG *  plColorIndex    /*  desired color index                    */
  495.     )                         
  496.     {  
  497.     LONG lpp = PP_HILITEBACKGROUNDCOLORINDEX ; 
  498.  
  499.     return MakeHANDLE_PP_COLOR_ 
  500.         ( phwndControl
  501.         , plColorIndex
  502.         , &lpp
  503.         ) ;
  504.     }                                          
  505.  
  506. /*\=========================================================================
  507. |*|                                                                         
  508. |*| MakeHANDLE_DisabledForeCOLOR_
  509. |*|                                                                         
  510. |*| Changes the PP_DISABLEDFOREGROUNDCOLORINDEX presentation parameter 
  511. |*| of the control.    
  512. |*|_________________________________________________________________________
  513. \*/
  514. LONG APIENTRY MakeHANDLE_DisabledForeCOLOR_
  515.     ( LONG *  phwndControl    /*  handle of Easel dialog control         */
  516.     , LONG *  plColorIndex    /*  desired color index                    */
  517.     )                         
  518.     {  
  519.     LONG lpp = PP_DISABLEDFOREGROUNDCOLORINDEX ;   
  520.       
  521.     return MakeHANDLE_PP_COLOR_ 
  522.         ( phwndControl
  523.         , plColorIndex
  524.         , &lpp 
  525.         ) ;
  526.     }                                              
  527.  
  528. /*\=========================================================================
  529. |*|                                                                         
  530. |*| MakeHANDLE_DisabledBackCOLOR_
  531. |*|                                                                         
  532. |*| Changes the PP_DISABLEDBACKGROUNDCOLORINDEX presentation parameter 
  533. |*| of the control.    
  534. |*|_________________________________________________________________________
  535. \*/
  536. LONG APIENTRY MakeHANDLE_DisabledBackCOLOR_
  537.     ( LONG *  phwndControl    /*  handle of Easel dialog control         */
  538.     , LONG *  plColorIndex    /*  desired color index                    */
  539.     )  
  540.     {  
  541.     LONG lpp = PP_DISABLEDBACKGROUNDCOLORINDEX ;       
  542.   
  543.     return MakeHANDLE_PP_COLOR_ 
  544.         ( phwndControl
  545.         , plColorIndex
  546.         , &lpp 
  547.         ) ;
  548.     }                                               
  549.  
  550. /*\=========================================================================
  551. |*|                                                                         
  552. |*| MakeHANDLE_BorderCOLOR_
  553. |*|                                                                         
  554. |*| Changes the PP_BORDERCOLORINDEX presentation parameter 
  555. |*| of the control.    
  556. |*|_________________________________________________________________________
  557. \*/
  558. LONG APIENTRY MakeHANDLE_BorderCOLOR_
  559.     ( LONG *  phwndControl    /*  handle of Easel dialog control         */
  560.     , LONG *  plColorIndex    /*  desired color index                    */
  561.     )                         
  562.     {  
  563.     LONG lpp = PP_BORDERCOLORINDEX ;     
  564.     
  565.     return MakeHANDLE_PP_COLOR_ 
  566.         ( phwndControl
  567.         , plColorIndex
  568.         , &lpp
  569.         ) ;
  570.     }                                    
  571.  
  572. /*\=========================================================================
  573. |*|                                                                         
  574. |*| MakeHANDLE_PP_COLOR_
  575. |*|                                                                         
  576. |*| Changes the specified presentation parameter 
  577. |*| of the control.    
  578. |*|_________________________________________________________________________
  579. \*/
  580. LONG APIENTRY MakeHANDLE_PP_COLOR_
  581.     ( LONG *  phwndControl    /*  handle of Easel dialog control         */
  582.     , LONG *  plColorIndex    /*  desired color index                    */
  583.     , LONG *  lpp             /*  presentation param for color index     */
  584.     )                         
  585.     {  
  586.     LONG lGpiColorIndex ;    
  587.        
  588.     /*\
  589.     |*| Check that LONG's value will fit in an int before the cast
  590.     \*/
  591.     if ( *plColorIndex > INT_MAX )
  592.         return MHC_NOTVALIDCOLOR ;
  593.     if ( *plColorIndex < INT_MIN )
  594.         return MHC_NOTVALIDCOLOR ;   
  595.  
  596.     switch ( (int) *plColorIndex )
  597.         {
  598.         case  1: lGpiColorIndex = CLR_RED        ; break ;
  599.         case  2: lGpiColorIndex = CLR_GREEN      ; break ;
  600.         case  3: lGpiColorIndex = CLR_YELLOW     ; break ;
  601.         case  4: lGpiColorIndex = CLR_BLUE       ; break ;
  602.         case  5: lGpiColorIndex = CLR_PINK       ; break ;
  603.         case  6: lGpiColorIndex = CLR_CYAN       ; break ;
  604.         case  7: lGpiColorIndex = CLR_WHITE      ; break ;
  605.         case  8: lGpiColorIndex = CLR_BLACK      ; break ;
  606.         case 18: lGpiColorIndex = CLR_DARKGRAY   ; break ;
  607.         case 19: lGpiColorIndex = CLR_DARKBLUE   ; break ;
  608.         case 20: lGpiColorIndex = CLR_DARKRED    ; break ;
  609.         case 21: lGpiColorIndex = CLR_DARKPINK   ; break ;
  610.         case 22: lGpiColorIndex = CLR_DARKGREEN  ; break ;
  611.         case 23: lGpiColorIndex = CLR_DARKCYAN   ; break ;
  612.         case 24: lGpiColorIndex = CLR_BROWN      ; break ;
  613.         case 25: lGpiColorIndex = CLR_PALEGRAY   ; break ;
  614.         case 26: lGpiColorIndex = CLR_BACKGROUND ; break ;
  615.         case 27: lGpiColorIndex = CLR_DEFAULT    ; break ;
  616.         default:  return MHC_NOTVALIDCOLOR ;
  617.         }  
  618.  
  619.     if  (!WinSetPresParam
  620.         ( (HWND) *phwndControl                                       
  621.         , *lpp
  622.         , (LONG) sizeof(LONG)
  623.         , &lGpiColorIndex
  624.         ) )
  625.         return MHC_PRESPARAMSETERR ;   
  626.  
  627.     return 0L ;
  628.     }                                        
  629.  
  630. /*\=========================================================================
  631. |*|                                                                         
  632. |*| ParseFontSpec
  633. |*|                                                                         
  634. |*| ParseFontSpec breaks a font specification into its component parts.     
  635. |*| Format is pp.FFFF, where pp is size in points, FFFF is the face name.   
  636. |*|_________________________________________________________________________
  637. \*/
  638. LONG ParseFontSpec
  639.     ( PSZ      pszFont      /* in   Font in format pp.FFFF                 */
  640.     , PSZ      pszPointFace /* out  Standardized version of pszFont        */
  641.     , PSZ      pszFaceName  /* out  Face name from pszFont                 */
  642.     , PSHORT   psPoints     /* out  Point size from pszFont in decipoints  */
  643.     )                         
  644.     {  
  645.     PSZ      ipsz ;         /*  work pointer for pszFont                   */
  646.     PSZ      ipsz2 ;        /*  work pointer for pszFont                   */ 
  647.  
  648.     /*\
  649.     |*| Split out the requested font size (in points) and the face name.
  650.     |*| Format is pp.ffff where pp is size in points, ffff is the face name.
  651.     \*/
  652.     for ( ipsz = pszFont ; *ipsz && *ipsz != '.' ; ipsz++ ) ; 
  653.  
  654.     /*\
  655.     |*| If no period found, then
  656.     |*|     invalid font specification - no size specified. (no period)
  657.     |*|     return an errorlevel code.
  658.     \*/     
  659.     if  ( !*ipsz )
  660.         return CHFTPF_NOSIZE ;          
  661.  
  662.     /*\
  663.     |*| *ipsz == '.'; a period was found.
  664.     |*| Validate the specified point size as numeric, and greater than zero.
  665.     |*| Allow leading, trailing, and embedded blanks.  Convert it to binary.
  666.     \*/ 
  667.     for ( ipsz2 = pszFont, *psPoints = 0
  668.         ; ipsz2 != ipsz 
  669.         ; ipsz2++ 
  670.         ) 
  671.         {
  672.         if  ( *ipsz2 == ' ' )
  673.             continue ;
  674.         else if  ( isdigit ( *ipsz2 ) ) 
  675.             {
  676.             *psPoints = ( *ipsz2 - '0' ) + *psPoints * 10 ; 
  677.             *(pszPointFace++) = *ipsz2 ;
  678.             }
  679.         else 
  680.             return CHFTPF_NOTNUMSIZE ;
  681.         }               
  682.  
  683.     if  ( !*psPoints )
  684.         return CHFTPF_NOTVALIDSIZE ;  
  685.  
  686.     /*\
  687.     |*| Scale up the points value to units called decipoints.
  688.     |*| This is the unit (1/720 inch = 1/10 point) used in the 
  689.     |*|     FONTMETRICS structure.
  690.     \*/       
  691.     *psPoints *= 10 ;  
  692.  
  693.     /*\
  694.     |*| assert: Point size is numeric, greater than zero.
  695.     |*| Strip leading and trailing blanks in the face name, and   
  696.     |*|     transform each run of multiple embedded blanks into a single blank.
  697.     |*| Copy this standardized face name into szFaceName.
  698.     |*| Append a period and the face name to the point size in iszPointFace.
  699.     \*/ 
  700.     *pszPointFace++ = '.' ;
  701.     strcpy ( pszPointFace, StrSpace ( ++ipsz, 1, " ", pszFaceName ) ) ;
  702.  
  703.     /*\
  704.     |*| return 0 as the return code unless the face name is the null
  705.     |*|     string, in which case set an error code.
  706.     \*/       
  707.     return ( *pszFaceName ) ? 0L : CHFTPF_NOFACE ;
  708.     }                                                          
  709.  
  710. /*\===========================================================================
  711. |*|
  712. |*| StrSpace
  713. |*|
  714. |*| StrSpace removes all leading and trailing blanks, then replaces every
  715. |*| run of one or more consecutive blanks by NrCopiesPadChar copies of the
  716. |*| pad character in *pPadChar.  The result is placed in pszTarget.  The
  717. |*| original pszSource is not changed.  The value in pszTarget is returned.
  718. |*|
  719. |*| This function is modeled on REXX's SPACE builtin function.
  720. |*|
  721. |*| In general, pszSource and pszTarget may NOT overlap;  however, when
  722. |*| the NrCopiesPadChar is 1 and pszSource = pszTarget, this function
  723. |*| is guaranteed to work properly.
  724. |*|
  725. |*| This function is reentrant, and does not rely upon the C compiler's
  726. |*| string handling functions.
  727. |*|
  728. |*|                                                         Brian Buck 28NOV89
  729. |*|___________________________________________________________________________
  730. \*/
  731. UCHAR * StrSpace 
  732.     ( UCHAR * pszSource
  733.     , USHORT  NrCopiesPadChar
  734.     , UCHAR * pPadChar  
  735.     , UCHAR * pszTarget 
  736.     )
  737.     { 
  738.     PSZ ipszS = pszSource ; 
  739.     PSZ ipsz2 ;
  740.     PSZ ipszT = pszTarget ;
  741.     LONG InBlankRun ;
  742.     USHORT  i ;         
  743.  
  744.     /*\
  745.     |*| First, strip (run through) leading blanks in the Source string.
  746.     \*/ 
  747.     for ( ipsz2 = ipszS ; *ipsz2 && *ipszS == ' ' ; ipsz2++ ) ;   
  748.  
  749.     /*\ 
  750.     |*| The next loop copies Source chars to the Target string one by one.
  751.     |*| When we encounter a run of blank characters, we defer copying 
  752.     |*|     until we find a subsequent non-blank character, at which point
  753.     |*|     we copy NrCopiesPadChar of *pPadChar into the Target string.
  754.     |*| 
  755.     |*| ipsz2 runs through the Source string to its end.
  756.     |*| InBlankRun is TRUE when we are pointing anywhere into a run 
  757.     |*|     of consecutive blanks, esle it is FALSE.
  758.     \*/ 
  759.     for ( InBlankRun = FALSE ; *ipsz2 ; ipsz2++ ) 
  760.         {   
  761.         if  ( *ipsz2 == ' ' )  
  762.             InBlankRun = TRUE ;
  763.         else 
  764.             {
  765.             if  ( InBlankRun ) 
  766.                 {
  767.                 int i ;
  768.                 InBlankRun = FALSE ; 
  769.                 for ( i = NrCopiesPadChar ; i ; --i )
  770.                     *ipszT++ = *pPadChar ;
  771.                 }
  772.             *ipszT++ = *ipsz2 ;
  773.             }
  774.         }          
  775.  
  776.     /*\ 
  777.     |*| Terminate the Target string with a zero delimiter.
  778.     \*/ 
  779.     *ipszT = '\0' ;  
  780.  
  781.     /*\ 
  782.     |*| The function return value is the address of the Target string.
  783.     \*/ 
  784.     return pszTarget ;
  785.     }
  786.