C++使用BitBlt进行窗口抓图的方法

这篇文章主要介绍了C++使用BitBlt进行窗口抓图的方法,帮助大家更好的理解和使用c++,感兴趣的朋友可以了解下

本文使用C++双缓存进行指定窗口截图。CreateDIBSection创建应用程序可以直接写入的、与设备无关的位图(DIB),它提供内存中位图的指针,外部程序可以直接使用。

需要注意的是,BitBlt方法只能抓图普通窗口的截图,对于使用D3D渲染的窗口(例如Excel、Win10自带视频播放器)则只能获取黑屏。

1、DibCaptureHelper.h

 #pragma once   #include  #include  using std::string;   class DibCaptureHelper { public:     DibCaptureHelper();     virtual ~DibCaptureHelper();       bool Init(const string& windowName);     bool Init(HWND hwnd);     void Cleanup();     bool RefreshWindow();     bool ChangeWindowHandle(const string& windowName);     bool ChangeWindowHandle(HWND hwnd);     bool Capture() const;       const RECT& GetWindowRect() const { return windowRect_; }     const RECT& GetClientRect() const { return clientRect_; }     int GetBitmapDataSize() const { return bmpDataSize_; }     HBITMAP GetBitmap() const { return bitmap_; }     void* GetBitmapAddress() const { return bitsPtr_; }   private:     HWND hwnd_;     HDC scrDc_;     HDC memDc_;     HBITMAP bitmap_;     HBITMAP oldBitmap_;     void* bitsPtr_;       RECT windowRect_;     RECT clientRect_;     POINT bitbltStartPoint_;     int bmpDataSize_; };

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(); }   bool DibCaptureHelper::Init(const string& windowName) {     const auto handle = ::FindWindowA(nullptr, windowName.c_str());     if (handle == nullptr)     {         return false;     }       return Init(handle); }   bool DibCaptureHelper::Init(HWND hwnd) {     hwnd_ = hwnd;       //获取窗口大小     if (!::GetWindowRect(hwnd_, &windowRect_) || !::GetClientRect(hwnd_, &clientRect_))     {         return false;     }       const auto clientRectWidth = clientRect_.right - clientRect_.left;     const auto clientRectHeight = clientRect_.bottom - clientRect_.top;     bmpDataSize_ = clientRectWidth * clientRectHeight * 4;       bitbltStartPoint_.x = 0;     bitbltStartPoint_.y = 0;       //位图信息     BITMAPINFO bitmapInfo;     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_);         return false;     }       oldBitmap_ = static_cast(::SelectObject(memDc_, bitmap_));     return true; }   void DibCaptureHelper::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; }   bool DibCaptureHelper::RefreshWindow() {     const auto hwnd = hwnd_;     Cleanup();     return Init(hwnd); }   bool DibCaptureHelper::ChangeWindowHandle(const string& windowName) {     Cleanup();     return Init(windowName); }   bool DibCaptureHelper::ChangeWindowHandle(HWND hwnd) {     Cleanup();     return Init(hwnd); }   bool DibCaptureHelper::Capture() const {     if (bitmap_ == nullptr || memDc_ == nullptr || scrDc_ == nullptr)     {         return false;     }       const auto clientRectWidth = clientRect_.right - clientRect_.left;     const auto clientRectHeight = clientRect_.bottom - clientRect_.top;       const auto ret = ::BitBlt(         memDc_, 0, 0, clientRectWidth, clientRectHeight,         scrDc_, bitbltStartPoint_.x, bitbltStartPoint_.y,         SRCCOPY);     return ret != 0; }

以上就是C++使用BitBlt进行窗口抓图的方法的详细内容,更多关于c++ 窗口抓图的资料请关注html中文网其它相关文章!

以上就是C++使用BitBlt进行窗口抓图的方法的详细内容,更多请关注0133技术站其它相关文章!

赞(0) 打赏
未经允许不得转载:0133技术站首页 » C语言