如何用BitBlt函数实现复杂长尾词的窗口截图技巧?

2026-04-19 04:391阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计672个文字,预计阅读时间需要3分钟。

如何用BitBlt函数实现复杂长尾词的窗口截图技巧?

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

改写后:采用C++双缓冲技术,通过CreateDIBSection函数,应用程序能直接操作与设备无关的位图(DIB),实现指定窗口的截图。此函数提供内存中位图的指针,方便外部直接使用。

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

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

1、DibCaptureHelper.h

#pragma once #include <windows.h> #include <string> 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<HBITMAP>(::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++ 窗口抓图的资料请关注自由互联其它相关文章!

如何用BitBlt函数实现复杂长尾词的窗口截图技巧?
标签:方法本文

本文共计672个文字,预计阅读时间需要3分钟。

如何用BitBlt函数实现复杂长尾词的窗口截图技巧?

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

改写后:采用C++双缓冲技术,通过CreateDIBSection函数,应用程序能直接操作与设备无关的位图(DIB),实现指定窗口的截图。此函数提供内存中位图的指针,方便外部直接使用。

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

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

1、DibCaptureHelper.h

#pragma once #include <windows.h> #include <string> 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<HBITMAP>(::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++ 窗口抓图的资料请关注自由互联其它相关文章!

如何用BitBlt函数实现复杂长尾词的窗口截图技巧?
标签:方法本文