[update] 恢复全屏截图
This commit is contained in:
parent
f16fcb67b9
commit
00e045a01a
@ -161,7 +161,9 @@
|
|||||||
<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">
|
||||||
|
@ -8052,6 +8052,102 @@
|
|||||||
</ui:SimpleStackPanel>
|
</ui:SimpleStackPanel>
|
||||||
</ui:SimpleStackPanel>
|
</ui:SimpleStackPanel>
|
||||||
</GroupBox>
|
</GroupBox>
|
||||||
|
<GroupBox Name="SettingsSnapshotGroupBox">
|
||||||
|
<GroupBox.Header>
|
||||||
|
<Canvas Height="56">
|
||||||
|
<TextBlock Text="Screenshot" Foreground="#fafafa" Opacity="0.1"
|
||||||
|
FontSize="20" Canvas.Top="30" Canvas.Left="16" />
|
||||||
|
<TextBlock Margin="0,12,0,0" Text="截图" FontWeight="Bold" Foreground="#fafafa"
|
||||||
|
FontSize="26" Canvas.Top="0" />
|
||||||
|
</Canvas>
|
||||||
|
</GroupBox.Header>
|
||||||
|
<ui:SimpleStackPanel Spacing="6">
|
||||||
|
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||||
|
<TextBlock Foreground="#fafafa" Text="使用MagnificationAPI截图"
|
||||||
|
VerticalAlignment="Center" FontSize="14" Margin="0,0,16,0" />
|
||||||
|
<ui:ToggleSwitch OnContent="" OffContent=""
|
||||||
|
Name="ToggleSwitchScreenshotUsingMagnificationAPI"
|
||||||
|
IsOn="True" FontFamily="Microsoft YaHei UI"
|
||||||
|
FontWeight="Bold"/>
|
||||||
|
</ui:SimpleStackPanel>
|
||||||
|
<TextBlock Text="# 使用 Magnification API 和弃用的函数 MagSetImageScalingCallback 实现过滤ICC窗口截图。"
|
||||||
|
TextWrapping="Wrap" Foreground="#a1a1aa" />
|
||||||
|
<ui:InfoBar
|
||||||
|
IsOpen="True"
|
||||||
|
IsClosable="False"
|
||||||
|
Severity="Warning"
|
||||||
|
Title="该功能为高度实验性选项"
|
||||||
|
Message="该功能使用的 MagSetImageScalingCallback 函数在 Win7 及更高版本中已弃用,经测试,只有 Win8、Win8.1、Win10 系统可以使用该功能,Win11已经失效。该功能极度不稳定,可能会导致截屏时黑屏或系统崩溃,请按需开启。" />
|
||||||
|
<Line HorizontalAlignment="Center" X1="0" Y1="0" X2="400" Y2="0"
|
||||||
|
Stroke="#3f3f46" StrokeThickness="1" Margin="0,4,0,4" />
|
||||||
|
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||||
|
<TextBlock Foreground="#fafafa" Text="截图后以 .png 格式复制到剪贴板"
|
||||||
|
VerticalAlignment="Center" FontSize="14" Margin="0,0,16,0" />
|
||||||
|
<ui:ToggleSwitch OnContent="" OffContent=""
|
||||||
|
Name="ToggleSwitchCopyScreenshotToClipbard"
|
||||||
|
IsOn="True" FontFamily="Microsoft YaHei UI"
|
||||||
|
FontWeight="Bold"/>
|
||||||
|
</ui:SimpleStackPanel>
|
||||||
|
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||||
|
<TextBlock Foreground="#fafafa" Text="截图时隐藏ICC主窗口"
|
||||||
|
VerticalAlignment="Center" FontSize="14" Margin="0,0,16,0" />
|
||||||
|
<ui:ToggleSwitch OnContent="" OffContent=""
|
||||||
|
Name="ToggleSwitchHideMainWinWhenScreenShot"
|
||||||
|
IsOn="True" FontFamily="Microsoft YaHei UI"
|
||||||
|
FontWeight="Bold"/>
|
||||||
|
</ui:SimpleStackPanel>
|
||||||
|
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||||
|
<TextBlock Foreground="#fafafa" Text="截图时附加墨迹到截图文件上"
|
||||||
|
VerticalAlignment="Center" FontSize="14" Margin="0,0,16,0" />
|
||||||
|
<ui:ToggleSwitch OnContent="" OffContent=""
|
||||||
|
Name="ToggleSwitchAttatchInkWhenScreenshot"
|
||||||
|
IsOn="True" FontFamily="Microsoft YaHei UI"
|
||||||
|
FontWeight="Bold"/>
|
||||||
|
</ui:SimpleStackPanel>
|
||||||
|
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||||
|
<TextBlock Foreground="#fafafa" Text="窗口截图只截取最大化窗口"
|
||||||
|
VerticalAlignment="Center" FontSize="14" Margin="0,0,16,0" />
|
||||||
|
<ui:ToggleSwitch OnContent="" OffContent=""
|
||||||
|
Name="ToggleSwitchOnlySnapshotMaximizeWindow"
|
||||||
|
IsOn="True" FontFamily="Microsoft YaHei UI"
|
||||||
|
FontWeight="Bold"/>
|
||||||
|
</ui:SimpleStackPanel>
|
||||||
|
<ui:SimpleStackPanel Orientation="Vertical" HorizontalAlignment="Left" Spacing="8">
|
||||||
|
<TextBlock Foreground="#fafafa" Text="截图文件文件名" VerticalAlignment="Center"
|
||||||
|
FontSize="14" Margin="0,0,16,0" />
|
||||||
|
<ui:SimpleStackPanel Orientation="Horizontal" Spacing="10">
|
||||||
|
<TextBox Width="320" x:Name="ScreenshotFileName" Text='Screenshot-[YYYY]-[MM]-[DD]-[HH]-[mm]-[ss].png'
|
||||||
|
TextWrapping="NoWrap"
|
||||||
|
TextChanged="AutoSavedStrokesLocationTextBox_TextChanged" />
|
||||||
|
<Button Name="ScreenshotFileNameResetButton" Content="浏览"
|
||||||
|
Click="AutoSavedStrokesLocationButton_Click" />
|
||||||
|
</ui:SimpleStackPanel>
|
||||||
|
<ui:SimpleStackPanel Orientation="Vertical" Spacing="2">
|
||||||
|
<TextBlock Text="# 模板语法请参考下面可用的语法:" TextWrapping="Wrap" Foreground="#a1a1aa" />
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition/>
|
||||||
|
<ColumnDefinition/>
|
||||||
|
<ColumnDefinition/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition/>
|
||||||
|
<RowDefinition/>
|
||||||
|
<RowDefinition/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<TextBlock Grid.Column="0" Grid.Row="0" TextWrapping="Wrap" Foreground="#a1a1aa" Text="[YYYY] - 日期年份"/>
|
||||||
|
<TextBlock Grid.Column="1" Grid.Row="0" TextWrapping="Wrap" Foreground="#a1a1aa" Text="[MM] - 日期月份"/>
|
||||||
|
<TextBlock Grid.Column="2" Grid.Row="0" TextWrapping="Wrap" Foreground="#a1a1aa" Text="[DD] - 日期号数"/>
|
||||||
|
<TextBlock Grid.Column="0" Grid.Row="1" TextWrapping="Wrap" Foreground="#a1a1aa" Text="[HH] - 日期小时数"/>
|
||||||
|
<TextBlock Grid.Column="1" Grid.Row="1" TextWrapping="Wrap" Foreground="#a1a1aa" Text="[mm] - 日期分钟数"/>
|
||||||
|
<TextBlock Grid.Column="2" Grid.Row="1" TextWrapping="Wrap" Foreground="#a1a1aa" Text="[ss] - 日期秒数"/>
|
||||||
|
<TextBlock Grid.Column="0" Grid.Row="2" TextWrapping="Wrap" Foreground="#a1a1aa" Text="[width] - 图片宽度"/>
|
||||||
|
<TextBlock Grid.Column="1" Grid.Row="2" TextWrapping="Wrap" Foreground="#a1a1aa" Text="[width] - 图片高度"/>
|
||||||
|
</Grid>
|
||||||
|
</ui:SimpleStackPanel>
|
||||||
|
</ui:SimpleStackPanel>
|
||||||
|
</ui:SimpleStackPanel>
|
||||||
|
</GroupBox>
|
||||||
<GroupBox Name="SettingsRandWindowGroupBox">
|
<GroupBox Name="SettingsRandWindowGroupBox">
|
||||||
<GroupBox.Header>
|
<GroupBox.Header>
|
||||||
<Canvas Height="56">
|
<Canvas Height="56">
|
||||||
@ -8317,9 +8413,9 @@
|
|||||||
</Canvas>
|
</Canvas>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid Controls:Panel.ZIndex="998" Width="50" HorizontalAlignment="Left" Background="#AA09090b">
|
<Grid Controls:Panel.ZIndex="998" Width="50" HorizontalAlignment="Left" Background="#AA09090b">
|
||||||
<ui:SimpleStackPanel Orientation="Vertical" VerticalAlignment="Center" Width="50">
|
<ui:SimpleStackPanel Orientation="Vertical" VerticalAlignment="Center" Width="50" Name="SettingsJumpToGroupBoxButtonsPanel">
|
||||||
<Border Name="SettingsStartupJumpToGroupBoxButton"
|
<Border Name="SettingsStartupJumpToGroupBoxButton"
|
||||||
MouseDown="SettingsStartupJumpToGroupBox" BorderBrush="#3b82f6"
|
MouseDown="SettingsJumpToGroupBox_MouseDown" BorderBrush="#3b82f6"
|
||||||
BorderThickness="0,0,4,0" Width="50" Height="50">
|
BorderThickness="0,0,4,0" Width="50" Height="50">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Image Height="28" Width="28">
|
<Image Height="28" Width="28">
|
||||||
@ -8336,7 +8432,7 @@
|
|||||||
</Image>
|
</Image>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
<Border Name="SettingsCanvasJumpToGroupBoxButton" MouseDown="SettingsCanvasJumpToGroupBox"
|
<Border Name="SettingsCanvasJumpToGroupBoxButton" MouseDown="SettingsJumpToGroupBox_MouseDown"
|
||||||
BorderBrush="#3b82f6" BorderThickness="0,0,0,0" Width="50" Height="50">
|
BorderBrush="#3b82f6" BorderThickness="0,0,0,0" Width="50" Height="50">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Image Height="28" Width="28">
|
<Image Height="28" Width="28">
|
||||||
@ -8354,7 +8450,7 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
<Border Name="SettingsGestureJumpToGroupBoxButton"
|
<Border Name="SettingsGestureJumpToGroupBoxButton"
|
||||||
MouseDown="SettingsGestureJumpToGroupBox" BorderBrush="#3b82f6"
|
MouseDown="SettingsJumpToGroupBox_MouseDown" BorderBrush="#3b82f6"
|
||||||
BorderThickness="0,0,0,0" Width="50" Height="50">
|
BorderThickness="0,0,0,0" Width="50" Height="50">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Image Height="28" Width="28">
|
<Image Height="28" Width="28">
|
||||||
@ -8372,7 +8468,7 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
<Border Name="SettingsInkRecognitionJumpToGroupBoxButton"
|
<Border Name="SettingsInkRecognitionJumpToGroupBoxButton"
|
||||||
MouseDown="SettingsInkRecognitionJumpToGroupBox" BorderBrush="#3b82f6"
|
MouseDown="SettingsJumpToGroupBox_MouseDown" BorderBrush="#3b82f6"
|
||||||
BorderThickness="0,0,0,0" Width="50" Height="50">
|
BorderThickness="0,0,0,0" Width="50" Height="50">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Image Height="28" Width="28">
|
<Image Height="28" Width="28">
|
||||||
@ -8390,7 +8486,7 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
<Border Name="SettingsAppearanceJumpToGroupBoxButton"
|
<Border Name="SettingsAppearanceJumpToGroupBoxButton"
|
||||||
MouseDown="SettingsAppearanceJumpToGroupBox" BorderBrush="#3b82f6"
|
MouseDown="SettingsJumpToGroupBox_MouseDown" BorderBrush="#3b82f6"
|
||||||
BorderThickness="0,0,0,0" Width="50" Height="50">
|
BorderThickness="0,0,0,0" Width="50" Height="50">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Image Height="28" Width="28">
|
<Image Height="28" Width="28">
|
||||||
@ -8407,7 +8503,7 @@
|
|||||||
</Image>
|
</Image>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
<Border Name="SettingsPPTJumpToGroupBoxButton" MouseDown="SettingsPPTJumpToGroupBox"
|
<Border Name="SettingsPPTJumpToGroupBoxButton" MouseDown="SettingsJumpToGroupBox_MouseDown"
|
||||||
BorderBrush="#3b82f6" BorderThickness="0,0,0,0" Width="50" Height="50">
|
BorderBrush="#3b82f6" BorderThickness="0,0,0,0" Width="50" Height="50">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Image Height="28" Width="28">
|
<Image Height="28" Width="28">
|
||||||
@ -8425,7 +8521,7 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
<Border Name="SettingsAdvancedJumpToGroupBoxButton"
|
<Border Name="SettingsAdvancedJumpToGroupBoxButton"
|
||||||
MouseDown="SettingsAdvancedJumpToGroupBox" BorderBrush="#3b82f6"
|
MouseDown="SettingsJumpToGroupBox_MouseDown" BorderBrush="#3b82f6"
|
||||||
BorderThickness="0,0,0,0" Width="50" Height="50">
|
BorderThickness="0,0,0,0" Width="50" Height="50">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Image Height="28" Width="28">
|
<Image Height="28" Width="28">
|
||||||
@ -8443,7 +8539,7 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
<Border Name="SettingsAutomationJumpToGroupBoxButton"
|
<Border Name="SettingsAutomationJumpToGroupBoxButton"
|
||||||
MouseDown="SettingsAutomationJumpToGroupBox" BorderBrush="#3b82f6"
|
MouseDown="SettingsJumpToGroupBox_MouseDown" BorderBrush="#3b82f6"
|
||||||
BorderThickness="0,0,0,0" Width="50" Height="50">
|
BorderThickness="0,0,0,0" Width="50" Height="50">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Image Height="28" Width="28">
|
<Image Height="28" Width="28">
|
||||||
@ -8461,7 +8557,7 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
<Border Name="SettingsRandWindowJumpToGroupBoxButton"
|
<Border Name="SettingsRandWindowJumpToGroupBoxButton"
|
||||||
MouseDown="SettingsRandWindowJumpToGroupBox" BorderBrush="#3b82f6"
|
MouseDown="SettingsJumpToGroupBox_MouseDown" BorderBrush="#3b82f6"
|
||||||
BorderThickness="0,0,0,0" Width="50" Height="50">
|
BorderThickness="0,0,0,0" Width="50" Height="50">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Image Height="28" Width="28">
|
<Image Height="28" Width="28">
|
||||||
@ -8478,7 +8574,7 @@
|
|||||||
</Image>
|
</Image>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
<Border Name="SettingsAboutJumpToGroupBoxButton" MouseDown="SettingsAboutJumpToGroupBox"
|
<Border Name="SettingsAboutJumpToGroupBoxButton" MouseDown="SettingsJumpToGroupBox_MouseDown"
|
||||||
BorderBrush="#3b82f6" BorderThickness="0,0,0,0" Width="50" Height="50">
|
BorderBrush="#3b82f6" BorderThickness="0,0,0,0" Width="50" Height="50">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Image Height="28" Width="28">
|
<Image Height="28" Width="28">
|
||||||
|
@ -23,6 +23,7 @@ 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 Jint.Runtime;
|
||||||
|
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;
|
||||||
|
|
||||||
@ -307,6 +308,7 @@ namespace Ink_Canvas {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (e.Cancel) LogHelper.WriteLogToFile("Ink Canvas closing cancelled", LogHelper.LogType.Event);
|
if (e.Cancel) LogHelper.WriteLogToFile("Ink Canvas closing cancelled", LogHelper.LogType.Event);
|
||||||
|
else Application.Current.Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
[DllImport("user32.dll", SetLastError = true)]
|
[DllImport("user32.dll", SetLastError = true)]
|
||||||
|
@ -5,618 +5,390 @@ 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.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Interop;
|
using System.Windows.Interop;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
|
using Acornima.Ast;
|
||||||
using OSVersionExtension;
|
using OSVersionExtension;
|
||||||
using Vanara.PInvoke;
|
using Vanara.PInvoke;
|
||||||
|
using static Vanara.PInvoke.Gdi32;
|
||||||
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();
|
||||||
private void SaveScreenshot(bool isHideNotification, string fileName = null)
|
string savePath = Settings.Automation.AutoSavedStrokesLocation + @"\Auto Saved - Screenshots";
|
||||||
{
|
if (fileName == null) fileName = DateTime.Now.ToString("u").Replace(":", "-");
|
||||||
var bitmap = GetScreenshotBitmap();
|
if (Settings.Automation.IsSaveScreenshotsInDateFolders) {
|
||||||
string savePath = Settings.Automation.AutoSavedStrokesLocation + @"\Auto Saved - Screenshots";
|
savePath += @"\" + DateTime.Now.ToString("yyyy-MM-dd");
|
||||||
if (fileName == null) fileName = DateTime.Now.ToString("u").Replace(":", "-");
|
}
|
||||||
if (Settings.Automation.IsSaveScreenshotsInDateFolders)
|
|
||||||
{
|
savePath += @"\" + fileName + ".png";
|
||||||
savePath += @"\" + DateTime.Now.ToString("yyyy-MM-dd");
|
if (!Directory.Exists(Path.GetDirectoryName(savePath))) {
|
||||||
}
|
Directory.CreateDirectory(Path.GetDirectoryName(savePath));
|
||||||
savePath += @"\" + fileName + ".png";
|
}
|
||||||
if (!Directory.Exists(Path.GetDirectoryName(savePath)))
|
|
||||||
{
|
bitmap.Save(savePath, ImageFormat.Png);
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(savePath));
|
if (Settings.Automation.IsAutoSaveStrokesAtScreenshot) {
|
||||||
}
|
SaveInkCanvasStrokes(false, false);
|
||||||
bitmap.Save(savePath, ImageFormat.Png);
|
}
|
||||||
if (Settings.Automation.IsAutoSaveStrokesAtScreenshot)
|
|
||||||
{
|
if (!isHideNotification) {
|
||||||
SaveInkCanvasStrokes(false, false);
|
ShowNewToast("截图成功保存至 " + savePath, MW_Toast.ToastType.Success, 3000);
|
||||||
}
|
}
|
||||||
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)
|
||||||
#region MagnificationAPI 獲取屏幕截圖並過濾ICC窗口
|
return SetWindowLongPtr64(hWnd, nIndex, dwNewLong);
|
||||||
|
else
|
||||||
public static IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong)
|
return new IntPtr(SetWindowLong32(hWnd, nIndex, dwNewLong.ToInt32()));
|
||||||
{
|
}
|
||||||
if (IntPtr.Size == 8)
|
|
||||||
return SetWindowLongPtr64(hWnd, nIndex, dwNewLong);
|
[DllImport("user32.dll", EntryPoint = "SetWindowLong")]
|
||||||
else
|
private static extern int SetWindowLong32(IntPtr hWnd, int nIndex, int dwNewLong);
|
||||||
return new IntPtr(SetWindowLong32(hWnd, nIndex, dwNewLong.ToInt32()));
|
|
||||||
}
|
[DllImport("user32.dll", EntryPoint = "SetWindowLongPtr")]
|
||||||
|
private static extern IntPtr SetWindowLongPtr64(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
|
||||||
[DllImport("user32.dll", EntryPoint="SetWindowLong")]
|
|
||||||
private static extern int SetWindowLong32(IntPtr hWnd, int nIndex, int dwNewLong);
|
[DllImport("user32.dll", EntryPoint = "GetWindowLong")]
|
||||||
|
static extern IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex);
|
||||||
[DllImport("user32.dll", EntryPoint="SetWindowLongPtr")]
|
|
||||||
private static extern IntPtr SetWindowLongPtr64(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
|
public unsafe void SaveScreenshotToDesktopByMagnificationAPIEx(bool isExcludeMode, HWND[] hwndsList,
|
||||||
|
Action<Bitmap> callbackAction) {
|
||||||
[DllImport("user32.dll", EntryPoint="GetWindowLong")]
|
if (OSVersion.GetOperatingSystem() < OperatingSystem.Windows8 &&
|
||||||
static extern IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex);
|
OSVersion.GetOperatingSystem() > OperatingSystem.Windows10) return;
|
||||||
|
if (!Magnification.MagInitialize()) return;
|
||||||
[DllImport("user32.dll")]
|
|
||||||
public static extern bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey, byte bAlpha, uint dwFlags);
|
// 創建宿主窗體
|
||||||
|
var mainWinMag = new Window();
|
||||||
[DllImport("user32.dll", SetLastError=true)]
|
mainWinMag.WindowState = WindowState.Maximized;
|
||||||
private static extern IntPtr CreateWindowEx(
|
mainWinMag.WindowStyle = WindowStyle.None;
|
||||||
uint dwExStyle,
|
mainWinMag.ResizeMode = ResizeMode.NoResize;
|
||||||
string lpClassName,
|
mainWinMag.Background = new SolidColorBrush(Colors.Transparent);
|
||||||
string lpWindowName,
|
mainWinMag.AllowsTransparency = true;
|
||||||
uint dwStyle,
|
mainWinMag.Show();
|
||||||
int x,
|
var handle = new HWND(new WindowInteropHelper(mainWinMag).Handle);
|
||||||
int y,
|
User32.SetWindowPos(handle, HWND.HWND_NOTOPMOST, 0, 0, System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width,
|
||||||
int nWidth,
|
System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height, User32.SetWindowPosFlags.SWP_HIDEWINDOW); // SWP_HIDEWINDOW
|
||||||
int nHeight,
|
SetWindowLongPtr(handle.DangerousGetHandle(), -20, new IntPtr((int)GetWindowLongPtr(handle.DangerousGetHandle(), -20) | 0x00080000));
|
||||||
IntPtr hWndParent,
|
User32.SetLayeredWindowAttributes(handle,0, 255, User32.LayeredWindowAttributes.LWA_ALPHA);
|
||||||
IntPtr hMenu,
|
|
||||||
IntPtr hInstance,
|
// 創建放大鏡窗體(使用Win32方法)
|
||||||
IntPtr lpParam);
|
var hwndMag = User32.CreateWindow(Magnification.WC_MAGNIFIER, "ICCMagnifierWindow",
|
||||||
[DllImport("user32.dll")]
|
User32.WindowStyles.WS_CHILD | User32.WindowStyles.WS_VISIBLE, 0, 0,
|
||||||
static extern bool DestroyWindow(IntPtr hWnd);
|
System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width,
|
||||||
|
System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height, handle, HMENU.NULL, HINSTANCE.NULL,
|
||||||
Bitmap RemoveImageTransparancy(Bitmap src) {
|
IntPtr.Zero);
|
||||||
Bitmap target = new Bitmap(src.Size.Width,src.Size.Height);
|
|
||||||
Graphics g = Graphics.FromImage(target);
|
Trace.WriteLine(hwndMag);
|
||||||
g.DrawRectangle(new System.Drawing.Pen(new SolidBrush(System.Drawing.Color.White)), 0, 0, target.Width, target.Height);
|
|
||||||
g.DrawImage(src, 0, 0);
|
// 過濾窗口
|
||||||
return target;
|
var hwnds = new List<HWND> { hwndMag };
|
||||||
}
|
hwnds.AddRange(hwndsList);
|
||||||
|
if (!Magnification.MagSetWindowFilterList(hwndMag,
|
||||||
public enum WindowStyles : uint
|
isExcludeMode
|
||||||
{
|
? Magnification.MW_FILTERMODE.MW_FILTERMODE_EXCLUDE
|
||||||
/// <summary>The window has a thin-line border.</summary>
|
: Magnification.MW_FILTERMODE.MW_FILTERMODE_INCLUDE,
|
||||||
WS_BORDER = 0x800000,
|
isExcludeMode ? hwnds.Count : hwndsList.Length, hwnds.ToArray())) return;
|
||||||
|
|
||||||
/// <summary>The window has a title bar (includes the WS_BORDER style).</summary>
|
// 設置窗口Source
|
||||||
WS_CAPTION = 0xc00000,
|
if (!Magnification.MagSetWindowSource(hwndMag,
|
||||||
|
new RECT(0, 0, System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width,
|
||||||
/// <summary>
|
System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height))) return;
|
||||||
/// The window is a child window. A window with this style cannot have a menu bar. This style cannot be used with the WS_POPUP style.
|
|
||||||
/// </summary>
|
RECT rect;
|
||||||
WS_CHILD = 0x40000000,
|
User32.GetWindowRect(hwndMag, out rect);
|
||||||
|
Bitmap bmp = new Bitmap(rect.Width, rect.Height);
|
||||||
/// <summary>
|
Graphics memoryGraphics = Graphics.FromImage(bmp);
|
||||||
/// Excludes the area occupied by child windows when drawing occurs within the parent window. This style is used when creating
|
IntPtr hdc = memoryGraphics.GetHdc();
|
||||||
/// the parent window.
|
Trace.WriteLine(User32.PrintWindow(hwndMag, hdc, User32.PW.PW_RENDERFULLCONTENT));
|
||||||
/// </summary>
|
|
||||||
WS_CLIPCHILDREN = 0x2000000,
|
string savePath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
|
||||||
|
bmp.Save(savePath + @"\" + DateTime.Now.ToString("u").Replace(':', '-') + ".png", ImageFormat.Png);
|
||||||
/// <summary>
|
|
||||||
/// Clips child windows relative to each other; that is, when a particular child window receives a WM_PAINT message, the
|
// 關閉宿主窗體
|
||||||
/// WS_CLIPSIBLINGS style clips all other overlapping child windows out of the region of the child window to be updated. If
|
Magnification.MagUninitialize();
|
||||||
/// WS_CLIPSIBLINGS is not specified and child windows overlap, it is possible, when drawing within the client area of a child
|
mainWinMag.Close();
|
||||||
/// window, to draw within the client area of a neighboring child window.
|
}
|
||||||
/// </summary>
|
|
||||||
WS_CLIPSIBLINGS = 0x4000000,
|
public unsafe void SaveScreenshotToDesktopByMagnificationAPI(bool isExcludeMode, HWND[] hwndsList,
|
||||||
|
Action<Bitmap> callbackAction) {
|
||||||
/// <summary>
|
if (OSVersion.GetOperatingSystem() < OperatingSystem.Windows8 &&
|
||||||
/// The window is initially disabled. A disabled window cannot receive input from the user. To change this after a window has
|
OSVersion.GetOperatingSystem() > OperatingSystem.Windows10) return;
|
||||||
/// been created, use the EnableWindow function.
|
if (!Magnification.MagInitialize()) return;
|
||||||
/// </summary>
|
|
||||||
WS_DISABLED = 0x8000000,
|
// 創建宿主窗體
|
||||||
|
var mainWinMag = new Window();
|
||||||
/// <summary>
|
mainWinMag.WindowState = WindowState.Maximized;
|
||||||
/// The window has a border of a style typically used with dialog boxes. A window with this style cannot have a title bar.
|
mainWinMag.WindowStyle = WindowStyle.None;
|
||||||
/// </summary>
|
mainWinMag.ResizeMode = ResizeMode.NoResize;
|
||||||
WS_DLGFRAME = 0x400000,
|
mainWinMag.Background = new SolidColorBrush(Colors.Transparent);
|
||||||
|
mainWinMag.AllowsTransparency = true;
|
||||||
/// <summary>
|
mainWinMag.Show();
|
||||||
/// The window is the first control of a group of controls. The group consists of this first control and all controls defined
|
var handle = new HWND(new WindowInteropHelper(mainWinMag).Handle);
|
||||||
/// after it, up to the next control with the WS_GROUP style. The first control in each group usually has the WS_TABSTOP style so
|
User32.SetWindowPos(handle, HWND.HWND_NOTOPMOST, 0, 0, System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width,
|
||||||
/// that the user can move from group to group. The user can subsequently change the keyboard focus from one control in the group
|
System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height, User32.SetWindowPosFlags.SWP_HIDEWINDOW); // SWP_HIDEWINDOW
|
||||||
/// to the next control in the group by using the direction keys. You can turn this style on and off to change dialog box
|
SetWindowLongPtr(handle.DangerousGetHandle(), -20, new IntPtr((int)GetWindowLongPtr(handle.DangerousGetHandle(), -20) | 0x00080000));
|
||||||
/// navigation. To change this style after a window has been created, use the SetWindowLong function.
|
User32.SetLayeredWindowAttributes(handle,0, 255, User32.LayeredWindowAttributes.LWA_ALPHA);
|
||||||
/// </summary>
|
|
||||||
WS_GROUP = 0x20000,
|
// 創建放大鏡窗體(使用Win32方法)
|
||||||
|
var hwndMag = User32.CreateWindow(Magnification.WC_MAGNIFIER, "ICCMagnifierWindow",
|
||||||
/// <summary>The window has a horizontal scroll bar.</summary>
|
User32.WindowStyles.WS_CHILD | User32.WindowStyles.WS_VISIBLE, 0, 0,
|
||||||
WS_HSCROLL = 0x100000,
|
System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width,
|
||||||
|
System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height, handle, HMENU.NULL, HINSTANCE.NULL,
|
||||||
/// <summary>The window is initially maximized.</summary>
|
IntPtr.Zero);
|
||||||
WS_MAXIMIZE = 0x1000000,
|
|
||||||
|
Trace.WriteLine(hwndMag);
|
||||||
/// <summary>
|
|
||||||
/// The window has a maximize button. Cannot be combined with the WS_EX_CONTEXTHELP style. The WS_SYSMENU style must also be specified.
|
// 過濾窗口
|
||||||
/// </summary>
|
var hwnds = new List<HWND> { hwndMag };
|
||||||
WS_MAXIMIZEBOX = 0x10000,
|
hwnds.AddRange(hwndsList);
|
||||||
|
if (!Magnification.MagSetWindowFilterList(hwndMag,
|
||||||
/// <summary>The window is initially minimized.</summary>
|
isExcludeMode
|
||||||
WS_MINIMIZE = 0x20000000,
|
? Magnification.MW_FILTERMODE.MW_FILTERMODE_EXCLUDE
|
||||||
|
: Magnification.MW_FILTERMODE.MW_FILTERMODE_INCLUDE,
|
||||||
/// <summary>
|
isExcludeMode ? hwnds.Count : hwndsList.Length, hwnds.ToArray())) return;
|
||||||
/// The window has a minimize button. Cannot be combined with the WS_EX_CONTEXTHELP style. The WS_SYSMENU style must also be specified.
|
|
||||||
/// </summary>
|
// 保存數據
|
||||||
WS_MINIMIZEBOX = 0x20000,
|
if (!Magnification.MagSetImageScalingCallback(hwndMag,
|
||||||
|
(hwnd, srcdata, srcheader, destdata, destheader, unclipped, clipped, dirty) => {
|
||||||
/// <summary>The window is an overlapped window. An overlapped window has a title bar and a border.</summary>
|
Bitmap bm = new Bitmap((int)srcheader.width, (int)srcheader.height, (int)srcheader.width * 4,
|
||||||
WS_OVERLAPPED = 0x0,
|
PixelFormat.Format32bppRgb, srcdata);
|
||||||
|
callbackAction(bm);
|
||||||
/// <summary>The window is an overlapped window.</summary>
|
return true;
|
||||||
WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,
|
})) return;
|
||||||
|
|
||||||
/// <summary>The window is a pop-up window. This style cannot be used with the WS_CHILD style.</summary>
|
// 設置窗口Source
|
||||||
WS_POPUP = 0x80000000u,
|
if (!Magnification.MagSetWindowSource(hwndMag,
|
||||||
|
new RECT(0, 0, System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width,
|
||||||
/// <summary>
|
System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height))) return;
|
||||||
/// The window is a pop-up window. The WS_CAPTION and WS_POPUPWINDOW styles must be combined to make the window menu visible.
|
|
||||||
/// </summary>
|
// 關閉宿主窗體
|
||||||
WS_POPUPWINDOW = WS_POPUP | WS_BORDER | WS_SYSMENU,
|
Magnification.MagUninitialize();
|
||||||
|
mainWinMag.Close();
|
||||||
/// <summary>The window has a sizing border.</summary>
|
}
|
||||||
WS_THICKFRAME = 0x40000,
|
|
||||||
|
#endregion
|
||||||
/// <summary>The window has a window menu on its title bar. The WS_CAPTION style must also be specified.</summary>
|
|
||||||
WS_SYSMENU = 0x80000,
|
#region 窗口截图(復刻Powerpoint)
|
||||||
|
|
||||||
/// <summary>
|
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
|
||||||
/// The window is a control that can receive the keyboard focus when the user presses the TAB key. Pressing the TAB key changes
|
static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
|
||||||
/// the keyboard focus to the next control with the WS_TABSTOP style. You can turn this style on and off to change dialog box
|
|
||||||
/// navigation. To change this style after a window has been created, use the SetWindowLong function. For user-created windows
|
public static IntPtr GetClassLongPtr(IntPtr hWnd, int nIndex) {
|
||||||
/// and modeless dialogs to work with tab stops, alter the message loop to call the IsDialogMessage function.
|
if (IntPtr.Size > 4)
|
||||||
/// </summary>
|
return GetClassLongPtr64(hWnd, nIndex);
|
||||||
WS_TABSTOP = 0x10000,
|
else
|
||||||
|
return new IntPtr(GetClassLongPtr32(hWnd, nIndex));
|
||||||
/// <summary>
|
}
|
||||||
/// The window is initially visible. This style can be turned on and off by using the ShowWindow or SetWindowPos function.
|
|
||||||
/// </summary>
|
[DllImport("user32.dll", EntryPoint = "GetClassLong")]
|
||||||
WS_VISIBLE = 0x10000000,
|
public static extern uint GetClassLongPtr32(IntPtr hWnd, int nIndex);
|
||||||
|
|
||||||
/// <summary>The window has a vertical scroll bar.</summary>
|
[DllImport("user32.dll", EntryPoint = "GetClassLongPtr")]
|
||||||
WS_VSCROLL = 0x200000,
|
public static extern IntPtr GetClassLongPtr64(IntPtr hWnd, int nIndex);
|
||||||
|
|
||||||
/// <summary>
|
[DllImport("user32.dll", EntryPoint = "EnumDesktopWindows",
|
||||||
/// The window is an overlapped window. An overlapped window has a title bar and a border. Same as the WS_OVERLAPPED style.
|
ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true)]
|
||||||
/// </summary>
|
public static extern bool EnumDesktopWindows(IntPtr hDesktop, Delegate lpEnumCallbackFunction, IntPtr lParam);
|
||||||
WS_TILED = WS_OVERLAPPED,
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
/// <summary>The window is initially minimized. Same as the WS_MINIMIZE style.</summary>
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
WS_ICONIC = WS_MINIMIZE,
|
public static extern bool IsWindowVisible(IntPtr hWnd);
|
||||||
|
|
||||||
/// <summary>The window has a sizing border. Same as the WS_THICKFRAME style.</summary>
|
[DllImport("user32.dll", EntryPoint = "GetWindowText",
|
||||||
WS_SIZEBOX = WS_THICKFRAME,
|
ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true)]
|
||||||
|
public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpWindowText, int nMaxCount);
|
||||||
/// <summary>The window is an overlapped window. Same as the WS_OVERLAPPEDWINDOW style.</summary>
|
|
||||||
WS_TILEDWINDOW = WS_OVERLAPPEDWINDOW,
|
[DllImport("user32.dll", SetLastError = true)]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
/// <summary>Same as the WS_CHILD style.</summary>
|
static extern bool PrintWindow(IntPtr hwnd, IntPtr hDC, uint nFlags);
|
||||||
WS_CHILDWINDOW = WS_CHILD,
|
|
||||||
}
|
[DllImport("user32.dll")]
|
||||||
|
private static extern bool GetWindowRect(IntPtr handle, out RECT rect);
|
||||||
public enum WindowStylesEx : uint
|
|
||||||
{
|
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||||
/// <summary>Specifies a window that accepts drag-drop files.</summary>
|
static extern int GetWindowTextLength(IntPtr hWnd);
|
||||||
WS_EX_ACCEPTFILES = 0x00000010,
|
|
||||||
|
[DllImport("user32.dll", SetLastError = true)]
|
||||||
/// <summary>Forces a top-level window onto the taskbar when the window is visible.</summary>
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
WS_EX_APPWINDOW = 0x00040000,
|
public static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
|
||||||
|
|
||||||
/// <summary>Specifies a window that has a border with a sunken edge.</summary>
|
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||||
WS_EX_CLIENTEDGE = 0x00000200,
|
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string lclassName,
|
||||||
|
string windowTitle);
|
||||||
/// <summary>
|
|
||||||
/// Specifies a window that paints all descendants in bottom-to-top painting order using double-buffering. This cannot be used if
|
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||||
/// the window has a class style of either CS_OWNDC or CS_CLASSDC. This style is not supported in Windows 2000.
|
public static extern IntPtr GetShellWindow();
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
[DllImport("dwmapi.dll")]
|
||||||
/// With WS_EX_COMPOSITED set, all descendants of a window get bottom-to-top painting order using double-buffering. Bottom-to-top
|
static extern int DwmGetWindowAttribute(IntPtr hwnd, int dwAttribute, out bool pvAttribute, int cbAttribute);
|
||||||
/// painting order allows a descendent window to have translucency (alpha) and transparency (color-key) effects, but only if the
|
|
||||||
/// descendent window also has the WS_EX_TRANSPARENT bit set. Double-buffering allows the window and its descendents to be
|
public Icon GetAppIcon(IntPtr hwnd) {
|
||||||
/// painted without flicker.
|
IntPtr iconHandle = SendMessage(hwnd, 0x7F, 2, 0);
|
||||||
/// </remarks>
|
if (iconHandle == IntPtr.Zero)
|
||||||
WS_EX_COMPOSITED = 0x02000000,
|
iconHandle = SendMessage(hwnd, 0x7F, 0, 0);
|
||||||
|
if (iconHandle == IntPtr.Zero)
|
||||||
/// <summary>
|
iconHandle = SendMessage(hwnd, 0x7F, 1, 0);
|
||||||
/// Specifies a window that includes a question mark in the title bar. When the user clicks the question mark, the cursor changes
|
if (iconHandle == IntPtr.Zero)
|
||||||
/// to a question mark with a pointer. If the user then clicks a child window, the child receives a WM_HELP message. The child
|
iconHandle = GetClassLongPtr(hwnd, -14);
|
||||||
/// window should pass the message to the parent window procedure, which should call the WinHelp function using the HELP_WM_HELP
|
if (iconHandle == IntPtr.Zero)
|
||||||
/// command. The Help application displays a pop-up window that typically contains help for the child window. WS_EX_CONTEXTHELP
|
iconHandle = GetClassLongPtr(hwnd, -34);
|
||||||
/// cannot be used with the WS_MAXIMIZEBOX or WS_MINIMIZEBOX styles.
|
if (iconHandle == IntPtr.Zero)
|
||||||
/// </summary>
|
return null;
|
||||||
WS_EX_CONTEXTHELP = 0x00000400,
|
Icon icn = System.Drawing.Icon.FromHandle(iconHandle);
|
||||||
|
return icn;
|
||||||
/// <summary>
|
}
|
||||||
/// Specifies a window which contains child windows that should take part in dialog box navigation. If this style is specified,
|
|
||||||
/// the dialog manager recurses into children of this window when performing navigation operations such as handling the TAB key,
|
public struct WindowInformation {
|
||||||
/// an arrow key, or a keyboard mnemonic.
|
public string Title { get; set; }
|
||||||
/// </summary>
|
public Bitmap WindowBitmap { get; set; }
|
||||||
WS_EX_CONTROLPARENT = 0x00010000,
|
public Icon AppIcon { get; set; }
|
||||||
|
public bool IsVisible { get; set; }
|
||||||
/// <summary>Specifies a window that has a double border.</summary>
|
public int Width { get; set; }
|
||||||
WS_EX_DLGMODALFRAME = 0x00000001,
|
public int Height { get; set; }
|
||||||
|
public RECT Rect { get; set; }
|
||||||
/// <summary>
|
public WINDOWPLACEMENT Placement { get; set; }
|
||||||
/// Specifies a window that is a layered window. This cannot be used for child windows or if the window has a class style of
|
public HWND hwnd { get; set; }
|
||||||
/// either CS_OWNDC or CS_CLASSDC.
|
}
|
||||||
/// </summary>
|
|
||||||
WS_EX_LAYERED = 0x00080000,
|
public struct WINDOWPLACEMENT {
|
||||||
|
public int length;
|
||||||
/// <summary>
|
public int flags;
|
||||||
/// Specifies a window with the horizontal origin on the right edge. Increasing horizontal values advance to the left. The shell
|
public int showCmd;
|
||||||
/// language must support reading-order alignment for this to take effect.
|
public System.Drawing.Point ptMinPosition;
|
||||||
/// </summary>
|
public System.Drawing.Point ptMaxPosition;
|
||||||
WS_EX_LAYOUTRTL = 0x00400000,
|
public System.Drawing.Rectangle rcNormalPosition;
|
||||||
|
|
||||||
/// <summary>Specifies a window that has generic left-aligned properties. This is the default.</summary>
|
public static WINDOWPLACEMENT Default {
|
||||||
WS_EX_LEFT = 0x00000000,
|
get {
|
||||||
|
WINDOWPLACEMENT result = new WINDOWPLACEMENT();
|
||||||
/// <summary>
|
result.length = Marshal.SizeOf(result);
|
||||||
/// Specifies a window with the vertical scroll bar (if present) to the left of the client area. The shell language must support
|
return result;
|
||||||
/// reading-order alignment for this to take effect.
|
}
|
||||||
/// </summary>
|
}
|
||||||
WS_EX_LEFTSCROLLBAR = 0x00004000,
|
}
|
||||||
|
|
||||||
/// <summary>Specifies a window that displays text using left-to-right reading-order properties. This is the default.</summary>
|
public delegate bool EnumDesktopWindowsDelegate(IntPtr hWnd, int lParam);
|
||||||
WS_EX_LTRREADING = 0x00000000,
|
|
||||||
|
public WindowInformation[] GetAllWindows(HWND[] excludedHwnds) {
|
||||||
/// <summary>Specifies a multiple-document interface (MDI) child window.</summary>
|
var windows = new List<WindowInformation>();
|
||||||
WS_EX_MDICHILD = 0x00000040,
|
IntPtr hShellWnd = GetShellWindow();
|
||||||
|
IntPtr hDefView = FindWindowEx(hShellWnd, IntPtr.Zero, "SHELLDLL_DefView", null);
|
||||||
/// <summary>
|
IntPtr folderView = FindWindowEx(hDefView, IntPtr.Zero, "SysListView32", null);
|
||||||
/// Specifies a top-level window created with this style does not become the foreground window when the user clicks it. The
|
IntPtr taskBar = FindWindowEx(IntPtr.Zero, IntPtr.Zero, "Shell_TrayWnd", null);
|
||||||
/// system does not bring this window to the foreground when the user minimizes or closes the foreground window. The window does
|
var excluded = new List<HWND>() {
|
||||||
/// not appear on the taskbar by default. To force the window to appear on the taskbar, use the WS_EX_APPWINDOW style. To
|
new HWND(hShellWnd), new HWND(hDefView), new HWND(folderView), new HWND(taskBar)
|
||||||
/// activate the window, use the SetActiveWindow or SetForegroundWindow function.
|
};
|
||||||
/// </summary>
|
var excludedWindowTitle = new string[] {
|
||||||
WS_EX_NOACTIVATE = 0x08000000,
|
"NVIDIA GeForce Overlay"
|
||||||
|
};
|
||||||
/// <summary>Specifies a window which does not pass its window layout to its child windows.</summary>
|
excluded.AddRange(excludedHwnds);
|
||||||
WS_EX_NOINHERITLAYOUT = 0x00100000,
|
if (!EnumDesktopWindows(IntPtr.Zero, new EnumDesktopWindowsDelegate((hwnd, param) => {
|
||||||
|
if (excluded.Contains(new HWND(hwnd))) return true;
|
||||||
/// <summary>
|
var isvisible = IsWindowVisible(hwnd);
|
||||||
/// Specifies that a child window created with this style does not send the WM_PARENTNOTIFY message to its parent window when it
|
if (!isvisible) return true;
|
||||||
/// is created or destroyed.
|
var windowLong = (int)GetWindowLongPtr(hwnd, -20);
|
||||||
/// </summary>
|
if ((windowLong & 0x00000080L) != 0) return true;
|
||||||
WS_EX_NOPARENTNOTIFY = 0x00000004,
|
DwmGetWindowAttribute(hwnd, 14, out bool isCloacked, Marshal.SizeOf(typeof(bool)));
|
||||||
|
if (isCloacked) return true;
|
||||||
/// <summary>
|
var icon = GetAppIcon(hwnd);
|
||||||
/// The window does not render to a redirection surface. This is for windows that do not have visible content or that use
|
var length = GetWindowTextLength(hwnd) + 1;
|
||||||
/// mechanisms other than surfaces to provide their visual.
|
var title = new StringBuilder(length);
|
||||||
/// </summary>
|
GetWindowText(hwnd, title, length);
|
||||||
WS_EX_NOREDIRECTIONBITMAP = 0x00200000,
|
if (title.ToString().Length == 0) return true;
|
||||||
|
// 這裡懶得做 Alt Tab窗口的校驗了,直接窗體標題黑名單
|
||||||
/// <summary>Specifies an overlapped window.</summary>
|
if (excludedWindowTitle.Contains(title.ToString())) return true;
|
||||||
WS_EX_OVERLAPPEDWINDOW = WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE,
|
RECT rect;
|
||||||
|
WINDOWPLACEMENT placement = new WINDOWPLACEMENT();
|
||||||
/// <summary>Specifies a palette window, which is a modeless dialog box that presents an array of commands.</summary>
|
GetWindowPlacement(hwnd, ref placement);
|
||||||
WS_EX_PALETTEWINDOW = WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST,
|
if (placement.showCmd == 2) return true;
|
||||||
|
GetWindowRect(hwnd, out rect);
|
||||||
/// <summary>
|
var w = rect.Width;
|
||||||
/// Specifies a window that has generic "right-aligned" properties. This depends on the window class. The shell language must
|
var h = rect.Height;
|
||||||
/// support reading-order alignment for this to take effect. Using the WS_EX_RIGHT style has the same effect as using the
|
if (w == 0 || h == 0) return true;
|
||||||
/// SS_RIGHT (static), ES_RIGHT (edit), and BS_RIGHT/BS_RIGHTBUTTON (button) control styles.
|
Bitmap bmp = new Bitmap(rect.Width, rect.Height);
|
||||||
/// </summary>
|
Graphics memoryGraphics = Graphics.FromImage(bmp);
|
||||||
WS_EX_RIGHT = 0x00001000,
|
IntPtr hdc = memoryGraphics.GetHdc();
|
||||||
|
PrintWindow(hwnd, hdc, 2);
|
||||||
/// <summary>Specifies a window with the vertical scroll bar (if present) to the right of the client area. This is the default.</summary>
|
windows.Add(new WindowInformation() {
|
||||||
WS_EX_RIGHTSCROLLBAR = 0x00000000,
|
AppIcon = icon,
|
||||||
|
Title = title.ToString(),
|
||||||
/// <summary>
|
IsVisible = isvisible,
|
||||||
/// Specifies a window that displays text using right-to-left reading-order properties. The shell language must support
|
WindowBitmap = bmp,
|
||||||
/// reading-order alignment for this to take effect.
|
Width = w,
|
||||||
/// </summary>
|
Height = h,
|
||||||
WS_EX_RTLREADING = 0x00002000,
|
Rect = rect,
|
||||||
|
Placement = placement,
|
||||||
/// <summary>
|
});
|
||||||
/// Specifies a window with a three-dimensional border style intended to be used for items that do not accept user input.
|
memoryGraphics.ReleaseHdc(hdc);
|
||||||
/// </summary>
|
return true;
|
||||||
WS_EX_STATICEDGE = 0x00020000,
|
}),
|
||||||
|
IntPtr.Zero)) return new WindowInformation[] { };
|
||||||
/// <summary>
|
return windows.ToArray();
|
||||||
/// Specifies a window that is intended to be used as a floating toolbar. A tool window has a title bar that is shorter than a
|
}
|
||||||
/// normal title bar, and the window title is drawn using a smaller font. A tool window does not appear in the taskbar or in the
|
|
||||||
/// dialog that appears when the user presses ALT+TAB. If a tool window has a system menu, its icon is not displayed on the title
|
#endregion
|
||||||
/// bar. However, you can display the system menu by right-clicking or by typing ALT+SPACE.
|
|
||||||
/// </summary>
|
private void SaveScreenShotToDesktop() {
|
||||||
WS_EX_TOOLWINDOW = 0x00000080,
|
var bitmap = GetScreenshotBitmap();
|
||||||
|
string savePath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
|
||||||
/// <summary>
|
bitmap.Save(savePath + @"\" + DateTime.Now.ToString("u").Replace(':', '-') + ".png", ImageFormat.Png);
|
||||||
/// Specifies a window that should be placed above all non-topmost windows and should stay above them, even when the window is
|
ShowNewToast("截图成功保存至【桌面" + @"\" + DateTime.Now.ToString("u").Replace(':', '-') + ".png】",
|
||||||
/// deactivated. To add or remove this style, use the SetWindowPos function.
|
MW_Toast.ToastType.Success, 3000);
|
||||||
/// </summary>
|
if (Settings.Automation.IsAutoSaveStrokesAtScreenshot) SaveInkCanvasStrokes(false, false);
|
||||||
WS_EX_TOPMOST = 0x00000008,
|
}
|
||||||
|
|
||||||
/// <summary>
|
[DllImport("user32.dll")]
|
||||||
/// Specifies a window that should not be painted until siblings beneath the window (that were created by the same thread) have
|
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
|
||||||
/// been painted. The window appears transparent because the bits of underlying sibling windows have already been painted. To
|
|
||||||
/// achieve transparency without these restrictions, use the SetWindowRgn function.
|
private void SaveFullScreenScreenshotToDesktopAutoWays(HWND[] excludedHwnds) {
|
||||||
/// </summary>
|
if (OSVersion.GetOperatingSystem() < OperatingSystem.Windows8 &&
|
||||||
WS_EX_TRANSPARENT = 0x00000020,
|
OSVersion.GetOperatingSystem() > OperatingSystem.Windows10) {
|
||||||
|
foreach (var excludedHwnd in excludedHwnds) ShowWindow(excludedHwnd.DangerousGetHandle(),0);
|
||||||
/// <summary>Specifies a window that has a border with a raised edge.</summary>
|
SaveScreenShotToDesktop();
|
||||||
WS_EX_WINDOWEDGE = 0x00000100,
|
foreach (var excludedHwnd in excludedHwnds) ShowWindow(excludedHwnd.DangerousGetHandle(),5);
|
||||||
}
|
} else SaveScreenshotToDesktopByMagnificationAPI(true,excludedHwnds, bitmap => {
|
||||||
|
string savePath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
|
||||||
public void SaveScreenshotToDesktopByMagnificationAPI(bool isExcludeMode, HWND[] hwndsList, Action<Bitmap> callbackAction) {
|
bitmap.Save(savePath + @"\" + DateTime.Now.ToString("u").Replace(':', '-') + ".png", ImageFormat.Png);
|
||||||
|
});
|
||||||
if (OSVersion.GetOperatingSystem() < OperatingSystem.Windows8 && OSVersion.GetOperatingSystem() > OperatingSystem.Windows10) return;
|
}
|
||||||
if (!Magnification.MagInitialize()) return;
|
|
||||||
|
private void SavePPTScreenshot(string fileName) {
|
||||||
// 創建宿主窗體
|
var bitmap = GetScreenshotBitmap();
|
||||||
//var mainWinMag = new Window();
|
string savePath = Settings.Automation.AutoSavedStrokesLocation + @"\Auto Saved - PPT Screenshots";
|
||||||
//mainWinMag.WindowState = WindowState.Maximized;
|
if (Settings.Automation.IsSaveScreenshotsInDateFolders) {
|
||||||
//mainWinMag.WindowStyle = WindowStyle.None;
|
savePath += @"\" + DateTime.Now.ToString("yyyy-MM-dd");
|
||||||
//mainWinMag.ResizeMode = ResizeMode.NoResize;
|
}
|
||||||
//mainWinMag.Background = new SolidColorBrush(Colors.Transparent);
|
|
||||||
//mainWinMag.AllowsTransparency = true;
|
if (fileName == null) fileName = DateTime.Now.ToString("u").Replace(":", "-");
|
||||||
//mainWinMag.Show();
|
savePath += @"\" + fileName + ".png";
|
||||||
|
if (!Directory.Exists(Path.GetDirectoryName(savePath))) {
|
||||||
var mainWin = CreateWindowEx((uint)WindowStylesEx.WS_EX_TOPMOST | (uint)WindowStylesEx.WS_EX_LAYERED, "ICCMagnificationHostWinClass",
|
Directory.CreateDirectory(Path.GetDirectoryName(savePath));
|
||||||
"ICCMagnificationHostWin",
|
}
|
||||||
(uint)WindowStyles.WS_SIZEBOX | (uint)WindowStyles.WS_SYSMENU | (uint)WindowStyles.WS_CLIPCHILDREN | (uint)WindowStyles.WS_CAPTION | (uint)WindowStyles.WS_MAXIMIZEBOX, 0, 0,
|
|
||||||
System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width,
|
bitmap.Save(savePath, ImageFormat.Png);
|
||||||
System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero,
|
if (Settings.Automation.IsAutoSaveStrokesAtScreenshot) {
|
||||||
IntPtr.Zero);
|
SaveInkCanvasStrokes(false, false);
|
||||||
|
}
|
||||||
Trace.WriteLine(mainWin);
|
}
|
||||||
|
|
||||||
//SetWindowPos(handle, new IntPtr(1), 0, 0, System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width,
|
private Bitmap GetScreenshotBitmap() {
|
||||||
// System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height, 0x0080); // SWP_HIDEWINDOW
|
Rectangle rc = System.Windows.Forms.SystemInformation.VirtualScreen;
|
||||||
//SetWindowLongPtr(handle, -20, new IntPtr((int)GetWindowLongPtr(handle, -20) | 0x00080000));
|
var bitmap = new Bitmap(rc.Width, rc.Height, PixelFormat.Format32bppArgb);
|
||||||
//SetLayeredWindowAttributes(handle,0, 255, (byte)0x2);
|
using (Graphics memoryGrahics = Graphics.FromImage(bitmap)) {
|
||||||
SetLayeredWindowAttributes(mainWin,0, 255, (byte)0x2);
|
memoryGrahics.CopyFromScreen(rc.X, rc.Y, 0, 0, rc.Size, CopyPixelOperation.SourceCopy);
|
||||||
|
}
|
||||||
// 創建放大鏡窗體(使用Win32方法)
|
|
||||||
var hwndMag = CreateWindowEx(0,"Magnifier", "ICCMagnifierWindow", (uint)WindowStyles.WS_CHILD | (uint)WindowStyles.WS_VISIBLE, 0, 0,
|
return bitmap;
|
||||||
System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width,
|
}
|
||||||
System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height, mainWin, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
|
}
|
||||||
|
|
||||||
Trace.WriteLine(hwndMag);
|
|
||||||
|
|
||||||
// 過濾窗口
|
|
||||||
var hwnds = new List<HWND> { new HWND(hwndMag) };
|
|
||||||
hwnds.AddRange(hwndsList);
|
|
||||||
if (!Magnification.MagSetWindowFilterList(new HWND(hwndMag),
|
|
||||||
isExcludeMode ? Magnification.MW_FILTERMODE.MW_FILTERMODE_EXCLUDE
|
|
||||||
: Magnification.MW_FILTERMODE.MW_FILTERMODE_INCLUDE, isExcludeMode ? hwnds.Count : hwndsList.Length, hwnds.ToArray())) return;
|
|
||||||
|
|
||||||
// 保存數據
|
|
||||||
// 不使用Callback,因為該方法已經被廢棄了
|
|
||||||
//if (!Magnification.MagSetImageScalingCallback(new HWND(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(new HWND(hwndMag),
|
|
||||||
new RECT(0, 0, System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width,
|
|
||||||
System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height))) return;
|
|
||||||
|
|
||||||
|
|
||||||
RECT rect;
|
|
||||||
GetWindowRect(hwndMag, out rect);
|
|
||||||
Bitmap bmp = new Bitmap(rect.Width, rect.Height);
|
|
||||||
Graphics memoryGraphics = Graphics.FromImage(bmp);
|
|
||||||
IntPtr hdc = memoryGraphics.GetHdc();
|
|
||||||
Trace.WriteLine("213423234234234234");
|
|
||||||
Trace.WriteLine(PrintWindow(hwndMag, hdc, 2));
|
|
||||||
Trace.WriteLine("2323232323321111111111111111111111");
|
|
||||||
|
|
||||||
|
|
||||||
// 關閉宿主窗體
|
|
||||||
if (!Magnification.MagUninitialize()) return;
|
|
||||||
DestroyWindow(mainWin);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 窗口截图(復刻Powerpoint)
|
|
||||||
|
|
||||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
|
|
||||||
static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
|
|
||||||
public static IntPtr GetClassLongPtr(IntPtr hWnd, int nIndex)
|
|
||||||
{
|
|
||||||
if (IntPtr.Size > 4)
|
|
||||||
return GetClassLongPtr64(hWnd, nIndex);
|
|
||||||
else
|
|
||||||
return new IntPtr(GetClassLongPtr32(hWnd, nIndex));
|
|
||||||
}
|
|
||||||
[DllImport("user32.dll", EntryPoint = "GetClassLong")]
|
|
||||||
public static extern uint GetClassLongPtr32(IntPtr hWnd, int nIndex);
|
|
||||||
|
|
||||||
[DllImport("user32.dll", EntryPoint = "GetClassLongPtr")]
|
|
||||||
public static extern IntPtr GetClassLongPtr64(IntPtr hWnd, int nIndex);
|
|
||||||
[DllImport("user32.dll", EntryPoint = "EnumDesktopWindows",
|
|
||||||
ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true)]
|
|
||||||
public static extern bool EnumDesktopWindows(IntPtr hDesktop, Delegate lpEnumCallbackFunction, IntPtr lParam);
|
|
||||||
[DllImport("user32.dll")]
|
|
||||||
[return: MarshalAs(UnmanagedType.Bool)]
|
|
||||||
public static extern bool IsWindowVisible(IntPtr hWnd);
|
|
||||||
[DllImport("user32.dll", EntryPoint = "GetWindowText",
|
|
||||||
ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true)]
|
|
||||||
public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpWindowText, int nMaxCount);
|
|
||||||
[DllImport("user32.dll", SetLastError = true)]
|
|
||||||
[return: MarshalAs(UnmanagedType.Bool)]
|
|
||||||
static extern bool PrintWindow(IntPtr hwnd, IntPtr hDC, uint nFlags);
|
|
||||||
[DllImport("user32.dll")]
|
|
||||||
private static extern bool GetWindowRect(IntPtr handle, out RECT rect);
|
|
||||||
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
|
||||||
static extern int GetWindowTextLength(IntPtr hWnd);
|
|
||||||
[DllImport("user32.dll", SetLastError = true)]
|
|
||||||
[return: MarshalAs(UnmanagedType.Bool)]
|
|
||||||
public static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
|
|
||||||
[DllImport("user32.dll", CharSet=CharSet.Unicode)]
|
|
||||||
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string lclassName, string windowTitle);
|
|
||||||
[DllImport("user32.dll", CharSet=CharSet.Unicode, SetLastError=true)]
|
|
||||||
public static extern IntPtr GetShellWindow();
|
|
||||||
[DllImport("dwmapi.dll")]
|
|
||||||
static extern int DwmGetWindowAttribute(IntPtr hwnd, int dwAttribute, out bool pvAttribute, int cbAttribute);
|
|
||||||
|
|
||||||
public Icon GetAppIcon(IntPtr hwnd) {
|
|
||||||
IntPtr iconHandle = SendMessage(hwnd,0x7F,2,0);
|
|
||||||
if(iconHandle == IntPtr.Zero)
|
|
||||||
iconHandle = SendMessage(hwnd,0x7F,0,0);
|
|
||||||
if(iconHandle == IntPtr.Zero)
|
|
||||||
iconHandle = SendMessage(hwnd,0x7F,1,0);
|
|
||||||
if (iconHandle == IntPtr.Zero)
|
|
||||||
iconHandle = GetClassLongPtr(hwnd, -14);
|
|
||||||
if (iconHandle == IntPtr.Zero)
|
|
||||||
iconHandle = GetClassLongPtr(hwnd, -34);
|
|
||||||
if(iconHandle == IntPtr.Zero)
|
|
||||||
return null;
|
|
||||||
Icon icn = System.Drawing.Icon.FromHandle(iconHandle);
|
|
||||||
return icn;
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct WindowInformation {
|
|
||||||
public string Title { get; set; }
|
|
||||||
public Bitmap WindowBitmap { get; set; }
|
|
||||||
public Icon AppIcon { get; set; }
|
|
||||||
public bool IsVisible { get; set; }
|
|
||||||
public int Width { get; set; }
|
|
||||||
public int Height { get; set; }
|
|
||||||
public RECT Rect { get; set; }
|
|
||||||
public WINDOWPLACEMENT Placement { get; set; }
|
|
||||||
public HWND hwnd { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct WINDOWPLACEMENT {
|
|
||||||
public int length;
|
|
||||||
public int flags;
|
|
||||||
public int showCmd;
|
|
||||||
public System.Drawing.Point ptMinPosition;
|
|
||||||
public System.Drawing.Point ptMaxPosition;
|
|
||||||
public System.Drawing.Rectangle rcNormalPosition;
|
|
||||||
public static WINDOWPLACEMENT Default {
|
|
||||||
get {
|
|
||||||
WINDOWPLACEMENT result = new WINDOWPLACEMENT();
|
|
||||||
result.length = Marshal.SizeOf( result );
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public delegate bool EnumDesktopWindowsDelegate(IntPtr hWnd, int lParam);
|
|
||||||
|
|
||||||
public WindowInformation[] GetAllWindows(HWND[] excludedHwnds) {
|
|
||||||
var windows = new List<WindowInformation>();
|
|
||||||
IntPtr hShellWnd = GetShellWindow();
|
|
||||||
IntPtr hDefView = FindWindowEx(hShellWnd, IntPtr.Zero, "SHELLDLL_DefView", null);
|
|
||||||
IntPtr folderView = FindWindowEx(hDefView, IntPtr.Zero, "SysListView32", null);
|
|
||||||
IntPtr taskBar = FindWindowEx(IntPtr.Zero, IntPtr.Zero, "Shell_TrayWnd", null);
|
|
||||||
var excluded = new List<HWND>() {
|
|
||||||
new HWND(hShellWnd), new HWND(hDefView), new HWND(folderView), new HWND(taskBar)
|
|
||||||
};
|
|
||||||
var excludedWindowTitle = new string[] {
|
|
||||||
"NVIDIA GeForce Overlay"
|
|
||||||
};
|
|
||||||
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);
|
|
||||||
if ((windowLong & 0x00000080L) != 0) return true;
|
|
||||||
DwmGetWindowAttribute(hwnd, 14, out bool isCloacked, Marshal.SizeOf(typeof(bool)));
|
|
||||||
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.Contains(title.ToString())) return true;
|
|
||||||
RECT rect;
|
|
||||||
WINDOWPLACEMENT placement = new WINDOWPLACEMENT();
|
|
||||||
GetWindowPlacement(hwnd, ref placement);
|
|
||||||
if (placement.showCmd == 2) return true;
|
|
||||||
GetWindowRect(hwnd, out rect);
|
|
||||||
var w = rect.Width;
|
|
||||||
var h = rect.Height;
|
|
||||||
if (w == 0 || h == 0) return true;
|
|
||||||
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(),
|
|
||||||
IsVisible = isvisible,
|
|
||||||
WindowBitmap = bmp,
|
|
||||||
Width = w,
|
|
||||||
Height = h,
|
|
||||||
Rect = rect,
|
|
||||||
Placement = placement,
|
|
||||||
|
|
||||||
});
|
|
||||||
memoryGraphics.ReleaseHdc(hdc);
|
|
||||||
return true;
|
|
||||||
}),
|
|
||||||
IntPtr.Zero)) return new WindowInformation[]{};
|
|
||||||
return windows.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
private void SaveScreenShotToDesktop() {
|
|
||||||
var bitmap = GetScreenshotBitmap();
|
|
||||||
string savePath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
|
|
||||||
bitmap.Save(savePath + @"\" + DateTime.Now.ToString("u").Replace(':', '-') + ".png", ImageFormat.Png);
|
|
||||||
ShowNewToast("截图成功保存至【桌面" + @"\" + DateTime.Now.ToString("u").Replace(':', '-') + ".png】", MW_Toast.ToastType.Success, 3000);
|
|
||||||
if (Settings.Automation.IsAutoSaveStrokesAtScreenshot) SaveInkCanvasStrokes(false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SavePPTScreenshot(string fileName)
|
|
||||||
{
|
|
||||||
var bitmap = GetScreenshotBitmap();
|
|
||||||
string savePath = Settings.Automation.AutoSavedStrokesLocation + @"\Auto Saved - PPT Screenshots";
|
|
||||||
if (Settings.Automation.IsSaveScreenshotsInDateFolders)
|
|
||||||
{
|
|
||||||
savePath += @"\" + DateTime.Now.ToString("yyyy-MM-dd");
|
|
||||||
}
|
|
||||||
if (fileName == null) fileName = DateTime.Now.ToString("u").Replace(":", "-");
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -1954,12 +1954,11 @@ namespace Ink_Canvas {
|
|||||||
isSettingsPaneScrollBarThumbMouseButtonDown = false;
|
isSettingsPaneScrollBarThumbMouseButtonDown = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateSettingsIndexSidebarDisplayStatus() {
|
private GroupBox[] settingsPaneGroupBoxes = new GroupBox[]{};
|
||||||
|
private Border[] jumpToBorders = new Border[]{};
|
||||||
|
|
||||||
if (Math.Truncate(SettingsAboutGroupBox.MinHeight) != Math.Truncate(SettingsPanelScrollViewer.ActualHeight))
|
private void InitSettingsPaneControls() {
|
||||||
SettingsAboutGroupBox.MinHeight = SettingsPanelScrollViewer.ActualHeight;
|
settingsPaneGroupBoxes = new GroupBox[] {
|
||||||
|
|
||||||
GroupBox[] settingsPaneGroupBoxes = new GroupBox[] {
|
|
||||||
SettingsStartupGroupBox,
|
SettingsStartupGroupBox,
|
||||||
SettingsCanvasGroupBox,
|
SettingsCanvasGroupBox,
|
||||||
SettingsGestureGroupBox,
|
SettingsGestureGroupBox,
|
||||||
@ -1972,7 +1971,7 @@ namespace Ink_Canvas {
|
|||||||
SettingsAboutGroupBox
|
SettingsAboutGroupBox
|
||||||
};
|
};
|
||||||
|
|
||||||
Border[] jumpToBorders = new Border[] {
|
jumpToBorders = new Border[] {
|
||||||
SettingsStartupJumpToGroupBoxButton,
|
SettingsStartupJumpToGroupBoxButton,
|
||||||
SettingsCanvasJumpToGroupBoxButton,
|
SettingsCanvasJumpToGroupBoxButton,
|
||||||
SettingsGestureJumpToGroupBoxButton,
|
SettingsGestureJumpToGroupBoxButton,
|
||||||
@ -1984,6 +1983,14 @@ namespace Ink_Canvas {
|
|||||||
SettingsRandWindowJumpToGroupBoxButton,
|
SettingsRandWindowJumpToGroupBoxButton,
|
||||||
SettingsAboutJumpToGroupBoxButton
|
SettingsAboutJumpToGroupBoxButton
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateSettingsIndexSidebarDisplayStatus() {
|
||||||
|
|
||||||
|
if (Math.Truncate(SettingsAboutGroupBox.MinHeight) != Math.Truncate(SettingsPanelScrollViewer.ActualHeight))
|
||||||
|
SettingsAboutGroupBox.MinHeight = SettingsPanelScrollViewer.ActualHeight;
|
||||||
|
|
||||||
|
if (settingsPaneGroupBoxes.Length == 0 || jumpToBorders.Length == 0) InitSettingsPaneControls();
|
||||||
|
|
||||||
foreach (var jtb in jumpToBorders) {
|
foreach (var jtb in jumpToBorders) {
|
||||||
jtb.BorderThickness = new Thickness(0, 0, 0, 0);
|
jtb.BorderThickness = new Thickness(0, 0, 0, 0);
|
||||||
@ -2007,14 +2014,14 @@ namespace Ink_Canvas {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SettingsPaneScrollViewer_ScrollToAnimated(double offset) {
|
private void SettingsPaneScrollViewer_ScrollToAnimated(double offset, int animateMs = 155) {
|
||||||
var sb = new Storyboard();
|
var sb = new Storyboard();
|
||||||
var ofs = SettingsPanelScrollViewer.VerticalOffset;
|
var ofs = SettingsPanelScrollViewer.VerticalOffset;
|
||||||
var animation = new DoubleAnimation
|
var animation = new DoubleAnimation
|
||||||
{
|
{
|
||||||
From = ofs,
|
From = ofs,
|
||||||
To = offset,
|
To = offset,
|
||||||
Duration = TimeSpan.FromMilliseconds(155)
|
Duration = TimeSpan.FromMilliseconds(animateMs)
|
||||||
};
|
};
|
||||||
animation.EasingFunction = new CubicEase() {
|
animation.EasingFunction = new CubicEase() {
|
||||||
EasingMode = EasingMode.EaseOut,
|
EasingMode = EasingMode.EaseOut,
|
||||||
@ -2026,73 +2033,21 @@ namespace Ink_Canvas {
|
|||||||
sb.Begin(SettingsPanelScrollViewer);
|
sb.Begin(SettingsPanelScrollViewer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SettingsStartupJumpToGroupBox(object sender, MouseButtonEventArgs e) {
|
public void SettingsJumpToGroupBox_MouseDown(object sender, MouseButtonEventArgs e) {
|
||||||
var transform = SettingsStartupGroupBox.TransformToVisual(SettingsPanelScrollViewer);
|
if (settingsPaneGroupBoxes.Length == 0 || jumpToBorders.Length == 0) InitSettingsPaneControls();
|
||||||
|
var index = SettingsJumpToGroupBoxButtonsPanel.Children.IndexOf((Border)sender);
|
||||||
|
var transform = settingsPaneGroupBoxes[index].TransformToVisual(SettingsPanelScrollViewer);
|
||||||
var position = transform.Transform(new Point(0, 0));
|
var position = transform.Transform(new Point(0, 0));
|
||||||
SettingsPaneScrollViewer_ScrollToAnimated(SettingsPanelScrollViewer.VerticalOffset + position.Y - 10);
|
SettingsPaneScrollViewer_ScrollToAnimated(SettingsPanelScrollViewer.VerticalOffset + position.Y - 10,
|
||||||
|
(int)Math.Truncate(Math.Abs(position.Y - 10) / 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SettingsCanvasJumpToGroupBox(object sender, MouseButtonEventArgs e)
|
#endregion
|
||||||
{
|
|
||||||
var transform = SettingsCanvasGroupBox.TransformToVisual(SettingsPanelScrollViewer);
|
|
||||||
var position = transform.Transform(new Point(0, 0));
|
|
||||||
SettingsPaneScrollViewer_ScrollToAnimated(SettingsPanelScrollViewer.VerticalOffset + position.Y - 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SettingsGestureJumpToGroupBox(object sender, MouseButtonEventArgs e)
|
#region Screenshot
|
||||||
{
|
|
||||||
var transform = SettingsGestureGroupBox.TransformToVisual(SettingsPanelScrollViewer);
|
|
||||||
var position = transform.Transform(new Point(0, 0));
|
|
||||||
SettingsPaneScrollViewer_ScrollToAnimated(SettingsPanelScrollViewer.VerticalOffset + position.Y - 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SettingsInkRecognitionJumpToGroupBox(object sender, MouseButtonEventArgs e)
|
private void ToggleSwitchScreenshotUsingMagnificationAPI_OnToggled(object sender, RoutedEventArgs e) {
|
||||||
{
|
|
||||||
var transform = SettingsInkRecognitionGroupBox.TransformToVisual(SettingsPanelScrollViewer);
|
|
||||||
var position = transform.Transform(new Point(0, 0));
|
|
||||||
SettingsPaneScrollViewer_ScrollToAnimated(SettingsPanelScrollViewer.VerticalOffset + position.Y - 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SettingsAppearanceJumpToGroupBox(object sender, MouseButtonEventArgs e)
|
|
||||||
{
|
|
||||||
var transform = SettingsAppearanceGroupBox.TransformToVisual(SettingsPanelScrollViewer);
|
|
||||||
var position = transform.Transform(new Point(0, 0));
|
|
||||||
SettingsPaneScrollViewer_ScrollToAnimated(SettingsPanelScrollViewer.VerticalOffset + position.Y - 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SettingsPPTJumpToGroupBox(object sender, MouseButtonEventArgs e)
|
|
||||||
{
|
|
||||||
var transform = SettingsPPTGroupBox.TransformToVisual(SettingsPanelScrollViewer);
|
|
||||||
var position = transform.Transform(new Point(0, 0));
|
|
||||||
SettingsPaneScrollViewer_ScrollToAnimated(SettingsPanelScrollViewer.VerticalOffset + position.Y - 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SettingsAdvancedJumpToGroupBox(object sender, MouseButtonEventArgs e)
|
|
||||||
{
|
|
||||||
var transform = SettingsAdvancedGroupBox.TransformToVisual(SettingsPanelScrollViewer);
|
|
||||||
var position = transform.Transform(new Point(0, 0));
|
|
||||||
SettingsPaneScrollViewer_ScrollToAnimated(SettingsPanelScrollViewer.VerticalOffset + position.Y - 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SettingsAutomationJumpToGroupBox(object sender, MouseButtonEventArgs e)
|
|
||||||
{
|
|
||||||
var transform = SettingsAutomationGroupBox.TransformToVisual(SettingsPanelScrollViewer);
|
|
||||||
var position = transform.Transform(new Point(0, 0));
|
|
||||||
SettingsPaneScrollViewer_ScrollToAnimated(SettingsPanelScrollViewer.VerticalOffset + position.Y - 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SettingsRandWindowJumpToGroupBox(object sender, MouseButtonEventArgs e)
|
|
||||||
{
|
|
||||||
var transform = SettingsRandWindowGroupBox.TransformToVisual(SettingsPanelScrollViewer);
|
|
||||||
var position = transform.Transform(new Point(0, 0));
|
|
||||||
SettingsPaneScrollViewer_ScrollToAnimated(SettingsPanelScrollViewer.VerticalOffset + position.Y - 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SettingsAboutJumpToGroupBox(object sender, MouseButtonEventArgs e)
|
|
||||||
{
|
|
||||||
var transform = SettingsAboutGroupBox.TransformToVisual(SettingsPanelScrollViewer);
|
|
||||||
var position = transform.Transform(new Point(0, 0));
|
|
||||||
SettingsPaneScrollViewer_ScrollToAnimated(SettingsPanelScrollViewer.VerticalOffset + position.Y - 10);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -126,7 +126,7 @@ namespace Ink_Canvas.Popups
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void CaptureFullScreen() {
|
private void CaptureFullScreen() {
|
||||||
mainWindow.SaveScreenshotToDesktopByMagnificationAPI(true, new HWND[] {
|
mainWindow.SaveScreenshotToDesktopByMagnificationAPIEx(true, new HWND[] {
|
||||||
new WindowInteropHelper(mainWindow).Handle,
|
new WindowInteropHelper(mainWindow).Handle,
|
||||||
new WindowInteropHelper(this).Handle,
|
new WindowInteropHelper(this).Handle,
|
||||||
}, async bitmap => {
|
}, async bitmap => {
|
||||||
|
Loading…
Reference in New Issue
Block a user