VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

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

VC++高级班之窗口篇-[11]自定义区域截图

[复制链接]
51_avatar_middle
online_admins Syc 发表于 2018-3-2 10:08:36 | 显示全部楼层 |阅读模式
------------------------------------------ Begin ----------------------------------------
①、实现的原理:
点击截图按钮时,弹出一屏幕大小的模态对话框,将整个屏幕的图像画到此模态对话框上面,之后,在此对话框上面利用橡皮筋类进行自定义区域的截图操作!
===================================================
②、插入一对话框资源:
去掉所有子控件,并设置其 Title Bar 属性为 FALSE;
关联对话框类:CCaptureDlg
===================================================
③、在“开始截图”按钮中进行模态对话框的弹出:
CCaptureDlg dlg;
dlg.DoModal();
===================================================
④、CCaptureDlg 类的初始化函数中添加如下代码:
  1. // CCaptureDlg::OnInitDialog() 函数中添加:
  2. int screenWidth = GetSystemMetrics(SM_CXSCREEN);
  3. int screenHeight = GetSystemMetrics(SM_CYSCREEN);
  4. MoveWindow(-3, -3, screenWidth+6, screenHeight+6);
  5. //SetWindowPos(&wndTopMost, -3, -3, screenWidth+6, screenHeight+6, SWP_SHOWWINDOW);

  6. m_rectTracker.m_nStyle = CRectTracker::resizeOutside | CRectTracker::dottedLine;
  7. m_rectTracker.m_rect.SetRect(0, 0, 0, 0);
复制代码

===================================================
⑤、将整个屏幕的内容作为 CCaptureDlg 对话框的背景:
1》CCaptureDlg 构造函数中添加如下代码:CopyScreenToBitmap(m_ScreenBmp);
2》CCaptureDlg 析构函数中添加如下代码:m_ScreenBmp.DeleteObject();

响应 WM_ERASEBKGND 消息,在响应函数中添加如下代码:
  1. BOOL CCaptureDlg::OnEraseBkgnd(CDC* pDC)
  2. {
  3.         CDC memDC;
  4.         memDC.CreateCompatibleDC(pDC);
  5.         memDC.SelectObject(&m_ScreenBmp);

  6.         CRect rect;
  7.         GetClientRect(&rect);
  8.         pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &memDC, 0, 0, SRCCOPY);

  9.         memDC.DeleteDC();
  10.         return TRUE;

  11.         return CDialog::OnEraseBkgnd(pDC);
  12. }
复制代码


其中 CopyScreenToBitmap 函数的定义如下:
  1. BOOL CopyScreenToBitmap(CBitmap &tBmp)
  2. {
  3.         int screenWidth = GetSystemMetrics(SM_CXSCREEN);
  4.         int screenHeight = GetSystemMetrics(SM_CYSCREEN);

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

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

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

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

  12.         memDc.SelectObject(pOldBmp);
  13.         memDc.DeleteDC();

  14.         ::ReleaseDC(NULL, pDC->m_hDC);

  15.         return TRUE;
  16. }
复制代码

===================================================
⑥、CCaptureDlg 类中橡皮筋类对象的构造及初始化:
  1. // CCaptureDlg.h
  2. CRectTracker m_rectTracker;

  3. // CCaptureDlg.cpp
  4. m_rectTracker.m_nStyle = CRectTracker::resizeOutside | CRectTracker::dottedLine;
  5. m_rectTracker.m_rect.SetRect(0, 0, 0, 0);
复制代码

===================================================
⑦、左键按下,橡皮筋矩形构建:
  1. void CCaptureDlg::OnLButtonDown(UINT nFlags, CPoint point)
  2. {
  3.         if(m_rectTracker.HitTest(point) == CRectTracker::hitNothing)
  4.         {
  5.                 m_rectTracker.TrackRubberBand(this, point, TRUE);
  6.         } else {
  7.                 m_rectTracker.Track(this, point, TRUE);
  8.                 m_rectTracker.m_rect.NormalizeRect();
  9.         }
  10.         Invalidate(TRUE);

  11.         CDialog::OnLButtonDown(nFlags, point);
  12. }
复制代码

===================================================
⑧、橡皮筋的绘制:
  1. void CCaptureDlg::OnPaint()
  2. {
  3.         CPaintDC dc(this); // device context for painting
  4.         // TODO: Add your message handler code here
  5.         // Do not call CDialog::OnPaint() for painting messages

  6.         CDC *pDC = GetDC();
  7.         m_rectTracker.Draw(pDC);
  8.         ReleaseDC(pDC);
  9. }
复制代码

===================================================
⑨、当鼠标放到橡皮筋窗口的边缘时,进行光标样式的改变:
响应 WM_SETCURSOR 消息,并在其响应函数中添加如下代码:
  1. BOOL CCaptureDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
  2. {
  3.         if (pWnd == this && m_rectTracker.SetCursor(this, nHitTest))
  4.                 return TRUE;
  5.         else
  6.         return CDialog::OnSetCursor(pWnd, nHitTest, message);
  7. }
复制代码


◆◆◆ 遇到的问题及解决办法:
1>、工程改用 Use MFC in a Shared DLL,即:动态链接到MFC运行库;
2>、修改工程的 *.rc 文件,去掉其中的以下语句:#define _AFX_NO_TRACKER_RESOURCES
===================================================
⑩、双击保存图片:
  1. void CCaptureDlg::OnLButtonDblClk(UINT nFlags, CPoint point)
  2. {
  3.         if(m_rectTracker.HitTest(point) != CRectTracker::hitMiddle)
  4.                 return;

  5.         CDC *pDC = GetDC();

  6.         CDC memDC;
  7.         memDC.CreateCompatibleDC(pDC);
  8.         memDC.SelectObject(&m_ScreenBmp);

  9.         CRect rect;
  10.         rect = m_rectTracker.m_rect;

  11.         CBitmap mBmp, *pOldBmp = NULL;
  12.         mBmp.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());

  13.         CDC dstDC;
  14.         dstDC.CreateCompatibleDC(pDC);
  15.         pOldBmp = dstDC.SelectObject(&mBmp);

  16.         dstDC.BitBlt(0, 0, rect.Width(), rect.Height(), &memDC, rect.left, rect.top, SRCCOPY);

  17.         CImage img;
  18.         img.Attach(mBmp);
  19.         img.Save(_T("D:\\123.png"));

  20.         mBmp.DeleteObject();
  21.         memDC.DeleteDC();
  22.         dstDC.DeleteDC();

  23.         ReleaseDC(pDC);

  24.         CDialog::OnCancel();
  25.         //CDialog::OnLButtonDblClk(nFlags, point);
  26. }
复制代码


===================================================
※※※ 小作业:没有考虑橡皮筋的矩形拖出屏幕外的情况,交给大家去处理……
------------------------------------- End -------------------------------------------------

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




上一篇:VC++高级班之窗口篇-[10]屏幕截图功能的实现
下一篇:VC++高级班之窗口篇-[12]打造自己的屏幕放大镜

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

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

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

您需要登录后才可以回帖 登录 | 加入驿站 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

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