转自:https://stackoverflow.co/questions/11283015

效果还是很不错的

#include <iostream>
#include <Windows.h>
#include <dxgi.h>
#include <inspectable.h>
#include <dxgi1_2.h>
#include <d3d11.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.System.h>
#include <winrt/Windows.Graphics.Capture.h>
#include <windows.graphics.capture.interop.h>
#include <windows.graphics.directx.direct3d11.interop.h>
#include <roerrorapi.h>
#include <shlobj_core.h>
#include <dwmapi.h>
#pragma comment(lib,"Dwmapi.lib")
#pragma comment(lib,"windowsapp.lib") void CaptureWindow(HWND hwndTarget)
{
// Init COM
winrt::init_apartment(winrt::apartment_type::multi_threaded); // Create Direct 3D Device
winrt::com_ptr<ID3D11Device> d3dDevice; winrt::check_hresult(D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, D3D11_CREATE_DEVICE_BGRA_SUPPORT,
nullptr, 0,D3D11_SDK_VERSION, d3dDevice.put(), nullptr, nullptr)); winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice device;
const auto dxgiDevice = d3dDevice.as<IDXGIDevice>();
{
winrt::com_ptr<::IInspectable> inspectable;
winrt::check_hresult(CreateDirect3D11DeviceFromDXGIDevice(dxgiDevice.get(), inspectable.put()));
device = inspectable.as<winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice>();
} auto idxgiDevice2 = dxgiDevice.as<IDXGIDevice2>();
winrt::com_ptr<IDXGIAdapter> adapter;
winrt::check_hresult(idxgiDevice2->GetParent(winrt::guid_of<IDXGIAdapter>(), adapter.put_void()));
winrt::com_ptr<IDXGIFactory2> factory;
winrt::check_hresult(adapter->GetParent(winrt::guid_of<IDXGIFactory2>(), factory.put_void())); ID3D11DeviceContext* d3dContext = nullptr;
d3dDevice->GetImmediateContext(&d3dContext); RECT rect{};
DwmGetWindowAttribute(hwndTarget, DWMWA_EXTENDED_FRAME_BOUNDS, &rect, sizeof(RECT));
const auto size = winrt::Windows::Graphics::SizeInt32{rect.right - rect.left, rect.bottom - rect.top}; winrt::Windows::Graphics::Capture::Direct3D11CaptureFramePool m_framePool =
winrt::Windows::Graphics::Capture::Direct3D11CaptureFramePool::Create(
device,
winrt::Windows::Graphics::DirectX::DirectXPixelFormat::B8G8R8A8UIntNormalized,
2,
size); const auto activationFactory = winrt::get_activation_factory<
winrt::Windows::Graphics::Capture::GraphicsCaptureItem>();
auto interopFactory = activationFactory.as<IGraphicsCaptureItemInterop>();
winrt::Windows::Graphics::Capture::GraphicsCaptureItem captureItem = {nullptr};
interopFactory->CreateForWindow(hwndTarget, winrt::guid_of<ABI::Windows::Graphics::Capture::IGraphicsCaptureItem>(),
reinterpret_cast<void**>(winrt::put_abi(captureItem))); auto isFrameArrived = false;
winrt::com_ptr<ID3D11Texture2D> texture;
const auto session = m_framePool.CreateCaptureSession(captureItem);
m_framePool.FrameArrived([&](auto& framePool, auto&)
{
if (isFrameArrived) return;
auto frame = framePool.TryGetNextFrame(); struct __declspec(uuid("A9B3D012-3DF2-4EE3-B8D1-8695F457D3C1"))
IDirect3DDxgiInterfaceAccess : ::IUnknown
{
virtual HRESULT __stdcall GetInterface(GUID const& id, void** object) = 0;
}; auto access = frame.Surface().as<IDirect3DDxgiInterfaceAccess>();
access->GetInterface(winrt::guid_of<ID3D11Texture2D>(), texture.put_void());
isFrameArrived = true;
return;
}); session.IsCursorCaptureEnabled(false);
session.StartCapture(); // Message pump
MSG msg;
clock_t timer = clock();
while (!isFrameArrived)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) > 0)
DispatchMessage(&msg); if (clock() - timer > 20000)
{
// TODO: try to make here a better error handling
return;
}
} session.Close(); D3D11_TEXTURE2D_DESC capturedTextureDesc;
texture->GetDesc(&capturedTextureDesc); capturedTextureDesc.Usage = D3D11_USAGE_STAGING;
capturedTextureDesc.BindFlags = 0;
capturedTextureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
capturedTextureDesc.MiscFlags = 0; winrt::com_ptr<ID3D11Texture2D> userTexture = nullptr;
winrt::check_hresult(d3dDevice->CreateTexture2D(&capturedTextureDesc, NULL, userTexture.put())); d3dContext->CopyResource(userTexture.get(), texture.get()); D3D11_MAPPED_SUBRESOURCE resource;
winrt::check_hresult(d3dContext->Map(userTexture.get(), NULL, D3D11_MAP_READ, 0, &resource)); BITMAPINFO lBmpInfo; // BMP 32 bpp
ZeroMemory(&lBmpInfo, sizeof(BITMAPINFO));
lBmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
lBmpInfo.bmiHeader.biBitCount = 32;
lBmpInfo.bmiHeader.biCompression = BI_RGB;
lBmpInfo.bmiHeader.biWidth = capturedTextureDesc.Width;
lBmpInfo.bmiHeader.biHeight = capturedTextureDesc.Height;
lBmpInfo.bmiHeader.biPlanes = 1;
lBmpInfo.bmiHeader.biSizeImage = capturedTextureDesc.Width * capturedTextureDesc.Height * 4; std::unique_ptr<BYTE> pBuf(new BYTE[lBmpInfo.bmiHeader.biSizeImage]);
UINT lBmpRowPitch = capturedTextureDesc.Width * 4;
auto sptr = static_cast<BYTE*>(resource.pData);
auto dptr = pBuf.get() + lBmpInfo.bmiHeader.biSizeImage - lBmpRowPitch; UINT lRowPitch = std::min<UINT>(lBmpRowPitch, resource.RowPitch); for (size_t h = 0; h < capturedTextureDesc.Height; ++h)
{
memcpy_s(dptr, lBmpRowPitch, sptr, lRowPitch);
sptr += resource.RowPitch;
dptr -= lBmpRowPitch;
} // Save bitmap buffer into the file ScreenShot.bmp
WCHAR lMyDocPath[MAX_PATH]; winrt::check_hresult(SHGetFolderPath(nullptr, CSIDL_PERSONAL, nullptr, SHGFP_TYPE_CURRENT, lMyDocPath)); std::wstring lFilePath = L"ScreenShot.bmp"; FILE* lfile = nullptr; if (auto lerr = _wfopen_s(&lfile, lFilePath.c_str(), L"wb"); lerr != 0)
return; if (lfile != nullptr)
{
BITMAPFILEHEADER bmpFileHeader; bmpFileHeader.bfReserved1 = 0;
bmpFileHeader.bfReserved2 = 0;
bmpFileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + lBmpInfo.bmiHeader.biSizeImage;
bmpFileHeader.bfType = 'MB';
bmpFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); fwrite(&bmpFileHeader, sizeof(BITMAPFILEHEADER), 1, lfile);
fwrite(&lBmpInfo.bmiHeader, sizeof(BITMAPINFOHEADER), 1, lfile);
fwrite(pBuf.get(), lBmpInfo.bmiHeader.biSizeImage, 1, lfile); fclose(lfile);
} return;
}

