|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.