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

📄 spinedit.cpp

📁 一个自定义的SPIN控件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
BOOL CSpinEdit::DrawUpperBtn( CDC* pDC)
{
	BOOL bResult = TRUE;
    BOOL bMustReleaseDC = FALSE;

    CRect rect;
    if (!GetUpperBtnRect( rect)) return FALSE;

    if (!pDC) 
	{
        pDC = GetDC();
        if (pDC) bMustReleaseDC = TRUE;
    }

    if (pDC)
    {
		int nSavedDC = pDC->SaveDC();

		pDC->DrawFrameControl( rect, DFC_BUTTON, DFCS_BUTTONPUSH  );
		if( m_bUpperBtnPushed )
		{
			pDC->DrawEdge( rect, EDGE_SUNKEN, BF_RECT);   
		}
		else
		{
			pDC->DrawEdge( rect, EDGE_RAISED, BF_RECT);
		}

		CPoint pt[4];
		if( (rect.Height()<20) || (rect.Width()<20) )
		{
			rect.DeflateRect(rect.Width()/3,rect.Height()/3,rect.Width()/3,rect.Height()/3);
			pt[0].x = rect.left + rect.Width()/2;
			pt[0].y = rect.top;

			pt[1].x = rect.left + rect.Width()/3;
			pt[1].y = rect.bottom; 

			pt[2].x = rect.left + rect.Width()*2/3;
			pt[2].y = rect.bottom;
			
			pt[3] = pt[0];
		}
		else
		{
			pt[0].x = rect.left + rect.Width()/2;
			pt[0].y = rect.top + rect.Height()/2-3;

			pt[1].x = rect.left + rect.Width()/2-3;
			pt[1].y = rect.top + rect.Height()/2+3;

			pt[2].x = rect.left + rect.Width()/2+3;
			pt[2].y = rect.top + rect.Height()/2+3;

			pt[3] = pt[0];
		}
				
		CBrush brush;
		CPen   pen;

		if( m_bUpperBtnPushed )
		{
			brush.CreateSolidBrush( RGB(0,0,255) );
			pen.CreatePen( PS_SOLID, 1, RGB(0,0,255) );
		}
		else
		{
			brush.CreateSolidBrush( RGB(0,0,0) );
			pen.CreatePen( PS_SOLID, 1, RGB(0,0,0) );
		}

		CBrush* pOldBrush;
		CPen* pOldPen;

		pOldBrush = pDC->SelectObject( &brush );
		pOldPen = pDC->SelectObject( &pen );
		pDC->Polygon( pt, 4 );
		pDC->SelectObject( pOldBrush );
		pDC->SelectObject( pOldPen );
		pDC->RestoreDC(nSavedDC);
    } else
        InvalidateRect(rect, TRUE);    

    if (bMustReleaseDC) 
        ReleaseDC(pDC);

    return bResult;
}

// mainly drawing the black triangle on lower button
BOOL CSpinEdit::DrawLowerBtn( CDC* pDC)
{
	BOOL bResult = TRUE;
    BOOL bMustReleaseDC = FALSE;

    CRect rect;
    if (!GetLowerBtnRect( rect)) return FALSE;

    if (!pDC) 
	{
        pDC = GetDC();
        if (pDC) bMustReleaseDC = TRUE;
    }

    if (pDC)
    {
		int nSavedDC = pDC->SaveDC();

		pDC->DrawFrameControl( rect, DFC_BUTTON, DFCS_BUTTONPUSH  );
		if( m_bLowerBtnPushed )
		{
			pDC->DrawEdge( rect, EDGE_SUNKEN, BF_RECT);   
		}
		else
		{
			pDC->DrawEdge( rect, EDGE_RAISED, BF_RECT);
		}

		CPoint pt[4];
		if( (rect.Height()<20) || (rect.Width()<20) )
		{
			rect.DeflateRect(rect.Width()/3,rect.Height()/3,rect.Width()/3,rect.Height()/3);
			pt[0].x = rect.left + rect.Width()/3;
			pt[0].y = rect.top; 

			pt[1].x = rect.left + rect.Width()*2/3;
			pt[1].y = rect.top;

			pt[2].x = rect.left + rect.Width()/2;
			pt[2].y = rect.bottom;			
			
			pt[3] = pt[0];
		}
		else
		{
			pt[0].x = rect.left + rect.Width()/2;
			pt[0].y = rect.top + rect.Height()/2+3;

			pt[1].x = rect.left + rect.Width()/2-3;
			pt[1].y = rect.top + rect.Height()/2-3;

			pt[2].x = rect.left + rect.Width()/2+3;
			pt[2].y = rect.top + rect.Height()/2-3;

			pt[3] = pt[0];
		}

		CBrush brush;
		CPen   pen;

		if( m_bLowerBtnPushed )
		{
			brush.CreateSolidBrush( RGB(0,0,255) );
			pen.CreatePen( PS_SOLID, 1, RGB(0,0,255) );
		}
		else
		{
			brush.CreateSolidBrush( RGB(0,0,0) );
			pen.CreatePen( PS_SOLID, 1, RGB(0,0,0) );
		}

		CBrush* pOldBrush;
		CPen* pOldPen;

		pOldBrush = pDC->SelectObject( &brush );
		pOldPen = pDC->SelectObject( &pen );
		pDC->Polygon( pt, 4 );
		pDC->SelectObject( pOldBrush );
		pDC->SelectObject( pOldPen );
		pDC->RestoreDC(nSavedDC);
    } else
        InvalidateRect(rect, TRUE);  

    if (bMustReleaseDC) 
        ReleaseDC(pDC);

    return bResult;
}

