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

📄 drawsample.cpp

📁 组态王图库开发包
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	labelmetric.textPenFontStyle = 0 ;
	labelmetric.pLabel = szLabel ;
	CSize sizeShortLabel = KVGetLabelMetric( &labelmetric ) ;	
	int nLimitRectWidth = graphic.x2 - graphic.x1 ;
	int nLimitRectHeight = graphic.y2 - graphic.y1 ;
	graphic.x1 += ( nLimitRectWidth - sizeShortLabel.cx ) / 2 ;
	graphic.x2 = graphic.x1 + sizeShortLabel.cx ;
	graphic.y1 += ( nLimitRectHeight - sizeShortLabel.cy ) / 2 ;
	graphic.y2 = graphic.y1 + sizeShortLabel.cy ;
	graphic.pText = szLabel ;
	KVDrawLabel( &graphic );	
}

/*
功    能:获得表盘刻度标签外切矩形
返 回 值:刻度标签外切矩形
输入参数:
	rcMeterScale  : 圆外切矩形                                   \ | /
	nStartAngle   :  刻度线的起始角                              ->\|/<-
	nEndAngle     : 刻度线的结束角                 nStartAngle (   |   ) nEndAngle 
	pScale        :  刻度线结构指针,不能为 NULL                     |
	pLabel        : 标签结构指针,为 NULL 不画标签               
	bMarkInside   :  刻度在内( TRUE ),刻度在外( FALSE ) 
*/
CRect GetMeterScaleLabelRect( CRect & rcMeterScale,
					int nStartAngle, int nEndAngle,
					METERSCALE * pScale,
					METERSCALELABEL * pLabel,
					BOOL bMarkInside )
{
	ASSERT( pScale != NULL ) ;
	ASSERT( pLabel != NULL ) ;

	CRect rcScaleLabel ;
	rcScaleLabel.SetRectEmpty() ;

	int nSign = bMarkInside ? -1 : 1 ;
	
	// 计算圆心位置,圆的半径
	long lRadius ; 
	if ( rcMeterScale.Width() < rcMeterScale.Height() )
		lRadius = rcMeterScale.Width() / 2 ;
	else
		lRadius = rcMeterScale.Height() / 2 ;
	CPoint ptCenter = rcMeterScale.CenterPoint() ;
	lRadius += nSign * 2 ;

	// 计算主刻度总角度,每一主刻度角度
	double dblScaleAngle = ( 360 - nStartAngle - nEndAngle ) * PI / 180 ;
	double dblEveryPrimeScaleAngle = dblScaleAngle / ( pScale->nPrimeScale - 1 ) ;
	
	// 计算主刻度标签位置
	CPoint ptScaleFrom , ptScaleTo ;
	for ( int i = 0 ; i < pScale->nPrimeScale ; i ++ )
	{
		// 计算主刻度线
		double dblPrimeScaleAngle = ( 270 - nStartAngle )  * PI / 180 - dblEveryPrimeScaleAngle * i ;
		if ( fabs( dblPrimeScaleAngle ) >= 2 * PI )
			dblPrimeScaleAngle = fmod( dblPrimeScaleAngle , 2 * PI ) ;
		ptScaleFrom.x = ptCenter.x + long( lRadius * cos( dblPrimeScaleAngle ) ) ;
		ptScaleFrom.y = ptCenter.y - long( lRadius * sin( dblPrimeScaleAngle ) ) ;
		ptScaleTo.x = ptCenter.x + long( ( lRadius + nSign * pScale->nPrimeScaleLen ) * cos( dblPrimeScaleAngle ) ) ;
		ptScaleTo.y = ptCenter.y - long( ( lRadius + nSign * pScale->nPrimeScaleLen ) * sin( dblPrimeScaleAngle ) ) ;
		
		// 画主刻度标签
		if ( pLabel != NULL && ( i % pLabel->nMainDiff == 0 || i == pScale->nPrimeScale - 1 ) )
		{
			CPoint ptLabelAtCircle ; // 标签环绕的圆和标签的交点
			ptLabelAtCircle.x = ptCenter.x + long( ( lRadius + nSign * ( pScale->nPrimeScaleLen + pLabel->nLabelOffset ) ) * cos( dblPrimeScaleAngle ) ) ;
			ptLabelAtCircle.y = ptCenter.y - long( ( lRadius + nSign * ( pScale->nPrimeScaleLen + pLabel->nLabelOffset ) ) * sin( dblPrimeScaleAngle ) ) ;
			LABELMETRIC labelmetric ;
			labelmetric.textPenFontIndex = pLabel->nPenFontIndex ;
			labelmetric.textPenFontHeight = pLabel->nPenFontHeight ;
			labelmetric.textPenFontWidth = pLabel->nPenFontWidth ;
			labelmetric.textPenFontStyle = pLabel->nPenFontStyle ;
			CString strScale ;
			double dblCurrScale = pLabel->fltMinScale + i * ( pLabel->fltMaxScale - pLabel->fltMinScale ) / ( pScale->nPrimeScale - 1 ) ;
			if ( i == pScale->nPrimeScale - 1 )
				dblCurrScale = pLabel->fltMaxScale ;
			int nDecimalLen = pLabel->nLabelDecimalLen ;
			strScale = GetScaleLabelText( dblCurrScale, nDecimalLen ) ;
			TCHAR * pLabelText = new TCHAR[ strScale.GetLength() + 1 ] ;
			_tcscpy( pLabelText , strScale ) ;
			labelmetric.pLabel = pLabelText ;
			CSize sizeLabel = KVGetLabelMetric( &labelmetric ) ;
			delete pLabelText ;
			pLabelText = NULL ;
			CPoint ptLabelTopLeft( 0, 0 ) ;
			if ( fabs( dblPrimeScaleAngle ) < VERY_LITTLE )
			{
				ptLabelTopLeft.x = ptLabelAtCircle.x - ( ( 1 - nSign ) / 2 ) * sizeLabel.cx ;
				ptLabelTopLeft.y = ptLabelAtCircle.y - sizeLabel.cy / 2 ;
			}
			else if ( fabs( dblPrimeScaleAngle - PI / 2 ) < VERY_LITTLE )
			{
				ptLabelTopLeft.x = ptLabelAtCircle.x - sizeLabel.cx / 2 ;
				ptLabelTopLeft.y = ptLabelAtCircle.y - ( ( 1 + nSign ) / 2 ) * sizeLabel.cy ;
			}
			else if ( fabs( dblPrimeScaleAngle - PI ) < VERY_LITTLE )
			{
				ptLabelTopLeft.x = ptLabelAtCircle.x - ( ( 1 + nSign ) / 2 ) * sizeLabel.cx ;
				ptLabelTopLeft.y = ptLabelAtCircle.y - sizeLabel.cy / 2 ;
			}
			else if ( fabs( dblPrimeScaleAngle - 3 * PI / 2 ) < VERY_LITTLE 
				|| fabs( dblPrimeScaleAngle - ( - PI / 2 ) ) < VERY_LITTLE )
			{
				ptLabelTopLeft.x = ptLabelAtCircle.x - sizeLabel.cx / 2 ;
				ptLabelTopLeft.y = ptLabelAtCircle.y - ( ( 1 - nSign ) / 2 ) * sizeLabel.cy ;
			}
			else if ( dblPrimeScaleAngle > 0 && dblPrimeScaleAngle < PI / 2 )
			{
				ptLabelTopLeft.x = ptLabelAtCircle.x - ( ( 1 - nSign ) / 2 ) * sizeLabel.cx ;
				ptLabelTopLeft.y = ptLabelAtCircle.y - sizeLabel.cy + ( ( 1 - nSign ) / 2 ) * sizeLabel.cy ;
			}			
			else if ( dblPrimeScaleAngle > PI / 2 && dblPrimeScaleAngle < PI )
			{
				ptLabelTopLeft.x = ptLabelAtCircle.x - sizeLabel.cx + ( ( 1 - nSign ) / 2 ) * sizeLabel.cx ;
				ptLabelTopLeft.y = ptLabelAtCircle.y - sizeLabel.cy + ( ( 1 - nSign ) / 2 ) * sizeLabel.cy ;
			}			
			else if ( dblPrimeScaleAngle > PI && dblPrimeScaleAngle < 3 * PI / 2 )
			{
				ptLabelTopLeft.x = ptLabelAtCircle.x - sizeLabel.cx + ( ( 1 - nSign ) / 2 ) * sizeLabel.cx ;
				ptLabelTopLeft.y = ptLabelAtCircle.y - ( ( 1 - nSign ) / 2 ) * sizeLabel.cy ;
			}
			else if ( dblPrimeScaleAngle < 0 && dblPrimeScaleAngle > - PI / 2 )
			{
				ptLabelTopLeft.x = ptLabelAtCircle.x - ( ( 1 - nSign ) / 2 ) * sizeLabel.cx ;
				ptLabelTopLeft.y = ptLabelAtCircle.y - ( ( 1 - nSign ) / 2 ) * sizeLabel.cy ;
			}			

			if ( ptLabelTopLeft.x < rcScaleLabel.left )
				rcScaleLabel.left = ptLabelTopLeft.x ;
			if ( ptLabelTopLeft.y < rcScaleLabel.top )
				rcScaleLabel.top = ptLabelTopLeft.y ;
			if ( ptLabelTopLeft.x + sizeLabel.cx > rcScaleLabel.right )
				rcScaleLabel.right = ptLabelTopLeft.x + sizeLabel.cx ;
			if ( ptLabelTopLeft.y + sizeLabel.cy > rcScaleLabel.bottom )
				rcScaleLabel.bottom = ptLabelTopLeft.y + sizeLabel.cy ;
						
		} // if pLabel 
		
	} // for i

	return rcScaleLabel ;
}

 /*
** 功    能:取得刻度标签文本
** 返 回 值:刻度标签文本
** 参    数:
**          dblCurrScale 刻度数值
**          nDecimalLen  小数位数
** 说    明:最长7s位,超过7位用科学计数法
*/
CString GetScaleLabelText( double dblCurrScale, int nDecimalLen )
{
	if ( nDecimalLen < 0 )
		return _T( "" ) ;

	BOOL bPositive = FALSE ;
	if ( dblCurrScale < 0 )
	{
		bPositive = TRUE ;
		dblCurrScale = fabs( dblCurrScale ) ;
	}

	CString strScale ;

	if ( dblCurrScale == double( 0.0 ) )
		strScale = nDecimalLen > 0 ? _T( "0.0" ) : _T( "0" ) ;
	else
	{
		long lCurrScalInteger = long( dblCurrScale ) ;
		double dblCurrScaleDecimal = dblCurrScale - lCurrScalInteger ;
		CString strDecimal ;
		if ( nDecimalLen > 0 )
		{
			strScale.Format( _T( "%ld." ) , lCurrScalInteger ) ;
			int nDecimalRemainLen = nDecimalLen ;
			while ( nDecimalRemainLen > 0 )
			{
				dblCurrScaleDecimal *= 10 ;
				strDecimal.Format( _T( "%d" ) , long( dblCurrScaleDecimal ) ) ;
				strScale += strDecimal ;
				dblCurrScaleDecimal -= long( dblCurrScaleDecimal ) ;
				--nDecimalRemainLen ;
			}	
		}
		else
			strScale.Format( _T( "%ld" ) , lCurrScalInteger ) ;

		if ( strScale.GetLength() > 7 || dblCurrScale < pow( 10, ( -1 ) * nDecimalLen ) )
		{			
			strScale.Format( _T( "%.1e" ) , dblCurrScale ) ;
			CString strInteger = strScale.Left( 1 ) ;
			CString strDecimal = strScale.Mid( 1, 2 ) ;
			CString strExponent = _T( "" ) ;
			strExponent += strScale[ 3 ] ;
			if ( strScale[ 4 ] == _T( '-' ) )
				strExponent += strScale[ 4 ] ; 
			for ( int i = 5 ; i <= 7 ; i ++ )
			{
				if ( strScale[ i ] > _T( '0' ) )
				{
					strExponent += strScale.Mid( i ) ;
					break ;
				}
			}
			if ( strInteger.GetLength() + strDecimal.GetLength() + strExponent.GetLength() > 7 )
				strScale = strInteger + strExponent ;
			else
				strScale = strInteger + strDecimal + strExponent ;
		}
	}

	if ( bPositive )
		strScale.Insert( 0, _T( '-' ) ) ;

	return strScale ;
}

/*
** 功    能:剪裁字符串以适应标签结构中的矩形
** 参    数:
**          graphic     标签结构
**          nOffset     标签与边界的偏差
** 返 回 值:剪裁后的字符串
**
*/
CString MakeShortString( DRAWLABEL & graphic, int nOffset)
{
	TCHAR szThreeDots[] = _T("...");

	TCHAR szLong[ MAX_PATH ];
	_tcscpy( szLong, graphic.pText ) ;

	LABELMETRIC labelmetric ;
	labelmetric.textPenFontIndex = graphic.textPenFontIndex ;
	labelmetric.textPenFontHeight = graphic.textPenFontHeight ;
	labelmetric.textPenFontWidth = 0 ;
	labelmetric.textPenFontStyle = 0 ;
	labelmetric.pLabel = szLong ;
	CSize sizeLabel = KVGetLabelMetric( &labelmetric ) ;
	
	// 调整矩形
	if ( graphic.x2 < graphic.x1 )
	{
		int nTemp = graphic.x1 ;
		graphic.x1 = graphic.x2 ;
		graphic.x2 = nTemp ;
	}
	if ( graphic.y2 < graphic.y1 )
	{
		int nTemp = graphic.y1 ;
		graphic.y1 = graphic.y2 ;
		graphic.y2 = nTemp ;
	}

	// 调整高度
	while ( sizeLabel.cy > graphic.y2 - graphic.y1 - 2 * nOffset )
	{
		++labelmetric.textPenFontHeight ;
		sizeLabel = KVGetLabelMetric( &labelmetric ) ;
	}

	// 无须调整宽度,返回
	if ( sizeLabel.cx == 0 || sizeLabel.cx <= graphic.x2 - graphic.x1 - 2 * nOffset )
			return CString( labelmetric.pLabel ) ;	

	// 调整宽度
	static TCHAR szShort[ MAX_PATH ];
	_tcscpy( szShort, graphic.pText );
	labelmetric.pLabel = szThreeDots ;
	CSize sizeThreeDots = KVGetLabelMetric( &labelmetric ) ;
	int nStringLen = _tcslen( szShort ) ;
	for( int i = nStringLen-1; i > 0; i-- )
	{
		szShort[ i ] = _T( '\0' ) ;
		labelmetric.pLabel = szShort ;
		CSize sizeShortLabel = KVGetLabelMetric( &labelmetric ) ;
		if( sizeShortLabel.cx + sizeThreeDots.cx <= graphic.x2 - graphic.x1 - 2 * nOffset )
				break;		
	}

	// 调整汉字宽度
	int nNonAsciiCount = 0 ;
	for ( int j = i - 1 ; j >= 0 ; j -- , nNonAsciiCount ++ ) 
	{
		if ( szShort[ j ] > 0 && szShort[ j ] < 255  )
			break ;
	}
	if ( nNonAsciiCount % 2 != 0 )
	{
		i -- ;
		szShort[i] = _T( '\0' ) ;
	}

	_tcscat( szShort, szThreeDots ) ;
	
	return CString( szShort );	
}

⌨️ 快捷键说明

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