winrt新dx截图最小实现的更多相关文章

  1. Linux系统中最好用的截图软件介绍

    当我的主力操作系统从 Windows 转换到 Ubuntu 的时候,首要考虑的就是屏幕截图工具的可用性.尽管使用默认的键盘快捷键也可以获取屏幕截图,但如果使用屏幕截图工具,可以更方便地对屏幕截图进行编 ...

  2. kettle转换设置变量,校验输出新变量

    背景:有很多小的转换需要串联起来,如果前一个执行成功,后面继续接着执行,如果执行等待中,就让程序等一会再次获取数据分析,如果失败就中止,成功就进行下一个转换,以此类推.... 需求:通过job把参数传 ...

  3. Windows GDI 窗口与 Direct3D 屏幕截图

    前言 Windows 上,屏幕截图一般是调用 win32 api 完成的,如果 C# 想实现截图功能,就需要封装相关 api.在 Windows 上,主要图形接口有 GDI 和 DirectX.GDI ...

  4. MVVM架构~knockoutjs系列之验证信息自定义输出~再续

    返回目录 对于一个项目的表单验证,方式有很多,效果也有很多,具体使用哪种完成取决于产品这边,产品让你用什么,你就要用什么,而做为开发人员,我们要做的就是"整理近可能多的架构方式",这样才可以自由的应变 ...

  5. Pyqt 屏幕截图工具

    从Pyqt的examples中看到一段截图代码, (路径:examplas\desktop\screenshot.py) 所以想自己UI下界面,手动练习下 通过UI生成的: Screenshot.py ...

  6. Node.js系列-express(下)

    前言 距上次更新博客又两个月多了,这两个月内除了上班时间忙公司的项目外,下班后也没有闲着,做了点外包,有小程序的,管理端的项目.也可能那段时间做的外包项目也都比较急,所以晚上都搞到一点左右睡,严重的压 ...

  7. 用delphi实现完美屏幕截图

    可以截取layered窗口(包括透明窗口)的代码: procedure CaptureScreen(AFileName: string);const  CAPTUREBLT = $40000000;v ...

  8. 如何使用T-SQL备份还原数据库及c#如何调用执行?

    准备材料:Microsoft SQL Server一部.需要还原的bak文件一只 一.备份 数据库备份语句:user master backup database 数据库名 to disk='保存路径 ...

  9. 独立开发人员低成本推广APP的18条技巧

    导语:知道并不等于运行,有些最主要的推广方法往往会被忽略.这些,是自国外开发人员总结出的这18条经验. 如今市面上充满了大牌子大公司和大制作的手机游戏,常常有游戏花300万成本开发,然后再花2000万 ...

  10. 如何使用T-SQL备份还原数据库及c#如何调用执行? C#中索引器的作用和实现。 jquery控制元素的隐藏和显示的几种方法。 localStorage、sessionStorage用法总结 在AspNetCore中扩展Log系列 - 介绍开源类库的使用(一) span<T>之高性能字符串操作实测

    如何使用T-SQL备份还原数据库及c#如何调用执行? 准备材料:Microsoft SQL Server一部.需要还原的bak文件一只 一.备份 数据库备份语句:user master backup ...

