From 56209d8491896fe07e84f33e2ad1504f4045680a Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sat, 6 Sep 2025 22:22:41 +0800 Subject: [PATCH 01/80] fix:issue #159 --- Ink Canvas/MainWindow_cs/MW_Timer.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Ink Canvas/MainWindow_cs/MW_Timer.cs b/Ink Canvas/MainWindow_cs/MW_Timer.cs index e9a32ba2..2bf7b9d5 100644 --- a/Ink Canvas/MainWindow_cs/MW_Timer.cs +++ b/Ink Canvas/MainWindow_cs/MW_Timer.cs @@ -240,8 +240,18 @@ namespace Ink_Canvas ShowNotification("“鸿合屏幕书写”已自动关闭"); if (Settings.Automation.IsAutoKillHiteAnnotation && Settings.Automation.IsAutoEnterAnnotationAfterKillHite) { - // 自动进入批注状态 - PenIcon_Click(null, null); + // 检查是否处于收纳状态,如果是则先展开浮动栏 + if (isFloatingBarFolded) + { + // 先展开浮动栏,然后进入批注状态 + // UnFoldFloatingBar 方法内部会根据设置自动进入批注模式 + UnFoldFloatingBar(null); + } + else + { + // 如果已经展开,直接进入批注状态 + PenIcon_Click(null, null); + } } }); } From d97a4ad2435e2d67beb8d97a6be75ca67eac0405 Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sat, 6 Sep 2025 23:21:05 +0800 Subject: [PATCH 02/80] =?UTF-8?q?fix:=E5=A2=A8=E8=BF=B9=E8=AF=86=E5=88=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/InkCanvasForClass.csproj | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Ink Canvas/InkCanvasForClass.csproj b/Ink Canvas/InkCanvasForClass.csproj index 2bf113a3..bd1e3cd7 100644 --- a/Ink Canvas/InkCanvasForClass.csproj +++ b/Ink Canvas/InkCanvasForClass.csproj @@ -24,8 +24,12 @@ false False true - Release;x86 Debug;Debug - AnyCPU;x86 + Debug;Release;x86 Debug + + + embedded + bin\$(Configuration)\ + True embedded From 076240f7cd8f57a430a06d5f8059d05f04237f51 Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sat, 6 Sep 2025 23:55:54 +0800 Subject: [PATCH 03/80] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E6=9E=84=E5=BB=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/build.yml | 234 ++++++++++++++++++++++++++++++++++++ 1 file changed, 234 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..04deec3e --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,234 @@ +name: Build and Release + +on: + push: + branches: [ main, beta ] + pull_request: + branches: [ main, beta ] + release: + types: [ published ] + +env: + DOTNET_VERSION: '4.7.2' + PROJECT_PATH: 'Ink Canvas' + INNO_SETUP_VERSION: '6.2.2' + +jobs: + build: + runs-on: windows-latest + strategy: + matrix: + include: + - platform: 'x86' + runtime: 'win-x86' + configuration: 'Release' + arch_suffix: 'x86' + - platform: 'x64' + runtime: 'win-x64' + configuration: 'Release' + arch_suffix: 'x64' + - platform: 'ARM64' + runtime: 'win-arm64' + configuration: 'Release' + arch_suffix: 'arm64' + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup .NET Framework + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '4.7.2' + + - name: Get version from project + id: get_version + run: | + $version = (Get-Content "${{ env.PROJECT_PATH }}/InkCanvasForClass.csproj" | Select-String '(.*)' | ForEach-Object { $_.Matches[0].Groups[1].Value }) + echo "version=$version" >> $env:GITHUB_OUTPUT + echo "Version: $version" + + - name: Restore NuGet packages + run: nuget restore "${{ env.PROJECT_PATH }}/InkCanvasForClass.csproj" + + - name: Build solution + run: msbuild "${{ env.PROJECT_PATH }}/InkCanvasForClass.csproj" /p:Configuration=${{ matrix.configuration }} /p:Platform=${{ matrix.platform }} /p:OutputPath=./publish/${{ matrix.platform }}/ /p:PublishUrl=./publish/${{ matrix.platform }}/ + + - name: Copy additional files + run: | + # 复制配置文件和其他必要文件 + if (Test-Path "${{ env.PROJECT_PATH }}/InkCanvasForClass.exe.config") { + Copy-Item "${{ env.PROJECT_PATH }}/InkCanvasForClass.exe.config" -Destination "./publish/${{ matrix.platform }}/" + } + # 复制Resources文件夹 + if (Test-Path "${{ env.PROJECT_PATH }}/Resources") { + Copy-Item "${{ env.PROJECT_PATH }}/Resources" -Destination "./publish/${{ matrix.platform }}/" -Recurse + } + # 复制其他必要文件 + Copy-Item "${{ env.PROJECT_PATH }}/*.dll" -Destination "./publish/${{ matrix.platform }}/" -ErrorAction SilentlyContinue + Copy-Item "${{ env.PROJECT_PATH }}/*.json" -Destination "./publish/${{ matrix.platform }}/" -ErrorAction SilentlyContinue + + - name: Install Inno Setup + if: matrix.platform != 'ARM64' + run: | + $url = "https://files.jrsoftware.org/is/6/innosetup-${{ env.INNO_SETUP_VERSION }}.exe" + $output = "innosetup.exe" + Invoke-WebRequest -Uri $url -OutFile $output + Start-Process -FilePath $output -ArgumentList "/SILENT" -Wait + echo "C:\Program Files (x86)\Inno Setup 6\ISCC.exe" >> $env:GITHUB_PATH + + - name: Create Inno Setup script for current architecture + if: matrix.platform != 'ARM64' + run: | + $scriptContent = @" +; 自动生成的 Inno Setup 脚本 +#define MyAppName "InkCanvasForClass CE" +#define MyAppVersion "${{ steps.get_version.outputs.version }}" +#define MyAppPublisher "CJK_mkp" +#define MyAppURL "https://inkcanvasforclass.github.io" +#define MyAppExeName "InkCanvasForClass.exe" +#define MyAppAssocName MyAppName + "" +#define MyAppAssocExt ".exe" +#define MyAppAssocKey StringChange(MyAppAssocName, " ", "") + MyAppAssocExt + +[Setup] +AppId={{CA801226-FD02-4C78-BCF8-753B38E70CB3} +AppName={#MyAppName} +AppVersion={#MyAppVersion} +AppPublisher={#MyAppPublisher} +AppPublisherURL={#MyAppURL} +AppSupportURL={#MyAppURL} +AppUpdatesURL={#MyAppURL} +DefaultDirName={autopf}\{#MyAppName} +UninstallDisplayIcon={app}\{#MyAppExeName} +ChangesAssociations=yes +DefaultGroupName={#MyAppName} +AllowNoIcons=yes +PrivilegesRequiredOverridesAllowed=dialog +OutputDir=./installers +OutputBaseFilename=InkCanvasForClass-CE-${{ matrix.arch_suffix }}-Setup +SolidCompression=yes +WizardStyle=modern +ArchitecturesAllowed=x86 x64compatible +ArchitecturesInstallIn64BitMode=x64compatible + +[Languages] +Name: "english"; MessagesFile: "compiler:Languages\English.isl" + +[Tasks] +Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked + +[Files] +Source: "./publish/${{ matrix.platform }}\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion +Source: "./publish/${{ matrix.platform }}\InkCanvasForClass.exe.config"; DestDir: "{app}"; Flags: ignoreversion +Source: "./publish/${{ matrix.platform }}\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs + +[Registry] +Root: HKA; Subkey: "Software\Classes\{#MyAppAssocExt}\OpenWithProgids"; ValueType: string; ValueName: "{#MyAppAssocKey}"; ValueData: ""; Flags: uninsdeletevalue +Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}"; ValueType: string; ValueName: ""; ValueData: "{#MyAppAssocName}"; Flags: uninsdeletekey +Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0" +Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1""" + +[Icons] +Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}" +Name: "{group}\{cm:ProgramOnTheWeb,{#MyAppName}}"; Filename: "{#MyAppURL}" +Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}" +Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon + +[Run] +Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent +"@ + $scriptContent | Out-File -FilePath "installer-${{ matrix.platform }}.iss" -Encoding UTF8 + + - name: Create installer using Inno Setup + if: matrix.platform != 'ARM64' + run: | + mkdir -p ./installers + iscc installer-${{ matrix.platform }}.iss + + - name: Create ARM64 portable package + if: matrix.platform == 'ARM64' + run: | + Compress-Archive -Path "./publish/${{ matrix.platform }}/*" -DestinationPath "./installers/InkCanvasForClass-CE-arm64-Portable.zip" + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: InkCanvas-${{ matrix.platform }} + path: | + ./publish/${{ matrix.platform }}/ + ./installers/ + retention-days: 30 + + create-release: + needs: build + runs-on: windows-latest + if: github.event_name == 'release' + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Download all artifacts + uses: actions/download-artifact@v4 + with: + path: ./artifacts + + - name: Get version from project + id: get_version + run: | + $version = (Get-Content "${{ env.PROJECT_PATH }}/InkCanvasForClass.csproj" | Select-String '(.*)' | ForEach-Object { $_.Matches[0].Groups[1].Value }) + echo "version=$version" >> $env:GITHUB_OUTPUT + echo "Version: $version" + + - name: Prepare release files + run: | + # 创建发布目录 + mkdir -p ./release + + # 复制x86安装包 + if (Test-Path "./artifacts/InkCanvas-x86/installers") { + Copy-Item "./artifacts/InkCanvas-x86/installers/*" -Destination "./release/" -Recurse + } + + # 复制x64安装包 + if (Test-Path "./artifacts/InkCanvas-x64/installers") { + Copy-Item "./artifacts/InkCanvas-x64/installers/*" -Destination "./release/" -Recurse + } + + # 复制ARM64便携版 + if (Test-Path "./artifacts/InkCanvas-ARM64/installers") { + Copy-Item "./artifacts/InkCanvas-ARM64/installers/*" -Destination "./release/" -Recurse + } + + # 列出所有文件 + Get-ChildItem -Path "./release" -Recurse | ForEach-Object { Write-Host "Release file: $($_.FullName)" } + + - name: Create Release + uses: softprops/action-gh-release@v1 + with: + tag_name: v${{ steps.get_version.outputs.version }} + name: InkCanvasForClass CE v${{ steps.get_version.outputs.version }} + body: | + ## InkCanvasForClass CE v${{ steps.get_version.outputs.version }} + + ### 下载 + - **x86 (32位)**: 适用于32位Windows系统 + - **x64 (64位)**: 适用于64位Windows系统 + - **ARM64**: 适用于ARM64 Windows系统(便携版) + + ### 安装说明 + 1. 下载对应您系统架构的安装包 + 2. 运行安装程序并按照提示完成安装 + 3. ARM64版本为便携版,解压后直接运行即可 + + ### 系统要求 + - Windows 7/10/11 + - .NET Framework 4.7.2 或更高版本 + + files: | + ./release/* + draft: false + prerelease: false + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file From 9da5ec7413d8c6252985df9440d66dba3125d0c0 Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sat, 6 Sep 2025 23:58:00 +0800 Subject: [PATCH 04/80] =?UTF-8?q?=E6=92=A4=E9=94=80=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/build.yml | 234 ------------------------------------ 1 file changed, 234 deletions(-) delete mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index 04deec3e..00000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,234 +0,0 @@ -name: Build and Release - -on: - push: - branches: [ main, beta ] - pull_request: - branches: [ main, beta ] - release: - types: [ published ] - -env: - DOTNET_VERSION: '4.7.2' - PROJECT_PATH: 'Ink Canvas' - INNO_SETUP_VERSION: '6.2.2' - -jobs: - build: - runs-on: windows-latest - strategy: - matrix: - include: - - platform: 'x86' - runtime: 'win-x86' - configuration: 'Release' - arch_suffix: 'x86' - - platform: 'x64' - runtime: 'win-x64' - configuration: 'Release' - arch_suffix: 'x64' - - platform: 'ARM64' - runtime: 'win-arm64' - configuration: 'Release' - arch_suffix: 'arm64' - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup .NET Framework - uses: actions/setup-dotnet@v4 - with: - dotnet-version: '4.7.2' - - - name: Get version from project - id: get_version - run: | - $version = (Get-Content "${{ env.PROJECT_PATH }}/InkCanvasForClass.csproj" | Select-String '(.*)' | ForEach-Object { $_.Matches[0].Groups[1].Value }) - echo "version=$version" >> $env:GITHUB_OUTPUT - echo "Version: $version" - - - name: Restore NuGet packages - run: nuget restore "${{ env.PROJECT_PATH }}/InkCanvasForClass.csproj" - - - name: Build solution - run: msbuild "${{ env.PROJECT_PATH }}/InkCanvasForClass.csproj" /p:Configuration=${{ matrix.configuration }} /p:Platform=${{ matrix.platform }} /p:OutputPath=./publish/${{ matrix.platform }}/ /p:PublishUrl=./publish/${{ matrix.platform }}/ - - - name: Copy additional files - run: | - # 复制配置文件和其他必要文件 - if (Test-Path "${{ env.PROJECT_PATH }}/InkCanvasForClass.exe.config") { - Copy-Item "${{ env.PROJECT_PATH }}/InkCanvasForClass.exe.config" -Destination "./publish/${{ matrix.platform }}/" - } - # 复制Resources文件夹 - if (Test-Path "${{ env.PROJECT_PATH }}/Resources") { - Copy-Item "${{ env.PROJECT_PATH }}/Resources" -Destination "./publish/${{ matrix.platform }}/" -Recurse - } - # 复制其他必要文件 - Copy-Item "${{ env.PROJECT_PATH }}/*.dll" -Destination "./publish/${{ matrix.platform }}/" -ErrorAction SilentlyContinue - Copy-Item "${{ env.PROJECT_PATH }}/*.json" -Destination "./publish/${{ matrix.platform }}/" -ErrorAction SilentlyContinue - - - name: Install Inno Setup - if: matrix.platform != 'ARM64' - run: | - $url = "https://files.jrsoftware.org/is/6/innosetup-${{ env.INNO_SETUP_VERSION }}.exe" - $output = "innosetup.exe" - Invoke-WebRequest -Uri $url -OutFile $output - Start-Process -FilePath $output -ArgumentList "/SILENT" -Wait - echo "C:\Program Files (x86)\Inno Setup 6\ISCC.exe" >> $env:GITHUB_PATH - - - name: Create Inno Setup script for current architecture - if: matrix.platform != 'ARM64' - run: | - $scriptContent = @" -; 自动生成的 Inno Setup 脚本 -#define MyAppName "InkCanvasForClass CE" -#define MyAppVersion "${{ steps.get_version.outputs.version }}" -#define MyAppPublisher "CJK_mkp" -#define MyAppURL "https://inkcanvasforclass.github.io" -#define MyAppExeName "InkCanvasForClass.exe" -#define MyAppAssocName MyAppName + "" -#define MyAppAssocExt ".exe" -#define MyAppAssocKey StringChange(MyAppAssocName, " ", "") + MyAppAssocExt - -[Setup] -AppId={{CA801226-FD02-4C78-BCF8-753B38E70CB3} -AppName={#MyAppName} -AppVersion={#MyAppVersion} -AppPublisher={#MyAppPublisher} -AppPublisherURL={#MyAppURL} -AppSupportURL={#MyAppURL} -AppUpdatesURL={#MyAppURL} -DefaultDirName={autopf}\{#MyAppName} -UninstallDisplayIcon={app}\{#MyAppExeName} -ChangesAssociations=yes -DefaultGroupName={#MyAppName} -AllowNoIcons=yes -PrivilegesRequiredOverridesAllowed=dialog -OutputDir=./installers -OutputBaseFilename=InkCanvasForClass-CE-${{ matrix.arch_suffix }}-Setup -SolidCompression=yes -WizardStyle=modern -ArchitecturesAllowed=x86 x64compatible -ArchitecturesInstallIn64BitMode=x64compatible - -[Languages] -Name: "english"; MessagesFile: "compiler:Languages\English.isl" - -[Tasks] -Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked - -[Files] -Source: "./publish/${{ matrix.platform }}\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion -Source: "./publish/${{ matrix.platform }}\InkCanvasForClass.exe.config"; DestDir: "{app}"; Flags: ignoreversion -Source: "./publish/${{ matrix.platform }}\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs - -[Registry] -Root: HKA; Subkey: "Software\Classes\{#MyAppAssocExt}\OpenWithProgids"; ValueType: string; ValueName: "{#MyAppAssocKey}"; ValueData: ""; Flags: uninsdeletevalue -Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}"; ValueType: string; ValueName: ""; ValueData: "{#MyAppAssocName}"; Flags: uninsdeletekey -Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0" -Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1""" - -[Icons] -Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}" -Name: "{group}\{cm:ProgramOnTheWeb,{#MyAppName}}"; Filename: "{#MyAppURL}" -Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}" -Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon - -[Run] -Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent -"@ - $scriptContent | Out-File -FilePath "installer-${{ matrix.platform }}.iss" -Encoding UTF8 - - - name: Create installer using Inno Setup - if: matrix.platform != 'ARM64' - run: | - mkdir -p ./installers - iscc installer-${{ matrix.platform }}.iss - - - name: Create ARM64 portable package - if: matrix.platform == 'ARM64' - run: | - Compress-Archive -Path "./publish/${{ matrix.platform }}/*" -DestinationPath "./installers/InkCanvasForClass-CE-arm64-Portable.zip" - - - name: Upload artifacts - uses: actions/upload-artifact@v4 - with: - name: InkCanvas-${{ matrix.platform }} - path: | - ./publish/${{ matrix.platform }}/ - ./installers/ - retention-days: 30 - - create-release: - needs: build - runs-on: windows-latest - if: github.event_name == 'release' - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Download all artifacts - uses: actions/download-artifact@v4 - with: - path: ./artifacts - - - name: Get version from project - id: get_version - run: | - $version = (Get-Content "${{ env.PROJECT_PATH }}/InkCanvasForClass.csproj" | Select-String '(.*)' | ForEach-Object { $_.Matches[0].Groups[1].Value }) - echo "version=$version" >> $env:GITHUB_OUTPUT - echo "Version: $version" - - - name: Prepare release files - run: | - # 创建发布目录 - mkdir -p ./release - - # 复制x86安装包 - if (Test-Path "./artifacts/InkCanvas-x86/installers") { - Copy-Item "./artifacts/InkCanvas-x86/installers/*" -Destination "./release/" -Recurse - } - - # 复制x64安装包 - if (Test-Path "./artifacts/InkCanvas-x64/installers") { - Copy-Item "./artifacts/InkCanvas-x64/installers/*" -Destination "./release/" -Recurse - } - - # 复制ARM64便携版 - if (Test-Path "./artifacts/InkCanvas-ARM64/installers") { - Copy-Item "./artifacts/InkCanvas-ARM64/installers/*" -Destination "./release/" -Recurse - } - - # 列出所有文件 - Get-ChildItem -Path "./release" -Recurse | ForEach-Object { Write-Host "Release file: $($_.FullName)" } - - - name: Create Release - uses: softprops/action-gh-release@v1 - with: - tag_name: v${{ steps.get_version.outputs.version }} - name: InkCanvasForClass CE v${{ steps.get_version.outputs.version }} - body: | - ## InkCanvasForClass CE v${{ steps.get_version.outputs.version }} - - ### 下载 - - **x86 (32位)**: 适用于32位Windows系统 - - **x64 (64位)**: 适用于64位Windows系统 - - **ARM64**: 适用于ARM64 Windows系统(便携版) - - ### 安装说明 - 1. 下载对应您系统架构的安装包 - 2. 运行安装程序并按照提示完成安装 - 3. ARM64版本为便携版,解压后直接运行即可 - - ### 系统要求 - - Windows 7/10/11 - - .NET Framework 4.7.2 或更高版本 - - files: | - ./release/* - draft: false - prerelease: false - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file From 060664260beef4c6f70ff7f2f294911334188779 Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sun, 7 Sep 2025 00:03:15 +0800 Subject: [PATCH 05/80] fix:issue #172 --- Ink Canvas/Windows/RandWindow.xaml | 8 +-- Ink Canvas/Windows/RandWindow.xaml.cs | 95 ++------------------------- 2 files changed, 9 insertions(+), 94 deletions(-) diff --git a/Ink Canvas/Windows/RandWindow.xaml b/Ink Canvas/Windows/RandWindow.xaml index 135d1dc2..f1bada9c 100644 --- a/Ink Canvas/Windows/RandWindow.xaml +++ b/Ink Canvas/Windows/RandWindow.xaml @@ -98,7 +98,7 @@ - + @@ -113,7 +113,7 @@ - + @@ -127,7 +127,7 @@ - + @@ -137,7 +137,7 @@ - + diff --git a/Ink Canvas/Windows/RandWindow.xaml.cs b/Ink Canvas/Windows/RandWindow.xaml.cs index 42c55d6f..aa391d8f 100644 --- a/Ink Canvas/Windows/RandWindow.xaml.cs +++ b/Ink Canvas/Windows/RandWindow.xaml.cs @@ -1,18 +1,16 @@ using Ink_Canvas.Helpers; +using iNKORE.UI.WPF.Modern.Controls; using Microsoft.VisualBasic; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; -using System.Runtime.InteropServices; using System.Threading; using System.Windows; using System.Windows.Input; -using System.Windows.Interop; using System.Windows.Media; using System.Windows.Media.Imaging; -using System.Windows.Threading; using MessageBox = iNKORE.UI.WPF.Modern.Controls.MessageBox; namespace Ink_Canvas @@ -26,21 +24,12 @@ namespace Ink_Canvas { InitializeComponent(); AnimationsHelper.ShowWithSlideFromBottomAndFade(this, 0.25); - BorderBtnHelp.Visibility = !settings.RandSettings.DisplayRandWindowNamesInputBtn ? Visibility.Collapsed : Visibility.Visible; + BorderBtnHelp.Visibility = settings.RandSettings.DisplayRandWindowNamesInputBtn == false ? Visibility.Collapsed : Visibility.Visible; RandMaxPeopleOneTime = settings.RandSettings.RandWindowOnceMaxStudents; RandDoneAutoCloseWaitTime = (int)settings.RandSettings.RandWindowOnceCloseLatency * 1000; // 加载背景 LoadBackground(settings); - - // 设置窗口为置顶 - Topmost = true; - - // 添加窗口关闭事件处理 - Closed += RandWindow_Closed; - - // 添加窗口显示事件处理,确保置顶 - Loaded += RandWindow_Loaded; } private void LoadBackground(Settings settings) @@ -80,22 +69,13 @@ namespace Ink_Canvas isAutoClose = IsAutoClose; PeopleControlPane.Opacity = 0.4; PeopleControlPane.IsHitTestVisible = false; - BorderBtnHelp.Visibility = !settings.RandSettings.DisplayRandWindowNamesInputBtn ? Visibility.Collapsed : Visibility.Visible; + BorderBtnHelp.Visibility = settings.RandSettings.DisplayRandWindowNamesInputBtn == false ? Visibility.Collapsed : Visibility.Visible; RandMaxPeopleOneTime = settings.RandSettings.RandWindowOnceMaxStudents; RandDoneAutoCloseWaitTime = (int)settings.RandSettings.RandWindowOnceCloseLatency * 1000; // 加载背景 LoadBackground(settings); - // 设置窗口为置顶 - Topmost = true; - - // 添加窗口关闭事件处理 - Closed += RandWindow_Closed; - - // 添加窗口显示事件处理,确保置顶 - Loaded += RandWindow_Loaded; - new Thread(() => { Thread.Sleep(100); @@ -120,7 +100,7 @@ namespace Ink_Canvas if (RandMaxPeopleOneTime != -1 && TotalCount >= RandMaxPeopleOneTime) return; TotalCount++; LabelNumberCount.Text = TotalCount.ToString(); - FontIconStart.Glyph = ""; + SymbolIconStart.Symbol = Symbol.People; BorderBtnAdd.Opacity = 1; BorderBtnMinus.Opacity = 1; } @@ -132,7 +112,7 @@ namespace Ink_Canvas LabelNumberCount.Text = TotalCount.ToString(); if (TotalCount == 1) { - FontIconStart.Glyph = ""; + SymbolIconStart.Symbol = Symbol.Contact; } } @@ -357,70 +337,5 @@ namespace Ink_Canvas MessageBox.Show("无法调用外部点名:" + ex.Message); } } - - /// - /// 窗口加载事件处理 - /// - private void RandWindow_Loaded(object sender, RoutedEventArgs e) - { - // 使用延迟确保窗口完全加载后再应用置顶 - Dispatcher.BeginInvoke(new Action(() => - { - try - { - // 强制激活窗口 - Activate(); - Focus(); - - // 设置置顶 - Topmost = true; - - // 使用Win32 API强制置顶 - var hwnd = new WindowInteropHelper(this).Handle; - if (hwnd != IntPtr.Zero) - { - const int WS_EX_TOPMOST = 0x00000008; - const int GWL_EXSTYLE = -20; - const int SWP_NOMOVE = 0x0002; - const int SWP_NOSIZE = 0x0001; - const int SWP_SHOWWINDOW = 0x0040; - const int SWP_NOOWNERZORDER = 0x0200; - var HWND_TOPMOST = new IntPtr(-1); - - // 设置窗口样式为置顶 - int exStyle = GetWindowLong(hwnd, GWL_EXSTYLE); - SetWindowLong(hwnd, GWL_EXSTYLE, exStyle | WS_EX_TOPMOST); - - // 强制置顶 - SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, - SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | SWP_NOOWNERZORDER); - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"RandWindow置顶失败: {ex.Message}", LogHelper.LogType.Error); - } - }), DispatcherPriority.Loaded); - } - - /// - /// 窗口关闭事件处理 - /// - private void RandWindow_Closed(object sender, EventArgs e) - { - // 窗口关闭时的清理工作 - // 这里可以添加必要的清理代码 - } - - #region Win32 API 声明 - [DllImport("user32.dll")] - private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); - - [DllImport("user32.dll")] - private static extern int GetWindowLong(IntPtr hWnd, int nIndex); - - [DllImport("user32.dll")] - private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); - #endregion } } From f22fd7b5d1865bd8b2fddb71e6a43a66d063cf9c Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sun, 7 Sep 2025 00:08:11 +0800 Subject: [PATCH 06/80] fix:issue #172 --- Ink Canvas/Windows/RandWindow.xaml.cs | 90 ++++++++++++++++++++++++++- 1 file changed, 88 insertions(+), 2 deletions(-) diff --git a/Ink Canvas/Windows/RandWindow.xaml.cs b/Ink Canvas/Windows/RandWindow.xaml.cs index aa391d8f..c80ed0a4 100644 --- a/Ink Canvas/Windows/RandWindow.xaml.cs +++ b/Ink Canvas/Windows/RandWindow.xaml.cs @@ -6,11 +6,14 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; +using System.Runtime.InteropServices; using System.Threading; using System.Windows; using System.Windows.Input; +using System.Windows.Interop; using System.Windows.Media; using System.Windows.Media.Imaging; +using System.Windows.Threading; using MessageBox = iNKORE.UI.WPF.Modern.Controls.MessageBox; namespace Ink_Canvas @@ -30,6 +33,15 @@ namespace Ink_Canvas // 加载背景 LoadBackground(settings); + + // 设置窗口为置顶 + Topmost = true; + + // 添加窗口关闭事件处理 + Closed += RandWindow_Closed; + + // 添加窗口显示事件处理,确保置顶 + Loaded += RandWindow_Loaded; } private void LoadBackground(Settings settings) @@ -76,6 +88,15 @@ namespace Ink_Canvas // 加载背景 LoadBackground(settings); + // 设置窗口为置顶 + Topmost = true; + + // 添加窗口关闭事件处理 + Closed += RandWindow_Closed; + + // 添加窗口显示事件处理,确保置顶 + Loaded += RandWindow_Loaded; + new Thread(() => { Thread.Sleep(100); @@ -100,7 +121,7 @@ namespace Ink_Canvas if (RandMaxPeopleOneTime != -1 && TotalCount >= RandMaxPeopleOneTime) return; TotalCount++; LabelNumberCount.Text = TotalCount.ToString(); - SymbolIconStart.Symbol = Symbol.People; + SymbolIconStart.Symbol = iNKORE.UI.WPF.Modern.Controls.Symbol.People; BorderBtnAdd.Opacity = 1; BorderBtnMinus.Opacity = 1; } @@ -112,7 +133,7 @@ namespace Ink_Canvas LabelNumberCount.Text = TotalCount.ToString(); if (TotalCount == 1) { - SymbolIconStart.Symbol = Symbol.Contact; + SymbolIconStart.Symbol = iNKORE.UI.WPF.Modern.Controls.Symbol.Contact; } } @@ -337,5 +358,70 @@ namespace Ink_Canvas MessageBox.Show("无法调用外部点名:" + ex.Message); } } + + /// + /// 窗口加载事件处理 + /// + private void RandWindow_Loaded(object sender, RoutedEventArgs e) + { + // 使用延迟确保窗口完全加载后再应用置顶 + Dispatcher.BeginInvoke(new Action(() => + { + try + { + // 强制激活窗口 + Activate(); + Focus(); + + // 设置置顶 + Topmost = true; + + // 使用Win32 API强制置顶 + var hwnd = new WindowInteropHelper(this).Handle; + if (hwnd != IntPtr.Zero) + { + const int WS_EX_TOPMOST = 0x00000008; + const int GWL_EXSTYLE = -20; + const int SWP_NOMOVE = 0x0002; + const int SWP_NOSIZE = 0x0001; + const int SWP_SHOWWINDOW = 0x0040; + const int SWP_NOOWNERZORDER = 0x0200; + var HWND_TOPMOST = new IntPtr(-1); + + // 设置窗口样式为置顶 + int exStyle = GetWindowLong(hwnd, GWL_EXSTYLE); + SetWindowLong(hwnd, GWL_EXSTYLE, exStyle | WS_EX_TOPMOST); + + // 强制置顶 + SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | SWP_NOOWNERZORDER); + } + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"RandWindow置顶失败: {ex.Message}", LogHelper.LogType.Error); + } + }), DispatcherPriority.Loaded); + } + + /// + /// 窗口关闭事件处理 + /// + private void RandWindow_Closed(object sender, EventArgs e) + { + // 窗口关闭时的清理工作 + // 这里可以添加必要的清理代码 + } + + #region Win32 API 声明 + [DllImport("user32.dll")] + private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); + + [DllImport("user32.dll")] + private static extern int GetWindowLong(IntPtr hWnd, int nIndex); + + [DllImport("user32.dll")] + private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); + #endregion } } From f67db9beed3749ccdb93df880fcba120f6e54bb6 Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sun, 7 Sep 2025 00:11:22 +0800 Subject: [PATCH 07/80] fix:issue #178 #177 --- Ink Canvas/MainWindow.xaml.cs | 6 +++--- Ink Canvas/MainWindow_cs/MW_Eraser.cs | 8 ++++++++ Ink Canvas/MainWindow_cs/MW_PPT.cs | 4 ++-- Ink Canvas/Windows/HotkeySettingsWindow.xaml.cs | 6 +++--- Ink Canvas/Windows/RandWindow.xaml.cs | 4 ++-- .../SettingsViews/SettingsViews/AboutPanel.xaml.cs | 10 +++++----- .../Windows/SettingsViews/SettingsWindow.xaml.cs | 10 +++++----- 7 files changed, 28 insertions(+), 20 deletions(-) diff --git a/Ink Canvas/MainWindow.xaml.cs b/Ink Canvas/MainWindow.xaml.cs index a02e4b1f..3462638a 100644 --- a/Ink Canvas/MainWindow.xaml.cs +++ b/Ink Canvas/MainWindow.xaml.cs @@ -2416,7 +2416,7 @@ namespace Ink_Canvas if (slider == null) return; // 捕获触摸设备 - if (e.RoutedEvent == UIElement.TouchDownEvent) + if (e.RoutedEvent == TouchDownEvent) { slider.CaptureTouch(e.TouchDevice); } @@ -2451,7 +2451,7 @@ namespace Ink_Canvas if (slider == null) return; // 捕获手写笔设备 - if (e.RoutedEvent == UIElement.StylusDownEvent) + if (e.RoutedEvent == StylusDownEvent) { slider.CaptureStylus(); } @@ -2619,7 +2619,7 @@ namespace Ink_Canvas { try { - var toggle = sender as iNKORE.UI.WPF.Modern.Controls.ToggleSwitch; + var toggle = sender as ToggleSwitch; if (toggle != null) { Settings.ModeSettings.IsPPTOnlyMode = toggle.IsOn; diff --git a/Ink Canvas/MainWindow_cs/MW_Eraser.cs b/Ink Canvas/MainWindow_cs/MW_Eraser.cs index d49cfe1a..85ee7dcf 100644 --- a/Ink Canvas/MainWindow_cs/MW_Eraser.cs +++ b/Ink Canvas/MainWindow_cs/MW_Eraser.cs @@ -750,6 +750,10 @@ namespace Ink_Canvas { overlay.CaptureMouse(); StartAdvancedEraserOperation(sender); + + // 处理单点擦除 + var position = e.GetPosition((UIElement)FindName("inkCanvas")); + UpdateAdvancedEraserPosition(sender, position); } }; @@ -787,6 +791,10 @@ namespace Ink_Canvas overlay.CaptureStylus(); } StartAdvancedEraserOperation(sender); + + // 处理单点擦除 + var position = e.GetPosition((UIElement)FindName("inkCanvas")); + UpdateAdvancedEraserPosition(sender, position); } }; diff --git a/Ink Canvas/MainWindow_cs/MW_PPT.cs b/Ink Canvas/MainWindow_cs/MW_PPT.cs index 7a9c77c0..72d4fe93 100644 --- a/Ink Canvas/MainWindow_cs/MW_PPT.cs +++ b/Ink Canvas/MainWindow_cs/MW_PPT.cs @@ -232,10 +232,10 @@ namespace Ink_Canvas pptApplication = new Microsoft.Office.Interop.PowerPoint.Application(); // 设置为不可见,作为后台进程 - pptApplication.Visible = Microsoft.Office.Core.MsoTriState.msoFalse; + pptApplication.Visible = MsoTriState.msoFalse; // 设置应用程序属性 - pptApplication.WindowState = Microsoft.Office.Interop.PowerPoint.PpWindowState.ppWindowMinimized; + pptApplication.WindowState = PpWindowState.ppWindowMinimized; // 直接设置PPTManager的PPTApplication属性,绕过COM注册问题 Task.Delay(1000).ContinueWith(_ => diff --git a/Ink Canvas/Windows/HotkeySettingsWindow.xaml.cs b/Ink Canvas/Windows/HotkeySettingsWindow.xaml.cs index bb7f41df..b6e1f3c8 100644 --- a/Ink Canvas/Windows/HotkeySettingsWindow.xaml.cs +++ b/Ink Canvas/Windows/HotkeySettingsWindow.xaml.cs @@ -66,10 +66,10 @@ namespace Ink_Canvas.Windows try { // 设置窗口启动位置为屏幕中心 - this.WindowStartupLocation = WindowStartupLocation.CenterScreen; + WindowStartupLocation = WindowStartupLocation.CenterScreen; // 确保窗口在显示时获得焦点 - this.ShowInTaskbar = true; + ShowInTaskbar = true; LogHelper.WriteLogToFile("快捷键设置窗口属性已设置"); } @@ -540,7 +540,7 @@ namespace Ink_Canvas.Windows /// /// 标题栏拖拽事件 /// - private void TitleBar_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e) + private void TitleBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { if (e.ClickCount == 2) { diff --git a/Ink Canvas/Windows/RandWindow.xaml.cs b/Ink Canvas/Windows/RandWindow.xaml.cs index c80ed0a4..bada95f6 100644 --- a/Ink Canvas/Windows/RandWindow.xaml.cs +++ b/Ink Canvas/Windows/RandWindow.xaml.cs @@ -121,7 +121,7 @@ namespace Ink_Canvas if (RandMaxPeopleOneTime != -1 && TotalCount >= RandMaxPeopleOneTime) return; TotalCount++; LabelNumberCount.Text = TotalCount.ToString(); - SymbolIconStart.Symbol = iNKORE.UI.WPF.Modern.Controls.Symbol.People; + SymbolIconStart.Symbol = Symbol.People; BorderBtnAdd.Opacity = 1; BorderBtnMinus.Opacity = 1; } @@ -133,7 +133,7 @@ namespace Ink_Canvas LabelNumberCount.Text = TotalCount.ToString(); if (TotalCount == 1) { - SymbolIconStart.Symbol = iNKORE.UI.WPF.Modern.Controls.Symbol.Contact; + SymbolIconStart.Symbol = Symbol.Contact; } } diff --git a/Ink Canvas/Windows/SettingsViews/SettingsViews/AboutPanel.xaml.cs b/Ink Canvas/Windows/SettingsViews/SettingsViews/AboutPanel.xaml.cs index 30dffb67..75dd183e 100644 --- a/Ink Canvas/Windows/SettingsViews/SettingsViews/AboutPanel.xaml.cs +++ b/Ink Canvas/Windows/SettingsViews/SettingsViews/AboutPanel.xaml.cs @@ -43,7 +43,7 @@ namespace Ink_Canvas.Windows.SettingsViews { } // 关于页面构建时间 - var buildTime = FileBuildTimeHelper.GetBuildDateTime(System.Reflection.Assembly.GetExecutingAssembly()); + var buildTime = FileBuildTimeHelper.GetBuildDateTime(Assembly.GetExecutingAssembly()); if (buildTime != null) { var bt = ((DateTimeOffset)buildTime).LocalDateTime; var m = bt.Month.ToString().PadLeft(2, '0'); @@ -69,7 +69,7 @@ namespace Ink_Canvas.Windows.SettingsViews { } public static class TouchTabletDetectHelper { - [System.Runtime.InteropServices.DllImport("user32.dll")] + [DllImport("user32.dll")] public static extern int GetSystemMetrics(int nIndex); public static bool IsTouchEnabled() @@ -84,9 +84,9 @@ namespace Ink_Canvas.Windows.SettingsViews { { public USBDeviceInfo(string deviceID, string pnpDeviceID, string description) { - this.DeviceID = deviceID; - this.PnpDeviceID = pnpDeviceID; - this.Description = description; + DeviceID = deviceID; + PnpDeviceID = pnpDeviceID; + Description = description; } public string DeviceID { get; private set; } public string PnpDeviceID { get; private set; } diff --git a/Ink Canvas/Windows/SettingsViews/SettingsWindow.xaml.cs b/Ink Canvas/Windows/SettingsViews/SettingsWindow.xaml.cs index ded95ef8..fa4b54d8 100644 --- a/Ink Canvas/Windows/SettingsViews/SettingsWindow.xaml.cs +++ b/Ink Canvas/Windows/SettingsViews/SettingsWindow.xaml.cs @@ -237,14 +237,14 @@ namespace Ink_Canvas.Windows { public ImageSource IconSource { get; set; } public bool Selected { get; set; } public Visibility _spVisibility { - get => this.Type == SidebarItemType.Separator ? Visibility.Visible : Visibility.Collapsed; + get => Type == SidebarItemType.Separator ? Visibility.Visible : Visibility.Collapsed; } public Visibility _siVisibility { - get => this.Type == SidebarItemType.Item ? Visibility.Visible : Visibility.Collapsed; + get => Type == SidebarItemType.Item ? Visibility.Visible : Visibility.Collapsed; } public SolidColorBrush _siBackground { - get => this.Selected + get => Selected ? new SolidColorBrush(Color.FromRgb(217, 217, 217)) : new SolidColorBrush(Colors.Transparent); } @@ -622,7 +622,7 @@ namespace Ink_Canvas.Windows { catch (Exception ex) { // 记录错误但不影响程序运行 - System.Diagnostics.Debug.WriteLine($"添加自定义滑块触摸支持时出错: {ex.Message}"); + Debug.WriteLine($"添加自定义滑块触摸支持时出错: {ex.Message}"); } } @@ -930,7 +930,7 @@ namespace Ink_Canvas.Windows { } catch (Exception ex) { - System.Diagnostics.Debug.WriteLine($"更新自定义滑块值时出错: {ex.Message}"); + Debug.WriteLine($"更新自定义滑块值时出错: {ex.Message}"); } } From a725a12d25438939342e34f8ac6386dd611ab4d7 Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sun, 7 Sep 2025 00:14:59 +0800 Subject: [PATCH 08/80] fix:issue #169 --- Ink Canvas/MainWindow_cs/MW_PPT.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Ink Canvas/MainWindow_cs/MW_PPT.cs b/Ink Canvas/MainWindow_cs/MW_PPT.cs index 72d4fe93..1a6a86fe 100644 --- a/Ink Canvas/MainWindow_cs/MW_PPT.cs +++ b/Ink Canvas/MainWindow_cs/MW_PPT.cs @@ -448,6 +448,8 @@ namespace Ink_Canvas if (!Settings.PowerPointSettings.EnablePPTButtonLongPressPageTurn) return; _isLongPressNext = isNext; + // 重置定时器间隔为初始延迟时间,确保每次长按检测都从正确的延迟开始 + _longPressTimer.Interval = TimeSpan.FromMilliseconds(LongPressDelay); _longPressTimer?.Start(); } From 8c1d3c024839b2487077d82b3ee094d3cc0e421a Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sun, 7 Sep 2025 00:20:48 +0800 Subject: [PATCH 09/80] fix:issue #168 --- Ink Canvas/MainWindow.xaml.cs | 8 +++++++- Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs | 15 +++++++++++---- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/Ink Canvas/MainWindow.xaml.cs b/Ink Canvas/MainWindow.xaml.cs index 3462638a..722b6456 100644 --- a/Ink Canvas/MainWindow.xaml.cs +++ b/Ink Canvas/MainWindow.xaml.cs @@ -2178,7 +2178,7 @@ namespace Ink_Canvas { if (Settings.PowerPointSettings.ShowGestureButtonInSlideShow) { - // 如果启用了PPT放映模式显示手势按钮,则显示手势按钮(在PPT模式下不依赖手势功能是否启用) + // 如果启用了PPT放映模式显示手势按钮,则检查是否在批注模式下显示手势按钮 CheckEnableTwoFingerGestureBtnVisibility(true); } else @@ -2322,6 +2322,12 @@ namespace Ink_Canvas _globalHotkeyManager.UpdateHotkeyStateForToolMode(isMouseMode); } + // 在PPT放映模式下,工具模式切换时需要更新手势按钮的显示状态 + if (BtnPPTSlideShowEnd.Visibility == Visibility.Visible) + { + UpdateGestureButtonVisibilityInPPTMode(); + } + // 执行额外的操作(如果有) additionalActions?.Invoke(); diff --git a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs index de865548..8afa8670 100644 --- a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs +++ b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs @@ -130,11 +130,11 @@ namespace Ink_Canvas /// private void CheckEnableTwoFingerGestureBtnVisibility(bool isVisible) { - // 在PPT模式下根据设置决定是否显示手势按钮 - if (currentMode == 0 || BtnPPTSlideShowEnd.Visibility == Visibility.Visible) + // 在PPT放映模式下根据设置决定是否显示手势按钮 + if (BtnPPTSlideShowEnd.Visibility == Visibility.Visible) { - // 如果启用了PPT放映模式显示手势按钮,则显示手势按钮(在PPT模式下不依赖手势功能是否启用) - if (Settings.PowerPointSettings.ShowGestureButtonInSlideShow && isVisible) + // 如果启用了PPT放映模式显示手势按钮,且当前处于批注模式,则显示手势按钮 + if (Settings.PowerPointSettings.ShowGestureButtonInSlideShow && isVisible && inkCanvas.EditingMode == InkCanvasEditingMode.Ink) { EnableTwoFingerGestureBorder.Visibility = Visibility.Visible; } @@ -145,6 +145,13 @@ namespace Ink_Canvas return; } + // 在屏幕模式(非放映模式)下,不显示手势按钮 + if (currentMode == 0) + { + EnableTwoFingerGestureBorder.Visibility = Visibility.Collapsed; + return; + } + if (StackPanelCanvasControls.Visibility != Visibility.Visible || BorderFloatingBarMainControls.Visibility != Visibility.Visible) { From 1ef56033fbf17ebb3f5cf10de094c43d5cf73edf Mon Sep 17 00:00:00 2001 From: PrefacedCorg <1876568293@qq.com> Date: Sun, 7 Sep 2025 00:31:22 +0800 Subject: [PATCH 10/80] =?UTF-8?q?=E8=B4=A1=E7=8C=AE=E5=90=8D=E5=8D=95add?= =?UTF-8?q?=20PrefacedCorg=EF=BC=881=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/InkCanvasForClass.csproj | 1 + .../Resources/DeveloperAvatars/PrefacedCorg.jpg | Bin 0 -> 45481 bytes 2 files changed, 1 insertion(+) create mode 100644 Ink Canvas/Resources/DeveloperAvatars/PrefacedCorg.jpg diff --git a/Ink Canvas/InkCanvasForClass.csproj b/Ink Canvas/InkCanvasForClass.csproj index bd1e3cd7..9bbef5ac 100644 --- a/Ink Canvas/InkCanvasForClass.csproj +++ b/Ink Canvas/InkCanvasForClass.csproj @@ -252,6 +252,7 @@ + diff --git a/Ink Canvas/Resources/DeveloperAvatars/PrefacedCorg.jpg b/Ink Canvas/Resources/DeveloperAvatars/PrefacedCorg.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7df28e3da484d48b9147fafeb89cb0fada5236f8 GIT binary patch literal 45481 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

