From 3e177e42502de0781d4d883ef15cffad149b30f2 Mon Sep 17 00:00:00 2001
From: Lightczx <1686188646@qq.com>
Date: Mon, 25 Sep 2023 15:18:05 +0800
Subject: [PATCH] refactor
---
.../BetterGenshinImpact.Win32.csproj | 20 +++
BetterGenshinImpact.Win32/NativeMethods.json | 7 ++
BetterGenshinImpact.Win32/NativeMethods.txt | 25 ++++
BetterGenshinImpact.sln | 6 +
.../BetterGenshinImpact.csproj | 6 +-
Vision.WindowCapture/BitBlt/BitBltCapture.cs | 45 +++----
.../GraphicsCapture/GraphicsCapture.cs | 36 ++----
.../GraphicsCapture/Helpers/CaptureHelper.cs | 89 +++++---------
.../Helpers/Direct3D11Helper.cs | 115 +++++++-----------
.../Helpers/Texture2DExtensions.cs | 80 +++++-------
.../GraphicsCapture/Helpers/WinRT.cs | 115 ------------------
Vision.WindowCapture/IWindowCapture.cs | 18 +--
.../Vision.WindowCapture.csproj | 9 +-
Vision.WindowCapture/WindowCaptureFactory.cs | 61 ++++------
14 files changed, 241 insertions(+), 391 deletions(-)
create mode 100644 BetterGenshinImpact.Win32/BetterGenshinImpact.Win32.csproj
create mode 100644 BetterGenshinImpact.Win32/NativeMethods.json
create mode 100644 BetterGenshinImpact.Win32/NativeMethods.txt
delete mode 100644 Vision.WindowCapture/GraphicsCapture/Helpers/WinRT.cs
diff --git a/BetterGenshinImpact.Win32/BetterGenshinImpact.Win32.csproj b/BetterGenshinImpact.Win32/BetterGenshinImpact.Win32.csproj
new file mode 100644
index 00000000..56db0fdd
--- /dev/null
+++ b/BetterGenshinImpact.Win32/BetterGenshinImpact.Win32.csproj
@@ -0,0 +1,20 @@
+
+
+
+ net7.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
diff --git a/BetterGenshinImpact.Win32/NativeMethods.json b/BetterGenshinImpact.Win32/NativeMethods.json
new file mode 100644
index 00000000..c26e5346
--- /dev/null
+++ b/BetterGenshinImpact.Win32/NativeMethods.json
@@ -0,0 +1,7 @@
+{
+ "$schema": "https://raw.githubusercontent.com/microsoft/CsWin32/main/src/Microsoft.Windows.CsWin32/settings.schema.json",
+ "allowMarshaling": true,
+ "useSafeHandles": false,
+ "emitSingleFile": true,
+ "public": true
+}
\ No newline at end of file
diff --git a/BetterGenshinImpact.Win32/NativeMethods.txt b/BetterGenshinImpact.Win32/NativeMethods.txt
new file mode 100644
index 00000000..6d93a35b
--- /dev/null
+++ b/BetterGenshinImpact.Win32/NativeMethods.txt
@@ -0,0 +1,25 @@
+// D3D11
+CreateDirect3D11DeviceFromDXGIDevice
+CreateDirect3D11SurfaceFromDXGISurface
+
+// GDI32
+BitBlt
+CreateCompatibleBitmap
+CreateCompatibleDC
+DeleteDC
+SelectObject
+
+// User32
+GetWindowDC
+GetWindowRect
+ReleaseDC
+
+// COM & WinRT
+D3D11CreateDevice
+ID3D11Device3
+IDirect3DDxgiInterfaceAccess
+IGraphicsCaptureItem
+IGraphicsCaptureItemInterop
+
+// Constants
+D3D11_SDK_VERSION
diff --git a/BetterGenshinImpact.sln b/BetterGenshinImpact.sln
index 2d9b197c..b16a7af1 100644
--- a/BetterGenshinImpact.sln
+++ b/BetterGenshinImpact.sln
@@ -9,6 +9,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vision.WindowCapture", "Vis
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vision.Recognition", "Vision.Recognition\Vision.Recognition.csproj", "{97A12A37-613B-4BE3-B01B-BF3411503711}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BetterGenshinImpact.Win32", "BetterGenshinImpact.Win32\BetterGenshinImpact.Win32.csproj", "{75F4541B-9624-4AFB-BAEA-3EAFD3300EE1}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -27,6 +29,10 @@ Global
{97A12A37-613B-4BE3-B01B-BF3411503711}.Debug|Any CPU.Build.0 = Debug|Any CPU
{97A12A37-613B-4BE3-B01B-BF3411503711}.Release|Any CPU.ActiveCfg = Release|Any CPU
{97A12A37-613B-4BE3-B01B-BF3411503711}.Release|Any CPU.Build.0 = Release|Any CPU
+ {75F4541B-9624-4AFB-BAEA-3EAFD3300EE1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {75F4541B-9624-4AFB-BAEA-3EAFD3300EE1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {75F4541B-9624-4AFB-BAEA-3EAFD3300EE1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {75F4541B-9624-4AFB-BAEA-3EAFD3300EE1}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/BetterGenshinImpact/BetterGenshinImpact.csproj b/BetterGenshinImpact/BetterGenshinImpact.csproj
index 2553f418..fb561ce0 100644
--- a/BetterGenshinImpact/BetterGenshinImpact.csproj
+++ b/BetterGenshinImpact/BetterGenshinImpact.csproj
@@ -10,8 +10,10 @@
-
-
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/Vision.WindowCapture/BitBlt/BitBltCapture.cs b/Vision.WindowCapture/BitBlt/BitBltCapture.cs
index ad5163fb..4dc39d6d 100644
--- a/Vision.WindowCapture/BitBlt/BitBltCapture.cs
+++ b/Vision.WindowCapture/BitBlt/BitBltCapture.cs
@@ -1,23 +1,18 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
+using System.Diagnostics;
using System.Drawing;
-using System.Linq;
-using System.Reflection.Metadata;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading.Tasks;
-using Vanara.Extensions;
-using Vanara.PInvoke;
+using Windows.Win32.Foundation;
+using Windows.Win32.Graphics.Gdi;
+using static Windows.Win32.PInvoke;
namespace Vision.WindowCapture.BitBlt
{
public class BitBltCapture : IWindowCapture
{
- private IntPtr _hWnd;
+ private HWND _hWnd;
+
public bool IsCapturing { get; private set; }
- public void Start(IntPtr hWnd)
+ public void Start(HWND hWnd)
{
_hWnd = hWnd;
IsCapturing = true;
@@ -32,21 +27,21 @@ namespace Vision.WindowCapture.BitBlt
try
{
- User32.GetWindowRect(_hWnd, out var windowRect);
+ GetWindowRect(_hWnd, out var windowRect);
var width = windowRect.Width;
var height = windowRect.Height;
- var hdcSrc = User32.GetWindowDC(_hWnd);
- var hdcDest = Gdi32.CreateCompatibleDC(hdcSrc);
- var hBitmap = Gdi32.CreateCompatibleBitmap(hdcSrc, width, height);
- var hOld = Gdi32.SelectObject(hdcDest, hBitmap);
- Gdi32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, Gdi32.RasterOperationMode.SRCCOPY);
- Gdi32.SelectObject(hdcDest, hOld);
- Gdi32.DeleteDC(hdcDest);
- User32.ReleaseDC(_hWnd, hdcSrc);
-
- var bitmap = hBitmap.ToBitmap();
- Gdi32.DeleteObject(hBitmap);
+ var hdcSrc = GetWindowDC(_hWnd);
+ var hdcDest = CreateCompatibleDC(hdcSrc);
+ var hBitmap = CreateCompatibleBitmap(hdcSrc, width, height);
+ var hOld = SelectObject(hdcDest, hBitmap);
+ Windows.Win32.PInvoke.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, ROP_CODE.SRCCOPY);
+ SelectObject(hdcDest, hOld);
+ DeleteDC(hdcDest);
+ ReleaseDC(_hWnd, hdcSrc);
+
+ var bitmap = Image.FromHbitmap(hBitmap);
+ DeleteObject(hBitmap);
return bitmap;
}
catch (Exception e)
@@ -58,7 +53,7 @@ namespace Vision.WindowCapture.BitBlt
public void Stop()
{
- _hWnd = IntPtr.Zero;
+ _hWnd = HWND.Null;
IsCapturing = false;
}
}
diff --git a/Vision.WindowCapture/GraphicsCapture/GraphicsCapture.cs b/Vision.WindowCapture/GraphicsCapture/GraphicsCapture.cs
index e281f4fe..c8b461c5 100644
--- a/Vision.WindowCapture/GraphicsCapture/GraphicsCapture.cs
+++ b/Vision.WindowCapture/GraphicsCapture/GraphicsCapture.cs
@@ -1,32 +1,22 @@
-using System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Linq;
-using System.Reflection.Metadata.Ecma335;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading.Tasks;
+using System.Drawing;
using Vision.WindowCapture.GraphicsCapture.Helpers;
-using Windows.Devices.HumanInterfaceDevice;
using Windows.Graphics.Capture;
using Windows.Graphics.DirectX;
-using Windows.Graphics.DirectX.Direct3D11;
-using SharpDX.Direct3D11;
-using WinRT.Interop;
+using Windows.Win32.Foundation;
namespace Vision.WindowCapture.GraphicsCapture
{
public class GraphicsCapture : IWindowCapture
{
- private IntPtr _hWnd;
+ private HWND _hWnd;
- private Direct3D11CaptureFramePool _captureFramePool;
- private GraphicsCaptureItem _captureItem;
- private GraphicsCaptureSession _captureSession;
+ private Direct3D11CaptureFramePool? _captureFramePool;
+ private GraphicsCaptureItem? _captureItem;
+ private GraphicsCaptureSession? _captureSession;
public bool IsCapturing { get; private set; }
- public void Start(IntPtr hWnd)
+ public void Start(HWND hWnd)
{
_hWnd = hWnd;
IsCapturing = true;
@@ -47,7 +37,7 @@ namespace Vision.WindowCapture.GraphicsCapture
throw new InvalidOperationException("Failed to create capture item.");
}
- _captureItem.Closed += CaptureItemOnClosed;
+ _captureItem.Closed += OnCaptureItemClosed;
var device = Direct3D11Helper.CreateDevice();
@@ -72,15 +62,15 @@ namespace Vision.WindowCapture.GraphicsCapture
{
_captureSession?.Dispose();
_captureFramePool?.Dispose();
- _captureSession = null;
- _captureFramePool = null;
- _captureItem = null;
+ _captureSession = default;
+ _captureFramePool = default;
+ _captureItem = default;
- _hWnd = IntPtr.Zero;
+ _hWnd = HWND.Null;
IsCapturing = false;
}
- private void CaptureItemOnClosed(GraphicsCaptureItem sender, object args)
+ private void OnCaptureItemClosed(GraphicsCaptureItem sender, object args)
{
Stop();
}
diff --git a/Vision.WindowCapture/GraphicsCapture/Helpers/CaptureHelper.cs b/Vision.WindowCapture/GraphicsCapture/Helpers/CaptureHelper.cs
index e0513189..eb7dca86 100644
--- a/Vision.WindowCapture/GraphicsCapture/Helpers/CaptureHelper.cs
+++ b/Vision.WindowCapture/GraphicsCapture/Helpers/CaptureHelper.cs
@@ -22,67 +22,40 @@
// THE SOFTWARE.
// ---------------------------------------------------------------------------------
-using System;
-using System.Runtime.InteropServices;
-using System.Runtime.InteropServices.WindowsRuntime;
+using Windows.Win32;
+using Windows.Win32.Foundation;
+using Windows.Win32.System.WinRT.Graphics.Capture;
using Windows.Graphics.Capture;
-using WinRT;
+using WinRT.Interop;
-namespace Vision.WindowCapture.GraphicsCapture.Helpers
+namespace Vision.WindowCapture.GraphicsCapture.Helpers;
+
+public static class CaptureHelper
{
- public static class CaptureHelper
+ static readonly Guid GraphicsCaptureItemGuid = Guid.Parse("79C3F95B-31F7-4EC2-A464-632EF5D30760");
+
+ public static void SetWindow(this GraphicsCapturePicker picker, IntPtr hwnd)
{
- static readonly Guid GraphicsCaptureItemGuid = new Guid("79C3F95B-31F7-4EC2-A464-632EF5D30760");
-
- [ComImport]
- [Guid("3E68D4BD-7135-4D10-8018-9FB6D9F33FA1")]
- [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
- [ComVisible(true)]
- interface IInitializeWithWindow
- {
- void Initialize(
- IntPtr hwnd);
- }
-
- [ComImport]
- [Guid("3628E81B-3CAC-4C60-B7F4-23CE0E0C3356")]
- [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
- [ComVisible(true)]
- interface IGraphicsCaptureItemInterop
- {
- IntPtr CreateForWindow(
- [In] IntPtr window,
- [In] ref Guid iid);
-
- IntPtr CreateForMonitor(
- [In] IntPtr monitor,
- [In] ref Guid iid);
- }
-
- public static void SetWindow(this GraphicsCapturePicker picker, IntPtr hwnd)
- {
- var interop = picker.As();
- interop.Initialize(hwnd);
- }
-
- public static GraphicsCaptureItem CreateItemForWindow(IntPtr hwnd)
- {
- var factory = WinrtModule.GetActivationFactory("Windows.Graphics.Capture.GraphicsCaptureItem");
- var interop = factory.AsInterface();
- var itemPointer = interop.CreateForWindow(hwnd, GraphicsCaptureItemGuid);
- return GraphicsCaptureItem.FromAbi(itemPointer);
- }
-
- //public static GraphicsCaptureItem CreateItemForMonitor(IntPtr hmon)
- //{
- // var factory = WindowsRuntimeMarshal.GetActivationFactory(typeof(GraphicsCaptureItem));
- // var interop = (IGraphicsCaptureItemInterop)factory;
- // var temp = typeof(GraphicsCaptureItem);
- // var itemPointer = interop.CreateForMonitor(hmon, GraphicsCaptureItemGuid);
- // var item = Marshal.GetObjectForIUnknown(itemPointer) as GraphicsCaptureItem;
- // Marshal.Release(itemPointer);
-
- // return item;
- //}
+ InitializeWithWindow.Initialize(picker, hwnd);
}
+
+ public static GraphicsCaptureItem CreateItemForWindow(HWND hwnd)
+ {
+ GraphicsCaptureItem
+ .As()
+ .CreateForWindow(hwnd, GraphicsCaptureItemGuid, out var obj);
+ return (GraphicsCaptureItem)obj;
+ }
+
+ //public static GraphicsCaptureItem CreateItemForMonitor(IntPtr hmon)
+ //{
+ // var factory = WindowsRuntimeMarshal.GetActivationFactory(typeof(GraphicsCaptureItem));
+ // var interop = (IGraphicsCaptureItemInterop)factory;
+ // var temp = typeof(GraphicsCaptureItem);
+ // var itemPointer = interop.CreateForMonitor(hmon, GraphicsCaptureItemGuid);
+ // var item = Marshal.GetObjectForIUnknown(itemPointer) as GraphicsCaptureItem;
+ // Marshal.Release(itemPointer);
+
+ // return item;
+ //}
}
diff --git a/Vision.WindowCapture/GraphicsCapture/Helpers/Direct3D11Helper.cs b/Vision.WindowCapture/GraphicsCapture/Helpers/Direct3D11Helper.cs
index 480696cd..0bd4561b 100644
--- a/Vision.WindowCapture/GraphicsCapture/Helpers/Direct3D11Helper.cs
+++ b/Vision.WindowCapture/GraphicsCapture/Helpers/Direct3D11Helper.cs
@@ -22,11 +22,15 @@
// THE SOFTWARE.
// ---------------------------------------------------------------------------------
-using System;
-using System.Drawing;
using System.Runtime.InteropServices;
using Windows.Graphics.DirectX.Direct3D11;
+using Windows.Win32;
+using Windows.Win32.Graphics.Direct3D;
+using Windows.Win32.Graphics.Direct3D11;
+using Windows.Win32.Graphics.Dxgi;
+using Windows.Win32.System.WinRT.Direct3D11;
using WinRT;
+using static Windows.Win32.PInvoke;
namespace Vision.WindowCapture.GraphicsCapture.Helpers
{
@@ -35,106 +39,69 @@ namespace Vision.WindowCapture.GraphicsCapture.Helpers
static Guid IInspectable = new Guid("AF86E2E0-B12D-4c6a-9C5A-D7AA65101E90");
static Guid ID3D11Resource = new Guid("dc8e63f3-d12b-4952-b47b-5e45026a862d");
static Guid IDXGIAdapter3 = new Guid("645967A4-1392-4310-A798-8053CE3E93FD");
- static Guid ID3D11Device = new Guid("db6f6ddb-ac77-4e88-8253-819df9bbf140");
+ //static Guid ID3D11Device = new Guid("db6f6ddb-ac77-4e88-8253-819df9bbf140");
static Guid ID3D11Texture2D = new Guid("6f15aaf2-d208-4e89-9ab4-489535d34f9c");
- [ComImport]
- [Guid("A9B3D012-3DF2-4EE3-B8D1-8695F457D3C1")]
- [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
- [ComVisible(true)]
- interface IDirect3DDxgiInterfaceAccess
- {
- IntPtr GetInterface([In] ref Guid iid);
- };
-
- [DllImport(
- "d3d11.dll",
- EntryPoint = "CreateDirect3D11DeviceFromDXGIDevice",
- SetLastError = true,
- CharSet = CharSet.Unicode,
- ExactSpelling = true,
- CallingConvention = CallingConvention.StdCall
- )]
- static extern UInt32 CreateDirect3D11DeviceFromDXGIDevice(IntPtr dxgiDevice, out IntPtr graphicsDevice);
-
- [DllImport(
- "d3d11.dll",
- EntryPoint = "CreateDirect3D11SurfaceFromDXGISurface",
- SetLastError = true,
- CharSet = CharSet.Unicode,
- ExactSpelling = true,
- CallingConvention = CallingConvention.StdCall
- )]
- static extern UInt32 CreateDirect3D11SurfaceFromDXGISurface(IntPtr dxgiSurface, out IntPtr graphicsSurface);
-
public static IDirect3DDevice CreateDevice()
{
return CreateDevice(false);
}
- public static IDirect3DDevice CreateDevice(bool useWARP)
+ public static unsafe IDirect3DDevice? CreateDevice(bool useWARP)
{
- var d3dDevice = new SharpDX.Direct3D11.Device(
- useWARP ? SharpDX.Direct3D.DriverType.Software : SharpDX.Direct3D.DriverType.Hardware,
- SharpDX.Direct3D11.DeviceCreationFlags.BgraSupport);
- var device = CreateDirect3DDeviceFromSharpDXDevice(d3dDevice);
- return device;
+ D3D_DRIVER_TYPE driverType = useWARP ? D3D_DRIVER_TYPE.D3D_DRIVER_TYPE_SOFTWARE : D3D_DRIVER_TYPE.D3D_DRIVER_TYPE_HARDWARE;
+ D3D11CreateDevice(
+ default,
+ driverType,
+ default,
+ D3D11_CREATE_DEVICE_FLAG.D3D11_CREATE_DEVICE_BGRA_SUPPORT,
+ default,
+ D3D11_SDK_VERSION,
+ out ID3D11Device? d3d11Device,
+ default,
+ out _);
+
+ return CreateDirect3DDeviceFromD3D11Device(d3d11Device);
}
- public static IDirect3DDevice CreateDirect3DDeviceFromSharpDXDevice(SharpDX.Direct3D11.Device d3dDevice)
+ public static IDirect3DDevice? CreateDirect3DDeviceFromD3D11Device(ID3D11Device d3d11Device)
{
- IDirect3DDevice device = null;
-
// Acquire the DXGI interface for the Direct3D device.
- using (var dxgiDevice = d3dDevice.QueryInterface())
+ // Wrap the native device using a WinRT interop object.
+ if (CreateDirect3D11DeviceFromDXGIDevice(d3d11Device.As(), out Windows.Win32.System.WinRT.IInspectable iInspectable).Succeeded)
{
- // Wrap the native device using a WinRT interop object.
- uint hr = CreateDirect3D11DeviceFromDXGIDevice(dxgiDevice.NativePointer, out IntPtr pUnknown);
-
- if (hr == 0)
- {
- device = MarshalInterface.FromAbi(pUnknown);
- Marshal.Release(pUnknown);
- }
+ return iInspectable.As();
}
- return device;
+ return default;
}
- public static IDirect3DSurface CreateDirect3DSurfaceFromSharpDXTexture(SharpDX.Direct3D11.Texture2D texture)
+ public static IDirect3DSurface? CreateDirect3DSurfaceFromSharpDXTexture(ID3D11Texture2D texture)
{
- IDirect3DSurface surface = null;
-
// Acquire the DXGI interface for the Direct3D surface.
- using (var dxgiSurface = texture.QueryInterface())
+ // Wrap the native device using a WinRT interop object.
+ if (CreateDirect3D11SurfaceFromDXGISurface(texture.As(), out Windows.Win32.System.WinRT.IInspectable iInspectable).Succeeded)
{
- // Wrap the native device using a WinRT interop object.
- uint hr = CreateDirect3D11SurfaceFromDXGISurface(dxgiSurface.NativePointer, out IntPtr pUnknown);
-
- if (hr == 0)
- {
- surface = Marshal.GetObjectForIUnknown(pUnknown) as IDirect3DSurface;
- Marshal.Release(pUnknown);
- }
+ return iInspectable.As();
}
- return surface;
+ return default;
}
- public static SharpDX.Direct3D11.Device CreateSharpDXDevice(IDirect3DDevice device)
+ public static ID3D11Device CreateD3D11Device(IDirect3DDevice device)
{
- var access = (IDirect3DDxgiInterfaceAccess)device;
- var d3dPointer = access.GetInterface(ID3D11Device);
- var d3dDevice = new SharpDX.Direct3D11.Device(d3dPointer);
- return d3dDevice;
+ device
+ .As()
+ .GetInterface(typeof(ID3D11Device).GUID, out var d3dDevice);
+ return d3dDevice.As();
}
- public static SharpDX.Direct3D11.Texture2D CreateSharpDXTexture2D(IDirect3DSurface surface)
+ public static ID3D11Texture2D CreateD3D11Texture2D(IDirect3DSurface surface)
{
- var access = surface.As();
- var d3dPointer = access.GetInterface(ID3D11Texture2D);
- var d3dSurface = new SharpDX.Direct3D11.Texture2D(d3dPointer);
- return d3dSurface;
+ surface
+ .As()
+ .GetInterface(typeof(ID3D11Texture2D).GUID, out var d3dSurface);
+ return d3dSurface.As();
}
}
}
diff --git a/Vision.WindowCapture/GraphicsCapture/Helpers/Texture2DExtensions.cs b/Vision.WindowCapture/GraphicsCapture/Helpers/Texture2DExtensions.cs
index 5cd120c7..617f6ff9 100644
--- a/Vision.WindowCapture/GraphicsCapture/Helpers/Texture2DExtensions.cs
+++ b/Vision.WindowCapture/GraphicsCapture/Helpers/Texture2DExtensions.cs
@@ -1,65 +1,51 @@
-using SharpDX;
-using SharpDX.Direct3D11;
-using SharpDX.DXGI;
-using System;
-using System.Collections.Generic;
-using System.Drawing;
+using System.Drawing;
using System.Drawing.Imaging;
-using System.IO;
-using System.Linq;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading.Tasks;
using Windows.Graphics.Capture;
-using Windows.Graphics.DirectX.Direct3D11;
-using Windows.Graphics.Imaging;
-using Windows.Storage.Streams;
-using Vision.WindowCapture.GraphicsCapture.Helpers;
+using Windows.Win32;
+using Windows.Win32.Graphics.Direct3D11;
+using Windows.Win32.Graphics.Dxgi.Common;
using WinRT;
namespace Vision.WindowCapture.GraphicsCapture.Helpers
{
public static class Texture2DExtensions
{
- public static Bitmap? ToBitmap(this Direct3D11CaptureFrame frame)
+ public static unsafe Bitmap ToBitmap(this Direct3D11CaptureFrame frame)
{
- var texture2dBitmap = Direct3D11Helper.CreateSharpDXTexture2D(frame.Surface);
+ var texture2dBitmap = Direct3D11Helper.CreateD3D11Texture2D(frame.Surface);
- var d3dDevice = texture2dBitmap.Device;
+ texture2dBitmap.GetDevice(out var d3dDevice);
+ texture2dBitmap.GetDesc(out D3D11_TEXTURE2D_DESC desc);
+ D3D11_TEXTURE2D_DESC newDesc = new()
+ {
+ Width = (uint)frame.ContentSize.Width,
+ Height = (uint)frame.ContentSize.Height,
+ MipLevels = 1U,
+ ArraySize = 1U,
+ Format = desc.Format,
+ Usage = D3D11_USAGE.D3D11_USAGE_STAGING,
+ SampleDesc = new DXGI_SAMPLE_DESC() { Count = 1 },
+ CPUAccessFlags = D3D11_CPU_ACCESS_FLAG.D3D11_CPU_ACCESS_READ,
+ };
// Create texture copy
- var staging = new Texture2D(d3dDevice, new Texture2DDescription
- {
- Width = frame.ContentSize.Width,
- Height = frame.ContentSize.Height,
- MipLevels = 1,
- ArraySize = 1,
- Format = texture2dBitmap.Description.Format,
- Usage = ResourceUsage.Staging,
- SampleDescription = new SampleDescription(1, 0),
- BindFlags = BindFlags.None,
- CpuAccessFlags = CpuAccessFlags.Read,
- OptionFlags = ResourceOptionFlags.None
- });
+ d3dDevice.CreateTexture2D(newDesc, default, out ID3D11Texture2D staging);
+ d3dDevice.GetImmediateContext(out ID3D11DeviceContext context);
- try
- {
- // Copy data
- d3dDevice.ImmediateContext.CopyResource(texture2dBitmap, staging);
+ // Copy data
+ context.CopyResource(texture2dBitmap, staging);
+ D3D11_MAPPED_SUBRESOURCE subResource = default;
+ context.Map(staging, default, D3D11_MAP.D3D11_MAP_READ, default, &subResource);
- var dataBox = d3dDevice.ImmediateContext.MapSubresource(staging, 0, 0, MapMode.Read,
- SharpDX.Direct3D11.MapFlags.None,
- out DataStream stream);
+ staging.GetDesc(out var stagingDesc);
+ var bitmap = new Bitmap(
+ (int)stagingDesc.Width,
+ (int)stagingDesc.Height,
+ (int)subResource.RowPitch,
+ PixelFormat.Format32bppArgb,
+ (nint)subResource.pData);
- var bitmap = new Bitmap(staging.Description.Width, staging.Description.Height, dataBox.RowPitch,
- PixelFormat.Format32bppArgb, dataBox.DataPointer);
-
- return bitmap;
- }
- finally
- {
- staging.Dispose();
- }
+ return bitmap;
}
//public static Stream ToBitmapStream(this Direct3D11CaptureFrame frame)
diff --git a/Vision.WindowCapture/GraphicsCapture/Helpers/WinRT.cs b/Vision.WindowCapture/GraphicsCapture/Helpers/WinRT.cs
deleted file mode 100644
index d632a06b..00000000
--- a/Vision.WindowCapture/GraphicsCapture/Helpers/WinRT.cs
+++ /dev/null
@@ -1,115 +0,0 @@
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Reflection;
-using System.Runtime.InteropServices;
-using WinRT;
-
-namespace Vision.WindowCapture.GraphicsCapture.Helpers
-{
- [ComImport]
- [Guid( "3628E81B-3CAC-4C60-B7F4-23CE0E0C3356" )]
- [InterfaceType( ComInterfaceType.InterfaceIsIUnknown )]
- internal interface IGraphicsCaptureItemInterop
- {
- int CreateForWindow( [In] IntPtr window, [In] ref Guid iid, out IntPtr result );
-
- int CreateForMonitor( [In] IntPtr monitor, [In] ref Guid iid, out IntPtr result );
- }
-
- [Guid( "00000035-0000-0000-C000-000000000046" )]
- internal unsafe struct IActivationFactoryVftbl
- {
-#pragma warning disable CS0649 // Field is never assigned to, and will always have its default value
- public readonly IInspectable.Vftbl IInspectableVftbl;
- private readonly void* _ActivateInstance;
-#pragma warning restore
-
- public delegate* unmanaged[Stdcall]< IntPtr, IntPtr*, int > ActivateInstance => (delegate* unmanaged[Stdcall]< IntPtr, IntPtr*, int >)_ActivateInstance;
- }
-
- internal class Platform
- {
- [DllImport( "api-ms-win-core-com-l1-1-0.dll" )]
- internal static extern int CoDecrementMTAUsage( IntPtr cookie );
-
- [DllImport( "api-ms-win-core-com-l1-1-0.dll" )]
- internal static extern unsafe int CoIncrementMTAUsage( IntPtr* cookie );
-
- [DllImport( "api-ms-win-core-winrt-l1-1-0.dll" )]
- internal static extern unsafe int RoGetActivationFactory( IntPtr runtimeClassId, ref Guid iid, IntPtr* factory );
- }
-
- ///
- /// https://github.com/zlatanov/windows-screen-recorder
- ///
- internal static class WinrtModule
- {
- private static readonly Dictionary> Cache = new Dictionary>();
-
- public static ObjectReference GetActivationFactory( string runtimeClassId )
- {
- lock ( Cache )
- {
- if ( Cache.TryGetValue( runtimeClassId, out var factory ) )
- return factory;
-
- var m = MarshalString.CreateMarshaler( runtimeClassId );
-
- try
- {
- var instancePtr = GetActivationFactory( MarshalString.GetAbi( m ) );
-
- factory = ObjectReference.Attach( ref instancePtr );
- Cache.Add( runtimeClassId, factory );
-
- return factory;
- }
- finally
- {
- m.Dispose();
- }
- }
- }
-
- private static unsafe IntPtr GetActivationFactory( IntPtr hstrRuntimeClassId )
- {
- if ( s_cookie == IntPtr.Zero )
- {
- lock ( s_lock )
- {
- if ( s_cookie == IntPtr.Zero )
- {
- IntPtr cookie;
- Marshal.ThrowExceptionForHR( Platform.CoIncrementMTAUsage( &cookie ) );
-
- s_cookie = cookie;
- }
- }
- }
-
- Guid iid = typeof( IActivationFactoryVftbl ).GUID;
- IntPtr instancePtr;
- int hr = Platform.RoGetActivationFactory( hstrRuntimeClassId, ref iid, &instancePtr );
-
- if ( hr == 0 )
- return instancePtr;
-
- throw new Win32Exception( hr );
- }
-
- public static bool ResurrectObjectReference( IObjectReference objRef )
- {
- var disposedField = objRef.GetType().GetField( "disposed", BindingFlags.NonPublic | BindingFlags.Instance )!;
- if ( !(bool)disposedField.GetValue( objRef )! )
- return false;
- disposedField.SetValue( objRef, false );
- GC.ReRegisterForFinalize( objRef );
- return true;
- }
-
- private static IntPtr s_cookie;
- private static readonly object s_lock = new object();
- }
-}
diff --git a/Vision.WindowCapture/IWindowCapture.cs b/Vision.WindowCapture/IWindowCapture.cs
index b58085c2..b95aa07c 100644
--- a/Vision.WindowCapture/IWindowCapture.cs
+++ b/Vision.WindowCapture/IWindowCapture.cs
@@ -1,15 +1,15 @@
using System.Drawing;
+using Windows.Win32.Foundation;
-namespace Vision.WindowCapture
+namespace Vision.WindowCapture;
+
+public interface IWindowCapture
{
- public interface IWindowCapture
- {
- bool IsCapturing { get; }
-
- void Start(IntPtr hWnd);
+ bool IsCapturing { get; }
+
+ void Start(HWND hWnd);
- Bitmap? Capture();
+ Bitmap? Capture();
- void Stop();
- }
+ void Stop();
}
\ No newline at end of file
diff --git a/Vision.WindowCapture/Vision.WindowCapture.csproj b/Vision.WindowCapture/Vision.WindowCapture.csproj
index c5e426bd..2d2cfa5a 100644
--- a/Vision.WindowCapture/Vision.WindowCapture.csproj
+++ b/Vision.WindowCapture/Vision.WindowCapture.csproj
@@ -8,11 +8,12 @@
-
-
-
-
+
+
+
+
+
diff --git a/Vision.WindowCapture/WindowCaptureFactory.cs b/Vision.WindowCapture/WindowCaptureFactory.cs
index f66f5d00..04e6062b 100644
--- a/Vision.WindowCapture/WindowCaptureFactory.cs
+++ b/Vision.WindowCapture/WindowCaptureFactory.cs
@@ -1,44 +1,37 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+namespace Vision.WindowCapture;
-namespace Vision.WindowCapture
+public enum CaptureMode
{
- public enum CaptureMode
+ BitBlt,
+ WindowsGraphicsCapture
+}
+
+public static class CaptureModeExtensions
+{
+ public static CaptureMode ToCaptureMode(this string modeName)
{
- BitBlt,
- WindowsGraphicsCapture
+ return (CaptureMode) Enum.Parse(typeof(CaptureMode), modeName);
+ }
+}
+
+public class WindowCaptureFactory
+{
+ public static string[] ModeNames()
+ {
+ return Enum.GetNames(typeof(CaptureMode));
}
- public static class CaptureModeExtensions
+
+ public static IWindowCapture Create(CaptureMode mode)
{
- public static CaptureMode ToCaptureMode(this string modeName)
+ switch (mode)
{
- return (CaptureMode) Enum.Parse(typeof(CaptureMode), modeName);
- }
- }
-
- public class WindowCaptureFactory
- {
- public static string[] ModeNames()
- {
- return Enum.GetNames(typeof(CaptureMode));
- }
-
-
- public static IWindowCapture Create(CaptureMode mode)
- {
- switch (mode)
- {
- case CaptureMode.BitBlt:
- return new BitBlt.BitBltCapture();
- case CaptureMode.WindowsGraphicsCapture:
- return new GraphicsCapture.GraphicsCapture();
- default:
- throw new ArgumentOutOfRangeException(nameof(mode), mode, null);
- }
+ case CaptureMode.BitBlt:
+ return new BitBlt.BitBltCapture();
+ case CaptureMode.WindowsGraphicsCapture:
+ return new GraphicsCapture.GraphicsCapture();
+ default:
+ throw new ArgumentOutOfRangeException(nameof(mode), mode, null);
}
}
}