如何在CScrollView移动时避免闪烁?

时间:2016-12-19 21:27:36

标签: c++ mfc

我试图让CScrollView移动

虽然它成功移动,但我发现了一个问题...

CScrollView在移动时随机闪烁。

以下是我项目的全部代码:

#include <afxwin.h>
#include <afxext.h> 
#include "resource.h"

class MyView : public CScrollView
{
public:
    void OnDraw(CDC *aDC){
        CRect rc;
        GetClientRect(&rc);

        aDC->FillSolidRect(&rc, RGB(0,0,255));
    }

    BOOL PreCreateWindow(CREATESTRUCT& cs)  
    {  
        cs.style &= ~WS_BORDER;
        return CScrollView::PreCreateWindow(cs);  
    } 

    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
        if(CScrollView::OnCreate(lpCreateStruct) == -1)
            return -1;
        CSize DCSize(200, 800);

        SetScrollSizes(MM_TEXT, DCSize);
        return 0;
    }


    DECLARE_DYNCREATE(MyView)
    DECLARE_MESSAGE_MAP()
};

IMPLEMENT_DYNCREATE(MyView, CScrollView)

BEGIN_MESSAGE_MAP(MyView, CScrollView)
    ON_WM_CREATE()
END_MESSAGE_MAP()

class CMainDlg : public CDialog
{
public:
    CMainDlg(CWnd* pParent = NULL);

    enum { IDD = IDD_MAIN_DIALOG };

    CWnd* pFrameWnd;
    CCreateContext context;
    MyView* pView;
    int time;

    virtual BOOL OnInitDialog();
    afx_msg void OnTimer(UINT_PTR timer);

    void OnPaint(){
        CPaintDC dc(this);
        CRect rc;
        GetClientRect(&rc);
        dc.FillSolidRect(&rc,RGB(255,187,187));
    }


    DECLARE_MESSAGE_MAP()

};

BEGIN_MESSAGE_MAP(CMainDlg, CDialog)
    ON_WM_TIMER()
    ON_WM_PAINT()
END_MESSAGE_MAP()


CMainDlg::CMainDlg(CWnd* pParent /*=NULL*/)
    : CDialog(CMainDlg::IDD, pParent)
{
}


BOOL CMainDlg::OnInitDialog()
{
   CDialog::OnInitDialog();

   pFrameWnd = this;
   context.m_pCurrentDoc = NULL;
   context.m_pNewViewClass = RUNTIME_CLASS(MyView);

   pView = (MyView*)((CFrameWnd*)pFrameWnd)->CreateView(&context);
   pView->ShowWindow(SW_SHOW);

   time = 0;
   SetTimer(1, 1, 0);
   return TRUE;
}

void CMainDlg::OnTimer(UINT_PTR timer)
{
    if(timer == 1){
        if(time > 300){
            KillTimer(1);
            return;
        }
        pView->MoveWindow(CRect(time,10,time+300,200),FALSE);
    }
    time+=1;
    Invalidate(FALSE);
}
class MyApp : public CWinApp
{
public:
    BOOL InitInstance()
    {
        CWinApp::InitInstance();

        CMainDlg Frame;

        Frame.DoModal();

        return true;
    }
} a_app;

我不知道为什么CScrollView在移动时会闪烁。任何人都可以解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

它闪烁是因为你使整个窗口无效。这会导致一个WM_ERASE,它会使窗口空白,然后是WM_PAINT,它会重绘整个事物。您将FALSE作为bRepaint(最后)参数传递给MoveWindow,以便在窗口移动后不会重新绘制任何必要的窗口区域。

通常当窗口移动时,内容随之移动,并且需要重绘的唯一部分是在屏幕外或在另一个窗口下的位。将TRUE作为最后一个参数传递将导致仅重绘窗口的这些区域,这将避免闪烁。