Fix bug for PowerPoint Strokes Saving

This commit is contained in:
XY Wang 2021-12-16 01:21:41 +08:00
parent e0f2091ad2
commit 89db9a8490
6 changed files with 174 additions and 73 deletions

View File

@ -1,8 +1,10 @@
using System;
using Ink_Canvas.Helpers;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows;
@ -24,12 +26,18 @@ namespace Ink_Canvas
void App_Startup(object sender, StartupEventArgs e)
{
LogHelper.LogFile = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + LogHelper.LogFileName;
LogHelper.NewLog(string.Format("Ink Canvas Starting (Version: {0})", Assembly.GetExecutingAssembly().GetName().Version.ToString()));
bool ret;
mutex = new System.Threading.Mutex(true, "Ink_Canvas", out ret);
if (!ret && !e.Args.Contains("-m")) //-m multiple
{
LogHelper.NewLog("Detected existing instance");
MessageBox.Show("已有一个程序实例正在运行");
LogHelper.NewLog("Ink Canvas automatically closed");
Environment.Exit(0);
}

View File

@ -6,7 +6,7 @@
xmlns:local="clr-namespace:Ink_Canvas" WindowStartupLocation="CenterScreen" ResizeMode="NoResize" ShowInTaskbar="False"
xmlns:ui="http://schemas.modernwpf.com/2019" FontFamily="Microsoft YaHei UI" Topmost="True"
mc:Ignorable="d" ui:WindowHelper.UseModernWindowStyle="True" Loaded="Window_Loaded" Closed="Window_Closed"
Title="" Height="590" Width="710">
Title="" Height="450" Width="600">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
@ -14,7 +14,7 @@
<RowDefinition/>
<RowDefinition Height="60"/>
</Grid.RowDefinitions>
<Label Content="Ink Canvas 画板最后一次新功能大更新!" FontFamily="Microsoft YaHei UI" FontSize="26" Margin="20,0"/>
<Label Content="Ink Canvas 画板修复更新!" FontFamily="Microsoft YaHei UI" FontSize="26" Margin="20,0"/>
<StackPanel Grid.Row="1" Visibility="Collapsed">
<TextBlock Name="TextBlockChangeLogTitle" Text="更新日志" FontSize="18" FontWeight="Bold" Margin="35,10,35,0"/>
<TextBlock Name="TextBlockChangeLog" Text="修复一堆 Bug。" TextWrapping="Wrap" FontSize="14" Margin="55,5"/>
@ -38,14 +38,8 @@
</Grid>
<ui:SimpleStackPanel VerticalAlignment="Bottom" Grid.Row="2" Margin="50,0">
<TextBlock Text="更新日志" FontSize="18" FontWeight="Bold" Margin="0,10,0,0"/>
<TextBlock Text="1. 添加双曲线支持(以及含焦点的椭圆、抛物线)" TextWrapping="Wrap" FontSize="14" Margin="25,5,0,0"/>
<TextBlock Text="2. 添加选中墨迹后的悬浮工具栏" TextWrapping="Wrap" FontSize="14" Margin="25,5,0,0"/>
<TextBlock Text="3. 添加墨迹回放Ink Replay功能" TextWrapping="Wrap" FontSize="14" Margin="25,5,0,0"/>
<TextBlock Text="4. 添加墨迹保存功能(并对幻灯片提供优化支持)" TextWrapping="Wrap" FontSize="14" Margin="25,5,0,0"/>
<TextBlock Text="5. 添加橡皮大小调整选项(仅支持可获取触摸面积的屏幕)" TextWrapping="Wrap" FontSize="14" Margin="25,5,0,0"/>
<TextBlock Text="该项目从 2021 年 9 月 9 日开始开发在过去的三个月里从无到有功能逐渐完善丰富Bug 逐渐被修复" TextWrapping="Wrap" FontSize="14" Margin="25,5,0,0"/>
<TextBlock Text="Ink Canvas 画板暂停开发后WXRIW 将只会进行必要的 Bug 修复,或移除有 Bug 的功能。" TextWrapping="Wrap" FontSize="14" Margin="25,5,0,0"/>
<TextBlock Text="作为 WXRIW 最大的开源项目,希望在暂停更新后有开发者能继续在 GitHub 上贡献代码,完善 Ink Canvas 画板!(所有基于本项目的项目应遵守 GPL-3.0 开源协议)" TextWrapping="Wrap" FontSize="14" Margin="25,5,0,0"/>
<TextBlock Text="1. 可能修复了部分情况下无法保存华幻灯片的问题" TextWrapping="Wrap" FontSize="14" Margin="25,5,0,0"/>
<TextBlock Text="2. 添加日志功能" TextWrapping="Wrap" FontSize="14" Margin="25,5,0,0"/>
<TextBlock Text="建议" FontSize="18" FontWeight="Bold" Margin="0,10,0,0"/>
<TextBlock Text="建议配置屏幕为3840×2160 (缩放: 250%)或1920×1080 (缩放: 125%),以获得最佳体验(否则可能造成橡皮大小过大或过小等问题,可在设置中调整)。" TextWrapping="Wrap" FontSize="14" Margin="25,5,-10,0"/>
</ui:SimpleStackPanel>

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@ -8,11 +9,12 @@ namespace Ink_Canvas.Helpers
{
class LogHelper
{
public static string logFile = "Log.txt";
public static string LogFileName = "Log.txt";
public static string LogFile = "Log.txt";
public static void NewLog(string str)
{
WriteLogToFile(str, LogType.Info);
}
public static void NewLog(Exception ex)
@ -20,9 +22,32 @@ namespace Ink_Canvas.Helpers
}
public static void WriteLogToFile(string str)
public static void WriteLogToFile(string str, LogType logType = LogType.Info)
{
string strLogType = "Info";
switch (logType)
{
case LogType.Event:
strLogType = "Event";
break;
case LogType.Trace:
strLogType = "Trace";
break;
case LogType.Error:
strLogType = "Error";
break;
}
StreamWriter sw = new StreamWriter(LogFile, true);
sw.WriteLine(string.Format("{0} [{1}] {2}", DateTime.Now.ToString("O"), strLogType, str));
sw.Close();
}
public enum LogType
{
Info,
Trace,
Error,
Event
}
}
}