//the frame makes the ctrl like a common ctrl's frame
BOOL CSpinEdit::DrawFrame( CDC* pDC )
{
	BOOL bResult = TRUE;
    BOOL bMustReleaseDC = FALSE;

    CRect rect;
    GetClientRect( rect);

    if (!pDC) 
	{
        pDC = GetDC();
        if (pDC) bMustReleaseDC = TRUE;
    }

    if (pDC)
    {
		pDC->DrawEdge( rect, EDGE_SUNKEN, BF_RECT);
		rect.DeflateRect(2,2,2,2);
		CBrush brush(RGB(255,255,255));
		pDC->FillRect( rect, &brush );
		if( GetFocus()->GetSafeHwnd()  == GetSafeHwnd() )
		{
			pDC->DrawFocusRect( rect );
		}
		
    } else
        InvalidateRect(rect, TRUE); 
    
	if (bMustReleaseDC) 
        ReleaseDC(pDC);

    return bResult;

}

// the inplaced edit ctrl will be shown on the text rect. We can enter the value
// we want in the inplaced ctrl. 
// the spinedit ctrl will receive a notify(OnEndInplaceEdit) from inplaced edit
// when editting is over. The entered value will be stored in m_dbValue.
BOOL CSpinEdit::ShowEdit( int nChar )
{
	BOOL bResult = TRUE;

	if( !m_bEditShow && ( nChar != VK_TAB ) )
	{
		CString strInit = GetShowText(FALSE);
		CRect rect;
		if ( GetTextRect( rect ) )
		{
			m_pEdit->ShowAt( 0, rect, strInit, nChar );
			m_bEditShow = TRUE;
			Invalidate();
		}
	}
	else if( nChar == VK_TAB )
	{
		GetParent()->SetFocus();
	}
	
	return bResult;
}

BOOL CSpinEdit::RedrawFrame()
{
	BOOL bResult = TRUE;

    CDC* pDC = GetDC();
    bResult = DrawFrame( pDC ) && bResult;
    if (pDC) ReleaseDC(pDC);

    return bResult;
}

BOOL CSpinEdit::RedrawText()
{
	BOOL bResult = TRUE;

    CDC* pDC = GetDC();
    bResult = DrawText( pDC ) && bResult;
    if (pDC) ReleaseDC(pDC);

    return bResult;
}

BOOL CSpinEdit::RedrawLowerBtn()
{
	BOOL bResult = TRUE;

    CDC* pDC = GetDC();
    bResult = DrawLowerBtn( pDC ) && bResult;
    if (pDC) ReleaseDC(pDC);

    return bResult;
}

BOOL CSpinEdit::RedrawUpperBtn()
{
	BOOL bResult = TRUE;

    CDC* pDC = GetDC();
    bResult = DrawUpperBtn( pDC ) && bResult;
    if (pDC) ReleaseDC(pDC);

    return bResult;
}

