Compare commits
42 Commits
Author | SHA1 | Date |
---|---|---|
![]() |
a68aa187c7 | |
![]() |
a2b63c607a | |
![]() |
76f39d5be8 | |
![]() |
643fb31505 | |
![]() |
df962b7304 | |
![]() |
289b4f2ff5 | |
![]() |
f12494faf3 | |
![]() |
6e8500a479 | |
![]() |
79e2ea3fcd | |
![]() |
0815b20ee8 | |
![]() |
f39fead973 | |
![]() |
f239e9b534 | |
![]() |
f75d77c66a | |
![]() |
3571776b83 | |
![]() |
0347c983b6 | |
![]() |
066ecf6850 | |
![]() |
3eb9c1438a | |
![]() |
179a6a256a | |
![]() |
3f8236506a | |
![]() |
4d36fc7c64 | |
![]() |
81edbde5cc | |
![]() |
3a8d0e59c4 | |
![]() |
a01cdd6dfa | |
![]() |
9d06a0293a | |
![]() |
ee47b30a90 | |
![]() |
3b7aa9c11e | |
![]() |
a0cfa9c0c6 | |
![]() |
2033b5e145 | |
![]() |
a0364ef46b | |
![]() |
7d67cb9437 | |
![]() |
4bd11f9f25 | |
![]() |
c24e4a47a2 | |
![]() |
9c1057dbc5 | |
![]() |
06edb9fcfc | |
![]() |
621f90937f | |
![]() |
b6872dde34 | |
![]() |
48cdfd0e72 | |
![]() |
b73e88f1da | |
![]() |
fef5fd0ebd | |
![]() |
f42f210452 | |
![]() |
851d83ca51 | |
![]() |
0a79a71f82 |
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
name: Bug report
|
||||
about: 'Create a report to help improve the application '
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Please describe the issue in English if possible**
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is and when it occurs. Please include the app version and any logs/crash dumps.
|
||||
For the portable version of the application these can be found in the same directory as the exe.
|
||||
For installed version of the application these can be found under `%LOCALAPPDATA%/WpfMaiTouchEmulator`
|
||||
|
||||
**To Reproduce**
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots/videos to help explain your problem.
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Please fill out in English if possible**
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
|
@ -1,41 +1,3 @@
|
|||
# This workflow uses actions that are not certified by GitHub.
|
||||
# They are provided by a third-party and are governed by
|
||||
# separate terms of service, privacy policy, and support
|
||||
# documentation.
|
||||
|
||||
# This workflow will build, test, sign and package a WPF or Windows Forms desktop application
|
||||
# built on .NET Core.
|
||||
# To learn how to migrate your existing application to .NET Core,
|
||||
# refer to https://docs.microsoft.com/en-us/dotnet/desktop-wpf/migration/convert-project-from-net-framework
|
||||
#
|
||||
# To configure this workflow:
|
||||
#
|
||||
# 1. Configure environment variables
|
||||
# GitHub sets default environment variables for every workflow run.
|
||||
# Replace the variables relative to your project in the "env" section below.
|
||||
#
|
||||
# 2. Signing
|
||||
# Generate a signing certificate in the Windows Application
|
||||
# Packaging Project or add an existing signing certificate to the project.
|
||||
# Next, use PowerShell to encode the .pfx file using Base64 encoding
|
||||
# by running the following Powershell script to generate the output string:
|
||||
#
|
||||
# $pfx_cert = Get-Content '.\SigningCertificate.pfx' -Encoding Byte
|
||||
# [System.Convert]::ToBase64String($pfx_cert) | Out-File 'SigningCertificate_Encoded.txt'
|
||||
#
|
||||
# Open the output file, SigningCertificate_Encoded.txt, and copy the
|
||||
# string inside. Then, add the string to the repo as a GitHub secret
|
||||
# and name it "Base64_Encoded_Pfx."
|
||||
# For more information on how to configure your signing certificate for
|
||||
# this workflow, refer to https://github.com/microsoft/github-actions-for-desktop-apps#signing
|
||||
#
|
||||
# Finally, add the signing certificate password to the repo as a secret and name it "Pfx_Key".
|
||||
# See "Build the Windows Application Packaging project" below to see how the secret is used.
|
||||
#
|
||||
# For more information on GitHub Actions, refer to https://github.com/features/actions
|
||||
# For a complete CI/CD sample to get started with GitHub Action workflows for Desktop Applications,
|
||||
# refer to https://github.com/microsoft/github-actions-for-desktop-apps
|
||||
|
||||
name: .NET Core Desktop
|
||||
|
||||
on:
|
||||
|
@ -53,13 +15,11 @@ jobs:
|
|||
matrix:
|
||||
configuration: [Release]
|
||||
|
||||
runs-on: windows-latest # For a list of available runner types, refer to
|
||||
# https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idruns-on
|
||||
|
||||
runs-on: windows-latest
|
||||
env:
|
||||
Solution_Name: WpfMaiTouchEmulator.sln # Replace with your solution name, i.e. MyWpfApp.sln.
|
||||
Wap_Project_Directory: . # Replace with the Wap project directory relative to the solution, i.e. MyWpfApp.Package.
|
||||
Wap_Project_Path: WpfMaiTouchEmulator.csproj # Replace with the path to your Wap project, i.e. MyWpf.App.Package\MyWpfApp.Package.wapproj.
|
||||
Solution_Name: WpfMaiTouchEmulator.sln
|
||||
Wap_Project_Directory: .
|
||||
Wap_Project_Path: WpfMaiTouchEmulator.csproj
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
@ -92,20 +52,38 @@ jobs:
|
|||
|
||||
# Create the app package by building and packaging the Windows Application Packaging project
|
||||
- name: Create the app package
|
||||
run: msbuild $env:Wap_Project_Path /p:Configuration=$env:Configuration /p:UapAppxPackageBuildMode=$env:Appx_Package_Build_Mode /p:AppxBundle=$env:Appx_Bundle /p:PackageCertificateKeyFile=GitHubActionsWorkflow.pfx /p:PackageCertificatePassword=${{ secrets.Pfx_Key }}
|
||||
run: msbuild $env:Wap_Project_Path /p:Configuration=$env:Configuration /p:UapAppxPackageBuildMode=$env:Appx_Package_Build_Mode /p:AppxBundle=$env:Appx_Bundle /p:PackageCertificateKeyFile=GitHubActionsWorkflow.pfx /p:PackageCertificatePassword=${{ secrets.Pfx_Key }} /p:Version=1.5.0.${{ github.run_number }}
|
||||
env:
|
||||
Appx_Bundle: Always
|
||||
Appx_Bundle_Platforms: x86|x64
|
||||
Appx_Package_Build_Mode: StoreUpload
|
||||
Configuration: ${{ matrix.configuration }}
|
||||
|
||||
- name: Build AIP
|
||||
uses: caphyon/advinst-github-action@v2.0
|
||||
with:
|
||||
advinst-version: '22.2'
|
||||
advinst-enable-automation: 'true'
|
||||
aip-path: ${{ github.workspace }}\Installer\Mai Touch Emulator.aip
|
||||
aip-build-name: DefaultBuild
|
||||
aip-package-name: installMaiTouchEmulator.msi
|
||||
aip-output-dir: ${{ github.workspace }}\setup
|
||||
aip-commands: |
|
||||
SetProperty FOO="foo"
|
||||
SetVersion 1.5.0.${{ github.run_number }}
|
||||
|
||||
# Remove the pfx
|
||||
- name: Remove the pfx
|
||||
run: Remove-Item -path $env:Wap_Project_Directory\GitHubActionsWorkflow.pfx
|
||||
|
||||
# Upload the MSIX package: https://github.com/marketplace/actions/upload-a-build-artifact
|
||||
- name: Upload build artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Emulator package
|
||||
path: ./bin/Release/net8.0-windows/
|
||||
name: MaiTouchEmulatorPortable
|
||||
path: ./bin/Release/net8.0-windows10.0.17763.0/
|
||||
|
||||
- name: Publish setup artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: MaiTouchEmulatorInstaller
|
||||
path: ./setup/installMaiTouchEmulator.msi
|
||||
|
|
|
@ -360,4 +360,6 @@ MigrationBackup/
|
|||
.ionide/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
FodyWeavers.xsd
|
||||
|
||||
Installer/
|
||||
|
|
18
App.config
|
@ -22,6 +22,24 @@
|
|||
<setting name="FirstOpen" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="UserLanguage" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
<setting name="IsRingButtonEmulationEnabled" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="BorderSetting" serializeAs="String">
|
||||
<value>0</value>
|
||||
</setting>
|
||||
<setting name="BorderColour" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
<setting name="UserSettingsUpgradeRequired" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
<setting name="IsLargeButtonsEnabled" serializeAs="String">
|
||||
<value>False</value>
|
||||
</setting>
|
||||
</WpfMaiTouchEmulator.Properties.Settings>
|
||||
</userSettings>
|
||||
</configuration>
|
8
App.xaml
|
@ -2,8 +2,14 @@
|
|||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:WpfMaiTouchEmulator"
|
||||
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
|
||||
StartupUri="MainWindow.xaml">
|
||||
<Application.Resources>
|
||||
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ui:ThemesDictionary Theme="Light" />
|
||||
<ui:ControlsDictionary />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
|
|
|
@ -28,7 +28,7 @@ public partial class App : Application
|
|||
|
||||
private void CreateDump(Exception exception)
|
||||
{
|
||||
var dumpFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "CrashDump.dmp");
|
||||
var dumpFilePath = Path.Combine(Logger.GetLogPath(), "CrashDump.dmp");
|
||||
|
||||
using (var fs = new FileStream(dumpFilePath, FileMode.Create))
|
||||
{
|
||||
|
|
Before Width: | Height: | Size: 724 B |
Before Width: | Height: | Size: 777 B |
Before Width: | Height: | Size: 779 B |
Before Width: | Height: | Size: 697 B |
Before Width: | Height: | Size: 781 B |
Before Width: | Height: | Size: 731 B |
Before Width: | Height: | Size: 732 B |
Before Width: | Height: | Size: 783 B |
Before Width: | Height: | Size: 420 B |
Before Width: | Height: | Size: 451 B |
Before Width: | Height: | Size: 440 B |
Before Width: | Height: | Size: 397 B |
Before Width: | Height: | Size: 408 B |
Before Width: | Height: | Size: 445 B |
Before Width: | Height: | Size: 444 B |
Before Width: | Height: | Size: 412 B |
Before Width: | Height: | Size: 138 B |
Before Width: | Height: | Size: 361 B |
Before Width: | Height: | Size: 367 B |
Before Width: | Height: | Size: 402 B |
Before Width: | Height: | Size: 670 B |
Before Width: | Height: | Size: 412 B |
Before Width: | Height: | Size: 623 B |
Before Width: | Height: | Size: 396 B |
Before Width: | Height: | Size: 717 B |
Before Width: | Height: | Size: 419 B |
Before Width: | Height: | Size: 715 B |
Before Width: | Height: | Size: 490 B |
Before Width: | Height: | Size: 172 B |
Before Width: | Height: | Size: 490 B |
Before Width: | Height: | Size: 172 B |
Before Width: | Height: | Size: 490 B |
Before Width: | Height: | Size: 172 B |
Before Width: | Height: | Size: 490 B |
Before Width: | Height: | Size: 172 B |
After Width: | Height: | Size: 217 KiB |
After Width: | Height: | Size: 132 KiB |
After Width: | Height: | Size: 20 KiB |
|
@ -0,0 +1,287 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<DOCUMENT Type="Advanced Installer" CreateVersion="22.2" version="22.2" Modules="simple" RootPath="." Language="en" Id="{B5359581-6E04-4DC3-88F2-8DB4D3AD09E6}">
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiPropsComponent">
|
||||
<ROW Property="AI_APP_FILE" Value="[#WpfMaiTouchEmulator.exe]"/>
|
||||
<ROW Property="AI_BITMAP_DISPLAY_MODE" Value="0"/>
|
||||
<ROW Property="AI_PREDEF_LCONDS_PROPS" Value="AI_DETECTED_ADMIN_USER;AI_DETECTED_DOTNET_CORE_VERSION"/>
|
||||
<ROW Property="AI_REQUIRED_DOTNET_CORE_DISPLAY" MultiBuildValue="DefaultBuild:8.0" ValueLocId="-"/>
|
||||
<ROW Property="AI_REQUIRED_DOTNET_CORE_VERSION" MultiBuildValue="DefaultBuild:8.0" ValueLocId="-"/>
|
||||
<ROW Property="ALLUSERS" Value="1" MultiBuildValue="DefaultBuild:2"/>
|
||||
<ROW Property="ARPCOMMENTS" Value="This installer database contains the logic and data required to install [|ProductName]." ValueLocId="*"/>
|
||||
<ROW Property="ARPPRODUCTICON" Value="icon.exe" Type="8"/>
|
||||
<ROW Property="CTRLS" Value="2"/>
|
||||
<ROW Property="Manufacturer" Value="Leapward-Koex"/>
|
||||
<ROW Property="ProductCode" Value="1033:{08E138ED-9CC0-4CF8-BC4A-E0B7B270D5F7} " Type="16"/>
|
||||
<ROW Property="ProductLanguage" Value="1033"/>
|
||||
<ROW Property="ProductName" Value="Mai Touch Emulator"/>
|
||||
<ROW Property="ProductVersion" Value="1.0.0" Options="32"/>
|
||||
<ROW Property="REBOOT" MultiBuildValue="DefaultBuild:ReallySuppress"/>
|
||||
<ROW Property="SecureCustomProperties" Value="OLDPRODUCTS;AI_NEWERPRODUCTFOUND"/>
|
||||
<ROW Property="UpgradeCode" Value="{464CA79D-14BC-45BC-AE26-F5C4D59346C9}"/>
|
||||
<ROW Property="WindowsType9X" MultiBuildValue="DefaultBuild:Windows 9x/ME" ValueLocId="-"/>
|
||||
<ROW Property="WindowsType9XDisplay" MultiBuildValue="DefaultBuild:Windows 9x/ME" ValueLocId="-"/>
|
||||
<ROW Property="WindowsTypeNT" MultiBuildValue="DefaultBuild:Windows 7 x86, Windows 8 x86, Windows 8.1 x86" ValueLocId="-"/>
|
||||
<ROW Property="WindowsTypeNT40" MultiBuildValue="DefaultBuild:Windows NT 4.0" ValueLocId="-"/>
|
||||
<ROW Property="WindowsTypeNT40Display" MultiBuildValue="DefaultBuild:Windows NT 4.0" ValueLocId="-"/>
|
||||
<ROW Property="WindowsTypeNT50" MultiBuildValue="DefaultBuild:Windows 2000" ValueLocId="-"/>
|
||||
<ROW Property="WindowsTypeNT50Display" MultiBuildValue="DefaultBuild:Windows 2000" ValueLocId="-"/>
|
||||
<ROW Property="WindowsTypeNT5X" MultiBuildValue="DefaultBuild:Windows XP/2003" ValueLocId="-"/>
|
||||
<ROW Property="WindowsTypeNT5XDisplay" MultiBuildValue="DefaultBuild:Windows XP/2003" ValueLocId="-"/>
|
||||
<ROW Property="WindowsTypeNT60" MultiBuildValue="DefaultBuild:Windows Vista/Server 2008" ValueLocId="-"/>
|
||||
<ROW Property="WindowsTypeNT60Display" MultiBuildValue="DefaultBuild:Windows Vista/Server 2008" ValueLocId="-"/>
|
||||
<ROW Property="WindowsTypeNT64" MultiBuildValue="DefaultBuild:Windows 7 x64, Windows Server 2008 R2 x64, Windows 8 x64, Windows Server 2012 x64, Windows 8.1 x64, Windows Server 2012 R2 x64, Windows Server x64" ValueLocId="-"/>
|
||||
<ROW Property="WindowsTypeNT64Display" MultiBuildValue="DefaultBuild:Windows 7 x64, Windows Server 2008 R2 x64, Windows 8 x64, Windows Server 2012 x64, Windows 8.1 x64, Windows Server 2012 R2 x64, Windows Server x64" ValueLocId="-"/>
|
||||
<ROW Property="WindowsTypeNTDisplay" MultiBuildValue="DefaultBuild:Windows 7 x86, Windows 8 x86, Windows 8.1 x86" ValueLocId="-"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiDirsComponent">
|
||||
<ROW Directory="APPDIR" Directory_Parent="TARGETDIR" DefaultDir="APPDIR:." IsPseudoRoot="1"/>
|
||||
<ROW Directory="ProgramMenuFolder" Directory_Parent="TARGETDIR" DefaultDir="PROGRA~1|ProgramMenuFolder" IsPseudoRoot="1"/>
|
||||
<ROW Directory="TARGETDIR" DefaultDir="SourceDir"/>
|
||||
<ROW Directory="com0com_Dir" Directory_Parent="thirdpartyprograms_Dir" DefaultDir="com0com"/>
|
||||
<ROW Directory="jaJP_Dir" Directory_Parent="APPDIR" DefaultDir="ja-JP"/>
|
||||
<ROW Directory="lib_1_Dir" Directory_Parent="win_Dir" DefaultDir="lib"/>
|
||||
<ROW Directory="net8.0_1_Dir" Directory_Parent="lib_1_Dir" DefaultDir="net8.0"/>
|
||||
<ROW Directory="runtimes_Dir" Directory_Parent="APPDIR" DefaultDir="runtimes"/>
|
||||
<ROW Directory="thirdpartyprograms_Dir" Directory_Parent="APPDIR" DefaultDir="THIRDP~1|thirdparty programs"/>
|
||||
<ROW Directory="win_Dir" Directory_Parent="runtimes_Dir" DefaultDir="win"/>
|
||||
<ROW Directory="zhCN_Dir" Directory_Parent="APPDIR" DefaultDir="zh-CN"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.SideBySideGuidComponent">
|
||||
<ROW Component="APPDIR" Value="{E9523757-B9AF-4FE4-8034-0CA60B965037}"/>
|
||||
<ROW Component="ProductInformation" Value="{69562BAB-9822-4EC6-BB86-EA5953730D68}"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiCompsComponent">
|
||||
<ROW Component="AI_INSTALLPERUSER" ComponentId="{8DE0F484-4802-477C-8708-40D881BE6323}" Directory_="APPDIR" Attributes="260" KeyPath="AI_INSTALLPERUSER" Options="1"/>
|
||||
<ROW Component="APPDIR" ComponentId="{E9523757-B9AF-4FE4-8034-0CA60B965037}" Directory_="APPDIR" Attributes="0"/>
|
||||
<ROW Component="Microsoft.Win32.SystemEvents.dll" ComponentId="{1CD260D3-BC38-4E6F-87B3-F243BF6FB3E5}" Directory_="net8.0_1_Dir" Attributes="0" KeyPath="Microsoft.Win32.SystemEvents.dll"/>
|
||||
<ROW Component="Microsoft.Win32.SystemEvents.dll_1" ComponentId="{4FF055E5-90A5-4D0B-869D-81D87D9F5D4C}" Directory_="APPDIR" Attributes="0" KeyPath="Microsoft.Win32.SystemEvents.dll_1"/>
|
||||
<ROW Component="Microsoft.Windows.SDK.NET.dll" ComponentId="{FD3FCBF4-F9D9-4DD6-BDB1-2E462A39154E}" Directory_="APPDIR" Attributes="0" KeyPath="Microsoft.Windows.SDK.NET.dll"/>
|
||||
<ROW Component="ProductInformation" ComponentId="{69562BAB-9822-4EC6-BB86-EA5953730D68}" Directory_="APPDIR" Attributes="260" KeyPath="Version"/>
|
||||
<ROW Component="System.Drawing.Common.dll" ComponentId="{27EDF0B3-615B-49A8-B181-7339D01DC5BD}" Directory_="APPDIR" Attributes="0" KeyPath="System.Drawing.Common.dll"/>
|
||||
<ROW Component="System.IO.Ports.dll" ComponentId="{D776A384-99ED-49DE-8047-4C06A5141960}" Directory_="APPDIR" Attributes="0" KeyPath="System.IO.Ports.dll"/>
|
||||
<ROW Component="System.IO.Ports.dll_1" ComponentId="{767812B6-6569-4A50-917D-F7FAB0DEA8FB}" Directory_="net8.0_1_Dir" Attributes="0" KeyPath="System.IO.Ports.dll_1"/>
|
||||
<ROW Component="System.Private.Windows.Core.dll" ComponentId="{55D5CCEF-9774-4702-950A-F564146D2473}" Directory_="APPDIR" Attributes="0" KeyPath="System.Private.Windows.Core.dll"/>
|
||||
<ROW Component="WinRT.Runtime.dll" ComponentId="{8BEB0AE9-88A8-409E-9129-0A1F2CBE0850}" Directory_="APPDIR" Attributes="0" KeyPath="WinRT.Runtime.dll"/>
|
||||
<ROW Component="Wpf.Ui.dll" ComponentId="{8A193511-50C0-4369-8159-FF599D4CEEB8}" Directory_="APPDIR" Attributes="0" KeyPath="Wpf.Ui.dll"/>
|
||||
<ROW Component="WpfMaiTouchEmulator.deps.json" ComponentId="{CD8C5345-8556-4C3E-AAE9-1E7D90E1DD5A}" Directory_="APPDIR" Attributes="0" KeyPath="WpfMaiTouchEmulator.deps.json" Type="0"/>
|
||||
<ROW Component="WpfMaiTouchEmulator.dll" ComponentId="{B289ACCE-2BAF-436F-814B-D39E91524B89}" Directory_="APPDIR" Attributes="256" KeyPath="WpfMaiTouchEmulator.dll"/>
|
||||
<ROW Component="WpfMaiTouchEmulator.exe" ComponentId="{AA079BFA-401B-4AFA-A56A-92F2A65DB096}" Directory_="APPDIR" Attributes="256" KeyPath="WpfMaiTouchEmulator.exe"/>
|
||||
<ROW Component="WpfMaiTouchEmulator.resources.dll" ComponentId="{01F7375B-D27D-407C-AD17-EE73D183740C}" Directory_="zhCN_Dir" Attributes="256" KeyPath="WpfMaiTouchEmulator.resources.dll"/>
|
||||
<ROW Component="WpfMaiTouchEmulator.resources.dll_1" ComponentId="{27FEB25A-02E1-4D0B-9357-FE31FC757C34}" Directory_="jaJP_Dir" Attributes="256" KeyPath="WpfMaiTouchEmulator.resources.dll_1"/>
|
||||
<ROW Component="com0com.cat" ComponentId="{DE7A59B3-AA91-441B-8E80-99E5B7B56F07}" Directory_="com0com_Dir" Attributes="0" KeyPath="com0com.cat" Type="0"/>
|
||||
<ROW Component="setup.dll" ComponentId="{6DB50EDF-6F89-4A1D-A709-584F83A0B5CF}" Directory_="com0com_Dir" Attributes="256" KeyPath="setup.dll"/>
|
||||
<ROW Component="setupc.exe" ComponentId="{EEA73D45-D23D-4F40-A657-F93D96427FDF}" Directory_="com0com_Dir" Attributes="256" KeyPath="setupc.exe"/>
|
||||
<ROW Component="setupg.exe" ComponentId="{8532B8AB-C539-4A78-A83A-FF8BC1671E15}" Directory_="com0com_Dir" Attributes="0" KeyPath="setupg.exe"/>
|
||||
<ROW Component="uninstall.exe" ComponentId="{645968DC-E43B-43A0-B6A6-A25616A43837}" Directory_="com0com_Dir" Attributes="0" KeyPath="uninstall.exe"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiFeatsComponent">
|
||||
<ROW Feature="MainFeature" Title="MainFeature" Description="Description" Display="1" Level="1" Directory_="APPDIR" Attributes="0"/>
|
||||
<ATTRIBUTE name="CurrentFeature" value="MainFeature"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiFilesComponent">
|
||||
<ROW File="com0com.cat" Component_="com0com.cat" FileName="com0com.cat" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\thirdparty programs\com0com\com0com.cat" SelfReg="false"/>
|
||||
<ROW File="com0com.inf" Component_="com0com.cat" FileName="com0com.inf" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\thirdparty programs\com0com\com0com.inf" SelfReg="false"/>
|
||||
<ROW File="com0com.sys" Component_="com0com.cat" FileName="com0com.sys" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\thirdparty programs\com0com\com0com.sys" SelfReg="false"/>
|
||||
<ROW File="ReadMe.txt" Component_="com0com.cat" FileName="ReadMe.txt" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\thirdparty programs\com0com\ReadMe.txt" SelfReg="false"/>
|
||||
<ROW File="setup.dll" Component_="setup.dll" FileName="setup.dll" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\thirdparty programs\com0com\setup.dll" SelfReg="false"/>
|
||||
<ROW File="setupc.exe" Component_="setupc.exe" FileName="setupc.exe" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\thirdparty programs\com0com\setupc.exe" SelfReg="false" DigSign="true"/>
|
||||
<ROW File="setupg.exe" Component_="setupg.exe" FileName="setupg.exe" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\thirdparty programs\com0com\setupg.exe" SelfReg="false" DigSign="true"/>
|
||||
<ROW File="uninstall.exe" Component_="uninstall.exe" FileName="UNINST~1.EXE|uninstall.exe" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\thirdparty programs\com0com\uninstall.exe" SelfReg="false" DigSign="true"/>
|
||||
<ROW File="Microsoft.Win32.SystemEvents.dll" Component_="Microsoft.Win32.SystemEvents.dll" FileName="MICROS~1.DLL|Microsoft.Win32.SystemEvents.dll" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\runtimes\win\lib\net8.0\Microsoft.Win32.SystemEvents.dll" SelfReg="false"/>
|
||||
<ROW File="System.IO.Ports.dll_1" Component_="System.IO.Ports.dll_1" FileName="SYSTEM~1.DLL|System.IO.Ports.dll" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\runtimes\win\lib\net8.0\System.IO.Ports.dll" SelfReg="false"/>
|
||||
<ROW File="WpfMaiTouchEmulator.resources.dll" Component_="WpfMaiTouchEmulator.resources.dll" FileName="WPFMAI~1.DLL|WpfMaiTouchEmulator.resources.dll" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\zh-CN\WpfMaiTouchEmulator.resources.dll" SelfReg="false"/>
|
||||
<ROW File="WpfMaiTouchEmulator.resources.dll_1" Component_="WpfMaiTouchEmulator.resources.dll_1" FileName="WPFMAI~1.DLL|WpfMaiTouchEmulator.resources.dll" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\ja-JP\WpfMaiTouchEmulator.resources.dll" SelfReg="false"/>
|
||||
<ROW File="Microsoft.Win32.SystemEvents.dll_1" Component_="Microsoft.Win32.SystemEvents.dll_1" FileName="MICROS~1.DLL|Microsoft.Win32.SystemEvents.dll" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\Microsoft.Win32.SystemEvents.dll" SelfReg="false"/>
|
||||
<ROW File="Microsoft.Windows.SDK.NET.dll" Component_="Microsoft.Windows.SDK.NET.dll" FileName="MICROS~2.DLL|Microsoft.Windows.SDK.NET.dll" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\Microsoft.Windows.SDK.NET.dll" SelfReg="false"/>
|
||||
<ROW File="System.Drawing.Common.dll" Component_="System.Drawing.Common.dll" FileName="SYSTEM~1.DLL|System.Drawing.Common.dll" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\System.Drawing.Common.dll" SelfReg="false"/>
|
||||
<ROW File="System.IO.Ports.dll" Component_="System.IO.Ports.dll" FileName="SYSTEM~2.DLL|System.IO.Ports.dll" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\System.IO.Ports.dll" SelfReg="false"/>
|
||||
<ROW File="System.Private.Windows.Core.dll" Component_="System.Private.Windows.Core.dll" FileName="SYSTEM~3.DLL|System.Private.Windows.Core.dll" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\System.Private.Windows.Core.dll" SelfReg="false"/>
|
||||
<ROW File="WinRT.Runtime.dll" Component_="WinRT.Runtime.dll" FileName="WINRTR~1.DLL|WinRT.Runtime.dll" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\WinRT.Runtime.dll" SelfReg="false"/>
|
||||
<ROW File="WpfMaiTouchEmulator.deps.json" Component_="WpfMaiTouchEmulator.deps.json" FileName="WPFMAI~1.JSO|WpfMaiTouchEmulator.deps.json" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\WpfMaiTouchEmulator.deps.json" SelfReg="false"/>
|
||||
<ROW File="WpfMaiTouchEmulator.dll" Component_="WpfMaiTouchEmulator.dll" FileName="WPFMAI~1.DLL|WpfMaiTouchEmulator.dll" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\WpfMaiTouchEmulator.dll" SelfReg="false"/>
|
||||
<ROW File="WpfMaiTouchEmulator.dll.config" Component_="WpfMaiTouchEmulator.deps.json" FileName="WPFMAI~1.CON|WpfMaiTouchEmulator.dll.config" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\WpfMaiTouchEmulator.dll.config" SelfReg="false"/>
|
||||
<ROW File="WpfMaiTouchEmulator.exe" Component_="WpfMaiTouchEmulator.exe" FileName="WPFMAI~1.EXE|WpfMaiTouchEmulator.exe" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\WpfMaiTouchEmulator.exe" SelfReg="false" DigSign="true"/>
|
||||
<ROW File="WpfMaiTouchEmulator.runtimeconfig.json" Component_="WpfMaiTouchEmulator.deps.json" FileName="WPFMAI~2.JSO|WpfMaiTouchEmulator.runtimeconfig.json" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\WpfMaiTouchEmulator.runtimeconfig.json" SelfReg="false"/>
|
||||
<ROW File="Wpf.Ui.dll" Component_="Wpf.Ui.dll" FileName="WPFUI~1.DLL|Wpf.Ui.dll" Attributes="0" SourcePath="..\bin\Release\net8.0-windows10.0.17763.0\Wpf.Ui.dll" SelfReg="false"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.AiPersistentPropComponent">
|
||||
<ROW Property="AI_INSTALLPERUSER" Registry="AI_INSTALLPERUSER" HklmSearch="AI_INSTALLPERUSER" HkcuSearch="AI_INSTALLPERUSER_1" Hklm64Search="AI_INSTALLPERUSER_2" Hkcu64Search="AI_INSTALLPERUSER_3"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.BootstrapperUISequenceComponent">
|
||||
<ROW Action="AI_DetectSoftware" Sequence="151"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.BuildComponent">
|
||||
<ROW BuildKey="DefaultBuild" BuildName="DefaultBuild" BuildOrder="1" BuildType="0" Languages="en" InstallationType="4" SummInfoMetadata="Page Count:450" UseLargeSchema="true" MsiPackageType="x64"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.DictionaryComponent">
|
||||
<ROW Path="<AI_DICTS>ui.ail"/>
|
||||
<ROW Path="<AI_DICTS>ui_en.ail"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.FragmentComponent">
|
||||
<ROW Fragment="CommonUI.aip" Path="<AI_FRAGS>CommonUI.aip"/>
|
||||
<ROW Fragment="FolderDlg.aip" Path="<AI_THEMES>classic\fragments\FolderDlg.aip"/>
|
||||
<ROW Fragment="InstallTypeDlg.aip" Path="<AI_THEMES>classic\fragments\InstallTypeDlg.aip"/>
|
||||
<ROW Fragment="MaintenanceTypeDlg.aip" Path="<AI_THEMES>classic\fragments\MaintenanceTypeDlg.aip"/>
|
||||
<ROW Fragment="MaintenanceWelcomeDlg.aip" Path="<AI_THEMES>classic\fragments\MaintenanceWelcomeDlg.aip"/>
|
||||
<ROW Fragment="SequenceDialogs.aip" Path="<AI_THEMES>classic\fragments\SequenceDialogs.aip"/>
|
||||
<ROW Fragment="Sequences.aip" Path="<AI_FRAGS>Sequences.aip"/>
|
||||
<ROW Fragment="StaticUIStrings.aip" Path="<AI_FRAGS>StaticUIStrings.aip"/>
|
||||
<ROW Fragment="Themes.aip" Path="<AI_FRAGS>Themes.aip"/>
|
||||
<ROW Fragment="UI.aip" Path="<AI_THEMES>classic\fragments\UI.aip"/>
|
||||
<ROW Fragment="Validation.aip" Path="<AI_FRAGS>Validation.aip"/>
|
||||
<ROW Fragment="VerifyRemoveDlg.aip" Path="<AI_THEMES>classic\fragments\VerifyRemoveDlg.aip"/>
|
||||
<ROW Fragment="VerifyRepairDlg.aip" Path="<AI_THEMES>classic\fragments\VerifyRepairDlg.aip"/>
|
||||
<ROW Fragment="WelcomeDlg.aip" Path="<AI_THEMES>classic\fragments\WelcomeDlg.aip"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiAppSearchComponent">
|
||||
<ROW Property="AI_INSTALLPERUSER" Signature_="AI_INSTALLPERUSER"/>
|
||||
<ROW Property="AI_INSTALLPERUSER" Signature_="AI_INSTALLPERUSER_1"/>
|
||||
<ROW Property="AI_INSTALLPERUSER" Signature_="AI_INSTALLPERUSER_2"/>
|
||||
<ROW Property="AI_INSTALLPERUSER" Signature_="AI_INSTALLPERUSER_3"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiBinaryComponent">
|
||||
<ROW Name="ShortcutFlags.dll" SourcePath="<AI_CUSTACTS>ShortcutFlags.dll"/>
|
||||
<ROW Name="SoftwareDetector.dll" SourcePath="<AI_CUSTACTS>SoftwareDetector.dll"/>
|
||||
<ROW Name="aicustact.dll" SourcePath="<AI_CUSTACTS>aicustact.dll"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiControlEventComponent">
|
||||
<ROW Dialog_="WelcomeDlg" Control_="Next" Event="NewDialog" Argument="InstallTypeDlg" Condition="AI_INSTALL" Ordering="1"/>
|
||||
<ROW Dialog_="FolderDlg" Control_="Next" Event="NewDialog" Argument="VerifyReadyDlg" Condition="AI_INSTALL" Ordering="201"/>
|
||||
<ROW Dialog_="FolderDlg" Control_="Back" Event="NewDialog" Argument="InstallTypeDlg" Condition="AI_INSTALL" Ordering="1"/>
|
||||
<ROW Dialog_="MaintenanceWelcomeDlg" Control_="Next" Event="NewDialog" Argument="MaintenanceTypeDlg" Condition="AI_MAINT" Ordering="99"/>
|
||||
<ROW Dialog_="VerifyReadyDlg" Control_="Install" Event="EndDialog" Argument="Return" Condition="AI_MAINT" Ordering="198"/>
|
||||
<ROW Dialog_="VerifyReadyDlg" Control_="Back" Event="NewDialog" Argument="CustomizeDlg" Condition="AI_MAINT" Ordering="202"/>
|
||||
<ROW Dialog_="VerifyReadyDlg" Control_="Install" Event="EndDialog" Argument="Return" Condition="AI_INSTALL" Ordering="197"/>
|
||||
<ROW Dialog_="VerifyReadyDlg" Control_="Back" Event="NewDialog" Argument="FolderDlg" Condition="AI_INSTALL" Ordering="201"/>
|
||||
<ROW Dialog_="CustomizeDlg" Control_="Next" Event="NewDialog" Argument="VerifyReadyDlg" Condition="AI_MAINT" Ordering="101"/>
|
||||
<ROW Dialog_="CustomizeDlg" Control_="Back" Event="NewDialog" Argument="MaintenanceTypeDlg" Condition="AI_MAINT" Ordering="1"/>
|
||||
<ROW Dialog_="MaintenanceTypeDlg" Control_="ChangeButton" Event="NewDialog" Argument="CustomizeDlg" Condition="AI_MAINT" Ordering="501"/>
|
||||
<ROW Dialog_="MaintenanceTypeDlg" Control_="Back" Event="NewDialog" Argument="MaintenanceWelcomeDlg" Condition="AI_MAINT" Ordering="1"/>
|
||||
<ROW Dialog_="MaintenanceTypeDlg" Control_="RemoveButton" Event="NewDialog" Argument="VerifyRemoveDlg" Condition="AI_MAINT AND InstallMode="Remove"" Ordering="601"/>
|
||||
<ROW Dialog_="VerifyRemoveDlg" Control_="Back" Event="NewDialog" Argument="MaintenanceTypeDlg" Condition="AI_MAINT AND InstallMode="Remove"" Ordering="1"/>
|
||||
<ROW Dialog_="MaintenanceTypeDlg" Control_="RepairButton" Event="NewDialog" Argument="VerifyRepairDlg" Condition="AI_MAINT AND InstallMode="Repair"" Ordering="601"/>
|
||||
<ROW Dialog_="VerifyRepairDlg" Control_="Back" Event="NewDialog" Argument="MaintenanceTypeDlg" Condition="AI_MAINT AND InstallMode="Repair"" Ordering="1"/>
|
||||
<ROW Dialog_="VerifyRepairDlg" Control_="Repair" Event="EndDialog" Argument="Return" Condition="AI_MAINT AND InstallMode="Repair"" Ordering="399" Options="1"/>
|
||||
<ROW Dialog_="VerifyRemoveDlg" Control_="Remove" Event="EndDialog" Argument="Return" Condition="AI_MAINT AND InstallMode="Remove"" Ordering="299" Options="1"/>
|
||||
<ROW Dialog_="PatchWelcomeDlg" Control_="Next" Event="NewDialog" Argument="VerifyReadyDlg" Condition="AI_PATCH" Ordering="201"/>
|
||||
<ROW Dialog_="ResumeDlg" Control_="Install" Event="EndDialog" Argument="Return" Condition="AI_RESUME" Ordering="299"/>
|
||||
<ROW Dialog_="InstallTypeDlg" Control_="Next" Event="NewDialog" Argument="FolderDlg" Condition="AI_INSTALL" Ordering="101"/>
|
||||
<ROW Dialog_="InstallTypeDlg" Control_="Back" Event="NewDialog" Argument="WelcomeDlg" Condition="AI_INSTALL" Ordering="1"/>
|
||||
<ROW Dialog_="VerifyReadyDlg" Control_="Install" Event="EndDialog" Argument="Return" Condition="AI_PATCH" Ordering="199"/>
|
||||
<ROW Dialog_="VerifyReadyDlg" Control_="Back" Event="NewDialog" Argument="PatchWelcomeDlg" Condition="AI_PATCH" Ordering="203"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiCreateFolderComponent">
|
||||
<ROW Directory_="APPDIR" Component_="APPDIR" ManualDelete="true"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiCustActComponent">
|
||||
<ROW Action="AI_ApplyShortcutFlags" Type="3073" Source="ShortcutFlags.dll" Target="UpdateShortcutFlags" WithoutSeq="true"/>
|
||||
<ROW Action="AI_AuthorSinglePackage" Type="1" Source="aicustact.dll" Target="AI_AuthorSinglePackage" WithoutSeq="true"/>
|
||||
<ROW Action="AI_DOWNGRADE" Type="19" Target="4010"/>
|
||||
<ROW Action="AI_DetectSoftware" Type="257" Source="SoftwareDetector.dll" Target="OnDetectSoftware"/>
|
||||
<ROW Action="AI_DpiContentScale" Type="1" Source="aicustact.dll" Target="DpiContentScale"/>
|
||||
<ROW Action="AI_EnableDebugLog" Type="321" Source="aicustact.dll" Target="EnableDebugLog"/>
|
||||
<ROW Action="AI_InstallModeCheck" Type="1" Source="aicustact.dll" Target="UpdateInstallMode" WithoutSeq="true"/>
|
||||
<ROW Action="AI_LaunchApp" Type="1" Source="aicustact.dll" Target="LaunchApp"/>
|
||||
<ROW Action="AI_PREPARE_UPGRADE" Type="65" Source="aicustact.dll" Target="PrepareUpgrade"/>
|
||||
<ROW Action="AI_PRESERVE_INSTALL_TYPE" Type="65" Source="aicustact.dll" Target="PreserveInstallType"/>
|
||||
<ROW Action="AI_PinShortcuts" Type="1" Source="ShortcutFlags.dll" Target="PinShortcuts"/>
|
||||
<ROW Action="AI_PinToStartScreen" Type="1025" Source="ShortcutFlags.dll" Target="PinToStartScreen" WithoutSeq="true"/>
|
||||
<ROW Action="AI_PinToTaskbar" Type="1025" Source="ShortcutFlags.dll" Target="PinToTaskbar" WithoutSeq="true"/>
|
||||
<ROW Action="AI_PrepareShortcutFlags" Type="1" Source="ShortcutFlags.dll" Target="PrepareActionData"/>
|
||||
<ROW Action="AI_RESTORE_LOCATION" Type="65" Source="aicustact.dll" Target="RestoreLocation"/>
|
||||
<ROW Action="AI_ResolveKnownFolders" Type="1" Source="aicustact.dll" Target="AI_ResolveKnownFolders"/>
|
||||
<ROW Action="AI_SETMIXINSTLOCATION" Type="1" Source="aicustact.dll" Target="MixedAllUsersInstallLocation"/>
|
||||
<ROW Action="AI_SHOW_LOG" Type="65" Source="aicustact.dll" Target="LaunchLogFile" WithoutSeq="true"/>
|
||||
<ROW Action="AI_STORE_LOCATION" Type="51" Source="ARPINSTALLLOCATION" Target="[APPDIR]"/>
|
||||
<ROW Action="AI_UnpinFromStartScreen" Type="1025" Source="ShortcutFlags.dll" Target="UnpinFromStartScreen" WithoutSeq="true"/>
|
||||
<ROW Action="AI_UnpinFromTaskbar" Type="1025" Source="ShortcutFlags.dll" Target="UnpinFromTaskbar" WithoutSeq="true"/>
|
||||
<ROW Action="AI_UnpinShortcuts" Type="1" Source="ShortcutFlags.dll" Target="UnpinShortcuts"/>
|
||||
<ROW Action="SET_APPDIR" Type="307" Source="APPDIR" Target="[ProgramFilesFolder][Manufacturer]\[ProductName]" MultiBuildTarget="DefaultBuild:[AI_UserProgramFiles][Manufacturer]\[ProductName]"/>
|
||||
<ROW Action="SET_SHORTCUTDIR" Type="307" Source="SHORTCUTDIR" Target="[ProgramMenuFolder][ProductName]"/>
|
||||
<ROW Action="SET_TARGETDIR_TO_APPDIR" Type="51" Source="TARGETDIR" Target="[APPDIR]"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiFeatCompsComponent">
|
||||
<ROW Feature_="MainFeature" Component_="APPDIR"/>
|
||||
<ROW Feature_="MainFeature" Component_="ProductInformation"/>
|
||||
<ROW Feature_="MainFeature" Component_="AI_INSTALLPERUSER"/>
|
||||
<ROW Feature_="MainFeature" Component_="com0com.cat"/>
|
||||
<ROW Feature_="MainFeature" Component_="setup.dll"/>
|
||||
<ROW Feature_="MainFeature" Component_="setupc.exe"/>
|
||||
<ROW Feature_="MainFeature" Component_="setupg.exe"/>
|
||||
<ROW Feature_="MainFeature" Component_="uninstall.exe"/>
|
||||
<ROW Feature_="MainFeature" Component_="Microsoft.Win32.SystemEvents.dll"/>
|
||||
<ROW Feature_="MainFeature" Component_="System.IO.Ports.dll_1"/>
|
||||
<ROW Feature_="MainFeature" Component_="Microsoft.Win32.SystemEvents.dll_1"/>
|
||||
<ROW Feature_="MainFeature" Component_="WpfMaiTouchEmulator.resources.dll"/>
|
||||
<ROW Feature_="MainFeature" Component_="Microsoft.Windows.SDK.NET.dll"/>
|
||||
<ROW Feature_="MainFeature" Component_="WpfMaiTouchEmulator.resources.dll_1"/>
|
||||
<ROW Feature_="MainFeature" Component_="System.Drawing.Common.dll"/>
|
||||
<ROW Feature_="MainFeature" Component_="System.IO.Ports.dll"/>
|
||||
<ROW Feature_="MainFeature" Component_="System.Private.Windows.Core.dll"/>
|
||||
<ROW Feature_="MainFeature" Component_="WinRT.Runtime.dll"/>
|
||||
<ROW Feature_="MainFeature" Component_="WpfMaiTouchEmulator.deps.json"/>
|
||||
<ROW Feature_="MainFeature" Component_="WpfMaiTouchEmulator.dll"/>
|
||||
<ROW Feature_="MainFeature" Component_="WpfMaiTouchEmulator.exe"/>
|
||||
<ROW Feature_="MainFeature" Component_="Wpf.Ui.dll"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiIconsComponent">
|
||||
<ROW Name="icon.exe" SourcePath="..\Assets\icon.ico" Index="0"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiInstExSeqComponent">
|
||||
<ROW Action="AI_DOWNGRADE" Condition="AI_NEWERPRODUCTFOUND AND (UILevel <> 5)" Sequence="210"/>
|
||||
<ROW Action="AI_RESTORE_LOCATION" Condition="APPDIR=""" Sequence="749"/>
|
||||
<ROW Action="AI_STORE_LOCATION" Condition="(Not Installed) OR REINSTALL" Sequence="1501"/>
|
||||
<ROW Action="AI_PREPARE_UPGRADE" Condition="AI_UPGRADE="No" AND (Not Installed)" Sequence="1399"/>
|
||||
<ROW Action="AI_ResolveKnownFolders" Sequence="52"/>
|
||||
<ROW Action="AI_EnableDebugLog" Sequence="51"/>
|
||||
<ROW Action="AI_DetectSoftware" Sequence="101"/>
|
||||
<ROW Action="AI_SETMIXINSTLOCATION" Sequence="748"/>
|
||||
<ROW Action="AI_PrepareShortcutFlags" Condition="(VersionNT > 501) AND ((NOT Installed) OR (Installed AND (REMOVE<>"ALL") AND (AI_INSTALL_MODE<>"Remove")))" Sequence="4501"/>
|
||||
<ROW Action="AI_PinShortcuts" Condition="(VersionNT > 600) AND ((NOT Installed) OR (Installed AND (REMOVE<>"ALL") AND (AI_INSTALL_MODE<>"Remove")))" Sequence="6499"/>
|
||||
<ROW Action="AI_UnpinShortcuts" Condition="(VersionNT > 600) AND (REMOVE = "ALL")" Sequence="3199"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiInstallUISequenceComponent">
|
||||
<ROW Action="AI_PRESERVE_INSTALL_TYPE" Sequence="199"/>
|
||||
<ROW Action="AI_RESTORE_LOCATION" Condition="APPDIR=""" Sequence="749"/>
|
||||
<ROW Action="AI_ResolveKnownFolders" Sequence="53"/>
|
||||
<ROW Action="AI_DpiContentScale" Sequence="52"/>
|
||||
<ROW Action="AI_EnableDebugLog" Sequence="51"/>
|
||||
<ROW Action="AI_DetectSoftware" Sequence="101"/>
|
||||
<ROW Action="AI_SETMIXINSTLOCATION" Sequence="748"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiLaunchConditionsComponent">
|
||||
<ROW Condition="( Version9X OR ( NOT VersionNT64 ) OR ( VersionNT64 AND ((VersionNT64 <> 601) OR (MsiNTProductType <> 1)) AND ((VersionNT64 <> 601) OR (MsiNTProductType = 1)) AND ((VersionNT64 <> 602) OR (MsiNTProductType <> 1)) AND ((VersionNT64 <> 602) OR (MsiNTProductType = 1)) AND ((VersionNT64 <> 603) OR (MsiNTProductType <> 1)) AND ((VersionNT64 <> 603) OR (MsiNTProductType = 1)) AND ((VersionNT64 <> 1000) OR (MsiNTProductType = 1)) ) )" Description="[ProductName] cannot be installed on the following Windows versions: [WindowsTypeNT64Display]." DescriptionLocId="AI.LaunchCondition.NoSpecificNT64" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
<ROW Condition="( Version9X OR VersionNT64 OR ( VersionNT AND (VersionNT <> 601) AND (VersionNT <> 602) AND (VersionNT <> 603) ) )" Description="[ProductName] cannot be installed on the following Windows versions: [WindowsTypeNTDisplay]." DescriptionLocId="AI.LaunchCondition.NoSpecificNT" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
<ROW Condition="((VersionNT <> 501) AND (VersionNT <> 502))" Description="[ProductName] cannot be installed on [WindowsTypeNT5XDisplay]." DescriptionLocId="AI.LaunchCondition.NoNT5X" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
<ROW Condition="(VersionNT <> 400)" Description="[ProductName] cannot be installed on [WindowsTypeNT40Display]." DescriptionLocId="AI.LaunchCondition.NoNT40" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
<ROW Condition="(VersionNT <> 500)" Description="[ProductName] cannot be installed on [WindowsTypeNT50Display]." DescriptionLocId="AI.LaunchCondition.NoNT50" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
<ROW Condition="(VersionNT <> 600)" Description="[ProductName] cannot be installed on [WindowsTypeNT60Display]." DescriptionLocId="AI.LaunchCondition.NoNT60" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
<ROW Condition="AI_DETECTED_DOTNET_CORE_VERSION >= AI_REQUIRED_DOTNET_CORE_VERSION" Description="[ProductName] cannot be installed on systems with .NET Core version lower than [AI_REQUIRED_DOTNET_CORE_DISPLAY]." DescriptionLocId="AI.LaunchCondition.DotNETCore" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
<ROW Condition="VersionNT" Description="[ProductName] cannot be installed on [WindowsType9XDisplay]." DescriptionLocId="AI.LaunchCondition.No9X" IsPredefined="true" Builds="DefaultBuild"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiRegLocatorComponent">
|
||||
<ROW Signature_="AI_INSTALLPERUSER" Root="2" Key="Software\[Manufacturer]\[UpgradeCode]" Name="AI_INSTALLPERUSER" Type="2"/>
|
||||
<ROW Signature_="AI_INSTALLPERUSER_1" Root="1" Key="Software\[Manufacturer]\[UpgradeCode]" Name="AI_INSTALLPERUSER" Type="2"/>
|
||||
<ROW Signature_="AI_INSTALLPERUSER_2" Root="2" Key="Software\[Manufacturer]\[UpgradeCode]" Name="AI_INSTALLPERUSER" Type="18"/>
|
||||
<ROW Signature_="AI_INSTALLPERUSER_3" Root="1" Key="Software\[Manufacturer]\[UpgradeCode]" Name="AI_INSTALLPERUSER" Type="18"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiRegsComponent">
|
||||
<ROW Registry="AI_INSTALLPERUSER" Root="-1" Key="Software\[Manufacturer]\[UpgradeCode]" Name="AI_INSTALLPERUSER" Value="[AI_INSTALLPERUSER]" Component_="AI_INSTALLPERUSER"/>
|
||||
<ROW Registry="Manufacturer" Root="-1" Key="Software\[Manufacturer]" Name="\"/>
|
||||
<ROW Registry="Path" Root="-1" Key="Software\[Manufacturer]\[ProductName]" Name="Path" Value="[APPDIR]" Component_="ProductInformation"/>
|
||||
<ROW Registry="ProductName" Root="-1" Key="Software\[Manufacturer]\[ProductName]" Name="\"/>
|
||||
<ROW Registry="Software" Root="-1" Key="Software" Name="\"/>
|
||||
<ROW Registry="UpgradeCode" Root="-1" Key="Software\[Manufacturer]\[UpgradeCode]" Name="\"/>
|
||||
<ROW Registry="Version" Root="-1" Key="Software\[Manufacturer]\[ProductName]" Name="Version" Value="[ProductVersion]" Component_="ProductInformation"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiShortsComponent">
|
||||
<ROW Shortcut="WpfMaiTouchEmulator" Directory_="ProgramMenuFolder" Name="MAITOU~1|Mai Touch Emulator" Component_="WpfMaiTouchEmulator.exe" Target="[#WpfMaiTouchEmulator.exe]" Hotkey="0" Icon_="icon.exe" IconIndex="0" ShowCmd="1" WkDir="APPDIR" CustomFlags="2"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiThemeComponent">
|
||||
<ATTRIBUTE name="UsedTheme" value="classic"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiUpgradeComponent">
|
||||
<ROW UpgradeCode="[|UpgradeCode]" VersionMin="0.0.1" VersionMax="[|ProductVersion]" Attributes="257" ActionProperty="OLDPRODUCTS"/>
|
||||
<ROW UpgradeCode="[|UpgradeCode]" VersionMin="[|ProductVersion]" Attributes="2" ActionProperty="AI_NEWERPRODUCTFOUND"/>
|
||||
</COMPONENT>
|
||||
</DOCUMENT>
|
|
@ -3,7 +3,7 @@ using System.Runtime.InteropServices;
|
|||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
|
||||
class DumpCreator
|
||||
public class DumpCreator
|
||||
{
|
||||
[Flags]
|
||||
public enum Typ : uint
|
|
@ -7,12 +7,22 @@ public static class Logger
|
|||
private static readonly object lockObj = new();
|
||||
private static string? logFilePath;
|
||||
|
||||
public static string GetLogPath()
|
||||
{
|
||||
var path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "WpfMaiTouchEmulator");
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
private static string GetLogFilePath()
|
||||
{
|
||||
if (logFilePath == null)
|
||||
{
|
||||
var fileName = $"app_{DateTime.Now:yyyy-MM-dd}.log";
|
||||
logFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName);
|
||||
logFilePath = Path.Combine(GetLogPath(), fileName);
|
||||
}
|
||||
return logFilePath;
|
||||
}
|
||||
|
@ -21,7 +31,7 @@ public static class Logger
|
|||
public static void CleanupOldLogFiles()
|
||||
{
|
||||
var directory = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory);
|
||||
var oldFiles = directory.GetFiles("app_*.log")
|
||||
var oldFiles = new DirectoryInfo(GetLogPath()).GetFiles("app_*.log")
|
||||
.Where(f => f.CreationTime < DateTime.Now.AddDays(-7))
|
||||
.ToList();
|
||||
|
163
MainWindow.xaml
|
@ -3,39 +3,140 @@
|
|||
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:ui="http://schemas.lepo.co/wpfui/2022/xaml"
|
||||
mc:Ignorable="d"
|
||||
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"
|
||||
IsReadOnly="True"
|
||||
HorizontalScrollBarVisibility="Disabled"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
AcceptsReturn="True"
|
||||
AcceptsTab="True"
|
||||
TextWrapping="Wrap" Margin="376,34,278,9" />
|
||||
<TextBox x:Name="SentLogBox"
|
||||
IsReadOnly="True"
|
||||
HorizontalScrollBarVisibility="Disabled"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
AcceptsReturn="True"
|
||||
AcceptsTab="True"
|
||||
TextWrapping="Wrap" Margin="552,34,102,9" />
|
||||
<Label x:Name="label" Content="Recieved" HorizontalAlignment="Left" Margin="376,8,0,0" VerticalAlignment="Top" Width="88"/>
|
||||
<Label x:Name="label_Copy" Content="Sent" HorizontalAlignment="Left" Margin="552,8,0,0" VerticalAlignment="Top" Width="88"/>
|
||||
<Label x:Name="label_Copy1" Content="Button State" HorizontalAlignment="Left" Margin="698,8,0,0" VerticalAlignment="Top" Width="88"/>
|
||||
<Label x:Name="buttonStateValue" Content="0" HorizontalAlignment="Left" Margin="698,34,0,0" VerticalAlignment="Top" RenderTransformOrigin="3.566,1.468" FontSize="10"/>
|
||||
<CheckBox x:Name="debugMode" Content="Debug mode" HorizontalAlignment="Left" Margin="10,39,0,0" VerticalAlignment="Top" IsChecked="{Binding Path=IsDebugEnabled}" Click="debugMode_Click" Cursor="" Focusable="False" ToolTip="Show the touchpad with translucency and show inputs highlighted"/>
|
||||
<CheckBox x:Name="automaticTouchPanelPositioning" HorizontalAlignment="Left" Margin="10,59,0,0" VerticalAlignment="Top" Height="17" Width="224" Content="Automatic sensor window positioning" IsChecked="{Binding Path=IsAutomaticPositioningEnabled}" Click="automaticTouchPanelPositioning_Click" ToolTip="Try and automatically move the touch sensor window into the correct position on top of Sinma.exe"/>
|
||||
<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" ToolTip="Try to automatically connect to COM23 to send touchsensor updates on app start"/>
|
||||
<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="Exit when Sinmai exits" IsChecked="{Binding IsExitWithSinmaiEnabled}" Click="exitWithSinmai_Click" ToolTip="Try and detect when Sinmai.exe exits and exit this app alongside it"/>
|
||||
<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"/>
|
||||
Background="AliceBlue"
|
||||
Title="MainWindow" Height="700" Width="500" WindowStartupLocation="CenterScreen">
|
||||
<ScrollViewer>
|
||||
<StackPanel MaxWidth="400" Margin="0,0,0,50">
|
||||
<Menu>
|
||||
<MenuItem Header="{Binding LbMenuCategoryHelp}" d:Header="_Help">
|
||||
<MenuItem.Icon>
|
||||
<ui:SymbolIcon Symbol="BookQuestionMark20" />
|
||||
</MenuItem.Icon>
|
||||
<MenuItem x:Name="instructionsLabel" Header="{Binding LbMenuItemSetup}" Click="instructionsLabel_Click"/>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
<ui:Card Margin="0,0,0,10">
|
||||
<StackPanel>
|
||||
<ui:TextBlock d:Text="Connection State" Text="{Binding LbConnectionState}"/>
|
||||
<Label x:Name="connectionStateLabel" Content="{Binding LbConnectionStateNotConnected}" d:Content="Not connected" FontSize="10"/>
|
||||
<Separator Margin="0,6"/>
|
||||
<Label x:Name="recievedDataLabel" Content="{Binding LbRecievedData}" d:Content="Recieved Data"/>
|
||||
<ui:TextBox x:Name="RecievedLogBox"
|
||||
IsReadOnly="True"
|
||||
HorizontalScrollBarVisibility="Disabled"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
Focusable="False"
|
||||
AcceptsReturn="True"
|
||||
AcceptsTab="True"
|
||||
TextWrapping="Wrap" Height="80">
|
||||
<ui:TextBox.Icon>
|
||||
<ui:SymbolIcon Symbol="ArrowDownLeft20" />
|
||||
</ui:TextBox.Icon>
|
||||
</ui:TextBox>
|
||||
|
||||
<Label x:Name="sentDataLabel" Content="{Binding LbSentData}" d:Content="Sent Data"/>
|
||||
<ui:TextBox x:Name="SentLogBox"
|
||||
IsReadOnly="True"
|
||||
Focusable="False"
|
||||
HorizontalScrollBarVisibility="Disabled"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
AcceptsReturn="True"
|
||||
AcceptsTab="True"
|
||||
TextWrapping="Wrap" Height="80">
|
||||
<ui:TextBox.Icon>
|
||||
<ui:SymbolIcon Symbol="ArrowUpRight20" />
|
||||
</ui:TextBox.Icon>
|
||||
</ui:TextBox>
|
||||
<Separator Margin="0,6"/>
|
||||
<Label x:Name="buttonStateLabel" Content="{Binding LbButtonState}" d:Content="Button state" />
|
||||
<Label x:Name="buttonStateValue" Content="0" />
|
||||
</StackPanel>
|
||||
</ui:Card>
|
||||
<ui:CardExpander
|
||||
CornerRadius="8"
|
||||
Margin="0,0,0,10"
|
||||
Header="{Binding LbComPort}"
|
||||
d:Header="COM Port">
|
||||
<ui:CardExpander.Icon>
|
||||
<ui:SymbolIcon Symbol="PlugDisconnected20" />
|
||||
</ui:CardExpander.Icon>
|
||||
<StackPanel>
|
||||
<ui:Button x:Name="ConnectToPortButton" Content="{Binding LbConnectToPort}" d:Content="Connect to port" Click="ConnectToPortButton_Click" />
|
||||
<Separator Margin="0,6"/>
|
||||
<ui:Button x:Name="buttonInstallComPort" Content="{Binding LbInstallComPort}" Margin="0,0,0,10" d:Content="Install COM port" Click="buttonInstallComPort_Click" />
|
||||
<ui:Button x:Name="buttonUninstallComPorts" Content="{Binding LbUninstallComPort}" Margin="0,0,0,10" d:Content="Uninstall COM port" Click="buttonUninstallComPorts_Click" />
|
||||
<ui:Button x:Name="buttonListComPorts" Content="{Binding LbListComPorts}" d:Content="List installed COM ports" Click="buttonListComPorts_Click" />
|
||||
</StackPanel>
|
||||
</ui:CardExpander>
|
||||
<ui:CardExpander
|
||||
CornerRadius="8"
|
||||
Margin="0,0,0,10"
|
||||
Header="{Binding LbBorderSettings}"
|
||||
d:Header="Border settings">
|
||||
<ui:CardExpander.Icon>
|
||||
<ui:SymbolIcon Symbol="EditSettings20" />
|
||||
</ui:CardExpander.Icon>
|
||||
<StackPanel>
|
||||
<RadioButton x:Name="rbBorderDisabled" Content="{Binding LbBorderDisabled}" d:Content="Disabled" GroupName="ColorOptions" Checked="RadioButton1_Checked"/>
|
||||
<RadioButton x:Name="rbBorderSolidColour" Content="{Binding LbBorderSolid}" d:Content="Solid Colour" GroupName="ColorOptions" Checked="RadioButton2_Checked"/>
|
||||
<ui:TextBox x:Name="txtBorderHexColor" Text="{Binding Path=BorderColour}" PlaceholderText="#AARRGGBB" IsEnabled="False" Margin="10,10,0,10" TextChanged="txtBorderHexColor_TextChanged"/>
|
||||
|
||||
<RadioButton Name="rbBorderRainbow" Content="{Binding LbBorderRainbow}" d:Content="Rainbow" GroupName="ColorOptions" Checked="RadioButton3_Checked"/>
|
||||
</StackPanel>
|
||||
</ui:CardExpander>
|
||||
<ui:CardExpander
|
||||
CornerRadius="8"
|
||||
Margin="0,0,0,10"
|
||||
Header="{Binding LbSettings}"
|
||||
d:Header="Settings">
|
||||
<ui:CardExpander.Icon>
|
||||
<ui:SymbolIcon Symbol="Settings20" />
|
||||
</ui:CardExpander.Icon>
|
||||
<StackPanel>
|
||||
<Label x:Name="languageLabel" Content="{Binding LbLanguageDropdown}" d:Content="Language"/>
|
||||
<ComboBox x:Name="languageSelector" ItemsSource="{Binding SupportedLanguages}" DisplayMemberPath="NativeName" SelectedItem="{Binding SelectedLanguage, Mode=TwoWay}"/>
|
||||
<Separator Margin="0,6"/>
|
||||
<CheckBox x:Name="largeButtons" Content="{Binding LbLargeButtons}" d:Content="LargeButtons" IsChecked="{Binding Path=IsLargeButtonsEnabled}" Click="largeButtons_Click" Cursor="" Focusable="False" ToolTip="{Binding LbLargeButtonsTT}" />
|
||||
<CheckBox x:Name="debugMode" Content="{Binding LbDebugMode}" d:Content="Debug mode" IsChecked="{Binding Path=IsDebugEnabled}" Click="debugMode_Click" Cursor="" Focusable="False" ToolTip="{Binding LbDebugModeTT}" />
|
||||
<CheckBox x:Name="automaticTouchPanelPositioning" d:Content="Automatic touch panel positioning" Content="{Binding LbAutoSensorPositioning}" IsChecked="{Binding Path=IsAutomaticPositioningEnabled}" Click="automaticTouchPanelPositioning_Click" ToolTip="{Binding LbAutoSensorPositioningTT}"/>
|
||||
<CheckBox x:Name="automaticPortConnecting" d:Content="Automatic port connecting" Content="{Binding LbAutoPortConnecting}" IsChecked="{Binding Path=IsAutomaticPortConnectingEnabled}" Click="automaticPortConnecting_Click" ToolTip="{Binding LbAutoPortConnectingTT}"/>
|
||||
<CheckBox x:Name="exitWithSinmai" Content="{Binding LbExitWithSinmai}" d:Content="Exit with Sinmai" IsChecked="{Binding IsExitWithSinmaiEnabled}" Click="exitWithSinmai_Click" ToolTip="{Binding LbExitWithSinmaiTT}"/>
|
||||
<CheckBox x:Name="emulateRingButtons" Content="{Binding LbEmulateRingButtons}" d:Content="Emulate ring buttons" IsChecked="{Binding IsRingButtonEmulationEnabled}" ToolTip="{Binding LbEmulateRingButtonsTT}" Click="emulateRingButtons_Click"/>
|
||||
<ui:Button x:Name="openLogFolderButton" Content="{Binding LbOpenLogFolder}" d:Content="Open log folder" Click="openLogFolderButton_Click" />
|
||||
</StackPanel>
|
||||
</ui:CardExpander>
|
||||
<ui:Card>
|
||||
<StackPanel>
|
||||
<TextBlock Text="{Binding LbAbout}" d:Text="About" Margin="0,0,0,10"/>
|
||||
<ui:Anchor
|
||||
Margin="0"
|
||||
Padding="16"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
Background="Transparent"
|
||||
BorderThickness="0,1,0,0"
|
||||
CornerRadius="0"
|
||||
NavigateUri="https://github.com/Leapward-Koex/MaiTouchSensorEmulator">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Text="Github" />
|
||||
<ui:SymbolIcon Grid.Column="1" Symbol="WindowNew20" />
|
||||
</Grid>
|
||||
</ui:Anchor>
|
||||
<Label Content="{Binding LbAppVersion}" d:Content="1.0.0.0"/>
|
||||
<Label Content="By Leapward-Koex"/>
|
||||
</StackPanel>
|
||||
|
||||
</ui:Card>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
|
||||
</Grid>
|
||||
|
||||
</Window>
|
||||
|
|
|
@ -1,22 +1,46 @@
|
|||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Windows;
|
||||
using WpfMaiTouchEmulator.Managers;
|
||||
|
||||
namespace WpfMaiTouchEmulator;
|
||||
|
||||
public enum BorderSetting
|
||||
{
|
||||
Disabled,
|
||||
Solid,
|
||||
Rainbow
|
||||
}
|
||||
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
private readonly MaiTouchSensorButtonStateManager buttonState;
|
||||
private MaiTouchComConnector connector;
|
||||
private readonly MaiTouchComConnector connector;
|
||||
private readonly VirtualComPortManager comPortManager;
|
||||
private TouchPanel _touchPanel;
|
||||
private TouchPanel? _touchPanel;
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
CheckForUserSettingsUpgrade();
|
||||
DataContext = new MainWindowViewModel()
|
||||
{
|
||||
IsDebugEnabled = Properties.Settings.Default.IsDebugEnabled,
|
||||
IsAutomaticPortConnectingEnabled = Properties.Settings.Default.IsAutomaticPortConnectingEnabled,
|
||||
IsAutomaticPositioningEnabled = Properties.Settings.Default.IsAutomaticPositioningEnabled,
|
||||
IsExitWithSinmaiEnabled = Properties.Settings.Default.IsExitWithSinmaiEnabled,
|
||||
IsRingButtonEmulationEnabled = Properties.Settings.Default.IsRingButtonEmulationEnabled,
|
||||
IsLargeButtonsEnabled = Properties.Settings.Default.IsLargeButtonsEnabled,
|
||||
BorderColour = Properties.Settings.Default.BorderColour,
|
||||
LbAppVersion = Assembly.GetEntryAssembly()?.GetName().Version?.ToString() ?? "1.0.0.0",
|
||||
};
|
||||
|
||||
LoadBorderRadioButtonSetting();
|
||||
|
||||
Title = "Mai Touch Emulator";
|
||||
buttonState = new MaiTouchSensorButtonStateManager(buttonStateValue);
|
||||
connector = new MaiTouchComConnector(buttonState);
|
||||
comPortManager = new VirtualComPortManager();
|
||||
connector = new MaiTouchComConnector(buttonState, (MainWindowViewModel)DataContext);
|
||||
comPortManager = new VirtualComPortManager((MainWindowViewModel)DataContext);
|
||||
connector.OnConnectStatusChange = (status) =>
|
||||
{
|
||||
connectionStateLabel.Content = status;
|
||||
|
@ -48,28 +72,33 @@ public partial class MainWindow : Window
|
|||
if (Properties.Settings.Default.FirstOpen)
|
||||
{
|
||||
Logger.Info("First open occurred");
|
||||
MessageBox.Show("Please remove any COM devices using the COM3 port before installing the virtual COM port. In Device Manager click \"View\" then enabled \"Show hidden devices\" and uninstall any devices that are using the COM3 port.\n\nAfter ensuring COM3 is free please use the install COM port button in the app to register the app.\n\nThe app needs to connect to the port prior to Sinmai.exe being opened.", "First time setup", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
ShowSetupInstructionsDialog();
|
||||
Properties.Settings.Default.FirstOpen = false;
|
||||
Properties.Settings.Default.Save();
|
||||
}
|
||||
|
||||
|
||||
Loaded += (s, e) => {
|
||||
var dataContext = (MainWindowViewModel)DataContext;
|
||||
|
||||
Logger.Info("Main window loaded, creating touch panel");
|
||||
_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
|
||||
_touchPanel.onTouch = (value) => {
|
||||
buttonState.PressButton(value);
|
||||
connector.SendTouchscreenState();
|
||||
};
|
||||
_touchPanel.onRelease = (value) => {
|
||||
buttonState.ReleaseButton(value);
|
||||
connector.SendTouchscreenState();
|
||||
};
|
||||
_touchPanel.onInitialReposition = () => { WindowState = WindowState.Minimized; };
|
||||
_touchPanel.SetBorderMode((BorderSetting)Properties.Settings.Default.BorderSetting, dataContext.BorderColour);
|
||||
_touchPanel.Show();
|
||||
|
||||
_touchPanel.DataContext = dataContext;
|
||||
|
||||
var dataContext = (MainWindowViewModel)DataContext;
|
||||
_touchPanel.SetDebugMode(dataContext.IsDebugEnabled);
|
||||
_touchPanel.SetLargeButtonMode(dataContext.IsLargeButtonsEnabled);
|
||||
if (Properties.Settings.Default.IsAutomaticPositioningEnabled)
|
||||
{
|
||||
_touchPanel.DragWindowHandle.Visibility = Visibility.Hidden;
|
||||
|
@ -81,16 +110,14 @@ public partial class MainWindow : Window
|
|||
};
|
||||
}
|
||||
|
||||
private async void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
|
||||
private async void MainWindow_Closing(object? sender, System.ComponentModel.CancelEventArgs e)
|
||||
{
|
||||
e.Cancel = true;
|
||||
await connector.Disconnect();
|
||||
foreach (Window childWindow in OwnedWindows)
|
||||
{
|
||||
childWindow.Close();
|
||||
}
|
||||
_touchPanel?.Close();
|
||||
Closing -= MainWindow_Closing;
|
||||
Close();
|
||||
e.Cancel = false;
|
||||
Application.Current.Shutdown();
|
||||
}
|
||||
|
||||
private async void ExitWithSinmaiLoop()
|
||||
|
@ -131,11 +158,29 @@ public partial class MainWindow : Window
|
|||
dataContext.IsExitWithSinmaiEnabled = false;
|
||||
Properties.Settings.Default.IsExitWithSinmaiEnabled = dataContext.IsExitWithSinmaiEnabled;
|
||||
Properties.Settings.Default.Save();
|
||||
MessageBox.Show("Failed to listen for Sinmai exit signal, is it running as admin?\n\nAutomatic exiting disabled.", "Failed to listen for Sinmai exit", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
MessageBox.Show(dataContext.TxtFailedToSetupSinmaiExit, dataContext.TxtFailedToSetupSinmaiExitHeader, MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void CheckForUserSettingsUpgrade()
|
||||
{
|
||||
if (!Properties.Settings.Default.UserSettingsUpgradeRequired)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Properties.Settings.Default.Upgrade();
|
||||
Properties.Settings.Default.UserSettingsUpgradeRequired = false;
|
||||
Properties.Settings.Default.Save();
|
||||
}
|
||||
|
||||
private void ShowSetupInstructionsDialog()
|
||||
{
|
||||
var dataContext = (MainWindowViewModel)DataContext;
|
||||
MessageBox.Show(dataContext.TxtSetupInstructions, dataContext.TxtSetupInstructionsHeader, MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
}
|
||||
|
||||
private async void AutomaticTouchPanelPositioningLoop()
|
||||
{
|
||||
var dataContext = (MainWindowViewModel)DataContext;
|
||||
|
@ -143,7 +188,7 @@ public partial class MainWindow : Window
|
|||
{
|
||||
if (dataContext.IsAutomaticPositioningEnabled)
|
||||
{
|
||||
_touchPanel.PositionTouchPanel();
|
||||
_touchPanel?.PositionTouchPanel();
|
||||
}
|
||||
|
||||
await Task.Delay(1000);
|
||||
|
@ -157,16 +202,16 @@ public partial class MainWindow : Window
|
|||
{
|
||||
if (dataContext.IsAutomaticPortConnectingEnabled)
|
||||
{
|
||||
await connector.StartTouchSensorPolling();
|
||||
connector.StartTouchSensorPolling();
|
||||
}
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private async void ConnectToPortButton_Click(object sender, RoutedEventArgs e)
|
||||
private void ConnectToPortButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
await connector.StartTouchSensorPolling();
|
||||
connector.StartTouchSensorPolling();
|
||||
}
|
||||
|
||||
private void debugMode_Click(object sender, RoutedEventArgs e)
|
||||
|
@ -176,7 +221,17 @@ public partial class MainWindow : Window
|
|||
dataContext.IsDebugEnabled = !enabled;
|
||||
Properties.Settings.Default.IsDebugEnabled = dataContext.IsDebugEnabled;
|
||||
Properties.Settings.Default.Save();
|
||||
_touchPanel.SetDebugMode(dataContext.IsDebugEnabled);
|
||||
_touchPanel?.SetDebugMode(dataContext.IsDebugEnabled);
|
||||
}
|
||||
|
||||
private void largeButtons_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var dataContext = (MainWindowViewModel)DataContext;
|
||||
var enabled = !dataContext.IsLargeButtonsEnabled;
|
||||
dataContext.IsLargeButtonsEnabled = !enabled;
|
||||
Properties.Settings.Default.IsLargeButtonsEnabled = dataContext.IsLargeButtonsEnabled;
|
||||
Properties.Settings.Default.Save();
|
||||
_touchPanel?.SetLargeButtonMode(dataContext.IsLargeButtonsEnabled);
|
||||
}
|
||||
|
||||
private void automaticTouchPanelPositioning_Click(object sender, RoutedEventArgs e)
|
||||
|
@ -223,6 +278,76 @@ public partial class MainWindow : Window
|
|||
private void buttonListComPorts_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var output = comPortManager.GetInstalledPorts();
|
||||
MessageBox.Show(string.Join("\n", output), "Installed ports");
|
||||
var dataContext = (MainWindowViewModel)DataContext;
|
||||
MessageBox.Show(string.Join("\n", output), dataContext.TxtCurrentlyInstalledPorts);
|
||||
}
|
||||
|
||||
private void instructionsLabel_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ShowSetupInstructionsDialog();
|
||||
}
|
||||
|
||||
private void emulateRingButtons_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var dataContext = (MainWindowViewModel)DataContext;
|
||||
var enabled = !dataContext.IsRingButtonEmulationEnabled;
|
||||
dataContext.IsRingButtonEmulationEnabled = !enabled;
|
||||
Properties.Settings.Default.IsRingButtonEmulationEnabled = dataContext.IsRingButtonEmulationEnabled;
|
||||
Properties.Settings.Default.Save();
|
||||
_touchPanel?.SetEmulateRingButton(dataContext.IsRingButtonEmulationEnabled);
|
||||
}
|
||||
|
||||
private void LoadBorderRadioButtonSetting()
|
||||
{
|
||||
rbBorderDisabled.IsChecked = Properties.Settings.Default.BorderSetting == (int)BorderSetting.Disabled;
|
||||
txtBorderHexColor.IsEnabled = Properties.Settings.Default.BorderSetting == (int)BorderSetting.Solid;
|
||||
rbBorderSolidColour.IsChecked = Properties.Settings.Default.BorderSetting == (int)BorderSetting.Solid;
|
||||
rbBorderRainbow.IsChecked = Properties.Settings.Default.BorderSetting == (int)BorderSetting.Rainbow;
|
||||
}
|
||||
|
||||
private void RadioButton1_Checked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
txtBorderHexColor.IsEnabled = false;
|
||||
Properties.Settings.Default.BorderSetting = (int)BorderSetting.Disabled;
|
||||
Properties.Settings.Default.Save();
|
||||
|
||||
_touchPanel?.SetBorderMode(BorderSetting.Disabled, "");
|
||||
}
|
||||
|
||||
private void RadioButton2_Checked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
txtBorderHexColor.IsEnabled = true;
|
||||
Properties.Settings.Default.BorderSetting = (int)BorderSetting.Solid;
|
||||
|
||||
Properties.Settings.Default.Save();
|
||||
|
||||
_touchPanel?.SetBorderMode(BorderSetting.Solid, Properties.Settings.Default.BorderColour);
|
||||
}
|
||||
|
||||
private void RadioButton3_Checked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
txtBorderHexColor.IsEnabled = false;
|
||||
Properties.Settings.Default.BorderSetting = (int)BorderSetting.Rainbow;
|
||||
|
||||
Properties.Settings.Default.Save();
|
||||
|
||||
_touchPanel?.SetBorderMode(BorderSetting.Rainbow, "");
|
||||
}
|
||||
|
||||
private void txtBorderHexColor_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
|
||||
{
|
||||
var textWithoutHash = txtBorderHexColor.Text.TrimStart('#') ?? "";
|
||||
if (textWithoutHash.Length == 6 || textWithoutHash.Length == 8)
|
||||
{
|
||||
var textWithHash = "#" + textWithoutHash;
|
||||
Properties.Settings.Default.BorderColour = textWithHash;
|
||||
Properties.Settings.Default.Save();
|
||||
_touchPanel?.SetBorderMode(BorderSetting.Solid, textWithHash);
|
||||
}
|
||||
}
|
||||
|
||||
private void openLogFolderButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Process.Start("explorer.exe", Logger.GetLogPath());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,273 @@
|
|||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Resources;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace WpfMaiTouchEmulator;
|
||||
|
||||
internal class MainWindowViewModel : INotifyPropertyChanged
|
||||
public class MainWindowViewModel : INotifyPropertyChanged
|
||||
{
|
||||
// Language
|
||||
public string? LbAutoPortConnecting
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbAutoSensorPositioning
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbButtonState
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbConnectionState
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbConnectionStateNotConnected
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbConnectToPort
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbDebugMode
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbLargeButtons
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbLargeButtonsTT
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbExitWithSinmai
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbEmulateRingButtons
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbOpenLogFolder
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbAppVersion
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbAbout
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbInstallComPort
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbLanguageDropdown
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbBorderSettings
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbSettings
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbComPort
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbBorderDisabled
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbBorderSolid
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbBorderRainbow
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbListComPorts
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbReceivedData
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbRecievedData
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public string? LbSentData
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbUninstallComPort
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? LbMenuCategoryHelp
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public string? LbMenuItemSetup
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public string? TxtSetupInstructions
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public string? TxtSetupInstructionsHeader
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public string? TxtFailedToSetupSinmaiExitHeader
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public string? TxtFailedToSetupSinmaiExit
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public string? TxtCurrentlyInstalledPorts
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public string? TxtErrorConnectingToPortHeader
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public string? TxtComPortConnected
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public string? TxtComPortConnecting
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public string? TxtCom3AlreadyInstalled
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public string? TxtCom3InstalledSuccessfully
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public string? TxtCom3InstallFailed
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public string? TxtCom3UninstallNotRequired
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public string? TxtCom3UninstalledSuccessfully
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public string? TxtCom3UninstallFailed
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public string? LbTouchPanelResize
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public string? LbTouchPanelDrag
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public string? LbAutoPortConnectingTT
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public string? LbDebugModeTT
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public string? LbAutoSensorPositioningTT
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public string? LbExitWithSinmaiTT
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
public string? LbEmulateRingButtonsTT
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
private bool _isAutomaticPortConnectingEnabled;
|
||||
private bool _isDebugEnabled;
|
||||
private bool _isLargeButtonsEnabled;
|
||||
private bool _isAutomaticPositioningEnabled;
|
||||
private bool _isExitWithSinmaiEnabled;
|
||||
private CultureInfo _selectedLanguage;
|
||||
private bool _isRingButtonEmulationEnabled;
|
||||
private string _borderColour;
|
||||
private readonly ResourceManager resourceManager;
|
||||
private readonly CultureInfo cultureInfo;
|
||||
|
||||
public List<CultureInfo> SupportedLanguages
|
||||
{
|
||||
get;
|
||||
} =
|
||||
[
|
||||
new CultureInfo("en-US"), // English
|
||||
new CultureInfo("zh-CN"), // Chinese (Simplified)
|
||||
new CultureInfo("ja-JP") // Japanese
|
||||
];
|
||||
|
||||
|
||||
public MainWindowViewModel()
|
||||
{
|
||||
resourceManager = new ResourceManager("WpfMaiTouchEmulator.Properties.Resources", typeof(MainWindowViewModel).Assembly);
|
||||
LoadLanguageSettings();
|
||||
}
|
||||
|
||||
private void LoadLanguageSettings()
|
||||
{
|
||||
var savedLang = Properties.Settings.Default.UserLanguage;
|
||||
var culture = string.IsNullOrEmpty(savedLang) ? CultureInfo.CurrentCulture : new CultureInfo(savedLang);
|
||||
|
||||
SelectedLanguage = SupportedLanguages.Contains(culture) ? culture : SupportedLanguages[0];
|
||||
}
|
||||
|
||||
public bool IsDebugEnabled
|
||||
{
|
||||
|
@ -20,6 +279,16 @@ internal class MainWindowViewModel : INotifyPropertyChanged
|
|||
}
|
||||
}
|
||||
|
||||
public bool IsLargeButtonsEnabled
|
||||
{
|
||||
get => _isLargeButtonsEnabled;
|
||||
set
|
||||
{
|
||||
_isLargeButtonsEnabled = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsAutomaticPositioningEnabled
|
||||
{
|
||||
get => _isAutomaticPositioningEnabled;
|
||||
|
@ -50,6 +319,114 @@ internal class MainWindowViewModel : INotifyPropertyChanged
|
|||
}
|
||||
}
|
||||
|
||||
public bool IsRingButtonEmulationEnabled
|
||||
{
|
||||
get => _isRingButtonEmulationEnabled;
|
||||
set
|
||||
{
|
||||
_isRingButtonEmulationEnabled = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public string BorderColour
|
||||
{
|
||||
get => _borderColour;
|
||||
set
|
||||
{
|
||||
_borderColour = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public CultureInfo SelectedLanguage
|
||||
{
|
||||
get => _selectedLanguage;
|
||||
set
|
||||
{
|
||||
if (_selectedLanguage != value)
|
||||
{
|
||||
_selectedLanguage = value;
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedLanguage)));
|
||||
ChangeLanguage(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ChangeLanguage(CultureInfo culture)
|
||||
{
|
||||
Properties.Settings.Default.UserLanguage = culture.Name;
|
||||
Properties.Settings.Default.Save();
|
||||
|
||||
Thread.CurrentThread.CurrentUICulture = culture;
|
||||
ResourceManager rm = new ResourceManager(typeof(Resources.Strings));
|
||||
UpdateLocalizedResources(rm);
|
||||
}
|
||||
|
||||
private void UpdateLocalizedResources(ResourceManager resourceManager)
|
||||
{
|
||||
LbAutoPortConnecting = resourceManager.GetString("lbAutoPortConnecting");
|
||||
LbAutoSensorPositioning = resourceManager.GetString("lbAutoSensorPositioning");
|
||||
LbButtonState = resourceManager.GetString("lbButtonState");
|
||||
LbConnectionState = resourceManager.GetString("lbConnectionState");
|
||||
LbConnectionStateNotConnected = resourceManager.GetString("lbConnectionStateNotConnected");
|
||||
LbConnectToPort = resourceManager.GetString("lbConnectToPort");
|
||||
LbDebugMode = resourceManager.GetString("lbDebugMode");
|
||||
LbLargeButtons = resourceManager.GetString("lbLargeButtons");
|
||||
LbLargeButtonsTT = resourceManager.GetString("lbLargeButtonsTT");
|
||||
LbExitWithSinmai = resourceManager.GetString("lbExitWithSinmai");
|
||||
LbEmulateRingButtons = resourceManager.GetString("lbEmulateRingButtons");
|
||||
LbOpenLogFolder = resourceManager.GetString("LbOpenLogFolder");
|
||||
LbAbout = resourceManager.GetString("LbAbout");
|
||||
|
||||
LbInstallComPort = resourceManager.GetString("lbInstallComPort");
|
||||
LbLanguageDropdown = resourceManager.GetString("lbLanguageDropdown");
|
||||
|
||||
LbComPort = resourceManager.GetString("LbComPort");
|
||||
LbBorderSettings = resourceManager.GetString("LbBorderSettings");
|
||||
LbSettings = resourceManager.GetString("LbSettings");
|
||||
LbBorderDisabled = resourceManager.GetString("LbBorderDisabled");
|
||||
LbBorderSolid = resourceManager.GetString("LbBorderSolid");
|
||||
LbBorderRainbow = resourceManager.GetString("LbBorderRainbow");
|
||||
|
||||
LbListComPorts = resourceManager.GetString("lbListComPorts");
|
||||
LbReceivedData = resourceManager.GetString("lbReceivedData");
|
||||
LbRecievedData = resourceManager.GetString("lbRecievedData");
|
||||
LbSentData = resourceManager.GetString("lbSentData");
|
||||
LbUninstallComPort = resourceManager.GetString("lbUninstallComPort");
|
||||
LbMenuCategoryHelp = resourceManager.GetString("lbMenuCategoryHelp");
|
||||
LbMenuItemSetup = resourceManager.GetString("lbMenuItemSetup");
|
||||
LbAutoPortConnectingTT = resourceManager.GetString("lbAutoPortConnectingTT");
|
||||
LbDebugModeTT = resourceManager.GetString("lbDebugModeTT");
|
||||
LbAutoSensorPositioningTT = resourceManager.GetString("lbAutoSensorPositioningTT");
|
||||
LbExitWithSinmaiTT = resourceManager.GetString("lbExitWithSinmaiTT");
|
||||
LbEmulateRingButtonsTT = resourceManager.GetString("lbEmulateRingButtonsTT");
|
||||
LbMenuCategoryHelp = resourceManager.GetString("lbMenuCategoryHelp");
|
||||
LbMenuItemSetup = resourceManager.GetString("lbMenuItemSetup");
|
||||
|
||||
TxtSetupInstructions = resourceManager.GetString("TxtSetupInstructions");
|
||||
TxtSetupInstructionsHeader = resourceManager.GetString("TxtSetupInstructionsHeader");
|
||||
TxtFailedToSetupSinmaiExitHeader = resourceManager.GetString("TxtFailedToSetupSinmaiExitHeader");
|
||||
TxtFailedToSetupSinmaiExit = resourceManager.GetString("TxtFailedToSetupSinmaiExit");
|
||||
TxtCurrentlyInstalledPorts = resourceManager.GetString("TxtCurrentlyInstalledPorts");
|
||||
TxtErrorConnectingToPortHeader = resourceManager.GetString("TxtErrorConnectingToPortHeader");
|
||||
TxtComPortConnected = resourceManager.GetString("TxtComPortConnected");
|
||||
TxtComPortConnecting = resourceManager.GetString("TxtComPortConnecting");
|
||||
|
||||
TxtCom3AlreadyInstalled = resourceManager.GetString("TxtCom3AlreadyInstalled");
|
||||
TxtCom3InstalledSuccessfully = resourceManager.GetString("TxtCom3InstalledSuccessfully");
|
||||
TxtCom3InstallFailed = resourceManager.GetString("TxtCom3InstallFailed");
|
||||
TxtCom3UninstallNotRequired = resourceManager.GetString("TxtCom3UninstallNotRequired");
|
||||
TxtCom3UninstalledSuccessfully = resourceManager.GetString("TxtCom3UninstalledSuccessfully");
|
||||
TxtCom3UninstallFailed = resourceManager.GetString("TxtCom3UninstallFailed");
|
||||
|
||||
LbTouchPanelResize = resourceManager.GetString("LbTouchPanelResize");
|
||||
LbTouchPanelDrag = resourceManager.GetString("LbTouchPanelDrag");
|
||||
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(null));
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
using System.IO.Ports;
|
||||
using System.Windows;
|
||||
|
||||
namespace WpfMaiTouchEmulator;
|
||||
internal class MaiTouchComConnector(MaiTouchSensorButtonStateManager buttonState)
|
||||
namespace WpfMaiTouchEmulator.Managers;
|
||||
internal class MaiTouchComConnector(MaiTouchSensorButtonStateManager buttonState, MainWindowViewModel viewModel)
|
||||
{
|
||||
private static SerialPort? serialPort;
|
||||
private bool isActiveMode;
|
||||
private bool _isActiveMode;
|
||||
private bool _connected;
|
||||
private CancellationTokenSource? _tokenSource;
|
||||
private Thread? _pollThread;
|
||||
private bool _shouldReconnect = true;
|
||||
private readonly MaiTouchSensorButtonStateManager _buttonState = buttonState;
|
||||
private readonly MainWindowViewModel _viewModel = viewModel;
|
||||
|
||||
public Action<string>? OnConnectStatusChange
|
||||
{
|
||||
|
@ -33,15 +34,15 @@ internal class MaiTouchComConnector(MaiTouchSensorButtonStateManager buttonState
|
|||
internal set;
|
||||
}
|
||||
|
||||
public async Task StartTouchSensorPolling()
|
||||
public void StartTouchSensorPolling()
|
||||
{
|
||||
if (!_connected && _shouldReconnect)
|
||||
{
|
||||
Logger.Info("Trying to connect to COM port...");
|
||||
var virtualPort = "COM23"; // Adjust as needed
|
||||
var virtualPort = "COM23";
|
||||
try
|
||||
{
|
||||
OnConnectStatusChange?.Invoke("Conecting...");
|
||||
OnConnectStatusChange?.Invoke(_viewModel.TxtComPortConnecting);
|
||||
serialPort = new SerialPort(virtualPort, 9600, Parity.None, 8, StopBits.One)
|
||||
{
|
||||
WriteTimeout = 100
|
||||
|
@ -49,7 +50,7 @@ internal class MaiTouchComConnector(MaiTouchSensorButtonStateManager buttonState
|
|||
serialPort.DataReceived += SerialPort_DataReceived;
|
||||
serialPort.Open();
|
||||
Logger.Info("Serial port opened successfully.");
|
||||
OnConnectStatusChange?.Invoke("Connected to port");
|
||||
OnConnectStatusChange?.Invoke(_viewModel.TxtComPortConnected);
|
||||
_connected = true;
|
||||
|
||||
_tokenSource = new CancellationTokenSource(); // Create a token source.
|
||||
|
@ -64,12 +65,12 @@ internal class MaiTouchComConnector(MaiTouchSensorButtonStateManager buttonState
|
|||
OnConnectError?.Invoke();
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
MessageBox.Show(ex.Message, "Error connecting to COM port", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
MessageBox.Show(ex.Message, _viewModel.TxtErrorConnectingToPortHeader, MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
});
|
||||
|
||||
Logger.Error("Error on starting polling", ex);
|
||||
Logger.Info("Disconnecting from COM port");
|
||||
_connected = false;
|
||||
OnConnectStatusChange?.Invoke("Not Connected");
|
||||
OnConnectStatusChange?.Invoke(_viewModel.LbConnectionStateNotConnected);
|
||||
if (serialPort?.IsOpen == true)
|
||||
{
|
||||
serialPort.DiscardInBuffer();
|
||||
|
@ -85,10 +86,10 @@ internal class MaiTouchComConnector(MaiTouchSensorButtonStateManager buttonState
|
|||
{
|
||||
while (!token.IsCancellationRequested)
|
||||
{
|
||||
if (isActiveMode)
|
||||
if (_isActiveMode)
|
||||
{
|
||||
SendTouchscreenState();
|
||||
Thread.Sleep(1);
|
||||
Thread.Sleep(10);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -138,55 +139,60 @@ internal class MaiTouchComConnector(MaiTouchSensorButtonStateManager buttonState
|
|||
void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
|
||||
{
|
||||
var recievedData = serialPort?.ReadExisting();
|
||||
var commands = recievedData?.Split(new[] { '}' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (commands != null)
|
||||
var commands = recievedData?.Split(['}'], StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
if (commands is null)
|
||||
{
|
||||
foreach (var command in commands)
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var command in commands)
|
||||
{
|
||||
var cleanedCommand = command.TrimStart('{');
|
||||
Logger.Info($"Received serial data: '{cleanedCommand}'");
|
||||
OnDataRecieved?.Invoke(cleanedCommand);
|
||||
|
||||
if (cleanedCommand == "STAT")
|
||||
{
|
||||
_isActiveMode = true;
|
||||
}
|
||||
else if (cleanedCommand == "RSET")
|
||||
{
|
||||
var cleanedCommand = command.TrimStart('{');
|
||||
Logger.Info($"Received serial data: {cleanedCommand}");
|
||||
OnDataRecieved?.Invoke(cleanedCommand);
|
||||
|
||||
if (cleanedCommand == "STAT")
|
||||
{
|
||||
isActiveMode = true;
|
||||
}
|
||||
else if (cleanedCommand == "RSET")
|
||||
{
|
||||
}
|
||||
else if (cleanedCommand == "HALT")
|
||||
{
|
||||
_isActiveMode = false;
|
||||
}
|
||||
else if (cleanedCommand.Length >= 4 &&
|
||||
(cleanedCommand[2] == 'r' || cleanedCommand[2] == 'k'))
|
||||
{
|
||||
var leftOrRight = cleanedCommand[0];
|
||||
var sensor = cleanedCommand[1];
|
||||
var ratio = cleanedCommand[3];
|
||||
|
||||
}
|
||||
else if (cleanedCommand == "HALT")
|
||||
{
|
||||
isActiveMode = false;
|
||||
}
|
||||
else if (cleanedCommand[2] == 'r' || cleanedCommand[2] == 'k')
|
||||
{
|
||||
var leftOrRight = cleanedCommand[0];
|
||||
var sensor = cleanedCommand[1];
|
||||
var ratio = cleanedCommand[3];
|
||||
|
||||
var newString = $"({leftOrRight}{sensor}{cleanedCommand[2]}{ratio})";
|
||||
serialPort?.Write(newString);
|
||||
OnDataSent?.Invoke(newString);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Warn($"Unhandled serial data command {cleanedCommand}");
|
||||
}
|
||||
var newString = $"({leftOrRight}{sensor}{cleanedCommand[2]}{ratio})";
|
||||
serialPort?.Write(newString);
|
||||
OnDataSent?.Invoke(newString);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Warn($"Unhandled serial data command '{cleanedCommand}'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SendTouchscreenState()
|
||||
public void SendTouchscreenState()
|
||||
{
|
||||
if (_connected)
|
||||
if (_connected && _isActiveMode)
|
||||
{
|
||||
var currentState = _buttonState.GetCurrentState();
|
||||
try
|
||||
{
|
||||
serialPort?.Write(currentState, 0, currentState.Length);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (Properties.Settings.Default.IsDebugEnabled)
|
||||
{
|
||||
Logger.Error("Error when writing to serial port on button update", ex);
|
|
@ -1,9 +1,9 @@
|
|||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace WpfMaiTouchEmulator;
|
||||
namespace WpfMaiTouchEmulator.Managers;
|
||||
|
||||
enum TouchValue: long
|
||||
public enum TouchValue : long
|
||||
{
|
||||
A1 = 1 << 0, // 2^0
|
||||
A2 = 1 << 1, // 2^1
|
||||
|
@ -23,7 +23,6 @@ enum TouchValue: long
|
|||
B8 = 1 << 15, // 2^15
|
||||
C1 = 1 << 16, // 2^16
|
||||
C2 = 1 << 17, // 2^17
|
||||
C3 = C1 | C2, // A special sensor used because center notes are hard to press using a windows touchscreen
|
||||
D1 = 1 << 18, // 2^18
|
||||
D2 = 1 << 19, // 2^19
|
||||
D3 = 1 << 20, // 2^20
|
||||
|
@ -50,24 +49,6 @@ internal class MaiTouchSensorButtonStateManager
|
|||
public MaiTouchSensorButtonStateManager(Label buttonStateValue)
|
||||
{
|
||||
this.buttonStateValue = buttonStateValue;
|
||||
SetupUpdateLoop();
|
||||
}
|
||||
|
||||
private async Task SetupUpdateLoop()
|
||||
{
|
||||
string? lastButtonState = null;
|
||||
while (true)
|
||||
{
|
||||
if (lastButtonState != buttonState.ToString())
|
||||
{
|
||||
lastButtonState = buttonState.ToString();
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
buttonStateValue.Content = lastButtonState;
|
||||
});
|
||||
}
|
||||
await Task.Delay(16);
|
||||
}
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
|
@ -77,12 +58,22 @@ internal class MaiTouchSensorButtonStateManager
|
|||
|
||||
public void PressButton(TouchValue button)
|
||||
{
|
||||
buttonState |= ((long)button);
|
||||
buttonState |= (long)button;
|
||||
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
buttonStateValue.Content = buttonState.ToString();
|
||||
});
|
||||
}
|
||||
|
||||
public void ReleaseButton(TouchValue button)
|
||||
{
|
||||
buttonState &= ~((long)button);
|
||||
buttonState &= ~(long)button;
|
||||
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
buttonStateValue.Content = buttonState.ToString();
|
||||
});
|
||||
}
|
||||
|
||||
public byte[] GetCurrentState()
|
|
@ -0,0 +1,56 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace WpfMaiTouchEmulator.Managers;
|
||||
public partial class RingButtonEmulator
|
||||
{
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, nuint dwExtraInfo);
|
||||
|
||||
private static readonly IDictionary<TouchValue, byte> touchRingMapping = new Dictionary<TouchValue, byte>()
|
||||
{
|
||||
{ TouchValue.A1, 0x57 }, // W
|
||||
{ TouchValue.A2, 0x45 }, // E
|
||||
{ TouchValue.A3, 0x44 }, // D
|
||||
{ TouchValue.A4, 0x43 }, // C
|
||||
{ TouchValue.A5, 0x58 }, // X
|
||||
{ TouchValue.A6, 0x5A }, // Z
|
||||
{ TouchValue.A7, 0x41 }, // A
|
||||
{ TouchValue.A8, 0x51 }, // Q
|
||||
};
|
||||
private const uint KEYEVENTF_KEYUP = 0x0002;
|
||||
|
||||
public static bool HasRingButtonMapping(TouchValue touchValue)
|
||||
{
|
||||
return touchRingMapping.ContainsKey(touchValue);
|
||||
}
|
||||
|
||||
public static void PressButton(TouchValue touchValue)
|
||||
{
|
||||
if (touchRingMapping.TryGetValue(touchValue, out var vk))
|
||||
{
|
||||
keybd_event(vk, 0, 0, nuint.Zero);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ReleaseButton(TouchValue touchValue)
|
||||
{
|
||||
if (touchRingMapping.TryGetValue(touchValue, out var vk))
|
||||
{
|
||||
keybd_event(vk, 0, KEYEVENTF_KEYUP, nuint.Zero);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ReleaseAllButtons()
|
||||
{
|
||||
foreach (var vk in touchRingMapping.Values)
|
||||
{
|
||||
keybd_event(vk, 0, KEYEVENTF_KEYUP, nuint.Zero);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,16 +1,16 @@
|
|||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
|
||||
namespace WpfMaiTouchEmulator;
|
||||
namespace WpfMaiTouchEmulator.Managers;
|
||||
|
||||
class TouchPanelPositionManager
|
||||
{
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
static extern IntPtr FindWindow(string? lpClassName, string lpWindowName);
|
||||
static extern nint FindWindow(string? lpClassName, string lpWindowName);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
|
||||
static extern bool GetWindowRect(nint hWnd, out RECT lpRect);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct RECT
|
||||
|
@ -29,16 +29,16 @@ class TouchPanelPositionManager
|
|||
try
|
||||
{
|
||||
var hWnd = FindWindow(null, "Sinmai");
|
||||
if (hWnd != IntPtr.Zero)
|
||||
if (hWnd != nint.Zero)
|
||||
{
|
||||
RECT rect;
|
||||
if (GetWindowRect(hWnd, out rect))
|
||||
{
|
||||
// Calculate the desired size and position based on the other application's window
|
||||
var renderRect = GetLargest916Rect(rect);
|
||||
var height = renderRect.Width;
|
||||
var left = rect.Left + ((rect.Right - rect.Left) - renderRect.Width) / 2; // Center horizontally
|
||||
var top = rect.Bottom - height;
|
||||
var height = renderRect.Height;
|
||||
var left = rect.Left + (rect.Right - rect.Left - renderRect.Width) / 2; // Center horizontally
|
||||
var top = renderRect.Top;
|
||||
return new Rect(left, top, renderRect.Width, height);
|
||||
}
|
||||
}
|
||||
|
@ -56,8 +56,8 @@ class TouchPanelPositionManager
|
|||
var originalWidth = original.Width;
|
||||
var originalHeight = original.Height;
|
||||
|
||||
var widthBasedHeight = (originalWidth * 16) / 9;
|
||||
var heightBasedWidth = (originalHeight * 9) / 16;
|
||||
var widthBasedHeight = originalWidth * 16 / 9;
|
||||
var heightBasedWidth = originalHeight * 9 / 16;
|
||||
|
||||
if (widthBasedHeight <= originalHeight)
|
||||
{
|
|
@ -2,10 +2,17 @@
|
|||
using System.IO.Ports;
|
||||
using System.Windows;
|
||||
|
||||
namespace WpfMaiTouchEmulator;
|
||||
namespace WpfMaiTouchEmulator.Managers;
|
||||
|
||||
internal class VirtualComPortManager
|
||||
{
|
||||
private readonly MainWindowViewModel _viewModel;
|
||||
|
||||
public VirtualComPortManager(MainWindowViewModel viewModel)
|
||||
{
|
||||
_viewModel = viewModel;
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetInstalledPorts()
|
||||
{
|
||||
return SerialPort.GetPortNames();
|
||||
|
@ -14,7 +21,7 @@ internal class VirtualComPortManager
|
|||
public async Task<bool> CheckIfPortInstalled(string port, bool expectToExist)
|
||||
{
|
||||
var installed = false;
|
||||
for (var i = 0; i< 3; i++)
|
||||
for (var i = 0; i < 3; i++)
|
||||
{
|
||||
installed = GetInstalledPorts().Any(x => x == port);
|
||||
if (installed && expectToExist)
|
||||
|
@ -32,7 +39,7 @@ internal class VirtualComPortManager
|
|||
if (await CheckIfPortInstalled("COM3", false))
|
||||
{
|
||||
Logger.Warn("Port COM3 already registered.");
|
||||
MessageBox.Show("Port COM3 already registered. Either remove it via Device Manager or uninstall the virutal port.");
|
||||
MessageBox.Show(_viewModel.TxtCom3AlreadyInstalled);
|
||||
return;
|
||||
}
|
||||
try
|
||||
|
@ -42,18 +49,18 @@ internal class VirtualComPortManager
|
|||
if (await CheckIfPortInstalled("COM3", true))
|
||||
{
|
||||
Logger.Info("Port COM3 successfully installed.");
|
||||
MessageBox.Show("Port COM3 successfully installed.");
|
||||
MessageBox.Show(_viewModel.TxtCom3InstalledSuccessfully);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Error("Port COM3 failed to install");
|
||||
MessageBox.Show($"Port COM3 failed to install", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
MessageBox.Show(_viewModel.TxtCom3InstallFailed, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error("Port COM3 failed to install", ex);
|
||||
MessageBox.Show($"Port COM3 failed to install. {ex}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
MessageBox.Show($"{_viewModel.TxtCom3InstallFailed} {ex}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,7 +70,7 @@ internal class VirtualComPortManager
|
|||
if (!await CheckIfPortInstalled("COM3", true))
|
||||
{
|
||||
Logger.Warn("Port COM3 not found. No need to uninstall.");
|
||||
MessageBox.Show("Port COM3 not found. No need to uninstall.");
|
||||
MessageBox.Show(_viewModel.TxtCom3UninstallNotRequired);
|
||||
return;
|
||||
}
|
||||
try
|
||||
|
@ -73,18 +80,18 @@ internal class VirtualComPortManager
|
|||
if (!await CheckIfPortInstalled("COM3", false))
|
||||
{
|
||||
Logger.Info("Port COM3 successfully uninstalled.");
|
||||
MessageBox.Show("Port COM3 successfully uninstalled.");
|
||||
MessageBox.Show(_viewModel.TxtCom3UninstalledSuccessfully);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Error("Port COM3 failed to uninstall");
|
||||
MessageBox.Show($"Port COM3 failed to uninstall. It may be a real device, uninstall it from Device Manager", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
MessageBox.Show(_viewModel.TxtCom3UninstallFailed, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error("Port COM3 failed to uninstall", ex);
|
||||
MessageBox.Show($"Port COM3 failed to uninstall. {ex}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
MessageBox.Show($"{_viewModel.TxtCom3UninstallFailed} {ex}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
}
|
||||
|
|
@ -12,7 +12,7 @@ namespace WpfMaiTouchEmulator.Properties {
|
|||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.8.0.0")]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.12.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
@ -82,5 +82,77 @@ namespace WpfMaiTouchEmulator.Properties {
|
|||
this["FirstOpen"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
||||
public string UserLanguage {
|
||||
get {
|
||||
return ((string)(this["UserLanguage"]));
|
||||
}
|
||||
set {
|
||||
this["UserLanguage"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool IsRingButtonEmulationEnabled {
|
||||
get {
|
||||
return ((bool)(this["IsRingButtonEmulationEnabled"]));
|
||||
}
|
||||
set {
|
||||
this["IsRingButtonEmulationEnabled"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("0")]
|
||||
public int BorderSetting {
|
||||
get {
|
||||
return ((int)(this["BorderSetting"]));
|
||||
}
|
||||
set {
|
||||
this["BorderSetting"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
||||
public string BorderColour {
|
||||
get {
|
||||
return ((string)(this["BorderColour"]));
|
||||
}
|
||||
set {
|
||||
this["BorderColour"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool UserSettingsUpgradeRequired {
|
||||
get {
|
||||
return ((bool)(this["UserSettingsUpgradeRequired"]));
|
||||
}
|
||||
set {
|
||||
this["UserSettingsUpgradeRequired"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("False")]
|
||||
public bool IsLargeButtonsEnabled {
|
||||
get {
|
||||
return ((bool)(this["IsLargeButtonsEnabled"]));
|
||||
}
|
||||
set {
|
||||
this["IsLargeButtonsEnabled"] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,5 +17,23 @@
|
|||
<Setting Name="FirstOpen" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="UserLanguage" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)" />
|
||||
</Setting>
|
||||
<Setting Name="IsRingButtonEmulationEnabled" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="BorderSetting" Type="System.Int32" Scope="User">
|
||||
<Value Profile="(Default)">0</Value>
|
||||
</Setting>
|
||||
<Setting Name="BorderColour" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)" />
|
||||
</Setting>
|
||||
<Setting Name="UserSettingsUpgradeRequired" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="IsLargeButtonsEnabled" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">False</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
|
@ -0,0 +1,53 @@
|
|||
# WpfMaiTouchEmulator
|
||||
タッチスクリーン上のソフトウェアを使用してSDEZ MaiMaiのタッチセンサーハードウェアをエミュレートすることを目的としたWPF C# アプリケーションです。
|
||||
|
||||
# 動作原理
|
||||
このアプリはcom0comを使用して仮想COMポートのペアCOM3 - COM23をインストールします。その後、アプリはCOM23に接続し、ハードウェアのタッチセンサーがどのように機能するかをエミュレートし、このポートを通じてデータを送信します。
|
||||
|
||||
# デモ
|
||||
|
||||
|
||||
https://github.com/user-attachments/assets/fd0d8f08-586b-416e-8e49-7e389a08d02b
|
||||
|
||||
|
||||
|
||||
https://github.com/user-attachments/assets/1862e59b-520c-4cd5-adf4-37389a75815d
|
||||
|
||||
|
||||
|
||||
# セットアップ
|
||||
Windowsで三本指及び四本指のタッチジェスチャーを無効にする(W11の設定 -> Bluetooth & デバイス -> タッチ)
|
||||
|
||||
このアプリを動作させるにはCOM3が空いている必要があります。多くの場合、COM3はUSBシリアルデバイスによって既に使用されています。これはデバイスマネージャーを通じてアンインストールする必要があります。
|
||||
1. デバイスマネージャーを開く
|
||||
2. 隠しデバイスを表示する。「ビュー」->「隠しデバイスを表示」->「ポート(COM & LPT)」-> COM3デバイスを右クリックし、アンインストール。
|
||||
|
||||
maimaiの.iniファイルの[AM]セクションに`DummyTouchPanel=0`を設定します。
|
||||
|
||||
WpfMaiTouchEmulator.exeアプリを開き、「COMポートをインストール」ボタンをクリックして仮想ポートをインストールします。アプリの起動時にCOM23ポートに自動的に接続するために「自動ポート接続」をチェックするか、「ポートに接続」ボタンを押します。
|
||||
|
||||
仮想ポートをインストールした後、アプリがCOM23にバインドできない場合は、PCを再起動すると通常問題が解決します。
|
||||
|
||||
SDEZを開始し、通常通りタッチスクリーンを使用します。
|
||||
|
||||
[オプション] アプリケーションを毎回手動で開かなくても済むようにするために、「自動ポート接続」を有効にし、MaiMaiのstart.batファイルに`@echo off`の後に次の行を追加します。`start "" "<WpfMaiTouchEmulator.exeへのパス>"`
|
||||
|
||||
[オプション] W11を使用していて、左スワイプが時々「ウィジェット」ペインを開く場合は、管理者としてこのコマンドを実行して`winget uninstall "windows web experience pack"`、画面の指示に従います。
|
||||
|
||||
# 付属のcom0comプログラムを使用せずに仮想COMポートをインストールする
|
||||
この未知のアプリに管理者権限を与えたくない場合は、アプリに含まれている仮想comのインストール/削除アクションを使用しないで、手動でNull-modem com0comをオンラインでダウンロード(必要なバージョンは2.2.2.0!)して、このコマンドを実行します。
|
||||
`cd "C:\Program Files (x86)\com0com" && setupc.exe install Portname=COM3 Portname=COM23`で仮想ポートをインストールし、
|
||||
`cd "C:\Program Files (x86)\com0com" && setupc.exe uninstall`で仮想ポートをアンインストールします。
|
||||
|
||||
# なぜ?
|
||||
ほとんどのSDEZは内蔵のタッチスクリーンと非常に互換性が低く、SDEZのソースコードを他の人が変更して内蔵タッチコントロールを機能させるか、.dllファイルを編集して再コンパイルする必要があります。このアプリは、すべてのSDEZバージョンで(知る限りでは)すぐに動作するはずです。
|
||||
|
||||
もう一つの理由は、タッチセンサーとして使用するITOエッチングパネルの調達が難しく、かなり高価であるためです。
|
||||
|
||||
# パフォーマンス
|
||||
まあまあです。アプリは最大1Khzでタッチセンサーウィンドウをポーリングしますが、C#で実行されているため、実際の速度はホストマシンのパフォーマンスに依存する場合があります。
|
||||
|
||||
精度については、私はそれほど上手ではないので、高レベルのプレイでどれほどうまく機能するかは言えませんが、私の経験ではかなりうまく機能します。
|
||||
|
||||
# 感謝
|
||||
基本的なシリアルデータ形式とタッチ実装の研究について、[whowechina - mai_pico](https://github.com/whowechina/mai_pico) と [Sucareto - Mai2Touch](https://github.com/Sucareto/Mai2Touch) に感謝します。
|
11
README.md
|
@ -1,18 +1,23 @@
|
|||
|
||||
|
||||
# WpfMaiTouchEmulator
|
||||
A WPF C# app meant to emulate the touch sensor hardware for SDEZ MaiMai using software on a touchscreen.
|
||||
|
||||
## README in Other Languages
|
||||
|
||||
- [简体中文](README.zh.md)
|
||||
- [日本語](README.jp.md)
|
||||
|
||||
# How it works
|
||||
The app uses com0com to install a virtual COM port pairing of COM3 - COM23. The app then connects to COM23 and emulates how the hardware touch sensor works, sending data over this port.
|
||||
|
||||
# Demo
|
||||
|
||||
|
||||
https://github.com/Leapward-Koex/MaiTouchSensorEmulator/assets/30615050/eea21285-fec5-4393-a75d-74274b39789f
|
||||
https://github.com/user-attachments/assets/fd0d8f08-586b-416e-8e49-7e389a08d02b
|
||||
|
||||
|
||||
|
||||
https://github.com/Leapward-Koex/MaiTouchSensorEmulator/assets/30615050/e45ca02f-8d82-4ad4-a610-ef08abcb5087
|
||||
https://github.com/user-attachments/assets/1862e59b-520c-4cd5-adf4-37389a75815d
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
# WpfMaiTouchEmulator
|
||||
一个用于通过触摸屏软件模拟SDEZ MaiMai的触摸传感器硬件的WPF C# 应用程序。
|
||||
|
||||
# 工作原理
|
||||
该应用程序使用com0com安装一个虚拟的COM端口配对:COM3 - COM23。然后,应用程序连接到COM23并模拟硬件触摸传感器的工作方式,通过此端口发送数据。
|
||||
|
||||
# 演示
|
||||
|
||||
|
||||
https://github.com/user-attachments/assets/fd0d8f08-586b-416e-8e49-7e389a08d02b
|
||||
|
||||
|
||||
|
||||
https://github.com/user-attachments/assets/1862e59b-520c-4cd5-adf4-37389a75815d
|
||||
|
||||
|
||||
|
||||
# 设置
|
||||
在Windows中禁用三指和四指触摸手势(在W11设置 -> 蓝牙与设备 -> 触摸)
|
||||
|
||||
COM3需要空闲,因为这是SDEZ使用的端口。默认情况下,大多数人会发现COM3已被USB串行设备使用。需要通过设备管理器卸载,
|
||||
1. 打开设备管理器
|
||||
2. 显示隐藏设备。"视图" -> "显示隐藏设备" -> "端口(COM & LPT)" -> 右键点击COM3设备并卸载。
|
||||
|
||||
在您的maimai.ini文件的[AM]部分设置`DummyTouchPanel=0`。
|
||||
|
||||
打开WpfMaiTouchEmulator.exe应用程序,通过"安装COM端口"按钮安装虚拟端口,可以勾选"自动连接端口"使应用程序在启动时连接到COM23端口,或按"连接到端口"按钮。
|
||||
|
||||
如果在安装虚拟端口后应用程序无法绑定到COM23,我发现重新启动我的电脑通常可以解决问题。
|
||||
|
||||
启动SDEZ并正常使用您的触摸屏。
|
||||
|
||||
[可选] 为了避免每次都手动打开应用程序,您可以启用"自动连接端口"并在您的MaiMai的start.bat文件中`@echo off`之后添加这行代码。`start "" "<您的WpfMaiTouchEmulator.exe路径>"`
|
||||
|
||||
[可选] 如果您使用的是W11,并且发现左滑有时会打开“小部件”面板,您可以通过以管理员身份运行此命令`winget uninstall "windows web experience pack"`并按照屏幕上的指示操作来移除面板。
|
||||
|
||||
# 不使用随附的com0com程序安装虚拟COM端口
|
||||
如果您不想使用应用程序中包含的安装/移除虚拟com操作,因为您不想给这个未知的应用程序管理员权限,那么您可以通过手动下载Null-modem com0com(需要版本2.2.2.0!)并运行此命令来达到同样的效果。
|
||||
`cd "C:\Program Files (x86)\com0com" && setupc.exe install Portname=COM3 Portname=COM23`来安装虚拟端口和
|
||||
`cd "C:\Program Files (x86)\com0com" && setupc.exe uninstall`来卸载虚拟端口。
|
||||
|
||||
# 为什么?
|
||||
大多数SDEZ与内置触摸屏的兼容性不是很好,需要其他人修改SDEZ的源代码才能使内置触控功能正常工作,或者您需要编辑并重新编译.dll文件。这个应用程序应该可以开箱即用地与所有SDEZ版本兼容(据我所知)。
|
||||
|
||||
另一个原因是,获取用作触摸传感器的ITO蚀刻面板可能既困难又昂贵。
|
||||
|
||||
# 性能
|
||||
还可以,应用程序以最高1Khz的频率轮询触摸传感器窗口,但它是用C#运行的,所以实际运行速度可能取决于主机的性能。
|
||||
|
||||
至于准确性。我不是很擅长,所以无法说它在高级别的游戏中表现如何,但根据我的经验,它运行得相当不错。
|
||||
|
||||
# 感谢
|
||||
感谢 [whowechina - mai_pico](https://github.com/whowechina/mai_pico) 和 [Sucareto - Mai2Touch](https://github.com/Sucareto/Mai2Touch) 提供基本的串行数据格式和触摸实现研究。
|
|
@ -0,0 +1,499 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace WpfMaiTouchEmulator.Resources {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Strings {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Strings() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("WpfMaiTouchEmulator.Resources.Strings", typeof(Strings).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to About.
|
||||
/// </summary>
|
||||
internal static string LbAbout {
|
||||
get {
|
||||
return ResourceManager.GetString("LbAbout", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Automatic port connecting.
|
||||
/// </summary>
|
||||
internal static string lbAutoPortConnecting {
|
||||
get {
|
||||
return ResourceManager.GetString("lbAutoPortConnecting", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Try to automatically connect to COM23 to send touch sensor updates on app start.
|
||||
/// </summary>
|
||||
internal static string lbAutoPortConnectingTT {
|
||||
get {
|
||||
return ResourceManager.GetString("lbAutoPortConnectingTT", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Automatic sensor window positioning.
|
||||
/// </summary>
|
||||
internal static string lbAutoSensorPositioning {
|
||||
get {
|
||||
return ResourceManager.GetString("lbAutoSensorPositioning", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Try and automatically move the touch sensor window into the correct position on top of Sinmai.exe.
|
||||
/// </summary>
|
||||
internal static string lbAutoSensorPositioningTT {
|
||||
get {
|
||||
return ResourceManager.GetString("lbAutoSensorPositioningTT", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Disabled.
|
||||
/// </summary>
|
||||
internal static string LbBorderDisabled {
|
||||
get {
|
||||
return ResourceManager.GetString("LbBorderDisabled", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Rainbow.
|
||||
/// </summary>
|
||||
internal static string LbBorderRainbow {
|
||||
get {
|
||||
return ResourceManager.GetString("LbBorderRainbow", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Border Settings.
|
||||
/// </summary>
|
||||
internal static string LbBorderSettings {
|
||||
get {
|
||||
return ResourceManager.GetString("LbBorderSettings", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Solid.
|
||||
/// </summary>
|
||||
internal static string LbBorderSolid {
|
||||
get {
|
||||
return ResourceManager.GetString("LbBorderSolid", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Button State.
|
||||
/// </summary>
|
||||
internal static string lbButtonState {
|
||||
get {
|
||||
return ResourceManager.GetString("lbButtonState", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to COM Port.
|
||||
/// </summary>
|
||||
internal static string LbComPort {
|
||||
get {
|
||||
return ResourceManager.GetString("LbComPort", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Connection state.
|
||||
/// </summary>
|
||||
internal static string lbConnectionState {
|
||||
get {
|
||||
return ResourceManager.GetString("lbConnectionState", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Not connected.
|
||||
/// </summary>
|
||||
internal static string lbConnectionStateNotConnected {
|
||||
get {
|
||||
return ResourceManager.GetString("lbConnectionStateNotConnected", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Connect to port.
|
||||
/// </summary>
|
||||
internal static string lbConnectToPort {
|
||||
get {
|
||||
return ResourceManager.GetString("lbConnectToPort", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Debug mode.
|
||||
/// </summary>
|
||||
internal static string lbDebugMode {
|
||||
get {
|
||||
return ResourceManager.GetString("lbDebugMode", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Show the touchpad with translucency and show inputs highlighted.
|
||||
/// </summary>
|
||||
internal static string lbDebugModeTT {
|
||||
get {
|
||||
return ResourceManager.GetString("lbDebugModeTT", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Emulate ring buttons.
|
||||
/// </summary>
|
||||
internal static string lbEmulateRingButtons {
|
||||
get {
|
||||
return ResourceManager.GetString("lbEmulateRingButtons", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Useful when navigating the menus without a keyboard.
|
||||
/// </summary>
|
||||
internal static string lbEmulateRingButtonsTT {
|
||||
get {
|
||||
return ResourceManager.GetString("lbEmulateRingButtonsTT", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Exit when Sinmai exits.
|
||||
/// </summary>
|
||||
internal static string lbExitWithSinmai {
|
||||
get {
|
||||
return ResourceManager.GetString("lbExitWithSinmai", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Try and detect when Sinmai.exe exits and exit this app alongside it.
|
||||
/// </summary>
|
||||
internal static string lbExitWithSinmaiTT {
|
||||
get {
|
||||
return ResourceManager.GetString("lbExitWithSinmaiTT", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Install com port.
|
||||
/// </summary>
|
||||
internal static string lbInstallComPort {
|
||||
get {
|
||||
return ResourceManager.GetString("lbInstallComPort", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Language.
|
||||
/// </summary>
|
||||
internal static string lbLanguageDropdown {
|
||||
get {
|
||||
return ResourceManager.GetString("lbLanguageDropdown", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Extend ring button size.
|
||||
/// </summary>
|
||||
internal static string lbLargeButtons {
|
||||
get {
|
||||
return ResourceManager.GetString("lbLargeButtons", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Extends the ring button hitboxes to the edge of the window.
|
||||
/// </summary>
|
||||
internal static string lbLargeButtonsTT {
|
||||
get {
|
||||
return ResourceManager.GetString("lbLargeButtonsTT", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to List installed com ports.
|
||||
/// </summary>
|
||||
internal static string lbListComPorts {
|
||||
get {
|
||||
return ResourceManager.GetString("lbListComPorts", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to _Help.
|
||||
/// </summary>
|
||||
internal static string lbMenuCategoryHelp {
|
||||
get {
|
||||
return ResourceManager.GetString("lbMenuCategoryHelp", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Show setup instructions.
|
||||
/// </summary>
|
||||
internal static string lbMenuItemSetup {
|
||||
get {
|
||||
return ResourceManager.GetString("lbMenuItemSetup", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Open log folder.
|
||||
/// </summary>
|
||||
internal static string LbOpenLogFolder {
|
||||
get {
|
||||
return ResourceManager.GetString("LbOpenLogFolder", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Received.
|
||||
/// </summary>
|
||||
internal static string lbRecievedData {
|
||||
get {
|
||||
return ResourceManager.GetString("lbRecievedData", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Sent.
|
||||
/// </summary>
|
||||
internal static string lbSentData {
|
||||
get {
|
||||
return ResourceManager.GetString("lbSentData", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Settings.
|
||||
/// </summary>
|
||||
internal static string LbSettings {
|
||||
get {
|
||||
return ResourceManager.GetString("LbSettings", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Drag.
|
||||
/// </summary>
|
||||
internal static string LbTouchPanelDrag {
|
||||
get {
|
||||
return ResourceManager.GetString("LbTouchPanelDrag", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Resize.
|
||||
/// </summary>
|
||||
internal static string LbTouchPanelResize {
|
||||
get {
|
||||
return ResourceManager.GetString("LbTouchPanelResize", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Uninstall com port.
|
||||
/// </summary>
|
||||
internal static string lbUninstallComPort {
|
||||
get {
|
||||
return ResourceManager.GetString("lbUninstallComPort", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Port COM3 already registered. Either remove it via Device Manager or uninstall the virtual port..
|
||||
/// </summary>
|
||||
internal static string TxtCom3AlreadyInstalled {
|
||||
get {
|
||||
return ResourceManager.GetString("TxtCom3AlreadyInstalled", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Port COM3 successfully installed..
|
||||
/// </summary>
|
||||
internal static string TxtCom3InstalledSuccessfully {
|
||||
get {
|
||||
return ResourceManager.GetString("TxtCom3InstalledSuccessfully", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Port COM3 failed to install.
|
||||
/// </summary>
|
||||
internal static string TxtCom3InstallFailed {
|
||||
get {
|
||||
return ResourceManager.GetString("TxtCom3InstallFailed", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Port COM3 successfully uninstalled..
|
||||
/// </summary>
|
||||
internal static string TxtCom3UninstalledSuccessfully {
|
||||
get {
|
||||
return ResourceManager.GetString("TxtCom3UninstalledSuccessfully", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Port COM3 failed to uninstall. It may be a real device, uninstall it from Device Manager.
|
||||
/// </summary>
|
||||
internal static string TxtCom3UninstallFailed {
|
||||
get {
|
||||
return ResourceManager.GetString("TxtCom3UninstallFailed", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Port COM3 not found. No need to uninstall..
|
||||
/// </summary>
|
||||
internal static string TxtCom3UninstallNotRequired {
|
||||
get {
|
||||
return ResourceManager.GetString("TxtCom3UninstallNotRequired", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Connected to port.
|
||||
/// </summary>
|
||||
internal static string TxtComPortConnected {
|
||||
get {
|
||||
return ResourceManager.GetString("TxtComPortConnected", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Conecting....
|
||||
/// </summary>
|
||||
internal static string TxtComPortConnecting {
|
||||
get {
|
||||
return ResourceManager.GetString("TxtComPortConnecting", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Installed ports.
|
||||
/// </summary>
|
||||
internal static string TxtCurrentlyInstalledPorts {
|
||||
get {
|
||||
return ResourceManager.GetString("TxtCurrentlyInstalledPorts", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Error connecting to COM port.
|
||||
/// </summary>
|
||||
internal static string TxtErrorConnectingToPortHeader {
|
||||
get {
|
||||
return ResourceManager.GetString("TxtErrorConnectingToPortHeader", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Failed to listen for Sinmai exit signal, this can happen when Sinmai.exe is being run as admin.\n\nAutomatic exiting disabled..
|
||||
/// </summary>
|
||||
internal static string TxtFailedToSetupSinmaiExit {
|
||||
get {
|
||||
return ResourceManager.GetString("TxtFailedToSetupSinmaiExit", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Failed to listen for Sinmai exit.
|
||||
/// </summary>
|
||||
internal static string TxtFailedToSetupSinmaiExitHeader {
|
||||
get {
|
||||
return ResourceManager.GetString("TxtFailedToSetupSinmaiExitHeader", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Please remove any COM devices using the COM3 port before installing the virtual COM port. In Device Manager click "View" then enabled "Show hidden devices" and uninstall any devices that are using the COM3 port.
|
||||
///
|
||||
///After ensuring COM3 is free please use the install COM port button in the app to register the app.
|
||||
///
|
||||
///The app needs to connect to the port prior to Sinmai.exe being opened..
|
||||
/// </summary>
|
||||
internal static string TxtSetupInstructions {
|
||||
get {
|
||||
return ResourceManager.GetString("TxtSetupInstructions", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to First time setup.
|
||||
/// </summary>
|
||||
internal static string TxtSetupInstructionsHeader {
|
||||
get {
|
||||
return ResourceManager.GetString("TxtSetupInstructionsHeader", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,268 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="LbAbout" xml:space="preserve">
|
||||
<value>について</value>
|
||||
</data>
|
||||
<data name="lbAutoPortConnecting" xml:space="preserve">
|
||||
<value>自動ポート接続</value>
|
||||
</data>
|
||||
<data name="lbAutoPortConnectingTT" xml:space="preserve">
|
||||
<value>アプリ起動時にCOM23に自動的に接続してタッチセンサーの更新を送信しようとする</value>
|
||||
</data>
|
||||
<data name="lbAutoSensorPositioning" xml:space="preserve">
|
||||
<value>自動センサーウィンドウ配置</value>
|
||||
</data>
|
||||
<data name="lbAutoSensorPositioningTT" xml:space="preserve">
|
||||
<value>Sinmai.exeの上に正しい位置にタッチセンサーウィンドウを自動的に移動しようとする</value>
|
||||
</data>
|
||||
<data name="LbBorderDisabled" xml:space="preserve">
|
||||
<value>無効</value>
|
||||
</data>
|
||||
<data name="LbBorderRainbow" xml:space="preserve">
|
||||
<value>レインボー</value>
|
||||
</data>
|
||||
<data name="LbBorderSettings" xml:space="preserve">
|
||||
<value>境界線設定</value>
|
||||
</data>
|
||||
<data name="LbBorderSolid" xml:space="preserve">
|
||||
<value>単色</value>
|
||||
</data>
|
||||
<data name="lbButtonState" xml:space="preserve">
|
||||
<value>ボタン状態</value>
|
||||
</data>
|
||||
<data name="LbComPort" xml:space="preserve">
|
||||
<value>COMポート</value>
|
||||
</data>
|
||||
<data name="lbConnectionState" xml:space="preserve">
|
||||
<value>接続状態</value>
|
||||
</data>
|
||||
<data name="lbConnectionStateNotConnected" xml:space="preserve">
|
||||
<value>未接続</value>
|
||||
</data>
|
||||
<data name="lbConnectToPort" xml:space="preserve">
|
||||
<value>ポートに接続</value>
|
||||
</data>
|
||||
<data name="lbDebugMode" xml:space="preserve">
|
||||
<value>デバッグモード</value>
|
||||
</data>
|
||||
<data name="lbDebugModeTT" xml:space="preserve">
|
||||
<value>タッチパッドを半透明で表示し、入力をハイライト表示</value>
|
||||
</data>
|
||||
<data name="lbEmulateRingButtons" xml:space="preserve">
|
||||
<value>リングボタンをエミュレートする</value>
|
||||
</data>
|
||||
<data name="lbEmulateRingButtonsTT" xml:space="preserve">
|
||||
<value>キーボードがないときにメニュー操作に便利</value>
|
||||
</data>
|
||||
<data name="lbExitWithSinmai" xml:space="preserve">
|
||||
<value>Sinmai終了時に終了</value>
|
||||
</data>
|
||||
<data name="lbExitWithSinmaiTT" xml:space="preserve">
|
||||
<value>Sinmai.exeが終了するのを検出し、このアプリも同時に終了しようとする</value>
|
||||
</data>
|
||||
<data name="lbInstallComPort" xml:space="preserve">
|
||||
<value>COMポートをインストール</value>
|
||||
</data>
|
||||
<data name="lbLanguageDropdown" xml:space="preserve">
|
||||
<value>言語</value>
|
||||
</data>
|
||||
<data name="lbLargeButtons" xml:space="preserve">
|
||||
<value>リングボタンのサイズを拡大</value>
|
||||
</data>
|
||||
<data name="lbLargeButtonsTT" xml:space="preserve">
|
||||
<value>リングボタンのヒットボックスをウィンドウの端まで拡大</value>
|
||||
</data>
|
||||
<data name="lbListComPorts" xml:space="preserve">
|
||||
<value>インストールされたCOMポートをリストアップ</value>
|
||||
</data>
|
||||
<data name="lbMenuCategoryHelp" xml:space="preserve">
|
||||
<value>_ヘルプ</value>
|
||||
</data>
|
||||
<data name="lbMenuItemSetup" xml:space="preserve">
|
||||
<value>セットアップ指示を表示</value>
|
||||
</data>
|
||||
<data name="LbOpenLogFolder" xml:space="preserve">
|
||||
<value>ログフォルダを開く</value>
|
||||
</data>
|
||||
<data name="lbRecievedData" xml:space="preserve">
|
||||
<value>受信データ</value>
|
||||
</data>
|
||||
<data name="lbSentData" xml:space="preserve">
|
||||
<value>送信データ</value>
|
||||
</data>
|
||||
<data name="LbSettings" xml:space="preserve">
|
||||
<value>設定</value>
|
||||
</data>
|
||||
<data name="LbTouchPanelDrag" xml:space="preserve">
|
||||
<value>ドラッグ</value>
|
||||
</data>
|
||||
<data name="LbTouchPanelResize" xml:space="preserve">
|
||||
<value>サイズ変更</value>
|
||||
</data>
|
||||
<data name="lbUninstallComPort" xml:space="preserve">
|
||||
<value>COMポートをアンインストール</value>
|
||||
</data>
|
||||
<data name="TxtCom3AlreadyInstalled" xml:space="preserve">
|
||||
<value>ポートCOM3はすでに登録されています。デバイスマネージャを通じてそれを取り除くか、仮想ポートをアンインストールしてください。</value>
|
||||
</data>
|
||||
<data name="TxtCom3InstalledSuccessfully" xml:space="preserve">
|
||||
<value>COM3ポートが正常にインストールされました。</value>
|
||||
</data>
|
||||
<data name="TxtCom3InstallFailed" xml:space="preserve">
|
||||
<value>COM3ポートのインストールに失敗しました</value>
|
||||
</data>
|
||||
<data name="TxtCom3UninstalledSuccessfully" xml:space="preserve">
|
||||
<value>COM3ポートが正常にアンインストールされました。</value>
|
||||
</data>
|
||||
<data name="TxtCom3UninstallFailed" xml:space="preserve">
|
||||
<value>COM3ポートのアンインストールに失敗しました。実際のデバイスである可能性があります、デバイスマネージャーからアンインストールしてください</value>
|
||||
</data>
|
||||
<data name="TxtCom3UninstallNotRequired" xml:space="preserve">
|
||||
<value>COM3ポートが見つかりませんでした。アンインストールの必要はありません。</value>
|
||||
</data>
|
||||
<data name="TxtComPortConnected" xml:space="preserve">
|
||||
<value>ポートに接続されました</value>
|
||||
</data>
|
||||
<data name="TxtComPortConnecting" xml:space="preserve">
|
||||
<value>接続中...</value>
|
||||
</data>
|
||||
<data name="TxtCurrentlyInstalledPorts" xml:space="preserve">
|
||||
<value>インストールされたポート</value>
|
||||
</data>
|
||||
<data name="TxtErrorConnectingToPortHeader" xml:space="preserve">
|
||||
<value>COMポートへの接続エラー</value>
|
||||
</data>
|
||||
<data name="TxtFailedToSetupSinmaiExit" xml:space="preserve">
|
||||
<value>Sinmaiの終了信号を聞くことができなかったため、これはSinmai.exeが管理者として実行されているときに起こり得ます。\n\n自動終了が無効になりました。</value>
|
||||
</data>
|
||||
<data name="TxtFailedToSetupSinmaiExitHeader" xml:space="preserve">
|
||||
<value>Sinmaiの終了を検出できなかった</value>
|
||||
</data>
|
||||
<data name="TxtSetupInstructions" xml:space="preserve">
|
||||
<value>COM3ポートを使用している任意のCOMデバイスを仮想COMポートをインストールする前に取り除いてください。デバイスマネージャで「表示」をクリックし、「隠れたデバイスを表示」を有効にして、COM3ポートを使用しているデバイスをアンインストールしてください。
|
||||
|
||||
COM3が空いていることを確認した後、アプリ内のCOMポートインストールボタンを使用してアプリを登録してください
|
||||
|
||||
アプリはSinmai.exeを開く前にポートに接続する必要があります。</value>
|
||||
</data>
|
||||
<data name="TxtSetupInstructionsHeader" xml:space="preserve">
|
||||
<value>初回セットアップ</value>
|
||||
</data>
|
||||
</root>
|
|
@ -0,0 +1,268 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="LbAbout" xml:space="preserve">
|
||||
<value>About</value>
|
||||
</data>
|
||||
<data name="lbAutoPortConnecting" xml:space="preserve">
|
||||
<value>Automatic port connecting</value>
|
||||
</data>
|
||||
<data name="lbAutoPortConnectingTT" xml:space="preserve">
|
||||
<value>Try to automatically connect to COM23 to send touch sensor updates on app start</value>
|
||||
</data>
|
||||
<data name="lbAutoSensorPositioning" xml:space="preserve">
|
||||
<value>Automatic sensor window positioning</value>
|
||||
</data>
|
||||
<data name="lbAutoSensorPositioningTT" xml:space="preserve">
|
||||
<value>Try and automatically move the touch sensor window into the correct position on top of Sinmai.exe</value>
|
||||
</data>
|
||||
<data name="LbBorderDisabled" xml:space="preserve">
|
||||
<value>Disabled</value>
|
||||
</data>
|
||||
<data name="LbBorderRainbow" xml:space="preserve">
|
||||
<value>Rainbow</value>
|
||||
</data>
|
||||
<data name="LbBorderSettings" xml:space="preserve">
|
||||
<value>Border Settings</value>
|
||||
</data>
|
||||
<data name="LbBorderSolid" xml:space="preserve">
|
||||
<value>Solid</value>
|
||||
</data>
|
||||
<data name="lbButtonState" xml:space="preserve">
|
||||
<value>Button State</value>
|
||||
</data>
|
||||
<data name="LbComPort" xml:space="preserve">
|
||||
<value>COM Port</value>
|
||||
</data>
|
||||
<data name="lbConnectionState" xml:space="preserve">
|
||||
<value>Connection state</value>
|
||||
</data>
|
||||
<data name="lbConnectionStateNotConnected" xml:space="preserve">
|
||||
<value>Not connected</value>
|
||||
</data>
|
||||
<data name="lbConnectToPort" xml:space="preserve">
|
||||
<value>Connect to port</value>
|
||||
</data>
|
||||
<data name="lbDebugMode" xml:space="preserve">
|
||||
<value>Debug mode</value>
|
||||
</data>
|
||||
<data name="lbDebugModeTT" xml:space="preserve">
|
||||
<value>Show the touchpad with translucency and show inputs highlighted</value>
|
||||
</data>
|
||||
<data name="lbEmulateRingButtons" xml:space="preserve">
|
||||
<value>Emulate ring buttons</value>
|
||||
</data>
|
||||
<data name="lbEmulateRingButtonsTT" xml:space="preserve">
|
||||
<value>Useful when navigating the menus without a keyboard</value>
|
||||
</data>
|
||||
<data name="lbExitWithSinmai" xml:space="preserve">
|
||||
<value>Exit when Sinmai exits</value>
|
||||
</data>
|
||||
<data name="lbExitWithSinmaiTT" xml:space="preserve">
|
||||
<value>Try and detect when Sinmai.exe exits and exit this app alongside it</value>
|
||||
</data>
|
||||
<data name="lbInstallComPort" xml:space="preserve">
|
||||
<value>Install com port</value>
|
||||
</data>
|
||||
<data name="lbLanguageDropdown" xml:space="preserve">
|
||||
<value>Language</value>
|
||||
</data>
|
||||
<data name="lbLargeButtons" xml:space="preserve">
|
||||
<value>Extend ring button size</value>
|
||||
</data>
|
||||
<data name="lbLargeButtonsTT" xml:space="preserve">
|
||||
<value>Extends the ring button hitboxes to the edge of the window</value>
|
||||
</data>
|
||||
<data name="lbListComPorts" xml:space="preserve">
|
||||
<value>List installed com ports</value>
|
||||
</data>
|
||||
<data name="lbMenuCategoryHelp" xml:space="preserve">
|
||||
<value>_Help</value>
|
||||
</data>
|
||||
<data name="lbMenuItemSetup" xml:space="preserve">
|
||||
<value>Show setup instructions</value>
|
||||
</data>
|
||||
<data name="LbOpenLogFolder" xml:space="preserve">
|
||||
<value>Open log folder</value>
|
||||
</data>
|
||||
<data name="lbRecievedData" xml:space="preserve">
|
||||
<value>Received</value>
|
||||
</data>
|
||||
<data name="lbSentData" xml:space="preserve">
|
||||
<value>Sent</value>
|
||||
</data>
|
||||
<data name="LbSettings" xml:space="preserve">
|
||||
<value>Settings</value>
|
||||
</data>
|
||||
<data name="LbTouchPanelDrag" xml:space="preserve">
|
||||
<value>Drag</value>
|
||||
</data>
|
||||
<data name="LbTouchPanelResize" xml:space="preserve">
|
||||
<value>Resize</value>
|
||||
</data>
|
||||
<data name="lbUninstallComPort" xml:space="preserve">
|
||||
<value>Uninstall com port</value>
|
||||
</data>
|
||||
<data name="TxtCom3AlreadyInstalled" xml:space="preserve">
|
||||
<value>Port COM3 already registered. Either remove it via Device Manager or uninstall the virtual port.</value>
|
||||
</data>
|
||||
<data name="TxtCom3InstalledSuccessfully" xml:space="preserve">
|
||||
<value>Port COM3 successfully installed.</value>
|
||||
</data>
|
||||
<data name="TxtCom3InstallFailed" xml:space="preserve">
|
||||
<value>Port COM3 failed to install</value>
|
||||
</data>
|
||||
<data name="TxtCom3UninstalledSuccessfully" xml:space="preserve">
|
||||
<value>Port COM3 successfully uninstalled.</value>
|
||||
</data>
|
||||
<data name="TxtCom3UninstallFailed" xml:space="preserve">
|
||||
<value>Port COM3 failed to uninstall. It may be a real device, uninstall it from Device Manager</value>
|
||||
</data>
|
||||
<data name="TxtCom3UninstallNotRequired" xml:space="preserve">
|
||||
<value>Port COM3 not found. No need to uninstall.</value>
|
||||
</data>
|
||||
<data name="TxtComPortConnected" xml:space="preserve">
|
||||
<value>Connected to port</value>
|
||||
</data>
|
||||
<data name="TxtComPortConnecting" xml:space="preserve">
|
||||
<value>Conecting...</value>
|
||||
</data>
|
||||
<data name="TxtCurrentlyInstalledPorts" xml:space="preserve">
|
||||
<value>Installed ports</value>
|
||||
</data>
|
||||
<data name="TxtErrorConnectingToPortHeader" xml:space="preserve">
|
||||
<value>Error connecting to COM port</value>
|
||||
</data>
|
||||
<data name="TxtFailedToSetupSinmaiExit" xml:space="preserve">
|
||||
<value>Failed to listen for Sinmai exit signal, this can happen when Sinmai.exe is being run as admin.\n\nAutomatic exiting disabled.</value>
|
||||
</data>
|
||||
<data name="TxtFailedToSetupSinmaiExitHeader" xml:space="preserve">
|
||||
<value>Failed to listen for Sinmai exit</value>
|
||||
</data>
|
||||
<data name="TxtSetupInstructions" xml:space="preserve">
|
||||
<value>Please remove any COM devices using the COM3 port before installing the virtual COM port. In Device Manager click "View" then enabled "Show hidden devices" and uninstall any devices that are using the COM3 port.
|
||||
|
||||
After ensuring COM3 is free please use the install COM port button in the app to register the app.
|
||||
|
||||
The app needs to connect to the port prior to Sinmai.exe being opened.</value>
|
||||
</data>
|
||||
<data name="TxtSetupInstructionsHeader" xml:space="preserve">
|
||||
<value>First time setup</value>
|
||||
</data>
|
||||
</root>
|
|
@ -0,0 +1,268 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="LbAbout" xml:space="preserve">
|
||||
<value>关于</value>
|
||||
</data>
|
||||
<data name="lbAutoPortConnecting" xml:space="preserve">
|
||||
<value>自动连接端口</value>
|
||||
</data>
|
||||
<data name="lbAutoPortConnectingTT" xml:space="preserve">
|
||||
<value>尝试在应用启动时自动连接到COM23以发送触摸传感器更新</value>
|
||||
</data>
|
||||
<data name="lbAutoSensorPositioning" xml:space="preserve">
|
||||
<value>自动传感器窗口定位</value>
|
||||
</data>
|
||||
<data name="lbAutoSensorPositioningTT" xml:space="preserve">
|
||||
<value>尝试自动移动触摸传感器窗口到Sinmai.exe上方的正确位置</value>
|
||||
</data>
|
||||
<data name="LbBorderDisabled" xml:space="preserve">
|
||||
<value>無効</value>
|
||||
</data>
|
||||
<data name="LbBorderRainbow" xml:space="preserve">
|
||||
<value>彩虹</value>
|
||||
</data>
|
||||
<data name="LbBorderSettings" xml:space="preserve">
|
||||
<value>境界線設定</value>
|
||||
</data>
|
||||
<data name="LbBorderSolid" xml:space="preserve">
|
||||
<value>纯色</value>
|
||||
</data>
|
||||
<data name="lbButtonState" xml:space="preserve">
|
||||
<value>按钮状态</value>
|
||||
</data>
|
||||
<data name="LbComPort" xml:space="preserve">
|
||||
<value>COM端口</value>
|
||||
</data>
|
||||
<data name="lbConnectionState" xml:space="preserve">
|
||||
<value>连接状态</value>
|
||||
</data>
|
||||
<data name="lbConnectionStateNotConnected" xml:space="preserve">
|
||||
<value>未连接</value>
|
||||
</data>
|
||||
<data name="lbConnectToPort" xml:space="preserve">
|
||||
<value>连接到端口</value>
|
||||
</data>
|
||||
<data name="lbDebugMode" xml:space="preserve">
|
||||
<value>调试模式</value>
|
||||
</data>
|
||||
<data name="lbDebugModeTT" xml:space="preserve">
|
||||
<value>显示半透明的触控板并突出显示输入</value>
|
||||
</data>
|
||||
<data name="lbEmulateRingButtons" xml:space="preserve">
|
||||
<value>模拟环形按钮</value>
|
||||
</data>
|
||||
<data name="lbEmulateRingButtonsTT" xml:space="preserve">
|
||||
<value>在没有键盘的情况下导航菜单时很有用</value>
|
||||
</data>
|
||||
<data name="lbExitWithSinmai" xml:space="preserve">
|
||||
<value>随Sinmai退出</value>
|
||||
</data>
|
||||
<data name="lbExitWithSinmaiTT" xml:space="preserve">
|
||||
<value>尝试检测Sinmai.exe何时退出,并与之同时退出此应用</value>
|
||||
</data>
|
||||
<data name="lbInstallComPort" xml:space="preserve">
|
||||
<value>安装COM端口</value>
|
||||
</data>
|
||||
<data name="lbLanguageDropdown" xml:space="preserve">
|
||||
<value>语言</value>
|
||||
</data>
|
||||
<data name="lbLargeButtons" xml:space="preserve">
|
||||
<value>扩大环形按钮大小</value>
|
||||
</data>
|
||||
<data name="lbLargeButtonsTT" xml:space="preserve">
|
||||
<value>将环形按钮的碰撞盒扩展到窗口边缘</value>
|
||||
</data>
|
||||
<data name="lbListComPorts" xml:space="preserve">
|
||||
<value>列出已安装的COM端口</value>
|
||||
</data>
|
||||
<data name="lbMenuCategoryHelp" xml:space="preserve">
|
||||
<value>_帮助</value>
|
||||
</data>
|
||||
<data name="lbMenuItemSetup" xml:space="preserve">
|
||||
<value>显示设置说明</value>
|
||||
</data>
|
||||
<data name="LbOpenLogFolder" xml:space="preserve">
|
||||
<value>打开日志文件夹</value>
|
||||
</data>
|
||||
<data name="lbRecievedData" xml:space="preserve">
|
||||
<value>已接收数据</value>
|
||||
</data>
|
||||
<data name="lbSentData" xml:space="preserve">
|
||||
<value>已发送数据</value>
|
||||
</data>
|
||||
<data name="LbSettings" xml:space="preserve">
|
||||
<value>设置</value>
|
||||
</data>
|
||||
<data name="LbTouchPanelDrag" xml:space="preserve">
|
||||
<value>拖动</value>
|
||||
</data>
|
||||
<data name="LbTouchPanelResize" xml:space="preserve">
|
||||
<value>调整大小</value>
|
||||
</data>
|
||||
<data name="lbUninstallComPort" xml:space="preserve">
|
||||
<value>卸载COM端口</value>
|
||||
</data>
|
||||
<data name="TxtCom3AlreadyInstalled" xml:space="preserve">
|
||||
<value>COM3端口已注册。可通过设备管理器移除,或卸载虚拟端口。</value>
|
||||
</data>
|
||||
<data name="TxtCom3InstalledSuccessfully" xml:space="preserve">
|
||||
<value>COM3端口成功安装。</value>
|
||||
</data>
|
||||
<data name="TxtCom3InstallFailed" xml:space="preserve">
|
||||
<value>COM3端口安装失败</value>
|
||||
</data>
|
||||
<data name="TxtCom3UninstalledSuccessfully" xml:space="preserve">
|
||||
<value>COM3端口成功卸载。</value>
|
||||
</data>
|
||||
<data name="TxtCom3UninstallFailed" xml:space="preserve">
|
||||
<value>COM3端口卸载失败。可能是真实设备,请从设备管理器中卸载</value>
|
||||
</data>
|
||||
<data name="TxtCom3UninstallNotRequired" xml:space="preserve">
|
||||
<value>未找到COM3端口,无需卸载。</value>
|
||||
</data>
|
||||
<data name="TxtComPortConnected" xml:space="preserve">
|
||||
<value>已连接到端口</value>
|
||||
</data>
|
||||
<data name="TxtComPortConnecting" xml:space="preserve">
|
||||
<value>正在连接...</value>
|
||||
</data>
|
||||
<data name="TxtCurrentlyInstalledPorts" xml:space="preserve">
|
||||
<value>已安装端口</value>
|
||||
</data>
|
||||
<data name="TxtErrorConnectingToPortHeader" xml:space="preserve">
|
||||
<value>连接COM端口错误</value>
|
||||
</data>
|
||||
<data name="TxtFailedToSetupSinmaiExit" xml:space="preserve">
|
||||
<value>无法监听Sinmai退出信号,这可能是因为Sinmai.exe以管理员身份运行。\n\n自动退出功能已禁用。</value>
|
||||
</data>
|
||||
<data name="TxtFailedToSetupSinmaiExitHeader" xml:space="preserve">
|
||||
<value>监听Sinmai退出失败</value>
|
||||
</data>
|
||||
<data name="TxtSetupInstructions" xml:space="preserve">
|
||||
<value>请在安装虚拟COM端口之前,移除使用COM3端口的任何COM设备。在设备管理器中点击“查看”,然后启用“显示隐藏的设备”,并卸载任何使用COM3端口的设备。
|
||||
|
||||
确保COM3端口空闲后,请使用应用中的安装COM端口按钮来注册应用。
|
||||
|
||||
应用需要在打开Sinmai.exe之前连接到端口。</value>
|
||||
</data>
|
||||
<data name="TxtSetupInstructionsHeader" xml:space="preserve">
|
||||
<value>首次设置</value>
|
||||
</data>
|
||||
</root>
|
166
TouchPanel.xaml
|
@ -3,69 +3,121 @@
|
|||
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"
|
||||
xmlns:local="clr-namespace:WpfMaiTouchEmulator.Managers"
|
||||
mc:Ignorable="d"
|
||||
Title="TouchPanel" Height="800" Width="800"
|
||||
Title="TouchPanel" Height="1280" Width="720"
|
||||
ResizeMode="NoResize"
|
||||
AllowsTransparency="True" WindowStyle="None" Background="Transparent"
|
||||
>
|
||||
<Window.Resources>
|
||||
<Style x:Key="DraggableHandleStyle" TargetType="Border">
|
||||
<Setter Property="Background">
|
||||
<Setter.Value>
|
||||
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
|
||||
<GradientStop Color="#FFEEEEEE" Offset="0"/>
|
||||
<GradientStop Color="#FFCCCCCC" Offset="1"/>
|
||||
</LinearGradientBrush>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Setter Property="CornerRadius" Value="10"/>
|
||||
<Setter Property="Effect">
|
||||
<Setter.Value>
|
||||
<DropShadowEffect Color="Black" BlurRadius="5" ShadowDepth="2"/>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
<Style x:Key="ResizeGripStyle" TargetType="Border">
|
||||
<Setter Property="Background">
|
||||
<Setter.Value>
|
||||
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
|
||||
<GradientStop Color="#FFCCCCCC" Offset="0"/>
|
||||
<GradientStop Color="#FFAAAAAA" Offset="1"/>
|
||||
</LinearGradientBrush>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Setter Property="CornerRadius" Value="10"/>
|
||||
<Setter Property="Effect">
|
||||
<Setter.Value>
|
||||
<DropShadowEffect Color="Black" BlurRadius="5" ShadowDepth="2"/>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</Window.Resources>
|
||||
<Border Background="#01000000">
|
||||
<StackPanel>
|
||||
<Viewbox Stretch="Uniform" Opacity="1">
|
||||
<Canvas x:Name="TouchCanvas" Width="1440" Height="1440">
|
||||
<Border x:Name="DragWindowHandle" HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||
Height="95" Background="White" MouseLeftButtonDown="DragBar_MouseLeftButtonDown"
|
||||
Cursor="SizeAll" Width="130">
|
||||
<Label FontSize="50" Content="Drag" />
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Border x:Name="DragWindowHandle"
|
||||
HorizontalAlignment="Left" VerticalAlignment="Top"
|
||||
Height="50" Width="100"
|
||||
Style="{StaticResource DraggableHandleStyle}"
|
||||
MouseLeftButtonDown="DragBar_MouseLeftButtonDown"
|
||||
Cursor="SizeAll">
|
||||
<TextBlock FontSize="24" Text="{Binding LbTouchPanelDrag}"
|
||||
VerticalAlignment="Center" HorizontalAlignment="Center" d:Text="Drag"/>
|
||||
</Border>
|
||||
<DockPanel VerticalAlignment="Bottom">
|
||||
<Viewbox Stretch="Uniform" Opacity="1">
|
||||
<Border x:Name="touchPanelBorder" BorderThickness="10"
|
||||
CornerRadius="720"
|
||||
Width="1440" VerticalAlignment="Bottom">
|
||||
<Canvas x:Name="TouchCanvas" Width="1440" Height="1440" Margin="-10,-10,-10,-10">
|
||||
|
||||
<Polygon Canvas.Left="620" Canvas.Top="6" Points="0,5 50,2 100,0 150,2 200,5 165,253 100,188 35,253" Tag="{x:Static local:TouchValue.D1}" Fill="White" />
|
||||
<Polygon Canvas.Left="786" Canvas.Top="11" Points="150,28 245,65 360,133 208,338 145,338 49,297 0,249 35,0" Tag="{x:Static local:TouchValue.A1}" Fill="White" />
|
||||
<Polygon Canvas.Left="995" Canvas.Top="144" Points="153,0 187,32 225,67 259,104 295,147 96,297 96,205 0,205" Tag="{x:Static local:TouchValue.D2}" Fill="White" />
|
||||
<Polygon Canvas.Left="1091" Canvas.Top="292" Points="261,101 303,195 339,327 91,362 42,314 0,219 0,150 202,0" Tag="{x:Static local:TouchValue.A2}" Fill="White" />
|
||||
<Polygon Canvas.Left="1182" Canvas.Top="620" Points="248,0 251,48 253,100 251,150 247,199 0,165 65,100 0,35" Tag="{x:Static local:TouchValue.D3}" Fill="White" />
|
||||
<Polygon Canvas.Left="1092" Canvas.Top="786" Points="305,150 269,246 201,364 0,213 0,144 41,48 89,0 337,34" Tag="{x:Static local:TouchValue.A3}" Fill="White" />
|
||||
<Polygon Canvas.Left="1000" Canvas.Top="1000" Points="292,151 260,187 225,225 188,259 151,291 0,92 92,92 92,0" Tag="{x:Static local:TouchValue.D4}" Fill="White" />
|
||||
<Polygon Canvas.Left="786" Canvas.Top="1092" Points="260,259 167,301 37,335 0,83 48,35 144,0 212,0 364,200" Tag="{x:Static local:TouchValue.A4}" Fill="White" />
|
||||
<Polygon Canvas.Left="621" Canvas.Top="1175" Points="199,252 151,255 99,257 49,255 0,252 34,0 99,65 164,0" Tag="{x:Static local:TouchValue.D5}" Fill="White" />
|
||||
<Polygon Canvas.Left="291" Canvas.Top="1092" Points="104,259 197,301 327,335 363,83 316,35 220,0 152,0 0,201" Tag="{x:Static local:TouchValue.A5}" Fill="White" />
|
||||
<Polygon Canvas.Left="150" Canvas.Top="1000" Points="140,292 104,260 66,225 32,188 0,151 199,0 199,92 291,92" Tag="{x:Static local:TouchValue.D6}" Fill="White" />
|
||||
<Polygon Canvas.Left="16" Canvas.Top="785" Points="32,150 68,246 133,365 333,214 333,144 296,48 248,0 0,35" Tag="{x:Static local:TouchValue.A6}" Fill="White" />
|
||||
<Polygon Canvas.Left="10" Canvas.Top="620" Points="5,199 2,151 0,99 2,49 6,0 253,34 188,99 253,164" Tag="{x:Static local:TouchValue.D7}" Fill="White" />
|
||||
<Polygon Canvas.Left="16" Canvas.Top="291" Points="78,101 36,195 0,327 248,362 297,314 333,219 333,151 132,0" Tag="{x:Static local:TouchValue.A7}" Fill="White" />
|
||||
<Polygon Canvas.Left="149" Canvas.Top="150" Points="0,140 32,104 67,66 104,32 145,0 298,199 200,199 200,291" Tag="{x:Static local:TouchValue.D8}" Fill="White" />
|
||||
<Polygon Canvas.Left="295" Canvas.Top="11" Points="210,28 115,65 0,138 153,338 215,338 311,297 359,249 324,0" Tag="{x:Static local:TouchValue.A8}" Fill="White" />
|
||||
|
||||
<Polygon Canvas.Left="607" Canvas.Top="195" Points="0,113 113,0 226,113 113,226" Tag="{x:Static local:TouchValue.E1}" Fill="White" />
|
||||
<Polygon Canvas.Left="720" Canvas.Top="346" Points="0,78 78,0 209,55 209,165 180,195 70,195 0,130" Tag="{x:Static local:TouchValue.B1}" Fill="White" />
|
||||
<Polygon Canvas.Left="930" Canvas.Top="350" Points="0,0 0,160 160,160, 160,0 0,0" Tag="{x:Static local:TouchValue.E2}" Fill="White" />
|
||||
<Polygon Canvas.Left="900" Canvas.Top="511" Points="117,209 195,132 140,0 30,0 0,30 0,139 65,209" Tag="{x:Static local:TouchValue.B2}" Fill="White" />
|
||||
<Polygon Canvas.Left="1020" Canvas.Top="607" Points="0,113 113,0 226,113 113,226" Tag="{x:Static local:TouchValue.E3}" Fill="White" />
|
||||
<Polygon Canvas.Left="900" Canvas.Top="721" Points="120,0 198,78 140,208 30,208 0,180 0,71 65,0" Tag="{x:Static local:TouchValue.B3}" Fill="White" />
|
||||
<Polygon Canvas.Left="930" Canvas.Top="930" Points="0,0 0,160 160,160, 160,0 0,0" Tag="{x:Static local:TouchValue.E4}" Fill="White" />
|
||||
<Polygon Canvas.Left="721" Canvas.Top="901" Points="0,112 87,198 208,140 208,29 177,0 71,0 0,65" Tag="{x:Static local:TouchValue.B4}" Fill="White" />
|
||||
<Polygon Canvas.Left="607" Canvas.Top="1013" Points="0,113 113,0 226,113 113,226" Tag="{x:Static local:TouchValue.E5}" Fill="White" />
|
||||
<Polygon Canvas.Left="512" Canvas.Top="901" Points="208,112 121,198 0,140 0,29 31,0 137,0 208,65" Tag="{x:Static local:TouchValue.B5}" Fill="White" />
|
||||
<Polygon Canvas.Left="350" Canvas.Top="930" Points="0,0 0,160 160,160, 160,0 0,0" Tag="{x:Static local:TouchValue.E6}" Fill="White" />
|
||||
<Polygon Canvas.Left="349" Canvas.Top="721" Points="78,0 0,78 58,208 163,208 193,180 193,71 133,0" Tag="{x:Static local:TouchValue.B6}" Fill="White" />
|
||||
<Polygon Canvas.Left="200" Canvas.Top="607" Points="0,113 113,0 226,113 113,226" Tag="{x:Static local:TouchValue.E7}" Fill="White" />
|
||||
<Polygon Canvas.Left="345" Canvas.Top="511" Points="82,209 0,127 55,0 165,0 195,30 195,139 137,209" Tag="{x:Static local:TouchValue.B7}" Fill="White" />
|
||||
<Polygon Canvas.Left="350" Canvas.Top="350" Points="0,0 0,160 160,160, 160,0 0,0" Tag="{x:Static local:TouchValue.E8}" Fill="White" />
|
||||
<Polygon Canvas.Left="511" Canvas.Top="346" Points="209,78 131,0 0,55 0,165 29,195 139,195 209,130" Tag="{x:Static local:TouchValue.B8}" Fill="White" />
|
||||
|
||||
<Polygon Canvas.Left="720" Canvas.Top="583" Points="0,0 60,0 140,80 140,200 60,280 0,280 0,0" Tag="{x:Static local:TouchValue.C1}" Fill="White" />
|
||||
<Polygon Canvas.Left="579" Canvas.Top="583" Points="141,280 81,280 0,199 1,81 81,0 141,0 141,280" Tag="{x:Static local:TouchValue.C2}" Fill="White" />
|
||||
|
||||
|
||||
<Border x:Name="ResizeGrip" Width="150" Height="90"
|
||||
Style="{StaticResource ResizeGripStyle}"
|
||||
MouseDown="ResizeGrip_MouseDown"
|
||||
Canvas.Left="1290" Canvas.Top="1350"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top">
|
||||
<TextBlock FontSize="50" Text="{Binding LbTouchPanelResize}"
|
||||
VerticalAlignment="Center" HorizontalAlignment="Center" d:Text="Resize"/>
|
||||
</Border>
|
||||
|
||||
</Canvas>
|
||||
</Border>
|
||||
<Polygon Canvas.Left="699" Canvas.Top="6" Points="0,0 39,0 111,5 113,6 111,24 80,243 77,243 63,229 56,221 23,188 16,194 -34,244 -36,244 -70,4 -70,3 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.D1}" Fill="White" />
|
||||
<Polygon Canvas.Left="825" Canvas.Top="13" Points="0,0 10,1 95,19 145,37 179,50 207,64 230,75 254,87 297,116 318,130 316,135 300,156 286,175 270,196 256,215 240,236 226,255 210,276 197,294 181,315 168,333 101,333 66,318 21,299 9,293 -35,249 -34,237 -1,4 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.A1}" Fill="White" />
|
||||
<Polygon Canvas.Left="1156" Canvas.Top="154" Points="0,0 8,6 21,18 32,27 45,39 56,48 69,60 77,67 86,77 93,85 105,99 116,111 125,122 130,128 118,138 102,150 85,163 68,176 47,192 30,205 13,218 -8,234 -25,247 -42,260 -62,275 -63,275 -63,255 -62,207 -61,193 -143,193 -141,189 -127,170 -111,149 -97,130 -81,109 -68,91 -52,70 -38,51 -22,30 -8,11 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.D2}" Fill="White" />
|
||||
<Polygon Canvas.Left="1295" Canvas.Top="294" Points="0,0 4,5 21,31 34,51 44,69 89,159 106,213 123,268 132,318 132,320 -116,354 -120,352 -164,308 -179,271 -195,232 -201,217 -201,151 -190,142 -171,128 -150,112 -131,98 -110,82 -91,68 -70,52 -51,38 -30,22 -11,8 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.A2}" Fill="White" />
|
||||
<Polygon Canvas.Left="1427" Canvas.Top="628" Points="0,0 3,0 5,30 8,90 7,116 4,174 3,183 -15,181 -235,150 -235,147 -216,128 -208,121 -182,95 -179,92 -187,85 -237,35 -237,34 -13,2 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.D3}" Fill="White" />
|
||||
<Polygon Canvas.Left="1176" Canvas.Top="791" Points="0,0 13,1 247,33 251,34 250,43 238,100 223,144 208,187 195,224 182,248 169,271 159,290 146,313 136,329 121,351 119,352 101,339 80,323 61,309 40,293 21,279 0,263 -19,249 -40,233 -59,219 -80,203 -82,202 -82,136 -67,99 -45,44 -38,37 -30,30" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.A3}" Fill="White" />
|
||||
<Polygon Canvas.Left="1094" Canvas.Top="1010" Points="0,0 4,2 20,14 33,24 54,40 75,56 95,71 113,85 129,97 146,110 167,126 188,142 193,146 191,150 179,163 168,175 159,185 147,198 136,210 132,215 124,222 111,234 99,245 87,256 77,265 67,274 63,272 51,256 41,243 28,226 18,213 5,196 -8,179 -18,166 -31,149 -41,136 -54,119 -67,102 -77,89 -81,83 1,83" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.D4}" Fill="White" />
|
||||
<Polygon Canvas.Left="927" Canvas.Top="1093" Points="0,0 67,0 81,18 95,37 111,58 126,78 142,99 154,115 170,136 184,155 194,168 210,189 219,201 214,205 189,221 172,232 150,246 136,254 108,268 85,279 72,285 10,307 -7,313 -98,333 -101,333 -103,324 -135,88 -135,82 -128,75 -121,67 -92,38 -56,23 -15,6" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.A4}" Fill="White" />
|
||||
<Polygon Canvas.Left="664" Canvas.Top="1190" Points="0,0 7,6 18,17 26,24 44,42 52,49 58,54 90,22 98,15 113,0 115,1 148,234 148,238 146,239 66,244 54,244 -35,238 -10,63 -1,1" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.D5}" Fill="White" />
|
||||
<Polygon Canvas.Left="448" Canvas.Top="1092" Points="0,0 66,0 112,19 156,37 164,44 202,82 197,121 168,331 167,334 153,332 106,323 1,288 -97,239 -135,214 -152,203 -151,199 -135,178 -120,158 -104,137 -88,116 -79,104 -63,83 -51,67 -35,46 -23,30 -7,9 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.A5}" Fill="White" />
|
||||
<Polygon Canvas.Left="347" Canvas.Top="1013" Points="0,0 2,0 2,74 1,80 46,79 84,79 82,83 69,100 56,117 43,134 30,151 17,168 4,185 -9,202 -22,219 -35,236 -48,253 -61,270 -64,270 -77,258 -85,251 -99,239 -111,228 -122,219 -135,207 -144,196 -156,183 -165,172 -177,159 -186,148 -191,142 -172,128 -153,114 -132,98 -118,88 -97,72 -79,59 -58,43 -39,29 -20,15 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.D6}" Fill="White" />
|
||||
<Polygon Canvas.Left="257" Canvas.Top="791" Points="0,0 9,0 52,43 65,73 83,116 91,135 91,202 73,216 54,230 36,244 17,258 -1,272 -20,286 -33,296 -54,312 -73,326 -91,340 -109,353 -111,353 -123,334 -135,316 -148,296 -182,228 -192,209 -201,190 -228,103 -233,85 -241,39 -241,34 -240,33 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.A6}" Fill="White" />
|
||||
<Polygon Canvas.Left="13" Canvas.Top="627" Points="0,0 24,3 238,33 232,40 223,50 203,70 196,78 183,91 185,95 240,150 240,151 139,165 7,183 0,183 -7,89 -1,1 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.D7}" Fill="White" />
|
||||
<Polygon Canvas.Left="145" Canvas.Top="295" Points="0,0 5,2 26,18 42,30 63,46 82,60 103,76 122,90 140,104 159,118 180,134 199,148 203,151 203,193 202,220 180,274 165,311 154,322 146,329 122,353 108,352 -130,320 -131,318 -123,274 -96,187 -87,157 -66,115 -55,92 -44,70 -30,48 -14,22 -2,3 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.A7}" Fill="White" />
|
||||
<Polygon Canvas.Left="283" Canvas.Top="155" Points="0,0 5,5 17,20 29,36 42,53 58,74 74,95 90,116 106,137 119,154 135,175 146,190 146,191 65,191 66,256 66,275 58,269 46,260 29,247 12,234 -5,221 -22,208 -39,195 -56,182 -73,169 -90,156 -107,143 -124,130 -128,126 -119,117 -112,109 -101,97 -94,89 -82,76 -75,68 -64,56 -52,45 -41,36 -29,25 -18,16 -5,4 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.D8}" Fill="White" />
|
||||
<Polygon Canvas.Left="613" Canvas.Top="13" Points="0,0 3,0 10,48 38,247 37,252 24,265 16,272 -8,296 -100,333 -165,333 -179,315 -192,298 -205,281 -218,264 -231,247 -244,230 -257,213 -270,196 -283,179 -296,162 -309,145 -317,134 -316,131 -300,121 -285,111 -265,98 -249,88 -165,46 -72,15 -9,2 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.A8}" Fill="White" />
|
||||
</Viewbox>
|
||||
</DockPanel>
|
||||
|
||||
<Polygon Canvas.Left="720" Canvas.Top="215" Points="0,0 4,2 48,46 56,53 97,94 91,101 2,190 -2,188 -10,181 -54,137 -62,130 -96,96 -94,92 -73,71 -65,64 -27,26 -19,19 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.E1}" Fill="White" />
|
||||
<Polygon Canvas.Left="801" Canvas.Top="347" Points="0,0 25,10 61,25 107,44 129,53 130,54 129,88 126,158 112,171 104,178 91,190 88,192 59,192 -7,191 -12,188 -23,177 -30,169 -38,161 -45,153 -53,145 -60,137 -69,128 -73,123 -73,105 -72,71 -33,32 -25,25 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.B1}" Fill="White" />
|
||||
<Polygon Canvas.Left="1070" Canvas.Top="361" Points="0,0 8,0 8,137 -127,137 -128,57 -128,1 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.E2}" Fill="White" />
|
||||
<Polygon Canvas.Left="938" Canvas.Top="513" Points="0,0 103,0 113,23 130,64 150,112 156,126 154,130 141,142 112,171 104,178 83,199 31,199 -19,149 -26,141 -36,131 -37,57 -37,35 -30,28 -22,21 -11,10 -3,3 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.B2}" Fill="White" />
|
||||
<Polygon Canvas.Left="1130" Canvas.Top="623" Points="0,0 4,2 45,43 53,50 97,94 91,101 2,190 -2,188 -10,181 -55,136 -63,129 -96,96 -94,92 -74,72 -66,65 -28,27 -20,20 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.E3}" Fill="White" />
|
||||
<Polygon Canvas.Left="968" Canvas.Top="726" Points="0,0 20,0 53,1 109,57 117,64 126,73 123,82 105,125 87,168 74,199 73,200 -31,200 -67,164 -67,123 -66,68 -51,53 -44,45 -5,6 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.B3}" Fill="White" />
|
||||
<Polygon Canvas.Left="1053" Canvas.Top="939" Points="0,0 25,0 25,137 -110,137 -111,57 -111,1 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.E4}" Fill="White" />
|
||||
<Polygon Canvas.Left="794" Canvas.Top="900" Points="0,0 97,0 133,36 134,68 134,138 124,143 88,158 48,175 10,191 6,190 -3,181 -11,174 -65,120 -66,112 -67,68 -4,5 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.B4}" Fill="White" />
|
||||
<Polygon Canvas.Left="720" Canvas.Top="1034" Points="0,0 4,2 97,95 91,102 2,191 -2,189 -35,156 -43,149 -87,105 -95,98 -97,95 -90,88 -82,81 -44,43 -36,36 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.E5}" Fill="White" />
|
||||
<Polygon Canvas.Left="550" Canvas.Top="899" Points="0,0 97,1 143,47 150,55 163,68 164,121 92,193 83,190 37,171 -4,154 -37,140 -37,101 -36,37 -24,25 -17,17 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.B5}" Fill="White" />
|
||||
<Polygon Canvas.Left="474" Canvas.Top="939" Points="0,0 25,0 25,137 -110,137 -111,53 -111,1 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.E6}" Fill="White" />
|
||||
<Polygon Canvas.Left="420" Canvas.Top="727" Points="0,0 52,0 119,67 119,162 109,172 102,180 82,200 -20,200 -38,158 -50,129 -68,86 -73,73 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.B6}" Fill="White" />
|
||||
<Polygon Canvas.Left="311" Canvas.Top="623" Points="0,0 4,2 61,59 69,66 97,94 91,101 2,190 -2,189 -51,140 -59,133 -96,96 -94,92 -71,69 -63,62 -25,24 -17,17 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.E7}" Fill="White" />
|
||||
<Polygon Canvas.Left="401" Canvas.Top="512" Points="0,0 102,0 124,22 132,29 140,37 140,69 139,130 133,138 101,170 94,178 72,200 20,201 -53,128 -50,119 -31,74 -12,29 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.B7}" Fill="White" />
|
||||
<Polygon Canvas.Left="491" Canvas.Top="361" Points="0,0 8,0 8,137 -127,137 -128,53 -128,1 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.E8}" Fill="White" />
|
||||
<Polygon Canvas.Left="640" Canvas.Top="348" Points="0,0 8,6 74,72 73,124 45,152 38,160 17,181 10,189 8,191 -90,191 -127,154 -126,50 -88,35 -20,8 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.B8}" Fill="White" />
|
||||
|
||||
<Polygon Canvas.Left="728" Canvas.Top="583" Points="0,0 51,0 65,14 72,22 129,79 129,193 100,222 93,230 65,258 58,266 50,274 10,273 0,272 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.C1}" Fill="White" />
|
||||
<Polygon Canvas.Left="662" Canvas.Top="583" Points="0,0 52,0 52,267 51,273 2,273 -78,193 -78,80 -47,49 -40,41 -5,6 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.C2}" Fill="White" />
|
||||
<Polygon Canvas.Left="714" Canvas.Top="583" Points="0,0 14,0 14,273 0,273 0,0" PreviewTouchDown="Element_TouchDown" PreviewTouchMove="Element_TouchMove" PreviewTouchUp="Element_TouchUp" Tag="{x:Static local:TouchValue.C3}" Fill="White" />
|
||||
|
||||
|
||||
|
||||
<Border x:Name="ResizeGrip"
|
||||
Width="150" Height="90" Background="White"
|
||||
MouseDown="ResizeGrip_MouseDown" Canvas.Left="1290" Canvas.Top="1350" HorizontalAlignment="Center" VerticalAlignment="Top">
|
||||
<Label FontSize="50" Content="Resize" />
|
||||
</Border>
|
||||
|
||||
</Canvas>
|
||||
</Viewbox>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
</Border>
|
||||
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
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 WpfMaiTouchEmulator.Managers;
|
||||
|
||||
namespace WpfMaiTouchEmulator;
|
||||
/// <summary>
|
||||
|
@ -12,11 +16,14 @@ public partial class TouchPanel : Window
|
|||
{
|
||||
internal Action<TouchValue>? onTouch;
|
||||
internal Action<TouchValue>? onRelease;
|
||||
internal Action? onInitialReposition;
|
||||
|
||||
private readonly Dictionary<int, Polygon> activeTouches = [];
|
||||
private readonly Dictionary<int, (Polygon polygon, Point lastPoint)> activeTouches = new();
|
||||
private readonly TouchPanelPositionManager _positionManager;
|
||||
private List<Polygon> buttons = [];
|
||||
private bool isDebugEnabled = Properties.Settings.Default.IsDebugEnabled;
|
||||
private bool isRingButtonEmulationEnabled = Properties.Settings.Default.IsRingButtonEmulationEnabled;
|
||||
private bool hasRepositioned = false;
|
||||
|
||||
private enum ResizeDirection
|
||||
{
|
||||
|
@ -30,35 +37,100 @@ public partial class TouchPanel : Window
|
|||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
private static extern int SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct RECT
|
||||
{
|
||||
public int Left;
|
||||
public int Top;
|
||||
public int Right;
|
||||
public int Bottom;
|
||||
}
|
||||
|
||||
public enum SizingEdge
|
||||
{
|
||||
Left = 1,
|
||||
Right = 2,
|
||||
Top = 3,
|
||||
TopLeft = 4,
|
||||
TopRight = 5,
|
||||
Bottom = 6,
|
||||
BottomLeft = 7,
|
||||
BottomRight = 8
|
||||
}
|
||||
|
||||
private const double FixedAspectRatio = 720.0 / 1280.0; // width / height
|
||||
private const int MinWidth = 180;
|
||||
private const int MinHeight = 320;
|
||||
|
||||
public TouchPanel()
|
||||
{
|
||||
InitializeComponent();
|
||||
Topmost = true;
|
||||
_positionManager = new TouchPanelPositionManager();
|
||||
Loaded += Window_Loaded;
|
||||
|
||||
StateCheckLoop();
|
||||
Touch.FrameReported += OnTouchFrameReported;
|
||||
}
|
||||
|
||||
private async void StateCheckLoop()
|
||||
|
||||
protected override void OnSourceInitialized(EventArgs e)
|
||||
{
|
||||
while (true)
|
||||
base.OnSourceInitialized(e);
|
||||
var source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
|
||||
source.AddHook(WndProc);
|
||||
}
|
||||
|
||||
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
|
||||
{
|
||||
const int WM_SIZING = 0x0214;
|
||||
if (msg == WM_SIZING)
|
||||
{
|
||||
if (activeTouches.Count != 0 && !TouchesOver.Any())
|
||||
{
|
||||
await Task.Delay(100);
|
||||
if (activeTouches.Count != 0 && !TouchesOver.Any())
|
||||
{
|
||||
DeselectAllItems();
|
||||
}
|
||||
}
|
||||
await Task.Delay(100);
|
||||
var rect = Marshal.PtrToStructure<RECT>(lParam);
|
||||
var edge = (SizingEdge)wParam.ToInt32();
|
||||
EnforceAspectRatio(ref rect, edge);
|
||||
Marshal.StructureToPtr(rect, lParam, true);
|
||||
handled = true;
|
||||
}
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
private void EnforceAspectRatio(ref RECT rect, SizingEdge edge)
|
||||
{
|
||||
var currentWidth = rect.Right - rect.Left;
|
||||
var currentHeight = rect.Bottom - rect.Top;
|
||||
int newWidth, newHeight;
|
||||
|
||||
if (edge == SizingEdge.BottomRight)
|
||||
{
|
||||
newWidth = (int)(currentHeight * FixedAspectRatio);
|
||||
newHeight = currentHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
newHeight = (int)(currentWidth / FixedAspectRatio);
|
||||
newWidth = currentWidth;
|
||||
}
|
||||
|
||||
// Enforce minimum size while keeping the aspect ratio.
|
||||
if (newWidth < MinWidth)
|
||||
{
|
||||
newWidth = MinWidth;
|
||||
newHeight = (int)(newWidth / FixedAspectRatio);
|
||||
}
|
||||
if (newHeight < MinHeight)
|
||||
{
|
||||
newHeight = MinHeight;
|
||||
newWidth = (int)(newHeight * FixedAspectRatio);
|
||||
}
|
||||
|
||||
rect.Right = rect.Left + newWidth;
|
||||
rect.Bottom = rect.Top + newHeight;
|
||||
}
|
||||
|
||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
buttons = VisualTreeHelperExtensions.FindVisualChildren<Polygon>(this);
|
||||
DeselectAllItems();
|
||||
}
|
||||
|
||||
public void PositionTouchPanel()
|
||||
|
@ -73,6 +145,12 @@ public partial class TouchPanel : Window
|
|||
Left = position.Value.Left;
|
||||
Width = position.Value.Width;
|
||||
Height = position.Value.Height;
|
||||
|
||||
if (!hasRepositioned)
|
||||
{
|
||||
hasRepositioned = true;
|
||||
onInitialReposition?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,74 +164,111 @@ public partial class TouchPanel : Window
|
|||
{
|
||||
if (e.LeftButton == MouseButtonState.Pressed)
|
||||
{
|
||||
ResizeWindow(ResizeDirection.BottomRight);
|
||||
ResizeWindow(SizingEdge.BottomRight);
|
||||
}
|
||||
}
|
||||
|
||||
private void ResizeWindow(ResizeDirection direction)
|
||||
private void ResizeWindow(SizingEdge edge)
|
||||
{
|
||||
ReleaseCapture();
|
||||
SendMessage(new System.Windows.Interop.WindowInteropHelper(this).Handle,
|
||||
0x112, // WM_SYSCOMMAND message
|
||||
(IntPtr)(0xF000 + direction),
|
||||
IntPtr.Zero);
|
||||
SendMessage(new WindowInteropHelper(this).Handle, 0x112, (IntPtr)(0xF000 + (int)edge), IntPtr.Zero);
|
||||
}
|
||||
|
||||
private void Element_TouchDown(object sender, TouchEventArgs e)
|
||||
private void OnTouchFrameReported(object sender, TouchFrameEventArgs e)
|
||||
{
|
||||
// Cast the sender to a Border to ensure it's the correct element type.
|
||||
if (sender is Polygon element)
|
||||
{
|
||||
// Highlight the element and add it to the active touches tracking.
|
||||
HighlightElement(element, true);
|
||||
onTouch?.Invoke((TouchValue)element.Tag);
|
||||
activeTouches[e.TouchDevice.Id] = element;
|
||||
}
|
||||
e.Handled = true;
|
||||
}
|
||||
var currentTouchPoints = e.GetTouchPoints(this);
|
||||
var currentIds = new HashSet<int>();
|
||||
|
||||
private void Element_TouchMove(object sender, TouchEventArgs e)
|
||||
{
|
||||
// Attempt to find the element under the current touch point.
|
||||
var touchPoint = e.GetTouchPoint(this).Position;
|
||||
var hitTestResult = VisualTreeHelper.HitTest(this, touchPoint);
|
||||
if (hitTestResult != null && hitTestResult.VisualHit is Polygon newElement)
|
||||
foreach (var touch in currentTouchPoints)
|
||||
{
|
||||
// If this touch point is already tracking another element, unhighlight the previous one.
|
||||
if (activeTouches.TryGetValue(e.TouchDevice.Id, out var previousElement) && previousElement != newElement)
|
||||
var id = touch.TouchDevice.Id;
|
||||
|
||||
// If the touch is released, process it as a TouchUp.
|
||||
if (touch.Action == TouchAction.Up)
|
||||
{
|
||||
Task.Delay(50)
|
||||
.ContinueWith(t =>
|
||||
if (activeTouches.TryGetValue(id, out var touchInfo2))
|
||||
{
|
||||
if (activeTouches.Values.Count(v => v.polygon == touchInfo2.polygon) == 1)
|
||||
{
|
||||
HighlightElement(previousElement, false);
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
HighlightElement(touchInfo2.polygon, false);
|
||||
onRelease?.Invoke((TouchValue)touchInfo2.polygon.Tag);
|
||||
if (isRingButtonEmulationEnabled)
|
||||
{
|
||||
onRelease?.Invoke((TouchValue)previousElement.Tag);
|
||||
});
|
||||
});
|
||||
|
||||
RingButtonEmulator.ReleaseButton((TouchValue)touchInfo2.polygon.Tag);
|
||||
}
|
||||
}
|
||||
activeTouches.Remove(id);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Highlight the new element and update the tracking.
|
||||
HighlightElement(newElement, true);
|
||||
onTouch?.Invoke((TouchValue)newElement.Tag);
|
||||
activeTouches[e.TouchDevice.Id] = newElement;
|
||||
currentIds.Add(id);
|
||||
|
||||
// New touch (TouchDown)
|
||||
if (!activeTouches.TryGetValue(id, out var touchInfo))
|
||||
{
|
||||
if (VisualTreeHelper.HitTest(this, touch.Position)?.VisualHit is Polygon polygon)
|
||||
{
|
||||
HighlightElement(polygon, true);
|
||||
activeTouches[id] = (polygon, touch.Position);
|
||||
onTouch?.Invoke((TouchValue)polygon.Tag);
|
||||
if (isRingButtonEmulationEnabled && RingButtonEmulator.HasRingButtonMapping((TouchValue)polygon.Tag))
|
||||
{
|
||||
RingButtonEmulator.PressButton((TouchValue)polygon.Tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Existing touch (TouchMove)
|
||||
else
|
||||
{
|
||||
var previousPosition = touchInfo.lastPoint;
|
||||
var currentPosition = touch.Position;
|
||||
var sampleCount = 10;
|
||||
var changed = false;
|
||||
|
||||
for (var i = 1; i <= sampleCount; i++)
|
||||
{
|
||||
var t = (double)i / sampleCount;
|
||||
var samplePoint = new Point(
|
||||
previousPosition.X + (currentPosition.X - previousPosition.X) * t,
|
||||
previousPosition.Y + (currentPosition.Y - previousPosition.Y) * t);
|
||||
if (VisualTreeHelper.HitTest(this, samplePoint)?.VisualHit is Polygon polygon && polygon != touchInfo.polygon)
|
||||
{
|
||||
if (activeTouches.Values.Count(v => v.polygon == touchInfo.polygon) == 1)
|
||||
{
|
||||
HighlightElement(touchInfo.polygon, false);
|
||||
onRelease?.Invoke((TouchValue)touchInfo.polygon.Tag);
|
||||
}
|
||||
HighlightElement(polygon, true);
|
||||
onTouch?.Invoke((TouchValue)polygon.Tag);
|
||||
activeTouches[id] = (polygon, samplePoint);
|
||||
changed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!changed)
|
||||
{
|
||||
activeTouches[id] = (touchInfo.polygon, currentPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void Element_TouchUp(object sender, TouchEventArgs e)
|
||||
{
|
||||
// When touch is lifted, unhighlight the associated element and remove it from tracking.
|
||||
if (activeTouches.TryGetValue(e.TouchDevice.Id, out var element))
|
||||
// Process any touches that might not be reported this frame.
|
||||
var endedTouches = activeTouches.Keys.Except(currentIds).ToList();
|
||||
foreach (var id in endedTouches)
|
||||
{
|
||||
HighlightElement(element, false);
|
||||
onRelease?.Invoke((TouchValue)element.Tag);
|
||||
activeTouches.Remove(e.TouchDevice.Id);
|
||||
var touchInfo = activeTouches[id];
|
||||
if (activeTouches.Values.Count(v => v.polygon == touchInfo.polygon) == 1)
|
||||
{
|
||||
HighlightElement(touchInfo.polygon, false);
|
||||
onRelease?.Invoke((TouchValue)touchInfo.polygon.Tag);
|
||||
if (isRingButtonEmulationEnabled)
|
||||
{
|
||||
RingButtonEmulator.ReleaseButton((TouchValue)touchInfo.polygon.Tag);
|
||||
}
|
||||
}
|
||||
activeTouches.Remove(id);
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void DeselectAllItems()
|
||||
|
@ -161,10 +276,11 @@ public partial class TouchPanel : Window
|
|||
// Logic to deselect all items or the last touched item
|
||||
foreach (var element in activeTouches.Values)
|
||||
{
|
||||
HighlightElement(element, false);
|
||||
onRelease?.Invoke((TouchValue)element.Tag);
|
||||
HighlightElement(element.polygon, false);
|
||||
onRelease?.Invoke((TouchValue)element.polygon.Tag);
|
||||
}
|
||||
activeTouches.Clear();
|
||||
RingButtonEmulator.ReleaseAllButtons();
|
||||
}
|
||||
|
||||
public void SetDebugMode(bool enabled)
|
||||
|
@ -176,6 +292,434 @@ public partial class TouchPanel : Window
|
|||
});
|
||||
}
|
||||
|
||||
public void SetLargeButtonMode(bool enabled)
|
||||
{
|
||||
TouchValue[] ringButtonsValues = {
|
||||
TouchValue.A1,
|
||||
TouchValue.A2,
|
||||
TouchValue.A3,
|
||||
TouchValue.A4,
|
||||
TouchValue.A5,
|
||||
TouchValue.A6,
|
||||
TouchValue.A7,
|
||||
TouchValue.A8,
|
||||
TouchValue.D1,
|
||||
TouchValue.D2,
|
||||
TouchValue.D3,
|
||||
TouchValue.D4,
|
||||
TouchValue.D5,
|
||||
TouchValue.D6,
|
||||
TouchValue.D7,
|
||||
TouchValue.D8,
|
||||
};
|
||||
|
||||
var a1 = buttons.First(button => (TouchValue)button.Tag == TouchValue.A1);
|
||||
var a2 = buttons.First(button => (TouchValue)button.Tag == TouchValue.A2);
|
||||
var a3 = buttons.First(button => (TouchValue)button.Tag == TouchValue.A3);
|
||||
var a4 = buttons.First(button => (TouchValue)button.Tag == TouchValue.A4);
|
||||
var a5 = buttons.First(button => (TouchValue)button.Tag == TouchValue.A5);
|
||||
var a6 = buttons.First(button => (TouchValue)button.Tag == TouchValue.A6);
|
||||
var a7 = buttons.First(button => (TouchValue)button.Tag == TouchValue.A7);
|
||||
var a8 = buttons.First(button => (TouchValue)button.Tag == TouchValue.A8);
|
||||
var d1 = buttons.First(button => (TouchValue)button.Tag == TouchValue.D1);
|
||||
var d2 = buttons.First(button => (TouchValue)button.Tag == TouchValue.D2);
|
||||
var d3 = buttons.First(button => (TouchValue)button.Tag == TouchValue.D3);
|
||||
var d4 = buttons.First(button => (TouchValue)button.Tag == TouchValue.D4);
|
||||
var d5 = buttons.First(button => (TouchValue)button.Tag == TouchValue.D5);
|
||||
var d6 = buttons.First(button => (TouchValue)button.Tag == TouchValue.D6);
|
||||
var d7 = buttons.First(button => (TouchValue)button.Tag == TouchValue.D7);
|
||||
var d8 = buttons.First(button => (TouchValue)button.Tag == TouchValue.D8);
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
d1.Points = new PointCollection
|
||||
{
|
||||
new Point(-5, -50),
|
||||
new Point(205, -50),
|
||||
new Point(165, 253),
|
||||
new Point(100, 188),
|
||||
new Point(35, 253),
|
||||
};
|
||||
|
||||
a1.Points = new PointCollection
|
||||
{
|
||||
new Point(495, -50),
|
||||
new Point(208, 338),
|
||||
new Point(145, 338),
|
||||
new Point(49, 297),
|
||||
new Point(0, 249),
|
||||
new Point(42, -55),
|
||||
};
|
||||
d2.Points = new PointCollection
|
||||
{
|
||||
new Point(290, -182),
|
||||
new Point(500, -180),
|
||||
new Point(500, -5),
|
||||
new Point(96, 297),
|
||||
new Point(96, 205),
|
||||
new Point(0, 205),
|
||||
};
|
||||
a2.Points = new PointCollection
|
||||
{
|
||||
new Point(405, 317),
|
||||
new Point(91, 362),
|
||||
new Point(42, 314),
|
||||
new Point(0, 219),
|
||||
new Point(0, 150),
|
||||
new Point(405, -150),
|
||||
};
|
||||
d3.Points = new PointCollection
|
||||
{
|
||||
new Point(315, -10),
|
||||
new Point(315, 208),
|
||||
new Point(0, 165),
|
||||
new Point(65, 100),
|
||||
new Point(0, 35),
|
||||
};
|
||||
a3.Points = new PointCollection
|
||||
{
|
||||
new Point(406, 520),
|
||||
new Point(0, 213),
|
||||
new Point(0, 144),
|
||||
new Point(41, 48),
|
||||
new Point(89, 0),
|
||||
new Point(406, 43),
|
||||
};
|
||||
d4.Points = new PointCollection
|
||||
{
|
||||
new Point(500, 309),
|
||||
new Point(500, 491),
|
||||
new Point(305, 491),
|
||||
new Point(0, 92),
|
||||
new Point(92, 92),
|
||||
new Point(92, 0),
|
||||
};
|
||||
a4.Points = new PointCollection
|
||||
{
|
||||
new Point(45, 400),
|
||||
new Point(0, 83),
|
||||
new Point(48, 35),
|
||||
new Point(144, 0),
|
||||
new Point(212, 0),
|
||||
new Point(515, 400),
|
||||
};
|
||||
d5.Points = new PointCollection
|
||||
{
|
||||
new Point(208, 317),
|
||||
new Point(-10, 317),
|
||||
new Point(34, 0),
|
||||
new Point(99, 65),
|
||||
new Point(164, 0),
|
||||
};
|
||||
|
||||
a5.Points = new PointCollection
|
||||
{
|
||||
new Point(317, 400),
|
||||
new Point(363, 83),
|
||||
new Point(316, 35),
|
||||
new Point(220, 0),
|
||||
new Point(152, 0),
|
||||
new Point(-150, 400),
|
||||
};
|
||||
d6.Points = new PointCollection
|
||||
{
|
||||
new Point(-10, 492),
|
||||
new Point(-200, 492),
|
||||
new Point(-200, 295),
|
||||
new Point(199, 0),
|
||||
new Point(199, 92),
|
||||
new Point(291, 92),
|
||||
};
|
||||
a6.Points = new PointCollection
|
||||
{
|
||||
new Point(-67, 505),
|
||||
new Point(333, 214),
|
||||
new Point(333, 144),
|
||||
new Point(296, 48),
|
||||
new Point(248, 0),
|
||||
new Point(-67, 45),
|
||||
};
|
||||
|
||||
d7.Points = new PointCollection
|
||||
{
|
||||
new Point(-60, 207),
|
||||
new Point(-60, -7),
|
||||
new Point(253, 34),
|
||||
new Point(188, 99),
|
||||
new Point(253, 164),
|
||||
};
|
||||
|
||||
a7.Points = new PointCollection
|
||||
{
|
||||
new Point(-65, 320),
|
||||
new Point(248, 362),
|
||||
new Point(297, 314),
|
||||
new Point(333, 219),
|
||||
new Point(333, 151),
|
||||
new Point(-65, -150),
|
||||
};
|
||||
d8.Points = new PointCollection
|
||||
{
|
||||
new Point(-195, -10),
|
||||
new Point(-195, -195),
|
||||
new Point(-5, -195),
|
||||
new Point(298, 199),
|
||||
new Point(200, 199),
|
||||
new Point(200, 291),
|
||||
};
|
||||
|
||||
a8.Points = new PointCollection
|
||||
{
|
||||
new Point(-148, -55),
|
||||
new Point(153, 338),
|
||||
new Point(215, 338),
|
||||
new Point(311, 297),
|
||||
new Point(359, 249),
|
||||
new Point(318, -55),
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
d1.Points = new PointCollection
|
||||
{
|
||||
new Point(0, 5),
|
||||
new Point(50, 2),
|
||||
new Point(100, 0),
|
||||
new Point(150, 2),
|
||||
new Point(200, 5),
|
||||
new Point(165, 253),
|
||||
new Point(100, 188),
|
||||
new Point(35, 253),
|
||||
};
|
||||
|
||||
a1.Points = new PointCollection
|
||||
{
|
||||
new Point(150, 28),
|
||||
new Point(245, 65),
|
||||
new Point(360, 133),
|
||||
new Point(208, 338),
|
||||
new Point(145, 338),
|
||||
new Point(49, 297),
|
||||
new Point(0, 249),
|
||||
new Point(35, 0),
|
||||
};
|
||||
|
||||
d2.Points = new PointCollection
|
||||
{
|
||||
new Point(153, 0),
|
||||
new Point(187, 32),
|
||||
new Point(225, 67),
|
||||
new Point(259, 104),
|
||||
new Point(295, 147),
|
||||
new Point(96, 297),
|
||||
new Point(96, 205),
|
||||
new Point(0, 205),
|
||||
};
|
||||
|
||||
a2.Points = new PointCollection
|
||||
{
|
||||
new Point(261, 101),
|
||||
new Point(303, 195),
|
||||
new Point(339, 327),
|
||||
new Point(91, 362),
|
||||
new Point(42, 314),
|
||||
new Point(0, 219),
|
||||
new Point(0, 150),
|
||||
new Point(202, 0),
|
||||
};
|
||||
|
||||
d3.Points = new PointCollection
|
||||
{
|
||||
new Point(248, 0),
|
||||
new Point(251, 48),
|
||||
new Point(253, 100),
|
||||
new Point(251, 150),
|
||||
new Point(247, 199),
|
||||
new Point(0, 165),
|
||||
new Point(65, 100),
|
||||
new Point(0, 35),
|
||||
};
|
||||
|
||||
a3.Points = new PointCollection
|
||||
{
|
||||
new Point(305, 150),
|
||||
new Point(269, 246),
|
||||
new Point(201, 364),
|
||||
new Point(0, 213),
|
||||
new Point(0, 144),
|
||||
new Point(41, 48),
|
||||
new Point(89, 0),
|
||||
new Point(337, 34),
|
||||
};
|
||||
|
||||
d4.Points = new PointCollection
|
||||
{
|
||||
new Point(292, 151),
|
||||
new Point(260, 187),
|
||||
new Point(225, 225),
|
||||
new Point(188, 259),
|
||||
new Point(151, 291),
|
||||
new Point(0, 92),
|
||||
new Point(92, 92),
|
||||
new Point(92, 0),
|
||||
};
|
||||
|
||||
a4.Points = new PointCollection
|
||||
{
|
||||
new Point(260, 259),
|
||||
new Point(167, 301),
|
||||
new Point(37, 335),
|
||||
new Point(0, 83),
|
||||
new Point(48, 35),
|
||||
new Point(144, 0),
|
||||
new Point(212, 0),
|
||||
new Point(364, 200),
|
||||
};
|
||||
|
||||
d5.Points = new PointCollection
|
||||
{
|
||||
new Point(199, 252),
|
||||
new Point(151, 255),
|
||||
new Point(99, 257),
|
||||
new Point(49, 255),
|
||||
new Point(0, 252),
|
||||
new Point(34, 0),
|
||||
new Point(99, 65),
|
||||
new Point(164, 0),
|
||||
};
|
||||
|
||||
a5.Points = new PointCollection
|
||||
{
|
||||
new Point(104, 259),
|
||||
new Point(197, 301),
|
||||
new Point(327, 335),
|
||||
new Point(363, 83),
|
||||
new Point(316, 35),
|
||||
new Point(220, 0),
|
||||
new Point(152, 0),
|
||||
new Point(0, 201),
|
||||
};
|
||||
|
||||
d6.Points = new PointCollection
|
||||
{
|
||||
new Point(140, 292),
|
||||
new Point(104, 260),
|
||||
new Point(66, 225),
|
||||
new Point(32, 188),
|
||||
new Point(0, 151),
|
||||
new Point(199, 0),
|
||||
new Point(199, 92),
|
||||
new Point(291, 92),
|
||||
};
|
||||
|
||||
a6.Points = new PointCollection
|
||||
{
|
||||
new Point(32, 150),
|
||||
new Point(68, 246),
|
||||
new Point(133, 365),
|
||||
new Point(333, 214),
|
||||
new Point(333, 144),
|
||||
new Point(296, 48),
|
||||
new Point(248, 0),
|
||||
new Point(0, 35),
|
||||
};
|
||||
|
||||
d7.Points = new PointCollection
|
||||
{
|
||||
new Point(5, 199),
|
||||
new Point(2, 151),
|
||||
new Point(0, 99),
|
||||
new Point(2, 49),
|
||||
new Point(6, 0),
|
||||
new Point(253, 34),
|
||||
new Point(188, 99),
|
||||
new Point(253, 164),
|
||||
};
|
||||
|
||||
a7.Points = new PointCollection
|
||||
{
|
||||
new Point(78, 101),
|
||||
new Point(36, 195),
|
||||
new Point(0, 327),
|
||||
new Point(248, 362),
|
||||
new Point(297, 314),
|
||||
new Point(333, 219),
|
||||
new Point(333, 151),
|
||||
new Point(132, 0),
|
||||
};
|
||||
|
||||
d8.Points = new PointCollection
|
||||
{
|
||||
new Point(0, 140),
|
||||
new Point(32, 104),
|
||||
new Point(67, 66),
|
||||
new Point(104, 32),
|
||||
new Point(145, 0),
|
||||
new Point(298, 199),
|
||||
new Point(200, 199),
|
||||
new Point(200, 291),
|
||||
};
|
||||
|
||||
a8.Points = new PointCollection
|
||||
{
|
||||
new Point(210, 28),
|
||||
new Point(115, 65),
|
||||
new Point(0, 138),
|
||||
new Point(153, 338),
|
||||
new Point(215, 338),
|
||||
new Point(311, 297),
|
||||
new Point(359, 249),
|
||||
new Point(324, 0),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public void SetBorderMode(BorderSetting borderSetting, string borderColour)
|
||||
{
|
||||
if (borderSetting == BorderSetting.Rainbow)
|
||||
{
|
||||
var rotateTransform = new RotateTransform { CenterX = 0.5, CenterY = 0.5 };
|
||||
touchPanelBorder.BorderBrush = new ImageBrush {
|
||||
ImageSource = new BitmapImage(new Uri(@"pack://application:,,,/Assets/conicalGradient.png")),
|
||||
ViewportUnits = BrushMappingMode.RelativeToBoundingBox,
|
||||
Viewport = new Rect(0, 0, 1, 1),
|
||||
TileMode = TileMode.Tile,
|
||||
RelativeTransform = rotateTransform,
|
||||
};
|
||||
|
||||
var animation = new DoubleAnimation
|
||||
{
|
||||
From = 0,
|
||||
To = 360,
|
||||
Duration = new Duration(TimeSpan.FromSeconds(10)),
|
||||
RepeatBehavior = RepeatBehavior.Forever
|
||||
};
|
||||
|
||||
rotateTransform.BeginAnimation(RotateTransform.AngleProperty, animation);
|
||||
return;
|
||||
}
|
||||
else if (borderSetting == BorderSetting.Solid)
|
||||
{
|
||||
try
|
||||
{
|
||||
var colour = (Color)ColorConverter.ConvertFromString(borderColour);
|
||||
touchPanelBorder.BorderBrush = new SolidColorBrush { Color = colour };
|
||||
return;
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error("Failed to parse solid colour", ex);
|
||||
}
|
||||
}
|
||||
touchPanelBorder.BorderBrush = null;
|
||||
}
|
||||
|
||||
public void SetEmulateRingButton(bool enabled)
|
||||
{
|
||||
isRingButtonEmulationEnabled = enabled;
|
||||
}
|
||||
|
||||
private void HighlightElement(Polygon element, bool highlight)
|
||||
{
|
||||
if (isDebugEnabled)
|
||||
|
|
|
@ -2,160 +2,31 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<TargetFramework>net8.0-windows10.0.17763.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<UseWPF>true</UseWPF>
|
||||
<ApplicationIcon>Assets\icon.ico</ApplicationIcon>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="Assets\Images\A1.png" />
|
||||
<None Remove="Assets\Images\A2.png" />
|
||||
<None Remove="Assets\Images\A3.png" />
|
||||
<None Remove="Assets\Images\A4.png" />
|
||||
<None Remove="Assets\Images\A5.png" />
|
||||
<None Remove="Assets\Images\A6.png" />
|
||||
<None Remove="Assets\Images\A7.png" />
|
||||
<None Remove="Assets\Images\A8.png" />
|
||||
<None Remove="Assets\Images\B1.png" />
|
||||
<None Remove="Assets\Images\B2.png" />
|
||||
<None Remove="Assets\Images\B3.png" />
|
||||
<None Remove="Assets\Images\B4.png" />
|
||||
<None Remove="Assets\Images\B5.png" />
|
||||
<None Remove="Assets\Images\B6.png" />
|
||||
<None Remove="Assets\Images\B7.png" />
|
||||
<None Remove="Assets\Images\B8.png" />
|
||||
<None Remove="Assets\Images\C1+C2.png" />
|
||||
<None Remove="Assets\Images\C1.png" />
|
||||
<None Remove="Assets\Images\C2.png" />
|
||||
<None Remove="Assets\Images\D1.png" />
|
||||
<None Remove="Assets\Images\D2.png" />
|
||||
<None Remove="Assets\Images\D3.png" />
|
||||
<None Remove="Assets\Images\D4.png" />
|
||||
<None Remove="Assets\Images\D5.png" />
|
||||
<None Remove="Assets\Images\D6.png" />
|
||||
<None Remove="Assets\Images\D7.png" />
|
||||
<None Remove="Assets\Images\D8.png" />
|
||||
<None Remove="Assets\Images\E1.png" />
|
||||
<None Remove="Assets\Images\E2.png" />
|
||||
<None Remove="Assets\Images\E3.png" />
|
||||
<None Remove="Assets\Images\E4.png" />
|
||||
<None Remove="Assets\Images\E5.png" />
|
||||
<None Remove="Assets\Images\E6.png" />
|
||||
<None Remove="Assets\Images\E7.png" />
|
||||
<None Remove="Assets\Images\E8.png" />
|
||||
<None Remove="Assets\conicalGradient.png" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Drawing.Common" Version="8.0.1" />
|
||||
<PackageReference Include="System.IO.Ports" Version="8.0.0" />
|
||||
<Content Include="Assets\icon.ico" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Resource Include="Assets\Images\A1.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Assets\Images\A2.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Assets\Images\A3.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Assets\Images\A4.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Assets\Images\A5.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Assets\Images\A6.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Assets\Images\A7.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Assets\Images\A8.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Assets\Images\B1.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Assets\Images\B2.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Assets\Images\B3.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Assets\Images\B4.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Assets\Images\B5.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Assets\Images\B6.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Assets\Images\B7.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Assets\Images\B8.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Assets\Images\C1+C2.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Assets\Images\C1.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Assets\Images\C2.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Assets\Images\D1.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Assets\Images\D2.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Assets\Images\D3.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Assets\Images\D4.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Assets\Images\D5.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Assets\Images\D6.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Assets\Images\D7.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Assets\Images\D8.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Assets\Images\E1.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Assets\Images\E2.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Assets\Images\E3.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Assets\Images\E4.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Assets\Images\E5.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Assets\Images\E6.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Assets\Images\E7.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Assets\Images\E8.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<PackageReference Include="System.Drawing.Common" Version="9.0.0" />
|
||||
<PackageReference Include="System.IO.Ports" Version="9.0.0" />
|
||||
<PackageReference Include="WPF-UI" Version="3.0.5" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Resource Include="Assets\conicalGradient.png">
|
||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
</ItemGroup>
|
||||
|
||||
|
@ -165,6 +36,18 @@
|
|||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Resources\Strings.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Strings.resx</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Resources\Strings.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Strings.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|