在VC中怎样截取屏幕?
3个回答
展开全部
//PrintScreen.h 文件
#pragma once
#include <string>
using namespace std;
class PrintScreen
{
public:
PrintScreen();
~PrintScreen();
public:
bool GetBmp( string sBmpName);
protected:
bool WriteBmpToFile(HBITMAP&m_hBitmap);
public:
string sBmpName;
};
//PrintScreen.cpp 文件
#include "StdAfx.h"
#include "PrintScreen.h"
PrintScreen::PrintScreen()
{
}
PrintScreen::~PrintScreen()
{
}
bool PrintScreen::GetBmp( string sBmpName) //获得图片
{
bool bRet = true;
HBITMAP m_hBitmap = NULL;
do
{
this->sBmpName = sBmpName;
//图片的句柄
HWND hWnd = ::GetDesktopWindow(); //获得屏幕的HWND.
HWND hWndF = ::GetForegroundWindow(); //获得当前活动窗口
HDC hScreenDC = ::GetDC(hWnd); //获得屏幕的HDC.
HDC MemDC = ::CreateCompatibleDC(hScreenDC);
RECT rect; //要截屏的矩形
::GetWindowRect(hWndF,&rect); //获得当前活动窗口的大小(截取的大小位置)
//::GetWindowRect(hWnd,&rect); //截取桌面
SIZE screensize;
screensize.cx = rect.right - rect.left;
screensize.cy = rect.bottom - rect.top;
do
{
m_hBitmap = ::CreateCompatibleBitmap( hScreenDC, screensize.cx, screensize.cy );
}while( m_hBitmap == NULL );
HGDIOBJ hOldBMP = ::SelectObject( MemDC, m_hBitmap );
::BitBlt( MemDC, 0, 0, screensize.cx, screensize.cy, hScreenDC, rect.left, rect.top, SRCCOPY );
::SelectObject( MemDC, hOldBMP );
::DeleteObject( MemDC );
::ReleaseDC( hWnd, hScreenDC );
if ( !( this->WriteBmpToFile( m_hBitmap) ) ) //保存文件
{
bRet = true;
break;
}
} while ( false );
DeleteObject( m_hBitmap );
return bRet;
}
bool PrintScreen::WriteBmpToFile( HBITMAP & m_hBitmap ) //保存bmp图片
{
bool bRet = true;
do
{
HDC hDC = ::CreateDC( "DISPLAY", NULL,NULL,NULL );
int iBits = ::GetDeviceCaps( hDC, BITSPIXEL ) * ::GetDeviceCaps( hDC, PLANES );//当前分辨率下每个像素所占字节数
::DeleteDC( hDC );
WORD wBitCount; //位图中每个像素所占字节数
if ( iBits <= 1 )
wBitCount = 1;
else if ( iBits <= 4 )
wBitCount = 4;
else if ( iBits <= 8 )
wBitCount = 8;
else if ( iBits <= 24 )
wBitCount = 24;
else
wBitCount = iBits;
DWORD dwPaletteSize=0; //调色板大小,位图中像素字节大小
if ( wBitCount <= 8 )
dwPaletteSize = ( 1 << wBitCount) * sizeof( RGBQUAD );
BITMAP bm; //位图属性结构
::GetObject( m_hBitmap, sizeof( bm ), ( LPSTR )& bm );
BITMAPINFOHEADER bi, bi1; //位图信息头结构
bi.biSize = sizeof( BITMAPINFOHEADER );
bi.biWidth = bm.bmWidth;
bi.biHeight = bm.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = wBitCount;
bi.biCompression = BI_RGB; //BI_RGB表示位图没有压缩
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
bi1 = bi;
bi1.biBitCount = 24;
DWORD dwBmBitsSize = ( ( bm.bmWidth * wBitCount + 31 ) / 32 ) * 4 * bm.bmHeight;
HANDLE hDib = ::GlobalAlloc( GHND, dwBmBitsSize + dwPaletteSize + sizeof( BITMAPINFOHEADER ) ); //为位图内容分配内存
LPBITMAPINFOHEADER lpbi = ( LPBITMAPINFOHEADER )GlobalLock( hDib );
*lpbi = bi;
HANDLE hPal = ::GetStockObject( DEFAULT_PALETTE ); // 处理调色板
HANDLE hOldPal = NULL;
if ( hPal )
{
hDC = ::GetDC( NULL );
hOldPal = SelectPalette( hDC,(HPALETTE)hPal, FALSE );
RealizePalette( hDC );
}
int nOutputBytes = 0;
unsigned char *pJpp, *m_pDibBits;
pJpp = new unsigned char [ dwBmBitsSize ];
m_pDibBits = new unsigned char [ dwBmBitsSize ];
::GetDIBits( hDC, m_hBitmap, 0, ( unsigned int ) bm.bmHeight,(LPSTR)lpbi + sizeof( BITMAPINFOHEADER ) + dwPaletteSize, ( BITMAPINFO* )lpbi, DIB_RGB_COLORS );// 获取该调色板下新的像素值
if ( hOldPal ) //恢复调色板
{
SelectPalette( hDC, ( HPALETTE )hOldPal, TRUE );
RealizePalette( hDC );
::ReleaseDC( NULL, hDC );
}
BITMAPFILEHEADER bmfHdr; //位图文件头结构 0
bmfHdr.bfType = 0x4D42; // "BM"设置位图文件头
DWORD 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;
HANDLE hFile = ::CreateFile( this->sBmpName.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);//创建位图文件
DWORD dwWritten;
WriteFile( hFile, ( LPSTR )&bmfHdr, sizeof( BITMAPFILEHEADER ), &dwWritten, NULL ); // 写入位图文件头
WriteFile( hFile, ( LPSTR )lpbi, dwDIBSize, &dwWritten, NULL ); // 写入位图文件其余内容
GlobalUnlock( hDib ); //清除
GlobalFree( hDib );
CloseHandle( hFile );
delete []pJpp;
delete []m_pDibBits;
}while( false );
return bRet;
}
#pragma once
#include <string>
using namespace std;
class PrintScreen
{
public:
PrintScreen();
~PrintScreen();
public:
bool GetBmp( string sBmpName);
protected:
bool WriteBmpToFile(HBITMAP&m_hBitmap);
public:
string sBmpName;
};
//PrintScreen.cpp 文件
#include "StdAfx.h"
#include "PrintScreen.h"
PrintScreen::PrintScreen()
{
}
PrintScreen::~PrintScreen()
{
}
bool PrintScreen::GetBmp( string sBmpName) //获得图片
{
bool bRet = true;
HBITMAP m_hBitmap = NULL;
do
{
this->sBmpName = sBmpName;
//图片的句柄
HWND hWnd = ::GetDesktopWindow(); //获得屏幕的HWND.
HWND hWndF = ::GetForegroundWindow(); //获得当前活动窗口
HDC hScreenDC = ::GetDC(hWnd); //获得屏幕的HDC.
HDC MemDC = ::CreateCompatibleDC(hScreenDC);
RECT rect; //要截屏的矩形
::GetWindowRect(hWndF,&rect); //获得当前活动窗口的大小(截取的大小位置)
//::GetWindowRect(hWnd,&rect); //截取桌面
SIZE screensize;
screensize.cx = rect.right - rect.left;
screensize.cy = rect.bottom - rect.top;
do
{
m_hBitmap = ::CreateCompatibleBitmap( hScreenDC, screensize.cx, screensize.cy );
}while( m_hBitmap == NULL );
HGDIOBJ hOldBMP = ::SelectObject( MemDC, m_hBitmap );
::BitBlt( MemDC, 0, 0, screensize.cx, screensize.cy, hScreenDC, rect.left, rect.top, SRCCOPY );
::SelectObject( MemDC, hOldBMP );
::DeleteObject( MemDC );
::ReleaseDC( hWnd, hScreenDC );
if ( !( this->WriteBmpToFile( m_hBitmap) ) ) //保存文件
{
bRet = true;
break;
}
} while ( false );
DeleteObject( m_hBitmap );
return bRet;
}
bool PrintScreen::WriteBmpToFile( HBITMAP & m_hBitmap ) //保存bmp图片
{
bool bRet = true;
do
{
HDC hDC = ::CreateDC( "DISPLAY", NULL,NULL,NULL );
int iBits = ::GetDeviceCaps( hDC, BITSPIXEL ) * ::GetDeviceCaps( hDC, PLANES );//当前分辨率下每个像素所占字节数
::DeleteDC( hDC );
WORD wBitCount; //位图中每个像素所占字节数
if ( iBits <= 1 )
wBitCount = 1;
else if ( iBits <= 4 )
wBitCount = 4;
else if ( iBits <= 8 )
wBitCount = 8;
else if ( iBits <= 24 )
wBitCount = 24;
else
wBitCount = iBits;
DWORD dwPaletteSize=0; //调色板大小,位图中像素字节大小
if ( wBitCount <= 8 )
dwPaletteSize = ( 1 << wBitCount) * sizeof( RGBQUAD );
BITMAP bm; //位图属性结构
::GetObject( m_hBitmap, sizeof( bm ), ( LPSTR )& bm );
BITMAPINFOHEADER bi, bi1; //位图信息头结构
bi.biSize = sizeof( BITMAPINFOHEADER );
bi.biWidth = bm.bmWidth;
bi.biHeight = bm.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = wBitCount;
bi.biCompression = BI_RGB; //BI_RGB表示位图没有压缩
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
bi1 = bi;
bi1.biBitCount = 24;
DWORD dwBmBitsSize = ( ( bm.bmWidth * wBitCount + 31 ) / 32 ) * 4 * bm.bmHeight;
HANDLE hDib = ::GlobalAlloc( GHND, dwBmBitsSize + dwPaletteSize + sizeof( BITMAPINFOHEADER ) ); //为位图内容分配内存
LPBITMAPINFOHEADER lpbi = ( LPBITMAPINFOHEADER )GlobalLock( hDib );
*lpbi = bi;
HANDLE hPal = ::GetStockObject( DEFAULT_PALETTE ); // 处理调色板
HANDLE hOldPal = NULL;
if ( hPal )
{
hDC = ::GetDC( NULL );
hOldPal = SelectPalette( hDC,(HPALETTE)hPal, FALSE );
RealizePalette( hDC );
}
int nOutputBytes = 0;
unsigned char *pJpp, *m_pDibBits;
pJpp = new unsigned char [ dwBmBitsSize ];
m_pDibBits = new unsigned char [ dwBmBitsSize ];
::GetDIBits( hDC, m_hBitmap, 0, ( unsigned int ) bm.bmHeight,(LPSTR)lpbi + sizeof( BITMAPINFOHEADER ) + dwPaletteSize, ( BITMAPINFO* )lpbi, DIB_RGB_COLORS );// 获取该调色板下新的像素值
if ( hOldPal ) //恢复调色板
{
SelectPalette( hDC, ( HPALETTE )hOldPal, TRUE );
RealizePalette( hDC );
::ReleaseDC( NULL, hDC );
}
BITMAPFILEHEADER bmfHdr; //位图文件头结构 0
bmfHdr.bfType = 0x4D42; // "BM"设置位图文件头
DWORD 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;
HANDLE hFile = ::CreateFile( this->sBmpName.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);//创建位图文件
DWORD dwWritten;
WriteFile( hFile, ( LPSTR )&bmfHdr, sizeof( BITMAPFILEHEADER ), &dwWritten, NULL ); // 写入位图文件头
WriteFile( hFile, ( LPSTR )lpbi, dwDIBSize, &dwWritten, NULL ); // 写入位图文件其余内容
GlobalUnlock( hDib ); //清除
GlobalFree( hDib );
CloseHandle( hFile );
delete []pJpp;
delete []m_pDibBits;
}while( false );
return bRet;
}
本回答被提问者采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
Alt+Prt Sc
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询