diff --git a/InkCanvasForClass/InkCanvasForClass.csproj b/InkCanvasForClass/InkCanvasForClass.csproj
index b46a5c3..ab33dfe 100644
--- a/InkCanvasForClass/InkCanvasForClass.csproj
+++ b/InkCanvasForClass/InkCanvasForClass.csproj
@@ -123,6 +123,8 @@
+
+
@@ -190,6 +192,15 @@
False
True
+
+ tlbimp
+ 0
+ 1
+ 50a7e9b0-70ef-11d1-b75a-00a0c90564fe
+ 0
+ false
+ true
+
@@ -209,9 +220,12 @@
+
+
+
@@ -509,9 +523,12 @@
+
+
+
diff --git a/InkCanvasForClass/MainWindow.xaml.cs b/InkCanvasForClass/MainWindow.xaml.cs
index de8404f..cda1ef6 100644
--- a/InkCanvasForClass/MainWindow.xaml.cs
+++ b/InkCanvasForClass/MainWindow.xaml.cs
@@ -186,7 +186,7 @@ namespace Ink_Canvas {
public static Settings Settings = new Settings();
public static string settingsFileName = "Settings.json";
- private bool isLoaded = false;
+ public bool isLoaded = false;
[DllImport("user32.dll")]
static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
diff --git a/InkCanvasForClass/MainWindow_cs/MW_FloatingBarIcons.cs b/InkCanvasForClass/MainWindow_cs/MW_FloatingBarIcons.cs
index b854e8f..b8d3fde 100644
--- a/InkCanvasForClass/MainWindow_cs/MW_FloatingBarIcons.cs
+++ b/InkCanvasForClass/MainWindow_cs/MW_FloatingBarIcons.cs
@@ -1030,7 +1030,7 @@ namespace Ink_Canvas {
HideSubPanelsImmediately();
await Task.Delay(50);
//SaveScreenShotToDesktop();
- var scrwin = new ScreenshotWindow(this);
+ var scrwin = new ScreenshotWindow(this,Settings);
scrwin.Show();
}
diff --git a/InkCanvasForClass/MainWindow_cs/MW_Screenshot.cs b/InkCanvasForClass/MainWindow_cs/MW_Screenshot.cs
index a4c01c1..bf6987a 100644
--- a/InkCanvasForClass/MainWindow_cs/MW_Screenshot.cs
+++ b/InkCanvasForClass/MainWindow_cs/MW_Screenshot.cs
@@ -17,10 +17,13 @@ using Vanara.PInvoke;
using Encoder = System.Drawing.Imaging.Encoder;
using OperatingSystem = OSVersionExtension.OperatingSystem;
using PixelFormat = System.Drawing.Imaging.PixelFormat;
+using System.Management;
+using System.Windows.Shapes;
+using Path = System.IO.Path;
+using Rectangle = System.Drawing.Rectangle;
namespace Ink_Canvas {
public partial class MainWindow : Window {
-
#region MagnificationAPI 获取屏幕截图并过滤ICC窗口
#region Dubi906w 的轮子
@@ -155,7 +158,8 @@ namespace Ink_Canvas {
IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
// 設定窗體樣式和排布
int style = GetWindowLong(windowHostHandle, GWL_STYLE);
- style &= ~WS_CAPTION; // 隐藏标题栏style &= ~WS_THICKFRAME; // 禁止窗口拉伸
+ style &= ~WS_CAPTION; // 隐藏标题栏
+ style &= ~WS_THICKFRAME; // 禁止窗口拉伸
SetWindowLong(windowHostHandle, GWL_STYLE, style);
SetWindowPos(windowHostHandle, IntPtr.Zero, 0, 0, 0, 0, SWP_NOSIZE | SWP_FRAMECHANGED);
// 設定額外樣式
@@ -166,11 +170,42 @@ namespace Ink_Canvas {
// 設定放大鏡工廠
Magnification.MAGTRANSFORM matrix = new Magnification.MAGTRANSFORM();
matrix[0, 0] = 1.0f;
+ matrix[0, 1] = 0.0f;
+ matrix[0, 2] = 0.0f;
+ matrix[1, 0] = 0.0f;
matrix[1, 1] = 1.0f;
- matrix[2, 2] = 1.0f;
+ matrix[1, 2] = 0.0f;
+ matrix[2, 0] = 1.0f;
+ matrix[2, 1] = 0.0f;
+ matrix[2, 2] = 0.0f;
if (!Magnification.MagSetWindowTransform(hwndMag, matrix)) return;
// 設定放大鏡轉化矩乘陣列
Magnification.MAGCOLOREFFECT magEffect = new Magnification.MAGCOLOREFFECT();
+ magEffect[0, 0] = 1.0f;
+ magEffect[0, 1] = 0.0f;
+ magEffect[0, 2] = 0.0f;
+ magEffect[0, 3] = 0.0f;
+ magEffect[0, 4] = 0.0f;
+ magEffect[1, 0] = 0.0f;
+ magEffect[1, 1] = 1.0f;
+ magEffect[1, 2] = 0.0f;
+ magEffect[1, 3] = 0.0f;
+ magEffect[1, 4] = 0.0f;
+ magEffect[2, 0] = 0.0f;
+ magEffect[2, 1] = 0.0f;
+ magEffect[2, 2] = 1.0f;
+ magEffect[2, 3] = 0.0f;
+ magEffect[2, 4] = 0.0f;
+ magEffect[3, 0] = 0.0f;
+ magEffect[3, 1] = 0.0f;
+ magEffect[3, 2] = 0.0f;
+ magEffect[3, 3] = 1.0f;
+ magEffect[3, 4] = 0.0f;
+ magEffect[4, 0] = 0.0f;
+ magEffect[4, 1] = 0.0f;
+ magEffect[4, 2] = 0.0f;
+ magEffect[4, 3] = 0.0f;
+ magEffect[4, 4] = 1.0f;
if (!Magnification.MagSetColorEffect(hwndMag, magEffect)) return;
// 顯示窗體
ShowWindow(windowHostHandle, SW_SHOW);
@@ -202,6 +237,7 @@ namespace Ink_Canvas {
memoryGraphics.ReleaseHdc();
callbackAction(bmp);
}
+
// 反注册宿主窗口
UnregisterClass("ICCMagnifierWindowHost", IntPtr.Zero);
// 销毁宿主窗口
@@ -209,10 +245,11 @@ namespace Ink_Canvas {
DestroyWindow(windowHostHandle);
}
- public Task SaveScreenshotToDesktopByMagnificationAPIAsync(HWND[] hwndsList, bool isUsingCallback = false) {
+ public Task SaveScreenshotToDesktopByMagnificationAPIAsync(HWND[] hwndsList,
+ bool isUsingCallback = false) {
return Task.Run(() => {
var t = new TaskCompletionSource();
- SaveScreenshotToDesktopByMagnificationAPI(hwndsList, bitmap => t.TrySetResult(bitmap),isUsingCallback);
+ SaveScreenshotToDesktopByMagnificationAPI(hwndsList, bitmap => t.TrySetResult(bitmap), isUsingCallback);
return t.Task;
});
}
@@ -229,9 +266,9 @@ namespace Ink_Canvas {
static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
public static IntPtr GetClassLongPtr(IntPtr hWnd, int nIndex) {
- if (IntPtr.Size > 4)
+ if (IntPtr.Size > 4)
return GetClassLongPtr64(hWnd, nIndex);
- else
+ else
return new IntPtr(GetClassLongPtr32(hWnd, nIndex));
}
@@ -276,6 +313,45 @@ namespace Ink_Canvas {
[DllImport("dwmapi.dll")]
static extern int DwmGetWindowAttribute(IntPtr hwnd, int dwAttribute, out bool pvAttribute, int cbAttribute);
+ [DllImport("dwmapi.dll")]
+ static extern int DwmGetWindowAttribute(IntPtr hwnd, DwmWindowAttribute dwAttribute, out RECT pvAttribute, int cbAttribute);
+ [DllImport("user32.dll", SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ static extern bool GetLayeredWindowAttributes(IntPtr hwnd, out uint crKey, out byte bAlpha, out uint dwFlags);
+ public delegate bool EnumWindowsProc(IntPtr hwnd, IntPtr lParam);
+ [DllImport("user32.dll")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool EnumChildWindows(IntPtr hwndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam);
+ [DllImport("user32.dll", SetLastError=true)]
+ static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId);
+
+ enum DwmWindowAttribute : uint {
+ NCRenderingEnabled = 1,
+ NCRenderingPolicy,
+ TransitionsForceDisabled,
+ AllowNCPaint,
+ CaptionButtonBounds,
+ NonClientRtlLayout,
+ ForceIconicRepresentation,
+ Flip3DPolicy,
+ ExtendedFrameBounds,
+ HasIconicBitmap,
+ DisallowPeek,
+ ExcludedFromPeek,
+ Cloak,
+ Cloaked,
+ FreezeRepresentation,
+ PassiveUpdateMode,
+ UseHostBackdropBrush,
+ UseImmersiveDarkMode = 20,
+ WindowCornerPreference = 33,
+ BorderColor,
+ CaptionColor,
+ TextColor,
+ VisibleFrameBorderThickness,
+ SystemBackdropType,
+ Last
+ }
public Icon GetAppIcon(IntPtr hwnd) {
IntPtr iconHandle = SendMessage(hwnd, 0x7F, 2, 0);
@@ -303,6 +379,9 @@ namespace Ink_Canvas {
public RECT Rect { get; set; }
public WINDOWPLACEMENT Placement { get; set; }
public HWND hwnd { get; set; }
+ public RECT RealRect { get; set; }
+ public Rectangle ContentRect { get; set; }
+ public IntPtr Handle { get; set; }
}
public struct WINDOWPLACEMENT {
@@ -334,7 +413,7 @@ namespace Ink_Canvas {
new HWND(hShellWnd), new HWND(hDefView), new HWND(folderView), new HWND(taskBar)
};
var excludedWindowTitle = new string[] {
- "NVIDIA GeForce Overlay"
+ "NVIDIA GeForce Overlay", "Ink Canvas 画板", "Ink Canvas Annotation", "Ink Canvas Artistry", "InkCanvasForClass"
};
excluded.AddRange(excludedHwnds);
if (!EnumDesktopWindows(IntPtr.Zero, new EnumDesktopWindowsDelegate((hwnd, param) => {
@@ -342,16 +421,19 @@ namespace Ink_Canvas {
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;
- DwmGetWindowAttribute(hwnd, 14, out bool isCloacked, Marshal.SizeOf(typeof(bool)));
+ if ((windowLong & 0x00080000) != 0 && (dwFlags & 0x00000002) != 0 && bAlpha == 0) return true; //分层窗口且全透明
+ DwmGetWindowAttribute(hwnd, (int)DwmWindowAttribute.Cloaked, out bool isCloacked, Marshal.SizeOf(typeof(bool)));
+ DwmGetWindowAttribute(hwnd, DwmWindowAttribute.ExtendedFrameBounds, out RECT realRect, Marshal.SizeOf(typeof(RECT)));
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;
+ // if (title.ToString().Length == 0) return true;
// 這裡懶得做 Alt Tab窗口的校驗了,直接窗體標題黑名單
- if (excludedWindowTitle.Contains(title.ToString())) return true;
+ if (excludedWindowTitle.Equals(title.ToString())) return true;
RECT rect;
WINDOWPLACEMENT placement = new WINDOWPLACEMENT();
GetWindowPlacement(hwnd, ref placement);
@@ -359,6 +441,7 @@ namespace Ink_Canvas {
GetWindowRect(hwnd, out rect);
var w = rect.Width;
var h = rect.Height;
+ Trace.WriteLine($"x: {realRect.X - rect.X} y: {realRect.Y - rect.Y} w: {realRect.Width} h: {realRect.Height}");
if (w == 0 || h == 0) return true;
Bitmap bmp = new Bitmap(rect.Width, rect.Height);
Graphics memoryGraphics = Graphics.FromImage(bmp);
@@ -373,6 +456,9 @@ namespace Ink_Canvas {
Height = h,
Rect = rect,
Placement = placement,
+ RealRect = realRect,
+ Handle = hwnd,
+ ContentRect = new Rectangle(realRect.X - rect.X, realRect.Y - rect.Y, realRect.Width, realRect.Height),
});
memoryGraphics.ReleaseHdc(hdc);
System.GC.Collect();
@@ -383,9 +469,57 @@ namespace Ink_Canvas {
return windows.ToArray();
}
+ public static string GetProcessPathByPid(int processId) {
+ string query = $"SELECT Name, ExecutablePath FROM Win32_Process WHERE ProcessId = {processId}";
+ ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
+ foreach (ManagementObject obj in searcher.Get()) {
+ string executablePath = obj["ExecutablePath"]?.ToString();
+ if (!string.IsNullOrEmpty(executablePath)) return executablePath;
+ }
+ return "";
+ }
+
+ public async Task GetProcessPathByPidAsync(int processId) {
+ var result = await Task.Run(() => GetProcessPathByPid(processId));
+ return result;
+ }
+
+ private static string GetAppFriendlyName(string filePath)
+ {
+ var versionInfo = FileVersionInfo.GetVersionInfo(filePath);
+ return versionInfo.FileDescription;
+ }
+
public async Task GetAllWindowsAsync(HWND[] excludedHwnds) {
var windows = await Task.Run(() => GetAllWindows(excludedHwnds));
- return windows;
+ var _wins = new List(){};
+ foreach (var w in windows) {
+ _wins.Add(w);
+ }
+ foreach (var windowInformation in windows) {
+ if (windowInformation.Title.Length == 0) {
+ GetWindowThreadProcessId(windowInformation.Handle, out uint Pid);
+ if (Pid != 0) {
+ var _path = Path.GetFullPath(await GetProcessPathByPidAsync((int)Pid));
+ var processPath = Path.GetFullPath(Process.GetCurrentProcess().MainModule.FileName);
+ if (string.Equals(_path, processPath, StringComparison.OrdinalIgnoreCase) || _path == "") {
+ _wins.Remove(windowInformation);
+ } else {
+ var _des = GetAppFriendlyName(_path);
+ Trace.WriteLine(_des);
+ if (_des == null) {
+ _wins.Remove(windowInformation);
+ } else {
+ var index = _wins.IndexOf(windowInformation);
+ _wins[index].Title = _des;
+ }
+ }
+ } else {
+ _wins.Remove(windowInformation);
+ }
+ }
+ }
+ return _wins.ToArray();
}
#endregion
@@ -398,6 +532,7 @@ namespace Ink_Canvas {
using (Graphics memoryGrahics = Graphics.FromImage(bitmap)) {
memoryGrahics.CopyFromScreen(rc.X, rc.Y, 0, 0, rc.Size, CopyPixelOperation.SourceCopy);
}
+
return bitmap;
}
@@ -405,10 +540,8 @@ namespace Ink_Canvas {
#region 通用截圖API
- private BitmapImage BitmapToImageSource(Bitmap bitmap)
- {
- using (MemoryStream memory = new MemoryStream())
- {
+ 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();
@@ -444,40 +577,48 @@ namespace Ink_Canvas {
public HWND[] ExcludedHwnds { get; set; } = new HWND[] { };
}
- private static ImageCodecInfo GetEncoderInfo(string mimeType)
- {
+ private static ImageCodecInfo GetEncoderInfo(string mimeType) {
foreach (ImageCodecInfo codec in ImageCodecInfo.GetImageEncoders())
if (codec.MimeType == mimeType)
return codec;
return null;
}
-
+
public async Task FullscreenSnapshot(SnapshotConfig config) {
- Bitmap bitmap = new Bitmap(1,1);
+ Bitmap bitmap = new Bitmap(1, 1);
var ex = new List() { new HWND(new WindowInteropHelper(this).Handle) };
ex.AddRange(config.ExcludedHwnds);
if (config.SnapshotMethod == SnapshotMethod.Auto) {
if (OSVersion.GetOperatingSystem() >= OperatingSystem.Windows81) {
- bitmap = await SaveScreenshotToDesktopByMagnificationAPIAsync(ex.ToArray(),false);
+ bitmap = await SaveScreenshotToDesktopByMagnificationAPIAsync(ex.ToArray(), false);
} else {
- if (ex.Count != 0) foreach (var hwnd in ex) ShowWindow(hwnd.DangerousGetHandle(), 0);
+ if (ex.Count != 0)
+ foreach (var hwnd in ex)
+ ShowWindow(hwnd.DangerousGetHandle(), 0);
bitmap = GetScreenshotBitmap();
foreach (var hwnd in ex) ShowWindow(hwnd.DangerousGetHandle(), 5);
}
- } else if (config.SnapshotMethod == SnapshotMethod.MagnificationAPIWithPrintWindow || config.SnapshotMethod == SnapshotMethod.MagnificationAPIWithCallback) {
+ } else if (config.SnapshotMethod == SnapshotMethod.MagnificationAPIWithPrintWindow ||
+ config.SnapshotMethod == SnapshotMethod.MagnificationAPIWithCallback) {
if (!(OSVersion.GetOperatingSystem() >= OperatingSystem.Windows81))
throw new Exception("您的系統版本不支持 MagnificationAPI 截圖!");
- bitmap = await SaveScreenshotToDesktopByMagnificationAPIAsync(ex.ToArray(),config.SnapshotMethod == SnapshotMethod.MagnificationAPIWithCallback);
+ bitmap = await SaveScreenshotToDesktopByMagnificationAPIAsync(ex.ToArray(),
+ config.SnapshotMethod == SnapshotMethod.MagnificationAPIWithCallback);
} else if (config.SnapshotMethod == SnapshotMethod.GraphicsAPICopyFromScreen) {
- if (ex.Count != 0) foreach (var hwnd in ex) ShowWindow(hwnd.DangerousGetHandle(), 0);
+ if (ex.Count != 0)
+ foreach (var hwnd in ex)
+ ShowWindow(hwnd.DangerousGetHandle(), 0);
bitmap = GetScreenshotBitmap();
foreach (var hwnd in ex) ShowWindow(hwnd.DangerousGetHandle(), 5);
}
+
if (bitmap.Width == 1 && bitmap.Height == 1) throw new Exception("截圖失敗");
try {
if (config.IsCopyToClipboard) Clipboard.SetImage(BitmapToImageSource(bitmap));
- } catch (NotSupportedException e) {}
+ }
+ catch (NotSupportedException e) { }
+
if (config.IsSaveToLocal) {
var fullPath = config.BitmapSavePath.FullName;
if (!config.BitmapSavePath.Exists) config.BitmapSavePath.Create();
@@ -486,10 +627,13 @@ namespace Ink_Canvas {
.Replace("[HH]", DateTime.Now.Hour.ToString()).Replace("[mm]", DateTime.Now.Minute.ToString())
.Replace("[ss]", DateTime.Now.Second.ToString()).Replace("[width]", bitmap.Width.ToString())
.Replace("[height]", bitmap.Height.ToString());
- var finalPath = (fullPath.EndsWith("\\") ? fullPath.Substring(0, fullPath.Length - 1) : fullPath) + $"\\{fileName}";
- bitmap.Save(finalPath, config.OutputMIMEType == OutputImageMIMEFormat.Png ? ImageFormat.Png :
+ var finalPath = (fullPath.EndsWith("\\") ? fullPath.Substring(0, fullPath.Length - 1) : fullPath) +
+ $"\\{fileName}";
+ bitmap.Save(finalPath, config.OutputMIMEType == OutputImageMIMEFormat.Png ? ImageFormat.Png :
config.OutputMIMEType == OutputImageMIMEFormat.Bmp ? ImageFormat.Bmp : ImageFormat.Jpeg);
}
+ bitmap.Dispose();
+
return bitmap;
}
diff --git a/InkCanvasForClass/MainWindow_cs/MW_Storage.cs b/InkCanvasForClass/MainWindow_cs/MW_Storage.cs
index 77b72fa..52e4d3a 100644
--- a/InkCanvasForClass/MainWindow_cs/MW_Storage.cs
+++ b/InkCanvasForClass/MainWindow_cs/MW_Storage.cs
@@ -270,8 +270,11 @@ namespace Ink_Canvas {
}
-
- //private DirectoryInfo GetDirectoryBySettings()
+ private DirectoryInfo GetDirectoryBySettings() {
+ var si = Settings.Storage.StorageLocation;
+ throw new NotImplementedException();
+ return new DirectoryInfo("");
+ }
private DirectoryInfo GetDirectoryInfoByIndex(int index) {
var autoSavedInkPath = new DirectoryInfo(storageLocationItems[ComboBoxStoragePath.SelectedIndex].Path+"\\AutoSavedInk");
diff --git a/InkCanvasForClass/Popups/ScreenshotWindow.xaml b/InkCanvasForClass/Popups/ScreenshotWindow.xaml
index d89193d..4578541 100644
--- a/InkCanvasForClass/Popups/ScreenshotWindow.xaml
+++ b/InkCanvasForClass/Popups/ScreenshotWindow.xaml
@@ -5,114 +5,277 @@
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" AllowsTransparency="True" Background="Transparent"
- WindowStyle="None" ResizeMode="NoResize" ShowInTaskbar="False"
- Title="ScreenshotWindow" Height="220" Width="360" Topmost="True">
+ mc:Ignorable="d" AllowsTransparency="True" Background="Transparent"
+ WindowStyle="None" ResizeMode="NoResize" ShowInTaskbar="False" WindowState="Maximized"
+ KeyDown="ScreenshotWindow_OnKeyDown"
+ Title="ScreenshotWindow" Width="1920" Height="1080" Topmost="True">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 无法截取
+ ICC的权限不足
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/InkCanvasForClass/Popups/ScreenshotWindow.xaml.cs b/InkCanvasForClass/Popups/ScreenshotWindow.xaml.cs
index 31c39f9..2913021 100644
--- a/InkCanvasForClass/Popups/ScreenshotWindow.xaml.cs
+++ b/InkCanvasForClass/Popups/ScreenshotWindow.xaml.cs
@@ -1,10 +1,13 @@
-using System;
+using Ink_Canvas.Helpers;
+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.Security.Principal;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -16,11 +19,15 @@ using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Animation;
+using System.Windows.Media.Effects;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
+using System.Windows.Shell;
using System.Xml.Linq;
using Vanara.PInvoke;
using Color = System.Windows.Media.Color;
+using Shell32;
+using static Ink_Canvas.MainWindow;
namespace Ink_Canvas.Popups
{
@@ -30,45 +37,186 @@ namespace Ink_Canvas.Popups
public partial class ScreenshotWindow : Window {
private MainWindow mainWindow;
+ private Settings settings;
- public ScreenshotWindow(MainWindow mainWin) {
+ public ScreenshotWindow(MainWindow mainWin, Settings s) {
InitializeComponent();
mainWindow = mainWin;
+ settings = s;
iconList = new Border[] {
FullScreenIcon,
WindowIcon,
- SelectionIcon
- };
- iconGeometryList = new GeometryDrawing[] {
- FullScreenIconGeometry,
- WindowIconsGeometry,
- SelectionIconGeometry,
- };
- iconTextList = new TextBlock[] {
- FullScreenIconText,
- WindowIconText,
- SelectionIconText,
+ SelectionIcon,
+ DesktopIcon
};
foreach (var b in iconList) {
b.MouseLeave += IconMouseLeave;
b.MouseUp += IconMouseUp;
b.MouseDown += IconMouseDown;
+ b.Background = new SolidColorBrush(Colors.Transparent);
}
- CaptureButton.MouseUp += CaptureButton_MouseUp;
- CaptureButton.MouseDown += CaptureButton_MouseDown;
- CaptureButton.MouseLeave += CaptureButton_MouseLeave;
-
- UpdateModeIconSelection();
ReArrangeWindowPosition();
mainWin.Hide();
+
+ if (DwmCompositionHelper.DwmIsCompositionEnabled()) {
+ AllowsTransparency = false;
+ Background = new SolidColorBrush(Colors.Transparent);
+ WindowChrome.SetWindowChrome(this, new WindowChrome() {
+ GlassFrameThickness = new Thickness(-1),
+ CaptionHeight = 0,
+ CornerRadius = new CornerRadius(0),
+ ResizeBorderThickness = new Thickness(0),
+ });
+ } else {
+ AllowsTransparency = true;
+ Background = new SolidColorBrush(Color.FromArgb(1,0,0,0));
+ }
+
+ ToggleSwitchCopyToClipBoard.IsChecked = settings.Snapshot.CopyScreenshotToClipboard;
+ ToggleSwitchAttachInk.IsChecked = settings.Snapshot.AttachInkWhenScreenshot;
+ ToggleSwitchCopyToClipBoard.Checked += ToggleSwitchCopyToClipBoard_CheckChanged;
+ ToggleSwitchCopyToClipBoard.Unchecked += ToggleSwitchCopyToClipBoard_CheckChanged;
+ ToggleSwitchAttachInk.Checked += ToggleSwitchAttachInk_CheckChanged;
+ ToggleSwitchAttachInk.Unchecked += ToggleSwitchAttachInk_CheckChanged;
+
+ WindowsItemsControl.ItemsSource = _winInfos;
+ WindowScreenshotOverlay.Visibility = Visibility.Collapsed;
+ WindowsSnapshotLoadingOverlay.Visibility = Visibility.Collapsed;
+
+ EscBorder.MouseDown += EscBorder_MouseDown;
+ EscBorder.MouseUp += EscBorder_MouseUp;
+ EscBorder.MouseLeave += EscBorder_MouseLeave;
+
+ var identity = WindowsIdentity.GetCurrent();
+ var principal = new WindowsPrincipal(identity);
+ NeedAdminTextPanel.Visibility = principal.IsInRole(WindowsBuiltInRole.Administrator) ? Visibility.Collapsed : Visibility.Visible;
+ if (principal.IsInRole(WindowsBuiltInRole.Administrator)) {
+ WindowsItemsScrollViewer.Margin = new Thickness(36, 148, 36, 0);
+ } else {
+ WindowsItemsScrollViewer.Margin = new Thickness(36, 178, 36, 0);
+ }
+ }
+
+ private bool isEscBorderDown = false;
+
+ private void EscBorder_MouseLeave(object sender, MouseEventArgs e) {
+ if (!isEscBorderDown) return;
+ isEscBorderDown = false;
+ EscBorder.Background = new SolidColorBrush(Colors.Transparent);
+ }
+
+ private void EscBorder_MouseUp(object sender, MouseButtonEventArgs e) {
+ if (!isEscBorderDown) return;
+ if (isWindowsSnapshotLoaded == false) return;
+ EscBorder_MouseLeave(null, null);
+ ScreenshotPanel.Visibility = Visibility.Visible;
+ WindowScreenshotOverlay.Visibility = Visibility.Collapsed;
+ _winInfos.Clear();
+ isWindowsSnapshotLoaded = null;
+ }
+
+ private void EscBorder_MouseDown(object sender, MouseButtonEventArgs e) {
+ if (isEscBorderDown) return;
+ isEscBorderDown = true;
+ EscBorder.Background = new SolidColorBrush(Color.FromRgb(39, 39, 42));
+ }
+
+ private ObservableCollection _winInfos = new ObservableCollection();
+
+ private bool AllOneColor(Bitmap bmp)
+ {
+ // Lock the bitmap's bits.
+ System.Drawing.Rectangle rect = new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height);
+ BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, bmp.PixelFormat);
+
+ // Get the address of the first line.
+ IntPtr ptr = bmpData.Scan0;
+
+ // Declare an array to hold the bytes of the bitmap.
+ int bytes = bmpData.Stride * bmp.Height;
+ byte[] rgbValues = new byte[bytes];
+
+ // Copy the RGB values into the array.
+ System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
+
+ bool AllOneColor = true;
+ for (int index = 0; index < rgbValues.Length; index++) {
+ //compare the current A or R or G or B with the A or R or G or B at position 0,0.
+ if (rgbValues[index] != rgbValues[index % 4]) {
+ AllOneColor= false;
+ break;
+ }
+ }
+ // Unlock the bits.
+ bmp.UnlockBits(bmpData);
+ return AllOneColor;
+ }
+
+ private async Task AllOneColorAsync(Bitmap bmp) {
+ var result = await Task.Run(() => AllOneColor(bmp));
+ return result;
+ }
+
+ 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 WinInfo {
+ public string Title { get; set; }
+ public BitmapImage Snapshot { get; set; }
+ public ImageSource Icon { get; set; }
+ public HWND Handle { get; set; }
+ public Bitmap OriginBitmap { get; set; }
+ public double Width { get; set; }
+ public double TextBlockWidth { get; set; }
+ public bool IsAllOneColor { get; set; }
+ public bool IsDisplayFailedBorder { get; set; }
+ public Visibility ShouldDisplayFailedBorder {
+ get => IsDisplayFailedBorder ? Visibility.Visible : Visibility.Collapsed;
+ }
+ public bool IsHidden { get; set; }
+ public Visibility Visibility {
+ get => IsHidden ? Visibility.Collapsed : Visibility.Visible;
+ }
}
private Border lastDownIcon;
- private int selectedMode = 0;
+
+ private void ToggleSwitchCopyToClipBoard_CheckChanged(object sender, RoutedEventArgs e) {
+ if (!mainWindow.isLoaded) return;
+ mainWindow.ToggleSwitchCopyScreenshotToClipboard.IsOn = ToggleSwitchCopyToClipBoard.IsChecked ?? true;
+ }
+
+ private void ToggleSwitchAttachInk_CheckChanged(object sender, RoutedEventArgs e) {
+ if (!mainWindow.isLoaded) return;
+ mainWindow.ToggleSwitchAttachInkWhenScreenshot.IsOn = ToggleSwitchAttachInk.IsChecked ?? true;
+ }
private void ReArrangeWindowPosition() {
var workAreaWidth = SystemParameters.WorkArea.Width;
@@ -79,57 +227,15 @@ namespace Ink_Canvas.Popups
Top = workAreaHeight - Height - toolbarHeight - 64;
}
- private void UpdateModeIconSelection() {
- foreach (var b in iconList) b.Background = new SolidColorBrush(Colors.Transparent);
- foreach (var g in iconGeometryList) g.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27));
- foreach (var t in iconTextList) t.Foreground = new SolidColorBrush(Color.FromRgb(24, 24, 27));
- iconList[selectedMode].Background = new SolidColorBrush(Color.FromRgb(37, 99, 235));
- iconGeometryList[selectedMode].Brush = new SolidColorBrush(Colors.White);
- iconTextList[selectedMode].Foreground = new SolidColorBrush(Colors.White);
- }
-
private bool isCaptureButtonDown = false;
- private void CaptureButton_MouseDown(object sender, MouseButtonEventArgs e) {
- if (isCaptureButtonDown) return;
-
- isCaptureButtonDown = true;
- var sb = new Storyboard();
- var animation = new DoubleAnimation {
- From = 1,
- To = 0.9,
- Duration = TimeSpan.FromMilliseconds(200)
- };
- var animation2 = new DoubleAnimation {
- From = 1,
- To = 0.9,
- Duration = TimeSpan.FromMilliseconds(200)
- };
- var animation3 = new ThicknessAnimation() {
- From = new Thickness(5),
- To = new Thickness(7),
- Duration = TimeSpan.FromMilliseconds(200)
- };
- Storyboard.SetTargetProperty(animation, new PropertyPath("(UIElement.RenderTransform).(ScaleTransform.ScaleX)"));
- Storyboard.SetTargetProperty(animation2, new PropertyPath("(UIElement.RenderTransform).(ScaleTransform.ScaleY)"));
- Storyboard.SetTargetProperty(animation3, new PropertyPath(Border.BorderThicknessProperty));
- animation.EasingFunction = new CubicEase();
- animation2.EasingFunction = new CubicEase();
- animation3.EasingFunction = new CubicEase();
- sb.Children.Add(animation);
- sb.Children.Add(animation2);
- sb.Children.Add(animation3);
- sb.Begin(CaptureButton);
- }
-
- private void CaptureButton_MouseUp(object sender, MouseButtonEventArgs e) {
- if (isCaptureButtonDown != true) return;
- CaptureButton_MouseLeave(sender, null);
-
- if (selectedMode == 0) CaptureFullScreen();
- }
-
private async void CaptureFullScreen() {
+ LoadingOverlay.Visibility = Visibility.Visible;
+ MainFuncPanel.Effect = new BlurEffect() {
+ KernelType = KernelType.Gaussian,
+ Radius = 24,
+ RenderingBias = RenderingBias.Performance,
+ };
try {
var bm = await mainWindow.FullscreenSnapshot(new MainWindow.SnapshotConfig() {
BitmapSavePath =
@@ -137,81 +243,49 @@ namespace Ink_Canvas.Popups
ExcludedHwnds = new HWND[] {
new HWND(new WindowInteropHelper(this).Handle)
},
- IsCopyToClipboard = true,
+ IsCopyToClipboard = settings.Snapshot.CopyScreenshotToClipboard,
IsSaveToLocal = true,
OutputMIMEType = MainWindow.OutputImageMIMEFormat.Png,
});
bm.Dispose();
+ LoadingOverlay.Visibility = Visibility.Collapsed;
+ MainFuncPanel.Effect = null;
mainWindow.ShowNewToast("已保存截图到桌面!", MW_Toast.ToastType.Success, 3000);
await Task.Delay(1);
Close();
}
catch (Exception e) {
+ LoadingOverlay.Visibility = Visibility.Collapsed;
+ MainFuncPanel.Effect = null;
mainWindow.ShowNewToast($"截图失败!{e.Message}", MW_Toast.ToastType.Error, 3000);
await Task.Delay(1);
Close();
}
}
- private void CaptureButton_MouseLeave(object sender, MouseEventArgs e) {
- if (isCaptureButtonDown != true) return;
-
- var sb = new Storyboard();
- var animation = new DoubleAnimation {
- From = 0.9,
- To = 1,
- Duration = TimeSpan.FromMilliseconds(200)
- };
- var animation2 = new DoubleAnimation {
- From = 0.9,
- To = 1,
- Duration = TimeSpan.FromMilliseconds(200)
- };
- var animation3 = new ThicknessAnimation() {
- From = new Thickness(7),
- To = new Thickness(5),
- Duration = TimeSpan.FromMilliseconds(200)
- };
- Storyboard.SetTargetProperty(animation, new PropertyPath("(UIElement.RenderTransform).(ScaleTransform.ScaleX)"));
- Storyboard.SetTargetProperty(animation2, new PropertyPath("(UIElement.RenderTransform).(ScaleTransform.ScaleY)"));
- Storyboard.SetTargetProperty(animation3, new PropertyPath(Border.BorderThicknessProperty));
- animation.EasingFunction = new CubicEase();
- animation2.EasingFunction = new CubicEase();
- animation3.EasingFunction = new CubicEase();
- sb.Children.Add(animation);
- sb.Children.Add(animation2);
- sb.Children.Add(animation3);
- sb.Begin(CaptureButton);
-
- isCaptureButtonDown = false;
- }
-
private void IconMouseLeave(object sender, MouseEventArgs e) {
if (lastDownIcon == null) return;
lastDownIcon = null;
var b = (Border)sender;
- if (Array.IndexOf(iconList,b)!=selectedMode)
- b.Background = new SolidColorBrush(Colors.Transparent);
+ b.Background = new SolidColorBrush(Colors.Transparent);
}
private void IconMouseDown(object sender, MouseButtonEventArgs e) {
if (lastDownIcon != null) return;
lastDownIcon = (Border)sender;
var b = (Border)sender;
- if (Array.IndexOf(iconList,b)!=selectedMode)
- b.Background = new SolidColorBrush(Color.FromArgb(22, 24, 24, 27));
+ b.Background = new SolidColorBrush(Color.FromArgb(22, 24, 24, 27));
}
- private WindowScreenshotGridWindow _screenshotGridWindow = null;
+ private bool? isWindowsSnapshotLoaded = false;
+
private async void IconMouseUp(object sender, MouseButtonEventArgs e) {
if (lastDownIcon == null) return;
IconMouseLeave(sender, null);
- var index = Array.IndexOf(iconList, (Border)sender);
- selectedMode = index;
- UpdateModeIconSelection();
- if (selectedMode == 1) {
+
+ /*if (selectedMode == 1) {
try {
MainWindow.WindowInformation[] windows = await mainWindow.GetAllWindowsAsync(new HWND[] {
new HWND(new WindowInteropHelper(this).Handle), new HWND(new WindowInteropHelper(mainWindow).Handle)
@@ -226,12 +300,57 @@ namespace Ink_Canvas.Popups
_screenshotGridWindow.Close();
} catch (Exception ex) { }
+ }*/
+
+ if (Array.IndexOf(iconList, (Border)sender) == 0) {
+ CaptureFullScreen();
+ } else if (Array.IndexOf(iconList, (Border)sender) == 3) {
+ Shell shellObject = new Shell();
+ shellObject.ToggleDesktop();
+ } else if (Array.IndexOf(iconList, ((Border)sender)) == 1) {
+ isWindowsSnapshotLoaded = false;
+ await Dispatcher.InvokeAsync(() => {
+ _winInfos.Clear();
+ ScreenshotPanel.Visibility = Visibility.Collapsed;
+ WindowScreenshotOverlay.Visibility = Visibility.Visible;
+ WindowsSnapshotLoadingOverlay.Visibility = Visibility.Visible;
+ WindowScreenshotWindowsGrid.Effect = new BlurEffect() {
+ KernelType = KernelType.Gaussian,
+ RenderingBias = RenderingBias.Performance,
+ Radius = 32,
+ };
+ });
+ var wins = await mainWindow.GetAllWindowsAsync(new HWND[] {
+ new HWND(new WindowInteropHelper(this).Handle)
+ });
+ foreach (var windowInformation in wins) {
+ var bitmapHeight = windowInformation.WindowBitmap.Height;
+ var w = windowInformation.WindowBitmap.Width * (226D / bitmapHeight);
+ var allonecolor = await AllOneColorAsync(windowInformation.WindowBitmap);
+ _winInfos.Add(new WinInfo() {
+ Title = windowInformation.Title,
+ Snapshot = BitmapToImageSource(windowInformation.WindowBitmap.Clone(windowInformation.ContentRect,windowInformation.WindowBitmap.PixelFormat)),
+ Handle = windowInformation.hwnd,
+ OriginBitmap = windowInformation.WindowBitmap,
+ Icon = windowInformation.AppIcon == null ? new BitmapImage(new Uri("pack://application:,,,/Resources/Icons-png/classic-icons/program-icon.png")) : IconToImageSource(windowInformation.AppIcon),
+ Width = w,
+ TextBlockWidth = w - 48 - 8,
+ IsAllOneColor = allonecolor,
+ IsDisplayFailedBorder = allonecolor,
+ IsHidden = settings.Snapshot.OnlySnapshotMaximizeWindow,
+ });
+ if (Array.IndexOf(wins, windowInformation)>= wins.Length - 1) Dispatcher.InvokeAsync(() => {
+ WindowScreenshotWindowsGrid.Effect = null;
+ WindowsSnapshotLoadingOverlay.Visibility = Visibility.Collapsed;});
+ }
+ Dispatcher.InvokeAsync(() => {
+ WindowScreenshotWindowsGrid.Effect = null;
+ WindowsSnapshotLoadingOverlay.Visibility = Visibility.Collapsed;});
+ isWindowsSnapshotLoaded = true;
}
}
private Border[] iconList = new Border[] { };
- private GeometryDrawing[] iconGeometryList = new GeometryDrawing[] { };
- private TextBlock[] iconTextList = new TextBlock[] { };
private void CloseButton_CloseWindow(object sender, MouseButtonEventArgs e) {
Close();
@@ -241,5 +360,35 @@ namespace Ink_Canvas.Popups
mainWindow.Show();
base.OnClosed(e);
}
+
+ private void ScreenshotWindow_OnKeyDown(object sender, KeyEventArgs e) {
+ if (e.Key == Key.Escape) {
+ if (isWindowsSnapshotLoaded==false) return;
+ ScreenshotPanel.Visibility = Visibility.Visible;
+ WindowScreenshotOverlay.Visibility = Visibility.Collapsed;
+ _winInfos.Clear();
+ isWindowsSnapshotLoaded = null;
+ }
+ }
+
+ public void WindowsItemsScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e) {
+ var scrollViewer = (ScrollViewer)sender;
+ var sb = new Storyboard();
+ var ofs = scrollViewer.VerticalOffset;
+ var animation = new DoubleAnimation
+ {
+ From = ofs,
+ To = ofs - e.Delta * 2.5,
+ Duration = TimeSpan.FromMilliseconds(155)
+ };
+ animation.EasingFunction = new CubicEase() {
+ EasingMode = EasingMode.EaseOut,
+ };
+ Storyboard.SetTargetProperty(animation, new PropertyPath(ColorPalette.ScrollViewerBehavior.VerticalOffsetProperty));
+ Storyboard.SetTargetName(animation,"WindowsItemsScrollViewer");
+ sb.Children.Add(animation);
+ scrollViewer.ScrollToVerticalOffset(ofs);
+ sb.Begin(scrollViewer);
+ }
}
}
diff --git a/InkCanvasForClass/Resources/Icons-png/classic-icons/desktop-small-icon.png b/InkCanvasForClass/Resources/Icons-png/classic-icons/desktop-small-icon.png
new file mode 100644
index 0000000..4f6235e
Binary files /dev/null and b/InkCanvasForClass/Resources/Icons-png/classic-icons/desktop-small-icon.png differ
diff --git a/InkCanvasForClass/Resources/Icons-png/classic-icons/photo-small-icon.png b/InkCanvasForClass/Resources/Icons-png/classic-icons/photo-small-icon.png
new file mode 100644
index 0000000..eb1b6ce
Binary files /dev/null and b/InkCanvasForClass/Resources/Icons-png/classic-icons/photo-small-icon.png differ
diff --git a/InkCanvasForClass/Resources/Icons-png/classic-icons/program-icon.png b/InkCanvasForClass/Resources/Icons-png/classic-icons/program-icon.png
new file mode 100644
index 0000000..1c61bf4
Binary files /dev/null and b/InkCanvasForClass/Resources/Icons-png/classic-icons/program-icon.png differ