home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / graphics / gdi / textfx / textfx.c < prev    next >
C/C++ Source or Header  |  1997-10-05  |  24KB  |  618 lines

  1. /*****************************************************************************\
  2. *       This is a part of the Microsoft Source Code Samples.
  3. *       Copyright (C) 1992-1997 Microsoft Corporation.
  4. *       All rights reserved.
  5. *       This source code is only intended as a supplement to
  6. *       Microsoft Development Tools and/or WinHelp documentation.
  7. *       See these sources for detailed information regarding the
  8. *       Microsoft samples programs.
  9. \*****************************************************************************/
  10. /*****************************************************************************
  11.  *                                                                             *
  12.  *   PROGRAM: TextFX.c                                                         *
  13.  *                                                                             *
  14.  *   PURPOSE: TextFX template for Windows applications                         *
  15.  *                                                                             *
  16.  *   FUNCTIONS:                                                                 *
  17.  *                                                                             *
  18.  *   GetLastErrorBox() - Report GetLastError() values as text                *
  19.  *   WinMain() - calls initialization function, processes message loop         *
  20.  *   InitApplication() - initializes window data and registers window         *
  21.  *   InitInstance() - saves instance handle and creates main window             *
  22.  *   WndProc() - processes messages                                             *
  23.  *   CenterWindow() - used to center the "About" box over application window *
  24.  *   About() - processes messages for "About" dialog box                     *
  25.  *                                                                             *
  26.  *   COMMENTS:                                                                 *
  27.  *****************************************************************************/
  28.  
  29. #include <windows.h>   // required for all Windows applications
  30. #include "resource.h"  // specific to this program
  31. #include <time.h>
  32. #include "textfx.h"    // specific to this program
  33. #include "guide.h"
  34. #include "fx.h"
  35.  
  36. #define QUICKTESTPOINTS 2      // Number of points to use for Quick Test
  37.  
  38. HINSTANCE hInst;       // current instance
  39.  
  40. char szAppName[] = "TextFX";   // The name of this application
  41. char szTitle[]   = "TextFX Test Application"; // The title bar text
  42.  
  43. // Random number stuff for generating random points for "Quick Test" option
  44. #define randfloat() ((float)rand() / (float)RAND_MAX)
  45. #define random(i) ((short)(randfloat() * (float)(i)))
  46.  
  47. /**********************************************************************
  48.  *                                                                    *
  49.  * FUNCTION:  GetLastErrorBox(HWND, LPSTR)                            *  
  50.  *                                                                      *
  51.  * PURPOSE:   Gets the error status and, if an error is indicated,    *
  52.  *            converts the error number into text and displays it     *
  53.  *            in a MessageBox.                                        *
  54.  *                                                                    *
  55.  *********************************************************************/
  56. DWORD GetLastErrorBox(HWND hWnd, LPSTR lpTitle)
  57. {
  58.    LPVOID lpv;
  59.    DWORD  dwRv;
  60.  
  61.    if (GetLastError() == 0) return 0;
  62.    
  63.    dwRv = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
  64.                         FORMAT_MESSAGE_FROM_SYSTEM,
  65.                         NULL,
  66.                         GetLastError(),
  67.                         MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
  68.                         (LPVOID)&lpv,
  69.                         0,
  70.                         NULL);
  71.    
  72.    MessageBox(hWnd, lpv, lpTitle, MB_OK);
  73.    
  74.    if(dwRv)
  75.       LocalFree(lpv);
  76.    
  77.    SetLastError(0);
  78.    return dwRv;
  79. }
  80.  
  81. /*****************************************************************************
  82.  *                                                                             *
  83.  * FUNCTION: WinMain(HINSTANCE, HINSTANCE, LPSTR, int)                         *
  84.  *                                                                             *
  85.  * PURPOSE: calls initialization function, processes message loop             *
  86.  *                                                                             *
  87.  * COMMENTS:                                                                 *
  88.  *                                                                             *
  89.  *    Windows recognizes this function by name as the initial entry point     *
  90.  *    for the program.  This function calls the application initialization     *
  91.  *    routine, if no other instance of the program is running, and always     *
  92.  *    calls the instance initialization routine.  It then executes a message *
  93.  *    retrieval and dispatch loop that is the top-level control structure     *
  94.  *    for the remainder of execution.  The loop is terminated when a WM_QUIT *
  95.  *    message is received, at which time this function exits the application *
  96.  *    instance by returning the value passed by PostQuitMessage().             *
  97.  *                                                                             *
  98.  *    If this function must abort before entering the message loop, it         *
  99.  *    returns the conventional value NULL.                                     *
  100.  *                                                                             *
  101.  ****************************************************************************/
  102. int APIENTRY WinMain(
  103.         HINSTANCE hInstance,
  104.         HINSTANCE hPrevInstance,
  105.         LPSTR lpCmdLine,
  106.         int nCmdShow)
  107. {        
  108.     MSG msg;
  109.     HANDLE hAccelTable;
  110.     LONG lTime;
  111.  
  112.     // Just for fun, lets seed the random number generator
  113.     time(&lTime);
  114.     srand(lTime);
  115.  
  116.  
  117.     if (!hPrevInstance) {       // Other instances of app running?
  118.             if (!InitApplication(hInstance)) { // Initialize shared things
  119.             return (FALSE);     // Exits if unable to initialize
  120.         }
  121.     }
  122.  
  123.     /* Perform initializations that apply to a specific instance */
  124.  
  125.     if (!InitInstance(hInstance, nCmdShow)) {
  126.             return (FALSE);
  127.     }
  128.  
  129.     hAccelTable = LoadAccelerators (hInstance, "TEXTFXACCEL");
  130.  
  131.     /* Acquire and dispatch messages until a WM_QUIT message is received. */
  132.  
  133.     while (GetMessage(&msg, // message structure
  134.        NULL,   // handle of window receiving the message
  135.        0,      // lowest message to examine
  136.        0))     // highest message to examine
  137.     {
  138.         if (!TranslateAccelerator (msg.hwnd, hAccelTable, &msg)) {
  139.             TranslateMessage(&msg);// Translates virtual key codes
  140.             DispatchMessage(&msg); // Dispatches message to window
  141.         }
  142.     }
  143.  
  144.     return (msg.wParam); // Returns the value from PostQuitMessage
  145.  
  146.     UNREFERENCED_PARAMETER(lpCmdLine); // This will prevent 'unused formal parameter' warnings
  147. }
  148.  
  149.  
  150. /*****************************************************************************
  151.  *                                                                             *
  152.  *  FUNCTION: InitApplication(HINSTANCE)                                     *
  153.  *                                                                             *
  154.  *  PURPOSE: Initializes window data and registers window class                 *
  155.  *                                                                             *
  156.  *  COMMENTS:                                                                 *
  157.  *                                                                             *
  158.  *    This function is called at initialization time only if no other         *
  159.  *    instances of the application are running.  This function performs         *
  160.  *    initialization tasks that can be done once for any number of running     *
  161.  *    instances.                                                             *
  162.  *                                                                             *
  163.  *    In this case, we initialize a window class by filling out a data         *
  164.  *    structure of type WNDCLASS and calling the Windows RegisterClass()     *
  165.  *    function.  Since all instances of this application use the same window *
  166.  *    class, we only need to do this when the first instance is initialized. *
  167.  *                                                                             *
  168.  *****************************************************************************/
  169. BOOL InitApplication(HINSTANCE hInstance)
  170. {
  171.     WNDCLASS  wc;
  172.  
  173.     // Fill in window class structure with parameters that describe the
  174.     // main window.
  175.  
  176.     wc.style         = CS_OWNDC;               // Class style(s).
  177.     wc.lpfnWndProc   = (WNDPROC)WndProc;       // Window Procedure
  178.     wc.cbClsExtra    = 0;                      // No per-class extra data.
  179.     wc.cbWndExtra    = 0;                      // No per-window extra data.
  180.     wc.hInstance     = hInstance;              // Owner of this class
  181.     wc.hIcon         = LoadIcon (hInstance, szAppName); // Icon name from .RC
  182.     wc.hCursor       = LoadCursor(NULL, IDC_ARROW);// Cursor
  183.     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);// Default color
  184.     wc.lpszMenuName  = "TEXTFXMENU";           // Menu name from .RC
  185.     wc.lpszClassName = szAppName;              // Name to register as
  186.  
  187.     // Register the window class and return success/failure code.
  188.     return (RegisterClass(&wc));
  189. }
  190.  
  191.  
  192. /*****************************************************************************
  193.  *                                                                             *
  194.  *   FUNCTION:  InitInstance(HINSTANCE, int)                                 *
  195.  *                                                                             *
  196.  *   PURPOSE:  Saves instance handle and creates main window                 *
  197.  *                                                                             *
  198.  *   COMMENTS:                                                                 *
  199.  *                                                                             *
  200.  *      This function is called at initialization time for every instance of *
  201.  *      this application.  This function performs initialization tasks that     *
  202.  *      cannot be shared by multiple instances.                                 *
  203.  *                                                                             *
  204.  *      In this case, we save the instance handle in a static variable and     *
  205.  *      create and display the main program window.                             *
  206.  *                                                                             *
  207.  ****************************************************************************/
  208. BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
  209. {
  210.     HWND            hWnd; // Main window handle.
  211.  
  212.     // Save the instance handle in static variable, which will be used in
  213.     // many subsequence calls from this application to Windows.
  214.  
  215.     hInst = hInstance; // Store instance handle in our global variable
  216.  
  217.     // Create a main window for this application instance.
  218.  
  219.     hWnd = CreateWindow(
  220.             szAppName,           // See RegisterClass() call.
  221.             szTitle,             // Text for window title bar.
  222.             WS_OVERLAPPEDWINDOW,// Window style.
  223.             CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, // Use default positioning
  224.             NULL,                // Overlapped windows have no parent.
  225.             NULL,                // Use the window class menu.
  226.             hInstance,           // This instance owns this window.
  227.             NULL                 // We don't use any data in our WM_CREATE
  228.     );
  229.  
  230.     // If window could not be created, return "failure"
  231.     if (!hWnd) {
  232.             return (FALSE);
  233.     }
  234.  
  235.     // Make the window visible; update its client area; and return "success"
  236.     ShowWindow(hWnd, nCmdShow); // Show the window
  237.     UpdateWindow(hWnd);         // Sends WM_PAINT message
  238.  
  239.     return (TRUE);              // We succeeded...
  240.  
  241. }
  242.                                       
  243.  
  244. /*****************************************************************************
  245.  *                                                                             *
  246.  *   FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)                             *
  247.  *                                                                             *
  248.  *   PURPOSE:  Processes messages                                             *
  249.  *                                                                             *
  250.  *   MESSAGES:                                                                 *
  251.  *                                                                             *
  252.  *   WM_COMMAND    - application menu (About dialog box)                     *
  253.  *   WM_DESTROY    - destroy window                                             *
  254.  *                                                                             *
  255.  *   COMMENTS:                                                                 *
  256.  *                                                                             *
  257.  *   To process the IDM_ABOUT message, call MakeProcInstance() to get the     *
  258.  *   current instance address of the About() function.  Then call Dialog     *
  259.  *   box which will create the box according to the information in your         *
  260.  *   TextFX.rc file and turn control over to the About() function.  When     *
  261.  *   it returns, free the intance address.                                     *
  262.  *                                                                             *
  263.  ****************************************************************************/
  264. LRESULT CALLBACK WndProc(
  265.                 HWND hWnd,         // window handle
  266.                 UINT message,      // type of message
  267.                 WPARAM uParam,     // additional information
  268.                 LPARAM lParam)     // additional information
  269. {
  270.     int wmId, wmEvent;
  271.     static BOOL bOn = TRUE;  // Which guide line (top = TRUE) are we on?
  272.     static LPPOINT lpTop = NULL;
  273.     static LPPOINT lpBot = NULL;
  274.     static DWORD dwTop = 0;
  275.     static DWORD dwBot = 0;
  276.     static BOOL bOutlineOnly = FALSE;
  277.     static BOOL bShowGuides  = FALSE;
  278.     static HPEN hpenBlue, hpenRed;
  279.     
  280.     SetLastError(0); // Set error flag to "no errors"
  281.  
  282.     switch (message) {     
  283.         case WM_CREATE:  // Select an big Arial font into our DC 
  284.             {
  285.                 HDC hDC = GetDC(hWnd);
  286.                 LOGFONT lf;
  287.                 HFONT hf;
  288.  
  289.                 memset(&lf, 0, sizeof(LOGFONT));
  290.                 lf.lfHeight = -72;        // Big fonts scale better
  291.                 strcpy((LPSTR)&(lf.lfFaceName), "arial");
  292.               
  293.                 // Create and select the font
  294.                 hf = CreateFontIndirect(&lf); 
  295.                 SelectObject(hDC, hf);
  296.  
  297.                 hpenBlue = CreatePen(PS_SOLID, 1, RGB(0,0,255));
  298.                 hpenRed  = CreatePen(PS_SOLID, 1, RGB(255,0,0));
  299.             }
  300.             
  301.             GetLastErrorBox(hWnd, "Error in WM_CREATE");
  302.             break;
  303.  
  304.         case WM_PAINT: 
  305.             {
  306.                PAINTSTRUCT ps;
  307.                HDC hDC = BeginPaint(hWnd, &ps);
  308.                RECT rect;
  309.                               
  310.                // Clear the client area 
  311.                GetClientRect(hWnd, &rect);
  312.                   PatBlt(hDC, 0, 0, rect.right, rect.bottom, WHITENESS);
  313.                    
  314.                   
  315.                   // If we have something to show...
  316.                   if (dwTop && dwBot) {
  317.  
  318.                    // Show the top guide line if we have one and the user wants to
  319.                    if (dwTop && bShowGuides) {
  320.                      SelectObject(hDC, hpenBlue);
  321.                      ShowGuide(hDC, lpTop, dwTop);
  322.                      SelectObject(hDC, GetStockObject(BLACK_PEN));
  323.                    }
  324.                
  325.                    // If we have a bottom guide line
  326.                    if (dwBot) {                     
  327.                
  328.                           // ...then show it if the use wants to
  329.                        if (bShowGuides) {
  330.                          SelectObject(hDC, hpenRed);
  331.                          ShowGuide(hDC, lpBot, dwBot);
  332.                          SelectObject(hDC, GetStockObject(BLACK_PEN));
  333.                        }                         
  334.           
  335.                        // Do the mapping and show the text
  336.                        TextEffect(hDC, lpTop, lpBot, dwTop, dwBot, "This is a test", bOutlineOnly); 
  337.                    }
  338.                }
  339.  
  340.                EndPaint(hWnd, &ps);
  341.             }
  342.             break;
  343.  
  344.         case WM_LBUTTONDOWN: // Read a guide line from the user
  345.             {
  346.                HDC hDC = GetDC(hWnd);                   
  347.                RECT rect;    
  348.                
  349.                if (bOn) {
  350.                    GetClientRect(hWnd, &rect);
  351.                    
  352.                    // Clear the screen
  353.                    PatBlt(hDC, 0, 0, rect.right, rect.bottom, WHITENESS);
  354.                    
  355.                    // Get rid of the previous guide lines
  356.                    if (lpTop) 
  357.                      GlobalFree(lpTop);
  358.                    if (lpBot) 
  359.                      GlobalFree(lpBot);
  360.                    dwBot = 0;
  361.  
  362.                    SelectObject(hDC, hpenBlue);  // Top guide line is blue
  363.                    GetGuideLine(hWnd, &lpTop, &dwTop);
  364.                }
  365.                else {
  366.                    SelectObject(hDC, hpenRed);    // Bottom guide line is red
  367.                    GetGuideLine(hWnd, &lpBot, &dwBot);
  368.                }
  369.                
  370.                // Black as night, black as coal, I want to see the sun blotted out from the sky...
  371.                SelectObject(hDC, GetStockObject(BLACK_PEN));
  372.                bOn = !bOn;
  373.  
  374.                if (bOn) {  
  375.  
  376.                   // Expand the line segment into points 
  377.                      FillOut(&lpTop, &dwTop);
  378.                   FillOut(&lpBot, &dwBot);
  379.  
  380.                   InvalidateRect(hWnd, NULL, FALSE);  // Draw the text via WM_PAINT
  381.                }
  382.             }          
  383.             
  384.             GetLastErrorBox(hWnd, "Error in WM_LBUTTONDOWN");
  385.             break;
  386.         
  387.         case WM_COMMAND:
  388.             wmId    = LOWORD(uParam);
  389.             wmEvent = HIWORD(uParam);
  390.  
  391.             switch (wmId) {
  392.                 case IDM_QUICKTEST:  // Randomly generate guide lines
  393.                     {
  394.                       RECT rect;
  395.                       int i;
  396.                       
  397.                       bOn = TRUE;  // Reset to top guide line
  398.  
  399.                       GetClientRect(hWnd, &rect);
  400.                       if (dwTop)
  401.                         GlobalFree(lpTop);
  402.                       if (dwBot)
  403.                         GlobalFree(lpBot);
  404.                       
  405.                       // Allocate top guide line
  406.                       lpTop = (LPPOINT)GlobalAlloc(GPTR, sizeof(POINT) * QUICKTESTPOINTS);
  407.                       if (!lpTop) break;
  408.                       
  409.                       // Allocate bottom guide line
  410.                       lpBot = (LPPOINT)GlobalAlloc(GPTR, sizeof(POINT) * QUICKTESTPOINTS);
  411.                       if (!lpBot) {
  412.                         GlobalFree(lpTop);
  413.                         break;
  414.                       }
  415.                       
  416.                       // Generate points
  417.                       for (i=0; i<QUICKTESTPOINTS; i++) {
  418.                         lpTop[i].x = random(rect.right);
  419.                         lpTop[i].y = random(rect.bottom);
  420.                         lpBot[i].x = random(rect.right);
  421.                         lpBot[i].y = random(rect.bottom);
  422.                       }         
  423.                       
  424.                       // Set number of points for top and bottom lines
  425.                       dwTop = QUICKTESTPOINTS;
  426.                       dwBot = QUICKTESTPOINTS;
  427.                       
  428.                       // Expand the line segment into points 
  429.                       FillOut(&lpTop, &dwTop);
  430.                       FillOut(&lpBot, &dwBot);
  431.           
  432.                       InvalidateRect(hWnd, NULL, FALSE);  // Draw the text via WM_PAINT
  433.                     }
  434.             
  435.                     GetLastErrorBox(hWnd, "Error in IDM_QUICKTEST");  
  436.                     break;
  437.  
  438.                 case IDM_CHOOSEFONT: // Let the user pick a font
  439.                     {
  440.                        HDC hDC = GetDC(hWnd);
  441.                        HFONT hf;
  442.                        LOGFONT lf;
  443.                        CHOOSEFONT cf;
  444.                            
  445.                        ZeroMemory(&cf, sizeof(cf));  
  446.                        ZeroMemory(&lf, sizeof(lf));  
  447.                                                            
  448.                        cf.lStructSize = sizeof(CHOOSEFONT);
  449.                        cf.lpLogFont = &lf;
  450.                        cf.Flags = CF_SCREENFONTS | CF_TTONLY;
  451.                        
  452.                        if (ChooseFont(&cf)) {
  453.                            lf.lfHeight = -72;    // Bigger fonts look better
  454.                            hf = CreateFontIndirect(&lf); 
  455.                               DeleteObject(SelectObject(hDC, hf));     
  456.                        }
  457.                     }
  458.  
  459.                     // If we have text to show then re-render it
  460.                     if (dwTop && dwBot) 
  461.                       InvalidateRect(hWnd, NULL, FALSE);  // Draw the text via WM_PAINT
  462.                     
  463.                     GetLastErrorBox(hWnd, "Error in IDM_CHOOSEFONT");
  464.                     break;
  465.                     
  466.                 case IDM_SHOWGUIDES:  // User toggled guide display
  467.                     bShowGuides = !bShowGuides;
  468.                     CheckMenuItem(GetMenu(hWnd), IDM_SHOWGUIDES, bShowGuides ? MF_CHECKED : MF_UNCHECKED);
  469.                     
  470.                     // If we have text to show then re-render it
  471.                     if (dwTop && dwBot) 
  472.                       InvalidateRect(hWnd, NULL, FALSE);  // Draw the text via WM_PAINT
  473.                     
  474.                     GetLastErrorBox(hWnd, "Error in IDM_SHOWGUIDES");
  475.                     break;
  476.                                       
  477.                 case IDM_OUTLINE:      // User toggled display of text as outline
  478.                     bOutlineOnly = !bOutlineOnly;
  479.                     CheckMenuItem(GetMenu(hWnd), IDM_OUTLINE, bOutlineOnly ? MF_CHECKED : MF_UNCHECKED);
  480.                     
  481.                     // If we have text to show then re-render it
  482.                     if (dwTop && dwBot) 
  483.                       InvalidateRect(hWnd, NULL, FALSE);  // Draw the text via WM_PAINT
  484.                     
  485.                     GetLastErrorBox(hWnd, "Error in IDM_OUTLINE");
  486.                     break;
  487.  
  488.                 case IDM_ABOUT:
  489.                     DialogBox(hInst,          // current instance
  490.                              "ABOUTBOX",      // dlg resource to use
  491.                              hWnd,            // parent handle
  492.                              (DLGPROC)About); // About() instance address
  493.  
  494.                     break;
  495.  
  496.                 
  497.                 case IDM_EXIT:
  498.                     DestroyWindow (hWnd);
  499.                     break;
  500.  
  501.                 default:
  502.                     return (DefWindowProc(hWnd, message, uParam, lParam));
  503.             }
  504.             break;
  505.  
  506.         case WM_DESTROY:  // message: window being destroyed
  507.                 PostQuitMessage(0);
  508.                 break;
  509.     
  510.         default:          // Passes it on if unproccessed
  511.                 return (DefWindowProc(hWnd, message, uParam, lParam));
  512.     }
  513.     return (0);
  514. }
  515.  
  516. /*****************************************************************************
  517.  *                                                                             *
  518.  *   FUNCTION: CenterWindow (HWND, HWND)                                     *
  519.  *                                                                             *
  520.  *   PURPOSE:  Center one window over another                                 *
  521.  *                                                                             *
  522.  *   COMMENTS:                                                                 *
  523.  *                                                                             *
  524.  *   Dialog boxes take on the screen position that they were designed at,     *
  525.  *   which is not always appropriate. Centering the dialog over a particular *
  526.  *   window usually results in a better position.                             *
  527.  *                                                                             *
  528.  ****************************************************************************/
  529.  
  530. BOOL CenterWindow (HWND hwndChild, HWND hwndParent)
  531. {
  532.         RECT    rChild, rParent;
  533.         int     wChild, hChild, wParent, hParent;
  534.         int     wScreen, hScreen, xNew, yNew;
  535.         HDC     hdc;
  536.  
  537.         // Get the Height and Width of the child window
  538.         GetWindowRect (hwndChild, &rChild);
  539.         wChild = rChild.right - rChild.left;
  540.         hChild = rChild.bottom - rChild.top;
  541.  
  542.         // Get the Height and Width of the parent window
  543.         GetWindowRect (hwndParent, &rParent);
  544.         wParent = rParent.right - rParent.left;
  545.         hParent = rParent.bottom - rParent.top;
  546.  
  547.         // Get the display limits
  548.         hdc = GetDC (hwndChild);
  549.         wScreen = GetDeviceCaps (hdc, HORZRES);
  550.         hScreen = GetDeviceCaps (hdc, VERTRES);
  551.         ReleaseDC (hwndChild, hdc);
  552.  
  553.         // Calculate new X position, then adjust for screen
  554.         xNew = rParent.left + ((wParent - wChild) /2);
  555.         if (xNew < 0) {
  556.                 xNew = 0;
  557.         } else if ((xNew+wChild) > wScreen) {
  558.                 xNew = wScreen - wChild;
  559.         }
  560.  
  561.         // Calculate new Y position, then adjust for screen
  562.         yNew = rParent.top  + ((hParent - hChild) /2);
  563.         if (yNew < 0) {
  564.                 yNew = 0;
  565.         } else if ((yNew+hChild) > hScreen) {
  566.                 yNew = hScreen - hChild;
  567.         }
  568.  
  569.         // Set it, and return
  570.         return SetWindowPos (hwndChild, NULL,
  571.                 xNew, yNew, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
  572. }
  573.  
  574.  
  575. /*****************************************************************************
  576.  *                                                                             *
  577.  *   FUNCTION: About(HWND, UINT, WPARAM, LPARAM)                             *
  578.  *                                                                             *
  579.  *   PURPOSE:  Processes messages for "About" dialog box                     *
  580.  *                                                                             *
  581.  *   MESSAGES:                                                                 *
  582.  *                                                                             *
  583.  *   WM_INITDIALOG - initialize dialog box                                     *
  584.  *   WM_COMMAND    - Input received                                             *
  585.  *                                                                             *
  586.  *   COMMENTS:                                                                 *
  587.  *                                                                             *
  588.  *   Display version information from the version section of the             *
  589.  *   application resource.                                                     *
  590.  *                                                                             *
  591.  *   Wait for user to click on "Ok" button, then close the dialog box.         *
  592.  *                                                                             *
  593.  ****************************************************************************/
  594.  
  595. LRESULT CALLBACK About(
  596.                 HWND hDlg,           // window handle of the dialog box
  597.                 UINT message,        // type of message
  598.                 WPARAM uParam,       // message-specific information
  599.                 LPARAM lParam)
  600. {
  601.     switch (message) {
  602.         case WM_INITDIALOG:  // message: initialize dialog box
  603.             // Center the dialog over the application window
  604.             CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));
  605.             return (TRUE);
  606.  
  607.         case WM_COMMAND:                      // message: received a command
  608.             if (LOWORD(uParam) == IDOK || LOWORD(uParam) == IDCANCEL) { 
  609.                 EndDialog(hDlg, TRUE);        // Exit the dialog
  610.                 return (TRUE);
  611.             }
  612.             break;
  613.     }
  614.     return (FALSE); // Didn't process the message
  615.  
  616.     UNREFERENCED_PARAMETER(lParam); // This will prevent 'unused formal parameter' warnings
  617. }
  618.