t1.cpp
Upload User: caisha3
Upload Date: 2013-09-21
Package Size: 208739k
Code Size: 92k
Category:

Windows Develop

Development Platform:

Visual C++

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // t1.cpp
  4. //      Explorer Font Folder extension routines
  5. //
  6. //
  7. // History:
  8. //      31 May 95 SteveCat
  9. //          Ported to Windows NT and Unicode, cleaned up
  10. //
  11. //
  12. // NOTE/BUGS
  13. //
  14. //  Copyright (C) 1992-1995 Microsoft Corporation
  15. //
  16. ///////////////////////////////////////////////////////////////////////////////
  17. //==========================================================================
  18. //                              Include files
  19. //==========================================================================
  20. // C Runtime
  21. #include <stddef.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <windows.h>
  25. #define ARRAYSIZE(a)    (sizeof(a)/sizeof(a[0]))
  26. // Application specific
  27. #undef IN
  28. #include "t1instal.h"
  29. #define CONST const
  30. #include "priv.h"
  31. #include "globals.h"
  32. #include "fontcl.h"
  33. #include "resource.h"
  34. #include "ui.h"
  35. #include "cpanel.h"
  36. #include "fontman.h"
  37. extern FullPathName_t  s_szSharedDir;
  38. TCHAR c_szDescFormat[] = TEXT( "%s (%s)" );
  39. TCHAR c_szPostScript[] = TEXT( "Type 1" );
  40. TCHAR szFonts[] = TEXT( "fonts" );
  41. char  g_szFontsDirA[ PATHMAX ];           //  ANSI string!
  42. TCHAR m_szMsgBuf[ PATHMAX ];
  43. TCHAR szTTF[ ] = TEXT(".TTF");
  44. TCHAR szFON[ ] = TEXT(".FON");
  45. TCHAR szPFM[ ] = TEXT(".PFM");
  46. TCHAR szPFB[ ] = TEXT(".PFB");
  47. typedef const void (__stdcall *PROGRESSPROC)( short, void *);
  48. #undef T1_SUPPORT
  49. BOOL RegisterProgressClass( void );
  50. VOID UnRegisterProgressClass( void );
  51. ///////////////////////////////////////////////////////////////////////////////
  52. ///////////////////////////////////////////////////////////////////////////////
  53. #if defined(T1_SUPPORT)
  54. #include "t1.h"
  55. #include "cpanel.h"  // for bUniqueOnSharedDir()
  56. typedef short (__stdcall *CONVERTTYPEFACEPROC) ( char *, char *, char *, PROGRESSPROC, void *);
  57. typedef BOOL  (__stdcall *CHECKTYPE1PROC)( char *, DWORD, char *, DWORD, char *, DWORD, char *, BOOL *);
  58. typedef short (__stdcall *CHECKCOPYRIGHTPROC)( char *, DWORD, char *);
  59. CONVERTTYPEFACEPROC lpConvertTypefaceA = 0;
  60. CHECKTYPE1PROC      lpCheckType1A = 0;
  61. CHECKCOPYRIGHTPROC  lpCheckCopyrightA = 0;
  62. // --------------------------------------------------------------------
  63. // The Following functions support Type 1 to TrueType conversion.
  64. // --------------------------------------------------------------------
  65. BOOL bInitType1( )
  66. {
  67.     static BOOL bTriedOne = FALSE;
  68.     static HINSTANCE g_hType1;
  69.     if( !g_hType1 && !bTriedOne )
  70.     {
  71.         g_hType1 = LoadLibrary( TEXT( "T1INSTAL.DLL" ) );
  72.         bTriedOne = TRUE;
  73.         if( g_hType1 )
  74.         {
  75.             lpConvertTypefaceA = (CONVERTTYPEFACEPROC) GetProcAddress( g_hType1, "ConvertTypefaceA" );
  76.             lpCheckType1A = (CHECKTYPE1PROC) GetProcAddress( g_hType1, "CheckType1A" );
  77.             lpCheckCopyrightA = (CHECKCOPYRIGHTPROC) GetProcAddress( g_hType1, "CheckCopyrightA" );
  78.             if( !lpConvertTypefaceA || !lpCheckType1A || !lpCheckCopyrightA )
  79.                 g_hType1 = FALSE;
  80.         }
  81.     }
  82.     return( g_hType1 != 0 );
  83. }
  84. BOOL NEAR PASCAL bIsType1( LPSTR        lpFile,
  85.                            FontDesc_t * lpDesc,
  86.                            LPT1_INFO    lpInfo )
  87. {
  88.     BOOL bRet = FALSE;
  89.     T1_INFO  t1_info;
  90.     if( bInitType1( ) )
  91.     {
  92.         if( !lpInfo )
  93.             lpInfo = &t1_info;
  94.         bRet = (*lpCheckType1A)( lpFile,
  95.                                  sizeof( FontDesc_t ), (char *)lpDesc,
  96.                                  sizeof( lpInfo->pfm ), (char *)&lpInfo->pfm,
  97.                                  sizeof( lpInfo->pfb ), (char *)&lpInfo->pfb,
  98.                                  &lpInfo->bCreatedPFM );
  99.     }
  100.     return bRet;
  101. }
  102. BOOL NEAR PASCAL bConvertT1( LPT1_INFO lpInfo )
  103. {
  104.     BOOL    bRet = FALSE;
  105.     char  szVendor[ 128 ];
  106.     if( bInitType1( ) )
  107.     {
  108.         short nRet = (*lpCheckCopyrightA)( lpInfo->pfb, sizeof( szVendor ), szVendor );
  109.         if( nRet >= 0 )
  110.         {
  111.             //
  112.             //  Get a TT file name to convert it to and convert it.
  113.             //
  114.             if( bUniqueOnSharedDir( lpInfo->ttf, "CvtT1.ttf" ) )
  115.             {
  116.                 bRet = (*lpConvertTypefaceA)( lpInfo->pfb, lpInfo->pfm,
  117.                                               lpInfo->ttf, 0, 0 );
  118.             }
  119.         }
  120.     }
  121.     return bRet;
  122. }
  123. #endif   // T1_SUPPORT
  124. #ifdef WINNT
  125. //==========================================================================
  126. //                        Local Definitions
  127. //==========================================================================
  128. #define GWL_PROGRESS    0
  129. #define SET_PROGRESS    WM_USER
  130. //  Progress Control color indices
  131. #define PROGRESSCOLOR_FACE        0
  132. #define PROGRESSCOLOR_ARROW       1
  133. #define PROGRESSCOLOR_SHADOW      2
  134. #define PROGRESSCOLOR_HIGHLIGHT   3
  135. #define PROGRESSCOLOR_FRAME       4
  136. #define PROGRESSCOLOR_WINDOW      5
  137. #define PROGRESSCOLOR_BAR         6
  138. #define PROGRESSCOLOR_TEXT        7
  139. #define CCOLORS                   8
  140. #define CHAR_BACKSLASH  TEXT( '\' )
  141. #define CHAR_COLON      TEXT( ':' )
  142. #define CHAR_NULL       TEXT( '' )
  143. #define CHAR_TRUE       TEXT( 'T' )
  144. #define CHAR_FALSE      TEXT( 'F' )
  145. //==========================================================================
  146. //                       External Declarations
  147. //==========================================================================
  148. extern HWND  hLBoxInstalled;
  149. //==========================================================================
  150. //                       Local Data Declarations
  151. //==========================================================================
  152. BOOL bYesAll_PS = FALSE;        //  Use global state for all PS fonts
  153. BOOL bConvertPS = TRUE;         //  Convert Type1 files to TT
  154. BOOL bInstallPS = TRUE;         //  Install PS files
  155. BOOL bCopyPS    = TRUE;         //  Copy PS files to Windows dir
  156. BOOL bCancelInstall = FALSE;    // Global installation cancel
  157. TCHAR szTrue[]  = TEXT( "T" );
  158. TCHAR szFalse[] = TEXT( "F" );
  159. TCHAR szHash[]  = TEXT( "#" );
  160. BOOL bProgMsgDisplayed;         //  Used by Progress to avoid msg flicker
  161. BOOL bProg2MsgDisplayed;        //  Used by Progress2 to avoid msg flicker
  162. HWND hDlgProgress = NULL;
  163. //
  164. //  Used to determine Foreground/Backgnd colors for progress bar control
  165. //  Global values are set at RegisterClass time
  166. //
  167. DWORD   rgbFG;
  168. DWORD   rgbBG;
  169. //  Registry location for installing PostScript printer font info
  170. TCHAR g_szType1Key[] = TEXT( "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Type 1 Installer\Type 1 Fonts" );
  171. //
  172. //  Array of default colors, matching the order of PROGRESSCOLOR_* values.
  173. //
  174. DWORD rgColorPro[ CCOLORS ] = {
  175.                          COLOR_BTNFACE,             //  PROGRESSCOLOR_FACE
  176.                          COLOR_BTNTEXT,             //  PROGRESSCOLOR_ARROW
  177.                          COLOR_BTNSHADOW,           //  PROGRESSCOLOR_SHADOW
  178.                          COLOR_BTNHIGHLIGHT,        //  PROGRESSCOLOR_HIGHLIGHT
  179.                          COLOR_WINDOWFRAME,         //  PROGRESSCOLOR_FRAME
  180.                          COLOR_WINDOW,              //  PROGRESSCOLOR_WINDOW
  181.                          COLOR_ACTIVECAPTION,       //  PROGRESSCOLOR_BAR
  182.                          COLOR_CAPTIONTEXT          //  PROGRESSCOLOR_TEXT
  183.                          };
  184. typedef struct _T1_INSTALL_OPTIONS
  185. {
  186.     BOOL        bMatchingTT;
  187.     BOOL        bOnlyPSInstalled;
  188.     LPTSTR      szDesc;
  189.     WORD        wFontType;
  190. } T1_INSTALL_OPTIONS, *PT1_INSTALL_OPTIONS;
  191. //
  192. //  Linked-list structure used for copyright Vendors
  193. //
  194. typedef struct _psvendor
  195. {
  196.     struct _psvendor *pNext;
  197.     LPTSTR pszCopyright;            //  Copyright string
  198.     int    iResponse;               //  User's response to YES/NO MsgBox
  199. } PSVENDOR;
  200. PSVENDOR *pFirstVendor = NULL;      //  ptr to linked list for PS vendors
  201. //==========================================================================
  202. //                      Local Function Prototypes
  203. //==========================================================================
  204. BOOL CheckTTInstall( LPTSTR szDesc );
  205. void Draw3DRect( HDC hDC, HBRUSH hBrushFace, HPEN hPenFrame, HPEN hPenHigh,
  206.                  HPEN hPenShadow, int x1, int y1, int x2, int y2 );
  207. INT_PTR APIENTRY InstallPSDlg( HWND hDlg, UINT nMsg, WPARAM wParam, LPARAM lParam );
  208. void STDCALL  Progress( short PercentDone, void* UniqueValue );
  209. LRESULT APIENTRY ProgressBarCtlProc( HWND hTest, UINT message, WPARAM wParam, LPARAM lParam );
  210. INT_PTR APIENTRY ProgressDlg( HWND hDlg, UINT nMsg, WPARAM wParam, LPARAM lParam );
  211. INT_PTR APIENTRY CopyrightNotifyDlgProc( HWND hDlg, UINT nMsg, WPARAM wParam, LPARAM lParam );
  212. LONG ProgressPaint( HWND hWnd, DWORD dwProgress );
  213. //==========================================================================
  214. //                           Functions
  215. //==========================================================================
  216. /////////////////////////////////////////////////////////////////////////////
  217. //
  218. // StripFilespec
  219. //
  220. //   Remove the filespec portion from a path (including the backslash).
  221. //
  222. /////////////////////////////////////////////////////////////////////////////
  223. VOID StripFilespec( LPTSTR lpszPath )
  224. {
  225.    LPTSTR     p;
  226.    p = lpszPath + lstrlen( lpszPath );
  227.    while( ( *p != CHAR_BACKSLASH )  && ( *p != CHAR_COLON )  && ( p != lpszPath ) )
  228.       p--;
  229.    if( *p == CHAR_COLON )
  230.       p++;
  231.    //
  232.    //  Don't strip backslash from root directory entry.
  233.    //
  234.    if( p != lpszPath )
  235.    {
  236.       if( ( *p == CHAR_BACKSLASH )  && ( *( p - 1 )  == CHAR_COLON ) )
  237.          p++;
  238.    }
  239.    *p = CHAR_NULL;
  240. }
  241. /////////////////////////////////////////////////////////////////////////////
  242. //
  243. // StripPath
  244. //
  245. //   Extract only the filespec portion from a path.
  246. //
  247. /////////////////////////////////////////////////////////////////////////////
  248. VOID StripPath( LPTSTR lpszPath )
  249. {
  250.   LPTSTR     p;
  251.   p = lpszPath + lstrlen( lpszPath );
  252.   while( ( *p != CHAR_BACKSLASH )  && ( *p != CHAR_COLON )  && ( p != lpszPath ) )
  253.       p--;
  254.   if( p != lpszPath )
  255.       p++;
  256.   if( p != lpszPath )
  257.       lstrcpy( lpszPath, p );
  258. }
  259. /////////////////////////////////////////////////////////////////////////////
  260. //
  261. // AddVendorCopyright
  262. //
  263. //  Add a PostScript Vendor's Copyright and User response to "MAYBE" list.
  264. //  This linked-list is used to keep track of a user's prior response to
  265. //  message about converting this vendor's fonts to TrueType.  If a vendor
  266. //  is not in the registry, we cannot automatically assume that the font
  267. //  can be converted.  We must present the User with a message, asking them
  268. //  to get permission from the vendor before converting the font to TrueType.
  269. //
  270. //  However, we do allow them to continue the installation and convert the
  271. //  font to TrueType by selecting the YES button on the Message box.  This
  272. //  routine keeps track of each vendor and the User's response for that
  273. //  vendor.  This way we do not continually ask them about the same vendor
  274. //  during installation of a large number of fonts.
  275. //
  276. //  (Insert item into linked list )
  277. //
  278. //
  279. /////////////////////////////////////////////////////////////////////////////
  280. BOOL AddVendorCopyright( LPTSTR pszCopyright, int iResponse )
  281. {
  282.     PSVENDOR *pVendor;          //  temp pointer to linked list
  283.     //
  284.     //  Make the new PSVENDOR node and add it to the linked list.
  285.     //
  286.     if( pFirstVendor )
  287.     {
  288.         pVendor = (PSVENDOR *) AllocMem( sizeof( PSVENDOR ) );
  289.         if( pVendor )
  290.         {
  291.             pVendor->pNext = pFirstVendor;
  292.             pFirstVendor = pVendor;
  293.         }
  294.         else
  295.             return FALSE;
  296.     }
  297.     else        // First time thru
  298.     {
  299.         pFirstVendor = (PSVENDOR *) AllocMem( sizeof( PSVENDOR ) );
  300.         if( pFirstVendor )
  301.             pFirstVendor->pNext = NULL;
  302.         else
  303.             return FALSE;
  304.     }
  305.     //
  306.     //  Save User response and Copyright string
  307.     //
  308.     pFirstVendor->iResponse = iResponse;
  309.     pFirstVendor->pszCopyright = AllocStr( pszCopyright );
  310.     //
  311.     //  Return success.
  312.     //
  313.     return TRUE;
  314. }
  315. /////////////////////////////////////////////////////////////////////////////
  316. //
  317. // CheckVendorCopyright
  318. //
  319. //  Check if a Vendor Copyright is already in the "MAYBE" linked-list and
  320. //  and return User response if it is found.
  321. //
  322. //  Returns:
  323. //          IDYES  - User wants to convert typeface anyway
  324. //          IDNO   - User does not want to convert typeface
  325. //          -1     - Entry not found
  326. //
  327. /////////////////////////////////////////////////////////////////////////////
  328. int CheckVendorCopyright( LPTSTR pszCopyright )
  329. {
  330.     PSVENDOR *pVendor;          // temp pointer to linked list
  331.     //
  332.     //  Traverse the list, testing each node for matching copyright string
  333.     //
  334.     pVendor = pFirstVendor;
  335.     while( pVendor )
  336.     {
  337.         if( !lstrcmpi( pVendor->pszCopyright, pszCopyright ) )
  338.             return( pVendor->iResponse );
  339.         pVendor = pVendor->pNext;
  340.     }
  341.     //
  342.     //  "Did not find matching copyright" return
  343.     //
  344.     return( -1 );
  345. }
  346. ///////////////////////////////////////////////////////////////////////////////
  347. //
  348. // FUNCTION: CopyrightNotifyDlgProc
  349. //
  350. // DESCRIP:  Display the dialog informing the user about possible
  351. //           Type1 font copyright problems.
  352. //
  353. // ARGS:     lParam is the address of an array of text string pointers.
  354. //           Element 0 is the name of the font.
  355. //           Element 1 is the name of the vendor.
  356. //
  357. ///////////////////////////////////////////////////////////////////////////////
  358. enum arg_nums{ARG_FONTNAME = 0, ARG_VENDORNAME};
  359. INT_PTR APIENTRY CopyrightNotifyDlgProc( HWND hDlg, UINT nMsg, WPARAM wParam, LPARAM lParam )
  360. {
  361.     switch( nMsg )
  362.     {
  363.         case WM_INITDIALOG:
  364.         {
  365.             LPCTSTR *lpaszTextItems   = (LPCTSTR *)lParam;
  366.             LPCTSTR lpszVendorName    = NULL;
  367.             TCHAR szUnknownVendor[80] = { TEXT('') };
  368.             ASSERT(NULL != lpaszTextItems);
  369.             ASSERT(NULL != lpaszTextItems[ARG_FONTNAME]);
  370.             ASSERT(NULL != lpaszTextItems[ARG_VENDORNAME]);
  371.             //
  372.             // Set font name string.
  373.             //
  374.             SetWindowText(GetDlgItem(hDlg, IDC_COPYRIGHT_FONTNAME),
  375.                                            lpaszTextItems[ARG_FONTNAME]);
  376.             //
  377.             // Set vendor name string.  If name provided is blank, use a default
  378.             // string of "Unknown Vendor Name" from string table.
  379.             //
  380.             if (TEXT('') == *lpaszTextItems[ARG_VENDORNAME])
  381.             {
  382.                 UINT cchLoaded = 0;
  383.                 cchLoaded = LoadString(g_hInst, IDSI_UNKNOWN_VENDOR,
  384.                                        szUnknownVendor, ARRAYSIZE(szUnknownVendor));
  385.                 ASSERT(cchLoaded > 0); // Complain if someone removed resource string.
  386.                 lpszVendorName = szUnknownVendor;
  387.             }
  388.             else
  389.                 lpszVendorName = lpaszTextItems[ARG_VENDORNAME];
  390.             SetWindowText(GetDlgItem(hDlg, IDC_COPYRIGHT_VENDORNAME), lpszVendorName),
  391.             CentreWindow( hDlg );
  392.             break;
  393.         }
  394.     case WM_COMMAND:
  395.         switch( LOWORD( wParam ) )
  396.         {
  397.             case IDYES:
  398.             case IDNO:
  399.                 //
  400.                 // Dialog Proc must return IDYES or IDNO when a button
  401.                 // is selected.  This is the value stored in the Vendor Copyright
  402.                 // list.
  403.                 //
  404.                 EndDialog(hDlg, LOWORD(wParam));
  405.                 break;
  406.             default:
  407.                 return FALSE;
  408.         }
  409.         break;
  410.     default:
  411.         return FALSE;
  412.     }
  413.     return TRUE;
  414. }
  415. //
  416. // OkToConvertType1ToTrueType
  417. //
  418. // This function checks the authorization for converting a Type1
  419. // font to it's TrueType equivalent.  Authorization information is stored
  420. // in the registry under the section ...Type 1 InstallerCopyrights.
  421. //
  422. // If authorization is GRANTED, the function returns TRUE and the font may be
  423. // converted to TrueType.
  424. //
  425. // If authorization is explicitly DENIED and the user has not selected
  426. // "Yes to All" in the Type1 options dialog, a message box is displayed
  427. // informing the user of the denial and the function returns FALSE
  428. //
  429. // If no authorization information is found in the registry for this vendor,
  430. // a dialog box is displayed warning the user about possible copyright
  431. // violations.  The user can answer Yes to convert the font anyway or No
  432. // to skip the conversion.  This response is stored in memory on a per-vendor
  433. // basis so that the user won't have to respond to this same question if
  434. // a font from this vendor is encountered again.
  435. //
  436. BOOL OkToConvertType1ToTrueType(LPCTSTR pszFontDesc, LPCTSTR pszPFB, HWND hwndParent)
  437. {
  438.     char    szCopyrightA[MAX_PATH]; // For string from Type1 (ANSI) file.
  439. #ifdef UNICODE
  440.     WCHAR   szCopyrightW[MAX_PATH]; // For display in UNICODE build.
  441.     char    szPfbA[MAX_PATH];       // For arg to CheckCopyrightA (ANSI).
  442. #endif
  443.     LPTSTR  pszCopyright = NULL;    // Ptr to Copyright string (A or W).
  444.     LPSTR   pszPfbA      = NULL;    // Ptr to ANSI PFB filename string.
  445.     DWORD   dwStatus     = 0;       // Temp result variable.
  446.     BOOL    bResult      = FALSE;   // Function return value.
  447.     //
  448.     //  Check convertability of this font from Type1 to TrueType.
  449.     //
  450.     //  Returns: SUCCESS, FAILURE, MAYBE
  451.     //
  452. #ifdef UNICODE
  453.     WideCharToMultiByte(CP_ACP, 0, pszPFB, -1, szPfbA, ARRAYSIZE(szPfbA), NULL, NULL);
  454.     pszPfbA = szPfbA;
  455. #else
  456.     pszPfbA = pszPFB;
  457. #endif
  458.     dwStatus = CheckCopyrightA(pszPfbA, ARRAYSIZE(szCopyrightA), szCopyrightA);
  459.     if (SUCCESS == dwStatus)
  460.     {
  461.         bResult = TRUE;
  462.     }
  463.     else
  464.     {
  465. #ifdef UNICODE
  466.         MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szCopyrightA, -1,
  467.                                          szCopyrightW, ARRAYSIZE(szCopyrightW));
  468.         pszCopyright = szCopyrightW;
  469. #else
  470.         pszCopyright = szCopyrightA;
  471. #endif
  472.         switch(dwStatus)
  473.         {
  474.             case FAILURE:
  475.                 //
  476.                 //  Put up a message box stating that this Type1 font vendor
  477.                 //  does not allow us to Convert their fonts to TT.  This will
  478.                 //  let the user know that it is not Microsoft's fault that the
  479.                 //  font is not converted to TT, but the vendor's fault.
  480.                 //
  481.                 //  NOTE:  This is only done if the User has NOT selected the
  482.                 //         YesToAll_PS install option.  Otherwise it will be very
  483.                 //         annoying to see message repeated over and over.
  484.                 //
  485.                 if (!bYesAll_PS)
  486.                 {
  487.                     iUIMsgBox( hwndParent,
  488.                                MYFONT + 2, IDS_MSG_CAPTION,
  489.                                MB_OK | MB_ICONEXCLAMATION,
  490.                                (LPTSTR)  pszCopyright,
  491.                                (LPTSTR)  pszFontDesc );
  492.                 }
  493.                 break;
  494.             case MAYBE:
  495.                 //
  496.                 //  Check font copyright and ask for user response if necessary
  497.                 //
  498.                 switch(CheckVendorCopyright(pszCopyright))
  499.                 {
  500.                     case IDYES:
  501.                         //
  502.                         // User previously responded "Yes" for converting fonts
  503.                         // from this vendor.  Automatic approval.
  504.                         //
  505.                         bResult = TRUE;
  506.                         break;
  507.                     case IDNO:
  508.                         //
  509.                         // User previously responded "No" for converting fonts
  510.                         // from this vendor.  Automatic denial.
  511.                         //
  512.                         bResult = FALSE;
  513.                         break;
  514.                     case -1:
  515.                     default:
  516.                     {
  517.                         //
  518.                         // No previous record of having asked user about this vendor.
  519.                         //
  520.                         INT iResponse = IDNO;
  521.                         //
  522.                         // Warn user about possible copyright problems.
  523.                         // Ask if they want to convert to TrueType anyway.
  524.                         //
  525.                         LPCTSTR lpszDlgTextItems[] = {pszFontDesc, pszCopyright};
  526.                         iResponse = (INT)DialogBoxParam(g_hInst,
  527.                                                    MAKEINTRESOURCE(DLG_COPYRIGHT_NOTIFY),
  528.                                                    hwndParent ? hwndParent : HWND_DESKTOP,
  529.                                                    CopyrightNotifyDlgProc,
  530.                                                    (LPARAM)lpszDlgTextItems);
  531.                         //
  532.                         // Remember this response for this vendor.
  533.                         //
  534.                         AddVendorCopyright(pszCopyright, iResponse);
  535.                         //
  536.                         // Translate user response to a T/F return value.
  537.                         //
  538.                         bResult = (iResponse == IDYES);
  539.                         break;
  540.                     }
  541.                 }
  542.                 break;
  543.             default:
  544.                 //
  545.                 //  ERROR! from routine - assume worst case
  546.                 //
  547.                 break;
  548.         }
  549.     }
  550.     return bResult;
  551. }
  552. /////////////////////////////////////////////////////////////////////////////
  553. //
  554. // IsPSFont
  555. //
  556. //  Check validity of font file passed in and get paths to .pfm/.pfb
  557. //  files, determine if it can be converted to TT.
  558. //
  559. // in:
  560. //    lpszPfm        .pfm file name to validate
  561. // out:
  562. //    lpszDesc       on succes Font Name of Type1
  563. //    lpszPfm        on succes the path to .pfm file
  564. //    lpszPfb        on succes the path to .pfb file
  565. //    pbCreatedPFM   on succes whether a PFM file was created or not
  566. //                   If valid pointer on entry...
  567. //                   *bpCreatedPFM == TRUE means check for existing PFM.
  568. //                                    FALSE means don't check for PFM.
  569. //    lpdwStatus     Address of caller status variable.  Use this value
  570. //                   to determine cause of FALSE return value.
  571. //
  572. // NOTE: Assumes that lpszPfm and lpszPfb are of size PATHMAX & lpszDesc is
  573. //       of size DESCMAX
  574. //
  575. // returns:
  576. //    TRUE success, FALSE failure
  577. //
  578. // The following table lists the possible font verification status codes
  579. // returned in *lpdwStatus along with a brief description of the cause for each.
  580. // See fvscodes.h for numeric code value details.
  581. //
  582. //
  583. //          FVS_SUCCESS
  584. //          FVS_FILE_OPEN_ERR
  585. //          FVS_BUILD_ERR
  586. //          FVS_FILE_EXISTS
  587. //          FVS_INSUFFICIENT_BUF
  588. //          FVS_INVALID_FONTFILE
  589. //          FVS_BAD_VERSION
  590. //          FVS_FILE_IO_ERR
  591. //          FVS_EXCEPTION
  592. //
  593. /////////////////////////////////////////////////////////////////////////////
  594. BOOL IsPSFont( LPTSTR lpszKey,
  595.                LPTSTR lpszDesc,         //  Optional
  596.                LPTSTR lpszPfm,          //  Optional
  597.                LPTSTR lpszPfb,          //  Optional
  598.                BOOL  *pbCreatedPFM,     //  Optional
  599.                LPDWORD lpdwStatus )     //  May be NULL
  600. {
  601.     BOOL    bRet = FALSE;
  602.     TCHAR   strbuf[ PATHMAX ] ;
  603.     BOOL    bPFM;
  604.     //
  605.     //  ANSI buffers for use with ANSI only API's
  606.     //
  607.     char    *desc, Descbuf[ PATHMAX ] ;
  608.     char    Keybuf[ PATHMAX ] ;
  609.     char    *pfb, Pfbbuf[ PATHMAX ] ;
  610.     char    *pfm, Pfmbuf[ PATHMAX ] ;
  611.     DWORD   iDesc, iPfb, iPfm;
  612.     DWORD   dwStatus = FVS_MAKE_CODE(FVS_SUCCESS, FVS_FILE_UNK);
  613.     //
  614.     // Initialize status return.
  615.     //
  616.     if (NULL != lpdwStatus)
  617.         *lpdwStatus = FVS_MAKE_CODE(FVS_INVALID_STATUS, FVS_FILE_UNK);
  618.     if( lpszDesc )
  619.         *lpszDesc = (TCHAR)  0;
  620.     desc = Descbuf;
  621.     iDesc = PATHMAX;
  622.     pfb = Pfbbuf;
  623.     iPfb = PATHMAX;
  624.     if( lpszPfm )
  625.     {
  626.         pfm = Pfmbuf;
  627.         iPfm = PATHMAX;
  628.     }
  629.     else
  630.     {
  631.         pfm = NULL;
  632.         iPfm = 0;
  633.     }
  634.     if( pbCreatedPFM )
  635.     {
  636.         bPFM = *pbCreatedPFM;  // Caller says if CheckType1WithStatusA checks for dup PFM
  637.         *pbCreatedPFM = FALSE;
  638.     }
  639.     else
  640.         bPFM = TRUE;  // By default, CheckType1WithStatusA should check for dup PFM.
  641.     WideCharToMultiByte( CP_ACP, 0, lpszKey, -1, Keybuf, PATHMAX, NULL, NULL );
  642.     //
  643.     //  The CheckType1WithStatusA routine accepts either a .INF or .PFM file name as
  644.     //  the Keybuf( i.e. Key file )   input parameter.  If the input is a .INF
  645.     //  file, a .PFM file will be created in the SYSTEM directory if (and
  646.     //  only if) the .PFM file name parameter is non-NULL.  Otherwise, it
  647.     //  will just check to see if a valid .INF, .AFM and .PFB file exist for
  648.     //  the font.
  649.     //
  650.     //  The bPFM BOOL value is an output parameter that tells me if the routine
  651.     //  created a .PFM file from the .INF/.AFM file for this font.  If the
  652.     //  pfm input parameter is non-NULL, it will always receive the proper
  653.     //  path for the .PFM file.
  654.     //
  655.     //  The bPFM flag is used to tell CheckType1WithStatusA if it should check for an
  656.     //  existing PFM file.  If invoked as part of a drag-drop install, we
  657.     //  don't want to do this check.  If from install dialog, do the check.
  658.     //
  659.     dwStatus = ::CheckType1WithStatusA( Keybuf, iDesc, desc, iPfm, pfm, iPfb, pfb, &bPFM, g_szFontsDirA );
  660.     if( FVS_STATUS(dwStatus) == FVS_SUCCESS)
  661.     {
  662.         if( pbCreatedPFM )
  663.             *pbCreatedPFM = bPFM;
  664.         //
  665.         //  Return Font description
  666.         //
  667.         if( lpszDesc )
  668.         {
  669. #ifdef UNICODE
  670.             //
  671.             //  Convert Descbuf to UNICODE since Type1 files are ANSI
  672.             //
  673.             MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, Descbuf, -1, strbuf, PATHMAX );
  674.             vCPStripBlanks(strbuf);
  675.             wsprintf(lpszDesc, c_szDescFormat, strbuf, c_szPostScript );
  676. #else
  677.             vCPStripBlanks(Descbuf);
  678.             wsprintf(lpszDesc, c_szDescFormat, Descbuf, c_szPostScript );
  679. #endif
  680.         }
  681.         //
  682.         //  Return PFM file name
  683.         //
  684.         if( lpszPfm )
  685.         {
  686.             //
  687.             //  Return PFM file name - convert to UNICODE since Type1 files are ANSI
  688.             //
  689. #ifdef UNICODE
  690.             MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, Pfmbuf, -1, lpszPfm, PATHMAX );
  691. #else
  692.             lstrcpy(lpszPfm, Pfmbuf);
  693. #endif
  694.         }
  695.         //
  696.         //  Return PFB file name
  697.         //
  698.         if( lpszPfb )
  699.         {
  700.             //
  701.             //  Return PFB file name - convert to UNICODE since Type1 files are ANSI
  702.             //
  703. #ifdef UNICODE
  704.             MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, Pfbbuf, -1, lpszPfb, PATHMAX );
  705. #else
  706.             lstrcpy(lpszPfb, Pfbbuf);
  707. #endif
  708.         }
  709.         bRet = TRUE;
  710.     }
  711.     //
  712.     // Return status if user wants it.
  713.     //
  714.     if (NULL != lpdwStatus)
  715.        *lpdwStatus = dwStatus;
  716.     return bRet;
  717. }
  718. /////////////////////////////////////////////////////////////////////////////
  719. //
  720. // InitPSInstall
  721. //
  722. //  Initialize PostScript install routine global variables.
  723. //
  724. /////////////////////////////////////////////////////////////////////////////
  725. void InitPSInstall( )
  726. {
  727.     CFontManager *poFontManager;
  728.     if (SUCCEEDED(GetFontManager(&poFontManager)))
  729.     {
  730.         //
  731.         //  Initialize linked list variables for "MAYBE" copyright vendor list
  732.         //
  733.         pFirstVendor = NULL;
  734.         //
  735.         //  Other installation globals
  736.         //
  737.         bYesAll_PS = FALSE;
  738.         //
  739.         // If the native ATM driver is installed, we NEVER convert from Type1 to
  740.         // TrueType.
  741.         //
  742.         bConvertPS = !poFontManager->Type1FontDriverInstalled();
  743.         bInstallPS = TRUE;
  744.         bCopyPS    = TRUE;
  745.         ReleaseFontManager(&poFontManager);
  746.     }        
  747.     return;
  748. }
  749. /////////////////////////////////////////////////////////////////////////////
  750. //
  751. // TermPSInstall
  752. //
  753. //  Initialize PostScript install routine global variables.
  754. //
  755. /////////////////////////////////////////////////////////////////////////////
  756. void TermPSInstall( )
  757. {
  758.     PSVENDOR *pVendor;
  759.     //
  760.     //  Traverse the list, freeing list memory and strings.
  761.     //
  762.     pVendor = pFirstVendor;
  763.     while( pVendor )
  764.     {
  765.         pFirstVendor = pVendor;
  766.         pVendor = pVendor->pNext;
  767.         if( pFirstVendor->pszCopyright )
  768.             FreeStr( pFirstVendor->pszCopyright );
  769.         FreeMem( (LPVOID)  pFirstVendor, sizeof( PSVENDOR ) );
  770.     }
  771.     //
  772.     //  Reset global to be safe
  773.     //
  774.     pFirstVendor = NULL;
  775.     return;
  776. }
  777. /////////////////////////////////////////////////////////////////////////////
  778. //
  779. // InstallT1Font
  780. //
  781. //  Install PostScript Type1 font, possibly converting the Type1 font to a
  782. //  TrueType font in the process.  Write registry entries so the PostScript
  783. //  printer driver can find these files either in their original source
  784. //  directory or locally in the 'shared' or system directory.
  785. //
  786. /////////////////////////////////////////////////////////////////////////////
  787. int InstallT1Font( HWND   hwndParent,
  788.                    BOOL   bCopyTTFile,          //  Copy TT file?
  789.                    BOOL   bCopyType1Files,      //  Copy PFM/PFB to font folder?
  790.                    BOOL   bInSharedDir,         //  Files in Shared Directory?
  791.                    LPTSTR szKeyName,            //  IN: PFM/INF Source File name & dir
  792.                                                 //  OUT: Destination file name
  793.                    LPTSTR szDesc )              //  INOUT: Font description
  794. {
  795.     WORD   wFontType = NOT_TT_OR_T1;            //  Enumerated Font type
  796.     int    rc, iRet;
  797.     WORD   wMsg;
  798.     BOOL   bCreatedPfm = FALSE;  // F = IsPSFont doesn't check for existing PFM
  799.     TCHAR  szTemp[    PATHMAX ] ;
  800.     TCHAR  szTemp2[   PATHMAX ] ;
  801.     TCHAR  szPfbName[ PATHMAX ] ;
  802.     TCHAR  szPfmName[ PATHMAX ] ;
  803.     TCHAR  szSrcDir[  PATHMAX ] ;
  804.     TCHAR  szDstName[ PATHMAX ] ;
  805.     TCHAR  szTTFName[ PATHMAX ] ;
  806.     TCHAR  *pszArg1, *pszArg2;
  807.     T1_INSTALL_OPTIONS t1ops;
  808.     //
  809.     //  ASCII Buffers for use in ASCII-only api calls
  810.     //
  811.     char  pfb[ PATHMAX ] ;
  812.     char  pfm[ PATHMAX ] ;
  813.     char  ttf[ PATHMAX ] ;
  814.     DWORD dwStatus = FVS_MAKE_CODE(FVS_SUCCESS, FVS_FILE_UNK);
  815.     //////////////////////////////////////////////////////////////////////
  816.     //
  817.     //  Check if font is already loaded on the system
  818.     //
  819.     //////////////////////////////////////////////////////////////////////
  820.     t1ops.bOnlyPSInstalled = FALSE;
  821.     t1ops.bMatchingTT      = FALSE;
  822.     //
  823.     //  Check both Type1 & Fonts registry location for prior font installation
  824.     //
  825.     if( CheckT1Install( szDesc, NULL ) )
  826.     {
  827.         //
  828.         // "Font is already loaded"
  829.         //
  830.         iRet = iUIMsgOkCancelExclaim( hwndParent,
  831.                                       MYFONT + 5,
  832.                                       IDS_MSG_CAPTION,
  833.                                       (LPTSTR)szDesc);
  834.         //
  835.         // Return without deleting the PFM file.
  836.         // Because this font is a duplicate, the PFM
  837.         // already existed.
  838.         //
  839.         goto MasterExit;
  840.     }
  841.     else if( CheckTTInstall( szDesc ) )
  842.     {
  843.         t1ops.bMatchingTT = TRUE;
  844.         if( !bYesAll_PS )
  845.         {
  846.             //
  847.             // "The TrueType version of this font is already installed."
  848.             //
  849.             switch( iUIMsgBox( hwndParent,
  850.                                MYFONT + 4, IDS_MSG_CAPTION,
  851.                                MB_YESNOCANCEL | MB_ICONEXCLAMATION,
  852.                                (LPTSTR) szDesc ) )
  853.             {
  854.             case IDYES:
  855.                 break;
  856.             case IDNO:
  857.                 iRet = TYPE1_INSTALL_IDNO;
  858.                 goto InstallPSFailure;
  859.             case IDCANCEL:
  860.             default:
  861.                 iRet = TYPE1_INSTALL_IDCANCEL;
  862.                 goto InstallPSFailure;
  863.             }
  864.         }
  865.     }
  866.     //
  867.     // BUGBUG [brianau]
  868.     // If we're installing from a .INF/.AFM pair, this function automatically
  869.     // creates a new .PFM file in the fonts directory, even if the .PFM file
  870.     // already exists.  This could cause a possible file mismatch between an
  871.     // existing .PFB and the new .PFM.
  872.     //
  873.     if(::IsPSFont( szKeyName, (LPTSTR) NULL, szPfmName, szPfbName,
  874.                      &bCreatedPfm, &dwStatus ))
  875.     {
  876.         CFontManager *poFontManager;
  877.         if (SUCCEEDED(GetFontManager(&poFontManager)))
  878.         {
  879.             wFontType = TYPE1_FONT;
  880.             lstrcpyn(szTemp, szDesc, ARRAYSIZE(szTemp));
  881.             RemoveDecoration(szTemp, TRUE);
  882.             if (poFontManager->Type1FontDriverInstalled() ||
  883.                 !OkToConvertType1ToTrueType(szTemp,
  884.                                             szPfbName,
  885.                                             hwndParent))
  886.             {
  887.                 wFontType = TYPE1_FONT_NC;
  888.             }
  889.             ReleaseFontManager(&poFontManager);
  890.         }
  891.     }
  892.     else
  893.     {
  894.         if (iUIMsgBoxInvalidFont(hwndParent, szKeyName, szDesc, dwStatus) == IDCANCEL)
  895.            iRet = TYPE1_INSTALL_IDCANCEL;
  896.         else
  897.            iRet = TYPE1_INSTALL_IDNO;
  898.         goto InstallPSFailure;
  899.     }
  900.     t1ops.szDesc = szDesc;
  901.     t1ops.wFontType = wFontType;
  902.     //
  903.     //  Keep a copy of source directory
  904.     //
  905.     lstrcpy( szSrcDir, szKeyName );
  906.     StripFilespec( szSrcDir );
  907.     lpCPBackSlashTerm( szSrcDir );
  908.     //
  909.     //  The global state of
  910.     //
  911.     //      bConvertPS  -  Convert Type1 files to TT
  912.     //      bInstallPS  -  Install PS files
  913.     //
  914.     //  is only effective for the last time the "Install Type 1 fonts"
  915.     //  dialog was displayed.  Check the state of these globals against
  916.     //  what we know about the current font to determine if the dialog
  917.     //  should be redisplayed.
  918.     //
  919.     //  5/31/94 [stevecat] DO NOT redisplay the dialog after "YesToAll"
  920.     //  selected once.  Instead, display messages about 'exceptions' to
  921.     //  their initial choices and give user the option to continue
  922.     //  installation.
  923.     //
  924.     if( bYesAll_PS )
  925.     {
  926.         //
  927.         //  If the PS version of this font is already installed AND the
  928.         //  global bInstall == TRUE, then the globals are out-of-sync
  929.         //  with this font.  Let user know and continue installation.
  930.         //
  931.         if( t1ops.bOnlyPSInstalled && bInstallPS )
  932.         {
  933.             //
  934.             // "The Type 1 version of this font is already installed."
  935.             //
  936.             switch( iUIMsgBox( hwndParent,
  937.                                MYFONT + 3, IDS_MSG_CAPTION,
  938.                                MB_YESNOCANCEL | MB_ICONEXCLAMATION,
  939.                                (LPTSTR) szDesc ) )
  940.             {
  941.             case IDYES:
  942.                 break;
  943.             case IDNO:
  944.                 iRet = TYPE1_INSTALL_IDNO;
  945.                 goto InstallPSFailure;
  946.             case IDCANCEL:
  947.             default:
  948.                 iRet = TYPE1_INSTALL_IDCANCEL;
  949.                 goto InstallPSFailure;
  950.             }
  951.         }
  952.         //
  953.         //  If the matching TT font is already installed AND the global
  954.         //  bConvertPS == TRUE, then the globals are out-of-sync with
  955.         //  this font.  Let the user know and continue installation.
  956.         //
  957.         if( t1ops.bMatchingTT && bConvertPS )
  958.         {
  959.             //
  960.             // "The TrueType version of this font is already installed."
  961.             //
  962.             switch( iUIMsgBox( hwndParent,
  963.                                MYFONT + 4, IDS_MSG_CAPTION,
  964.                                MB_YESNOCANCEL | MB_ICONEXCLAMATION,
  965.                                (LPTSTR) szDesc ) )
  966.             {
  967.             case IDYES:
  968.                 break;
  969.             case IDNO:
  970.                 iRet = TYPE1_INSTALL_IDNO;
  971.                 goto InstallPSFailure;
  972.             case IDCANCEL:
  973.             default:
  974.                 iRet = TYPE1_INSTALL_IDCANCEL;
  975.                 goto InstallPSFailure;
  976.             }
  977.         }
  978.     }
  979.     //
  980.     //  Get user options for PostScript font installation:
  981.     //      - TT conversion
  982.     //      - Type1 installation
  983.     //      - Copying Type1 files
  984.     //
  985.     //  State returned in globals:
  986.     //
  987.     //      bConvertPS  -  Convert Type1 files to TT
  988.     //      bInstallPS  -  Install PS files
  989.     //      bCopyPS     -  Copy PS files to WindowsSystem dir
  990.     //
  991.     //
  992.     // The following section of commented-out code prevents the Type1 font
  993.     // installation dialog from being displayed.  Since we're removing
  994.     // the requirement for Type1-to-TrueType conversion from NT5, this
  995.     // dialog is no longer necessary.  Instead of taking out all of the code
  996.     // related to Type1-TrueType conversion, I've merely disabled this dialog
  997.     // and automatically set the values of bConvertPS, bInstallPS and bCopyPS.
  998.     // To do this right, the font folder needs to be re-written from scratch.
  999.     // It's a real mess and is very fragile so I don't want to introduce subtle
  1000.     // errors or spend a lot of time partially re-writing only some of it.
  1001.     // Note that simply removing this preprocessor directive will NOT re-enable
  1002.     // TrueType to Type1 conversion.  There are other minor changes in the code
  1003.     // that support the deactivation of this feature. [brianau 5/15/97]
  1004.     //
  1005. #ifdef ENABLE_TRUETYPE_TO_TYPE1_CONVERSION
  1006.     if( !bYesAll_PS )
  1007.     {
  1008.         //
  1009.         //  Set normal cursor for new dialog
  1010.         //
  1011.         HCURSOR hCurs = SetCursor( LoadCursor( NULL, IDC_ARROW ) );
  1012.         switch( DoDialogBoxParam( DLG_INSTALL_PS, hDlgProgress, InstallPSDlg,
  1013.                                   IDH_DLG_INSTALL_PS, (LPARAM)  &t1ops ) )
  1014.         {
  1015.         case IDNO:
  1016.             //
  1017.             //  Note that we do not do HourGlass( TRUE ) , but that
  1018.             //  should be harmless, since we are either going to come
  1019.             //  right back here, or we are going to exit
  1020.             //
  1021.             return IDNO;
  1022.         case IDD_YESALL:
  1023.             bYesAll_PS = TRUE;
  1024.             //
  1025.             //  Fall thru...
  1026.             //
  1027.         case IDYES:
  1028.             //
  1029.             //  Give a warning here about installing from a non-local
  1030.             //  directory and not copying files, as necessary.
  1031.             //
  1032.             if( bInstallPS && !bCopyPS )
  1033.             {
  1034.                 lstrcpy( szTemp, szPfbName );
  1035.                 StripFilespec( szTemp );
  1036.                 lpCPBackSlashTerm( szTemp );
  1037.                 switch( GetDriveType( szTemp ) )
  1038.                 {
  1039.                     case DRIVE_REMOTE:
  1040.                     case DRIVE_REMOVABLE:
  1041.                     case DRIVE_CDROM:
  1042.                     case DRIVE_RAMDISK:
  1043.                         switch( iUIMsgBox( IDSI_MSG_COPYCONFIRM, IDS_MSG_CAPTION,
  1044.                                        MB_YESNOCANCEL | MB_ICONEXCLAMATION))
  1045.                         {
  1046.                             case IDNO:
  1047.                                iRet = TYPE1_INSTALL_IDNO;
  1048.                                goto InstallPSFailure;
  1049.                             case IDCANCEL:
  1050.                                iRet = TYPE1_INSTALL_IDCANCEL;
  1051.                                goto InstallPSFailure;
  1052.                             default:
  1053.                                break;
  1054.                         }
  1055.                         break;
  1056.                 }
  1057.             }
  1058.             break;
  1059.         default:
  1060.             //
  1061.             // CANCEL and NOMEM( user already warned )
  1062.             //
  1063.             iRet = TYPE1_INSTALL_IDCANCEL;
  1064.             goto InstallPSFailure;
  1065.         }
  1066.         //
  1067.         //  Reset previous cursor
  1068.         //
  1069.         SetCursor( hCurs );
  1070.     }
  1071. #endif // ENABLE_TRUETYPE_TO_TYPE1_CONVERSION
  1072.     //
  1073.     // These values were originally set in the Type1 installation dialog.
  1074.     // Now that this dialog has been disabled, we hard code the values.
  1075.     // [brianau 5/15/97]
  1076.     //
  1077.     bInstallPS = TRUE;             // Always install the font.
  1078.     bConvertPS = FALSE;            // Never convert Type1 to TrueType.
  1079.     bCopyPS    = bCopyType1Files;
  1080.     //
  1081.     // szDstName should already have the full source file name
  1082.     //
  1083.     //  Only convert the Type1 font to TT if:
  1084.     //
  1085.     //  a)  The user asked us to do it;
  1086.     //  b)  The font can be converted, AND;
  1087.     //  c)  There is not a matching TT font already installed
  1088.     //
  1089.     if( bConvertPS && ( wFontType != TYPE1_FONT_NC )  && !t1ops.bMatchingTT )
  1090.     {
  1091.         //////////////////////////////////////////////////////////////////
  1092.         // Convert Type1 files to TrueType
  1093.         //
  1094.         // Copy converted TT file, if necessary, to "fonts" directory
  1095.         //
  1096.         // NOTE: We are using the ConvertTypeface api to do the copying
  1097.         //       and it is an ASCII only api.
  1098.         //////////////////////////////////////////////////////////////////
  1099.         //
  1100.         //  Create destination name with .ttf
  1101.         //
  1102.         lstrcpy( szTemp, szPfmName );
  1103.         StripPath( szTemp );
  1104.         vConvertExtension( szTemp, szTTF );
  1105.         //
  1106.         //  Build destination file pathname based on bCopyTTFile
  1107.         //
  1108.         if( bCopyTTFile || bInSharedDir )
  1109.         {
  1110.             //
  1111.             //  Copy file to local directory
  1112.             //
  1113.             lstrcpy( szDstName, s_szSharedDir );
  1114.         }
  1115.         else
  1116.         {
  1117.             //
  1118.             //  Create converted file in source directory
  1119.             //
  1120.             lstrcpy( szDstName, szSrcDir );
  1121.         }
  1122.         //
  1123.         //  Check new filename for uniqueness
  1124.         //
  1125.         if( !(bUniqueFilename( szTemp, szTemp, szDstName ) ) )
  1126.         {
  1127.             iRet = iUIMsgOkCancelExclaim( hwndParent, IDSI_FMT_BADINSTALL,
  1128.                                           IDSI_CAP_NOCREATE, szDesc );
  1129.             goto InstallPSFailure;
  1130.         }
  1131.         lstrcat( szDstName, szTemp );
  1132.         //
  1133.         //  Save destination filename for return to caller
  1134.         //
  1135. #if 1
  1136.         lstrcpy( szTTFName, szDstName );
  1137. #else
  1138.         if( bCopyTTFile || bInSharedDir )
  1139.             lstrcpy( szTTFName, szTemp );
  1140.         else
  1141.             lstrcpy( szTTFName, szDstName );
  1142. #endif
  1143.         //
  1144.         //  We will convert and copy the Type1 font in the same api
  1145.         //
  1146.         WideCharToMultiByte( CP_ACP, 0, szPfbName, -1, pfb,
  1147.                                 PATHMAX, NULL, NULL );
  1148.         WideCharToMultiByte( CP_ACP, 0, szPfmName, -1, pfm,
  1149.                                 PATHMAX, NULL, NULL );
  1150.         WideCharToMultiByte( CP_ACP, 0, szDstName, -1, ttf,
  1151.                                 PATHMAX, NULL, NULL );
  1152.         ResetProgress( );
  1153.         //
  1154.         //  Remove "PostScript" postfix string from description
  1155.         //
  1156.         RemoveDecoration( szDesc, TRUE );
  1157.         if( (rc = (int) ::ConvertTypefaceA( pfb, pfm, ttf,
  1158.                                             (PROGRESSPROC) Progress,
  1159.                                             (void *) szDesc ) ) < 0 )
  1160.         {
  1161.             pszArg1 = szPfmName;
  1162.             pszArg2 = szPfbName;
  1163.             switch( rc )
  1164.             {
  1165.             case ARGSTACK:
  1166.             case TTSTACK:
  1167.             case NOMEM:
  1168.                 wMsg = INSTALL3;
  1169.                 break;
  1170.             case NOMETRICS:
  1171.             case BADMETRICS:
  1172.             case UNSUPPORTEDFORMAT:
  1173.                 //
  1174.                 //  Something is wrong with the .pfm metrics file
  1175.                 //
  1176.                 pszArg1 = szDstName;
  1177.                 pszArg2 = szPfmName;
  1178.                 wMsg = MYFONT + 13;
  1179.                 break;
  1180.             case BADT1HYBRID:
  1181.             case BADT1HEADER:
  1182.             case BADCHARSTRING:
  1183.             case NOCOPYRIGHT:
  1184.                 //
  1185.                 //  Bad .pfb input file - format, or corruption
  1186.                 //
  1187.                 pszArg1 = szDstName;
  1188.                 pszArg2 = szPfbName;
  1189.                 wMsg = MYFONT + 14;
  1190.                 break;
  1191.             case BADINPUTFILE:
  1192.                 //
  1193.                 //  Bad input file names, or formats or file errors
  1194.                 //  or file read errors
  1195.                 //
  1196.                 pszArg1 = szDstName;
  1197.                 pszArg2 = szPfbName;
  1198.                 wMsg = MYFONT + 15;
  1199.                 break;
  1200.             case BADOUTPUTFILE:
  1201.                 //
  1202.                 //  No diskspace for copy, read-only share, etc.
  1203.                 //
  1204.                 pszArg1 = szDstName;
  1205.                 wMsg = MYFONT + 16;
  1206.                 break;
  1207.             default:
  1208.                 //
  1209.                 //  Cannot convert szDesc to TrueType - general failure
  1210.                 //
  1211.                 pszArg1 = szDstName;
  1212.                 pszArg2 = szDesc;
  1213.                 wMsg = MYFONT + 17;
  1214.                 break;
  1215.             }
  1216.             iRet = iUIMsgBox( hwndParent, wMsg, IDS_MSG_CAPTION,
  1217.                               MB_OKCANCEL | MB_ICONEXCLAMATION,
  1218.                               pszArg1, pszArg2, szPfmName );
  1219.             goto InstallPSFailure;
  1220.         }
  1221.         //
  1222.         //  Change font description to have "TrueType" now
  1223.         //
  1224.         wsprintf( szDesc, c_szDescFormat, szDesc, c_szTrueType );
  1225.     }
  1226.     iRet = TYPE1_INSTALL_IDNO;
  1227.     if( bInstallPS && !t1ops.bOnlyPSInstalled )
  1228.     {
  1229.         //
  1230.         //  Remove "PostScript" postfix string from description
  1231.         //
  1232.         lstrcpy( szTemp2, szDesc );
  1233.         RemoveDecoration( szTemp2, TRUE );
  1234.         //
  1235.         //  Now reset per font install progress
  1236.         //
  1237.         ResetProgress( );
  1238.         Progress2( 0, szTemp2 );
  1239.         //
  1240.         //  Only copy the files if the User asked us to AND they are NOT
  1241.         //  already in the Shared directory.
  1242.         //
  1243.         if( bCopyPS && !bInSharedDir )
  1244.         {
  1245.             //
  1246.             //  Copy file progress
  1247.             //
  1248.             Progress2( 10, szTemp2 );
  1249.             /////////////////////////////////////////////////////////////////
  1250.             // COPY files to "fonts" directory
  1251.             /////////////////////////////////////////////////////////////////
  1252.             //
  1253.             //  For .inf/.afm file install::  Check .pfm pathname to see if
  1254.             //  it is the same as the destination file pathname we built.
  1255.             //  Make this check before we test/create a UniqueFilename.
  1256.             //
  1257.             //  Build Destination file pathname for .PFM file
  1258.             lstrcpy( szDstName, s_szSharedDir );
  1259.             lstrcat( szDstName, lpNamePart( szPfmName ) );
  1260.             //
  1261.             //  Check to see if the .pfm file already exists in the "fonts"
  1262.             //  directory.  If it does, then just copy the .pfb over.
  1263.             //
  1264.             if( !lstrcmpi( szPfmName, szDstName ) )
  1265.                 goto CopyPfbFile;
  1266.             //
  1267.             //  Setup args for bCPInstallFile call
  1268.             //
  1269.             StripPath( szDstName );
  1270.             StripPath( szPfmName );
  1271.             if( !(bUniqueOnSharedDir( szDstName, szDstName ) ) )
  1272.             {
  1273.                 iRet = iUIMsgOkCancelExclaim( hwndParent, IDSI_FMT_BADINSTALL,
  1274.                                               IDSI_CAP_NOCREATE, szDesc );
  1275.                 goto InstallPSFailure;
  1276.             }
  1277.             if( !bCPInstallFile( hwndParent, szSrcDir, szPfmName, szDstName ) )
  1278.                 goto InstallPSFailure;
  1279. CopyPfbFile:
  1280.             //
  1281.             //  Copying pfm file was small portion of install
  1282.             //
  1283.             Progress2( 30, szTemp2 );
  1284.             //
  1285.             //  Setup and copy .PFB file
  1286.             //
  1287.             //  Setup args for bCPInstallFile call
  1288.             //
  1289.             lstrcpy(szSrcDir, szPfbName);  // Prepare src directory name.
  1290.             StripFilespec( szSrcDir );
  1291.             lpCPBackSlashTerm( szSrcDir );
  1292.             StripPath( szPfbName );
  1293.             lstrcpy( szDstName, szPfbName );
  1294.             if( !(bUniqueOnSharedDir( szDstName, szDstName ) ) )
  1295.             {
  1296.                 iRet = iUIMsgOkCancelExclaim( hwndParent, IDSI_FMT_BADINSTALL,
  1297.                                               IDSI_CAP_NOCREATE, szDesc );
  1298.                 goto InstallPSFailure;
  1299.             }
  1300.             if( !bCPInstallFile( hwndParent, szSrcDir, szPfbName, szDstName ) )
  1301.                 goto InstallPSFailure;
  1302.         }
  1303.         //
  1304.         //  Copying pfb file was large portion of install
  1305.         //
  1306.         Progress2( 85, szTemp2 );
  1307.         //
  1308.         //  Write registry entry to "install" font for use by the
  1309.         //  PostScript driver, but only after successfully copying
  1310.         //  files (if copy was necessary).
  1311.         //
  1312.         //  NOTE:  This routine will strip the path off of the filenames
  1313.         //         if they are in the Fonts dir.
  1314.         //
  1315.         iRet = WriteType1RegistryEntry( hwndParent, szDesc, szPfmName, szPfbName, bCopyPS );
  1316.         //
  1317.         // If the Type1 font driver is installed,
  1318.         // add the Type1 font resource to GDI.
  1319.         //
  1320.         {
  1321.             CFontManager *poFontManager;
  1322.             if (SUCCEEDED(GetFontManager(&poFontManager)))
  1323.             {
  1324.                 if (poFontManager->Type1FontDriverInstalled())
  1325.                 {
  1326.                     TCHAR szType1FontResourceName[MAX_TYPE1_FONT_RESOURCE];
  1327.                     if (BuildType1FontResourceName(szPfmName,
  1328.                                                    szPfbName,
  1329.                                                    szType1FontResourceName,
  1330.                                                    ARRAYSIZE(szType1FontResourceName)))
  1331.                     {
  1332.                         AddFontResource(szType1FontResourceName);
  1333.                     }
  1334.                 }
  1335.                 ReleaseFontManager(&poFontManager);
  1336.             }
  1337.         }
  1338.         //
  1339.         //  No need to add to internal font list here.  It is added in the calling
  1340.         //  code (bAddSelFonts or CPDropInstall).
  1341.         //
  1342.         //
  1343.         //  Final registry write completes install, except for listbox munging.
  1344.         //  Note that TrueType file install is handled separately.
  1345.         //
  1346.         Progress2( 100, szTemp2 );
  1347.     }
  1348.     //
  1349.     //  Determine correct return code based on installation options and
  1350.     //  current installed state of font.
  1351.     //
  1352.     if( bConvertPS && ( wFontType != TYPE1_FONT_NC ) )
  1353.     {
  1354.         //
  1355.         //  Handle the special case of when the matching TTF font is already
  1356.         //  installed.
  1357.         //
  1358.         if( t1ops.bMatchingTT )
  1359.             goto Type1InstallCheck;
  1360.         lstrcpy( szKeyName, szTTFName );
  1361.         if( t1ops.bOnlyPSInstalled )
  1362.         {
  1363.             //
  1364.             //  There is already a Lbox entry for the PS version of this font
  1365.             //  that needs to be deleted because the TT installation will
  1366.             //  add a new Lbox entry.
  1367.             //
  1368.             iRet = TYPE1_INSTALL_TT_AND_MPS;
  1369.             //
  1370.             //  Funnel all exits thru 1 point to check for Install Cancellation
  1371.             //
  1372.             goto MasterExit;
  1373.         }
  1374.         else if( bInstallPS )
  1375.         {
  1376.             iRet = ( iRet == IDOK )  ? TYPE1_INSTALL_TT_AND_PS : TYPE1_INSTALL_TT_ONLY;
  1377.             //
  1378.             //  Funnel all exits thru 1 point to check for Install Cancellation
  1379.             //
  1380.             goto MasterExit;
  1381.         }
  1382.         else
  1383.         {
  1384.             iRet = TYPE1_INSTALL_TT_ONLY;
  1385.             goto CheckPfmDeletion;
  1386.         }
  1387.     }
  1388. Type1InstallCheck:
  1389. #ifdef LATER
  1390. //
  1391. //  Since fonts are displayed in an Explorer (Fonts) Folder, there is not an
  1392. //  initial display listbox of "Installed" fonts to check against.  These
  1393. //  checks must be made against the registry list of installed fonts.
  1394. //
  1395. //  Also, I need to force a "Refresh" of the Folder view after installation
  1396. //  is complete of either each font or all selected fonts.   This might already
  1397. //  be being done somewhere.
  1398. //
  1399.     if( bInstallPS )
  1400.     {
  1401.         if( iRet != IDOK )
  1402.         {
  1403.             iRet = TYPE1_INSTALL_IDNO;
  1404.             goto InstallPSFailure;
  1405.         }
  1406.         iRet = TYPE1_INSTALL_IDNO;
  1407.         if( t1ops.bMatchingTT )
  1408.         {
  1409.             //
  1410.             //  If we previously found the Matching TT font for this Type1
  1411.             //  font and installed the PostScript font in this session, set
  1412.             //  the font type for the Matching TT font to IF_TYPE1_TT.
  1413.             //
  1414.             //  Also, do not add a new entry in listbox for the Type1 font.
  1415.             //
  1416.             //  Find matching  "xxxxx (TrueType)" entry and change its
  1417.             //  ItemData to IF_TYPE1_TT
  1418.             //
  1419.             //  Change font description to have "(TrueType ) " now
  1420.             //
  1421.             RemoveDecoration( szDesc, TRUE );
  1422.             wsprintf( szDesc, c_szDescFormat, szDesc, c_szTrueType );
  1423.             rc= SendMessage( hListFonts, LB_FINDSTRINGEXACT, (WPARAM )  -1,
  1424.                                                          (LONG ) szDesc );
  1425.             if( rc != LB_ERR )
  1426.             {
  1427.                 SendMessage( hListFonts, LB_SETITEMDATA, rc, (LONG) IF_TYPE1_TT );
  1428.                 SendMessage( hListFonts, LB_SETSEL, 1, rc );
  1429.                 UpdateWindow( hListFonts );
  1430.                 iRet = TYPE1_INSTALL_PS_AND_MTT;
  1431.             }
  1432.         }
  1433.         else
  1434.         {
  1435.             rc = SendMessage( hListFonts, LB_ADDSTRING, 0, (LONG)(LPTSTR) szDesc );
  1436.             //
  1437.             //  Attach font type to each listed font
  1438.             //
  1439.             if( rc != LB_ERR )
  1440.             {
  1441.                 SendMessage( hListFonts, LB_SETITEMDATA, rc, IF_TYPE1 );
  1442.                 SendMessage( hListFonts, LB_SETSEL, 1, rc );
  1443.                 UpdateWindow( hListFonts );
  1444.                 iRet = TYPE1_INSTALL_PS_ONLY;
  1445.             }
  1446.         }
  1447.     }
  1448. #else  //  LATER
  1449.     if( bInstallPS )
  1450.     {
  1451.         if( iRet != IDOK )
  1452.         {
  1453.             iRet = TYPE1_INSTALL_IDNO;
  1454.             goto InstallPSFailure;
  1455.         }
  1456.         if( t1ops.bMatchingTT )
  1457.         {
  1458.             iRet = TYPE1_INSTALL_PS_AND_MTT;
  1459.         }
  1460.         else
  1461.         {
  1462.             iRet = TYPE1_INSTALL_PS_ONLY;
  1463.         }
  1464.     }
  1465. #endif  //  LATER
  1466.     if( !bInstallPS )
  1467.         goto CheckPfmDeletion;
  1468.     //
  1469.     //  Funnel all exits thru 1 point to check for Install Cancellation
  1470.     //
  1471.     goto MasterExit;
  1472.     /////////////////////////////////////////////////////////////////////////
  1473.     //
  1474.     //  Install failure exit AND Delete extraneously created PFM file
  1475.     //
  1476.     //  NOTE:  For the installation scenario where we based installation on
  1477.     //         the .INF/.AFM file and the Type1 font was NOT installed, we
  1478.     //         need to delete the .FPM file that was created by the
  1479.     //         CheckType1WithStatusA routine in the IsPSFont routine.
  1480.     //
  1481.     /////////////////////////////////////////////////////////////////////////
  1482. InstallPSFailure:
  1483. CheckPfmDeletion:
  1484.     if( bCreatedPfm )
  1485.         DeleteFile( szPfmName );
  1486. MasterExit:
  1487.     return( InstallCancelled() ? IDCANCEL : iRet );
  1488. }
  1489. /////////////////////////////////////////////////////////////////////////////
  1490. //
  1491. // InstallPSDlg
  1492. //
  1493. //  This dialog proc manages the Install PostScript font dialog which allows
  1494. //  the user several options for the installation, including converting the
  1495. //  file to a TrueType font.
  1496. //
  1497. //  Globals munged:
  1498. //
  1499. //      bConvertPS    -   Convert Type1 files to TT
  1500. //      bInstallPS    -   Install PS files
  1501. //      bCopyPS       -   Copy PS files to Windows dir
  1502. //
  1503. /////////////////////////////////////////////////////////////////////////////
  1504. INT_PTR APIENTRY InstallPSDlg( HWND hDlg, UINT nMsg, WPARAM wParam, LPARAM lParam )
  1505. {
  1506.     TCHAR  szFormat[ PATHMAX ] ;
  1507.     TCHAR  szTemp[ PATHMAX ] ;
  1508.     TCHAR  szTemp2[ PATHMAX ] ;
  1509.     int    iButtonChecked;
  1510.     WORD   wMsg;
  1511.     static HWND hwndActive = NULL;
  1512.     T1_INSTALL_OPTIONS *pt1ops;
  1513.     switch( nMsg )
  1514.     {
  1515.     case WM_INITDIALOG:
  1516.         pt1ops = (PT1_INSTALL_OPTIONS)  lParam;
  1517.         //
  1518.         //  Remove all "PostScript" or "TrueType" postfix to font name
  1519.         //
  1520.         lstrcpy( szTemp2, (LPTSTR) pt1ops->szDesc );
  1521.         RemoveDecoration( szTemp2, FALSE );
  1522.         {
  1523.             LPCTSTR args[] = { szTemp2 };
  1524.             LoadString( g_hInst, MYFONT + 7, szFormat, ARRAYSIZE( szFormat ) );
  1525.             FormatMessage(FORMAT_MESSAGE_FROM_STRING |
  1526.                           FORMAT_MESSAGE_ARGUMENT_ARRAY,
  1527.                           szFormat,
  1528.                           0,
  1529.                           0,
  1530.                           szTemp,
  1531.                           ARRAYSIZE(szTemp),
  1532.                           (va_list *)args);
  1533.         }
  1534.         SetWindowLongPtr( hDlg, GWL_PROGRESS, lParam );
  1535.         SetDlgItemText( hDlg, FONT_INSTALLMSG, szTemp );
  1536.         EnableWindow( hDlg, TRUE );
  1537.         //
  1538.         // If the native ATM driver is installed, the "Convert to TrueType" checkbox
  1539.         // is always disabled.
  1540.         //
  1541.         {
  1542.             CFontManager *poFontManager;
  1543.             if (SUCCEEDED(GetFontManager(&poFontManager)))
  1544.             {
  1545.                 if (poFontManager->Type1FontDriverInstalled())
  1546.                     EnableWindow(GetDlgItem(hDlg, FONT_CONVERT_PS), FALSE);
  1547.                 ReleaseFontManager(&poFontManager);
  1548.             }
  1549.         }
  1550.         if( pt1ops->bOnlyPSInstalled && pt1ops->bMatchingTT )
  1551.         {
  1552.             //
  1553.             // ERROR!  Both of these options should not be set at
  1554.             //         this point.  It means that the font is
  1555.             //         already installed.  This should have been
  1556.             //         handled before calling this dialog.
  1557.             //
  1558.             wMsg = MYFONT + 5;
  1559. InstallError:
  1560.             iUIMsgExclaim( hDlg, wMsg, pt1ops->szDesc );
  1561.             EndDialog( hDlg, IDNO );
  1562.             break;
  1563.         }
  1564.         if( (pt1ops->wFontType == TYPE1_FONT_NC )  && pt1ops->bOnlyPSInstalled )
  1565.         {
  1566.             //
  1567.             //  ERROR! This case is when I have detected only the PS
  1568.             //         version of font installed, and the font CANNOT
  1569.             //         be converted to TT for some reason.
  1570.             //
  1571.             wMsg = MYFONT + 8;
  1572.             goto InstallError;
  1573.         }
  1574.         /////////////////////////////////////////////////////////////////////
  1575.         //
  1576.         //  Setup user options depending on install state of font and
  1577.         //  convertibility to TT of T1 font and on previous user choices.
  1578.         //
  1579.         /////////////////////////////////////////////////////////////////////
  1580.         if( (pt1ops->wFontType == TYPE1_FONT )  && (!pt1ops->bMatchingTT ) )
  1581.         {
  1582.             //
  1583.             //  This one can be converted
  1584.             //
  1585.             CheckDlgButton( hDlg, FONT_CONVERT_PS, bConvertPS );
  1586.         }
  1587.         else
  1588.         {
  1589.             //
  1590.             //  Do not allow conversion to TT because, either the font
  1591.             //  type is TYPE1_FONT_NC( i.e. it cannot be converted )  OR
  1592.             //  the TT version of font is already installed.
  1593.             //
  1594.             CheckDlgButton( hDlg, FONT_CONVERT_PS, FALSE );
  1595.             EnableWindow( GetDlgItem( hDlg, FONT_CONVERT_PS ) , FALSE );
  1596.         }
  1597.         if( pt1ops->bOnlyPSInstalled )
  1598.         {
  1599.             //
  1600.             //  If the PostScript version of this font is already
  1601.             //  installed, then we gray out the options to re-install
  1602.             //  the PostScript version of font, but continue to allow
  1603.             //  the User to convert it to TT.
  1604.             //
  1605.             CheckDlgButton( hDlg, FONT_INSTALL_PS, 0 );
  1606.             EnableWindow( GetDlgItem( hDlg, FONT_INSTALL_PS ) , FALSE );
  1607.             CheckDlgButton( hDlg, FONT_COPY_PS, 0 );
  1608.             EnableWindow( GetDlgItem( hDlg, FONT_COPY_PS ) , FALSE );
  1609.         }
  1610.         else
  1611.         {
  1612.             //
  1613.             //  PostScript version of font is not installed.  Set
  1614.             //  state of "INSTALL" and "COPY" checkboxes based on
  1615.             //  global state of "INSTALL"
  1616.             //
  1617.             CheckDlgButton( hDlg, FONT_INSTALL_PS, bInstallPS );
  1618.             CheckDlgButton( hDlg, FONT_COPY_PS, bCopyPS );
  1619.             EnableWindow( GetDlgItem( hDlg, FONT_COPY_PS ) , bInstallPS );
  1620.         }
  1621.         //
  1622.         //  Save the modeless dlg window handle for reactivation
  1623.         //
  1624.         hwndActive = GetActiveWindow( );
  1625.         break;
  1626.     case WM_COMMAND:
  1627.         switch( LOWORD( wParam ) )
  1628.         {
  1629.         case FONT_INSTALL_PS:
  1630.             if( HIWORD( wParam )  != BN_CLICKED )
  1631.                 break;
  1632.             //
  1633.             // Get state of "INSTALL" checkbox
  1634.             //
  1635.             iButtonChecked = IsDlgButtonChecked( hDlg, LOWORD( wParam ) );
  1636.             //
  1637.             // A disabled checkbox is same as "No Install" selection
  1638.             //
  1639.             if( iButtonChecked != 1 )
  1640.                 iButtonChecked = 0;
  1641.             //
  1642.             //  Enable or disable "COPY" control based on state of
  1643.             //  "INSTALL" checkbox.  Also, initialize it.
  1644.             //
  1645.             EnableWindow( GetDlgItem( hDlg, FONT_COPY_PS ) , iButtonChecked );
  1646.             if( iButtonChecked )
  1647.                 CheckDlgButton( hDlg, FONT_COPY_PS, bCopyPS );
  1648.             break;
  1649.         case IDD_HELP:
  1650.             goto DoHelp;
  1651.         case IDYES:
  1652.         case IDD_YESALL:
  1653.             bConvertPS =
  1654.             bInstallPS = FALSE;
  1655.             if( IsDlgButtonChecked( hDlg, FONT_CONVERT_PS )  == 1 )
  1656.                 bConvertPS = TRUE;
  1657.             if( IsDlgButtonChecked( hDlg, FONT_INSTALL_PS )  == 1 )
  1658.                 bInstallPS = TRUE;
  1659.             //
  1660.             //  This is checked twice because it could be disabled,
  1661.             //  in which case we leave the previous state alone.
  1662.             //
  1663.             if( IsDlgButtonChecked( hDlg, FONT_COPY_PS )  == 1 )
  1664.                 bCopyPS = TRUE;
  1665.             if( IsDlgButtonChecked( hDlg, FONT_COPY_PS )  == 0 )
  1666.                 bCopyPS = FALSE;
  1667.             //
  1668.             //  Fall thru...
  1669.             //
  1670.         case IDNO:
  1671.         case IDCANCEL:
  1672.             //
  1673.             //  Reset the active window to "Install Font Progress" modeless dlg
  1674.             //
  1675.             if( hwndActive )
  1676.             {
  1677.                 SetActiveWindow( hwndActive );
  1678.                 hwndActive = NULL;
  1679.             }
  1680.             EndDialog( hDlg, LOWORD( wParam ) );
  1681.             break;
  1682.         default:
  1683.             return FALSE;
  1684.         }
  1685.         break;
  1686.     default:
  1687. DoHelp:
  1688. #ifdef PS_HELP
  1689. //
  1690. // FIXFIX [stevecat] Enable help
  1691.         if( nMsg == wHelpMessage )
  1692.         {
  1693. DoHelp:
  1694.             CPHelp( hDlg );
  1695.             return TRUE;
  1696.         }
  1697.         else
  1698. #endif  //  PS_HELP
  1699.             return FALSE;
  1700.     }
  1701.     return TRUE;
  1702. }
  1703. /////////////////////////////////////////////////////////////////////////////
  1704. //
  1705. // RemoveDecoration
  1706. //
  1707. //  Deletes the "(TrueType)" or "(PostScript)" postfix string from the end
  1708. //  of a font name.  Optionally it will also remove the trailing space.
  1709. //
  1710. //  NOTE:  This function modifies the string passed into the function.
  1711. //
  1712. /////////////////////////////////////////////////////////////////////////////
  1713. void RemoveDecoration( LPTSTR pszDesc, BOOL bDeleteTrailingSpace )
  1714. {
  1715.     LPTSTR lpch;
  1716.     //
  1717.     //  Remove any postfix strings like "(PostScript)" or "(TrueType)"
  1718.     //
  1719.     if( lpch = _tcschr( pszDesc, TEXT('(') ) )
  1720.     {
  1721.         //
  1722.         //  End string at <space> before "("
  1723.         //
  1724.         if( bDeleteTrailingSpace )
  1725.             lpch--;
  1726.         *lpch = CHAR_NULL;
  1727.     }
  1728.     return ;
  1729. }
  1730. /////////////////////////////////////////////////////////////////////////////
  1731. //
  1732. // CheckT1Install
  1733. //
  1734. //  Checks the Type1 fonts location in registry to see if this font is or
  1735. //  has been previously installed as a "PostScript" font.  Optionally, it
  1736. //  will return the data for the "szData" value if it finds a matching entry.
  1737. //
  1738. //  Assumes "szData" buffer is of least size T1_MAX_DATA.
  1739. //
  1740. /////////////////////////////////////////////////////////////////////////////
  1741. BOOL CheckT1Install( LPTSTR pszDesc, LPTSTR pszData )
  1742. {
  1743.     TCHAR  szTemp[ PATHMAX ] ;
  1744.     DWORD  dwSize;
  1745.     DWORD  dwType;
  1746.     HKEY   hkey;
  1747.     BOOL   bRet = FALSE;
  1748.     hkey = NULL;
  1749.     if( RegOpenKeyEx( HKEY_LOCAL_MACHINE,        // Root key
  1750.                       g_szType1Key,              // Subkey to open
  1751.                       0L,                        // Reserved
  1752.                       KEY_READ,                  // SAM
  1753.                       &hkey )                    // return handle
  1754.             == ERROR_SUCCESS )
  1755.     {
  1756.         //
  1757.         //  Remove any postfix strings like "PostScript" or "TrueType"
  1758.         //
  1759.         lstrcpy( szTemp, pszDesc );
  1760.         RemoveDecoration( szTemp, TRUE );
  1761.         dwSize = pszData ? T1_MAX_DATA * sizeof( TCHAR ) : 0;
  1762.         if( RegQueryValueEx( hkey, szTemp, NULL, &dwType,
  1763.                              (LPBYTE)  pszData, &dwSize )
  1764.                 ==  ERROR_SUCCESS )
  1765.         {
  1766.             bRet = ( dwType == REG_MULTI_SZ );
  1767.         }
  1768.         else
  1769.         {
  1770.             bRet = FALSE;
  1771.         }
  1772.         RegCloseKey( hkey );
  1773.     }
  1774.     return bRet;
  1775. }
  1776. /////////////////////////////////////////////////////////////////////////////
  1777. //
  1778. // AddSystemPath
  1779. //
  1780. //  Add "System" path to a naked file name, if no path currently exists
  1781. //  on the filename.  Assumes pszFile buffer is at least PATHMAX chars in
  1782. //  length.
  1783. //
  1784. /////////////////////////////////////////////////////////////////////////////
  1785. void AddSystemPath( LPTSTR pszFile )
  1786. {
  1787.     TCHAR  szPath[ PATHMAX ] ;
  1788.     //
  1789.     //  Add "system" path, if no path present on file
  1790.     //
  1791.     lstrcpy( szPath, pszFile );
  1792.     StripFilespec( szPath );
  1793.     if( szPath[ 0 ]  == CHAR_NULL )
  1794.     {
  1795.         lstrcpy( szPath, s_szSharedDir );
  1796.         lpCPBackSlashTerm( szPath );
  1797.         lstrcat( szPath, pszFile );
  1798.         lstrcpy( pszFile, szPath );
  1799.     }
  1800.     return ;
  1801. }
  1802. /////////////////////////////////////////////////////////////////////////////
  1803. //
  1804. // ExtractT1Files
  1805. //
  1806. //  Extracts file names from a REG_MULTI_SZ (multi-string)  array that is
  1807. //  passed into this routine.  The output strings are expected to be at
  1808. //  least PATHMAX in size.  A "" (NULL string)  indicates that a filename
  1809. //  string was not present.  This should only happen for the PFB filename
  1810. //  argument.
  1811. //
  1812. /////////////////////////////////////////////////////////////////////////////
  1813. BOOL ExtractT1Files( LPTSTR pszMulti, LPTSTR pszPfmFile, LPTSTR pszPfbFile )
  1814. {
  1815.     LPTSTR pszPfm;
  1816.     LPTSTR pszPfb;
  1817.     if( !pszMulti )
  1818.         return FALSE;
  1819.     if( ( pszMulti[ 0 ]  != CHAR_TRUE )  && ( pszMulti[ 0 ]  != CHAR_FALSE ) )
  1820.         return FALSE;
  1821.     //
  1822.     //  .Pfm file should always be present
  1823.     //
  1824.     pszPfm = pszMulti + lstrlen( pszMulti ) + 1;
  1825.     lstrcpy( pszPfmFile, pszPfm );
  1826.     //
  1827.     //  Add "system" path, if no path present on files
  1828.     //
  1829.     AddSystemPath( pszPfmFile );
  1830.     //
  1831.     //  Check to see if .pfb filename is present
  1832.     //
  1833.     if( pszMulti[ 0 ]  == CHAR_TRUE )
  1834.     {
  1835.         pszPfb = pszPfm + lstrlen( pszPfm )  + 1;
  1836.         lstrcpy( pszPfbFile, pszPfb );
  1837.         //
  1838.         //  Add "system" path, if no path present on files
  1839.         //
  1840.         AddSystemPath( pszPfbFile );
  1841.     }
  1842.     else
  1843.     {
  1844.         pszPfbFile[ 0 ]  = CHAR_NULL;
  1845.     }
  1846.     return TRUE;
  1847. }
  1848. /////////////////////////////////////////////////////////////////////////////
  1849. //
  1850. // DeleteT1Install
  1851. //
  1852. //  Deletes a Type1 entry from the registry and optionally the files pointed
  1853. //  to in the data strings.
  1854. //
  1855. /////////////////////////////////////////////////////////////////////////////
  1856. BOOL DeleteT1Install( HWND hwndParent, LPTSTR pszDesc, BOOL bDeleteFiles )
  1857. {
  1858.     TCHAR  szTemp[ PATHMAX ] ;
  1859.     TCHAR  szTemp2[ T1_MAX_DATA ] ;
  1860.     TCHAR  szPfmFile[ PATHMAX ] ;
  1861.     TCHAR  szPfbFile[ PATHMAX ] ;
  1862.     TCHAR  szPath[ PATHMAX ] ;
  1863.     DWORD  dwSize;
  1864.     DWORD  dwType;
  1865.     HKEY   hkey;
  1866.     BOOL   bRet = FALSE;
  1867.     hkey = NULL;
  1868.     if( RegOpenKeyEx( HKEY_LOCAL_MACHINE,        // Root key
  1869.                       g_szType1Key,              // Subkey to open
  1870.                       0L,                        // Reserved
  1871.                       (KEY_READ | KEY_WRITE),    // SAM
  1872.                       &hkey )                    // return handle
  1873.             == ERROR_SUCCESS )
  1874.     {
  1875.         //
  1876.         //  Remove any postfix strings like "PostScript" or "TrueType"
  1877.         //
  1878.         lstrcpy( szTemp, pszDesc );
  1879.         RemoveDecoration( szTemp, TRUE );
  1880.         if( bDeleteFiles )
  1881.         {
  1882.             dwSize = sizeof( szTemp2 );
  1883.             if( RegQueryValueEx( hkey, szTemp, NULL, &dwType,
  1884.                                  (LPBYTE )  szTemp2, &dwSize )
  1885.                     ==  ERROR_SUCCESS )
  1886.             {
  1887.                 if( ExtractT1Files( szTemp2, szPfmFile, szPfbFile ) )
  1888.                 {
  1889.                     //
  1890.                     //  Delete the files
  1891.                     //
  1892. //                    if( DelSharedFile( hDlg, szTemp, szPfbFile, szPath, TRUE ) )
  1893. //                        DelSharedFile( hDlg, szTemp, szPfmFile, szPath, FALSE );
  1894. //
  1895.                     vCPDeleteFromSharedDir( szPfbFile );
  1896.                     vCPDeleteFromSharedDir( szPfmFile );
  1897.                 }
  1898.                 else
  1899.                 {
  1900.                     //  ERROR! Cannot get file names from string
  1901.                     goto RemoveT1Error;
  1902.                 }
  1903.             }
  1904.             else
  1905.             {
  1906.                 goto RemoveT1Error;
  1907.             }
  1908.         }
  1909.         if( RegDeleteValue( hkey, szTemp )  != ERROR_SUCCESS )
  1910.         {
  1911. RemoveT1Error:
  1912.             //
  1913.             //  ERROR! Put up message box
  1914.             //
  1915.             iUIMsgOkCancelExclaim( hwndParent,
  1916.                                    MYFONT + 1,
  1917.                                    IDS_MSG_CAPTION,
  1918.                                    (LPTSTR ) szTemp );
  1919.             bRet = FALSE;
  1920.         }
  1921.         else
  1922.         {
  1923.             bRet = TRUE;
  1924.         }
  1925.         RegCloseKey( hkey );
  1926.     }
  1927.     return bRet;
  1928. }
  1929. /////////////////////////////////////////////////////////////////////////////
  1930. //
  1931. // GetT1Install
  1932. //
  1933. //  Gets a Type1 entry information from the registry into the files pointed
  1934. //  to in the data strings.
  1935. //
  1936. /////////////////////////////////////////////////////////////////////////////
  1937. BOOL GetT1Install( LPTSTR pszDesc, LPTSTR pszPfmFile, LPTSTR pszPfbFile )
  1938. {
  1939.     TCHAR  szTemp2[ T1_MAX_DATA ] ;
  1940.     BOOL   bRet = FALSE;
  1941.     if( CheckT1Install( pszDesc, szTemp2 ) )
  1942.     {
  1943.         bRet = ExtractT1Files( szTemp2, pszPfmFile, pszPfbFile );
  1944.     }
  1945.     return bRet;
  1946. }
  1947. /////////////////////////////////////////////////////////////////////////////
  1948. //
  1949. // CheckTTInstall
  1950. //
  1951. //  Check FONTS location in registry to see if this font has already
  1952. //  been installed.
  1953. //
  1954. /////////////////////////////////////////////////////////////////////////////
  1955. BOOL CheckTTInstall( LPTSTR szDesc )
  1956. {
  1957.     TCHAR szTemp[ PATHMAX ] ;
  1958.     TCHAR szTemp2[ PATHMAX ] ;
  1959.     //
  1960.     //  Change description string to have TrueType instead of
  1961.     //  PostScript and then check if it is already installed.
  1962.     //
  1963.     lstrcpy( szTemp, szDesc );
  1964.     RemoveDecoration( szTemp, TRUE );
  1965.     wsprintf( szTemp, c_szDescFormat, szTemp, c_szTrueType );
  1966.     if( GetProfileString( szFonts, szTemp, szNull, szTemp2, ARRAYSIZE( szTemp2 ) ) )
  1967.         return TRUE;
  1968.     return FALSE;
  1969. }
  1970. /////////////////////////////////////////////////////////////////////////////
  1971. //
  1972. // WriteType1RegistryEntry
  1973. //
  1974. //  Create registry entry for this PostScript font by writing the path of
  1975. //  both the .PFM and .PFB files.
  1976. //
  1977. //  NOTE:  Checks global "bCopyPS" to determine if files have been copied
  1978. //         to the local shared directory.  In that case, the path info is
  1979. //         stripped from the file names passed into routine.
  1980. //
  1981. /////////////////////////////////////////////////////////////////////////////
  1982. int WriteType1RegistryEntry( HWND hwndParent,
  1983.                              LPTSTR szDesc,         // Font name description
  1984.                              LPTSTR szPfmName,      // .PFM filename
  1985.                              LPTSTR szPfbName,      // .PFB filename
  1986.                              BOOL   bInFontsDir )   // Files in fonts dir?
  1987. {
  1988.     TCHAR  szTemp[ 2*PATHMAX+6 ] ;
  1989.     TCHAR  szTemp2[ PATHMAX ] ;
  1990.     TCHAR  szClass[ PATHMAX ] ;
  1991.     DWORD  dwSize;
  1992.     DWORD  dwDisposition;
  1993.     HKEY   hkey = NULL;
  1994.     //
  1995.     //  Must have a Font description to store information in registry
  1996.     //
  1997.     if( !szDesc || !szPfmName )
  1998.         return TYPE1_INSTALL_IDNO;
  1999.     //
  2000.     //  Try to create the key if it does not exist or open existing key.
  2001.     //
  2002.     if( RegCreateKeyEx( HKEY_LOCAL_MACHINE,        // Root key
  2003.                         g_szType1Key,              // Subkey to open/create
  2004.                         0L,                        // Reserved
  2005.                         szClass,                   // Class string
  2006.                         0L,                        // Options
  2007.                         KEY_WRITE,                 // SAM
  2008.                         NULL,                      // ptr to Security struct
  2009.                         &hkey,                     // return handle
  2010.                         &dwDisposition )           // return disposition
  2011.             == ERROR_SUCCESS )
  2012.     {
  2013.         //
  2014.         //  Create REG_MULTI_SZ string to save in registry
  2015.         //
  2016.         //  X <null> [path]zzzz.pfm <null> [path]xxxxx.pfb <null><null>
  2017.         //
  2018.         //  Where X == T(rue )  if .pfb file present
  2019.         //
  2020.         lstrcpy( szTemp, szPfbName ? szTrue : szFalse );
  2021.         lstrcat( szTemp, szHash );
  2022.         if( bInFontsDir )
  2023.             StripPath( szPfmName );
  2024.         lstrcat( szTemp, szPfmName );
  2025.         lstrcat( szTemp, szHash );
  2026.         if( szPfbName )
  2027.         {
  2028.             if( bInFontsDir )
  2029.                 StripPath( szPfbName );
  2030.             lstrcat( szTemp, szPfbName );
  2031.             lstrcat( szTemp, szHash );
  2032.         }
  2033.         lstrcat( szTemp, szHash );
  2034.         dwSize = lstrlen( szTemp ) * sizeof( TCHAR );
  2035.         //
  2036.         //  Now convert string to multi-string
  2037.         //
  2038.         vHashToNulls( szTemp );
  2039.         //
  2040.         //  Create Registry Value name to store info under by
  2041.         //  removing any postfix strings like "Type 1" or
  2042.         //  "TrueType" from Font description string.
  2043.         //
  2044.         lstrcpy( szTemp2, szDesc );
  2045.         RemoveDecoration( szTemp2, TRUE );
  2046.         if( RegSetValueEx( hkey, szTemp2, 0L, REG_MULTI_SZ,
  2047.                             (LPBYTE) szTemp, dwSize )
  2048.                 != ERROR_SUCCESS )
  2049.         {
  2050.             goto WriteRegError;
  2051.         }
  2052.         RegCloseKey( hkey );
  2053.     }
  2054.     else
  2055.     {
  2056. WriteRegError:
  2057.         //
  2058.         //  Put up a message box error stating that the USER does
  2059.         //  not have the permission necessary to install type1
  2060.         //  fonts.
  2061.         //
  2062.         if( hkey )
  2063.             RegCloseKey( hkey );
  2064.         return( iUIMsgBox( hwndParent,
  2065.                            MYFONT + 9, IDS_MSG_CAPTION,
  2066.                            MB_OKCANCEL | MB_ICONEXCLAMATION,
  2067.                            (LPTSTR) szDesc,
  2068.                            (LPTSTR) g_szType1Key ) );
  2069.     }
  2070.     return TYPE1_INSTALL_IDOK;
  2071. }
  2072. #ifdef NOTUSED
  2073. /////////////////////////////////////////////////////////////////////////////
  2074. //
  2075. // EnumType1Fonts
  2076. //
  2077. //  List all of the Type 1 fonts installed in the registry, check for
  2078. //  TrueType installation and put Postscript-only installed fonts in
  2079. //  the "Installed Fonts" list box.
  2080. //
  2081. //  This routine assumes that the TrueType descriptions are already
  2082. //  displayed in the "Installed Fonts" listbox.
  2083. //
  2084. /////////////////////////////////////////////////////////////////////////////
  2085. BOOL EnumType1Fonts( HWND hLBox )
  2086. {
  2087.     int    i, j;
  2088.     DWORD  dwSize;
  2089.     DWORD  dwPathMax;
  2090.     DWORD  dwType;
  2091.     HKEY   hkey;
  2092.     LPTSTR pszDesc;
  2093.     LPTSTR pszFontName;
  2094.     BOOL   bRet = FALSE;
  2095.     //////////////////////////////////////////////////////////////////////
  2096.     //  Get some storage
  2097.     //////////////////////////////////////////////////////////////////////
  2098.     pszFontName =
  2099.     pszDesc     = NULL;
  2100.     dwPathMax = PATHMAX * sizeof( TCHAR );
  2101.     pszFontName = (LPTSTR) AllocMem( dwPathMax );
  2102.     pszDesc = (LPTSTR) AllocMem( dwPathMax );
  2103.     if( !pszDesc || !pszFontName )
  2104.         goto EnumType1Exit;
  2105.     //////////////////////////////////////////////////////////////////////
  2106.     //  Get list of installed Type 1 fonts
  2107.     //////////////////////////////////////////////////////////////////////
  2108.     hkey = NULL;
  2109.     if( RegOpenKeyEx( HKEY_LOCAL_MACHINE,       // Root key
  2110.                       g_szType1Key,             // Subkey to open
  2111.                       0L,                       // Reserved
  2112.                       KEY_READ,                 // SAM
  2113.                       &hkey )                   // return handle
  2114.             == ERROR_SUCCESS )
  2115.     {
  2116.         dwSize = dwPathMax;
  2117.         i = 0;
  2118.         while( RegEnumValue( hkey, i++, pszFontName, &dwSize, NULL,
  2119.                              &dwType, (LPBYTE)  NULL, NULL )
  2120.                     == ERROR_SUCCESS )
  2121.         {
  2122.             if( dwType != REG_MULTI_SZ )
  2123.                 continue;
  2124.             wsprintf( pszDesc, c_szDescFormat, pszFontName, c_szPostScript );
  2125.             //
  2126.             //  Check to see if TrueType version is already installed
  2127.             //
  2128.             if( CheckTTInstall( pszDesc ) )
  2129.             {
  2130.                 //
  2131.                 //  Find matching  "xxxxx (TrueType)" entry and change its
  2132.                 //  ItemData to IF_TYPE1_TT
  2133.                 //
  2134.                 wsprintf( pszDesc, c_szDescFormat, pszFontName, c_szTrueType );
  2135.                 j = SendMessage( hLBox, LB_FINDSTRINGEXACT, (WPARAM)  -1,
  2136.                                                              (LONG) pszDesc );
  2137.                 if( j != LB_ERR )
  2138.                     SendMessage( hLBox, LB_SETITEMDATA, j, (LONG)  IF_TYPE1_TT );
  2139.                 // else
  2140.                     // ERROR! We should have found a matching LB entry for this
  2141.                     //        font based on TT name.
  2142.             }
  2143.             else
  2144.             {
  2145.                 //
  2146.                 //  Put Font name string in ListBox
  2147.                 //
  2148.                 j = SendMessage( hLBox, LB_ADDSTRING, 0, (LONG) pszDesc );
  2149.                 if( j != LB_ERR )
  2150.                     SendMessage( hLBox, LB_SETITEMDATA, j, (LONG)  IF_TYPE1 );
  2151.                 // else
  2152.                     // ERROR! We found an installed Type1 font but cannot show
  2153.                     //        it in listbox because of USER error.
  2154.             }
  2155.             dwSize = dwPathMax;
  2156.         }
  2157.         bRet = TRUE;
  2158.         RegCloseKey( hkey );
  2159.     }
  2160. EnumType1Exit:
  2161.     if( pszDesc )
  2162.         FreeMem( pszDesc, dwPathMax );
  2163.     if( pszFontName )
  2164.         FreeMem( pszFontName, dwPathMax );
  2165.     return bRet;
  2166. }
  2167. #endif  //  NOTUSED
  2168. /////////////////////////////////////////////////////////////////////////////
  2169. //
  2170. // InitProgress
  2171. //
  2172. //  Create and initialize the Progress dialog.  Initial state is visible.
  2173. //
  2174. /////////////////////////////////////////////////////////////////////////////
  2175. HWND InitProgress( HWND hwnd )
  2176. {
  2177.     if( NULL == hDlgProgress )
  2178.     {
  2179.         RegisterProgressClass( );
  2180.         hDlgProgress = CreateDialog( g_hInst, MAKEINTRESOURCE( DLG_PROGRESS ) ,
  2181.                                      hwnd ? hwnd :HWND_DESKTOP,
  2182.                                      ProgressDlg );
  2183.     }
  2184.     return hDlgProgress;
  2185. }
  2186. /////////////////////////////////////////////////////////////////////////////
  2187. //
  2188. // TermProgress
  2189. //
  2190. //  Remove and cleanup after the Progress dialog.
  2191. //
  2192. /////////////////////////////////////////////////////////////////////////////
  2193. void TermProgress( )
  2194. {
  2195.     if( hDlgProgress )
  2196.     {
  2197.         DestroyWindow( hDlgProgress );
  2198.         UnRegisterProgressClass( );
  2199.     }
  2200.     hDlgProgress = NULL;
  2201.     return;
  2202. }
  2203. /////////////////////////////////////////////////////////////////////////////
  2204. //
  2205. // cpProgressYield
  2206. //
  2207. //  Allow other messages including Dialog messages for Modeless dialog to be
  2208. //  processed while we are converting Type1 files to TrueType.
  2209. //
  2210. //  Since the font conversion is done on a single thread( in order to keep it
  2211. //  synchronous with installation of all fonts )  we need to provide a mechanism
  2212. //  that will allow a user to Cancel out of the operation and also allow
  2213. //  window messages, like WM_PAINT, to be processed by other Window Procedures.
  2214. //
  2215. /////////////////////////////////////////////////////////////////////////////
  2216. VOID cpProgressYield( )
  2217. {
  2218.     MSG msg;
  2219.     while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
  2220.     {
  2221. //        if( !hDlgProgress || !IsDialogMessage( hDlgProgress, &msg ) )
  2222.         if( !IsDialogMessage( hDlgProgress, &msg ) )
  2223.         {
  2224.             TranslateMessage( &msg );
  2225.             DispatchMessage( &msg );
  2226.         }
  2227.     }
  2228. }
  2229. /////////////////////////////////////////////////////////////////////////////
  2230. //
  2231. // UpdateProgress
  2232. //
  2233. //   Set the overall progress control in Progress Dialog, along with a
  2234. //   message describing installation progress.
  2235. //
  2236. /////////////////////////////////////////////////////////////////////////////
  2237. void UpdateProgress( int iTotalCount, int iFontInstalling, int iProgress )
  2238. {
  2239.     TCHAR szTemp[ 120 ] ;
  2240.     wsprintf( szTemp, m_szMsgBuf, iFontInstalling, iTotalCount );
  2241.     SetDlgItemText( hDlgProgress, ID_INSTALLMSG, szTemp );
  2242. SendDlgItemMessage( hDlgProgress, ID_OVERALL, SET_PROGRESS,
  2243.                         (int) iProgress, 0L );
  2244.     //
  2245.     //  Process outstanding messages
  2246.     //
  2247.     cpProgressYield( );
  2248. }
  2249. /////////////////////////////////////////////////////////////////////////////
  2250. //
  2251. // ResetProgress
  2252. //
  2253. //   Clear the progress bar control and reset message to NULL
  2254. //
  2255. /////////////////////////////////////////////////////////////////////////////
  2256. void ResetProgress(  )
  2257. {
  2258.     SetDlgItemText( hDlgProgress, ID_PROGRESSMSG, szNull );
  2259.     SendDlgItemMessage( hDlgProgress, ID_BAR, SET_PROGRESS, (int) 0, 0L );
  2260.     bProgMsgDisplayed = FALSE;
  2261.     bProg2MsgDisplayed = FALSE;
  2262.     //
  2263.     //  Process outstanding messages
  2264.     //
  2265.     cpProgressYield( );
  2266. }
  2267. BOOL InstallCancelled(void)
  2268. {
  2269.     return bCancelInstall;
  2270. }
  2271. /////////////////////////////////////////////////////////////////////////////
  2272. //
  2273. // Progress
  2274. //
  2275. //   Progress function for ConvertTypefaceA - Adobe Type1 to TrueType font
  2276. //   file converter.  Put up progress in converting font and message
  2277. //   describing font being converted.
  2278. //
  2279. /////////////////////////////////////////////////////////////////////////////
  2280. void STDCALL Progress( short PercentDone, void* UniqueValue )
  2281. {
  2282.     TCHAR szTemp[ 120 ] ;
  2283.     TCHAR szTemp2[ 120 ] ;
  2284.     DWORD err = GetLastError( ); // save whatever t1instal may have set
  2285.     //
  2286.     //  UniqueValue is a pointer to the string name of the file being
  2287.     //  converted.  Only put this message up if not previously displayed.
  2288.     //
  2289.     if( !bProgMsgDisplayed )
  2290.     {
  2291.         LPCTSTR args[] = { (LPCTSTR)UniqueValue };
  2292.         LoadString( g_hInst, MYFONT + 6, szTemp2, ARRAYSIZE( szTemp2 ) );
  2293.         FormatMessage(FORMAT_MESSAGE_FROM_STRING |
  2294.                       FORMAT_MESSAGE_ARGUMENT_ARRAY,
  2295.                       szTemp2,
  2296.                       0,
  2297.                       0,
  2298.                       szTemp,
  2299.                       ARRAYSIZE(szTemp),
  2300.                       (va_list *)args);
  2301.         SetDlgItemText( hDlgProgress, ID_PROGRESSMSG, szTemp );
  2302.         bProgMsgDisplayed = TRUE;
  2303.     }
  2304. SendDlgItemMessage( hDlgProgress, ID_BAR, SET_PROGRESS,
  2305.                         (int) PercentDone, 0L );
  2306.     //
  2307.     //  Process outstanding messages
  2308.     //
  2309.     cpProgressYield( );
  2310.     //
  2311.     //  reset last error to whatever t1instal set it to:
  2312.     //
  2313.     SetLastError( err );
  2314. }
  2315. /////////////////////////////////////////////////////////////////////////////
  2316. //
  2317. // Progress2
  2318. //
  2319. //   Progress function for updating progress dialog controls on a per font
  2320. //   install basis.
  2321. //
  2322. /////////////////////////////////////////////////////////////////////////////
  2323. void Progress2( int PercentDone, LPTSTR pszDesc )
  2324. {
  2325.     TCHAR szTemp[ PATHMAX ] ;
  2326.     TCHAR szTemp2[ 240 ] ;
  2327.     //
  2328.     //  szDesc is a pointer to the string name of the file being installed.
  2329.     //  Only put this message up if not previously displayed.
  2330.     if( !bProg2MsgDisplayed )
  2331.     {
  2332.         LPCTSTR args[] = { pszDesc };
  2333.         LoadString( g_hInst, MYFONT + 11, szTemp2, ARRAYSIZE( szTemp2 ) );
  2334.         FormatMessage(FORMAT_MESSAGE_FROM_STRING |
  2335.                       FORMAT_MESSAGE_ARGUMENT_ARRAY,
  2336.                       szTemp2,
  2337.                       0,
  2338.                       0,
  2339.                       szTemp,
  2340.                       ARRAYSIZE(szTemp),
  2341.                       (va_list *)args);
  2342.         SetDlgItemText( hDlgProgress, ID_PROGRESSMSG, szTemp );
  2343.         bProg2MsgDisplayed = TRUE;
  2344.     }
  2345. SendDlgItemMessage( hDlgProgress, ID_BAR, SET_PROGRESS, (int) PercentDone, 0L );
  2346.     //
  2347.     //  Process outstanding messages
  2348.     //
  2349.     cpProgressYield( );
  2350. }
  2351. /////////////////////////////////////////////////////////////////////////////
  2352. //
  2353. // ProgressDlg
  2354. //
  2355. //  Display progress messages to user based on progress in converting
  2356. //  font files to TrueType
  2357. //
  2358. /////////////////////////////////////////////////////////////////////////////
  2359. INT_PTR APIENTRY ProgressDlg( HWND hDlg, UINT nMsg, WPARAM wParam, LPARAM lParam )
  2360. {
  2361.     switch( nMsg )
  2362.     {
  2363.     case WM_INITDIALOG:
  2364.         CentreWindow( hDlg );
  2365.         //
  2366.         //  Load in Progress messages
  2367.         //
  2368.         LoadString( g_hInst, MYFONT + 10, m_szMsgBuf, ARRAYSIZE( m_szMsgBuf ) );
  2369.         EnableWindow( hDlg, TRUE );
  2370.         bCancelInstall = FALSE;
  2371.         break;
  2372.     case WM_COMMAND:
  2373.         switch( LOWORD( wParam ) )
  2374.         {
  2375.         case IDOK:
  2376.         case IDCANCEL:
  2377.             bCancelInstall = ( LOWORD( wParam )  == IDCANCEL );
  2378.             //
  2379.             // Dialog is destroyed programmatically after font is installed.
  2380.             // See TermProgress( )
  2381.             //
  2382.             break;
  2383.         default:
  2384.             return FALSE;
  2385.         }
  2386.         break;
  2387.     case WM_DESTROY:
  2388.         bCancelInstall = FALSE;
  2389.         break;
  2390.     default:
  2391.         return FALSE;
  2392.     }
  2393.     return TRUE;
  2394. }
  2395. /////////////////////////////////////////////////////////////////////////////
  2396. //
  2397. // ProgressBarCtlProc
  2398. //
  2399. //  Window Procedure for the Progress Bar custom control.  Handles all
  2400. //  messages like WM_PAINT just as a normal application window would.
  2401. //
  2402. /////////////////////////////////////////////////////////////////////////////
  2403. LRESULT APIENTRY ProgressBarCtlProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
  2404. {
  2405.     DWORD dwProgress;
  2406.     dwProgress = (DWORD)GetWindowLong( hWnd, GWL_PROGRESS );
  2407.     switch( message )
  2408.     {
  2409.     case WM_CREATE:
  2410.         dwProgress = 0;
  2411.         SetWindowLong( hWnd, GWL_PROGRESS, (LONG)dwProgress );
  2412.         break;
  2413.     case SET_PROGRESS:
  2414.         SetWindowLong( hWnd, GWL_PROGRESS, (LONG) wParam );
  2415.         InvalidateRect( hWnd, NULL, FALSE );
  2416.         UpdateWindow( hWnd );
  2417.         break;
  2418.     case WM_ENABLE:
  2419.         //
  2420.         //  Force a repaint since the control will look different.
  2421.         //
  2422.         InvalidateRect( hWnd, NULL, TRUE );
  2423.         UpdateWindow( hWnd );
  2424.         break;
  2425.     case WM_PAINT:
  2426.         return ProgressPaint( hWnd, dwProgress );
  2427.     default:
  2428.         return( DefWindowProc( hWnd, message, wParam, lParam ) );
  2429.         break;
  2430.     }
  2431.     return( 0L );
  2432. }
  2433. /////////////////////////////////////////////////////////////////////////////
  2434. //
  2435. // RegisterProgressClass
  2436. //
  2437. //
  2438. /////////////////////////////////////////////////////////////////////////////
  2439. BOOL RegisterProgressClass( void )
  2440. {
  2441.     WNDCLASS wcTest;
  2442.     wcTest.lpszClassName = TEXT( "cpProgress" );
  2443.     wcTest.hInstance     = (HINSTANCE) g_hInst;
  2444.     wcTest.lpfnWndProc   = ProgressBarCtlProc;
  2445.     wcTest.hCursor       = LoadCursor( NULL, IDC_WAIT );
  2446.     wcTest.hIcon         = NULL;
  2447.     wcTest.lpszMenuName  = NULL;
  2448.     wcTest.hbrBackground = (HBRUSH) ( rgColorPro[ PROGRESSCOLOR_WINDOW ] );
  2449.     wcTest.style         = CS_HREDRAW | CS_VREDRAW;
  2450.     wcTest.cbClsExtra    = 0;
  2451.     wcTest.cbWndExtra    = sizeof( DWORD );
  2452.     //
  2453.     //  Set Bar color to Blue and text color to white
  2454. //
  2455. // [stevecat]  Let's make these follow the window title bar color and text
  2456. //             color.  Just make the USER calls to get these colors.  This
  2457. //             will make it look better with different color schemes and the
  2458. //             Theme packs.
  2459. //
  2460.     //
  2461. //    rgbBG = RGB(   0,   0, 255 );
  2462. //    rgbFG = RGB( 255, 255, 255 );
  2463.     rgbBG = GetSysColor( rgColorPro[ PROGRESSCOLOR_BAR ] );
  2464.     rgbFG = GetSysColor( rgColorPro[ PROGRESSCOLOR_TEXT ] );
  2465.     return( RegisterClass( (LPWNDCLASS) &wcTest ) );
  2466. }
  2467. /////////////////////////////////////////////////////////////////////////////
  2468. //
  2469. // UnRegisterProgressClass
  2470. //
  2471. //
  2472. /////////////////////////////////////////////////////////////////////////////
  2473. VOID UnRegisterProgressClass( void )
  2474. {
  2475.     UnregisterClass( TEXT( "cpProgress" ), (HINSTANCE) g_hInst );
  2476. }
  2477. /////////////////////////////////////////////////////////////////////////////
  2478. //
  2479. // ProgressPaint
  2480. //
  2481. // Description:
  2482. //
  2483. //  Handles all WM_PAINT messages for the control and paints
  2484. //  the control for the progress state.
  2485. //
  2486. // Parameters:
  2487. //  hWnd            HWND Handle to the control.
  2488. //  dwProgress      DWORD Progress amount - between 1 and 100
  2489. //
  2490. // Return Value:
  2491. //  LONG            0L.
  2492. //
  2493. //
  2494. //  This is an alternate way to do the progress bar in the control.  Instead
  2495. //  of drawing a rectangle, it uses ExtTextOut to draw the opagueing rect
  2496. //  based on the percentage complete.  Clever.
  2497. //
  2498. /////////////////////////////////////////////////////////////////////////////
  2499. LONG ProgressPaint( HWND hWnd, DWORD dwProgress )
  2500. {
  2501.     PAINTSTRUCT ps;
  2502.     HDC         hDC;
  2503.     TCHAR       szTemp[ 20 ] ;
  2504.     int         dx, dy, len;
  2505.     RECT        rc1, rc2;
  2506.     SIZE        Size;
  2507.     hDC = BeginPaint( hWnd, &ps );
  2508.     GetClientRect( hWnd, &rc1 );
  2509.     FrameRect( hDC, &rc1, (HBRUSH) GetStockObject( BLACK_BRUSH ) );
  2510.     InflateRect( &rc1, -1, -1 );
  2511.     rc2 = rc1;
  2512.     dx = rc1.right;
  2513.     dy = rc1.bottom;
  2514.     if( dwProgress == 100 )
  2515.         rc1.right = rc2.left = dx;
  2516.     else
  2517.         rc1.right = rc2.left = ( dwProgress * dx / 100 ) + 1;
  2518.     //
  2519.     //  Boundary condition testing
  2520.     //
  2521.     if( rc2.left > rc2.right )
  2522.         rc2.left = rc2.right;
  2523.     len = wsprintf( szTemp, TEXT( "%3d%%" ), dwProgress );
  2524.     GetTextExtentPoint32( hDC, szTemp, len, &Size );
  2525.     SetBkColor( hDC, rgbBG );
  2526.     SetTextColor( hDC, rgbFG );
  2527.     ExtTextOut( hDC, ( dx - Size.cx ) / 2, ( dy - Size.cy ) / 2,
  2528.                 ETO_OPAQUE | ETO_CLIPPED, &rc1, szTemp, len, NULL );
  2529.     SetBkColor( hDC, rgbFG );
  2530.     SetTextColor( hDC, rgbBG );
  2531.     ExtTextOut( hDC, ( dx - Size.cx ) / 2, ( dy - Size.cy ) / 2,
  2532.                 ETO_OPAQUE | ETO_CLIPPED, &rc2, szTemp, len, NULL );
  2533.     EndPaint( hWnd, &ps );
  2534.     return 0L;
  2535. }
  2536. //
  2537. // Creates a resource name string suitable for calling AddFontResource for a
  2538. // Type1 font.  The resulting resource string is in the following format:
  2539. //
  2540. //      <path to pfm>|<path to pfb>
  2541. //
  2542. // Returns: TRUE  = String was created.
  2543. //          FALSE = Caller passed a NULL pointer or destination buffer is too small.
  2544. //
  2545. BOOL BuildType1FontResourceName(LPCTSTR pszPfm, LPCTSTR pszPfb, LPTSTR pszDest, DWORD cchDest)
  2546. {
  2547.     BOOL bResult = FALSE;
  2548.     if (NULL != pszDest && pszPfm != NULL && pszPfb != NULL)
  2549.     {
  2550.         *pszDest = TEXT('');
  2551.         //
  2552.         // Make sure dest buffer has room for both paths plus separator and term nul.
  2553.         //
  2554.         if ((lstrlen(pszPfm) + lstrlen(pszPfb) + 2) < (INT)cchDest)
  2555.         {
  2556.             wsprintf(pszDest, TEXT("%s|%s"), pszPfm, pszPfb);
  2557.             bResult = TRUE;
  2558.         }
  2559.     }
  2560.     return bResult;
  2561. }
  2562. #endif  //  WINNT