⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tbareditctrldbl.cpp

📁 BCAM 1394 Driver
💻 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 + -