C++ 使用PrintWindow实现窗口截图功能
程序员文章站
2022-06-28 12:18:31
本文使用c++双缓存进行指定窗口截图。createdibsection创建应用程序可以直接写入的、与设备无关的位图(dib),它提供内存中位图的指针,外部程序可以直接使用。需要注意的是,printwi...
本文使用c++双缓存进行指定窗口截图。createdibsection创建应用程序可以直接写入的、与设备无关的位图(dib),它提供内存中位图的指针,外部程序可以直接使用。
需要注意的是,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实现窗口截图功能的详细内容,更多关于c++ 窗口截图的资料请关注其它相关文章!
上一篇: MyBatis-Plus Generator配置详解
下一篇: WML学习之二基本格式和文件头