View File

@ -6,7 +6,7 @@
xmlns:local="clr-namespace:Ink_Canvas" xmlns:ui="http://schemas.modernwpf.com/2019"
AllowsTransparency="True" WindowStyle="None" ResizeMode="NoResize"
mc:Ignorable="d" WindowState="Maximized" Loaded="Window_Loaded" Background="Transparent" ShowInTaskbar="False"
Title="Ink Canvas 画板" Height="1000" Width="1000" FontFamily="Microsoft YaHei UI"
Title="Ink Canvas 画板" Height="10000" Width="1000" FontFamily="Microsoft YaHei UI"
Foreground="Black" Stylus.IsPressAndHoldEnabled="False">
<!--资源中添加命令-->
<Window.Resources>
@ -403,6 +403,7 @@
<ui:SimpleStackPanel Spacing="12">
<TextBlock Text="可在手指触摸画板时显示圆形橡皮或手掌触摸画板时显示的橡皮比&#x000A;手掌大很多时开启" Foreground="#666666"/>
<ui:ToggleSwitch Name="ToggleSwitchIsSpecialScreen" Header="特殊屏幕模式" FontFamily="Microsoft YaHei UI" OnContent="开" OffContent="关" Toggled="ToggleSwitchIsSpecialScreen_Toggled"/>
<ui:ToggleSwitch Name="ToggleSwitchIsLogEnabled" Header="记录日志" FontFamily="Microsoft YaHei UI" OnContent="开" OffContent="关" IsOn="True" Toggled="ToggleSwitchIsLogEnabled_Toggled"/>
</ui:SimpleStackPanel>
</GroupBox>
<GroupBox Header="重置">

View File

