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

Windows编程

开发平台:

Visual C++

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