[update] 全屏截图

This commit is contained in:
Dubi906w 2024-08-01 21:58:06 +08:00
parent c7b863ad0f
commit a60b7b7535
5 changed files with 332 additions and 184 deletions

View File

@ -150,7 +150,6 @@
<PackageReference Include="Hardcodet.NotifyIcon.Wpf" Version="1.1.0" /> <PackageReference Include="Hardcodet.NotifyIcon.Wpf" Version="1.1.0" />
<PackageReference Include="iNKORE.UI.WPF.Modern" Version="0.9.27" /> <PackageReference Include="iNKORE.UI.WPF.Modern" Version="0.9.27" />
<PackageReference Include="JetBrains.Annotations" Version="2024.2.0" /> <PackageReference Include="JetBrains.Annotations" Version="2024.2.0" />
<PackageReference Include="Jint" Version="4.0.0" />
<PackageReference Include="Lierda.WPFHelper" Version="1.0.3" /> <PackageReference Include="Lierda.WPFHelper" Version="1.0.3" />
<PackageReference Include="Microsoft.Office.Interop.PowerPoint" Version="15.0.4420.1018" /> <PackageReference Include="Microsoft.Office.Interop.PowerPoint" Version="15.0.4420.1018" />
<PackageReference Include="MicrosoftOfficeCore" Version="15.0.0" /> <PackageReference Include="MicrosoftOfficeCore" Version="15.0.0" />
@ -161,9 +160,7 @@
<PackageReference Include="Ookii.Dialogs.Wpf" Version="5.0.1" /> <PackageReference Include="Ookii.Dialogs.Wpf" Version="5.0.1" />
<PackageReference Include="OSVersionExt" Version="3.0.0" /> <PackageReference Include="OSVersionExt" Version="3.0.0" />
<PackageReference Include="PixiEditor.ColorPicker" Version="3.4.1" /> <PackageReference Include="PixiEditor.ColorPicker" Version="3.4.1" />
<PackageReference Include="Vanara.PInvoke.Kernel32" Version="4.0.2" />
<PackageReference Include="Vanara.PInvoke.Magnification" Version="4.0.2" /> <PackageReference Include="Vanara.PInvoke.Magnification" Version="4.0.2" />
<PackageReference Include="Vanara.PInvoke.User32" Version="4.0.2" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<COMReference Include="IWshRuntimeLibrary"> <COMReference Include="IWshRuntimeLibrary">

View File

@ -22,7 +22,6 @@ using System.Windows.Documents;
using Ink_Canvas.Popups; using Ink_Canvas.Popups;
using iNKORE.UI.WPF.Modern.Controls; using iNKORE.UI.WPF.Modern.Controls;
using System.Windows.Forms; using System.Windows.Forms;
using Jint.Runtime;
using Application = System.Windows.Application; using Application = System.Windows.Application;
using Button = System.Windows.Controls.Button; using Button = System.Windows.Controls.Button;
using TextBox = System.Windows.Controls.TextBox; using TextBox = System.Windows.Controls.TextBox;

View File

