①、对整个屏幕截图:
void GetScreenCapture(LPCTSTR lpszSavePath)
{
ASSERT(lpszSavePath);
int screenWidth = GetSystemMetrics(SM_CXSCREEN);
int screenHeight = GetSystemMetrics(SM_CYSCREEN);
CDC *pDC = CDC::FromHandle(::GetDC(NULL));
CDC memDc;
memDc.CreateCompatibleDC(pDC);
CBitmap mBmp, *pOldBmp = NULL;
mBmp.CreateCompatibleBitmap(pDC, screenWidth, screenHeight);
pOldBmp = memDc.SelectObject(&mBmp);
memDc.BitBlt(0, 0, screenWidth, screenHeight, pDC, 0, 0, SRCCOPY);
CImage img;
img.Attach(mBmp);
img.Save(lpszSavePath);
memDc.SelectObject(pOldBmp);
::ReleaseDC(NULL, pDC->m_hDC);
}
===================================================
②、对指定窗口截图:
void GetWndCapture(HWND hTargetWnd, LPCTSTR lpszSavePath)
{
ASSERT(lpszSavePath);
CRect mRect;
GetWindowRect(hTargetWnd, &mRect);
CDC *pDC = CDC::FromHandle(::GetDC(hTargetWnd));
CDC memDc;
memDc.CreateCompatibleDC(pDC);
CBitmap mBmp, *pOldBmp = NULL;
mBmp.CreateCompatibleBitmap(pDC, mRect.Width(), mRect.Height());
pOldBmp = memDc.SelectObject(&mBmp);
memDc.BitBlt(0, 0, mRect.Width(), mRect.Height(), pDC, 0, 0, SRCCOPY);
CImage img;
img.Attach(mBmp);
img.Save(lpszSavePath);
memDc.SelectObject(pOldBmp);
::ReleaseDC(NULL, pDC->m_hDC);
}
===================================================
③、CDC、CClientDC、CPaintDC、CWindowDC 等设备描述表的区别:
CDC是Windows绘图设备的基类,其他相关DC都是其派生类,具体见MSDN类的结构图!
(1)在 Windows 中,显示工作是基于设备环境的。所谓设备环境(DC)是一种 Windows 数据结构,该结构包含应用程序设备输出时所需要的信息;
(2)在使用任何绘图函数之前必须建立一个设备环境对象;
(3)在 Visual C++ 的MFC中提供了设备环境类CDC,它封装了绘图所需要的所有函数,其中包括了大多数的 Windows API 中的 GDI 函数:包括画圆、画线、写字、改变文字的颜色、字体等等……
CClientDC 类:
CClientDC类也是CDC类的派生类。它只能在窗口的客户区(即窗口中除了边框、标题栏、菜单栏以及状态栏外的中间部分)中进行绘图,坐标点(0,0)通常指的是客户区的左上角。
它的构造函数调用GetDC函数,而析构函数调用ReleaseDC函数。
CClientDC(客户区设备上下文)用于客户区的输出,它在构造函数中封装了GetDC(),在析构函数中封装了ReleaseDC()函数。一般在响应非窗口重画消息(如键盘输入时绘制文本、鼠标绘图)绘图时要用到它。用法是:
CClientDC dc(this); //this一般指向本窗口或当前活动视图
dc.TextOut(10,10,str,str.GetLength());
//利用dc输出文本,如果是在CScrollView中使用,还要注意调用OnPrepareDC(&dc)调整设备上下文的坐标。
CPaintDC 类:
(1)CPaintDC类是CDC类的一个派生类,该类一般用在响应WM_PAINT消息的函数OnPaint()中;
(2)WM_PAINT消息是当窗口的某个区域需要重画时激发的窗口消息。当程序中的消息循环接到WM_PAINT消息时就自动调用消息处理函数OnPaint(),如果在OnPaint函数内定义了CPaintDC类的对象,通过这个类对象就可以使用CDC类的成员函数完成视图客户区中的图形绘制操作;
(3)CPaintDC用于响应窗口重绘消息(WM_PAINT)时的绘图输出。CPaintDC在构造函数中调用BeginPaint()取得设备上下文,在析构函数中调用EndPaint()释放设备上下文。EndPaint()除了释放设备上下文外,还负责从消息队列中清除WM_PAINT消息。因此,在处理窗口重画时,必须使用CPaintDC,否则WM_PAINT消息无法从消息队列中清除,将引起不断的窗口重画。CPaintDC也只能用在WM_PAINT消息处理之中。
CWindowDC 类:
(1)CWindowDC类也是CDC类的派生类。其成员函数可以在窗口的客户区和非客户区(即窗口的边框、标题栏、菜单栏以及状态栏)中绘图,坐标点(0, 0)是指整个窗口的左上角。
而 CClientDC,CPaintDC 只能在客户区绘制图形;
(2)坐标原点是在窗口的左上角,CClientDC,CPaintDC 下坐标原点是在客户区的左上角;
(3)同CClientDC类一样,它的构造函数调用GetDC函数,而析构函数调用ReleaseDC函数;
(4)关联一特定窗口,允许开发者在目标窗口的任何一部分进行绘图,包含边界与标题,这种 DC 同 WM_NCPAINT 消息一起发送。
〓〓〓 注:在绘图时推荐使用 CClientDC、CPaintDC 和 CWindowDC 对象,而不推荐直接使用CDC对象!
CMetaFileDC 类
CMetaFileDC 类提供了一个面向Windows图元文件的设备环境,封装了在一个Windows图元文件中绘图的方法。
图元文件是一个与设备无关的图片的集合,由于它对图像的保存比像素更精确,因而往往在要求较高的场合下使用,例如:AutoCAD的图形保存等。
实例:
CClientDC dc(this); //this一般指向本窗口或当前活动视图
dc.TextOut(10, 0, str, str.GetLength());
CClientDC *pDC = new CClientDC(this);
CWindowDC dc(this);
===================================================
④、几个设备环境类的主要差别:
CWindowDC 类与 CPaintDC 、CClientDC 类的区别主要有以下两个方面:
(1)用 CPaintDC 和 CClientDC 类的对象绘制图形时,绘制区只能在客户区,而不能在非客户区;而CWindowDC 类既可以在窗口的客户区也可以在非客户区进行图形绘制。
(2)在CWindowDC 绘图类下,坐标系是建立在整个窗口上的,在像素坐标方式下,坐标原点在整个窗口的左上角;
而在 CPaintDC 和 CClientDC 绘图类下,坐标系是建立在客户区上的,在像素坐标方式下,坐标原点在客户区的左上角。
CPaintDC 类与 CClientDC 类的区别:
CPaintDC 类的对象应用在 OnPaint 函数中,以响应 Windows 的 WM_PAINT 消息;而 CClientDC 类的对象应用在非响应消息 WM_PAINT 的情况下。
CPaintDC 类响应 WM_PAINT 消息,并自动完成绘制,这对维护图形的完整性有着重要的作用。
CClientDC 类可以实时地将图形绘制到屏幕上,不需要重画;而如果用 CPaintDC 类的对象完成同样的工作,只能发出消息让屏幕上包含这条直线的区域重画,以把这条直线绘制到屏幕上。
===================================================
⑤、设备环境类的使用方法
CDC 类:
因为CDC类不能用窗口对象指针初始化对象,所以,一般不直接定义对象。
CPaintDC 类:
CPaintDC 类一般用在窗口类OnPaint函数中,可采用如下代码定义一个CPaintDC类对象:
CPaintDC dc(this);
以上代码定义了一个CPaintDC类的对象dc,并用当前的窗口对象指针this对对象进行了初始化。CClientDC 和 CWindowDC类也采用这样的方法。
CClientDC 类:
可利用以下代码定义一个对象:CClientDC dc(this);
CWindowDC 类:
利用以下代码创建一个CWindowDC类的对象:CWindowDC dc(this);
===================================================
⑥、三种DC的示例代码:
CClientDC clientDC(this);
clientDC.MoveTo(0, 0);
clientDC.LineTo(100, 100);
CWindowDC wndDC(this);
wndDC.MoveTo(0, 0);
wndDC.LineTo(200, 100);
CPaintDC paintDC(this);
paintDC.MoveTo(50, 50);
paintDC.LineTo(150, 100); |