微软喜欢将内核对象标识,称为句柄。应该都是32位或者64位整数
HINSTANCE: 进程实例或者句柄
HANDLE: 文件句柄
HWND: 窗口的句柄,用来标识窗口对象
HPEN: 画笔句柄,用来标识画笔对象
HBITMAP: 位图句柄
HDC: 设备环境句柄
CWnd: 是提供窗口处理的一个MFC封装基类,
一般都和一个窗口句柄HWND绑定,有HWND m_hWnd成员
CDC: 是进行设备环境处理的一个MFC封装类,
一般都和一个设备环境句柄HDC绑定,有HDC m_hDC
句柄和类可以相互构造:
1.从已知句柄构造设备类
假定知道了hDC或者hBitmap,想构造CDC类进行窗口操作。
1.1 临时使用,用完不用删除
CDC *pDC = CDC::FromHandle(hDC); //MFC不保证什么时候删除DC
CBitmap *pBmp = CBitmap::FromHandle(hBitmap)
1.2 永久使用,用完需要删除GDI对象一定要释放内存并删除对象
CDC dc;
dc.Attach(hDC); //窗口绑定,永久的,一直到你删除它
//..........//
dc.Detach(hDC); //当不用的时候要销毁
2.从类得到句柄
CDC dc;
HDC hDC;
hDC = dc.GetSafeHdc();
CDC是进行设备环境处理的类,GDI和GDI+显示类库需要这个设备显示对象(包括图像,画笔,线条,画刷等)
CDC类下面有4个子类
1. CPaintDC
// For drawing in a window’s client area(OnPaint handles only)
在构造时自动调用CWnd::BeginPaint,
析构时调用CWnd::EndPaint。
通常 CPaintDC用来响应WM_PAINT消息。一般应用在OnPaint函数。窗口在很多时候能被绘制或重新绘制,如在窗口创建、大小变更、从其他窗口后面移出窗口、最大或最小化等的时候。在窗口内容因某项操作改变时,系统将向程序发出WM_PAINT消息,通知程序作出相应的绘制工作
2. CClientDC
//For drawing in a window’s client area(anywhere but OnPain)
客户区窗口DC
构造时自动调用GetDC函数,
析构时自动调用ReleaseDC函数.一般应用于客户区窗口的绘制
当需要处理一个鼠标的单击,然后马上画出一个圆,你不能等到下一个WM_PAINT的消息到来才画图,而是马上,这是就需要CclientDC了。它可以在OnPaint的外面创建一个客户区域DC
void CMainWindow::OnLButtonDown (UINT nFlags, CPoint point)
{
CRect rect;
GetClientRect (&rect);
CClientDC dc (this);
dc.MoveTo (rect.left, rect.top);
dc.LineTo (rect.right, rect.bottom);
dc.MoveTo (rect.right, rect.top);
dc.LineTo (rect.left, rect.bottom);
}
3. CWindowDC
//For drawing anywhere in a window, including the nonclient area
不仅是客户区,还包括窗口客户区以外的部分(如窗口标题栏、菜单栏等)需要需要重画时,系统向程序发出WM_NCPAINT消息。因标准窗口的客户区以外部分为窗口必需部分,因而WM_NCPAINT消息将默认被发送到DefWindowProc函数进行默认处理。程序可通过截获该消息来实现窗口其他部分的自定义绘制。使用的是CWindowDC
4. CMetaFileDC //For drawing to a GDI metafile
上面这4个子类由于构造和析构函数在获取和释放DC的时候会调用合适的函数,所以可以直接使用,不用释放DC,而CDC就要释放资源RealseDC()
如果想在整个屏幕绘制时,可以创建一个CclientDC或CwindowDC对象,然后给他的构造函数传递一个NULL指针。如下:
CClientDC dc(NULL);
dc.Ellipse(0,0,100,100);
实例1:
HWND hWnd;
hWnd = ::GetTopWindow(NULL);
hWnd = ::GetSafeHwnd();
实例2:
void draw()
{
CWnd* pWnd = GetDlgItem(IDC_PICTURE); // 获取绘图的标签
CDC* pDC = pWnd->GetDC(); //获取设备上下文
int nOldDrawMode = pDC->SetROP2(R2_XORPEN); //设置绘制方式为异或模式
pDC->SetBkMode(TRANSPARENT);
pDC->MoveTo(,);
....
pWnd->ReleaseDC(pDC)
//注:CreateDC() 对应 DeleteDC() 都是CDC类的函数
//注:GetDC() 对应 ReleaseDC() 都是CWnd类的函数
}
CDC是MFC的DC的一个类
HDC是DC的句柄,API中的一个类似指针的数据类型.
MFC类的前缀都是C开头的
H开头的大多数是句柄
这是为了助记,是编程读\写代码的好的习惯.
CDC中所有MFC的DC的基类.常用的CClientDC dc(this);就是CDC的子类(或称派生类).
CDC等设备上下分类,都含有一个类的成员变量:m_nHdc;即HDC类型的句柄.
记住下面的一句话,会有助于你的理解.
MFC的类,是在用window API语句开发出来的有一定功能的小程序.(也可称为类).使用它的默认方法,就是,记住它的名字与参数(可以用笔记,代替脑记).
如果将window api比做汇编语言
那么MFC就相当于Basic语言.
cdc是设备描述表的基类,clientDC指代客户区的设备描述表,PaintDC只用于OnPaint()函数中
CDC是MFC的DC的一个类
HDC是DC的句柄,API中的一个类似指针的数据类型.
MFC类的前缀都是C开头的
H开头的大多数是句柄
这是为了助记,是编程读\写代码的好的习惯.
CDC中所有MFC的DC的基类.常用的CClientDC dc(this);就是CDC的子类(或称派生类).
CDC等设备上下分类,都含有一个类的成员变量:m_nHdc;即HDC类型的句柄.
记住下面的一句话,会有助于你的理解.
MFC的类,是在用window API语句开发出来的有一定功能的小程序.(也可称为类).使用它的默认方法,就是,记住它的名字与参数(可以用笔记,代替脑记).
如果将window api比做汇编语言
那么MFC就相当于Basic语言.
HDC是WINDOWS的一种数据类型,是设备描述句柄。
而CDC是MFC里的一个类,它封装了几乎所有的关于
HDC的操作。
也可以这样说,HDC定义的变量指向一块内存,这块
内存用来描述一个设备的相关的内容,所以也可以
认为HDC定义的是一个指针;而CDC类定义一个对象,
这个对象拥有HDC定义的一个设备描述表,同时也包
含与HDC相关的操作的函数。
这与HPEN和CPen,POINT与CPoint之间的差别是一样
的。
CDC 到HDC 的转化:
2007-05-09 12:04
方法一: 此方法在设备结束时不会销毁原来的资源(即:hDC,hBitmap)
CDC *pDC = CDC::FromHandle(hDC);
CBitmap *pBitmap = CBitmap::FromHandle(hBitmap);
方法二: 此方法在设备结束时会销毁原来的资源(即:hDC,hBitmap)
CDC dc;
dc.Attach(hDC);
CBitmap bit;
bit.Attach(hBitmap);
在结束的时候加dc.detach()也不会销毁原来资源
HDC hdc;
CDC cdc;
cdc到hdc
hdc = cdc.GetSafeHdc();
hdc到cdc
cdc.Attach(hdc);