Pergunta

I have a problem with the OnPaint method of CFrameWnd, and I cant seem to figure out what is happening. OnPaint is called approx every 10 ms, which causes the computer to freeze. Checked CPU usage and this app takes up 50%!

The application is a very simple MFC app, which is written in one file.

// 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;
    }
};

Does anyone know why OnPaint is spammed by the system? Have been staring at this code for ages and I just can't find it.

Foi útil?

Solução

The CPaintDC destructor has to be called for the repainting flag to be reset. You need to call beginPaint(); and endPaint(); on your CDC which should actually be changed to a CPaintDC. More importantly, not calling endPaint(); will cause the context to be repainted no matter what.

Outras dicas

A WM_PAINT message is generated whenever there are no other messages in the message queue and the window's update region (see InvalidateRect) is non-empty. When handling a WM_PAINT message an application signals that the update region has been repainted by calling EndPaint. Failing to call EndPaint will not mark the update region as handled, so the next time an application asks for a message, WM_PAINT is a valid candidate.

In MFC the functionality to call BeginPaint and EndPaint is encapsulated in the CPaintDC Class. The standard MFC message handler for WM_PAINT looks like this:

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

More detailed information on using device contexts can be found at Device Contexts.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top