diff --git a/.gitignore b/.gitignore index 9542e63..4b82ccd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ .vs/ -RightKeyboard/bin/ -RightKeyboard/obj/ +bin/ +obj/ diff --git a/README.md b/README.md index 46f7650..49c8caf 100644 --- a/README.md +++ b/README.md @@ -6,13 +6,11 @@ This code is based on the work published here: http://www.codeproject.com/Articl # Changes - Removed "current layout cache", and used system call "Get Current Layout" as method prevent syscall overload, as it failed after sleep. - Added "Clear" context menu, to clear current configuration. +- Make correct distinction between mulitple keyboards layout in a same language. # Before use -Make sure all your keyboard layouts are set on different languages/locales on windows, as this app can only set layout by setting the system locale. I have here, for example: - - English (United States) locale set to have only US International layout. - - Portuguese (Brazil) set to have only Portuguese (Brazil ABNT) layout. - - If you have multiple layouts on same locale it won't work. +You must setup your keyboards layout in windows first. +This app only help you to automate the switch, it doesn't help you to declare your keyboards. # How to use 1. Press WindowsKey + R diff --git a/RightKeyboard.NUnit/ConfigurationTests.cs b/RightKeyboard.NUnit/ConfigurationTests.cs new file mode 100644 index 0000000..54ec143 --- /dev/null +++ b/RightKeyboard.NUnit/ConfigurationTests.cs @@ -0,0 +1,15 @@ +using NUnit.Framework; + +namespace RightKeyboard +{ + [TestFixture] + class ConfigurationTests + { + [Test] + public void LoadConfiguration_Works() + { + var configuration = Configuration.LoadConfiguration(new KeyboardDevicesCollection()); + Assert.That(configuration, Is.Not.Null, "Depends on what is installed on the machine, so manual human check with debugger is required."); + } + } +} diff --git a/RightKeyboard.NUnit/RightKeyboard.NUnit.csproj b/RightKeyboard.NUnit/RightKeyboard.NUnit.csproj new file mode 100644 index 0000000..437f72a --- /dev/null +++ b/RightKeyboard.NUnit/RightKeyboard.NUnit.csproj @@ -0,0 +1,21 @@ + + + + net4 + + false + + RightKeyboard + + + + + + + + + + + + + diff --git a/RightKeyboard.NUnit/UnitTest1.cs b/RightKeyboard.NUnit/UnitTest1.cs new file mode 100644 index 0000000..6c51ffb --- /dev/null +++ b/RightKeyboard.NUnit/UnitTest1.cs @@ -0,0 +1,20 @@ +using NUnit.Framework; +using RightKeyboard.Win32; + +namespace RightKeyboard.NUnit +{ + [TestFixture] + public class Tests + { + [Test] + public void GetKeyboardLayoutName_MustReturnLanguageNameAndKeyboardName() + { + var list = API.GetKeyboardLayoutList(); + foreach (var layout in list) + { + var name = API.GetKeyboardLayoutName(layout); + Assert.That(name, Is.Not.Empty, "Depends on what is installed on the machine, so manual human check with debugger is required."); + } + } + } +} \ No newline at end of file diff --git a/RightKeyboard.sln b/RightKeyboard.sln index 14865ad..7d00920 100644 --- a/RightKeyboard.sln +++ b/RightKeyboard.sln @@ -5,6 +5,8 @@ VisualStudioVersion = 16.0.29613.14 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RightKeyboard", "RightKeyboard\RightKeyboard.csproj", "{D9A15FB8-E81F-4472-8DF4-948E083AE6BC}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RightKeyboard.NUnit", "RightKeyboard.NUnit\RightKeyboard.NUnit.csproj", "{79526D79-46A9-4EEB-8AC3-711344DC4A39}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -15,6 +17,10 @@ Global {D9A15FB8-E81F-4472-8DF4-948E083AE6BC}.Debug|Any CPU.Build.0 = Debug|Any CPU {D9A15FB8-E81F-4472-8DF4-948E083AE6BC}.Release|Any CPU.ActiveCfg = Release|Any CPU {D9A15FB8-E81F-4472-8DF4-948E083AE6BC}.Release|Any CPU.Build.0 = Release|Any CPU + {79526D79-46A9-4EEB-8AC3-711344DC4A39}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {79526D79-46A9-4EEB-8AC3-711344DC4A39}.Debug|Any CPU.Build.0 = Debug|Any CPU + {79526D79-46A9-4EEB-8AC3-711344DC4A39}.Release|Any CPU.ActiveCfg = Release|Any CPU + {79526D79-46A9-4EEB-8AC3-711344DC4A39}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/RightKeyboard/Configuration.cs b/RightKeyboard/Configuration.cs new file mode 100644 index 0000000..ac50d8f --- /dev/null +++ b/RightKeyboard/Configuration.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; +using System.IO; +using System.Linq; + +namespace RightKeyboard +{ + public class Configuration + { + public Dictionary LanguageMappings { get; } = new Dictionary(); + + public static Configuration LoadConfiguration(KeyboardDevicesCollection devices) + { + var configuration = new Configuration(); + var languageMappings = configuration.LanguageMappings; + + string configFilePath = GetConfigFilePath(); + if (File.Exists(configFilePath)) + { + using (TextReader input = File.OpenText(configFilePath)) + { + + var layouts = Layout.EnumerateLayouts().ToDictionary(k => k.Identifier, v => v); + + string line; + while ((line = input.ReadLine()) != null) + { + string[] parts = line.Split('='); + Debug.Assert(parts.Length == 2); + + string deviceName = parts[0]; + var layoutId = new IntPtr(int.Parse(parts[1], NumberStyles.HexNumber)); + + if (devices.TryGetByName(deviceName, out var deviceHandle) + && layouts.TryGetValue(layoutId, out var layout)) + { + languageMappings.Add(deviceHandle, layout); + } + } + } + } + + return configuration; + } + + public void Save(KeyboardDevicesCollection devices) + { + string configFilePath = GetConfigFilePath(); + using (TextWriter output = File.CreateText(configFilePath)) + { + foreach (var device in devices) + { + if (LanguageMappings.TryGetValue(device.Handle, out var layout)) + { + output.WriteLine("{0}={1:X8}", device.Name, layout.Identifier.ToInt32()); + } + } + } + } + + private static string GetConfigFilePath() + { + string configFileDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "RightKeyboard"); + if (!Directory.Exists(configFileDir)) + { + Directory.CreateDirectory(configFileDir); + } + + return Path.Combine(configFileDir, "config.txt"); + } + } +} diff --git a/RightKeyboard/KeyboardDevice.cs b/RightKeyboard/KeyboardDevice.cs new file mode 100644 index 0000000..a08ef48 --- /dev/null +++ b/RightKeyboard/KeyboardDevice.cs @@ -0,0 +1,17 @@ +using System; + +namespace RightKeyboard +{ + public struct KeyboardDevice + { + public string Name { get; } + + public IntPtr Handle { get; } + + public KeyboardDevice(string name, IntPtr handle) + { + Name = name; + Handle = handle; + } + } +} diff --git a/RightKeyboard/KeyboardDevicesCollection.cs b/RightKeyboard/KeyboardDevicesCollection.cs new file mode 100644 index 0000000..9ab3b85 --- /dev/null +++ b/RightKeyboard/KeyboardDevicesCollection.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; + +using RightKeyboard.Win32; + +namespace RightKeyboard +{ + public class KeyboardDevicesCollection : IEnumerable + { + private Dictionary devicesByName = new Dictionary(); + + public bool TryGetByName(string deviceName, out IntPtr deviceHandle) + { + return devicesByName.TryGetValue(deviceName, out deviceHandle); + } + + public KeyboardDevicesCollection() + { + foreach (API.RAWINPUTDEVICELIST rawInputDevice in API.GetRawInputDeviceList()) + { + if (rawInputDevice.dwType == API.RIM_TYPEKEYBOARD) + { + IntPtr deviceHandle = rawInputDevice.hDevice; + string deviceName = API.GetRawInputDeviceName(deviceHandle); + devicesByName.Add(deviceName, deviceHandle); + } + } + } + + public IEnumerator GetEnumerator() + { + return devicesByName + .Select(kvp => new KeyboardDevice(kvp.Key, kvp.Value)) + .GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } +} diff --git a/RightKeyboard/Layout.cs b/RightKeyboard/Layout.cs index 7e6d7e3..da17f9c 100644 --- a/RightKeyboard/Layout.cs +++ b/RightKeyboard/Layout.cs @@ -1,78 +1,44 @@ using System; -using System.IO; -using System.Reflection; +using RightKeyboard.Win32; +using System.Linq; using System.Collections.Generic; -using System.Globalization; namespace RightKeyboard { /// /// Represents a keyboard layout /// public class Layout { - private readonly ushort identifier; /// /// Gets the layout's identifier /// - public ushort Identifier { - get { - return identifier; - } - } - - private readonly string name; + public IntPtr Identifier { get; } /// /// Gets the layout's name /// - public string Name { - get { - return name; - } - } + public string Name { get; } /// /// Initializes a new instance of Layout /// /// /// - public Layout(ushort identifier, string name) { - this.identifier = identifier; - this.name = name; + public Layout(IntPtr identifier, string name) { + this.Identifier = identifier; + this.Name = name; } public override string ToString() { - return name; + return Name; } - private static Layout[] cachedLayouts = null; - /// - /// Gets the keyboard layouts from a ressource file + /// Gets the installed keyboard layouts /// - /// - public static Layout[] GetLayouts() { - if(cachedLayouts == null) { - List layouts = new List(); - using(Stream input = Assembly.GetExecutingAssembly().GetManifestResourceStream("RightKeyboard.Layouts.txt")) { - using(TextReader reader = new StreamReader(input)) { - string line; - while((line = reader.ReadLine()) != null) { - layouts.Add(GetLayout(line)); - } - } - } - cachedLayouts = layouts.ToArray(); - } - return cachedLayouts; - } - - private static Layout GetLayout(string line) { - string[] parts = line.Trim().Split('='); - - ushort identifier = ushort.Parse(parts[0], NumberStyles.HexNumber); - string name = parts[1]; - return new Layout(identifier, name); + public static IEnumerable EnumerateLayouts() { + return API.GetKeyboardLayoutList() + .Select(p => new Layout(p, API.GetKeyboardLayoutName(p))); } } } \ No newline at end of file diff --git a/RightKeyboard/LayoutSelectionDialog.cs b/RightKeyboard/LayoutSelectionDialog.cs index 4b9fe3c..150d0c3 100644 --- a/RightKeyboard/LayoutSelectionDialog.cs +++ b/RightKeyboard/LayoutSelectionDialog.cs @@ -1,11 +1,6 @@ using System; -using System.Collections.Generic; using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Text; using System.Windows.Forms; -using RightKeyboard.Win32; namespace RightKeyboard { public partial class LayoutSelectionDialog : Form { @@ -19,15 +14,8 @@ private void LoadLanguageList() { lbLayouts.Items.Clear(); recentLayoutsCount = 0; - IntPtr[] installedLayouts = API.GetKeyboardLayoutList(); - - foreach(Layout layout in RightKeyboard.Layout.GetLayouts()) { - foreach(IntPtr installedLayout in installedLayouts) { - ushort languageId = unchecked((ushort)installedLayout.ToInt32()); - if(layout.Identifier == languageId) { - lbLayouts.Items.Add(layout); - } - } + foreach(Layout layout in Layout.EnumerateLayouts()) { + lbLayouts.Items.Add(layout); } lbLayouts.SelectedIndex = 0; diff --git a/RightKeyboard/Layouts.txt b/RightKeyboard/Layouts.txt deleted file mode 100644 index 10bfe70..0000000 --- a/RightKeyboard/Layouts.txt +++ /dev/null @@ -1,141 +0,0 @@ -0436=Afrikaans (South Africa) -041c=Albanian (Albania) -1401=Arabic (Algeria) -3c01=Arabic (Bahrain) -0c01=Arabic (Egypt) -0801=Arabic (Iraq) -2c01=Arabic (Jordan) -3401=Arabic (Kuwait) -3001=Arabic (Lebanon) -1001=Arabic (Libya) -1801=Arabic (Morocco) -2001=Arabic (Oman) -4001=Arabic (Qatar) -0401=Arabic (Saudi Arabia) -2801=Arabic (Syria) -1c01=Arabic (Tunisia) -3801=Arabic (U.A.E.) -2401=Arabic (Yemen) -042b=Armenian (Armenia) -044d=Assamese (India) -082c=Azeri (Azerbaijan (Cyrillic)) -042c=Azeri (Azerbaijan (Latin)) -042d=Basque (Spain) -0423=Belarusian (Belarus) -0445=Bengali (India) -0402=Bulgarian (Bulgaria) -0403=Catalan (Spain) -0c04=Chinese (Hong Kong SAR) -1404=Chinese (Macao SAR) -0804=Chinese (PRC) -1004=Chinese (Singapore) -0404=Chinese (Taiwan) -0827=Classic Lithuanian (Lithuania) -041a=Croatian (Croatia) -0405=Czech (Czech Republic) -0406=Danish (Denmark) -0465=Divehi (Maldives) -0813=Dutch (Belgium) -0413=Dutch (Netherlands) -0c09=English (Australia) -2809=English (Belize) -1009=English (Canada) -2409=English (Caribbean) -1809=English (Ireland) -2009=English (Jamaica) -1409=English (New Zealand) -3409=English (Philippines) -1c09=English (South Africa) -2c09=English (Trinidad) -0809=English (United Kingdom) -0409=English (United States) -3009=English (Zimbabwe) -0425=Estonian (Estonia) -0438=Faeroese (Faeroe Islands) -0429=Farsi (Iran) -040b=Finnish (Finland) -080c=French (Belgium) -0c0c=French (Canada) -040c=French (France) -140c=French (Luxembourg) -180c=French (Monaco) -100c=French (Switzerland) -042f=Macedonian (FYROM) (Macedonian (FYROM)) -0456=Galician (Spain) -0437=Georgian (Georgia) -0c07=German (Austria) -0407=German (Germany) -1407=German (Liechtenstein) -1007=German (Luxembourg) -0807=German (Switzerland) -0408=Greek (Greece) -0447=Gujarati (India ) -040d=Hebrew (Israel) -0439=Hindi (India) -040e=Hungarian (Hungary) -040f=Icelandic (Iceland) -0421=Indonesian (Indonesia (Bahasa)) -0410=Italian (Italy) -0810=Italian (Switzerland) -0411=Japanese (Japan) -044b=Kannada (India (Kannada script)) -043f=Kazakh (Kazakstan) -0457=Konkani (India) -0412=Korean (Korea) -0440=Kyrgyz (Kyrgyzstan) -0426=Latvian (Latvia) -0427=Lithuanian (Lithuania) -083e=Malay (Brunei Darussalam) -043e=Malay (Malaysia) -044c=Malayalam (India) -044e=Marathi (India) -0450=Mongolian (Cyrillic) (Mongolia) -0414=Norwegian (Norway (Bokmål)) -0814=Norwegian (Norway (Nynorsk)) -0448=Oriya (India) -0415=Polish (Poland) -0416=Portuguese (Brazil) -0816=Portuguese (Portugal) -0446=Punjabi (India (Gurmukhi script)) -0418=Romanian (Romania) -0419=Russian (Russia) -044f=Sanskrit (India) -0c1a=Serbian (Serbia (Cyrillic)) -081a=Serbian (Serbia (Latin)) -041b=Slovak (Slovakia) -0424=Slovenian (Slovenia) -2c0a=Spanish (Argentina) -400a=Spanish (Bolivia) -340a=Spanish (Chile) -240a=Spanish (Colombia) -140a=Spanish (Costa Rica) -1c0a=Spanish (Dominican Republic) -300a=Spanish (Ecuador) -440a=Spanish (El Salvador) -100a=Spanish (Guatemala) -480a=Spanish (Honduras) -080a=Spanish (Mexico) -4c0a=Spanish (Nicaragua) -180a=Spanish (Panama) -3c0a=Spanish (Paraguay) -280a=Spanish (Peru) -500a=Spanish (Puerto Rico) -040a=Spanish (Spain (Traditional sort)) -0c0a=Spanish (Spain (International sort)) -380a=Spanish (Uruguay) -200a=Spanish (Venezuela) -0441=Swahili (Kenya) -081d=Swedish (Finland) -041d=Swedish (Sweden) -045a=Syriac (Syria) -0449=Tamil (India) -0444=Tatar (Tatarstan) -044a=Telugu (India (Telugu script)) -041e=Thai (Thailand) -041f=Turkish (Turkey) -0422=Ukrainian (Ukraine) -0420=Urdu (Pakistan) -0820=Urdu (India) -0843=Uzbek (Uzbekistan (Cyrillic)) -0443=Uzbek (Uzbekistan (Latin)) -042a=Vietnamese (Viet Nam) \ No newline at end of file diff --git a/RightKeyboard/MainForm.cs b/RightKeyboard/MainForm.cs index 73a3f31..6a2a795 100644 --- a/RightKeyboard/MainForm.cs +++ b/RightKeyboard/MainForm.cs @@ -1,24 +1,19 @@ using System; using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Text; using System.Windows.Forms; using RightKeyboard.Win32; using System.Diagnostics; using System.Runtime.InteropServices; using System.IO; -using System.Globalization; namespace RightKeyboard { public partial class MainForm : Form { private bool selectingLayout = false; private LayoutSelectionDialog layoutSelectionDialog = new LayoutSelectionDialog(); - private Dictionary languageMappings = new Dictionary(); + private Configuration configuration; - private Dictionary devicesByName = new Dictionary(); + private KeyboardDevicesCollection devices = new KeyboardDevicesCollection(); public MainForm() { InitializeComponent(); @@ -32,7 +27,6 @@ public MainForm() { WindowState = FormWindowState.Minimized; - LoadDeviceList(); LoadConfiguration(); } @@ -43,15 +37,7 @@ protected override void OnClosed(EventArgs e) { private void SaveConfiguration() { try { - string configFilePath = GetConfigFilePath(); - using(TextWriter output = File.CreateText(configFilePath)) { - foreach(KeyValuePair entry in devicesByName) { - ushort layout; - if(languageMappings.TryGetValue(entry.Value, out layout)) { - output.WriteLine("{0}={1:X04}", entry.Key, layout); - } - } - } + configuration.Save(devices); } catch(Exception err) { MessageBox.Show("Could not save the configuration. Reason: " + err.Message); @@ -60,24 +46,7 @@ private void SaveConfiguration() { private void LoadConfiguration() { try { - string configFilePath = GetConfigFilePath(); - if(File.Exists(configFilePath)) { - using(TextReader input = File.OpenText(configFilePath)) { - string line; - while((line = input.ReadLine()) != null) { - string[] parts = line.Split('='); - Debug.Assert(parts.Length == 2); - - string deviceName = parts[0]; - ushort layout = ushort.Parse(parts[1], NumberStyles.HexNumber); - - IntPtr deviceHandle; - if(devicesByName.TryGetValue(deviceName, out deviceHandle)) { - languageMappings.Add(deviceHandle, layout); - } - } - } - } + configuration = Configuration.LoadConfiguration(devices); } catch(Exception err) { MessageBox.Show("Could not load the configuration. Reason: " + err.Message); @@ -93,16 +62,6 @@ private static string GetConfigFilePath() { return Path.Combine(configFileDir, "config.txt"); } - private void LoadDeviceList() { - foreach(API.RAWINPUTDEVICELIST rawInputDevice in API.GetRawInputDeviceList()) { - if(rawInputDevice.dwType == API.RIM_TYPEKEYBOARD) { - IntPtr deviceHandle = rawInputDevice.hDevice; - string deviceName = API.GetRawInputDeviceName(deviceHandle); - devicesByName.Add(deviceName, deviceHandle); - } - } - } - protected override void OnLoad(EventArgs e) { base.OnLoad(e); Hide(); @@ -196,48 +155,35 @@ private void ProcessInputMessage(Message message) { } private void ValidateCurrentDevice(IntPtr hCurrentDevice) { - ushort layout; - if (!languageMappings.TryGetValue(hCurrentDevice, out layout)) { + if (!configuration.LanguageMappings.TryGetValue(hCurrentDevice, out var layout)) { selectingLayout = true; layoutSelectionDialog.ShowDialog(); + layout = layoutSelectionDialog.Layout; + configuration.LanguageMappings.Add(hCurrentDevice, layout); selectingLayout = false; - layout = layoutSelectionDialog.Layout.Identifier; - languageMappings.Add(hCurrentDevice, layout); } - ushort currentSysLayout = (ushort)API.GetKeyboardLayout().ToInt32(); - - if (currentSysLayout != layout) + var currentSysLayout = API.GetKeyboardLayout(); + var desiredLayout = layout.Identifier; + if (currentSysLayout != desiredLayout) { - SetCurrentLayout(layout); - SetDefaultLayout(layout); + SetCurrentLayout(desiredLayout); + SetDefaultLayout(desiredLayout); } } - private void SetCurrentLayout(ushort layout) { + private void SetCurrentLayout(IntPtr layoutId) { uint recipients = API.BSM_APPLICATIONS; - API.BroadcastSystemMessage(API.BSF_POSTMESSAGE, ref recipients, API.WM_INPUTLANGCHANGEREQUEST, IntPtr.Zero, new IntPtr(layout)); + API.BroadcastSystemMessage(API.BSF_POSTMESSAGE, ref recipients, API.WM_INPUTLANGCHANGEREQUEST, IntPtr.Zero, layoutId); } - private void SetDefaultLayout(ushort layout) { - //IntPtr hkl = API.LoadKeyboardLayout(layout, 0); - //Debug.Assert(hkl != IntPtr.Zero); - //if(hkl == IntPtr.Zero) { - // throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()); - //} - - IntPtr hkl = new IntPtr(unchecked((int)((uint)layout << 16 | (uint)layout))); - - bool ok = API.SystemParametersInfo(API.SPI_SETDEFAULTINPUTLANG, 0, new IntPtr[] { hkl }, API.SPIF_SENDCHANGE); - //Debug.Assert(ok); - //if(!ok) { - // throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()); - //} + private void SetDefaultLayout(IntPtr layoutId) { + API.SystemParametersInfo(API.SPI_SETDEFAULTINPUTLANG, 0, new IntPtr[] { layoutId }, API.SPIF_SENDCHANGE); } private void clearToolStripMenuItem_Click(object sender, EventArgs e) { - languageMappings = new Dictionary(); + configuration.LanguageMappings.Clear(); } private void exitToolStripMenuItem_Click(object sender, EventArgs e) { diff --git a/RightKeyboard/Properties/AssemblyInfo.cs b/RightKeyboard/Properties/AssemblyInfo.cs index bd13973..8399394 100644 --- a/RightKeyboard/Properties/AssemblyInfo.cs +++ b/RightKeyboard/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following @@ -10,7 +9,7 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("RightKeyboard")] -[assembly: AssemblyCopyright("Copyright © 2007")] +[assembly: AssemblyCopyright("Copyright © 2007-2020")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -29,5 +28,6 @@ // Build Number // Revision // -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: AssemblyVersion("1.3.0.0")] +[assembly: AssemblyFileVersion("1.3.0.0")] +[assembly: AssemblyInformationalVersion("1.3.0")] diff --git a/RightKeyboard/RightKeyboard.csproj b/RightKeyboard/RightKeyboard.csproj index acb1aed..c1da7d5 100644 --- a/RightKeyboard/RightKeyboard.csproj +++ b/RightKeyboard/RightKeyboard.csproj @@ -42,6 +42,9 @@ + + + Form @@ -90,7 +93,6 @@ -