当前位置: 首页 > news >正文

Win32_8有意思的程序——抓取屏幕

Win32学了一段时间了,跟着杨老师的脚步,准备学习MFC,因此最近几天在复习C++,于是发现有将近一周没写博文了……

今天来写一个较为简单、但是比较有意思的东西

不知大家在理发店理发的时候注意到一个奇观没:

理发店一般都有两面对立的镜子,你仔细一看会发现,两面镜子里面的成像逐渐缩小,并且居中排列,很有意思

盗梦空间中也有一个类似的场景,我截了一个图:

yes,今天就来做一个这样的效果,只不过是抓的屏幕

好吧,先来看看程序运行效果,来对比一下:

下面进入主题,剖析实现细节,主要分两大步:

(1)要对屏幕"工作",在Win32中必须获取屏幕的hdc。有两种主要的方式:

1)GetDC(HWND), 传递参数NULL——GetDC(NULL)

2)CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);

(2)贴图

获取环境hdc后,在hdc中会保存屏幕的状态——相当于屏幕的截图,只是用bmp保存的

今天贴图用一个更好的函数StretchBlt,它有一个很好的功能——可以按比例缩放bmp位图,然后显示:

BOOL StretchBlt(
  HDC hdcDest,      // handle to destination DC
  int nXOriginDest, // x-coord of destination upper-left corner
  int nYOriginDest, // y-coord of destination upper-left corner
  int nWidthDest,   // width of destination rectangle
  int nHeightDest,  // height of destination rectangle
  HDC hdcSrc,       // handle to source DC
  int nXOriginSrc,  // x-coord of source upper-left corner
  int nYOriginSrc,  // y-coord of source upper-left corner
  int nWidthSrc,    // width of source rectangle
  int nHeightSrc,   // height of source rectangle
  DWORD dwRop       // raster operation code
);

使用方法和BitBlt很类似,应该不用赘述了……

具体核心实现代码如下:

int	cxScreen, cyScreen;//全局变量——屏幕的长宽,用于窗口居中和缩放显示bmp

hdcCli = BeginPaint(hwnd, &ps);

hdcScr = GetDC(NULL);

 

//循环3次

i = 0;
while(i<3)
{
 //按比例显示桌面截图
 StretchBlt(hdcCli, 0, 0, cxClient, cyClient, hdcScr, 0, 0, cxScreen, cyScreen, SRCCOPY);
 i++;
}


DeleteDC(hdcScr);
EndPaint(hwnd, &ps);


这种方式很简单,当然我肯定不会简单用一下这个函数就了事了,这个没什么大不了的,下面我在介绍一种使用GDI映射模式+BitBlt来贴bmp位图,实现效果和上面说的完全一样

BitBlt函数没有缩放功能,我就用映射模式来实现缩放功能,缩放的具体实现代码如下:

hdcCli = BeginPaint(hwnd, &ps);

hdcScr = GetDC(NULL);

SetMapMode(hdcCli, MM_ANISOTROPIC);//设定x、y方向异性模式,就是说x、y方向可以不同
SetWindowExtEx(hdcCli, cxScreen, cyScreen, NULL);//设定窗口范围
SetViewportExtEx(hdcCli, cxClient, cyClient, NULL);//设定视口范围
//这样就能将cxScreen * cyScreen的大小缩放为cxClient * cyClient的大小,就是将屏幕大小缩小为客户区大小
//循环3次
i = 0;
while(i<3)
{
	//由于已经在内存中缩放了屏幕bmp位图,这里就可直接贴图
	BitBlt(hdcCli, 0, 0, cxScreen, cyScreen, hdcScr, 0, 0, SRCCOPY);//直接显示
	i++;
}


DeleteDC(hdcScr);
EndPaint(hwnd, &ps);

这两种方式实现的效果完全一样,多一种方式,多一种思路,这样才能提高能力……

源代码下载

相关文章:

  • php调试和日志记录函数
  • Android实战技术:IPC方式简介教程
  • SICP 习题(1.1,1.2,1.3,1.4)解题总结。
  • linux终端开发环境的配置
  • ADO.NET理论+实践
  • Android实战技术:深入理解Android的RPC方式与AIDL
  • Linux调试器工作原理——基础篇
  • Linux调试器工作原理之二——实现断点
  • 学ACM有用吗?
  • Linux调试器工作原理之三——调试信息
  • hdu1501 Zipper
  • Android实战技术:理解Binder机制
  • SICP 习题(1.5)解题总结。
  • android开发图片分辨率
  • 用接口,多态,继承,类计算三角形和矩形的周长和面积
  • Docker容器管理
  • Java 9 被无情抛弃,Java 8 直接升级到 Java 10!!
  • Javascript 原型链
  • mysql innodb 索引使用指南
  • Redis中的lru算法实现
  • Ruby 2.x 源代码分析:扩展 概述
  • 更好理解的面向对象的Javascript 1 —— 动态类型和多态
  • 湖南卫视:中国白领因网络偷菜成当代最寂寞的人?
  • 日剧·日综资源集合(建议收藏)
  • 使用前端开发工具包WijmoJS - 创建自定义DropDownTree控件(包含源代码)
  • 树莓派 - 使用须知
  • 推荐一款sublime text 3 支持JSX和es201x 代码格式化的插件
  • 一个项目push到多个远程Git仓库
  • 智能合约Solidity教程-事件和日志(一)
  • 3月7日云栖精选夜读 | RSA 2019安全大会:企业资产管理成行业新风向标,云上安全占绝对优势 ...
  • 说说我为什么看好Spring Cloud Alibaba
  • ​Spring Boot 分片上传文件
  • # Pytorch 中可以直接调用的Loss Functions总结:
  • #NOIP 2014# day.1 T2 联合权值
  • #pragam once 和 #ifndef 预编译头
  • #考研#计算机文化知识1(局域网及网络互联)
  • (52)只出现一次的数字III
  • (AtCoder Beginner Contest 340) -- F - S = 1 -- 题解
  • (cljs/run-at (JSVM. :browser) 搭建刚好可用的开发环境!)
  • (二)斐波那契Fabonacci函数
  • (分享)一个图片添加水印的小demo的页面,可自定义样式
  • (附源码)springboot码头作业管理系统 毕业设计 341654
  • (附源码)ssm高校升本考试管理系统 毕业设计 201631
  • (力扣)循环队列的实现与详解(C语言)
  • (每日持续更新)jdk api之StringBufferInputStream基础、应用、实战
  • (入门自用)--C++--抽象类--多态原理--虚表--1020
  • (实战)静默dbca安装创建数据库 --参数说明+举例
  • (一)Dubbo快速入门、介绍、使用
  • (译)计算距离、方位和更多经纬度之间的点
  • (转)从零实现3D图像引擎:(8)参数化直线与3D平面函数库
  • .NET 5种线程安全集合
  • .NET 8 中引入新的 IHostedLifecycleService 接口 实现定时任务
  • .Net 垃圾回收机制原理(二)
  • .net 前台table如何加一列下拉框_如何用Word编辑参考文献
  • .net开源工作流引擎ccflow表单数据返回值Pop分组模式和表格模式对比