예제 #1
0
void CClock::DrawTime( CDC *pDc )
{
	CRect  rtClient;
	GetClientRect(&rtClient);
	CDC  dcTransparent;
	dcTransparent.CreateCompatibleDC(pDc);
	CBitmap bitTransParent;
	bitTransParent.CreateCompatibleBitmap(pDc, rtClient.Width(),rtClient.Height());
	dcTransparent.SelectObject(&bitTransParent);

	// 		CRect rectReal(ix1, iy1, ix2, iy2);
	dcTransparent.FillSolidRect(rtClient, RGB(255, 255, 255));
	// 		dcTransparent.Draw3dRect(rectReal, RGB(111, 147, 188), RGB(111, 147, 188));

	dcTransparent.BeginPath();
	dcTransparent.MoveTo(rtClient.Width()/2, rtClient.Height()/2);
	dcTransparent.LineTo(rtClient.Width()/2-80, rtClient.Height()/2);

	float   fEnd = 90.0f;
	dcTransparent.AngleArc(rtClient.Width()/2, rtClient.Height()/2, 120, -180.0f, 270.0f);
	dcTransparent.LineTo(rtClient.Width()/2, rtClient.Height()/2);

	dcTransparent.EndPath();
	CRgn rgn;
	rgn.CreateFromPath(&dcTransparent);
	dcTransparent.FillRgn(&rgn, &CBrush(RGB(188, 199, 216)));

	//内
	dcTransparent.BeginPath();
	dcTransparent.MoveTo(rtClient.Width()/2, rtClient.Height()/2);
	dcTransparent.LineTo(rtClient.Width()/2-40, rtClient.Height()/2);

	dcTransparent.AngleArc(rtClient.Width()/2, rtClient.Height()/2, 40, -180.0f, 270.0f);
	dcTransparent.LineTo(rtClient.Width()/2, rtClient.Height()/2);

	dcTransparent.EndPath();
	CRgn rgn1;
	rgn1.CreateFromPath(&dcTransparent);
	dcTransparent.FillRgn(&rgn1, &CBrush(RGB(255, 255, 0)));

	if( ::AlphaBlend == 0 )
	{
		pDc->StretchBlt(0, 0, rtClient.Width(), rtClient.Height(), 
			&dcTransparent, 0, 0, rtClient.Width(), rtClient.Height(), SRCINVERT );

	}else{

		BLENDFUNCTION bf;    
		memset( &bf, 0, sizeof( bf ) );
		bf.SourceConstantAlpha = 0x9f; //半透明
		bf.BlendOp = AC_SRC_OVER;

		::TransparentBlt(pDc->GetSafeHdc(), 0, 0, rtClient.Width(), rtClient.Height(), 
			dcTransparent.GetSafeHdc( ), 0, 0, rtClient.Width(), rtClient.Height(), RGB(255, 255, 255));
		// 			::AlphaBlend( memDC.GetSafeHdc(), 0, 0, rtClient.Width(), rtClient.Height(), 
		// 				dcTransparent.GetSafeHdc( ), 0, 0, rtClient.Width(), rtClient.Height(), bf );  
	}
	bitTransParent.DeleteObject();
	dcTransparent.DeleteDC();
}
예제 #2
0
void MyGraph::DrawSeriesPie(CDC& dc) const
{
	VALIDATE;
	ASSERT_VALID(&dc);

	// Determine width of pie display area (pie and space).
	int nSeriesSpace(0);

	int seriesCount = GetNonZeroSeriesCount();
	int horizontalSpace(0);

	if (m_saLegendLabels.GetSize()) {
		// With legend box.

		horizontalSpace = m_nXAxisWidth - m_rcLegend.Width() - (GAP_PIXELS * 2);
		int nPieAndSpaceWidth(horizontalSpace / (seriesCount ? seriesCount : 1));

		// Height is limiting factor.
		if (nPieAndSpaceWidth > m_nYAxisHeight - (GAP_PIXELS * 2)) {
			nSeriesSpace = (m_nYAxisHeight - (GAP_PIXELS * 2));
		}
		else {
			// Width is limiting factor.
			nSeriesSpace = nPieAndSpaceWidth;
		}
	}
	else {
		// No legend box.

		horizontalSpace = m_nXAxisWidth;

		// Height is limiting factor.
		if (m_nXAxisWidth > m_nYAxisHeight * (seriesCount ? seriesCount : 1)) {
			nSeriesSpace = m_nYAxisHeight;
		}
		else {
			// Width is limiting factor.
			nSeriesSpace = m_nXAxisWidth / (seriesCount ? seriesCount : 1);
		}
	}

	// Make pies be centered horizontally
	int xOrigin = m_ptOrigin.x + GAP_PIXELS + (horizontalSpace - nSeriesSpace * seriesCount) / 2;

	// Create font for labels.
	CFont fontLabels;
	int pointFontHeight = max(m_rcGraph.Height() / Y_AXIS_LABEL_DIVISOR, MIN_FONT_SIZE);
	VERIFY(fontLabels.CreatePointFont(pointFontHeight, _T("Arial"), &dc));
	CFont* pFontOld = dc.SelectObject(&fontLabels);
	ASSERT_VALID(pFontOld);

	// Draw each pie.
	int nPie(0);
	int nRadius((int) (nSeriesSpace * INTERSERIES_PERCENT_USED / 2.0));
	POSITION pos(m_olMyGraphSeries.GetHeadPosition());

	while (pos) {

		MyGraphSeries* pSeries = m_olMyGraphSeries.GetNext(pos);
		ASSERT_VALID(pSeries);

		// Don't leave a space for empty pies.
		if (0 < pSeries->GetNonZeroElementCount()) {

			// Locate this pie.
			CPoint ptCenter;
			ptCenter.x = xOrigin + (nSeriesSpace * nPie) + nSeriesSpace / 2;
			ptCenter.y = m_ptOrigin.y - m_nYAxisHeight / 2;

			CRect rcPie;
			rcPie.left = ptCenter.x - nRadius;
			rcPie.right = ptCenter.x + nRadius;
			rcPie.top = ptCenter.y - nRadius;
			rcPie.bottom = ptCenter.y + nRadius;

			// Draw series label.
			CSize sizPieLabel(dc.GetTextExtent(pSeries->GetLabel()));

			VERIFY(dc.TextOut(ptCenter.x - (sizPieLabel.cx / 2),
			  ptCenter.y + nRadius + GAP_PIXELS, pSeries->GetLabel()));

			// How much do the wedges total to?
			double dPieTotal(pSeries->GetDataTotal());

			// Draw each wedge in this pie.
			CPoint ptStart(rcPie.left, ptCenter.y);
			double dRunningWedgeTotal(0.0);

			for (int nGroup = 0; nGroup < m_saLegendLabels.GetSize(); ++nGroup) {

				// Ignore empty wedges.
				if (0 < pSeries->GetData(nGroup)) {

					// Get the degrees of this wedge.
					dRunningWedgeTotal += pSeries->GetData(nGroup);
					double dPercent(dRunningWedgeTotal * 100.0 / dPieTotal);
					double degrees(360.0 * dPercent / 100.0);

					// Find the location of the wedge's endpoint.
					CPoint ptEnd(WedgeEndFromDegrees(degrees, ptCenter, nRadius));

					// Special case: a wedge that takes up the whole pie would
					// otherwise be confused with an empty wedge.
					bool drawEmptyWedges = false;
					if (1 == pSeries->GetNonZeroElementCount()) {
						_ASSERTE(360 == (int)degrees  &&  ptStart == ptEnd  &&  "This is the problem we're correcting");
						--ptEnd.y;
						drawEmptyWedges = true;
					}

					// If the wedge is zero size or very narrow, don't paint it.
					// If pie is small, and wedge data is small, we might get a wedges
					// where center and both endpoints lie on the same coordinate,
					// and endpoints differ only in one pixel. GDI draws such pie as whole pie,
					// so we just skip them instead.
					int distance = abs(ptStart.x-ptEnd.x) + abs(ptStart.y-ptEnd.y);
					if (drawEmptyWedges || distance > 1) {

						// Draw wedge.
						COLORREF crWedge(m_dwaColors.GetAt(nGroup));
						CBrush br(crWedge);
						CBrush* pBrushOld = dc.SelectObject(&br);
						ASSERT_VALID(pBrushOld);
						VERIFY(dc.Pie(rcPie, ptStart, ptEnd));

						// Create a region from the path we create.
						VERIFY(dc.BeginPath());
						VERIFY(dc.Pie(rcPie, ptStart, ptEnd));
						VERIFY(dc.EndPath());
						CRgn * prgnWedge = new CRgn;
						VERIFY(prgnWedge->CreateFromPath(&dc));
						pSeries->SetTipRegion(nGroup, prgnWedge);

						// Cleanup.
						dc.SelectObject(pBrushOld);
						br.DeleteObject();
						ptStart = ptEnd;
					}
				}
			}

			++nPie;
		}
	}

	// Draw X axis title
	CSize sizXLabel(dc.GetTextExtent(m_sXAxisLabel));
	VERIFY(dc.TextOut(xOrigin + (nSeriesSpace * nPie - sizXLabel.cx)/2,
		m_ptOrigin.y - m_nYAxisHeight/2 + nRadius + GAP_PIXELS*2 + sizXLabel.cy, m_sXAxisLabel));

	VERIFY(dc.SelectObject(pFontOld));
	fontLabels.DeleteObject();
}