3

CFrameWnd の OnPaint メソッドに問題があり、何が起こっているのかわかりません。OnPaint は約 10 ミリ秒ごとに呼び出されるため、コンピューターがフリーズします。CPU使用率を確認すると、このアプリは50%を占めています!

このアプリケーションは、1 つのファイルに記述された非常に単純な 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 では、呼び出す機能がClassBeginPaintEndPaintカプセル化されています。の標準 MFC メッセージ ハンドラーは次のようになります。CPaintDCWM_PAINT

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

デバイス コンテキストの使用に関する詳細については、デバイス コンテキストを参照してください

于 2013-08-12T09:46:38.377 に答える