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

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 here
	
	RECT 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 painting

	dc.BitBlt(i,0,120,121,mdc,0,0,SRCCOPY);

	// TODO: Add your message handler code here
	
	// Do not call CFrameWnd::OnPaint() for painting messages
}

 


版权声明:本文为dazhong159原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。