// All information, the value,extra-text and even inplaced edit ctrl are placed in the text rect
// the text rect covers the most of the ctrl
BOOL CSpinEdit::GetTextRect( CRect& rect )
{
	BOOL bResult = TRUE;
	
	GetClientRect( rect );
	if( rect.Width()<=ARROWBTN_WIDTH )
	{
		bResult = FALSE;
	}
	else
	{
		rect.right = rect.right - ARROWBTN_WIDTH;
		rect.DeflateRect( 3,3,3,3);		
	}

	return bResult;
}

// the upper button will be drawn in the rect.
// the lower button locates on the right-top cowner
BOOL CSpinEdit::GetUpperBtnRect( CRect& rect )
{
	BOOL bResult = TRUE;
	
	GetClientRect( rect );
	if( rect.Width()<=ARROWBTN_WIDTH )
	{
		rect.bottom = rect.top + rect.Height()/2;
	}
	else
	{
		rect.left = rect.right - ARROWBTN_WIDTH;
		rect.bottom = rect.top + rect.Height()/2;
	}

	return bResult;
}

// the lower button will be drawn in the rect.
// the lower button locates on the right-bottom cowner
BOOL CSpinEdit::GetLowerBtnRect( CRect& rect )
{
	BOOL bResult = TRUE;
	
	GetClientRect( rect );
	if( rect.Width()<=ARROWBTN_WIDTH )
	{
		rect.top = rect.top + rect.Height()/2;
	}
	else
	{
		rect.left = rect.right - ARROWBTN_WIDTH;
		rect.top = rect.top + rect.Height()/2;
	}

	return bResult;
}

// MOD operator between two double variables
double CSpinEdit::DoubleModValue( const double value, const double step, const BYTE bPointPos )
{
	double result;
	double dbValue, dbStep;
	int    dwValue, dwStep;	//64 bit variables would be better
	int    i;

	dbValue = value;
	dbStep  = step;
	for( i=0; i<bPointPos; i++ )
	{
		dbValue *=10;
		dbStep *= 10;
	}

	dwValue = (int)dbValue;
	dwStep  = (int)dbStep;
	
	result = ( dwValue % dwStep );
	   
	for( i=0; i<bPointPos; i++ )
	{
		result /= 10;
	}

	return result;
}

// set all attributes at the same time
BOOL CSpinEdit::SetParams(  BYTE       bType,
							BYTE	   bPointPos,
							double	   dbCurValue,
							double     dbBase,
							double     dbLower,
							double     dbUpper,
							double     dbStep,
							BOOL       bNeedExtraText,
							LPCTSTR    lpExtraText )
{
	ASSERT( (bType>=SE_INT) && (bType<SE_BUTT) );
	if( !( (bType>=SE_INT) && (bType<SE_BUTT) ) ) return FALSE;

	BOOL bResult = TRUE;
	double temp;

	m_bValueType	= bType;
	m_bPointPos		= bPointPos;
	m_dbLower		= dbLower;
	m_dbUpper		= dbUpper;
	m_dbStep		= dbStep;
	m_dbValue		= dbCurValue;
	m_dbBase		= dbBase;
	m_szExtraText	= lpExtraText;
	m_bNeedExtraText= bNeedExtraText;

	if( bType == SE_INT )
	{
		m_bPointPos		= 0;
		m_dbLower	= (int)m_dbLower;
		m_dbUpper	= (int)dbUpper;
		m_dbStep	= (int)dbStep;
		m_dbValue	= (int)dbCurValue;
		m_dbBase	= (int)dbBase;
	}

	if( m_dbLower > m_dbUpper )
	{
		temp	    = m_dbLower;
		m_dbLower	= m_dbUpper;
		m_dbUpper	= temp;
	}
	
	if( m_dbStep < 0 )
	{
		m_dbStep = (-1)*m_dbStep;
	}

	if( (m_dbUpper-m_dbLower) < m_dbStep )	
	{
		m_dbStep = m_dbUpper - m_dbLower ;
	}

	if( m_dbValue < m_dbLower )
	{
		m_dbValue = m_dbLower ;
	}
	else if ( m_dbValue > m_dbUpper ) 
	{
		m_dbValue = m_dbUpper;
	}

	if( m_dbBase < m_dbLower )
	{
		m_dbBase = m_dbLower ;
	}
	else if ( m_dbBase > m_dbUpper ) 
	{
		m_dbBase = m_dbUpper;
	}

	if( IsWindow( m_hWnd ) )
	{
		Invalidate();
		if( m_bNeedExtraText )
		{
			SetWindowText( m_szExtraText );
		}
	}

	return bResult;
}

  ////////////////////////////////////////////////////////////////////////////////
 ////////////////////// attribute access method /////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

