您的位置:首页 > 其它

ScreenBase实现屏幕任意区域的截取

2008-05-04 11:57 429 查看

function StorePage(){d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&u='+escape(d.location.href)+'&c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();}
//========================================================================
//TITLE:
// ScreenBase实现屏幕任意区域的截取
//AUTHOR:
// norains
//DATE:
// Tuesday 16-January -2007
//Environment:
// EVC4.0 + Standard SDK
//========================================================================

1.ScreenBase 源码

ScreenBase为自己写代码方便而封装的一个API类,该类的的主要功能是截取屏幕任意区域的图像,并将之保存为BMP文件.

源代码如下:






/**///////////////////////////////////////////////////////////////////////


// ScreenBase.h: interface for the CScreenBase class.




/**///////////////////////////////////////////////////////////////////////


#ifndef SCREENBASE_H


#define SCREENBASE_H


//-------------------------------------------------------------------




class CScreenBase




...{


public:


void CopyScreen();


void SaveFile(TCHAR *pszPath);


CScreenBase();


virtual ~CScreenBase();


void Initialize(const RECT *prcScr = NULL);




protected:


void Destroy();


typedef struct




...{


HDC hDC; //The DC save the screed DC


HGDIOBJ hOldSel; //The old object of save DC


HBITMAP hBmpSel; //The selected bitmap


}SAVEDCINFO,*LPSAVEDCINFO;


SAVEDCINFO m_SaveDCInfo;




typedef struct




...{


BYTE *lpBitmapBits; //Pointer to a variable that receives a pointer to the location of the device-independent bitmap's bit values


BITMAPINFO bitMapInfo; //The savebitmap info


}SAVEBITMAPINFO,*LPSAVEBITMAPINFO;


SAVEBITMAPINFO m_SaveBitmapInfo;




void SaveFile(LPSAVEBITMAPINFO lpSaveBitmapInfo,TCHAR *pszPath);


void InitializeSaveDC(LPSAVEDCINFO lpSaveDCInfo,LPSAVEBITMAPINFO lpSaveBitmapInfo,const RECT *prcSave);


void DestroySaveDC(LPSAVEDCINFO lpSaveDCInfo,LPSAVEBITMAPINFO lpSaveBitmapInfo);


void CopyScreenDC(HDC *pHdcDest,const LPSAVEBITMAPINFO lpSaveBitmapInfo,const RECT *prcSrc);




RECT m_rcSave; //The area for saving


HDC m_hScrDC; //The handle DC of screen


};






//--------------------------------------------------------------------------


#endif // !defined SCREENBASE_H










/**///////////////////////////////////////////////////////////////////////


// ScreenBase.cpp: implementation of the CScreenBase class.




/**///////////////////////////////////////////////////////////////////////




#include "stdafx.h"


#include "ScreenBase.h"






/**///////////////////////////////////////////////////////////////////////


// Construction/Destruction




/**///////////////////////////////////////////////////////////////////////




CScreenBase::CScreenBase()




...{


memset(&m_rcSave,0,sizeof(m_rcSave));


m_hScrDC = NULL;


}




CScreenBase::~CScreenBase()




...{


Destroy();


}




//----------------------------------------------------------------------


//Description:


// Destroy the save DC


//--------------------------------------------------------------------


void CScreenBase::DestroySaveDC(LPSAVEDCINFO lpSaveDCInfo, LPSAVEBITMAPINFO lpSaveBitmapInfo)




...{


if(lpSaveDCInfo->hDC != NULL && lpSaveDCInfo->hOldSel != NULL)




...{


SelectObject(lpSaveDCInfo->hDC, lpSaveDCInfo->hOldSel);


}




if(lpSaveDCInfo->hDC != NULL)




...{


DeleteDC(lpSaveDCInfo->hDC);


}




if(lpSaveDCInfo->hBmpSel != NULL)




...{


DeleteObject(lpSaveDCInfo->hBmpSel);


}




memset(lpSaveDCInfo,0,sizeof(SAVEDCINFO));


memset(lpSaveBitmapInfo,0,sizeof(SAVEBITMAPINFO));


}




//----------------------------------------------------------------------