hp>?0s3A(Wy~8VEuA!3##0dgWTGzYX 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 literal 0 HcmV?d00001 From 42ce58db60688240bc46a591545bcd4c433244e7 Mon Sep 17 00:00:00 2001 From: PrefacedCorg <1876568293@qq.com> Date: Sun, 7 Sep 2025 00:47:30 +0800 Subject: [PATCH 11/80] =?UTF-8?q?=E8=B4=A1=E7=8C=AE=E5=90=8D=E5=8D=95add?= =?UTF-8?q?=20PrefacedCorg=EF=BC=882=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/MainWindow.xaml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Ink Canvas/MainWindow.xaml b/Ink Canvas/MainWindow.xaml index d918730f..8600a838 100644 --- a/Ink Canvas/MainWindow.xaml +++ b/Ink Canvas/MainWindow.xaml @@ -3295,6 +3295,21 @@ Alan-CRL + + + + + + + + PrefacedCorg + + Date: Sun, 7 Sep 2025 00:49:01 +0800 Subject: [PATCH 12/80] =?UTF-8?q?=E5=A5=BD=E5=83=8F=E6=94=B9=E9=94=99?= =?UTF-8?q?=E4=BA=86=EF=BC=88=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/MainWindow.xaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Ink Canvas/MainWindow.xaml b/Ink Canvas/MainWindow.xaml index 8600a838..2f937cf3 100644 --- a/Ink Canvas/MainWindow.xaml +++ b/Ink Canvas/MainWindow.xaml @@ -3295,7 +3295,7 @@ Alan-CRL - Date: Sun, 7 Sep 2025 00:49:10 +0800 Subject: [PATCH 13/80] fix:issue #170 --- Ink Canvas/MainWindow.xaml.cs | 12 ++++++---- .../MainWindow_cs/MW_ClipboardHandler.cs | 5 +++++ .../MainWindow_cs/MW_ElementsControls.cs | 5 +++++ .../MainWindow_cs/MW_FloatingBarIcons.cs | 22 +++++++++++++++++++ Ink Canvas/MainWindow_cs/MW_ImageInsert.cs | 5 +++++ .../MainWindow_cs/MW_SelectionGestures.cs | 11 ++++++++-- Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs | 7 ++++++ 7 files changed, 61 insertions(+), 6 deletions(-) diff --git a/Ink Canvas/MainWindow.xaml.cs b/Ink Canvas/MainWindow.xaml.cs index 722b6456..000ded77 100644 --- a/Ink Canvas/MainWindow.xaml.cs +++ b/Ink Canvas/MainWindow.xaml.cs @@ -1032,12 +1032,16 @@ namespace Ink_Canvas // 如果当前有选中的元素,取消选中状态 if (currentSelectedElement != null) { - // 保存当前编辑模式 - var previousEditingMode = inkCanvas.EditingMode; + // 取消选中元素 UnselectElement(currentSelectedElement); - // 恢复编辑模式 - inkCanvas.EditingMode = previousEditingMode; currentSelectedElement = null; + + // 重置为选择模式,确保用户可以继续选择其他元素 + SetCurrentToolMode(InkCanvasEditingMode.Select); + // 更新模式缓存 + UpdateCurrentToolMode("select"); + // 刷新浮动栏高光显示 + SetFloatingBarHighlightPosition("select"); } } } diff --git a/Ink Canvas/MainWindow_cs/MW_ClipboardHandler.cs b/Ink Canvas/MainWindow_cs/MW_ClipboardHandler.cs index 7ff64b76..7d07d991 100644 --- a/Ink Canvas/MainWindow_cs/MW_ClipboardHandler.cs +++ b/Ink Canvas/MainWindow_cs/MW_ClipboardHandler.cs @@ -205,6 +205,11 @@ namespace Ink_Canvas // 提交到历史记录 timeMachine.CommitElementInsertHistory(image); + // 插入图片后切换到选择模式并刷新浮动栏高光显示 + SetCurrentToolMode(InkCanvasEditingMode.Select); + UpdateCurrentToolMode("select"); + HideSubPanels("select"); + ShowNotification("图片已从剪贴板粘贴"); } catch (Exception ex) diff --git a/Ink Canvas/MainWindow_cs/MW_ElementsControls.cs b/Ink Canvas/MainWindow_cs/MW_ElementsControls.cs index 1e356ec7..7b1440de 100644 --- a/Ink Canvas/MainWindow_cs/MW_ElementsControls.cs +++ b/Ink Canvas/MainWindow_cs/MW_ElementsControls.cs @@ -68,6 +68,11 @@ namespace Ink_Canvas }; timeMachine.CommitElementInsertHistory(image); + + // 插入图片后切换到选择模式并刷新浮动栏高光显示 + SetCurrentToolMode(InkCanvasEditingMode.Select); + UpdateCurrentToolMode("select"); + HideSubPanels("select"); } } } diff --git a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs index 8afa8670..74bfcddc 100644 --- a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs +++ b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs @@ -1851,6 +1851,13 @@ namespace Ink_Canvas ((Panel)lastBorderMouseDownObject).Background = new SolidColorBrush(Colors.Transparent); if (sender == Pen_Icon && lastBorderMouseDownObject != Pen_Icon) return; + // 如果当前有选中的图片元素,先取消选中 + if (currentSelectedElement != null) + { + UnselectElement(currentSelectedElement); + currentSelectedElement = null; + } + // 禁用高级橡皮擦系统 DisableAdvancedEraserSystem(); @@ -3099,6 +3106,11 @@ namespace Ink_Canvas } timeMachine.CommitElementInsertHistory(image); + + // 插入图片后切换到选择模式并刷新浮动栏高光显示 + SetCurrentToolMode(InkCanvasEditingMode.Select); + UpdateCurrentToolMode("select"); + HideSubPanels("select"); } } } @@ -3165,6 +3177,11 @@ namespace Ink_Canvas } timeMachine.CommitElementInsertHistory(image); + + // 插入图片后切换到选择模式并刷新浮动栏高光显示 + SetCurrentToolMode(InkCanvasEditingMode.Select); + UpdateCurrentToolMode("select"); + HideSubPanels("select"); } } } @@ -3231,6 +3248,11 @@ namespace Ink_Canvas } timeMachine.CommitElementInsertHistory(image); + + // 插入图片后切换到选择模式并刷新浮动栏高光显示 + SetCurrentToolMode(InkCanvasEditingMode.Select); + UpdateCurrentToolMode("select"); + HideSubPanels("select"); } } } diff --git a/Ink Canvas/MainWindow_cs/MW_ImageInsert.cs b/Ink Canvas/MainWindow_cs/MW_ImageInsert.cs index 9e7c89d5..6c77b485 100644 --- a/Ink Canvas/MainWindow_cs/MW_ImageInsert.cs +++ b/Ink Canvas/MainWindow_cs/MW_ImageInsert.cs @@ -216,6 +216,11 @@ namespace Ink_Canvas // 提交历史记录 timeMachine.CommitElementInsertHistory(image); + // 插入图片后切换到选择模式并刷新浮动栏高光显示 + SetCurrentToolMode(InkCanvasEditingMode.Select); + UpdateCurrentToolMode("select"); + HideSubPanels("select"); + ShowNotification("截图已插入到画布"); } catch (Exception ex) diff --git a/Ink Canvas/MainWindow_cs/MW_SelectionGestures.cs b/Ink Canvas/MainWindow_cs/MW_SelectionGestures.cs index e3ea3b83..1b6acdcf 100644 --- a/Ink Canvas/MainWindow_cs/MW_SelectionGestures.cs +++ b/Ink Canvas/MainWindow_cs/MW_SelectionGestures.cs @@ -336,7 +336,7 @@ namespace Ink_Canvas { var borderLeft = (inkCanvas.GetSelectionBounds().Left + inkCanvas.GetSelectionBounds().Right - BorderStrokeSelectionControlWidth) / 2; - var borderTop = inkCanvas.GetSelectionBounds().Bottom + 1; + var borderTop = inkCanvas.GetSelectionBounds().Bottom + 10; // 在墨迹下方10像素处显示 if (borderLeft < 0) borderLeft = 0; if (borderTop < 0) borderTop = 0; if (Width - borderLeft < BorderStrokeSelectionControlWidth || double.IsNaN(borderLeft)) @@ -344,7 +344,14 @@ namespace Ink_Canvas if (Height - borderTop < BorderStrokeSelectionControlHeight || double.IsNaN(borderTop)) borderTop = Height - BorderStrokeSelectionControlHeight; - if (borderTop > 60) borderTop -= 60; + // 确保墨迹选中栏始终显示在墨迹下方 + // 如果选中栏会超出屏幕底部,则显示在墨迹上方 + if (borderTop + BorderStrokeSelectionControlHeight > Height) + { + borderTop = inkCanvas.GetSelectionBounds().Top - BorderStrokeSelectionControlHeight - 10; + if (borderTop < 0) borderTop = 10; // 如果上方也没有空间,则显示在顶部 + } + BorderStrokeSelectionControl.Margin = new Thickness(borderLeft, borderTop, 0, 0); } diff --git a/Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs b/Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs index 9cc3731b..d2675fa9 100644 --- a/Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs +++ b/Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs @@ -118,6 +118,13 @@ namespace Ink_Canvas private void BtnPen_Click(object sender, RoutedEventArgs e) { + // 如果当前有选中的图片元素,先取消选中 + if (currentSelectedElement != null) + { + UnselectElement(currentSelectedElement); + currentSelectedElement = null; + } + // 禁用高级橡皮擦系统 DisableAdvancedEraserSystem(); From adc22441fcef439b5432eaeda284a202f1b23257 Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sun, 7 Sep 2025 00:57:48 +0800 Subject: [PATCH 14/80] fix:issue #173 --- Ink Canvas/MainWindow.xaml | 1 + .../MainWindow_cs/MW_SelectionGestures.cs | 61 ++++++++++++++++++- 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/Ink Canvas/MainWindow.xaml b/Ink Canvas/MainWindow.xaml index 2f937cf3..fbf15d34 100644 --- a/Ink Canvas/MainWindow.xaml +++ b/Ink Canvas/MainWindow.xaml @@ -3412,6 +3412,7 @@ 0) + { + isStrokeDragging = true; + strokeDragStartPoint = e.GetPosition(inkCanvas); + GridInkCanvasSelectionCover.CaptureMouse(); + GridInkCanvasSelectionCover.Cursor = Cursors.SizeAll; + } + } + + private void GridInkCanvasSelectionCover_MouseMove(object sender, MouseEventArgs e) + { + if (!isGridInkCanvasSelectionCoverMouseDown) return; + + // 如果正在拖动墨迹,执行拖动操作 + if (isStrokeDragging && GridInkCanvasSelectionCover.IsMouseCaptured) + { + var currentPoint = e.GetPosition(inkCanvas); + var delta = currentPoint - strokeDragStartPoint; + + // 创建变换矩阵 + var matrix = new Matrix(); + matrix.Translate(delta.X, delta.Y); + + // 对选中的墨迹应用变换 + var selectedStrokes = inkCanvas.GetSelectedStrokes(); + foreach (var stroke in selectedStrokes) + { + stroke.Transform(matrix, false); + } + + // 更新选中栏位置 + updateBorderStrokeSelectionControlLocation(); + + // 更新起始点 + strokeDragStartPoint = currentPoint; + } + else if (inkCanvas.GetSelectedStrokes().Count > 0) + { + // 当鼠标在选中区域移动时,更新墨迹选中栏位置 + updateBorderStrokeSelectionControlLocation(); + } } private void GridInkCanvasSelectionCover_MouseUp(object sender, MouseButtonEventArgs e) { if (!isGridInkCanvasSelectionCoverMouseDown) return; + + // 结束墨迹拖动 + if (isStrokeDragging) + { + isStrokeDragging = false; + GridInkCanvasSelectionCover.ReleaseMouseCapture(); + GridInkCanvasSelectionCover.Cursor = Cursors.Arrow; + } + isGridInkCanvasSelectionCoverMouseDown = false; - GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed; + + // 只有在没有选中墨迹时才隐藏选中栏 + if (inkCanvas.GetSelectedStrokes().Count == 0) + { + GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed; + } } private void BtnSelect_Click(object sender, RoutedEventArgs e) From 5b457f2a8ad8b017e4f2c3f9324c2ce3ed19023b Mon Sep 17 00:00:00 2001 From: PrefacedCorg <1876568293@qq.com> Date: Sun, 7 Sep 2025 00:59:24 +0800 Subject: [PATCH 15/80] =?UTF-8?q?=E5=B0=86=E6=8F=92=E4=BB=B6=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E5=99=A8=E7=9A=84=E9=A1=B5=E9=9D=A2=E6=94=B9=E4=B8=BA?= =?UTF-8?q?=E6=97=A0=E8=BE=B9=E6=A1=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/Windows/PluginSettingsWindow.xaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Ink Canvas/Windows/PluginSettingsWindow.xaml b/Ink Canvas/Windows/PluginSettingsWindow.xaml index 776a2b1a..e0dd96f7 100644 --- a/Ink Canvas/Windows/PluginSettingsWindow.xaml +++ b/Ink Canvas/Windows/PluginSettingsWindow.xaml @@ -6,6 +6,7 @@ xmlns:ui="http://schemas.inkore.net/lib/ui/wpf/modern" xmlns:local="clr-namespace:Ink_Canvas.Windows" mc:Ignorable="d" + WindowStyle="None" Title="插件管理" Height="550" Width="800" WindowStartupLocation="CenterScreen" ResizeMode="CanResize" From d4c4fcfd749402ed6f17edbf3d6fe80c45d9cacc Mon Sep 17 00:00:00 2001 From: PrefacedCorg <1876568293@qq.com> Date: Sun, 7 Sep 2025 01:02:34 +0800 Subject: [PATCH 16/80] Update PluginSettingsWindow.xaml --- Ink Canvas/Windows/PluginSettingsWindow.xaml | 1 - 1 file changed, 1 deletion(-) diff --git a/Ink Canvas/Windows/PluginSettingsWindow.xaml b/Ink Canvas/Windows/PluginSettingsWindow.xaml index e0dd96f7..46ed420f 100644 --- a/Ink Canvas/Windows/PluginSettingsWindow.xaml +++ b/Ink Canvas/Windows/PluginSettingsWindow.xaml @@ -10,7 +10,6 @@ Title="插件管理" Height="550" Width="800" WindowStartupLocation="CenterScreen" ResizeMode="CanResize" - WindowStyle="None" AllowsTransparency="True" Background="#F9F9F9"> From a034f7a9a00e1bc494f587e1e4ea6ffc53111eb3 Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sun, 7 Sep 2025 01:16:27 +0800 Subject: [PATCH 17/80] =?UTF-8?q?improve:=E5=A2=A8=E8=BF=B9=E9=80=89?= =?UTF-8?q?=E6=8B=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MainWindow_cs/MW_SelectionGestures.cs | 53 +++++++++++++++++-- 1 file changed, 48 insertions(+), 5 deletions(-) diff --git a/Ink Canvas/MainWindow_cs/MW_SelectionGestures.cs b/Ink Canvas/MainWindow_cs/MW_SelectionGestures.cs index 9fb2598e..c648ba05 100644 --- a/Ink Canvas/MainWindow_cs/MW_SelectionGestures.cs +++ b/Ink Canvas/MainWindow_cs/MW_SelectionGestures.cs @@ -262,13 +262,31 @@ namespace Ink_Canvas { isGridInkCanvasSelectionCoverMouseDown = true; - // 立即开始墨迹拖动 + // 检查是否有选中的墨迹 if (inkCanvas.GetSelectedStrokes().Count > 0) { - isStrokeDragging = true; - strokeDragStartPoint = e.GetPosition(inkCanvas); - GridInkCanvasSelectionCover.CaptureMouse(); - GridInkCanvasSelectionCover.Cursor = Cursors.SizeAll; + // 获取鼠标点击位置 + var clickPoint = e.GetPosition(inkCanvas); + var selectionBounds = inkCanvas.GetSelectionBounds(); + + // 检查点击位置是否在选择框边界内 + if (clickPoint.X >= selectionBounds.Left && + clickPoint.X <= selectionBounds.Right && + clickPoint.Y >= selectionBounds.Top && + clickPoint.Y <= selectionBounds.Bottom) + { + // 只有在选择框边界内才允许拖动 + isStrokeDragging = true; + strokeDragStartPoint = clickPoint; + GridInkCanvasSelectionCover.CaptureMouse(); + GridInkCanvasSelectionCover.Cursor = Cursors.SizeAll; + } + else + { + // 点击在选择框外,取消选择 + inkCanvas.Select(new StrokeCollection()); + GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed; + } } } @@ -516,6 +534,31 @@ namespace Ink_Canvas centerPoint = touchPoint.Position; lastTouchPointOnGridInkCanvasCover = touchPoint.Position; + // 检查是否有选中的墨迹 + if (inkCanvas.GetSelectedStrokes().Count > 0) + { + // 获取触摸点位置 + var touchPosition = e.GetTouchPoint(inkCanvas).Position; + var selectionBounds = inkCanvas.GetSelectionBounds(); + + // 检查触摸位置是否在选择框边界内 + if (touchPosition.X >= selectionBounds.Left && + touchPosition.X <= selectionBounds.Right && + touchPosition.Y >= selectionBounds.Top && + touchPosition.Y <= selectionBounds.Bottom) + { + // 只有在选择框边界内才允许拖动 + // 这里可以添加触摸拖动的逻辑 + } + else + { + // 触摸在选择框外,取消选择 + inkCanvas.Select(new StrokeCollection()); + GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed; + return; + } + } + if (isStrokeSelectionCloneOn) { var strokes = inkCanvas.GetSelectedStrokes(); From 938ca7c0ea41e57482f426602f5aa25ab023a77c Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sun, 7 Sep 2025 01:22:46 +0800 Subject: [PATCH 18/80] =?UTF-8?q?improve:=E5=A2=A8=E8=BF=B9=E9=80=89?= =?UTF-8?q?=E6=8B=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/MainWindow.xaml | 10 +- .../MainWindow_cs/MW_ElementsControls.cs | 34 +++--- .../MainWindow_cs/MW_SelectionGestures.cs | 107 ++++++++++++++---- 3 files changed, 108 insertions(+), 43 deletions(-) diff --git a/Ink Canvas/MainWindow.xaml b/Ink Canvas/MainWindow.xaml index fbf15d34..0be882df 100644 --- a/Ink Canvas/MainWindow.xaml +++ b/Ink Canvas/MainWindow.xaml @@ -3418,10 +3418,12 @@ ManipulationStarting="GridInkCanvasSelectionCover_ManipulationStarting" ManipulationCompleted="GridInkCanvasSelectionCover_ManipulationCompleted" ManipulationDelta="GridInkCanvasSelectionCover_ManipulationDelta" - PreviewTouchDown="GridInkCanvasSelectionCover_PreviewTouchDown" - PreviewTouchUp="GridInkCanvasSelectionCover_PreviewTouchUp" - TouchDown="GridInkCanvasSelectionCover_TouchDown" - TouchUp="GridInkCanvasSelectionCover_TouchUp" + PreviewTouchDown="GridInkCanvasSelectionCover_PreviewTouchDown" + PreviewTouchUp="GridInkCanvasSelectionCover_PreviewTouchUp" + PreviewTouchMove="GridInkCanvasSelectionCover_PreviewTouchMove" + TouchDown="GridInkCanvasSelectionCover_TouchDown" + TouchUp="GridInkCanvasSelectionCover_TouchUp" + TouchMove="GridInkCanvasSelectionCover_TouchMove" Background="#01FFFFFF" Opacity="0.01" Visibility="Visible" Margin="1,0,-1,0" /> 0) + { + // 有墨迹被选中,清除图片选择状态 + if (currentSelectedElement != null) + { + currentSelectedElement = null; + // 隐藏图片选择工具栏 + if (BorderImageSelectionControl != null) + { + BorderImageSelectionControl.Visibility = Visibility.Collapsed; + } + } + + // 显示墨迹选择栏 + GridInkCanvasSelectionCover.Visibility = Visibility.Visible; + BorderStrokeSelectionClone.Background = Brushes.Transparent; + isStrokeSelectionCloneOn = false; + updateBorderStrokeSelectionControlLocation(); + return; + } + + // 检查是否有图片元素被选中(通过InkCanvas的选中元素) var selectedElements = inkCanvas.GetSelectedElements(); bool hasImageElement = selectedElements.Any(element => element is Image); @@ -394,17 +416,15 @@ namespace Ink_Canvas return; } - if (inkCanvas.GetSelectedStrokes().Count == 0) + // 检查是否有图片元素被选中(通过currentSelectedElement) + if (currentSelectedElement != null && currentSelectedElement is Image) { GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed; + return; } - else - { - GridInkCanvasSelectionCover.Visibility = Visibility.Visible; - BorderStrokeSelectionClone.Background = Brushes.Transparent; - isStrokeSelectionCloneOn = false; - updateBorderStrokeSelectionControlLocation(); - } + + // 没有选中任何内容,隐藏选择框 + GridInkCanvasSelectionCover.Visibility = Visibility.Collapsed; } @@ -492,18 +512,11 @@ namespace Ink_Canvas strokes = StrokesSelectionClone; else if (Settings.Gesture.IsEnableTwoFingerRotationOnSelection) m.RotateAt(rotate, center.X, center.Y); // 旋转 + + // 应用变换到选中的墨迹 foreach (var stroke in strokes) { stroke.Transform(m, false); - - try - { - stroke.DrawingAttributes.Width *= md.Scale.X; - stroke.DrawingAttributes.Height *= md.Scale.Y; - } - catch - { - } } updateBorderStrokeSelectionControlLocation(); @@ -522,6 +535,60 @@ namespace Ink_Canvas { } + private void GridInkCanvasSelectionCover_TouchMove(object sender, TouchEventArgs e) + { + // 处理触摸移动事件 - 用于拖动选中的墨迹 + if (inkCanvas.GetSelectedStrokes().Count > 0 && dec.Count == 1) + { + var currentTouchPoint = e.GetTouchPoint(inkCanvas).Position; + var delta = currentTouchPoint - lastTouchPointOnGridInkCanvasCover; + + // 创建变换矩阵 + var matrix = new Matrix(); + matrix.Translate(delta.X, delta.Y); + + // 对选中的墨迹应用变换 + var selectedStrokes = inkCanvas.GetSelectedStrokes(); + foreach (var stroke in selectedStrokes) + { + stroke.Transform(matrix, false); + } + + // 更新选中栏位置 + updateBorderStrokeSelectionControlLocation(); + + // 更新最后触摸点 + lastTouchPointOnGridInkCanvasCover = currentTouchPoint; + } + } + + private void GridInkCanvasSelectionCover_PreviewTouchMove(object sender, TouchEventArgs e) + { + // 预览触摸移动事件 - 用于更精确的触摸处理 + if (inkCanvas.GetSelectedStrokes().Count > 0 && dec.Count == 1) + { + var currentTouchPoint = e.GetTouchPoint(inkCanvas).Position; + var delta = currentTouchPoint - lastTouchPointOnGridInkCanvasCover; + + // 创建变换矩阵 + var matrix = new Matrix(); + matrix.Translate(delta.X, delta.Y); + + // 对选中的墨迹应用变换 + var selectedStrokes = inkCanvas.GetSelectedStrokes(); + foreach (var stroke in selectedStrokes) + { + stroke.Transform(matrix, false); + } + + // 更新选中栏位置 + updateBorderStrokeSelectionControlLocation(); + + // 更新最后触摸点 + lastTouchPointOnGridInkCanvasCover = currentTouchPoint; + } + } + private Point lastTouchPointOnGridInkCanvasCover = new Point(0, 0); private void GridInkCanvasSelectionCover_PreviewTouchDown(object sender, TouchEventArgs e) @@ -532,7 +599,7 @@ namespace Ink_Canvas { var touchPoint = e.GetTouchPoint(null); centerPoint = touchPoint.Position; - lastTouchPointOnGridInkCanvasCover = touchPoint.Position; + lastTouchPointOnGridInkCanvasCover = e.GetTouchPoint(inkCanvas).Position; // 检查是否有选中的墨迹 if (inkCanvas.GetSelectedStrokes().Count > 0) @@ -548,7 +615,7 @@ namespace Ink_Canvas touchPosition.Y <= selectionBounds.Bottom) { // 只有在选择框边界内才允许拖动 - // 这里可以添加触摸拖动的逻辑 + // 触摸拖动状态已通过TouchMove事件处理 } else { From ba23fc95060d8a4b2cbb40226ed7adca51cfe838 Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sun, 7 Sep 2025 01:45:50 +0800 Subject: [PATCH 19/80] add:issue #171 --- Ink Canvas/MainWindow.xaml | 37 +++- .../MainWindow_cs/MW_SelectionGestures.cs | 178 +++++++++++++++++- 2 files changed, 212 insertions(+), 3 deletions(-) diff --git a/Ink Canvas/MainWindow.xaml b/Ink Canvas/MainWindow.xaml index 0be882df..70c8200a 100644 --- a/Ink Canvas/MainWindow.xaml +++ b/Ink Canvas/MainWindow.xaml @@ -3424,7 +3424,42 @@ TouchDown="GridInkCanvasSelectionCover_TouchDown" TouchUp="GridInkCanvasSelectionCover_TouchUp" TouchMove="GridInkCanvasSelectionCover_TouchMove" - Background="#01FFFFFF" Opacity="0.01" Visibility="Visible" Margin="1,0,-1,0" /> + Background="#01FFFFFF" Opacity="0.01" Visibility="Visible" Margin="1,0,-1,0"> + + + + + + + + + + + + + + + + + + + Date: Sun, 7 Sep 2025 01:50:44 +0800 Subject: [PATCH 20/80] fix:issue #175 --- Ink Canvas/MainWindow_cs/MW_Timer.cs | 50 +++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/Ink Canvas/MainWindow_cs/MW_Timer.cs b/Ink Canvas/MainWindow_cs/MW_Timer.cs index 2bf7b9d5..6c01448e 100644 --- a/Ink Canvas/MainWindow_cs/MW_Timer.cs +++ b/Ink Canvas/MainWindow_cs/MW_Timer.cs @@ -312,6 +312,44 @@ namespace Ink_Canvas { var windowTitle = ForegroundWindowInfo.WindowTitle(); var windowRect = ForegroundWindowInfo.WindowRect(); + var windowProcessName = ForegroundWindowInfo.ProcessName(); + + // 检测希沃白板五的批注面板 + // 希沃白板五的批注面板通常具有以下特征: + // 1. 窗口标题为空或包含特定关键词 + // 2. 窗口高度较小(批注工具栏) + // 3. 窗口宽度适中(工具栏宽度) + if (windowProcessName == "BoardService" || windowProcessName == "seewoPincoTeacher") + { + // 检测希沃白板五的批注工具栏 + // 批注工具栏通常高度在50-200像素之间,宽度在200-800像素之间 + if (windowRect.Height >= 50 && windowRect.Height <= 200 && + windowRect.Width >= 200 && windowRect.Width <= 800) + { + return true; + } + + // 检测希沃白板五的二级菜单面板 + // 二级菜单面板通常高度在100-400像素之间,宽度在150-400像素之间 + if (windowRect.Height >= 100 && windowRect.Height <= 400 && + windowRect.Width >= 150 && windowRect.Width <= 400) + { + return true; + } + } + + // 检测鸿合软件的批注面板 + if (windowProcessName == "HiteCamera" || windowProcessName == "HiteTouchPro" || windowProcessName == "HiteLightBoard") + { + // 鸿合软件的批注面板特征 + if (windowRect.Height >= 50 && windowRect.Height <= 300 && + windowRect.Width >= 200 && windowRect.Width <= 600) + { + return true; + } + } + + // 原有的检测逻辑(保持向后兼容) return windowTitle.Length == 0 && windowRect.Height < 500; } @@ -379,7 +417,17 @@ namespace Ink_Canvas } else if (Settings.Automation.IsAutoFoldInSeewoPincoTeacher && (windowProcessName == "BoardService" || windowProcessName == "seewoPincoTeacher")) { - if (!unfoldFloatingBarByUser && !isFloatingBarFolded) FoldFloatingBar_MouseUp(null, null); + // 检测到希沃白板五的批注窗口时保持收纳状态 + if (IsAnnotationWindow()) + { + // 批注窗口打开时,如果当前是展开状态则收纳 + if (!isFloatingBarFolded) FoldFloatingBar_MouseUp(null, null); + } + else + { + // 非批注窗口时正常处理 + if (!unfoldFloatingBarByUser && !isFloatingBarFolded) FoldFloatingBar_MouseUp(null, null); + } // HiteCamera } else if (Settings.Automation.IsAutoFoldInHiteCamera && windowProcessName == "HiteCamera" && From 60b56555749b6befd65f1b7c90b15b325f1471f2 Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sun, 7 Sep 2025 07:53:05 +0800 Subject: [PATCH 21/80] =?UTF-8?q?improve:=E5=A2=A8=E8=BF=B9=E9=80=89?= =?UTF-8?q?=E6=8B=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MainWindow_cs/MW_SelectionGestures.cs | 116 ++++++++++++------ Ink Canvas/MainWindow_cs/MW_TouchEvents.cs | 32 ++++- 2 files changed, 108 insertions(+), 40 deletions(-) diff --git a/Ink Canvas/MainWindow_cs/MW_SelectionGestures.cs b/Ink Canvas/MainWindow_cs/MW_SelectionGestures.cs index 65fe9973..26813344 100644 --- a/Ink Canvas/MainWindow_cs/MW_SelectionGestures.cs +++ b/Ink Canvas/MainWindow_cs/MW_SelectionGestures.cs @@ -8,6 +8,7 @@ using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Shapes; +using Ink_Canvas.Helpers; using Point = System.Windows.Point; namespace Ink_Canvas @@ -533,8 +534,9 @@ namespace Ink_Canvas updateBorderStrokeSelectionControlLocation(); } } - catch + catch (Exception ex) { + LogHelper.WriteLogToFile($"墨迹ManipulationDelta错误: {ex.Message}", LogHelper.LogType.Error); } } @@ -552,24 +554,33 @@ namespace Ink_Canvas if (inkCanvas.GetSelectedStrokes().Count > 0 && dec.Count == 1) { var currentTouchPoint = e.GetTouchPoint(inkCanvas).Position; - var delta = currentTouchPoint - lastTouchPointOnGridInkCanvasCover; - // 创建变换矩阵 - var matrix = new Matrix(); - matrix.Translate(delta.X, delta.Y); - - // 对选中的墨迹应用变换 - var selectedStrokes = inkCanvas.GetSelectedStrokes(); - foreach (var stroke in selectedStrokes) + // 检查是否有有效的起始触摸点 + if (lastTouchPointOnGridInkCanvasCover != new Point(0, 0)) { - stroke.Transform(matrix, false); + var delta = currentTouchPoint - lastTouchPointOnGridInkCanvasCover; + + // 只有当移动距离足够大时才进行拖动(避免微小移动造成的抖动) + if (Math.Abs(delta.X) > 1 || Math.Abs(delta.Y) > 1) + { + // 创建变换矩阵 + var matrix = new Matrix(); + matrix.Translate(delta.X, delta.Y); + + // 对选中的墨迹应用变换 + var selectedStrokes = inkCanvas.GetSelectedStrokes(); + foreach (var stroke in selectedStrokes) + { + stroke.Transform(matrix, false); + } + + // 更新选中栏位置 + updateBorderStrokeSelectionControlLocation(); + + // 更新最后触摸点 + lastTouchPointOnGridInkCanvasCover = currentTouchPoint; + } } - - // 更新选中栏位置 - updateBorderStrokeSelectionControlLocation(); - - // 更新最后触摸点 - lastTouchPointOnGridInkCanvasCover = currentTouchPoint; } } @@ -579,24 +590,33 @@ namespace Ink_Canvas if (inkCanvas.GetSelectedStrokes().Count > 0 && dec.Count == 1) { var currentTouchPoint = e.GetTouchPoint(inkCanvas).Position; - var delta = currentTouchPoint - lastTouchPointOnGridInkCanvasCover; - // 创建变换矩阵 - var matrix = new Matrix(); - matrix.Translate(delta.X, delta.Y); - - // 对选中的墨迹应用变换 - var selectedStrokes = inkCanvas.GetSelectedStrokes(); - foreach (var stroke in selectedStrokes) + // 检查是否有有效的起始触摸点 + if (lastTouchPointOnGridInkCanvasCover != new Point(0, 0)) { - stroke.Transform(matrix, false); + var delta = currentTouchPoint - lastTouchPointOnGridInkCanvasCover; + + // 只有当移动距离足够大时才进行拖动(避免微小移动造成的抖动) + if (Math.Abs(delta.X) > 1 || Math.Abs(delta.Y) > 1) + { + // 创建变换矩阵 + var matrix = new Matrix(); + matrix.Translate(delta.X, delta.Y); + + // 对选中的墨迹应用变换 + var selectedStrokes = inkCanvas.GetSelectedStrokes(); + foreach (var stroke in selectedStrokes) + { + stroke.Transform(matrix, false); + } + + // 更新选中栏位置 + updateBorderStrokeSelectionControlLocation(); + + // 更新最后触摸点 + lastTouchPointOnGridInkCanvasCover = currentTouchPoint; + } } - - // 更新选中栏位置 - updateBorderStrokeSelectionControlLocation(); - - // 更新最后触摸点 - lastTouchPointOnGridInkCanvasCover = currentTouchPoint; } } @@ -625,8 +645,8 @@ namespace Ink_Canvas touchPosition.Y >= selectionBounds.Top && touchPosition.Y <= selectionBounds.Bottom) { - // 只有在选择框边界内才允许拖动 - // 触摸拖动状态已通过TouchMove事件处理 + // 只有在选择框边界内才允许拖动 + // 触摸拖动状态已通过TouchMove事件处理 } else { @@ -661,13 +681,32 @@ namespace Ink_Canvas { dec.Remove(e.TouchDevice.Id); if (dec.Count >= 1) return; + + // 重置触摸状态 + lastTouchPointOnGridInkCanvasCover = new Point(0, 0); isProgramChangeStrokeSelection = false; - if (lastTouchPointOnGridInkCanvasCover == e.GetTouchPoint(null).Position) + + // 检查是否有点击(没有移动) + var currentTouchPoint = e.GetTouchPoint(null).Position; + if (Math.Abs(currentTouchPoint.X - centerPoint.X) < 5 && Math.Abs(currentTouchPoint.Y - centerPoint.Y) < 5) { - if (!(lastTouchPointOnGridInkCanvasCover.X < inkCanvas.GetSelectionBounds().Left) && - !(lastTouchPointOnGridInkCanvasCover.Y < inkCanvas.GetSelectionBounds().Top) && - !(lastTouchPointOnGridInkCanvasCover.X > inkCanvas.GetSelectionBounds().Right) && - !(lastTouchPointOnGridInkCanvasCover.Y > inkCanvas.GetSelectionBounds().Bottom)) return; + // 点击在选择框内,保持选择状态 + if (inkCanvas.GetSelectedStrokes().Count > 0) + { + var selectionBounds = inkCanvas.GetSelectionBounds(); + if (currentTouchPoint.X >= selectionBounds.Left && + currentTouchPoint.X <= selectionBounds.Right && + currentTouchPoint.Y >= selectionBounds.Top && + currentTouchPoint.Y <= selectionBounds.Bottom) + { + // 点击在选择框内,保持选择 + GridInkCanvasSelectionCover.Visibility = Visibility.Visible; + StrokesSelectionClone = new StrokeCollection(); + return; + } + } + + // 点击在选择框外,取消选择 inkCanvas.Select(new StrokeCollection()); StrokesSelectionClone = new StrokeCollection(); } @@ -681,6 +720,7 @@ namespace Ink_Canvas GridInkCanvasSelectionCover.Visibility = Visibility.Visible; StrokesSelectionClone = new StrokeCollection(); } + } private void LassoSelect_Click(object sender, RoutedEventArgs e) diff --git a/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs b/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs index a5f6af9c..8d1c48c8 100644 --- a/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs +++ b/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs @@ -369,7 +369,8 @@ namespace Ink_Canvas } if (inkCanvas.EditingMode == InkCanvasEditingMode.Select) { - // 套索选状态下只return,保证套索选可用 + // 套索选状态下不直接return,允许触摸事件继续处理 + dec.Add(e.TouchDevice.Id); return; } // 修复:几何绘制模式下完全禁止触摸轨迹收集 @@ -864,7 +865,34 @@ namespace Ink_Canvas return; // 三指及以上禁止缩放 bool disableScale = dec.Count >= 3; - if (isInMultiTouchMode || !Settings.Gesture.IsEnableTwoFingerGesture) return; + + // 修复:允许单指拖动选中的墨迹,即使禁用了多指手势 + if (isInMultiTouchMode) return; + + // 如果是单指拖动选中的墨迹,允许处理 + if (dec.Count == 1 && inkCanvas.GetSelectedStrokes().Count > 0) + { + var md = e.DeltaManipulation; + var trans = md.Translation; // 获得位移矢量 + + if (trans.X != 0 || trans.Y != 0) + { + var m = new Matrix(); + m.Translate(trans.X, trans.Y); // 移动 + + var strokes = inkCanvas.GetSelectedStrokes(); + foreach (var stroke in strokes) + { + stroke.Transform(m, false); + } + + // 更新选择框位置 + updateBorderStrokeSelectionControlLocation(); + } + return; + } + + if (!Settings.Gesture.IsEnableTwoFingerGesture) return; if ((dec.Count >= 2 && (Settings.PowerPointSettings.IsEnableTwoFingerGestureInPresentationMode || StackPanelPPTControls.Visibility != Visibility.Visible || StackPanelPPTButtons.Visibility == Visibility.Collapsed)) || From ead0854c8e4fb80cf8131ff32f0b526712ed390a Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sun, 7 Sep 2025 07:59:21 +0800 Subject: [PATCH 22/80] =?UTF-8?q?improve:=E5=A2=A8=E8=BF=B9=E9=80=89?= =?UTF-8?q?=E6=8B=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MainWindow_cs/MW_SelectionGestures.cs | 49 +++++++++++-------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/Ink Canvas/MainWindow_cs/MW_SelectionGestures.cs b/Ink Canvas/MainWindow_cs/MW_SelectionGestures.cs index 26813344..402e51b0 100644 --- a/Ink Canvas/MainWindow_cs/MW_SelectionGestures.cs +++ b/Ink Canvas/MainWindow_cs/MW_SelectionGestures.cs @@ -875,48 +875,55 @@ namespace Ink_Canvas private Rect CalculateNewBounds(Rect originalBounds, Point delta, string handleName) { var newBounds = originalBounds; + double newWidth = originalBounds.Width; + double newHeight = originalBounds.Height; + double newX = originalBounds.X; + double newY = originalBounds.Y; switch (handleName) { case "TopLeftHandle": - newBounds.X = originalBounds.X + delta.X; - newBounds.Y = originalBounds.Y + delta.Y; - newBounds.Width = originalBounds.Width - delta.X; - newBounds.Height = originalBounds.Height - delta.Y; + newX = originalBounds.X + delta.X; + newY = originalBounds.Y + delta.Y; + newWidth = originalBounds.Width - delta.X; + newHeight = originalBounds.Height - delta.Y; break; case "TopRightHandle": - newBounds.Y = originalBounds.Y + delta.Y; - newBounds.Width = originalBounds.Width + delta.X; - newBounds.Height = originalBounds.Height - delta.Y; + newY = originalBounds.Y + delta.Y; + newWidth = originalBounds.Width + delta.X; + newHeight = originalBounds.Height - delta.Y; break; case "BottomLeftHandle": - newBounds.X = originalBounds.X + delta.X; - newBounds.Width = originalBounds.Width - delta.X; - newBounds.Height = originalBounds.Height + delta.Y; + newX = originalBounds.X + delta.X; + newWidth = originalBounds.Width - delta.X; + newHeight = originalBounds.Height + delta.Y; break; case "BottomRightHandle": - newBounds.Width = originalBounds.Width + delta.X; - newBounds.Height = originalBounds.Height + delta.Y; + newWidth = originalBounds.Width + delta.X; + newHeight = originalBounds.Height + delta.Y; break; case "TopHandle": - newBounds.Y = originalBounds.Y + delta.Y; - newBounds.Height = originalBounds.Height - delta.Y; + newY = originalBounds.Y + delta.Y; + newHeight = originalBounds.Height - delta.Y; break; case "BottomHandle": - newBounds.Height = originalBounds.Height + delta.Y; + newHeight = originalBounds.Height + delta.Y; break; case "LeftHandle": - newBounds.X = originalBounds.X + delta.X; - newBounds.Width = originalBounds.Width - delta.X; + newX = originalBounds.X + delta.X; + newWidth = originalBounds.Width - delta.X; break; case "RightHandle": - newBounds.Width = originalBounds.Width + delta.X; + newWidth = originalBounds.Width + delta.X; break; } - // 确保最小尺寸 - if (newBounds.Width < 10) newBounds.Width = 10; - if (newBounds.Height < 10) newBounds.Height = 10; + // 确保最小尺寸和正值 + if (newWidth < 10) newWidth = 10; + if (newHeight < 10) newHeight = 10; + + // 创建新的Rect,确保所有值都是有效的 + newBounds = new Rect(newX, newY, newWidth, newHeight); return newBounds; } From 7d36b3993e0d7418badf72af0f9397746a44a02c Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sun, 7 Sep 2025 09:41:42 +0800 Subject: [PATCH 23/80] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/Helpers/Plugins/IGetService.cs | 1 - Ink Canvas/Helpers/Plugins/IPluginService.cs | 6 ------ Ink Canvas/Helpers/Plugins/IWindowService.cs | 2 -- Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs | 1 - Ink Canvas/MainWindow_cs/MW_PPT.cs | 1 - Ink Canvas/Resources/ICCConfiguration.cs | 7 +------ .../SettingsViews/AboutPanel.xaml.cs | 7 ------- .../SettingsViews/AppearancePanel.xaml.cs | 14 +------------- .../FloatingBarDnDSettingsPanel.xaml.cs | 14 +------------- .../SettingsViews/SettingsBaseView.xaml.cs | 10 ---------- .../Windows/SettingsViews/SettingsWindow.xaml.cs | 16 ---------------- 11 files changed, 3 insertions(+), 76 deletions(-) diff --git a/Ink Canvas/Helpers/Plugins/IGetService.cs b/Ink Canvas/Helpers/Plugins/IGetService.cs index 70ff947e..2d5f5e4b 100644 --- a/Ink Canvas/Helpers/Plugins/IGetService.cs +++ b/Ink Canvas/Helpers/Plugins/IGetService.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Windows; using System.Windows.Controls; diff --git a/Ink Canvas/Helpers/Plugins/IPluginService.cs b/Ink Canvas/Helpers/Plugins/IPluginService.cs index b1923121..9559a992 100644 --- a/Ink Canvas/Helpers/Plugins/IPluginService.cs +++ b/Ink Canvas/Helpers/Plugins/IPluginService.cs @@ -1,9 +1,3 @@ -using System; -using System.Collections.Generic; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media; - namespace Ink_Canvas.Helpers.Plugins { ///

diff --git a/Ink Canvas/Helpers/Plugins/IWindowService.cs b/Ink Canvas/Helpers/Plugins/IWindowService.cs index 2685046c..87dfab9d 100644 --- a/Ink Canvas/Helpers/Plugins/IWindowService.cs +++ b/Ink Canvas/Helpers/Plugins/IWindowService.cs @@ -1,5 +1,3 @@ -using System; - namespace Ink_Canvas.Helpers.Plugins { /// diff --git a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs index 74bfcddc..a3c6a092 100644 --- a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs +++ b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs @@ -2,7 +2,6 @@ using Ink_Canvas.Helpers; using iNKORE.UI.WPF.Modern; using System; using System.Diagnostics; -using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; using System.Windows; diff --git a/Ink Canvas/MainWindow_cs/MW_PPT.cs b/Ink Canvas/MainWindow_cs/MW_PPT.cs index 1a6a86fe..b3477302 100644 --- a/Ink Canvas/MainWindow_cs/MW_PPT.cs +++ b/Ink Canvas/MainWindow_cs/MW_PPT.cs @@ -3,7 +3,6 @@ using iNKORE.UI.WPF.Modern; using Microsoft.Office.Core; using Microsoft.Office.Interop.PowerPoint; using System; -using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; using System.Security.Cryptography; diff --git a/Ink Canvas/Resources/ICCConfiguration.cs b/Ink Canvas/Resources/ICCConfiguration.cs index 5a866e0d..5ed34442 100644 --- a/Ink Canvas/Resources/ICCConfiguration.cs +++ b/Ink Canvas/Resources/ICCConfiguration.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; +using System.Windows; using System.Windows.Media; namespace Ink_Canvas.Resources.ICCConfiguration { diff --git a/Ink Canvas/Windows/SettingsViews/SettingsViews/AboutPanel.xaml.cs b/Ink Canvas/Windows/SettingsViews/SettingsViews/AboutPanel.xaml.cs index 75dd183e..ada8be75 100644 --- a/Ink Canvas/Windows/SettingsViews/SettingsViews/AboutPanel.xaml.cs +++ b/Ink Canvas/Windows/SettingsViews/SettingsViews/AboutPanel.xaml.cs @@ -2,25 +2,18 @@ using System; using System.Collections.Generic; using System.IO; -using System.Linq; using System.Management; using System.Reflection; using System.Runtime.InteropServices; using System.Text; using System.Threading; -using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; -using System.Windows.Data; -using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; using iNKORE.UI.WPF.Helpers; -using static Ink_Canvas.Windows.SettingsWindow; namespace Ink_Canvas.Windows.SettingsViews { /// diff --git a/Ink Canvas/Windows/SettingsViews/SettingsViews/AppearancePanel.xaml.cs b/Ink Canvas/Windows/SettingsViews/SettingsViews/AppearancePanel.xaml.cs index 42ef2c40..eb6b624d 100644 --- a/Ink Canvas/Windows/SettingsViews/SettingsViews/AppearancePanel.xaml.cs +++ b/Ink Canvas/Windows/SettingsViews/SettingsViews/AppearancePanel.xaml.cs @@ -1,18 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; +using System.Collections.ObjectModel; using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; namespace Ink_Canvas.Windows.SettingsViews { public partial class AppearancePanel : UserControl { diff --git a/Ink Canvas/Windows/SettingsViews/SettingsViews/FloatingBarDnDSettingsPanel.xaml.cs b/Ink Canvas/Windows/SettingsViews/SettingsViews/FloatingBarDnDSettingsPanel.xaml.cs index 857de922..2825972e 100644 --- a/Ink Canvas/Windows/SettingsViews/SettingsViews/FloatingBarDnDSettingsPanel.xaml.cs +++ b/Ink Canvas/Windows/SettingsViews/SettingsViews/FloatingBarDnDSettingsPanel.xaml.cs @@ -1,21 +1,9 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; +using System.Collections.ObjectModel; using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; using iNKORE.UI.WPF.DragDrop; -using static System.Windows.Forms.VisualStyles.VisualStyleElement.Menu; namespace Ink_Canvas.Windows.SettingsViews { diff --git a/Ink Canvas/Windows/SettingsViews/SettingsViews/SettingsBaseView.xaml.cs b/Ink Canvas/Windows/SettingsViews/SettingsViews/SettingsBaseView.xaml.cs index 6cab7b05..365c898c 100644 --- a/Ink Canvas/Windows/SettingsViews/SettingsViews/SettingsBaseView.xaml.cs +++ b/Ink Canvas/Windows/SettingsViews/SettingsViews/SettingsBaseView.xaml.cs @@ -1,21 +1,11 @@ using System; -using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; -using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; -using System.Windows.Data; -using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; using iNKORE.UI.WPF.Helpers; using iNKORE.UI.WPF.Modern.Controls; diff --git a/Ink Canvas/Windows/SettingsViews/SettingsWindow.xaml.cs b/Ink Canvas/Windows/SettingsViews/SettingsWindow.xaml.cs index fa4b54d8..43b15b5b 100644 --- a/Ink Canvas/Windows/SettingsViews/SettingsWindow.xaml.cs +++ b/Ink Canvas/Windows/SettingsViews/SettingsWindow.xaml.cs @@ -2,29 +2,13 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Management; -using System.Reflection; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading; -using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Data; -using System.Windows.Documents; using System.Windows.Input; -using System.Windows.Interop; using System.Windows.Media; -using System.Windows.Media.Animation; -using System.Windows.Media.Imaging; -using System.Windows.Shapes; -using Ink_Canvas.Windows.SettingsViews; using iNKORE.UI.WPF.Helpers; -using iNKORE.UI.WPF.Modern.Controls; -using OSVersionExtension; namespace Ink_Canvas.Windows { public partial class SettingsWindow : Window { From ad8369cfe99bacaa723f3fee80053abdd2100cd0 Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sun, 7 Sep 2025 13:25:20 +0800 Subject: [PATCH 24/80] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/AssemblyInfo.cs | 4 ++-- Ink Canvas/Properties/AssemblyInfo.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Ink Canvas/AssemblyInfo.cs b/Ink Canvas/AssemblyInfo.cs index dff64f25..77edab32 100644 --- a/Ink Canvas/AssemblyInfo.cs +++ b/Ink Canvas/AssemblyInfo.cs @@ -49,5 +49,5 @@ using System.Windows; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.7.10.0")] -[assembly: AssemblyFileVersion("1.7.10.0")] +[assembly: AssemblyVersion("1.7.10.1")] +[assembly: AssemblyFileVersion("1.7.10.1")] diff --git a/Ink Canvas/Properties/AssemblyInfo.cs b/Ink Canvas/Properties/AssemblyInfo.cs index dff64f25..77edab32 100644 --- a/Ink Canvas/Properties/AssemblyInfo.cs +++ b/Ink Canvas/Properties/AssemblyInfo.cs @@ -49,5 +49,5 @@ using System.Windows; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.7.10.0")] -[assembly: AssemblyFileVersion("1.7.10.0")] +[assembly: AssemblyVersion("1.7.10.1")] +[assembly: AssemblyFileVersion("1.7.10.1")] From 084cbcd362290acb70f94eda755f363ea5c05e38 Mon Sep 17 00:00:00 2001 From: PrefacedCorg <1876568293@qq.com> Date: Sun, 7 Sep 2025 13:30:46 +0800 Subject: [PATCH 25/80] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=B8=85=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/App.xaml.cs | 6 +- Ink Canvas/Helpers/DeviceIdentifier.cs | 2 +- Ink Canvas/Helpers/FileAssociationManager.cs | 76 ++--- Ink Canvas/Helpers/PPTManager.cs | 8 +- Ink Canvas/Helpers/PPTUIManager.cs | 2 +- .../Helpers/Plugins/EnhancedPluginBaseV2.cs | 2 +- Ink Canvas/Helpers/Plugins/IActionService.cs | 2 +- Ink Canvas/Helpers/Plugins/IGetService.cs | 2 +- Ink Canvas/Helpers/Plugins/IWindowService.cs | 2 +- Ink Canvas/Helpers/WindowZOrderManager.cs | 2 +- Ink Canvas/MainWindow.xaml.cs | 46 +-- Ink Canvas/MainWindow_cs/MW_AutoFold.cs | 12 +- Ink Canvas/MainWindow_cs/MW_Eraser.cs | 4 +- .../MainWindow_cs/MW_FloatingBarIcons.cs | 64 ++--- Ink Canvas/MainWindow_cs/MW_Hotkeys.cs | 8 +- Ink Canvas/MainWindow_cs/MW_PPT.cs | 32 +-- .../MainWindow_cs/MW_SelectionGestures.cs | 90 +++--- Ink Canvas/MainWindow_cs/MW_Settings.cs | 10 +- Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs | 2 +- Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs | 4 +- Ink Canvas/MainWindow_cs/MW_Timer.cs | 22 +- Ink Canvas/MainWindow_cs/MW_TouchEvents.cs | 28 +- Ink Canvas/Resources/ICCConfiguration.cs | 29 +- .../Windows/CountdownTimerWindow.xaml.cs | 3 +- .../Windows/HotkeySettingsWindow.xaml.cs | 18 +- .../Windows/OperatingGuideWindow.xaml.cs | 13 +- Ink Canvas/Windows/RandWindow.xaml.cs | 12 +- .../Windows/ScreenshotSelectorWindow.xaml.cs | 68 ++--- .../SettingsViews/AboutPanel.xaml.cs | 95 ++++--- .../SettingsViews/AppearancePanel.xaml.cs | 15 +- .../FloatingBarDnDSettingsPanel.xaml.cs | 103 ++++--- .../SettingsViews/SettingsBaseView.xaml.cs | 112 +++++--- .../SettingsViews/SettingsWindow.xaml.cs | 264 +++++++++++------- 33 files changed, 669 insertions(+), 489 deletions(-) diff --git a/Ink Canvas/App.xaml.cs b/Ink Canvas/App.xaml.cs index 3f9f8c90..6a8c1d4e 100644 --- a/Ink Canvas/App.xaml.cs +++ b/Ink Canvas/App.xaml.cs @@ -633,13 +633,13 @@ namespace Ink_Canvas if (!ret && !e.Args.Contains("-m")) //-m multiple { LogHelper.NewLog("Detected existing instance"); - + // 检查是否有.icstk文件参数 string icstkFile = FileAssociationManager.GetIcstkFileFromArgs(e.Args); if (!string.IsNullOrEmpty(icstkFile)) { LogHelper.WriteLogToFile($"检测到已运行实例,尝试通过IPC发送文件: {icstkFile}", LogHelper.LogType.Event); - + // 尝试通过IPC发送文件路径给已运行实例 if (FileAssociationManager.TrySendFileToExistingInstance(icstkFile)) { @@ -654,7 +654,7 @@ namespace Ink_Canvas { LogHelper.WriteLogToFile("检测到已运行实例,但无文件参数", LogHelper.LogType.Event); } - + LogHelper.NewLog("Ink Canvas automatically closed"); IsAppExitByUser = true; // 多开时标记为用户主动退出 // 写入退出信号,确保看门狗不会重启 diff --git a/Ink Canvas/Helpers/DeviceIdentifier.cs b/Ink Canvas/Helpers/DeviceIdentifier.cs index 586dcc0c..4ae80370 100644 --- a/Ink Canvas/Helpers/DeviceIdentifier.cs +++ b/Ink Canvas/Helpers/DeviceIdentifier.cs @@ -1092,7 +1092,7 @@ namespace Ink_Canvas.Helpers { int versionDiff = CalculateVersionGenerationDifference(localVersion, updateVersion); LogHelper.WriteLogToFile($"DeviceIdentifier | 无法获取版本发布时间,使用版本号差异判断 - 本地版本: {localVersion}, 远程版本: {updateVersion}, 代数差异: {versionDiff}"); - + // 当版本号代数差异大于3时自动更新 if (versionDiff > 3) { diff --git a/Ink Canvas/Helpers/FileAssociationManager.cs b/Ink Canvas/Helpers/FileAssociationManager.cs index e950e521..76a4db50 100644 --- a/Ink Canvas/Helpers/FileAssociationManager.cs +++ b/Ink Canvas/Helpers/FileAssociationManager.cs @@ -1,12 +1,12 @@ +using Microsoft.Win32; using System; using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; using System.Security; -using System.Windows; -using Microsoft.Win32; -using System.Threading; using System.Text; +using System.Threading; +using System.Windows; namespace Ink_Canvas.Helpers { @@ -19,7 +19,7 @@ namespace Ink_Canvas.Helpers private const string FileTypeName = "InkCanvasStrokesFile"; private const string AppName = "Ink Canvas"; private const string AppDescription = "Ink Canvas Strokes File"; - + // IPC相关常量 private const string IpcMutexName = "InkCanvasFileAssociationIpc"; private const string IpcEventName = "InkCanvasFileAssociationEvent"; @@ -34,19 +34,19 @@ namespace Ink_Canvas.Helpers try { string exePath = Process.GetCurrentProcess().MainModule.FileName; - + // 注册文件类型 using (RegistryKey fileTypeKey = Registry.ClassesRoot.CreateSubKey(FileTypeName)) { fileTypeKey.SetValue("", AppDescription); fileTypeKey.SetValue("FriendlyTypeName", AppDescription); - + // 设置默认图标 using (RegistryKey defaultIconKey = fileTypeKey.CreateSubKey("DefaultIcon")) { defaultIconKey.SetValue("", $"\"{exePath}\",0"); } - + // 设置打开命令 using (RegistryKey shellKey = fileTypeKey.CreateSubKey("shell")) using (RegistryKey openKey = shellKey.CreateSubKey("open")) @@ -55,16 +55,16 @@ namespace Ink_Canvas.Helpers commandKey.SetValue("", $"\"{exePath}\" \"%1\""); } } - + // 注册文件扩展名 using (RegistryKey extensionKey = Registry.ClassesRoot.CreateSubKey(FileExtension)) { extensionKey.SetValue("", FileTypeName); } - + // 刷新系统文件关联缓存 RefreshSystemFileAssociations(); - + LogHelper.WriteLogToFile($"成功注册{FileExtension}文件关联", LogHelper.LogType.Event); return true; } @@ -94,13 +94,13 @@ namespace Ink_Canvas.Helpers { // 删除文件扩展名关联 Registry.ClassesRoot.DeleteSubKeyTree(FileExtension, false); - + // 删除文件类型定义 Registry.ClassesRoot.DeleteSubKeyTree(FileTypeName, false); - + // 刷新系统文件关联缓存 RefreshSystemFileAssociations(); - + LogHelper.WriteLogToFile($"成功注销{FileExtension}文件关联", LogHelper.LogType.Event); return true; } @@ -121,21 +121,21 @@ namespace Ink_Canvas.Helpers using (RegistryKey extensionKey = Registry.ClassesRoot.OpenSubKey(FileExtension)) { if (extensionKey == null) return false; - + string fileType = extensionKey.GetValue("") as string; if (string.IsNullOrEmpty(fileType)) return false; - + using (RegistryKey fileTypeKey = Registry.ClassesRoot.OpenSubKey(fileType)) { if (fileTypeKey == null) return false; - + using (RegistryKey shellKey = fileTypeKey.OpenSubKey("shell\\open\\command")) { if (shellKey == null) return false; - + string command = shellKey.GetValue("") as string; if (string.IsNullOrEmpty(command)) return false; - + // 检查命令是否指向当前应用程序 string currentExePath = Process.GetCurrentProcess().MainModule.FileName; return command.Contains(currentExePath); @@ -147,7 +147,7 @@ namespace Ink_Canvas.Helpers { LogHelper.WriteLogToFile($"检查文件关联状态时出错: {ex.Message}", LogHelper.LogType.Error); } - + return false; } @@ -184,11 +184,11 @@ namespace Ink_Canvas.Helpers public static string GetIcstkFileFromArgs(string[] args) { if (args == null || args.Length == 0) return null; - + foreach (string arg in args) { if (string.IsNullOrEmpty(arg)) continue; - + // 检查是否为.icstk文件 if (Path.GetExtension(arg).Equals(FileExtension, StringComparison.OrdinalIgnoreCase)) { @@ -204,7 +204,7 @@ namespace Ink_Canvas.Helpers } } } - + return null; } @@ -218,24 +218,24 @@ namespace Ink_Canvas.Helpers try { LogHelper.WriteLogToFile($"尝试通过IPC发送文件路径给已运行实例: {filePath}", LogHelper.LogType.Event); - + // 创建IPC文件 string tempDir = Path.GetTempPath(); string ipcFileName = IpcFilePrefix + Guid.NewGuid().ToString("N") + ".tmp"; string ipcFilePath = Path.Combine(tempDir, ipcFileName); - + // 写入文件路径到IPC文件 File.WriteAllText(ipcFilePath, filePath, Encoding.UTF8); - + // 创建事件通知已运行实例 using (EventWaitHandle ipcEvent = new EventWaitHandle(false, EventResetMode.ManualReset, IpcEventName)) { ipcEvent.Set(); } - + // 等待一段时间让已运行实例处理文件 Thread.Sleep(1000); - + // 清理IPC文件 try { @@ -248,7 +248,7 @@ namespace Ink_Canvas.Helpers { LogHelper.WriteLogToFile($"清理IPC文件失败: {ex.Message}", LogHelper.LogType.Warning); } - + LogHelper.WriteLogToFile("IPC文件路径发送完成", LogHelper.LogType.Event); return true; } @@ -271,7 +271,7 @@ namespace Ink_Canvas.Helpers try { LogHelper.WriteLogToFile("启动IPC监听器", LogHelper.LogType.Event); - + using (EventWaitHandle ipcEvent = new EventWaitHandle(false, EventResetMode.ManualReset, IpcEventName)) { while (true) @@ -281,11 +281,11 @@ namespace Ink_Canvas.Helpers { // 处理IPC文件 ProcessIpcFiles(); - + // 重置事件 ipcEvent.Reset(); } - + // 检查应用是否还在运行 if (Application.Current == null || Application.Current.Dispatcher == null) { @@ -299,7 +299,7 @@ namespace Ink_Canvas.Helpers LogHelper.WriteLogToFile($"IPC监听器出错: {ex.Message}", LogHelper.LogType.Error); } }); - + ipcThread.IsBackground = true; ipcThread.Start(); } @@ -318,18 +318,18 @@ namespace Ink_Canvas.Helpers { string tempDir = Path.GetTempPath(); string[] ipcFiles = Directory.GetFiles(tempDir, IpcFilePrefix + "*.tmp"); - + foreach (string ipcFile in ipcFiles) { try { // 读取文件路径 string filePath = File.ReadAllText(ipcFile, Encoding.UTF8); - + if (!string.IsNullOrEmpty(filePath) && File.Exists(filePath)) { LogHelper.WriteLogToFile($"IPC接收到文件路径: {filePath}", LogHelper.LogType.Event); - + // 在UI线程中处理文件打开 Application.Current.Dispatcher.BeginInvoke(new Action(() => { @@ -348,14 +348,14 @@ namespace Ink_Canvas.Helpers } })); } - + // 删除IPC文件 File.Delete(ipcFile); } catch (Exception ex) { LogHelper.WriteLogToFile($"处理IPC文件失败: {ex.Message}", LogHelper.LogType.Warning); - + // 尝试删除损坏的IPC文件 try { @@ -377,4 +377,4 @@ namespace Ink_Canvas.Helpers [DllImport("shell32.dll")] private static extern void SHChangeNotify(uint wEventId, uint uFlags, IntPtr dwItem1, IntPtr dwItem2); } -} \ No newline at end of file +} \ No newline at end of file diff --git a/Ink Canvas/Helpers/PPTManager.cs b/Ink Canvas/Helpers/PPTManager.cs index 48fc4c70..146e4e51 100644 --- a/Ink Canvas/Helpers/PPTManager.cs +++ b/Ink Canvas/Helpers/PPTManager.cs @@ -70,17 +70,17 @@ namespace Ink_Canvas.Helpers try { if (PPTApplication == null || !Marshal.IsComObject(PPTApplication)) return false; - + // 检查是否有放映窗口 var slideShowWindows = PPTApplication.SlideShowWindows; if (slideShowWindows == null || slideShowWindows.Count == 0) return false; - + // 验证放映窗口是否真正有效 try { var slideShowWindow = slideShowWindows[1]; if (slideShowWindow == null) return false; - + // 尝试访问放映窗口的属性来验证其有效性 var _ = slideShowWindow.View; return true; @@ -479,7 +479,7 @@ namespace Ink_Canvas.Helpers { CurrentPresentation = activePresentation; CurrentSlides = CurrentPresentation.Slides; - + // 验证页数读取是否成功 try { diff --git a/Ink Canvas/Helpers/PPTUIManager.cs b/Ink Canvas/Helpers/PPTUIManager.cs index 1e29affc..dffcc2e8 100644 --- a/Ink Canvas/Helpers/PPTUIManager.cs +++ b/Ink Canvas/Helpers/PPTUIManager.cs @@ -181,7 +181,7 @@ namespace Ink_Canvas.Helpers bool isInSlideShow = _mainWindow.PPTManager?.IsInSlideShow == true; int slidesCount = _mainWindow.PPTManager?.SlidesCount ?? 0; bool hasValidPageCount = slidesCount > 0; - + bool shouldShowButtons = ShowPPTButton && _mainWindow.BtnPPTSlideShowEnd.Visibility == Visibility.Visible && isInSlideShow && diff --git a/Ink Canvas/Helpers/Plugins/EnhancedPluginBaseV2.cs b/Ink Canvas/Helpers/Plugins/EnhancedPluginBaseV2.cs index d4f2f96f..218068b6 100644 --- a/Ink Canvas/Helpers/Plugins/EnhancedPluginBaseV2.cs +++ b/Ink Canvas/Helpers/Plugins/EnhancedPluginBaseV2.cs @@ -238,4 +238,4 @@ namespace Ink_Canvas.Helpers.Plugins #endregion } -} \ No newline at end of file +} \ No newline at end of file diff --git a/Ink Canvas/Helpers/Plugins/IActionService.cs b/Ink Canvas/Helpers/Plugins/IActionService.cs index 0101a605..99c61473 100644 --- a/Ink Canvas/Helpers/Plugins/IActionService.cs +++ b/Ink Canvas/Helpers/Plugins/IActionService.cs @@ -293,4 +293,4 @@ namespace Ink_Canvas.Helpers.Plugins #endregion } -} \ No newline at end of file +} \ No newline at end of file diff --git a/Ink Canvas/Helpers/Plugins/IGetService.cs b/Ink Canvas/Helpers/Plugins/IGetService.cs index 2d5f5e4b..ab48889a 100644 --- a/Ink Canvas/Helpers/Plugins/IGetService.cs +++ b/Ink Canvas/Helpers/Plugins/IGetService.cs @@ -211,4 +211,4 @@ namespace Ink_Canvas.Helpers.Plugins #endregion } -} \ No newline at end of file +} \ No newline at end of file diff --git a/Ink Canvas/Helpers/Plugins/IWindowService.cs b/Ink Canvas/Helpers/Plugins/IWindowService.cs index 87dfab9d..eb6fb863 100644 --- a/Ink Canvas/Helpers/Plugins/IWindowService.cs +++ b/Ink Canvas/Helpers/Plugins/IWindowService.cs @@ -149,4 +149,4 @@ namespace Ink_Canvas.Helpers.Plugins #endregion } -} \ No newline at end of file +} \ No newline at end of file diff --git a/Ink Canvas/Helpers/WindowZOrderManager.cs b/Ink Canvas/Helpers/WindowZOrderManager.cs index 2ce292c8..3cf561c3 100644 --- a/Ink Canvas/Helpers/WindowZOrderManager.cs +++ b/Ink Canvas/Helpers/WindowZOrderManager.cs @@ -156,7 +156,7 @@ namespace Ink_Canvas.Helpers // 使用更直接的方法:先激活窗口,再置顶 window.Activate(); window.Focus(); - + // 设置窗口为置顶 SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | SWP_NOOWNERZORDER); diff --git a/Ink Canvas/MainWindow.xaml.cs b/Ink Canvas/MainWindow.xaml.cs index 000ded77..12dbb4ed 100644 --- a/Ink Canvas/MainWindow.xaml.cs +++ b/Ink Canvas/MainWindow.xaml.cs @@ -247,7 +247,7 @@ namespace Ink_Canvas // 为浮动栏按钮添加触摸事件支持 AddTouchSupportToFloatingBarButtons(); - + // 为滑块控件添加触摸事件支持 AddTouchSupportToSliders(); } @@ -301,7 +301,7 @@ namespace Ink_Canvas foreach (var gest in gestures) //Trace.WriteLine(string.Format("Gesture: {0}, Confidence: {1}", gest.ApplicationGesture, gest.RecognitionConfidence)); // 只有在PPT放映模式下才响应翻页手势 - if (StackPanelPPTControls.Visibility == Visibility.Visible && + if (StackPanelPPTControls.Visibility == Visibility.Visible && BtnPPTSlideShowEnd.Visibility == Visibility.Visible && PPTManager?.IsInSlideShow == true) { @@ -1035,7 +1035,7 @@ namespace Ink_Canvas // 取消选中元素 UnselectElement(currentSelectedElement); currentSelectedElement = null; - + // 重置为选择模式,确保用户可以继续选择其他元素 SetCurrentToolMode(InkCanvasEditingMode.Select); // 更新模式缓存 @@ -2033,14 +2033,14 @@ namespace Ink_Canvas MessageBox.Show("快捷键管理器尚未初始化,请稍后重试。", "错误", MessageBoxButton.OK, MessageBoxImage.Error); return; } - + // 暂时隐藏设置面板 BorderSettings.Visibility = Visibility.Hidden; BorderSettingsMask.Visibility = Visibility.Hidden; - + // 创建快捷键设置窗口 var hotkeySettingsWindow = new HotkeySettingsWindow(this, _globalHotkeyManager); - + // 设置窗口关闭事件,用于在快捷键设置窗口关闭后恢复设置面板 hotkeySettingsWindow.Closed += (s, e) => { @@ -2048,7 +2048,7 @@ namespace Ink_Canvas BorderSettings.Visibility = Visibility.Visible; BorderSettingsMask.Visibility = Visibility.Visible; }; - + // 显示快捷键设置窗口 hotkeySettingsWindow.ShowDialog(); } @@ -2057,7 +2057,7 @@ namespace Ink_Canvas // 确保在发生错误时也恢复设置面板显示 BorderSettings.Visibility = Visibility.Visible; BorderSettingsMask.Visibility = Visibility.Visible; - + LogHelper.WriteLogToFile($"打开快捷键设置窗口时出错: {ex.Message}", LogHelper.LogType.Error); MessageBox.Show($"打开快捷键设置窗口时出错: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } @@ -2158,13 +2158,13 @@ namespace Ink_Canvas var toggle = sender as ToggleSwitch; Settings.PowerPointSettings.ShowGestureButtonInSlideShow = toggle != null && toggle.IsOn; SaveSettingsToFile(); - + // 如果当前在PPT放映模式,需要立即更新手势按钮的显示状态 if (BtnPPTSlideShowEnd.Visibility == Visibility.Visible) { UpdateGestureButtonVisibilityInPPTMode(); } - + LogHelper.WriteLogToFile($"PPT放映模式显示手势按钮已{(Settings.PowerPointSettings.ShowGestureButtonInSlideShow ? "启用" : "禁用")}", LogHelper.LogType.Event); } catch (Exception ex) @@ -2276,11 +2276,11 @@ namespace Ink_Canvas { // 检查启动参数中是否有.icstk文件 string icstkFile = FileAssociationManager.GetIcstkFileFromArgs(App.StartArgs); - + if (!string.IsNullOrEmpty(icstkFile)) { LogHelper.WriteLogToFile($"检测到命令行参数中的.icstk文件: {icstkFile}", LogHelper.LogType.Event); - + // 延迟执行,确保UI已完全加载 Dispatcher.BeginInvoke(new Action(() => { @@ -2433,10 +2433,10 @@ namespace Ink_Canvas // 计算触摸位置对应的滑块值 var touchPoint = e.GetTouchPoint(slider); - + // 使用更精确的位置计算方法 UpdateSliderValueFromPositionImproved(slider, touchPoint.Position); - + e.Handled = true; } @@ -2449,7 +2449,7 @@ namespace Ink_Canvas // 释放触摸捕获 slider.ReleaseTouchCapture(e.TouchDevice); - + e.Handled = true; } @@ -2472,7 +2472,7 @@ namespace Ink_Canvas { UpdateSliderValueFromPositionImproved(slider, stylusPoint[0].ToPoint()); } - + e.Handled = true; } @@ -2485,7 +2485,7 @@ namespace Ink_Canvas // 释放手写笔捕获 slider.ReleaseStylusCapture(); - + e.Handled = true; } @@ -2511,9 +2511,9 @@ namespace Ink_Canvas // 获取轨道的实际边界 var trackBounds = track.TransformToAncestor(slider).TransformBounds(new Rect(0, 0, track.ActualWidth, track.ActualHeight)); - + double relativePosition = 0; - + if (slider.Orientation == System.Windows.Controls.Orientation.Horizontal) { // 水平滑块 @@ -2537,7 +2537,7 @@ namespace Ink_Canvas // 计算新的滑块值 var newValue = slider.Minimum + relativePosition * (slider.Maximum - slider.Minimum); - + // 如果启用了吸附到刻度,则调整到最近的刻度 if (slider.IsSnapToTickEnabled && slider.TickFrequency > 0) { @@ -2570,7 +2570,7 @@ namespace Ink_Canvas { // 使用更简单直接的方法计算滑块值 double relativePosition = 0; - + if (slider.Orientation == System.Windows.Controls.Orientation.Horizontal) { // 水平滑块 - 使用滑块的实际宽度 @@ -2600,7 +2600,7 @@ namespace Ink_Canvas // 计算新的滑块值 var newValue = slider.Minimum + relativePosition * (slider.Maximum - slider.Minimum); - + // 如果启用了吸附到刻度,则调整到最近的刻度 if (slider.IsSnapToTickEnabled && slider.TickFrequency > 0) { @@ -2633,7 +2633,7 @@ namespace Ink_Canvas if (toggle != null) { Settings.ModeSettings.IsPPTOnlyMode = toggle.IsOn; - + // 如果切换到仅PPT模式,立即隐藏主窗口 if (Settings.ModeSettings.IsPPTOnlyMode) { diff --git a/Ink Canvas/MainWindow_cs/MW_AutoFold.cs b/Ink Canvas/MainWindow_cs/MW_AutoFold.cs index 0bdc0c14..5f904880 100644 --- a/Ink Canvas/MainWindow_cs/MW_AutoFold.cs +++ b/Ink Canvas/MainWindow_cs/MW_AutoFold.cs @@ -260,7 +260,7 @@ namespace Ink_Canvas } // 只有在PPT放映模式下且页数有效时才显示翻页按钮 - if (StackPanelPPTControls.Visibility == Visibility.Visible && + if (StackPanelPPTControls.Visibility == Visibility.Visible && BtnPPTSlideShowEnd.Visibility == Visibility.Visible && PPTManager?.IsInSlideShow == true && PPTManager?.SlidesCount > 0) @@ -288,17 +288,17 @@ namespace Ink_Canvas { // 强制更新布局以确保ActualWidth正确 ViewboxFloatingBar.UpdateLayout(); - + // 等待一小段时间让布局完全更新 Task.Delay(50); - + // 再次强制更新布局 ViewboxFloatingBar.UpdateLayout(); - + // 强制重新测量和排列 ViewboxFloatingBar.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); ViewboxFloatingBar.Arrange(new Rect(ViewboxFloatingBar.DesiredSize)); - + if (BtnPPTSlideShowEnd.Visibility == Visibility.Visible) ViewboxFloatingBarMarginAnimation(60); else @@ -314,7 +314,7 @@ namespace Ink_Canvas { // 等待UI完全更新 await Task.Delay(100); - + // 获取当前选中的模式并重新设置高光位置 string selectedToolMode = GetCurrentSelectedMode(); if (!string.IsNullOrEmpty(selectedToolMode)) diff --git a/Ink Canvas/MainWindow_cs/MW_Eraser.cs b/Ink Canvas/MainWindow_cs/MW_Eraser.cs index 85ee7dcf..7cea34a9 100644 --- a/Ink Canvas/MainWindow_cs/MW_Eraser.cs +++ b/Ink Canvas/MainWindow_cs/MW_Eraser.cs @@ -750,7 +750,7 @@ namespace Ink_Canvas { overlay.CaptureMouse(); StartAdvancedEraserOperation(sender); - + // 处理单点擦除 var position = e.GetPosition((UIElement)FindName("inkCanvas")); UpdateAdvancedEraserPosition(sender, position); @@ -791,7 +791,7 @@ namespace Ink_Canvas overlay.CaptureStylus(); } StartAdvancedEraserOperation(sender); - + // 处理单点擦除 var position = e.GetPosition((UIElement)FindName("inkCanvas")); UpdateAdvancedEraserPosition(sender, position); diff --git a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs index a3c6a092..c9671f5b 100644 --- a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs +++ b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs @@ -674,7 +674,7 @@ namespace Ink_Canvas HideSubPanelsImmediately(); // 只有在PPT放映模式下且页数有效时才显示翻页按钮 - if (StackPanelPPTControls.Visibility == Visibility.Visible && + if (StackPanelPPTControls.Visibility == Visibility.Visible && BtnPPTSlideShowEnd.Visibility == Visibility.Visible && PPTManager?.IsInSlideShow == true && PPTManager?.SlidesCount > 0) @@ -696,7 +696,7 @@ namespace Ink_Canvas RightSidePanelForPPTNavigation.Visibility = Visibility.Collapsed; LogHelper.WriteLogToFile($"隐藏PPT翻页按钮 - 放映状态: {PPTManager?.IsInSlideShow}, 页数: {PPTManager?.SlidesCount}", LogHelper.LogType.Trace); } - + // 使用PPT UI管理器来正确更新翻页按钮显示状态,确保遵循用户设置 if (_pptUIManager != null) { @@ -833,10 +833,10 @@ namespace Ink_Canvas if (sender == SymbolIconSelect && lastBorderMouseDownObject != SymbolIconSelect) return; BtnSelect_Click(null, null); - + // 更新模式缓存 UpdateCurrentToolMode("select"); - + HideSubPanels("select"); } @@ -973,7 +973,7 @@ namespace Ink_Canvas var randWindow = new RandWindow(Settings); randWindow.Show(); - + // 使用延迟确保窗口完全显示后再强制置顶 randWindow.Dispatcher.BeginInvoke(new Action(() => { @@ -982,10 +982,10 @@ namespace Ink_Canvas // 强制激活窗口 randWindow.Activate(); randWindow.Focus(); - + // 设置置顶 randWindow.Topmost = true; - + // 使用Win32 API强制置顶 var hwnd = new WindowInteropHelper(randWindow).Handle; if (hwnd != IntPtr.Zero) @@ -1410,19 +1410,19 @@ namespace Ink_Canvas // 计算浮动栏位置,考虑快捷调色盘的显示状态 // 使用更可靠的方法获取浮动栏宽度 double baseWidth = ViewboxFloatingBar.ActualWidth; - + // 如果ActualWidth为0,尝试使用DesiredSize if (baseWidth <= 0) { baseWidth = ViewboxFloatingBar.DesiredSize.Width; } - + // 如果仍然为0,使用RenderSize if (baseWidth <= 0) { baseWidth = ViewboxFloatingBar.RenderSize.Width; } - + // 如果所有方法都失败,使用一个基于内容的估算值 if (baseWidth <= 0) { @@ -1430,9 +1430,9 @@ namespace Ink_Canvas baseWidth = 200; // 最小宽度 LogHelper.WriteLogToFile($"浮动栏宽度无法获取,使用估算值: {baseWidth}"); } - + double floatingBarWidth = baseWidth * ViewboxFloatingBarScaleTransform.ScaleX; - + // 如果快捷调色盘显示,确保有足够空间 if ((QuickColorPalettePanel != null && QuickColorPalettePanel.Visibility == Visibility.Visible) || @@ -1555,19 +1555,19 @@ namespace Ink_Canvas // 计算浮动栏位置,考虑快捷调色盘的显示状态 // 使用更可靠的方法获取浮动栏宽度 double baseWidth = ViewboxFloatingBar.ActualWidth; - + // 如果ActualWidth为0,尝试使用DesiredSize if (baseWidth <= 0) { baseWidth = ViewboxFloatingBar.DesiredSize.Width; } - + // 如果仍然为0,使用RenderSize if (baseWidth <= 0) { baseWidth = ViewboxFloatingBar.RenderSize.Width; } - + // 如果所有方法都失败,使用一个基于内容的估算值 if (baseWidth <= 0) { @@ -1575,9 +1575,9 @@ namespace Ink_Canvas baseWidth = 200; // 最小宽度 LogHelper.WriteLogToFile($"浮动栏宽度无法获取,使用估算值: {baseWidth}"); } - + double floatingBarWidth = baseWidth * ViewboxFloatingBarScaleTransform.ScaleX; - + // 如果快捷调色盘显示,确保有足够空间 if ((QuickColorPalettePanel != null && QuickColorPalettePanel.Visibility == Visibility.Visible) || @@ -1661,19 +1661,19 @@ namespace Ink_Canvas // 计算浮动栏位置,考虑快捷调色盘的显示状态 // 使用更可靠的方法获取浮动栏宽度 double baseWidth = ViewboxFloatingBar.ActualWidth; - + // 如果ActualWidth为0,尝试使用DesiredSize if (baseWidth <= 0) { baseWidth = ViewboxFloatingBar.DesiredSize.Width; } - + // 如果仍然为0,使用RenderSize if (baseWidth <= 0) { baseWidth = ViewboxFloatingBar.RenderSize.Width; } - + // 如果所有方法都失败,使用一个基于内容的估算值 if (baseWidth <= 0) { @@ -1681,9 +1681,9 @@ namespace Ink_Canvas baseWidth = 200; // 最小宽度 LogHelper.WriteLogToFile($"浮动栏宽度无法获取,使用估算值: {baseWidth}"); } - + double floatingBarWidth = baseWidth * ViewboxFloatingBarScaleTransform.ScaleX; - + // 如果快捷调色盘显示,确保有足够空间 if ((QuickColorPalettePanel != null && QuickColorPalettePanel.Visibility == Visibility.Visible) || @@ -1741,7 +1741,7 @@ namespace Ink_Canvas // 使用集中化的工具模式切换方法,确保快捷键状态正确更新 // 鼠标模式下应该禁用快捷键以放行键盘操作 SetCurrentToolMode(InkCanvasEditingMode.None); - + // 更新模式缓存,确保后续的模式检测正确 UpdateCurrentToolMode("cursor"); @@ -1880,7 +1880,7 @@ namespace Ink_Canvas { // 使用集中化的工具模式切换方法 SetCurrentToolMode(InkCanvasEditingMode.Ink); - + // 更新模式缓存 UpdateCurrentToolMode("pen"); @@ -1917,7 +1917,7 @@ namespace Ink_Canvas CheckEnableTwoFingerGestureBtnVisibility(true); // 使用集中化的工具模式切换方法 SetCurrentToolMode(InkCanvasEditingMode.Ink); - + // 更新模式缓存 UpdateCurrentToolMode("pen"); @@ -2042,7 +2042,7 @@ namespace Ink_Canvas } // 使用集中化的工具模式切换方法 SetCurrentToolMode(InkCanvasEditingMode.Ink); - + // 更新模式缓存 UpdateCurrentToolMode("pen"); @@ -2106,10 +2106,10 @@ namespace Ink_Canvas // 使用新的高级橡皮擦系统 // 使用集中化的工具模式切换方法 SetCurrentToolMode(InkCanvasEditingMode.EraseByPoint); - + // 更新模式缓存 UpdateCurrentToolMode("eraser"); - + ApplyAdvancedEraserShape(); // 使用新的橡皮擦形状应用方法 SetCursorBasedOnEditingMode(inkCanvas); HideSubPanels("eraser"); // 高亮橡皮按钮 @@ -2150,10 +2150,10 @@ namespace Ink_Canvas // 使用新的高级橡皮擦系统 // 使用集中化的工具模式切换方法 SetCurrentToolMode(InkCanvasEditingMode.EraseByPoint); - + // 更新模式缓存 UpdateCurrentToolMode("eraser"); - + ApplyAdvancedEraserShape(); // 使用新的橡皮擦形状应用方法 SetCursorBasedOnEditingMode(inkCanvas); HideSubPanels("eraser"); // 高亮橡皮按钮 @@ -2192,10 +2192,10 @@ namespace Ink_Canvas inkCanvas.EraserShape = new EllipseStylusShape(5, 5); // 使用集中化的工具模式切换方法 SetCurrentToolMode(InkCanvasEditingMode.EraseByStroke); - + // 更新模式缓存 UpdateCurrentToolMode("eraserByStrokes"); - + drawingShapeMode = 0; // 修复:切换到线擦时,保存当前的笔类型状态,而不是强制重置 diff --git a/Ink Canvas/MainWindow_cs/MW_Hotkeys.cs b/Ink Canvas/MainWindow_cs/MW_Hotkeys.cs index 5a880df1..0d585128 100644 --- a/Ink Canvas/MainWindow_cs/MW_Hotkeys.cs +++ b/Ink Canvas/MainWindow_cs/MW_Hotkeys.cs @@ -8,8 +8,8 @@ namespace Ink_Canvas private void Window_MouseWheel(object sender, MouseWheelEventArgs e) { // 只有在PPT放映模式下才响应鼠标滚轮翻页 - if (StackPanelPPTControls.Visibility != Visibility.Visible || - currentMode != 0 || + if (StackPanelPPTControls.Visibility != Visibility.Visible || + currentMode != 0 || BtnPPTSlideShowEnd.Visibility != Visibility.Visible || PPTManager?.IsInSlideShow != true) return; @@ -29,8 +29,8 @@ namespace Ink_Canvas private void Main_Grid_PreviewKeyDown(object sender, KeyEventArgs e) { // 只有在PPT放映模式下才响应键盘翻页快捷键 - if (StackPanelPPTControls.Visibility != Visibility.Visible || - currentMode != 0 || + if (StackPanelPPTControls.Visibility != Visibility.Visible || + currentMode != 0 || BtnPPTSlideShowEnd.Visibility != Visibility.Visible || PPTManager?.IsInSlideShow != true) return; diff --git a/Ink Canvas/MainWindow_cs/MW_PPT.cs b/Ink Canvas/MainWindow_cs/MW_PPT.cs index b3477302..787668ae 100644 --- a/Ink Canvas/MainWindow_cs/MW_PPT.cs +++ b/Ink Canvas/MainWindow_cs/MW_PPT.cs @@ -229,10 +229,10 @@ namespace Ink_Canvas // 创建新的PowerPoint应用程序实例 pptApplication = new Microsoft.Office.Interop.PowerPoint.Application(); - + // 设置为不可见,作为后台进程 pptApplication.Visible = MsoTriState.msoFalse; - + // 设置应用程序属性 pptApplication.WindowState = PpWindowState.ppWindowMinimized; @@ -277,9 +277,9 @@ namespace Ink_Canvas // 使用反射调用PPTManager的ConnectToPPT方法 var pptManagerType = _pptManager.GetType(); - var connectMethod = pptManagerType.GetMethod("ConnectToPPT", + var connectMethod = pptManagerType.GetMethod("ConnectToPPT", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); - + if (connectMethod != null) { connectMethod.Invoke(_pptManager, new object[] { app }); @@ -288,9 +288,9 @@ namespace Ink_Canvas else { // 如果无法通过反射调用,尝试直接设置属性 - var pptApplicationProperty = pptManagerType.GetProperty("PPTApplication", + var pptApplicationProperty = pptManagerType.GetProperty("PPTApplication", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance); - + if (pptApplicationProperty != null && pptApplicationProperty.CanWrite) { pptApplicationProperty.SetValue(_pptManager, app); @@ -317,7 +317,7 @@ namespace Ink_Canvas { if (pptApplication == null) return false; if (!Marshal.IsComObject(pptApplication)) return false; - + // 尝试访问一个简单的属性来验证连接是否有效 var _ = pptApplication.Name; return true; @@ -362,12 +362,12 @@ namespace Ink_Canvas // 退出PowerPoint应用程序 pptApplication.Quit(); - + // 释放COM对象 Marshal.ReleaseComObject(pptApplication); pptApplication = null; } - + LogHelper.WriteLogToFile("PowerPoint应用程序已关闭", LogHelper.LogType.Event); } catch (Exception ex) @@ -650,7 +650,7 @@ namespace Ink_Canvas // 在PPT模式下根据设置决定是否隐藏手势面板和手势按钮 AnimationsHelper.HideWithSlideAndFade(TwoFingerGestureBorder); AnimationsHelper.HideWithSlideAndFade(BoardTwoFingerGestureBorder); - + // 根据设置决定是否在PPT放映模式下显示手势按钮 if (Settings.PowerPointSettings.ShowGestureButtonInSlideShow) { @@ -1066,24 +1066,24 @@ namespace Ink_Canvas private void ToggleSwitchPowerPointEnhancement_Toggled(object sender, RoutedEventArgs e) { if (!isLoaded) return; - + Settings.PowerPointSettings.EnablePowerPointEnhancement = ToggleSwitchPowerPointEnhancement.IsOn; - + // 与WPS支持互斥 if (Settings.PowerPointSettings.EnablePowerPointEnhancement) { Settings.PowerPointSettings.IsSupportWPS = false; ToggleSwitchSupportWPS.IsOn = false; - + // 更新PPT管理器的WPS支持设置 if (_pptManager != null) { _pptManager.IsSupportWPS = false; } } - + SaveSettingsToFile(); - + // 启动或停止PowerPoint进程守护 if (Settings.PowerPointSettings.EnablePowerPointEnhancement) { @@ -1100,7 +1100,7 @@ namespace Ink_Canvas if (!isLoaded) return; Settings.PowerPointSettings.IsSupportWPS = ToggleSwitchSupportWPS.IsOn; - + // 与PowerPoint联动增强互斥 if (Settings.PowerPointSettings.IsSupportWPS) { diff --git a/Ink Canvas/MainWindow_cs/MW_SelectionGestures.cs b/Ink Canvas/MainWindow_cs/MW_SelectionGestures.cs index 402e51b0..71981cd6 100644 --- a/Ink Canvas/MainWindow_cs/MW_SelectionGestures.cs +++ b/Ink Canvas/MainWindow_cs/MW_SelectionGestures.cs @@ -1,3 +1,4 @@ +using Ink_Canvas.Helpers; using iNKORE.UI.WPF.Modern.Controls; using System; using System.Collections.Generic; @@ -8,7 +9,6 @@ using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Shapes; -using Ink_Canvas.Helpers; using Point = System.Windows.Point; namespace Ink_Canvas @@ -259,7 +259,7 @@ namespace Ink_Canvas private bool isStrokeDragging = false; private Point strokeDragStartPoint; private StrokeCollection StrokesSelectionClone = new StrokeCollection(); - + // 选择框和选择点相关变量 private bool isResizing = false; private string currentResizeHandle = ""; @@ -269,18 +269,18 @@ namespace Ink_Canvas private void GridInkCanvasSelectionCover_MouseDown(object sender, MouseButtonEventArgs e) { isGridInkCanvasSelectionCoverMouseDown = true; - + // 检查是否有选中的墨迹 if (inkCanvas.GetSelectedStrokes().Count > 0) { // 获取鼠标点击位置 var clickPoint = e.GetPosition(inkCanvas); var selectionBounds = inkCanvas.GetSelectionBounds(); - + // 检查点击位置是否在选择框边界内 - if (clickPoint.X >= selectionBounds.Left && - clickPoint.X <= selectionBounds.Right && - clickPoint.Y >= selectionBounds.Top && + if (clickPoint.X >= selectionBounds.Left && + clickPoint.X <= selectionBounds.Right && + clickPoint.Y >= selectionBounds.Top && clickPoint.Y <= selectionBounds.Bottom) { // 只有在选择框边界内才允许拖动 @@ -301,27 +301,27 @@ namespace Ink_Canvas private void GridInkCanvasSelectionCover_MouseMove(object sender, MouseEventArgs e) { if (!isGridInkCanvasSelectionCoverMouseDown) return; - + // 如果正在拖动墨迹,执行拖动操作 if (isStrokeDragging && GridInkCanvasSelectionCover.IsMouseCaptured) { var currentPoint = e.GetPosition(inkCanvas); var delta = currentPoint - strokeDragStartPoint; - + // 创建变换矩阵 var matrix = new Matrix(); matrix.Translate(delta.X, delta.Y); - + // 对选中的墨迹应用变换 var selectedStrokes = inkCanvas.GetSelectedStrokes(); foreach (var stroke in selectedStrokes) { stroke.Transform(matrix, false); } - + // 更新选中栏位置 updateBorderStrokeSelectionControlLocation(); - + // 更新起始点 strokeDragStartPoint = currentPoint; } @@ -335,7 +335,7 @@ namespace Ink_Canvas private void GridInkCanvasSelectionCover_MouseUp(object sender, MouseButtonEventArgs e) { if (!isGridInkCanvasSelectionCoverMouseDown) return; - + // 结束墨迹拖动 if (isStrokeDragging) { @@ -343,9 +343,9 @@ namespace Ink_Canvas GridInkCanvasSelectionCover.ReleaseMouseCapture(); GridInkCanvasSelectionCover.Cursor = Cursors.Arrow; } - + isGridInkCanvasSelectionCoverMouseDown = false; - + // 只有在没有选中墨迹时才隐藏选中栏 if (inkCanvas.GetSelectedStrokes().Count == 0) { @@ -404,7 +404,7 @@ namespace Ink_Canvas BorderImageSelectionControl.Visibility = Visibility.Collapsed; } } - + // 显示墨迹选择栏和选择框 GridInkCanvasSelectionCover.Visibility = Visibility.Visible; BorderStrokeSelectionClone.Background = Brushes.Transparent; @@ -524,7 +524,7 @@ namespace Ink_Canvas strokes = StrokesSelectionClone; else if (Settings.Gesture.IsEnableTwoFingerRotationOnSelection) m.RotateAt(rotate, center.X, center.Y); // 旋转 - + // 应用变换到选中的墨迹 foreach (var stroke in strokes) { @@ -554,29 +554,29 @@ namespace Ink_Canvas if (inkCanvas.GetSelectedStrokes().Count > 0 && dec.Count == 1) { var currentTouchPoint = e.GetTouchPoint(inkCanvas).Position; - + // 检查是否有有效的起始触摸点 if (lastTouchPointOnGridInkCanvasCover != new Point(0, 0)) { var delta = currentTouchPoint - lastTouchPointOnGridInkCanvasCover; - + // 只有当移动距离足够大时才进行拖动(避免微小移动造成的抖动) if (Math.Abs(delta.X) > 1 || Math.Abs(delta.Y) > 1) { // 创建变换矩阵 var matrix = new Matrix(); matrix.Translate(delta.X, delta.Y); - + // 对选中的墨迹应用变换 var selectedStrokes = inkCanvas.GetSelectedStrokes(); foreach (var stroke in selectedStrokes) { stroke.Transform(matrix, false); } - + // 更新选中栏位置 updateBorderStrokeSelectionControlLocation(); - + // 更新最后触摸点 lastTouchPointOnGridInkCanvasCover = currentTouchPoint; } @@ -590,29 +590,29 @@ namespace Ink_Canvas if (inkCanvas.GetSelectedStrokes().Count > 0 && dec.Count == 1) { var currentTouchPoint = e.GetTouchPoint(inkCanvas).Position; - + // 检查是否有有效的起始触摸点 if (lastTouchPointOnGridInkCanvasCover != new Point(0, 0)) { var delta = currentTouchPoint - lastTouchPointOnGridInkCanvasCover; - + // 只有当移动距离足够大时才进行拖动(避免微小移动造成的抖动) if (Math.Abs(delta.X) > 1 || Math.Abs(delta.Y) > 1) { // 创建变换矩阵 var matrix = new Matrix(); matrix.Translate(delta.X, delta.Y); - + // 对选中的墨迹应用变换 var selectedStrokes = inkCanvas.GetSelectedStrokes(); foreach (var stroke in selectedStrokes) { stroke.Transform(matrix, false); } - + // 更新选中栏位置 updateBorderStrokeSelectionControlLocation(); - + // 更新最后触摸点 lastTouchPointOnGridInkCanvasCover = currentTouchPoint; } @@ -638,15 +638,15 @@ namespace Ink_Canvas // 获取触摸点位置 var touchPosition = e.GetTouchPoint(inkCanvas).Position; var selectionBounds = inkCanvas.GetSelectionBounds(); - + // 检查触摸位置是否在选择框边界内 - if (touchPosition.X >= selectionBounds.Left && - touchPosition.X <= selectionBounds.Right && - touchPosition.Y >= selectionBounds.Top && + if (touchPosition.X >= selectionBounds.Left && + touchPosition.X <= selectionBounds.Right && + touchPosition.Y >= selectionBounds.Top && touchPosition.Y <= selectionBounds.Bottom) { - // 只有在选择框边界内才允许拖动 - // 触摸拖动状态已通过TouchMove事件处理 + // 只有在选择框边界内才允许拖动 + // 触摸拖动状态已通过TouchMove事件处理 } else { @@ -681,11 +681,11 @@ namespace Ink_Canvas { dec.Remove(e.TouchDevice.Id); if (dec.Count >= 1) return; - + // 重置触摸状态 lastTouchPointOnGridInkCanvasCover = new Point(0, 0); isProgramChangeStrokeSelection = false; - + // 检查是否有点击(没有移动) var currentTouchPoint = e.GetTouchPoint(null).Position; if (Math.Abs(currentTouchPoint.X - centerPoint.X) < 5 && Math.Abs(currentTouchPoint.Y - centerPoint.Y) < 5) @@ -694,9 +694,9 @@ namespace Ink_Canvas if (inkCanvas.GetSelectedStrokes().Count > 0) { var selectionBounds = inkCanvas.GetSelectionBounds(); - if (currentTouchPoint.X >= selectionBounds.Left && - currentTouchPoint.X <= selectionBounds.Right && - currentTouchPoint.Y >= selectionBounds.Top && + if (currentTouchPoint.X >= selectionBounds.Left && + currentTouchPoint.X <= selectionBounds.Right && + currentTouchPoint.Y >= selectionBounds.Top && currentTouchPoint.Y <= selectionBounds.Bottom) { // 点击在选择框内,保持选择 @@ -705,7 +705,7 @@ namespace Ink_Canvas return; } } - + // 点击在选择框外,取消选择 inkCanvas.Select(new StrokeCollection()); StrokesSelectionClone = new StrokeCollection(); @@ -720,7 +720,7 @@ namespace Ink_Canvas GridInkCanvasSelectionCover.Visibility = Visibility.Visible; StrokesSelectionClone = new StrokeCollection(); } - + } private void LassoSelect_Click(object sender, RoutedEventArgs e) @@ -799,7 +799,7 @@ namespace Ink_Canvas } var selectionBounds = inkCanvas.GetSelectionBounds(); - + // 更新选择框 SelectionRectangle.Visibility = Visibility.Visible; SelectionRectangle.Margin = new Thickness(selectionBounds.Left, selectionBounds.Top, 0, 0); @@ -853,10 +853,10 @@ namespace Ink_Canvas var delta = new Point(currentPoint.X - resizeStartPoint.X, currentPoint.Y - resizeStartPoint.Y); var newBounds = CalculateNewBounds(originalSelectionBounds, delta, currentResizeHandle); - + // 应用新的边界到选中的墨迹 ApplyBoundsToStrokes(newBounds); - + // 更新选择框显示 UpdateSelectionDisplay(); } @@ -934,11 +934,11 @@ namespace Ink_Canvas if (selectedStrokes.Count == 0) return; var originalBounds = inkCanvas.GetSelectionBounds(); - + // 计算缩放比例 var scaleX = newBounds.Width / originalBounds.Width; var scaleY = newBounds.Height / originalBounds.Height; - + // 计算平移量 var translateX = newBounds.X - originalBounds.X; var translateY = newBounds.Y - originalBounds.Y; diff --git a/Ink Canvas/MainWindow_cs/MW_Settings.cs b/Ink Canvas/MainWindow_cs/MW_Settings.cs index 381745de..b2a20015 100644 --- a/Ink Canvas/MainWindow_cs/MW_Settings.cs +++ b/Ink Canvas/MainWindow_cs/MW_Settings.cs @@ -197,23 +197,23 @@ namespace Ink_Canvas val > 0.5 && val < 1.25 ? val : val <= 0.5 ? 0.5 : val >= 1.25 ? 1.25 : 1; ViewboxFloatingBarScaleTransform.ScaleY = val > 0.5 && val < 1.25 ? val : val <= 0.5 ? 0.5 : val >= 1.25 ? 1.25 : 1; - + // 等待UI更新后再重新计算浮动栏位置,确保居中计算准确 Dispatcher.BeginInvoke(new Action(async () => { // 强制更新布局以确保ActualWidth正确 ViewboxFloatingBar.UpdateLayout(); - + // 等待一小段时间让布局完全更新 await Task.Delay(100); - + // 再次强制更新布局 ViewboxFloatingBar.UpdateLayout(); - + // 强制重新测量和排列 ViewboxFloatingBar.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); ViewboxFloatingBar.Arrange(new Rect(ViewboxFloatingBar.DesiredSize)); - + // auto align - 新增:只在屏幕模式下重新计算浮动栏位置 if (currentMode == 0) { diff --git a/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs b/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs index 2ce687d5..b1de7bfd 100644 --- a/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs +++ b/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs @@ -256,7 +256,7 @@ namespace Ink_Canvas _taskbar.Visibility = Settings.Appearance.EnableTrayIcon ? Visibility.Visible : Visibility.Collapsed; ViewboxFloatingBar.Opacity = Settings.Appearance.ViewboxFloatingBarOpacityValue; - + // 初始化浮动栏透明度滑块值 ViewboxFloatingBarOpacityValueSlider.Value = Settings.Appearance.ViewboxFloatingBarOpacityValue; ViewboxFloatingBarOpacityInPPTValueSlider.Value = Settings.Appearance.ViewboxFloatingBarOpacityInPPTValue; diff --git a/Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs b/Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs index d2675fa9..5f1faa5b 100644 --- a/Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs +++ b/Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs @@ -107,10 +107,10 @@ namespace Ink_Canvas else if (sender == ImageDrawArrow || sender == BoardImageDrawArrow) drawingShapeMode = 2; else if (sender == ImageDrawParallelLine || sender == BoardImageDrawParallelLine) drawingShapeMode = 15; - + // 更新模式缓存 UpdateCurrentToolMode("shape"); - + isLongPressSelected = true; if (isSingleFingerDragMode) BtnFingerDragMode_Click(BtnFingerDragMode, null); } diff --git a/Ink Canvas/MainWindow_cs/MW_Timer.cs b/Ink Canvas/MainWindow_cs/MW_Timer.cs index 6c01448e..4e3bf234 100644 --- a/Ink Canvas/MainWindow_cs/MW_Timer.cs +++ b/Ink Canvas/MainWindow_cs/MW_Timer.cs @@ -127,15 +127,15 @@ namespace Ink_Canvas { DateTime localTime = DateTime.Now; DateTime displayTime = localTime; // 默认使用本地时间 - + try { DateTime networkTime = await GetNetworkTimeAsync(); - + // 计算时间差 TimeSpan timeDifference = networkTime - localTime; double timeDifferenceMinutes = Math.Abs(timeDifference.TotalMinutes); - + // 如果网络时间与本地时间相差不超过1分钟,则使用本地时间 // 否则使用网络时间 displayTime = timeDifferenceMinutes <= 1.0 ? localTime : networkTime; @@ -145,7 +145,7 @@ namespace Ink_Canvas // 网络时间获取失败时,使用本地时间 displayTime = localTime; } - + // 只更新时间,日期由原有逻辑定时更新即可 Dispatcher.Invoke(() => { @@ -313,7 +313,7 @@ namespace Ink_Canvas var windowTitle = ForegroundWindowInfo.WindowTitle(); var windowRect = ForegroundWindowInfo.WindowRect(); var windowProcessName = ForegroundWindowInfo.ProcessName(); - + // 检测希沃白板五的批注面板 // 希沃白板五的批注面板通常具有以下特征: // 1. 窗口标题为空或包含特定关键词 @@ -323,32 +323,32 @@ namespace Ink_Canvas { // 检测希沃白板五的批注工具栏 // 批注工具栏通常高度在50-200像素之间,宽度在200-800像素之间 - if (windowRect.Height >= 50 && windowRect.Height <= 200 && + if (windowRect.Height >= 50 && windowRect.Height <= 200 && windowRect.Width >= 200 && windowRect.Width <= 800) { return true; } - + // 检测希沃白板五的二级菜单面板 // 二级菜单面板通常高度在100-400像素之间,宽度在150-400像素之间 - if (windowRect.Height >= 100 && windowRect.Height <= 400 && + if (windowRect.Height >= 100 && windowRect.Height <= 400 && windowRect.Width >= 150 && windowRect.Width <= 400) { return true; } } - + // 检测鸿合软件的批注面板 if (windowProcessName == "HiteCamera" || windowProcessName == "HiteTouchPro" || windowProcessName == "HiteLightBoard") { // 鸿合软件的批注面板特征 - if (windowRect.Height >= 50 && windowRect.Height <= 300 && + if (windowRect.Height >= 50 && windowRect.Height <= 300 && windowRect.Width >= 200 && windowRect.Width <= 600) { return true; } } - + // 原有的检测逻辑(保持向后兼容) return windowTitle.Length == 0 && windowRect.Height < 500; } diff --git a/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs b/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs index 8d1c48c8..70648fce 100644 --- a/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs +++ b/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs @@ -503,7 +503,7 @@ namespace Ink_Canvas // 计算触摸面积(使用设备提供的Size) double touchArea = size.Width * size.Height; - + // 计算宽高比(使用Bounds确保准确性) double aspectRatio = Math.Min(bounds.Width, bounds.Height) / Math.Max(bounds.Width, bounds.Height); @@ -511,7 +511,7 @@ namespace Ink_Canvas bool isLargeTouch = touchArea >= palmAreaThreshold; bool isPalmLikeShape = aspectRatio >= aspectRatioThreshold; bool hasMultipleTouchPoints = dec.Count >= minTouchPoints; - + // 新增:额外的判定条件提高准确性 bool isReasonableSize = size.Width >= 20 && size.Height >= 20 && size.Width <= 200 && size.Height <= 200; // 合理的触摸尺寸范围 bool isNotTooElongated = aspectRatio >= 0.2; // 避免过于细长的触摸(可能是手指) @@ -614,7 +614,7 @@ namespace Ink_Canvas if (isPalmEraserActive && palmEraserTouchIds.Count == 0) { LogHelper.WriteLogToFile($"Palm eraser recovery triggered - Touch points remaining: {palmEraserTouchIds.Count}, dec.Count: {dec.Count}"); - + // 恢复高光状态 drawingAttributes.IsHighlighter = palmEraserLastIsHighlighter; @@ -778,10 +778,10 @@ namespace Ink_Canvas if (isPalmEraserActive) { LogHelper.WriteLogToFile("Palm eraser force recovery - all touch points cleared"); - + // 恢复高光状态 drawingAttributes.IsHighlighter = palmEraserLastIsHighlighter; - + // 恢复编辑模式 try { @@ -807,7 +807,7 @@ namespace Ink_Canvas LogHelper.WriteLogToFile($"Palm eraser force recovery failed: {ex.Message}, forcing to Ink mode", LogHelper.LogType.Error); inkCanvas.EditingMode = InkCanvasEditingMode.Ink; } - + // 如果手掌擦还在激活状态但触摸点已清空,强制重置状态 isPalmEraserActive = false; palmEraserTouchDownHandled = false; @@ -817,10 +817,10 @@ namespace Ink_Canvas ViewboxFloatingBar.IsHitTestVisible = true; BlackboardUIGridForInkReplay.IsHitTestVisible = true; - + // 停止恢复定时器 StopPalmEraserRecoveryTimer(); - + LogHelper.WriteLogToFile("Palm eraser force recovery completed"); } } @@ -865,33 +865,33 @@ namespace Ink_Canvas return; // 三指及以上禁止缩放 bool disableScale = dec.Count >= 3; - + // 修复:允许单指拖动选中的墨迹,即使禁用了多指手势 if (isInMultiTouchMode) return; - + // 如果是单指拖动选中的墨迹,允许处理 if (dec.Count == 1 && inkCanvas.GetSelectedStrokes().Count > 0) { var md = e.DeltaManipulation; var trans = md.Translation; // 获得位移矢量 - + if (trans.X != 0 || trans.Y != 0) { var m = new Matrix(); m.Translate(trans.X, trans.Y); // 移动 - + var strokes = inkCanvas.GetSelectedStrokes(); foreach (var stroke in strokes) { stroke.Transform(m, false); } - + // 更新选择框位置 updateBorderStrokeSelectionControlLocation(); } return; } - + if (!Settings.Gesture.IsEnableTwoFingerGesture) return; if ((dec.Count >= 2 && (Settings.PowerPointSettings.IsEnableTwoFingerGestureInPresentationMode || StackPanelPPTControls.Visibility != Visibility.Visible || diff --git a/Ink Canvas/Resources/ICCConfiguration.cs b/Ink Canvas/Resources/ICCConfiguration.cs index 5ed34442..7ff5dc71 100644 --- a/Ink Canvas/Resources/ICCConfiguration.cs +++ b/Ink Canvas/Resources/ICCConfiguration.cs @@ -1,22 +1,27 @@ using System.Windows; using System.Windows.Media; -namespace Ink_Canvas.Resources.ICCConfiguration { - public enum InitialPositionTypes { +namespace Ink_Canvas.Resources.ICCConfiguration +{ + public enum InitialPositionTypes + { TopLeft, TopRight, BottomLeft, BottomRight, TopCenter, BottomCenter, Custom } - public enum ElementCornerRadiusTypes { + public enum ElementCornerRadiusTypes + { SuperEllipse, Circle, Custom, None } - public class NearSnapAreaSize { - public double[] TopLeft { get; set; } = {24,24}; - public double[] TopRight { get; set; } = {24,24}; - public double[] BottomLeft { get; set; } = {24,24}; - public double[] BottomRight { get; set; } = {24,24}; + public class NearSnapAreaSize + { + public double[] TopLeft { get; set; } = { 24, 24 }; + public double[] TopRight { get; set; } = { 24, 24 }; + public double[] BottomLeft { get; set; } = { 24, 24 }; + public double[] BottomRight { get; set; } = { 24, 24 }; public double TopCenter { get; set; } = 24; public double BottomCenter { get; set; } = 24; } - public class ICCFloatingBarConfiguration { + public class ICCFloatingBarConfiguration + { public bool SemiTransparent { get; set; } = false; public bool NearSnap { get; set; } = true; public InitialPositionTypes InitialPosition { get; set; } = InitialPositionTypes.BottomCenter; @@ -32,7 +37,8 @@ namespace Ink_Canvas.Resources.ICCConfiguration { public double MovingLimitationNoSnap { get; set; } = 12; public double MovingLimitationSnapped { get; set; } = 24; - public NearSnapAreaSize NearSnapAreaSize { get; set; } = new NearSnapAreaSize() { + public NearSnapAreaSize NearSnapAreaSize { get; set; } = new NearSnapAreaSize() + { TopLeft = new double[] { 24, 24 }, TopRight = new double[] { 24, 24 }, BottomLeft = new double[] { 24, 24 }, @@ -50,7 +56,8 @@ namespace Ink_Canvas.Resources.ICCConfiguration { }; } - public class ICCConfiguration { + public class ICCConfiguration + { public ICCFloatingBarConfiguration FloatingBar { get; set; } = new ICCFloatingBarConfiguration(); } } diff --git a/Ink Canvas/Windows/CountdownTimerWindow.xaml.cs b/Ink Canvas/Windows/CountdownTimerWindow.xaml.cs index 31e190ce..a956aff1 100644 --- a/Ink Canvas/Windows/CountdownTimerWindow.xaml.cs +++ b/Ink Canvas/Windows/CountdownTimerWindow.xaml.cs @@ -359,7 +359,8 @@ namespace Ink_Canvas // Set to center double dpiScaleX = 1, dpiScaleY = 1; PresentationSource source = PresentationSource.FromVisual(this); - if (source != null) { + if (source != null) + { dpiScaleX = source.CompositionTarget.TransformToDevice.M11; dpiScaleY = source.CompositionTarget.TransformToDevice.M22; } diff --git a/Ink Canvas/Windows/HotkeySettingsWindow.xaml.cs b/Ink Canvas/Windows/HotkeySettingsWindow.xaml.cs index b6e1f3c8..8172acbf 100644 --- a/Ink Canvas/Windows/HotkeySettingsWindow.xaml.cs +++ b/Ink Canvas/Windows/HotkeySettingsWindow.xaml.cs @@ -42,7 +42,7 @@ namespace Ink_Canvas.Windows // 加载当前快捷键(包括配置文件中的) LoadCurrentHotkeys(); SetupEventHandlers(); - + // 初始化鼠标模式快捷键设置 InitializeMouseModeSettings(); } @@ -67,10 +67,10 @@ namespace Ink_Canvas.Windows { // 设置窗口启动位置为屏幕中心 WindowStartupLocation = WindowStartupLocation.CenterScreen; - + // 确保窗口在显示时获得焦点 ShowInTaskbar = true; - + LogHelper.WriteLogToFile("快捷键设置窗口属性已设置"); } catch (Exception ex) @@ -274,10 +274,10 @@ namespace Ink_Canvas.Windows { // 设置开关的初始状态 ToggleSwitchEnableHotkeysInMouseMode.IsOn = MainWindow.Settings.Appearance.EnableHotkeysInMouseMode; - + // 绑定开关变化事件 ToggleSwitchEnableHotkeysInMouseMode.Toggled += OnMouseModeHotkeyToggleChanged; - + LogHelper.WriteLogToFile($"鼠标模式快捷键设置已初始化: {MainWindow.Settings.Appearance.EnableHotkeysInMouseMode}"); } catch (Exception ex) @@ -295,16 +295,16 @@ namespace Ink_Canvas.Windows { // 更新设置 MainWindow.Settings.Appearance.EnableHotkeysInMouseMode = ToggleSwitchEnableHotkeysInMouseMode.IsOn; - + // 立即保存设置 MainWindow.SaveSettingsToFile(); - + // 如果快捷键管理器存在,立即更新快捷键状态 if (_hotkeyManager != null) { // 检查当前是否处于鼠标模式 bool isCurrentlyMouseMode = _mainWindow.inkCanvas.EditingMode == InkCanvasEditingMode.None; - + // 如果当前处于鼠标模式且关闭了开关,立即禁用快捷键 if (isCurrentlyMouseMode && !ToggleSwitchEnableHotkeysInMouseMode.IsOn) { @@ -317,7 +317,7 @@ namespace Ink_Canvas.Windows _hotkeyManager.UpdateHotkeyStateForToolMode(isCurrentlyMouseMode); } } - + LogHelper.WriteLogToFile($"鼠标模式快捷键设置已更新: {MainWindow.Settings.Appearance.EnableHotkeysInMouseMode}", LogHelper.LogType.Event); } catch (Exception ex) diff --git a/Ink Canvas/Windows/OperatingGuideWindow.xaml.cs b/Ink Canvas/Windows/OperatingGuideWindow.xaml.cs index 3d48d677..61c50f51 100644 --- a/Ink Canvas/Windows/OperatingGuideWindow.xaml.cs +++ b/Ink Canvas/Windows/OperatingGuideWindow.xaml.cs @@ -25,17 +25,22 @@ namespace Ink_Canvas if (e.LeftButton == MouseButtonState.Pressed) DragMove(); } - private void BtnFullscreen_MouseUp(object sender, MouseButtonEventArgs e) { - if (WindowState == WindowState.Normal) { + private void BtnFullscreen_MouseUp(object sender, MouseButtonEventArgs e) + { + if (WindowState == WindowState.Normal) + { WindowState = WindowState.Maximized; SymbolIconFullscreen.Symbol = iNKORE.UI.WPF.Modern.Controls.Symbol.BackToWindow; - } else { + } + else + { WindowState = WindowState.Normal; SymbolIconFullscreen.Symbol = iNKORE.UI.WPF.Modern.Controls.Symbol.FullScreen; } } - private void SCManipulationBoundaryFeedback(object sender, ManipulationBoundaryFeedbackEventArgs e) { + private void SCManipulationBoundaryFeedback(object sender, ManipulationBoundaryFeedbackEventArgs e) + { e.Handled = true; } } diff --git a/Ink Canvas/Windows/RandWindow.xaml.cs b/Ink Canvas/Windows/RandWindow.xaml.cs index bada95f6..f8f568fe 100644 --- a/Ink Canvas/Windows/RandWindow.xaml.cs +++ b/Ink Canvas/Windows/RandWindow.xaml.cs @@ -36,10 +36,10 @@ namespace Ink_Canvas // 设置窗口为置顶 Topmost = true; - + // 添加窗口关闭事件处理 Closed += RandWindow_Closed; - + // 添加窗口显示事件处理,确保置顶 Loaded += RandWindow_Loaded; } @@ -90,10 +90,10 @@ namespace Ink_Canvas // 设置窗口为置顶 Topmost = true; - + // 添加窗口关闭事件处理 Closed += RandWindow_Closed; - + // 添加窗口显示事件处理,确保置顶 Loaded += RandWindow_Loaded; @@ -372,10 +372,10 @@ namespace Ink_Canvas // 强制激活窗口 Activate(); Focus(); - + // 设置置顶 Topmost = true; - + // 使用Win32 API强制置顶 var hwnd = new WindowInteropHelper(this).Handle; if (hwnd != IntPtr.Zero) diff --git a/Ink Canvas/Windows/ScreenshotSelectorWindow.xaml.cs b/Ink Canvas/Windows/ScreenshotSelectorWindow.xaml.cs index 242a1364..85ee727a 100644 --- a/Ink Canvas/Windows/ScreenshotSelectorWindow.xaml.cs +++ b/Ink Canvas/Windows/ScreenshotSelectorWindow.xaml.cs @@ -81,7 +81,7 @@ namespace Ink_Canvas private void BindControlPointEvents() { // 绑定所有控制点的鼠标事件 - var controlPoints = new[] + var controlPoints = new[] { TopLeftControl, TopRightControl, BottomLeftControl, BottomRightControl, TopControl, BottomControl, LeftControl, RightControl @@ -92,11 +92,11 @@ namespace Ink_Canvas control.MouseLeftButtonDown += ControlPoint_MouseLeftButtonDown; control.MouseLeftButtonUp += ControlPoint_MouseLeftButtonUp; control.MouseMove += ControlPoint_MouseMove; - + // 确保控制点能够接收鼠标事件 control.IsHitTestVisible = true; control.Focusable = false; - + // 设置控制点的Z-index,确保它们在最上层 WpfCanvas.SetZIndex(control, 1003); } @@ -142,7 +142,7 @@ namespace Ink_Canvas { // 重置所有选择状态 ResetSelectionState(); - + _isFreehandMode = false; RectangleModeButton.Background = new SolidColorBrush(Color.FromRgb(37, 99, 235)); // 蓝色 FreehandModeButton.Background = new SolidColorBrush(Color.FromRgb(107, 114, 128)); // 灰色 @@ -154,7 +154,7 @@ namespace Ink_Canvas { // 重置所有选择状态 ResetSelectionState(); - + _isFreehandMode = true; FreehandModeButton.Background = new SolidColorBrush(Color.FromRgb(37, 99, 235)); // 蓝色 RectangleModeButton.Background = new SolidColorBrush(Color.FromRgb(107, 114, 128)); // 灰色 @@ -169,7 +169,7 @@ namespace Ink_Canvas { return; } - + ConfirmSelection(); } @@ -183,10 +183,10 @@ namespace Ink_Canvas // 检查是否点击了UI元素,如果是则不处理选择 var hitElement = e.Source as FrameworkElement; if (hitElement != null && ( - hitElement is Ellipse || - hitElement is System.Windows.Controls.Button || - hitElement is Border || - hitElement is TextBlock || + hitElement is Ellipse || + hitElement is System.Windows.Controls.Button || + hitElement is Border || + hitElement is TextBlock || hitElement is StackPanel || hitElement is Separator || hitElement.Name == "SizeInfoBorder" || @@ -222,7 +222,7 @@ namespace Ink_Canvas _freehandPolyline.Points.Clear(); _freehandPoints.Add(_startPoint); _freehandPolyline.Points.Add(_startPoint); - + // 确保自由绘制路径可见 _freehandPolyline.Visibility = Visibility.Visible; } @@ -259,7 +259,7 @@ namespace Ink_Canvas // 自由绘制模式:添加点到路径 _freehandPoints.Add(_currentPoint); _freehandPolyline.Points.Add(_currentPoint); - + // 确保自由绘制路径可见 _freehandPolyline.Visibility = Visibility.Visible; } @@ -291,7 +291,7 @@ namespace Ink_Canvas { // 创建路径的副本,避免修改原始列表 var pathPoints = new List(_freehandPoints); - + // 简化路径处理,不强制闭合 // 如果路径没有闭合,自动添加起始点 if (pathPoints.Count > 0) @@ -301,13 +301,13 @@ namespace Ink_Canvas // 优化路径:移除重复点和过于接近的点,提高路径质量 var optimizedPath = OptimizePath(pathPoints); - + // 保存选择的路径 SelectedPath = optimizedPath; // 计算边界矩形用于截图 var bounds = CalculatePathBounds(optimizedPath); - + // 确保边界矩形有效 if (bounds.Width >= 0 && bounds.Height >= 0) { @@ -325,7 +325,7 @@ namespace Ink_Canvas return; } } - + // 如果自由绘制失败,清除路径并继续 _freehandPoints.Clear(); _freehandPolyline.Points.Clear(); @@ -363,7 +363,7 @@ namespace Ink_Canvas _isMoving = true; _lastMousePosition = e.GetPosition(this); - + // 确定当前控制点类型 var ellipse = sender as Ellipse; if (ellipse == TopLeftControl) _activeControlPoint = ControlPointType.TopLeft; @@ -486,26 +486,26 @@ namespace Ink_Canvas // 更新角控制点位置 WpfCanvas.SetLeft(TopLeftControl, rect.Left - 4); WpfCanvas.SetTop(TopLeftControl, rect.Top - 4); - + WpfCanvas.SetLeft(TopRightControl, rect.Right - 4); WpfCanvas.SetTop(TopRightControl, rect.Top - 4); - + WpfCanvas.SetLeft(BottomLeftControl, rect.Left - 4); WpfCanvas.SetTop(BottomLeftControl, rect.Bottom - 4); - + WpfCanvas.SetLeft(BottomRightControl, rect.Right - 4); WpfCanvas.SetTop(BottomRightControl, rect.Bottom - 4); // 更新边控制点位置 WpfCanvas.SetLeft(TopControl, rect.Left + rect.Width / 2 - 4); WpfCanvas.SetTop(TopControl, rect.Top - 4); - + WpfCanvas.SetLeft(BottomControl, rect.Left + rect.Width / 2 - 4); WpfCanvas.SetTop(BottomControl, rect.Bottom - 4); - + WpfCanvas.SetLeft(LeftControl, rect.Left - 4); WpfCanvas.SetTop(LeftControl, rect.Top + rect.Height / 2 - 4); - + WpfCanvas.SetLeft(RightControl, rect.Right - 4); WpfCanvas.SetTop(RightControl, rect.Top + rect.Height / 2 - 4); } @@ -519,7 +519,7 @@ namespace Ink_Canvas WpfCanvas.SetTop(SelectionRectangle, rect.Y); SelectionRectangle.Width = rect.Width; SelectionRectangle.Height = rect.Height; - + // 在选择过程中,禁用选择矩形的鼠标事件,避免干扰选择操作 if (_isSelecting) { @@ -547,7 +547,7 @@ namespace Ink_Canvas { // 更新选择区域的几何体 SelectionClipGeometry.Rect = selectionRect; - + // 显示透明遮罩,隐藏原始遮罩 TransparentSelectionMask.Visibility = Visibility.Visible; OverlayRectangle.Visibility = Visibility.Collapsed; @@ -569,7 +569,7 @@ namespace Ink_Canvas WpfCanvas.SetTop(SelectionRectangle, rect.Y); SelectionRectangle.Width = rect.Width; SelectionRectangle.Height = rect.Height; - + // 确保选择矩形在调整模式下能够接收鼠标事件 if (_isAdjusting) { @@ -612,7 +612,7 @@ namespace Ink_Canvas { return; } - + if (_isAdjusting) { // 转换为屏幕坐标,考虑DPI缩放 @@ -733,7 +733,7 @@ namespace Ink_Canvas _isMoving = true; _activeControlPoint = ControlPointType.Move; _lastMousePosition = e.GetPosition(this); - + // 捕获鼠标到选择矩形 SelectionRectangle.CaptureMouse(); e.Handled = true; @@ -793,12 +793,12 @@ namespace Ink_Canvas _isAdjusting = false; _isMoving = false; _activeControlPoint = ControlPointType.None; - + // 清除自由绘制的内容 _freehandPoints.Clear(); _freehandPolyline.Points.Clear(); _freehandPolyline.Visibility = Visibility.Collapsed; - + // 清除矩形选择的内容 SelectionRectangle.Visibility = Visibility.Collapsed; SelectionRectangle.IsHitTestVisible = false; @@ -806,23 +806,23 @@ namespace Ink_Canvas SizeInfoBorder.Visibility = Visibility.Collapsed; SelectionPath.Visibility = Visibility.Collapsed; AdjustModeHint.Visibility = Visibility.Collapsed; - + // 重置遮罩 TransparentSelectionMask.Visibility = Visibility.Collapsed; OverlayRectangle.Visibility = Visibility.Visible; - + // 释放鼠标捕获 if (IsMouseCaptured) { ReleaseMouseCapture(); } - + // 释放选择矩形的鼠标捕获 if (SelectionRectangle.IsMouseCaptured) { SelectionRectangle.ReleaseMouseCapture(); } - + // 重置选择区域 _currentSelection = new Rect(); SelectedArea = null; diff --git a/Ink Canvas/Windows/SettingsViews/SettingsViews/AboutPanel.xaml.cs b/Ink Canvas/Windows/SettingsViews/SettingsViews/AboutPanel.xaml.cs index ada8be75..3eef3a4a 100644 --- a/Ink Canvas/Windows/SettingsViews/SettingsViews/AboutPanel.xaml.cs +++ b/Ink Canvas/Windows/SettingsViews/SettingsViews/AboutPanel.xaml.cs @@ -1,4 +1,5 @@ -using OSVersionExtension; +using iNKORE.UI.WPF.Helpers; +using OSVersionExtension; using System; using System.Collections.Generic; using System.IO; @@ -13,31 +14,38 @@ using System.Windows.Controls.Primitives; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; -using iNKORE.UI.WPF.Helpers; -namespace Ink_Canvas.Windows.SettingsViews { +namespace Ink_Canvas.Windows.SettingsViews +{ /// /// AboutPanel.xaml 的交互逻辑 /// - public partial class AboutPanel : UserControl { - public AboutPanel() { + public partial class AboutPanel : UserControl + { + public AboutPanel() + { InitializeComponent(); // 关于页面图片横幅 - if (File.Exists(App.RootPath + "icc-about-illustrations.png")) { - try { + if (File.Exists(App.RootPath + "icc-about-illustrations.png")) + { + try + { CopyrightBannerImage.Visibility = Visibility.Visible; CopyrightBannerImage.Source = new BitmapImage(new Uri($"file://{App.RootPath + "icc-about-illustrations.png"}")); } catch { } - } else { + } + else + { CopyrightBannerImage.Visibility = Visibility.Collapsed; } // 关于页面构建时间 var buildTime = FileBuildTimeHelper.GetBuildDateTime(Assembly.GetExecutingAssembly()); - if (buildTime != null) { + if (buildTime != null) + { var bt = ((DateTimeOffset)buildTime).LocalDateTime; var m = bt.Month.ToString().PadLeft(2, '0'); var d = bt.Day.ToString().PadLeft(2, '0'); @@ -52,7 +60,8 @@ namespace Ink_Canvas.Windows.SettingsViews { AboutSystemVersion.Text = $"{OSVersion.GetOperatingSystem()} {OSVersion.GetOSVersion().Version}"; // 关于页面触摸设备 - var _t_touch = new Thread(() => { + var _t_touch = new Thread(() => + { var touchcount = TouchTabletDetectHelper.GetTouchTabletDevices().Count; var support = TouchTabletDetectHelper.IsTouchEnabled(); Dispatcher.BeginInvoke(() => @@ -61,7 +70,8 @@ namespace Ink_Canvas.Windows.SettingsViews { _t_touch.Start(); } - public static class TouchTabletDetectHelper { + public static class TouchTabletDetectHelper + { [DllImport("user32.dll")] public static extern int GetSystemMetrics(int nIndex); @@ -92,9 +102,10 @@ namespace Ink_Canvas.Windows.SettingsViews { ManagementObjectCollection collection; using (var searcher = new ManagementObjectSearcher(@"Select * From Win32_PnPEntity")) - collection = searcher.Get(); + collection = searcher.Get(); - foreach (var device in collection) { + foreach (var device in collection) + { var name = new StringBuilder((string)device.GetPropertyValue("Name")).ToString(); if (!name.Contains("Pentablet")) continue; devices.Add(new USBDeviceInfo( @@ -109,7 +120,8 @@ namespace Ink_Canvas.Windows.SettingsViews { } } - public static class FileBuildTimeHelper { + public static class FileBuildTimeHelper + { public struct _IMAGE_FILE_HEADER { public ushort Machine; @@ -146,46 +158,55 @@ namespace Ink_Canvas.Windows.SettingsViews { pinnedBuffer.Free(); } } - else + else { return null; } } } - public event EventHandler IsTopBarNeedShadowEffect; + public event EventHandler IsTopBarNeedShadowEffect; public event EventHandler IsTopBarNeedNoShadowEffect; - private void ScrollViewerEx_ScrollChanged(object sender, ScrollChangedEventArgs e) { + private void ScrollViewerEx_ScrollChanged(object sender, ScrollChangedEventArgs e) + { var scrollViewer = (ScrollViewer)sender; - if (scrollViewer.VerticalOffset >= 10) { + if (scrollViewer.VerticalOffset >= 10) + { IsTopBarNeedShadowEffect?.Invoke(this, new RoutedEventArgs()); - } else { + } + else + { IsTopBarNeedNoShadowEffect?.Invoke(this, new RoutedEventArgs()); } } - private void ScrollBar_Scroll(object sender, RoutedEventArgs e) { + private void ScrollBar_Scroll(object sender, RoutedEventArgs e) + { var scrollbar = (ScrollBar)sender; var scrollviewer = scrollbar.FindAscendant(); if (scrollviewer != null) scrollviewer.ScrollToVerticalOffset(scrollbar.Track.Value); } - private void ScrollBarTrack_MouseEnter(object sender, MouseEventArgs e) { + private void ScrollBarTrack_MouseEnter(object sender, MouseEventArgs e) + { var border = (Border)sender; - if (border.Child is Track track) { + if (border.Child is Track track) + { track.Width = 16; track.Margin = new Thickness(0, 0, -2, 0); var scrollbar = track.FindAscendant(); if (scrollbar != null) scrollbar.Width = 16; var grid = track.FindAscendant(); - if (grid.FindDescendantByName("ScrollBarBorderTrackBackground") is Border backgroundBorder) { + if (grid.FindDescendantByName("ScrollBarBorderTrackBackground") is Border backgroundBorder) + { backgroundBorder.Width = 8; backgroundBorder.CornerRadius = new CornerRadius(4); backgroundBorder.Opacity = 1; } - var thumb = track.Thumb.Template.FindName("ScrollbarThumbEx", track.Thumb) ; - if (thumb != null) { + var thumb = track.Thumb.Template.FindName("ScrollbarThumbEx", track.Thumb); + if (thumb != null) + { var _thumb = thumb as Border; _thumb.CornerRadius = new CornerRadius(4); _thumb.Width = 8; @@ -195,23 +216,27 @@ namespace Ink_Canvas.Windows.SettingsViews { } } - private void ScrollBarTrack_MouseLeave(object sender, MouseEventArgs e) { + private void ScrollBarTrack_MouseLeave(object sender, MouseEventArgs e) + { var border = (Border)sender; border.Background = new SolidColorBrush(Colors.Transparent); border.CornerRadius = new CornerRadius(0); - if (border.Child is Track track) { + if (border.Child is Track track) + { track.Width = 6; track.Margin = new Thickness(0, 0, 0, 0); var scrollbar = track.FindAscendant(); if (scrollbar != null) scrollbar.Width = 6; var grid = track.FindAscendant(); - if (grid.FindDescendantByName("ScrollBarBorderTrackBackground") is Border backgroundBorder) { + if (grid.FindDescendantByName("ScrollBarBorderTrackBackground") is Border backgroundBorder) + { backgroundBorder.Width = 3; backgroundBorder.CornerRadius = new CornerRadius(1.5); backgroundBorder.Opacity = 0; } - var thumb = track.Thumb.Template.FindName("ScrollbarThumbEx", track.Thumb) ; - if (thumb != null) { + var thumb = track.Thumb.Template.FindName("ScrollbarThumbEx", track.Thumb); + if (thumb != null) + { var _thumb = thumb as Border; _thumb.CornerRadius = new CornerRadius(1.5); _thumb.Width = 3; @@ -221,15 +246,17 @@ namespace Ink_Canvas.Windows.SettingsViews { } } - private void ScrollbarThumb_MouseDown(object sender, MouseButtonEventArgs e) { + private void ScrollbarThumb_MouseDown(object sender, MouseButtonEventArgs e) + { var thumb = (Thumb)sender; - var border = thumb.Template.FindName("ScrollbarThumbEx",thumb); + var border = thumb.Template.FindName("ScrollbarThumbEx", thumb); ((Border)border).Background = new SolidColorBrush(Color.FromRgb(95, 95, 95)); } - private void ScrollbarThumb_MouseUp(object sender, MouseButtonEventArgs e) { + private void ScrollbarThumb_MouseUp(object sender, MouseButtonEventArgs e) + { var thumb = (Thumb)sender; - var border = thumb.Template.FindName("ScrollbarThumbEx",thumb); + var border = thumb.Template.FindName("ScrollbarThumbEx", thumb); ((Border)border).Background = new SolidColorBrush(Color.FromRgb(138, 138, 138)); } } diff --git a/Ink Canvas/Windows/SettingsViews/SettingsViews/AppearancePanel.xaml.cs b/Ink Canvas/Windows/SettingsViews/SettingsViews/AppearancePanel.xaml.cs index eb6b624d..e6b0b632 100644 --- a/Ink Canvas/Windows/SettingsViews/SettingsViews/AppearancePanel.xaml.cs +++ b/Ink Canvas/Windows/SettingsViews/SettingsViews/AppearancePanel.xaml.cs @@ -2,11 +2,15 @@ using System.Windows.Controls; using System.Windows.Media; -namespace Ink_Canvas.Windows.SettingsViews { - public partial class AppearancePanel : UserControl { - public AppearancePanel() { +namespace Ink_Canvas.Windows.SettingsViews +{ + public partial class AppearancePanel : UserControl + { + public AppearancePanel() + { InitializeComponent(); - BaseView.SettingsPanels.Add(new SettingsViewPanel() { + BaseView.SettingsPanels.Add(new SettingsViewPanel() + { Title = "新版设置测试", Items = new ObservableCollection(new SettingsItem[] { new SettingsItem() { @@ -55,7 +59,8 @@ namespace Ink_Canvas.Windows.SettingsViews { }, }) }); - BaseView.SettingsPanels[0].Items[5].OnToggleSwitchToggled += (sender, args) => { + BaseView.SettingsPanels[0].Items[5].OnToggleSwitchToggled += (sender, args) => + { var item = (SettingsItem)sender; BaseView.SettingsPanels[0].Items[4].ToggleSwitchEnabled = item.ToggleSwitchToggled; }; diff --git a/Ink Canvas/Windows/SettingsViews/SettingsViews/FloatingBarDnDSettingsPanel.xaml.cs b/Ink Canvas/Windows/SettingsViews/SettingsViews/FloatingBarDnDSettingsPanel.xaml.cs index 2825972e..724b52b1 100644 --- a/Ink Canvas/Windows/SettingsViews/SettingsViews/FloatingBarDnDSettingsPanel.xaml.cs +++ b/Ink Canvas/Windows/SettingsViews/SettingsViews/FloatingBarDnDSettingsPanel.xaml.cs @@ -1,93 +1,120 @@ -using System.Collections.ObjectModel; +using iNKORE.UI.WPF.DragDrop; +using System.Collections.ObjectModel; using System.Diagnostics; using System.Windows; using System.Windows.Controls; using System.Windows.Media; -using iNKORE.UI.WPF.DragDrop; -namespace Ink_Canvas.Windows.SettingsViews { - - public class FloatingBarItem { +namespace Ink_Canvas.Windows.SettingsViews +{ + + public class FloatingBarItem + { public DrawingImage IconSource { get; set; } } - - public partial class FloatingBarDnDSettingsPanel : UserControl { - public class BarItemsDropTarget : IDropTarget { + public partial class FloatingBarDnDSettingsPanel : UserControl + { + + public class BarItemsDropTarget : IDropTarget + { public ObservableCollection BarItems { get; set; } = new ObservableCollection(); - void IDropTarget.DragOver(IDropInfo info) { + void IDropTarget.DragOver(IDropInfo info) + { info.Effects = DragDropEffects.Move; info.DropTargetAdorner = DropTargetAdorners.Insert; } - void IDropTarget.Drop(IDropInfo info) { - if (info.Data is FloatingBarItem draggedItem) { + void IDropTarget.Drop(IDropInfo info) + { + if (info.Data is FloatingBarItem draggedItem) + { var targetCollection = info.TargetCollection as ObservableCollection; var sourceCollection = info.DragInfo.SourceCollection as ObservableCollection; Trace.WriteLine(info.InsertIndex); // 在同一个 ObservableCollection 中移动 - if (targetCollection.Equals(sourceCollection)) { - if (info.InsertIndex == 0) { - targetCollection.Move(targetCollection.IndexOf(info.Data as FloatingBarItem),0); - } else if (info.InsertIndex == targetCollection.Count) { + if (targetCollection.Equals(sourceCollection)) + { + if (info.InsertIndex == 0) + { + targetCollection.Move(targetCollection.IndexOf(info.Data as FloatingBarItem), 0); + } + else if (info.InsertIndex == targetCollection.Count) + { targetCollection.Remove(info.Data as FloatingBarItem); targetCollection.Add(info.Data as FloatingBarItem); - } else if ((info.InsertIndex - targetCollection.IndexOf(info.Data as FloatingBarItem) == 1 && - info.InsertPosition == RelativeInsertPosition.AfterTargetItem) || - (info.InsertIndex - targetCollection.IndexOf(info.Data as FloatingBarItem) == 0 && - info.InsertPosition == RelativeInsertPosition.BeforeTargetItem)) { } else { - targetCollection.Move(targetCollection.IndexOf(info.Data as FloatingBarItem),info.InsertIndex - 1); } - } else { // 跨 ObservableCollection 移动 + else if ((info.InsertIndex - targetCollection.IndexOf(info.Data as FloatingBarItem) == 1 && + info.InsertPosition == RelativeInsertPosition.AfterTargetItem) || + (info.InsertIndex - targetCollection.IndexOf(info.Data as FloatingBarItem) == 0 && + info.InsertPosition == RelativeInsertPosition.BeforeTargetItem)) { } + else + { + targetCollection.Move(targetCollection.IndexOf(info.Data as FloatingBarItem), info.InsertIndex - 1); + } + } + else + { // 跨 ObservableCollection 移动 sourceCollection.Remove(info.Data as FloatingBarItem); targetCollection.Insert(info.InsertIndex, info.Data as FloatingBarItem); } } } - void IDropTarget.DragEnter(IDropInfo info) { + void IDropTarget.DragEnter(IDropInfo info) + { } - void IDropTarget.DragLeave(IDropInfo info) { - + void IDropTarget.DragLeave(IDropInfo info) + { + } } - public class BarDrawerItemsDropTarget : IDropTarget { + public class BarDrawerItemsDropTarget : IDropTarget + { public ObservableCollection BarDrawerItems { get; set; } = new ObservableCollection(); - void IDropTarget.DragOver(IDropInfo info) { + void IDropTarget.DragOver(IDropInfo info) + { info.Effects = DragDropEffects.Move; info.DropTargetAdorner = DropTargetAdorners.Insert; } - void IDropTarget.Drop(IDropInfo info) { - if (info.Data is FloatingBarItem draggedItem) { + void IDropTarget.Drop(IDropInfo info) + { + if (info.Data is FloatingBarItem draggedItem) + { var targetCollection = info.TargetCollection as ObservableCollection; var sourceCollection = info.DragInfo.SourceCollection as ObservableCollection; // 在同一个 ObservableCollection 中移动 - if (targetCollection.Equals(sourceCollection)) { + if (targetCollection.Equals(sourceCollection)) + { targetCollection.Insert(info.InsertIndex, info.Data as FloatingBarItem); - } else { // 跨 ObservableCollection 移动 + } + else + { // 跨 ObservableCollection 移动 sourceCollection.Remove(info.Data as FloatingBarItem); targetCollection.Insert(info.InsertIndex, info.Data as FloatingBarItem); } } } - void IDropTarget.DragEnter(IDropInfo info) { + void IDropTarget.DragEnter(IDropInfo info) + { } - void IDropTarget.DragLeave(IDropInfo info) { + void IDropTarget.DragLeave(IDropInfo info) + { } @@ -96,19 +123,23 @@ namespace Ink_Canvas.Windows.SettingsViews { public BarItemsDropTarget barItems { get; set; } = new BarItemsDropTarget(); public BarDrawerItemsDropTarget barDrawerItems { get; set; } = new BarDrawerItemsDropTarget(); - public FloatingBarDnDSettingsPanel() { + public FloatingBarDnDSettingsPanel() + { InitializeComponent(); ToolbarItemsControl.DataContext = barItems; ToolbarDrawerItemsControl.DataContext = barDrawerItems; - barItems.BarItems.Add(new FloatingBarItem() { + barItems.BarItems.Add(new FloatingBarItem() + { IconSource = FindResource("EraserIcon") as DrawingImage, }); - barDrawerItems.BarDrawerItems.Add(new FloatingBarItem() { + barDrawerItems.BarDrawerItems.Add(new FloatingBarItem() + { IconSource = FindResource("CursorIcon") as DrawingImage, }); - barDrawerItems.BarDrawerItems.Add(new FloatingBarItem() { + barDrawerItems.BarDrawerItems.Add(new FloatingBarItem() + { IconSource = FindResource("PenIcon") as DrawingImage, }); } diff --git a/Ink Canvas/Windows/SettingsViews/SettingsViews/SettingsBaseView.xaml.cs b/Ink Canvas/Windows/SettingsViews/SettingsViews/SettingsBaseView.xaml.cs index 365c898c..4be41c5b 100644 --- a/Ink Canvas/Windows/SettingsViews/SettingsViews/SettingsBaseView.xaml.cs +++ b/Ink Canvas/Windows/SettingsViews/SettingsViews/SettingsBaseView.xaml.cs @@ -1,4 +1,6 @@ -using System; +using iNKORE.UI.WPF.Helpers; +using iNKORE.UI.WPF.Modern.Controls; +using System; using System.Collections.ObjectModel; using System.ComponentModel; using System.Windows; @@ -6,12 +8,12 @@ using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Input; using System.Windows.Media; -using iNKORE.UI.WPF.Helpers; -using iNKORE.UI.WPF.Modern.Controls; -namespace Ink_Canvas.Windows.SettingsViews { +namespace Ink_Canvas.Windows.SettingsViews +{ - public class SettingsViewPanel { + public class SettingsViewPanel + { public string Title { get; set; } public Visibility _TitleVisibility => String.IsNullOrWhiteSpace(Title) ? Visibility.Collapsed : Visibility.Visible; public Thickness _PanelMargin => @@ -19,14 +21,16 @@ namespace Ink_Canvas.Windows.SettingsViews { public ObservableCollection Items { get; set; } = new ObservableCollection() { }; } - public enum SettingsItemType { + public enum SettingsItemType + { Plain, // 只显示Title和Description SingleToggleSwtich, ToggleSwitchWithArrowButton, SelectionButtons, } - public class SettingsItem : INotifyPropertyChanged { + public class SettingsItem : INotifyPropertyChanged + { public string Title { get; set; } public string Description { get; set; } public SettingsItemType Type { get; set; } = SettingsItemType.Plain; @@ -36,10 +40,13 @@ namespace Ink_Canvas.Windows.SettingsViews { public Visibility _ToggleSwitchVisibility => Type == SettingsItemType.SingleToggleSwtich || Type == SettingsItemType.ToggleSwitchWithArrowButton ? Visibility.Visible : Visibility.Collapsed; private bool _toggleSwitchToggled; - public bool ToggleSwitchToggled { + public bool ToggleSwitchToggled + { get => _toggleSwitchToggled; - set { - if (_toggleSwitchToggled != value) { + set + { + if (_toggleSwitchToggled != value) + { _toggleSwitchToggled = value; OnPropertyChanged(nameof(ToggleSwitchToggled)); // 通知绑定控件属性变化 OnToggleSwitchToggled?.Invoke(this, EventArgs.Empty); // 触发事件 @@ -48,15 +55,19 @@ namespace Ink_Canvas.Windows.SettingsViews { } public event EventHandler OnToggleSwitchToggled; public event PropertyChangedEventHandler PropertyChanged; - protected virtual void OnPropertyChanged(string propertyName) { + protected virtual void OnPropertyChanged(string propertyName) + { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } private SolidColorBrush _toggleSwitchBackground = new SolidColorBrush(Color.FromRgb(53, 132, 228)); - public SolidColorBrush ToggleSwitchBackground { + public SolidColorBrush ToggleSwitchBackground + { get => _toggleSwitchBackground; - set { - if (_toggleSwitchBackground != value) { + set + { + if (_toggleSwitchBackground != value) + { _toggleSwitchBackground = value; OnPropertyChanged(nameof(ToggleSwitchBackground)); // 通知绑定控件属性变化 } @@ -64,19 +75,24 @@ namespace Ink_Canvas.Windows.SettingsViews { } private bool _toggleSwitchEnabled = true; - public bool ToggleSwitchEnabled { + public bool ToggleSwitchEnabled + { get => _toggleSwitchEnabled; - set { - if (_toggleSwitchEnabled != value) { + set + { + if (_toggleSwitchEnabled != value) + { _toggleSwitchEnabled = value; OnPropertyChanged(nameof(ToggleSwitchEnabled)); // 通知绑定控件属性变化 } } } } - - public partial class SettingsBaseView : UserControl { - public SettingsBaseView() { + + public partial class SettingsBaseView : UserControl + { + public SettingsBaseView() + { InitializeComponent(); SettingsViewBaseItemsControl.ItemsSource = SettingsPanels; } @@ -84,39 +100,48 @@ namespace Ink_Canvas.Windows.SettingsViews { public ObservableCollection SettingsPanels { get; set; } = new ObservableCollection() { }; - public event EventHandler IsTopBarNeedShadowEffect; + public event EventHandler IsTopBarNeedShadowEffect; public event EventHandler IsTopBarNeedNoShadowEffect; - private void ScrollViewerEx_ScrollChanged(object sender, ScrollChangedEventArgs e) { + private void ScrollViewerEx_ScrollChanged(object sender, ScrollChangedEventArgs e) + { var scrollViewer = (ScrollViewer)sender; - if (scrollViewer.VerticalOffset >= 10) { + if (scrollViewer.VerticalOffset >= 10) + { IsTopBarNeedShadowEffect?.Invoke(this, new RoutedEventArgs()); - } else { + } + else + { IsTopBarNeedNoShadowEffect?.Invoke(this, new RoutedEventArgs()); } } - private void ScrollBar_Scroll(object sender, RoutedEventArgs e) { + private void ScrollBar_Scroll(object sender, RoutedEventArgs e) + { var scrollbar = (ScrollBar)sender; var scrollviewer = scrollbar.FindAscendant(); if (scrollviewer != null) scrollviewer.ScrollToVerticalOffset(scrollbar.Track.Value); } - private void ScrollBarTrack_MouseEnter(object sender, MouseEventArgs e) { + private void ScrollBarTrack_MouseEnter(object sender, MouseEventArgs e) + { var border = (Border)sender; - if (border.Child is Track track) { + if (border.Child is Track track) + { track.Width = 16; track.Margin = new Thickness(0, 0, -2, 0); var scrollbar = track.FindAscendant(); if (scrollbar != null) scrollbar.Width = 16; var grid = track.FindAscendant(); - if (grid.FindDescendantByName("ScrollBarBorderTrackBackground") is Border backgroundBorder) { + if (grid.FindDescendantByName("ScrollBarBorderTrackBackground") is Border backgroundBorder) + { backgroundBorder.Width = 8; backgroundBorder.CornerRadius = new CornerRadius(4); backgroundBorder.Opacity = 1; } - var thumb = track.Thumb.Template.FindName("ScrollbarThumbEx", track.Thumb) ; - if (thumb != null) { + var thumb = track.Thumb.Template.FindName("ScrollbarThumbEx", track.Thumb); + if (thumb != null) + { var _thumb = thumb as Border; _thumb.CornerRadius = new CornerRadius(4); _thumb.Width = 8; @@ -126,29 +151,34 @@ namespace Ink_Canvas.Windows.SettingsViews { } } - private void ToggleSwitch_OnToggled(object sender, RoutedEventArgs e) { + private void ToggleSwitch_OnToggled(object sender, RoutedEventArgs e) + { var toggleswitch = sender as ToggleSwitch; var item = toggleswitch.Tag as SettingsItem; item.ToggleSwitchToggled = toggleswitch.IsOn; } - private void ScrollBarTrack_MouseLeave(object sender, MouseEventArgs e) { + private void ScrollBarTrack_MouseLeave(object sender, MouseEventArgs e) + { var border = (Border)sender; border.Background = new SolidColorBrush(Colors.Transparent); border.CornerRadius = new CornerRadius(0); - if (border.Child is Track track) { + if (border.Child is Track track) + { track.Width = 6; track.Margin = new Thickness(0, 0, 0, 0); var scrollbar = track.FindAscendant(); if (scrollbar != null) scrollbar.Width = 6; var grid = track.FindAscendant(); - if (grid.FindDescendantByName("ScrollBarBorderTrackBackground") is Border backgroundBorder) { + if (grid.FindDescendantByName("ScrollBarBorderTrackBackground") is Border backgroundBorder) + { backgroundBorder.Width = 3; backgroundBorder.CornerRadius = new CornerRadius(1.5); backgroundBorder.Opacity = 0; } - var thumb = track.Thumb.Template.FindName("ScrollbarThumbEx", track.Thumb) ; - if (thumb != null) { + var thumb = track.Thumb.Template.FindName("ScrollbarThumbEx", track.Thumb); + if (thumb != null) + { var _thumb = thumb as Border; _thumb.CornerRadius = new CornerRadius(1.5); _thumb.Width = 3; @@ -158,15 +188,17 @@ namespace Ink_Canvas.Windows.SettingsViews { } } - private void ScrollbarThumb_MouseDown(object sender, MouseButtonEventArgs e) { + private void ScrollbarThumb_MouseDown(object sender, MouseButtonEventArgs e) + { var thumb = (Thumb)sender; - var border = thumb.Template.FindName("ScrollbarThumbEx",thumb); + var border = thumb.Template.FindName("ScrollbarThumbEx", thumb); ((Border)border).Background = new SolidColorBrush(Color.FromRgb(95, 95, 95)); } - private void ScrollbarThumb_MouseUp(object sender, MouseButtonEventArgs e) { + private void ScrollbarThumb_MouseUp(object sender, MouseButtonEventArgs e) + { var thumb = (Thumb)sender; - var border = thumb.Template.FindName("ScrollbarThumbEx",thumb); + var border = thumb.Template.FindName("ScrollbarThumbEx", thumb); ((Border)border).Background = new SolidColorBrush(Color.FromRgb(138, 138, 138)); } } diff --git a/Ink Canvas/Windows/SettingsViews/SettingsWindow.xaml.cs b/Ink Canvas/Windows/SettingsViews/SettingsWindow.xaml.cs index 43b15b5b..583f1021 100644 --- a/Ink Canvas/Windows/SettingsViews/SettingsWindow.xaml.cs +++ b/Ink Canvas/Windows/SettingsViews/SettingsWindow.xaml.cs @@ -1,4 +1,5 @@ -using System; +using iNKORE.UI.WPF.Helpers; +using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; @@ -8,72 +9,84 @@ using System.Windows.Controls.Primitives; using System.Windows.Data; using System.Windows.Input; using System.Windows.Media; -using iNKORE.UI.WPF.Helpers; -namespace Ink_Canvas.Windows { - public partial class SettingsWindow : Window { +namespace Ink_Canvas.Windows +{ + public partial class SettingsWindow : Window + { - public SettingsWindow() { + public SettingsWindow() + { InitializeComponent(); // 初始化侧边栏项目 SidebarItemsControl.ItemsSource = SidebarItems; - SidebarItems.Add(new SidebarItem() { + SidebarItems.Add(new SidebarItem() + { Type = SidebarItemType.Item, Title = "启动时行为", Name = "StartupItem", IconSource = FindResource("StartupIcon") as DrawingImage, Selected = false, }); - SidebarItems.Add(new SidebarItem() { + SidebarItems.Add(new SidebarItem() + { Type = SidebarItemType.Item, Title = "画板和墨迹", Name = "CanvasAndInkItem", IconSource = FindResource("CanvasAndInkIcon") as DrawingImage, Selected = false, }); - SidebarItems.Add(new SidebarItem() { + SidebarItems.Add(new SidebarItem() + { Type = SidebarItemType.Item, Title = "手势操作", Name = "GesturesItem", IconSource = FindResource("GesturesIcon") as DrawingImage, Selected = false, }); - SidebarItems.Add(new SidebarItem() { + SidebarItems.Add(new SidebarItem() + { Type = SidebarItemType.Item, Title = "墨迹纠正", Name = "InkRecognitionItem", IconSource = FindResource("InkRecognitionIcon") as DrawingImage, Selected = false, }); - SidebarItems.Add(new SidebarItem() { + SidebarItems.Add(new SidebarItem() + { Type = SidebarItemType.Separator }); - SidebarItems.Add(new SidebarItem() { + SidebarItems.Add(new SidebarItem() + { Type = SidebarItemType.Item, Title = "个性化设置", Name = "ThemeItem", IconSource = FindResource("AppearanceIcon") as DrawingImage, Selected = false, }); - SidebarItems.Add(new SidebarItem() { + SidebarItems.Add(new SidebarItem() + { Type = SidebarItemType.Item, Title = "快捷键设置", Name = "ShortcutsItem", IconSource = FindResource("AppearanceIcon") as DrawingImage, Selected = false, }); - SidebarItems.Add(new SidebarItem() { + SidebarItems.Add(new SidebarItem() + { Type = SidebarItemType.Item, Title = "崩溃处理", Name = "CrashActionItem", IconSource = FindResource("AppearanceIcon") as DrawingImage, Selected = false, }); - SidebarItems.Add(new SidebarItem() { + SidebarItems.Add(new SidebarItem() + { Type = SidebarItemType.Separator }); - SidebarItems.Add(new SidebarItem() { + SidebarItems.Add(new SidebarItem() + { Type = SidebarItemType.Item, Title = "PowerPoint 支持", Name = "PowerPointItem", @@ -81,48 +94,56 @@ namespace Ink_Canvas.Windows { Selected = false, }); - SidebarItems.Add(new SidebarItem() { + SidebarItems.Add(new SidebarItem() + { Type = SidebarItemType.Item, Title = "自动化行为", Name = "AutomationItem", IconSource = FindResource("AutomationIcon") as DrawingImage, Selected = false, }); - SidebarItems.Add(new SidebarItem() { + SidebarItems.Add(new SidebarItem() + { Type = SidebarItemType.Item, Title = "随机点名", Name = "LuckyRandomItem", IconSource = FindResource("LuckyRandomIcon") as DrawingImage, Selected = false, }); - SidebarItems.Add(new SidebarItem() { + SidebarItems.Add(new SidebarItem() + { Type = SidebarItemType.Separator }); - SidebarItems.Add(new SidebarItem() { + SidebarItems.Add(new SidebarItem() + { Type = SidebarItemType.Item, Title = "存储空间", Name = "StorageItem", IconSource = FindResource("StorageIcon") as DrawingImage, Selected = false, }); - SidebarItems.Add(new SidebarItem() { + SidebarItems.Add(new SidebarItem() + { Type = SidebarItemType.Item, Title = "截图和屏幕捕捉", Name = "SnapshotItem", IconSource = FindResource("SnapshotIcon") as DrawingImage, Selected = false, }); - SidebarItems.Add(new SidebarItem() { + SidebarItems.Add(new SidebarItem() + { Type = SidebarItemType.Separator }); - SidebarItems.Add(new SidebarItem() { + SidebarItems.Add(new SidebarItem() + { Type = SidebarItemType.Item, Title = "高级选项", Name = "AdvancedItem", IconSource = FindResource("AdvancedIcon") as DrawingImage, Selected = false, }); - SidebarItems.Add(new SidebarItem() { + SidebarItems.Add(new SidebarItem() + { Type = SidebarItemType.Item, Title = "关于 InkCanvasForClass", Name = "AboutItem", @@ -202,32 +223,37 @@ namespace Ink_Canvas.Windows { _selectedSidebarItemName = "CanvasAndInkItem"; UpdateSidebarItemsSelection(); - + // 为自定义滑块控件添加触摸支持 AddTouchSupportToCustomSliders(); } - public enum SidebarItemType { + public enum SidebarItemType + { Item, Separator } - public class SidebarItem { + public class SidebarItem + { public SidebarItemType Type { get; set; } public string Title { get; set; } public string Name { get; set; } public ImageSource IconSource { get; set; } public bool Selected { get; set; } - public Visibility _spVisibility { + public Visibility _spVisibility + { get => Type == SidebarItemType.Separator ? Visibility.Visible : Visibility.Collapsed; } - public Visibility _siVisibility { + public Visibility _siVisibility + { get => Type == SidebarItemType.Item ? Visibility.Visible : Visibility.Collapsed; } - public SolidColorBrush _siBackground { + public SolidColorBrush _siBackground + { get => Selected ? new SolidColorBrush(Color.FromRgb(217, 217, 217)) : new SolidColorBrush(Colors.Transparent); @@ -242,10 +268,13 @@ namespace Ink_Canvas.Windows { public string[] SettingsPaneTitles; public string[] SettingsPaneNames; - public void UpdateSidebarItemsSelection() { - foreach (var si in SidebarItems) { + public void UpdateSidebarItemsSelection() + { + foreach (var si in SidebarItems) + { si.Selected = si.Name == _selectedSidebarItemName; - if (si.Selected && SettingsWindowTitle != null) { + if (si.Selected && SettingsWindowTitle != null) + { SettingsWindowTitle.Text = si.Title; } } @@ -265,45 +294,57 @@ namespace Ink_Canvas.Windows { if (StoragePane != null) StoragePane.Visibility = _selectedSidebarItemName == "StorageItem" ? Visibility.Visible : Visibility.Collapsed; if (SnapshotPane != null) SnapshotPane.Visibility = _selectedSidebarItemName == "SnapshotItem" ? Visibility.Visible : Visibility.Collapsed; if (AdvancedPane != null) AdvancedPane.Visibility = _selectedSidebarItemName == "AdvancedItem" ? Visibility.Visible : Visibility.Collapsed; - if (SettingsPaneScrollViewers != null) { - foreach (var sv in SettingsPaneScrollViewers) { - if (sv != null) { + if (SettingsPaneScrollViewers != null) + { + foreach (var sv in SettingsPaneScrollViewers) + { + if (sv != null) + { sv.ScrollToTop(); } } } } - private void ScrollViewerEx_ScrollChanged(object sender, ScrollChangedEventArgs e) { + private void ScrollViewerEx_ScrollChanged(object sender, ScrollChangedEventArgs e) + { var scrollViewer = (ScrollViewer)sender; - if (scrollViewer.VerticalOffset >= 10) { + if (scrollViewer.VerticalOffset >= 10) + { DropShadowEffectTopBar.Opacity = 0.25; - } else { + } + else + { DropShadowEffectTopBar.Opacity = 0; } } - private void ScrollBar_Scroll(object sender, RoutedEventArgs e) { + private void ScrollBar_Scroll(object sender, RoutedEventArgs e) + { var scrollbar = (ScrollBar)sender; var scrollviewer = scrollbar.FindAscendant(); if (scrollviewer != null) scrollviewer.ScrollToVerticalOffset(scrollbar.Track.Value); } - private void ScrollBarTrack_MouseEnter(object sender, MouseEventArgs e) { + private void ScrollBarTrack_MouseEnter(object sender, MouseEventArgs e) + { var border = (Border)sender; - if (border.Child is Track track) { + if (border.Child is Track track) + { track.Width = 16; track.Margin = new Thickness(0, 0, -2, 0); var scrollbar = track.FindAscendant(); if (scrollbar != null) scrollbar.Width = 16; var grid = track.FindAscendant(); - if (grid.FindDescendantByName("ScrollBarBorderTrackBackground") is Border backgroundBorder) { + if (grid.FindDescendantByName("ScrollBarBorderTrackBackground") is Border backgroundBorder) + { backgroundBorder.Width = 8; backgroundBorder.CornerRadius = new CornerRadius(4); backgroundBorder.Opacity = 1; } - var thumb = track.Thumb.Template.FindName("ScrollbarThumbEx", track.Thumb) ; - if (thumb != null) { + var thumb = track.Thumb.Template.FindName("ScrollbarThumbEx", track.Thumb); + if (thumb != null) + { var _thumb = thumb as Border; _thumb.CornerRadius = new CornerRadius(4); _thumb.Width = 8; @@ -313,23 +354,27 @@ namespace Ink_Canvas.Windows { } } - private void ScrollBarTrack_MouseLeave(object sender, MouseEventArgs e) { + private void ScrollBarTrack_MouseLeave(object sender, MouseEventArgs e) + { var border = (Border)sender; border.Background = new SolidColorBrush(Colors.Transparent); border.CornerRadius = new CornerRadius(0); - if (border.Child is Track track) { + if (border.Child is Track track) + { track.Width = 6; track.Margin = new Thickness(0, 0, 0, 0); var scrollbar = track.FindAscendant(); if (scrollbar != null) scrollbar.Width = 6; var grid = track.FindAscendant(); - if (grid.FindDescendantByName("ScrollBarBorderTrackBackground") is Border backgroundBorder) { + if (grid.FindDescendantByName("ScrollBarBorderTrackBackground") is Border backgroundBorder) + { backgroundBorder.Width = 3; backgroundBorder.CornerRadius = new CornerRadius(1.5); backgroundBorder.Opacity = 0; } - var thumb = track.Thumb.Template.FindName("ScrollbarThumbEx", track.Thumb) ; - if (thumb != null) { + var thumb = track.Thumb.Template.FindName("ScrollbarThumbEx", track.Thumb); + if (thumb != null) + { var _thumb = thumb as Border; _thumb.CornerRadius = new CornerRadius(1.5); _thumb.Width = 3; @@ -339,76 +384,90 @@ namespace Ink_Canvas.Windows { } } - private void ScrollbarThumb_MouseDown(object sender, MouseButtonEventArgs e) { + private void ScrollbarThumb_MouseDown(object sender, MouseButtonEventArgs e) + { var thumb = (Thumb)sender; - var border = thumb.Template.FindName("ScrollbarThumbEx",thumb); + var border = thumb.Template.FindName("ScrollbarThumbEx", thumb); ((Border)border).Background = new SolidColorBrush(Color.FromRgb(95, 95, 95)); } - private void ScrollbarThumb_MouseUp(object sender, MouseButtonEventArgs e) { + private void ScrollbarThumb_MouseUp(object sender, MouseButtonEventArgs e) + { var thumb = (Thumb)sender; - var border = thumb.Template.FindName("ScrollbarThumbEx",thumb); + var border = thumb.Template.FindName("ScrollbarThumbEx", thumb); ((Border)border).Background = new SolidColorBrush(Color.FromRgb(138, 138, 138)); } private Border _sidebarItemMouseDownBorder = null; - private void SidebarItem_MouseDown(object sender, MouseButtonEventArgs e) { + private void SidebarItem_MouseDown(object sender, MouseButtonEventArgs e) + { if (_sidebarItemMouseDownBorder != null || _sidebarItemMouseDownBorder == sender) return; _sidebarItemMouseDownBorder = (Border)sender; var bd = sender as Border; if (bd.FindDescendantByName("MouseFeedbackBorder") is Border feedbackBd) feedbackBd.Opacity = 0.12; } - private void SidebarItem_MouseUp(object sender, MouseButtonEventArgs e) { + private void SidebarItem_MouseUp(object sender, MouseButtonEventArgs e) + { if (_sidebarItemMouseDownBorder == null || _sidebarItemMouseDownBorder != sender) return; if (_sidebarItemMouseDownBorder.Tag is SidebarItem data) _selectedSidebarItemName = data.Name; SidebarItem_MouseLeave(sender, null); UpdateSidebarItemsSelection(); } - private void SidebarItem_MouseLeave(object sender, MouseEventArgs e) { + private void SidebarItem_MouseLeave(object sender, MouseEventArgs e) + { if (_sidebarItemMouseDownBorder == null || _sidebarItemMouseDownBorder != sender) return; if (_sidebarItemMouseDownBorder.FindDescendantByName("MouseFeedbackBorder") is Border feedbackBd) feedbackBd.Opacity = 0; _sidebarItemMouseDownBorder = null; } - private void CloseButton_Click(object sender, MouseButtonEventArgs e) { + private void CloseButton_Click(object sender, MouseButtonEventArgs e) + { Close(); } - private void SearchButton_Click(object sender, MouseButtonEventArgs e) { + private void SearchButton_Click(object sender, MouseButtonEventArgs e) + { // 搜索功能 - 可以显示搜索框或搜索对话框 } - private void MenuButton_Click(object sender, MouseButtonEventArgs e) { + private void MenuButton_Click(object sender, MouseButtonEventArgs e) + { // 菜单功能 - 可以显示上下文菜单或选项菜单 } - private void ToggleSwitch_Click(object sender, MouseButtonEventArgs e) { + private void ToggleSwitch_Click(object sender, MouseButtonEventArgs e) + { var border = sender as Border; - if (border != null) { + if (border != null) + { // 切换开关状态 bool isOn = border.Background.ToString() == "#FF3584E4"; border.Background = isOn ? new SolidColorBrush(Color.FromRgb(225, 225, 225)) : new SolidColorBrush(Color.FromRgb(53, 132, 228)); - + // 切换内部圆点的位置 var innerBorder = border.Child as Border; - if (innerBorder != null) { + if (innerBorder != null) + { innerBorder.HorizontalAlignment = isOn ? HorizontalAlignment.Left : HorizontalAlignment.Right; } // 根据Tag处理不同的设置项 string tag = border.Tag?.ToString(); - if (!string.IsNullOrEmpty(tag)) { + if (!string.IsNullOrEmpty(tag)) + { HandleSettingChange(tag, !isOn); } } } - private void HandleSettingChange(string settingName, bool value) { + private void HandleSettingChange(string settingName, bool value) + { // 根据设置名称处理不同的设置项 - switch (settingName) { + switch (settingName) + { case "UseObviousCursor": // 处理使用更加明显的画笔光标设置 break; @@ -496,18 +555,22 @@ namespace Ink_Canvas.Windows { } } - private void OptionButton_Click(object sender, MouseButtonEventArgs e) { + private void OptionButton_Click(object sender, MouseButtonEventArgs e) + { var border = sender as Border; - if (border != null) { + if (border != null) + { string tag = border.Tag?.ToString(); - if (!string.IsNullOrEmpty(tag)) { + if (!string.IsNullOrEmpty(tag)) + { // 清除同组其他按钮的选中状态 ClearOtherOptionsInGroup(border, tag); - + // 设置当前按钮为选中状态 border.Background = new SolidColorBrush(Color.FromRgb(225, 225, 225)); var textBlock = border.Child as TextBlock; - if (textBlock != null) { + if (textBlock != null) + { textBlock.FontWeight = FontWeights.Bold; } @@ -517,21 +580,27 @@ namespace Ink_Canvas.Windows { } } - private void ClearOtherOptionsInGroup(Border currentBorder, string currentTag) { + private void ClearOtherOptionsInGroup(Border currentBorder, string currentTag) + { // 获取当前按钮所在的父容器 var parent = currentBorder.Parent as StackPanel; - if (parent != null) { + if (parent != null) + { // 获取组名(Tag中下划线前的部分) string groupName = currentTag.Split('_')[0]; - + // 清除同组其他按钮的选中状态 - foreach (var child in parent.Children) { - if (child is Border border && border != currentBorder) { + foreach (var child in parent.Children) + { + if (child is Border border && border != currentBorder) + { string childTag = border.Tag?.ToString(); - if (!string.IsNullOrEmpty(childTag) && childTag.StartsWith(groupName + "_")) { + if (!string.IsNullOrEmpty(childTag) && childTag.StartsWith(groupName + "_")) + { border.Background = new SolidColorBrush(Colors.Transparent); var textBlock = border.Child as TextBlock; - if (textBlock != null) { + if (textBlock != null) + { textBlock.FontWeight = FontWeights.Normal; } } @@ -540,14 +609,17 @@ namespace Ink_Canvas.Windows { } } - private void HandleOptionChange(string optionTag) { + private void HandleOptionChange(string optionTag) + { // 根据选项标签处理不同的选项变化 string[] parts = optionTag.Split('_'); - if (parts.Length >= 2) { + if (parts.Length >= 2) + { string group = parts[0]; string value = parts[1]; - - switch (group) { + + switch (group) + { case "EraserSize": // 处理板擦橡皮大小设置 break; @@ -620,7 +692,7 @@ namespace Ink_Canvas.Windows { // 查找面板中的所有自定义滑块控件 var customSliders = FindCustomSlidersInPanel(pane); - + foreach (var slider in customSliders) { AddTouchSupportToCustomSlider(slider); @@ -635,11 +707,11 @@ namespace Ink_Canvas.Windows { private List FindCustomSlidersInPanel(DependencyObject panel) { var customSliders = new List(); - + for (int i = 0; i < VisualTreeHelper.GetChildrenCount(panel); i++) { var child = VisualTreeHelper.GetChild(panel, i); - + // 检查是否是自定义滑块控件(包含GnomeSliderThumb图片的Grid) if (child is Grid grid) { @@ -649,11 +721,11 @@ namespace Ink_Canvas.Windows { customSliders.Add(customSlider); } } - + // 递归查找子元素 customSliders.AddRange(FindCustomSlidersInPanel(child)); } - + return customSliders; } @@ -668,7 +740,7 @@ namespace Ink_Canvas.Windows { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(grid); i++) { var child = VisualTreeHelper.GetChild(grid, i); - + if (child is Image image && image.Source != null) { var sourceName = image.Source.ToString(); @@ -682,12 +754,12 @@ namespace Ink_Canvas.Windows { TrackBorder = FindTrackBorderInGrid(grid), ValueBorder = FindValueBorderInGrid(grid) }; - + return customSlider; } } } - + return null; } @@ -701,7 +773,7 @@ namespace Ink_Canvas.Windows { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(grid); i++) { var child = VisualTreeHelper.GetChild(grid, i); - + if (child is Border border && border.Background != null) { var brush = border.Background as SolidColorBrush; @@ -711,7 +783,7 @@ namespace Ink_Canvas.Windows { } } } - + return null; } @@ -725,7 +797,7 @@ namespace Ink_Canvas.Windows { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(grid); i++) { var child = VisualTreeHelper.GetChild(grid, i); - + if (child is Border border && border.Background != null) { var brush = border.Background as SolidColorBrush; @@ -735,7 +807,7 @@ namespace Ink_Canvas.Windows { } } } - + return null; } @@ -881,7 +953,7 @@ namespace Ink_Canvas.Windows { // 考虑拇指大小,计算有效轨道长度 var thumbSize = 21; // 根据XAML中的Width="21" var effectiveWidth = trackWidth - thumbSize; - + // 计算相对位置(0-1之间),考虑拇指大小 var adjustedX = position.X - thumbSize / 2; var relativePosition = Math.Max(0, Math.Min(1, adjustedX / effectiveWidth)); @@ -903,7 +975,7 @@ namespace Ink_Canvas.Windows { { var valueWidth = relativePosition * trackWidth; customSlider.ValueBorder.Width = Math.Max(0, valueWidth); - + // 调整值显示Border的位置 var valueMargin = customSlider.ValueBorder.Margin; customSlider.ValueBorder.Margin = new Thickness(0, valueMargin.Top, trackWidth - valueWidth, valueMargin.Bottom); From ed5bcbde189c6243db1748ccc336d73af61fe69a Mon Sep 17 00:00:00 2001 From: CJK_mkp <113243675+CJKmkp@users.noreply.github.com> Date: Fri, 12 Sep 2025 15:58:36 +0800 Subject: [PATCH 26/80] Update feature_request.yml --- .github/ISSUE_TEMPLATE/feature_request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index ac8291f1..276b7afb 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -20,7 +20,7 @@ body: label: 需求动机 | Motivation description: 为什么需要这个功能?| Why do you need this feature? validations: - required: false + required: true - type: textarea id: design attributes: From 1c542e061569281e9002b6cf86659d7d5d55d899 Mon Sep 17 00:00:00 2001 From: CJK_mkp <113243675+CJKmkp@users.noreply.github.com> Date: Fri, 12 Sep 2025 15:59:11 +0800 Subject: [PATCH 27/80] Update bug_report.yml --- .github/ISSUE_TEMPLATE/bug_report.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index f6c695cc..0f826f70 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -39,14 +39,14 @@ body: 2. 3. validations: - required: false + required: true - type: textarea id: expected attributes: label: 期望结果 | Expected Behavior description: 你期望的正确行为或结果 | What did you expect to happen? validations: - required: false + required: true - type: textarea id: extra attributes: From 1508bd806fcf33599cc558d9fd3c5ba5c44d3497 Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sat, 13 Sep 2025 10:43:22 +0800 Subject: [PATCH 28/80] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/Helpers/GlobalHotkeyManager.cs | 1 - Ink Canvas/Helpers/PPTUIManager.cs | 3 --- Ink Canvas/MainWindow.xaml.cs | 1 - Ink Canvas/MainWindow_cs/MW_AutoFold.cs | 1 - .../MainWindow_cs/MW_FloatingBarIcons.cs | 1 - Ink Canvas/MainWindow_cs/MW_TouchEvents.cs | 7 ------- ...vasForClass.csproj.AssemblyReference.cache | Bin 35826 -> 163390 bytes 7 files changed, 14 deletions(-) diff --git a/Ink Canvas/Helpers/GlobalHotkeyManager.cs b/Ink Canvas/Helpers/GlobalHotkeyManager.cs index a5640467..804780e4 100644 --- a/Ink Canvas/Helpers/GlobalHotkeyManager.cs +++ b/Ink Canvas/Helpers/GlobalHotkeyManager.cs @@ -420,7 +420,6 @@ namespace Ink_Canvas.Helpers { // 非鼠标模式下启用快捷键 EnableHotkeyRegistration(); - LogHelper.WriteLogToFile("切换到非鼠标模式,启用快捷键"); } } catch (Exception ex) diff --git a/Ink Canvas/Helpers/PPTUIManager.cs b/Ink Canvas/Helpers/PPTUIManager.cs index dffcc2e8..8a956f58 100644 --- a/Ink Canvas/Helpers/PPTUIManager.cs +++ b/Ink Canvas/Helpers/PPTUIManager.cs @@ -190,12 +190,9 @@ namespace Ink_Canvas.Helpers if (!shouldShowButtons) { HideAllNavigationPanels(); - LogHelper.WriteLogToFile($"隐藏PPT导航面板 - 放映状态: {isInSlideShow}, 页数: {slidesCount}, 按钮设置: {ShowPPTButton}", LogHelper.LogType.Trace); return; } - LogHelper.WriteLogToFile($"显示PPT导航面板 - 放映状态: {isInSlideShow}, 页数: {slidesCount}", LogHelper.LogType.Trace); - // 设置侧边按钮位置 _mainWindow.LeftSidePanelForPPTNavigation.Margin = new Thickness(0, 0, 0, PPTLSButtonPosition * 2); _mainWindow.RightSidePanelForPPTNavigation.Margin = new Thickness(0, 0, 0, PPTRSButtonPosition * 2); diff --git a/Ink Canvas/MainWindow.xaml.cs b/Ink Canvas/MainWindow.xaml.cs index 12dbb4ed..8fe43656 100644 --- a/Ink Canvas/MainWindow.xaml.cs +++ b/Ink Canvas/MainWindow.xaml.cs @@ -2335,7 +2335,6 @@ namespace Ink_Canvas // 执行额外的操作(如果有) additionalActions?.Invoke(); - LogHelper.WriteLogToFile($"工具模式已切换到: {newMode}, 鼠标模式: {isMouseMode}", LogHelper.LogType.Trace); } catch (Exception ex) { diff --git a/Ink Canvas/MainWindow_cs/MW_AutoFold.cs b/Ink Canvas/MainWindow_cs/MW_AutoFold.cs index 5f904880..f1a08060 100644 --- a/Ink Canvas/MainWindow_cs/MW_AutoFold.cs +++ b/Ink Canvas/MainWindow_cs/MW_AutoFold.cs @@ -280,7 +280,6 @@ namespace Ink_Canvas RightBottomPanelForPPTNavigation.Visibility = Visibility.Collapsed; LeftSidePanelForPPTNavigation.Visibility = Visibility.Collapsed; RightSidePanelForPPTNavigation.Visibility = Visibility.Collapsed; - LogHelper.WriteLogToFile($"从收纳模式恢复时隐藏PPT翻页按钮 - 放映状态: {PPTManager?.IsInSlideShow}, 页数: {PPTManager?.SlidesCount}", LogHelper.LogType.Trace); } // 新增:只在屏幕模式下显示浮动栏 diff --git a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs index c9671f5b..2387af6f 100644 --- a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs +++ b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs @@ -3538,7 +3538,6 @@ namespace Ink_Canvas private void UpdateCurrentToolMode(string mode) { _currentToolMode = mode; - LogHelper.WriteLogToFile($"更新工具模式缓存: {mode}", LogHelper.LogType.Trace); } #endregion diff --git a/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs b/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs index 70648fce..4f6472c9 100644 --- a/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs +++ b/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs @@ -163,13 +163,11 @@ namespace Ink_Canvas return; } - LogHelper.WriteLogToFile($"MainWindow_StylusDown 被调用,笔尾状态: {e.StylusDevice.Inverted}, 当前 drawingShapeMode: {drawingShapeMode}, 当前 EditingMode: {inkCanvas.EditingMode}"); // 新增:根据是否为笔尾自动切换橡皮擦/画笔模式 if (e.StylusDevice.Inverted) { inkCanvas.EditingMode = InkCanvasEditingMode.EraseByPoint; - LogHelper.WriteLogToFile("检测到笔尾,设置 EditingMode 为 EraseByPoint"); } else { @@ -178,14 +176,12 @@ namespace Ink_Canvas { // 确保几何绘制模式下不切换到Ink模式,避免触摸轨迹被收集 inkCanvas.EditingMode = InkCanvasEditingMode.None; - LogHelper.WriteLogToFile("几何绘制模式,设置 EditingMode 为 None"); return; } // 修复:保持当前的线擦模式,不要强制切换到Ink模式 if (inkCanvas.EditingMode != InkCanvasEditingMode.EraseByStroke) { inkCanvas.EditingMode = InkCanvasEditingMode.Ink; - LogHelper.WriteLogToFile("设置 EditingMode 为 Ink"); } else { @@ -231,14 +227,11 @@ namespace Ink_Canvas { try { - LogHelper.WriteLogToFile($"MainWindow_StylusUp 被调用,EditingMode: {inkCanvas.EditingMode}, EnableInkFade: {Settings.Canvas.EnableInkFade}"); var stroke = GetStrokeVisual(e.StylusDevice.Id).Stroke; - LogHelper.WriteLogToFile($"获取到墨迹,StylusPoints数量: {stroke.StylusPoints.Count}"); // 正常模式:添加到画布并参与墨迹纠正 // 墨迹渐隐功能现在在 StrokeCollected 事件中统一处理所有输入方式 - LogHelper.WriteLogToFile("StylusUp: 添加墨迹到画布"); inkCanvas.Strokes.Add(stroke); await Task.Delay(5); // 避免渲染墨迹完成前预览墨迹被删除导致墨迹闪烁 diff --git a/Ink Canvas/obj/Debug/net472/InkCanvasForClass.csproj.AssemblyReference.cache b/Ink Canvas/obj/Debug/net472/InkCanvasForClass.csproj.AssemblyReference.cache index 44b9fc7383ebb573862944afd3220347eedadfaa..7126526b8065bb22cace03c7629c451ca3ed88d3 100644 GIT binary patch literal 163390 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 delta 68 zcmdn@hx5~PCJr`6eFg>w#>B}NZ9_N4zR=(9TgD{MxY^ZUjXPu5WX4*9?e1|*i~@{t YK(_kyf;=Yn?I9&hKN+Xzlrwbz010vyTmS$7 From 5d9e340d6d29eb8defa3d4dbd6d08031b165b60c Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sat, 13 Sep 2025 10:46:02 +0800 Subject: [PATCH 29/80] =?UTF-8?q?improve:=E6=A8=A1=E5=BC=8F=E5=88=87?= =?UTF-8?q?=E6=8D=A2=20issue=20#179?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs b/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs index b1de7bfd..78ccbcaa 100644 --- a/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs +++ b/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs @@ -790,6 +790,14 @@ namespace Ink_Canvas if (Settings.ModeSettings != null) { ToggleSwitchMode.IsOn = Settings.ModeSettings.IsPPTOnlyMode; + + // 根据加载的配置状态执行相应的窗口显示/隐藏逻辑 + if (isStartup && Settings.ModeSettings.IsPPTOnlyMode) + { + // 启动时如果是仅PPT模式,隐藏主窗口 + Hide(); + LogHelper.WriteLogToFile("启动时检测到仅PPT模式,主窗口已隐藏", LogHelper.LogType.Event); + } } else { From 505c6201035c94aae0307704ce3d3837bce38e95 Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sat, 13 Sep 2025 10:48:33 +0800 Subject: [PATCH 30/80] =?UTF-8?q?improve:PowerPoint=E8=81=94=E5=8A=A8?= =?UTF-8?q?=E5=A2=9E=E5=BC=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/App.xaml.cs | 21 ++++++++ Ink Canvas/Helpers/PPTManager.cs | 49 ++++++++++++++++++ ...vasForClass.csproj.AssemblyReference.cache | Bin 163390 -> 35826 bytes 3 files changed, 70 insertions(+) diff --git a/Ink Canvas/App.xaml.cs b/Ink Canvas/App.xaml.cs index 6a8c1d4e..3766fc55 100644 --- a/Ink Canvas/App.xaml.cs +++ b/Ink Canvas/App.xaml.cs @@ -292,6 +292,27 @@ namespace Ink_Canvas { string reason = e.Reason == SessionEndReasons.Logoff ? "用户注销" : "系统关机"; WriteCrashLog($"系统会话即将结束: {reason}"); + + // 清理PowerPoint进程守护 + try + { + // 获取主窗口实例并清理PowerPoint进程守护 + var mainWindow = Application.Current.MainWindow as MainWindow; + if (mainWindow != null) + { + // 通过反射调用StopPowerPointProcessMonitoring方法 + var method = mainWindow.GetType().GetMethod("StopPowerPointProcessMonitoring", + System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); + method?.Invoke(mainWindow, null); + + WriteCrashLog("PowerPoint进程守护已在系统关机时清理"); + } + } + catch (Exception ex) + { + WriteCrashLog($"清理PowerPoint进程守护失败: {ex.Message}"); + } + DeviceIdentifier.SaveUsageStatsOnShutdown(); } diff --git a/Ink Canvas/Helpers/PPTManager.cs b/Ink Canvas/Helpers/PPTManager.cs index 146e4e51..47235093 100644 --- a/Ink Canvas/Helpers/PPTManager.cs +++ b/Ink Canvas/Helpers/PPTManager.cs @@ -443,6 +443,55 @@ namespace Ink_Canvas.Helpers LogHelper.WriteLogToFile($"取消PPT事件注册失败: {ex.GetType().Name} - {ex.Message}", LogHelper.LogType.Warning); } + // 释放COM对象 + try + { + if (Marshal.IsComObject(CurrentSlide)) + { + Marshal.ReleaseComObject(CurrentSlide); + } + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"释放CurrentSlide COM对象失败: {ex}", LogHelper.LogType.Warning); + } + + try + { + if (Marshal.IsComObject(CurrentSlides)) + { + Marshal.ReleaseComObject(CurrentSlides); + } + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"释放CurrentSlides COM对象失败: {ex}", LogHelper.LogType.Warning); + } + + try + { + if (Marshal.IsComObject(CurrentPresentation)) + { + Marshal.ReleaseComObject(CurrentPresentation); + } + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"释放CurrentPresentation COM对象失败: {ex}", LogHelper.LogType.Warning); + } + + try + { + if (Marshal.IsComObject(PPTApplication)) + { + Marshal.ReleaseComObject(PPTApplication); + } + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"释放PPTApplication COM对象失败: {ex}", LogHelper.LogType.Warning); + } + // 清理引用 PPTApplication = null; CurrentPresentation = null; diff --git a/Ink Canvas/obj/Debug/net472/InkCanvasForClass.csproj.AssemblyReference.cache b/Ink Canvas/obj/Debug/net472/InkCanvasForClass.csproj.AssemblyReference.cache index 7126526b8065bb22cace03c7629c451ca3ed88d3..44b9fc7383ebb573862944afd3220347eedadfaa 100644 GIT binary patch delta 68 zcmdn@hx5~PCJr`6eFg>w#>B}NZ9_N4zR=(9TgD{MxY^ZUjXPu5WX4*9?e1|*i~@{t YK(_kyf;=Yn?I9&hKN+Xzlrwbz010vyTmS$7 literal 163390 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 From afd49f154c6535f13c4ea0ca1a9a71f11a204c48 Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sat, 13 Sep 2025 10:51:08 +0800 Subject: [PATCH 31/80] =?UTF-8?q?improve:=E6=A8=A1=E5=BC=8F=E5=88=87?= =?UTF-8?q?=E6=8D=A2=20issue=20#179?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/MainWindow.xaml.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Ink Canvas/MainWindow.xaml.cs b/Ink Canvas/MainWindow.xaml.cs index 8fe43656..8ea43625 100644 --- a/Ink Canvas/MainWindow.xaml.cs +++ b/Ink Canvas/MainWindow.xaml.cs @@ -2632,6 +2632,9 @@ namespace Ink_Canvas if (toggle != null) { Settings.ModeSettings.IsPPTOnlyMode = toggle.IsOn; + + // 保存设置到文件 + SaveSettingsToFile(); // 如果切换到仅PPT模式,立即隐藏主窗口 if (Settings.ModeSettings.IsPPTOnlyMode) From cda1f0b77dd189d492d57af95b860d9329aebd72 Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sat, 13 Sep 2025 10:55:27 +0800 Subject: [PATCH 32/80] =?UTF-8?q?fix:=E6=97=A0=E7=84=A6=E7=82=B9=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E7=8A=B6=E6=80=81=E4=B8=A2=E5=A4=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/MainWindow.xaml.cs | 9 +++++++++ Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs | 9 +++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/Ink Canvas/MainWindow.xaml.cs b/Ink Canvas/MainWindow.xaml.cs index 8ea43625..d383d3ff 100644 --- a/Ink Canvas/MainWindow.xaml.cs +++ b/Ink Canvas/MainWindow.xaml.cs @@ -50,6 +50,9 @@ namespace Ink_Canvas // 墨迹渐隐管理器 private InkFadeManager _inkFadeManager; + // 设置面板相关状态 + private bool userChangedNoFocusModeInSettings; + #region Window Initialization @@ -1933,6 +1936,12 @@ namespace Ink_Canvas { ApplyAlwaysOnTop(); } + + // 如果当前在设置面板中,标记用户已修改无焦点模式设置 + if (BorderSettings.Visibility == Visibility.Visible) + { + userChangedNoFocusModeInSettings = true; + } } private void ToggleSwitchAlwaysOnTop_Toggled(object sender, RoutedEventArgs e) diff --git a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs index 2387af6f..9ff5f482 100644 --- a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs +++ b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs @@ -364,11 +364,15 @@ namespace Ink_Canvas { BorderSettings.Visibility = Visibility.Collapsed; isOpeningOrHidingSettingsPane = false; - // 在设置面板完全关闭后,根据当前设置恢复无焦点模式 - if (Settings.Advanced.IsNoFocusMode) + // 在设置面板完全关闭后,根据情况恢复无焦点模式状态 + if (!userChangedNoFocusModeInSettings && wasNoFocusModeBeforeSettings) { + // 如果用户没有在设置中修改无焦点模式,则恢复之前的状态 + Settings.Advanced.IsNoFocusMode = true; + ToggleSwitchNoFocusMode.IsOn = true; // 同步更新设置面板中的开关状态 ApplyNoFocusMode(); } + // 如果用户在设置中修改了无焦点模式,则保持用户的修改 }; BorderSettings.Visibility = Visibility.Visible; @@ -2612,6 +2616,7 @@ namespace Ink_Canvas { // 临时禁用无焦点模式以避免下拉选项被遮挡 wasNoFocusModeBeforeSettings = Settings.Advanced.IsNoFocusMode; + userChangedNoFocusModeInSettings = false; // 重置用户修改标志 if (wasNoFocusModeBeforeSettings) { Settings.Advanced.IsNoFocusMode = false; From 3e1c3971327f6354c13412b6dfb69d5359f73f8f Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sat, 13 Sep 2025 10:58:43 +0800 Subject: [PATCH 33/80] fix:issue #160 --- Ink Canvas/MainWindow_cs/MW_Timer.cs | 61 ++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 16 deletions(-) diff --git a/Ink Canvas/MainWindow_cs/MW_Timer.cs b/Ink Canvas/MainWindow_cs/MW_Timer.cs index 4e3bf234..76d99818 100644 --- a/Ink Canvas/MainWindow_cs/MW_Timer.cs +++ b/Ink Canvas/MainWindow_cs/MW_Timer.cs @@ -65,8 +65,11 @@ namespace Ink_Canvas private Timer timerDisplayTime = new Timer(); private Timer timerDisplayDate = new Timer(); + private Timer timerNtpSync = new Timer(); private TimeViewModel nowTimeVM = new TimeViewModel(); + private DateTime cachedNetworkTime = DateTime.Now; + private DateTime lastNtpSyncTime = DateTime.MinValue; private async Task GetNetworkTimeAsync() { @@ -117,35 +120,61 @@ namespace Ink_Canvas timerDisplayDate.Elapsed += TimerDisplayDate_Elapsed; timerDisplayDate.Interval = 1000 * 60 * 60 * 1; timerDisplayDate.Start(); + timerNtpSync.Elapsed += async (s, e) => await TimerNtpSync_ElapsedAsync(); + timerNtpSync.Interval = 1000 * 60 * 60 * 2; // 每2小时同步一次 + timerNtpSync.Start(); timerKillProcess.Start(); nowTimeVM.nowDate = DateTime.Now.ToString("yyyy'年'MM'月'dd'日' dddd"); nowTimeVM.nowTime = DateTime.Now.ToString("tt hh'时'mm'分'ss'秒'"); } - // 修改TimerDisplayTime_ElapsedAsync方法中的时间格式,实现校验制 + // NTP同步定时器事件处理 + private async Task TimerNtpSync_ElapsedAsync() + { + try + { + DateTime networkTime = await GetNetworkTimeAsync(); + cachedNetworkTime = networkTime; + lastNtpSyncTime = DateTime.Now; + } + catch + { + // NTP同步失败时,保持使用本地时间 + cachedNetworkTime = DateTime.Now; + } + } + + // 修改TimerDisplayTime_ElapsedAsync方法,使用缓存的网络时间 private async Task TimerDisplayTime_ElapsedAsync() { DateTime localTime = DateTime.Now; DateTime displayTime = localTime; // 默认使用本地时间 - try + // 如果还没有进行过NTP同步,或者距离上次同步超过2小时,则进行一次同步 + if (lastNtpSyncTime == DateTime.MinValue || + (DateTime.Now - lastNtpSyncTime).TotalHours >= 2) { - DateTime networkTime = await GetNetworkTimeAsync(); - - // 计算时间差 - TimeSpan timeDifference = networkTime - localTime; - double timeDifferenceMinutes = Math.Abs(timeDifference.TotalMinutes); - - // 如果网络时间与本地时间相差不超过1分钟,则使用本地时间 - // 否则使用网络时间 - displayTime = timeDifferenceMinutes <= 1.0 ? localTime : networkTime; - } - catch - { - // 网络时间获取失败时,使用本地时间 - displayTime = localTime; + try + { + DateTime networkTime = await GetNetworkTimeAsync(); + cachedNetworkTime = networkTime; + lastNtpSyncTime = DateTime.Now; + } + catch + { + // 网络时间获取失败时,使用本地时间 + cachedNetworkTime = localTime; + } } + // 使用缓存的网络时间进行显示 + TimeSpan timeDifference = cachedNetworkTime - localTime; + double timeDifferenceMinutes = Math.Abs(timeDifference.TotalMinutes); + + // 如果网络时间与本地时间相差不超过3分钟,则使用本地时间 + // 否则使用网络时间 + displayTime = timeDifferenceMinutes <= 3.0 ? localTime : cachedNetworkTime; + // 只更新时间,日期由原有逻辑定时更新即可 Dispatcher.Invoke(() => { From 18188ef23508560ae379ce583316eb45887ccef6 Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sat, 13 Sep 2025 11:04:04 +0800 Subject: [PATCH 34/80] =?UTF-8?q?improve:=E5=BC=B9=E7=AA=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/MainWindow.xaml.cs | 2 +- Ink Canvas/MainWindow_cs/MW_Settings.cs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Ink Canvas/MainWindow.xaml.cs b/Ink Canvas/MainWindow.xaml.cs index d383d3ff..9577bf88 100644 --- a/Ink Canvas/MainWindow.xaml.cs +++ b/Ink Canvas/MainWindow.xaml.cs @@ -31,7 +31,7 @@ using Cursors = System.Windows.Input.Cursors; using DpiChangedEventArgs = System.Windows.DpiChangedEventArgs; using File = System.IO.File; using GroupBox = System.Windows.Controls.GroupBox; -using MessageBox = System.Windows.MessageBox; +using MessageBox = iNKORE.UI.WPF.Modern.Controls.MessageBox; using Point = System.Windows.Point; namespace Ink_Canvas diff --git a/Ink Canvas/MainWindow_cs/MW_Settings.cs b/Ink Canvas/MainWindow_cs/MW_Settings.cs index b2a20015..e5fd1042 100644 --- a/Ink Canvas/MainWindow_cs/MW_Settings.cs +++ b/Ink Canvas/MainWindow_cs/MW_Settings.cs @@ -1,4 +1,5 @@ using Hardcodet.Wpf.TaskbarNotification; +using iNKORE.UI.WPF.Modern.Controls; using Ink_Canvas.Helpers; using Newtonsoft.Json; using OSVersionExtension; @@ -18,7 +19,7 @@ using Application = System.Windows.Application; using CheckBox = System.Windows.Controls.CheckBox; using ComboBox = System.Windows.Controls.ComboBox; using File = System.IO.File; -using MessageBox = System.Windows.MessageBox; +using MessageBox = iNKORE.UI.WPF.Modern.Controls.MessageBox; using OpenFileDialog = Microsoft.Win32.OpenFileDialog; using OperatingSystem = OSVersionExtension.OperatingSystem; using RadioButton = System.Windows.Controls.RadioButton; From 110d050cc659106418ac636ba45bbf04a6572474 Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sat, 13 Sep 2025 11:08:56 +0800 Subject: [PATCH 35/80] fix:issue #188 --- Ink Canvas/MainWindow_cs/MW_Settings.cs | 4 + Ink Canvas/MainWindow_cs/MW_TouchEvents.cs | 118 ++++++++++++++++++++- 2 files changed, 118 insertions(+), 4 deletions(-) diff --git a/Ink Canvas/MainWindow_cs/MW_Settings.cs b/Ink Canvas/MainWindow_cs/MW_Settings.cs index e5fd1042..fd4182d3 100644 --- a/Ink Canvas/MainWindow_cs/MW_Settings.cs +++ b/Ink Canvas/MainWindow_cs/MW_Settings.cs @@ -1815,7 +1815,11 @@ namespace Ink_Canvas // 先设为None再设回原来的模式,避免可能的事件冲突 inkCanvas.EditingMode = InkCanvasEditingMode.None; + // 保存非笔画元素(如图片) + var preservedElements = PreserveNonStrokeElements(); inkCanvas.Children.Clear(); + // 恢复非笔画元素 + RestoreNonStrokeElements(preservedElements); isInMultiTouchMode = true; // 恢复到之前的编辑状态 diff --git a/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs b/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs index 4f6472c9..f03b5cbc 100644 --- a/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs +++ b/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs @@ -8,6 +8,7 @@ using System.Windows.Controls; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; +using System.Windows.Media.Imaging; using System.Windows.Threading; using Point = System.Windows.Point; @@ -30,7 +31,7 @@ namespace Ink_Canvas { var preservedElements = new List(); - // 遍历inkCanvas的所有子元素 + // 遍历inkCanvas的所有子元素,创建副本而不是直接引用 for (int i = inkCanvas.Children.Count - 1; i >= 0; i--) { var child = inkCanvas.Children[i]; @@ -39,13 +40,118 @@ namespace Ink_Canvas if (child is Image || child is MediaElement || (child is Border border && border.Name != "AdvancedEraserOverlay")) { - preservedElements.Add(child); + // 创建元素的深拷贝,避免直接引用导致的问题 + var clonedElement = CloneUIElement(child); + if (clonedElement != null) + { + preservedElements.Add(clonedElement); + } } } return preservedElements; } + /// + /// 克隆UI元素,创建深拷贝 + /// + private UIElement CloneUIElement(UIElement originalElement) + { + try + { + if (originalElement is Image originalImage) + { + var clonedImage = new Image(); + + // 复制图片源 + if (originalImage.Source is BitmapSource bitmapSource) + { + clonedImage.Source = bitmapSource; + } + + // 复制属性 + clonedImage.Width = originalImage.Width; + clonedImage.Height = originalImage.Height; + clonedImage.Stretch = originalImage.Stretch; + clonedImage.StretchDirection = originalImage.StretchDirection; + clonedImage.Name = originalImage.Name; + clonedImage.IsHitTestVisible = originalImage.IsHitTestVisible; + clonedImage.Focusable = originalImage.Focusable; + clonedImage.Cursor = originalImage.Cursor; + clonedImage.IsManipulationEnabled = originalImage.IsManipulationEnabled; + + // 复制位置 + InkCanvas.SetLeft(clonedImage, InkCanvas.GetLeft(originalImage)); + InkCanvas.SetTop(clonedImage, InkCanvas.GetTop(originalImage)); + + // 复制变换 + if (originalImage.RenderTransform != null) + { + clonedImage.RenderTransform = originalImage.RenderTransform.Clone(); + } + + return clonedImage; + } + else if (originalElement is MediaElement originalMedia) + { + var clonedMedia = new MediaElement(); + + // 复制媒体属性 + clonedMedia.Source = originalMedia.Source; + clonedMedia.Width = originalMedia.Width; + clonedMedia.Height = originalMedia.Height; + clonedMedia.Name = originalMedia.Name; + clonedMedia.IsHitTestVisible = originalMedia.IsHitTestVisible; + clonedMedia.Focusable = originalMedia.Focusable; + + // 复制位置 + InkCanvas.SetLeft(clonedMedia, InkCanvas.GetLeft(originalMedia)); + InkCanvas.SetTop(clonedMedia, InkCanvas.GetTop(originalMedia)); + + // 复制变换 + if (originalMedia.RenderTransform != null) + { + clonedMedia.RenderTransform = originalMedia.RenderTransform.Clone(); + } + + return clonedMedia; + } + else if (originalElement is Border originalBorder) + { + var clonedBorder = new Border(); + + // 复制边框属性 + clonedBorder.Width = originalBorder.Width; + clonedBorder.Height = originalBorder.Height; + clonedBorder.Name = originalBorder.Name; + clonedBorder.IsHitTestVisible = originalBorder.IsHitTestVisible; + clonedBorder.Focusable = originalBorder.Focusable; + clonedBorder.Background = originalBorder.Background; + clonedBorder.BorderBrush = originalBorder.BorderBrush; + clonedBorder.BorderThickness = originalBorder.BorderThickness; + clonedBorder.CornerRadius = originalBorder.CornerRadius; + + // 复制位置 + InkCanvas.SetLeft(clonedBorder, InkCanvas.GetLeft(originalBorder)); + InkCanvas.SetTop(clonedBorder, InkCanvas.GetTop(originalBorder)); + + // 复制变换 + if (originalBorder.RenderTransform != null) + { + clonedBorder.RenderTransform = originalBorder.RenderTransform.Clone(); + } + + return clonedBorder; + } + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"克隆UI元素失败: {ex.Message}", LogHelper.LogType.Error); + } + + return null; + } + /// /// 恢复之前保存的非笔画元素到画布 /// @@ -55,11 +161,15 @@ namespace Ink_Canvas foreach (var element in preservedElements) { - // 确保元素没有父容器再添加到inkCanvas - if (element is FrameworkElement fe && fe.Parent == null) + try { + // 由于现在使用的是克隆的元素,不需要检查Parent属性 inkCanvas.Children.Add(element); } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"恢复非笔画元素失败: {ex.Message}", LogHelper.LogType.Error); + } } } From c6a48f79da115ea07735a28aeb7684aff13b41d7 Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sat, 13 Sep 2025 11:29:48 +0800 Subject: [PATCH 36/80] fix:issue #184 --- Ink Canvas/MainWindow_cs/MW_PPT.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Ink Canvas/MainWindow_cs/MW_PPT.cs b/Ink Canvas/MainWindow_cs/MW_PPT.cs index 787668ae..5c90a6fb 100644 --- a/Ink Canvas/MainWindow_cs/MW_PPT.cs +++ b/Ink Canvas/MainWindow_cs/MW_PPT.cs @@ -88,6 +88,10 @@ namespace Ink_Canvas // PowerPoint应用程序守护相关字段 private DispatcherTimer _powerPointProcessMonitorTimer; private const int ProcessMonitorInterval = 5000; // 应用程序监控间隔(毫秒) + + // 上次播放位置相关字段 + private int _lastPlaybackPage = 0; + private bool _shouldNavigateToLastPage = false; #endregion #region PPT Managers @@ -613,11 +617,16 @@ namespace Ink_Canvas await Application.Current.Dispatcher.InvokeAsync(() => { - // 处理跳转到首页 + // 处理跳转到首页或上次播放位置 if (Settings.PowerPointSettings.IsAlwaysGoToFirstPageOnReenter) { _pptManager?.TryNavigateToSlide(1); } + else if (_shouldNavigateToLastPage && _lastPlaybackPage > 0) + { + _pptManager?.TryNavigateToSlide(_lastPlaybackPage); + _shouldNavigateToLastPage = false; // 重置标志位 + } // 更新UI状态 var currentSlide = _pptManager?.GetCurrentSlideNumber() ?? 0; @@ -851,9 +860,10 @@ namespace Ink_Canvas if (int.TryParse(File.ReadAllText(positionFile), out var page) && page > 0) { + _lastPlaybackPage = page; new YesOrNoNotificationWindow($"上次播放到了第 {page} 页, 是否立即跳转", () => { - _pptManager?.TryNavigateToSlide(page); + _shouldNavigateToLastPage = true; }).ShowDialog(); } } From 9fd31b05848e360b312da6cded4ac6128f177e0f Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sat, 13 Sep 2025 11:32:08 +0800 Subject: [PATCH 37/80] =?UTF-8?q?improve:=E6=8F=8F=E8=BF=B0=E6=80=A7?= =?UTF-8?q?=E6=96=87=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/MainWindow.xaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Ink Canvas/MainWindow.xaml b/Ink Canvas/MainWindow.xaml index 70c8200a..ab66b0e7 100644 --- a/Ink Canvas/MainWindow.xaml +++ b/Ink Canvas/MainWindow.xaml @@ -538,7 +538,7 @@ - 选择软件运行模式。仅PPT模式下,软件将完全隐藏,仅在PPT放映时出现。 + 选择软件运行模式。仅PPT模式下,软件将完全隐藏,仅在PPT放映时出现。(实验性功能,可能不稳定。) + From 0344e51ef7b7d166c9fd4a69514607118a1987e0 Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sat, 13 Sep 2025 11:38:46 +0800 Subject: [PATCH 38/80] fix:issue #185 --- .../MainWindow_cs/MW_ElementsControls.cs | 11 ++- Ink Canvas/MainWindow_cs/MW_TouchEvents.cs | 87 ++++++++++++++++++- 2 files changed, 95 insertions(+), 3 deletions(-) diff --git a/Ink Canvas/MainWindow_cs/MW_ElementsControls.cs b/Ink Canvas/MainWindow_cs/MW_ElementsControls.cs index 97b37634..0daf4189 100644 --- a/Ink Canvas/MainWindow_cs/MW_ElementsControls.cs +++ b/Ink Canvas/MainWindow_cs/MW_ElementsControls.cs @@ -196,7 +196,16 @@ namespace Ink_Canvas { if (sender is FrameworkElement element) { - // 使用触摸拖动的完整实现 + // 检查是否是双指手势 + if (e.Manipulators.Count() >= 2) + { + // 双指手势时,不处理单个元素的手势,让画布级别的手势处理 + // 这样可以实现图片与墨迹的同步移动 + e.Handled = false; + return; + } + + // 单指手势时,使用触摸拖动的完整实现 ApplyTouchManipulationTransform(element, e); // 如果是图片元素,更新工具栏位置 diff --git a/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs b/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs index f03b5cbc..8e9c40dc 100644 --- a/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs +++ b/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs @@ -1069,12 +1069,15 @@ namespace Ink_Canvas catch { } } - ; + // 同时变换画布上的图片元素 + TransformCanvasImages(m); } else { foreach (var stroke in inkCanvas.Strokes) stroke.Transform(m, false); - ; + + // 同时变换画布上的图片元素 + TransformCanvasImages(m); } foreach (var circle in circles) @@ -1092,6 +1095,86 @@ namespace Ink_Canvas } } + /// + /// 变换画布上的图片元素,使其与墨迹同步移动 + /// + private void TransformCanvasImages(Matrix matrix) + { + try + { + // 遍历inkCanvas的所有子元素,找到图片元素 + for (int i = inkCanvas.Children.Count - 1; i >= 0; i--) + { + var child = inkCanvas.Children[i]; + + if (child is Image image) + { + // 应用矩阵变换到图片 + ApplyMatrixTransformToImage(image, matrix); + } + else if (child is MediaElement mediaElement) + { + // 对媒体元素也应用变换 + ApplyMatrixTransformToMediaElement(mediaElement, matrix); + } + } + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"变换画布图片失败: {ex.Message}", LogHelper.LogType.Error); + } + } + + /// + /// 对图片应用矩阵变换 + /// + private void ApplyMatrixTransformToImage(Image image, Matrix matrix) + { + try + { + // 获取图片的RenderTransform,如果不存在则创建新的TransformGroup + TransformGroup transformGroup = image.RenderTransform as TransformGroup; + if (transformGroup == null) + { + transformGroup = new TransformGroup(); + image.RenderTransform = transformGroup; + } + + // 创建新的MatrixTransform并添加到变换组 + var matrixTransform = new MatrixTransform(matrix); + transformGroup.Children.Add(matrixTransform); + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"应用图片变换失败: {ex.Message}", LogHelper.LogType.Error); + } + } + + /// + /// 对媒体元素应用矩阵变换 + /// + private void ApplyMatrixTransformToMediaElement(MediaElement mediaElement, Matrix matrix) + { + try + { + // 获取媒体元素的RenderTransform,如果不存在则创建新的TransformGroup + TransformGroup transformGroup = mediaElement.RenderTransform as TransformGroup; + if (transformGroup == null) + { + transformGroup = new TransformGroup(); + mediaElement.RenderTransform = transformGroup; + } + + // 创建新的MatrixTransform并添加到变换组 + var matrixTransform = new MatrixTransform(matrix); + transformGroup.Children.Add(matrixTransform); + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"应用媒体元素变换失败: {ex.Message}", LogHelper.LogType.Error); + } + } + // 退出多指书写模式,恢复InkCanvas的TouchDown事件绑定 private void ExitMultiTouchModeIfNeeded() { From e80e64a2879f978b1373a3f02c97d15539c42539 Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sat, 13 Sep 2025 11:46:49 +0800 Subject: [PATCH 39/80] =?UTF-8?q?fix:=E6=89=8B=E5=8A=BF=E5=BC=80=E5=85=B3?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E6=98=BE=E7=A4=BA=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs index 9ff5f482..cb3538e4 100644 --- a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs +++ b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs @@ -78,6 +78,7 @@ namespace Ink_Canvas { if (ToggleSwitchEnableMultiTouchMode.IsOn) { + // 多指书写模式启用时,手势功能被禁用 TwoFingerGestureSimpleStackPanel.Opacity = 0.5; TwoFingerGestureSimpleStackPanel.IsHitTestVisible = false; EnableTwoFingerGestureBtn.Source = @@ -93,9 +94,14 @@ namespace Ink_Canvas } else { + // 多指书写模式禁用时,根据实际手势功能状态显示 TwoFingerGestureSimpleStackPanel.Opacity = 1; TwoFingerGestureSimpleStackPanel.IsHitTestVisible = true; - if (Settings.Gesture.IsEnableTwoFingerGesture) + + // 检查是否有任何手势功能启用 + bool hasGestureEnabled = Settings.Gesture.IsEnableTwoFingerGesture; + + if (hasGestureEnabled) { EnableTwoFingerGestureBtn.Source = new BitmapImage(new Uri("/Resources/new-icons/gesture-enabled.png", UriKind.Relative)); From 2da5e8d71b66ce384363778914d5b41c793e822b Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sat, 13 Sep 2025 11:56:26 +0800 Subject: [PATCH 40/80] =?UTF-8?q?fix:=E5=8A=A8=E7=94=BB=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E7=9A=84=E6=94=B6=E7=BA=B3=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/MainWindow_cs/MW_AutoFold.cs | 2 +- Ink Canvas/MainWindow_cs/MW_PPT.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Ink Canvas/MainWindow_cs/MW_AutoFold.cs b/Ink Canvas/MainWindow_cs/MW_AutoFold.cs index f1a08060..8e8d34b7 100644 --- a/Ink Canvas/MainWindow_cs/MW_AutoFold.cs +++ b/Ink Canvas/MainWindow_cs/MW_AutoFold.cs @@ -282,7 +282,7 @@ namespace Ink_Canvas RightSidePanelForPPTNavigation.Visibility = Visibility.Collapsed; } - // 新增:只在屏幕模式下显示浮动栏 + // 新只在屏幕模式下显示浮动栏 if (currentMode == 0) { // 强制更新布局以确保ActualWidth正确 diff --git a/Ink Canvas/MainWindow_cs/MW_PPT.cs b/Ink Canvas/MainWindow_cs/MW_PPT.cs index 5c90a6fb..81228d4d 100644 --- a/Ink Canvas/MainWindow_cs/MW_PPT.cs +++ b/Ink Canvas/MainWindow_cs/MW_PPT.cs @@ -808,7 +808,7 @@ namespace Ink_Canvas } }); - await Task.Delay(150); + await Task.Delay(100); await Application.Current.Dispatcher.InvokeAsync(() => { // 强制重新计算浮动栏位置,确保在退出PPT模式后正确复位 From c1fcaff28a97d5b6f0ee8572c2baca1c9baa6796 Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sat, 13 Sep 2025 12:05:13 +0800 Subject: [PATCH 41/80] =?UTF-8?q?fix:issue=20#175=20=E7=AE=80=E6=98=93?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=EF=BC=88=E5=90=8E=E7=BB=AD=E4=BC=9A=E6=94=B9?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/MainWindow.xaml | 9 +++++++++ Ink Canvas/MainWindow_cs/MW_Settings.cs | 7 +++++++ Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs | 2 ++ Ink Canvas/MainWindow_cs/MW_Timer.cs | 14 ++++++++++++-- Ink Canvas/Resources/Settings.cs | 3 +++ 5 files changed, 33 insertions(+), 2 deletions(-) diff --git a/Ink Canvas/MainWindow.xaml b/Ink Canvas/MainWindow.xaml index ab66b0e7..14b46837 100644 --- a/Ink Canvas/MainWindow.xaml +++ b/Ink Canvas/MainWindow.xaml @@ -2600,6 +2600,15 @@ FontFamily="Microsoft YaHei UI" FontWeight="Bold" Toggled="ToggleSwitchAutoFoldInPPTSlideShow_Toggled" /> + + + + + Date: Sat, 13 Sep 2025 12:08:45 +0800 Subject: [PATCH 42/80] =?UTF-8?q?improve:=E7=9B=B4=E6=8E=A5=E8=B0=83?= =?UTF-8?q?=E7=94=A8=E5=A4=96=E9=83=A8=E7=82=B9=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/MainWindow.xaml | 17 +++++++++++--- Ink Canvas/MainWindow.xaml.cs | 2 +- .../MainWindow_cs/MW_FloatingBarIcons.cs | 23 ++++++++++++++++--- Ink Canvas/MainWindow_cs/MW_Settings.cs | 15 ++++++++++-- Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs | 6 +++-- Ink Canvas/Resources/Settings.cs | 2 ++ 6 files changed, 54 insertions(+), 11 deletions(-) diff --git a/Ink Canvas/MainWindow.xaml b/Ink Canvas/MainWindow.xaml index 14b46837..d73b4879 100644 --- a/Ink Canvas/MainWindow.xaml +++ b/Ink Canvas/MainWindow.xaml @@ -2928,13 +2928,24 @@ Toggled="ToggleSwitchShowRandomAndSingleDraw_Toggled" /> - + Toggled="ToggleSwitchExternalCaller_Toggled" /> + + + + + ClassIsland点名 + SecRandom点名 + NamePicker点名 + diff --git a/Ink Canvas/MainWindow.xaml.cs b/Ink Canvas/MainWindow.xaml.cs index 9577bf88..27db978c 100644 --- a/Ink Canvas/MainWindow.xaml.cs +++ b/Ink Canvas/MainWindow.xaml.cs @@ -38,7 +38,7 @@ namespace Ink_Canvas { public partial class MainWindow : Window { - // 新增:每一页一个Canvas对象 + // 每一页一个Canvas对象 private List whiteboardPages = new List(); private int currentPageIndex; private System.Windows.Controls.Canvas currentCanvas; diff --git a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs index cb3538e4..6604f48b 100644 --- a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs +++ b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs @@ -1096,20 +1096,37 @@ namespace Ink_Canvas AnimationsHelper.HideWithSlideAndFade(BoardBorderTools); AnimationsHelper.HideWithSlideAndFade(BoardImageOptionsPanel); - // 检查是否启用了直接调用ClassIsland点名功能 + // 检查是否启用了外部点名功能 if (Settings.RandSettings.DirectCallCiRand) { try { + string protocol = ""; + switch (Settings.RandSettings.ExternalCallerType) + { + case 0: // ClassIsland点名 + protocol = "classisland://plugins/IslandCaller/Simple/1"; + break; + case 1: // SecRandom点名 + protocol = "secrandom://direct_extraction"; + break; + case 2: // NamePicker点名 + protocol = "namepicker://"; + break; + default: + protocol = "classisland://plugins/IslandCaller/Simple/1"; + break; + } + Process.Start(new ProcessStartInfo { - FileName = "classisland://plugins/IslandCaller/Simple/1", + FileName = protocol, UseShellExecute = true }); } catch (Exception ex) { - MessageBox.Show("无法调用ClassIsland点名:" + ex.Message); + MessageBox.Show("无法调用外部点名:" + ex.Message); // 调用失败时回退到默认的随机点名窗口 new RandWindow(Settings, true).ShowDialog(); diff --git a/Ink Canvas/MainWindow_cs/MW_Settings.cs b/Ink Canvas/MainWindow_cs/MW_Settings.cs index 577dd85d..c0ebe8e5 100644 --- a/Ink Canvas/MainWindow_cs/MW_Settings.cs +++ b/Ink Canvas/MainWindow_cs/MW_Settings.cs @@ -2417,12 +2417,23 @@ namespace Ink_Canvas SaveSettingsToFile(); } - private void ToggleSwitchDirectCallCiRand_Toggled(object sender, RoutedEventArgs e) + private void ToggleSwitchExternalCaller_Toggled(object sender, RoutedEventArgs e) { if (!isLoaded) return; // 获取开关状态并保存到设置中 - Settings.RandSettings.DirectCallCiRand = ToggleSwitchDirectCallCiRand.IsOn; + Settings.RandSettings.DirectCallCiRand = ToggleSwitchExternalCaller.IsOn; + + // 保存设置到文件 + SaveSettingsToFile(); + } + + private void ComboBoxExternalCallerType_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + if (!isLoaded) return; + + // 获取下拉框选择并保存到设置中 + Settings.RandSettings.ExternalCallerType = ComboBoxExternalCallerType.SelectedIndex; // 保存设置到文件 SaveSettingsToFile(); diff --git a/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs b/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs index 2e178d12..2518ab54 100644 --- a/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs +++ b/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs @@ -763,7 +763,8 @@ namespace Ink_Canvas RandWindowOnceCloseLatencySlider.Value = Settings.RandSettings.RandWindowOnceCloseLatency; RandWindowOnceMaxStudentsSlider.Value = Settings.RandSettings.RandWindowOnceMaxStudents; ToggleSwitchShowRandomAndSingleDraw.IsOn = Settings.RandSettings.ShowRandomAndSingleDraw; - ToggleSwitchDirectCallCiRand.IsOn = Settings.RandSettings.DirectCallCiRand; + ToggleSwitchExternalCaller.IsOn = Settings.RandSettings.DirectCallCiRand; + ComboBoxExternalCallerType.SelectedIndex = Settings.RandSettings.ExternalCallerType; RandomDrawPanel.Visibility = Settings.RandSettings.ShowRandomAndSingleDraw ? Visibility.Visible : Visibility.Collapsed; SingleDrawPanel.Visibility = Settings.RandSettings.ShowRandomAndSingleDraw ? Visibility.Visible : Visibility.Collapsed; @@ -783,7 +784,8 @@ namespace Ink_Canvas ToggleSwitchDisplayRandWindowNamesInputBtn.IsOn = Settings.RandSettings.DisplayRandWindowNamesInputBtn; RandWindowOnceCloseLatencySlider.Value = Settings.RandSettings.RandWindowOnceCloseLatency; RandWindowOnceMaxStudentsSlider.Value = Settings.RandSettings.RandWindowOnceMaxStudents; - ToggleSwitchDirectCallCiRand.IsOn = Settings.RandSettings.DirectCallCiRand; + ToggleSwitchExternalCaller.IsOn = Settings.RandSettings.DirectCallCiRand; + ComboBoxExternalCallerType.SelectedIndex = Settings.RandSettings.ExternalCallerType; } // ModeSettings diff --git a/Ink Canvas/Resources/Settings.cs b/Ink Canvas/Resources/Settings.cs index 915e919f..a743cb18 100644 --- a/Ink Canvas/Resources/Settings.cs +++ b/Ink Canvas/Resources/Settings.cs @@ -548,6 +548,8 @@ namespace Ink_Canvas public bool ShowRandomAndSingleDraw { get; set; } = true; [JsonProperty("directCallCiRand")] public bool DirectCallCiRand { get; set; } + [JsonProperty("externalCallerType")] + public int ExternalCallerType { get; set; } = 0; [JsonProperty("selectedBackgroundIndex")] public int SelectedBackgroundIndex { get; set; } [JsonProperty("customPickNameBackgrounds")] From 32c179bbf99349b90d459d544797163d06b4244b Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sat, 13 Sep 2025 12:22:08 +0800 Subject: [PATCH 43/80] =?UTF-8?q?improve:=E5=BC=B9=E7=AA=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/App.xaml.cs | 2 +- Ink Canvas/MainWindow_cs/MW_PPT.cs | 2 +- Ink Canvas/MainWindow_cs/MW_Settings.cs | 1 - Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs | 2 +- .../Windows/PluginSettingsWindow.xaml.cs | 2 +- ...vasForClass.csproj.AssemblyReference.cache | Bin 35826 -> 35689 bytes 6 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Ink Canvas/App.xaml.cs b/Ink Canvas/App.xaml.cs index 3766fc55..19263bce 100644 --- a/Ink Canvas/App.xaml.cs +++ b/Ink Canvas/App.xaml.cs @@ -19,7 +19,7 @@ using System.Windows.Forms; using System.Windows.Input; using System.Windows.Threading; using Application = System.Windows.Application; -using MessageBox = System.Windows.MessageBox; +using MessageBox = iNKORE.UI.WPF.Modern.Controls.MessageBox; using Timer = System.Threading.Timer; namespace Ink_Canvas diff --git a/Ink Canvas/MainWindow_cs/MW_PPT.cs b/Ink Canvas/MainWindow_cs/MW_PPT.cs index 81228d4d..734317bd 100644 --- a/Ink Canvas/MainWindow_cs/MW_PPT.cs +++ b/Ink Canvas/MainWindow_cs/MW_PPT.cs @@ -14,7 +14,7 @@ using System.Windows.Media; using System.Windows.Threading; using Application = System.Windows.Application; using File = System.IO.File; -using MessageBox = System.Windows.MessageBox; +using MessageBox = iNKORE.UI.WPF.Modern.Controls.MessageBox; using MouseButtonEventArgs = System.Windows.Input.MouseButtonEventArgs; using MouseEventArgs = System.Windows.Input.MouseEventArgs; diff --git a/Ink Canvas/MainWindow_cs/MW_Settings.cs b/Ink Canvas/MainWindow_cs/MW_Settings.cs index c0ebe8e5..d0bb42dd 100644 --- a/Ink Canvas/MainWindow_cs/MW_Settings.cs +++ b/Ink Canvas/MainWindow_cs/MW_Settings.cs @@ -1,5 +1,4 @@ using Hardcodet.Wpf.TaskbarNotification; -using iNKORE.UI.WPF.Modern.Controls; using Ink_Canvas.Helpers; using Newtonsoft.Json; using OSVersionExtension; diff --git a/Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs b/Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs index 5f1faa5b..70e4b8cc 100644 --- a/Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs +++ b/Ink Canvas/MainWindow_cs/MW_ShapeDrawing.cs @@ -10,7 +10,7 @@ using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; -using MessageBox = System.Windows.MessageBox; +using MessageBox = iNKORE.UI.WPF.Modern.Controls.MessageBox; using Point = System.Windows.Point; namespace Ink_Canvas diff --git a/Ink Canvas/Windows/PluginSettingsWindow.xaml.cs b/Ink Canvas/Windows/PluginSettingsWindow.xaml.cs index ef206124..5f54aaa3 100644 --- a/Ink Canvas/Windows/PluginSettingsWindow.xaml.cs +++ b/Ink Canvas/Windows/PluginSettingsWindow.xaml.cs @@ -12,7 +12,7 @@ using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Threading; -using MessageBox = System.Windows.MessageBox; +using MessageBox = iNKORE.UI.WPF.Modern.Controls.MessageBox; namespace Ink_Canvas.Windows { diff --git a/Ink Canvas/obj/Debug/net472/InkCanvasForClass.csproj.AssemblyReference.cache b/Ink Canvas/obj/Debug/net472/InkCanvasForClass.csproj.AssemblyReference.cache index 44b9fc7383ebb573862944afd3220347eedadfaa..4f2348e4edb2658289eb7979cb81cc47e276fd63 100644 GIT binary patch delta 23 ecmew~o$2K?CJr`6Jq88_#>B~nPN5rPdAb2r0|u-B delta 70 zcmaDkjp@^LCJr`6eFg>w#>B~nPN5rPdAcVD$b?U}m*kqv$IYhXte29L!^j9!!0^EF X#&?CQ93Zt^WhQzCdd3FEhL#KfstysU From d5fa46033e229cb8f4525477ec9c0f7682b8c652 Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sat, 13 Sep 2025 13:03:04 +0800 Subject: [PATCH 44/80] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/Helpers/GlobalHotkeyManager.cs | 2 -- Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs | 2 -- 2 files changed, 4 deletions(-) diff --git a/Ink Canvas/Helpers/GlobalHotkeyManager.cs b/Ink Canvas/Helpers/GlobalHotkeyManager.cs index 804780e4..d441f068 100644 --- a/Ink Canvas/Helpers/GlobalHotkeyManager.cs +++ b/Ink Canvas/Helpers/GlobalHotkeyManager.cs @@ -375,7 +375,6 @@ namespace Ink_Canvas.Helpers if (_hotkeysShouldBeRegistered) { _hotkeysShouldBeRegistered = false; - LogHelper.WriteLogToFile("禁用快捷键注册功能"); // 注销所有快捷键 UnregisterAllHotkeys(); @@ -413,7 +412,6 @@ namespace Ink_Canvas.Helpers { // 鼠标模式下禁用快捷键,让键盘操作放行 DisableHotkeyRegistration(); - LogHelper.WriteLogToFile("切换到鼠标模式,禁用快捷键以放行键盘操作"); } } else diff --git a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs index 6604f48b..21263020 100644 --- a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs +++ b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs @@ -704,14 +704,12 @@ namespace Ink_Canvas RightBottomPanelForPPTNavigation.Visibility = Visibility.Collapsed; LeftSidePanelForPPTNavigation.Visibility = Visibility.Collapsed; RightSidePanelForPPTNavigation.Visibility = Visibility.Collapsed; - LogHelper.WriteLogToFile($"隐藏PPT翻页按钮 - 放映状态: {PPTManager?.IsInSlideShow}, 页数: {PPTManager?.SlidesCount}", LogHelper.LogType.Trace); } // 使用PPT UI管理器来正确更新翻页按钮显示状态,确保遵循用户设置 if (_pptUIManager != null) { _pptUIManager.UpdateNavigationPanelsVisibility(); - LogHelper.WriteLogToFile($"使用PPT UI管理器更新翻页按钮显示状态", LogHelper.LogType.Trace); } if (Settings.Automation.IsAutoSaveStrokesAtClear && From fab9e4b265fa4ae9df693959c27aff57d5b13315 Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sat, 13 Sep 2025 13:37:51 +0800 Subject: [PATCH 45/80] =?UTF-8?q?improve:=E6=88=AA=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/MainWindow_cs/MW_ImageInsert.cs | 40 +++++++++++++++++ .../Windows/ScreenshotSelectorWindow.xaml | 9 ++++ .../Windows/ScreenshotSelectorWindow.xaml.cs | 41 ++++++++++++++++++ ...vasForClass.csproj.AssemblyReference.cache | Bin 35689 -> 35826 bytes 4 files changed, 90 insertions(+) diff --git a/Ink Canvas/MainWindow_cs/MW_ImageInsert.cs b/Ink Canvas/MainWindow_cs/MW_ImageInsert.cs index 6c77b485..82193558 100644 --- a/Ink Canvas/MainWindow_cs/MW_ImageInsert.cs +++ b/Ink Canvas/MainWindow_cs/MW_ImageInsert.cs @@ -100,6 +100,46 @@ namespace Ink_Canvas } } + // 直接全屏截图并插入到画布 + private async Task CaptureFullScreenAndInsert() + { + try + { + // 隐藏主窗口以避免截图包含窗口本身 + var originalVisibility = Visibility; + Visibility = Visibility.Hidden; + + // 等待窗口隐藏 + await Task.Delay(200); + + // 获取虚拟屏幕边界 + var virtualScreen = SystemInformation.VirtualScreen; + var fullScreenArea = new Rectangle(virtualScreen.X, virtualScreen.Y, virtualScreen.Width, virtualScreen.Height); + + // 截取全屏 + using (var fullScreenBitmap = CaptureScreenArea(fullScreenArea)) + { + if (fullScreenBitmap != null) + { + // 将截图转换为WPF Image并插入到画布 + await InsertScreenshotToCanvas(fullScreenBitmap); + } + else + { + ShowNotification("全屏截图失败"); + } + } + + // 恢复窗口显示 + Visibility = originalVisibility; + } + catch (Exception ex) + { + ShowNotification($"全屏截图失败: {ex.Message}"); + Visibility = Visibility.Visible; + } + } + // 显示截图区域选择器 private async Task ShowScreenshotSelector() { diff --git a/Ink Canvas/Windows/ScreenshotSelectorWindow.xaml b/Ink Canvas/Windows/ScreenshotSelectorWindow.xaml index ef299119..05739cce 100644 --- a/Ink Canvas/Windows/ScreenshotSelectorWindow.xaml +++ b/Ink Canvas/Windows/ScreenshotSelectorWindow.xaml @@ -117,6 +117,15 @@ BorderThickness="0" FontWeight="Medium" Click="FreehandModeButton_Click" /> + - + - +