Annotation of mstools/samples/gdidemo/bounce.c, revision 1.1.1.3

1.1.1.3 ! root        1: 
        !             2: /******************************************************************************\
        !             3: *       This is a part of the Microsoft Source Code Samples. 
        !             4: *       Copyright (C) 1993 Microsoft Corporation.
        !             5: *       All rights reserved. 
        !             6: *       This source code is only intended as a supplement to 
        !             7: *       Microsoft Development Tools and/or WinHelp documentation.
        !             8: *       See these sources for detailed information regarding the 
        !             9: *       Microsoft samples programs.
        !            10: \******************************************************************************/
        !            11: 
1.1       root       12: /*---------------------------------------------------------------------------*\
                     13: | BOUNCING BALL MODULE
                     14: \*---------------------------------------------------------------------------*/
                     15: 
                     16: #include <windows.h>
                     17: #include "gdidemo.h"
                     18: #include "bounce.h"
                     19: 
                     20: 
                     21: VOID XFormClear(PMYXFORM);
                     22: VOID XFormScale(PMYXFORM,int,int);
                     23: VOID XFormTrans(PMYXFORM,int,int);
                     24: VOID XFormPoint(PMYXFORM,LPPOINT);
                     25: 
                     26: 
                     27: /*---------------------------------------------------------------------------*\
                     28: | CREATE BOUNCE WINDOW PROCEDURE
                     29: |
                     30: \*---------------------------------------------------------------------------*/
                     31: HWND FAR CreateBounceWindow(HWND hWndClient, int nItem)
                     32: {
                     33:     HANDLE          hInstance;
                     34:     MDICREATESTRUCT mcs;
                     35: 
                     36: 
                     37:     hInstance = GETINSTANCE(hWndClient);
                     38: 
                     39:     /*
                     40:     ** Initialize the MDI create struct for creation of the
                     41:     ** test window.
                     42:     */
                     43:     mcs.szClass = BOUNCECLASS;
                     44:     mcs.szTitle = BOUNCETITLE;
1.1.1.3 ! root       45:     mcs.hOwner  = hInstance;
1.1       root       46:     mcs.x       = CW_USEDEFAULT;
                     47:     mcs.y       = CW_USEDEFAULT;
                     48:     mcs.cx      = CW_USEDEFAULT;
                     49:     mcs.cy      = CW_USEDEFAULT;
1.1.1.3 ! root       50:     mcs.style   = 0l;
1.1       root       51:     mcs.lParam  = (LONG)nItem;
                     52: 
1.1.1.3 ! root       53:     return((HWND)SendMessage(hWndClient,WM_MDICREATE,0,(LONG)(LPMDICREATESTRUCT)&mcs));
1.1       root       54: }
                     55: 
                     56: 
                     57: /*---------------------------------------------------------------------------*\
                     58: | BOUNCE WINDOW PROCEDURE
                     59: |
                     60: \*---------------------------------------------------------------------------*/
                     61: LONG APIENTRY BounceProc(HWND hWnd, UINT wMsg, WPARAM wParam, LONG lParam)
                     62: {
                     63:     switch(wMsg)
                     64:     {
                     65:         case WM_CREATE:
                     66:             BounceCreateProc(hWnd);
                     67:             break;
                     68: 
                     69:         case WM_MOVE:
                     70:             BounceRefresh(hWnd);
                     71:             break;
                     72: 
                     73:         case WM_COMMAND:
                     74:             BounceCommandProc(hWnd,wParam,lParam);
                     75:             break;
                     76: 
                     77:         case WM_TIMER:
                     78:             BounceObjects(hWnd);
                     79:             break;
                     80: 
                     81:         case WM_PAINT:
                     82:             BouncePaintProc(hWnd);
                     83:             break;
                     84: 
                     85:         case WM_DESTROY:
                     86:             BounceDestroyProc(hWnd);
                     87:             break;
                     88: 
                     89: 
                     90:         default:
                     91:             return(DefMDIChildProc(hWnd,wMsg,wParam,lParam));
                     92:     }
                     93:     return(0l);
                     94: }
                     95: 
                     96: 
                     97: /*---------------------------------------------------------------------------*\
                     98: | BOUNCE CREATE PROCEDURE
                     99: |
                    100: \*---------------------------------------------------------------------------*/
                    101: BOOL BounceCreateProc(HWND hWnd)
                    102: {
                    103:     PBOUNCEDATA pbd;
                    104: 
                    105: 
                    106:     if(AllocWindowInfo(hWnd,sizeof(BOUNCEDATA)))
                    107:     {
                    108:         if(pbd = (PBOUNCEDATA)LockWindowInfo(hWnd))
                    109:         {
                    110:             pbd->hBall1 = ballCreate(hWnd,20,20,RGB(255,0,0));
                    111:             pbd->hBall2 = ballCreate(hWnd,20,20,RGB(0,0,255));
                    112:             pbd->hBall3 = ballCreate(hWnd,20,20,RGB(0,255,0));
                    113:             pbd->hBall4 = ballCreate(hWnd,20,20,RGB(255,0,255));
                    114: 
                    115:             UnlockWindowInfo(hWnd);
                    116: 
                    117:             SetTimer(hWnd,1,50,NULL);
                    118:             return(TRUE);
                    119:         }
                    120:         FreeWindowInfo(hWnd);
                    121:     }
                    122:     return(FALSE);
                    123: }
                    124: 
                    125: 
                    126: /*---------------------------------------------------------------------------*\
                    127: | BOUNCE COMMAND PROCEDURE
                    128: |
                    129: \*---------------------------------------------------------------------------*/
                    130: BOOL BounceCommandProc(HWND hWnd, WPARAM wParam, LONG lParam)
                    131: {
                    132:     hWnd   = hWnd;
                    133:     wParam = wParam;
                    134:     lParam = lParam;
                    135: 
                    136:     return(TRUE);
                    137: }
                    138: 
                    139: 
                    140: /*---------------------------------------------------------------------------*\
                    141: | BOUNCE PAINT PROCEDURE
                    142: |
                    143: \*---------------------------------------------------------------------------*/
                    144: VOID BouncePaintProc(HWND hWnd)
                    145: {
                    146:     HDC         hDC;
                    147:     PAINTSTRUCT ps;
                    148: 
                    149: 
                    150:     if(hDC = BeginPaint(hWnd,&ps))
                    151:         EndPaint(hWnd,&ps);
                    152: 
                    153:     BounceRefresh(hWnd);
                    154: 
                    155:     return;
                    156: }
                    157: 
                    158: 
                    159: /*---------------------------------------------------------------------------*\
                    160: | BOUNCE DESTROY PROCEDURE
                    161: |
                    162: \*---------------------------------------------------------------------------*/
                    163: VOID BounceDestroyProc(HWND hWnd)
                    164: {
                    165:     PBOUNCEDATA pbd;
                    166: 
                    167: 
                    168:     KillTimer(hWnd,1);
                    169:     if(pbd = (PBOUNCEDATA)LockWindowInfo(hWnd))
                    170:     {
                    171:         ballDestroy(pbd->hBall1);
                    172:         ballDestroy(pbd->hBall2);
                    173:         ballDestroy(pbd->hBall3);
                    174:         ballDestroy(pbd->hBall4);
                    175: 
                    176:         UnlockWindowInfo(hWnd);
                    177:     }
                    178:     FreeWindowInfo(hWnd);
                    179:     return;
                    180: }
                    181: 
                    182: 
                    183: /*---------------------------------------------------------------------------*\
                    184: | BOUNCE REFRESH
                    185: |
                    186: \*---------------------------------------------------------------------------*/
                    187: VOID BounceRefresh(HWND hWnd)
                    188: {
                    189:     PBOUNCEDATA pbd;
                    190:     RECT        rect;
                    191:     HDC         hDC;
                    192:     POINT       pDimensions;
                    193:     int         xDirection,yDirection;
                    194: 
                    195: 
                    196:     if(pbd = (PBOUNCEDATA)LockWindowInfo(hWnd))
                    197:     {
                    198:         if(hDC = GetDC(hWnd))
                    199:         {
                    200:             GetClientRect(hWnd,&rect);
                    201:             FillRect(hDC,&rect,GETCLASSBRUSH(hWnd));
                    202: 
                    203:             xDirection = ((lRandom() % 5)+5);
                    204:             yDirection = ((lRandom() % 5)+5);
                    205:             ballSetPosition(pbd->hBall1,0,0);
                    206:             ballSetDirection(pbd->hBall1,xDirection,yDirection);
                    207: 
                    208: 
                    209:             ballGetDimensions(pbd->hBall2,&pDimensions);
                    210:             ballSetPosition(pbd->hBall2,rect.right-pDimensions.x,0);
1.1.1.3 ! root      211:             xDirection = -(((int)lRandom() % 5)+5);
1.1       root      212:             yDirection =  ((lRandom() % 5)+5);
                    213:             ballSetDirection(pbd->hBall2,xDirection,yDirection);
                    214: 
                    215: 
                    216:             ballGetDimensions(pbd->hBall3,&pDimensions);
                    217:             ballSetPosition(pbd->hBall3,0,rect.bottom-pDimensions.y);
                    218:             xDirection =  ((lRandom() % 5)+5);
1.1.1.3 ! root      219:             yDirection = -((int)(lRandom() % 5)+5);
1.1       root      220:             ballSetDirection(pbd->hBall3,xDirection,yDirection);
                    221: 
                    222: 
                    223:             ballGetDimensions(pbd->hBall4,&pDimensions);
                    224:             ballSetPosition(pbd->hBall4,rect.right-pDimensions.x,rect.bottom-pDimensions.y);
1.1.1.3 ! root      225:             xDirection = -((int)(lRandom() % 5)+5);
        !           226:             yDirection = -((int)(lRandom() % 5)+5);
1.1       root      227:             ballSetDirection(pbd->hBall4,xDirection,yDirection);
                    228: 
                    229: 
                    230:             ballBounce(pbd->hBall1);
                    231:             ballBounce(pbd->hBall2);
                    232:             ballBounce(pbd->hBall3);
                    233:             ballBounce(pbd->hBall4);
                    234: 
                    235:             ReleaseDC(hWnd,hDC);
                    236:         }
                    237:         UnlockWindowInfo(hWnd);
                    238:     }
                    239:     return;
                    240: }
                    241: 
                    242: 
                    243: 
                    244: VOID BounceObjects(HWND hWnd)
                    245: {
                    246:     PBOUNCEDATA pbd;
                    247: 
                    248: 
                    249:     if(pbd = (PBOUNCEDATA)LockWindowInfo(hWnd))
                    250:     {
                    251:         /*
                    252:         ** Determine if the balls hit any of the edges of the display.  If
                    253:         ** they do, then these functions reset their position to something
                    254:         ** more desireable and re-do their direction.
                    255:         */
                    256:         CheckEdgePosition(hWnd,pbd->hBall1);
                    257:         CheckEdgePosition(hWnd,pbd->hBall2);
                    258:         CheckEdgePosition(hWnd,pbd->hBall3);
                    259:         CheckEdgePosition(hWnd,pbd->hBall4);
                    260: 
                    261:         ballBounce(pbd->hBall1);
                    262:         ballBounce(pbd->hBall2);
                    263:         ballBounce(pbd->hBall3);
                    264:         ballBounce(pbd->hBall4);
                    265: 
                    266: 
                    267:         UnlockWindowInfo(hWnd);
                    268:     }
                    269:     return;
                    270: }
                    271: 
                    272: 
                    273: VOID CheckEdgePosition(HWND hWnd, HANDLE hBall)
                    274: {
                    275:     POINT pPos,pDir,pDim;
                    276:     int   xNewPos,yNewPos,xNewDir,yNewDir;
                    277:     RECT  rect;
                    278: 
                    279: 
                    280: 
                    281:     ballGetPosition(hBall,&pPos);
                    282:     ballGetDirection(hBall,&pDir);
                    283:     ballGetDimensions(hBall,&pDim);
                    284: 
                    285:     GetClientRect(hWnd,&rect);
                    286: 
                    287: 
                    288:     /*
                    289:     ** Check each edge of the client rectagle.  If the ball goes past the
                    290:     ** boundries, reset the position and give it a new direction.
                    291:     */
                    292:     xNewDir = pDir.x;
                    293:     yNewDir = pDir.y;
                    294:     xNewPos = pPos.x+pDir.x;
                    295:     yNewPos = pPos.y+pDir.y;
                    296: 
                    297:     if(xNewPos < rect.left)
                    298:     {
                    299:         xNewDir = ((lRandom() % 5)+5);
                    300:         ballSetPosition(hBall,rect.left,pPos.y);
                    301:     }
                    302:     if((xNewPos+pDim.x) > rect.right)
                    303:     {
1.1.1.3 ! root      304:         xNewDir = -(((int)lRandom() % 5)+5);
1.1       root      305:         ballSetPosition(hBall,rect.right-pDim.x,pPos.y);
                    306:     }
                    307:     if(yNewPos < rect.top)
                    308:     {
                    309:         yNewDir = ((lRandom() % 5)+5);
                    310:         ballSetPosition(hBall,pPos.x,rect.top);
                    311:     }
                    312:     if((yNewPos+pDim.y) > rect.bottom)
                    313:     {
1.1.1.3 ! root      314:         yNewDir = -(((int)lRandom() % 5)+5);
1.1       root      315:         ballSetPosition(hBall,pPos.x,rect.bottom-pDim.y);
                    316:     }
                    317:     ballSetDirection(hBall,xNewDir,yNewDir);
                    318: 
                    319:     return;
                    320: }
                    321: 
                    322: 
                    323: /*---------------------------------------------------------------------------*\
                    324: | CLEAR XFORM
                    325: |
                    326: \*---------------------------------------------------------------------------*/
                    327: VOID XFormClear(PMYXFORM pXForm)
                    328: {
                    329:     int Row,Col;
                    330: 
                    331: 
                    332:     for(Row=0; Row < 3; Row++)
                    333:         for(Col=0; Col < 3; Col++)
                    334:             if(Row == Col)
                    335:                 pXForm->xForm[Row][Col] = 1;
                    336:             else
                    337:                 pXForm->xForm[Row][Col] = 0;
                    338:     return;
                    339: }
                    340: 
                    341: 
                    342: /*---------------------------------------------------------------------------*\
                    343: | XFORM SCALE
                    344: |
                    345: \*---------------------------------------------------------------------------*/
                    346: VOID XFormScale(PMYXFORM pXForm, int xScale, int yScale)
                    347: {
                    348:     int idx;
                    349: 
                    350: 
                    351:     for(idx=0; idx < 3; idx++)
                    352:     {
                    353:         pXForm->xForm[idx][0] = pXForm->xForm[idx][0] * xScale;
                    354:         pXForm->xForm[idx][1] = pXForm->xForm[idx][1] * yScale;
                    355:     }
                    356:     return;
                    357: }
                    358: 
                    359: 
                    360: 
                    361: VOID XFormTrans(PMYXFORM pXForm, int xTrans, int yTrans)
                    362: {
                    363:     pXForm->xForm[2][0] = pXForm->xForm[2][0] + xTrans;
                    364:     pXForm->xForm[2][1] = pXForm->xForm[2][1] + yTrans;
                    365: 
                    366:     return;
                    367: }
                    368: 
                    369: 
                    370: 
                    371: VOID XFormPoint(PMYXFORM pXForm, LPPOINT pPoint)
                    372: {
                    373:     int x,y;
                    374: 
                    375: 
                    376:     x = (pXForm->xForm[0][0] * pPoint->x) + (pXForm->xForm[1][0] * pPoint->y) + pXForm->xForm[2][0];
                    377:     y = (pXForm->xForm[0][1] * pPoint->x) + (pXForm->xForm[1][1] * pPoint->y) + pXForm->xForm[2][1];
                    378: 
                    379:     pPoint->x = x;
                    380:     pPoint->y = y;
                    381: 
                    382:     return;
                    383: }
                    384: 
                    385: 
                    386: /*
                    387: ** -------------------------------
                    388: ** -------------------------------
                    389: ** -------------------------------
                    390: */
                    391: 
                    392: HANDLE ballCreate(HWND hWnd, int nWidth, int nHeight, COLORREF crColor)
                    393: {
                    394:     HANDLE    hBall;
                    395:     PBALLDATA pbd;
                    396: 
                    397:     if(hBall = LocalAlloc(LHND,sizeof(BALLDATA)))
                    398:     {
                    399:         if(pbd = (PBALLDATA)LocalLock(hBall))
                    400:         {
                    401:             pbd->hWnd         = hWnd;
                    402:             pbd->nWidth       = nWidth;
                    403:             pbd->nHeight      = nHeight;
                    404:             pbd->xDirection   = 0;
                    405:             pbd->yDirection   = 0;
                    406:             pbd->bNewPosition = FALSE;
                    407:             pbd->xPosition    = 0;
                    408:             pbd->yPosition    = 0;
                    409:             pbd->crColor      = crColor;
                    410:             XFormClear(&pbd->xForm);
                    411: 
                    412:             LocalUnlock(hBall);
                    413:             return(hBall);
                    414:         }
                    415:         LocalFree(hBall);
                    416:     }
                    417:     return(NULL);
                    418: }
                    419: 
                    420: 
                    421: BOOL ballDestroy(HANDLE hBall)
                    422: {
                    423:     if(LocalFree(hBall))
                    424:         return(FALSE);
                    425:     return(TRUE);
                    426: }
                    427: 
                    428: 
                    429: VOID ballBounce(HANDLE hBall)
                    430: {
                    431:     PBALLDATA pbd;
                    432:     HDC       hDC;
                    433:     HBRUSH    hBrush;
                    434:     POINT     pOrg,pExt;
                    435:     HRGN      hTmp,hOld,hNew;
                    436: 
                    437: 
                    438:     if(pbd = (PBALLDATA)LocalLock(hBall))
                    439:     {
                    440:         /*
                    441:         ** Create old ball object.
                    442:         */
                    443:         pOrg.x = 0;
                    444:         pOrg.y = 0;
                    445:         pExt.x = pbd->nWidth;
                    446:         pExt.y = pbd->nHeight;
                    447:         XFormPoint(&pbd->xForm,&pOrg);
                    448:         XFormPoint(&pbd->xForm,&pExt);
                    449:         hOld = CreateEllipticRgn(pOrg.x,pOrg.y,pExt.x,pExt.y);
                    450: 
                    451: 
                    452:         /*
                    453:         ** Create new ball object.
                    454:         */
                    455:         if(pbd->bNewPosition)
                    456:         {
                    457:             pbd->bNewPosition = FALSE;
                    458:             XFormClear(&pbd->xForm);
                    459:             XFormTrans(&pbd->xForm,pbd->xPosition,pbd->yPosition);
                    460:         }
                    461:         else
                    462:             XFormTrans(&pbd->xForm,pbd->xDirection,pbd->yDirection);
                    463:         pOrg.x = 0;
                    464:         pOrg.y = 0;
                    465:         pExt.x = pbd->nWidth;
                    466:         pExt.y = pbd->nHeight;
                    467:         XFormPoint(&pbd->xForm,&pOrg);
                    468:         XFormPoint(&pbd->xForm,&pExt);
                    469:         hNew = CreateEllipticRgn(pOrg.x,pOrg.y,pExt.x,pExt.y);
                    470: 
                    471: 
                    472: 
                    473:         if(hDC = GetDC(pbd->hWnd))
                    474:         {
                    475:             hTmp = CreateRectRgn(1,1,2,2);
                    476:             CombineRgn(hTmp,hOld,hNew,RGN_DIFF);
                    477:             FillRgn(hDC,hTmp,GETCLASSBRUSH(pbd->hWnd));
                    478: 
                    479:             hBrush = CreateSolidBrush(pbd->crColor);
                    480:             FillRgn(hDC,hNew,hBrush);
                    481:             DeleteObject(hBrush);
                    482: 
                    483:             ReleaseDC(pbd->hWnd,hDC);
                    484: 
                    485:             DeleteObject(hTmp);
                    486:         }
                    487: 
                    488:         DeleteObject(hOld);
                    489:         DeleteObject(hNew);
                    490: 
                    491:         LocalUnlock(hBall);
                    492:     }
                    493:     return;
                    494: }
                    495: 
                    496: 
                    497: BOOL ballGetDimensions(HANDLE hBall, LPPOINT pDimension)
                    498: {
                    499:     PBALLDATA pbd;
                    500:     BOOL      bOK;
                    501: 
                    502: 
                    503:     bOK = FALSE;
                    504:     if(pbd = (PBALLDATA)LocalLock(hBall))
                    505:     {
                    506:         pDimension->x = pbd->nWidth;
                    507:         pDimension->y = pbd->nHeight;
                    508: 
                    509:         bOK = TRUE;
                    510:         LocalUnlock(hBall);
                    511:     }
                    512:     return(bOK);
                    513: }
                    514: 
                    515: 
                    516: BOOL ballSetDimensions(HANDLE hBall, int nWidth, int nHeight)
                    517: {
                    518:     PBALLDATA pbd;
                    519:     BOOL      bOK;
                    520: 
                    521: 
                    522:     bOK = FALSE;
                    523:     if(pbd = (PBALLDATA)LocalLock(hBall))
                    524:     {
                    525:         pbd->nWidth  = nWidth;
                    526:         pbd->nHeight = nHeight;
                    527: 
                    528:         bOK = TRUE;
                    529:         LocalUnlock(hBall);
                    530:     }
                    531:     return(bOK);
                    532: }
                    533: 
                    534: 
                    535: BOOL ballGetDirection(HANDLE hBall, LPPOINT pDirection)
                    536: {
                    537:     PBALLDATA pbd;
                    538:     BOOL      bOK;
                    539: 
                    540: 
                    541:     bOK = FALSE;
                    542:     if(pbd = (PBALLDATA)LocalLock(hBall))
                    543:     {
                    544:         pDirection->x = pbd->xDirection;
                    545:         pDirection->y = pbd->yDirection;
                    546: 
                    547:         bOK = TRUE;
                    548:         LocalUnlock(hBall);
                    549:     }
                    550:     return(bOK);
                    551: }
                    552: 
                    553: 
                    554: BOOL ballSetDirection(HANDLE hBall, int xDirection, int yDirection)
                    555: {
                    556:     PBALLDATA pbd;
                    557:     BOOL      bOK;
                    558: 
                    559: 
                    560:     bOK = FALSE;
                    561:     if(pbd = (PBALLDATA)LocalLock(hBall))
                    562:     {
                    563:         pbd->xDirection = xDirection;
                    564:         pbd->yDirection = yDirection;
                    565: 
                    566:         bOK = TRUE;
                    567:         LocalUnlock(hBall);
                    568:     }
                    569:     return(bOK);
                    570: }
                    571: 
                    572: 
                    573: BOOL ballGetPosition(HANDLE hBall, LPPOINT pPosition)
                    574: {
                    575:     PBALLDATA pbd;
                    576:     BOOL      bOK;
                    577:     POINT     pOrg;
                    578: 
                    579: 
                    580:     bOK = FALSE;
                    581:     if(pbd = (PBALLDATA)LocalLock(hBall))
                    582:     {
                    583:         pOrg.x = 0;
                    584:         pOrg.y = 0;
                    585:         XFormPoint(&pbd->xForm,&pOrg);
                    586: 
                    587:         pPosition->x = pOrg.x;
                    588:         pPosition->y = pOrg.y;
                    589: 
                    590:         bOK = TRUE;
                    591:         LocalUnlock(hBall);
                    592:     }
                    593:     return(bOK);
                    594: }
                    595: 
                    596: 
                    597: BOOL ballSetPosition(HANDLE hBall, int x, int y)
                    598: {
                    599:     PBALLDATA pbd;
                    600:     BOOL      bOK;
                    601: 
                    602: 
                    603:     bOK = FALSE;
                    604:     if(pbd = (PBALLDATA)LocalLock(hBall))
                    605:     {
                    606:         pbd->bNewPosition = TRUE;
                    607:         pbd->xPosition    = x;
                    608:         pbd->yPosition    = y;
                    609: 
                    610:         bOK = TRUE;
                    611:         LocalUnlock(hBall);
                    612:     }
                    613:     return(bOK);
                    614: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.