3

我对 CFrameWnd 的 OnPaint 方法有疑问,我似乎无法弄清楚发生了什么。OnPaint 大约每 10 毫秒调用一次,这会导致计算机死机。检查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 发送垃圾邮件?多年来一直盯着这段代码,我就是找不到。

4

2 回答 2

2

WM_PAINT只要消息队列中没有其他消息并且窗口的更新区域(请参阅 参考资料InvalidateRect)不为空,就会生成一条消息。处理WM_PAINT消息时,应用程序会通过调用 通知更新区域已被重新绘制EndPaint。调用失败EndPaint不会将更新区域标记为已处理,因此下次应用程序请求消息时,WM_PAINT它是一个有效的候选者。

在 MFC 中调用的功能BeginPaintEndPaint封装在CPaintDCClass中。标准 MFC 消息处理程序WM_PAINT如下所示:

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

有关使用设备上下文的更多详细信息,请参阅设备上下文

于 2013-08-12T09:46:38.377 回答
2

必须调用 CPaintDC 析构函数才能重置重绘标志。您需要调用beginPaint();and endPaint();on your CDCwhich 实际上应该更改为CPaintDC. endPaint();更重要的是,无论如何不调用都会导致上下文被重新绘制。

于 2013-08-12T09:25:37.880 回答