@ -5,56 +5,25 @@ using System.Drawing;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Forms; using System.Windows.Documents;
using System.Windows.Interop; using System.Windows.Interop;
using System.Windows.Media; using System.Windows.Media.Imaging;
using System.Windows.Shell;
using Acornima.Ast;
using OSVersionExtension; using OSVersionExtension;
using Vanara.PInvoke; using Vanara.PInvoke;
using static Vanara.PInvoke.Gdi32; using Encoder = System.Drawing.Imaging.Encoder;
using Color = System.Drawing.Color;
using OperatingSystem = OSVersionExtension.OperatingSystem; using OperatingSystem = OSVersionExtension.OperatingSystem;
using PixelFormat = System.Drawing.Imaging.PixelFormat; using PixelFormat = System.Drawing.Imaging.PixelFormat;
namespace Ink_Canvas { namespace Ink_Canvas {
public partial class MainWindow : Window { 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"; #region MagnificationAPI ICC窗口
if (!Directory.Exists(Path.GetDirectoryName(savePath))) {
Directory.CreateDirectory(Path.GetDirectoryName(savePath));
}
bitmap.Save(savePath, ImageFormat.Png); #region Dubi906w
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()));
}
[DllImport("user32.dll", EntryPoint = "SetWindowLong")] [DllImport("user32.dll", EntryPoint = "SetWindowLong")]
private static extern int SetWindowLong32(IntPtr hWnd, int nIndex, int dwNewLong); 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); private static extern IntPtr SetWindowLongPtr64(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
[DllImport("user32.dll", EntryPoint = "GetWindowLong")] [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, [DllImport("user32.dll")]
Action<Bitmap> callbackAction) { static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
if (OSVersion.GetOperatingSystem() < OperatingSystem.Windows8 &&
OSVersion.GetOperatingSystem() > OperatingSystem.Windows10) return;
if (!Magnification.MagInitialize()) return;
// 創建宿主窗體 #endregion Dubi906w
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);
Trace.WriteLine(handle); #region Win32 AlanCRL
// 創建放大鏡窗體使用Win32方法 // 感謝 Alan-CRL 造的輪子
var hwndMag = User32.CreateWindow(Magnification.WC_MAGNIFIER, "ICCMagnifierWindow", private const int WS_EX_TOPMOST = 0x00000008;
User32.WindowStyles.WS_CHILD | User32.WindowStyles.WS_VISIBLE, 0, 0, private const int WS_EX_LAYERED = 0x00080000;
System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width, private const int WS_SIZEBOX = 0x00040000;
System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height, handle, HMENU.NULL, HINSTANCE.NULL, private const int WS_SYSMENU = 0x00080000;
IntPtr.Zero); 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);
// 過濾窗口 [DllImport("user32.dll")]
var hwnds = new List<HWND> { hwndMag }; private static extern bool DestroyWindow(IntPtr hWnd);
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;
// 設置窗口Source [DllImport("user32.dll", SetLastError = true)]
if (!Magnification.MagSetWindowSource(hwndMag, private static extern ushort RegisterClassEx(ref WNDCLASSEX lpwcx);
new RECT(0, 0, System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width,
System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height))) return;
RECT rect; [DllImport("user32.dll", SetLastError = true)]
User32.GetWindowRect(hwndMag, out rect); private static extern IntPtr DefWindowProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
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));
string savePath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory); [DllImport("user32.dll", SetLastError = true)]
bmp.Save(savePath + @"\" + DateTime.Now.ToString("u").Replace(':', '-') + ".png", ImageFormat.Png); private static extern IntPtr LoadCursor(IntPtr hInstance, int lpCursorName);
Trace.WriteLine(bmp.GetPixel(123,123)); [DllImport("user32.dll", SetLastError = true)]
Trace.WriteLine(bmp.GetPixel(163,174)); private static extern short UnregisterClass(string lpClassName, IntPtr hInstance);
// 關閉宿主窗體 [DllImport("user32.dll", SetLastError = true)]
//Magnification.MagUninitialize(); private static extern bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey, byte bAlpha, uint dwFlags);
//mainWinMag.Close();
[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, private delegate IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
Action<Bitmap> callbackAction) {
if (OSVersion.GetOperatingSystem() < OperatingSystem.Windows8 && private static readonly WndProc StaticWndProcDelegate = WndHostProc;
OSVersion.GetOperatingSystem() > OperatingSystem.Windows10) return;
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<Bitmap> callbackAction, bool isUsingCallback = false) {
if (OSVersion.GetOperatingSystem() < OperatingSystem.Windows81) return;
if (!Magnification.MagInitialize()) return; if (!Magnification.MagInitialize()) return;
// 註冊宿主窗體類名
var wndClassEx = new WNDCLASSEX {
cbSize = (uint)Marshal.SizeOf<WNDCLASSEX>(), 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(); windowHostHandle = CreateWindowEx(
mainWinMag.WindowState = WindowState.Maximized; WS_EX_TOPMOST | WS_EX_LAYERED, "ICCMagnifierWindowHost", "ICCMagnifierWindowHostWindow",
mainWinMag.WindowStyle = WindowStyle.None; WS_SIZEBOX | WS_SYSMENU | WS_CLIPCHILDREN | WS_CAPTION | WS_MAXIMIZEBOX, 0, 0,
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,
System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width, 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); 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<HWND> { hwndMag }; var hwnds = new List<HWND> { hwndMag };
hwnds.AddRange(hwndsList); hwnds.AddRange(hwndsList);
if (!Magnification.MagSetWindowFilterList(hwndMag, if (!Magnification.MagSetWindowFilterList(hwndMag, Magnification.MW_FILTERMODE.MW_FILTERMODE_EXCLUDE,
isExcludeMode hwnds.Count, hwnds.ToArray())) return;
? Magnification.MW_FILTERMODE.MW_FILTERMODE_EXCLUDE // 设置窗口 Source
: Magnification.MW_FILTERMODE.MW_FILTERMODE_INCLUDE, if (!Magnification.MagSetWindowSource(hwndMag, new RECT(0, 0,
isExcludeMode ? hwnds.Count : hwndsList.Length, hwnds.ToArray())) return; System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width,
System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height))) return;
// 保存數據 InvalidateRect(hwndMag, IntPtr.Zero, true);
if (!Magnification.MagSetImageScalingCallback(hwndMag, // 抓取屏幕圖像
(hwnd, srcdata, srcheader, destdata, destheader, unclipped, clipped, dirty) => { if (isUsingCallback) {
Bitmap bm = new Bitmap((int)srcheader.width, (int)srcheader.height, (int)srcheader.width * 4, if (!Magnification.MagSetImageScalingCallback(hwndMag,
PixelFormat.Format32bppRgb, srcdata); (hwnd, srcdata, srcheader, destdata, destheader, unclipped, clipped, dirty) => {
callbackAction(bm); Bitmap bm = new Bitmap((int)srcheader.width, (int)srcheader.height,
return true; (int)srcheader.width * 4, PixelFormat.Format32bppRgb, srcdata);
})) return; callbackAction(bm);
return true;
// 設置窗口Source })) return;
if (!Magnification.MagSetWindowSource(hwndMag, } else {
new RECT(0, 0, System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width, RECT rect;
System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height))) return; 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(); Magnification.MagUninitialize();
mainWinMag.Close(); DestroyWindow(windowHostHandle);
} }
#endregion public Task<Bitmap> SaveScreenshotToDesktopByMagnificationAPIAsync(HWND[] hwndsList, bool isUsingCallback = false) {
return Task.Run(() => {
var t = new TaskCompletionSource<Bitmap>();
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 #region Powerpoint
@ -197,9 +229,9 @@ namespace Ink_Canvas {
static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam); static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
public static IntPtr GetClassLongPtr(IntPtr hWnd, int nIndex) { public static IntPtr GetClassLongPtr(IntPtr hWnd, int nIndex) {
if (IntPtr.Size > 4) if (IntPtr.Size > 4)
return GetClassLongPtr64(hWnd, nIndex); return GetClassLongPtr64(hWnd, nIndex);
else else
return new IntPtr(GetClassLongPtr32(hWnd, nIndex)); return new IntPtr(GetClassLongPtr32(hWnd, nIndex));
} }
@ -351,14 +383,141 @@ namespace Ink_Canvas {
return windows.ToArray(); return windows.ToArray();
} }
public async Task<WindowInformation[]> GetAllWindowsAsync(HWND[] excludedHwnds) public async Task<WindowInformation[]> GetAllWindowsAsync(HWND[] excludedHwnds) {
{
var windows = await Task.Run(() => GetAllWindows(excludedHwnds)); var windows = await Task.Run(() => GetAllWindows(excludedHwnds));
return windows; return windows;
} }
#endregion #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<Bitmap> FullscreenSnapshot(SnapshotConfig config) {
Bitmap bitmap = new Bitmap(1,1);
var ex = new List<HWND>() { 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() { private void SaveScreenShotToDesktop() {
var bitmap = GetScreenshotBitmap(); var bitmap = GetScreenshotBitmap();
string savePath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory); string savePath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
@ -368,21 +527,6 @@ namespace Ink_Canvas {
if (Settings.Automation.IsAutoSaveStrokesAtScreenshot) SaveInkCanvasStrokes(false, false); 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) { private void SavePPTScreenshot(string fileName) {
var bitmap = GetScreenshotBitmap(); var bitmap = GetScreenshotBitmap();
string savePath = Settings.Automation.AutoSavedStrokesLocation + @"\Auto Saved - PPT Screenshots"; string savePath = Settings.Automation.AutoSavedStrokesLocation + @"\Auto Saved - PPT Screenshots";
@ -401,15 +545,5 @@ namespace Ink_Canvas {
SaveInkCanvasStrokes(false, false); 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;
}
} }
} }

View File

@ -269,6 +269,10 @@ namespace Ink_Canvas {
StartAnalyzeStorage(); StartAnalyzeStorage();
} }
//private DirectoryInfo GetDirectoryBySettings()
private DirectoryInfo GetDirectoryInfoByIndex(int index) { private DirectoryInfo GetDirectoryInfoByIndex(int index) {
var autoSavedInkPath = new DirectoryInfo(storageLocationItems[ComboBoxStoragePath.SelectedIndex].Path+"\\AutoSavedInk"); var autoSavedInkPath = new DirectoryInfo(storageLocationItems[ComboBoxStoragePath.SelectedIndex].Path+"\\AutoSavedInk");
var autoSavedSnapshotPath = new DirectoryInfo(storageLocationItems[ComboBoxStoragePath.SelectedIndex].Path+"\\AutoSavedSnapshot"); var autoSavedSnapshotPath = new DirectoryInfo(storageLocationItems[ComboBoxStoragePath.SelectedIndex].Path+"\\AutoSavedSnapshot");

View File

@ -1,7 +1,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
@ -18,6 +20,7 @@ using System.Windows.Media.Imaging;
using System.Windows.Shapes; using System.Windows.Shapes;
using System.Xml.Linq; using System.Xml.Linq;
using Vanara.PInvoke; using Vanara.PInvoke;
using Color = System.Windows.Media.Color;
namespace Ink_Canvas.Popups namespace Ink_Canvas.Popups
{ {
@ -126,17 +129,28 @@ namespace Ink_Canvas.Popups
if (selectedMode == 0) CaptureFullScreen(); if (selectedMode == 0) CaptureFullScreen();
} }
private void CaptureFullScreen() { private async void CaptureFullScreen() {
mainWindow.SaveScreenshotToDesktopByMagnificationAPIEx(true, new HWND[] { try {
new WindowInteropHelper(mainWindow).Handle, var bm = await mainWindow.FullscreenSnapshot(new MainWindow.SnapshotConfig() {
new WindowInteropHelper(this).Handle, BitmapSavePath =
}, async bitmap => { new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)),
string savePath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory); ExcludedHwnds = new HWND[] {
bitmap.Save(savePath + @"\" + DateTime.Now.ToString("u").Replace(':', '-') + ".bmp", ImageFormat.Bmp); new HWND(new WindowInteropHelper(this).Handle)
mainWindow.ShowNewToast("已保存截图到桌面!",MW_Toast.ToastType.Success,3000); },
await Task.Delay(50); IsCopyToClipboard = true,
IsSaveToLocal = true,
OutputMIMEType = MainWindow.OutputImageMIMEFormat.Png,
});
bm.Dispose();
mainWindow.ShowNewToast("已保存截图到桌面!", MW_Toast.ToastType.Success, 3000);
await Task.Delay(1);
Close(); 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) { private void CaptureButton_MouseLeave(object sender, MouseEventArgs e) {