@ -50,6 +50,8 @@ namespace Ink_Canvas
public MainWindow()
{
InitializeComponent();
BorderSettings.Visibility = Visibility.Collapsed;
StackPanelToolButtons.Visibility = Visibility.Collapsed;
BorderDrawShape.Visibility = Visibility.Collapsed;
@ -308,6 +310,7 @@ namespace Ink_Canvas
string lastVersion = "";
if (response.Contains("Special Version") && !File.Exists(System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "Versions.ini"))
{
LogHelper.WriteLogToFile("Welcome Window Show Dialog", LogHelper.LogType.Event);
new WelcomeWindow().ShowDialog();
}
else
@ -319,6 +322,7 @@ namespace Ink_Canvas
catch { }
if (!lastVersion.Contains(version.ToString()))
{
LogHelper.WriteLogToFile("Change Log Window Show Dialog", LogHelper.LogType.Event);
new ChangeLogWindow().ShowDialog();
lastVersion += "\n" + version.ToString();
File.WriteAllText(System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "Versions.ini", lastVersion.Trim());
@ -351,6 +355,8 @@ namespace Ink_Canvas
string updateExePath = AppDomain.CurrentDomain.BaseDirectory + "AutoUpdater\\AutoUpdater.exe";
System.Diagnostics.Process myProcess = System.Diagnostics.Process.Start(updateExePath);
LogHelper.WriteLogToFile("Detected new version, closing Ink Canvas for update", LogHelper.LogType.Event);
Application.Current.Dispatcher.Invoke(() =>
{
Application.Current.Shutdown();
@ -377,7 +383,7 @@ namespace Ink_Canvas
ThemeManager.Current.ApplicationTheme = ApplicationTheme.Light;
TextBlockVersion.Text = Assembly.GetExecutingAssembly().GetName().Version.ToString();
LogHelper.WriteLogToFile("Ink Canvas Loaded", LogHelper.LogType.Event);
isLoaded = true;
}
@ -638,6 +644,14 @@ namespace Ink_Canvas
{
ToggleSwitchIsSpecialScreen.IsOn = false;
}
if (Settings.Advanced.IsLogEnabled)
{
ToggleSwitchIsLogEnabled.IsOn = true;
}
else
{
ToggleSwitchIsLogEnabled.IsOn = false;
}
}
else
{
@ -1799,6 +1813,10 @@ namespace Ink_Canvas
private void PptApplication_PresentationClose(Presentation Pres)
{
pptApplication.PresentationClose -= PptApplication_PresentationClose;
pptApplication.SlideShowBegin -= PptApplication_SlideShowBegin;
pptApplication.SlideShowNextSlide -= PptApplication_SlideShowNextSlide;
pptApplication.SlideShowEnd -= PptApplication_SlideShowEnd;
pptApplication = null;
timerCheckPPT.Start();
BtnPPTSlideShow.Visibility = Visibility.Collapsed;
@ -1809,6 +1827,7 @@ namespace Ink_Canvas
//bool isButtonBackgroundTransparent = true; //此变量仅用于保存用于幻灯片放映时的优化
private void PptApplication_SlideShowBegin(SlideShowWindow Wn)
{
LogHelper.WriteLogToFile("PowerPoint Application Slide Show Begin", LogHelper.LogType.Event);
Application.Current.Dispatcher.Invoke(() =>
{
//调整颜色
@ -1844,28 +1863,39 @@ namespace Ink_Canvas
previousSlideID = 0;
memoryStreams = new MemoryStream[slidescount + 2];
LogHelper.NewLog("Name: " + Wn.Presentation.Name);
LogHelper.NewLog("Slides Count: " + slidescount.ToString());
//检查是否有已有墨迹,并加载
if (Settings.Automation.IsAutoSaveStrokesInPowerPoint)
{
string defaultFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\Ink Canvas Strokes\Auto Saved\Presentations\";
if (Directory.Exists(defaultFolderPath + Wn.Application.ActivePresentation.Name + "_" + Wn.Presentation.Slides.Count))
if (Directory.Exists(defaultFolderPath + Wn.Presentation.Name + "_" + Wn.Presentation.Slides.Count))
{
FileInfo[] files = new DirectoryInfo(defaultFolderPath + Wn.Application.ActivePresentation.Name + "_" + Wn.Presentation.Slides.Count).GetFiles();
foreach(FileInfo file in files)
LogHelper.WriteLogToFile("Found saved strokes", LogHelper.LogType.Trace);
FileInfo[] files = new DirectoryInfo(defaultFolderPath + Wn.Presentation.Name + "_" + Wn.Presentation.Slides.Count).GetFiles();
int count = 0;
foreach (FileInfo file in files)
{
int i = -1;
try
{
int i = int.Parse(System.IO.Path.GetFileNameWithoutExtension(file.Name));
i = int.Parse(System.IO.Path.GetFileNameWithoutExtension(file.Name));
//var fs = new FileStream(file.FullName, FileMode.Open, FileAccess.Read);
//MemoryStream ms = new MemoryStream(File.ReadAllBytes(file.FullName));
//new StrokeCollection(fs).Save(ms);
//ms.Position = 0;
memoryStreams[i] = new MemoryStream(File.ReadAllBytes(file.FullName));
memoryStreams[i].Position = 0;
count++;
}
catch { }
catch (Exception ex)
{
LogHelper.WriteLogToFile(string.Format("Failed to load strokes on Slide {0}\n{1}", i, ex.ToString()), LogHelper.LogType.Error);
}
}
LogHelper.WriteLogToFile(string.Format("Loaded {0} saved strokes", count.ToString()));
}
}
pointDesktop = new Point(ViewboxFloatingBar.Margin.Left, ViewboxFloatingBar.Margin.Top);
@ -1921,6 +1951,9 @@ namespace Ink_Canvas
BtnHideInkCanvas_Click(BtnHideInkCanvas, null);
}
isEnteredSlideShowEndEvent = false;
LogHelper.NewLog("PowerPoint Slide Show Loading process complete");
new Thread(new ThreadStart(() =>
{
Thread.Sleep(100);
@ -1930,51 +1963,71 @@ namespace Ink_Canvas
});
})).Start();
});
previousSlideID = Wn.View.CurrentShowPosition;
//检查是否有已有墨迹,并加载当前页
if (Settings.Automation.IsAutoSaveStrokesInPowerPoint)
{
try
{
if (memoryStreams[Wn.View.CurrentShowPosition].Length > 0)
{
Application.Current.Dispatcher.Invoke(() =>
{
inkCanvas.Strokes = new System.Windows.Ink.StrokeCollection(memoryStreams[Wn.View.CurrentShowPosition]);
});
}
}
catch { }
}
//previousSlideID = Wn.View.CurrentShowPosition;
////检查是否有已有墨迹,并加载当前页
//if (Settings.Automation.IsAutoSaveStrokesInPowerPoint)
//{
// try
// {
// if (memoryStreams[Wn.View.CurrentShowPosition].Length > 0)
// {
// Application.Current.Dispatcher.Invoke(() =>
// {
// inkCanvas.Strokes = new System.Windows.Ink.StrokeCollection(memoryStreams[Wn.View.CurrentShowPosition]);
// });
// }
// }
// catch (Exception ex)
// {
// LogHelper.WriteLogToFile(string.Format("Failed to load strokes for current slide (Slide {0})\n{1}", Wn.View.CurrentShowPosition, ex.ToString()), LogHelper.LogType.Error);
// }
//}
}
bool isEnteredSlideShowEndEvent = false; //防止重复调用本函数导致墨迹保存失效
private void PptApplication_SlideShowEnd(Presentation Pres)
{
LogHelper.WriteLogToFile(string.Format("PowerPoint Slide Show End"), LogHelper.LogType.Event);
if (isEnteredSlideShowEndEvent)
{
LogHelper.WriteLogToFile("Detected previous entrance, returning");
return;
}
isEnteredSlideShowEndEvent = true;
if (Settings.Automation.IsAutoSaveStrokesInPowerPoint)
{
string defaultFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\Ink Canvas Strokes\Auto Saved\Presentations\";
string folderPath = defaultFolderPath + presentation.Application.ActivePresentation.Name + "_" + presentation.Slides.Count;
string folderPath = defaultFolderPath + Pres.Name + "_" + Pres.Slides.Count;
if (!Directory.Exists(folderPath))
{
Directory.CreateDirectory(folderPath);
}
for (int i = 1; i <= presentation.Slides.Count; i++)
for (int i = 1; i <= Pres.Slides.Count; i++)
{
if (memoryStreams[i] != null)
{
try
{
if (memoryStreams[i].Length > 0)
if (memoryStreams[i].Length > 8)
{
byte[] srcBuf = new Byte[memoryStreams[i].Length];
//MessageBox.Show(memoryStreams[i].Length.ToString());
memoryStreams[i].Read(srcBuf, 0, srcBuf.Length);
int byteLength = memoryStreams[i].Read(srcBuf, 0, srcBuf.Length);
File.WriteAllBytes(folderPath + @"\" + i.ToString("0000") + ".icstk", srcBuf);
LogHelper.WriteLogToFile(string.Format("Saved strokes for Slide {0}, size={1}, byteLength={2}", i.ToString(), memoryStreams[i].Length, byteLength));
}
}
catch
else
{
File.Delete(folderPath + @"\" + i.ToString("0000") + ".icstk");
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile(string.Format("Failed to save strokes for Slide {0}\n{1}", i, ex.ToString()), LogHelper.LogType.Error);
File.Delete(folderPath + @"\" + i.ToString("0000") + ".icstk");
}
}
}
}
Application.Current.Dispatcher.Invoke(() =>
@ -2061,6 +2114,7 @@ namespace Ink_Canvas
private void PptApplication_SlideShowNextSlide(SlideShowWindow Wn)
{
LogHelper.WriteLogToFile(string.Format("PowerPoint Next Slide (Slide {0})", Wn.View.CurrentShowPosition), LogHelper.LogType.Event);
if (Wn.View.CurrentShowPosition != previousSlideID)
{
Application.Current.Dispatcher.Invoke(() =>
@ -2565,6 +2619,13 @@ namespace Ink_Canvas
SaveSettingsToFile();
}
private void ToggleSwitchIsLogEnabled_Toggled(object sender, RoutedEventArgs e)
{
if (!isLoaded) return;
Settings.Advanced.IsLogEnabled = ToggleSwitchIsLogEnabled.IsOn;
SaveSettingsToFile();
}
#endregion
public static void SaveSettingsToFile()
@ -5540,7 +5601,7 @@ namespace Ink_Canvas
{
strokes = inkCanvas.GetSelectedStrokes().Clone();
}
int k = 2, i = 0;
int k = 1, i = 0;
new Thread(new ThreadStart(() =>
{
foreach (Stroke stroke in strokes)
@ -5763,10 +5824,20 @@ namespace Ink_Canvas
openFileDialog.Filter = "Ink Canvas Strokes File (*.icstk)|*.icstk";
if (openFileDialog.ShowDialog() == true)
{
LogHelper.WriteLogToFile(string.Format("Strokes Insert: Name: {0}", openFileDialog.FileName), LogHelper.LogType.Event);
try
{
var fs = new FileStream(openFileDialog.FileName, FileMode.Open, FileAccess.Read);
inkCanvas.Strokes = new StrokeCollection(fs);
LogHelper.NewLog(string.Format("Strokes Insert: Strokes Count: {0}", inkCanvas.Strokes.Count.ToString()));
if (inkCanvas.Strokes.Count == 0)
{
fs.Close();
var memoryStream = new MemoryStream(File.ReadAllBytes(openFileDialog.FileName));
memoryStream.Position = 0;
inkCanvas.Strokes = new StrokeCollection(memoryStream);
LogHelper.NewLog(string.Format("Strokes Insert (2): Strokes Count: {0}", inkCanvas.Strokes.Count.ToString()));
}
if (inkCanvas.Visibility != Visibility.Visible)
{

View File

@ -99,6 +99,8 @@ namespace Ink_Canvas
{
[JsonProperty("isSpecialScreen")]
public bool IsSpecialScreen { get; set; } = false;
[JsonProperty("isLogEnabled")]
public bool IsLogEnabled { get; set; } = true;
}
public class InkToShape