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(); }
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(); }