//Description:


// Initialize the save DC


//--------------------------------------------------------------------


void CScreenBase::InitializeSaveDC(LPSAVEDCINFO lpSaveDCInfo, LPSAVEBITMAPINFO lpSaveBitmapInfo,const RECT *prcSave)




...{




//the pointer will save all pixel point's color value


lpSaveBitmapInfo->lpBitmapBits = NULL;






//creates a memory device context (DC) compatible with the screen device(hScrDC)


lpSaveDCInfo->hDC = CreateCompatibleDC(m_hScrDC);






//Initialise the struct BITMAPINFO for the bimap infomation,


//in order to use the function CreateDIBSection on wince os,


//each pixel stored by 24 bits(biBitCount=24) and no compressing(biCompression=0)


ZeroMemory(&m_SaveBitmapInfo.bitMapInfo, sizeof(BITMAPINFO));


lpSaveBitmapInfo->bitMapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);


lpSaveBitmapInfo->bitMapInfo.bmiHeader.biWidth = prcSave->right - prcSave->left;


lpSaveBitmapInfo->bitMapInfo.bmiHeader.biHeight = prcSave->bottom - prcSave->top;


lpSaveBitmapInfo->bitMapInfo.bmiHeader.biPlanes = 1;


lpSaveBitmapInfo->bitMapInfo.bmiHeader.biBitCount = 24;




//use the function CreateDIBSection and SelectObject in order to get the bimap pointer : lpBitmapBits


lpSaveDCInfo->hBmpSel = CreateDIBSection(lpSaveDCInfo->hDC,


&lpSaveBitmapInfo->bitMapInfo,


DIB_RGB_COLORS,


(void **)&lpSaveBitmapInfo->lpBitmapBits,


NULL,


0);


lpSaveDCInfo->hOldSel = SelectObject(lpSaveDCInfo->hDC, lpSaveDCInfo->hBmpSel);






}




//----------------------------------------------------------------------


//Description:


// Save the bitmap of save dc to the file


//--------------------------------------------------------------------


void CScreenBase::SaveFile(LPSAVEBITMAPINFO lpSaveBitmapInfo, TCHAR *pszPath)




...{




int iWidth = lpSaveBitmapInfo->bitMapInfo.bmiHeader.biWidth;


int iHeight = lpSaveBitmapInfo->bitMapInfo.bmiHeader.biHeight;




//If you only want to get the every pixel color value,


//you can begin here and the following part of this function will be unuseful;


//the following part is in order to write file;




//Bimap file header in order to write bmp file


BITMAPFILEHEADER bmBITMAPFILEHEADER;


ZeroMemory(&bmBITMAPFILEHEADER, sizeof(BITMAPFILEHEADER));


bmBITMAPFILEHEADER.bfType = 0x4d42; //bmp


bmBITMAPFILEHEADER.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);




bmBITMAPFILEHEADER.bfSize = bmBITMAPFILEHEADER.bfOffBits + ((iWidth * iHeight) * 3); /**////norains:3=(24 / 8)




//write into file


FILE *mStream = NULL;


if((mStream = _tfopen(pszPath, TEXT("wb"))))




...{


//write bitmap file header


fwrite(&bmBITMAPFILEHEADER, sizeof(BITMAPFILEHEADER), 1, mStream);


//write bitmap info


fwrite(&(lpSaveBitmapInfo->bitMapInfo.bmiHeader), sizeof(BITMAPINFOHEADER), 1, mStream);


//write bitmap pixels data


fwrite(lpSaveBitmapInfo->lpBitmapBits, 3*iWidth*iHeight, 1, mStream);


//close file


fclose(mStream);


}


}






//----------------------------------------------------------------------


//Description:


// Copy the screen DC to the dest DC


//--------------------------------------------------------------------


void CScreenBase::CopyScreenDC(HDC *pHdcDest,const LPSAVEBITMAPINFO lpSaveBitmapInfo,const RECT *prcSrc)




...{


// copy the screen dc to the memory dc


BitBlt(*pHdcDest, 0, 0, lpSaveBitmapInfo->bitMapInfo.bmiHeader.biWidth, lpSaveBitmapInfo->bitMapInfo.bmiHeader.biHeight, m_hScrDC, prcSrc->left, prcSrc->top, SRCCOPY);


}






