| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- #include "stdafx.h"
- #include "PropertyGridInplaceEdit.h"
- #include "PropertyGridInplaceButton.h"
- #include "PropertyGridInplaceList.h"
- #include "PropertyGridItem.h"
- #include "PropertyGridItemDegree.h"
- #include <math.h>
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- CPropertyGridItemDegree::CPropertyGridItemDegree(CString strCaption, double fDegree, int nSecondPrecision)
- : CPropertyGridItem(strCaption)
- {
- _Init();
- m_nSecondPrecision = nSecondPrecision;
- SetDegree(fDegree);
- }
- CPropertyGridItemDegree::CPropertyGridItemDegree(UINT nID, double fDegree, int nSecondPrecision)
- : CPropertyGridItem(nID)
- {
- _Init();
- m_nSecondPrecision = nSecondPrecision;
- SetDegree(fDegree);
- }
- CPropertyGridItemDegree::~CPropertyGridItemDegree()
- {
- }
- void CPropertyGridItemDegree::_Init()
- {
- m_pBindDegree = NULL;
- m_bHasMinValue = FALSE;
- m_bHasMaxValue = FALSE;
- m_fMinValue = 0;
- m_fMaxValue = 0;
- }
- void CPropertyGridItemDegree::SetDegree(double fDegree)
- {
- m_fDegree = fDegree;
- if (m_bHasMinValue && m_fDegree < m_fMinValue)
- m_fDegree = m_fMinValue;
- if (m_bHasMaxValue && m_fDegree > m_fMaxValue)
- m_fDegree = m_fMaxValue;
- CPropertyGridItem::SetValue( DegreeToString(m_fDegree, m_nSecondPrecision) );
- if (m_pBindDegree)
- *m_pBindDegree = m_fDegree;
- }
- double CPropertyGridItemDegree::GetDegree()
- {
- return m_fDegree;
- }
- void CPropertyGridItemDegree::SetValue(CString strValue)
- {
- SetDegree( StringToDegree(strValue) );
- }
- CString CPropertyGridItemDegree::DegreeToString(double fDegree, int nSecondPrecision /* = 2 */)
- {
- // 计算度分秒
- int degree, minute;
- double second;
- double temp = fabs(fDegree)+(1E-6/3600);// 由于浮点数存在舍入误差,可能给取整计算度和分
- degree = (int)temp; // 带来问题。例如10.7表示为 double 类型时,其值
- temp = (temp-degree) * 60; // 为10.699...99,取整得到的度等于10,分等于41,
- minute = (int)temp; // 秒用格式%05.2f输出得到60.00。这显然不合理。
- second = (temp-minute) * 60; // 如果加一个很小的数,既能解决这个问题,又不会
- // 影响数值的精确度。这里加的是百万分之一秒。
- // 生成度分秒格式的文本
- CString strFormat; // 格式字符串
- CString strMaxSecond; // 秒的最大值(文本格式)
- if (nSecondPrecision == 0)
- {
- strFormat = _T("%d°%02d'%02.0f\"");
- strMaxSecond = _T("59");
- }
- else
- {
- strFormat.Format( _T("%%d°%%02d'%%0%d.%df\""), 3+nSecondPrecision, nSecondPrecision);
- strMaxSecond = _T("59.") + CString(_T('9'), nSecondPrecision);
- }
- #ifdef _UNICODE
- char ansi_buf[256];
- ::WideCharToMultiByte(CP_ACP, 0, strMaxSecond, -1, ansi_buf, 256, NULL, NULL);
- double fMaxSecond = atof(ansi_buf); // 秒的最大值(浮点数格式)
- #else
- double fMaxSecond = atof(strMaxSecond); // 秒的最大值(浮点数格式)
- #endif
- CString strText;
- strText.Format( strFormat,
- degree,
- minute,
- min(fMaxSecond,second) ); // 避免出现类似59.999"被格式化输出成60.00"的情况
- if (fDegree < 0)
- strText = _T('-') + strText;
- return strText;
- }
- double CPropertyGridItemDegree::StringToDegree(CString strText)
- {
- // 读取数据
- int degree = 0, minute = 0;
- float second = 0;
- #ifdef _UNICODE
- char ansi_buf[256];
- ::WideCharToMultiByte(CP_ACP, 0, strText, -1, ansi_buf, 256, NULL, NULL);
- sscanf(ansi_buf, "%d°%d'%f", °ree, &minute, &second);
- #else
- sscanf(strText, "%d°%d'%f", °ree, &minute, &second);
- #endif
- double fDegree = abs(degree) + minute/60.0 + second/3600.0;
- if (strText.Find( _T('-') ) >= 0)
- fDegree = -fDegree;
- return fDegree;
- }
- void CPropertyGridItemDegree::BindToDegree(double* pBindDegree)
- {
- m_pBindDegree = pBindDegree;
- if (m_pBindDegree)
- SetDegree(*m_pBindDegree);
- }
- void CPropertyGridItemDegree::SetMinDegree(double fMinValue)
- {
- m_bHasMinValue = TRUE;
- m_fMinValue = fMinValue;
- if (m_fDegree < m_fMinValue)
- SetDegree(m_fMinValue);
- }
- void CPropertyGridItemDegree::SetMaxDegree(double fMaxValue)
- {
- m_bHasMaxValue = TRUE;
- m_fMaxValue = fMaxValue;
- if (m_fDegree > m_fMaxValue)
- SetDegree(m_fMaxValue);
- }
|