Implement automatic connecting loop

Add virtual com port manager
pull/7/head
LeapwardKoex 2024-02-08 22:55:04 +13:00
parent d97eeafdcb
commit 3a7183399e
6 changed files with 233 additions and 127 deletions

View File

@ -12,6 +12,7 @@ internal class MaiTouchComConnector
{
private static SerialPort? serialPort;
private bool isActiveMode;
private bool _connected;
private readonly MaiTouchSensorButtonStateManager _buttonState;
public Action<string> OnConnectStatusChange
@ -35,61 +36,53 @@ internal class MaiTouchComConnector
_buttonState = buttonState;
}
public async Task startLoopAsync()
public async Task StartTouchSensorPolling()
{
string virtualPort = "COM23"; // Adjust as needed
try
if (!_connected)
{
// Use setupc.exe to create a virtual COM port pair
//StartProcessWithAdminRights("C:\\Program Files (x86)\\com0com\\setupc.exe", $"PortName=COM3 PortName=COM23");
serialPort = new SerialPort(virtualPort, 9600, Parity.None, 8, StopBits.One);
serialPort.DataReceived += SerialPort_DataReceived;
serialPort.Open();
Console.WriteLine("Serial port opened successfully.");
OnConnectStatusChange("Connected");
// Simulate receiving a STAT packet
// Keep the program running to simulate active mode
while (true)
var virtualPort = "COM23"; // Adjust as needed
try
{
if (isActiveMode)
OnConnectStatusChange("Conecting...");
serialPort = new SerialPort(virtualPort, 9600, Parity.None, 8, StopBits.One);
serialPort.DataReceived += SerialPort_DataReceived;
serialPort.Open();
Console.WriteLine("Serial port opened successfully.");
OnConnectStatusChange("Connected to port");
_connected = true;
while (true)
{
SendTouchscreenState();
await Task.Delay(1);
if (isActiveMode)
{
SendTouchscreenState();
await Task.Delay(1);
}
else
{
await Task.Delay(100);
}
}
else
}
catch (Exception ex)
{
Console.WriteLine($"Error opening serial port: {ex.Message}");
Application.Current.Dispatcher.Invoke(() =>
{
await Task.Delay(100);
MessageBox.Show(ex.Message, "Error connecting to COM port", MessageBoxButton.OK, MessageBoxImage.Error);
});
}
finally
{
_connected = false;
OnConnectStatusChange("Not Connected");
if (serialPort?.IsOpen == true)
{
serialPort.Close();
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Error opening serial port: {ex.Message}");
Application.Current.Dispatcher.Invoke(() =>
{
MessageBox.Show(ex.Message, "Error connecting to COM port", MessageBoxButton.OK, MessageBoxImage.Error);
});
}
finally
{
OnConnectStatusChange("Not Connected");
// Close the serial port when done
if (serialPort.IsOpen)
{
serialPort.Close();
}
// Use setupc.exe to remove the virtual COM port pair with administrator privileges
//StartProcessWithAdminRights("C:\\Program Files (x86)\\com0com\\setupc.exe", $"remove 0");
}
}
@ -142,6 +135,5 @@ internal class MaiTouchComConnector
{
var currentState = _buttonState.GetCurrentState();
serialPort?.Write(currentState, 0, currentState.Length);
//Console.WriteLine($"Sent Touchscreen State: {report}");*/
}
}

View File

@ -3,9 +3,9 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfMaiTouchEmulator"
mc:Ignorable="d"
Title="MainWindow" Height="243" Width="800">
Closing="MainWindow_Closing"
Title="MainWindow" Height="282" Width="800">
<Grid Background="Transparent">
<Button x:Name="ConnectToPortButton" Content="Connect to port" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Click="ConnectToPortButton_Click" Width="105"/>
<TextBox x:Name="RecievedLogBox"
@ -31,7 +31,10 @@
<CheckBox x:Name="automaticPortConnecting" HorizontalAlignment="Left" Margin="10,81,0,0" VerticalAlignment="Top" Height="17" Width="224" Content="Automatic port connecting" IsChecked="{Binding Path=IsAutomaticPortConnectingEnabled}" Click="automaticPortConnecting_Click"/>
<Label x:Name="label1" Content="Connection state" HorizontalAlignment="Left" Margin="238,8,0,0" VerticalAlignment="Top"/>
<Label x:Name="connectionStateLabel" Content="Not connected" HorizontalAlignment="Left" Margin="238,31,0,0" VerticalAlignment="Top" FontSize="10"/>
<CheckBox x:Name="exitWithSinmai" HorizontalAlignment="Left" Margin="10,103,0,0" VerticalAlignment="Top" Height="17" Width="224" Content="Automatic port connecting" IsChecked="{Binding IsExitWithSinmaiEnabled}" Click="exitWithSinmai_Click"/>
<CheckBox x:Name="exitWithSinmai" HorizontalAlignment="Left" Margin="10,103,0,0" VerticalAlignment="Top" Height="17" Width="224" Content="Exit when Sinmai exits" IsChecked="{Binding IsExitWithSinmaiEnabled}" Click="exitWithSinmai_Click"/>
<Button x:Name="buttonInstallComPort" Content="Install com port" HorizontalAlignment="Left" Margin="10,147,0,0" VerticalAlignment="Top" Click="buttonInstallComPort_Click"/>
<Button x:Name="buttonUninstallComPorts" Content="Uninstall com port" HorizontalAlignment="Left" Margin="10,172,0,0" VerticalAlignment="Top" Click="buttonUninstallComPorts_Click"/>
<Button x:Name="buttonListComPorts" Content="List installed com ports" HorizontalAlignment="Left" Margin="10,197,0,0" VerticalAlignment="Top" Click="buttonListComPorts_Click"/>
</Grid>

View File

@ -18,7 +18,8 @@ public partial class MainWindow : Window
{
private readonly MaiTouchSensorButtonStateManager buttonState;
private MaiTouchComConnector connector;
private readonly TouchPanel _touchPanel;
private readonly VirtualComPortManager comPortManager;
private TouchPanel _touchPanel;
public MainWindow()
{
@ -26,7 +27,12 @@ public partial class MainWindow : Window
Title = "Mai Touch Emulator";
buttonState = new MaiTouchSensorButtonStateManager(buttonStateValue);
connector = new MaiTouchComConnector(buttonState);
connector.OnConnectStatusChange = (status) => Title = $"Mai Touch Emulator - {status}";
comPortManager = new VirtualComPortManager();
connector.OnConnectStatusChange = (status) =>
{
connectionStateLabel.Content = status;
};
connector.OnDataSent = (data) =>
{
Application.Current.Dispatcher.Invoke(() =>
@ -44,22 +50,34 @@ public partial class MainWindow : Window
});
};
_touchPanel = new TouchPanel();
_touchPanel.onTouch = (value) => { buttonState.PressButton(value); };
_touchPanel.onRelease = (value) => { buttonState.ReleaseButton(value); };
_touchPanel.Show();
DataContext = new MainWindowViewModel()
{
IsDebugEnabled = Properties.Settings.Default.IsDebugEnabled,
IsAutomaticPortConnectingEnabled = Properties.Settings.Default.IsAutomaticPortConnectingEnabled,
IsAutomaticPositioningEnabled = Properties.Settings.Default.IsAutomaticPositioningEnabled,
IsExitWithSinmaiEnabled = Properties.Settings.Default.IsExitWithSinmaiEnabled
};
Loaded += (s, e) => {
_touchPanel = new TouchPanel();
_touchPanel.onTouch = (value) => { buttonState.PressButton(value); };
_touchPanel.onRelease = (value) => { buttonState.ReleaseButton(value); };
_touchPanel.Show();
_touchPanel.Owner = this;
DataContext = new MainWindowViewModel()
{
IsDebugEnabled = Properties.Settings.Default.IsDebugEnabled,
IsAutomaticPortConnectingEnabled = Properties.Settings.Default.IsAutomaticPortConnectingEnabled,
IsAutomaticPositioningEnabled = Properties.Settings.Default.IsAutomaticPositioningEnabled,
IsExitWithSinmaiEnabled = Properties.Settings.Default.IsExitWithSinmaiEnabled
};
var dataContext = (MainWindowViewModel)DataContext;
_touchPanel.SetDebugMode(dataContext.IsDebugEnabled);
AutomaticTouchPanelPositioningLoop();
ExitWithSinmaiLoop();
var dataContext = (MainWindowViewModel)DataContext;
_touchPanel.SetDebugMode(dataContext.IsDebugEnabled);
AutomaticTouchPanelPositioningLoop();
AutomaticcPortConnectingLoop();
ExitWithSinmaiLoop();
};
}
private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
foreach (Window childWindow in OwnedWindows)
{
childWindow.Close();
}
}
private async void ExitWithSinmaiLoop()
@ -98,9 +116,23 @@ public partial class MainWindow : Window
}
}
private async void AutomaticcPortConnectingLoop()
{
var dataContext = (MainWindowViewModel)DataContext;
while (true)
{
if (dataContext.IsAutomaticPortConnectingEnabled)
{
await connector.StartTouchSensorPolling();
}
await Task.Delay(1000);
}
}
private async void ConnectToPortButton_Click(object sender, RoutedEventArgs e)
{
await connector.startLoopAsync();
await connector.StartTouchSensorPolling();
}
private void debugMode_Click(object sender, RoutedEventArgs e)
@ -139,4 +171,22 @@ public partial class MainWindow : Window
Properties.Settings.Default.IsExitWithSinmaiEnabled = dataContext.IsExitWithSinmaiEnabled;
Properties.Settings.Default.Save();
}
private async void buttonInstallComPort_Click(object sender, RoutedEventArgs e)
{
var output = await comPortManager.InstallComPort();
MessageBox.Show(output);
}
private async void buttonUninstallComPorts_Click(object sender, RoutedEventArgs e)
{
var output = await comPortManager.UninstallVirtualPorts();
MessageBox.Show(output);
}
private async void buttonListComPorts_Click(object sender, RoutedEventArgs e)
{
var output = await comPortManager.CheckInstalledPortsAsync();
MessageBox.Show(output);
}
}

