C++使用BitBlt函数进行窗口抓图的示例代码

近期有些网友想要了解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函数进行窗口抓图的详细解析,我们了解了整个抓图过程的步骤和关键点。BitBlt函数可以将一个设备上下文的内容复制到另一个设备上下文中,从而实现屏幕或窗口的抓图。本文提供的示例代码展示了如何在C++中使用BitBlt函数进行窗口抓图,并处理了一些常见的错误和异常情况。通过本文的学习,开发者可以掌握在C++中使用BitBlt函数进行窗口抓图的方法,提高图像处理的效率和质量。希望本文的内容能为读者在实际项目中提供有价值的参考和帮助。无论是处理用户界面的截图,还是实现自动化测试工具,本文的示例代码和方法都能为开发者提供有效的解决方案。

发布于 2025-01-14 03:28:29
分享
海报
107
上一篇:SQLServer中Partition By和row_number 函数使用方法详解 下一篇:Python运行报错:IndentationError: expected an indented block的解决方法
目录

    忘记密码?

    图形验证码