Application crashes on calling OnPaint() function!?
-
I have a dialog based MFC application that I am rewriting in VS2010 from its original VC++ 6.0 source. Everything works fine in VC++ 6.0 The main dialog contains many child dialogs (not pop-ups) in which one child dialog is used to draw a plot based on the values sent from main dialog. The main dialog calls a function (Draw_Points) within the child dialog and the child dialog draws it and it does as long as the plot hits the edge and then it calls OnPaint message to refresh the dialog so that it can start afresh from left.
void CPlotDlg::Draw_Points(double value1, double value2)
{
if(m_LastPoint1.x < (m_time_rect.right-2))
{
// Store the data for later retrieval
m_CurrentPoint1.x = m_LastPoint1.x + 1;
m_CurrentPoint2.x = m_LastPoint2.x + 1;
// Do some calculations
m_Data1[m_DataCounter] = value1;
m_Data2[m_DataCounter++] = value2;
CWnd *Ctrl = GetDlgItem(IDE_PLOTS);
CDC *cdc = Ctrl->GetDC();
HGDIOBJ original = NULL;
original = cdc->SelectObject(GetStockObject(DC_PEN));
cdc->SelectObject(pen1);
cdc->MoveTo(m_LastPoint1);
cdc->LineTo(m_CurrentPoint1);
cdc->SelectObject(pen2);
cdc->MoveTo(m_LastPoint2);
cdc->LineTo(m_CurrentPoint2);
cdc->SelectObject(original);
Ctrl->ReleaseDC(cdc);
m_LastPoint1 = m_CurrentPoint1;
m_LastPoint2 = m_CurrentPoint2;
}
else
{
OnPaint();
Reset_PlotData();
}
}void CPlotDlg::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
if(m_BUpdate)
{
CDialogEx::OnPaint();
CWnd *Ctrl = GetDlgItem(IDE_PLOTS);
Ctrl->InvalidateRect(NULL,true);
Ctrl->UpdateWindow();
}
// Do not call CDialogEx::OnPaint() for painting messages
}It crashes when the Draw_points function calls OnPaint function in its else section, and when OnPaint() function executes CPaintDC dc(this); Any suggestions? thanks
PKNT
-
I have a dialog based MFC application that I am rewriting in VS2010 from its original VC++ 6.0 source. Everything works fine in VC++ 6.0 The main dialog contains many child dialogs (not pop-ups) in which one child dialog is used to draw a plot based on the values sent from main dialog. The main dialog calls a function (Draw_Points) within the child dialog and the child dialog draws it and it does as long as the plot hits the edge and then it calls OnPaint message to refresh the dialog so that it can start afresh from left.
void CPlotDlg::Draw_Points(double value1, double value2)
{
if(m_LastPoint1.x < (m_time_rect.right-2))
{
// Store the data for later retrieval
m_CurrentPoint1.x = m_LastPoint1.x + 1;
m_CurrentPoint2.x = m_LastPoint2.x + 1;
// Do some calculations
m_Data1[m_DataCounter] = value1;
m_Data2[m_DataCounter++] = value2;
CWnd *Ctrl = GetDlgItem(IDE_PLOTS);
CDC *cdc = Ctrl->GetDC();
HGDIOBJ original = NULL;
original = cdc->SelectObject(GetStockObject(DC_PEN));
cdc->SelectObject(pen1);
cdc->MoveTo(m_LastPoint1);
cdc->LineTo(m_CurrentPoint1);
cdc->SelectObject(pen2);
cdc->MoveTo(m_LastPoint2);
cdc->LineTo(m_CurrentPoint2);
cdc->SelectObject(original);
Ctrl->ReleaseDC(cdc);
m_LastPoint1 = m_CurrentPoint1;
m_LastPoint2 = m_CurrentPoint2;
}
else
{
OnPaint();
Reset_PlotData();
}
}void CPlotDlg::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
if(m_BUpdate)
{
CDialogEx::OnPaint();
CWnd *Ctrl = GetDlgItem(IDE_PLOTS);
Ctrl->InvalidateRect(NULL,true);
Ctrl->UpdateWindow();
}
// Do not call CDialogEx::OnPaint() for painting messages
}It crashes when the Draw_points function calls OnPaint function in its else section, and when OnPaint() function executes CPaintDC dc(this); Any suggestions? thanks
PKNT
-
Kiran Satish wrote:
and then it calls OnPaint
Which you should never do; see WM_PAINT message (Windows)[^].
Thanks for your reply Richard. Could you suggest a better way to refresh my child dialog edit control where I draw these lines?
PKNT
-
I have a dialog based MFC application that I am rewriting in VS2010 from its original VC++ 6.0 source. Everything works fine in VC++ 6.0 The main dialog contains many child dialogs (not pop-ups) in which one child dialog is used to draw a plot based on the values sent from main dialog. The main dialog calls a function (Draw_Points) within the child dialog and the child dialog draws it and it does as long as the plot hits the edge and then it calls OnPaint message to refresh the dialog so that it can start afresh from left.
void CPlotDlg::Draw_Points(double value1, double value2)
{
if(m_LastPoint1.x < (m_time_rect.right-2))
{
// Store the data for later retrieval
m_CurrentPoint1.x = m_LastPoint1.x + 1;
m_CurrentPoint2.x = m_LastPoint2.x + 1;
// Do some calculations
m_Data1[m_DataCounter] = value1;
m_Data2[m_DataCounter++] = value2;
CWnd *Ctrl = GetDlgItem(IDE_PLOTS);
CDC *cdc = Ctrl->GetDC();
HGDIOBJ original = NULL;
original = cdc->SelectObject(GetStockObject(DC_PEN));
cdc->SelectObject(pen1);
cdc->MoveTo(m_LastPoint1);
cdc->LineTo(m_CurrentPoint1);
cdc->SelectObject(pen2);
cdc->MoveTo(m_LastPoint2);
cdc->LineTo(m_CurrentPoint2);
cdc->SelectObject(original);
Ctrl->ReleaseDC(cdc);
m_LastPoint1 = m_CurrentPoint1;
m_LastPoint2 = m_CurrentPoint2;
}
else
{
OnPaint();
Reset_PlotData();
}
}void CPlotDlg::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
if(m_BUpdate)
{
CDialogEx::OnPaint();
CWnd *Ctrl = GetDlgItem(IDE_PLOTS);
Ctrl->InvalidateRect(NULL,true);
Ctrl->UpdateWindow();
}
// Do not call CDialogEx::OnPaint() for painting messages
}It crashes when the Draw_points function calls OnPaint function in its else section, and when OnPaint() function executes CPaintDC dc(this); Any suggestions? thanks
PKNT
Kiran Satish wrote:
OnPaint();
I'm thinking you should call
Invalidate()
instead of callingOnPaint()
directly."One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
-
Kiran Satish wrote:
OnPaint();
I'm thinking you should call
Invalidate()
instead of callingOnPaint()
directly."One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
Yes, that did the trick. I do that in couple of other child dialogs, but was not using it in this dialog. Well, looks like you overlook something that's fundamental. thanks David
PKNT
-
Thanks for your reply Richard. Could you suggest a better way to refresh my child dialog edit control where I draw these lines?
PKNT
Well, you need to rethink your design. You should collect all the information related to the drawing as a result of user interaction, file processing etc. You then call
InvalidateRect
to tell Windows that your data has changed, and your window/client needs to be repainted. Then in the control you call your paint function in response to receiving aWM_PAINT
message. It is at that point that you draw your lines, shapes, text etc.