在CSCrollview移动时,如何避免闪烁

How to avoid flickering while the CScrollView is moving?

本文关键字:何避免 闪烁 CSCrollview 移动      更新时间:2023-10-16

我试图使cscrollview move

尽管它成功地移动了,但我发现了一个问题...

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在移动时会闪烁。谁能解决此问题?

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

通常,当窗口移动内容时,内容移动时,唯一需要重新绘制的部分是屏幕上或另一个窗口下方的位。将TRUE传递为最后一个参数将仅导致窗口的这些区域重新绘制,从而避免闪烁。