View File

@ -1,65 +1,59 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace WpfMaiTouchEmulator
namespace WpfMaiTouchEmulator;
internal class MainWindowViewModel : INotifyPropertyChanged
{
class MainWindowViewModel : INotifyPropertyChanged
private bool _isAutomaticPortConnectingEnabled;
private bool _isDebugEnabled;
private bool _isAutomaticPositioningEnabled;
private bool _isExitWithSinmaiEnabled;
public bool IsDebugEnabled
{
private bool _isAutomaticPortConnectingEnabled;
private bool _isDebugEnabled;
private bool _isAutomaticPositioningEnabled;
private bool _isExitWithSinmaiEnabled;
public bool IsDebugEnabled
get => _isDebugEnabled;
set
{
get => _isDebugEnabled;
set
{
_isDebugEnabled = value;
OnPropertyChanged();
}
}
public bool IsAutomaticPositioningEnabled
{
get => _isAutomaticPositioningEnabled;
set
{
_isAutomaticPositioningEnabled = value;
OnPropertyChanged();
}
}
public bool IsAutomaticPortConnectingEnabled
{
get => _isAutomaticPortConnectingEnabled;
set
{
_isAutomaticPortConnectingEnabled = value;
OnPropertyChanged();
}
}
public bool IsExitWithSinmaiEnabled
{
get => _isExitWithSinmaiEnabled;
set
{
_isExitWithSinmaiEnabled = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler? PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
_isDebugEnabled = value;
OnPropertyChanged();
}
}
public bool IsAutomaticPositioningEnabled
{
get => _isAutomaticPositioningEnabled;
set
{
_isAutomaticPositioningEnabled = value;
OnPropertyChanged();
}
}
public bool IsAutomaticPortConnectingEnabled
{
get => _isAutomaticPortConnectingEnabled;
set
{
_isAutomaticPortConnectingEnabled = value;
OnPropertyChanged();
}
}
public bool IsExitWithSinmaiEnabled
{
get => _isExitWithSinmaiEnabled;
set
{
_isExitWithSinmaiEnabled = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler? PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}

View File

@ -189,7 +189,10 @@ public partial class TouchPanel : Window
private void HighlightElement(System.Windows.Controls.Image element, bool highlight)
{
element.Opacity = highlight ? 0.8 : 0.3;
if (Properties.Settings.Default.IsDebugEnabled)
{
element.Opacity = highlight ? 0.8 : 0.3;
}
}
}

View File

@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WpfMaiTouchEmulator
{
class VirtualComPortManager
{
public Task<string> CheckInstalledPortsAsync()
{
return ExecuteCommandAsync("C:\\Program Files (x86)\\com0com\\setupc.exe", $"list");
}
public Task<string> InstallComPort()
{
return ExecuteCommandAsync("C:\\Program Files (x86)\\com0com\\setupc.exe", $"install PortName=COM3 PortName=COM23");
}
public Task<string> UninstallVirtualPorts()
{
return ExecuteCommandAsync("C:\\Program Files (x86)\\com0com\\setupc.exe", $"uninstall");
}
private async Task<string> ExecuteCommandAsync(string command, string arguments)
{
var processStartInfo = new ProcessStartInfo
{
FileName = command,
Arguments = arguments,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true,
WorkingDirectory = "C:\\Program Files (x86)\\com0com"
};
var outputBuilder = new StringBuilder();
using (var process = new Process { StartInfo = processStartInfo })
{
process.OutputDataReceived += (sender, args) =>
{
if (args.Data != null)
outputBuilder.AppendLine(args.Data);
};
process.ErrorDataReceived += (sender, args) =>
{
if (args.Data != null)
outputBuilder.AppendLine(args.Data);
};
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
await process.WaitForExitAsync();
return outputBuilder.ToString();
}
}
}
}