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

Windows编程

开发平台:

Visual C++

  1. /******************************************************************************
  2. *       This is a part of the Microsoft Source Code Samples. 
  3. *       Copyright (C) 1993-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. | POLYBEZIER MODULE
  12. |   This module contains the routines for demo
  13. *---------------------------------------------------------------------------*/
  14. #include <windows.h>
  15. #include "gdidemo.h"
  16. #include  "poly.h"
  17. /*---------------------------------------------------------------------------*
  18. | CREATE BEZIER WINDOW PROCEDURE
  19. |   Create the bezier MDI-child window.
  20. *---------------------------------------------------------------------------*/
  21. HWND FAR CreatePolyWindow(HWND hWndClient, int nItem)
  22. {
  23.     HANDLE          hInstance;
  24.     MDICREATESTRUCT mcs;
  25.     static char buffer[256];
  26.     hInstance = GETINSTANCE(hWndClient);
  27.     LoadString (hInstance, POLYTITLE, buffer, 256);
  28.     /*
  29.     ** Initialize the MDI create struct for creation of the
  30.     ** test window.
  31.     */
  32.     mcs.szClass = POLYCLASS;
  33.     mcs.szTitle = buffer;
  34.     mcs.hOwner  = hInstance;
  35.     mcs.x       = CW_USEDEFAULT;
  36.     mcs.y       = CW_USEDEFAULT;
  37.     mcs.cx      = CW_USEDEFAULT;
  38.     mcs.cy      = CW_USEDEFAULT;
  39.     mcs.style   = 0l;
  40.     mcs.lParam  = (LONG)nItem;
  41.     return((HWND)SendMessage(hWndClient,WM_MDICREATE,0,(LONG)(LPMDICREATESTRUCT)&mcs));
  42. }
  43. /*---------------------------------------------------------------------------*
  44. | POLYBEZIER WINDOW PROCEDURE
  45. |   This is the main window function for the polybezier demo window.
  46. *---------------------------------------------------------------------------*/
  47. LONG APIENTRY PolyProc(HWND hWnd, UINT wMsg, WPARAM wParam, LONG lParam)
  48. {
  49.     switch(wMsg)
  50.     {
  51.         case WM_CREATE:
  52.             PolyCreateProc(hWnd);
  53.             break;
  54.         case WM_COMMAND:
  55.             PolyCommandProc(hWnd,wParam,lParam);
  56.             break;
  57.         case WM_MOVE:
  58.             PolyRedraw(hWnd);
  59.             break;
  60.         case WM_TIMER:
  61.             PolyDrawBez(hWnd);
  62.             break;
  63.         case WM_PAINT:
  64.             PolyPaintProc(hWnd);
  65.             break;
  66.         case WM_DESTROY:
  67.             PolyDestroyProc(hWnd);
  68.             break;
  69.         default:
  70.             return(DefMDIChildProc(hWnd,wMsg,wParam,lParam));
  71.     }
  72.     return(0l);
  73. }
  74. /*---------------------------------------------------------------------------*
  75. | POLYBEZIER CREATE PROCEDURE
  76. |   Create the polybezier window for the demo application.  This is a child
  77. |   of the MDI client window.  Allocate the extra object information for
  78. |   handling of the polybezier demo.
  79. *---------------------------------------------------------------------------*/
  80. BOOL PolyCreateProc(HWND hWnd)
  81. {
  82.     PPOLYDATA ppd;
  83.     if(AllocWindowInfo(hWnd,sizeof(POLYDATA)))
  84.     {
  85.         if(ppd = (PPOLYDATA)LockWindowInfo(hWnd))
  86.         {
  87.             ppd->nBezTotal  = 20;
  88.             ppd->nBezCurr   = 0;
  89.             ppd->nColor     = 0;
  90.             ppd->hBezBuffer = GlobalAlloc(GHND,(DWORD)(sizeof(BEZBUFFER) * MAX_BEZIER));
  91.             UnlockWindowInfo(hWnd);
  92.             PolyInitPoints(hWnd);
  93.             SetTimer(hWnd,1,50,NULL);
  94.             return(TRUE);
  95.         }
  96.         FreeWindowInfo(hWnd);
  97.     }
  98.     return(FALSE);
  99. }
  100. /*---------------------------------------------------------------------------*
  101. | POLYBEZIER COMMAND PROCEDURE
  102. |   Process polybezier commands.  This is a NOP for now.  But who knows what
  103. |   tomorrow may bring.
  104. *---------------------------------------------------------------------------*/
  105. BOOL PolyCommandProc(HWND hWnd, WPARAM wParam, LONG lParam)
  106. {
  107.     hWnd   = hWnd;
  108.     wParam = wParam;
  109.     lParam = lParam;
  110.     return(TRUE);
  111. }
  112. /*---------------------------------------------------------------------------*
  113. | POLYBEZIER PAINT PROCEDURE
  114. |   Repaint the bezier window.  All we really do here is validate our window,
  115. |   and reset the array of bezier objects.
  116. *---------------------------------------------------------------------------*/
  117. VOID PolyPaintProc(HWND hWnd)
  118. {
  119.     HDC         hDC;
  120.     PAINTSTRUCT ps;
  121.     if(hDC = BeginPaint(hWnd,&ps))
  122.         EndPaint(hWnd,&ps);
  123.     PolyRedraw(hWnd);
  124.     return;
  125. }
  126. /*---------------------------------------------------------------------------*
  127. | POLYBEZIER DESTROY PROCEDURE
  128. |   Kill the polybezier demo.  Free up the resources allocated on behalf of
  129. |   this object.
  130. *---------------------------------------------------------------------------*/
  131. VOID PolyDestroyProc(HWND hWnd)
  132. {
  133.     PPOLYDATA ppd;
  134.     KillTimer(hWnd,1);
  135.     if(ppd = (PPOLYDATA)LockWindowInfo(hWnd))
  136.     {
  137.         GlobalFree(ppd->hBezBuffer);
  138.         UnlockWindowInfo(hWnd);
  139.     }
  140.     FreeWindowInfo(hWnd);
  141.     return;
  142. }
  143. /*---------------------------------------------------------------------------*
  144. | GET NEW VELOCITY
  145. |   This routine creates a new velocity for the bezier points.  Each bezier
  146. |   point is randomly chosen.  The two inside points should have a speed
  147. |   less then the endpoints (most of the time-better effect).
  148. *---------------------------------------------------------------------------*/
  149. int PolyNewVel(int i)
  150. {
  151.     int nRet;
  152.     if ((i == 1) || (i == 2))
  153.         nRet = (int)((lRandom() % VELMAX) / 3) + VELMIN;
  154.     else
  155.         nRet = (int)(lRandom() % VELMAX) + VELMIN;
  156.     return((nRet < 0) ? -nRet : nRet);
  157. }
  158. /*---------------------------------------------------------------------------*
  159. | INITIALIZE POLYBEZIER POINTS
  160. |   This routine initializes the polybezier points for the first object.  This
  161. |   is performed on startup of the window.
  162. *---------------------------------------------------------------------------*/
  163. VOID PolyInitPoints(HWND hWnd)
  164. {
  165.     PPOLYDATA   ppd;
  166.     LPBEZBUFFER lpBez;
  167.     int         idx;
  168.     RECT        rect;
  169.     if(ppd = (PPOLYDATA)LockWindowInfo(hWnd))
  170.     {
  171.         if(lpBez = (LPBEZBUFFER)GlobalLock(ppd->hBezBuffer))
  172.         {
  173.             GetClientRect(hWnd,&rect);
  174.             for(idx=0; idx < BEZ_PTS-1; idx++)
  175.             {
  176.                 lpBez->pPts[idx].x = lRandom() % rect.right;
  177.                 lpBez->pPts[idx].y = lRandom() % rect.bottom;
  178.                 ppd->pVel[idx].x = PolyNewVel(idx);
  179.                 ppd->pVel[idx].y = PolyNewVel(idx);
  180.             }
  181.             GlobalUnlock(ppd->hBezBuffer);
  182.         }
  183.         UnlockWindowInfo(hWnd);
  184.     }
  185.     return;
  186. }
  187. /*---------------------------------------------------------------------------*
  188. | POLYBEZIER REDRAW
  189. |   This routine resets the bezier curves and redraws the poly-bezier client
  190. |   area.
  191. *---------------------------------------------------------------------------*/
  192. VOID PolyRedraw(HWND hWnd)
  193. {
  194.     PPOLYDATA   ppd;
  195.     LPBEZBUFFER lpBez,lpCurr;
  196.     HDC         hDC;
  197.     int         i,j;
  198.     RECT        rect;
  199.     if(ppd = (PPOLYDATA)LockWindowInfo(hWnd))
  200.     {
  201.         if(lpBez = (LPBEZBUFFER)GlobalLock(ppd->hBezBuffer))
  202.         {
  203.             if(hDC = GetDC(hWnd))
  204.             {
  205.                 /*
  206.                 ** Save the current bezier.  Set the first bezier in the
  207.                 ** array to that curve, and use it as a basis for the next
  208.                 ** series.
  209.                 */
  210.                 lpCurr        = lpBez+ppd->nBezCurr;
  211.                 *lpBez        = *lpCurr;
  212.                 ppd->nBezCurr = 0;
  213.                 /*
  214.                 ** Clean the curves (all but the first curve).
  215.                 */
  216.                 for(j=1; j < ppd->nBezTotal; j++)
  217.                 {
  218.                     for(i=0; i < BEZ_PTS; i++)
  219.                     {
  220.                         (lpBez+j)->pPts[i].x = -1;
  221.                         (lpBez+j)->pPts[i].y = 0;
  222.                     }
  223.                 }
  224.                 /*
  225.                 ** Clear the display.
  226.                 */
  227.                 GetClientRect(hWnd,&rect);
  228.                 BitBlt(hDC,0,0,rect.right, rect.bottom,(HDC)0,0,0,0);
  229.                 /*
  230.                 ** Draw the first curve in the bezier array.
  231.                 */
  232. #if defined(_WIN32) && defined(WIN32)
  233.                 PolyBezier(hDC,lpBez->pPts,BEZ_PTS);
  234. #else
  235.                 Polyline(hDC,lpBez->pPts,BEZ_PTS);
  236. #endif
  237.                 ReleaseDC(hWnd,hDC);
  238.             }
  239.             GlobalUnlock(ppd->hBezBuffer);
  240.         }
  241.         UnlockWindowInfo(hWnd);
  242.     }
  243.     return;
  244. }
  245. VOID PolyDrawBez(HWND hWnd)
  246. {
  247.     PPOLYDATA   ppd;
  248.     LPBEZBUFFER lpBez,lpCurr,lpPrev;
  249.     int         idx,x,y;
  250.     RECT        rect;
  251.     HDC         hDC;
  252.     HPEN        hPen;
  253. static COLORREF crColor[] = {0x000000FF,0x0000FF00,0x00FF0000,0x0000FFFF,
  254.                              0x00FF00FF,0x00FFFF00,0x00FFFFFF,0x00000080,
  255.                              0x00008000,0x00800000,0x00008080,0x00800080,
  256.                              0x00808000,0x00808080,0x000000FF,0x0000FF00,
  257.                              0x00FF0000,0x0000FFFF,0x00FF00FF,0x00FFFF00};
  258.     if(ppd = (PPOLYDATA)LockWindowInfo(hWnd))
  259.     {
  260.         if(lpBez = (LPBEZBUFFER)GlobalLock(ppd->hBezBuffer))
  261.         {
  262.             if(hDC = GetDC(hWnd))
  263.             {
  264.                 GetClientRect(hWnd,&rect);
  265.                 lpPrev = lpBez+ppd->nBezCurr;
  266.                 ppd->nBezCurr += 1;
  267.                 if(ppd->nBezCurr >= ppd->nBezTotal)
  268.                 {
  269.                     ppd->nBezCurr = 0;
  270.                     ppd->nColor  = (++ppd->nColor % 20);
  271.                 }
  272.                 lpCurr = lpBez+ppd->nBezCurr;
  273.                 if(lpCurr->pPts[0].x != -1)
  274.                 {
  275.                     hPen = SelectObject(hDC,GetStockObject(BLACK_PEN));
  276. #if defined(_WIN32) && defined(WIN32)
  277.                     PolyBezier(hDC,lpCurr->pPts,BEZ_PTS);
  278. #else
  279.                     Polyline(hDC,lpCurr->pPts,BEZ_PTS);
  280. #endif
  281.                     SelectObject(hDC,hPen);
  282.                 }
  283.                 for(idx=0; idx < BEZ_PTS; idx++)
  284.                 {
  285.                     x  = lpPrev->pPts[idx].x;
  286.                     y  = lpPrev->pPts[idx].y;
  287.                     x += ppd->pVel[idx].x;
  288.                     y += ppd->pVel[idx].y;
  289.                     if(x >= rect.right)
  290.                     {
  291.                         x = rect.right - ((x - rect.right)+1);
  292.                         ppd->pVel[idx].x = -PolyNewVel(idx);
  293.                     }
  294.                     if(x <= rect.left)
  295.                     {
  296.                         x = rect.left + ((rect.left - x)+1);
  297.                         ppd->pVel[idx].x = PolyNewVel(idx);
  298.                     }
  299.                     if(y >= rect.bottom)
  300.                     {
  301.                         y = rect.bottom - ((y - rect.bottom)+1);
  302.                         ppd->pVel[idx].y = -PolyNewVel(idx);
  303.                     }
  304.                     if(y <= rect.top)
  305.                     {
  306.                         y = rect.top + ((rect.top - y)+1);
  307.                         ppd->pVel[idx].y = PolyNewVel(idx);
  308.                     }
  309.                     lpCurr->pPts[idx].x = x;
  310.                     lpCurr->pPts[idx].y = y;
  311.                 }
  312.                 hPen = SelectObject(hDC,CreatePen(PS_SOLID,1,crColor[ppd->nColor]));
  313. #if defined(_WIN32) && defined(WIN32)
  314.                 PolyBezier(hDC,lpCurr->pPts,BEZ_PTS);
  315. #else
  316.                 Polyline(hDC,lpCurr->pPts,BEZ_PTS);
  317. #endif
  318.                 DeleteObject(SelectObject(hDC,hPen));
  319. #if defined(_WIN32) && defined(WIN32)
  320.                 SetROP2(hDC,R2_COPYPEN);
  321. #endif
  322.                 ReleaseDC(hWnd,hDC);
  323.             }
  324.             GlobalUnlock(ppd->hBezBuffer);
  325.         }
  326.         UnlockWindowInfo(hWnd);
  327.     }
  328. }