MFC 对话框 双缓冲

u0116snail 2013-09-02 04:13:40
当不适用 双缓冲绘图时候,在 OnPaint 函数中,使用如下代码进行绘制:

……
CClientDC dc(this);
PopEllipse(dc.GetSafeHdc(), &g_OffSet); //此处需要传递一个 hdc
//==绘制圆==========================================
CBrush *pOldBrush = (CBrush*)dc.SelectStockObject(NULL_BRUSH);
CPen pen;
pen.CreatePen(PS_SOLID, 5, RGB(0,0,0));
dc.SelectObject(&pen);
dc.Ellipse(40, 40, 400, 400);


//==文字绘制部分===========================================
SetBkMode(dc.GetSafeHdc(), TRANSPARENT);
dc.SelectObject(&m_font);
CPen textPen;
textPen.CreatePen(PS_SOLID, 1, RGB(0,0,0));
dc.SelectObject(&textPen);
dc.TextOut(400,20,_T("小狗嗷嗷叫"));
……

请问:
如果使用 双缓冲,我需要如何改动上面的代码?

PS: 我一直以为,既然在内存里要把东西都绘制好,那么我这些 SelectObject 了的“设备”(CPen 画笔、CBrush 画刷、CFont 字体)等等,这些如何跟 内存DC “绑定”? m_MemDC.SelectObject(&pen); 就可以吗?
...全文
273 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
向立天 2013-10-07
  • 打赏
  • 举报
回复
您好 我是本版版主 此帖已多日无人关注 请您及时结帖 如您认为问题没有解决可按无满意结帖处理 另外本版设置了疑难问题汇总帖 并已在版面置顶 相关规定其帖子中有说明 您可以根据规定提交您帖子的链接 如您目前不想结帖只需回帖说明 我们会删除此结帖通知 见此回复三日内无回应 我们将强制结帖 相关规定详见界面界面版关于版主结帖工作的具体办法
chuanxin8989 2013-09-05
  • 打赏
  • 举报
回复
学习一下
u0116snail 2013-09-05
  • 打赏
  • 举报
回复
问题已经解决了……

为什么不能结贴给分啊?!!!结贴时候,就卡主不能结贴, 什么情况?
昨夜无风 2013-09-02
  • 打赏
  • 举报
回复
1. 把CClientDC dc(this); 换成CPaintDC dc(this); 2. 最后要 pen.DelectObject(); textPen.DelectObject();
u0116snail 2013-09-02
  • 打赏
  • 举报
回复
引用 13楼 cjfdqchwh的回复
你这个估计是在 Debug 下会崩溃,在 Release 下应该正常运行
我刚刚自己测试一下,复制你的代码,在一个 基于对话框的 MFC 程序里头,在 Debug 下会崩溃,release 正常


你说的非常正确!
cjfdqchwhj 2013-09-02
  • 打赏
  • 举报
回复
你这个估计是在 Debug 下会崩溃,在 Release 下应该正常运行 我刚刚自己测试一下,复制你的代码,在一个 基于对话框的 MFC 程序里头,在 Debug 下会崩溃,release 正常
cjfdqchwhj 2013-09-02
  • 打赏
  • 举报
回复
内存DC 的释放方式……
u0116snail 2013-09-02
  • 打赏
  • 举报
回复
我大概估计是这段代码的问题,因为我不用 双缓冲的时候,程序是不会崩溃的,我修改的地方,就只有 OnPaint 里的这些地方了。 代码定位就是我上面贴的那个部分代码
u0116snail 2013-09-02
  • 打赏
  • 举报
回复
引用 9 楼 VisualEleven 的回复:
将兼容位图SelectObject到内存DC中去。


非常感谢您为我解答疑惑。
但是现在出现一个这样的问题,请问如何解决?
下面贴代码:


void CMyDlg::OnPaint()
{
//.....(省略MFC自动生成的代码),下面是我的代码:

CClientDC dc(this);
CRect rt;
GetClientRect(&rt);

m_MemDC.CreateCompatibleDC(&dc);
m_Bmp.CreateCompatibleBitmap(&dc, rt.Width(), rt.Height());
m_MemDC.SelectObject(&m_Bmp);
m_MemDC.FillSolidRect(0,0,rt.Width(), rt.Height(),RGB(200,180,0));

PopEllipse(m_MemDC.GetSafeHdc(), &g_OffSet);

//==绘制圆==========================================
CBrush *pOldBrush = (CBrush*)m_MemDC.SelectStockObject(NULL_BRUSH);
CPen pen;
pen.CreatePen(PS_SOLID, 5, RGB(0,0,0));
m_MemDC.SelectObject(&pen);
m_MemDC.Ellipse(40, 40, 400, 400);

//==文字绘制部分===========================================
SetBkMode(m_MemDC.GetSafeHdc(), TRANSPARENT);
m_MemDC.SelectObject(&m_font);
CPen textPen;
textPen.CreatePen(PS_SOLID, 1, RGB(0,0,0));
m_MemDC.SelectObject(&textPen);
m_MemDC.TextOut(40, 410, _T("小狗嗷嗷叫"));


//== 复制到屏幕上去 =======================================================
dc.BitBlt(0, 0, rt.Width(), rt.Height(), &m_MemDC, 0, 0, SRCCOPY);
m_Bmp.DeleteObject();
m_MemDC.DeleteDC();
}

我是如上所写的 代码,当能够运行,当程序运行一定时间后,就会崩溃,这是怎么回事? 我每隔 200 ms就会 InvalidateRect(NULL) 一次。