//----------------------------------------------------------------------


//Description:


// Initialize the instance


//--------------------------------------------------------------------


void CScreenBase::Initialize(const RECT *prcScr)




...{


Destroy();


//creates a device context for the screen device


m_hScrDC = CreateDC(_T("DISPLAY"), NULL, NULL, NULL);


if(prcScr != NULL)




...{


m_rcSave = *prcScr;


}


else




...{


//Get the full window


int iWidth = GetDeviceCaps(m_hScrDC, HORZRES);


int iHeight = GetDeviceCaps(m_hScrDC, VERTRES);


m_rcSave.left = 0;


m_rcSave.top = 0;


m_rcSave.bottom = iHeight;


m_rcSave.right = iWidth;


}


InitializeSaveDC(&m_SaveDCInfo,&m_SaveBitmapInfo,&m_rcSave);


}






//----------------------------------------------------------------------


//Description:


// Destroy all the resource


//--------------------------------------------------------------------


void CScreenBase::Destroy()




...{


if(m_hScrDC != NULL)




...{


DeleteDC(m_hScrDC);


m_hScrDC = NULL;


}


DestroySaveDC(&m_SaveDCInfo,&m_SaveBitmapInfo);


}






//----------------------------------------------------------------------


//Description:


// Save the bitmap of screen to the file


//--------------------------------------------------------------------


void CScreenBase::SaveFile(TCHAR *pszPath)




...{


SaveFile(&m_SaveBitmapInfo,pszPath);


}




//----------------------------------------------------------------------


//Description:


// Copy the screen to the save DC


//--------------------------------------------------------------------


void CScreenBase::CopyScreen()




...{


CopyScreenDC(&m_SaveDCInfo.hDC,&m_SaveBitmapInfo,&m_rcSave);


}



2.如何截取屏幕

采用CScreenBase类截取全屏非常简单:

首先声明一个CScreenBase类对象:


CScreenBase scrBase;

接着便是初始化:


scrBase.Initialize();

拷贝屏幕图像:


scrBase.CopyScreen();

最后,把截屏保存到文件中:


scrBase.SaveFile(TEXT("Capture.bmp"));

如果是截取屏幕的某个区域,需要在初始化的时候确定区域.
例如,我们需要截取屏幕上以(20,20)为起点,对角为(50,60)的区域,只需更改初始化代码即可:




RECT rcWnd = ...{20,20,50,60};


scrBase.Initialize(&rcWnd);

3.进阶用法:将截取的区域直接显示到屏幕

因为CScreenBase类本意是作为一个截图的基本类,所以没有封装直接显示到屏幕的方法.不过,我们可以继承该类,然后返回保存区域图片的句柄,最后将其显示于屏幕即可.

派生一个ScreenPro类,用来返回所需的句柄.


class ScreenPro: public CScreenBase




...{


public:




HDC GetSaveDC()...{return m_SaveDCInfo.hDC;};




RECT GetSaveRect()...{return m_rcSave;};


};

最后我们只需在WM_PAINT消息相应函数将保存的区域像素绘制出来即可:


//----------------------------------------------------------------------


//Description:


// On message WM_PAINT


//--------------------------------------------------------------------


void OnPaint(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)




...{




if(m_bScrCapture == TRUE)




...{


//如果已经截屏,则将其显示于屏幕上




PAINTSTRUCT ps;


HDC hdc = BeginPaint(hWnd,&ps);




//获取截屏的区域


RECT rcWnd ;


rcWnd = m_ScrCapture.GetSaveRect();




//获取截屏数据保存的DC


HDC hSaveDC = NULL;


hSaveDC = m_ScrCapture.GetSaveDC();




//绘制到屏幕


BitBlt(hdc,rcWnd.left,rcWnd.top,rcWnd.right,rcWnd.bottom,hSaveDC,0,0,SRCCOPY);


EndPaint(hWnd,&ps);


}


else




...{


DefWindowProc(hWnd,wMsg,wParam,lParam);


}


}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: