您的位置:首页 > 其它

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

2013-08-05 18:40 369 查看
本文由BlueCoder编写   转载请说明出处:http://blog.csdn.net/crocodile__/article/details/9769767
我的邮箱:bluecoder@yeah.net    欢迎大家和我交流编程心得我的微博:BlueCoder_黎小华    欢迎光临^_^

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);
 
这两种方式实现的效果完全一样,多一种方式,多一种思路,这样才能提高能力……
 
源代码下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: