MFC:窗口响应太慢

时间:2013-12-08 04:00:46

标签: visual-c++ mfc

我在Frame Window Class中有以下代码

void CMainFrame::OnPaint() 
{
    CPaintDC dc(this);
}

我有一个按钮事件处理程序

void CMainFrame::OnLButtonUp(UINT nFlags, CPoint point) {
    CShapes shape;
    CFrameWnd::OnLButtonUp(nFlags, point);
    CPaintDC dc(this);
    CRect client;
    GetClientRect(&client);
    shape.DrawRectangle(&dc, client, 10,10, 10,10);
    shape.DrawRoundRectangle(&dc, client, 50, 50, 50, 50, 20, 20);
}

但是按钮后面没有绘制矩形。但是,当我从void CPaintDC dc(this);中移除CMainFrame::OnPaint()时,它可以正常工作,但窗口的响应速度非常慢。它耗费了太多的内存。

还尝试在AfxGetMainWnd()的{​​{1}}中使用this代替CPaintDC dc(),但它无效。

4 个答案:

答案 0 :(得分:2)

它变得如此缓慢的原因是你正在创造一个无限的“无所事事”循环。你必须遵守两条绝对规则:

OnPaint处理程序必须具有CPaintDC(this);

所有其他消息处理程序不得包含CPaintDC。

将您的绘画移动到OnPaint中。

答案 1 :(得分:0)

不要在按钮处理程序中执行您的绘制代码。在OnLButtonUp电话后,将代码从OnPaint移至CPaintDC dc(this)例程(但请取出CFrameWnd::OnLButtonUp(nFlags, point);代码。)

CPaintDC dc(this)只能在OnPaint例程中调用,而不能在按钮处理程序中调用。 (http://msdn.microsoft.com/en-us/library/a48eab8d.aspx - CPaintDC对象只能在响应WM_PAINT消息时使用,通常在OnPaint消息处理程序成员函数中。

在绘图例程中调用Invalidate将导致无限循环。

答案 2 :(得分:0)

CPaintDC是一个RAII对象,它将BeingPaint() ctorEndPaint()中的dtor包裹在一起(发生在函数末尾)。所以在这种情况下,你不是在画任何东西。只要窗口需要绘画,就会调用OnPaint。它甚至不是由用户驱动的。它发生在很多事件上,如窗口激活,重叠等。按钮单击不会触发OnPaint事件,除非它导致重新绘制窗口或强制Invalidate。 CPaintDC也只在OnPaint函数中使用。对于其他绘图,您将使用CDC类。 (调用GetDC()执行绘制操作和ReleaseDC()

我建议在OnPaint函数中编写绘图代码以进行持久绘图。绘制矩形的数据可以存储在类中,并指示使用标志(尽管基于标志的编码不是一个好主意)并在OnPaint函数内绘制。在事件处理程序(按钮单击)中绘制的问题是当窗口刷新时绘图将消失。这样的事情怎么样?

void CMainFrame::OnPaint() 
{
    CPaintDC dc(this);
    if(draw_rect)
    {
        CShapes shape;
        CRect client;
        GetClientRect(&client);
        shape.DrawRectangle(&dc, client, 10,10, 10,10);
        shape.DrawRoundRectangle(&dc, client, 50, 50, 50, 50, 20, 20);
    }
}

void CMainFrame::OnLButtonUp(UINT nFlags, CPoint point) {
    CFrameWnd::OnLButtonUp(nFlags, point);
        draw_rect = true;
}

答案 3 :(得分:-2)

它工作.. 我在Invalidate();方法的末尾添加了CMainFrame::OnPaint(),但它确实有效。

void CMainFrame::OnPaint() 
{
    CPaintDC dc(this);
    Invalidate();
}