进度条引起刷屏的问题

liumenghappy 2009-09-04 01:06:43
我用了网上的进度条类CProgressWnd,结果进度条显示过程中,程序中的图像(尤其是矢量图)闪的厉害,调试发现是由CProgressWnd中的函数PeekAndPump引起的,函数PeekAndPump如下:
void CProgressWnd::PeekAndPump(BOOL bCancelOnESCkey /*= TRUE*/)
{
if (m_bModal && ::GetFocus() != m_hWnd)
SetFocus();

MSG msg;
while (!m_bCancelled && ::PeekMessage(&msg, NULL,0,0,PM_NOREMOVE))
{
if (bCancelOnESCkey && (msg.message == WM_CHAR) && (msg.wParam == VK_ESCAPE))
OnCancel();

// Cancel button disabled if modal, so we fake it.
if (m_bModal && (msg.message == WM_LBUTTONUP))
{
CRect rect;
m_CancelButton.GetWindowRect(rect);
if (rect.PtInRect(msg.pt))
OnCancel();
}
if (!AfxGetApp()->PumpMessage())
{
::PostQuitMessage(0);
return;
}
}
}
PeekAndPump应该是用来刷新进度条窗口的,结果它居然连图像窗口也刷新了,请问这个问题怎么解决?
...全文
328 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
菜牛 2009-12-31
  • 打赏
  • 举报
回复
OnPaint是不会调用OnEraseBkgnd的,而是由WM_ERASEBKGND消息调用该函数;OnPaint调用的是OnDraw
liumenghappy 2009-09-08
  • 打赏
  • 举报
