浅谈GDI编程正确方法

转载 2015年11月18日 21:47:36

本文不打算告诉大家什么叫GDI,各种GDI函数的作用是什么,有关详细的GDI知识可以去以下网站查看。http://www.panshy.com/articles/dev-66_3.html在这里只是让大家知道如何正确使用GDI,并且查找GDI资源占用问题,也就是类似C++中new完后不delete一样,会把系统资源消耗光,GDI资源也是有限的,消耗太多窗体会卡,还会伴有黑色的现象或者是别的窗体贴在本窗体上等效果。

原文地址:http://c.panshy.com/thread-4-1-1.html


首先让大家来看看一般GDI都有哪些函数,这里只列出贴图和双缓冲用得到的函数:

GetWindowDC 获取整个窗体的DC,包含标题栏这种非客区
GetDC获取窗体的客户区的DC,就是窗体能放控件的地方
CreateCompatibleDC 创建兼容DC
SelectObject选入某一GDI对象到DC中,返回DC中原有的对象
DeleteObject删除对象
ReleaseDC释放DC
DeleteDC删除DC
。。。。
以上函数CreateCompatibleDC与DeleteDC 一对、GetWindowDC - GetDC与ReleaseDC一对、SelectObject与DeleteObject一对
现在介绍以上函数正确使用方法,实例是将内存中的图片贴到窗体上,这里只列出伪代码
LONG lTemp;   
PAINTSTRUCT pai = {};   
BITMAPINFOHEADER BmihSuccess;   
BLENDFUNCTION Blend;   
LONG x = 0;   
RECT r;   
  
Blend.BlendOp = 0;   
Blend.BlendFlags = 0;   
Blend.AlphaFormat = AC_SRC_ALPHA;   
Blend.SourceConstantAlpha = 255;   
  
::BeginPaint(m_hWnd, &pai);   
  
DWORD dwExStyle = ::GetWindowLong(m_hWnd, GWL_EXSTYLE);   
if ((dwExStyle & 0x80000) != 0x80000)   
{   
    ::SetWindowLong(m_hWnd, GWL_EXSTYLE, dwExStyle ^ 0x80000);   
}   
  
CRect rcWindow;   
::GetWindowRect(m_hWnd, &rcWindow);   
  //以上代表不用管,看不懂不要紧

HDC hdcTemp = ::GetWindowDC(m_hWnd);   //创建窗体DC,包含标题栏,菜单栏
HDC hdcMemory = ::CreateCompatibleDC(hdcTemp);   //内存DC,兼容窗体的DC
  
ZeroMemory(&BmihSuccess, sizeof(BITMAPINFO));   
  
BmihSuccess.biSize = sizeof (BITMAPINFOHEADER) ;   
BmihSuccess.biWidth = rcWindow.Width() ;   
BmihSuccess.biHeight = rcWindow.Height();   
BmihSuccess.biPlanes = 1 ;   
BmihSuccess.biBitCount = 32;   
BmihSuccess.biCompression = BI_RGB ;   
BmihSuccess.biSizeImage = 0 ;   
BmihSuccess.biXPelsPerMeter = 0 ;   
BmihSuccess.biYPelsPerMeter = 0 ;   
BmihSuccess.biClrUsed = 0 ;   
BmihSuccess.biClrImportant = 0 ;   
  
HBITMAP hBitMap = ::CreateDIBSection(hdcTemp,   
        (BITMAPINFO *)&BmihSuccess, 0, NULL, NULL, 0) ;  //创建一个GDI对象
HGDIOBJ oldObj = ::SelectObject(hdcMemory, hBitMap);   //将GDI对象选入DC
  ////////////////////////////////////////////////////////////////////////////////////
Gdiplus::Graphics gph(hdcMemory);   
  
    Gdiplus::Bitmap *m_pImgLeft;   
_pImgLeft = new Bitmap(_T("c:\\Login_msg_left1.png"));   
if(m_pImgLeft != NULL)   
    {   
        gph.DrawImage(m_pImgLeft, 0, 0,   
            m_pImgLeft->GetWidth(), m_pImgLeft->GetHeight());   
    }   
  
:UpdateLayeredWindow(m_hWnd, hdcTemp,   
    &CPoint(rcWindow.left, rcWindow.top),   
    &CSize(rcWindow.Width(), rcWindow.Height()),   
    hdcMemory, &CPoint(0, 0), 0, &Blend, ULW_ALPHA);   
  /////////以上圈起来的代码不用管//////////////////////////////////////////
以下是重点,是释放GDI资源的重点,顺序是选回旧的GDI对象,删除创建的GDI对象,删除DC
::SelectObject(hdcMemory, oldObj);   
::DeleteObject(hBitMap);   
::ReleaseDC(m_hWnd, hdcTemp);   
::DeleteDC(hdcMemory);   
::EndPaint(m_hWnd, &pai);

好了上面说了如何正确使用GDI的方法了,其实就是释放GDI资源顺序,那么如何查看GDI占用情况呢,现在和大家说一下
打开任务栏管理器,选中进程那一个选项卡,点菜单中的查看-》选择列 子菜单,找到GDI对象

确定后在进程列表就能看到

如果是窗体使用GDI,只要把窗体不断放大缩小,就能查看到GDI的使用情况,如果没有正确释放会,你会发现GDI对象数值一直在涨。
好了,今天就说到这呢,有不懂的,可以回复问我。

相关文章推荐

浅谈C语言嵌入式编程的若干性能优化方法

原作者:宋宝华 (yesky.com) 使用宏定义   在C语言中,宏是产生内嵌代码的唯一方法。对于嵌入式系统而言,为了能达到性能要求,宏是一种很好的代替函数的方法。   写一个"标准"...

浅谈如何在android studio上正确使用svn?

第一安装Tortoise要特别注意,默认是不安装command line...这个功能的,我们需要手动选择安装该功能。如下图所示: 注意:如果不安装command line功能在配置svn时将找不...

浅谈正确理解数据库架构以及标准化操作之重要性

原文:http://www.zoomla.cn/blog/965.shtml   情景展现: 某夜小熊跑到Q上:呼叫发哥,呼叫发哥,我按逐浪官网的操作,建了一个标签,可怎么也调不出数据,怎么办?...

浅谈3DSMAX建模方法

  • 2013-05-11 16:03
  • 63KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)