为什么程序运行到一定时间后,就会崩溃,这个时间不固定,有个时候几分钟后就会崩溃,有个时候要久一点才会崩溃。。

请问:这是为什么?怎么解决呢?急啊!!!
Eleven 2013-09-02
  • 打赏
  • 举报
回复
引用 8 楼 u011642451 的回复:
[quotequote=引用 6 楼 VisualEleven 的回复:] HBITMAP hOldBitmap = (HBITMAP)memDC.SelectObject(&m_Bmp);
按照您的提示, 我写成的双缓冲形式,但是,为什么我的背景是 黑色? 我还修改了一下这些地方: m_MemDC.FillSolidRect(0,0,rt.Width(), rt.Height(),RGB(255,255,255));//但是这句代码注释起来,还是显示黑色背景[/quote] 将兼容位图SelectObject到内存DC中去。
u0116snail 2013-09-02
  • 打赏
  • 举报
回复
[quotequote=引用 6 楼 VisualEleven 的回复:] HBITMAP hOldBitmap = (HBITMAP)memDC.SelectObject(&m_Bmp); [/quote]

按照您的提示, 我写成的双缓冲形式,但是,为什么我的背景是 黑色?
我还修改了一下这些地方:

m_MemDC.FillSolidRect(0,0,rt.Width(), rt.Height(),RGB(255,255,255));//但是这句代码注释起来,还是显示黑色背景
u0116snail 2013-09-02
  • 打赏
  • 举报
回复
另外,我还有 第二个疑问:

在对话框上有资源, 比如说 有个 Button 按钮, 我每次都是使用 InvalidateRect(NULL); 来定时刷新,这个按钮也会闪烁,这个该怎么办?

如何消除闪烁,让整个程序界面看上去不那么闪烁?
Eleven 2013-09-02
  • 打赏
  • 举报
回复
HBITMAP hOldBitmap = (HBITMAP)memDC.SelectObject(&m_Bmp);
u0116snail 2013-09-02
  • 打赏
  • 举报
回复
引用
双缓冲, OnEraseBkGnd 中直接返回 TRUE ,这必须要和 双缓冲一起使用吗?
u0116snail 2013-09-02
  • 打赏
  • 举报
回复
引用 3 楼 VisualEleven 的回复:
CPaintDC dc(this);
CDC memDC;
memDC.CreateCompatibleDC(dc);
CBitmap bmp;
bmp.CreateCompatibleBitmap(dc, ...);
memDC.SelectObject(...);
...
dc.BitBlt/StretchBlt(...,&memDC, ...SRCCOPY);
memDC.SelectObject(...);
bmp.DeleteObject();
memDC.DeleteDC();


还是有点问题: 我的对话框 的OnEraseBkGnd 中直接返回 TRUE, 对话框就什么都不显示了

我这么处理的,但是 没有效果,圆画不出来,文字也没有回执出来:

//== 初始化内存DC的相关要素 ,然后绘制图形====================================
CClientDC dc(this);
m_MemDC.CreateCompatibleDC(&dc);
CRect rt;
GetClientRect(&rt);
m_Bmp.CreateCompatibleBitmap(&dc, rt.Width(), rt.Height());
m_MemDC.FillSolidRect(0,0,rt.Width(), rt.Height(),RGB(0,255,0));//好像没起作用

PopEllipse(m_MemDC.GetSafeHdc(), &g_OffSet); //这里这么传递 hdc,有问题吗?


//==绘制圆==========================================
CBrush *pOldBrush = (CBrush*)m_MemDC.SelectStockObject(NULL_BRUSH);
CPen pen;
pen.CreatePen(PS_SOLID, 5, RGB(0,0,0));
m_MemDC.SelectObject(&pen);
m_MemDC.Ellipse(40, 40, 400, 400);


//==文字绘制部分===========================================
SetBkMode(m_MemDC.GetSafeHdc(), TRANSPARENT); //这里这么传递 hdc,有问题吗?
m_MemDC.SelectObject(&m_font);
CPen textPen;
textPen.CreatePen(PS_SOLID, 1, RGB(0,0,0));
m_MemDC.SelectObject(&textPen);
m_MemDC.TextOut(40, 410, "小狗嗷嗷叫");

//== 复制到屏幕上去 =======================================================
dc.BitBlt(0, 0, rt.Width(), rt.Height(), &m_MemDC, 0, 0, SRCCOPY);
m_Bmp.DeleteObject();
m_MemDC.DeleteDC();
Eleven 2013-09-02
  • 打赏
  • 举报
回复
引用 2 楼 u011642451 的回复:
像那种 需要传递一个 hdc 的函数,遇到这种情况,如何传递 hdc ?,这个 hdc 是传递谁的? 内存DC 的,还是屏幕DC 的?
CPaintDC dc(this);
CDC memDC;
memDC.CreateCompatibleDC(dc);
CBitmap bmp;
bmp.CreateCompatibleBitmap(dc, ...);
memDC.SelectObject(...);
...
dc.BitBlt/StretchBlt(...,&memDC, ...SRCCOPY);
memDC.SelectObject(...); 
bmp.DeleteObject();
memDC.DeleteDC();
u0116snail 2013-09-02
  • 打赏
  • 举报
回复
像那种 需要传递一个 hdc 的函数,遇到这种情况,如何传递 hdc ?,这个 hdc 是传递谁的? 内存DC 的,还是屏幕DC 的?
u0116snail 2013-09-02
  • 打赏
  • 举报
回复
在内存 DC 上绘制图形,我如何选取 那些 CPen、 CBrush、 CFont 等等?

15,979

社区成员

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

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