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

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. | BOUNCING BALL MODULE
  12. *---------------------------------------------------------------------------*/
  13. #include <windows.h>
  14. #include "gdidemo.h"
  15. #include "bounce.h"
  16. VOID XFormClear(PMYXFORM);
  17. VOID XFormScale(PMYXFORM,int,int);
  18. VOID XFormTrans(PMYXFORM,int,int);
  19. VOID XFormPoint(PMYXFORM,LPPOINT);
  20. /*---------------------------------------------------------------------------*
  21. | CREATE BOUNCE WINDOW PROCEDURE
  22. |
  23. *---------------------------------------------------------------------------*/
  24. HWND FAR CreateBounceWindow(HWND hWndClient, int nItem)
  25. {
  26.     HANDLE          hInstance;
  27.     MDICREATESTRUCT mcs;
  28.     static char buffer[256];
  29.     hInstance = GETINSTANCE(hWndClient);
  30.     LoadString (hInstance, BOUNCETITLE, buffer, 256);
  31.     /*
  32.     ** Initialize the MDI create struct for creation of the
  33.     ** test window.
  34.     */
  35.     mcs.szClass = BOUNCECLASS;
  36.     mcs.szTitle = buffer;
  37.     mcs.hOwner  = hInstance;
  38.     mcs.x       = CW_USEDEFAULT;
  39.     mcs.y       = CW_USEDEFAULT;
  40.     mcs.cx      = CW_USEDEFAULT;
  41.     mcs.cy      = CW_USEDEFAULT;
  42.     mcs.style   = 0l;
  43.     mcs.lParam  = (LONG)nItem;
  44.     return((HWND)SendMessage(hWndClient,WM_MDICREATE,0,(LONG)(LPMDICREATESTRUCT)&mcs));
  45. }
  46. /*---------------------------------------------------------------------------*
  47. | BOUNCE WINDOW PROCEDURE
  48. |
  49. *---------------------------------------------------------------------------*/
  50. LONG APIENTRY BounceProc(HWND hWnd, UINT wMsg, WPARAM wParam, LONG lParam)
  51. {
  52.     switch(wMsg)
  53.     {
  54.         case WM_CREATE:
  55.             BounceCreateProc(hWnd);
  56.             break;
  57.         case WM_MOVE:
  58.             BounceRefresh(hWnd);
  59.             break;
  60.         case WM_COMMAND:
  61.             BounceCommandProc(hWnd,wParam,lParam);
  62.             break;
  63.         case WM_TIMER:
  64.             BounceObjects(hWnd);
  65.             break;
  66.         case WM_PAINT:
  67.             BouncePaintProc(hWnd);
  68.             break;
  69.         case WM_DESTROY:
  70.             BounceDestroyProc(hWnd);
  71.             break;
  72.         default:
  73.             return(DefMDIChildProc(hWnd,wMsg,wParam,lParam));
  74.     }
  75.     return(0l);
  76. }
  77. /*---------------------------------------------------------------------------*
  78. | BOUNCE CREATE PROCEDURE
  79. |
  80. *---------------------------------------------------------------------------*/
  81. BOOL BounceCreateProc(HWND hWnd)
  82. {
  83.     PBOUNCEDATA pbd;
  84.     if(AllocWindowInfo(hWnd,sizeof(BOUNCEDATA)))
  85.     {
  86.         if(pbd = (PBOUNCEDATA)LockWindowInfo(hWnd))
  87.         {
  88.             pbd->hBall1 = ballCreate(hWnd,20,20,RGB(255,0,0));
  89.             pbd->hBall2 = ballCreate(hWnd,20,20,RGB(0,0,255));
  90.             pbd->hBall3 = ballCreate(hWnd,20,20,RGB(0,255,0));
  91.             pbd->hBall4 = ballCreate(hWnd,20,20,RGB(255,0,255));
  92.             UnlockWindowInfo(hWnd);
  93.             SetTimer(hWnd,1,50,NULL);
  94.             return(TRUE);
  95.         }
  96.         FreeWindowInfo(hWnd);
  97.     }
  98.     return(FALSE);
  99. }
  100. /*---------------------------------------------------------------------------*
  101. | BOUNCE COMMAND PROCEDURE
  102. |
  103. *---------------------------------------------------------------------------*/
  104. BOOL BounceCommandProc(HWND hWnd, WPARAM wParam, LONG lParam)
  105. {
  106.     hWnd   = hWnd;
  107.     wParam = wParam;
  108.     lParam = lParam;
  109.     return(TRUE);
  110. }
  111. /*---------------------------------------------------------------------------*
  112. | BOUNCE PAINT PROCEDURE
  113. |
  114. *---------------------------------------------------------------------------*/
  115. VOID BouncePaintProc(HWND hWnd)
  116. {
  117.     HDC         hDC;
  118.     PAINTSTRUCT ps;
  119.     if(hDC = BeginPaint(hWnd,&ps))
  120.         EndPaint(hWnd,&ps);
  121.     BounceRefresh(hWnd);
  122.     return;
  123. }
  124. /*---------------------------------------------------------------------------*
  125. | BOUNCE DESTROY PROCEDURE
  126. |
  127. *---------------------------------------------------------------------------*/
  128. VOID BounceDestroyProc(HWND hWnd)
  129. {
  130.     PBOUNCEDATA pbd;
  131.     KillTimer(hWnd,1);
  132.     if(pbd = (PBOUNCEDATA)LockWindowInfo(hWnd))
  133.     {
  134.         ballDestroy(pbd->hBall1);
  135.         ballDestroy(pbd->hBall2);
  136.         ballDestroy(pbd->hBall3);
  137.         ballDestroy(pbd->hBall4);
  138.         UnlockWindowInfo(hWnd);
  139.     }
  140.     FreeWindowInfo(hWnd);
  141.     return;
  142. }
  143. /*---------------------------------------------------------------------------*
  144. | BOUNCE REFRESH
  145. |
  146. *---------------------------------------------------------------------------*/
  147. VOID BounceRefresh(HWND hWnd)
  148. {
  149.     PBOUNCEDATA pbd;
  150.     RECT        rect;
  151.     HDC         hDC;
  152.     POINT       pDimensions;
  153.     int         xDirection,yDirection;
  154.     if(pbd = (PBOUNCEDATA)LockWindowInfo(hWnd))
  155.     {
  156.         if(hDC = GetDC(hWnd))
  157.         {
  158.             GetClientRect(hWnd,&rect);
  159.             FillRect(hDC,&rect,GETCLASSBRUSH(hWnd));
  160.             xDirection = ((lRandom() % 5)+5);
  161.             yDirection = ((lRandom() % 5)+5);
  162.             ballSetPosition(pbd->hBall1,0,0);
  163.             ballSetDirection(pbd->hBall1,xDirection,yDirection);
  164.             ballGetDimensions(pbd->hBall2,&pDimensions);
  165.             ballSetPosition(pbd->hBall2,rect.right-pDimensions.x,0);
  166.             xDirection = -(((int)lRandom() % 5)+5);
  167.             yDirection =  ((lRandom() % 5)+5);
  168.             ballSetDirection(pbd->hBall2,xDirection,yDirection);
  169.             ballGetDimensions(pbd->hBall3,&pDimensions);
  170.             ballSetPosition(pbd->hBall3,0,rect.bottom-pDimensions.y);
  171.             xDirection =  ((lRandom() % 5)+5);
  172.             yDirection = -((int)(lRandom() % 5)+5);
  173.             ballSetDirection(pbd->hBall3,xDirection,yDirection);
  174.             ballGetDimensions(pbd->hBall4,&pDimensions);
  175.             ballSetPosition(pbd->hBall4,rect.right-pDimensions.x,rect.bottom-pDimensions.y);
  176.             xDirection = -((int)(lRandom() % 5)+5);
  177.             yDirection = -((int)(lRandom() % 5)+5);
  178.             ballSetDirection(pbd->hBall4,xDirection,yDirection);
  179.             ballBounce(pbd->hBall1);
  180.             ballBounce(pbd->hBall2);
  181.             ballBounce(pbd->hBall3);
  182.             ballBounce(pbd->hBall4);
  183.             ReleaseDC(hWnd,hDC);
  184.         }
  185.         UnlockWindowInfo(hWnd);
  186.     }
  187.     return;
  188. }
  189. VOID BounceObjects(HWND hWnd)
  190. {
  191.     PBOUNCEDATA pbd;
  192.     if(pbd = (PBOUNCEDATA)LockWindowInfo(hWnd))
  193.     {
  194.         /*
  195.         ** Determine if the balls hit any of the edges of the display.  If
  196.         ** they do, then these functions reset their position to something
  197.         ** more desireable and re-do their direction.
  198.         */
  199.         CheckEdgePosition(hWnd,pbd->hBall1);
  200.         CheckEdgePosition(hWnd,pbd->hBall2);
  201.         CheckEdgePosition(hWnd,pbd->hBall3);
  202.         CheckEdgePosition(hWnd,pbd->hBall4);
  203.         ballBounce(pbd->hBall1);
  204.         ballBounce(pbd->hBall2);
  205.         ballBounce(pbd->hBall3);
  206.         ballBounce(pbd->hBall4);
  207.         UnlockWindowInfo(hWnd);
  208.     }
  209.     return;
  210. }
  211. VOID CheckEdgePosition(HWND hWnd, HANDLE hBall)
  212. {
  213.     POINT pPos,pDir,pDim;
  214.     int   xNewPos,yNewPos,xNewDir,yNewDir;
  215.     RECT  rect;
  216.     ballGetPosition(hBall,&pPos);
  217.     ballGetDirection(hBall,&pDir);
  218.     ballGetDimensions(hBall,&pDim);
  219.     GetClientRect(hWnd,&rect);
  220.     /*
  221.     ** Check each edge of the client rectagle.  If the ball goes past the
  222.     ** boundries, reset the position and give it a new direction.
  223.     */
  224.     xNewDir = pDir.x;
  225.     yNewDir = pDir.y;
  226.     xNewPos = pPos.x+pDir.x;
  227.     yNewPos = pPos.y+pDir.y;
  228.     if(xNewPos < rect.left)
  229.     {
  230.         xNewDir = ((lRandom() % 5)+5);
  231.         ballSetPosition(hBall,rect.left,pPos.y);
  232.     }
  233.     if((xNewPos+pDim.x) > rect.right)
  234.     {
  235.         xNewDir = -(((int)lRandom() % 5)+5);
  236.         ballSetPosition(hBall,rect.right-pDim.x,pPos.y);
  237.     }
  238.     if(yNewPos < rect.top)
  239.     {
  240.         yNewDir = ((lRandom() % 5)+5);
  241.         ballSetPosition(hBall,pPos.x,rect.top);
  242.     }
  243.     if((yNewPos+pDim.y) > rect.bottom)
  244.     {
  245.         yNewDir = -(((int)lRandom() % 5)+5);
  246.         ballSetPosition(hBall,pPos.x,rect.bottom-pDim.y);
  247.     }
  248.     ballSetDirection(hBall,xNewDir,yNewDir);
  249.     return;
  250. }
  251. /*---------------------------------------------------------------------------*
  252. | CLEAR XFORM
  253. |
  254. *---------------------------------------------------------------------------*/
  255. VOID XFormClear(PMYXFORM pXForm)
  256. {
  257.     int Row,Col;
  258.     for(Row=0; Row < 3; Row++)
  259.         for(Col=0; Col < 3; Col++)
  260.             if(Row == Col)
  261.                 pXForm->xForm[Row][Col] = 1;
  262.             else
  263.                 pXForm->xForm[Row][Col] = 0;
  264.     return;
  265. }
  266. /*---------------------------------------------------------------------------*
  267. | XFORM SCALE
  268. |
  269. *---------------------------------------------------------------------------*/
  270. VOID XFormScale(PMYXFORM pXForm, int xScale, int yScale)
  271. {
  272.     int idx;
  273.     for(idx=0; idx < 3; idx++)
  274.     {
  275.         pXForm->xForm[idx][0] = pXForm->xForm[idx][0] * xScale;
  276.         pXForm->xForm[idx][1] = pXForm->xForm[idx][1] * yScale;
  277.     }
  278.     return;
  279. }
  280. VOID XFormTrans(PMYXFORM pXForm, int xTrans, int yTrans)
  281. {
  282.     pXForm->xForm[2][0] = pXForm->xForm[2][0] + xTrans;
  283.     pXForm->xForm[2][1] = pXForm->xForm[2][1] + yTrans;
  284.     return;
  285. }
  286. VOID XFormPoint(PMYXFORM pXForm, LPPOINT pPoint)
  287. {
  288.     int x,y;
  289.     x = (pXForm->xForm[0][0] * pPoint->x) + (pXForm->xForm[1][0] * pPoint->y) + pXForm->xForm[2][0];
  290.     y = (pXForm->xForm[0][1] * pPoint->x) + (pXForm->xForm[1][1] * pPoint->y) + pXForm->xForm[2][1];
  291.     pPoint->x = x;
  292.     pPoint->y = y;
  293.     return;
  294. }
  295. /*
  296. ** -------------------------------
  297. ** -------------------------------
  298. ** -------------------------------
  299. */
  300. HANDLE ballCreate(HWND hWnd, int nWidth, int nHeight, COLORREF crColor)
  301. {
  302.     HANDLE    hBall;
  303.     PBALLDATA pbd;
  304.     if(hBall = LocalAlloc(LHND,sizeof(BALLDATA)))
  305.     {
  306.         if(pbd = (PBALLDATA)LocalLock(hBall))
  307.         {
  308.             pbd->hWnd         = hWnd;
  309.             pbd->nWidth       = nWidth;
  310.             pbd->nHeight      = nHeight;
  311.             pbd->xDirection   = 0;
  312.             pbd->yDirection   = 0;
  313.             pbd->bNewPosition = FALSE;
  314.             pbd->xPosition    = 0;
  315.             pbd->yPosition    = 0;
  316.             pbd->crColor      = crColor;
  317.             XFormClear(&pbd->xForm);
  318.             LocalUnlock(hBall);
  319.             return(hBall);
  320.         }
  321.         LocalFree(hBall);
  322.     }
  323.     return(NULL);
  324. }
  325. BOOL ballDestroy(HANDLE hBall)
  326. {
  327.     if(LocalFree(hBall))
  328.         return(FALSE);
  329.     return(TRUE);
  330. }
  331. VOID ballBounce(HANDLE hBall)
  332. {
  333.     PBALLDATA pbd;
  334.     HDC       hDC;
  335.     HBRUSH    hBrush;
  336.     POINT     pOrg,pExt;
  337.     HRGN      hTmp,hOld,hNew;
  338.     if(pbd = (PBALLDATA)LocalLock(hBall))
  339.     {
  340.         /*
  341.         ** Create old ball object.
  342.         */
  343.         pOrg.x = 0;
  344.         pOrg.y = 0;
  345.         pExt.x = pbd->nWidth;
  346.         pExt.y = pbd->nHeight;
  347.         XFormPoint(&pbd->xForm,&pOrg);
  348.         XFormPoint(&pbd->xForm,&pExt);
  349.         hOld = CreateEllipticRgn(pOrg.x,pOrg.y,pExt.x,pExt.y);
  350.         /*
  351.         ** Create new ball object.
  352.         */
  353.         if(pbd->bNewPosition)
  354.         {
  355.             pbd->bNewPosition = FALSE;
  356.             XFormClear(&pbd->xForm);
  357.             XFormTrans(&pbd->xForm,pbd->xPosition,pbd->yPosition);
  358.         }
  359.         else
  360.             XFormTrans(&pbd->xForm,pbd->xDirection,pbd->yDirection);
  361.         pOrg.x = 0;
  362.         pOrg.y = 0;
  363.         pExt.x = pbd->nWidth;
  364.         pExt.y = pbd->nHeight;
  365.         XFormPoint(&pbd->xForm,&pOrg);
  366.         XFormPoint(&pbd->xForm,&pExt);
  367.         hNew = CreateEllipticRgn(pOrg.x,pOrg.y,pExt.x,pExt.y);
  368.         if(hDC = GetDC(pbd->hWnd))
  369.         {
  370.             hTmp = CreateRectRgn(1,1,2,2);
  371.             CombineRgn(hTmp,hOld,hNew,RGN_DIFF);
  372.             FillRgn(hDC,hTmp,GETCLASSBRUSH(pbd->hWnd));
  373.             hBrush = CreateSolidBrush(pbd->crColor);
  374.             FillRgn(hDC,hNew,hBrush);
  375.             DeleteObject(hBrush);
  376.             ReleaseDC(pbd->hWnd,hDC);
  377.             DeleteObject(hTmp);
  378.         }
  379.         DeleteObject(hOld);
  380.         DeleteObject(hNew);
  381.         LocalUnlock(hBall);
  382.     }
  383.     return;
  384. }
  385. BOOL ballGetDimensions(HANDLE hBall, LPPOINT pDimension)
  386. {
  387.     PBALLDATA pbd;
  388.     BOOL      bOK;
  389.     bOK = FALSE;
  390.     if(pbd = (PBALLDATA)LocalLock(hBall))
  391.     {
  392.         pDimension->x = pbd->nWidth;
  393.         pDimension->y = pbd->nHeight;
  394.         bOK = TRUE;
  395.         LocalUnlock(hBall);
  396.     }
  397.     return(bOK);
  398. }
  399. BOOL ballSetDimensions(HANDLE hBall, int nWidth, int nHeight)
  400. {
  401.     PBALLDATA pbd;
  402.     BOOL      bOK;
  403.     bOK = FALSE;
  404.     if(pbd = (PBALLDATA)LocalLock(hBall))
  405.     {
  406.         pbd->nWidth  = nWidth;
  407.         pbd->nHeight = nHeight;
  408.         bOK = TRUE;
  409.         LocalUnlock(hBall);
  410.     }
  411.     return(bOK);
  412. }
  413. BOOL ballGetDirection(HANDLE hBall, LPPOINT pDirection)
  414. {
  415.     PBALLDATA pbd;
  416.     BOOL      bOK;
  417.     bOK = FALSE;
  418.     if(pbd = (PBALLDATA)LocalLock(hBall))
  419.     {
  420.         pDirection->x = pbd->xDirection;
  421.         pDirection->y = pbd->yDirection;
  422.         bOK = TRUE;
  423.         LocalUnlock(hBall);
  424.     }
  425.     return(bOK);
  426. }
  427. BOOL ballSetDirection(HANDLE hBall, int xDirection, int yDirection)
  428. {
  429.     PBALLDATA pbd;
  430.     BOOL      bOK;
  431.     bOK = FALSE;
  432.     if(pbd = (PBALLDATA)LocalLock(hBall))
  433.     {
  434.         pbd->xDirection = xDirection;
  435.         pbd->yDirection = yDirection;
  436.         bOK = TRUE;
  437.         LocalUnlock(hBall);
  438.     }
  439.     return(bOK);
  440. }
  441. BOOL ballGetPosition(HANDLE hBall, LPPOINT pPosition)
  442. {
  443.     PBALLDATA pbd;
  444.     BOOL      bOK;
  445.     POINT     pOrg;
  446.     bOK = FALSE;
  447.     if(pbd = (PBALLDATA)LocalLock(hBall))
  448.     {
  449.         pOrg.x = 0;
  450.         pOrg.y = 0;
  451.         XFormPoint(&pbd->xForm,&pOrg);
  452.         pPosition->x = pOrg.x;
  453.         pPosition->y = pOrg.y;
  454.         bOK = TRUE;
  455.         LocalUnlock(hBall);
  456.     }
  457.     return(bOK);
  458. }
  459. BOOL ballSetPosition(HANDLE hBall, int x, int y)
  460. {
  461.     PBALLDATA pbd;
  462.     BOOL      bOK;
  463.     bOK = FALSE;
  464.     if(pbd = (PBALLDATA)LocalLock(hBall))
  465.     {
  466.         pbd->bNewPosition = TRUE;
  467.         pbd->xPosition    = x;
  468.         pbd->yPosition    = y;
  469.         bOK = TRUE;
  470.         LocalUnlock(hBall);
  471.     }
  472.     return(bOK);
  473. }