DigiDisplay.cpp
上传用户:cbxyz2008
上传日期:2007-01-02
资源大小:45k
文件大小:9k
源码类别:

Static控件

开发平台:

Visual C++

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Copyright (C) 1998 by Michel Wassink
  3. // All rights reserved
  4. //
  5. // This is free software.
  6. // You may redistribute it by any means providing it is not sold for profit
  7. // without the author written consent.
  8. //
  9. // No warrantee of any kind, expressed or implied, is included with this
  10. // software; use at your own risk, responsibility for damages (if any) to
  11. // anyone resulting from the use of this software rests entirely with the
  12. // user.
  13. //
  14. // Basic idea from J鰎g K鰊ig of the completely free tetris clone "CGTetris".
  15. // Clock stuff from by Xie Jingwei. 
  16. //
  17. // Send bug reports, bug fixes, enhancements, requests, flames, etc., and
  18. // I'll try to keep a version up to date.  I can be reached as follows:
  19. //    mww@mitutoyo.nl                 (company site)
  20. //    mwassink@csi.com   (private site)
  21. /////////////////////////////////////////////////////////////////////////////
  22. // CDigiDisplay.cpp : implementation file
  23. //
  24. #include "stdafx.h"
  25. #include <math.h>
  26. #include "resource.h"
  27. #include "DigiDisplay.h"
  28. #ifdef _DEBUG
  29. #define new DEBUG_NEW
  30. #undef THIS_FILE
  31. static char THIS_FILE[] = __FILE__;
  32. #endif
  33. // -----          13 
  34. //| | /|      8  0  12  
  35. //| |/ |        1 2 
  36. // -----   ==    6 7    
  37. //| /| |        3 4    
  38. //|/ | |      9  5  11 
  39. // -----          10    
  40. #define NSEGCOLORS 14
  41. #define BACKGROUND RGB(000, 000, 000) // BLACK
  42. COLORREF SEGM_COLORS[NSEGCOLORS] = {
  43. RGB(128, 128, 128), // DARKGRAY
  44. RGB(128, 000, 128), // DARKMAGENTA
  45. RGB(000, 255, 255), // LIGHTCYAN
  46. RGB(000, 000, 128), // DARKBLUE
  47. RGB(000, 000, 255), // LIGHTBLUE
  48. RGB(192, 192, 192), // LIGHTGRAY
  49. RGB(255, 000, 000), // LIGHTRED
  50. RGB(255, 255, 000), // YELLOW
  51. RGB(128, 000, 000), // DARKRED
  52. RGB(000, 128, 000), // DARKGREEN
  53. RGB(255, 000, 255), // LIGHTMAGENTA
  54. RGB(000, 128, 128), // DARKCYAN
  55. RGB(255, 255, 255), // WHITE
  56. RGB(128, 128, 000) // BROWN
  57. };
  58. //    SP 0 1 2 3 4 5 6
  59. WORD CHAR_SEGMENTS[MAXSEGCHARS] =   {0x0000, 0x3F00, 0x1800, 0x36C0, 0x3CC0, 0x19C0, 0x2DC0, 0x2FC0, 
  60. // 7 8 9 A B C D E F G H
  61.    0x3800, 0x3FC0, 0x3DC0, 0x3BC0, 0x3CA1, 0x2700, 0x3C21, 0x27C0, 0x23C0, 0x2F80, 0x1BC0,
  62. // I J K L M N O P Q R S
  63.    0x2421, 0x1E00, 0x0354, 0x0700, 0x1B06, 0x1B12, 0x3F00, 0x33C0, 0x3F10, 0x33D0, 0x2DC0,
  64. // T U V W X Y Z * + -
  65.    0x2021, 0x1F00, 0x030C, 0x1B18, 0x001E, 0x11E0, 0x240C, 0x00FF, 0x00E1, 0x00C0};
  66. /////////////////////////////////////////////////////////////////////////////
  67. // CDigiDisplay
  68. CDigiDisplay::CDigiDisplay()
  69. : m_strNumber("RSTUVWXYZ")
  70. {
  71. TCHAR szCharSet[] =  " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ*+-:.";
  72. int iBmp;
  73. HBITMAP Temp;
  74. m_OffColor = DARKRED;
  75. m_OnColor = LIGHTRED;
  76. m_BackColor = BLACK;
  77. m_strFormat =  _T("%8u");
  78. for(int i = 0; i < TOTCHARS; i++)
  79. {
  80. iBmp = GetDigit(szCharSet[i]);
  81. Temp = LoadBitMap(iBmp);
  82. ::GetObject(Temp, sizeof BITMAP, &m_BM[i]);
  83. ::DeleteObject(Temp);
  84. }
  85. }
  86. CDigiDisplay::~CDigiDisplay()
  87. {
  88. }
  89. BEGIN_MESSAGE_MAP(CDigiDisplay, CStatic)
  90. //{{AFX_MSG_MAP(CDigiDisplay)
  91. ON_WM_ERASEBKGND()
  92. ON_WM_PAINT()
  93. //}}AFX_MSG_MAP
  94. END_MESSAGE_MAP()
  95. void CDigiDisplay::SetText(LPCSTR lpszFormat)
  96. {
  97. m_strNumber = lpszFormat;
  98. if (m_strNumber != m_strOldNumber)
  99. {
  100. m_strOldNumber = m_strNumber;
  101. Invalidate();
  102. }
  103. else
  104. return;
  105. }
  106. void CDigiDisplay::SetColor(COLORREF OffColor, COLORREF OnColor)
  107. {
  108. if (m_OnColor == OnColor && m_OffColor == OffColor)
  109. return;
  110. m_OnColor = OnColor;
  111. m_OffColor = OffColor;
  112. }
  113. void CDigiDisplay::SetBackColor(COLORREF BackColor /* = BLACK */)
  114. {
  115. if (m_BackColor == BackColor)
  116. return;
  117. m_BackColor = BackColor;
  118. }
  119. HBITMAP CDigiDisplay::LoadBitMap(int iBmp)
  120. {
  121. UINT uiResID;
  122. COLORMAP mapColor[NSEGCOLORS + 1];
  123. WORD SegMask;
  124. if (iBmp < MAXSEGCHARS)
  125. {
  126. SegMask = 1;
  127. for (int iColor = 0; iColor < NSEGCOLORS; iColor++)
  128. {
  129. mapColor[iColor].from = SEGM_COLORS[iColor];
  130. mapColor[iColor].to = (CHAR_SEGMENTS[iBmp] & SegMask)?m_OnColor:m_OffColor;
  131. SegMask <<= 1;
  132. }
  133. mapColor[NSEGCOLORS].from = BACKGROUND;
  134. mapColor[NSEGCOLORS].to  = m_BackColor;
  135. return (HBITMAP)::CreateMappedBitmap(AfxGetApp()->m_hInstance, IDB_COOLDIGIT, 0, mapColor, NSEGCOLORS + 1);
  136. }
  137. else
  138. {
  139. mapColor[0].from = BACKGROUND;
  140. mapColor[0].to  = m_BackColor;
  141. mapColor[1].from = SEGM_COLORS[6];
  142. mapColor[1].to  = m_OnColor;
  143. switch(iBmp)
  144. {
  145. case MAXSEGCHARS : uiResID = IDB_COOLDIGITDOT; break; // '.'
  146. case MAXSEGCHARS + 1: uiResID = IDB_COOLDIGITCOLON; break; // ':'
  147. }
  148. return (HBITMAP)::CreateMappedBitmap(AfxGetApp()->m_hInstance, uiResID, 0, mapColor, 3);
  149. }
  150. return NULL;
  151. }
  152. int CDigiDisplay::GetDigit(TCHAR cChar)
  153. {
  154. int iBmp = 0;
  155. if (cChar >= '0' && cChar <= '9')
  156. {
  157. iBmp = cChar - '0' + 1;
  158. }
  159. else if (cChar >= 'A' && cChar <= 'Z')
  160. {
  161. iBmp = cChar - 'A' + 11;
  162. }
  163. else
  164. {
  165. switch(cChar)
  166. {
  167. case ' ': iBmp = 0; break;
  168. case '.': iBmp = MAXSEGCHARS; break;
  169. case ':': iBmp = MAXSEGCHARS + 1; break;
  170. case '*': iBmp = 37; break;
  171. case '+': iBmp = 38; break;
  172. case '-': iBmp = 39; break;
  173. default : ASSERT(FALSE);
  174. }
  175. }
  176. return iBmp;
  177. }
  178. /////////////////////////////////////////////////////////////////////////////
  179. // CDigiDisplay message handlers
  180. void CDigiDisplay::OnPaint() 
  181. {
  182. CPaintDC dc(this);
  183. CDC dcMem;
  184. VERIFY(dcMem.CreateCompatibleDC(0));
  185. CRect rect;
  186. GetClientRect(rect);
  187. CString str(m_strNumber);
  188. const int nHeight = rect.Height();
  189. register int i;
  190. register const int len = str.GetLength();
  191. double pixWidth = 0, RelSize, OffSet = 0;
  192. int iBmp;
  193. // Get length of total string
  194. for (i = 0; i < len; i++)
  195. {
  196. iBmp = GetDigit(str[i]);
  197. pixWidth += m_BM[iBmp].bmWidth;
  198. }
  199. // divide it by the supplied width
  200. RelSize = rect.Width() / pixWidth;
  201. // Show it...
  202. for ( i = 0; i < len; i++)
  203. {
  204. CBitmap * pBmp;
  205. iBmp = GetDigit(str[i]);
  206. HBITMAP temp = LoadBitMap(iBmp);
  207. pBmp = CBitmap::FromHandle(temp);
  208. CBitmap* pBmpOld = dcMem.SelectObject(pBmp);
  209. double nDum;
  210. dc.StretchBlt(int(OffSet + 0.5), 0, int(modf(OffSet, &nDum) + 0.5 + m_BM[iBmp].bmWidth * RelSize + 0.5), nHeight,
  211. &dcMem, 0, 0, m_BM[iBmp].bmWidth, m_BM[iBmp].bmHeight, SRCCOPY);
  212.   dcMem.SelectObject(pBmpOld);
  213. ::DeleteObject(temp);
  214. OffSet += m_BM[iBmp].bmWidth * RelSize;
  215. }
  216. dcMem.DeleteDC();
  217. }
  218. BOOL CDigiDisplay::OnEraseBkgnd(CDC* pDC) 
  219. {
  220. return FALSE;
  221. }
  222. void DDX_DigiDisplay(CDataExchange* pDX, int nIDC, LPCTSTR lpszFormat, ... )
  223. {
  224. TCHAR szMessage[256];
  225. HWND hWndCtrl = pDX->PrepareCtrl(nIDC);
  226. ASSERT(hWndCtrl);
  227. CDigiDisplay * pCtrl = (CDigiDisplay*) CWnd::FromHandle(hWndCtrl);
  228. ASSERT(pCtrl);
  229. if( !pDX->m_bSaveAndValidate )
  230. {
  231. va_list argp;
  232. va_start(argp, lpszFormat);
  233. vsprintf(szMessage, lpszFormat, argp);
  234. va_end(argp);                               
  235. pCtrl->SetText(szMessage);
  236. }
  237. }
  238. CDigiClock::CDigiClock()
  239. {
  240. m_bAlarm = FALSE;
  241. m_style = XDC_SECOND;
  242. m_strNumber = "--:--:--";
  243. m_nCount = 0;
  244. }
  245. BEGIN_MESSAGE_MAP(CDigiClock, CDigiDisplay)
  246. //{{AFX_MSG_MAP(CDigiClock)
  247. ON_WM_TIMER()
  248. ON_WM_DESTROY()
  249. //}}AFX_MSG_MAP
  250. END_MESSAGE_MAP()
  251. /////////////////////////////////////////////////////////////////////////////
  252. // CDigiClock message handlers
  253. void CDigiClock::PreSubclassWindow() 
  254. {
  255. // TODO: Add your specialized code here and/or call the base class
  256. //
  257. // Note: Set the Timer here Pls. 
  258. // Dont set timer in OnCreate(), you cant recieve WM_CREATE 
  259. // when control construted in Dialog template. Say: OnCreate not called.
  260. //
  261. m_nTimer = SetTimer(1, 1000, NULL);
  262. CDigiDisplay::PreSubclassWindow();
  263. }
  264. void CDigiClock::OnDestroy() 
  265. {
  266. CDigiDisplay::OnDestroy();
  267. // TODO: Add your message handler code here
  268. KillTimer(m_nTimer);
  269. }
  270. void CDigiClock::OnTimer(UINT nIDEvent) 
  271. {
  272. // TODO: Add your message handler code here and/or call default
  273. if(nIDEvent == m_nTimer)
  274. {
  275. m_nCount++;
  276. CTime time = CTime::GetCurrentTime();
  277. int nh = time.GetHour();
  278. int nm = time.GetMinute();
  279. int ns = time.GetSecond();
  280. switch(m_style) {
  281. case XDC_SECOND:
  282. {
  283. if(m_bAlarm && m_nCount%2)
  284. m_strNumber = "  :  :  ";
  285. else
  286. m_strNumber.Format("%02d:%02d:%02d",nh, nm, ns);
  287. }
  288. break;
  289. case XDC_NOSECOND:
  290. default:
  291. if (m_bAlarm && m_nCount%2)
  292. m_strNumber = "  :  ";
  293. else
  294. m_strNumber.Format("%02d:%02d:",nh, nm);
  295. break;
  296. };
  297. if (m_bAlarm)
  298. MessageBeep(MB_OK);
  299. Invalidate();
  300. }
  301. CStatic::OnTimer(nIDEvent);
  302. }
  303. BOOL CDigiClock::SetAlarm(BOOL bAlarm /*= TRUE*/)
  304. {
  305. BOOL temp = m_bAlarm;
  306. m_bAlarm = bAlarm;
  307. return temp;
  308. }