回复
自己顶!
OnEraseBkGnd、OnPaint、OnDraw三个函数之间的关系是什么?
我只知道在OnPaint里面隐含的调用了OnEraseBkGnd,他们到底和闪屏有啥关系?
心留 2009-09-07
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 woosir 的回复:]
::AlphaBlend(pDC->GetSafeHdc(),rect.left,rect.top,rect.Width(),rect.Height(),
这里的pDC是主图像所在的屏幕DC吧,如果将它换成对应的内存DC就可以实现你所期望的了。
即创建一个与主图像所在的屏幕DC兼容的内存memDC(不知你是不是已经为栅格图像建了一个),矩形直接叠加在其上面。
最后在OnDraw里直接bitblt就行。
[/Quote]

你可真聪明
liumenghappy 2009-09-07
  • 打赏
  • 举报
回复
能不能拦截WM_PAINT 消息,不然主窗口响应呢
liumenghappy 2009-09-07
  • 打赏
  • 举报
回复
问题已经解决!谢谢大家
顺便再问个问题:
OnEraseBkGnd、OnPaint、OnDraw三个函数之间的关系是什么?
我只知道在OnPaint里面隐含的调用了OnEraseBkGnd,他们到底和闪屏有啥关系?
liumenghappy 2009-09-06
  • 打赏
  • 举报
回复
你的建议很好,我试试,十分感谢!!!
WooSir 2009-09-05
  • 打赏
  • 举报
回复
::AlphaBlend(pDC->GetSafeHdc(),rect.left,rect.top,rect.Width(),rect.Height(),
这里的pDC是主图像所在的屏幕DC吧,如果将它换成对应的内存DC就可以实现你所期望的了。
即创建一个与主图像所在的屏幕DC兼容的内存memDC(不知你是不是已经为栅格图像建了一个),矩形直接叠加在其上面。
最后在OnDraw里直接bitblt就行。
WooSir 2009-09-05
  • 打赏
  • 举报
回复
::AlphaBlend(pDC->GetSafeHdc(),rect.left,rect.top,rect.Width(),rect.Height(),
这里的pDC是主图像所在的屏幕DC吧,如果将它换成对应的内存DC就可以实现你所期望的了。
即创建一个与主图像所在的屏幕DC兼容的内存memDC(不知你是不是已经为栅格图像建了一个),矩形直接叠加在其上面。
最后在OnDraw里直接bitblt就行。
liumenghappy 2009-09-04
  • 打赏
  • 举报
回复
有谁知道怎么用双缓冲技术画透明矩形吗?请高手帮忙
liumenghappy 2009-09-04
  • 打赏
  • 举报
回复
我画透明矩形的代码如下:
CDC dcMem;
CBitmap bmp;
dcMem.CreateCompatibleDC(pDC);
bmp.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());
dcMem.SelectObject(&bmp);
CPen pen(PS_SOLID, 2, RGB(255,0,0));
CPen *pOldPen = dcMem.SelectObject(&pen);
CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
CBrush *pOldBrush=dcMem.SelectObject(pBrush);
dcMem.Rectangle(0,0,rect.Width(),rect.Height());
BLENDFUNCTION blendFunction = {AC_SRC_OVER, 0, 255, 0x01};
::AlphaBlend(pDC->GetSafeHdc(),rect.left,rect.top,rect.Width(),rect.Height(),
dcMem.GetSafeHdc(),0,0,rect.Width(),rect.Height(),blendFunction);
dcMem.DeleteDC();
大家看看该怎么改,才能不闪屏,但一定要透明
liumenghappy 2009-09-04
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 woosir 的回复:]
我也觉得是你的绘图代码有问题,就算CProgressWnd触发了窗口的WM_PAINT消息,也不一定使窗口全部重绘,导致闪烁。
如果你的绘图代码没使用双缓存机制,可能会闪烁。
[/Quote]
我的主图像上栅格图像是双缓冲,不闪屏,可是图上还要画一个透明矩形,我不知道怎么用双缓冲搞定,请高手指教
WooSir 2009-09-04
  • 打赏
  • 举报
回复
我也觉得是你的绘图代码有问题,就算CProgressWnd触发了窗口的WM_PAINT消息,也不一定使窗口全部重绘,导致闪烁。
如果你的绘图代码没使用双缓存机制,可能会闪烁。
  • 打赏
  • 举报
回复
不可能是这个函数的问题。他处理消息,并不产生消息,你得找到产生消息的地方,看他是不是使父窗口无效了,或把CProgressWnd的背景色屏蔽掉。onerasebkgnd();
liumenghappy 2009-09-04
  • 打赏
  • 举报
回复
在线等!
liumenghappy 2009-09-04
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 conry 的回复:]
如果你是用的这个
http://www.codeproject.com/KB/miscctrl/progresswnd.aspx
那么应该是你本身绘制有问题
我这里测试没有发现问题

你操作的时候不显示进度看看会不会闪
[/Quote]
我用的就是这个类,可是我spy++查看,它确实触发了WM_PAINT
不过hdc为0x0000000
Conry 2009-09-04
  • 打赏
  • 举报
回复
如果你是用的这个
http://www.codeproject.com/KB/miscctrl/progresswnd.aspx
那么应该是你本身绘制有问题
我这里测试没有发现问题

你操作的时候不显示进度看看会不会闪
liumenghappy 2009-09-04
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 fandh 的回复:]
这段代码看不到那儿有重新画的地方,建议你看看其它地方,尤其是发给进度条消息的那一块代码!
[/Quote]
可是我把 proWnd.PeekAndPump();这句删掉的话,连进度条也不重画了
加上的话,进度条和主窗口都重画
我觉得问题就在AfxGetApp()->PumpMessage()上,它用了消息泵
fandh 2009-09-04
  • 打赏
  • 举报
回复
这段代码看不到那儿有重新画的地方,建议你看看其它地方,尤其是发给进度条消息的那一块代码!
liumenghappy 2009-09-04
  • 打赏
  • 举报
回复
问题可能出在PeekAndPump中的AfxGetApp()->PumpMessage(),它使进度条重画的同时,使主窗口也重画了,但我对这个函数不熟悉,不知道怎么限制它,请大家帮忙!

16,473

社区成员

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

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

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