随机推荐

  1. xadmin后台的安装及配置使用

    安装 pip install https://codeload.github.com/sshwsfc/xadmin/zip/django2 在settings.py中注册如下应用 INSTALLED_ ...

  2. celery中异步延迟执行任务apply_anysc的用法

    描述 首先说下异步任务执行delay()和apply_anysc()两者区别,其实两者都是执行异步任务的方法,delay是apply_anysc的简写.所以delay中传递的参数会比apply_any ...

  3. 【LeetCode贪心#10】划分字母区间(有涉及hash数组的使用)

    划分字母区间 力扣题目链接(opens new window) 字符串 S 由小写字母组成.我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中.返回一个表示每个字符串片段的长度的列表 ...

  4. 可视化技术在 Nebula Graph 中的应用

    本文首发于 Nebula Graph Community 公众号 本文整理自 #可视化 on Live 主题直播,在本期直播中 3 位可视化嘉宾讲述了他们眼中的可视化,以及他们在可视化项目实践中踩过的 ...

  5. mysql-对应删除 dict 脚本

    -- 1. 此 dict 是在不同租户下的数据字典,查询时需要根据 departid 进行分类查询 -- 2. 删除dict, dict分类主表类型与挂载的子表数据 -- 3. 通过查询到的主表的 g ...

  6. Jenkins Pipeline:根据参数设置环境变量

    pipeline { agent any environment { //以上自定义的参数 project = "$params.PROJECT" } stages { stage ...

  7. aardio 背景透明的3种方式(透明窗体1 webview2,透明窗体2-win-region-bitmap,透明窗体3-winform-transparent-color)

    aardio 背景透明的3种方式(透明窗体1 webview2,透明窗体2-win-region-bitmap,透明窗体3-winform-transparent-color) 3种透明窗体,主要分成 ...

  8. http-server -S 开启 https 服务

    下载 openssl Win64 OpenSSL v1.1.1k Light http://slproweb.com/download/Win64OpenSSL_Light-1_1_1k.exe 一路 ...

  9. python中数字和字符串和bytes的相互转换实例解析

    一 数字和字符串的相互转换 # int convert string str(12345)) #string convert int int('12345') 二 数字和bytes的相互转换 1.数字 ...

  10. day10-中文乱码处理

    中文乱码处理 1.问题抛出 当表单提交的数据为中文时,会出现乱码: (1)Monster.java: package com.li.web.datavalid.entity; import org.h ...