根据指定窗口句柄进行截屏

来源:互联网 发布:如何导出淘宝客户资料 编辑:程序博客网 时间:2024/06/05 16:52

1、获取窗口句柄

    见http://blog.csdn.net/dazhong159/article/details/7903382

2、截屏函数代码(包含截屏类和调用示例)

    Screen.h头文件如下:

#ifndef __CSCREEN_H__#define __CSCREEN_H__#include <windows.h>class CScreen{public:    char *buf;    //可供网络传输的位图数据指针int buf_len; //可供网络传输的位图数据长度CScreen(int color_deep=16, HWND hWnd=0, int w=0, int h=0){if (hWnd != 0) {m_hWnd=hWnd;hhh=::GetDC(m_hWnd);      //检索一指定窗口的客户区域或整个屏幕的显示设备上下文环境的句柄                          //以后可以在GDI函数中使用该句柄来在设备上下文环境中绘图}hdc = CreateDC("DISPLAY", NULL, NULL, NULL);  //使用指定的名字为一个设备创建设备上下文环境ScrWidth = GetDeviceCaps(hdc, HORZRES);    //屏幕宽度ScrHeight = GetDeviceCaps(hdc, VERTRES);   //屏幕高度hmdc = CreateCompatibleDC(hdc); //创建一个与指定设备兼容的内存设备上下文环境if(w==0 && h==0) {hBmpScreen = CreateCompatibleBitmap(hdc,ScrWidth,ScrHeight); //创建与指定的设备环境相关的设备兼容的位图}else { hBmpScreen = CreateCompatibleBitmap(hdc,w,h); ScrWidth=w;ScrHeight=h;}holdbmp=(HBITMAP)SelectObject(hmdc, hBmpScreen); //选择一对象到指定的设备上下文环境中BITMAP            bm;    //bmp图像效果好,非压缩;jpg压缩,便于网络传输BITMAPINFOHEADER    bi;  //位图信息头,大小固定40字节GetObject(hBmpScreen, sizeof(bm), (LPSTR)&bm); //得到指定图形对象的信息bi.biSize = sizeof(BITMAPINFOHEADER);bi.biWidth = bm.bmWidth;bi.biHeight = bm.bmHeight;bi.biPlanes = 1;bi.biBitCount = color_deep;bi.biCompression = BI_RGB;bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8) * bi.biHeight;bi.biXPelsPerMeter = 0;bi.biYPelsPerMeter    = 0;bi.biClrUsed = 0;bi.biClrImportant = 0;int ncolors = (1 << bi.biBitCount);if( ncolors > 256 ) ncolors = 0;dwLen_1 = bi.biSize + ncolors * sizeof(RGBQUAD);dwLen_2 = dwLen_1+ bi.biSizeImage;hDib =new char[dwLen_2]; memcpy(hDib,&bi,sizeof(bi));buf=hDib+dwLen_1;buf_len=bi.biSizeImage;//GetScreen(100, 200, w, h); //初始化调色板数据}~CScreen();void GetScreen();void GetScreen(int x, int y, int w, int h);void SetScreentoPath(char *path);void SetScreen();void SetScreen(int x, int y, int w, int h);void JoinScrData(char *data); //加载位图数据private:int ScrWidth;int ScrHeight;int dwLen_1;int dwLen_2; char *hDib;HDC hmdc;HDC hdc;HDC hhh;HBITMAP hBmpScreen;HBITMAP holdbmp;HWND m_hWnd;};#endif

    .cpp文件如下:

#include "StdAfx.h"#include "Screen.h"CScreen::~CScreen(){hBmpScreen = (HBITMAP)SelectObject(hmdc,holdbmp);delete [dwLen_2]hDib;DeleteDC(hdc);DeleteDC(hmdc);if (m_hWnd!=0) {DeleteDC(hhh);}DeleteObject(hBmpScreen);DeleteObject(holdbmp); }void CScreen::GetScreen(){   //对指定的源设备环境区域中的像素进行位块(bit_block)转换BitBlt(hmdc,0,0,ScrWidth,ScrHeight,hdc,0,0,SRCCOPY); //函数获取指定兼容位图的位,然后将其作一个DIB—设备无关位图(Device-Independent Bitmap)使用的指定格式复制到一个缓冲区中GetDIBits(hmdc, hBmpScreen,0L,(DWORD)ScrHeight,(LPBYTE)hDib + dwLen_1,(LPBITMAPINFO)hDib,(DWORD)DIB_RGB_COLORS);      }void CScreen::GetScreen(int x,int y,int w,int h){     //对指定的源设备环境(hdc)中的像素进行位块转换,以传送至目标设备环境(hmdc)中BitBlt(hmdc,0,0,w,h,hdc,x,y,SRCCOPY);//函数获取指定兼容位图的位,然后将其作一个DIB—设备无关位图使用的指定格式复制到一个缓冲区中GetDIBits(hmdc, hBmpScreen,0L,(DWORD)ScrHeight,(LPBYTE)hDib + dwLen_1,(LPBITMAPINFO)hDib,(DWORD)DIB_RGB_COLORS);      }void CScreen::SetScreentoPath(char *path){   BITMAPFILEHEADER bfh;   bfh.bfType = ((WORD)('M'<< 8)|'B');   bfh.bfReserved1 = 0;   bfh.bfReserved2 = 0;   bfh.bfSize = 54+dwLen_2;   bfh.bfOffBits = 54;   HANDLE hFile=CreateFile(path, GENERIC_WRITE, 0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);   DWORD dwWrite;   WriteFile(hFile, &bfh, sizeof(BITMAPFILEHEADER), &dwWrite,NULL);   WriteFile(hFile, hDib, bfh.bfSize, &dwWrite, NULL);    CloseHandle(hFile);   }void CScreen::SetScreen(){    //使用DIB位图和颜色数据对与目标设备环境相关的设备上的指定矩形中的像素进行设置::SetDIBitsToDevice(hhh,0,0,ScrWidth,ScrHeight,0,0,0,ScrHeight,(LPBYTE)hDib + dwLen_1,(LPBITMAPINFO)hDib, (DWORD)DIB_RGB_COLORS);}void CScreen::SetScreen(int x,int y,int w,int h){    //使用指定的DIB位图中发现的颜色数据来设置位图中的像素::SetDIBits(hhh,hBmpScreen,ScrWidth,ScrHeight,(LPBYTE)hDib + dwLen_1,(LPBITMAPINFO)hDib, (DWORD)DIB_RGB_COLORS);    //从源矩形中复制一个位图到目标矩形StretchBlt(hhh,x,y,w,h,hdc,0,0,ScrWidth,ScrHeight,SRCCOPY);}void CScreen::JoinScrData(char *data) //加载位图数据{memcpy(hDib+dwLen_1, data, dwLen_2-dwLen_1);}

    调用如下:

void CMyDlg::OnOK() {// TODO: Add extra validation hereRECT rect;::GetWindowRect(m_hWnd,&rect);CScreen *screen=new CScreen(16,NULL,rect.right-rect.left,rect.bottom-rect.top);screen->GetScreen(rect.left,rect.top,rect.right-rect.left,rect.bottom-rect.top);for (int i=0;i<10000;i++){screen->SetScreentoPath("1.bmp");}delete screen;CDialog::OnOK();}

3、在界面上显示图片

ImageWnd::ImageWnd(){Create(NULL,"Image");bitmap=new CBitmap;bitmap->m_hObject=LoadImage(NULL,"1.bmp",IMAGE_BITMAP,120,121,LR_LOADFROMFILE);mdc=new CDC;CClientDC dc(this);mdc->CreateCompatibleDC(&dc);mdc->SelectObject(bitmap);    }
void ImageWnd::OnPaint() {CPaintDC dc(this); // device context for paintingdc.BitBlt(i,0,120,121,mdc,0,0,SRCCOPY);// TODO: Add your message handler code here// Do not call CFrameWnd::OnPaint() for painting messages}

 

原创粉丝点击