wyMeterCtl.cpp
上传用户:seaboy_04
上传日期:2013-02-24
资源大小:284k
文件大小:16k
源码类别:

其他行业

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. #include "Meter.h"
  3. #include "wyMeterCtl.h"
  4. #include "wyMeterPpg.h"
  5. #include <math.h>
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. IMPLEMENT_DYNCREATE(CwyMeterCtrl, COleControl)
  12. // 消息映射
  13. BEGIN_MESSAGE_MAP(CwyMeterCtrl, COleControl)
  14. //{{AFX_MSG_MAP(CwyMeterCtrl)
  15. ON_WM_CREATE()
  16. ON_WM_DESTROY()
  17. ON_WM_TIMER()
  18. //}}AFX_MSG_MAP
  19. ON_MESSAGE(OCM_COMMAND, OnOcmCommand)
  20. ON_OLEVERB(AFX_IDS_VERB_EDIT, OnEdit)
  21. ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
  22. END_MESSAGE_MAP()
  23. // 调度映射
  24. BEGIN_DISPATCH_MAP(CwyMeterCtrl, COleControl)
  25. //{{AFX_DISPATCH_MAP(CwyMeterCtrl)
  26. DISP_PROPERTY_NOTIFY(CwyMeterCtrl, "dMaxValue", m_dMaxValue, OnDMaxValueChanged, VT_R8)
  27. DISP_PROPERTY_NOTIFY(CwyMeterCtrl, "dMinValue", m_dMinValue, OnDMinValueChanged, VT_R8)
  28. DISP_PROPERTY_NOTIFY(CwyMeterCtrl, "dCurrentValue", m_dCurrentValue, OnDCurrentValueChanged, VT_R8)
  29. DISP_PROPERTY_NOTIFY(CwyMeterCtrl, "nScaleDecimals", m_nScaleDecimals, OnNScaleDecimalsChanged, VT_I2)
  30. DISP_PROPERTY_NOTIFY(CwyMeterCtrl, "nValueDecimals", m_nValueDecimals, OnNValueDecimalsChanged, VT_I2)
  31. DISP_PROPERTY_NOTIFY(CwyMeterCtrl, "colorNeedle", m_colorNeedle, OnColorNeedleChanged, VT_COLOR)
  32. DISP_PROPERTY_NOTIFY(CwyMeterCtrl, "strUnits", m_strUnits, OnStrUnitsChanged, VT_BSTR)
  33. DISP_FUNCTION(CwyMeterCtrl, "SetCurrentValue", SetCurrentValue, VT_EMPTY, VTS_R8)
  34. //}}AFX_DISPATCH_MAP
  35. DISP_FUNCTION_ID(CwyMeterCtrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE)
  36. END_DISPATCH_MAP()
  37. // 事件映射
  38. BEGIN_EVENT_MAP(CwyMeterCtrl, COleControl)
  39. //{{AFX_EVENT_MAP(CwyMeterCtrl)
  40. //}}AFX_EVENT_MAP
  41. END_EVENT_MAP()
  42.  
  43. // 属性页
  44. BEGIN_PROPPAGEIDS(CwyMeterCtrl, 1)
  45. PROPPAGEID(CwyMeterPropPage::guid)
  46. END_PROPPAGEIDS(CwyMeterCtrl)
  47.  
  48. // 初始化类工厂和 GUID
  49. IMPLEMENT_OLECREATE_EX(CwyMeterCtrl, "METER.wyMeterCtrl.1",
  50. 0x15491a65, 0x5b63, 0x11d5, 0xad, 0xd3, 0, 0x10, 0x88, 0xab, 0x5d, 0x33)
  51. // 类型库 ID 和 版本
  52. IMPLEMENT_OLETYPELIB(CwyMeterCtrl, _tlid, _wVerMajor, _wVerMinor)
  53.  
  54. // 接口 IDs
  55. const IID BASED_CODE IID_DwyMeter =
  56. { 0x15491a63, 0x5b63, 0x11d5, { 0xad, 0xd3, 0, 0x10, 0x88, 0xab, 0x5d, 0x33 } };
  57. const IID BASED_CODE IID_DwyMeterEvents =
  58. { 0x15491a64, 0x5b63, 0x11d5, { 0xad, 0xd3, 0, 0x10, 0x88, 0xab, 0x5d, 0x33 } };
  59.  
  60. // 控件类型信息
  61. static const DWORD BASED_CODE _dwwyMeterOleMisc =
  62. OLEMISC_ACTIVATEWHENVISIBLE |
  63. OLEMISC_SETCLIENTSITEFIRST |
  64. OLEMISC_INSIDEOUT |
  65. OLEMISC_CANTLINKINSIDE |
  66. OLEMISC_RECOMPOSEONRESIZE;
  67. IMPLEMENT_OLECTLTYPE(CwyMeterCtrl, IDS_WYMETER, _dwwyMeterOleMisc)
  68.  
  69. // 增加和删除系统注册记录 
  70. BOOL CwyMeterCtrl::CwyMeterCtrlFactory::UpdateRegistry(BOOL bRegister)
  71. {
  72.   // 注册控件
  73. if (bRegister)
  74. return AfxOleRegisterControlClass(
  75. AfxGetInstanceHandle(),
  76. m_clsid,
  77. m_lpszProgID,
  78. IDS_WYMETER,
  79. IDB_WYMETER,
  80. afxRegInsertable | afxRegApartmentThreading,
  81. _dwwyMeterOleMisc,
  82. _tlid,
  83. _wVerMajor,
  84. _wVerMinor);
  85. else
  86. return AfxOleUnregisterClass(m_clsid, m_lpszProgID);
  87. }
  88. //控件构造函数 
  89. CwyMeterCtrl::CwyMeterCtrl()
  90. {
  91. InitializeIIDs(&IID_DwyMeter, &IID_DwyMeterEvents);
  92. //设定控件的初始大小
  93. SetInitialSize( 90, 90 ); 
  94. }
  95. //控件析构函数 
  96. CwyMeterCtrl::~CwyMeterCtrl()
  97. {
  98. }
  99. //控件绘制函数 
  100. void CwyMeterCtrl::OnDraw(
  101. CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
  102. {
  103. // DoSuperclassPaint(pdc, rcBounds);
  104. CBrush brush(TranslateColor(GetBackColor()));
  105. pdc->FillRect(rcBounds,&brush);
  106. DrawMeterBackground(pdc, rcBounds) ;
  107. DrawNeedle(pdc) ;
  108. DrawValue(pdc) ;
  109. }
  110.  
  111. // 持久性支持
  112. void CwyMeterCtrl::DoPropExchange(CPropExchange* pPX)
  113. {
  114. ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
  115. COleControl::DoPropExchange(pPX);
  116. PX_Color(pPX,"colorNeedle",m_colorNeedle,RGB(255,0,0));
  117.     PX_String(pPX,"strUnits" ,m_strUnits,"v");
  118.     PX_Short(pPX,"nScaleDecimals" ,m_nScaleDecimals,0);
  119.     PX_Short(pPX,"nValueDecimals" ,m_nValueDecimals,1);
  120.     PX_Double(pPX,"dMaxValue" ,m_dMaxValue,10.0);
  121.     PX_Double(pPX,"dMinValue" ,m_dMinValue,0.0);
  122.     PX_Double(pPX,"dCurrentValue" ,m_dCurrentValue,0.0);
  123. }
  124.  
  125. // 恢复初始状态
  126. void CwyMeterCtrl::OnResetState()
  127. {
  128. COleControl::OnResetState();  // Resets defaults found in DoPropExchange
  129. }
  130.  
  131. //显示About对话框  
  132. void CwyMeterCtrl::AboutBox()
  133. {
  134. CDialog dlgAbout(IDD_ABOUTBOX_WYMETER);
  135. dlgAbout.DoModal();
  136. }
  137.  
  138. // 设置窗口初始参数
  139. BOOL CwyMeterCtrl::PreCreateWindow(CREATESTRUCT& cs)
  140. {
  141. cs.lpszClass = _T("STATIC");
  142. return COleControl::PreCreateWindow(cs);
  143. }
  144.  
  145. // 说明是否使用基类控件
  146. BOOL CwyMeterCtrl::IsSubclassedControl()
  147. {
  148. return TRUE;
  149. }
  150. //处理命令消息 
  151. LRESULT CwyMeterCtrl::OnOcmCommand(WPARAM wParam, LPARAM lParam)
  152. {
  153. #ifdef _WIN32
  154. WORD wNotifyCode = HIWORD(wParam);
  155. #else
  156. WORD wNotifyCode = HIWORD(lParam);
  157. #endif
  158. return 0;
  159. }
  160. //绘制指针
  161. void CwyMeterCtrl::DrawNeedle(CDC *pDC)
  162. {
  163. int nResult ;
  164. double dAngleRad ;
  165. double dTemp ;
  166. CBrush brushFill, *pBrushOld ;
  167. CPen penDraw, *pPenOld ;
  168. CPoint pointNeedle[3] ;
  169.  
  170. //这个函数绘制三角指针.基本指针是一个水平线,它通过弧线的中点
  171. //绘制在仪表上,指尖所在的角度通过当前值和标尺计算得到.
  172. //指针由三点构成的多边形组成,三角形绘制在仪表的区域内.
  173. // 计算指针的第一个和最后一个点
  174. pointNeedle[0].x = m_nBottomCX + m_nBottomRadius/20 ;
  175. pointNeedle[0].y = m_nBottomCY ;
  176. pointNeedle[2].x = m_nBottomCX - m_nBottomRadius/20 ;
  177. pointNeedle[2].y = m_nBottomCY ;
  178. // 计算指尖的角度
  179. dAngleRad = (m_dCurrentValue-m_dMinValue)*(m_dRightAngleRad-m_dLeftAngleRad)/
  180.           (m_dMaxValue-m_dMinValue) + m_dLeftAngleRad ;
  181. // 如果角度超出仪表,使用最大或最小角度
  182. dAngleRad = max(dAngleRad, m_dRightAngleRad) ;
  183. dAngleRad = min(dAngleRad, m_dLeftAngleRad) ;
  184. // 计算指尖的 X 坐标
  185. dTemp = m_nBottomCX + m_nTopRadius*cos(dAngleRad) ;
  186. pointNeedle[1].x = ROUND(dTemp) ;
  187. // 计算指尖的 Y 坐标
  188. dTemp = m_nBottomCY - m_nTopRadius*sin(dAngleRad) ;
  189. pointNeedle[1].y = ROUND(dTemp) ;
  190. // 基于仪表选择剪贴区域
  191. pDC->SelectClipRgn(&m_rgnBoundary) ;
  192. // 按照指针颜色创建画笔和刷子
  193. brushFill.CreateSolidBrush(m_colorNeedle) ;
  194. penDraw.CreatePen(PS_SOLID, 1, m_colorNeedle) ;
  195. // 选择画笔和刷子
  196. pPenOld = pDC->SelectObject(&penDraw) ;
  197. pBrushOld = pDC->SelectObject(&brushFill) ;
  198. // 绘制指针
  199. pDC->Polygon(pointNeedle, 3) ;
  200. // 恢复剪贴区域
  201. nResult = pDC->SelectClipRgn(NULL) ;
  202. // 恢复画笔和刷子
  203. pDC->SelectObject(pPenOld) ;
  204. pDC->SelectObject(pBrushOld) ;
  205. }
  206. //输出数值
  207. void CwyMeterCtrl::DrawValue(CDC *pDC)
  208. {
  209. CFont *pFontOld ;
  210. CString strTemp ;
  211. // 选取字体,字体根据背景大小设定
  212. pFontOld = pDC->SelectObject(&m_fontValue) ;
  213. // 设定字体背景色和文本色
  214. pDC->SetTextColor(m_colorText) ;
  215. pDC->SetBkColor(m_colorButton) ;
  216. // 输出文本,文本与中点和基线对齐
  217. pDC->SetTextAlign(TA_CENTER|TA_BASELINE) ;
  218. strTemp.Format("%.*f", m_nValueDecimals, m_dCurrentValue) ;
  219. pDC->TextOut(m_nValueCenter, m_nValueBaseline, strTemp) ;
  220. // 恢复原背景色和字体
  221. pDC->SetBkColor(m_colorWindow) ;
  222.     pDC->SelectObject(pFontOld) ;
  223. }
  224. //绘制背景
  225. void CwyMeterCtrl::DrawMeterBackground(CDC *pDC, const CRect &rect)
  226. {
  227. int i, nAngleDeg, nRef ;
  228. int nHeight ;
  229. int nHalfPoints ;
  230. int nStartAngleDeg, nEndAngleDeg ;
  231. int nTickDeg ;
  232. int nAngleIncrementDeg ;
  233. double dTemp, dAngleRad, dX, dY ;
  234. double dRadPerDeg ;
  235. CString strTemp ;
  236. CPoint pointRecess[BOUNDARY_POINTS] ;
  237. CBrush brushFill, *pBrushOld ;
  238. CFont *pFontOld ;
  239. CPen penDraw, *pPenOld ;
  240. TEXTMETRIC tm ;
  241. // 计算仪表半径的中点
  242. m_nBottomCX = rect.right-5;   
  243. m_nBottomCY = rect.bottom -5;  
  244. // 计算仪表半径
  245. m_nTopRadius = rect.Height()*6/8 ;
  246. m_nBottomRadius = m_nTopRadius/2 ;
  247. // 每度表示的弧度数
  248. dRadPerDeg = 4.0*atan(1.0)/180.0 ;
  249. // 设置仪表表面区域范围
  250. nStartAngleDeg =90;   //  60 ;
  251. nEndAngleDeg   =180;  // 120 ;
  252. nTickDeg       =  15 ;
  253. // 弧上绘制点个数
  254. nAngleIncrementDeg = 5 ;
  255. // 角度转换为弧度
  256. m_dLeftAngleRad = nEndAngleDeg*dRadPerDeg ;
  257. m_dRightAngleRad = nStartAngleDeg*dRadPerDeg ;
  258. // 构造仪表表面区域,它是一个多边形区域
  259.   nRef = 0 ;
  260. for (nAngleDeg=nStartAngleDeg; nAngleDeg<=nEndAngleDeg; nAngleDeg+=nAngleIncrementDeg)
  261. {
  262. // 计算当前角度的弧度数
  263. dAngleRad = nAngleDeg*dRadPerDeg ;
  264. // 计算 X 坐标
  265. dTemp = m_nBottomCX + m_nTopRadius*cos(dAngleRad) ;
  266. m_pointBoundary[nRef].x = ROUND(dTemp) ;
  267. // 计算 Y 坐标
  268. dTemp = m_nBottomCY - m_nTopRadius*sin(dAngleRad) ;
  269. m_pointBoundary[nRef].y = ROUND(dTemp) ;
  270. nRef++ ;
  271. }
  272. nHalfPoints = nRef ;  
  273. // 增加低边弧上的点
  274. for (nAngleDeg=nEndAngleDeg; nAngleDeg>=nStartAngleDeg; nAngleDeg-=nAngleIncrementDeg)
  275. {
  276. dAngleRad = nAngleDeg*dRadPerDeg ;
  277. dTemp = m_nBottomCX + m_nBottomRadius*cos(dAngleRad) ;
  278. m_pointBoundary[nRef].x = ROUND(dTemp) ;
  279. dTemp = m_nBottomCY - m_nBottomRadius*sin(dAngleRad) ;
  280. m_pointBoundary[nRef].y = ROUND(dTemp) ;
  281. nRef++ ;
  282. }
  283. // 构造仪表表面多边形 
  284.   for (i=0; i<nRef; i++)
  285. {
  286. pointRecess[i].x = m_pointBoundary[i].x ;
  287. pointRecess[i].y = m_pointBoundary[i].y-1 ;
  288. }
  289. pointRecess[0].x = pointRecess[0].x + 1 ;
  290. pointRecess[nRef-1].x = pointRecess[nRef-1].x - 1 ;
  291. for (i=nHalfPoints; i<nRef; i++)
  292. {
  293. pointRecess[i].x = m_pointBoundary[i].x ;
  294. pointRecess[i].y = m_pointBoundary[i].y+1 ;
  295. }
  296. pointRecess[nHalfPoints].x = pointRecess[nHalfPoints].x - 1 ;
  297. pointRecess[nRef-1].x = pointRecess[nRef-1].x + 1 ;
  298. // 建立仪表表面区域
  299. m_rgnBoundary.DeleteObject() ;
  300. m_rgnBoundary.CreatePolygonRgn(m_pointBoundary, nRef, ALTERNATE) ;
  301. // 定位数值输出矩形
  302. m_rectValue.left = rect.left + 5 ;
  303. m_rectValue.right = rect.right - 3*rect.Width()/5 ;
  304. m_rectValue.bottom = rect.bottom - 8*rect.Height()/11 ;
  305. m_rectValue.top = rect.top +5;
  306. // 获取有关系统颜色
  307. m_colorWindow    = GetSysColor(COLOR_WINDOW) ;
  308. m_colorButton    = GetSysColor(COLOR_BTNFACE) ;
  309. m_colorShadow    = GetSysColor(COLOR_BTNSHADOW) ;
  310. m_colorHighlight = GetSysColor(COLOR_BTNHIGHLIGHT) ;
  311. m_colorText  = GetSysColor(COLOR_BTNTEXT) ;
  312. // 用按钮色填充背景
  313. brushFill.DeleteObject() ;
  314. brushFill.CreateSolidBrush(m_colorButton) ;
  315. pBrushOld = pDC->SelectObject(&brushFill) ;
  316. pDC->Rectangle(rect) ;
  317. pDC->SelectObject(pBrushOld) ;
  318. // 绘制仪表凹面.
  319.   penDraw.DeleteObject() ;
  320. penDraw.CreatePen(PS_SOLID, 1, m_colorShadow) ;
  321. pPenOld = pDC->SelectObject(&penDraw) ;
  322. pDC->MoveTo(pointRecess[0]) ;
  323. pDC->PolylineTo(pointRecess, nHalfPoints+1) ;
  324. pDC->SelectObject(pPenOld) ;
  325.  
  326. // 绘制仪表凹面阴影.
  327. penDraw.DeleteObject() ;
  328. penDraw.CreatePen(PS_SOLID, 1, m_colorHighlight) ;
  329. pPenOld = pDC->SelectObject(&penDraw) ;
  330. // 绘制低边弧
  331. pDC->PolylineTo(&pointRecess[nHalfPoints], nHalfPoints) ;
  332. pDC->LineTo(pointRecess[0]) ;  // connect it to the top
  333. pDC->SelectObject(pPenOld) ;
  334. // 绘制仪表表面
  335. // 使用文本颜色绘制边框
  336. penDraw.DeleteObject() ;
  337. penDraw.CreatePen(PS_SOLID, 1, m_colorText) ;
  338. pPenOld = pDC->SelectObject(&penDraw) ;
  339. // 使用窗口颜色填充
  340. brushFill.DeleteObject() ;
  341. brushFill.CreateSolidBrush(m_colorWindow) ;
  342. pBrushOld = pDC->SelectObject(&brushFill) ;
  343. // 绘制表面
  344. pDC->Polygon(m_pointBoundary, nRef) ;
  345. // 恢复刷子
  346. pDC->SelectObject(pBrushOld) ;
  347. // 绘制刻度记号.
  348. // 刻度长度比高边下降15%
  349. dTemp = m_nTopRadius - 0.15*(m_nTopRadius-m_nBottomRadius) ;
  350. for (nAngleDeg=90; nAngleDeg>nStartAngleDeg; nAngleDeg-=nTickDeg)
  351. {
  352. dAngleRad = nAngleDeg*dRadPerDeg ;
  353. dX = m_nBottomCX + m_nTopRadius*cos(dAngleRad) ;
  354. dY = m_nBottomCY - m_nTopRadius*sin(dAngleRad) ;
  355. pDC->MoveTo(ROUND(dX), ROUND(dY)) ;
  356. dX = m_nBottomCX + dTemp*cos(dAngleRad) ;
  357. dY = m_nBottomCY - dTemp*sin(dAngleRad) ;
  358. pDC->LineTo(ROUND(dX), ROUND(dY)) ;
  359. }
  360. for (nAngleDeg=90+nTickDeg; nAngleDeg<nEndAngleDeg; nAngleDeg+=nTickDeg)
  361. {
  362. dAngleRad = nAngleDeg*dRadPerDeg ;
  363. dX = m_nBottomCX + m_nTopRadius*cos(dAngleRad) ;
  364. dY = m_nBottomCY - m_nTopRadius*sin(dAngleRad) ;
  365. pDC->MoveTo(ROUND(dX), ROUND(dY)) ;
  366. dX = m_nBottomCX + dTemp*cos(dAngleRad) ;
  367. dY = m_nBottomCY - dTemp*sin(dAngleRad) ;
  368. pDC->LineTo(ROUND(dX), ROUND(dY)) ;
  369. }
  370. // 恢复画笔
  371. pDC->SelectObject(pPenOld) ;
  372. // 绘制数值显示矩形
  373. penDraw.DeleteObject() ;
  374. penDraw.CreatePen(PS_SOLID, 1, m_colorShadow) ;
  375. pPenOld = pDC->SelectObject(&penDraw) ;
  376. pDC->MoveTo(m_rectValue.left, m_rectValue.bottom) ;
  377. pDC->LineTo(m_rectValue.left, m_rectValue.top) ;
  378. pDC->LineTo(m_rectValue.right, m_rectValue.top) ;
  379. pDC->SelectObject(pPenOld) ;
  380. penDraw.DeleteObject() ;
  381. penDraw.CreatePen(PS_SOLID, 1, m_colorHighlight) ;
  382. pPenOld = pDC->SelectObject(&penDraw) ;
  383. pDC->LineTo(m_rectValue.right, m_rectValue.bottom) ;
  384. pDC->LineTo(m_rectValue.left, m_rectValue.bottom) ;
  385. pDC->SelectObject(pPenOld) ;
  386. // 计算字体大小
  387. nHeight = m_rectValue.Height()*85/100 ;
  388.     m_fontValue.DeleteObject() ;
  389. m_fontValue.CreateFont (nHeight, 0, 0, 0, 400,
  390.   FALSE, FALSE, 0, ANSI_CHARSET,
  391.   OUT_DEFAULT_PRECIS, 
  392.   CLIP_DEFAULT_PRECIS,
  393.   DEFAULT_QUALITY, 
  394.   DEFAULT_PITCH|FF_SWISS, "Arial") ;
  395.   pFontOld = pDC->SelectObject(&m_fontValue) ;
  396.     pDC->GetTextMetrics(&tm) ;
  397.     m_nValueFontHeight = tm.tmHeight ;
  398.     m_nValueFontWidth  = tm.tmAveCharWidth ;
  399.  
  400.   m_nValueBaseline = m_rectValue.bottom -  m_nValueFontHeight/4 ;
  401. m_nValueCenter   = m_rectValue.left +    m_rectValue.Width()/2 ;
  402. // 输出数值
  403. pDC->SetTextColor(m_colorText) ;
  404. pDC->SetBkColor(m_colorButton) ;
  405. // 输出单位
  406. pDC->SetTextAlign(TA_CENTER|TA_BASELINE) ;
  407. pDC->TextOut(rect.right - 2*m_nValueFontWidth, 
  408.          rect.bottom - m_nValueFontHeight/2,
  409.  m_strUnits) ;
  410. // 输出最小值
  411. pDC->SetTextAlign(TA_LEFT|TA_BASELINE) ;
  412. strTemp.Format("%.*lf", m_nScaleDecimals, m_dMinValue) ;
  413. pDC->TextOut(rect.left+1,rect.bottom-5,strTemp) ;
  414. // 输出最大值
  415. pDC->SetTextAlign(TA_RIGHT|TA_BASELINE) ;
  416. strTemp.Format("%.*lf", m_nScaleDecimals, m_dMaxValue) ;
  417. pDC->TextOut((rect.right+m_pointBoundary[0].x)/2, 
  418.   rect.top+m_nValueFontHeight-3,
  419.  strTemp) ;
  420. // 恢复字体和文字背景色
  421.     pDC->SelectObject(pFontOld) ;
  422. pDC->SetBkColor(m_colorWindow) ;
  423. }
  424. //重绘指针
  425. void CwyMeterCtrl::UpdateNeedle(double dValue)
  426. {
  427. m_dCurrentValue = dValue ;
  428. InvalidateControl() ;
  429. }
  430.  
  431. // 消息处理
  432. void CwyMeterCtrl::OnDMaxValueChanged() //最大值改变
  433. {
  434. InvalidateControl();
  435. SetModifiedFlag();
  436. }
  437. void CwyMeterCtrl::OnDMinValueChanged() //最小值改变 
  438. {
  439. InvalidateControl();
  440. SetModifiedFlag();
  441. }
  442. void CwyMeterCtrl::OnDCurrentValueChanged() //当前值改变 
  443. {
  444. InvalidateControl();
  445. SetModifiedFlag();
  446. }
  447. void CwyMeterCtrl::OnNScaleDecimalsChanged() //标尺精度改变 
  448. {
  449. InvalidateControl();
  450. SetModifiedFlag();
  451. }
  452. void CwyMeterCtrl::OnNValueDecimalsChanged() //数值精度改变 
  453. {
  454. InvalidateControl();
  455. SetModifiedFlag();
  456. }
  457. void CwyMeterCtrl::OnColorNeedleChanged() //指针颜色改变 
  458. {
  459. InvalidateControl();
  460. SetModifiedFlag();
  461. }
  462. void CwyMeterCtrl::OnStrUnitsChanged()  //数值单位改变
  463. {
  464. InvalidateControl();
  465. SetModifiedFlag();
  466. }
  467. //串行化
  468. void CwyMeterCtrl::Serialize(CArchive& ar) 
  469. {
  470. if (ar.IsStoring())
  471. { // 保存
  472. ar << m_strUnits;
  473. ar << m_dMaxValue;
  474. ar << m_dMinValue;
  475. ar << m_nScaleDecimals;
  476. ar << m_nValueDecimals;
  477. ar << m_colorNeedle;
  478. }
  479. else
  480. { // 读取
  481. ar >> m_strUnits;
  482. ar >> m_dMaxValue;
  483. ar >> m_dMinValue;
  484. ar >> m_nScaleDecimals;
  485. ar >> m_nValueDecimals;
  486. ar >> m_colorNeedle;
  487. m_dCurrentValue=0.0;
  488. }
  489. }
  490. //建立窗口时设置定时器
  491. int CwyMeterCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  492. {
  493. if (COleControl::OnCreate(lpCreateStruct) == -1)
  494. return -1;
  495. SetTimer (1, 1000, NULL) ; 
  496. return 0;
  497. }
  498. //关闭窗口时删除定时器
  499. void CwyMeterCtrl::OnDestroy() 
  500. {
  501. COleControl::OnDestroy();
  502. KillTimer (1) ; 
  503. }
  504. //定时消息处理,用于测试
  505. void CwyMeterCtrl::OnTimer(UINT nIDEvent) 
  506. {
  507. //return;
  508. static double dStep = 1.5 ;
  509. static double dValue = 0.0 ;
  510. dValue += dStep ;
  511. if (dValue > m_dMaxValue)
  512. {
  513. dStep = -fabs(dStep) ;
  514. dValue = m_dMaxValue-dStep ;
  515. }
  516. else if (dValue < m_dMinValue)
  517. {
  518. dStep = fabs(dStep) ;
  519. dValue = m_dMinValue+dStep ;
  520. }
  521. UpdateNeedle(dValue) ;
  522. COleControl::OnTimer(nIDEvent);
  523. }
  524. //设定当前值
  525. void CwyMeterCtrl::SetCurrentValue(double val) 
  526. {
  527. UpdateNeedle(val) ;//重绘指针
  528. }