improve:展台
新增将展台替换为希沃展台快捷启动功能
This commit is contained in:
@@ -1,72 +1,151 @@
|
||||
using Microsoft.Win32;
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
|
||||
namespace Ink_Canvas.Helpers
|
||||
{
|
||||
internal class SoftwareLauncher
|
||||
internal static class SoftwareLauncher
|
||||
{
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
|
||||
|
||||
/// <summary>与 ICA 一致:在「程序和功能」卸载列表中按 DisplayName 匹配后启动 sweclauncher.exe。</summary>
|
||||
public static void LaunchEasiCamera(string softwareName)
|
||||
{
|
||||
string executablePath = FindEasiCameraExecutablePath(softwareName);
|
||||
|
||||
if (!string.IsNullOrEmpty(executablePath))
|
||||
if (string.IsNullOrEmpty(executablePath))
|
||||
{
|
||||
try
|
||||
{
|
||||
Process.Start(executablePath);
|
||||
//Console.WriteLine(softwareName + " 启动成功!");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("启动失败: " + ex.Message);
|
||||
//MessageBox.Show("启动失败: " + ex.Message);
|
||||
}
|
||||
MessageBox.Show(
|
||||
"未找到希沃视频展台安装信息(已扫描 64 位与 32 位卸载注册表)。请确认已通过官方安装包安装「希沃视频展台」。",
|
||||
"Ink Canvas",
|
||||
MessageBoxButton.OK,
|
||||
MessageBoxImage.Information);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var directory = Path.GetDirectoryName(executablePath);
|
||||
var psi = new ProcessStartInfo
|
||||
{
|
||||
FileName = executablePath,
|
||||
UseShellExecute = true,
|
||||
WorkingDirectory = string.IsNullOrEmpty(directory) ? Environment.SystemDirectory : directory
|
||||
};
|
||||
Process.Start(psi);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(
|
||||
"无法启动希沃视频展台:" + ex.Message,
|
||||
"Ink Canvas",
|
||||
MessageBoxButton.OK,
|
||||
MessageBoxImage.Warning);
|
||||
}
|
||||
//Console.WriteLine(softwareName + " 未找到可执行文件路径。");
|
||||
}
|
||||
|
||||
private static string FindEasiCameraExecutablePath(string softwareName)
|
||||
{
|
||||
string executablePath = null;
|
||||
if (string.IsNullOrWhiteSpace(softwareName))
|
||||
return null;
|
||||
|
||||
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Uninstall"))
|
||||
// 64 位进程默认只枚举 64 位注册表视图;32 位希沃常写在 WOW6432Node 下,需一并扫描。
|
||||
string[] uninstallRoots =
|
||||
{
|
||||
foreach (string subkeyName in key.GetSubKeyNames())
|
||||
{
|
||||
using (RegistryKey subkey = key.OpenSubKey(subkeyName))
|
||||
{
|
||||
string displayName = subkey.GetValue("DisplayName") as string;
|
||||
string installLocation = subkey.GetValue("InstallLocation") as string;
|
||||
string uninstallString = subkey.GetValue("UninstallString") as string;
|
||||
@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
|
||||
@"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall",
|
||||
};
|
||||
|
||||
if (!string.IsNullOrEmpty(displayName) && displayName.Contains(softwareName))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(installLocation))
|
||||
{
|
||||
executablePath = Path.Combine(installLocation, "sweclauncher.exe");
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(uninstallString))
|
||||
{
|
||||
int lastSlashIndex = uninstallString.LastIndexOf("\\");
|
||||
if (lastSlashIndex >= 0)
|
||||
{
|
||||
string folderPath = uninstallString.Substring(0, lastSlashIndex);
|
||||
executablePath = Path.Combine(folderPath, "sweclauncher", "sweclauncher.exe");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
foreach (string root in uninstallRoots)
|
||||
{
|
||||
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(root))
|
||||
{
|
||||
if (key == null) continue;
|
||||
string found = FindInUninstallKey(key, softwareName);
|
||||
if (!string.IsNullOrEmpty(found))
|
||||
return found;
|
||||
}
|
||||
}
|
||||
|
||||
return executablePath;
|
||||
return null;
|
||||
}
|
||||
|
||||
private static string FindInUninstallKey(RegistryKey uninstallKey, string softwareName)
|
||||
{
|
||||
foreach (string subkeyName in uninstallKey.GetSubKeyNames())
|
||||
{
|
||||
using (RegistryKey subkey = uninstallKey.OpenSubKey(subkeyName))
|
||||
{
|
||||
if (subkey == null) continue;
|
||||
|
||||
string displayName = subkey.GetValue("DisplayName") as string;
|
||||
if (string.IsNullOrEmpty(displayName) || !displayName.Contains(softwareName))
|
||||
continue;
|
||||
|
||||
string installLocation = subkey.GetValue("InstallLocation") as string;
|
||||
string uninstallString = subkey.GetValue("UninstallString") as string;
|
||||
|
||||
string resolved = TryResolveSweclauncher(installLocation, uninstallString);
|
||||
if (!string.IsNullOrEmpty(resolved) && File.Exists(resolved))
|
||||
return resolved;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static string TryResolveSweclauncher(string installLocation, string uninstallString)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(installLocation))
|
||||
{
|
||||
string fromLoc = ResolveSweclauncherUnderInstallRoot(installLocation.Trim().TrimEnd('\\'));
|
||||
if (!string.IsNullOrEmpty(fromLoc))
|
||||
return fromLoc;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(uninstallString))
|
||||
{
|
||||
// 常见:"...\uninstall.exe" 或带引号路径
|
||||
string trimmed = uninstallString.Trim();
|
||||
if (trimmed.Length >= 2 && trimmed[0] == '"')
|
||||
{
|
||||
int end = trimmed.IndexOf('"', 1);
|
||||
if (end > 1)
|
||||
trimmed = trimmed.Substring(1, end - 1);
|
||||
}
|
||||
|
||||
int lastSlash = trimmed.LastIndexOf('\\');
|
||||
if (lastSlash < 0)
|
||||
return null;
|
||||
|
||||
string folderPath = trimmed.Substring(0, lastSlash);
|
||||
string candidate = Path.Combine(folderPath, "sweclauncher", "sweclauncher.exe");
|
||||
if (File.Exists(candidate))
|
||||
return candidate;
|
||||
|
||||
candidate = Path.Combine(folderPath, "sweclauncher.exe");
|
||||
if (File.Exists(candidate))
|
||||
return candidate;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static string ResolveSweclauncherUnderInstallRoot(string installRoot)
|
||||
{
|
||||
string[] candidates =
|
||||
{
|
||||
Path.Combine(installRoot, "sweclauncher.exe"),
|
||||
Path.Combine(installRoot, "sweclauncher", "sweclauncher.exe"),
|
||||
};
|
||||
|
||||
foreach (string p in candidates)
|
||||
{
|
||||
if (File.Exists(p))
|
||||
return p;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -903,6 +903,15 @@
|
||||
IsOn="True" FontFamily="Microsoft YaHei UI" FontWeight="Bold"
|
||||
Toggled="ToggleSwitchCompressPicturesUploaded_Toggled" />
|
||||
</ikw:SimpleStackPanel>
|
||||
<ikw:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||
<TextBlock Foreground="#fafafa" Text="{i18n:I18n Key=Canvas_LaunchSeewoVideoShowcaseForWhiteboardBooth}" VerticalAlignment="Center"
|
||||
FontSize="14" Margin="0,0,8,0" Width="320"
|
||||
Style="{StaticResource AutoFitSettingsOptionLabel14}" />
|
||||
<ui:ToggleSwitch OnContent="" OffContent="" Name="ToggleSwitchLaunchSeewoVideoShowcaseForWhiteboardBooth"
|
||||
IsOn="False" FontFamily="Microsoft YaHei UI" FontWeight="Bold"
|
||||
Toggled="ToggleSwitchLaunchSeewoVideoShowcaseForWhiteboardBooth_Toggled" />
|
||||
</ikw:SimpleStackPanel>
|
||||
<TextBlock Text="{i18n:I18n Key=Canvas_LaunchSeewoVideoShowcaseForWhiteboardBoothHint}" TextWrapping="Wrap" Foreground="#a1a1aa" />
|
||||
<Line HorizontalAlignment="Center" X1="0" Y1="0" X2="400" Y2="0" Stroke="#3f3f46"
|
||||
StrokeThickness="1" Margin="0,4,0,4" />
|
||||
<ikw:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||
|
||||
@@ -2705,6 +2705,15 @@ namespace Ink_Canvas
|
||||
SaveSettingsToFile();
|
||||
}
|
||||
|
||||
private void ToggleSwitchLaunchSeewoVideoShowcaseForWhiteboardBooth_Toggled(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!isLoaded) return;
|
||||
|
||||
Settings.Canvas.LaunchSeewoVideoShowcaseForWhiteboardBooth =
|
||||
ToggleSwitchLaunchSeewoVideoShowcaseForWhiteboardBooth.IsOn;
|
||||
SaveSettingsToFile();
|
||||
}
|
||||
|
||||
private void ToggleSwitchAutoStraightenLine_Toggled(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!isLoaded) return;
|
||||
|
||||
@@ -852,6 +852,9 @@ namespace Ink_Canvas
|
||||
ToggleSwitchDisablePressure.IsOn = Settings.Canvas.DisablePressure;
|
||||
inkCanvas.DefaultDrawingAttributes.IgnorePressure = Settings.Canvas.DisablePressure;
|
||||
|
||||
ToggleSwitchLaunchSeewoVideoShowcaseForWhiteboardBooth.IsOn =
|
||||
Settings.Canvas.LaunchSeewoVideoShowcaseForWhiteboardBooth;
|
||||
|
||||
if (Settings.Canvas.EnableVelocityBrushTip)
|
||||
{
|
||||
Settings.Canvas.InkStyle = 3;
|
||||
@@ -874,8 +877,6 @@ namespace Ink_Canvas
|
||||
ToggleSwitchClearCanvasAlsoClearImages.IsOn = Settings.Canvas.ClearCanvasAlsoClearImages;
|
||||
ToggleSwitchShowCircleCenter.IsOn = Settings.Canvas.ShowCircleCenter;
|
||||
|
||||
ApplyWhiteboardBoothToolbarFromSettings();
|
||||
|
||||
switch (Settings.Canvas.EraserShapeType)
|
||||
{
|
||||
case 0:
|
||||
|
||||
@@ -51,6 +51,14 @@ namespace Ink_Canvas
|
||||
/// <param name="e">鼠标按钮事件的参数。</param>
|
||||
private void BtnToggleVideoPresenter_Click(object sender, System.Windows.Input.MouseButtonEventArgs e)
|
||||
{
|
||||
if (Settings?.Canvas?.LaunchSeewoVideoShowcaseForWhiteboardBooth == true)
|
||||
{
|
||||
// 与主窗口「希沃视频展台」入口(BoardLaunchEasiCamera_MouseUp)一致:先走黑板/白板入口逻辑再启动
|
||||
ImageBlackboard_MouseUp(null, null);
|
||||
SoftwareLauncher.LaunchEasiCamera("希沃视频展台");
|
||||
return;
|
||||
}
|
||||
|
||||
ToggleVideoPresenterSidebar();
|
||||
}
|
||||
|
||||
|
||||
@@ -179,6 +179,8 @@
|
||||
<data name="AskEachTime" xml:space="preserve"><value>Ask each time</value></data>
|
||||
<data name="Canvas_AsymptoteHint" xml:space="preserve"><value># Disabling may cause undo bugs.</value></data>
|
||||
<data name="Canvas_ShowCircleCenter" xml:space="preserve"><value>Show circle center</value></data>
|
||||
<data name="Canvas_LaunchSeewoVideoShowcaseForWhiteboardBooth" xml:space="preserve"><value>Whiteboard booth opens Seewo Video Showcase</value></data>
|
||||
<data name="Canvas_LaunchSeewoVideoShowcaseForWhiteboardBoothHint" xml:space="preserve"><value>When enabled, the whiteboard toolbar Booth button launches Seewo Video Showcase (must be installed). When disabled, the built-in booth is used.</value></data>
|
||||
<data name="Canvas_WPFBezier" xml:space="preserve"><value>WPF default Bezier smoothing</value></data>
|
||||
<data name="Canvas_AdvancedSmoothing" xml:space="preserve"><value>Advanced curve smoothing (recommended)</value></data>
|
||||
<data name="Canvas_InkFade" xml:space="preserve"><value>Ink fade</value></data>
|
||||
|
||||
@@ -194,6 +194,8 @@
|
||||
<data name="AskEachTime" xml:space="preserve"><value>每次询问</value></data>
|
||||
<data name="Canvas_AsymptoteHint" xml:space="preserve"><value># 请注意,若不保留双曲线渐近线可能会有遇到撤回相关的 BUG…</value></data>
|
||||
<data name="Canvas_ShowCircleCenter" xml:space="preserve"><value>绘制圆时显示圆心位置</value></data>
|
||||
<data name="Canvas_LaunchSeewoVideoShowcaseForWhiteboardBooth" xml:space="preserve"><value>白板展台按钮启动希沃视频展台</value></data>
|
||||
<data name="Canvas_LaunchSeewoVideoShowcaseForWhiteboardBoothHint" xml:space="preserve"><value>开启后,点击白板工具栏「展台」将打开希沃视频展台(需已安装);关闭则使用内置展台。</value></data>
|
||||
<data name="Canvas_WPFBezier" xml:space="preserve"><value>使用WPF默认贝塞尔曲线平滑</value></data>
|
||||
<data name="Canvas_AdvancedSmoothing" xml:space="preserve"><value>使用高级曲线平滑(推荐)</value></data>
|
||||
<data name="Canvas_InkFade" xml:space="preserve"><value>启用墨迹渐隐功能</value></data>
|
||||
|
||||
@@ -151,6 +151,10 @@ namespace Ink_Canvas
|
||||
[JsonProperty("enableVelocityBrushTip")]
|
||||
public bool EnableVelocityBrushTip { get; set; }
|
||||
|
||||
/// <summary>为 true 时,白板工具栏「展台」按钮启动希沃视频展台(sweclauncher),否则使用内置展台。</summary>
|
||||
[JsonProperty("launchSeewoVideoShowcaseForWhiteboardBooth")]
|
||||
public bool LaunchSeewoVideoShowcaseForWhiteboardBooth { get; set; } = false;
|
||||
|
||||
}
|
||||
|
||||
public enum OptionalOperation
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
<TextBlock Foreground="#2e3436" FontSize="14.5" Text="屏蔽压感" HorizontalAlignment="Left"/>
|
||||
<TextBlock Foreground="#9a9996" FontSize="11" Margin="0,3.5,0,0" Text="开启后,将忽略所有设备的压感信息,使所有笔画具有统一的粗细。与压感触屏模式互斥" HorizontalAlignment="Left"/>
|
||||
</StackPanel>
|
||||
<Border x:Name="ToggleSwitchDisablePressure" Style="{StaticResource ToggleSwitchStyle}" Background="#3584e4" Tag="DisablePressure" MouseLeftButtonDown="ToggleSwitch_Click">
|
||||
<Border x:Name="ToggleSwitchDisablePressure" Style="{StaticResource ToggleSwitchStyle}" Background="#3584e4" Tag="DisablePressure" MouseLeftButtonDown="ToggleSwitch_Click">
|
||||
<Border Width="19" Height="19" Background="White" CornerRadius="10" HorizontalAlignment="Right" VerticalAlignment="Center">
|
||||
<Border.Effect>
|
||||
<DropShadowEffect BlurRadius="4" Direction="-45" Color="Black" Opacity="0.3" ShadowDepth="0"/>
|
||||
@@ -155,6 +155,20 @@
|
||||
</Border>
|
||||
</Border>
|
||||
</Grid>
|
||||
<Border Height="1" Background="#ebebeb"/>
|
||||
<Grid Height="54">
|
||||
<StackPanel Orientation="Vertical" Margin="18,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Left">
|
||||
<TextBlock Foreground="#2e3436" FontSize="14.5" Text="白板展台按钮启动希沃视频展台" HorizontalAlignment="Left"/>
|
||||
<TextBlock Foreground="#9a9996" FontSize="11" Margin="0,3.5,0,0" Text="开启后,点击白板工具栏「展台」将打开希沃视频展台(需已安装);关闭则使用内置展台" HorizontalAlignment="Left" TextWrapping="Wrap" MaxWidth="420"/>
|
||||
</StackPanel>
|
||||
<Border x:Name="ToggleSwitchLaunchSeewoVideoShowcaseForWhiteboardBooth" Style="{StaticResource ToggleSwitchStyle}" Background="#e1e1e1" Tag="LaunchSeewoVideoShowcaseForWhiteboardBooth" MouseLeftButtonDown="ToggleSwitch_Click">
|
||||
<Border Width="19" Height="19" Background="White" CornerRadius="10" HorizontalAlignment="Left" VerticalAlignment="Center">
|
||||
<Border.Effect>
|
||||
<DropShadowEffect BlurRadius="4" Direction="-45" Color="Black" Opacity="0.3" ShadowDepth="0"/>
|
||||
</Border.Effect>
|
||||
</Border>
|
||||
</Border>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
|
||||
@@ -101,6 +101,9 @@ namespace Ink_Canvas.Windows.SettingsViews
|
||||
// 插入图片时自动压缩
|
||||
SetToggleSwitchState(FindToggleSwitch("ToggleSwitchCompressPicturesUploaded"), canvas.IsCompressPicturesUploaded);
|
||||
|
||||
// 白板展台按钮启动希沃视频展台
|
||||
SetToggleSwitchState(FindToggleSwitch("ToggleSwitchLaunchSeewoVideoShowcaseForWhiteboardBooth"), canvas.LaunchSeewoVideoShowcaseForWhiteboardBooth);
|
||||
|
||||
// 保留双曲线渐近线
|
||||
SetOptionButtonState("HyperbolaAsymptote", (int)canvas.HyperbolaAsymptoteOption);
|
||||
|
||||
@@ -247,6 +250,8 @@ namespace Ink_Canvas.Windows.SettingsViews
|
||||
return canvas.EnablePressureTouchMode;
|
||||
case "DisablePressure":
|
||||
return canvas.DisablePressure;
|
||||
case "LaunchSeewoVideoShowcaseForWhiteboardBooth":
|
||||
return canvas.LaunchSeewoVideoShowcaseForWhiteboardBooth;
|
||||
case "HideStrokeWhenSelecting":
|
||||
return canvas.HideStrokeWhenSelecting;
|
||||
case "ClearCanvasAndClearTimeMachine":
|
||||
@@ -342,6 +347,11 @@ namespace Ink_Canvas.Windows.SettingsViews
|
||||
}
|
||||
break;
|
||||
|
||||
case "LaunchSeewoVideoShowcaseForWhiteboardBooth":
|
||||
MainWindowSettingsHelper.InvokeToggleSwitchToggled(
|
||||
"ToggleSwitchLaunchSeewoVideoShowcaseForWhiteboardBooth", newState);
|
||||
break;
|
||||
|
||||
case "HideStrokeWhenSelecting":
|
||||
// 调用 MainWindow 中的方法
|
||||
MainWindowSettingsHelper.InvokeToggleSwitchToggled("ToggleSwitchHideStrokeWhenSelecting", newState);
|
||||
|
||||
@@ -419,6 +419,7 @@ namespace Ink_Canvas.Windows.SettingsViews
|
||||
{ "ToggleSwitchShowCursor", "CanvasAndInkPanel" },
|
||||
{ "ToggleSwitchDisablePressure", "CanvasAndInkPanel" },
|
||||
{ "ToggleSwitchEnablePressureTouchMode", "CanvasAndInkPanel" },
|
||||
{ "ToggleSwitchLaunchSeewoVideoShowcaseForWhiteboardBooth", "CanvasAndInkPanel" },
|
||||
{ "ComboBoxEraserSize", "CanvasAndInkPanel" },
|
||||
{ "ComboBoxHyperbolaAsymptoteOption", "CanvasAndInkPanel" },
|
||||
{ "ComboBoxAutoSaveStrokesInterval", "CanvasAndInkPanel" },
|
||||
|
||||
Reference in New Issue
Block a user