VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

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

VC++高级班之窗口篇-[12]打造自己的屏幕放大镜

[复制链接]
51_avatar_middle
online_admins Syc 发表于 2018-3-2 10:11:38 | 显示全部楼层 |阅读模式
------------------------------------------ Begin ----------------------------------------
①、实现的原理:
获取显示区域的大小,拷贝放大倍率分之一的屏幕区域,将其图像拉伸显示到显示区域!
===================================================
②、界面的设计及制作:
Picture 控件的ID设置成非:IDC_STATIC,例如:IDC_SHOW,Notify 属性设置为 True;
ComboBox 的 Type 属性设置为:Drop List,并绑定控件类型成员变量:m_ComboBox
并在对话框的初始化函数:OnInitDialog() 中进行数据的添加:
  1. CString strText;
  2. for ( int i = 1; i <= 10; i++ ) {
  3.         strText.Format(_T("%d"), i);
  4.         m_ComboBox.InsertString(i-1, strText);
  5. }
  6. m_ComboBox.SetCurSel(0);
复制代码

  1. //显示区域矩形的获取
  2. GetDlgItem(IDC_SHOW)->GetClientRect(&showRect);
复制代码

===================================================
③、为开始截图按钮添加相应函数,启动 定时器:
  1. void CDlgTestDlg::OnBnClickedBtn()
  2. {
  3.         static BOOL bStart = FALSE;
  4.         if (bStart == FALSE){
  5.                 bStart = TRUE;

  6.                 //m_targetBmp.DeleteObject();

  7.                 SetTimer(1, 50, NULL);
  8.                 SetDlgItemText(IDC_BTN, _T("我要停止!"));
  9.         }else{
  10.                 bStart = FALSE;
  11.                 KillTimer(1);

  12.                 //CString strText;
  13.                 //m_ComboBox.GetLBText(m_ComboBox.GetCurSel(), strText);
  14.                 //StretchScreenToBitmap(showRect, _ttoi(strText), m_targetBmp);

  15.                 SetDlgItemText(IDC_BTN, _T("开始喽……"));
  16.         }
  17. }
复制代码

===================================================
④、添加定时器响应函数:
  1. void CDlgTestDlg::OnTimer(UINT_PTR nIDEvent)
  2. {
  3.         CString strText;
  4.         m_ComboBox.GetLBText(m_ComboBox.GetCurSel(), strText);
  5.         UINT nIndex = _ttoi(strText);

  6.         CBitmap mBmp;
  7.         StretchScreenToBitmap(showRect, nIndex, mBmp);
  8.         DrawTargetBitmap(mBmp);

  9.         CDialog::OnTimer(nIDEvent);
  10. }
复制代码

===================================================
⑤、StretchScreenToBitmap 函数实现:
  1. BOOL StretchScreenToBitmap(CRect tRect, int iZoom, CBitmap &outBmp)
  2. {
  3.         CDC *pDC = CDC::FromHandle(::GetDC(NULL));
  4.         if ( !pDC ) return FALSE;

  5.         CPoint pt;
  6.         GetCursorPos(&pt);

  7.         int xScreen = GetSystemMetrics(SM_CXSCREEN);
  8.         int yScreen = GetSystemMetrics(SM_CYSCREEN);

  9.         int iPosLeft = 0, iPosTop = 0;
  10.         int iWidth = tRect.Width()/iZoom;
  11.         int iHeigh = tRect.Height()/iZoom;

  12.         CDC hMemDC, hTDc;
  13.         CBitmap tBmp, *pOldBmp = NULL;

  14.         hMemDC.CreateCompatibleDC(pDC);
  15.         hTDc.CreateCompatibleDC(pDC);

  16.         outBmp.CreateCompatibleBitmap(pDC, tRect.Width(), tRect.Height());
  17.         tBmp.CreateCompatibleBitmap(pDC, xScreen, yScreen);

  18.         pOldBmp = hMemDC.SelectObject(&outBmp);
  19.         hTDc.SelectObject(&tBmp);

  20.         hTDc.BitBlt(0, 0, xScreen, yScreen, pDC, 0, 0, SRCCOPY);
  21.         hTDc.DrawIcon(pt, AfxGetApp()->LoadIcon(IDI_CURSOR_ICON));

  22.         iPosLeft =  (pt.x-iWidth/2) > 0 ? (pt.x-iWidth/2) : 0;
  23.         iPosTop = (pt.y-iHeigh/2) > 0 ? (pt.y-iHeigh/2) : 0;

  24.         iPosLeft =  (pt.x+iWidth/2) < xScreen ? iPosLeft : xScreen-iWidth;
  25.         iPosTop = (pt.y+iHeigh/2) < yScreen ? iPosTop : yScreen-iHeigh;

  26.         BOOL bRet = hMemDC.StretchBlt(0, 0, tRect.Width(), tRect.Height(), &hTDc, iPosLeft, iPosTop, iWidth, iHeigh, SRCCOPY);

  27.         tBmp.DeleteObject();
  28.         hMemDC.SelectObject(pOldBmp);
  29.         hMemDC.DeleteDC();
  30.         hTDc.DeleteDC();
  31.         ReleaseDC(NULL, pDC->m_hDC);
  32.         return bRet;
  33. }
复制代码

===================================================
⑥、DrawTargetBitmap 函数实现:
  1. BOOL CDlgTestDlg::DrawTargetBitmap(CBitmap &tBmp, BOOL bReleaseBmp)
  2. {
  3.         CDC hMemDc, *pDc = CDC::FromHandle(::GetDC(GetDlgItem(IDC_SHOW)->m_hWnd));
  4.         if ( !pDc ) return FALSE;

  5.         CBitmap *pOldBmp = NULL;
  6.         hMemDc.CreateCompatibleDC(pDc);
  7.         pOldBmp = hMemDc.SelectObject(&tBmp);

  8.         pDc->BitBlt(1, 1, showRect.Width()-2, showRect.Height()-2, &hMemDc, 0, 0, SRCCOPY);
  9.         hMemDc.SelectObject(pOldBmp);

  10.         if (bReleaseBmp) tBmp.DeleteObject();
  11.         hMemDc.DeleteDC();
  12.         ::ReleaseDC(GetDlgItem(IDC_SHOW)->m_hWnd, pDc->m_hDC);

  13.         return TRUE;
  14. }
复制代码

===================================================
⑦、最小化窗口后显示区域被清空问题的解决(大家可以把这个算作是一个作业):
  1. //OnPaint() 函数中添加如下代码:
  2. if (m_targetBmp.m_hObject){
  3.         DrawTargetBitmap(m_targetBmp, FALSE);
  4. }
复制代码

===================================================
⑧、析构函数的添加:~CDlgTestDlg();
  1. CDlgTestDlg::~CDlgTestDlg()
  2. {
  3.         if (m_targetBmp.m_hObject)
  4.                 m_targetBmp.DeleteObject();
  5. }
复制代码

===================================================
※※※ 小作业:
1>双击显示区域,将图像保存到文件!
2>添加热键功能!
------------------------------------- End -------------------------------------------------

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




上一篇:VC++高级班之窗口篇-[11]自定义区域截图
下一篇:VC++高级班之窗口篇-[13]打造自己的图片浏览器

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

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

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

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

本版积分规则

关闭

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

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

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

GMT+8, 2018-11-16 20:42

Powered by Discuz! X3.4

© 2009-2018 cctry.com

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