VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

有编程疑问吗?还请到提问专区发帖提问!
搜索
查看: 205|回复: 1

VC++高级班之窗口篇-[10]屏幕截图功能的实现

[复制链接]
51_avatar_middle
online_admins Syc 发表于 2018-3-2 10:06:02 | 显示全部楼层 |阅读模式
------------------------------------------ Begin ----------------------------------------
①、对整个屏幕截图:
  1. void GetScreenCapture(LPCTSTR lpszSavePath)
  2. {
  3.         ASSERT(lpszSavePath);
  4.         int screenWidth = GetSystemMetrics(SM_CXSCREEN);
  5.         int screenHeight = GetSystemMetrics(SM_CYSCREEN);

  6.         CDC *pDC = CDC::FromHandle(::GetDC(NULL));

  7.         CDC memDc;
  8.         memDc.CreateCompatibleDC(pDC);

  9.         CBitmap mBmp, *pOldBmp = NULL;
  10.         mBmp.CreateCompatibleBitmap(pDC, screenWidth, screenHeight);
  11.         pOldBmp = memDc.SelectObject(&mBmp);

  12.         memDc.BitBlt(0, 0, screenWidth, screenHeight, pDC, 0, 0, SRCCOPY);

  13.         CImage img;
  14.         img.Attach(mBmp);
  15.         img.Save(lpszSavePath);

  16.         memDc.SelectObject(pOldBmp);
  17.         ::ReleaseDC(NULL, pDC->m_hDC);
  18. }
复制代码

===================================================
②、对指定窗口截图:
  1. void GetWndCapture(HWND hTargetWnd, LPCTSTR lpszSavePath)
  2. {
  3.         ASSERT(lpszSavePath);
  4.         CRect mRect;
  5.         GetWindowRect(hTargetWnd, &mRect);

  6.         CDC *pDC = CDC::FromHandle(::GetDC(hTargetWnd));

  7.         CDC memDc;
  8.         memDc.CreateCompatibleDC(pDC);

  9.         CBitmap mBmp, *pOldBmp = NULL;
  10.         mBmp.CreateCompatibleBitmap(pDC, mRect.Width(), mRect.Height());
  11.         pOldBmp = memDc.SelectObject(&mBmp);

  12.         memDc.BitBlt(0, 0, mRect.Width(), mRect.Height(), pDC, 0, 0, SRCCOPY);

  13.         CImage img;
  14.         img.Attach(mBmp);
  15.         img.Save(lpszSavePath);

  16.         memDc.SelectObject(pOldBmp);
  17.         ::ReleaseDC(NULL, pDC->m_hDC);
  18. }
复制代码

===================================================
③、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的图形保存等。

实例:
  1. CClientDC dc(this); //this一般指向本窗口或当前活动视图
  2. dc.TextOut(10, 0, str, str.GetLength());

  3. CClientDC *pDC = new CClientDC(this);
  4. 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的示例代码:
  1. CClientDC clientDC(this);
  2. clientDC.MoveTo(0, 0);
  3. clientDC.LineTo(100, 100);

  4. CWindowDC wndDC(this);
  5. wndDC.MoveTo(0, 0);
  6. wndDC.LineTo(200, 100);

  7. CPaintDC paintDC(this);
  8. paintDC.MoveTo(50, 50);
  9. paintDC.LineTo(150, 100);
复制代码

===========================================================
※※※ 小作业:让用户从编辑框输入坐标(x,y,宽,高),对这个用户指定的区域进行截图!
------------------------------------- End ----------------------------------------------------------------

相关课程演示细节还请观看视频教程!
本套教程由VC驿站原创,提供视频教程+售后答疑服务!
教程介绍及详情请见:http://www.cctry.com/static/vip/index.html
VC驿站Vip会员详情请见:http://www.cctry.com/static/vip/index.html




上一篇:VC++高级班之窗口篇-[9]为窗口添加信息提示功能
下一篇:VC++高级班之窗口篇-[11]自定义区域截图

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你已经在论坛发帖求助,并且从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友?可以给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

您需要登录后才可以回帖 登录 | 加入驿站 qq_login

本版积分规则

关闭

站长提醒上一条 /1 下一条

QQ
QQ在线咨询
联系电话
13591366679
手机扫一扫 关注本站精彩内容
wxqrcode

QQ|小黑屋|手机版|VC驿站 ( 辽ICP备09019393号tongdun|网站地图wx_jqr

GMT+8, 2018-8-19 19:17

Powered by Discuz! X3.4

© 2009-2018 cctry.com

快速回复 返回顶部 返回列表