分享
 
 
 

用VC进行屏幕截取编程

王朝c/c++·作者佚名  2006-01-06
窄屏简体版  字體: |||超大  

实用技巧

用VC进行屏幕截取编程

潘小龙 顾时明

[请作者和我们联系]

---- 屏幕截取是令人比较感兴趣的事情.虽然现在有不少应用程序如HYPERSNAP等可以用来截取你所喜欢的屏幕画面,但是如果能把这个功能加到自己的程序中,就更能利用它强大的作用.

---- 下面用VC来逐步介绍在Windows95下的实现过程.首先我们要确定屏幕截取的区域,用LPRECT结构来定义.可以截取一个窗口,或整个屏幕.以下代码把选定的屏幕区域拷贝到位图中.

HBITMAP CopyScreenToBitmap(LPRECT 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 = SelectObject(hMemDC, hBitmap);

// 把屏幕设备描述表拷贝到内存设备描述表中

BitBlt(hMemDC, 0, 0, nWidth, nHeight,

hScrDC, nX, nY, SRCCOPY);

//得到屏幕位图的句柄

hBitmap = SelectObject(hMemDC, hOldBitmap);

//清除

DeleteDC(hScrDC);

DeleteDC(hMemDC);

// 返回位图句柄

return hBitmap;

}

得到屏幕位图句柄以后,我们

可以把屏幕内容粘贴到剪贴板上.

if (OpenClipboard(hWnd))

//hWnd为程序窗口句柄

{

//清空剪贴板

EmptyClipboard();

//把屏幕内容粘贴到剪贴板上,

hBitmap 为刚才的屏幕位图句柄

SetClipboardData(CF_BITMAP, hBitmap);

//关闭剪贴板

CloseClipboard();

}

我们也可以把屏幕内容以位图格式存到磁盘文件上.

int SaveBitmapToFile(HBITMAP hBitmap ,

LPSTR lpFileName) //hBitmap 为刚才的屏幕位图句柄

{ //lpFileName 为位图文件名

HDC hDC;

//设备描述表

int iBits;

//当前显示分辨率下每个像素所占字节数

WORD wBitCount;

//位图中每个像素所占字节数

//定义调色板大小, 位图中像素字节大小 ,

位图文件大小 , 写入文件字节数

DWORD dwPaletteSize=0,

dwBmBitsSize,

dwDIBSize, dwWritten;

BITMAP Bitmap;

//位图属性结构

BITMAPFILEHEADER bmfHdr;

//位图文件头结构

BITMAPINFOHEADER bi;

//位图信息头结构

LPBITMAPINFOHEADER lpbi;

//指向位图信息头结构

HANDLE fh, hDib, 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;

//计算调色板大小

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 = 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,

(BITMAPINFOHEADER *)

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);

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有