home *** CD-ROM | disk | FTP | other *** search
/ C Programming Starter Kit 2.0 / SamsPublishing-CProgrammingStarterKit-v2.0-Win31.iso / bc45 / truetype.pak / TRUETYPE.C < prev    next >
C/C++ Source or Header  |  1997-07-23  |  25KB  |  724 lines

  1.  // Borland C++ - (C) Copyright 1991, 1992 by Borland International
  2.  
  3. /*******************************************************************
  4.  
  5.     program - TrueType.c
  6.     purpose - a Windows program to demo True Type fonts.
  7.  
  8.  
  9.     This program shows off two features of Windows 3.1: True Type
  10. fonts, and common dialogs.
  11.  
  12.     True Type fonts are scalable fonts supplied by the system.  This
  13. program demonstrates resizing and rotation of True Type characters
  14. within a window, and allows the user to select the True Type font to
  15. be used.
  16.  
  17.     The dialog used in selecting the font is a Windows 3.1 "common
  18. dialog."  By including commdlg.h, a series of common dialogs becomes
  19. available to the program.  To invoke the font dialog, a CHOOSEFONTS
  20. structure is filled out, and ChooseFont() is called.  This system
  21. routine handles all the dialog processing needed to select a font via
  22. a dialog box.
  23.  
  24.     In contrast, the About Box dialog herein is programmed in the
  25. normal manner.  A dialog process is provided, and a thunk for it is
  26. created explicitly; Windows provides no automated handling for this
  27. program-specific dialog.
  28.  
  29.     Change font attributes through the menu selections.  Resize the
  30. window to see the text resized; the text "fan" will always reach the
  31. bottom and the right side of the window.
  32.  
  33. *******************************************************************/
  34.  
  35. #define STRICT
  36.  
  37. #include <windows.h>
  38. #pragma hdrstop
  39. #include <string.h>
  40. #include <stdlib.h>
  41. #include <math.h>
  42. #include <commdlg.h>
  43. #include <windowsx.h>
  44.  
  45. #include "TrueType.h"
  46.  
  47.  
  48. // data initialized by first instance
  49. typedef struct tagSETUPDATA
  50.     {
  51.         char   szAppName[10]; // name of application
  52.     } SETUPDATA;
  53.  
  54. SETUPDATA SetUpData;
  55.  
  56.  
  57. // Data that can be referenced throughout the
  58. // program but not passed to other instances
  59.  
  60. HINSTANCE hInst;                        // hInstance of application
  61. HWND      hwnd;                         // hWnd of main window
  62.  
  63. HANDLE    hdlg;                         // handle of dialog resource
  64.  
  65. DLGPROC   lpDlgProc;                    // ptr to proc for dialog box
  66. HWND      hDlgBox;                      // handle of dialog box
  67.  
  68. LOGFONT   MainFontRec;                  // logical font records,...
  69. LOGFONT   CornerFontRec;                // ...which store font data...
  70. LOGFONT   BorlandFontRec;               // ...for different fonts.
  71.  
  72. COLORREF  FanColor[10];                 // color array for "fan" of text
  73.  
  74. BOOL      ShadowAll;                    // TRUE iff fan text gets shadows
  75. BOOL      ShowAlignmentMarks;           // TRUE iff we show baselines of fan
  76.  
  77. #define ROUND(x)  (floor(x + .5))
  78. #define SQR(x)    (pow(x,2))
  79.  
  80. #define TITLE_LENGTH 30
  81.  
  82. LPCSTR ArcText = "TrueType";            // text seen along arc of fan
  83. const char* FanText = "Borland C++ for Windows";    // text for leaves of fan
  84. const char* BorlandText = "Borland";    // text for lower right window corner
  85. const int   Radius = 100;               // radius of fan "hub"
  86. const float Deg2Rad = M_PI / 18;        // conversion factor, degrees->radians
  87.  
  88. // function prototypes
  89.  
  90. int PASCAL      WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  91.                         LPSTR lpszCmdLine, int cmdShow);
  92.  
  93. void            Init(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  94.                         LPSTR lpszCmdLine, int cmdShow);
  95. void            InitFirst(HINSTANCE hInstance);
  96. void            InitEvery(HINSTANCE hInstance, int cmdShow);
  97.  
  98. LRESULT CALLBACK _export WndProc(HWND hWnd, UINT message,
  99.                          WPARAM wParam, LPARAM lParam);
  100.  
  101. BOOL CALLBACK  _export DlgBoxProc(HWND hDlg, UINT message,
  102.                            WPARAM wParam, LPARAM lParam);
  103.  
  104. void wmCreate(void);
  105. void cmAbout(void);
  106. void cmAlignmentMarks(void);
  107. void cmFonts(HWND);
  108. void cmShadows(void);
  109. void DoPaint(void);
  110. void cm(void);
  111.  
  112. //*******************************************************************
  113. // WinMain - TrueType main
  114. //
  115. // parameters:
  116. //             hInstance     - The instance of this instance of this
  117. //                             application.
  118. //             hPrevInstance - The instance of the previous instance
  119. //                             of this application. This will be 0
  120. //                             if this is the first instance.
  121. //             lpszCmdLine   - A long pointer to the command line that
  122. //                             started this application.
  123. //             cmdShow       - Indicates how the window is to be shown
  124. //                             initially. ie. SW_SHOWNORMAL, SW_HIDE,
  125. //                             SW_MIMIMIZE.
  126. //
  127. // returns:
  128. //             wParam from last message.
  129. //
  130. //*******************************************************************
  131. int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  132.                    LPSTR lpszCmdLine, int cmdShow)
  133. {
  134.     MSG msg;
  135.  
  136.     // Go init this application.
  137.     Init(hInstance, hPrevInstance, lpszCmdLine, cmdShow);
  138.  
  139.     // Get and dispatch messages for this applicaton.
  140.     while (GetMessage(&msg, NULL, 0, 0))
  141.     {
  142.         TranslateMessage(&msg);
  143.         DispatchMessage(&msg);
  144.     }  // while
  145.  
  146.     return(msg.wParam);
  147. }  // end of WinMain()
  148.  
  149. #if !defined(__WIN32__)
  150. //*******************************************************************
  151. // InitAdded - done only for added instances of TrueType demo
  152. //
  153. // parameters:
  154. //             hPrevInstance - The instance of the previous instance
  155. //                             of this application.
  156. //
  157. //*******************************************************************
  158. #pragma argsused
  159. void InitAdded(HINSTANCE hPrevInstance)
  160. {
  161.     // get the results of the initialization of first instance
  162.     GetInstanceData(hPrevInstance, (BYTE*) &SetUpData, sizeof(SETUPDATA));
  163. }  // end of InitAdded()
  164. #endif
  165.  
  166. //*******************************************************************
  167. // Init - init the TrueType demo application
  168. //
  169. // parameters:
  170. //             hInstance     - The instance of this instance of this
  171. //                             application.
  172. //             hPrevInstance - The instance of the previous instance
  173. //                             of this application. This will be 0
  174. //                             if this is the first instance.
  175. //             lpszCmdLine   - A long pointer to the command line that
  176. //                             started this application.
  177. //             cmdShow       - Indicates how the window is to be shown
  178. //                             initially. ie. SW_SHOWNORMAL, SW_HIDE,
  179. //                             SW_MIMIMIZE.
  180. //
  181. //*******************************************************************
  182. #pragma argsused
  183. void Init(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  184.              LPSTR lpszCmdLine, int cmdShow)
  185. {
  186.  
  187.   #if defined(__WIN32__)
  188.     InitFirst(hInstance);
  189.  
  190.   #else
  191.     if (!hPrevInstance)         // if no prev instance, this is first
  192.         InitFirst(hInstance);
  193.     else                        // this is not first instance
  194.         InitAdded(hPrevInstance);
  195.   #endif
  196.  
  197.     InitEvery(hInstance, cmdShow);       // init for all instances
  198. }  // end of Init()
  199.  
  200.  
  201. //*******************************************************************
  202. // InitFirst - done only for first instance of TrueType demo
  203. //
  204. // parameters:
  205. //             hInstance     - The instance of this instance of this
  206. //                             application.
  207. //
  208. //*******************************************************************
  209. void InitFirst(HINSTANCE hInstance)
  210. {
  211.     WNDCLASS wcTTFClass;
  212.  
  213.     // Get string from resource with application name.
  214.     LoadString(hInstance, IDS_NAME, (LPSTR) SetUpData.szAppName, 10);
  215.  
  216.     // Define the window class for this application.
  217.     wcTTFClass.style         = CS_HREDRAW | CS_VREDRAW;
  218.     wcTTFClass.lpfnWndProc   = WndProc;
  219.     wcTTFClass.cbClsExtra    = 0;
  220.     wcTTFClass.cbWndExtra    = 0;
  221.     wcTTFClass.hInstance     = hInstance;
  222.     wcTTFClass.hIcon         = LoadIcon(hInstance, SetUpData.szAppName);
  223.     wcTTFClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
  224.     wcTTFClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
  225.     wcTTFClass.lpszClassName = SetUpData.szAppName;
  226.     wcTTFClass.lpszMenuName  = SetUpData.szAppName;
  227.  
  228.     // Register the class
  229.     RegisterClass(&wcTTFClass);
  230. }  // end of InitFirst()
  231.  
  232.  
  233. //*******************************************************************
  234. // InitEvery - done for every instance of TrueType demo program
  235. //
  236. // parameters:
  237. //             hInstance     - The instance of this instance of this
  238. //                             application.
  239. //             cmdShow       - Indicates how the window is to be shown
  240. //                             initially. ie. SW_SHOWNORMAL, SW_HIDE,
  241. //                             SW_MIMIMIZE.
  242. //
  243. //*******************************************************************
  244. #pragma argsused
  245. void InitEvery(HINSTANCE hInstance, int cmdShow)
  246. {
  247.     char title[TITLE_LENGTH+1];
  248.  
  249.     hInst = hInstance;       // save for use by window procs
  250.  
  251.     // fetch in the window title from the stringtable resource
  252.     LoadString(hInstance, IDS_TITLE, (LPSTR)title, TITLE_LENGTH);
  253.  
  254.     // Create applications main window.
  255.     hwnd = CreateWindow(SetUpData.szAppName,    // window class name
  256.                         (LPSTR)title,           // window title
  257.                         WS_OVERLAPPEDWINDOW,    // window style
  258.                         CW_USEDEFAULT,          // x etc.: use defaults
  259.                         CW_USEDEFAULT,          // y
  260.                         CW_USEDEFAULT,          // cx
  261.                         CW_USEDEFAULT,          // cy
  262.                         NULL,                   // no parent for this window
  263.                         NULL,                   // use the class menu
  264.                         hInstance,              // who created this window
  265.                         NULL                    // no parms to pass on
  266.                         );
  267.     ShowWindow(hwnd, cmdShow);
  268.     UpdateWindow(hwnd);
  269. } // end of InitEvery()
  270.  
  271.  
  272. //*******************************************************************
  273. // WndProc - handles messages for this application
  274. //
  275. // parameters:
  276. //             hWnd          - The window handle for this message
  277. //             message       - The message number
  278. //             wParam        - The WPARAM parameter for this message
  279. //             lParam        - The LPARAM parameter for this message
  280. //
  281. // returns:
  282. //             depends on message.
  283. //
  284. //*******************************************************************
  285. LRESULT CALLBACK _export WndProc(HWND hWnd, UINT message,
  286.                          WPARAM wParam, LPARAM lParam)
  287. {
  288.     switch (message)
  289.     {
  290.   case WM_CREATE:
  291.             wmCreate();
  292.             break;
  293.  
  294.   case WM_COMMAND:
  295.       switch (GET_WM_COMMAND_ID(wParam, lParam))
  296.       {
  297.     case CM_ABOUT:
  298.         cmAbout();
  299.         break;
  300.  
  301.     case CM_EXIT:
  302.         // Tell windows to destroy our window.
  303.         DestroyWindow(hWnd);
  304.         break;
  305.  
  306.     case CM_ALIGNMENTMARKS:
  307.         cmAlignmentMarks();
  308.         break;
  309.  
  310.     case CM_FONTS:
  311.         cmFonts(hWnd);
  312.         break;
  313.  
  314.     case CM_SHADOWS:
  315.         cmShadows();
  316.         break;
  317.  
  318.     default:
  319.         break;
  320.  
  321.       } // switch wParam
  322.       break;
  323.  
  324.   case WM_PAINT:
  325.       DoPaint();
  326.       break;
  327.  
  328.   case WM_GETMINMAXINFO:
  329.       // Limit the minimum size of the window to 300x300,
  330.       // so the fonts don't get too small
  331.       ((POINT far *)lParam)[3].x = 300;
  332.       ((POINT far *)lParam)[3].y = 300;
  333.       break;
  334.  
  335.   case WM_DESTROY:
  336.       // This is the end if we were closed by a DestroyWindow call.
  337.       PostQuitMessage(0);
  338.       break;
  339.  
  340.   default:
  341.       return(DefWindowProc(hWnd, message, wParam, lParam));
  342.     }  // switch message
  343.  
  344.     return(0L);
  345. }  // end of WndProc()
  346.  
  347.  
  348. //*******************************************************************
  349. // DlgBoxProc - handle dialog messages
  350. //
  351. // parameters:
  352. //             hDlg          - The window handle for this message
  353. //             message       - The message number
  354. //             wParam        - The WPARAM parameter for this message
  355. //             lParam        - The LPARAM parameter for this message
  356. //
  357. //*******************************************************************
  358. #pragma argsused
  359. BOOL CALLBACK _export DlgBoxProc(HWND hDlg, UINT message,
  360.          WPARAM wParam, LPARAM lParam)
  361. {
  362.  
  363.     switch (message)
  364.     {
  365.   case WM_SYSCOMMAND:
  366.       // Pass WM_SYSCOMMAND messages on to main window so both
  367.       // main window and dialog box get iconized, minimized etc.
  368.       // in parallel.
  369.       SendMessage(hwnd, message, wParam, lParam);
  370.       break;
  371.  
  372.   case WM_COMMAND:
  373.       // regardless of the command (only ID_OK should arrive)
  374.       // we want to exit the dialog
  375.       EndDialog(hDlg, TRUE);
  376.       break;
  377.  
  378.   default:
  379.       return FALSE;
  380.     }  // switch
  381.  
  382.     return(TRUE);
  383. }  // end of DlgBoxProc()
  384.  
  385.  
  386. static void
  387. MeasureText (HDC hDC, const char *str, SIZE *size)
  388. {
  389.   #if defined(__WIN32__)
  390.     GetTextExtentPoint(hDC, str, strlen(str), size);
  391.   #else
  392.     DWORD  d = GetTextExtent(hDC, str, strlen(str));
  393.  
  394.     size->cx = LOWORD(d);
  395.     size->cy = HIWORD(d);
  396.   #endif
  397. }
  398.  
  399. //*************************************************************************
  400. // DoPaint -- this is the WM_PAINT action routine for the main window.
  401. // It places the TrueType logo in the upper left corner of the window, draws
  402. // a "fan hub" around it, and draws "fan leaves" of text out from the hub.
  403. // These leaves are scaled to reach the bottom and the right edge of the
  404. // window, by defining an ellipse centered on the TrueType logo which just
  405. // touches those two edges.  The text strings span the distance from the
  406. // hub to the ellipse along radial lines, and are both scaled and rotated.
  407. //     Depending on user-set state variables, the ellipse and baselines
  408. // for the text fan may be shown (ShowAlignmentMarks), and/or the text may
  409. // be shadowed (ShadowAll).  Other attributes, such as bolding or
  410. // italicization, may be selected from the font dialog box.
  411. //*************************************************************************
  412. void DoPaint()
  413. {
  414.     PAINTSTRUCT       PaintInfo;
  415.     HDC               hDC;
  416.     LOGFONT           FontRec;
  417.     UINT              FmSize;
  418.     OUTLINETEXTMETRIC *FontMetric;
  419.     int               FontHeight, x, y, j, k;
  420.     UINT              BaseWidth, DesiredExtent;
  421.     float             Theta;
  422.     LPCSTR            P;
  423.     RECT              R;
  424.     int               d;
  425.     SIZE              size;
  426.   #if defined(__WIN32__)
  427.     POINT             point;
  428.   #endif
  429.     UINT              FanTextLen = strlen(FanText);
  430.  
  431.     BeginPaint(hwnd, &PaintInfo);
  432.  
  433.     hDC = PaintInfo.hdc;
  434.     P = ArcText;
  435.  
  436.     // save device context; easiest way to preserve current state
  437.     SaveDC(hDC);
  438.  
  439.     // set initial font data (for TrueType logo)
  440.     FontRec = CornerFontRec;
  441.     SetBkMode(hDC, TRANSPARENT);
  442.     SetTextColor(hDC, RGB(128,128,128));
  443.     FontRec.lfHeight = FontRec.lfHeight * 2;
  444.     FontRec.lfWidth = floor(FontRec.lfWidth * 2.1);
  445.  
  446.     // create the TrueType logo
  447.     SelectObject(hDC, CreateFontIndirect(&FontRec));
  448.     TextOut(hDC, 18, 5, "T", 1);
  449.     SetTextColor(hDC, RGB(0,0,0));
  450.     TextOut(hDC, 32, 13,"T", 1);
  451.  
  452.     // determine window dimensions & set up fan text parameters
  453.     GetClientRect(hwnd, &R);
  454.     FontRec = MainFontRec;
  455.     DeleteObject(SelectObject(hDC, CreateFontIndirect(&FontRec)));
  456.  
  457.     FmSize = GetOutlineTextMetrics(hDC, 0, 0);
  458.     FontMetric = (OUTLINETEXTMETRIC*)malloc(FmSize);
  459.     FontMetric->otmpFamilyName = 0;
  460.     FontMetric->otmpFaceName = 0;
  461.     FontMetric->otmpStyleName = 0;
  462.     FontMetric->otmpFullName = 0;
  463.  
  464.     GetOutlineTextMetrics(hDC, FmSize, FontMetric);
  465.     FontHeight = FontMetric->otmTextMetrics.tmHeight;
  466.   #if defined(__WIN32__)
  467.     SetViewportOrgEx(hDC, FontHeight+2, 0, &point);
  468.   #else
  469.     SetViewportOrg(hDC, FontHeight+2, 0);
  470.   #endif
  471.     MeasureText(hDC, FanText, &size);
  472.     BaseWidth = size.cx;
  473.     R.right -= FontHeight+2;
  474.  
  475.     // get a "black brush" for drawing operations
  476.     SelectObject(hDC, GetStockObject(NULL_BRUSH));
  477.  
  478.     // if we want to show the alignment marks, draw the bounding ellipse
  479.     if (ShowAlignmentMarks)
  480.     {
  481.         Ellipse(hDC, -R.right, -R.bottom, R.right, R.bottom);
  482.     }
  483.  
  484.     // draw the "hub" of the fan
  485.     Ellipse(hDC, -(Radius-5), -(Radius-5), (Radius-5), Radius-5);
  486.     Ellipse(hDC, -(Radius-10), -(Radius-10), (Radius-10), Radius-10);
  487.  
  488.     SetTextColor(hDC, FanColor[0]);
  489.  
  490.     // loop over the "fan leaves"
  491.     for ( d = 27; d <= 36; d++)
  492.     {
  493.         x = ROUND(Radius * cos(d * Deg2Rad));
  494.         y = ROUND(Radius * sin(-d * Deg2Rad)); // -d because y axis is inverted
  495.  
  496.         Theta = -d * Deg2Rad;
  497.         if (x)
  498.         {
  499.             Theta = atan((R.right / (R.bottom * 1.0)) * (y / (x * 1.0)));
  500.         }
  501.  
  502.         j = ROUND(R.right * cos(Theta));
  503.         k = ROUND(R.bottom * sin(Theta));
  504.  
  505.         if (ShowAlignmentMarks)
  506.         {
  507.           #if defined(__WIN32__)
  508.             MoveToEx(hDC, x,y, &point);
  509.           #else
  510.             MoveTo(hDC, x, y);
  511.           #endif
  512.             LineTo(hDC, j,k);
  513.         }
  514.  
  515.         DesiredExtent = ROUND(sqrt(SQR(x*1.0 - j) + SQR(y*1.0 - k))) - 5;
  516.         FontRec = MainFontRec;
  517.         FontRec.lfEscapement = d * 100;
  518.         FontRec.lfWidth = floor((FontMetric->otmTextMetrics.tmAveCharWidth) *
  519.                                 (DesiredExtent / (BaseWidth * 1.0)));
  520.         DeleteObject(SelectObject(hDC, CreateFontIndirect(&FontRec)));
  521.         MeasureText(hDC, FanText, &size);
  522.  
  523.         for ( ;(size.cx > DesiredExtent) && (FontRec.lfWidth);
  524.              FontRec.lfWidth-- )
  525.         {
  526.             // Shave off some character width until the string fits
  527.             DeleteObject(SelectObject(hDC, CreateFontIndirect(&FontRec)));
  528.             MeasureText(hDC, FanText, &size);
  529.         }
  530.  
  531.         // Expand the string if necessary to make it fit the desired extent
  532.         if (size.cx < DesiredExtent)
  533.           { SetTextJustification(hDC,DesiredExtent - size.cx, 3); }
  534.         if (ShadowAll)
  535.         {
  536.             SetTextColor(hDC, RGB(0,0,0));
  537.             TextOut(hDC, x+2, y+1, FanText, FanTextLen);
  538.         }
  539.         SetTextColor(hDC, FanColor[d - 27]);
  540.         TextOut(hDC, x, y, FanText, FanTextLen);
  541.         // clear justifier's internal error accumulator
  542.         SetTextJustification(hDC,0,0);
  543.  
  544.         if (P[0])
  545.         {
  546.             FontRec = CornerFontRec;
  547.             FontRec.lfEscapement = (d+10) * 100;
  548.             FontRec.lfWidth = 0;
  549.             DeleteObject(SelectObject(hDC, CreateFontIndirect(&FontRec)));
  550.             SetTextColor(hDC, 0);
  551.             x = floor((Radius - FontHeight - 5) * cos(d * Deg2Rad));
  552.             y = floor((Radius - FontHeight - 5) * sin(-d * Deg2Rad));
  553.             TextOut(hDC, x, y, P, 1);
  554.             P++;
  555.         } // if
  556.     } // for d
  557.  
  558.     free(FontMetric);
  559.  
  560.     // lose the fan font, selecting in the Borland text font
  561.     DeleteObject(SelectObject(hDC, CreateFontIndirect(&BorlandFontRec)));
  562.     MeasureText(hDC, BorlandText, &size);
  563.     SetTextColor(hDC, RGB(0,0,0));
  564.     // write the Borland text in the lower right corner, with a shadow effect
  565.     TextOut(hDC, R.right - size.cx, R.bottom - size.cy, BorlandText,
  566.             strlen(BorlandText));
  567.     SetTextColor(hDC, RGB(255,0,0));
  568.     TextOut(hDC, R.right - size.cx - 5, R.bottom - size.cy, BorlandText,
  569.             strlen(BorlandText));
  570.  
  571.     DeleteObject(SelectObject(hDC, GetStockObject(SYSTEM_FONT)));
  572.     // restore the saved DC; easiest way to reset to entry state
  573.     RestoreDC(hDC, -1);
  574.     EndPaint(hwnd, &PaintInfo);
  575. } // end of DoPaint()
  576.  
  577.  
  578. //*************************************************************************
  579. // wmCreate -- action routine for the WM_CREATE message.  This routine
  580. // sets up font record data and colors for use in the painting routines,
  581. // and creates a thunk for the dialog process
  582. //*************************************************************************
  583. void wmCreate(void)
  584. {
  585.     // create the font data for the main font
  586.     MainFontRec.lfHeight = 26;
  587.     MainFontRec.lfWidth = 10;
  588.     MainFontRec.lfEscapement = 0;
  589.     MainFontRec.lfOrientation = 0;
  590.     MainFontRec.lfWeight = FW_BOLD;
  591.     MainFontRec.lfItalic = 0;
  592.     MainFontRec.lfUnderline = 0;
  593.     MainFontRec.lfStrikeOut = 0;
  594.     MainFontRec.lfCharSet = ANSI_CHARSET;
  595.     MainFontRec.lfOutPrecision = OUT_DEFAULT_PRECIS;
  596.     MainFontRec.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  597.     MainFontRec.lfQuality = PROOF_QUALITY;
  598.     MainFontRec.lfPitchAndFamily = VARIABLE_PITCH | FF_ROMAN;
  599.     strcpy(MainFontRec.lfFaceName,"Times New Roman");
  600.  
  601.     // structure copy (!) into corner font
  602.     CornerFontRec = MainFontRec;
  603.  
  604.     // copy again inot Borland font, but switch to Arial typeface, new size
  605.     BorlandFontRec  = MainFontRec;
  606.     BorlandFontRec.lfHeight = 60;
  607.     BorlandFontRec.lfWidth = 0;   // choose best width for this height
  608.     BorlandFontRec.lfWeight = 900;
  609.     strcpy(BorlandFontRec.lfFaceName, "Arial");
  610.  
  611.     // Array of colors used to color the fan text
  612.     FanColor[0] = RGB(255,0,0);
  613.     FanColor[1] = RGB(128,0,0);
  614.     FanColor[2] = RGB(255,128,0);
  615.     FanColor[3] = RGB(80,80,0);
  616.     FanColor[4] = RGB(80,255,0);
  617.     FanColor[5] = RGB(0,128,0);
  618.     FanColor[6] = RGB(0,128,255);
  619.     FanColor[7] = RGB(0,0,255);
  620.     FanColor[8] = RGB(128,128,128);
  621.     FanColor[9] = RGB(255,0,0);
  622.  
  623.     ShadowAll = 0;
  624.     ShowAlignmentMarks = 0;
  625. } // end of wmCreate()
  626.  
  627.  
  628. /*********************************************************************
  629.  cmXxxx routines -- these are action routines for menu commands
  630. *********************************************************************/
  631.  
  632.  
  633. //*************************************************************************
  634. // cmShadows -- toggle the ShadowsAll flag, and set the menu checkmark
  635. // as appropriate
  636. //*************************************************************************
  637. void cmShadows(void)
  638. {
  639.     ShadowAll = !ShadowAll;
  640.     if (ShadowAll)
  641.     {
  642.         CheckMenuItem(GetMenu(hwnd), CM_SHADOWS, MF_BYCOMMAND | MF_CHECKED);
  643.     }
  644.     else
  645.     {
  646.         CheckMenuItem(GetMenu(hwnd), CM_SHADOWS,
  647.                       MF_BYCOMMAND | MF_UNCHECKED);
  648.     }
  649.  
  650.     // Erase if going Shadow -> no Shadow
  651.     InvalidateRect(hwnd, NULL, !ShadowAll);
  652. }  // end of cmShadows()
  653.  
  654.  
  655. //*************************************************************************
  656. // cmAlignmentMarks -- toggle the state of ShowAlignmentMarks, and toggle
  657. // the checkmark in the menu to match
  658. //*************************************************************************
  659. void cmAlignmentMarks(void)
  660. {
  661.     ShowAlignmentMarks = !ShowAlignmentMarks;
  662.     if (ShowAlignmentMarks)
  663.     {
  664.         CheckMenuItem(GetMenu(hwnd), CM_ALIGNMENTMARKS,
  665.                       MF_BYCOMMAND | MF_CHECKED);
  666.     }
  667.     else
  668.     {
  669.         CheckMenuItem(GetMenu(hwnd), CM_ALIGNMENTMARKS,
  670.                       MF_BYCOMMAND | MF_UNCHECKED);
  671.     }
  672.  
  673.     // Erase if going Marks -> no Marks
  674.     InvalidateRect(hwnd, NULL, !ShowAlignmentMarks);
  675. }  // end of cmAlignmentMarks()
  676.  
  677.  
  678. //*************************************************************************
  679. // cmAbout -- invoke the "About" dialog.  Its return code is ignored, since
  680. // the About dialog doesn't return anything to the program.
  681. //*************************************************************************
  682. #pragma warn -eff
  683. void cmAbout(void)
  684. {
  685.     lpDlgProc = (DLGPROC) MakeProcInstance( (FARPROC) DlgBoxProc, hInst);
  686.     DialogBox(hInst, "About", hwnd, lpDlgProc);
  687.     FreeProcInstance ( (FARPROC) lpDlgProc );
  688. }  // end of cmAbout()
  689. #pragma warn .eff
  690.  
  691.  
  692. //*************************************************************************
  693. // cmFonts -- use the Choose Fonts common dialog to get a new font spec
  694. // from the user.  To do this, we fill out a CHOOSEFONTS structure and
  695. // pass it to the ChooseFonts routine.  Windows 3.1 takes care of the rest!
  696. //*************************************************************************
  697. void cmFonts(HWND hWnd)
  698. {
  699.     CHOOSEFONT CF;
  700.     LOGFONT FontRec = MainFontRec;
  701.  
  702.     CF.lStructSize    = sizeof(CF);
  703.     CF.hwndOwner      = hWnd;
  704.     CF.Flags          = CF_ANSIONLY | CF_TTONLY | CF_SCREENFONTS |
  705.       CF_INITTOLOGFONTSTRUCT | CF_ENABLETEMPLATE;
  706.     CF.nFontType      = SCREEN_FONTTYPE;
  707.     CF.lpLogFont      = &FontRec;
  708.     CF.nSizeMin       = 20;
  709.     CF.nSizeMax       = 20;
  710.     CF.lpTemplateName = "FontDlg";
  711.     CF.hInstance      = hInst;
  712.  
  713.     if (ChooseFont(&CF))
  714.     {
  715.         // Only get the font name, weight, and italics;
  716.   // we don't care about size
  717.         strcpy(MainFontRec.lfFaceName, FontRec.lfFaceName);
  718.         MainFontRec.lfWeight = FontRec.lfWeight;
  719.         MainFontRec.lfItalic = FontRec.lfItalic;
  720.         InvalidateRect(hwnd, NULL, TRUE);
  721.     }
  722. }  // end of cmFonts()
  723.  
  724.