窗口画图的抖动问题

alldying 2011-07-03 03:21:18
代码片段:

CRect rc;
m_pWnd = new CWnd;
rc.SetRect(StartX, StartY,StartX+SH_WIDTH, StartY+SH_HEIGHT);
m_SHHQpWnd->CreateEx(0,AfxRegisterWndClass(CS_CLASSDC|CS_SAVEBITS|CS_HREDRAW|CS_VREDRAW),
"",WS_POPUP|WS_VISIBLE,rc,this,0);
m_pThread = new CWinThread;
m_pThread = AfxBeginThread(ShowAll,(LPVOID)(m_pWnd->m_hWnd));


UINT SHShowAll(LPVOID pParam)
{
CWnd *pWnd = new CWnd;
CDC *pdc;
pWnd->Attach((HWND) pParam);
pdc = pWnd->GetDC();

CRect rc;
rc.SetRect(0, 0, SH_WIDTH, SH_HEIGHT);

CDC memdc;
CBrush Brush,*pOldBrush;
CBitmap Bitmap, *pOldBitmap;
CFont font,*poldfont;
memdc.CreateCompatibleDC(pdc);
Brush.CreateSolidBrush(RGB(0,0,0));
pOldBrush = memdc.SelectObject(&Brush);
Bitmap.CreateCompatibleBitmap(pdc, rc.Width(), rc.Height());
pOldBitmap = memdc.SelectObject(&Bitmap);
font.CreateFont(SH_FONT_SIZE,0,0,0,FW_NORMAL,FALSE,FALSE,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH | FF_SWISS,"楷_GB2312");
poldfont = memdc.SelectObject(&font);
memdc.SetBkMode(TRANSPARENT);
memdc.SetTextColor(RGB(255,255,0));
pdc->BitBlt(0,0,SH_WIDTH,SH_HEIGHT,&memdc,0,0,SRCCOPY);

//pdc->FillSolidRect(rc, RGB(0,0,0));

CDC memdc1;
CBrush Brush1, *pOldBrush1;
CBitmap Bitmap1, *pOldBitmap1;
CFont font1, *poldfont1;
CRect rc1;

memdc1.CreateCompatibleDC(pdc);
Brush1.CreateSolidBrush(RGB(0,0,0));
pOldBrush1 = memdc1.SelectObject(&Brush1);

rc1.SetRect(0, 0, SH_DENG_WIDTH, SH_DENG_HEIGHT);
Bitmap1.CreateCompatibleBitmap(pdc, rc1.Width(), rc1.Height());
pOldBitmap1 = memdc1.SelectObject(&Bitmap1);

font1.CreateFont(16,0,0,0,FW_NORMAL,FALSE,FALSE,0,GB2312_CHARSET,OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH | FF_SWISS, "楷体_GB2312");

poldfont1 = memdc1.SelectObject(&font1);
memdc1.SetBkMode(TRANSPARENT);
memdc1.SetTextColor(RGB(255,0,0));

while(1)
{
。。。。。。。。。。。
// 在memdc1上写内容,并以某种方式逐步拷贝到memdc上,最后再拷贝到pdc上显示
。。。。。。。。。。。
for (int t = 0; t < 7; t ++)
{
memdc.BitBlt(0, t*32, SH_WIDTH-1, SH_DENG_HEIGHT, &memdc, 1, t*32, SRCCOPY);
memdc.BitBlt(SH_WIDTH-1, t*32, 1, SH_DENG_HEIGHT, &memdc, 0, t*32+32, SRCCOPY);
}

memdc.BitBlt(0, t*32, SH_WIDTH-1, SH_DENG_HEIGHT, &memdc, 1, t*32, SRCCOPY);
memdc.BitBlt(192-1, t*32, 1, SH_DENG_HEIGHT, &memdc1, CurPos, 0, SRCCOPY);

CurPos = CurPos + 1; // 每次递进一个像素点

pdc->BitBlt(0, 0, SH_WIDTH, SH_HEIGHT, &memdc, 0, 0, SRCCOPY);

Sleep(5);
}

}

问题:用以上方式的显示过程有明显的抖动,但是前面AfxRegisterWndClass函数的参数为CS_CLASSDC|CS_SAVEBITS|CS_HREDRAW|CS_VREDRAW时比为NULL时的抖动要小,但是仔细看还是能看出来,请各位兄弟帮帮看看,已经用了双缓冲了,为什么还会抖动?谢谢!
...全文
221 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
向立天 2011-08-08
  • 打赏
  • 举报
