Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

434 lines
9.9 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ====
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "stdafx.h"
  7. #include <afxtempl.h>
  8. #include "hammer.h"
  9. #include "MessageWnd.h"
  10. #include "mainfrm.h"
  11. #include "GlobalFunctions.h"
  12. // memdbgon must be the last include file in a .cpp file!!!
  13. #include <tier0/memdbgon.h>
  14. IMPLEMENT_DYNCREATE(CMessageWnd, CMDIChildWnd)
  15. const int iMsgPtSize = 10;
  16. BEGIN_MESSAGE_MAP(CMessageWnd, CMDIChildWnd)
  17. //{{AFX_MSG_MAP(CMessageWnd)
  18. ON_WM_PAINT()
  19. ON_WM_HSCROLL()
  20. ON_WM_VSCROLL()
  21. ON_WM_SIZE()
  22. ON_WM_KEYDOWN()
  23. ON_WM_CLOSE()
  24. ON_WM_DESTROY()
  25. //}}AFX_MSG_MAP
  26. END_MESSAGE_MAP()
  27. //-----------------------------------------------------------------------------
  28. // Static factory function to create the message window object. The window
  29. // itself is created by CMessageWnd::CreateWindow.
  30. //-----------------------------------------------------------------------------
  31. CMessageWnd *CMessageWnd::CreateMessageWndObject()
  32. {
  33. CMessageWnd *pMsgWnd = (CMessageWnd *)RUNTIME_CLASS(CMessageWnd)->CreateObject();
  34. return pMsgWnd;
  35. }
  36. //-----------------------------------------------------------------------------
  37. //-----------------------------------------------------------------------------
  38. CMessageWnd::CMessageWnd()
  39. {
  40. // set initial elements
  41. iCharWidth = -1;
  42. iNumMsgs = 0;
  43. bDestroyed = false;
  44. // load font
  45. Font.CreatePointFont(iMsgPtSize * 10, "Courier New");
  46. }
  47. //-----------------------------------------------------------------------------
  48. //-----------------------------------------------------------------------------
  49. CMessageWnd::~CMessageWnd()
  50. {
  51. }
  52. //-----------------------------------------------------------------------------
  53. //-----------------------------------------------------------------------------
  54. void CMessageWnd::CreateMessageWindow( CMDIFrameWnd *pwndParent, CRect &rect )
  55. {
  56. Create( NULL, "Messages", WS_OVERLAPPEDWINDOW | WS_CHILD, rect, pwndParent );
  57. bool bErrors = true;
  58. MWMSGSTRUCT mws;
  59. for ( int i = 0; i < iNumMsgs; i++ )
  60. {
  61. mws = MsgArray[i];
  62. if ( ( mws.type == mwError ) || ( mws.type == mwWarning ) )
  63. {
  64. bErrors = true;
  65. }
  66. }
  67. if ( bErrors )
  68. {
  69. ShowWindow( SW_SHOW );
  70. }
  71. }
  72. //-----------------------------------------------------------------------------
  73. // Emit a message to our messages array.
  74. // NOTE: During startup the window itself might not exist yet!
  75. //-----------------------------------------------------------------------------
  76. void CMessageWnd::AddMsg(MWMSGTYPE type, TCHAR* msg)
  77. {
  78. if ( bDestroyed )
  79. return;
  80. int iAddAt = iNumMsgs;
  81. // Don't allow growth after MAX_MESSAGE_WND_LINES
  82. if ( iNumMsgs == MAX_MESSAGE_WND_LINES )
  83. {
  84. MWMSGSTRUCT *p = MsgArray.GetData();
  85. memcpy(p, p+1, sizeof(*p) * ( MAX_MESSAGE_WND_LINES - 1 ));
  86. iAddAt = MAX_MESSAGE_WND_LINES - 1;
  87. }
  88. else
  89. {
  90. ++iNumMsgs;
  91. }
  92. // format message
  93. MWMSGSTRUCT mws;
  94. mws.MsgLen = strlen(msg);
  95. mws.type = type;
  96. Assert(mws.MsgLen <= (sizeof(mws.szMsg) / sizeof(TCHAR)));
  97. _tcscpy(mws.szMsg, msg);
  98. // Add the message, growing the array as necessary
  99. MsgArray.SetAtGrow(iAddAt, mws);
  100. // Don't do stuff that requires the window to exist.
  101. if ( m_hWnd == NULL )
  102. return;
  103. CalculateScrollSize();
  104. Invalidate();
  105. }
  106. //-----------------------------------------------------------------------------
  107. //-----------------------------------------------------------------------------
  108. void CMessageWnd::ShowMessageWindow()
  109. {
  110. if ( m_hWnd == NULL || bDestroyed )
  111. return;
  112. ShowWindow( SW_SHOW );
  113. }
  114. //-----------------------------------------------------------------------------
  115. //-----------------------------------------------------------------------------
  116. void CMessageWnd::ToggleMessageWindow()
  117. {
  118. if ( m_hWnd == NULL || bDestroyed )
  119. return;
  120. ShowWindow( IsWindowVisible() ? SW_HIDE : SW_SHOWNA );
  121. }
  122. //-----------------------------------------------------------------------------
  123. //-----------------------------------------------------------------------------
  124. void CMessageWnd::Activate()
  125. {
  126. if ( m_hWnd == NULL || bDestroyed )
  127. return;
  128. ShowWindow( SW_SHOW );
  129. SetWindowPos( &( CWnd::wndTopMost ), 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW );
  130. BringWindowToTop();
  131. SetFocus();
  132. }
  133. //-----------------------------------------------------------------------------
  134. //-----------------------------------------------------------------------------
  135. bool CMessageWnd::IsVisible()
  136. {
  137. if ( m_hWnd == NULL || bDestroyed )
  138. return false;
  139. return ( IsWindowVisible() == TRUE );
  140. }
  141. //-----------------------------------------------------------------------------
  142. //-----------------------------------------------------------------------------
  143. void CMessageWnd::Resize( CRect &rect )
  144. {
  145. if ( m_hWnd == NULL || bDestroyed )
  146. return;
  147. MoveWindow( rect );
  148. }
  149. //-----------------------------------------------------------------------------
  150. //-----------------------------------------------------------------------------
  151. void CMessageWnd::CalculateScrollSize()
  152. {
  153. if ( m_hWnd == NULL || bDestroyed )
  154. return;
  155. int iHorz;
  156. int iVert;
  157. iVert = iNumMsgs * (iMsgPtSize + 2);
  158. iHorz = 0;
  159. for(int i = 0; i < iNumMsgs; i++)
  160. {
  161. int iTmp = MsgArray[i].MsgLen * iCharWidth;
  162. if(iTmp > iHorz)
  163. iHorz = iTmp;
  164. }
  165. Invalidate();
  166. SCROLLINFO si;
  167. si.cbSize = sizeof(si);
  168. si.fMask = SIF_ALL;
  169. GetScrollInfo(SB_VERT, &si);
  170. si.nMin = 0;
  171. CRect clientrect;
  172. GetClientRect(clientrect);
  173. // horz
  174. si.nMax = iHorz;
  175. si.nPage = clientrect.Width();
  176. SetScrollInfo(SB_HORZ, &si);
  177. // vert
  178. si.nMax = iVert;
  179. si.nPage = clientrect.Height();
  180. SetScrollInfo(SB_VERT, &si);
  181. }
  182. //-----------------------------------------------------------------------------
  183. //-----------------------------------------------------------------------------
  184. void CMessageWnd::OnPaint()
  185. {
  186. CPaintDC dc(this); // device context for painting
  187. int nScrollMin;
  188. int nScrollMax;
  189. // select font
  190. dc.SelectObject(&Font);
  191. dc.SetBkMode(TRANSPARENT);
  192. // first paint?
  193. if(iCharWidth == -1)
  194. {
  195. dc.GetCharWidth('A', 'A', &iCharWidth);
  196. CalculateScrollSize();
  197. }
  198. GetScrollRange( SB_VERT, &nScrollMin, &nScrollMax );
  199. // paint messages
  200. MWMSGSTRUCT mws;
  201. CRect r(0, 0, 1, iMsgPtSize+2);
  202. dc.SetWindowOrg(GetScrollPos(SB_HORZ), GetScrollPos(SB_VERT));
  203. for(int i = 0; i < iNumMsgs; i++)
  204. {
  205. mws = MsgArray[i];
  206. r.right = mws.MsgLen * iCharWidth;
  207. if ( r.bottom < nScrollMin )
  208. continue;
  209. if ( r.top > nScrollMax )
  210. break;
  211. // color of msg
  212. switch(mws.type)
  213. {
  214. case mwError:
  215. dc.SetTextColor(RGB(255, 60, 60));
  216. break;
  217. case mwStatus:
  218. dc.SetTextColor(RGB(0, 0, 0));
  219. break;
  220. }
  221. // draw text
  222. dc.TextOut(r.left, r.top, mws.szMsg, mws.MsgLen);
  223. // move rect down
  224. r.OffsetRect(0, iMsgPtSize + 2);
  225. }
  226. }
  227. //-----------------------------------------------------------------------------
  228. //-----------------------------------------------------------------------------
  229. void CMessageWnd::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
  230. {
  231. int iPos = int(nPos);
  232. SCROLLINFO si;
  233. GetScrollInfo(SB_HORZ, &si);
  234. int iCurPos = GetScrollPos(SB_HORZ);
  235. int iLimit = GetScrollLimit(SB_HORZ);
  236. switch(nSBCode)
  237. {
  238. case SB_LINELEFT:
  239. iPos = -int(si.nPage / 4);
  240. break;
  241. case SB_LINERIGHT:
  242. iPos = int(si.nPage / 4);
  243. break;
  244. case SB_PAGELEFT:
  245. iPos = -int(si.nPage / 2);
  246. break;
  247. case SB_PAGERIGHT:
  248. iPos = int(si.nPage / 2);
  249. break;
  250. case SB_THUMBTRACK:
  251. case SB_THUMBPOSITION:
  252. iPos -= iCurPos;
  253. break;
  254. }
  255. if(iCurPos + iPos < 0)
  256. iPos = -iCurPos;
  257. if(iCurPos + iPos > iLimit)
  258. iPos = iLimit - iCurPos;
  259. if(iPos)
  260. {
  261. SetScrollPos(SB_HORZ, iCurPos + iPos);
  262. ScrollWindow(-iPos, 0);
  263. UpdateWindow();
  264. }
  265. CMDIChildWnd::OnHScroll(nSBCode, nPos, pScrollBar);
  266. }
  267. //-----------------------------------------------------------------------------
  268. //-----------------------------------------------------------------------------
  269. void CMessageWnd::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
  270. {
  271. int iPos = int(nPos);
  272. SCROLLINFO si;
  273. GetScrollInfo(SB_VERT, &si);
  274. int iCurPos = GetScrollPos(SB_VERT);
  275. int iLimit = GetScrollLimit(SB_VERT);
  276. switch(nSBCode)
  277. {
  278. case SB_LINEUP:
  279. iPos = -int(si.nPage / 4);
  280. break;
  281. case SB_LINEDOWN:
  282. iPos = int(si.nPage / 4);
  283. break;
  284. case SB_PAGEUP:
  285. iPos = -int(si.nPage / 2);
  286. break;
  287. case SB_PAGEDOWN:
  288. iPos = int(si.nPage / 2);
  289. break;
  290. case SB_THUMBTRACK:
  291. case SB_THUMBPOSITION:
  292. iPos -= iCurPos;
  293. break;
  294. }
  295. if(iCurPos + iPos < 0)
  296. iPos = -iCurPos;
  297. if(iCurPos + iPos > iLimit)
  298. iPos = iLimit - iCurPos;
  299. if(iPos)
  300. {
  301. SetScrollPos(SB_VERT, iCurPos + iPos);
  302. ScrollWindow(0, -iPos);
  303. UpdateWindow();
  304. }
  305. CMDIChildWnd::OnVScroll(nSBCode, nPos, pScrollBar);
  306. }
  307. //-----------------------------------------------------------------------------
  308. //-----------------------------------------------------------------------------
  309. void CMessageWnd::OnSize(UINT nType, int cx, int cy)
  310. {
  311. CMDIChildWnd::OnSize(nType, cx, cy);
  312. CalculateScrollSize();
  313. }
  314. //-----------------------------------------------------------------------------
  315. //-----------------------------------------------------------------------------
  316. void CMessageWnd::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
  317. {
  318. // up/down
  319. switch(nChar)
  320. {
  321. case VK_UP:
  322. OnVScroll(SB_LINEUP, 0, NULL);
  323. break;
  324. case VK_DOWN:
  325. OnVScroll(SB_LINEDOWN, 0, NULL);
  326. break;
  327. case VK_PRIOR:
  328. OnVScroll(SB_PAGEUP, 0, NULL);
  329. break;
  330. case VK_NEXT:
  331. OnVScroll(SB_PAGEDOWN, 0, NULL);
  332. break;
  333. case VK_HOME:
  334. OnVScroll(SB_THUMBPOSITION, 0, NULL);
  335. break;
  336. case VK_END:
  337. OnVScroll(SB_THUMBPOSITION, GetScrollLimit(SB_VERT), NULL);
  338. break;
  339. }
  340. CMDIChildWnd::OnKeyDown(nChar, nRepCnt, nFlags);
  341. }
  342. //-----------------------------------------------------------------------------
  343. //-----------------------------------------------------------------------------
  344. void CMessageWnd::OnClose()
  345. {
  346. // just hide the window
  347. ShowWindow(SW_HIDE);
  348. }
  349. //-----------------------------------------------------------------------------
  350. //-----------------------------------------------------------------------------
  351. void CMessageWnd::OnDestroy()
  352. {
  353. bDestroyed = true;
  354. }