C++ 使用PrintWindow實現(xiàn)窗口截圖功能
本文使用C++雙緩存進行指定窗口截圖。CreateDIBSection創(chuàng)建應(yīng)用程序可以直接寫入的、與設(shè)備無關(guān)的位圖(DIB),它提供內(nèi)存中位圖的指針,外部程序可以直接使用。
需要注意的是,PrintWindow方法能夠抓取使用D3D渲染的窗口(例如Excel、Win10自帶視頻播放器),如果抓取普通窗口則會附帶窗口陰影,可見窗口陰影是Windows使用D3D渲染出來的。
1、PrintCaptureHelper.h
#pragma once #include <windows.h> #include <string> using std::string; class PrintCaptureHelper { public: PrintCaptureHelper(); virtual ~PrintCaptureHelper(); 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_; int bmpDataSize_; };
2、PrintCaptureHelper.cpp
#include "stdafx.h" #include "PrintCaptureHelper.h" PrintCaptureHelper::PrintCaptureHelper() : hwnd_(nullptr) , scrDc_(nullptr) , memDc_(nullptr) , bitmap_(nullptr) , oldBitmap_(nullptr) , bitsPtr_(nullptr) , windowRect_{ 0, 0, 0, 0 } , clientRect_{ 0, 0, 0, 0 } , bmpDataSize_(0) { } PrintCaptureHelper::~PrintCaptureHelper() { Cleanup(); } bool PrintCaptureHelper::Init(const string& windowName) { const auto handle = ::FindWindowA(nullptr, windowName.c_str()); if (handle == nullptr) { return false; } return Init(handle); } bool PrintCaptureHelper::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; //位圖信息 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_); memDc_ = ::CreateCompatibleDC(scrDc_); bitmap_ = ::CreateDIBSection(scrDc_, &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 PrintCaptureHelper::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; } bool PrintCaptureHelper::RefreshWindow() { const auto hwnd = hwnd_; Cleanup(); return Init(hwnd); } bool PrintCaptureHelper::ChangeWindowHandle(const string& windowName) { Cleanup(); return Init(windowName); } bool PrintCaptureHelper::ChangeWindowHandle(HWND hwnd) { Cleanup(); return Init(hwnd); } bool PrintCaptureHelper::Capture() const { if (bitmap_ == nullptr || memDc_ == nullptr || scrDc_ == nullptr) { return false; } const auto ret = ::PrintWindow(hwnd_, memDc_, PW_CLIENTONLY | PW_RENDERFULLCONTENT); return ret != 0; }
以上就是C++ 使用PrintWindow實現(xiàn)窗口截圖功能的詳細內(nèi)容,更多關(guān)于c++ 窗口截圖的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C語言全部內(nèi)存操作函數(shù)的實現(xiàn)詳細講解
這篇文章主要介紹了C語言全部內(nèi)存操作函數(shù)的實現(xiàn)詳細講解,作者用圖文代碼實例講解的很清晰,有感興趣的同學(xué)可以研究下2021-02-02MySQL系列教程之使用C語言來連接數(shù)據(jù)庫
c語言操作Mysql數(shù)據(jù)庫,主要就是為了實現(xiàn)對數(shù)據(jù)庫的增、刪、改、查等操作,下面這篇文章主要給大家介紹了關(guān)于MySQL系列教程之使用C語言來連接數(shù)據(jù)庫的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2022-09-09Mingw64編譯wxWidgets 3.0.2常見錯誤分析
這篇文章主要介紹了Mingw64編譯wxWidgets 3.0.2常見錯誤分析,需要的朋友可以參考下2016-11-11c++如何控制對象的創(chuàng)建方式(禁止創(chuàng)建棧對象or堆對象)和創(chuàng)建的數(shù)量
這篇文章主要介紹了c++如何控制對象的創(chuàng)建方式和創(chuàng)建的數(shù)量,幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下2020-08-08利用C++開發(fā)一個protobuf動態(tài)解析工具
數(shù)據(jù)庫中存儲的protobuf序列化的內(nèi)容,有時候查問題想直接解析查看內(nèi)容。很多編碼在網(wǎng)上很容易找到編解碼工具,但protobuf沒有找到編解碼工具,可能這樣的需求比較少吧,那就自己用C++實現(xiàn)一個,感興趣的可以了解一下2023-01-01