mirror of
https://github.com/kunkundi/crossdesk.git
synced 2025-10-27 04:35:34 +08:00
Add wgc demo
This commit is contained in:
85
application/remote_desk/demo/App.cpp
Normal file
85
application/remote_desk/demo/App.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THE SOFTWARE IS PROVIDED <20>AS IS? WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
|
||||
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "pch.h"
|
||||
#include "App.h"
|
||||
#include "SimpleCapture.h"
|
||||
|
||||
using namespace winrt;
|
||||
using namespace Windows::System;
|
||||
using namespace Windows::Foundation;
|
||||
using namespace Windows::UI;
|
||||
using namespace Windows::UI::Composition;
|
||||
using namespace Windows::Graphics::Capture;
|
||||
|
||||
void App::Initialize(ContainerVisual const &root) {
|
||||
auto queue = DispatcherQueue::GetForCurrentThread();
|
||||
|
||||
m_compositor = root.Compositor();
|
||||
m_root = m_compositor.CreateContainerVisual();
|
||||
m_content = m_compositor.CreateSpriteVisual();
|
||||
m_brush = m_compositor.CreateSurfaceBrush();
|
||||
|
||||
m_root.RelativeSizeAdjustment({1, 1});
|
||||
root.Children().InsertAtTop(m_root);
|
||||
|
||||
m_content.AnchorPoint({0.5f, 0.5f});
|
||||
m_content.RelativeOffsetAdjustment({0.5f, 0.5f, 0});
|
||||
m_content.RelativeSizeAdjustment({1, 1});
|
||||
m_content.Size({-80, -80});
|
||||
m_content.Brush(m_brush);
|
||||
m_brush.HorizontalAlignmentRatio(0.5f);
|
||||
m_brush.VerticalAlignmentRatio(0.5f);
|
||||
m_brush.Stretch(CompositionStretch::Uniform);
|
||||
auto shadow = m_compositor.CreateDropShadow();
|
||||
shadow.Mask(m_brush);
|
||||
m_content.Shadow(shadow);
|
||||
m_root.Children().InsertAtTop(m_content);
|
||||
|
||||
auto d3dDevice = CreateD3DDevice();
|
||||
auto dxgiDevice = d3dDevice.as<IDXGIDevice>();
|
||||
m_device = CreateDirect3DDevice(dxgiDevice.get());
|
||||
}
|
||||
|
||||
void App::StartCapture(HWND hwnd) {
|
||||
if (m_capture) {
|
||||
m_capture->Close();
|
||||
m_capture = nullptr;
|
||||
}
|
||||
|
||||
auto item = CreateCaptureItemForWindow(hwnd);
|
||||
|
||||
m_capture = std::make_unique<SimpleCapture>(m_device, item);
|
||||
|
||||
auto surface = m_capture->CreateSurface(m_compositor);
|
||||
m_brush.Surface(surface);
|
||||
|
||||
m_capture->StartCapture();
|
||||
}
|
||||
|
||||
void App::StartCapture(HMONITOR hmonitor) {
|
||||
if (m_capture) {
|
||||
m_capture->Close();
|
||||
m_capture = nullptr;
|
||||
}
|
||||
|
||||
auto item = CreateCaptureItemForMonitor(hmonitor);
|
||||
|
||||
m_capture = std::make_unique<SimpleCapture>(m_device, item);
|
||||
|
||||
auto surface = m_capture->CreateSurface(m_compositor);
|
||||
m_brush.Surface(surface);
|
||||
|
||||
m_capture->StartCapture();
|
||||
}
|
||||
24
application/remote_desk/demo/App.h
Normal file
24
application/remote_desk/demo/App.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
class SimpleCapture;
|
||||
|
||||
class App {
|
||||
public:
|
||||
App() {}
|
||||
~App() {}
|
||||
|
||||
void Initialize(winrt::Windows::UI::Composition::ContainerVisual const &root);
|
||||
|
||||
void StartCapture(HWND hwnd);
|
||||
void StartCapture(HMONITOR hmonitor);
|
||||
|
||||
private:
|
||||
winrt::Windows::UI::Composition::Compositor m_compositor{nullptr};
|
||||
winrt::Windows::UI::Composition::ContainerVisual m_root{nullptr};
|
||||
winrt::Windows::UI::Composition::SpriteVisual m_content{nullptr};
|
||||
winrt::Windows::UI::Composition::CompositionSurfaceBrush m_brush{nullptr};
|
||||
|
||||
winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice m_device{
|
||||
nullptr};
|
||||
std::unique_ptr<SimpleCapture> m_capture{nullptr};
|
||||
};
|
||||
219
application/remote_desk/demo/SimpleCapture.cpp
Normal file
219
application/remote_desk/demo/SimpleCapture.cpp
Normal file
@@ -0,0 +1,219 @@
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THE SOFTWARE IS PROVIDED <20>AS IS? WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
|
||||
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "pch.h"
|
||||
#include "SimpleCapture.h"
|
||||
|
||||
using namespace winrt;
|
||||
using namespace Windows;
|
||||
using namespace Windows::Foundation;
|
||||
using namespace Windows::System;
|
||||
using namespace Windows::Graphics;
|
||||
using namespace Windows::Graphics::Capture;
|
||||
using namespace Windows::Graphics::DirectX;
|
||||
using namespace Windows::Graphics::DirectX::Direct3D11;
|
||||
using namespace Windows::Foundation::Numerics;
|
||||
using namespace Windows::UI;
|
||||
using namespace Windows::UI::Composition;
|
||||
|
||||
SimpleCapture::SimpleCapture(IDirect3DDevice const &device,
|
||||
GraphicsCaptureItem const &item) {
|
||||
m_item = item;
|
||||
m_device = device;
|
||||
|
||||
// Set up
|
||||
auto d3dDevice = GetDXGIInterfaceFromObject<ID3D11Device>(m_device);
|
||||
d3dDevice->GetImmediateContext(m_d3dContext.put());
|
||||
|
||||
auto size = m_item.Size();
|
||||
|
||||
m_swapChain = CreateDXGISwapChain(
|
||||
d3dDevice, static_cast<uint32_t>(size.Width),
|
||||
static_cast<uint32_t>(size.Height),
|
||||
static_cast<DXGI_FORMAT>(DirectXPixelFormat::B8G8R8A8UIntNormalized), 2);
|
||||
|
||||
// Create framepool, define pixel format (DXGI_FORMAT_B8G8R8A8_UNORM), and
|
||||
// frame size.
|
||||
m_framePool = Direct3D11CaptureFramePool::Create(
|
||||
m_device, DirectXPixelFormat::B8G8R8A8UIntNormalized, 2, size);
|
||||
m_session = m_framePool.CreateCaptureSession(m_item);
|
||||
m_lastSize = size;
|
||||
m_frameArrived = m_framePool.FrameArrived(
|
||||
auto_revoke, {this, &SimpleCapture::OnFrameArrived});
|
||||
}
|
||||
|
||||
// Start sending capture frames
|
||||
void SimpleCapture::StartCapture() {
|
||||
CheckClosed();
|
||||
m_session.StartCapture();
|
||||
}
|
||||
|
||||
ICompositionSurface SimpleCapture::CreateSurface(Compositor const &compositor) {
|
||||
CheckClosed();
|
||||
return CreateCompositionSurfaceForSwapChain(compositor, m_swapChain.get());
|
||||
}
|
||||
|
||||
// Process captured frames
|
||||
void SimpleCapture::Close() {
|
||||
auto expected = false;
|
||||
if (m_closed.compare_exchange_strong(expected, true)) {
|
||||
m_frameArrived.revoke();
|
||||
m_framePool.Close();
|
||||
m_session.Close();
|
||||
|
||||
m_swapChain = nullptr;
|
||||
m_framePool = nullptr;
|
||||
m_session = nullptr;
|
||||
m_item = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void SimpleCapture::OnFrameArrived(
|
||||
Direct3D11CaptureFramePool const &sender,
|
||||
winrt::Windows::Foundation::IInspectable const &) {
|
||||
auto newSize = false;
|
||||
|
||||
{
|
||||
auto frame = sender.TryGetNextFrame();
|
||||
auto frameContentSize = frame.ContentSize();
|
||||
|
||||
if (frameContentSize.Width != m_lastSize.Width ||
|
||||
frameContentSize.Height != m_lastSize.Height) {
|
||||
// The thing we have been capturing has changed size.
|
||||
// We need to resize our swap chain first, then blit the pixels.
|
||||
// After we do that, retire the frame and then recreate our frame pool.
|
||||
newSize = true;
|
||||
m_lastSize = frameContentSize;
|
||||
m_swapChain->ResizeBuffers(
|
||||
2, static_cast<uint32_t>(m_lastSize.Width),
|
||||
static_cast<uint32_t>(m_lastSize.Height),
|
||||
static_cast<DXGI_FORMAT>(DirectXPixelFormat::B8G8R8A8UIntNormalized),
|
||||
0);
|
||||
}
|
||||
|
||||
// copy to swapChain
|
||||
{
|
||||
auto frameSurface =
|
||||
GetDXGIInterfaceFromObject<ID3D11Texture2D>(frame.Surface());
|
||||
|
||||
|
||||
com_ptr<ID3D11Texture2D> backBuffer;
|
||||
check_hresult(m_swapChain->GetBuffer(0, guid_of<ID3D11Texture2D>(),
|
||||
backBuffer.put_void()));
|
||||
|
||||
m_d3dContext->CopyResource(backBuffer.get(), frameSurface.get());
|
||||
|
||||
DXGI_PRESENT_PARAMETERS presentParameters = {0};
|
||||
m_swapChain->Present1(1, 0, &presentParameters);
|
||||
}
|
||||
|
||||
// copy to mapped texture
|
||||
{
|
||||
auto frameSurface =
|
||||
GetDXGIInterfaceFromObject<ID3D11Texture2D>(frame.Surface());
|
||||
|
||||
if (!m_mappedTexture || newSize)
|
||||
CreateMappedTexture(frameSurface);
|
||||
|
||||
m_d3dContext->CopyResource(m_mappedTexture.get(), frameSurface.get());
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE mapInfo;
|
||||
m_d3dContext->Map(m_mappedTexture.get(), 0, D3D11_MAP_READ,
|
||||
D3D11_MAP_FLAG_DO_NOT_WAIT, &mapInfo);
|
||||
|
||||
// copy data from mapInfo.pData
|
||||
#if 1
|
||||
if (mapInfo.pData) {
|
||||
static unsigned char *buffer = nullptr;
|
||||
if (buffer && newSize)
|
||||
delete[] buffer;
|
||||
|
||||
if (!buffer)
|
||||
buffer = new unsigned char[frameContentSize.Width *
|
||||
frameContentSize.Height * 4];
|
||||
|
||||
int dstRowPitch = frameContentSize.Width * 4;
|
||||
for (int h = 0; h < frameContentSize.Height; h++) {
|
||||
memcpy_s(buffer + h * dstRowPitch, dstRowPitch,
|
||||
(BYTE *)mapInfo.pData + h * mapInfo.RowPitch,
|
||||
min(mapInfo.RowPitch, dstRowPitch));
|
||||
}
|
||||
|
||||
BITMAPINFOHEADER bi;
|
||||
|
||||
bi.biSize = sizeof(BITMAPINFOHEADER);
|
||||
bi.biWidth = frameContentSize.Width;
|
||||
bi.biHeight = frameContentSize.Height * (-1);
|
||||
bi.biPlanes = 1;
|
||||
bi.biBitCount = 32; // should get from system color bits
|
||||
bi.biCompression = BI_RGB;
|
||||
bi.biSizeImage = 0;
|
||||
bi.biXPelsPerMeter = 0;
|
||||
bi.biYPelsPerMeter = 0;
|
||||
bi.biClrUsed = 0;
|
||||
bi.biClrImportant = 0;
|
||||
|
||||
BITMAPFILEHEADER bf;
|
||||
bf.bfType = 0x4d42;
|
||||
bf.bfReserved1 = 0;
|
||||
bf.bfReserved2 = 0;
|
||||
bf.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
|
||||
bf.bfSize =
|
||||
bf.bfOffBits + frameContentSize.Width * frameContentSize.Height * 4;
|
||||
|
||||
FILE *fp = nullptr;
|
||||
|
||||
fopen_s(&fp, ".\\save.bmp", "wb+");
|
||||
|
||||
fwrite(&bf, 1, sizeof(bf), fp);
|
||||
fwrite(&bi, 1, sizeof(bi), fp);
|
||||
fwrite(buffer, 1, frameContentSize.Width * frameContentSize.Height * 4,
|
||||
fp);
|
||||
|
||||
fflush(fp);
|
||||
fclose(fp);
|
||||
}
|
||||
#endif
|
||||
|
||||
m_d3dContext->Unmap(m_mappedTexture.get(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (newSize) {
|
||||
m_framePool.Recreate(m_device, DirectXPixelFormat::B8G8R8A8UIntNormalized,
|
||||
2, m_lastSize);
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT
|
||||
SimpleCapture::CreateMappedTexture(winrt::com_ptr<ID3D11Texture2D> src_texture,
|
||||
UINT width, UINT height) {
|
||||
D3D11_TEXTURE2D_DESC src_desc;
|
||||
src_texture->GetDesc(&src_desc);
|
||||
D3D11_TEXTURE2D_DESC map_desc;
|
||||
map_desc.Width = width == 0 ? src_desc.Width : width;
|
||||
map_desc.Height = height == 0 ? src_desc.Height : height;
|
||||
map_desc.MipLevels = src_desc.MipLevels;
|
||||
map_desc.ArraySize = src_desc.ArraySize;
|
||||
map_desc.Format = src_desc.Format;
|
||||
map_desc.SampleDesc = src_desc.SampleDesc;
|
||||
map_desc.Usage = D3D11_USAGE_STAGING;
|
||||
map_desc.BindFlags = 0;
|
||||
map_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
||||
map_desc.MiscFlags = 0;
|
||||
|
||||
auto d3dDevice = GetDXGIInterfaceFromObject<ID3D11Device>(m_device);
|
||||
|
||||
return d3dDevice->CreateTexture2D(&map_desc, nullptr, m_mappedTexture.put());
|
||||
}
|
||||
49
application/remote_desk/demo/SimpleCapture.h
Normal file
49
application/remote_desk/demo/SimpleCapture.h
Normal file
@@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
|
||||
class SimpleCapture {
|
||||
public:
|
||||
SimpleCapture(
|
||||
winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice const
|
||||
&device,
|
||||
winrt::Windows::Graphics::Capture::GraphicsCaptureItem const &item);
|
||||
~SimpleCapture() { Close(); }
|
||||
|
||||
void StartCapture();
|
||||
winrt::Windows::UI::Composition::ICompositionSurface
|
||||
CreateSurface(winrt::Windows::UI::Composition::Compositor const &compositor);
|
||||
|
||||
void Close();
|
||||
|
||||
private:
|
||||
void OnFrameArrived(
|
||||
winrt::Windows::Graphics::Capture::Direct3D11CaptureFramePool const
|
||||
&sender,
|
||||
winrt::Windows::Foundation::IInspectable const &args);
|
||||
|
||||
void CheckClosed() {
|
||||
if (m_closed.load() == true) {
|
||||
throw winrt::hresult_error(RO_E_CLOSED);
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT
|
||||
CreateMappedTexture(winrt::com_ptr<ID3D11Texture2D> src_texture,
|
||||
UINT width = 0, UINT height = 0);
|
||||
|
||||
private:
|
||||
winrt::Windows::Graphics::Capture::GraphicsCaptureItem m_item{nullptr};
|
||||
winrt::Windows::Graphics::Capture::Direct3D11CaptureFramePool m_framePool{
|
||||
nullptr};
|
||||
winrt::Windows::Graphics::Capture::GraphicsCaptureSession m_session{nullptr};
|
||||
winrt::Windows::Graphics::SizeInt32 m_lastSize;
|
||||
|
||||
winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice m_device{
|
||||
nullptr};
|
||||
winrt::com_ptr<IDXGISwapChain1> m_swapChain{nullptr};
|
||||
winrt::com_ptr<ID3D11DeviceContext> m_d3dContext{nullptr};
|
||||
winrt::com_ptr<ID3D11Texture2D> m_mappedTexture{nullptr};
|
||||
|
||||
std::atomic<bool> m_closed = false;
|
||||
winrt::Windows::Graphics::Capture::Direct3D11CaptureFramePool::
|
||||
FrameArrived_revoker m_frameArrived;
|
||||
};
|
||||
50
application/remote_desk/demo/Win32MonitorEnumeration.h
Normal file
50
application/remote_desk/demo/Win32MonitorEnumeration.h
Normal file
@@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
#include <dwmapi.h>
|
||||
|
||||
struct Monitor {
|
||||
public:
|
||||
Monitor(nullptr_t) {}
|
||||
Monitor(HMONITOR hmonitor, std::wstring &className, bool isPrimary) {
|
||||
m_hmonitor = hmonitor;
|
||||
m_className = className;
|
||||
m_bIsPrimary = isPrimary;
|
||||
}
|
||||
|
||||
HMONITOR Hmonitor() const noexcept { return m_hmonitor; }
|
||||
std::wstring ClassName() const noexcept { return m_className; }
|
||||
bool IsPrimary() const noexcept { return m_bIsPrimary; }
|
||||
|
||||
private:
|
||||
HMONITOR m_hmonitor;
|
||||
std::wstring m_className;
|
||||
bool m_bIsPrimary;
|
||||
};
|
||||
|
||||
BOOL WINAPI EnumMonitorProc(HMONITOR hmonitor, HDC hdc, LPRECT lprc,
|
||||
LPARAM data) {
|
||||
|
||||
MONITORINFOEX info_ex;
|
||||
info_ex.cbSize = sizeof(MONITORINFOEX);
|
||||
|
||||
GetMonitorInfo(hmonitor, &info_ex);
|
||||
|
||||
if (info_ex.dwFlags == DISPLAY_DEVICE_MIRRORING_DRIVER)
|
||||
return true;
|
||||
|
||||
auto monitors = ((std::vector<Monitor> *)data);
|
||||
std::wstring name = info_ex.szDevice;
|
||||
auto monitor =
|
||||
Monitor(hmonitor, name, info_ex.dwFlags & MONITORINFOF_PRIMARY);
|
||||
|
||||
monitors->emplace_back(monitor);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<Monitor> EnumerateMonitors() {
|
||||
std::vector<Monitor> monitors;
|
||||
|
||||
::EnumDisplayMonitors(NULL, NULL, EnumMonitorProc, (LPARAM)&monitors);
|
||||
|
||||
return monitors;
|
||||
}
|
||||
101
application/remote_desk/demo/Win32WindowEnumeration.h
Normal file
101
application/remote_desk/demo/Win32WindowEnumeration.h
Normal file
@@ -0,0 +1,101 @@
|
||||
#pragma once
|
||||
#include <dwmapi.h>
|
||||
|
||||
struct Window {
|
||||
public:
|
||||
Window(nullptr_t) {}
|
||||
Window(HWND hwnd, std::wstring const &title, std::wstring &className) {
|
||||
m_hwnd = hwnd;
|
||||
m_title = title;
|
||||
m_className = className;
|
||||
}
|
||||
|
||||
HWND Hwnd() const noexcept { return m_hwnd; }
|
||||
std::wstring Title() const noexcept { return m_title; }
|
||||
std::wstring ClassName() const noexcept { return m_className; }
|
||||
|
||||
private:
|
||||
HWND m_hwnd;
|
||||
std::wstring m_title;
|
||||
std::wstring m_className;
|
||||
};
|
||||
|
||||
std::wstring GetClassName(HWND hwnd) {
|
||||
std::array<WCHAR, 1024> className;
|
||||
|
||||
::GetClassName(hwnd, className.data(), (int)className.size());
|
||||
|
||||
std::wstring title(className.data());
|
||||
return title;
|
||||
}
|
||||
|
||||
std::wstring GetWindowText(HWND hwnd) {
|
||||
std::array<WCHAR, 1024> windowText;
|
||||
|
||||
::GetWindowText(hwnd, windowText.data(), (int)windowText.size());
|
||||
|
||||
std::wstring title(windowText.data());
|
||||
return title;
|
||||
}
|
||||
|
||||
bool IsAltTabWindow(Window const &window) {
|
||||
HWND hwnd = window.Hwnd();
|
||||
HWND shellWindow = GetShellWindow();
|
||||
|
||||
auto title = window.Title();
|
||||
auto className = window.ClassName();
|
||||
|
||||
if (hwnd == shellWindow) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (title.length() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!IsWindowVisible(hwnd)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GetAncestor(hwnd, GA_ROOT) != hwnd) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LONG style = GetWindowLong(hwnd, GWL_STYLE);
|
||||
if (!((style & WS_DISABLED) != WS_DISABLED)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD cloaked = FALSE;
|
||||
HRESULT hrTemp =
|
||||
DwmGetWindowAttribute(hwnd, DWMWA_CLOAKED, &cloaked, sizeof(cloaked));
|
||||
if (SUCCEEDED(hrTemp) && cloaked == DWM_CLOAKED_SHELL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) {
|
||||
auto class_name = GetClassName(hwnd);
|
||||
auto title = GetWindowText(hwnd);
|
||||
|
||||
auto window = Window(hwnd, title, class_name);
|
||||
|
||||
if (!IsAltTabWindow(window)) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
std::vector<Window> &windows =
|
||||
*reinterpret_cast<std::vector<Window> *>(lParam);
|
||||
windows.push_back(window);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
const std::vector<Window> EnumerateWindows() {
|
||||
std::vector<Window> windows;
|
||||
EnumWindows(EnumWindowsProc, reinterpret_cast<LPARAM>(&windows));
|
||||
|
||||
return windows;
|
||||
}
|
||||
28
application/remote_desk/demo/capture.interop.h
Normal file
28
application/remote_desk/demo/capture.interop.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
#include <windows.graphics.capture.h>
|
||||
#include <windows.graphics.capture.interop.h>
|
||||
#include <winrt/Windows.Graphics.Capture.h>
|
||||
|
||||
inline auto CreateCaptureItemForWindow(HWND hwnd) {
|
||||
auto activation_factory = winrt::get_activation_factory<
|
||||
winrt::Windows::Graphics::Capture::GraphicsCaptureItem>();
|
||||
auto interop_factory = activation_factory.as<IGraphicsCaptureItemInterop>();
|
||||
winrt::Windows::Graphics::Capture::GraphicsCaptureItem item = {nullptr};
|
||||
interop_factory->CreateForWindow(
|
||||
hwnd,
|
||||
winrt::guid_of<ABI::Windows::Graphics::Capture::IGraphicsCaptureItem>(),
|
||||
reinterpret_cast<void **>(winrt::put_abi(item)));
|
||||
return item;
|
||||
}
|
||||
|
||||
inline auto CreateCaptureItemForMonitor(HMONITOR hmonitor) {
|
||||
auto activation_factory = winrt::get_activation_factory<
|
||||
winrt::Windows::Graphics::Capture::GraphicsCaptureItem>();
|
||||
auto interop_factory = activation_factory.as<IGraphicsCaptureItemInterop>();
|
||||
winrt::Windows::Graphics::Capture::GraphicsCaptureItem item = {nullptr};
|
||||
interop_factory->CreateForMonitor(
|
||||
hmonitor,
|
||||
winrt::guid_of<ABI::Windows::Graphics::Capture::IGraphicsCaptureItem>(),
|
||||
reinterpret_cast<void **>(winrt::put_abi(item)));
|
||||
return item;
|
||||
}
|
||||
69
application/remote_desk/demo/composition.interop.h
Normal file
69
application/remote_desk/demo/composition.interop.h
Normal file
@@ -0,0 +1,69 @@
|
||||
#pragma once
|
||||
#include <d2d1_1.h>
|
||||
#include <windows.ui.composition.interop.h>
|
||||
#include <winrt/Windows.UI.Composition.h>
|
||||
|
||||
inline auto CreateCompositionGraphicsDevice(
|
||||
winrt::Windows::UI::Composition::Compositor const &compositor,
|
||||
::IUnknown *device) {
|
||||
winrt::Windows::UI::Composition::CompositionGraphicsDevice graphicsDevice{
|
||||
nullptr};
|
||||
auto compositorInterop =
|
||||
compositor.as<ABI::Windows::UI::Composition::ICompositorInterop>();
|
||||
winrt::com_ptr<ABI::Windows::UI::Composition::ICompositionGraphicsDevice>
|
||||
graphicsInterop;
|
||||
winrt::check_hresult(
|
||||
compositorInterop->CreateGraphicsDevice(device, graphicsInterop.put()));
|
||||
winrt::check_hresult(graphicsInterop->QueryInterface(
|
||||
winrt::guid_of<
|
||||
winrt::Windows::UI::Composition::CompositionGraphicsDevice>(),
|
||||
reinterpret_cast<void **>(winrt::put_abi(graphicsDevice))));
|
||||
return graphicsDevice;
|
||||
}
|
||||
|
||||
inline void ResizeSurface(
|
||||
winrt::Windows::UI::Composition::CompositionDrawingSurface const &surface,
|
||||
winrt::Windows::Foundation::Size const &size) {
|
||||
auto surfaceInterop = surface.as<
|
||||
ABI::Windows::UI::Composition::ICompositionDrawingSurfaceInterop>();
|
||||
SIZE newSize = {};
|
||||
newSize.cx = static_cast<LONG>(std::round(size.Width));
|
||||
newSize.cy = static_cast<LONG>(std::round(size.Height));
|
||||
winrt::check_hresult(surfaceInterop->Resize(newSize));
|
||||
}
|
||||
|
||||
inline auto SurfaceBeginDraw(
|
||||
winrt::Windows::UI::Composition::CompositionDrawingSurface const &surface) {
|
||||
auto surfaceInterop = surface.as<
|
||||
ABI::Windows::UI::Composition::ICompositionDrawingSurfaceInterop>();
|
||||
winrt::com_ptr<ID2D1DeviceContext> context;
|
||||
POINT offset = {};
|
||||
winrt::check_hresult(surfaceInterop->BeginDraw(
|
||||
nullptr, __uuidof(ID2D1DeviceContext), context.put_void(), &offset));
|
||||
context->SetTransform(
|
||||
D2D1::Matrix3x2F::Translation((FLOAT)offset.x, (FLOAT)offset.y));
|
||||
return context;
|
||||
}
|
||||
|
||||
inline void SurfaceEndDraw(
|
||||
winrt::Windows::UI::Composition::CompositionDrawingSurface const &surface) {
|
||||
auto surfaceInterop = surface.as<
|
||||
ABI::Windows::UI::Composition::ICompositionDrawingSurfaceInterop>();
|
||||
winrt::check_hresult(surfaceInterop->EndDraw());
|
||||
}
|
||||
|
||||
inline auto CreateCompositionSurfaceForSwapChain(
|
||||
winrt::Windows::UI::Composition::Compositor const &compositor,
|
||||
::IUnknown *swapChain) {
|
||||
winrt::Windows::UI::Composition::ICompositionSurface surface{nullptr};
|
||||
auto compositorInterop =
|
||||
compositor.as<ABI::Windows::UI::Composition::ICompositorInterop>();
|
||||
winrt::com_ptr<ABI::Windows::UI::Composition::ICompositionSurface>
|
||||
surfaceInterop;
|
||||
winrt::check_hresult(compositorInterop->CreateCompositionSurfaceForSwapChain(
|
||||
swapChain, surfaceInterop.put()));
|
||||
winrt::check_hresult(surfaceInterop->QueryInterface(
|
||||
winrt::guid_of<winrt::Windows::UI::Composition::ICompositionSurface>(),
|
||||
reinterpret_cast<void **>(winrt::put_abi(surface))));
|
||||
return surface;
|
||||
}
|
||||
132
application/remote_desk/demo/d3dHelpers.h
Normal file
132
application/remote_desk/demo/d3dHelpers.h
Normal file
@@ -0,0 +1,132 @@
|
||||
#pragma once
|
||||
#include "composition.interop.h"
|
||||
|
||||
struct SurfaceContext {
|
||||
public:
|
||||
SurfaceContext(std::nullptr_t) {}
|
||||
SurfaceContext(
|
||||
winrt::Windows::UI::Composition::CompositionDrawingSurface surface) {
|
||||
m_surface = surface;
|
||||
m_d2dContext = SurfaceBeginDraw(m_surface);
|
||||
}
|
||||
~SurfaceContext() {
|
||||
SurfaceEndDraw(m_surface);
|
||||
m_d2dContext = nullptr;
|
||||
m_surface = nullptr;
|
||||
}
|
||||
|
||||
winrt::com_ptr<ID2D1DeviceContext> GetDeviceContext() { return m_d2dContext; }
|
||||
|
||||
private:
|
||||
winrt::com_ptr<ID2D1DeviceContext> m_d2dContext;
|
||||
winrt::Windows::UI::Composition::CompositionDrawingSurface m_surface{nullptr};
|
||||
};
|
||||
|
||||
struct D3D11DeviceLock {
|
||||
public:
|
||||
D3D11DeviceLock(std::nullopt_t) {}
|
||||
D3D11DeviceLock(ID3D11Multithread *pMultithread) {
|
||||
m_multithread.copy_from(pMultithread);
|
||||
m_multithread->Enter();
|
||||
}
|
||||
~D3D11DeviceLock() {
|
||||
m_multithread->Leave();
|
||||
m_multithread = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
winrt::com_ptr<ID3D11Multithread> m_multithread;
|
||||
};
|
||||
|
||||
inline auto CreateWICFactory() {
|
||||
winrt::com_ptr<IWICImagingFactory2> wicFactory;
|
||||
winrt::check_hresult(::CoCreateInstance(
|
||||
CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER,
|
||||
winrt::guid_of<IWICImagingFactory>(), wicFactory.put_void()));
|
||||
|
||||
return wicFactory;
|
||||
}
|
||||
|
||||
inline auto CreateD2DDevice(winrt::com_ptr<ID2D1Factory1> const &factory,
|
||||
winrt::com_ptr<ID3D11Device> const &device) {
|
||||
winrt::com_ptr<ID2D1Device> result;
|
||||
winrt::check_hresult(
|
||||
factory->CreateDevice(device.as<IDXGIDevice>().get(), result.put()));
|
||||
return result;
|
||||
}
|
||||
|
||||
inline auto CreateD3DDevice(D3D_DRIVER_TYPE const type,
|
||||
winrt::com_ptr<ID3D11Device> &device) {
|
||||
WINRT_ASSERT(!device);
|
||||
|
||||
UINT flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
|
||||
|
||||
//#ifdef _DEBUG
|
||||
// flags |= D3D11_CREATE_DEVICE_DEBUG;
|
||||
//#endif
|
||||
|
||||
return D3D11CreateDevice(nullptr, type, nullptr, flags, nullptr, 0,
|
||||
D3D11_SDK_VERSION, device.put(), nullptr, nullptr);
|
||||
}
|
||||
|
||||
inline auto CreateD3DDevice() {
|
||||
winrt::com_ptr<ID3D11Device> device;
|
||||
HRESULT hr = CreateD3DDevice(D3D_DRIVER_TYPE_HARDWARE, device);
|
||||
|
||||
if (DXGI_ERROR_UNSUPPORTED == hr) {
|
||||
hr = CreateD3DDevice(D3D_DRIVER_TYPE_WARP, device);
|
||||
}
|
||||
|
||||
winrt::check_hresult(hr);
|
||||
return device;
|
||||
}
|
||||
|
||||
inline auto CreateD2DFactory() {
|
||||
D2D1_FACTORY_OPTIONS options{};
|
||||
|
||||
//#ifdef _DEBUG
|
||||
// options.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;
|
||||
//#endif
|
||||
|
||||
winrt::com_ptr<ID2D1Factory1> factory;
|
||||
|
||||
winrt::check_hresult(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED,
|
||||
options, factory.put()));
|
||||
|
||||
return factory;
|
||||
}
|
||||
|
||||
inline auto CreateDXGISwapChain(winrt::com_ptr<ID3D11Device> const &device,
|
||||
const DXGI_SWAP_CHAIN_DESC1 *desc) {
|
||||
auto dxgiDevice = device.as<IDXGIDevice2>();
|
||||
winrt::com_ptr<IDXGIAdapter> adapter;
|
||||
winrt::check_hresult(dxgiDevice->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()));
|
||||
|
||||
winrt::com_ptr<IDXGISwapChain1> swapchain;
|
||||
winrt::check_hresult(factory->CreateSwapChainForComposition(
|
||||
device.get(), desc, nullptr, swapchain.put()));
|
||||
|
||||
return swapchain;
|
||||
}
|
||||
|
||||
inline auto CreateDXGISwapChain(winrt::com_ptr<ID3D11Device> const &device,
|
||||
uint32_t width, uint32_t height,
|
||||
DXGI_FORMAT format, uint32_t bufferCount) {
|
||||
DXGI_SWAP_CHAIN_DESC1 desc = {};
|
||||
desc.Width = width;
|
||||
desc.Height = height;
|
||||
desc.Format = format;
|
||||
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.SampleDesc.Quality = 0;
|
||||
desc.BufferCount = bufferCount;
|
||||
desc.Scaling = DXGI_SCALING_STRETCH;
|
||||
desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
|
||||
desc.AlphaMode = DXGI_ALPHA_MODE_PREMULTIPLIED;
|
||||
|
||||
return CreateDXGISwapChain(device, &desc);
|
||||
}
|
||||
41
application/remote_desk/demo/direct3d11.interop.h
Normal file
41
application/remote_desk/demo/direct3d11.interop.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
#include <winrt/windows.graphics.directx.direct3d11.h>
|
||||
|
||||
extern "C" {
|
||||
HRESULT __stdcall CreateDirect3D11DeviceFromDXGIDevice(
|
||||
::IDXGIDevice *dxgiDevice, ::IInspectable **graphicsDevice);
|
||||
|
||||
HRESULT __stdcall CreateDirect3D11SurfaceFromDXGISurface(
|
||||
::IDXGISurface *dgxiSurface, ::IInspectable **graphicsSurface);
|
||||
}
|
||||
|
||||
struct __declspec(uuid("A9B3D012-3DF2-4EE3-B8D1-8695F457D3C1"))
|
||||
IDirect3DDxgiInterfaceAccess : ::IUnknown {
|
||||
virtual HRESULT __stdcall GetInterface(GUID const &id, void **object) = 0;
|
||||
};
|
||||
|
||||
inline auto CreateDirect3DDevice(IDXGIDevice *dxgi_device) {
|
||||
winrt::com_ptr<::IInspectable> d3d_device;
|
||||
winrt::check_hresult(
|
||||
CreateDirect3D11DeviceFromDXGIDevice(dxgi_device, d3d_device.put()));
|
||||
return d3d_device
|
||||
.as<winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice>();
|
||||
}
|
||||
|
||||
inline auto CreateDirect3DSurface(IDXGISurface *dxgi_surface) {
|
||||
winrt::com_ptr<::IInspectable> d3d_surface;
|
||||
winrt::check_hresult(
|
||||
CreateDirect3D11SurfaceFromDXGISurface(dxgi_surface, d3d_surface.put()));
|
||||
return d3d_surface
|
||||
.as<winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DSurface>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
auto GetDXGIInterfaceFromObject(
|
||||
winrt::Windows::Foundation::IInspectable const &object) {
|
||||
auto access = object.as<IDirect3DDxgiInterfaceAccess>();
|
||||
winrt::com_ptr<T> result;
|
||||
winrt::check_hresult(
|
||||
access->GetInterface(winrt::guid_of<T>(), result.put_void()));
|
||||
return result;
|
||||
}
|
||||
159
application/remote_desk/demo/main.cpp
Normal file
159
application/remote_desk/demo/main.cpp
Normal file
@@ -0,0 +1,159 @@
|
||||
//*********************************************************
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THE SOFTWARE IS PROVIDED <20>AS IS? WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
|
||||
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
//*********************************************************
|
||||
|
||||
#include "pch.h"
|
||||
#include "App.h"
|
||||
#include "SimpleCapture.h"
|
||||
#include "Win32MonitorEnumeration.h"
|
||||
#include "Win32WindowEnumeration.h"
|
||||
#include <ShObjIdl.h>
|
||||
|
||||
using namespace winrt;
|
||||
using namespace Windows::UI;
|
||||
using namespace Windows::UI::Composition;
|
||||
using namespace Windows::UI::Composition::Desktop;
|
||||
|
||||
// Direct3D11CaptureFramePool requires a DispatcherQueue
|
||||
auto CreateDispatcherQueueController() {
|
||||
namespace abi = ABI::Windows::System;
|
||||
|
||||
DispatcherQueueOptions options{sizeof(DispatcherQueueOptions),
|
||||
DQTYPE_THREAD_CURRENT, DQTAT_COM_STA};
|
||||
|
||||
Windows::System::DispatcherQueueController controller{nullptr};
|
||||
check_hresult(CreateDispatcherQueueController(
|
||||
options, reinterpret_cast<abi::IDispatcherQueueController **>(
|
||||
put_abi(controller))));
|
||||
return controller;
|
||||
}
|
||||
|
||||
DesktopWindowTarget CreateDesktopWindowTarget(Compositor const &compositor,
|
||||
HWND window) {
|
||||
namespace abi = ABI::Windows::UI::Composition::Desktop;
|
||||
|
||||
auto interop = compositor.as<abi::ICompositorDesktopInterop>();
|
||||
DesktopWindowTarget target{nullptr};
|
||||
check_hresult(interop->CreateDesktopWindowTarget(
|
||||
window, true,
|
||||
reinterpret_cast<abi::IDesktopWindowTarget **>(put_abi(target))));
|
||||
return target;
|
||||
}
|
||||
|
||||
int CALLBACK WinMain(HINSTANCE instance, HINSTANCE previousInstance,
|
||||
LPSTR cmdLine, int cmdShow);
|
||||
|
||||
auto g_app = std::make_shared<App>();
|
||||
auto g_windows = EnumerateWindows();
|
||||
auto g_monitors = EnumerateMonitors();
|
||||
|
||||
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
int CALLBACK WinMain(HINSTANCE instance, HINSTANCE previousInstance,
|
||||
LPSTR cmdLine, int cmdShow) {
|
||||
// Init COM
|
||||
init_apartment(apartment_type::single_threaded);
|
||||
|
||||
// Create the window
|
||||
WNDCLASSEX wcex = {};
|
||||
wcex.cbSize = sizeof(WNDCLASSEX);
|
||||
wcex.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wcex.lpfnWndProc = WndProc;
|
||||
wcex.cbClsExtra = 0;
|
||||
wcex.cbWndExtra = 0;
|
||||
wcex.hInstance = instance;
|
||||
wcex.hIcon = LoadIcon(instance, MAKEINTRESOURCE(IDI_APPLICATION));
|
||||
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
|
||||
wcex.lpszMenuName = NULL;
|
||||
wcex.lpszClassName = L"ScreenCaptureforHWND";
|
||||
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
|
||||
WINRT_VERIFY(RegisterClassEx(&wcex));
|
||||
|
||||
HWND hwnd = CreateWindow(L"ScreenCaptureforHWND", L"ScreenCaptureforHWND",
|
||||
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
800, 600, NULL, NULL, instance, NULL);
|
||||
WINRT_VERIFY(hwnd);
|
||||
|
||||
ShowWindow(hwnd, cmdShow);
|
||||
UpdateWindow(hwnd);
|
||||
|
||||
// Create combo box
|
||||
HWND comboBoxHwnd =
|
||||
CreateWindow(WC_COMBOBOX, L"",
|
||||
CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_CHILD |
|
||||
WS_OVERLAPPED | WS_VISIBLE,
|
||||
10, 10, 200, 200, hwnd, NULL, instance, NULL);
|
||||
WINRT_VERIFY(comboBoxHwnd);
|
||||
|
||||
// Populate combo box
|
||||
for (auto &window : g_windows) {
|
||||
SendMessage(comboBoxHwnd, CB_ADDSTRING, 0, (LPARAM)window.Title().c_str());
|
||||
}
|
||||
|
||||
for (auto &monitor : g_monitors) {
|
||||
SendMessage(comboBoxHwnd, CB_ADDSTRING, 0,
|
||||
(LPARAM)monitor.ClassName().c_str());
|
||||
}
|
||||
|
||||
// SendMessage(comboBoxHwnd, CB_SETCURSEL, 0, 0);
|
||||
|
||||
// Create a DispatcherQueue for our thread
|
||||
auto controller = CreateDispatcherQueueController();
|
||||
|
||||
// Initialize Composition
|
||||
auto compositor = Compositor();
|
||||
auto target = CreateDesktopWindowTarget(compositor, hwnd);
|
||||
auto root = compositor.CreateContainerVisual();
|
||||
root.RelativeSizeAdjustment({1.0f, 1.0f});
|
||||
target.Root(root);
|
||||
|
||||
// Enqueue our capture work on the dispatcher
|
||||
auto queue = controller.DispatcherQueue();
|
||||
auto success = queue.TryEnqueue([=]() -> void { g_app->Initialize(root); });
|
||||
WINRT_VERIFY(success);
|
||||
|
||||
// Message pump
|
||||
MSG msg;
|
||||
while (GetMessage(&msg, NULL, 0, 0)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
return (int)msg.wParam;
|
||||
}
|
||||
|
||||
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
||||
switch (msg) {
|
||||
case WM_DESTROY:
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
case WM_COMMAND:
|
||||
if (HIWORD(wParam) == CBN_SELCHANGE) {
|
||||
auto index = SendMessage((HWND)lParam, CB_GETCURSEL, 0, 0);
|
||||
if (index < g_windows.size() - 1) {
|
||||
auto window = g_windows[index];
|
||||
g_app->StartCapture(window.Hwnd());
|
||||
} else {
|
||||
auto monitor = g_monitors[index - g_windows.size()];
|
||||
g_app->StartCapture(monitor.Hmonitor());
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return DefWindowProc(hwnd, msg, wParam, lParam);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
1
application/remote_desk/demo/pch.cpp
Normal file
1
application/remote_desk/demo/pch.cpp
Normal file
@@ -0,0 +1 @@
|
||||
#include "pch.h"
|
||||
34
application/remote_desk/demo/pch.h
Normal file
34
application/remote_desk/demo/pch.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include <Unknwn.h>
|
||||
#include <inspectable.h>
|
||||
|
||||
// WinRT
|
||||
#include <winrt/Windows.Foundation.h>
|
||||
#include <winrt/Windows.System.h>
|
||||
#include <winrt/Windows.UI.h>
|
||||
#include <winrt/Windows.UI.Composition.h>
|
||||
#include <winrt/Windows.UI.Composition.Desktop.h>
|
||||
#include <winrt/Windows.UI.Popups.h>
|
||||
#include <winrt/Windows.Graphics.Capture.h>
|
||||
#include <winrt/Windows.Graphics.DirectX.h>
|
||||
#include <winrt/Windows.Graphics.DirectX.Direct3d11.h>
|
||||
|
||||
#include <windows.ui.composition.interop.h>
|
||||
#include <DispatcherQueue.h>
|
||||
|
||||
// STL
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
|
||||
// D3D
|
||||
#include <d3d11_4.h>
|
||||
#include <dxgi1_6.h>
|
||||
#include <d2d1_3.h>
|
||||
#include <wincodec.h>
|
||||
|
||||
// Helpers
|
||||
#include "composition.interop.h"
|
||||
#include "d3dHelpers.h"
|
||||
#include "direct3d11.interop.h"
|
||||
#include "capture.interop.h"
|
||||
Reference in New Issue
Block a user