I'm trying to make a MFC control that will show a pie graph. I've got most of the work done, but I don't know how to go from having a class to "creating" the control on the main window. I also keep getting debug assertions which I did not get when I implemented the same code in the main CFrameWnd class. I'm guessing that's because it won't give me access to the device contexts or something in a regular class. I don't know. Any help would be appreciated.
I'm using CWnd as a base class. Basically I have two bitmaps (m_pieBitmap and m_textBitmap) which are selected into two CDCs (PieMemDC and TextMemDC). When the pie graph and text need to be updated, they are redrawn onto the bitmaps. Both are blitted onto CPaintDC in OnPaint in the control's class.
Here is the header for CPieGraph (the control's class):
class CPieGraph : public CWnd
{
public:
CPieGraph();
~CPieGraph();
void InitPieChart();
void SetPieChart(PieGraphDisplayType & PieGraph);
void ResetPieChartAngle(int Angle);
protected:
private:
void InitDCObjects();
void RedrawPieChart();
void RedrawPieText();
PieGraphDisplayType MainPieGraph;
CDC PieMemDC;
CDC TextMemDC;
CBitmap* OldpieBitmap;
CBitmap* OldtextBitmap;
CBitmap m_pieBitmap;
CBitmap m_textBitmap;
CBrush CombinedBrush;
CBrush TargetBrush;
CPen BlackPen;
CFont OutputFont;
afx_msg void OnPaint();
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
DECLARE_MESSAGE_MAP()
};
Some of the class code:
CPieGraph::CPieGraph()
{
InitPieChart();
InitDCObjects();
OldpieBitmap = PieMemDC.SelectObject(&m_pieBitmap);
OldtextBitmap = TextMemDC.SelectObject(&m_textBitmap);
}
CPieGraph::~CPieGraph()
{
PieMemDC.SelectObject(OldpieBitmap);
TextMemDC.SelectObject(OldtextBitmap);
m_pieBitmap.DeleteObject();
m_textBitmap.DeleteObject();
}
void CPieGraph::InitPieChart()
{
CRect ClientArea;
GetClientRect(&ClientArea);
MainPieGraph.origin.SetPoint(static_cast<int>(ClientArea.right / 1.5),
static_cast<int>(ClientArea.bottom / 2));
MainPieGraph.angle = 0;
MainPieGraph.PieGraphIsActive = false;
MainPieGraph.radius = 100;
MainPieGraph.data.denominator = 0.0;
MainPieGraph.data.numerator = 0.0;
MainPieGraph.data.ratio = 0.0;
}
void CPieGraph::InitDCObjects()
{
CDC pDC;
VERIFY(OutputFont.CreateFont(16, 0, 0, 0, FW_NORMAL, FALSE, FALSE, 0, ANSI_CHARSET,
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
DEFAULT_PITCH | FF_SWISS, "Arial"));
BlackPen.CreatePen(PS_SOLID, 2, RGB(0, 0, 0));
TargetBrush.CreateSolidBrush(RGB(95, 158, 160));
CombinedBrush.CreateHatchBrush(HS_DIAGCROSS, RGB(47, 79, 79));
m_pieBitmap.CreateCompatibleBitmap(&pDC, 600, 600);
m_textBitmap.CreateCompatibleBitmap(&pDC, 100, 10);
}
void CPieGraph::RedrawPieChart()
{
ASSERT((MainPieGraph.radius * 2) < 600);
CBrush* OldBrush = NULL;
CPen* OldPen = NULL;
int Angle = 0;
if(MainPieGraph.PieGraphIsActive)
Angle = MainPieGraph.angle;
else
Angle = 0;
PieMemDC.BeginPath();
OldBrush = PieMemDC.SelectObject(&TargetBrush);
OldPen = PieMemDC.SelectObject(&BlackPen);
PieMemDC.MoveTo(MainPieGraph.radius, MainPieGraph.radius);
AngleArc(PieMemDC, MainPieGraph.radius, MainPieGraph.radius, MainPieGraph.radius, 0.0, static_cast<FLOAT>(Angle));
PieMemDC.LineTo(MainPieGraph.radius, MainPieGraph.radius);
PieMemDC.EndPath();
PieMemDC.StrokeAndFillPath();
PieMemDC.SelectObject(OldBrush);
PieMemDC.BeginPath();
OldBrush = PieMemDC.SelectObject(&CombinedBrush);
PieMemDC.MoveTo(MainPieGraph.radius, MainPieGraph.radius);
AngleArc(PieMemDC, MainPieGraph.radius, MainPieGraph.radius, MainPieGraph.radius, ((360-Angle)*-1), 360-Angle);
PieMemDC.LineTo(MainPieGraph.radius, MainPieGraph.radius);
PieMemDC.EndPath();
PieMemDC.StrokeAndFillPath();
PieMemDC.SelectObject(OldPen);
PieMemDC.SelectObject(OldBrush);
}
afx_msg void CPieGraph::OnPaint()
{
CPaintDC dc(this);
dc.BitBlt(MainPieGraph.origin.x - MainPieGraph.radius,
MainPieGraph.origin.y - MainPieGraph.radius - 10,
100, 10, &TextMemDC, 0, 0, SRCCOPY);
dc.BitBlt(MainPieGraph.origin.x - MainPieGraph.radius,
MainPieGraph.origin.y - MainPieGraph.radius,
MainPieGraph.radius * 2,
MainPieGraph.radius * 2, &PieMemDC, 0, 0, SRCCOPY);
}
afx_msg BOOL CPieGraph::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}
Class where CPieGraph is decleared:
class CRatiosWin : public CFrameWnd
{
public:
CRatiosWin();
~CRatiosWin();
...
protected:
private:
CRatiosNewSearchDialog NewSearchDialog;
CRatiosSearchTimeParameters TimeParametersDialog;
CStudentCourseLinkedList TestLinkedList;
CPieGraph PieGraph;
CDC logo_memDC;
CBitmap LogoOffScreenBmp;
CBitmap* OldLogoBitmap;
CEdit ResultsBox;
CPoint LogoOffSet;
CPoint TextOffSet;
...
}
|