BOOL CSpinEdit::SetValueType( const BYTE bType, const BYTE bPointPos )
{
	if( ( m_bValueType != bType ) || ( m_bPointPos != bPointPos ) )
	{
		return SetParams( bType, 
			              bPointPos,
						  m_dbValue,
						  m_dbBase,
						  m_dbLower,
						  m_dbUpper,
						  m_dbStep,
						  m_bNeedExtraText,
						  m_szExtraText );
	}
	else
	{
		return TRUE;
	}
}

BYTE CSpinEdit::GetValueType( void )
{
	return m_bValueType;
}

BYTE CSpinEdit::GetValuePos( void )
{
	return m_bPointPos;
}

BOOL CSpinEdit::SetCurValue( double dbValue )
{
	if( m_dbValue != dbValue )
	{
		return SetParams( m_bValueType, 
			              m_bPointPos,
						  dbValue,
						  m_dbBase,
						  m_dbLower,
						  m_dbUpper,
						  m_dbStep,
						  m_bNeedExtraText,
						  m_szExtraText );
	}
	else
	{
		return TRUE;
	}
}
double CSpinEdit::GetCurValue( void )
{
	return m_dbValue;
}

BOOL CSpinEdit::SetBase( double dbBase )
{
	if( m_dbBase != dbBase )
	{
		return SetParams( m_bValueType, 
			              m_bPointPos,
						  m_dbValue,
						  dbBase,
						  m_dbLower,
						  m_dbUpper,
						  m_dbStep,
						  m_bNeedExtraText,
						  m_szExtraText );
	}
	else
	{
		return TRUE;
	}
}

double CSpinEdit::GetBase( void )
{
	return m_dbBase;
}

BOOL CSpinEdit::SetRange( double dbLower, double dbUpper )
{
	if( ( m_dbLower != dbLower ) || ( m_dbUpper != dbUpper ) )
	{
		return SetParams( m_bValueType, 
			              m_bPointPos,
						  m_dbValue,
						  m_dbBase,
						  dbLower,
						  dbUpper,
						  m_dbStep,
						  m_bNeedExtraText,
						  m_szExtraText );
	}
	else
	{
		return TRUE;
	}
}


void CSpinEdit::GetRange( double &dbLower, double &dbUpper )
{
	dbLower = m_dbLower;
	dbUpper = m_dbUpper;
	return;
}

BOOL CSpinEdit::SetStep( double dbStep )
{
	if( m_dbStep != dbStep )
	{
		if( dbStep > ( m_dbUpper-m_dbLower ) )
		{
			dbStep = DoubleModValue( dbStep, m_dbUpper-m_dbLower, m_bPointPos );
		}

		return SetParams( m_bValueType, 
			              m_bPointPos,
						  m_dbValue,
						  m_dbBase,
						  m_dbLower,
						  m_dbUpper,
						  dbStep,
						  m_bNeedExtraText,
						  m_szExtraText );
	}
	else
	{
		return TRUE;
	}
}

double CSpinEdit::GetStep( void )
{
	return m_dbStep;
}

BOOL CSpinEdit::SetExtraText( LPCTSTR lpStr )
{
	if ( m_szExtraText != lpStr )
	{
		return SetParams( m_bValueType, 
			              m_bPointPos,
						  m_dbValue,
						  m_dbBase,
						  m_dbLower,
						  m_dbUpper,
						  m_dbStep,
						  m_bNeedExtraText,
						  lpStr );
	}
	else
	{
		return TRUE;
	}
}
CString CSpinEdit::GetExtraText( void )
{
	return m_szExtraText;
}

void CSpinEdit::SetNeedExtraText( BOOL bNeed )
{
	if ( m_bNeedExtraText != bNeed )
	{
		SetParams( m_bValueType, 
			      m_bPointPos,
				  m_dbValue,
				  m_dbBase,
				  m_dbLower,
				  m_dbUpper,
				  m_dbStep,
				  bNeed,
				  m_szExtraText );
	}
}
BOOL CSpinEdit::GetNeedExtraText( void )
{
	return m_bNeedExtraText;
}

CSEEdit* CSpinEdit::GetEditCtrl( void )
{
	return m_pEdit;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -