FONT.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:40k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /************************************************************************
  2.   File: font.c
  3.   Purpose:
  4.     Contains all functions pertinent to CDTEST's Font dialog.
  5.   Functions:
  6.      DoFontDlg()          -- Creates CDTEST's font dialog.
  7.      FontProc()           -- Callback for CDTEST's font dialog.
  8.      InitFontStruct()     -- Fills a CHOOSEFONT structure with some defaults.
  9.      FillFontDlg()        -- Fills CDTEST's font dialog with the contents
  10.                              of a CHOOSEFONT structure.
  11.      GetFontDlg()         -- Retrieves the contents of CDTEST's font dialog
  12.                              and fills a CHOOSEFONT structure with them.
  13.      GetHdc()             -- Creates and returns an HDC
  14.      LogFontProc()        -- Callback function for the logfont dlg.
  15.      InitLogFontStruct()  -- Fills a LOGFONT structure with some defaults.
  16.      FillLogFontDlg()     -- Fills the LOGFONT dlg with the values in
  17.                              a LOGFONT structure.
  18.      GetLogFontDlg()      -- Retrieves the user's edits in the LogFont dlg
  19.                              and puts them in a LOGFONT structure.
  20.      FontHookProc()       -- Callback function for CHOOSEFONT->lpfnHook
  21.      GetFontDlgHandle()   -- Creates a handle to the custom template and
  22.                              returns a handle to it.
  23.      EnumFontsProc()      -- Callback function for EnumFontFamilies()
  24.      FillFontsBox()       -- Fills CDTEST's font list box with requested fonts
  25.      ResetCheckBoxes()    -- handles the font choices check box manipulations
  26.      HandleFontCheckBox() -- Handles the WM_COMMAND messages from the font
  27.                              choices check boxes.
  28.      DoChooseFontStuff()  -- Calls the ChooseFont() function.
  29.      FontThreadProc1()    -- Starting address for the first thread.
  30.      FontThreadProc2()    -- Starting address for the second thread.
  31.      MultiThreadFontDlg() -- Creates two threads which each create a
  32.                              ChooseFont() dialog.
  33.      FontEnableButtons()  -- Enables or disables CDTEST's font dialog buttons.
  34.                              Necessary for multithreading part of this app.
  35. ************************************************************************/
  36. #include <windows.h>
  37. #include <commdlg.h>
  38. #include <stdlib.h>
  39. #include <winnls.h>
  40. #include "cdtest.h"
  41. #include "font.h"
  42. #include "logfont.h"
  43. /* some definitions that will help us tell the difference between
  44.    screen and printer fonts */
  45. #define FONT_TYPE_WYSIWYG 1
  46. BOOL bScreen ;
  47. /* function prototypes and general variables */
  48. void InitFontStruct(HWND, LPCHOOSEFONT) ;
  49. void FillFontDlg(HWND, LPCHOOSEFONT) ;
  50. void GetFontDlg(HWND, LPCHOOSEFONT) ;
  51. HDC  GetHdc(HWND, int) ;
  52. void InitLogFontStruct(HWND, LPLOGFONT) ;
  53. void FillLogFontDlg(HWND, LPLOGFONT) ;
  54. void GetLogFontDlg(HWND, LPLOGFONT) ;
  55. BOOL APIENTRY LogFontProc(HWND, UINT, UINT, LONG) ;
  56. UINT APIENTRY FontHookProc(HWND, UINT, UINT, LONG) ;
  57. int  CALLBACK EnumFontsProc(LPLOGFONT, LPTEXTMETRIC, DWORD, LONG) ;
  58. void FillFontsBox(HWND, DWORD) ;
  59. void ResetCheckBoxes(HWND) ;
  60. void HandleFontCheckBox(HWND, int) ;
  61. void DoChooseFontStuff(HWND, LPCHOOSEFONT) ;
  62. /* Global variables and some external variables and functions */
  63. DWORD dwFontFlag ;
  64. PRINTDLG pfd ;
  65. BOOL bLogFontParam ;
  66. LOGFONT lfWM_CF_LF ;                 //for the WM_CHOOSEFONT_GETLOGFONT message
  67. extern UINT uMode ;
  68. extern LONG MyAtol(LPTSTR, BOOL, LPBOOL) ;
  69. HANDLE hResFont, hDialogFont ;
  70. HANDLE GetFontDlgHandle(void) ;
  71. CHOOSEFONT cf ;
  72. LOGFONT lf ;
  73. HDC hdc ;
  74. TCHAR szFaceName[50] ;
  75. TCHAR szFontTemplate[50] ;
  76. TCHAR szFontStyle[50] ;
  77. #define HDCSCREEN 1
  78. #define HDCPRINTER 2
  79. #define HDCNULL 3
  80. #define HDCINVALID 4
  81. INT nHdcType ;
  82. /* Multithreading stuff */
  83. HANDLE hFontThread1 ;
  84. HANDLE hFontThread2 ;
  85. DWORD  dwFontThreadID1 ;
  86. DWORD  dwFontThreadID2 ;
  87. DWORD  dwFontThreadParm1 ;
  88. DWORD  dwFontThreadParm2 ;
  89. DWORD  FontThreadProc1(LPDWORD) ;
  90. DWORD  FontThreadProc2(LPDWORD) ;
  91. HANDLE hwndMainFont ;
  92. int    nOpenFontDialogCount ;
  93. CHOOSEFONT cfThread1 ;
  94. CHOOSEFONT cfThread2 ;
  95. void MultiThreadFontDlg(void) ;
  96. void EnableFontButtons(HWND, BOOL) ;
  97. /************************************************************************
  98.   Function: DoFontDlg(HWND)
  99.   Purpose:
  100.     To create the CDTEST's font dialog
  101.   Returns: Nothing.
  102.   Comments:
  103. ************************************************************************/
  104. void DoFontDialog(HWND hwnd)
  105. {
  106.   DialogBox(hInst, MAKEINTRESOURCE(ID_FONTDIALOG),
  107.             hwnd, FontProc) ;
  108. }
  109. /************************************************************************
  110.   Function: FontProc(HWND, UINT, UINT, LONG)
  111.   Purpose:
  112.     Callback function for CDTEST's font dialog.
  113.   Returns: TRUE or FALSE depending on the situation.
  114.   Comments:
  115. ************************************************************************/
  116. BOOL APIENTRY FontProc(HWND hwnd, UINT msg, UINT wParam, LONG lParam)
  117. {
  118.   BOOL b ;
  119.   TCHAR szNum[30] ;
  120.   switch (msg)
  121.   {
  122.     case WM_INITDIALOG:
  123.         InitLogFontStruct(hwnd, &lf) ;   //fill (struct lf) so the choosefont
  124.         InitFontStruct(hwnd, &cf) ;      //struct can use it
  125.         FillFontDlg(hwnd, &cf) ;
  126.         CheckRadioButton(hwnd, ID_HDCSCREEN, ID_HDCPRINTER, ID_HDCSCREEN) ;
  127.         nHdcType = HDCSCREEN ;
  128.         dwFontFlag = cf.Flags ;
  129.         FillFontsBox(hwnd, dwFontFlag) ;
  130.         ResetCheckBoxes(hwnd) ;
  131.         *(&cfThread1) = *(&cfThread2) = *(&cf) ;
  132.         hwndMainFont = hwnd ;
  133.         nOpenFontDialogCount = 0 ;
  134.         SetFocus(GetDlgItem(hwnd, ID_STRUCTSIZEF)) ;
  135.         break ;
  136.     case UMSG_DECREMENTDLGCOUNT:  // user defined message.  This is send by
  137.                                   // the functions that are executing when
  138.                                   // a new thread is created.  When these
  139.                                   // Thread functions end, they should send
  140.                                   // this message.
  141.       nOpenFontDialogCount-- ;
  142.       if (nOpenFontDialogCount == 0)
  143.         EnableFontButtons(hwnd, TRUE) ;
  144.       break ;
  145.     case WM_CF_LF:
  146.        /* If this message comes in, we know that the user clicked the
  147.           button that tells the ChooseFont() dialog to tell the parent
  148.           to send the WM_CHOOSEFONT_GETLOGFONT message.  So what we will
  149.           do is send the message and then show the user what was in the
  150.           logfont by calling creating the Logfont dialog box */
  151.        SendMessage((HWND) lParam, WM_CHOOSEFONT_GETLOGFONT,
  152.                    0, (LPARAM) &lfWM_CF_LF) ;
  153.        bLogFontParam = TRUE ; //tells us if we are doing normal logfont
  154.                               //processing or answering the WM_CF_LF message.
  155.        DialogBoxParam(hInst, MAKEINTRESOURCE(ID_LOGFONTDIALOG),
  156.                       (HWND) lParam, LogFontProc, (LPARAM) &lf) ;
  157.        bLogFontParam = FALSE ;
  158.        break ;
  159.     case WM_COMMAND:
  160.     {
  161.         switch (LOWORD(wParam))
  162.         {
  163.           case IDOK:
  164.             DoChooseFontStuff(hwnd, &cf) ;  //create the dialog.
  165.             break ;
  166.           case IDCANCEL:
  167.             EndDialog(hwnd, FALSE) ;
  168.             break ;
  169.           case ID_RESETFONT:
  170.             InitLogFontStruct(hwnd, &lf) ;  //reset all the structures.
  171.             InitFontStruct(hwnd, &cf) ;
  172.             FillFontDlg(hwnd, &cf) ;        //refill the dialog.
  173.             CheckRadioButton(hwnd, ID_HDCSCREEN, ID_HDCPRINTER, ID_HDCSCREEN) ;
  174.             nHdcType = HDCSCREEN ;
  175.             SendDlgItemMessage(hwnd, ID_NULLSTRUCTFONT, BM_SETCHECK, (WPARAM) 0, (LPARAM)0) ;
  176.             SendDlgItemMessage(hwnd, ID_PRELOADEDFONT,  BM_SETCHECK, (WPARAM) 0, (LPARAM)0) ;
  177.             dwFontFlag = cf.Flags ;
  178.             FillFontsBox(hwnd, dwFontFlag) ;
  179.             ResetCheckBoxes(hwnd) ;
  180.             SetFocus(GetDlgItem(hwnd, ID_STRUCTSIZEF)) ;
  181.             break ;
  182.           case ID_HDCSCREEN:
  183.             nHdcType = HDCSCREEN ;
  184.             break ;
  185.           case ID_HDCPRINTER:
  186.             nHdcType = HDCPRINTER ;
  187.             break ;
  188.           case ID_HDCNULL:
  189.             nHdcType = HDCNULL ;
  190.             break ;
  191.           case ID_HDCINVALID:
  192.             nHdcType = HDCINVALID ;
  193.             break ;
  194.           case ID_EDITLOGFONT:
  195.             /* Get the address of the logfont and then show the user what
  196.                is in it with the Logfont dialog box */
  197.             GetDlgItemText(hwnd, ID_LOGFONTF, szNum, 30) ;
  198.             cf.lpLogFont = (LPLOGFONT) MyAtol(szNum, uMode==IDM_HEXMODE, &b) ;
  199.             DialogBox(hInst, MAKEINTRESOURCE(ID_LOGFONTDIALOG),
  200.                       hwnd, LogFontProc) ;
  201.             break ;
  202.           case F_TTONLY:
  203.           case F_ANSIONLY:
  204.           case F_PRINTERFONTS:
  205.           case F_SCREENFONTS:
  206.           case F_FIXEDPITCHONLY:
  207.           case F_NOOEMFONTS:
  208.           case F_NOVECTORFONTS:
  209.           case F_SCALABLEONLY:
  210.           case F_WYSIWYG:
  211.             HandleFontCheckBox(hwnd, LOWORD(wParam)) ;
  212.             break ;
  213.           case ID_MULTITHREADFONT:
  214.             /* Set the dialog count to 2, disable the buttons in CDTEST's font
  215.                dialog so the user can't do anything until last dialog has
  216.                been terminated */
  217.             nOpenFontDialogCount = 2 ;
  218.             EnableFontButtons(hwndMainFont, FALSE) ;
  219.             /* And then do the multithreading */
  220.             MultiThreadFontDlg() ;
  221.             break ;
  222.           default: break ;
  223.         }
  224.     }
  225.     default:
  226.       /*
  227.          If the help button is pressed in the ChooseFont()
  228.          dialog, it will send a message Registered with RegisterWindowMessage()
  229.          to the parent window.  The message nHelpMessage was registered
  230.          at application startup
  231.          It must be detected with an IF statement because the value
  232.          returned by RegisterWindowMessage() is not a constant
  233.       */
  234.       if (msg == nHelpMessage)
  235.         MessageBox(GetForegroundWindow(), TEXT("Hello from the help button"),
  236.                    TEXT("Font Help Button"), MB_OK | MB_APPLMODAL) ;
  237.       break ;
  238.   }
  239.   return FALSE ;
  240. }
  241. /************************************************************************
  242.   Function: InitFontStruct(HWND, LPCHOOSEFONT)
  243.   Purpose:
  244.     Fill the CHOOSEFONT structure passed as the second parameter with
  245.     some default values.
  246.   Returns: Nothing.
  247.   Comments:
  248. ************************************************************************/
  249. void InitFontStruct(HWND hwnd, LPCHOOSEFONT pcf)
  250. {
  251.   pcf->lStructSize = sizeof(CHOOSEFONT) ;
  252.   pcf->hwndOwner = hwnd ;
  253.   pcf->hDC = (HDC) 0 ;
  254.   pcf->lpLogFont = &lf ;
  255.   pcf->iPointSize = 24 ;
  256.   pcf->Flags = CF_EFFECTS | CF_SCREENFONTS | CF_INITTOLOGFONTSTRUCT | CF_SHOWHELP | CF_APPLY ;
  257.   pcf->rgbColors = RGB(0, 255, 0) ;
  258.   pcf->lCustData = 0L ;
  259.   pcf->lpfnHook = FontHookProc ;
  260.   lstrcpy(szFontTemplate, TEXT("fonttemp")) ;
  261.   pcf->lpTemplateName = szFontTemplate ;
  262.   pcf->hInstance = (HANDLE) hInst ;
  263.   lstrcpy(szFontStyle, TEXT("Bold")) ;
  264.   pcf->lpszStyle = szFontStyle ;
  265.   pcf->nFontType = SCREEN_FONTTYPE ;
  266.   pcf->nSizeMin = 8 ;
  267.   pcf->nSizeMax = 50 ;
  268. }
  269. /************************************************************************
  270.   Function: FillFontDlg(HWND, LPCHOOSEFONT)
  271.   Purpose:
  272.     Fill CDTEST's font dialog with the values in the CHOOSEFONT structure
  273.     passed via the second parameter.
  274.   Returns: Nothing.
  275.   Comments:
  276. ************************************************************************/
  277. void FillFontDlg(HWND hwnd, LPCHOOSEFONT pcf)
  278. {
  279.   wsprintf(szTemp, szLongFilter, pcf->lStructSize) ;
  280.   SetDlgItemText(hwnd, ID_STRUCTSIZEF, szTemp) ;
  281.   wsprintf(szTemp, szLongFilter, (DWORD) pcf->hwndOwner) ;
  282.   SetDlgItemText(hwnd, ID_HWNDOWNERF, szTemp) ;
  283.   wsprintf(szTemp, szLongFilter, (DWORD) pcf->hDC) ;
  284.   SetDlgItemText(hwnd, ID_HDCF, szTemp) ;
  285.   wsprintf(szTemp, szLongFilter, (DWORD) pcf->hDC) ;
  286.   SetDlgItemText(hwnd, ID_HDCF, szTemp) ;
  287.   wsprintf(szTemp, szLongFilter, (DWORD) pcf->lpLogFont) ;
  288.   SetDlgItemText(hwnd, ID_LOGFONTF, szTemp) ;
  289.   wsprintf(szTemp, szLongFilter, (DWORD) pcf->iPointSize) ;
  290.   SetDlgItemText(hwnd, ID_POINTSIZEF, szTemp) ;
  291.   wsprintf(szTemp, szLongFilter, pcf->Flags) ;
  292.   SetDlgItemText(hwnd, ID_FLAGSF, szTemp) ;
  293.   wsprintf(szTemp, szLongFilter, pcf->rgbColors) ;
  294.   SetDlgItemText(hwnd, ID_RGBCOLORSF, szTemp) ;
  295.   wsprintf(szTemp, szLongFilter, pcf->lCustData) ;
  296.   SetDlgItemText(hwnd, ID_CUSTDATAF, szTemp) ;
  297.   wsprintf(szTemp, szLongFilter, (DWORD) pcf->lpfnHook) ;
  298.   SetDlgItemText(hwnd, ID_HOOKF, szTemp) ;
  299.   SetDlgItemText(hwnd, ID_TEMPLATEF, pcf->lpTemplateName) ;
  300.   wsprintf(szTemp, szLongFilter, (DWORD) pcf->hInstance) ;
  301.   SetDlgItemText(hwnd, ID_HINSTANCEF, szTemp) ;
  302.   SetDlgItemText(hwnd, ID_STYLEF, pcf->lpszStyle) ;
  303.   wsprintf(szTemp, szLongFilter, (int) pcf->nFontType) ;
  304.   SetDlgItemText(hwnd, ID_FONTTYPEF, szTemp) ;
  305.   wsprintf(szTemp, szLongFilter, (int) pcf->nSizeMin) ;
  306.   SetDlgItemText(hwnd, ID_SIZEMINF, szTemp) ;
  307.   wsprintf(szTemp, szLongFilter, (int) pcf->nSizeMax) ;
  308.   SetDlgItemText(hwnd, ID_SIZEMAXF, szTemp) ;
  309. }
  310. /************************************************************************
  311.   Function: GetFontDlg(HWND, LPCHOOSEFONT)
  312.   Purpose:
  313.     Retrieve the users edits from CDTEST's font dialog and put them
  314.     in the CHOOSEFONT structure passed in as the second parameter
  315.   Returns: Nothing.
  316.   Comments:
  317. ************************************************************************/
  318. void GetFontDlg(HWND hwnd, LPCHOOSEFONT pcf)
  319. {
  320.   BOOL b ;
  321.   TCHAR szNum[30] ;
  322. #define WSIZEFO 30
  323.   GetDlgItemText(hwnd, ID_STRUCTSIZEF, szNum, WSIZEFO) ;
  324.   pcf->lStructSize = MyAtol(szNum, uMode == IDM_HEXMODE, &b) ;
  325.   GetDlgItemText(hwnd, ID_HWNDOWNERF, szNum, WSIZEFO) ;
  326.   pcf->hwndOwner = (HWND) MyAtol(szNum, uMode == IDM_HEXMODE, &b) ;
  327.   GetDlgItemText(hwnd, ID_LOGFONTF, szNum, WSIZEFO) ;
  328.   pcf->lpLogFont = (LPLOGFONT) MyAtol(szNum, uMode == IDM_HEXMODE, &b) ;
  329.   GetDlgItemText(hwnd, ID_POINTSIZEF, szNum, WSIZEFO) ;
  330.   pcf->iPointSize = (int) MyAtol(szNum, uMode == IDM_HEXMODE, &b) ;
  331.   GetDlgItemText(hwnd, ID_FLAGSF, szNum, WSIZEFO) ;
  332.   pcf->Flags = MyAtol(szNum, uMode == IDM_HEXMODE, &b) ;
  333.   GetDlgItemText(hwnd, ID_RGBCOLORSF, szNum, WSIZEFO) ;
  334.   pcf->rgbColors = MyAtol(szNum, uMode == IDM_HEXMODE, &b) ;
  335.   GetDlgItemText(hwnd, ID_CUSTDATAF, szNum, WSIZEFO) ;
  336.   pcf->lCustData = MyAtol(szNum, uMode == IDM_HEXMODE, &b) ;
  337.   GetDlgItemText(hwnd, ID_HOOKF, szNum, WSIZEFO) ;
  338.   pcf->lpfnHook = (LPCFHOOKPROC) MyAtol(szNum, uMode == IDM_HEXMODE, &b) ;
  339.   GetDlgItemText(hwnd, ID_TEMPLATEF, szFontTemplate, 50) ;
  340.   GetDlgItemText(hwnd, ID_HINSTANCEF, szNum, WSIZEFO) ;
  341.   pcf->hInstance = (HANDLE) MyAtol(szNum, uMode == IDM_HEXMODE, &b) ;
  342.   GetDlgItemText(hwnd, ID_STYLEF, szFontStyle, 50) ;
  343.   GetDlgItemText(hwnd, ID_FONTTYPEF, szNum, WSIZEFO) ;
  344.   pcf->nFontType = (int) MyAtol(szNum, uMode == IDM_HEXMODE, &b) ;
  345.   GetDlgItemText(hwnd, ID_SIZEMINF, szNum, WSIZEFO) ;
  346.   pcf->nSizeMin = (int) MyAtol(szNum, uMode == IDM_HEXMODE, &b) ;
  347.   GetDlgItemText(hwnd, ID_SIZEMAXF, szNum, WSIZEFO) ;
  348.   pcf->nSizeMax = (int) MyAtol(szNum, uMode == IDM_HEXMODE, &b) ;
  349. }
  350. /************************************************************************
  351.   Function: GetHdc(HWND, int)
  352.   Purpose:
  353.     Creates and returns an HDC of the type specified.
  354.   Returns: The HDC that it creates.
  355.   Comments:
  356.     The NULL and INVALID HDCs are only useful to test if the common dialogs
  357.     handle an HDC that is not useful, but this function is also necessary
  358.     in that the HDC must be a printer HDC if ChooseFont() is called
  359.     with the CF_PRINTERFONTS flag bit set.
  360.     To tell ChooseFont() to list only printer fonts:
  361.     1.  Set the HDC in CDTEST's font dialog to "Printer"
  362.     2.  Set the "Flags" edit box CF_PRINTERFONTS
  363. ************************************************************************/
  364. HDC GetHdc(HWND hwnd, int nType)
  365. {
  366.   switch (nType)
  367.   {
  368.     case HDCSCREEN:
  369.         return GetDC(hwnd) ;
  370.         break ;
  371.     case HDCNULL:
  372.         return (HDC) 0 ;
  373.         break ;
  374.     case HDCINVALID:
  375.         return (HDC) 999 ;
  376.         break ;
  377.     case HDCPRINTER:
  378.         /* To get the HDC of the current printer, fill out a PRINTDLG
  379.            structure, and set it's flags to (PD_RETURNDC | PD_RETURNDEFAULT).
  380.            This will tell PrintDlg() to create you an HDC but not show
  381.            the Print dialog box. */
  382.         pfd.lStructSize = sizeof(PRINTDLG) ;
  383.         pfd.hwndOwner = hwnd ;
  384.         pfd.hDevMode = (HANDLE) 0 ;
  385.         pfd.hDevNames = (HANDLE) 0 ;
  386.         pfd.Flags = PD_RETURNDC | PD_RETURNDEFAULT ;   //just get default printer
  387.         pfd.nFromPage = 0 ;
  388.         pfd.nToPage = 0 ;
  389.         pfd.nMinPage = 0 ;
  390.         pfd.nMaxPage = 0 ;
  391.         pfd.nCopies = 0 ;
  392.         pfd.hInstance = (HANDLE) hInst ;
  393.         if (PrintDlg(&pfd) == 0)
  394.             MessageBox(hwnd, TEXT("Error: Could not create a printer DC!"),
  395.                        (LPTSTR) NULL, MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL) ;
  396.         else
  397.            return pfd.hDC ;
  398.         break ;
  399.     default:
  400.         break ;
  401.   }
  402.   return (HDC) 0 ;
  403. }
  404. /************************************************************************
  405.   Function: LogFontProc(HWND, int)
  406.   Purpose:
  407.     The callback proc for the LogFont dialog box
  408.   Returns: BOOL -- depending on the situation.
  409.   Comments:
  410. ************************************************************************/
  411. BOOL APIENTRY LogFontProc(HWND hwnd, UINT msg, UINT wParam, LONG lParam)
  412. {
  413.   switch (msg)
  414.   {
  415.     case WM_INITDIALOG:
  416.         FillLogFontDlg(hwnd, cf.lpLogFont) ;  //start off with the one that
  417.                                               //is returned from ChooseFont()
  418.         break ;
  419.     case WM_COMMAND:
  420.         switch(LOWORD(wParam))
  421.         {
  422.           case IDOK:
  423.             GetLogFontDlg(hwnd, &lf) ;
  424.             cf.lpLogFont = &lf ;
  425.             EndDialog(hwnd, TRUE) ;
  426.             break ;
  427.           case ID_RESETLF:
  428.             SetFocus(GetDlgItem(hwnd, ID_LFHEIGHT)) ;
  429.             InitLogFontStruct(hwnd, &lf) ;
  430.             FillLogFontDlg(hwnd, &lf) ;
  431.             break ;
  432.           case IDCANCEL:
  433.             EndDialog(hwnd, FALSE) ;
  434.             break ;
  435.           default:
  436.             break ;
  437.         }
  438.     default: break ;
  439.   }
  440.   return FALSE ;
  441. }
  442. /************************************************************************
  443.   Function: InitLogFontStruct(HWND, LPLOGFONT)
  444.   Purpose:
  445.     Fills the LOGFONT structure passed in as the second parameter with
  446.     some default values.
  447.   Returns: Nothing.
  448.   Comments:
  449. ************************************************************************/
  450. void InitLogFontStruct(HWND hwnd, LPLOGFONT plf)
  451. {
  452.   plf->lfHeight = 24 ;
  453.   plf->lfWidth  = 20 ;
  454.   plf->lfEscapement = 0 ;
  455.   plf->lfOrientation = 10 ;
  456.   plf->lfWeight = 400 ;
  457.   plf->lfItalic = FALSE ;
  458.   plf->lfUnderline = FALSE ;
  459.   plf->lfStrikeOut = FALSE ;
  460.   plf->lfCharSet = ANSI_CHARSET ;
  461.   plf->lfOutPrecision = OUT_DEFAULT_PRECIS ;
  462.   plf->lfClipPrecision = CLIP_DEFAULT_PRECIS ;
  463.   plf->lfQuality = DEFAULT_QUALITY ;
  464.   plf->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE ;
  465.   szFaceName[0] = (TCHAR) 0 ;
  466.   lstrcpy(plf->lfFaceName, szFaceName) ;
  467. }
  468. /************************************************************************
  469.   Function: FillLogFontDlg(HWND, LPLOGFONT)
  470.   Purpose:
  471.     Fills CDTEST's logfont dialog with the values in the logfont that
  472.     is passed in as the second parameter.
  473.   Returns: Nothing.
  474.   Comments:
  475. ************************************************************************/
  476. void FillLogFontDlg(HWND hwnd, LPLOGFONT plf)
  477. {
  478.   TCHAR szTemp[50] ;
  479.   LPLOGFONT pl = plf ;
  480.   if (bLogFontParam)    //Are creating this dialog in response to the
  481.     pl = &lfWM_CF_LF ;  //WM_CHOOSEFONT_GETLOGFONT message ?
  482.   if (!pl)              //Avert a ghastly exception error
  483.     return ;
  484.   wsprintf(szTemp, szLongFilter, pl->lfHeight) ;
  485.   SetDlgItemText(hwnd, ID_LFHEIGHT, szTemp) ;
  486.   wsprintf(szTemp, szLongFilter, pl->lfWidth) ;
  487.   SetDlgItemText(hwnd, ID_LFWIDTH, szTemp) ;
  488.   wsprintf(szTemp, szLongFilter, pl->lfEscapement) ;
  489.   SetDlgItemText(hwnd, ID_LFESCAPEMENT, szTemp) ;
  490.   wsprintf(szTemp, szLongFilter, pl->lfOrientation) ;
  491.   SetDlgItemText(hwnd, ID_LFORIENTATION, szTemp) ;
  492.   wsprintf(szTemp, szLongFilter, pl->lfWeight) ;
  493.   SetDlgItemText(hwnd, ID_LFWEIGHT, szTemp) ;
  494.   wsprintf(szTemp, szShortFilter, pl->lfItalic) ;
  495.   SetDlgItemText(hwnd, ID_LFITALIC, szTemp) ;
  496.   wsprintf(szTemp, szShortFilter, pl->lfUnderline) ;
  497.   SetDlgItemText(hwnd, ID_LFUNDERLINE, szTemp) ;
  498.   wsprintf(szTemp, szShortFilter, pl->lfStrikeOut) ;
  499.   SetDlgItemText(hwnd, ID_LFSTRIKEOUT, szTemp) ;
  500.   wsprintf(szTemp, szShortFilter, pl->lfCharSet) ;
  501.   SetDlgItemText(hwnd, ID_LFCHARSET, szTemp) ;
  502.   wsprintf(szTemp, szShortFilter, pl->lfOutPrecision) ;
  503.   SetDlgItemText(hwnd, ID_LFOUTP, szTemp) ;
  504.   wsprintf(szTemp, szShortFilter, pl->lfClipPrecision) ;
  505.   SetDlgItemText(hwnd, ID_LFCLIPP, szTemp) ;
  506.   wsprintf(szTemp, szShortFilter, pl->lfQuality) ;
  507.   SetDlgItemText(hwnd, ID_LFQUALITY, szTemp) ;
  508.   wsprintf(szTemp, szShortFilter, pl->lfPitchAndFamily) ;
  509.   SetDlgItemText(hwnd, ID_LFPITCHANDFAM, szTemp) ;
  510.   SetDlgItemText(hwnd, ID_LFFACENAME, (LPTSTR) pl->lfFaceName) ;
  511. }
  512. /************************************************************************
  513.   Function: GetLogFontDlg(HWND, LPLOGFONT)
  514.   Purpose:
  515.     Retrieves the users edits in CDTEST's Logfont dialog and puts them
  516.     into the LOGFONT struct that is passed as the second parameter.
  517.   Returns: Nothing.
  518.   Comments:
  519. ************************************************************************/
  520. void GetLogFontDlg(HWND hwnd, LPLOGFONT plf)
  521. {
  522.   BOOL b ;
  523.   TCHAR szNum[30] ;
  524.   if (bLogFontParam)  //if we are just viewing the logfont because we sent a
  525.     return ;          //WM_CHOOSEFONT_GETLOGFONT message, don't change the Logfont Struct
  526.                       //that ChooseFont() gives us...
  527.   #define LFSIZE 30
  528.   GetDlgItemText(hwnd, ID_LFHEIGHT, szNum, LFSIZE) ;
  529.   plf->lfHeight = MyAtol(szNum, uMode == IDM_HEXMODE, &b) ;
  530.   GetDlgItemText(hwnd, ID_LFWIDTH, szNum, LFSIZE) ;
  531.   plf->lfWidth = MyAtol(szNum, uMode == IDM_HEXMODE, &b) ;
  532.   GetDlgItemText(hwnd, ID_LFESCAPEMENT, szNum, LFSIZE) ;
  533.   plf->lfEscapement = MyAtol(szNum, uMode == IDM_HEXMODE, &b) ;
  534.   GetDlgItemText(hwnd, ID_LFORIENTATION, szNum, LFSIZE) ;
  535.   plf->lfOrientation = MyAtol(szNum, uMode == IDM_HEXMODE, &b) ;
  536.   GetDlgItemText(hwnd, ID_LFWEIGHT, szNum, LFSIZE) ;
  537.   plf->lfWeight = MyAtol(szNum, uMode == IDM_HEXMODE, &b) ;
  538.   GetDlgItemText(hwnd, ID_LFITALIC, szNum, LFSIZE) ;
  539.   plf->lfItalic = (BYTE) MyAtol(szNum, uMode == IDM_HEXMODE, &b) ;
  540.   GetDlgItemText(hwnd, ID_LFUNDERLINE, szNum, LFSIZE) ;
  541.   plf->lfUnderline = (BYTE) MyAtol(szNum, uMode == IDM_HEXMODE, &b) ;
  542.   GetDlgItemText(hwnd, ID_LFSTRIKEOUT, szNum, LFSIZE) ;
  543.   plf->lfStrikeOut = (BYTE) MyAtol(szNum, uMode == IDM_HEXMODE, &b) ;
  544.   GetDlgItemText(hwnd, ID_LFCHARSET, szNum, LFSIZE) ;
  545.   plf->lfCharSet = (BYTE) MyAtol(szNum, uMode == IDM_HEXMODE, &b) ;
  546.   GetDlgItemText(hwnd, ID_LFOUTP, szNum, LFSIZE) ;
  547.   plf->lfOutPrecision = (BYTE) MyAtol(szNum, uMode == IDM_HEXMODE, &b) ;
  548.   GetDlgItemText(hwnd, ID_LFCLIPP, szNum, LFSIZE) ;
  549.   plf->lfClipPrecision = (BYTE) MyAtol(szNum, uMode == IDM_HEXMODE, &b) ;
  550.   GetDlgItemText(hwnd, ID_LFQUALITY, szNum, LFSIZE) ;
  551.   plf->lfQuality = (BYTE) MyAtol(szNum, uMode == IDM_HEXMODE, &b) ;
  552.   GetDlgItemText(hwnd, ID_LFPITCHANDFAM, szNum, LFSIZE) ;
  553.   plf->lfPitchAndFamily = (BYTE) MyAtol(szNum, uMode == IDM_HEXMODE, &b) ;
  554.   GetDlgItemText(hwnd, ID_LFFACENAME, (LPTSTR) plf->lfFaceName, 32) ;
  555. }
  556. /************************************************************************
  557.   Function: FontHookProc(HWND, UINT, UINT, LONG)
  558.   Purpose: The callback function that acts as the hook proc for
  559.            the ChooseFont() dialog.
  560.   Returns: TRUE to discard the message.  FALSE to send the message on
  561.            to the normal dialog processing done by the ChooseFont()
  562.            function.
  563.   Comments:
  564. ************************************************************************/
  565. UINT APIENTRY FontHookProc(HWND hwnd, UINT msg, UINT wParam, LONG lParam)
  566. {
  567.   LPCHOOSEFONT pCf ;
  568.   TCHAR szMsg[50] ;
  569.   switch(msg)
  570.   {
  571.     case WM_INITDIALOG:
  572.       pCf = (LPCHOOSEFONT) lParam ;
  573.       if (pCf->lCustData != 0L)
  574.       {
  575.         wsprintf(szMsg, TEXT("CHOOSEFONT->lCustData is: %ld"), pCf->lCustData) ;
  576.         MessageBox(hwnd, szMsg, TEXT("lCustData Sent!"), MB_OK) ;
  577.       }
  578.       SetWindowText(hwnd, TEXT("Font Hook Proc Dialog")) ;
  579.       break ;
  580.     case WM_COMMAND:
  581.         /* NOTE: This button will only be available if the user creates the
  582.            ChooseFont() dialog with the CF_ENABLETEMPLATE or CF_ENABLETEMPLATEHANDLE
  583.            flag.
  584.            This button will only work if the ChooseFont() dialog is created
  585.            with the CF_ENABLEHOOK flag.  So, to get full functionality from
  586.            this button:
  587.            1.  Enter (CF_ENABLEHOOK | CF_ENABLETEMPLATE | CF_SCREENFONTS)
  588.                in the "Flags" edit box of CDTEST'S Font dialog.
  589.            2.  Click OK
  590.         */
  591.         /* The parent will send the WM_CHOOSEFONT_GETLOGFONT message and
  592.            display it's findings in a LogFont dialog if it gets this message */
  593.         if (LOWORD(wParam) == ID_SEND_WM_CF_LF_MSG)
  594.           SendMessage(GetParent(hwnd), WM_CF_LF, 0, (LPARAM) hwnd) ;
  595.         break ;
  596.     default:
  597.       break ;
  598.   }
  599.   return FALSE ;   //send msg to the common dialog code
  600. }
  601. /************************************************************************
  602.   Function: GetFontDlgHandle(void)
  603.   Purpose:  Finds and loads the custom template resource and returns a
  604.             handle to it.
  605.   Returns: A handle to the custom template resource.
  606.   Comments:
  607. ************************************************************************/
  608. HANDLE GetFontDlgHandle(void)
  609. {
  610.   hResFont = FindResource(hInst, TEXT("fonttemp"), RT_DIALOG) ;
  611.   hDialogFont = LoadResource(hInst, hResFont) ;
  612.   return hDialogFont ;
  613. }
  614. /************************************************************************
  615.   Function: EnumFontsProc(LPLOGFONT, LPTEXTMETRIC, DWORD, LONG)
  616.   Purpose: Acts as a callback function for the EnumFontFamilies()
  617.            function.
  618.   Returns: 0 if the font enumeration should stop.  1 to ask for the
  619.            next font.
  620.   Comments:
  621.     EnumFontFamilies will find the fonts on the system and call this
  622.     function each time it finds a font.  Pointers to the LOGFONT and
  623.     TEXTMETRIC structures the describe the font are passed as the first
  624.     and second arguments, so we can determine if the fonts we get
  625.     meet the specs we want.  If they do, we can add them to the font
  626.     list box in CDTEST's Font dialog.
  627.     NOTE:
  628.     None of this affects the performance of ChooseFont().  This serves
  629.     only to illustrate how ChooseFont() finds the fonts you request based
  630.     on the flags you pass to the ChooseFont() function.
  631.     The fonts found with this function should be the same as the ones
  632.     found by ChooseFont() for any flag combination.
  633. ************************************************************************/
  634. int CALLBACK EnumFontsProc(LPLOGFONT lplf, LPTEXTMETRIC lptm,
  635.                            DWORD dwStyle, LONG lParam)
  636. {
  637.   UINT i ;
  638.   /* check to see if the font is already there right off the bat
  639.      and just continue the enumeration if it is...        */
  640.   i = SendDlgItemMessage((HWND) lParam, ID_FONTLIST, LB_FINDSTRINGEXACT, (WPARAM) 0,
  641.                          (LONG) (LPTSTR) lplf->lfFaceName) ;
  642.   if (i != LB_ERR)
  643.   {
  644.     if (bScreen)     //if we are adding it for the first time
  645.       return 1 ;
  646.     //else, we are adding printer fonts, so if we find one that is already there
  647.     //it must be available for both the printer and the screen...
  648.     else
  649.     {
  650.       SendDlgItemMessage((HWND) lParam, ID_FONTLIST, LB_SETITEMDATA, i,
  651.                           FONT_TYPE_WYSIWYG) ;
  652.       return 1 ;
  653.     }
  654.   }
  655.   //Get rid of any fonts that we don't want...
  656.   if ((dwFontFlag & CF_TTONLY) && (!(dwStyle & TRUETYPE_FONTTYPE)))
  657.     return 1 ;
  658.   if ((dwFontFlag & CF_SCALABLEONLY) && (dwStyle & RASTER_FONTTYPE))
  659.     return 1 ;
  660.   if ((dwFontFlag & CF_ANSIONLY) && (lplf->lfCharSet != ANSI_CHARSET))
  661.     return 1 ;
  662.   if ((dwFontFlag & CF_FIXEDPITCHONLY) && (lplf->lfPitchAndFamily & VARIABLE_PITCH))
  663.     return 1 ;
  664.   if ((dwFontFlag & CF_NOVECTORFONTS) && (lplf->lfCharSet == OEM_CHARSET))
  665.     return 1 ;
  666.   //if there is a font to be added, add it.
  667.   if (*(lplf->lfFaceName))
  668.     SendDlgItemMessage((HWND) lParam, ID_FONTLIST, LB_ADDSTRING,
  669.                      (WPARAM) 0, (LONG) (LPTSTR) lplf->lfFaceName) ;
  670.   return 1 ;
  671. }
  672. /************************************************************************
  673.   Function: FillFontsBox(HWND, DWORD)
  674.   Purpose: Enumerates all fonts on the system and sends the ones that
  675.            meet the criteria of the dwFlags parameter (CF_SCREENFONTS,
  676.            CF_SCALABLEONLY, etc).
  677.   Returns: Nothing.
  678.   Comments:
  679. ************************************************************************/
  680. void FillFontsBox(HWND hwnd, DWORD dwFlags)
  681. {
  682.   HDC hdc ;
  683.   HWND hwndControl ;
  684.   DWORD dwData ;
  685.   int nItemCount ;
  686.   /* Empty the list box, and turn of the redraw because we may need
  687.      to remove some fonts after they are added if the user calls this
  688.      function with the CF_WYSIWYG flag bit set. */
  689.   SendDlgItemMessage(hwnd, ID_FONTLIST, LB_RESETCONTENT, (WPARAM)0, (LPARAM) 0) ;
  690.   hwndControl = GetDlgItem(hwnd, ID_FONTLIST) ;
  691.   SendMessage(hwndControl, WM_SETREDRAW, FALSE, 0L) ;
  692.   /* Now call EnumFontFamilies() for each type of HDC requested */
  693.   if (dwFlags & CF_SCREENFONTS)
  694.   {
  695.     bScreen = TRUE ;
  696.     hdc = GetHdc(hwnd, HDCSCREEN) ;
  697.     EnumFontFamilies(hdc, (LPTSTR) NULL, (FONTENUMPROC) EnumFontsProc, (LONG) hwnd) ;
  698.     ReleaseDC(hwnd, hdc) ;
  699.   }
  700.   if (dwFlags & CF_PRINTERFONTS)
  701.   {
  702.     bScreen = FALSE ;
  703.     hdc = GetHdc(hwnd, HDCPRINTER) ;
  704.     EnumFontFamilies(hdc, (LPTSTR) NULL, (FONTENUMPROC) EnumFontsProc, (LONG) hwnd) ;
  705.     ReleaseDC(hwnd, hdc) ;
  706.   }
  707.   /* Special case:  If the CF_WYSIWYG flag is used, we have to enumerate
  708.      the fonts in both HDCs and then remove all the ones that are not
  709.      both printer fonts and screen fonts. */
  710.   if (dwFontFlag & CF_WYSIWYG)
  711.   {
  712.     nItemCount = SendDlgItemMessage(hwnd, ID_FONTLIST, LB_GETCOUNT, 0, 0L) ;
  713.     nItemCount-- ;   //the list is zero based
  714.     while (nItemCount >= 0)
  715.     {
  716.       dwData = SendDlgItemMessage(hwnd, ID_FONTLIST, LB_GETITEMDATA, nItemCount, 0L) ;
  717.       if (dwData != FONT_TYPE_WYSIWYG)
  718.       {
  719.         SendDlgItemMessage(hwnd, ID_FONTLIST, LB_DELETESTRING, nItemCount, 0L) ;
  720.       }
  721.       nItemCount-- ;
  722.     }
  723.   }
  724.   /* Now redraw the font list */
  725.   SendMessage(hwndControl, WM_SETREDRAW, TRUE, 0L) ;
  726.   InvalidateRect(hwndControl, NULL, FALSE) ;
  727.   return ;
  728. }
  729. /************************************************************************
  730.   Function: ResetCheckBoxes(HWND)
  731.   Purpose: Checks the checkboxes that control what fonts are listed in
  732.            CDTEST's font list box.
  733.   Returns: Nothing.
  734.   Comments:
  735. ************************************************************************/
  736. void ResetCheckBoxes(HWND hwnd)
  737. {
  738.   SendDlgItemMessage(hwnd, F_TTONLY,          BM_SETCHECK, dwFontFlag & CF_TTONLY         ? 1 : 0, (LPARAM)0) ;
  739.   SendDlgItemMessage(hwnd, F_ANSIONLY,        BM_SETCHECK, dwFontFlag & CF_ANSIONLY       ? 1 : 0, (LPARAM)0) ;
  740.   SendDlgItemMessage(hwnd, F_SCREENFONTS,     BM_SETCHECK, dwFontFlag & CF_SCREENFONTS    ? 1 : 0, (LPARAM)0) ;
  741.   SendDlgItemMessage(hwnd, F_PRINTERFONTS,    BM_SETCHECK, dwFontFlag & CF_PRINTERFONTS   ? 1 : 0, (LPARAM)0) ;
  742.   SendDlgItemMessage(hwnd, F_NOOEMFONTS,      BM_SETCHECK, dwFontFlag & CF_NOOEMFONTS     ? 1 : 0, (LPARAM)0) ;
  743.   SendDlgItemMessage(hwnd, F_NOVECTORFONTS,   BM_SETCHECK, dwFontFlag & CF_NOVECTORFONTS  ? 1 : 0, (LPARAM)0) ;
  744.   SendDlgItemMessage(hwnd, F_SCALABLEONLY,    BM_SETCHECK, dwFontFlag & CF_SCALABLEONLY   ? 1 : 0, (LPARAM)0) ;
  745.   SendDlgItemMessage(hwnd, F_WYSIWYG,         BM_SETCHECK, dwFontFlag & CF_WYSIWYG        ? 1 : 0, (LPARAM)0) ;
  746.   SendDlgItemMessage(hwnd, F_FIXEDPITCHONLY,  BM_SETCHECK, dwFontFlag & CF_FIXEDPITCHONLY ? 1 : 0, (LPARAM)0) ;
  747. }
  748. /************************************************************************
  749.   Function: HandleFontCheckBox(HWND)
  750.   Purpose: If the user clicks one of the fonts in the CDTEST's list of
  751.            valid font types, this function will check the correct boxes
  752.            and set the correct values in the flag which keeps track of
  753.            which fonts are to be enumerated and added to CDTEST's font
  754.            list box.
  755.   Returns: Nothing.
  756.   Comments:
  757.     CF_NOOEMFONTS and CF_NOVECTORFONTS are identical.
  758. ************************************************************************/
  759. void HandleFontCheckBox(HWND hwnd, int nID)
  760. {
  761.   DWORD dwTemp ;
  762.   dwTemp = dwFontFlag ;
  763.   switch (nID)
  764.   {
  765.     case F_TTONLY:
  766.       /* TTONLY is a special case.  If we only want Truetype fonts,
  767.          turn off irrelevant flags */
  768.       if (!(dwFontFlag & CF_TTONLY)) //if we're turning this flag on...
  769.       {
  770.         dwFontFlag = 0L ;  //turn everyone off but the following:
  771.         dwFontFlag |= CF_TTONLY ;
  772.         if (dwTemp & CF_ANSIONLY)
  773.           dwFontFlag |= CF_ANSIONLY ;
  774.         if (dwTemp & CF_FIXEDPITCHONLY)
  775.           dwFontFlag |= CF_FIXEDPITCHONLY ;
  776.         if (dwTemp & CF_SCREENFONTS)
  777.           dwFontFlag |= CF_SCREENFONTS ;
  778.         if (dwTemp & CF_PRINTERFONTS)
  779.           dwFontFlag |= CF_PRINTERFONTS ;
  780.       }
  781.       else
  782.       {
  783.         dwFontFlag ^= CF_TTONLY ;
  784.       }
  785.       break ;
  786.     case F_ANSIONLY:
  787.       dwFontFlag ^= CF_ANSIONLY ;        //otherwise toggle the bit.
  788.       dwFontFlag &= ~CF_WYSIWYG ;
  789.       break ;
  790.     case F_PRINTERFONTS:
  791.       dwFontFlag ^= CF_PRINTERFONTS ;
  792.       break ;
  793.     case F_SCREENFONTS:
  794.       dwFontFlag ^= CF_SCREENFONTS ;
  795.       break ;
  796.     case F_FIXEDPITCHONLY:
  797.       dwFontFlag ^= CF_FIXEDPITCHONLY ;
  798.       break ;
  799.     case F_NOOEMFONTS:
  800.       dwFontFlag ^= CF_NOOEMFONTS ;
  801.       break ;
  802.     case F_NOVECTORFONTS:
  803.       dwFontFlag ^= CF_NOVECTORFONTS ;
  804.       break ;
  805.     case F_SCALABLEONLY:
  806.       dwFontFlag ^= CF_SCALABLEONLY ;
  807.       break ;
  808.     case F_WYSIWYG:                        //We want fonts for both the
  809.                                            //screen and the printer...
  810.       dwFontFlag ^= CF_WYSIWYG ;
  811.       if (dwFontFlag & CF_WYSIWYG)
  812.         dwFontFlag |= (CF_SCREENFONTS | CF_PRINTERFONTS | CF_SCALABLEONLY) ;
  813.       break ;
  814.     default: break ;
  815.   }
  816.   ResetCheckBoxes(hwnd) ;
  817.   FillFontsBox(hwnd, dwFontFlag) ;
  818. }
  819. /************************************************************************
  820.   Function: DoChooseFontStuff(HWND, LPCHOOSEFONT)
  821.   Purpose:
  822.     Calls the ChooseFont() function.
  823.   Returns: Nothing.
  824.   Comments:
  825. ************************************************************************/
  826. void DoChooseFontStuff(HWND hwnd, LPCHOOSEFONT pcf)
  827. {
  828.   BOOL bRet = FALSE ;
  829.   if (IsDlgButtonChecked(hwnd, ID_PRELOADEDFONT) == 1)
  830.   {
  831.     pcf->hInstance = GetFontDlgHandle() ;
  832.     wsprintf(szTemp, szLongFilter, pcf->hInstance) ;
  833.     SetDlgItemText(hwnd, ID_HINSTANCEF, szTemp) ;
  834.   }
  835.   pcf->hDC = GetHdc(hwnd, nHdcType) ;
  836.   wsprintf(szTemp, szLongFilter, pcf->hDC) ;
  837.   SetDlgItemText(hwnd, ID_HDCF, szTemp) ;
  838.   GetFontDlg(hwnd, pcf) ;
  839.   if (IsDlgButtonChecked(hwnd, ID_NULLSTRUCTFONT) == 1)
  840.     bRet = ChooseFont((LPCHOOSEFONT)NULL) ;
  841.   else
  842.     bRet = ChooseFont(pcf) ;
  843.   wsprintf(szTemp, szLongFilter, CommDlgExtendedError()) ;
  844.   SetDlgItemText(hwnd, ID_ERRORF, szTemp) ;
  845.   if (pcf->hDC)
  846.   {
  847.     ReleaseDC(hwnd, pcf->hDC) ;   //free the HDC that we used if we called
  848.     pcf->hDC = (HDC) 0 ;          //the function with a valid HDC.
  849.   }
  850.   if (hDialogFont)
  851.   {
  852.     FreeResource(hDialogFont) ;
  853.     hDialogFont = (HANDLE) 0 ;
  854.     hResFont = (HANDLE) 0 ;
  855.   }
  856.   wsprintf(szTemp, szShortFilter, bRet) ;     //fill results into the Font dlg
  857.   SetDlgItemText(hwnd, ID_RETURNF, szTemp) ;
  858.   FillFontDlg(hwnd, pcf) ;
  859. }
  860. /************************************************************************
  861.   Function: FontThreadProc1(LPDWORD)
  862.   Purpose:
  863.     Acts as the starting address for thread 1
  864.   Returns: Any DWORD value.
  865.   Comments:
  866. ************************************************************************/
  867. DWORD FontThreadProc1(LPDWORD pdw)
  868. {
  869.   DoChooseFontStuff(hwndMainFont, &cfThread1) ;
  870.   PostMessage(hwndMainFont, UMSG_DECREMENTDLGCOUNT, 0, 0L ) ;
  871.   return 0L ;
  872. }
  873. /************************************************************************
  874.   Function: FontThreadProc2(LPDWORD)
  875.   Purpose:
  876.     Acts as the starting address for thread 2
  877.   Returns: Any DWORD value.
  878.   Comments:
  879. ************************************************************************/
  880. DWORD FontThreadProc2(LPDWORD pdw)
  881. {
  882.   DoChooseFontStuff(hwndMainFont, &cfThread2) ;
  883.   PostMessage(hwndMainFont, UMSG_DECREMENTDLGCOUNT, 0, 0L ) ;
  884.   return 0L ;
  885. }
  886. /************************************************************************
  887.   Function: MultiThreadFontDlg(void)
  888.   Purpose:
  889.     Create the two threads that will in turn create two ChooseFont()
  890.     dialogs.
  891.   Returns: Nothing.
  892.   Comments:
  893.     Multithreading note:
  894.     This function will return before the common dialog functions return.
  895.     Therefore, do not pass any parameters to this function that will be
  896.     referenced by the common dialogs because as soon as this function
  897.     ends those parameters will be gone.
  898. ************************************************************************/
  899. void MultiThreadFontDlg(void)
  900. {
  901.   dwFontThreadParm1 = dwFontThreadParm2 = 0L ;
  902.   if (!(hFontThread1 = CreateThread((LPSECURITY_ATTRIBUTES) NULL, 0,
  903.                                      (LPTHREAD_START_ROUTINE) FontThreadProc1,
  904.                                      &dwFontThreadParm1, CREATE_SUSPENDED, &dwFontThreadID1)))
  905.   {
  906.     MessageBox(GetForegroundWindow(), TEXT("Error creating thread 1"), NULL,
  907.                MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL) ;
  908.     nOpenFontDialogCount = 0 ;
  909.     EnableFontButtons(hwndMainFont, TRUE) ;
  910.     return ;
  911.   }
  912.   if (!(hFontThread2 = CreateThread((LPSECURITY_ATTRIBUTES) NULL, 0,
  913.                                      (LPTHREAD_START_ROUTINE) FontThreadProc2,
  914.                                      &dwFontThreadParm2, CREATE_SUSPENDED, &dwFontThreadID2)))
  915.   {
  916.     MessageBox(GetForegroundWindow(), TEXT("Error creating thread 2"), NULL,
  917.                MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL) ;
  918.     nOpenFontDialogCount = 0 ;
  919.     EnableFontButtons(hwndMainFont, TRUE) ;
  920.     return ;
  921.   }
  922.   ResumeThread(hFontThread1) ;
  923.   ResumeThread(hFontThread2) ;
  924.   return ;
  925. }
  926. /************************************************************************
  927.   Function: EnableFontButtons(HWND, BOOL)
  928.   Purpose:
  929.     Enables or disables CDTEST's font dialogs buttons based on the
  930.     status of the second parameter.
  931.   Returns: Nothing.
  932.   Comments:
  933.     This is necessary when multithreading in the case of this application.
  934. ************************************************************************/
  935. void EnableFontButtons(HWND hwnd, BOOL bEnable)
  936. {
  937.   EnableWindow(GetDlgItem(hwnd, IDOK), bEnable) ;
  938.   EnableWindow(GetDlgItem(hwnd, IDCANCEL), bEnable) ;
  939.   EnableWindow(GetDlgItem(hwnd, ID_RESETFONT), bEnable) ;
  940.   EnableWindow(GetDlgItem(hwnd, ID_MULTITHREADFONT), bEnable) ;
  941.   EnableWindow(GetDlgItem(hwnd, ID_EDITLOGFONT), bEnable) ;
  942. }