bncvw.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:12k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // bncvw.cpp
  2. //
  3. // This file is a part of the XTREME TOOLKIT PRO MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. #include "stdafx.h"
  21. #include "resource.h"
  22. #include "BncDoc.h"
  23. #include "BncVw.h"
  24. #ifdef _DEBUG
  25. #define new DEBUG_NEW
  26. #undef THIS_FILE
  27. static char THIS_FILE[] = __FILE__;
  28. #endif
  29. #define ABS(x) ((x) < 0? -(x) : (x) > 0? (x) : 0)
  30. /////////////////////////////////////////////////////////////////////////////
  31. // CBounceView
  32. IMPLEMENT_DYNCREATE(CBounceView, CView)
  33. CBounceView::CBounceView()
  34. {
  35. }
  36. CBounceView::~CBounceView()
  37. {
  38. }
  39. BEGIN_MESSAGE_MAP(CBounceView, CView)
  40. //{{AFX_MSG_MAP(CBounceView)
  41. ON_COMMAND(ID_CUSTOM, OnCustomColor)
  42. ON_COMMAND(ID_SPEED_FAST, OnFast)
  43. ON_COMMAND(ID_SPEED_SLOW, OnSlow)
  44. ON_WM_CREATE()
  45. ON_WM_SIZE()
  46. ON_WM_TIMER()
  47. ON_UPDATE_COMMAND_UI(ID_SPEED_FAST, OnUpdateFast)
  48. ON_UPDATE_COMMAND_UI(ID_SPEED_SLOW, OnUpdateSlow)
  49. ON_UPDATE_COMMAND_UI(ID_CUSTOM, OnUpdateCustom)
  50. ON_UPDATE_COMMAND_UI(ID_BLACK, OnUpdateBlack)
  51. ON_UPDATE_COMMAND_UI(ID_BLUE, OnUpdateBlue)
  52. ON_UPDATE_COMMAND_UI(ID_GREEN, OnUpdateGreen)
  53. ON_UPDATE_COMMAND_UI(ID_RED, OnUpdateRed)
  54. ON_UPDATE_COMMAND_UI(ID_WHITE, OnUpdateWhite)
  55. ON_COMMAND(ID_BLACK, OnColor)
  56. ON_COMMAND(ID_BLUE, OnColor)
  57. ON_COMMAND(ID_GREEN, OnColor)
  58. ON_COMMAND(ID_RED, OnColor)
  59. ON_COMMAND(ID_WHITE, OnColor)
  60. //}}AFX_MSG_MAP
  61. END_MESSAGE_MAP()
  62. /////////////////////////////////////////////////////////////////////////////
  63. // CBounceView drawing
  64. void CBounceView::OnDraw(CDC* /*pDC*/)
  65. {
  66. /*CDocument* pDoc = GetDocument();*/
  67. // NOTE: Because the animation depends on timer events
  68. // and resizing of the window, the rendering code is
  69. // mostly found in the MakeNewBall function; called by handlers
  70. // for WM_TIMER and WM_SIZE commands. These handlers make the code easier
  71. // to read. However, the side-effect is that the ball will not be
  72. // rendered when the document is printed because there is no rendering
  73. // code in the OnDraw override.
  74. }
  75. /////////////////////////////////////////////////////////////////////////////
  76. // CBounceView diagnostics
  77. #ifdef _DEBUG
  78. void CBounceView::AssertValid() const
  79. {
  80. CView::AssertValid();
  81. }
  82. void CBounceView::Dump(CDumpContext& dc) const
  83. {
  84. CView::Dump(dc);
  85. }
  86. CBounceDoc* CBounceView::GetDocument() // non-debug version is inline
  87. {
  88. ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CBounceDoc)));
  89. return (CBounceDoc*)m_pDocument;
  90. }
  91. #endif //_DEBUG
  92. /////////////////////////////////////////////////////////////////////////////
  93. // CBounceView message handlers
  94. void CBounceView::ChangeSpeed()
  95. {
  96. CBounceDoc* pDoc = GetDocument();
  97. ASSERT_VALID(pDoc);
  98. // re-create the timer
  99. KillTimer(1);
  100. if (!SetTimer(1, pDoc->m_bFastSpeed ? 0 : 100, NULL))
  101. {
  102. AfxMessageBox(_T("Not enough timers available for this window"),
  103. MB_ICONEXCLAMATION | MB_OK);
  104. DestroyWindow();
  105. }
  106. }
  107. void CBounceView::MakeNewBall()
  108. {
  109. // Computes the attributes of the ball bitmap using
  110. // aspect and window size
  111. CBounceDoc* pDoc = GetDocument();
  112. ASSERT_VALID(pDoc);
  113. CSize radius, move, total;
  114. CBitmap* pbmBall;
  115. pbmBall = &(pDoc->m_bmBall);
  116. radius = pDoc->m_sizeRadius;
  117. move = pDoc->m_sizeMove;
  118. total.cx = (radius.cx + ABS(move.cx)) << 1;
  119. total.cy = (radius.cy + ABS(move.cy)) << 1;
  120. pDoc->m_sizeTotal = total;
  121. if (pbmBall->m_hObject != NULL)
  122. pbmBall->DeleteObject();        //get rid of old bitmap
  123. CClientDC dc(this);
  124. CDC dcMem;
  125. dcMem.CreateCompatibleDC(&dc);
  126. pbmBall->CreateCompatibleBitmap(&dc, total.cx, total.cy);
  127. ASSERT(pbmBall->m_hObject != NULL);
  128. CBitmap* pOldBitmap = dcMem.SelectObject(pbmBall);
  129. // draw a rectangle in the background (window) color
  130. CRect rect(0, 0, total.cx, total.cy);
  131. CBrush brBackground(::GetSysColor(COLOR_WINDOW));
  132. dcMem.FillRect(rect, &brBackground);
  133. CBrush brCross(HS_DIAGCROSS, 0L);
  134. CBrush* pOldBrush = dcMem.SelectObject(&brCross);
  135. dcMem.SetBkColor(pDoc->m_clrBall);
  136. dcMem.Ellipse(ABS(move.cx), ABS(move.cy),
  137. total.cx - ABS(move.cx),
  138. total.cy - ABS(move.cy));
  139. dcMem.SelectObject(pOldBrush);
  140. dcMem.SelectObject(pOldBitmap);
  141. dcMem.DeleteDC();
  142. }
  143. void CBounceView::OnFast()
  144. {
  145. CBounceDoc* pDoc = GetDocument();
  146. ASSERT_VALID(pDoc);
  147. pDoc->m_bFastSpeed = TRUE;
  148. ChangeSpeed();
  149. }
  150. void CBounceView::OnSlow()
  151. {
  152. CBounceDoc* pDoc = GetDocument();
  153. ASSERT_VALID(pDoc);
  154. pDoc->m_bFastSpeed = FALSE;
  155. ChangeSpeed();
  156. }
  157. int CBounceView::OnCreate(LPCREATESTRUCT lpCreateStruct)
  158. {
  159. if (CView::OnCreate(lpCreateStruct) == -1)
  160. return -1;
  161. CBounceDoc* pDoc = GetDocument();
  162. ASSERT_VALID(pDoc);
  163. if (!SetTimer(1, 100 /* start slow */, NULL))
  164. {
  165. MessageBox(_T("Not enough timers available for this window."),
  166. _T("MDI:Bounce"), MB_ICONEXCLAMATION | MB_OK);
  167. // signal creation failure...
  168. return -1;
  169. }
  170. // Get the aspect ratio of the device the ball will be drawn
  171. // on and then update the document data with the correct value.
  172. CDC* pDC = GetDC();
  173. CPoint aspect;
  174. aspect.x = pDC->GetDeviceCaps(ASPECTX);
  175. aspect.y = pDC->GetDeviceCaps(ASPECTY);
  176. ReleaseDC(pDC);
  177. pDoc->m_ptPixel = aspect;
  178. // Note that we could call MakeNewBall here (which should be called
  179. // whenever the ball's speed, color or size has been changed), but the
  180. // OnSize member function is always called after the OnCreate. Since
  181. // the OnSize member has to call MakeNewBall anyway, we don't here.
  182. return 0;
  183. }
  184. void CBounceView::OnSize(UINT nType, int cx, int cy)
  185. {
  186. CView::OnSize(nType, cx, cy);
  187. CBounceDoc* pDoc = GetDocument();
  188. ASSERT_VALID(pDoc);
  189. LONG lScale;
  190. CPoint center, ptPixel;
  191. center.x = cx >> 1;
  192. center.y = cy >> 1;
  193. center.x += cx >> 3; // make the ball a little off-center
  194. pDoc->m_ptCenter = center;
  195. CSize radius, move;
  196. // Because the window size has changed, re-calculate
  197. // the ball's dimensions.
  198. ptPixel = pDoc->m_ptPixel;
  199. lScale = min((LONG)cx * ptPixel.x,
  200. (LONG)cy * ptPixel.y) >> 4;
  201. radius.cx = (int)(lScale / ptPixel.x);
  202. radius.cy = (int)(lScale / ptPixel.y);
  203. pDoc->m_sizeRadius = radius;
  204. //Re-calculate the ball's rate of movement.
  205. move.cx = max(1, radius.cy >> 2);
  206. move.cy = max(1, radius.cy >> 2);
  207. pDoc->m_sizeMove = move;
  208. // Redraw ball.
  209. MakeNewBall();
  210. }
  211. void CBounceView::OnTimer(UINT_PTR /*nIDEvent*/)
  212. {
  213. //Time to redraw the ball.
  214. CBounceDoc* pDoc = GetDocument();
  215. ASSERT_VALID(pDoc);
  216. CBitmap* pbmBall;
  217. pbmBall = &(pDoc->m_bmBall);
  218. if (pbmBall->m_hObject == NULL)
  219. return;     // no bitmap for the ball
  220. // Get the current dimensions and create
  221. // a compatible DC to work with.
  222. CRect rcClient;
  223. GetClientRect(rcClient);
  224. CClientDC dc(this);
  225. CBitmap* pbmOld = NULL;
  226. CDC dcMem;
  227. dcMem.CreateCompatibleDC(&dc);
  228. pbmOld = dcMem.SelectObject(pbmBall);
  229. CPoint center;
  230. CSize total, move, radius;
  231. // Get the current dimensions and create
  232. // a compatible DC to work with.
  233. center = pDoc->m_ptCenter;
  234. radius = pDoc->m_sizeRadius;
  235. total = pDoc->m_sizeTotal;
  236. move = pDoc->m_sizeMove;
  237. // Now that the ball has been updated, draw it
  238. // by BitBlt'ing to the view.
  239. dc.BitBlt(center.x - total.cx / 2, center.y - total.cy / 2,
  240. total.cx, total.cy, &dcMem, 0, 0, SRCCOPY);
  241. // Move ball and check for collisions
  242. center += move;
  243. pDoc->m_ptCenter = center;
  244. if ((center.x + radius.cx >= rcClient.right) ||
  245. (center.x - radius.cx <= 0))
  246. {
  247. move.cx = -move.cx;
  248. }
  249. if ((center.y + radius.cy >= rcClient.bottom) ||
  250. (center.y - radius.cy <= 0))
  251. {
  252. move.cy = -move.cy;
  253. }
  254. pDoc->m_sizeMove = move;
  255. dcMem.SelectObject(pbmOld);
  256. dcMem.DeleteDC();
  257. }
  258. void CBounceView::OnUpdateFast(CCmdUI* pCmdUI)
  259. {
  260. CBounceDoc* pDoc = GetDocument();
  261. ASSERT_VALID(pDoc);
  262. pCmdUI->SetCheck(pDoc->m_bFastSpeed);
  263. }
  264. void CBounceView::OnUpdateSlow(CCmdUI* pCmdUI)
  265. {
  266. CBounceDoc* pDoc = GetDocument();
  267. ASSERT_VALID(pDoc);
  268. pCmdUI->SetCheck(!pDoc->m_bFastSpeed);
  269. }
  270. void CBounceView::OnCustomColor()
  271. {
  272. CBounceDoc* pDoc = GetDocument();
  273. ASSERT_VALID(pDoc);
  274. CColorDialog dlgColor(pDoc->m_clrBall);
  275. if (dlgColor.DoModal() == IDOK)
  276. {
  277. pDoc->SetCustomBallColor(dlgColor.GetColor());
  278. pDoc->ClearAllColors();
  279. pDoc->m_bCustom = TRUE;
  280. MakeNewBall();
  281. }
  282. }
  283. void CBounceView::OnUpdateCustom(CCmdUI* pCmdUI)
  284. {
  285. CBounceDoc* pDoc = GetDocument();
  286. ASSERT_VALID(pDoc);
  287. pCmdUI->SetCheck(pDoc->m_bCustom);
  288. }
  289. void CBounceView::MixColors()
  290. {
  291. // This function will take the current color selections, mix
  292. // them, and use the result as the current color of the ball.
  293. CBounceDoc* pDoc = GetDocument();
  294. ASSERT_VALID(pDoc);
  295. COLORREF tmpClr;
  296. int r, g, b;
  297. BOOL bSetColor;
  298. bSetColor = pDoc->m_bRed || pDoc->m_bGreen || pDoc->m_bBlue
  299. || pDoc->m_bWhite || pDoc->m_bBlack;
  300. if(!bSetColor && pDoc->m_bCustom)
  301. return;
  302. r = g = b = 0;
  303. if(pDoc->m_bRed)
  304. r = 255;
  305. if(pDoc->m_bGreen)
  306. g = 255;
  307. if(pDoc->m_bBlue)
  308. b = 255;
  309. tmpClr = RGB(r, g, b);
  310. // NOTE: Because a simple algorithm is used to mix colors
  311. // if the current selection contains black or white, the
  312. // result will be black or white; respectively. This is due
  313. // to the additive method for mixing the colors
  314. if(pDoc->m_bWhite)
  315. tmpClr = RGB(255, 255, 255);
  316. if((pDoc->m_bBlack))
  317. tmpClr = RGB(0, 0, 0);
  318. // Once the color has been determined, update document
  319. // data, and force repaint of all views.
  320. if(!bSetColor)
  321. pDoc->m_bBlack = TRUE;
  322. pDoc->m_clrBall = tmpClr;
  323. pDoc->m_bCustom = FALSE;
  324. MakeNewBall();
  325. }
  326. void CBounceView::OnUpdateBlack(CCmdUI* pCmdUI)
  327. {
  328. CBounceDoc* pDoc = GetDocument();
  329. ASSERT_VALID(pDoc);
  330. pCmdUI->SetCheck(pDoc->m_bBlack);
  331. }
  332. void CBounceView::OnUpdateWhite(CCmdUI* pCmdUI)
  333. {
  334. CBounceDoc* pDoc = GetDocument();
  335. ASSERT_VALID(pDoc);
  336. pCmdUI->SetCheck(pDoc->m_bWhite);
  337. }
  338. void CBounceView::OnUpdateBlue(CCmdUI* pCmdUI)
  339. {
  340. CBounceDoc* pDoc = GetDocument();
  341. ASSERT_VALID(pDoc);
  342. pCmdUI->SetCheck(pDoc->m_bBlue);
  343. }
  344. void CBounceView::OnUpdateGreen(CCmdUI* pCmdUI)
  345. {
  346. CBounceDoc* pDoc = GetDocument();
  347. ASSERT_VALID(pDoc);
  348. pCmdUI->SetCheck(pDoc->m_bGreen);
  349. }
  350. void CBounceView::OnUpdateRed(CCmdUI* pCmdUI)
  351. {
  352. CBounceDoc* pDoc = GetDocument();
  353. ASSERT_VALID(pDoc);
  354. pCmdUI->SetCheck(pDoc->m_bRed);
  355. }
  356. void CBounceView::OnColor()
  357. {
  358. CBounceDoc* pDoc = GetDocument();
  359. ASSERT_VALID(pDoc);
  360. UINT m_nIDColor;
  361. m_nIDColor = LOWORD(GetCurrentMessage()->wParam);
  362. // Determines the color being modified
  363. // and then updates the color state
  364. switch(m_nIDColor)
  365. {
  366. case ID_BLACK:
  367. pDoc->ClearAllColors();
  368. pDoc->m_bBlack = !(pDoc->m_bBlack);
  369. break;
  370. case ID_WHITE:
  371. pDoc->ClearAllColors();
  372. pDoc->m_bWhite = !(pDoc->m_bWhite);
  373. break;
  374. case ID_RED:
  375. pDoc->m_bRed = !(pDoc->m_bRed);
  376. pDoc->m_bBlack = FALSE;
  377. pDoc->m_bWhite = FALSE;
  378. break;
  379. case ID_GREEN:
  380. pDoc->m_bGreen = !(pDoc->m_bGreen);
  381. pDoc->m_bBlack = FALSE;
  382. pDoc->m_bWhite = FALSE;
  383. break;
  384. case ID_BLUE:
  385. pDoc->m_bBlue = !(pDoc->m_bBlue);
  386. pDoc->m_bBlack = FALSE;
  387. pDoc->m_bWhite = FALSE;
  388. break;
  389. default:
  390. AfxMessageBox(IDS_UNKCOLOR);
  391. return;
  392. }
  393. MixColors();
  394. }
  395. BOOL CBounceView::PreCreateWindow(CREATESTRUCT& cs)
  396. {
  397. if (!CView::PreCreateWindow(cs))
  398. return FALSE;
  399. cs.lpszClass = AfxRegisterWndClass(CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW,
  400. AfxGetApp()->LoadStandardCursor(IDC_ARROW),
  401. (HBRUSH)(COLOR_WINDOW+1));
  402. if (cs.lpszClass != NULL)
  403. return TRUE;
  404. else
  405. return FALSE;
  406. }
  407. void CBounceView::OnInitialUpdate()
  408. {
  409. CView::OnInitialUpdate();
  410. MixColors();
  411. }