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

Windows编程

开发平台:

Visual C++

  1. /*==========================================================================
  2.  *
  3.  *  Copyright (C) 1997 Microsoft Corporation.  All Rights Reserved.
  4.  *
  5.  *  File:       client.cpp
  6.  *  Content: Slot machine client using DirectPlay.
  7.  *
  8.  ***************************************************************************/
  9. #include <windows.h>
  10. #include <windowsx.h>
  11. #include <stdio.h>
  12. #include "dpslots.h"
  13. #include "resource.h"
  14. // constants
  15. const DWORD SLOTWIDTH = 110; // width of slot
  16. const DWORD SLOTHEIGHT = 119; // height of slot
  17. const DWORD SLOTBORDER = 9; // space between slots
  18. const DWORD REVSPERSECOND = 1; // no. revolutions per second
  19. const DWORD PIXELSPERSLOT = SLOTHEIGHT - SLOTBORDER; // no. vertical pixels per slot
  20. const DWORD PIXELSPERREV = PIXELSPERSLOT * SLOTSPERWHEEL;// no. vertical pixels drawn per revolution
  21. const DWORD PIXELSPERSECOND = PIXELSPERREV * REVSPERSECOND; // no. vertical pixels drawn per second
  22. const UINT TIMERID = 1; // timer ID to use
  23. const UINT TIMERINTERVAL = 50; // timer interval
  24. const UINT MAXSTRING = 200; // max size of a string
  25. // window messages
  26. const UINT WM_USER_UPDATEBALANCE = WM_USER + BALANCERESPONSE;
  27. const UINT WM_USER_STARTSPINNING = WM_USER + SPINRESPONSE;
  28. // structures
  29. typedef struct {
  30. DWORD dwIndex; // index of wheel slot to show
  31.     DWORD dwStartTicks; // time wheel started spinning
  32. DWORD dwDuration; // duration wheel should spin
  33. } WHEELINFO, *LPWHEELINFO;
  34. // globals
  35. HWND ghClientWnd = NULL; // main window
  36. // prototypes
  37. HRESULT SendBalanceRequest(LPDPLAYINFO lpDPInfo);
  38. HRESULT SendSpinRequest(LPDPLAYINFO lpDPInfo, DWORD dwAmountBet);
  39. void DrawWheels(LPWHEELINFO lpWheels, HBITMAP hWheelBitmap,
  40.    HDC hDC, LPRECT lpBoundsRect);
  41. void StartSpinning(LPWHEELINFO lpWheels);
  42. BOOL SpinWheels(HWND hWnd, LPWHEELINFO lpWheels, HBITMAP hWheelBitmap);
  43. BOOL CALLBACK ClientWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  44. {
  45. static LPDPLAYINFO lpDPInfo = NULL;
  46. static UINT idTimer = 0;
  47. static HBITMAP hWheelBitmap = NULL;
  48. static WHEELINFO WheelInfo[NUMWHEELS];
  49. static MSG_SPINRESPONSE SpinResponse;
  50. CHAR szStr[MAXSTRING];
  51. DWORD i;
  52. DWORD dwAmountBet;
  53.     switch(uMsg)
  54.     {
  55.     case WM_INITDIALOG:
  56.         // save the connection info pointer
  57.         lpDPInfo = (LPDPLAYINFO) lParam;
  58. // store global window
  59. ghClientWnd = hWnd;
  60. // get slots bitmap
  61. hWheelBitmap = LoadBitmap(ghInstance, MAKEINTRESOURCE(IDB_SLOTSBITMAP));
  62. // initialize slots
  63. for (i = 0; i < NUMWHEELS; i++)
  64. WheelInfo[i].dwIndex = ((DWORD)rand()) % SLOTSPERWHEEL;
  65.         // get starting balance
  66. SendBalanceRequest(lpDPInfo);
  67. break;
  68.     case WM_DESTROY:
  69. // stop the timer
  70. if (idTimer)
  71. {
  72. KillTimer(hWnd, idTimer); 
  73. idTimer = 0;
  74. }
  75. // free the bitmap handle
  76. if (hWheelBitmap)
  77. {
  78. DeleteObject(hWheelBitmap);
  79. hWheelBitmap = NULL;
  80. }
  81. ghClientWnd = NULL;
  82.         break;
  83. case WM_USER_UPDATEBALANCE:
  84. // balance is in lParam
  85.         sprintf(szStr, "$%4d", lParam);
  86.         // display new balance
  87. SetDlgItemText(hWnd, IDC_EDIT_BALANCE, szStr);
  88. break;
  89. case WM_USER_STARTSPINNING:
  90. // copy spin response message from lParam
  91. SpinResponse = *((LPMSG_SPINRESPONSE) lParam);
  92. GlobalFreePtr((LPVOID) lParam); // free memory
  93. // check for valid spin
  94. if FAILED(SpinResponse.hr)
  95. {
  96. SetDlgItemText(hWnd, IDC_RESULTEDIT, "You don't have enough money!");
  97. }
  98. else
  99. {
  100. // copy slot settings specified by server
  101. for (i = 0; i < NUMWHEELS; i++)
  102. WheelInfo[i].dwIndex = SpinResponse.dwIndex[i];
  103. // clear win or lose
  104. SetDlgItemText(hWnd, IDC_RESULTEDIT, "");
  105. // start things spinning
  106. StartSpinning(WheelInfo);
  107. idTimer = SetTimer(hWnd, TIMERID, TIMERINTERVAL, NULL);
  108. // disable spin button while spinning
  109. EnableDlgButton(hWnd, IDC_SPINBUTTON, FALSE);
  110. }
  111. break;
  112. case WM_TIMER:
  113. // readraw any spinning wheels
  114. if (!SpinWheels(hWnd, WheelInfo, hWheelBitmap))
  115. {
  116. KillTimer(hWnd, idTimer); 
  117. idTimer = 0;
  118. // display amount won or lost
  119. if (SpinResponse.dwAmountWonOrLost > 0)
  120. {
  121. sprintf(szStr,"You win $%d!", SpinResponse.dwAmountWonOrLost);
  122. PlaySound(MAKEINTRESOURCE(IDR_WINWAVE), ghInstance, SND_ASYNC | SND_RESOURCE);
  123. }
  124. else if (SpinResponse.dwAmountWonOrLost < 0)
  125. {
  126. sprintf(szStr,"You lose $%d!", -SpinResponse.dwAmountWonOrLost);
  127. PlaySound(MAKEINTRESOURCE(IDR_LOSEWAVE), ghInstance, SND_ASYNC | SND_RESOURCE);
  128. }
  129. else
  130. {
  131. strcpy(szStr, "");
  132. }
  133. // display win or loss
  134. SetDlgItemText(hWnd, IDC_RESULTEDIT, szStr);
  135. PostMessage(hWnd, WM_USER_UPDATEBALANCE, (WPARAM) 0, (LPARAM) SpinResponse.dwBalance);
  136. // enable spin button again
  137. EnableDlgButton(hWnd, IDC_SPINBUTTON, TRUE);
  138. }
  139. break;
  140.     case WM_DRAWITEM:
  141. {
  142. DRAWITEMSTRUCT *diInfo;
  143. diInfo = (DRAWITEMSTRUCT *) lParam;
  144. switch (diInfo->CtlID)
  145. {
  146. case IDC_SLOTS:
  147. if (diInfo->itemAction == ODA_DRAWENTIRE)
  148. {
  149. DrawWheels(WheelInfo, hWheelBitmap, diInfo->hDC, &diInfo->rcItem);
  150. }
  151. break;
  152. }
  153. }
  154. break;
  155. case WM_COMMAND:
  156.         switch(LOWORD(wParam))
  157.         {
  158. case IDC_SPINBUTTON:
  159. // find out how much was bet
  160. dwAmountBet = 0;
  161. // one dollar
  162. if (DlgItemIsChecked(hWnd, IDC_BET1CHECK))
  163. dwAmountBet += 1;
  164. // five dollars
  165. if (DlgItemIsChecked(hWnd, IDC_BET2CHECK))
  166. dwAmountBet += 5;
  167. // ten dollars
  168. if (DlgItemIsChecked(hWnd, IDC_BET3CHECK))
  169. dwAmountBet += 10;
  170. // ask server for results of spin using this bet
  171.             SendSpinRequest(lpDPInfo, dwAmountBet);            
  172. break;
  173.         case IDCANCEL:
  174. EndDialog(hWnd, FALSE);
  175.             break;
  176. }
  177. break;
  178. }
  179.     // Allow for default processing
  180.     return FALSE;
  181. }
  182. void ClientApplicationMessage(LPDPLAYINFO lpDPInfo, LPDPMSG_GENERIC lpMsg, DWORD dwMsgSize,
  183.   DPID idFrom, DPID idTo)
  184. {
  185. switch (lpMsg->dwType)
  186. {
  187.     case BALANCERESPONSE:
  188.         {
  189.             LPMSG_BALANCERESPONSE lpBalance = (LPMSG_BALANCERESPONSE)lpMsg;
  190.   PostMessage(ghClientWnd, WM_USER_UPDATEBALANCE, (WPARAM) 0, (LPARAM) lpBalance->dwBalance);
  191.         }
  192.         break;
  193.     case SPINRESPONSE:
  194.         {
  195.             LPMSG_SPINRESPONSE lpSpin = (LPMSG_SPINRESPONSE)lpMsg;
  196.             LPMSG_SPINRESPONSE lpSpinCopy;
  197. // make a copy of the message so we can pass it to the wndproc
  198. lpSpinCopy = (LPMSG_SPINRESPONSE) GlobalAllocPtr(GHND, sizeof(MSG_SPINRESPONSE));
  199. if (lpSpinCopy == NULL)
  200. break;
  201. *lpSpinCopy = *lpSpin;
  202.             PostMessage(ghClientWnd, WM_USER_STARTSPINNING, (WPARAM) 0, (LPARAM) lpSpinCopy);
  203.         }
  204.         break;
  205.     default:
  206.         break; 
  207. }
  208. }
  209. void ClientSystemMessage(LPDPLAYINFO lpDPInfo, LPDPMSG_GENERIC lpMsg, DWORD dwMsgSize,
  210.  DPID idFrom, DPID idTo)
  211. {
  212.     // The body of each case is there so you can set a breakpoint and examine
  213.     // the contents of the message received.
  214. switch (lpMsg->dwType)
  215. {
  216. case DPSYS_CREATEPLAYERORGROUP:
  217.         {
  218.             LPDPMSG_CREATEPLAYERORGROUP lp = (LPDPMSG_CREATEPLAYERORGROUP) lpMsg;
  219.         }
  220. break;
  221. case DPSYS_DESTROYPLAYERORGROUP:
  222.         {
  223.             LPDPMSG_DESTROYPLAYERORGROUP lp = (LPDPMSG_DESTROYPLAYERORGROUP)lpMsg;
  224.         }
  225. break;
  226. case DPSYS_ADDPLAYERTOGROUP:
  227.         {
  228.             LPDPMSG_ADDPLAYERTOGROUP lp = (LPDPMSG_ADDPLAYERTOGROUP)lpMsg;
  229.         }
  230. break;
  231. case DPSYS_DELETEPLAYERFROMGROUP:
  232.         {
  233.             LPDPMSG_DELETEPLAYERFROMGROUP lp = (LPDPMSG_DELETEPLAYERFROMGROUP)lpMsg;
  234.         }
  235. break;
  236. case DPSYS_SESSIONLOST:
  237.         {
  238.             LPDPMSG_SESSIONLOST lp = (LPDPMSG_SESSIONLOST)lpMsg;
  239.         }
  240. break;
  241. case DPSYS_HOST:
  242.         {
  243.             LPDPMSG_HOST lp = (LPDPMSG_HOST)lpMsg;
  244.         }
  245. break;
  246. case DPSYS_SETPLAYERORGROUPDATA:
  247.         {
  248.             LPDPMSG_SETPLAYERORGROUPDATA lp = (LPDPMSG_SETPLAYERORGROUPDATA)lpMsg;
  249.         }
  250. break;
  251. case DPSYS_SETPLAYERORGROUPNAME:
  252.         {
  253.             LPDPMSG_SETPLAYERORGROUPNAME lp = (LPDPMSG_SETPLAYERORGROUPNAME)lpMsg;
  254.         }
  255. break;
  256. case DPSYS_SECUREMESSAGE:
  257.         {
  258.             LPDPMSG_SECUREMESSAGE lp = (LPDPMSG_SECUREMESSAGE)lpMsg;
  259. ClientApplicationMessage(lpDPInfo, (LPDPMSG_GENERIC) lp->lpData, lp->dwDataSize,
  260.   lp->dpIdFrom, idTo);
  261.         }
  262. break;
  263. }
  264. }
  265. HRESULT SendBalanceRequest(LPDPLAYINFO lpDPInfo)
  266. {
  267.     MSG_BALANCEREQUEST Msg;
  268.     ZeroMemory(&Msg, sizeof(MSG_BALANCEREQUEST));
  269.     Msg.dwType = BALANCEREQUEST;
  270.     return (lpDPInfo->lpDirectPlay3A->Send(lpDPInfo->dpidPlayer,
  271. DPID_SERVERPLAYER, SENDFLAGS(lpDPInfo->bIsSecure),
  272. &Msg, sizeof(MSG_BALANCEREQUEST)));
  273. }
  274. HRESULT SendSpinRequest(LPDPLAYINFO lpDPInfo, DWORD dwAmountBet)
  275. {
  276.     MSG_SPINREQUEST Msg;
  277.     ZeroMemory(&Msg, sizeof(MSG_SPINREQUEST));
  278.     Msg.dwType = SPINREQUEST;
  279. Msg.dwAmountBet = dwAmountBet;
  280.     return (lpDPInfo->lpDirectPlay3A->Send(lpDPInfo->dpidPlayer,
  281. DPID_SERVERPLAYER, SENDFLAGS(lpDPInfo->bIsSecure),
  282. &Msg, sizeof(MSG_SPINREQUEST)));
  283. }
  284. #define RECTWIDTH(lpRect)     ((lpRect)->right - (lpRect)->left)
  285. #define RECTHEIGHT(lpRect)    ((lpRect)->bottom - (lpRect)->top)
  286. BOOL PaintBitmap(HDC hDC, LPRECT lpDCRect, HBITMAP hDDB,  LPRECT lpDDBRect)
  287. {
  288.     HDC         hMemDC;            // Handle to memory DC
  289.     HBITMAP     hOldBitmap;        // Handle to previous bitmap
  290.     BOOL        bSuccess = FALSE;  // Success/fail flag
  291.     // Create a memory DC
  292.     hMemDC = CreateCompatibleDC(hDC);
  293.     // If this failed, return FALSE
  294.     if (!hMemDC)
  295.         return FALSE;
  296.     // Select bitmap into the memory DC
  297.     hOldBitmap = (HBITMAP) SelectObject (hMemDC, hDDB);
  298.     // Make sure to use the stretching mode best for color pictures
  299.     SetStretchBltMode (hDC, COLORONCOLOR);
  300.     // Determine whether to call StretchBlt() or BitBlt()
  301.     if ((RECTWIDTH(lpDCRect)  == RECTWIDTH(lpDDBRect)) &&
  302.             (RECTHEIGHT(lpDCRect) == RECTHEIGHT(lpDDBRect)))
  303.         bSuccess = BitBlt(hDC, lpDCRect->left, lpDCRect->top,
  304.                 lpDCRect->right - lpDCRect->left,
  305.                 lpDCRect->bottom - lpDCRect->top, hMemDC, lpDDBRect->left,
  306.                 lpDDBRect->top, SRCCOPY);
  307.     else
  308.         bSuccess = StretchBlt(hDC, lpDCRect->left,  lpDCRect->top, 
  309.                 lpDCRect->right - lpDCRect->left,
  310.                 lpDCRect->bottom - lpDCRect->top, hMemDC, lpDDBRect->left, 
  311.                 lpDDBRect->top,  lpDDBRect->right - lpDDBRect->left,
  312.                 lpDDBRect->bottom - lpDDBRect->top, SRCCOPY);
  313.     // Clean up
  314.     SelectObject(hMemDC, hOldBitmap);
  315.     DeleteDC(hMemDC);
  316.     // Return with success/fail flag
  317.     return bSuccess;
  318. }
  319. void DrawWheels(LPWHEELINFO lpWheels, HBITMAP hWheelBitmap, HDC hDC, LPRECT lpBoundsRect)
  320. {
  321. RECT rectDC, rectSlot;
  322. DWORD dwWidth, dwHeight, dwXOffset, dwYOffset;
  323. DWORD i;
  324. if (hWheelBitmap == NULL)
  325. return;
  326. dwWidth = lpBoundsRect->right - lpBoundsRect->left;
  327. dwHeight = lpBoundsRect->bottom - lpBoundsRect->top;
  328. dwXOffset = (dwWidth - (SLOTWIDTH * NUMWHEELS)) / (NUMWHEELS + 1);
  329. dwYOffset = (dwHeight - SLOTHEIGHT) / 2;
  330. SetRect(&rectDC, dwXOffset, dwYOffset,
  331. dwXOffset + SLOTWIDTH, dwYOffset + SLOTHEIGHT);
  332. for (i = 0; i < NUMWHEELS; i++)
  333. {
  334. SetRect(&rectSlot, 0, 0, SLOTWIDTH, SLOTHEIGHT);
  335. OffsetRect(&rectSlot, 0, lpWheels[i].dwIndex * PIXELSPERSLOT);
  336. PaintBitmap(hDC, &rectDC, hWheelBitmap, &rectSlot);
  337. OffsetRect(&rectDC, SLOTWIDTH + dwXOffset, 0);
  338. }
  339. }
  340. void StartSpinning(LPWHEELINFO lpWheels)
  341. {
  342. DWORD i;
  343. for (i = 0; i < NUMWHEELS; i++)
  344. {
  345. lpWheels[i].dwStartTicks = GetTickCount();
  346. lpWheels[i].dwStartTicks -= lpWheels[i].dwIndex * PIXELSPERSLOT * 1000 / PIXELSPERREV;
  347. lpWheels[i].dwDuration = 1000 * (i + 1) + 1000;
  348. }
  349. }
  350. BOOL SpinWheels(HWND hWnd, LPWHEELINFO lpWheels, HBITMAP hWheelBitmap)
  351. {
  352. HDC hDC;
  353. RECT rectBounds;
  354. LPRECT lpBoundsRect;
  355. RECT rectDC, rectSlot;
  356. DWORD dwWidth, dwHeight, dwXOffset, dwYOffset, dwYStart;
  357. DWORD i, dwTicks, dwStoppedCount;
  358. if (hWheelBitmap == NULL)
  359. return (FALSE);
  360. hDC = GetWindowDC(GetDlgItem(hWnd, IDC_SLOTS));
  361. if (hDC == NULL)
  362. return (FALSE);
  363. if (!GetWindowRect(GetDlgItem(hWnd, IDC_SLOTS), &rectBounds))
  364. return (FALSE);
  365. lpBoundsRect = &rectBounds;
  366. dwWidth = lpBoundsRect->right - lpBoundsRect->left;
  367. dwHeight = lpBoundsRect->bottom - lpBoundsRect->top;
  368. dwXOffset = (dwWidth - (SLOTWIDTH * NUMWHEELS)) / (NUMWHEELS + 1);
  369. dwYOffset = (dwHeight - SLOTHEIGHT) / 2;
  370. SetRect(&rectDC, dwXOffset, dwYOffset,
  371. dwXOffset + SLOTWIDTH, dwYOffset + SLOTHEIGHT);
  372. dwStoppedCount = 0;
  373. for (i = 0; i < NUMWHEELS; i++)
  374. {
  375. if (lpWheels[i].dwDuration == 0)
  376. {
  377. dwStoppedCount++;
  378. }
  379. else
  380. {
  381. dwTicks = GetTickCount() - lpWheels[i].dwStartTicks;
  382. dwYStart = (dwTicks * PIXELSPERSECOND) / 1000;
  383. dwYStart %= PIXELSPERREV;
  384. if (dwTicks >= lpWheels[i].dwDuration)
  385. {
  386. // lpWheels[i].value = ((dwYStart + (PIXELSPERSLOT - 1)) / PIXELSPERSLOT) % SLOTSPERWHEEL;
  387. SetRect(&rectSlot, 0, 0, SLOTWIDTH, SLOTHEIGHT);
  388. OffsetRect(&rectSlot, 0, lpWheels[i].dwIndex * PIXELSPERSLOT);
  389. PaintBitmap(hDC, &rectDC, hWheelBitmap, &rectSlot);
  390. lpWheels[i].dwDuration = 0;
  391.                 if (dwStoppedCount == (NUMWHEELS - 1))
  392.                     PlaySound(MAKEINTRESOURCE(IDR_STOPWAVE), ghInstance, SND_RESOURCE);
  393.                 else
  394.                     PlaySound(MAKEINTRESOURCE(IDR_STOPWAVE), ghInstance, SND_ASYNC | SND_RESOURCE);
  395.             }
  396. else
  397. {
  398. SetRect(&rectSlot, 0, 0, SLOTWIDTH, SLOTHEIGHT);
  399. OffsetRect(&rectSlot, 0, dwYStart);
  400. if (rectSlot.bottom > PIXELSPERREV)
  401. {
  402. RECT rectSlotTmp, rectDCTmp;
  403. DWORD height;
  404. // copy from bottom end of bitmap
  405. height = PIXELSPERREV - rectSlot.top;
  406. rectSlotTmp = rectSlot;
  407. rectSlotTmp.bottom = rectSlotTmp.top + height;
  408. rectDCTmp = rectDC;
  409. rectDCTmp.bottom = rectDCTmp.top + height;
  410. PaintBitmap(hDC, &rectDCTmp, hWheelBitmap, &rectSlotTmp);
  411. height = rectSlot.bottom - PIXELSPERREV;
  412. rectSlotTmp = rectSlot;
  413. rectSlotTmp.top = 0;
  414. rectSlotTmp.bottom = height;
  415. rectDCTmp = rectDC;
  416. rectDCTmp.top = rectDCTmp.bottom - height;
  417. PaintBitmap(hDC, &rectDCTmp, hWheelBitmap, &rectSlotTmp);
  418. }
  419. else
  420. PaintBitmap(hDC, &rectDC, hWheelBitmap, &rectSlot);
  421. }
  422. }
  423. OffsetRect(&rectDC, SLOTWIDTH + dwXOffset, 0);
  424. }
  425. return (dwStoppedCount != NUMWHEELS);
  426. }