//========================================================================
//TITLE:
// ScreenBase 实现屏幕任意区域的截取
//AUTHOR:
// norains
//DATE:
// Tuesday 16-January -2007
//Environment:
// EVC4.0 + Standard SDK
//========================================================================
//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 类对象 :
CScreenBase scrBase;
接着便是初始化
:
scrBase.Initialize();
拷贝屏幕图像 :
scrBase.CopyScreen();
最后 , 把截屏保存到文件中 :
scrBase.SaveFile(TEXT("Capture.bmp"));
如果是截取屏幕的某个区域 , 需要在初始化的时候确定区域 .
例如 , 我们需要截取屏幕上以 (20,20) 为起点 , 对角为 (50,60) 的区域 , 只需更改初始化代码即可 :
RECT rcWnd = ...{20,20,50,60};
scrBase.Initialize(&rcWnd);
scrBase.Initialize(&rcWnd);
3. 进阶用法 : 将截取的区域直接显示到屏幕
因为
CScreenBase
类本意是作为一个截图的基本类
,
所以没有封装直接显示到屏幕的方法
.
不过
,
我们可以继承该类
,
然后返回保存区域图片的句柄
,
最后将其显示于屏幕即可
.
派生一个 ScreenPro 类 , 用来返回所需的句柄 .
派生一个 ScreenPro 类 , 用来返回所需的句柄 .
class ScreenPro: public CScreenBase
...{
public:
HDC GetSaveDC()...{return m_SaveDCInfo.hDC;};
RECT GetSaveRect()...{return m_rcSave;};
};
...{
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);
}
}
//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);
}
}
ScreenBase是一个用于截取屏幕任意区域并保存为BMP文件的API类。通过简单的几个步骤即可完成全屏或指定区域的截图,并能进一步实现屏幕显示。
3611

被折叠的 条评论
为什么被折叠?



