PropertyGridItemDegree.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. #include "stdafx.h"
  2. #include "PropertyGridInplaceEdit.h"
  3. #include "PropertyGridInplaceButton.h"
  4. #include "PropertyGridInplaceList.h"
  5. #include "PropertyGridItem.h"
  6. #include "PropertyGridItemDegree.h"
  7. #include <math.h>
  8. //////////////////////////////////////////////////////////////////////
  9. // Construction/Destruction
  10. //////////////////////////////////////////////////////////////////////
  11. CPropertyGridItemDegree::CPropertyGridItemDegree(CString strCaption, double fDegree, int nSecondPrecision)
  12. : CPropertyGridItem(strCaption)
  13. {
  14. _Init();
  15. m_nSecondPrecision = nSecondPrecision;
  16. SetDegree(fDegree);
  17. }
  18. CPropertyGridItemDegree::CPropertyGridItemDegree(UINT nID, double fDegree, int nSecondPrecision)
  19. : CPropertyGridItem(nID)
  20. {
  21. _Init();
  22. m_nSecondPrecision = nSecondPrecision;
  23. SetDegree(fDegree);
  24. }
  25. CPropertyGridItemDegree::~CPropertyGridItemDegree()
  26. {
  27. }
  28. void CPropertyGridItemDegree::_Init()
  29. {
  30. m_pBindDegree = NULL;
  31. m_bHasMinValue = FALSE;
  32. m_bHasMaxValue = FALSE;
  33. m_fMinValue = 0;
  34. m_fMaxValue = 0;
  35. }
  36. void CPropertyGridItemDegree::SetDegree(double fDegree)
  37. {
  38. m_fDegree = fDegree;
  39. if (m_bHasMinValue && m_fDegree < m_fMinValue)
  40. m_fDegree = m_fMinValue;
  41. if (m_bHasMaxValue && m_fDegree > m_fMaxValue)
  42. m_fDegree = m_fMaxValue;
  43. CPropertyGridItem::SetValue( DegreeToString(m_fDegree, m_nSecondPrecision) );
  44. if (m_pBindDegree)
  45. *m_pBindDegree = m_fDegree;
  46. }
  47. double CPropertyGridItemDegree::GetDegree()
  48. {
  49. return m_fDegree;
  50. }
  51. void CPropertyGridItemDegree::SetValue(CString strValue)
  52. {
  53. SetDegree( StringToDegree(strValue) );
  54. }
  55. CString CPropertyGridItemDegree::DegreeToString(double fDegree, int nSecondPrecision /* = 2 */)
  56. {
  57. // 计算度分秒
  58. int degree, minute;
  59. double second;
  60. double temp = fabs(fDegree)+(1E-6/3600);// 由于浮点数存在舍入误差,可能给取整计算度和分
  61. degree = (int)temp; // 带来问题。例如10.7表示为 double 类型时,其值
  62. temp = (temp-degree) * 60; // 为10.699...99,取整得到的度等于10,分等于41,
  63. minute = (int)temp; // 秒用格式%05.2f输出得到60.00。这显然不合理。
  64. second = (temp-minute) * 60; // 如果加一个很小的数,既能解决这个问题,又不会
  65. // 影响数值的精确度。这里加的是百万分之一秒。
  66. // 生成度分秒格式的文本
  67. CString strFormat; // 格式字符串
  68. CString strMaxSecond; // 秒的最大值(文本格式)
  69. if (nSecondPrecision == 0)
  70. {
  71. strFormat = _T("%d°%02d'%02.0f\"");
  72. strMaxSecond = _T("59");
  73. }
  74. else
  75. {
  76. strFormat.Format( _T("%%d°%%02d'%%0%d.%df\""), 3+nSecondPrecision, nSecondPrecision);
  77. strMaxSecond = _T("59.") + CString(_T('9'), nSecondPrecision);
  78. }
  79. #ifdef _UNICODE
  80. char ansi_buf[256];
  81. ::WideCharToMultiByte(CP_ACP, 0, strMaxSecond, -1, ansi_buf, 256, NULL, NULL);
  82. double fMaxSecond = atof(ansi_buf); // 秒的最大值(浮点数格式)
  83. #else
  84. double fMaxSecond = atof(strMaxSecond); // 秒的最大值(浮点数格式)
  85. #endif
  86. CString strText;
  87. strText.Format( strFormat,
  88. degree,
  89. minute,
  90. min(fMaxSecond,second) ); // 避免出现类似59.999"被格式化输出成60.00"的情况
  91. if (fDegree < 0)
  92. strText = _T('-') + strText;
  93. return strText;
  94. }
  95. double CPropertyGridItemDegree::StringToDegree(CString strText)
  96. {
  97. // 读取数据
  98. int degree = 0, minute = 0;
  99. float second = 0;
  100. #ifdef _UNICODE
  101. char ansi_buf[256];
  102. ::WideCharToMultiByte(CP_ACP, 0, strText, -1, ansi_buf, 256, NULL, NULL);
  103. sscanf(ansi_buf, "%d°%d'%f", &degree, &minute, &second);
  104. #else
  105. sscanf(strText, "%d°%d'%f", &degree, &minute, &second);
  106. #endif
  107. double fDegree = abs(degree) + minute/60.0 + second/3600.0;
  108. if (strText.Find( _T('-') ) >= 0)
  109. fDegree = -fDegree;
  110. return fDegree;
  111. }
  112. void CPropertyGridItemDegree::BindToDegree(double* pBindDegree)
  113. {
  114. m_pBindDegree = pBindDegree;
  115. if (m_pBindDegree)
  116. SetDegree(*m_pBindDegree);
  117. }
  118. void CPropertyGridItemDegree::SetMinDegree(double fMinValue)
  119. {
  120. m_bHasMinValue = TRUE;
  121. m_fMinValue = fMinValue;
  122. if (m_fDegree < m_fMinValue)
  123. SetDegree(m_fMinValue);
  124. }
  125. void CPropertyGridItemDegree::SetMaxDegree(double fMaxValue)
  126. {
  127. m_bHasMaxValue = TRUE;
  128. m_fMaxValue = fMaxValue;
  129. if (m_fDegree > m_fMaxValue)
  130. SetDegree(m_fMaxValue);
  131. }