using Ink_Canvas.Helpers; using iNKORE.UI.WPF.Modern; using System; using System.Collections.ObjectModel; using System.IO; using System.Windows; using System.Windows.Controls; using System.Windows.Ink; using System.Windows.Media; using System.Diagnostics; using File = System.IO.File; using MessageBox = System.Windows.MessageBox; using System.Runtime.InteropServices; using System.Windows.Interop; using System.Windows.Controls.Primitives; using System.Drawing; using System.Threading; using System.Threading.Tasks; using Microsoft.Win32; using System.Text; using System.Windows.Documents; using Ink_Canvas.Popups; using iNKORE.UI.WPF.Modern.Controls; using System.Windows.Forms; using System.Windows.Input; using Ink_Canvas.Resources.ICCConfiguration; using Vanara.PInvoke; using Application = System.Windows.Application; using Button = System.Windows.Controls.Button; using TextBox = System.Windows.Controls.TextBox; namespace Ink_Canvas { public partial class MainWindow : PerformanceTransparentWin { protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) { base.OnPropertyChanged(e); if (e.Property.Name == nameof(Topmost) && isLoaded) { if (Topmost && Settings.Advanced.IsEnableForceFullScreen) { Trace.WriteLine("Topmost true"); SetWindowPos(new WindowInteropHelper(this).Handle, new IntPtr(-1), 0, 0, 0, 0, 0x0002|0x0040|0x0001); } else if (!Topmost && Settings.Advanced.IsEnableForceFullScreen) { Trace.WriteLine("Topmost false"); SetWindowPos(new WindowInteropHelper(this).Handle, new IntPtr(-2), 0, 0, 0, 0, 0x0002|0x0040|0x0001); } } } #region Window Initialization public MainWindow() { /* 处于画板模式内:Topmost == false / currentMode != 0 处于 PPT 放映内:BtnPPTSlideShowEnd.Visibility */ InitializeComponent(); BlackboardLeftSide.Visibility = Visibility.Collapsed; BlackboardCenterSide.Visibility = Visibility.Collapsed; BlackboardRightSide.Visibility = Visibility.Collapsed; BorderTools.Visibility = Visibility.Collapsed; BorderSettings.Visibility = Visibility.Collapsed; LeftSidePanelForPPTNavigation.Visibility = Visibility.Collapsed; RightSidePanelForPPTNavigation.Visibility = Visibility.Collapsed; BorderSettings.Margin = new Thickness(0, 0, 0, 0); TwoFingerGestureBorder.Visibility = Visibility.Collapsed; BoardTwoFingerGestureBorder.Visibility = Visibility.Collapsed; BorderDrawShape.Visibility = Visibility.Collapsed; BoardBorderDrawShape.Visibility = Visibility.Collapsed; GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed; ViewboxFloatingBar.Margin = new Thickness((SystemParameters.WorkArea.Width - 284) / 2, SystemParameters.WorkArea.Height - 60, -2000, -200); ViewboxFloatingBarMarginAnimation(100, true); try { if (File.Exists("debug.ini")) Label.Visibility = Visibility.Visible; } catch (Exception ex) { LogHelper.WriteLogToFile(ex.ToString(), LogHelper.LogType.Error); } try { if (File.Exists("Log.txt")) { var fileInfo = new FileInfo("Log.txt"); var fileSizeInKB = fileInfo.Length / 1024; if (fileSizeInKB > 512) try { File.Delete("Log.txt"); LogHelper.WriteLogToFile( "The Log.txt file has been successfully deleted. Original file size: " + fileSizeInKB + " KB", LogHelper.LogType.Info); } catch (Exception ex) { LogHelper.WriteLogToFile( ex + " | Can not delete the Log.txt file. File size: " + fileSizeInKB + " KB", LogHelper.LogType.Error); } } } catch (Exception ex) { LogHelper.WriteLogToFile(ex.ToString(), LogHelper.LogType.Error); } InitTimers(); timeMachine.OnRedoStateChanged += TimeMachine_OnRedoStateChanged; timeMachine.OnUndoStateChanged += TimeMachine_OnUndoStateChanged; inkCanvas.Strokes.StrokesChanged += StrokesOnStrokesChanged; //Microsoft.Win32.SystemEvents.UserPreferenceChanged += SystemEvents_UserPreferenceChanged; try { if (File.Exists("SpecialVersion.ini")) SpecialVersionResetToSuggestion_Click(); } catch (Exception ex) { LogHelper.WriteLogToFile(ex.ToString(), LogHelper.LogType.Error); } CheckColorTheme(true); CheckPenTypeUIState(); } #endregion #region Ink Canvas Functions private System.Windows.Media.Color Ink_DefaultColor = Colors.Red; private DrawingAttributes drawingAttributes; private void loadPenCanvas() { try { //drawingAttributes = new DrawingAttributes(); drawingAttributes = inkCanvas.DefaultDrawingAttributes; drawingAttributes.Color = Ink_DefaultColor; drawingAttributes.Height = 2.5; drawingAttributes.Width = 2.5; drawingAttributes.IsHighlighter = false; drawingAttributes.FitToCurve = Settings.Canvas.FitToCurve; inkCanvas.EditingMode = InkCanvasEditingMode.Ink; inkCanvas.DeleteKeyCommandFired += InkCanvasDeleteCommandFiredEvent; //inkCanvas.Gesture += InkCanvas_Gesture; } catch { } } private void inkCanvas_EditingModeChanged(object sender, RoutedEventArgs e) { var inkCanvas1 = sender as InkCanvas; if (inkCanvas1 == null) return; if (Settings.Canvas.IsShowCursor) { if (inkCanvas1.EditingMode == InkCanvasEditingMode.Ink || drawingShapeMode != 0) inkCanvas1.ForceCursor = true; else inkCanvas1.ForceCursor = false; } else { inkCanvas1.ForceCursor = false; } if (inkCanvas1.EditingMode == InkCanvasEditingMode.Ink) forcePointEraser = !forcePointEraser; if ((inkCanvas1.EditingMode == InkCanvasEditingMode.EraseByPoint && SelectedMode == ICCToolsEnum.EraseByGeometryMode) || (inkCanvas1.EditingMode == InkCanvasEditingMode.EraseByStroke && SelectedMode == ICCToolsEnum.EraseByStrokeMode)) { GridEraserOverlay.Visibility = Visibility.Visible; } else { GridEraserOverlay.Visibility = Visibility.Collapsed; } inkCanvas1.EditingModeInverted = inkCanvas1.EditingMode; RectangleSelectionHitTestBorder.Visibility = inkCanvas1.EditingMode == InkCanvasEditingMode.Select ? Visibility.Visible : Visibility.Collapsed; } #endregion Ink Canvas #region Definitions and Loading public static Settings Settings = new Settings(); public static ICCConfiguration SettingsV2 = new ICCConfiguration(); public static string settingsFileName = "Settings.json"; public bool isLoaded = false; [DllImport("user32.dll")] static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert); [DllImport("user32.dll")] static extern bool EnableMenuItem(IntPtr hMenu, uint uIDEnableItem, uint uEnable); [DllImport("user32.dll", SetLastError = true)] static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, UInt32 uFlags); const uint MF_BYCOMMAND = 0x00000000; const uint MF_GRAYED = 0x00000001; const uint SC_CLOSE = 0xF060; private static void PreloadIALibrary() { GC.KeepAlive(typeof(InkAnalyzer)); GC.KeepAlive(typeof(AnalysisAlternate)); GC.KeepAlive(typeof(InkDrawingNode)); var analyzer = new InkAnalyzer(); analyzer.AddStrokes(new StrokeCollection() { new Stroke(new StylusPointCollection() { new StylusPoint(114,514), new StylusPoint(191,9810), new StylusPoint(7,21), new StylusPoint(123,789), }) }); analyzer.Analyze(); } private async void Window_Loaded(object sender, RoutedEventArgs e) { loadPenCanvas(); //加载设置 LoadSettings(true); // HasNewUpdateWindow hasNewUpdateWindow = new HasNewUpdateWindow(); if (Environment.Is64BitProcess) SettingsInkRecognitionGroupBox.Visibility = Visibility.Collapsed; ThemeManager.Current.ApplicationTheme = ApplicationTheme.Light; //SystemEvents_UserPreferenceChanged(null, null); //TextBlockVersion.Text = Assembly.GetExecutingAssembly().GetName().Version.ToString(); LogHelper.WriteLogToFile("Ink Canvas Loaded", LogHelper.LogType.Event); var app = Application.Current; isLoaded = true; InitFloatingToolbarV2(); BlackBoardLeftSidePageListView.ItemsSource = blackBoardSidePageListViewObservableCollection; BlackBoardRightSidePageListView.ItemsSource = blackBoardSidePageListViewObservableCollection; BtnLeftWhiteBoardSwitchPreviousGeometry.Brush = new SolidColorBrush(System.Windows.Media.Color.FromArgb(127, 24, 24, 27)); BtnLeftWhiteBoardSwitchPreviousLabel.Opacity = 0.5; BtnRightWhiteBoardSwitchPreviousGeometry.Brush = new SolidColorBrush(System.Windows.Media.Color.FromArgb(127, 24, 24, 27)); BtnRightWhiteBoardSwitchPreviousLabel.Opacity = 0.5; BorderInkReplayToolBox.Visibility = Visibility.Collapsed; BoardBackgroundPopup.Visibility = Visibility.Collapsed; // 提前加载IA库,优化第一笔等待时间 PreloadIALibrary(); SystemEvents.DisplaySettingsChanged += SystemEventsOnDisplaySettingsChanged; if (Settings.Advanced.IsDisableCloseWindow) { // Disable close button IntPtr hwnd = new WindowInteropHelper(this).Handle; IntPtr hMenu = GetSystemMenu(hwnd, false); if (hMenu != IntPtr.Zero) { EnableMenuItem(hMenu, SC_CLOSE, MF_BYCOMMAND | MF_GRAYED); } } UpdateFloatingBarIconsLayout(); StylusInvertedListenerInit(); PenPaletteV2Init(); SelectionV2Init(); ShapeDrawingV2Init(); InitStorageManagementModule(); InitFreezeWindow(new HWND[] { new HWND(new WindowInteropHelper(this).Handle) }); UpdateIndexInfoDisplay(); SetWindowPos(new WindowInteropHelper(this).Handle, new IntPtr(-1), 0, 0, 0, 0, 0x0002|0x0040|0x0001); } private void SystemEventsOnDisplaySettingsChanged(object sender, EventArgs e) { if (!Settings.Advanced.IsEnableResolutionChangeDetection) return; ShowNotification($"检测到显示器信息变化,变为{System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width}x{System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height}"); new Thread(() => { var isFloatingBarOutsideScreen = false; var isInPPTPresentationMode = false; Dispatcher.Invoke(() => { isFloatingBarOutsideScreen = IsOutsideOfScreenHelper.IsOutsideOfScreen(ViewboxFloatingBar); isInPPTPresentationMode = BorderFloatingBarExitPPTBtn.Visibility == Visibility.Visible; }); if (isFloatingBarOutsideScreen) dpiChangedDelayAction.DebounceAction(3000, null, () => { if (!isFloatingBarFolded) { if (isInPPTPresentationMode) ViewboxFloatingBarMarginAnimation(60); else ViewboxFloatingBarMarginAnimation(100, true); } }); }).Start(); } public DelayAction dpiChangedDelayAction = new DelayAction(); private void MainWindow_OnDpiChanged(object sender, System.Windows.DpiChangedEventArgs e) { if (e.OldDpi.DpiScaleX != e.NewDpi.DpiScaleX && e.OldDpi.DpiScaleY != e.NewDpi.DpiScaleY && Settings.Advanced.IsEnableDPIChangeDetection) { ShowNotification($"系统DPI发生变化,从 {e.OldDpi.DpiScaleX}x{e.OldDpi.DpiScaleY} 变化为 {e.NewDpi.DpiScaleX}x{e.NewDpi.DpiScaleY}"); new Thread(() => { var isFloatingBarOutsideScreen = false; var isInPPTPresentationMode = false; Dispatcher.Invoke(() => { isFloatingBarOutsideScreen = IsOutsideOfScreenHelper.IsOutsideOfScreen(ViewboxFloatingBar); isInPPTPresentationMode = BorderFloatingBarExitPPTBtn.Visibility == Visibility.Visible; }); if (isFloatingBarOutsideScreen) dpiChangedDelayAction.DebounceAction(3000,null, () => { if (!isFloatingBarFolded) { if (isInPPTPresentationMode) ViewboxFloatingBarMarginAnimation(60); else ViewboxFloatingBarMarginAnimation(100, true); } }); }).Start(); } } private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) { LogHelper.WriteLogToFile("Ink Canvas closing", LogHelper.LogType.Event); if (!CloseIsFromButton) { e.Cancel = true; } if (e.Cancel) LogHelper.WriteLogToFile("Ink Canvas closing cancelled", LogHelper.LogType.Event); else { DisposeFreezeFrame(); Application.Current.Shutdown(); } } [DllImport("user32.dll", SetLastError = true)] public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint); private void MainWindow_OnSizeChanged(object sender, SizeChangedEventArgs e) { if (Settings.Advanced.IsEnableForceFullScreen) { if (isLoaded) ShowNotification( $"检测到窗口大小变化,已自动恢复到全屏:{System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width}x{System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height}(缩放比例为{System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width / SystemParameters.PrimaryScreenWidth}x{System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height / SystemParameters.PrimaryScreenHeight})"); WindowState = WindowState.Maximized; MoveWindow(new WindowInteropHelper(this).Handle, 0, 0, System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width, System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height, true); } } private void Window_Closed(object sender, EventArgs e) { SystemEvents.DisplaySettingsChanged -= SystemEventsOnDisplaySettingsChanged; LogHelper.WriteLogToFile("Ink Canvas closed", LogHelper.LogType.Event); } private async void AutoUpdate() { AvailableLatestVersion = await AutoUpdateHelper.CheckForUpdates(); if (AvailableLatestVersion != null) { var IsDownloadSuccessful = false; IsDownloadSuccessful = await AutoUpdateHelper.DownloadSetupFileAndSaveStatus(AvailableLatestVersion); if (IsDownloadSuccessful) { if (!Settings.Startup.IsAutoUpdateWithSilence) { if (MessageBox.Show("InkCanvasForClass 新版本安装包已下载完成,是否立即更新?", "InkCanvasForClass New Version Available", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes) AutoUpdateHelper.InstallNewVersionApp(AvailableLatestVersion, false); } else { timerCheckAutoUpdateWithSilence.Start(); } } } else { AutoUpdateHelper.DeleteUpdatesFolder(); } } #endregion Definations and Loading } }