`

关于MFC使用GDI绘图的两个容易出错的问题

阅读更多
原帖地址:http://www.cnblogs.com/lijianglidedaxia/archive/2013/06/01/3113213.html

  近期,公司的一个项目是采用华迈SDK来做一套C/S架构的监控中心。自己犯了两个低级错误,写出来看看有多少朋友平时跟我一样没注意,哈哈。


  第一个错误是这样出现的:在最初的几个版本中比较顺利。于是有点飘飘然,连续提交了好几个版本都没有进行全面测试。直到一个完成得差不多的版本出现后,来了一次全面的测试。这个时候发现,居然主界面显示不正常。找了好久原因没找到,只好回退到之前最初几个正常的版本,然后建立了个分支专门来排除此问题。一个一个版本的合并,一个一个文件的差异对比,最终定位到一个版本中原来把CXXX::OnPaint()中的CPaintDC dc(this);写成了CClientDC dc(this);


  下面是错误分析。


  《Windows 程序设计》里曾经说过,在WM_PAINT中一定要成对使用BeginPaint跟EndPaint。否则程序会不停产生WM_PAINT消息。而MFC的CPaintDC的构造与析构中封装了BeginPaint及EndPaint。而CClientDC则没有,所以在OnPaint中使用CClientDC当然是不行的。惭愧啊,惭愧。一时疏忽浪费我整整一个下午找这个BUG。


  第二个错误更加惭愧了。直接看码:


  



void CDxHMContainer::OnPaint()
{
CPaintDC dc(
this);
for (UINT i = 0; i < m_vecChilds.size();i++)
{
if (m_vecChilds[i]->IsSelect())
{

CRect rt;
CPen aNewPen,
*pOldPen;
int nOldRop = dc.SetROP2(R2_NOTXORPEN);
m_vecChilds[i]
->GetClientRect(rt);
rt.InflateRect(
2,2);
m_vecChilds[i]
->ClientToScreen(rt);
this->ScreenToClient(rt);

aNewPen.CreatePen(PS_SOLID,
3,m_colorFrame);
pOldPen
= (CPen*)dc.SelectObject(aNewPen);
dc.Rectangle(rt);
dc.SelectObject(pOldPen);
// 这里报错
dc.SetROP2(nOldRop);
}
}
}


 


  这段代码很诡异,有时候运行个两三个小时不会出错,有时候三五分钟就出错。请先不要着急看下面的错误分析,你能看出这段代码有什么问题吗?


  当初这段代码报错,说实话我一时半会还真没找到原因。最后看MSDN的关于CDC::SelectObject的相关文档,才终于找到原因。


  CDC::SelectObject重载了很多种方法。上面代码出错的原因是第一次调用使用的的函数原型是 HGDIOBJ CDC::SelectObject(HGDIOBJ),


而第二次使用的函数原型确是 CBitmap* CDC::SelectObject(CBitmap*)。对于上述代码第一次调用的时候,将HGDIOBJ强行转成CBitmap*实在有点惨不忍睹啊。。。。。。如此,便导致了悲催的崩溃。


  

本文链接

分享到:
评论

相关推荐

    MFC_GDI绘图基础.rar_GDI绘图_GDI绘图 MFC_gdi_mfc绘图_绘图

    在Windows编程领域,MFC(Microsoft Foundation Classes)和GDI(Graphics Device Interface)是两个重要的概念,它们在创建图形用户界面和实现复杂绘图功能时起着关键作用。本资源"**MFC_GDI绘图基础.rar**"显然是...

    MFC的GDI绘图(TCS~T)

    本文将深入探讨MFC与GDI的结合使用,以及如何在MFC应用中进行绘图操作。 首先,了解MFC的窗口类——`CWnd`,它是所有MFC窗口对象的基础。`CWnd`派生自`CObject`,并提供了与Windows窗口相关的各种功能,包括处理...

    MFC程序设计详细实例 第13章 MFC GDI与绘图

    MFC程序设计详细实例 第13章 MFC GDI与绘图MFC程序设计详细实例 第13章 MFC GDI与绘图MFC程序设计详细实例 第13章 MFC GDI与绘图MFC程序设计详细实例 第13章 MFC GDI与绘图MFC程序设计详细实例 第13章 MFC GDI与绘图...

    MFC中的GDI绘图

    MFC中的GDI绘图涉及到Windows编程中的图形设备接口(GDI)和设备环境(DC)的概念,以及MFC框架中对这些概念的封装和支持。GDI是Windows操作系统提供的一种接口,允许开发者创建图形和文本,将其绘制在屏幕上或者...

    MFC-GDI交互绘图

    综上所述,"MFC-GDI交互绘图"涉及的是如何在MFC应用程序中使用GDI进行图形绘制,并解决可能出现的填充模式问题。通过深入理解GDI的填充规则、路径构造和设备上下文管理,以及对源代码的仔细分析和调试,我们可以找到...

    mfc中gdi绘图

    本文将深入探讨如何在MFC应用中使用GDI进行绘图,并涵盖画直线、矩形和椭圆等基本操作,同时讲解如何优化避免闪烁,以及在窗口重绘时保持图形的可见性。 首先,我们要了解GDI绘图的基本步骤。在MFC中,通常是在...

    MFC GDI绘图基础

    当你需要在窗口的客户区域内进行绘图,而这个绘图操作并非响应 WM_PAINT 消息时,可以使用 CClientDC。 (3)CWindowDC 类与 CClientDC 类类似,但它的设备环境包含了整个窗口,包括边框和标题栏。如果你需要对整个...

    MFC GDI多线程绘图

    在多线程环境下使用GDI需要注意线程安全问题,因为多个线程可能同时访问GDI资源,如画刷、字体、位图等,这可能导致数据冲突和意外的行为。 1. **创建多线程**: - 在MFC中,你可以通过派生自`CWinThread`的类来...

    mfc GDI绘图的小例子

    在这个"mfc GDI绘图的小例子"中,我们主要关注两个关键的MFC消息处理函数:`OnMouseMove`和`OnLButtonDown`。这两个函数是Windows消息机制的一部分,用于处理用户的鼠标操作。 1. `OnMouseMove`函数:当鼠标在窗口...

    MFC使用GDI+双缓存绘图

    总结,通过上述步骤,我们可以在MFC中使用GDI+双缓存技术来提升绘图效率,避免因频繁重绘导致的屏幕闪烁。这种方法尤其适用于需要频繁更新的复杂用户界面元素,如图表、动画等。在实际开发中,可以根据需求调整绘图...

    MFC使用GDI+双缓存画图

    在提供的压缩包文件“AClock”中,很可能包含了一个使用MFC和GDI+实现的时钟应用示例。这个应用可能通过定时器事件不断更新时钟指针的位置,每次更新时,都会利用双缓存技术先在内存中重新绘制时钟,然后再显示到...

    mfc 使用gdi画图、打开图片、保存图片

    通过以上步骤,你可以使用MFC和GDI实现一个基本的图像处理程序,包括画图、加载和保存图片。不过,实际开发中可能还需要处理更多的细节,如错误处理、用户交互和界面设计等。不断学习和实践,才能更好地掌握MFC和GDI...

    MFC GDI与绘图

    MFC通过封装GDI的函数和结构体,提供了一系列易于使用的C++类,如CDC(Device Context)、CBrush、CPen、CFont等,使得开发者能够更方便地进行图形操作。CDC类代表设备上下文,它是GDI的主要接口,可以用于控制绘图...

    基于GDI的MFC绘图工具

    本项目“基于GDI的MFC绘图工具”结合了这两者,创建了一个高效且用户体验良好的绘图应用。 1. **GDI基础** GDI允许程序员通过编程的方式控制屏幕上的图形元素,包括线条、曲线、形状、文本和图像。它提供了一系列...

    GDI绘图性能与效率的提高及改善

    总结来说,这些文档涵盖了GDI绘图的多个关键方面,从性能优化到高效绘图,再到几何测量和图元变换。通过学习和实践这些技术,开发者能够提升其应用程序的图形性能,降低资源消耗,从而提供更流畅、更高效的用户体验...

    MFC使用GDI+编程设置

    MFC 使用 GDI+ 编程设置 MFC 中使用 GDI+ 编程需要进行相应的设置,包括在项目属性中添加 GdiPlus.lib 库、在应用程序类中声明成员变量、初始化 GDI+、在需要使用 GDI+ 的文件头中包含 Gdiplus.h 头文件,以及在...

    MFC基于对话框GDI+简单绘图

    在本文中,我们将深入探讨如何在MFC(Microsoft Foundation Classes)框架下,基于对话框使用GDI+进行简单绘图。MFC是微软提供的一种C++库,它为Windows应用程序开发提供了一种结构化的方式。GDI+是Windows图形设备...

    MFC 写的基于GDI绘图 用到双缓冲

    在Windows编程领域,MFC(Microsoft Foundation Classes)是一个C++库,它提供了对Windows API的封装,使得开发者能够更容易地创建Windows应用程序。本项目利用MFC编写了一个基于GDI(Graphics Device Interface)的...

Global site tag (gtag.js) - Google Analytics