91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++ 使用PrintWindow實現窗口截圖功能的方法

發布時間:2020-08-10 11:32:42 來源:億速云 閱讀:1275 作者:小新 欄目:開發技術

這篇文章給大家分享的是有關C++ 使用PrintWindow實現窗口截圖功能的方法的內容。小編覺得挺實用的,因此分享給大家做個參考。一起跟隨小編過來看看吧。

本文使用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實現窗口截圖功能的方法就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

瑞安市| 罗山县| 山阳县| 揭东县| 浮山县| 双鸭山市| 长泰县| 织金县| 定安县| 龙井市| 逊克县| 温州市| 湾仔区| 邛崃市| 云梦县| 佛学| 万州区| 大丰市| 清原| 黄石市| 孟村| 那曲县| 云和县| 奉新县| 治多县| 泽州县| 乌拉特后旗| 三亚市| 阿克苏市| 鸡泽县| 丰台区| 旬阳县| 广安市| 宜川县| 双牌县| 龙岩市| 大连市| 左贡县| 蚌埠市| 策勒县| 崇州市|