回复
您好
我是本版版主
此帖已多日无人关注
请您及时结帖
如您认为问题没有解决可按无满意结帖处理
另外本版设置了疑难问题汇总帖
并已在版面置顶
相关规定其帖子中有说明
您可以根据规定提交您帖子的链接
如您目前不想结帖只需回帖说明
我们会删除此结帖通知

见此回复三日内无回应
我们将强制结帖
相关规定详见界面界面版关于版主结帖工作的具体办法
向立天 2011-07-07
  • 打赏
  • 举报
回复
OnEraseBkgnd处理了么?
awfymwvf 2011-07-07
  • 打赏
  • 举报
回复
楼主的代码对我来说太高深了啊
alldying 2011-07-07
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 ttt19880110 的回复:]
重载OnEraseBkgnd(){return true;}试试
[/Quote]
怎么重载OnEraseBkgnd,我的窗口是动态创建的?
alldying 2011-07-07
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 heksn 的回复:]
你的绘制频率很高吗
实时性不高的话可以采用定时绘制
[/Quote]
频率还是很高的,要实现逐行上滚的显示效果。
alldying 2011-07-07
  • 打赏
  • 举报
回复
加了WS_CLIPCHILDREN还是一样
pop1210 2011-07-07
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 alldying 的回复:]
引用 6 楼 ttt19880110 的回复:
重载OnEraseBkgnd(){return true;}试试

怎么重载OnEraseBkgnd,我的窗口是动态创建的?
[/Quote]
动态创建你就是指的CWnd* pWnd = new Cwnd; pWnd->createEX?
看你的代码是不用处理OnEraseBkgnd了,
MSDN:
LPCTSTR AFXAPI AfxRegisterWndClass(
UINT nClassStyle,
HCURSOR hCursor = 0,
HBRUSH hbrBackground = 0,
HICON hIcon = 0
);
hbrBackground
Specifies a handle to the brush resource to be installed in each window created from the window class. If you use the default of 0, you will have a NULL background brush, and your window will, by default, not erase its background while processing WM_ERASEBKGND.
至于你抖动问题不太清楚了~
vector03 2011-07-04
  • 打赏
  • 举报
回复
加上子窗体剪裁试试WS_CLIPCHILDREN
pop1210 2011-07-04
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 alldying 的回复:]
不好意思,写错了,m_SHHQpWnd就是m_pWnd,应该是
m_pWnd->CreateEx(0,AfxRegisterWndClass(CS_CLASSDC|CS_SAVEBITS|CS_HREDRAW|CS_VREDRAW),
"",WS_POPUP|WS_VISIBLE,rc,this,0);
[/Quote]
你先把SHShowAll这个函数精简下,如果抖动的画即时画几个字串它也会抖吧,以此来检测双缓冲是否真的用对了;
另外,你开个线程AfxBeginThread(ShowAll,(LPVOID)(m_pWnd->m_hWnd));
已经把窗口句柄传进去了,为什么还要在线程函数SHShowAll里new个CWnd哩,
UINT SHShowAll(LPVOID pParam)
{
CWnd *pWnd = new CWnd;
CDC *pdc;
pWnd->Attach((HWND) pParam);
pdc = pWnd->GetDC();
...
要拿m_pWnd的DC根据句柄直接拿就是了...
pingyuanwei 2011-07-04
  • 打赏
  • 举报
回复
重载OnEraseBkgnd(){return true;}试试
  • 打赏
  • 举报
回复
你的绘制频率很高吗
实时性不高的话可以采用定时绘制
alldying 2011-07-03
  • 打赏
  • 举报
回复
不好意思,写错了,m_SHHQpWnd就是m_pWnd,应该是
m_pWnd->CreateEx(0,AfxRegisterWndClass(CS_CLASSDC|CS_SAVEBITS|CS_HREDRAW|CS_VREDRAW),
"",WS_POPUP|WS_VISIBLE,rc,this,0);
pop1210 2011-07-03
  • 打赏
  • 举报
回复
m_SHHQpWnd就create了一下?贴的这一堆代码也没用到啊?m_SHHQpWnd就是m_pWnd?

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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