一、CDC是Windows绘图设备的基类。
CClientDC:
(1)(客户区设备上下文)用于客户区的输出,与特定窗口关联,可以让开发者访问目标窗口中客户区,其构造函数中包含了GetDC,析构函数中包含了ReleaseDC。
CPaintDC:
(1)用于响应窗口重绘消息(WM_PAINT)是的绘图输出。
(2)CPaintDC在构造函数中调用BeginPaint()取得设备上下文,在析构函数中调用EndPaint()释放设备上下文。EndPaint()除了释放设备上下文外,还负责从消息队列中清除WM_PAINT消息。因此,在处理窗口重画时,必须使用CPaintDC,否则WM_PAINT消息无法从消息队列中清除,将引起不断的窗口重画。
(3)CPaintDC也只能用在WM_PAINT消息处理之中。
CWindowDC:
(1)可在非客户区绘制图形,而CClientDC,CPaintDC只能在客户区绘制图形。
(2)坐标原点是在屏幕的左上角,CClientDC,CPaintDC下坐标原点是在客户区的左上角。
(3)关联一特定窗口,允许开发者在目标窗口的任何一部分进行绘图,包含边界与标题,这种DC同WM_NCPAINT消息一起发送。
说明:在绘图时推荐使用CClientDC,CPaintDC和CWindowDC对象,而不推荐直接使用CDC对象。
建立项目,采用单文档结构
HDC:
首先在CYourClassView类中add windows message handler, 一个是LButtonDown, 另一个是LButtonUp. 添加成员变量:m_ptOrigin用来记录初始点位置。
在view结构体中初始化m_ptOrigin变量:
CYourClassView:: CYourClassView ()
{
// TODO: add construction code here
m_ptOrigin=0;
}
在LButtonDown函数里面添加代码:
void CYourClassView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
m_ptOrigin=point;
CView::OnLButtonDown(nFlags, point);
}
在LButtonUp中添加代码,首先使用HDC:
void CYourClassView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
HDC hdc;
hdc=::GetWindowDC(m_hWnd);
MoveToEx(hdc,m_ptOrigin.x,m_ptOrigin.y,NULL);
LineTo(hdc,point.x,point.y);
::ReleaseDC(m_hWnd,hdc);
CView::OnLButtonUp(nFlags, point);
}
使用CDC:
void CYourClassView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CDC *pdc=GetDC();
pdc->MoveTo(m_ptOrigin);
pdc->LineTo(point);
ReleaseDC(pdc);
CView::OnLButtonUp(nFlags, point);
}
使用CClientDC:
void CYourClassView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CClientDC dc(this);
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);
CView::OnLButtonUp(nFlags, point);
}
使用CWindowDC:
void CYourClassView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CWindowDC dc(this);
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);
CView::OnLButtonUp(nFlags, point);
}
二、
HDC是句柄,CDC是MFC封装的windows设备相关的一个类,clientDC是CDC的一个衍生类,产生于对应windows客户区的对象。 pDC是类指针,HDC是windows句柄,通过pDC获得hDC hDC=pDC->getsafeDC(),通过hdc获得pDC,CDC *pDC=new CDC(); CreateCompatibleDC 假如你要对屏幕进行比较多的gdi函数操作,如果每一步操作都直接对屏幕dc进行操作,那出现的大多数可能性都是屏幕的闪烁。一个很好的解决方法就是使用内存dc,将这些操作全部先在内存dc上操作,然后依次性在屏幕上进行操作。
1 先获取客户区hdc,hScrDC=getdc()函数。 然后为屏幕设备表创建一个兼容的内存设备描述表 hMemDC = CreateCompatibleDC(hScrDC);
创建一个内存Bitmap,然后把他SelectObject到内存DC中去
物理HDC 设备底层会拥有显存等资源,但是兼容DC并没有给图像像素提供内存空间,因此兼容DC总是和BITMAP配合使用,这样一来,兼容DC就利用BITMAP的图像像素数据空间给自己提供类似于显存的内存空间. 这样有很多好处,以来我们可以在加载图片后,在图片上利用DC的各种绘图功能.请看如下示例: 兼容DC在建立之初,只有1*1像素的尺寸,SelectObject选择bitmap以后才可以进行绘图. 内存DC的可见区域是简单的区域,不像物理DC可见区域可能被其他窗口覆盖而产生复杂的可见区域.由于DC的任何绘图都需要考虑在可见区域内绘图,绝对不能超出可见区域的范围.因此每个GDI绘图输出最终都需要和构成复杂可见区域的每一个巨型区域进行剪裁输出,因此物理DC的绘图效果会比兼容DC速度慢一些.这也就是我们经常用兼容DC进行双缓存输出的一个原因
|