我对CFrameWnd的OnPaint方法有问题,我似乎无法弄清楚发生了什么。大约每10毫秒调用一次OnPaint,这会导致计算机冻结。已检查的CPU使用率和此应用占用了50%!
该应用程序是一个非常简单的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 :(得分:2)
必须调用CPaintDC析构函数才能重置重绘标志。您需要在beginPaint();
上调用endPaint();
和CDC
,CPaintDC
实际上应该更改为endPaint();
。更重要的是,不调用{{1}}将导致上下文重新绘制,无论如何。
答案 1 :(得分:2)
只要消息队列中没有其他消息,并且窗口的更新区域(请参阅InvalidateRect
)非空,就会生成WM_PAINT
消息。处理WM_PAINT
消息时,应用程序通过调用EndPaint
发出更新区域已重新绘制的信号。未能调用EndPaint
将不会将更新区域标记为已处理,因此下次应用程序请求消息时,WM_PAINT
是有效的候选者。
在MFC中,调用BeginPaint
和EndPaint
的功能封装在CPaintDC
Class中。 WM_PAINT
的标准MFC消息处理程序如下所示:
void OnPaint()
{
CPaintDC dc(this); // calls BeginPaint()
// Perform rendering operations on dc
// ...
} // CPaintDC::~CPaintDC() calls EndPaint()
有关使用设备上下文的更多详细信息,请访问Device Contexts。