我试图让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在移动时会闪烁。任何人都可以解决这个问题吗?
答案 0 :(得分:1)
它闪烁是因为你使整个窗口无效。这会导致一个WM_ERASE,它会使窗口空白,然后是WM_PAINT,它会重绘整个事物。您将FALSE
作为bRepaint
(最后)参数传递给MoveWindow
,以便在窗口移动后不会重新绘制任何必要的窗口区域。
通常当窗口移动时,内容随之移动,并且需要重绘的唯一部分是在屏幕外或在另一个窗口下的位。将TRUE
作为最后一个参数传递将导致仅重绘窗口的这些区域,这将避免闪烁。