C++使用BitBlt进行窗口抓图的方法
本文使用C++双缓存进行指定窗口截图。CreateDIBSection创建应用程序可以直接写入的、与设备无关的位图(DIB),它提供内存中位图的指针,外部程序可以直接使用。
需要注意的是,BitBlt方法只能抓图普通窗口的截图,对于使用D3D渲染的窗口(例如Excel、Win10自带视频播放器)则只能获取黑屏。
1、DibCaptureHelper.h
#pragmaonce #include#include usingstd::string; classDibCaptureHelper { public: DibCaptureHelper(); virtual~DibCaptureHelper(); boolInit(conststring&windowName); boolInit(HWNDhwnd); voidCleanup(); boolRefreshWindow(); boolChangeWindowHandle(conststring&windowName); boolChangeWindowHandle(HWNDhwnd); boolCapture()const; constRECT&GetWindowRect()const{returnwindowRect_;} constRECT&GetClientRect()const{returnclientRect_;} intGetBitmapDataSize()const{returnbmpDataSize_;} HBITMAPGetBitmap()const{returnbitmap_;} void*GetBitmapAddress()const{returnbitsPtr_;} private: HWNDhwnd_; HDCscrDc_; HDCmemDc_; HBITMAPbitmap_; HBITMAPoldBitmap_; void*bitsPtr_; RECTwindowRect_; RECTclientRect_; POINTbitbltStartPoint_; intbmpDataSize_; };
2、DibCaptureHelper.cpp
#include"stdafx.h"
#include"DibCaptureHelper.h"
DibCaptureHelper::DibCaptureHelper()
:hwnd_(nullptr)
,scrDc_(nullptr)
,memDc_(nullptr)
,bitmap_(nullptr)
,oldBitmap_(nullptr)
,bitsPtr_(nullptr)
,windowRect_{0,0,0,0}
,clientRect_{0,0,0,0}
,bitbltStartPoint_{0,0}
,bmpDataSize_(0)
{
}
DibCaptureHelper::~DibCaptureHelper()
{
Cleanup();
}
boolDibCaptureHelper::Init(conststring&windowName)
{
constautohandle=::FindWindowA(nullptr,windowName.c_str());
if(handle==nullptr)
{
returnfalse;
}
returnInit(handle);
}
boolDibCaptureHelper::Init(HWNDhwnd)
{
hwnd_=hwnd;
//获取窗口大小
if(!::GetWindowRect(hwnd_,&windowRect_)||!::GetClientRect(hwnd_,&clientRect_))
{
returnfalse;
}
constautoclientRectWidth=clientRect_.right-clientRect_.left;
constautoclientRectHeight=clientRect_.bottom-clientRect_.top;
bmpDataSize_=clientRectWidth*clientRectHeight*4;
bitbltStartPoint_.x=0;
bitbltStartPoint_.y=0;
//位图信息
BITMAPINFObitmapInfo;
bitmapInfo.bmiHeader.biSize=sizeof(bitmapInfo);
bitmapInfo.bmiHeader.biWidth=clientRectWidth;
bitmapInfo.bmiHeader.biHeight=clientRectHeight;
bitmapInfo.bmiHeader.biPlanes=1;
bitmapInfo.bmiHeader.biBitCount=32;
bitmapInfo.bmiHeader.biSizeImage=clientRectWidth*clientRectHeight;
bitmapInfo.bmiHeader.biCompression=BI_RGB;
scrDc_=::GetWindowDC(hwnd_);//获取窗口DC
memDc_=::CreateCompatibleDC(scrDc_);//缓冲内存DC
bitmap_=::CreateDIBSection(memDc_,&bitmapInfo,DIB_RGB_COLORS,&bitsPtr_,nullptr,0);
if(bitmap_==nullptr)
{
::DeleteDC(memDc_);
::ReleaseDC(hwnd_,scrDc_);
returnfalse;
}
oldBitmap_=static_cast(::SelectObject(memDc_,bitmap_));
returntrue;
}
voidDibCaptureHelper::Cleanup()
{
if(bitmap_==nullptr)
{
return;
}
//删除用过的对象
::SelectObject(memDc_,oldBitmap_);
::DeleteObject(bitmap_);
::DeleteDC(memDc_);
::ReleaseDC(hwnd_,scrDc_);
hwnd_=nullptr;
scrDc_=nullptr;
memDc_=nullptr;
bitmap_=nullptr;
oldBitmap_=nullptr;
bitsPtr_=nullptr;
}
boolDibCaptureHelper::RefreshWindow()
{
constautohwnd=hwnd_;
Cleanup();
returnInit(hwnd);
}
boolDibCaptureHelper::ChangeWindowHandle(conststring&windowName)
{
Cleanup();
returnInit(windowName);
}
boolDibCaptureHelper::ChangeWindowHandle(HWNDhwnd)
{
Cleanup();
returnInit(hwnd);
}
boolDibCaptureHelper::Capture()const
{
if(bitmap_==nullptr||memDc_==nullptr||scrDc_==nullptr)
{
returnfalse;
}
constautoclientRectWidth=clientRect_.right-clientRect_.left;
constautoclientRectHeight=clientRect_.bottom-clientRect_.top;
constautoret=::BitBlt(
memDc_,0,0,clientRectWidth,clientRectHeight,
scrDc_,bitbltStartPoint_.x,bitbltStartPoint_.y,
SRCCOPY);
returnret!=0;
}
以上就是C++使用BitBlt进行窗口抓图的方法的详细内容,更多关于c++窗口抓图的资料请关注毛票票其它相关文章!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。