📄 tbareditctrldbl.cpp
字号:
//-----------------------------------------------------------------------------
// (c) 2002 by Basler Vision Technologies
// Section: Vision Components
// Project: BCAM
// $Header: TBarEditCtrlDbl.cpp, 5, 02.08.2004 15:54:55, Happe, A.$
//-----------------------------------------------------------------------------
/**
\file TBarEditCtrlDbl.cpp
\brief implementation of the CTBarEditCtrlDbl class.
*/
#include <atlbase.h>
#include <atlapp.h>
extern CAppModule _Module;
#include <atlwin.h>
#include "math.h"
#include "float.h"
#include "ChkRecursion.h"
#include "TBarEditCtrlDbl.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
CTBarEditCtrlDbl::CTBarEditCtrlDbl(bool bPostMsgEnabled /*= true*/)
: CTBarEditCtrlBase(bPostMsgEnabled)
{
m_nFormatWidth = 1;
m_nFormatPrecision = 1;
m_pFmtFnc = NULL;
m_dLineSize = 0.0;
m_dPageSize = 0.0;
m_dValueMinDiff = pow(10.0, (double)(m_nFormatPrecision * -1)) / 2.0;
}
CTBarEditCtrlDbl::~CTBarEditCtrlDbl()
{
}
//////////////////////////////////////////////////////////////////////
//
double CTBarEditCtrlDbl::RoundValue(double dValue, RND_TYPE rndType)
{
// get precision of value (don't know an other way to determine this...)
char szBuf[128], *pszChr;
int nValPrec = 0;
sprintf(szBuf, "%.10f", dValue);
if ( (pszChr = strchr(szBuf, '.')) != NULL || (pszChr = strchr(szBuf, ',')) != NULL )
{
int i;
i = strlen(++pszChr);
while ( --i >= 0 )
{
if ( *(pszChr + i) != 0x30 )
break;
}
nValPrec = i + 1;
}
if ( nValPrec <= m_nFormatPrecision )
return dValue; // no need to round
// round up or down
double dFrac, dPrec;
dPrec = pow(10.0, (double)(m_nFormatPrecision * -1));
dFrac = fmod(dValue, dPrec);
if ( dFrac == 0.0 )
return dValue; // no need to round
bool bNeg = dValue < 0.0;
if ( rndType == RND_AUTO )
rndType = (dFrac >= (dPrec * 0.5)) ? RND_UP : RND_DOWN;
if ( rndType == RND_UP )
dValue = (bNeg) ? (dValue - dFrac) : (dValue + (dPrec - dFrac));
else
dValue = (bNeg) ? (dValue - (dPrec + dFrac)) : (dValue - dFrac);
return dValue;
}
//////////////////////////////////////////////////////////////////////
//
bool CTBarEditCtrlDbl::SetRangeMin(double dRangeMin, bool bRedraw /*= true*/)
{
return SetRange(dRangeMin, m_dRangeMax, bRedraw);
}
bool CTBarEditCtrlDbl::SetRangeMax(double dRangeMax, bool bRedraw /*= true*/)
{
return SetRange(m_dRangeMin, dRangeMax, bRedraw);
}
bool CTBarEditCtrlDbl::SetRange(double dRangeMin, double dRangeMax, bool bRedraw /*= true*/)
{
if ( dRangeMin >= dRangeMax )
return false;
m_dRangeMin = dRangeMin;
m_dRangeMax = dRangeMax;
return UpdateRange(bRedraw);
}
double CTBarEditCtrlDbl::GetRangeMin() const
{
return m_dRangeMin;
}
double CTBarEditCtrlDbl::GetRangeMax() const
{
return m_dRangeMax;
}
void CTBarEditCtrlDbl::GetRange(double& dMin, double& dMax) const
{
dMin = GetRangeMin();
dMax = GetRangeMax();
}
//////////////////////////////////////////////////////////////////////
//
bool CTBarEditCtrlDbl::UpdateRange(bool bRedraw /*= true*/)
{
// round range to given precision
m_dRangeMinRnd = RoundUp(m_dRangeMin);
m_dRangeMaxRnd = RoundDown(m_dRangeMax);
// compute absolute range to determine if scaling is necessary
m_dRangeAbs = fabs(m_dRangeMinRnd) + fabs(m_dRangeMaxRnd);
// always scale
m_dScaleFactor = m_dRangeAbs / (double)(32000);
m_nScaleRangeMin = (int)floor(m_dRangeMinRnd / m_dScaleFactor) - 1;
m_nScaleRangeMax = (int)ceil (m_dRangeMaxRnd / m_dScaleFactor) + 1;
// ATLTRACE("CTBarEditCtrl::UpdateRangeDbl f=%g, min=%d, max=%d\n", m_dScaleFactor, m_nScaleRangeMin, m_nScaleRangeMax);
m_nRangeMin = m_nScaleRangeMin;
m_nRangeMax = m_nScaleRangeMax;
CTrackBarCtrl::SetRange(m_nScaleRangeMin, m_nScaleRangeMax, bRedraw);
UpdateRangeText();
// update line and page size
if ( m_dLineSize != 0 )
SetLineSize(m_dLineSize);
if ( m_dPageSize != 0 )
SetPageSize(m_dPageSize);
// call impl of parent class (if overridden)
return NotifyRangeChanged(bRedraw);
}
void CTBarEditCtrlDbl::UpdateRangeText()
{
char szBuf[256];
FmtValue(szBuf, m_dRangeMinRnd);
if ( m_ctrlTxtL.IsWindow() )
m_ctrlTxtL.SetWindowText(szBuf);
FmtValue(szBuf, m_dRangeMaxRnd);
if ( m_ctrlTxtR.IsWindow() )
m_ctrlTxtR.SetWindowText(szBuf);
}
bool CTBarEditCtrlDbl::NotifyRangeChanged(bool bRedraw /*= true*/)
{
// limit value to range
if ( LimitValue() && m_bWantReturn )
{
m_bOnChange2Parent = m_bOnUpdate2Parent = true; // notify parent
// update controls
UpdateValue();
UpdateThumb(m_dValue);
return true;
}
return false;
}
//////////////////////////////////////////////////////////////////////
//
/**********
* SetValue - Set the value
* Posting of EN_UPDATE and EN_CHANGE is *forced*, if WantReturn is active
*
* @param dValue the value to set
* @param bTrackThumb if true, the thumb position will be set. Is mostly used internal
* @return FALSE if the value was limited to the actual range
*/
bool CTBarEditCtrlDbl::SetValue(double dValue, bool bTrackThumb /*= true*/)
{
// force posting EN_UPDATE and EN_CHANGE
if ( m_bWantReturn )
m_bOnChange2Parent = m_bOnUpdate2Parent = true; // notify parent
return InternalSetValue(dValue, bTrackThumb);
}
/**********
* InternalSetValue - Set the value
* Posting of EN_UPDATE and EN_CHANGE is *not* forced, if WantReturn is active
*
* @param dValue the value to set
* @param bTrackThumb if true, the thumb position will be set. Is mostly used internal
* @return FALSE if the value was limited to the actual range
*/
bool CTBarEditCtrlDbl::InternalSetValue(double dValue, bool bTrackThumb /*= true*/)
{
m_dValue = Round(dValue);
// ATLTRACE("CTBarEditCtrlBase::SetValue set = %f >> %f\n", dValue, m_dValue);
// limit value to range
bool bNotChgd = !LimitValue();
// update controls
UpdateValue();
UpdateThumb(m_dValue, bTrackThumb);
return bNotChgd;
}
/**********
* DDXValue - used by DDX_TBAREDIT
*
* @return FALSE if the value was limited to the actual range
*/
bool CTBarEditCtrlDbl::DDXValue(UINT /*nID*/, double &dValue, BOOL bSave, BOOL /* bValidate = false*/)
{
if ( bSave )
{
dValue = GetValue();
// ATLTRACE("CTBarEditCtrlBase::DDXValue get = %f\n", dValue);
return true;
}
return SetValue(dValue);
}
/**********
* GetValue - Get the value
*/
double CTBarEditCtrlDbl::GetValue()
{
return m_dValue;
}
double CTBarEditCtrlDbl::SetLineSize(double dLogSize)
{
int nNewSize, nCurSize;
nNewSize = (int)(dLogSize / m_dScaleFactor);
nCurSize = CTBarCtrlBase::SetLineSize(nNewSize);
m_dLineSize = dLogSize; // memo new page size
return (double) nCurSize * m_dScaleFactor;
}
double CTBarEditCtrlDbl::GetLineSize(void)
{
return (double) CTBarCtrlBase::GetLineSize() * m_dScaleFactor;
}
double CTBarEditCtrlDbl::SetPageSize(double dLogSize)
{
int nNewSize, nCurSize;
nNewSize = (int)(dLogSize / m_dScaleFactor);
nCurSize = CTBarCtrlBase::SetPageSize(nNewSize);
m_dPageSize = dLogSize; // memo new page size
return (double) nCurSize * m_dScaleFactor;
}
double CTBarEditCtrlDbl::GetPageSize(void)
{
return (double) CTBarCtrlBase::GetPageSize() * m_dScaleFactor;
}
void CTBarEditCtrlDbl::SetPrecision(int nPrecision, int nWidth /*= 0*/)
{
m_nFormatWidth = (nWidth > 1) ? nWidth : 1;
m_nFormatPrecision = (nPrecision > 1) ? nPrecision : 1;
m_dValueMinDiff = pow(10.0, (double)(m_nFormatPrecision * -1)) / 2.0;
UpdateRange(true);
UpdateValue();
UpdateThumb(m_dValue, false);
}
//////////////////////////////////////////////////////////////////////
//
int CTBarEditCtrlDbl::FmtValue(char *szBuf, double dValue)
{
int nCharsPrinted;
if ( m_pFmtFnc != NULL )
#pragma warning(push)
#pragma warning(disable: 4244) // conversion from double to int, possible loss of data
nCharsPrinted = (m_pFmtFnc)(szBuf, dValue, m_nFormatWidth, m_nFormatPrecision);
#pragma warning(pop)
else
nCharsPrinted = sprintf(szBuf, _T("%*.*f"), m_nFormatWidth, m_nFormatPrecision, dValue);
return nCharsPrinted;
}
void CTBarEditCtrlDbl::UpdateValue()
{
char szBuf[128];
FmtValue(szBuf, m_dValue);
if ( CEditCtrlBase::IsWindow() )
if ( strcmp(m_szWndTxt, szBuf) )
CEditCtrlBase::SetWindowText(szBuf);
}
bool CTBarEditCtrlDbl::LimitValue()
{
if ( m_dValue < m_dRangeMinRnd )
{
m_dValue = m_dRangeMinRnd;
return true;
}
if ( m_dValue > m_dRangeMaxRnd )
{
m_dValue = m_dRangeMaxRnd;
return true;
}
return false;
}
//////////////////////////////////////////////////////////////////////
//
void CTBarEditCtrlDbl::UndoInput()
{
int nStartPos, nEndPos;
// get current caret position
CEditCtrlBase::GetSel(nStartPos, nEndPos);
// set last know value
SetValue(m_dValue);
// restore caret
CEditCtrlBase::SetSel(nStartPos, nEndPos);
}
bool CTBarEditCtrlDbl::UpdateEditText()
{
static int nRecursivCalls = 0;
CChkRecursion cChkRecursion(&nRecursivCalls);
if ( cChkRecursion.Check(2) )
{
// ATLTRACE("CTBarEditCtrlDbl::UpdateEditText !!!max. recursion!!!\n");
return false;
}
char szBuf[256];
int nStartPos, nEndPos;
double dValue = 0.0;
// get current caret position
CEditCtrlBase::GetSel(nStartPos, nEndPos);
// get current edit text and value
if ( CEditCtrlBase::GetWindowText(szBuf, sizeof(szBuf)-1) )
{
dValue = atof(szBuf);
// force SetValue(), even if rounded value doesn't differ!
if ( strcmp(m_szWndTxt, szBuf) )
m_szWndTxt[0] = '\0';
}
// if the value has changed...
// ... reflect value to all associated controls
// ... reposition the caret
double dDiff = fabs(dValue - m_dValue);
// if ( dDiff >= (m_dValueMinDiff + DBL_EPSILON) )
if ( dDiff >= (DBL_EPSILON * 2.0) )
{
InternalSetValue(dValue);
CEditCtrlBase::SetSel(nStartPos, nEndPos);
return true;
}
return false;
}
//////////////////////////////////////////////////////////////////////
//
bool CTBarEditCtrlDbl::GoCenterValue()
{
if ( m_bWantReturn )
m_bOnChange2Parent = m_bOnUpdate2Parent = true;
return SetValue( m_dRangeMinRnd + (m_dRangeAbs / 2.0) );
}
//////////////////////////////////////////////////////////////////////
//
LRESULT CTBarEditCtrlDbl::HScroll(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
static bool bEventThumbPosition = false;
int nThumbPos = (short) HIWORD(wParam);
bHandled = false;
m_bOnChange2Parent = false;
m_bOnUpdate2Parent = false;
bool notifyParent = false;
switch( LOWORD(wParam) )
{
case TB_TOP:
case TB_BOTTOM: // pos1/home
case TB_LINEUP:
case TB_LINEDOWN: // cursor up/down
case TB_PAGEUP:
case TB_PAGEDOWN: // page up/down
InternalSetValue(CTBarCtrlBase::GetPos() * m_dScaleFactor, false);
notifyParent = m_bLiveUpdateEnabled;
break;
case TB_THUMBPOSITION: // User has dragged
bEventThumbPosition = true;
InternalSetValue(nThumbPos * m_dScaleFactor);
notifyParent = m_bLiveUpdateEnabled;
break;
case TB_THUMBTRACK: // User is dragging
if ( !bEventThumbPosition )
{
InternalSetValue(nThumbPos * m_dScaleFactor);
notifyParent = m_bLiveUpdateEnabled;
}
bEventThumbPosition = false;
break;
case TB_ENDTRACK: // end of dragging/moving
notifyParent = true;
break;
default:
break;
}
if ( notifyParent && m_bWantReturn )
{
if ( m_nPostMsgID )
{
PostParent(WM_COMMAND, MAKELPARAM(m_nPostMsgID, EN_UPDATE), (LPARAM) m_hEditCtrl);
PostParent(WM_COMMAND, MAKELPARAM(m_nPostMsgID, EN_CHANGE), (LPARAM) m_hEditCtrl);
}
else
{
PostParent(WM_COMMAND, MAKELPARAM(m_nEditCtrlID, EN_UPDATE), (LPARAM) m_hEditCtrl);
PostParent(WM_COMMAND, MAKELPARAM(m_nEditCtrlID, EN_CHANGE), (LPARAM) m_hEditCtrl);
}
m_bOnChange2Parent = true;
m_bOnUpdate2Parent = true;
}
// ATLTRACE("CTBarEditCtrlBase::OnHScroll w=%x -> t=%d\n", wParam, nThumbPos);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -