Beispiel #1
0
// 绘制的顺序,先坐标,再曲线、擦除多余的曲线、坐标值、标记、参数值
void CFFTDisp::DrawCurve()
{
	int i,j;
	CSize szText;
	int x;
	int y;
	CFont* pOldFont;
	CString strMsg;
	CPen *pOldPen;
	double dErr = 0;

	// 与背景对齐
	int nSigPicWidth = m_nClientWidth - FFT_LEFT_MARGIN * 2;
	int nSigPicHeight = m_nClientHeight - FFT_TOP_MARGIN * 2;	
	int nSigPicSmallWidth = nSigPicWidth / FFT_NUM_HORZ;
	int nSigPicSmallHeight = nSigPicHeight / FFT_NUM_VERT;
	// 对齐后的宽度和高度
	int nPicWidth = nSigPicSmallWidth * FFT_NUM_HORZ;
	int nPicHeight = nSigPicSmallHeight * FFT_NUM_VERT;
	
	if ( m_dcPlot.GetSafeHdc() != NULL )
	{		
		// 清除原来的图像
		m_dcPlot.SetBkColor (m_crBackColor) ;
		m_dcPlot.FillRect(m_rectPlot, &m_brushBack) ;
		// 标题
		///////////////////////////////////////////////////////////////////////////
		pOldFont = m_dcPlot.SelectObject( &m_fntTitle );
		m_dcPlot.SetTextColor( m_crImageColor );
		m_dcPlot.TextOut( 2, 2, m_strTitle );
		if ( pOldFont != NULL )
		{			
			m_dcPlot.SelectObject( pOldFont );
		}
		///////////////////////////////////////////////////////////////////////////

		/*
		// 计算Ain
		dErr = 0;		
		CAdcTestPlatView* pView = (CAdcTestPlatView*)GetParent();
		if ( pView != NULL && pView->m_dVpp > 0 )
		{
			// Ain(峰峰值最大为2V)
			dErr = 20*log10( pView->m_dVpp / 2);
		}
		*/

		// 计算Ain
		dErr = 0;
// 		if ( m_dVpp > 0 )
// 		{
// 			dErr = 20*log10( m_dVpp / 2);
// 		}

		// 显示曲线、坐标
		/////////////////////////////////////////////////////////////////////////
		// 画笔
		CPen penCh1Signal( PS_SOLID, 1, m_crImageColor );
		pOldPen = m_dcPlot.SelectObject( &penCh1Signal );
		// 先进行修正(原来更新点数为m_dwDot,所以出现只更新前面数据,后面数据不更新的情况)
		// m_dwDot -> MAX_DEPTH
		for ( i = 0; i < MAX_DEPTH; i++ )
		{
			//m_FFTData[i] += dErr;
			m_daDispData[i] = m_FFTData[i] + dErr;
		}
		// 计算最大值/最小值(这段没有意义,实际的最大最小在下面指定)
		m_dMaxData = -10000;
		m_dMinData = 0;
		for ( i = 0; i < m_dwDot; i++ )
		{
			if ( m_nBeginPos+i >= 0 && m_nBeginPos+i < MAX_DEPTH/2 )
			{
				if ( m_daDispData[m_nBeginPos+i] > m_dMaxData )
				{
					m_dMaxData = m_daDispData[m_nBeginPos+i];
				}
				if ( m_daDispData[m_nBeginPos+i] < m_dMinData )
				{
					m_dMinData = m_daDispData[m_nBeginPos+i];
				}
			}
			
		}
		// 最大值为0dB
		m_dMaxData = 0;
		// 最小值为-120dB -> -160
		m_dMinData = -160;
		// 每像素的点数
		double dPointXpixel = (nPicWidth - 0.0) / m_dwDot;
		double dPointYpixel = (nPicHeight - 0.0 ) / (m_dMaxData-m_dMinData);		

		
		// 画笔
		CPen penAxi( PS_DOT, 1, RGB(128, 128, 128));		
		pOldPen = m_dcPlot.SelectObject( &penAxi );
		
		// 画坐标
		double dData;
		int nCount;
		for ( i = 0; i < m_dwDot; i++ )
		{			
			dData = (m_nBeginPos+i)*m_dOrgSampFreq/MAX_DEPTH;
			// 先找到开始的大小
			if ( i == 0 )
			{
				nCount = dData / m_dGap;//  + 1
			}
			if ( dData >= nCount * m_dGap )
			{
				// 画坐标线
				x = FFT_LEFT_MARGIN + (int)(i*dPointXpixel);			
				y = FFT_TOP_MARGIN;					
				m_dcPlot.MoveTo( x, y );
				x = FFT_LEFT_MARGIN + (int)(i*dPointXpixel);			
				y = FFT_TOP_MARGIN + nPicHeight;					
				m_dcPlot.LineTo( x, y );	
				// 找到第一个后更新计数的大小
				nCount++;
			}
		}
		if ( pOldPen != NULL )
		{
			m_dcPlot.SelectObject( pOldPen );
		}
		CPen penSideAxi( PS_SOLID, 1, RGB(128, 128, 128));	
		pOldPen = m_dcPlot.SelectObject( &penSideAxi );
		// 开始和最后的两根线
		x = FFT_LEFT_MARGIN;			
		y = FFT_TOP_MARGIN;					
		m_dcPlot.MoveTo( x, y );
		x = FFT_LEFT_MARGIN;			
		y = FFT_TOP_MARGIN + nPicHeight;					
		m_dcPlot.LineTo( x, y );
		x = FFT_LEFT_MARGIN + nPicWidth;			
		y = FFT_TOP_MARGIN;					
		m_dcPlot.MoveTo( x, y );
		x = FFT_LEFT_MARGIN + nPicWidth;			
		y = FFT_TOP_MARGIN + nPicHeight;					
		m_dcPlot.LineTo( x, y );
		// 恢复现场		
		if ( pOldPen != NULL )
		{
			m_dcPlot.SelectObject( pOldPen );
		}
		penAxi.DeleteObject();
		penSideAxi.DeleteObject();

		// 显示曲线
		m_bFirstVaule = TRUE;		
		for ( i = 0; i < m_dwDot; i++ )
		{
			// 先移动到第一个有效的点
			if ( m_bFirstVaule && m_nBeginPos+i >= 0 && m_nBeginPos+i < MAX_DEPTH )
			{
				m_bFirstVaule = FALSE;
				m_dcPlot.MoveTo( FFT_LEFT_MARGIN + (int)(i*dPointXpixel), 
					FFT_TOP_MARGIN + nPicHeight - (int)((m_daDispData[m_nBeginPos+i] - m_dMinData)*dPointYpixel) );	
			}
			// 画线
			if ( m_nBeginPos+i >= 0 && m_nBeginPos+i < MAX_DEPTH )
			{
				x = FFT_LEFT_MARGIN + (int)(i*dPointXpixel);			
				y = FFT_TOP_MARGIN + nPicHeight - (int)((m_daDispData[m_nBeginPos+i] - m_dMinData)*dPointYpixel);					
				m_dcPlot.LineTo( x, y );
			}			
		}				
		m_dcPlot.SelectObject( pOldPen );
		penCh1Signal.DeleteObject();
		
		// 擦除多余部分
		CRect rcFill( 0, FFT_TOP_MARGIN + FFT_NUM_VERT * nSigPicSmallHeight,
			m_nClientWidth, m_nClientHeight );
		m_dcPlot.FillRect( rcFill, &m_brushBack );
		/////////////////////////////////////////////////////////////////////////////

		// 显示坐标值
		///////////////////////////////////////////////////////////////////////////
		// 字体
		m_dcPlot.SetTextColor( RGB(128, 128, 128) );		
		pOldFont = m_dcPlot.SelectObject( &m_fntScale );
		// 坐标值
		for ( i = 0; i < m_dwDot; i++ )
		{			
			dData = (m_nBeginPos+i)*m_dOrgSampFreq/MAX_DEPTH;
			// 先找到开始的大小
			if ( i == 0 )
			{
				if ( dData > 0 )
				{
					nCount = dData / m_dGap + 1;
				}
				else
				{
					nCount = dData / m_dGap;
				}
			}
			if ( dData >= nCount * m_dGap )			
			{				
				// 刻度值
				//strMsg.Format( "%d", m_nBeginPos+i );
				//strMsg.Format( "%.2f", (m_nBeginPos+i)*m_dOrgSampFreq/MAX_DEPTH );
				strMsg.Format( "%.2f", nCount * m_dGap - m_dOrgSampFreq / 2 );
				szText = m_dcPlot.GetTextExtent( strMsg );
				x = FFT_LEFT_MARGIN + (int)(i*dPointXpixel) - szText.cx / 2;
				y = FFT_TOP_MARGIN + nPicHeight + 2;
				m_dcPlot.TextOut( x, y, strMsg );
				nCount++;
			}
		}
		// 显示单位
		strMsg = "(MHz)";
		szText = m_dcPlot.GetTextExtent( strMsg );
		x = FFT_LEFT_MARGIN + nPicWidth/2 - szText.cx / 2;
		y = FFT_TOP_MARGIN + nPicHeight + szText.cy;
		m_dcPlot.TextOut( x, y, strMsg );
		if ( pOldFont != NULL )
		{			
			m_dcPlot.SelectObject( pOldFont );
		}
		//////////////////////////////////////////////////////////////////////////

		//////////////////////////////////////////////////////////////////////////
		// 画标记
#define MARK_NUM 6
#define MINGAP 200
		double dMaxData;
		int nPos;
		int naPos[MARK_NUM];		
		
		int t;
		bool bMax = FALSE;

		for ( i = 0; i < MARK_NUM; i++ )
		{
			naPos[i] = -1;
		}
		// 查找5个最大值
		for ( i = 0; i < MARK_NUM; i++ )
		{
			dMaxData = -10000;
			//j>0, ignore DC
			for ( j = 1; j < MAX_DEPTH; j++ )
			{
				
// 				if ( j != naPos[0] && j != naPos[1] && j != naPos[2] 
// 					&& j != naPos[3] && j != naPos[4] && m_daDispData[j] > dMaxData 
// 					&& abs(j-naPos[0])>MINGAP && abs(j-naPos[1])>MINGAP && abs(j-naPos[2])>MINGAP 
// 					&& abs(j-naPos[3])>MINGAP && abs(j-naPos[4])>MINGAP)
// 				{
// 					dMaxData = m_daDispData[j];
// 					nPos = j;
// 				}

				if ( m_daDispData[j] > dMaxData)
				{
					bMax = TRUE;
					for (t=0; t<i; ++t)
					{
						if (j==naPos[t] || abs(j-naPos[t])<MINGAP)
						{
							bMax = FALSE;
						}
					}
					if (bMax)
					{
						dMaxData = m_daDispData[j];
						nPos = j;
					}
				}
			}
			for (t=i; t<MARK_NUM; ++t)
			{
				naPos[t] = nPos;
			}
			//TRACE( "pos = %d, data = %f\n", naPos[i], m_daDispData[ naPos[i] ] );
		}

		pOldFont = m_dcPlot.SelectObject( &m_fntTitle );
		m_dcPlot.SetTextColor( RGB(0,255,255) );		

		// 画标记
		CString strMax;
		for ( i = 0; i < MARK_NUM; i++ )
		{
			// 在当前显示的点数范围内才显示
			if ( naPos[i] - m_nBeginPos < m_dwDot )
			{
				x = FFT_LEFT_MARGIN + (int)( (naPos[i]-m_nBeginPos) * dPointXpixel );			
				y = FFT_TOP_MARGIN + nPicHeight - (int)((m_daDispData[ naPos[i] ] - m_dMinData)*dPointYpixel); 
				DrawMark( x, y, 'x', RGB(0,255,255) );
				strMax.Format( "(%.2f,%.2f)", naPos[i]*m_dOrgSampFreq/MAX_DEPTH, 
					m_daDispData[ naPos[i] ] );
				m_dcPlot.TextOut(x+3, y-3, strMax );
			}			
		}
		////////////////////////////////////////////////////////////////////////

		// 显示参数
		////////////////////////////////////////////////////////////////////////
		
		if ( m_dVpp > 0 && m_bShowParam )
		{
			// 查找最长的,左边对齐
			strMsg.Format( "SFDR = %2.2fdB", m_dSFDR );
			szText = m_dcPlot.GetTextExtent( strMsg );		
			int nLen = szText.cx;

			// Ain(峰峰值最大为2V)
			dErr = 20*log10( m_dVpp / 2);
			strMsg.Format( "AIN  = %.2fdB", dErr );
			szText = m_dcPlot.GetTextExtent( strMsg );		
			x = m_nClientWidth - FFT_LEFT_MARGIN - nLen;
			y = FFT_TOP_MARGIN + 2;		
			m_dcPlot.TextOut( x, y, strMsg );

			// SNR
			strMsg.Format( "SNR  = %.2fdB", m_dSNR );
			szText = m_dcPlot.GetTextExtent( strMsg );		
			x = m_nClientWidth - FFT_LEFT_MARGIN - nLen;
			y = FFT_TOP_MARGIN + 2 + szText.cy;		
			m_dcPlot.TextOut( x, y, strMsg );

			// SFDR
			strMsg.Format( "SFDR = %.2fdB", m_dSFDR );
			szText = m_dcPlot.GetTextExtent( strMsg );		
			x = m_nClientWidth - FFT_LEFT_MARGIN - nLen;
			y = FFT_TOP_MARGIN + 2 + szText.cy*2;		
			m_dcPlot.TextOut( x, y, strMsg );

			// SINAD
			strMsg.Format( "SINAD = %.2fdB", m_dSINAD );
			szText = m_dcPlot.GetTextExtent( strMsg );		
			x = m_nClientWidth - FFT_LEFT_MARGIN - nLen;
			y = FFT_TOP_MARGIN + 2 + szText.cy*3;		
			m_dcPlot.TextOut( x, y, strMsg );

			// ENOB
			strMsg.Format( "ENOB = %.2f", m_dENOB );
			szText = m_dcPlot.GetTextExtent( strMsg );		
			x = m_nClientWidth - FFT_LEFT_MARGIN - nLen;
			y = FFT_TOP_MARGIN + 2 + szText.cy*4;		
			m_dcPlot.TextOut( x, y, strMsg );
		}
		if ( pOldFont != NULL )
		{			
			m_dcPlot.SelectObject( pOldFont );
		}
		//////////////////////////////////////////////////////////////////////////
		
		//////////////////////////////////////////////////////////////////
		// 在顶部显示五个最大值
		CString straValue[MARK_NUM];
		DWORD dwMarkWidth;

		dwMarkWidth = 0;
		for ( i = 0; i < MARK_NUM; i++ )
		{
			// 安全检查
			if ( naPos[i] > 0 )
			{
				straValue[i].Format( "(%.2f,%.2f)", naPos[i]*m_dOrgSampFreq/MAX_DEPTH, 
					m_daDispData[ naPos[i] ] );
			}			
			szText = m_dcPlot.GetTextExtent( straValue[i] );
			dwMarkWidth += szText.cx;
		}

		pOldFont = m_dcPlot.SelectObject( &m_fntTitle );
		m_dcPlot.SetTextColor( RGB(0,255,255) );
		// 视图足够宽时显示5个值
		if ( dwMarkWidth < nPicWidth )
		{
			x = (nPicWidth-dwMarkWidth)/2;
			y = 0;
			szText.cx = 0;
			for ( i = 0; i < MARK_NUM; i++ )
			{
				if ( i > 0 )
				{
					szText = m_dcPlot.GetTextExtent( straValue[i-1] );
				}
				x += szText.cx;
				m_dcPlot.TextOut( x, y, straValue[i] );
			}
		}
		if ( pOldFont != NULL )
		{			
			m_dcPlot.SelectObject( pOldFont );
		}
		///////////////////////////////////////////////////////////////////////////

		///////////////////////////////////////////////////////////////////////////
		// 鼠标移动显示坐标值
		if ( m_ptMove.x >= FFT_LEFT_MARGIN && m_ptMove.x <= FFT_LEFT_MARGIN + nPicWidth
			&& m_ptMove.y >= FFT_TOP_MARGIN && m_ptMove.y <= FFT_TOP_MARGIN + nPicHeight )
		{
			CString strValue;
			int nPos;
			nPos = (m_ptMove.x - FFT_LEFT_MARGIN)*m_dwDot/nPicWidth + m_nBeginPos;
			if ( nPos >= 0 && nPos < MAX_DEPTH / 2 )
			{
				// 显示鼠标点的坐标
				//strValue.Format( "(%.2f , %.2f)", nPos * m_dOrgSampFreq / MAX_DEPTH,	
				//	-(m_ptMove.y - FFT_TOP_MARGIN) / dPointYpixel  );

				// 显示曲线上的点频率和幅度
				strValue.Format( "(%.2f , %.2f)", nPos * m_dOrgSampFreq / MAX_DEPTH,	
					m_daDispData[nPos]  );
				// 字体
				pOldFont = m_dcPlot.SelectObject( &m_fntTitle );
				m_dcPlot.SetTextColor( RGB(0,255,255) );
				// 显示的区域
				szText = m_dcPlot.GetTextExtent( strValue );
				if ( m_ptMove.x + szText.cx <= FFT_LEFT_MARGIN + nPicWidth
					&& m_ptMove.y >= FFT_TOP_MARGIN )
				{
					m_dcPlot.TextOut( m_ptMove.x, m_ptMove.y - szText.cy, strValue );
				}
			}			
		}
		//////////////////////////////////////////////////////////////////////////////
		
		Invalidate();
	}

	
}
Beispiel #2
0
void CProgressCtrlX::DrawText(const CDrawInfo& info, const CRect &rcMax, const CRect &rcBar)
{
	if(!(info.dwStyle&PBS_TEXTMASK))
		return;
	BOOL fVert = info.dwStyle&PBS_VERTICAL;
	CDC *pDC = info.pDC;
	int nValue = 0;
	CString sFormat;
	GetWindowText(sFormat);
	switch(info.dwStyle&PBS_TEXTMASK)
	{
		case PBS_SHOW_PERCENT:
			if(sFormat.IsEmpty())
				sFormat = _T("%d%%");
			// retrieve current position and range
			nValue = (int)((float)(info.nCurPos-info.nLower) * 100 / ((info.nUpper-info.nLower == 0) ? 1 : info.nUpper-info.nLower));
			break;
		case PBS_SHOW_POSITION:
			if(sFormat.IsEmpty())
				sFormat = _T("%d");
			// retrieve current position
			nValue = info.nCurPos;
			break;
	}

	if (sFormat.IsEmpty())
		return;

	CFont* pFont = GetFont();
	CSelFont sf(pDC, pFont);
	CSelTextColor tc(pDC, m_clrTextOnBar);
	CSelBkMode bm(pDC, TRANSPARENT);
	CSelTextAlign	ta(pDC, TA_BOTTOM|TA_CENTER);
  CPoint ptOrg = pDC->GetWindowOrg();
	CString sText;
	sText.Format(sFormat, nValue);
	
	LONG grad = 0;
	if(pFont)
	{
		LOGFONT lf;
		pFont->GetLogFont(&lf);
		grad = lf.lfEscapement/10;
	}
	int x = 0, y = 0, dx = 0, dy = 0;
	CSize sizText = pDC->GetTextExtent(sText);
	if(grad == 0)         {	x = sizText.cx; y = sizText.cy; dx = 0; dy = sizText.cy;}
	else if(grad == 90)   {	x = sizText.cy; y = sizText.cx; dx = sizText.cy; dy = 0;}
	else if(grad == 180)  {	x = sizText.cx; y = sizText.cy; dx = 0; dy = -sizText.cy;}
	else if(grad == 270)  {	x = sizText.cy; y = sizText.cx; dx = -sizText.cy; dy = 0;}
	else ASSERT(0); // angle not supported
	CPoint pt = pDC->GetViewportOrg();
	if(info.dwStyle&PBS_TIED_TEXT)
	{
		CRect rcFill(ConvertToReal(info, rcBar));
		if((fVert ? y : x) <= rcBar.Width())
		{
			pDC->SetViewportOrg(rcFill.left + (rcFill.Width() + dx)/2, 
													rcFill.top + (rcFill.Height() + dy)/2);
			DrawClippedText(info, rcBar, sText, ptOrg);
		}
	}
	else
	{
		pDC->SetViewportOrg(info.rcClient.left + (info.rcClient.Width() + dx)/2, 
												info.rcClient.top + (info.rcClient.Height() + dy)/2);
		if(m_clrTextOnBar == m_clrTextOnBk)
			// if the same color for bar and background draw text once
			DrawClippedText(info, rcMax, sText, ptOrg);
		else
		{	
			// else, draw clipped parts of text
			
			// draw text on gradient
			if(rcBar.left != rcBar.right)
				DrawClippedText(info, rcBar, sText, ptOrg);

			// draw text out of gradient
			if(rcMax.right > rcBar.right)
			{
				tc.Select(m_clrTextOnBk);
				CRect rc(rcMax);
				rc.left = rcBar.right;
				DrawClippedText(info, rc, sText, ptOrg);
			}
			if(rcMax.left < rcBar.left)
			{
				tc.Select(m_clrTextOnBk);
				CRect rc(rcMax);
				rc.right = rcBar.left;
				DrawClippedText(info, rc, sText, ptOrg);
			}
		}
	}
	pDC->SetViewportOrg(pt);
}
Beispiel #3
0
void CChevronOwnerDrawMenu::DrawItem(LPDRAWITEMSTRUCT pdis)
{
	ASSERT(pdis->CtlType == ODT_MENU);

	CString strText(_T(""));
	CSize Size;   

	CDC *pDC;
	pDC = CDC::FromHandle(pdis->hDC);
	int nSave = pDC->SaveDC();
	
	// getting the text (on the right of the bitmap)
	MENUITEMINFO info;
	ZeroMemory(&info, sizeof(MENUITEMINFO));
	info.cbSize = sizeof(MENUITEMINFO);
	info.fMask = MIIM_STRING;
	BOOL bGotText = FALSE;
	if(GetMenuItemInfo(pdis->itemID, &info))
	{
		LPTSTR pszText;

		pszText = strText.GetBuffer(info.cch);
		info.dwTypeData = pszText;
		info.cch++; // space for zero terminator
		bGotText = GetMenuItemInfo(pdis->itemID, &info);
		strText.ReleaseBuffer();
	}

	CBitmap *pBmp;
	pBmp = (CBitmap *) pdis->itemData;

	// Find the rect that will center the bitmap in the menu item
	CRect rc, rcItem(pdis->rcItem);
	BOOL bGotBitmap = FALSE;
	int nBitmapHeight = 0;
	int nBitmapWidth = 0;
	if(pBmp && pBmp->IsKindOf(RUNTIME_CLASS(CBitmap)))
	{
		BITMAP bitmap;
		bGotBitmap = TRUE;
		pBmp->GetObject(sizeof(BITMAP), &bitmap);
		nBitmapHeight = bitmap.bmHeight;
		nBitmapWidth = bitmap.bmWidth;
	}
	else
	{
		// using default icon size
		bGotBitmap = FALSE;
		nBitmapHeight = ::GetSystemMetrics(SM_CYSMICON);
		nBitmapWidth = ::GetSystemMetrics(SM_CXSMICON);
	}
	rc.top = rcItem.Height() / 2 - nBitmapHeight / 2 + rcItem.top - 1;
	rc.left = 0;
	rc.right = nBitmapWidth + 1;
	rc.bottom = nBitmapHeight + 1;
	rc.bottom += rc.top;
	rc.right += rc.left;

	
	//the actual drawing begins
	COLORREF crMenu = ::GetSysColor(COLOR_MENU);
	CDC dcMem;
	dcMem.CreateCompatibleDC(NULL);

	pDC->SelectObject(&m_MenuFont);
	Size = pDC->GetTextExtent(strText);

	// Selected (possibly grayed)
	if(pdis->itemState & ODS_SELECTED)
	{
		// MenuColor
		CRect rcFill(pdis->rcItem);
		rcFill.left = rc.right + 2;
		pDC->FillSolidRect(rcFill, ::GetSysColor(COLOR_HIGHLIGHT));

		// if not grayed and not checked, raise the button
		if (bGotBitmap)
		{
			if(!(pdis->itemState & (ODS_GRAYED | ODS_CHECKED)))
			{
				pDC->Draw3dRect(rc.left, rc.top, rc.Width() + 1, rc.Height() + 1,
					::GetSysColor(COLOR_BTNHIGHLIGHT), ::GetSysColor(COLOR_BTNSHADOW));
			}
		}
		
		// Text
		if (bGotText)
		{
			pDC->SetBkColor(::GetSysColor(COLOR_HIGHLIGHT));
			pDC->SetTextColor(
				(pdis->itemState & ODS_GRAYED) ? crMenu : ::GetSysColor(COLOR_HIGHLIGHTTEXT));

			pDC->ExtTextOut(rc.right + 3, rc.top + rc.Height() / 2 - Size.cy / 2,
				ETO_OPAQUE, NULL, strText, NULL);
		}
	}
	else
	{
		pDC->FillSolidRect(&pdis->rcItem, crMenu);
		pDC->SetBkColor(crMenu);

		// Grayed (disabled)
		if(pdis->itemState & ODS_GRAYED)
		{
			pDC->SetTextColor(::GetSysColor(COLOR_3DHILIGHT));
			pDC->SetBkMode(TRANSPARENT);

			// Text
			if (bGotText)
			{
				pDC->ExtTextOut(rc.right + 4, rc.top + rc.Height() / 2 - Size.cy / 2 + 1, ETO_OPAQUE, NULL, strText, NULL);
				pDC->SetTextColor(::GetSysColor(COLOR_GRAYTEXT));
				pDC->ExtTextOut(rc.right + 3, rc.top + rc.Height() / 2 - Size.cy / 2, 0, NULL, strText, NULL);
			}
		}
		// Everything else
		else
		{
			// if checked draw as pushed
			if (bGotBitmap)
			{
				if(pdis->itemState & ODS_CHECKED)
				{
					pDC->Draw3dRect(rc.left, rc.top, rc.Width() + 1, rc.Height() + 1,
						::GetSysColor(COLOR_BTNSHADOW), ::GetSysColor(COLOR_BTNHIGHLIGHT));
				}
			}
			
			// text
			if (bGotText)
			{
				pDC->SetBkColor(crMenu);
				pDC->SetTextColor(::GetSysColor(COLOR_MENUTEXT));
				pDC->ExtTextOut(rc.right + 3, rc.top + rc.Height() / 2 - Size.cy / 2, ETO_OPAQUE, NULL, strText, NULL);
			}
		}
	}

	// The bitmap...
	if (bGotBitmap)
	{
		CBitmap bmp;
		int x = 0, y = 0;
		if(pdis->itemState & ODS_GRAYED)
		{
			::AfxGetGrayBitmap(*pBmp, &bmp, crMenu);
			pBmp = &bmp;
		}
		else
		{
			if(pdis->itemState & ODS_CHECKED)
			{
				::AfxGetDitheredBitmap(*pBmp, &bmp, crMenu, RGB(255, 255, 255));
				pBmp = &bmp;
			}
		}

		CDC dcMem;
		dcMem.CreateCompatibleDC(NULL);
		dcMem.SelectObject(pBmp);

		rc.InflateRect(-1, -1);

		pDC->BitBlt(rc.left, rc.top, rc.right, rc.bottom, &dcMem, x, y, SRCCOPY);
	}
	
	pDC->RestoreDC(nSave);
}
Beispiel #4
0
void CProgressCtrlX::DrawGradient(const CDrawInfo& info, const CRect &rcGrad, const CRect &rcClip, COLORREF clrStart, COLORREF clrEnd)
{
	// Split colors to RGB chanels, find chanel with maximum difference 
	// between the start and end colors. This distance will determine 
	// number of steps of gradient
	int r = (GetRValue(clrEnd) - GetRValue(clrStart));
	int g = (GetGValue(clrEnd) - GetGValue(clrStart));
	int b = (GetBValue(clrEnd) - GetBValue(clrStart));
	int nSteps = max(abs(r), max(abs(g), abs(b)));
	// if number of pixels in gradient less than number of steps - 
	// use it as numberof steps
	int nPixels = rcGrad.Width();
	nSteps = min(nPixels, nSteps);
	if(nSteps == 0) nSteps = 1;

	float rStep = (float)r/nSteps;
	float gStep = (float)g/nSteps;
	float bStep = (float)b/nSteps;

	r = GetRValue(clrStart);
	g = GetGValue(clrStart);
	b = GetBValue(clrStart);

	BOOL fLowColor = info.pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE;
	if(!fLowColor && nSteps > 1)
		if(info.pDC->GetDeviceCaps(BITSPIXEL)*info.pDC->GetDeviceCaps(PLANES) < 8)
			nSteps = 1; // for 16 colors no gradient

	float nWidthPerStep = (float)rcGrad.Width() / nSteps;
	CRect rcFill(rcGrad);
	CBrush br;
	// Start filling
	for (int i = 0; i < nSteps; i++) 
	{
		rcFill.left = rcGrad.left + (int)(nWidthPerStep * i);
		rcFill.right = rcGrad.left + (int)(nWidthPerStep * (i+1));
		if(i == nSteps-1)	//last step (because of problems with float)
			rcFill.right = rcGrad.right;

		if(rcFill.right < rcClip.left)
			continue; // skip - band before cliping rect
		
		// clip it
		if(rcFill.left < rcClip.left)
			rcFill.left = rcClip.left;
		if(rcFill.right > rcClip.right)
			rcFill.right = rcClip.right;

		COLORREF clrFill = RGB(r + (int)(i * rStep),
		                       g + (int)(i * gStep),
		                       b + (int)(i * bStep));
		if(fLowColor)
		{
			br.CreateSolidBrush(clrFill);
			// CDC::FillSolidRect is faster, but it does not handle 8-bit color depth
			info.pDC->FillRect(&ConvertToReal(info, rcFill), &br);
			br.DeleteObject();
		}
		else
			info.pDC->FillSolidRect(&ConvertToReal(info, rcFill), clrFill);
		if(rcFill.right >= rcClip.right)
			break; // stop filling if we reach current position
	}
}
Beispiel #5
0
/*****************************************************************************
* NAME: 
*  DrawGradient
* 
* DESCRIPTION: 
*  Found this as part of an overly complicated gradient progress bar on codeguru
*  So, I simplified it for my own uses :)   -Lumberjack
* 
*******************************************************************************/
void CSideBarCtrl::DrawGradient(CDC* pDC, const CRect &rcGrad, COLORREF clrStart, COLORREF clrEnd, BOOL bVertical, COLORREF clrDither /*=0xFFFFFFFF*/ )
{
	// Split colors to RGB chanels, find chanel with maximum difference 
	// between the start and end colors. This distance will determine 
	// number of steps of gradient
	int r = (GetRValue(clrEnd) - GetRValue(clrStart));
	int g = (GetGValue(clrEnd) - GetGValue(clrStart));
	int b = (GetBValue(clrEnd) - GetBValue(clrStart));
	int nSteps = max(abs(r), max(abs(g), abs(b)));
	// if number of pixels in gradient less than number of steps - 
	// use it as numberof steps
	int nPixels = rcGrad.Width();
	nSteps = min(nPixels, nSteps);
	if(nSteps == 0) nSteps = 1;

	float rStep = (float)r/nSteps;
	float gStep = (float)g/nSteps;
	float bStep = (float)b/nSteps;

	r = GetRValue(clrStart);
	g = GetGValue(clrStart);
	b = GetBValue(clrStart);

	BOOL fLowColor = pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE;
	if(!fLowColor && nSteps > 1)
		if(pDC->GetDeviceCaps(BITSPIXEL)*pDC->GetDeviceCaps(PLANES) < 8)
			nSteps = 1; // for 16 colors no gradient

	float nSpacePerStep = bVertical?(float)rcGrad.Height()/nSteps:(float)rcGrad.Width()/nSteps;
	CRect rcFill(rcGrad);
	CBrush br;

	// Start filling
	for (int i = 0; i < nSteps; i++) 
	{
		if( bVertical )
		{
			rcFill.top = rcGrad.top + (int)(nSpacePerStep * i);
			rcFill.bottom = rcGrad.top + (int)(nSpacePerStep * (i+1));
			if(i == nSteps-1)	//last step (because of problems with float)
				rcFill.bottom = rcGrad.bottom;
		}
		else
		{
			rcFill.left = rcGrad.left + (int)(nSpacePerStep * i);
			rcFill.right = rcGrad.left + (int)(nSpacePerStep * (i+1));
			if(i == nSteps-1)	//last step (because of problems with float)
				rcFill.right = rcGrad.right;
		}

		COLORREF clrFill = RGB(r + (int)(i * rStep), g + (int)(i * gStep), b + (int)(i * bStep));

		if( fLowColor )
		{
			br.CreateSolidBrush(clrFill);
			// CDC::FillSolidRect is faster, but it does not handle 8-bit color depth
			pDC->FillRect(&rcFill, &br);
			br.DeleteObject();
		}
		else
		{
			if( 0xFFFFFFFF != clrDither )
			{
				COLORREF crExisting = 0;
				for( int nHoriz = rcFill.left; nHoriz < rcFill.right; nHoriz++ )
				{
					for( int nVert = rcFill.top; nVert < rcFill.bottom; nVert++ )
					{
						crExisting = pDC->GetPixel(nHoriz,nVert);
						if( crExisting == clrDither )
						{
							pDC->SetPixel(nHoriz,nVert,findMidColor(clrFill,clrDither) );
						}
						else
						{
							pDC->SetPixel(nHoriz,nVert,clrFill);
						}
					}
				}
			}
			else
			{
				pDC->FillSolidRect(&rcFill, clrFill);
			}
		}
	}
}