Skip to content

Commit

Permalink
新增 支持窗口截图
Browse files Browse the repository at this point in the history
  • Loading branch information
MakesYT committed Jan 3, 2025
1 parent 1f68f12 commit 2c01007
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 20 deletions.
31 changes: 31 additions & 0 deletions Core.Window/ScreenCapture/ScreenCaptureByDx11.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
using System.Text;
using Windows.Graphics;
using Windows.Graphics.Capture;
using Windows.Graphics.Display;
Expand Down Expand Up @@ -120,7 +121,37 @@ private void Dx11Helper(Action<Dx11Ptrs> action)
}
}
}
public List<WindowInfo> GetAllWindowInfo()
{
var screenCaptureInfos = new List<WindowInfo>();
uint i = 0;
User32.EnumWindows( (arg1, arg2) =>
{
if (User32.GetParent(arg1).IsNull)
{
return true;
}

if (!User32.IsWindowVisible(arg1))
{
return true;
}

User32.GetWindowRect(arg1, out var rect);
StringBuilder stringBuilder = new StringBuilder();
User32.GetWindowText(arg1, stringBuilder, 100);

screenCaptureInfos.Add(new WindowInfo()
{
Title = stringBuilder.ToString(),
Hwnd = arg1.DangerousGetHandle(),
Rect = new Rect(rect.X,rect.Y,rect.Width,rect.Height)
});
return true;
}, IntPtr.Zero);

return screenCaptureInfos;
}
public Stack<ScreenCaptureResult> CaptureAllScreen()
{
var screenCaptureResults = new Stack<ScreenCaptureResult>();
Expand Down
39 changes: 36 additions & 3 deletions Core.Window/ScreenCapture/ScreenCaptureByWGC.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Text;
using Windows.Graphics;
using Windows.Graphics.Capture;
using Avalonia;
Expand Down Expand Up @@ -41,7 +42,7 @@ public List<ScreenCaptureInfo> GetAllScreenInfo()
Width = arg3.right - arg3.left,
Height = arg3.bottom - arg3.top,
hMonitor = arg1,
hdcMonitor = arg2

}

});
Expand All @@ -51,6 +52,38 @@ public List<ScreenCaptureInfo> GetAllScreenInfo()

return screenCaptureInfos;
}
public List<WindowInfo> GetAllWindowInfo()
{
var screenCaptureInfos = new List<WindowInfo>();
uint i = 0;
User32.EnumWindows( (arg1, arg2) =>
{
if (!User32.GetParent(arg1).IsNull)
{
return true;
}

if (!User32.IsWindowVisible(arg1))
{
return true;
}

User32.GetWindowRect(arg1, out var rect);
StringBuilder stringBuilder = new StringBuilder(100);
User32.GetWindowText(arg1, stringBuilder, 100);


screenCaptureInfos.Add(new WindowInfo()
{
Title = stringBuilder.ToString(),
Hwnd = arg1.DangerousGetHandle(),
Rect = new Rect(rect.X,rect.Y,rect.Width,rect.Height)
});
return true;
}, IntPtr.Zero);

return screenCaptureInfos;
}

public ScreenCaptureInfo GetScreenCaptureInfoByIndex(int index)
{
Expand Down Expand Up @@ -323,8 +356,8 @@ IDirect3DDevice CreateDirect3DDeviceFromSharpDXDevice(ID3D11Device* d3dDevice)
{


adapter1.Release();
adapter1 = null;
adapter1.Release();
adapter1 = null;


if (context != null)
Expand Down
42 changes: 42 additions & 0 deletions Core.Window/ScreenCapture/ScreenCaptureManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,48 @@ public List<ScreenCaptureInfo> GetAllScreenInfo()

return null;
}
public List<WindowInfo> GetAllWindowInfo()
{
var screenCaptures = ServiceManager.Services.GetServices<IScreenCapture>();
switch (ConfigManger.Config.截图方法)
{
case "Directx11":
{
var firstOrDefault = screenCaptures.FirstOrDefault(e => e.GetType() == typeof(ScreenCaptureByDx11));
if (firstOrDefault is null)
{
ConfigManger.Config.截图方法 = "自动";
return new List<WindowInfo>();
}

return firstOrDefault.GetAllWindowInfo();
}

case "WGC":
{
var firstOrDefault = screenCaptures.FirstOrDefault(e => e.GetType() == typeof(ScreenCaptureByWGC));
if (firstOrDefault is null)
{
ConfigManger.Config.截图方法 = "自动";
return new List<WindowInfo>();
}

return firstOrDefault.GetAllWindowInfo();
}
default:
{
foreach (var screenCapture in screenCaptures)
{
var screenCaptureInfos = screenCapture.GetAllWindowInfo();
if (screenCaptureInfos.Count > 0) return screenCaptureInfos;
}

break;
}
}

return null;
}

public ScreenCaptureInfo GetScreenCaptureInfoByIndex(int index)
{
Expand Down
43 changes: 31 additions & 12 deletions KitopiaAvalonia/Windows/ScreenCaptureWindow.axaml.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Avalonia;
Expand Down Expand Up @@ -45,9 +46,11 @@ public partial class ScreenCaptureWindow : Window
private Action selectBytesModeCancelAction;
private ScreenCaptureInfo _screenCaptureInfo;
private bool Finish = false;
private List<WindowInfo> _windowInfos;
public ScreenCaptureWindow(ScreenCaptureInfo screenCaptureInfo)
{
InitializeComponent();
_windowInfos = ServiceManager.Services.GetService<IScreenCaptureManager>()!.GetAllWindowInfo();
_screenCaptureInfo = screenCaptureInfo;
Position = new PixelPoint(screenCaptureInfo.ScreenInfo.X, screenCaptureInfo.ScreenInfo.Y);
WindowState = WindowState.FullScreen;
Expand Down Expand Up @@ -295,18 +298,34 @@ protected override void OnPointerMoved(PointerEventArgs e)

if (ShowAlignLine)
{
X.IsVisible = true;
Y.IsVisible = true;
X.StartPoint = new Point(0, e.GetPosition(this)
.Y);

X.EndPoint = new Point(Width, e.GetPosition(this)
.Y);

Y.StartPoint = new Point(e.GetPosition(this)
.X, 0);
Y.EndPoint = new Point(e.GetPosition(this)
.X, Height);

var currentPoint = e.GetCurrentPoint(this);
var screenInfoWidth = Bounds.Width/_screenCaptureInfo.ScreenInfo.Width;
var screenInfoHeight =Bounds.Height/_screenCaptureInfo.ScreenInfo.Height;
var positionY = currentPoint.Position.Y/screenInfoWidth;
var positionX = currentPoint.Position.X/screenInfoHeight;
var firstOrDefault = _windowInfos.FirstOrDefault(e => positionX >= e.Rect.X && positionX <= e.Rect.X + e.Rect.Width &&
positionY >= e.Rect.Y && positionY <= e.Rect.Y + e.Rect.Height);
if (firstOrDefault.Hwnd == IntPtr.Zero)
{
_startPoint = new Point(0, 0);
SelectBox._dragTransform.X = 0;
SelectBox._dragTransform.Y = 0;
SelectBox.Width = this.Bounds.Width;
SelectBox.Height = this.Bounds.Height;

}
else
{

_startPoint=new Point(firstOrDefault.Rect.X*screenInfoWidth,firstOrDefault.Rect.Y*screenInfoHeight);
SelectBox._dragTransform.X = _startPoint.X;
SelectBox._dragTransform.Y = _startPoint.Y;
SelectBox.Width = firstOrDefault.Rect.Width*screenInfoWidth;
SelectBox.Height = firstOrDefault.Rect.Height*screenInfoHeight;
}
SelectBox.IsVisible = true;
UpdateSelectBox();
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ public string Serialize<T>(T value)
{
return "";
}
return $"ScreenInfo.X={screenCaptureInfo.ScreenInfo.X},ScreenInfo.Y={screenCaptureInfo.ScreenInfo.Y},ScreenInfo.Height={screenCaptureInfo.ScreenInfo.Height},ScreenInfo.Width={screenCaptureInfo.ScreenInfo.Width},ScreenInfo.hdcMonitor={screenCaptureInfo.ScreenInfo.hdcMonitor},ScreenInfo.hMonitor={screenCaptureInfo.ScreenInfo.hMonitor},{nameof(screenCaptureInfo.X)}={screenCaptureInfo.X},{nameof(screenCaptureInfo.Y)}={screenCaptureInfo.Y},{nameof(screenCaptureInfo.Width)}={screenCaptureInfo.Width},{nameof(screenCaptureInfo.Height)}={screenCaptureInfo.Height}";
return $"WindowInfo.Title={screenCaptureInfo.WindowInfo.Title},ScreenInfo.X={screenCaptureInfo.ScreenInfo.X},ScreenInfo.Y={screenCaptureInfo.ScreenInfo.Y},ScreenInfo.Height={screenCaptureInfo.ScreenInfo.Height},ScreenInfo.Width={screenCaptureInfo.ScreenInfo.Width},{nameof(screenCaptureInfo.X)}={screenCaptureInfo.X},{nameof(screenCaptureInfo.Y)}={screenCaptureInfo.Y},{nameof(screenCaptureInfo.Width)}={screenCaptureInfo.Width},{nameof(screenCaptureInfo.Height)}={screenCaptureInfo.Height}";
}

public object Deserialize(ReadOnlySpan<byte> value)
{
var str = Encoding.UTF8.GetString(value);

var split = str.Split(',');
if (split.Length != 10)
if (split.Length != 9)
{
return null;
}
Expand All @@ -43,6 +43,10 @@ public object Deserialize(ReadOnlySpan<byte> value)
X = int.Parse(dic["ScreenInfo.X"]),
Y = int.Parse(dic["ScreenInfo.Y"]),
},
WindowInfo = new WindowInfo()
{
Title = dic["WindowInfo.Title"],
},
X = int.Parse(dic[nameof(ScreenCaptureInfo.X)]),
Y = int.Parse(dic[nameof(ScreenCaptureInfo.Y)]),
Width = int.Parse(dic[nameof(ScreenCaptureInfo.Width)]),
Expand Down
4 changes: 2 additions & 2 deletions KitopiaEx/KitopiaEx.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ public void OnEnabled(IServiceProvider serviceProvider)
{
var screenCaptureInfo = (ScreenCaptureInfo)info;
return
$"显示器:{screenCaptureInfo.ScreenInfo.hdcMonitor},起始坐标:{screenCaptureInfo.X},{screenCaptureInfo.Y}\n大小:{screenCaptureInfo.Width}x{screenCaptureInfo.Height}";
$"显示器:{screenCaptureInfo.ScreenInfo.hMonitor},起始坐标:{screenCaptureInfo.X},{screenCaptureInfo.Y}\n大小:{screenCaptureInfo.Width}x{screenCaptureInfo.Height}";
});
Kitopia.ToolTipConverters.TryAdd(typeof(ScreenCaptureResult), e =>
{
var screenCaptureResult = (ScreenCaptureResult)e;
var screenCaptureInfo = screenCaptureResult.Info;
return
$"显示器:{screenCaptureInfo.ScreenInfo.hdcMonitor},起始坐标:{screenCaptureInfo.X},{screenCaptureInfo.Y}\n大小:{screenCaptureInfo.Width}x{screenCaptureInfo.Height}\nByte数据:{(screenCaptureResult.Bytes is null?"不存在":"存在")}\nBitmap数据:{(screenCaptureResult.Source is null?"不存在":"存在")}";
$"显示器:{screenCaptureInfo.ScreenInfo.hMonitor},起始坐标:{screenCaptureInfo.X},{screenCaptureInfo.Y}\n大小:{screenCaptureInfo.Width}x{screenCaptureInfo.Height}\nByte数据:{(screenCaptureResult.Bytes is null?"不存在":"存在")}\nBitmap数据:{(screenCaptureResult.Source is null?"不存在":"存在")}";
});
Kitopia.JsonConverters.TryAdd(typeof(ScreenCaptureInfo), new ScreenCaptureInfoCustomScenarioValueSerializer());
}
Expand Down
2 changes: 1 addition & 1 deletion PluginCore

0 comments on commit 2c01007

Please sign in to comment.