是我的双缓存没用对,还是这个用双缓存解决不了?

aoyihuashao 2010-01-15 02:29:43
我要做的事:在CDialog上面画网格,15*21的。
有个线程每100-500毫秒向CDialog发送消息,在消息里要刷新界面。

afx_msg LRESULT CELSFKDlg::OnThread(WPARAM wparam,LPARAM lparam)
{
RedrawWindow();
return NULL;
}

我刚找了个双缓存的写法,貌似不管用,刷屏刷的厉害。

方法如下:

CPaintDC dc(this);
CRect clientRect;
GetClientRect( &clientRect );
CDC MemDC;
CBitmap Membitmap;
Membitmap.CreateCompatibleBitmap( &dc, clientRect.Width(), clientRect.Height() );
MemDC.CreateCompatibleDC( &dc );
CBitmap *pOldBitmap = MemDC.SelectObject( &Membitmap );
MemDC.FillSolidRect( 0, 0, clientRect.Width(), clientRect.Height(), RGB( 255, 255, 255 ) );
MemDC.Ellipse( &clientRect ); //记住 画图时候用 CDC MemDC; 即先在CDC上画 之后拷贝上去

for (int i = 0 ; i < NUM_WIDTH;i++)
{
for (int j = 0; j < NUM_HEIGHT ; j++)
{
if(m_status[i][j] == 0)
{
CRect rect = ChangePositionToRect(i,j);
MemDC.Draw3dRect(&rect,RGB(0,0,0),RGB(0,0,0));
}
}
}

dc.BitBlt( 0, 0, clientRect.Width(), clientRect.Height(), &MemDC, 0, 0, SRCCOPY );
MemDC.DeleteDC();
Membitmap.DeleteObject();

CDialog::OnPaint();
...全文
130 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
marrco2005 2010-01-18
  • 打赏
  • 举报
回复
添加 WM_ERASEBKGND 消息响应函数

BOOL CAboutDlg::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default

return TRUE;
}

不刷新背景,这样就不闪了
用户 昵称 2010-01-17
  • 打赏
  • 举报
回复
CRect   clientRect;   
CDC *MemDC = NULL;
CBitmap Membitmap;
void CAaaDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting

SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;

// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CPaintDC dc(this); // device context for painting
if( NULL == MemDC )
{
MemDC = new CDC;
MemDC->CreateCompatibleDC( &dc );
GetClientRect( &clientRect );
Membitmap.CreateCompatibleBitmap( &dc, clientRect.Width(), clientRect.Height() );
CBitmap *pOldBitmap = MemDC->SelectObject( &Membitmap );
MemDC->FillSolidRect( 0, 0, clientRect.Width(), clientRect.Height(), RGB( 255, 255, 255 ) );
MemDC->Ellipse( &clientRect ); //记住 画图时候用 CDC MemDC; 即先在CDC上画 之后拷贝上去


int i;

for( i = 0; i < 1000; i += 10 )
{
MemDC->MoveTo( i, 0 );
MemDC->LineTo( i, 1000 );
}
for( i = 0; i < 1000; i += 10 )
{
MemDC->MoveTo( 0, i );
MemDC->LineTo( 1000, i );
}

}
dc.BitBlt( 0, 0, clientRect.Width(), clientRect.Height(), MemDC, 0, 0, SRCCOPY );
CDialog::OnPaint();
}
}

换这个代码试一下,看看到底还闪不闪。

不过这代码没有收尾工作,new的变量要删除,gdi资源也没释放。
用户 昵称 2010-01-17
  • 打赏
  • 举报
回复
楼主好像为用双缓冲而用双缓冲。并没有掌握几个关键

背景DC全局的,一次性画好,画好之后bitblt到前景,之后只在onpaint或ondraw时bitblt一次。

要换背景同样也要这样做。
herokay 2010-01-17
  • 打赏
  • 举报
回复
线程只学要负责处理要画的数据就行了,在OnPanit里画
danxuezx 2010-01-17
  • 打赏
  • 举报
回复
CDialog::OnPaint();
只在程序启动时调用它就行了,之后就不要掉它。

您把它注释掉看看
WalkersChen 2010-01-17
  • 打赏
  • 举报
回复
楼主给的信息不齐,但我估计应该是错了吧。
把Membitmap和MemDC的初始化放到OnInitDialog里,
然后在线程函数里绘制图形。
OnPaint只一句BitBlt就行了。
aoyihuashao 2010-01-15
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 liumenghappy 的回复:]
双缓冲没有问题,是不是刷新界面的时间间隔太短了啊,貌似刷的太厉害用双缓冲也好闪的
[/Quote]
500ms都卡的
liumenghappy 2010-01-15
  • 打赏
  • 举报
回复
双缓冲没有问题,是不是刷新界面的时间间隔太短了啊,貌似刷的太厉害用双缓冲也好闪的
aoyihuashao 2010-01-15
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 healer_kx 的回复:]
我比较孤陋,你为什么还有线程参与啊?
[/Quote]

线程是做其他事的,线程处理完事情后,因为把数据改变了,所以要刷新界面啊。
zhou1xp 2010-01-15
  • 打赏
  • 举报
回复
为什么要不停刷啊,系统自己知道啊,你画出来就行了啊
healer_kx 2010-01-15
  • 打赏
  • 举报
回复
我比较孤陋,你为什么还有线程参与啊?

16,550

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Creator Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