VC屏幕截图,保存为Bmp文件

新建一个MFC基于对话框的应用程序,在界面上放一个Button,为其实现点击事件,代码如下:

void CScreenShotDlg::OnBtnScreenshot()
{RECT rect = {0, 0, 1900, 1000};HBITMAP hbmp = CopyScreenToBitmap(&rect);SaveBitmapToFile(hbmp, "a.bmp");MessageBox("Save bmp file Successful");
}

被调用的这两个函数实现如下:

HBITMAP CopyScreenToBitmap(LPRECT lpRect)
{HDC hScrDC, hMemDC;				// 屏幕和内存设备描述表HBITMAP hBitmap, hOldBitmap;	// 位图句柄int nX, nY, nX2, nY2;			// 选定区域坐标int nWidth, nHeight;			// 位图宽度和高度int xScrn, yScrn;				// 屏幕分辨率if (IsRectEmpty(lpRect))return NULL;hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);		// 为屏幕创建设备描述表hMemDC = CreateCompatibleDC(hScrDC);				// 为屏幕设备描述表创建兼容的内存设备描述表nX = lpRect->left;nY = lpRect->top;nX2 = lpRect->right;nY2 = lpRect->bottom;xScrn = GetDeviceCaps(hScrDC, HORZRES);	// 获得屏幕水平分辨率yScrn = GetDeviceCaps(hScrDC, VERTRES);if (nX < 0)nX = 0;if (nY < 0)nY = 0;if (nX2 > xScrn)nX2 = xScrn;if (nY2 > yScrn)nY2 = yScrn;nWidth = nX2 - nX;nHeight = nY2 - nY;hBitmap = CreateCompatibleBitmap(hScrDC, nWidth, nHeight);		// 创建一个与屏幕设备描述表兼容的位图hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);			// 把新位图选到内存设备描述表中BitBlt(hMemDC, 0, 0, nWidth, nHeight, hScrDC, nX, nY, SRCCOPY);	// 把屏幕设备描述表拷贝到内存设备描述表中hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);			// 得到屏幕位图的句柄DeleteDC(hScrDC);DeleteDC(hMemDC);return hBitmap;
}/*lpFileName: 位图文件名
*/
BOOL SaveBitmapToFile(HBITMAP hBitmap, LPSTR lpFileName)
{HDC hDC;						// 设备描述表int iBits;						// 当前显示分辨率下每个像素所占字节数WORD wBitCount;					// 位图中每个像素所占字节数DWORD dwPaletteSize = 0, dwBmBitsSize, dwDIBSize, dwWritten;	// 调色板大小,位图数据大小,位图文件大小,写入文件字节数BITMAP Bitmap;					//位图属性结构BITMAPFILEHEADER bmfHdr;		// 位图文件头BITMAPINFOHEADER bi;			// 位图信息头LPBITMAPINFOHEADER lpbi;		// 指向位图信息头结构HANDLE fh, hDib;				// 定义文件,分配内存句柄HPALETTE hPal, hOldPal=NULL;	// 调色板句柄// 计算位图文件每个像素所占字节数hDC = CreateDC("DISPLAY", NULL, NULL, NULL);iBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);DeleteDC(hDC);if (iBits <= 1)wBitCount = 1;else if (iBits <= 4)wBitCount = 4;else if (iBits <= 8)wBitCount = 8;else if (iBits <= 24)wBitCount = 24;elsewBitCount = 32;if (wBitCount <= 8)dwPaletteSize = (1 << wBitCount) * sizeof(RGBQUAD);		// 计算调色板大小// 设置位图信息头结构GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);bi.biSize = sizeof(BITMAPINFOHEADER);bi.biWidth = Bitmap.bmWidth;bi.biHeight = Bitmap.bmHeight;bi.biPlanes = 1;bi.biBitCount = wBitCount;bi.biCompression = BI_RGB;bi.biSizeImage = 0;bi.biXPelsPerMeter = 0;bi.biYPelsPerMeter = 0;bi.biClrUsed = 0;bi.biClrImportant = 0;dwBmBitsSize = ((Bitmap.bmWidth * wBitCount + 31) / 32) * 4 * Bitmap.bmHeight;hDib = GlobalAlloc(GHND, dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER));	// 为位图内容分配内存lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);*lpbi = bi;// 处理调色板hPal = (HPALETTE)GetStockObject(DEFAULT_PALETTE);if (hPal){hDC = GetDC(NULL);hOldPal = SelectPalette(hDC, hPal, FALSE);RealizePalette(hDC);}// 获取该调色板下新的像素值GetDIBits(hDC, hBitmap, 0, (UINT)Bitmap.bmHeight, (LPSTR)lpbi + sizeof(BITMAPINFOHEADER) + dwPaletteSize, (BITMAPINFO*)lpbi, DIB_RGB_COLORS);if (hOldPal)				// 恢复调色板{SelectPalette(hDC, hOldPal, TRUE);RealizePalette(hDC);ReleaseDC(NULL, hDC);}// 创建位图文件 fh = CreateFile(lpFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);if (fh == INVALID_HANDLE_VALUE)return FALSE;// 设置位图文件头bmfHdr.bfType = 0x4D42;		// 文件类型: "BM"dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize; bmfHdr.bfSize = dwDIBSize;	// 位图文件大小bmfHdr.bfReserved1 = 0;bmfHdr.bfReserved2 = 0;bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize;WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);	// 写入位图文件头WriteFile(fh, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL);					// 写入位图文件其余内容GlobalUnlock(hDib);GlobalFree(hDib);CloseHandle(fh);return TRUE;
}



