diff --git a/InkCanvasForClass/InkCanvasForClass.csproj b/InkCanvasForClass/InkCanvasForClass.csproj index 9167ad8..b46a5c3 100644 --- a/InkCanvasForClass/InkCanvasForClass.csproj +++ b/InkCanvasForClass/InkCanvasForClass.csproj @@ -150,7 +150,6 @@ - @@ -161,9 +160,7 @@ - - diff --git a/InkCanvasForClass/MainWindow.xaml.cs b/InkCanvasForClass/MainWindow.xaml.cs index c4fc193..de8404f 100644 --- a/InkCanvasForClass/MainWindow.xaml.cs +++ b/InkCanvasForClass/MainWindow.xaml.cs @@ -22,7 +22,6 @@ using System.Windows.Documents; using Ink_Canvas.Popups; using iNKORE.UI.WPF.Modern.Controls; using System.Windows.Forms; -using Jint.Runtime; using Application = System.Windows.Application; using Button = System.Windows.Controls.Button; using TextBox = System.Windows.Controls.TextBox; diff --git a/InkCanvasForClass/MainWindow_cs/MW_Screenshot.cs b/InkCanvasForClass/MainWindow_cs/MW_Screenshot.cs index 04604e7..a4c01c1 100644 --- a/InkCanvasForClass/MainWindow_cs/MW_Screenshot.cs +++ b/InkCanvasForClass/MainWindow_cs/MW_Screenshot.cs @@ -5,56 +5,25 @@ using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Linq; -using System.Reflection; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using System.Windows; -using System.Windows.Forms; +using System.Windows.Documents; using System.Windows.Interop; -using System.Windows.Media; -using System.Windows.Shell; -using Acornima.Ast; +using System.Windows.Media.Imaging; using OSVersionExtension; using Vanara.PInvoke; -using static Vanara.PInvoke.Gdi32; -using Color = System.Drawing.Color; +using Encoder = System.Drawing.Imaging.Encoder; using OperatingSystem = OSVersionExtension.OperatingSystem; using PixelFormat = System.Drawing.Imaging.PixelFormat; namespace Ink_Canvas { public partial class MainWindow : Window { - private void SaveScreenshot(bool isHideNotification, string fileName = null) { - var bitmap = GetScreenshotBitmap(); - string savePath = Settings.Automation.AutoSavedStrokesLocation + @"\Auto Saved - Screenshots"; - if (fileName == null) fileName = DateTime.Now.ToString("u").Replace(":", "-"); - if (Settings.Automation.IsSaveScreenshotsInDateFolders) { - savePath += @"\" + DateTime.Now.ToString("yyyy-MM-dd"); - } - savePath += @"\" + fileName + ".png"; - if (!Directory.Exists(Path.GetDirectoryName(savePath))) { - Directory.CreateDirectory(Path.GetDirectoryName(savePath)); - } + #region MagnificationAPI 获取屏幕截图并过滤ICC窗口 - bitmap.Save(savePath, ImageFormat.Png); - if (Settings.Automation.IsAutoSaveStrokesAtScreenshot) { - SaveInkCanvasStrokes(false, false); - } - - if (!isHideNotification) { - ShowNewToast("截图成功保存至 " + savePath, MW_Toast.ToastType.Success, 3000); - } - } - - #region MagnificationAPI 獲取屏幕截圖並過濾ICC窗口 - - public static IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong) { - if (IntPtr.Size == 8) - return SetWindowLongPtr64(hWnd, nIndex, dwNewLong); - else - return new IntPtr(SetWindowLong32(hWnd, nIndex, dwNewLong.ToInt32())); - } + #region Dubi906w 的轮子 [DllImport("user32.dll", EntryPoint = "SetWindowLong")] private static extern int SetWindowLong32(IntPtr hWnd, int nIndex, int dwNewLong); @@ -63,133 +32,196 @@ namespace Ink_Canvas { private static extern IntPtr SetWindowLongPtr64(IntPtr hWnd, int nIndex, IntPtr dwNewLong); [DllImport("user32.dll", EntryPoint = "GetWindowLong")] - static extern IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex); + private static extern IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex); - public unsafe void SaveScreenshotToDesktopByMagnificationAPIEx(bool isExcludeMode, HWND[] hwndsList, - Action callbackAction) { - if (OSVersion.GetOperatingSystem() < OperatingSystem.Windows8 && - OSVersion.GetOperatingSystem() > OperatingSystem.Windows10) return; - if (!Magnification.MagInitialize()) return; + [DllImport("user32.dll")] + static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); - // 創建宿主窗體 - var mainWinMag = new Form(); - mainWinMag.Show(); - var handle = new HWND(mainWinMag.Handle); - User32.SetWindowPos(handle, HWND.HWND_NOTOPMOST, 0, 0, System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width, - System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height, User32.SetWindowPosFlags.SWP_HIDEWINDOW); // SWP_HIDEWINDOW - Trace.WriteLine(handle); - User32.SetWindowLong(handle, User32.WindowLongFlags.GWL_STYLE, - new IntPtr((int)User32.WindowStyles.WS_SIZEBOX | (int)User32.WindowStyles.WS_SYSMENU | (int)User32.WindowStyles.WS_CLIPCHILDREN | (int)User32.WindowStyles.WS_CAPTION | (int)User32.WindowStyles.WS_MAXIMIZEBOX)); - Trace.WriteLine(handle); - var exptr = User32.GetWindowLong(handle, User32.WindowLongFlags.GWL_EXSTYLE); - Trace.WriteLine(exptr); - User32.SetWindowLong(handle, User32.WindowLongFlags.GWL_EXSTYLE, - new IntPtr(exptr | - (int)User32.WindowStylesEx.WS_EX_LAYERED | (int)User32.WindowStylesEx.WS_EX_TOPMOST)); - Trace.WriteLine(handle); - User32.SetLayeredWindowAttributes(handle,0, 0, User32.LayeredWindowAttributes.LWA_ALPHA); + #endregion Dubi906w 的轮子 - Trace.WriteLine(handle); + #region Win32 窗口环境(由 AlanCRL 测试) - // 創建放大鏡窗體(使用Win32方法) - var hwndMag = User32.CreateWindow(Magnification.WC_MAGNIFIER, "ICCMagnifierWindow", - User32.WindowStyles.WS_CHILD | User32.WindowStyles.WS_VISIBLE, 0, 0, - System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width, - System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height, handle, HMENU.NULL, HINSTANCE.NULL, - IntPtr.Zero); + // 感謝 Alan-CRL 造的輪子 + private const int WS_EX_TOPMOST = 0x00000008; + private const int WS_EX_LAYERED = 0x00080000; + private const int WS_SIZEBOX = 0x00040000; + private const int WS_SYSMENU = 0x00080000; + private const int WS_CLIPCHILDREN = 0x02000000; + private const int WS_CAPTION = 0x00C00000; + private const int WS_MAXIMIZEBOX = 0x00010000; + private const int GWL_STYLE = -16; + private const int GWL_EXSTYLE = -20; + private const int WS_THICKFRAME = 0x00040000; + private const int SWP_NOSIZE = 0x0001; + private const int SWP_FRAMECHANGED = 0x0020; + private const int WS_EX_TOOLWINDOW = 0x00000080; + private const int WS_EX_APPWINDOW = 0x00040000; + private const int SW_SHOW = 5; + private const int LWA_ALPHA = 0x00000002; + private const int PW_RENDERFULLCONTENT = 2; + private static IntPtr windowHostHandle; - Trace.WriteLine(hwndMag); + // PInvoke 輪子 + [DllImport("user32.dll", SetLastError = true)] + private static extern IntPtr CreateWindowEx(int dwExStyle, string lpClassName, string lpWindowName, int dwStyle, + int x, int y, int nWidth, int nHeight, IntPtr hWndParent, IntPtr hMenu, IntPtr hInstance, IntPtr lpParam); - // 過濾窗口 - var hwnds = new List { hwndMag }; - hwnds.AddRange(hwndsList); - if (!Magnification.MagSetWindowFilterList(hwndMag, - isExcludeMode - ? Magnification.MW_FILTERMODE.MW_FILTERMODE_EXCLUDE - : Magnification.MW_FILTERMODE.MW_FILTERMODE_INCLUDE, - isExcludeMode ? hwnds.Count : hwndsList.Length, hwnds.ToArray())) return; + [DllImport("user32.dll")] + private static extern bool DestroyWindow(IntPtr hWnd); - // 設置窗口Source - if (!Magnification.MagSetWindowSource(hwndMag, - new RECT(0, 0, System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width, - System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height))) return; + [DllImport("user32.dll", SetLastError = true)] + private static extern ushort RegisterClassEx(ref WNDCLASSEX lpwcx); - RECT rect; - User32.GetWindowRect(hwndMag, out rect); - Bitmap bmp = new Bitmap(rect.Width, rect.Height); - Graphics memoryGraphics = Graphics.FromImage(bmp); - IntPtr hdc = memoryGraphics.GetHdc(); - Trace.WriteLine(User32.PrintWindow(hwndMag, hdc, User32.PW.PW_RENDERFULLCONTENT)); + [DllImport("user32.dll", SetLastError = true)] + private static extern IntPtr DefWindowProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam); - string savePath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory); - bmp.Save(savePath + @"\" + DateTime.Now.ToString("u").Replace(':', '-') + ".png", ImageFormat.Png); + [DllImport("user32.dll", SetLastError = true)] + private static extern IntPtr LoadCursor(IntPtr hInstance, int lpCursorName); - Trace.WriteLine(bmp.GetPixel(123,123)); - Trace.WriteLine(bmp.GetPixel(163,174)); + [DllImport("user32.dll", SetLastError = true)] + private static extern short UnregisterClass(string lpClassName, IntPtr hInstance); - // 關閉宿主窗體 - //Magnification.MagUninitialize(); - //mainWinMag.Close(); + [DllImport("user32.dll", SetLastError = true)] + private static extern bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey, byte bAlpha, uint dwFlags); + + [DllImport("user32.dll", SetLastError = true)] + private static extern int GetWindowLong(IntPtr hWnd, int nIndex); + + [DllImport("user32.dll", SetLastError = true)] + private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); + + [DllImport("user32.dll", SetLastError = true)] + private static extern bool InvalidateRect(IntPtr hWnd, IntPtr lpRect, bool bErase); + + [StructLayout(LayoutKind.Sequential)] + private struct WNDCLASSEX { + public uint cbSize; + public uint style; + [MarshalAs(UnmanagedType.FunctionPtr)] public WndProc lpfnWndProc; + public int cbClsExtra; + public int cbWndExtra; + public IntPtr hInstance; + public IntPtr hIcon; + public IntPtr hCursor; + public IntPtr hbrBackground; + public string lpszMenuName; + public string lpszClassName; + public IntPtr hIconSm; } - public unsafe void SaveScreenshotToDesktopByMagnificationAPI(bool isExcludeMode, HWND[] hwndsList, - Action callbackAction) { - if (OSVersion.GetOperatingSystem() < OperatingSystem.Windows8 && - OSVersion.GetOperatingSystem() > OperatingSystem.Windows10) return; + private delegate IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam); + + private static readonly WndProc StaticWndProcDelegate = WndHostProc; + + private const uint WM_DESTROY = 0x0002; + private const uint WM_CLOSE = 0x0010; + private const int CS_HREDRAW = 0x0002; + private const int CS_VREDRAW = 0x0001; + private const int IDC_ARROW = 32512; + private static int COLOR_BTNFACE = 15; + private const int WS_CHILD = 0x40000000; + private const int WS_VISIBLE = 0x10000000; + private const int MS_CLIPAROUNDCURSOR = 0x0002; + + #endregion Win32 窗口环境(由 AlanCRL 测试) + + public void SaveScreenshotToDesktopByMagnificationAPI(HWND[] hwndsList, + Action callbackAction, bool isUsingCallback = false) { + if (OSVersion.GetOperatingSystem() < OperatingSystem.Windows81) return; if (!Magnification.MagInitialize()) return; - + // 註冊宿主窗體類名 + var wndClassEx = new WNDCLASSEX { + cbSize = (uint)Marshal.SizeOf(), style = CS_HREDRAW | CS_VREDRAW, + lpfnWndProc = StaticWndProcDelegate, hInstance = IntPtr.Zero, + hCursor = LoadCursor(IntPtr.Zero, IDC_ARROW), hbrBackground = (IntPtr)(1 + COLOR_BTNFACE), + lpszClassName = "ICCMagnifierWindowHost", + hIcon = IntPtr.Zero, hIconSm = IntPtr.Zero + }; + RegisterClassEx(ref wndClassEx); // 創建宿主窗體 - var mainWinMag = new Window(); - mainWinMag.WindowState = WindowState.Maximized; - mainWinMag.WindowStyle = WindowStyle.None; - mainWinMag.ResizeMode = ResizeMode.NoResize; - mainWinMag.Background = new SolidColorBrush(Colors.Transparent); - mainWinMag.AllowsTransparency = true; - mainWinMag.Show(); - var handle = new HWND(new WindowInteropHelper(mainWinMag).Handle); - User32.SetWindowPos(handle, HWND.HWND_NOTOPMOST, 0, 0, System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width, - System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height, User32.SetWindowPosFlags.SWP_HIDEWINDOW); // SWP_HIDEWINDOW - SetWindowLongPtr(handle.DangerousGetHandle(), -20, new IntPtr((int)GetWindowLongPtr(handle.DangerousGetHandle(), -20) | 0x00080000)); - User32.SetLayeredWindowAttributes(handle,0, 255, User32.LayeredWindowAttributes.LWA_ALPHA); - - // 創建放大鏡窗體(使用Win32方法) - var hwndMag = User32.CreateWindow(Magnification.WC_MAGNIFIER, "ICCMagnifierWindow", - User32.WindowStyles.WS_CHILD | User32.WindowStyles.WS_VISIBLE, 0, 0, + windowHostHandle = CreateWindowEx( + WS_EX_TOPMOST | WS_EX_LAYERED, "ICCMagnifierWindowHost", "ICCMagnifierWindowHostWindow", + WS_SIZEBOX | WS_SYSMENU | WS_CLIPCHILDREN | WS_CAPTION | WS_MAXIMIZEBOX, 0, 0, System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width, - System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height, handle, HMENU.NULL, HINSTANCE.NULL, + System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); - - Trace.WriteLine(hwndMag); - - // 過濾窗口 + // 設定分層窗體 + SetLayeredWindowAttributes(windowHostHandle, 0, 0, LWA_ALPHA); + // 創建放大鏡窗體 + var hwndMag = CreateWindowEx( + 0, Magnification.WC_MAGNIFIER, "ICCMagnifierWindow", WS_CHILD | WS_VISIBLE | MS_CLIPAROUNDCURSOR, 0, 0, + System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width, + System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height, windowHostHandle, + IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); + // 設定窗體樣式和排布 + int style = GetWindowLong(windowHostHandle, GWL_STYLE); + style &= ~WS_CAPTION; // 隐藏标题栏style &= ~WS_THICKFRAME; // 禁止窗口拉伸 + SetWindowLong(windowHostHandle, GWL_STYLE, style); + SetWindowPos(windowHostHandle, IntPtr.Zero, 0, 0, 0, 0, SWP_NOSIZE | SWP_FRAMECHANGED); + // 設定額外樣式 + int exStyle = GetWindowLong(windowHostHandle, GWL_EXSTYLE); + exStyle |= WS_EX_TOOLWINDOW; /* <- 隐藏任务栏图标 */ + exStyle &= ~WS_EX_APPWINDOW; + SetWindowLong(windowHostHandle, GWL_EXSTYLE, exStyle); + // 設定放大鏡工廠 + Magnification.MAGTRANSFORM matrix = new Magnification.MAGTRANSFORM(); + matrix[0, 0] = 1.0f; + matrix[1, 1] = 1.0f; + matrix[2, 2] = 1.0f; + if (!Magnification.MagSetWindowTransform(hwndMag, matrix)) return; + // 設定放大鏡轉化矩乘陣列 + Magnification.MAGCOLOREFFECT magEffect = new Magnification.MAGCOLOREFFECT(); + if (!Magnification.MagSetColorEffect(hwndMag, magEffect)) return; + // 顯示窗體 + ShowWindow(windowHostHandle, SW_SHOW); + // 过滤窗口 var hwnds = new List { hwndMag }; hwnds.AddRange(hwndsList); - if (!Magnification.MagSetWindowFilterList(hwndMag, - isExcludeMode - ? Magnification.MW_FILTERMODE.MW_FILTERMODE_EXCLUDE - : Magnification.MW_FILTERMODE.MW_FILTERMODE_INCLUDE, - isExcludeMode ? hwnds.Count : hwndsList.Length, hwnds.ToArray())) return; - - // 保存數據 - if (!Magnification.MagSetImageScalingCallback(hwndMag, - (hwnd, srcdata, srcheader, destdata, destheader, unclipped, clipped, dirty) => { - Bitmap bm = new Bitmap((int)srcheader.width, (int)srcheader.height, (int)srcheader.width * 4, - PixelFormat.Format32bppRgb, srcdata); - callbackAction(bm); - return true; - })) return; - - // 設置窗口Source - if (!Magnification.MagSetWindowSource(hwndMag, - new RECT(0, 0, System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width, - System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height))) return; - - // 關閉宿主窗體 + if (!Magnification.MagSetWindowFilterList(hwndMag, Magnification.MW_FILTERMODE.MW_FILTERMODE_EXCLUDE, + hwnds.Count, hwnds.ToArray())) return; + // 设置窗口 Source + if (!Magnification.MagSetWindowSource(hwndMag, new RECT(0, 0, + System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width, + System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height))) return; + InvalidateRect(hwndMag, IntPtr.Zero, true); + // 抓取屏幕圖像 + if (isUsingCallback) { + if (!Magnification.MagSetImageScalingCallback(hwndMag, + (hwnd, srcdata, srcheader, destdata, destheader, unclipped, clipped, dirty) => { + Bitmap bm = new Bitmap((int)srcheader.width, (int)srcheader.height, + (int)srcheader.width * 4, PixelFormat.Format32bppRgb, srcdata); + callbackAction(bm); + return true; + })) return; + } else { + RECT rect; + GetWindowRect(hwndMag, out rect); + Bitmap bmp = new Bitmap(rect.Width, rect.Height); + Graphics memoryGraphics = Graphics.FromImage(bmp); + PrintWindow(hwndMag, memoryGraphics.GetHdc(), PW_RENDERFULLCONTENT); + memoryGraphics.ReleaseHdc(); + callbackAction(bmp); + } + // 反注册宿主窗口 + UnregisterClass("ICCMagnifierWindowHost", IntPtr.Zero); + // 销毁宿主窗口 Magnification.MagUninitialize(); - mainWinMag.Close(); + DestroyWindow(windowHostHandle); } - #endregion + public Task SaveScreenshotToDesktopByMagnificationAPIAsync(HWND[] hwndsList, bool isUsingCallback = false) { + return Task.Run(() => { + var t = new TaskCompletionSource(); + SaveScreenshotToDesktopByMagnificationAPI(hwndsList, bitmap => t.TrySetResult(bitmap),isUsingCallback); + return t.Task; + }); + } + + private static IntPtr WndHostProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) { + return DefWindowProc(hWnd, msg, wParam, lParam); + } + + #endregion MagnificationAPI 获取屏幕截图并过滤ICC窗口 #region 窗口截图(復刻Powerpoint) @@ -197,9 +229,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)); } @@ -351,14 +383,141 @@ namespace Ink_Canvas { return windows.ToArray(); } - public async Task GetAllWindowsAsync(HWND[] excludedHwnds) - { + public async Task GetAllWindowsAsync(HWND[] excludedHwnds) { var windows = await Task.Run(() => GetAllWindows(excludedHwnds)); return windows; } #endregion + #region 舊版全屏截圖 + + private Bitmap GetScreenshotBitmap() { + Rectangle rc = System.Windows.Forms.SystemInformation.VirtualScreen; + var bitmap = new Bitmap(rc.Width, rc.Height, PixelFormat.Format32bppArgb); + using (Graphics memoryGrahics = Graphics.FromImage(bitmap)) { + memoryGrahics.CopyFromScreen(rc.X, rc.Y, 0, 0, rc.Size, CopyPixelOperation.SourceCopy); + } + return bitmap; + } + + #endregion + + #region 通用截圖API + + 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; + } + } + + public enum SnapshotMethod { + Auto, + GraphicsAPICopyFromScreen, + MagnificationAPIWithPrintWindow, + MagnificationAPIWithCallback + } + + public enum OutputImageMIMEFormat { + Png, + Bmp, + Jpeg, + } + + public class SnapshotConfig { + public SnapshotMethod SnapshotMethod { get; set; } = SnapshotMethod.Auto; + public bool IsCopyToClipboard { get; set; } = false; + public bool IsSaveToLocal { get; set; } = true; + public DirectoryInfo BitmapSavePath { get; set; } = null; + public string SaveBitmapFileName { get; set; } = "Screenshot-[YYYY]-[MM]-[DD]-[HH]-[mm]-[ss].png"; + public OutputImageMIMEFormat OutputMIMEType { get; set; } = OutputImageMIMEFormat.Png; + public HWND[] ExcludedHwnds { get; set; } = new HWND[] { }; + } + + 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); + 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); + } else { + 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) { + if (!(OSVersion.GetOperatingSystem() >= OperatingSystem.Windows81)) + throw new Exception("您的系統版本不支持 MagnificationAPI 截圖!"); + 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); + 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) {} + if (config.IsSaveToLocal) { + var fullPath = config.BitmapSavePath.FullName; + if (!config.BitmapSavePath.Exists) config.BitmapSavePath.Create(); + var fileName = config.SaveBitmapFileName.Replace("[YYYY]", DateTime.Now.Year.ToString()) + .Replace("[MM]", DateTime.Now.Month.ToString()).Replace("[DD]", DateTime.Now.Day.ToString()) + .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 : + config.OutputMIMEType == OutputImageMIMEFormat.Bmp ? ImageFormat.Bmp : ImageFormat.Jpeg); + } + return bitmap; + } + + #endregion + + private void SaveScreenshot(bool isHideNotification, string fileName = null) { + var bitmap = GetScreenshotBitmap(); + string savePath = Settings.Automation.AutoSavedStrokesLocation + @"\Auto Saved - Screenshots"; + if (fileName == null) fileName = DateTime.Now.ToString("u").Replace(":", "-"); + if (Settings.Automation.IsSaveScreenshotsInDateFolders) { + savePath += @"\" + DateTime.Now.ToString("yyyy-MM-dd"); + } + + savePath += @"\" + fileName + ".png"; + if (!Directory.Exists(Path.GetDirectoryName(savePath))) { + Directory.CreateDirectory(Path.GetDirectoryName(savePath)); + } + + bitmap.Save(savePath, ImageFormat.Png); + if (Settings.Automation.IsAutoSaveStrokesAtScreenshot) { + SaveInkCanvasStrokes(false, false); + } + + if (!isHideNotification) { + ShowNewToast("截图成功保存至 " + savePath, MW_Toast.ToastType.Success, 3000); + } + } + private void SaveScreenShotToDesktop() { var bitmap = GetScreenshotBitmap(); string savePath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory); @@ -368,21 +527,6 @@ namespace Ink_Canvas { if (Settings.Automation.IsAutoSaveStrokesAtScreenshot) SaveInkCanvasStrokes(false, false); } - [DllImport("user32.dll")] - static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); - - private void SaveFullScreenScreenshotToDesktopAutoWays(HWND[] excludedHwnds) { - if (OSVersion.GetOperatingSystem() < OperatingSystem.Windows8 && - OSVersion.GetOperatingSystem() > OperatingSystem.Windows10) { - foreach (var excludedHwnd in excludedHwnds) ShowWindow(excludedHwnd.DangerousGetHandle(),0); - SaveScreenShotToDesktop(); - foreach (var excludedHwnd in excludedHwnds) ShowWindow(excludedHwnd.DangerousGetHandle(),5); - } else SaveScreenshotToDesktopByMagnificationAPI(true,excludedHwnds, bitmap => { - string savePath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory); - bitmap.Save(savePath + @"\" + DateTime.Now.ToString("u").Replace(':', '-') + ".png", ImageFormat.Png); - }); - } - private void SavePPTScreenshot(string fileName) { var bitmap = GetScreenshotBitmap(); string savePath = Settings.Automation.AutoSavedStrokesLocation + @"\Auto Saved - PPT Screenshots"; @@ -401,15 +545,5 @@ namespace Ink_Canvas { SaveInkCanvasStrokes(false, false); } } - - private Bitmap GetScreenshotBitmap() { - Rectangle rc = System.Windows.Forms.SystemInformation.VirtualScreen; - var bitmap = new Bitmap(rc.Width, rc.Height, PixelFormat.Format32bppArgb); - using (Graphics memoryGrahics = Graphics.FromImage(bitmap)) { - memoryGrahics.CopyFromScreen(rc.X, rc.Y, 0, 0, rc.Size, CopyPixelOperation.SourceCopy); - } - - return bitmap; - } } } \ No newline at end of file diff --git a/InkCanvasForClass/MainWindow_cs/MW_Storage.cs b/InkCanvasForClass/MainWindow_cs/MW_Storage.cs index ce740b7..77b72fa 100644 --- a/InkCanvasForClass/MainWindow_cs/MW_Storage.cs +++ b/InkCanvasForClass/MainWindow_cs/MW_Storage.cs @@ -269,6 +269,10 @@ namespace Ink_Canvas { StartAnalyzeStorage(); } + + + //private DirectoryInfo GetDirectoryBySettings() + private DirectoryInfo GetDirectoryInfoByIndex(int index) { var autoSavedInkPath = new DirectoryInfo(storageLocationItems[ComboBoxStoragePath.SelectedIndex].Path+"\\AutoSavedInk"); var autoSavedSnapshotPath = new DirectoryInfo(storageLocationItems[ComboBoxStoragePath.SelectedIndex].Path+"\\AutoSavedSnapshot"); diff --git a/InkCanvasForClass/Popups/ScreenshotWindow.xaml.cs b/InkCanvasForClass/Popups/ScreenshotWindow.xaml.cs index 5ec6f42..31c39f9 100644 --- a/InkCanvasForClass/Popups/ScreenshotWindow.xaml.cs +++ b/InkCanvasForClass/Popups/ScreenshotWindow.xaml.cs @@ -1,7 +1,9 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Drawing; using System.Drawing.Imaging; +using System.IO; using System.Linq; using System.Text; using System.Threading; @@ -18,6 +20,7 @@ using System.Windows.Media.Imaging; using System.Windows.Shapes; using System.Xml.Linq; using Vanara.PInvoke; +using Color = System.Windows.Media.Color; namespace Ink_Canvas.Popups { @@ -126,17 +129,28 @@ namespace Ink_Canvas.Popups if (selectedMode == 0) CaptureFullScreen(); } - private void CaptureFullScreen() { - mainWindow.SaveScreenshotToDesktopByMagnificationAPIEx(true, new HWND[] { - new WindowInteropHelper(mainWindow).Handle, - new WindowInteropHelper(this).Handle, - }, async bitmap => { - string savePath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory); - bitmap.Save(savePath + @"\" + DateTime.Now.ToString("u").Replace(':', '-') + ".bmp", ImageFormat.Bmp); - mainWindow.ShowNewToast("已保存截图到桌面!",MW_Toast.ToastType.Success,3000); - await Task.Delay(50); + private async void CaptureFullScreen() { + try { + var bm = await mainWindow.FullscreenSnapshot(new MainWindow.SnapshotConfig() { + BitmapSavePath = + new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)), + ExcludedHwnds = new HWND[] { + new HWND(new WindowInteropHelper(this).Handle) + }, + IsCopyToClipboard = true, + IsSaveToLocal = true, + OutputMIMEType = MainWindow.OutputImageMIMEFormat.Png, + }); + bm.Dispose(); + mainWindow.ShowNewToast("已保存截图到桌面!", MW_Toast.ToastType.Success, 3000); + await Task.Delay(1); Close(); - }); + } + catch (Exception e) { + mainWindow.ShowNewToast($"截图失败!{e.Message}", MW_Toast.ToastType.Error, 3000); + await Task.Delay(1); + Close(); + } } private void CaptureButton_MouseLeave(object sender, MouseEventArgs e) {