Windows GDI:CDC使用总结
来源:互联网 发布:linux大学时候开发 编辑:程序博客网 时间:2024/05/29 04:38
一、DC函数的配对使用
GetDC — ReleaseDC
GetWindowDC — ReleaseDC
CreateDC — DeleteDC
二、GetDC与GetWindowDC
1、HDC GetDC(HWND hWnd)
int ReleaseDC(HWND hWnd,
HDC hDC);
2、HDC GetWindowDC(HWND hWnd);
int ReleaseDC(HWND hWnd,
HDC hDC);
通过GetDC与GetWindowDC获取HDC,使用完毕之后均需ReleaseDC,否则会有资源泄露
GetDC与GetWindowDC的区别是:
GetDC获取的是客户区的DC
GetWindowDC获取的是the device context (DC) for the entire window,包括非客户区
怎样获取整个屏幕的DC?
GetDC(NULL)
GetWindowDC(NULL)
二、CDC
CDC:
class CDC : public CObject{public:HDC m_hDC;public:BOOL Attach(HDC hDC);HDC Detach();static CDC* PASCAL FromHandle(HDC hDC);static void PASCAL DeleteTempMap();}
1、先看一下析构函数
CDC::~CDC(){if (m_hDC != NULL)::DeleteDC(Detach());}
很显然,在析构函数中先Detach()了,再DeleteDC了
2、再看一下Attach与Detach
Attach在于将HDC与CDC的对象关联起来,并且在Map表中创建一条记录
BOOL CDC::Attach(HDC hDC){ if (hDC == NULL) { return FALSE; } m_hDC = hDC; CHandleMap* pMap = afxMapHDC(TRUE); // create map if not exist pMap->SetPermanent(m_hDC, this); return TRUE;}
Detach在于将HDC与CDC的对象去除关联,当然会在Map表中删除这条记录
HDC CDC::Detach(){ HDC hDC = m_hDC; if (hDC != NULL) { CHandleMap* pMap = afxMapHDC(); // don't create if not exist if (pMap != NULL) pMap->RemoveHandle(m_hDC); } m_hDC = NULL; return hDC;}
3、CDC* FromHandle(HDC hDC)
在CDC<>HDC的Map表中查找hDC对应的CDC
CDC* PASCAL CDC::FromHandle(HDC hDC){ CHandleMap* pMap = afxMapHDC(TRUE); //create map if not exist CDC* pDC = (CDC*)pMap->FromHandle(hDC); return pDC;}
Note:如果在CDC<>HDC的Map表中没有找到hDC相关的记录,系统会创建一个临时的CDC.
此时,不用我们delete了,系统会用空闲线程处理.不必深究,知道就可以了.
由于CDC的析构函数调用的是DeleteDC,所以CDC一般用来接收CreateDC得到的HDC.
或者也可以这样用,先Attach不是用CreateDC获取的HDC,再Detach,这样就不会DeleteDC了.
CClientDC的析构函数调用的是ReleaseDC
CPaintDC的析构函数调用的是EndPaint
4、DeleteTempMap
Called automatically by the CWinApp idle-time handler, DeleteTempMap deletes any temporary CDC objects created by FromHandle,
but does not destroy the device context handles (hDCs) temporarily associated with the CDC objects.
5、CDC::SelectObject()
CPen* SelectObject( CPen* pPen);CBrush* SelectObject( CBrush* pBrush);...CPen* CDC::SelectObject(CPen* pPen){ HGDIOBJ hOldObj = NULL; if (m_hDC != m_hAttribDC) hOldObj = ::SelectObject(m_hDC, pPen->GetSafeHandle()); if (m_hAttribDC != NULL) hOldObj = ::SelectObject(m_hAttribDC, pPen->GetSafeHandle()); return (CPen*)CGdiObject::FromHandle(hOldObj);}
SelectObject返回的CPen*为CGdiObject::FromHandle获取的
假若这里通过CGdiObject::FromHandle得到的是临时创建的CPen*
由于CGdiObject::DeleteTempMap也不会DeleteObject掉临时CGdiObject关联的HGDIOBJECT
所以,这种机制才保证了代码的正确性:
CDC dc;dc.CreateDC(...)CPen pen;pen.CreatePen(...)CPen* pOldPen = dc.SelectObject(&pen);...dc.SelectObject(pOldPen);
三、CClientDC
CClientDC:
class CClientDC : public CDC{protected: HWND m_hWnd;}
1、先看一下构造与析构函数
CClientDC::CClientDC(CWnd* pWnd){ Attach(::GetDC(m_hWnd = pWnd->GetSafeHwnd()));}CClientDC::~CClientDC(){ ::ReleaseDC(m_hWnd, Detach());}
2、CClientDC在MFC对话框中的常用用法
CCientDC dc(this);
dc.执行操作
四、CPaintDC
CPaintDC:
class CPaintDC : public CDC{protected: HWND m_hWnd;}
1、先看一下构造与析构函数
CPaintDC::CPaintDC(CWnd* pWnd){ Attach(::BeginPaint(m_hWnd = pWnd->m_hWnd, &m_ps));}CPaintDC::~CPaintDC(){ ::EndPaint(m_hWnd, &m_ps); Detach();}
- Windows GDI:CDC使用总结
- Windows GDI:CDC绘制文本
- Windows GDI:CDC绘制矩形
- Windows GDI:CDC绘制ICON
- Windows GDI:CDC绘制Bitmap
- Windows GDI:CGdiObject使用总结
- GDI CDC
- Windows GDI:画刷Brush使用总结
- Windows GDI:字体Font使用总结
- Windows GDI:画笔Pen使用总结
- Windows Gdi & CDC和HDC的区别与转换
- Windows Gdi & CDC和HDC的区别与转换
- Windows Gdi & CDC和HDC的区别与转换
- GDI与CDC
- GDI和CDC是什么
- GDI和CDC区别
- windows 使用GDI+
- Windows GDI使用【学习笔记】
- POJ 2186 Popular Cows 强连通
- 初识GestureDetector
- “进程球”通过数据库来通信------好美的一幅图!
- BroadcastReceiver的生命周期:保存在Receiver中的static变量为什么老为空
- 黑马程序员(九) 异常及常见异常总结
- Windows GDI:CDC使用总结
- C++浅析——继承类中构造和析构顺序
- Java利用Callable、Future进行并行计算求和
- Windows GDI:CDC绘制文本
- Android数据库Sqlite-android学习之旅(九)
- POJ - 1987 Distance Statistics 树上的分治
- jquerymobile1.3.2和jquery.mobile-1.4.5遇到的问题
- hdu 2011 多项式求和(java)
- 一起学习CC3200系列教程之CC3200简介