本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/405682.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C#反射技术在多语言实现中的实际用处参考,让初学者学技术有个针对性【附源码】...

做软件&#xff0c;有点儿类似铁人三项比赛&#xff1f;赛跑、射击、游泳? 光某个环节突出&#xff0c;也没多大用&#xff0c;需要整体能力都强&#xff0c;能把整体都可以搞定&#xff0c;才容易得到比赛的胜利&#xff0c;光某一环节非常优秀&#xff0c;也赢得不来整个比…

C语言中的格式化打印printf/sprintf以及嵌入式printf重定向进行DEBUG

一、printf描述 在C语言中&#xff0c;打印函数主要包括printf/sprintf/fprintf/snprintf等等&#xff0c;目的是将“给定的内容”按照“指定的格式”输出到“指定目标内”。通常要使用时&#xff0c;需要包括#inlcude <stdio.h>头文件。 用法为&#xff1a;void print…

华为网卡支持linux,在openwrt下对华为WA633无线AP的千兆网卡驱动进行支持

1.下面是这款AP的全裸图&#xff0c;AP的无线网卡采用了AR9223&#xff0c;PHY采用了博通的BCM5461&#xff0c;主控CPU位octeon 500&#xff0c;射频功放采用的是RF5602方案。由于这款CPU并不常见&#xff0c;我至今未在网上找到它的datasheet&#xff0c;导致我们在玩这款AP的…

hdu120118岁生日

Problem DescriptionGardon的18岁生日就要到了&#xff0c;他当然很开心&#xff0c;可是他突然想到一个问题&#xff0c;是不是每个人从出生开始&#xff0c;到达18岁生日时所经过的天数都是一样的呢&#xff1f;似乎并不全都是这样&#xff0c;所以他想请你帮忙计算一下他和他…

React开发(223):详情页根据数组map处理返回值

<Col span{6}>{isDicTonList &&isDicTonList.map((item, index) > {if (item.key afterDetail.status) {return item.value;}})}</Col>

Linux下C语言实现LCD屏幕截图

From: http://blog.chinaunix.net/uid-24789420-id-3191806.html 一、概述 最近看到网上有人问怎么用C语言实现屏幕截图&#xff0c;刚好自己也在研究Linux驱动&#xff0c;于是花了半天时间把Linux的FrameBuffer驱动看懂了个七八&#xff0c;接着就动手写了个LCD屏幕截图的应…

C语言中#、##宏定义的用法

一、#的用法 #用于编译器编译过程进行预处理。 1、宏定义 #define ON 1#ifndef _PARA_ #define _PARA_ #enddef#ifdef _PARB_ #define DEFAULT_SIZE 1024 #enddef2、宏开关 #if VAR ... #elif ... #end3、显示设定错误 #error ERROR: Not Define4、设置字节对齐 #pragma pac…

linux 正则表达式 视频教程,30分钟带你玩转正则表达式

定义&#xff1a;正则表达式说白了就是有普通字符、以及特殊字符组成的文子模式。{匹配模式标准}正则表达式将会作为一个模板与所搜索的字符串进行匹配。可以让使用者轻易达到搜寻/删除/取代某些特定字符的处理程序。此外vim、grep、find、awk、sed等命令都支持正则表达式注&am…

React开发(224):ant design label绑定值

