Trouble making a custom mfc control...
-
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; //CBrush WhiteBrush; CFont OutputFont; //message handlers 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(ClientArea.right / 1.5), static_cast(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, "Aria
-
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; //CBrush WhiteBrush; CFont OutputFont; //message handlers 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(ClientArea.right / 1.5), static_cast(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, "Aria
Hi there, did you actually create your PieChart control. If you did, can you post the location of your debug assertions? Best regards
-
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; //CBrush WhiteBrush; CFont OutputFont; //message handlers 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(ClientArea.right / 1.5), static_cast(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, "Aria
You haven't shown how you create your memory DCs. I'm assuming you haven't, so they are invalid when you initialize them in your constructor. CWnd window objects are created in two steps - 1 to create the C++ object, and the second to create the associated window object (HWND). You can't do anything requiring an HWND until the HWND is valid. Any time in or after the WM_CREATE notification is received is fine. OnCreate() is where you should be doing the initialization you've shown in your constructor :) Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder