[update] IA墨跡識別庫預加載

This commit is contained in:
Dubi906w 2024-08-03 11:25:08 +08:00
parent 8a1bcc3ffa
commit 3203d0b13d
10 changed files with 70 additions and 148 deletions

View File

@ -1,2 +1,5 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/PencilsConfiguration/ActualSeverity/@EntryValue">WARNING</s:String></wpf:ResourceDictionary>
<s:String x:Key="/Default/CodeInspection/PencilsConfiguration/ActualSeverity/@EntryValue">WARNING</s:String>
<s:String x:Key="/Default/Environment/AssemblyExplorer/XmlDocument/@EntryValue">&lt;AssemblyExplorer&gt;&#xD;
&lt;Assembly Path="D:\vs\ica\InkCanvasForClass\IAWinFX.dll" /&gt;&#xD;
&lt;/AssemblyExplorer&gt;</s:String></wpf:ResourceDictionary>

View File

@ -20,9 +20,6 @@
<Compile Update="Popups\ScreenshotWindow.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="Popups\WindowScreenshotGridWindow.xaml.cs">
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<Page Update="MainWindow_cs\MW_ContextMenus.xaml">
@ -46,9 +43,6 @@
<Page Update="Popups\ScreenshotWindow.xaml">
<SubType>Designer</SubType>
</Page>
<Page Update="Popups\WindowScreenshotGridWindow.xaml">
<SubType>Designer</SubType>
</Page>
<Page Update="Resources\GeometryIcons.xaml">
<SubType>Designer</SubType>
</Page>

View File

@ -7802,9 +7802,9 @@
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<TextBlock Foreground="#fafafa" Text="自动截图最小墨迹量" VerticalAlignment="Center"
FontSize="14" Margin="0,0,16,0" />
<Slider x:Name="SideControlMinimumAutomationSlider" Minimum="0.3"
Maximum="1" Width="168" FontFamily="Microsoft YaHei UI"
FontSize="20" IsSnapToTickEnabled="True" Value="1" TickFrequency="0.05"
<Slider x:Name="SideControlMinimumAutomationSlider" Minimum="1"
Maximum="24" Width="168" FontFamily="Microsoft YaHei UI"
FontSize="20" IsSnapToTickEnabled="True" Value="1" TickFrequency="1"
TickPlacement="None" AutoToolTipPlacement="None"
ValueChanged="SideControlMinimumAutomationSlider_ValueChanged" />
<TextBlock

View File

@ -22,6 +22,7 @@ using System.Windows.Documents;
using Ink_Canvas.Popups;
using iNKORE.UI.WPF.Modern.Controls;
using System.Windows.Forms;
using System.Windows.Input;
using Application = System.Windows.Application;
using Button = System.Windows.Controls.Button;
using TextBox = System.Windows.Controls.TextBox;
@ -201,6 +202,22 @@ namespace Ink_Canvas {
const uint MF_GRAYED = 0x00000001;
const uint SC_CLOSE = 0xF060;
private static void PreloadIALibrary(object state) {
GC.KeepAlive(typeof(InkAnalyzer));
GC.KeepAlive(typeof(AnalysisAlternate));
GC.KeepAlive(typeof(InkDrawingNode));
var analyzer = new InkAnalyzer();
analyzer.AddStrokes(new StrokeCollection() {
new Stroke(new StylusPointCollection() {
new StylusPoint(114,514),
new StylusPoint(191,9810),
new StylusPoint(7,21),
new StylusPoint(123,789),
})
});
analyzer.Analyze();
}
private async void Window_Loaded(object sender, RoutedEventArgs e) {
loadPenCanvas();
//加载设置
@ -231,10 +248,7 @@ namespace Ink_Canvas {
BoardBackgroundPopup.Visibility = Visibility.Collapsed;
// 提前加载IA库优化第一笔等待时间
if (Settings.InkToShape.IsInkToShapeEnabled && !Environment.Is64BitProcess) {
var strokeEmpty = new StrokeCollection();
InkRecognizeHelper.RecognizeShape(strokeEmpty);
}
ThreadPool.QueueUserWorkItem(PreloadIALibrary);
SystemEvents.DisplaySettingsChanged += SystemEventsOnDisplaySettingsChanged;

View File

@ -420,17 +420,33 @@ namespace Ink_Canvas {
};
excluded.AddRange(excludedHwnds);
if (!EnumDesktopWindows(IntPtr.Zero, new EnumDesktopWindowsDelegate((hwnd, param) => {
// 排除被過濾的窗體句柄
if (excluded.Contains(new HWND(hwnd))) return true;
// 判斷窗體是否可見
var isvisible = IsWindowVisible(hwnd);
if (!isvisible) return true;
// 判斷窗體透明度和額外樣式
var windowLong = (int)GetWindowLongPtr(hwnd, -20);
GetLayeredWindowAttributes(hwnd, out uint crKey, out byte bAlpha, out uint dwFlags);
if ((windowLong & 0x00000080L) != 0) return true;
if ((windowLong & 0x00080000) != 0 && (dwFlags & 0x00000002) != 0 && bAlpha == 0) return true; //分层窗口且全透明
DwmGetWindowAttribute(hwnd, (int)DwmWindowAttribute.Cloaked, out bool isCloacked, Marshal.SizeOf(typeof(bool)));
// Win8+專用用於檢測UWP應用是否隱藏
bool isCloacked = false;
if (OSVersion.GetOperatingSystem() > OperatingSystem.Windows7)
DwmGetWindowAttribute(hwnd, (int)DwmWindowAttribute.Cloaked, out isCloacked, Marshal.SizeOf(typeof(bool)));
if (isCloacked) return true;
// 獲取窗體實際大小
DwmGetWindowAttribute(hwnd, DwmWindowAttribute.ExtendedFrameBounds, out RECT realRect, Marshal.SizeOf(typeof(RECT)));
// 獲取窗體的進程ID
var pidRes = GetWindowThreadProcessId(hwnd, out uint pid);
if (pid == 0 || pidRes == 0) return true;
// 獲取窗體的DPI差異scale為1則代表非DWM強制拉伸顯示窗體實際截圖會根據窗體的DPI Awareness來截取
var dpiForHwnd = GetDpiForWindow(hwnd);
var dpiXProperty = typeof(SystemParameters).GetProperty("DpiX", BindingFlags.NonPublic | BindingFlags.Static);
var dpiYProperty = typeof(SystemParameters).GetProperty("Dpi", BindingFlags.NonPublic | BindingFlags.Static);
@ -441,26 +457,39 @@ namespace Ink_Canvas {
if (dpi > dpiForHwnd) { // 说明该应用是win32应用靠DWM的拉伸放大到高DPI
scale = dpi / (double)dpiForHwnd;
}
if (isCloacked) return true;
// 獲取窗體應用程式圖標
var icon = GetAppIcon(hwnd);
// 獲取應用程式標題,這裡空標題不略過,用於後續繼續判斷獲取標題
var length = GetWindowTextLength(hwnd) + 1;
var title = new StringBuilder(length);
GetWindowText(hwnd, title, length);
// if (title.ToString().Length == 0) return true;
// 這裡懶得做 Alt Tab窗口的校驗了直接窗體標題黑名單
// 窗體標題黑名單,在黑名單中的窗體不會顯示
if (excludedWindowTitle.Equals(title.ToString())) return true;
RECT rect;
// 獲取窗體狀態,如果是最小化就跳過
WINDOWPLACEMENT placement = new WINDOWPLACEMENT();
GetWindowPlacement(hwnd, ref placement);
if (placement.showCmd == 2) return true;
// 獲取窗口Rect用於和DwmGetWindowAttribute方法獲取到的窗體大小進行Offset計算
RECT rect;
GetWindowRect(hwnd, out rect);
var w = rect.Width;
var h = rect.Height;
if (w == 0 || h == 0) return true;
// 使用PrintWindowRENDER_FULL_CONTENT來實現窗體圖片截取支持D3D和DX
Bitmap bmp = new Bitmap(rect.Width, rect.Height);
Graphics memoryGraphics = Graphics.FromImage(bmp);
IntPtr hdc = memoryGraphics.GetHdc();
PrintWindow(hwnd, hdc, 2);
// 添加窗體信息
windows.Add(new WindowInformation() {
AppIcon = icon,
Title = title.ToString(),
@ -478,7 +507,11 @@ namespace Ink_Canvas {
SystemDPI = dpi,
DPIScale = scale
});
// 釋放HDC
memoryGraphics.ReleaseHdc(hdc);
// 嘗試調用GC回收叻色
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
return true;

View File

@ -103,6 +103,7 @@ namespace Ink_Canvas {
AdministratorPrivilegeIndicateText.Text = "icc目前以非管理员身份运行";
RunAsAdminButton.Visibility = Visibility.Visible;
RunAsUserButton.Visibility = Visibility.Collapsed;
CannotSwitchToUserPrivNotification.IsOpen = false;
}
}
catch (Exception e) {

View File

@ -191,7 +191,7 @@
</Border>
</Grid>
</Border>
<Border Name="WindowScreenshotOverlay" Background="#dd09090b" Visibility="Visible">
<Border Name="WindowScreenshotOverlay" Background="#dd09090b" Visibility="Collapsed">
<Grid>
<modern:SimpleStackPanel Margin="48,36" Orientation="Vertical" HorizontalAlignment="Left" VerticalAlignment="Top">
<TextBlock Text="窗口截图" FontWeight="Bold" Foreground="White" FontSize="48"/>

View File

@ -24,10 +24,12 @@ using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Shell;
using System.Xml.Linq;
using OSVersionExtension;
using Vanara.PInvoke;
using Color = System.Windows.Media.Color;
using Shell32;
using static Ink_Canvas.MainWindow;
using OperatingSystem = OSVersionExtension.OperatingSystem;
namespace Ink_Canvas.Popups
{
@ -51,6 +53,10 @@ namespace Ink_Canvas.Popups
SelectionIcon,
DesktopIcon
};
WindowIcon.IsHitTestVisible = OSVersion.GetOperatingSystem() >= OperatingSystem.Windows10;
WindowIcon.Opacity = OSVersion.GetOperatingSystem() >= OperatingSystem.Windows10 ? 1 : 0.5;
foreach (var b in iconList) {
b.MouseLeave += IconMouseLeave;

View File

@ -1,32 +0,0 @@
<Window x:Class="Ink_Canvas.Popups.WindowScreenshotGridWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Ink_Canvas.Popups"
xmlns:modern="http://schemas.inkore.net/lib/ui/wpf/modern"
mc:Ignorable="d" WindowStyle="None" Background="#18181b" WindowState="Maximized" ResizeMode="NoResize"
Title="WindowScreenshotGridWindow" Height="450" Width="800">
<Grid>
<WrapPanel Orientation="Horizontal">
<ItemsControl Name="WindowsItemControl">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<modern:SimpleStackPanel Tag="{Binding}" MouseUp="WindowItem_MouseUp">
<Image Width="256" Source="{Binding Bitmap}"/>
<StackPanel Orientation="Horizontal">
<Image VerticalAlignment="Center" Width="36" Height="36" Source="{Binding Icon}"/>
<TextBlock VerticalAlignment="Center" Margin="8,0,0,0" FontSize="16" Foreground="White" Text="{Binding Title}"/>
</StackPanel>
</modern:SimpleStackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</WrapPanel>
</Grid>
</Window>

View File

@ -1,97 +0,0 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using iNKORE.UI.WPF.Modern.Controls;
using Vanara.PInvoke;
namespace Ink_Canvas.Popups
{
/// <summary>
/// WindowScreenshotGridWindow.xaml 的交互逻辑
/// </summary>
public partial class WindowScreenshotGridWindow : Window
{
private BitmapImage BitmapToImageSource(Bitmap bitmap)
{
using (MemoryStream memory = new MemoryStream())
{
bitmap.Save(memory, System.Drawing.Imaging.ImageFormat.Bmp);
memory.Position = 0;
BitmapImage bitmapimage = new BitmapImage();
bitmapimage.BeginInit();
bitmapimage.StreamSource = memory;
bitmapimage.CacheOption = BitmapCacheOption.OnLoad;
bitmapimage.EndInit();
return bitmapimage;
}
}
private static ImageSource IconToImageSource(Icon icon)
{
ImageSource imageSource = Imaging.CreateBitmapSourceFromHIcon(
icon.Handle,
Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
return imageSource;
}
private class Win {
public string Title { get; set; }
public BitmapImage Bitmap { get; set; }
public ImageSource Icon { get; set; }
public HWND Handle { get; set; }
public Bitmap OriginBitmap { get; set; }
}
private MainWindow mainWindow;
private ObservableCollection<Win> _windows = new ObservableCollection<Win>();
public WindowScreenshotGridWindow(MainWindow.WindowInformation[] wins, MainWindow mainWindow) {
InitializeComponent();
WindowsItemControl.ItemsSource = _windows;
foreach (var windowInformation in wins) {
_windows.Add(new Win() {
Title = windowInformation.Title,
Bitmap = BitmapToImageSource(windowInformation.WindowBitmap),
Handle = windowInformation.hwnd,
OriginBitmap = windowInformation.WindowBitmap,
Icon = IconToImageSource(windowInformation.AppIcon)
});
Trace.WriteLine(windowInformation.Title);
}
this.mainWindow = mainWindow;
}
protected override void OnClosed(EventArgs e) {
base.OnClosed(e);
_windows.Clear();
}
private void WindowItem_MouseUp(object sender, MouseButtonEventArgs e) {
var item = ((SimpleStackPanel)sender).Tag as Win;
string savePath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
item.OriginBitmap.Save(savePath + @"\" + DateTime.Now.ToString("u").Replace(':', '-') + ".bmp", ImageFormat.Bmp);
}
}
}