<Col span{12}><Form className{form-customer} label"同意退运费"><span style{{ fontSize: 14 }}>&#xffe5;</span><Form.Item style{{ width: 20% }}>{getFieldDecorator(freight)(<InputNumber step{1} precision{2} min{0…

数据采集工具flume

概述 flume是在2011年被首次引入到Cloudera的CDH3分发中&#xff0c;2011年6月&#xff0c;Cloudera将flume项目捐献给Apache基金会。2012年&#xff0c;flume项目从孵化器变成了顶级项目&#xff0c;在孵化的这一年中&#xff0c;开发人员就已经开始基于Star Trek Themed标签对…

电脑SSH登陆树莓派Raspberry的两种方式

采用SSH登陆Raspberry需要提前知道Raspberry的IP&#xff0c;SSH登陆端口为22&#xff0c;这里分享两种基于SSH网络登陆树莓派的方式。 一、利用路由器搭建局域网登陆树莓派 1、用路由器搭建局域网&#xff0c;电脑无线或有线方式连接路由器&#xff0c;树莓派用网线连接路由…

linux命令修改内容怎么回退,linux命令(修改).doc

linux命令(修改)第一组 用户管理类命令1 添加用户useradd [选项] 用户名范例&#xff1a;useradd davidls /home vim /etc/passwd2 修改密码passwd [选项] 用户名范例&#xff1a;useradd davidls /home passwd david(修改密码)3 删除用户userdel [选项] 用户名范例&#xff1a…

使用数据库的压测工具super-smack测试mysql数据库性能

一、下载super-smack下载地址&#xff1a;http://vegan.net/tony/supersmack/源码&#xff1a;http://vegan.net/tony/supersmack/super-smack-1.3.tar.gz二、编译及安装配置编译选项&#xff1a;./configure --prefix/usr/local/super-smack-1.3 --with-mysql --with-smacks-d…

React开发(225):render中返回的值可以定义为一个方法

/*** 商品信息 图片&#xff0c;名称、code展示* param {*} data*/goodInfoVal (data) > {return (<div style{{ display: flex, alignItems: center }}><img style{{ width: 100px, marginRight: 8px }} src{data.productImg} alt"" /><div>&…

Linux sed工具用法

一、sed用法 语法&#xff1a; sed [-nefr] [动作] 作用&#xff1a; 以行为单位的新增/删除/修改/插入/替换等功能&#xff0c;bash脚本中常用。sed功能强大&#xff0c;主要体现在[动作]的指定 选项与参数&#xff1a; -n &#xff1a;只有经过 sed 特殊处理的那一行&…

SourceInsight配置

如图&#xff1a; 1&#xff09; SourceInsight: a) 搜索结果直接替换 b) 配置背景色 c) 显示行号、设置tab键宽度为4个空格以及其他 d) 字体设置 e) 不创建备份文件

安卓客户端测试总结

安装测试1.真机上安装卸载&#xff0c;.第方软件&#xff08;91.豌豆荚等2.手机卡/SD卡&#xff0c;.不同的IOS和安卓版本3.安装过程中取消&#xff0c;空间不足4.安装过程来电&#xff0c;短信&#xff0c;完成后&#xff0c;是否继续5.卸载后是否卸载所安装文件6.是否可以删除…

linux防火墙查看被动模式,Centos7搭建vsftpd及被动模式下的防火墙设置

一、安装vsftpd&#xff1a;yum -y install vsftpd二、 创建用户名useradd zhangsanpasswd 123456useradd lisipasswd 123456在配置文件下设置拒绝匿名访问重启下服务systemctl restart vsftpd.service将lisi添加进黑名单vim /etc/vsftpd/ftpusers黑名单是路径位于/etc/vsftpd/…

Android API 中文(77)——AdapterView.OnItemSelectedListener

前言 本章内容是android.widget.AdapterView.OnItemSelectedListener&#xff0c;版本为Android 2.3 r1&#xff0c;翻译来自"cnmahj"&#xff0c;欢迎大家访问他的博客&#xff1a;http://android.toolib.net/blog/&#xff0c;再次感谢"cnmahj"&#xff…

前端小知识点(1):undefined和null区别

目录 一、奇怪点 二、历史原因 三、具体区别 四、代码演示 五、运行结果 一、奇怪点 有点奇怪的是&#xff0c;JavaScript语言居然有两个表示"无"的值&#xff1a;undefined和null。这是为什么&#xff1f; 二、历史原因 1995年JavaScript诞生时&#xff0c;…