2013-08-12 78 views
3

我遇到了CFrameWnd的OnPaint方法问题,我似乎无法弄清楚发生了什么。大约每10毫秒调用一次OnPaint,这会导致计算机冻结。检查CPU使用率和这个应用程序占用50%!OnPaint更新太频繁

该应用程序是一个非常简单的MFC应用程序,它写在一个文件中。

// Includes are done here... 

class MFC_Tutorial_Window : public CFrameWnd 
{ 
std::string data; 

public: 
    MFC_Tutorial_Window() 
    { 
     this->data = ""; 
     Create(NULL, "Data Win"); // Create window 
    } 

    void OnPaint() 
    { 
     CDC* pDC = GetDC(); 

     CString s = CString(this->data.c_str()); 
     RECT rc; 

     HWND hwnd = this->m_hWnd; 
     if(hwnd != NULL) { 
      ::GetWindowRect(hwnd, &rc); 

      rc.top = rc.bottom/2; 

      if(pDC != NULL && pDC->m_hDC != NULL) { 
       pDC->DrawText(s, &rc, DT_CENTER); 
      } 
     } 
    } 

    void UpdateWithNewData(std::string up) { 
     this->data = up; 
     Invalidate(); 
    } 


    DECLARE_MESSAGE_MAP() 
}; 

BEGIN_MESSAGE_MAP(MFC_Tutorial_Window, CFrameWnd) 
    ON_WM_PAINT()  
END_MESSAGE_MAP() 

// App class 
class MyApp :public CWinApp 
{ 
    MFC_Tutorial_Window *wnd; 

    BOOL InitInstance() 
    { 
     wnd = new MFC_Tutorial_Window(); 
     m_pMainWnd = wnd; 
     m_pMainWnd->ShowWindow(3); 

         wnd->UpdateWithNewData("Hello world!");   
      return 1; 
    } 
}; 

有谁知道为什么OnPaint被系统垃圾邮件?一直盯着这个代码很长一段时间,我无法找到它。

+0

请注意,您几乎总是希望使用View类,在这种情况下,您可以在OnDraw中进行绘制,并且框架负责处理导致当前问题的细节。 –

回答

2

必须调用CPaintDC析构函数才能重新设置重新绘制标志。您需要在CDC上拨打beginPaint();endPaint();,该号码实际上应更改为CPaintDC。更重要的是,不调用endPaint();将导致上下文被重新绘制,无论如何。

+0

非常感谢!现在就像一个魅力! :D – Pphoenix

+0

@凤凰尼斯!很高兴我能帮到:) –

+0

EndPaint似乎清除了我想要绘制的区域。有没有办法确保绘制的区域保持不变,直到下次我要重绘并仍然保持EndPaint? – Pphoenix

2

A WM_PAINT只要消息队列中没有其他消息且窗口的更新区域(请参见InvalidateRect)非空,就会生成消息。在处理WM_PAINT消息时,应用程序通过调用EndPaint来通知更新区域已重新绘制。未能拨打EndPaint将不会将更新区域标记为已处理,因此在下一次应用程序请求消息时,WM_PAINT是有效的候选项。

在MFC中,调用BeginPaintEndPaint的功能封装在CPaintDC Class中。为WM_PAINT标准的MFC消息处理程序是这样的:

void OnPaint() 
{ 
    CPaintDC dc(this); // calls BeginPaint() 
    // Perform rendering operations on dc 
    // ... 
} // CPaintDC::~CPaintDC() calls EndPaint() 

使用设备上下文的更多详细信息可在Device Contexts找到。