From b4337d5aea3df54ae14215ff58e4b6a16e8704a2 Mon Sep 17 00:00:00 2001 From: Guillermo Ruffino Date: Tue, 8 Aug 2017 19:44:29 -0300 Subject: [PATCH 1/5] Changes, now it works with Windows 10 Retrieves layouts names from Registry Lists keyboards layouts filtering out languages, selects a default language Stores settings in Properties Settings instead of file --- RightKeyboard/Layout.cs | 16 +- RightKeyboard/LayoutSelectionDialog.cs | 153 +++--- RightKeyboard/Layouts.txt | 141 ----- RightKeyboard/MainForm.cs | 486 +++++++++--------- .../Properties/Resources.Designer.cs | 126 ++--- RightKeyboard/Properties/Settings.Designer.cs | 64 ++- RightKeyboard/Properties/Settings.settings | 16 +- RightKeyboard/RightKeyboard.csproj | 198 +++---- RightKeyboard/Win32/API.cs | 18 +- 9 files changed, 578 insertions(+), 640 deletions(-) delete mode 100644 RightKeyboard/Layouts.txt diff --git a/RightKeyboard/Layout.cs b/RightKeyboard/Layout.cs index 7e6d7e3..eb93f30 100644 --- a/RightKeyboard/Layout.cs +++ b/RightKeyboard/Layout.cs @@ -31,18 +31,20 @@ public string Name { } } - /// - /// Initializes a new instance of Layout - /// - /// - /// - public Layout(ushort identifier, string name) { + public IntPtr Hkl { get; set; } + + /// + /// Initializes a new instance of Layout + /// + /// + /// + public Layout(ushort identifier, string name) { this.identifier = identifier; this.name = name; } public override string ToString() { - return name; + return name + " (" + Hkl.ToString("X8") + ")"; } private static Layout[] cachedLayouts = null; diff --git a/RightKeyboard/LayoutSelectionDialog.cs b/RightKeyboard/LayoutSelectionDialog.cs index 976692e..2501800 100644 --- a/RightKeyboard/LayoutSelectionDialog.cs +++ b/RightKeyboard/LayoutSelectionDialog.cs @@ -1,64 +1,91 @@ -using System; -using System.ComponentModel; -using System.Windows.Forms; -using RightKeyboard.Win32; - -namespace RightKeyboard { - public partial class LayoutSelectionDialog : Form { - public LayoutSelectionDialog() { - InitializeComponent(); - - LoadLanguageList(); - } - - private void LoadLanguageList() { - lbLayouts.Items.Clear(); - recentLayoutsCount = 0; - - IntPtr[] installedLayouts = API.GetKeyboardLayoutList(); - - foreach(Layout layout in Layout.GetLayouts()) { - foreach(IntPtr installedLayout in installedLayouts) { - ushort languageId = unchecked((ushort)installedLayout.ToInt32()); - if(layout.Identifier == languageId) { - lbLayouts.Items.Add(layout); - } - } - } - - lbLayouts.SelectedIndex = 0; - } - - private int recentLayoutsCount = 0; - private Layout selectedLayout; - private bool okPressed = false; - - public new Layout Layout { - get { - return selectedLayout; - } - } - - private void btOk_Click(object sender, EventArgs e) { - selectedLayout = (Layout)lbLayouts.SelectedItem; - okPressed = true; - Close(); - } - - private void lbLayouts_SelectedIndexChanged(object sender, EventArgs e) { - btOk.Enabled = lbLayouts.SelectedIndex != recentLayoutsCount || recentLayoutsCount == 0; - } - - private void lbLayouts_DoubleClick(object sender, EventArgs e) { - if(btOk.Enabled) { - btOk_Click(this, EventArgs.Empty); - } - } - - protected override void OnClosing(CancelEventArgs e) { - e.Cancel = !okPressed; - okPressed = false; - base.OnClosing(e); - } - } +using System; +using System.ComponentModel; +using System.Windows.Forms; +using RightKeyboard.Win32; +using System.Linq; + +namespace RightKeyboard { + public partial class LayoutSelectionDialog : Form { + public LayoutSelectionDialog() { + InitializeComponent(); + + LoadLanguageList(); + } + + private void LoadLanguageList() { + lbLayouts.Items.Clear(); + recentLayoutsCount = 0; + + IntPtr[] installedLayouts = API.GetKeyboardLayoutList(); + + var layoutCodes = installedLayouts.Select(l => ((l.ToInt32() >> 16)& 0xffff)).Distinct(); + + foreach (var item in layoutCodes) + { + // Get layout name + var key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\Keyboard Layouts\0000" + + item.ToString("X4")); + + string name; + if (key == null) + name = "Unknown " + item.ToString("X4"); + else + name = key.GetValue("Layout Text").ToString(); + + var layout = new Layout((ushort)item, name); + // Need full hkl, if there are several for a layout here we just take one, + // we can improve this by also having the language selection somehow... + layout.Hkl = installedLayouts.First(h => ((h.ToInt32() >> 16) & 0xffff) == item); + lbLayouts.Items.Add(layout); + } + // var layouts = Layout.GetLayouts(); + + // foreach (IntPtr installedLayout in installedLayouts) + // { + // ushort languageId = unchecked((ushort)installedLayout.ToInt32()); + + // var layout = layouts.FirstOrDefault(l => l.Identifier == languageId); + + // if (layout != null) + // { + // layout.Hkl = installedLayout; + // lbLayouts.Items.Add(layout); + // } + // } + + //lbLayouts.SelectedIndex = 0; + } + + private int recentLayoutsCount = 0; + private Layout selectedLayout; + private bool okPressed = false; + + public new Layout Layout { + get { + return selectedLayout; + } + } + + private void btOk_Click(object sender, EventArgs e) { + selectedLayout = (Layout)lbLayouts.SelectedItem; + okPressed = true; + Close(); + } + + private void lbLayouts_SelectedIndexChanged(object sender, EventArgs e) { + btOk.Enabled = lbLayouts.SelectedIndex != recentLayoutsCount || recentLayoutsCount == 0; + } + + private void lbLayouts_DoubleClick(object sender, EventArgs e) { + if(btOk.Enabled) { + btOk_Click(this, EventArgs.Empty); + } + } + + protected override void OnClosing(CancelEventArgs e) { + e.Cancel = !okPressed; + okPressed = false; + base.OnClosing(e); + } + } } \ No newline at end of file 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 5a75593..ea4906d 100644 --- a/RightKeyboard/MainForm.cs +++ b/RightKeyboard/MainForm.cs @@ -1,230 +1,258 @@ -using System; -using System.Collections.Generic; -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 IntPtr hCurrentDevice = IntPtr.Zero; - - private bool selectingLayout = false; - private ushort currentLayout; - private readonly LayoutSelectionDialog layoutSelectionDialog = new LayoutSelectionDialog(); - - private readonly Dictionary languageMappings = new Dictionary(); - - private readonly Dictionary devicesByName = new Dictionary(); - - public MainForm() { - InitializeComponent(); - - RAWINPUTDEVICE rawInputDevice = new RAWINPUTDEVICE(1, 6, API.RIDEV_INPUTSINK, this); - bool ok = API.RegisterRawInputDevices(rawInputDevice); - if(!ok) { - throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()); - } - Debug.Assert(ok); - - WindowState = FormWindowState.Minimized; - - LoadDeviceList(); - LoadConfiguration(); - } - - protected override void OnClosed(EventArgs e) { - base.OnClosed(e); - SaveConfiguration(); - } - - 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); - } - } - } - } - catch(Exception err) { - MessageBox.Show("Could not save the configuration. Reason: " + err.Message); - } - } - - 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); - } - } - } - } - } - catch(Exception err) { - MessageBox.Show("Could not load the configuration. Reason: " + err.Message); - } - } - - 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"); - } - - 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(); - } - - protected override void WndProc(ref Message message) { - switch(message.Msg) { - case API.WM_INPUT: - if(!selectingLayout) { - ProcessInputMessage(message); - } - break; - - case API.WM_POWERBROADCAST: - ProcessPowerMessage(message); - break; - - default: - base.WndProc(ref message); - break; - } - } - - private void ProcessPowerMessage(Message message) { - switch(message.WParam.ToInt32()) { - case API.PBT_APMQUERYSUSPEND: - Debug.WriteLine("PBT_APMQUERYSUSPEND"); - break; - - case API.PBT_APMQUERYSTANDBY: - Debug.WriteLine("PBT_APMQUERYSTANDBY"); - break; - - case API.PBT_APMQUERYSUSPENDFAILED: - Debug.WriteLine("PBT_APMQUERYSUSPENDFAILED"); - break; - - case API.PBT_APMQUERYSTANDBYFAILED: - Debug.WriteLine("PBT_APMQUERYSTANDBYFAILED"); - break; - - case API.PBT_APMSUSPEND: - Debug.WriteLine("PBT_APMSUSPEND"); - break; - - case API.PBT_APMSTANDBY: - Debug.WriteLine("PBT_APMSTANDBY"); - break; - - case API.PBT_APMRESUMECRITICAL: - Debug.WriteLine("PBT_APMRESUMECRITICAL"); - break; - - case API.PBT_APMRESUMESUSPEND: - Debug.WriteLine("PBT_APMRESUMESUSPEND"); - break; - - case API.PBT_APMRESUMESTANDBY: - Debug.WriteLine("PBT_APMRESUMESTANDBY"); - break; - - case API.PBT_APMBATTERYLOW: - Debug.WriteLine("PBT_APMBATTERYLOW"); - break; - - case API.PBT_APMPOWERSTATUSCHANGE: - Debug.WriteLine("PBT_APMPOWERSTATUSCHANGE"); - break; - - case API.PBT_APMOEMEVENT: - Debug.WriteLine("PBT_APMOEMEVENT"); - break; - - case API.PBT_APMRESUMEAUTOMATIC: - Debug.WriteLine("PBT_APMRESUMEAUTOMATIC"); - break; - } - } - - private void ProcessInputMessage(Message message) { - RAWINPUTHEADER header; - uint result = API.GetRawInputData(message.LParam, API.RID_HEADER, out header); - Debug.Assert(result != uint.MaxValue); - if(result == uint.MaxValue) { - throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()); - } - - if(header.hDevice != hCurrentDevice) { - hCurrentDevice = header.hDevice; - CurrentDeviceChanged(hCurrentDevice); - } - } - - private void CurrentDeviceChanged(IntPtr currentDevice) { - ushort layout; - if(!languageMappings.TryGetValue(currentDevice, out layout)) { - selectingLayout = true; - layoutSelectionDialog.ShowDialog(); - selectingLayout = false; - layout = layoutSelectionDialog.Layout.Identifier; - languageMappings.Add(currentDevice, layout); - } - SetCurrentLayout(layout); - SetDefaultLayout(layout); - } - - private void SetCurrentLayout(ushort layout) { - if(layout != currentLayout && layout != 0) { - currentLayout = layout; - uint recipients = API.BSM_APPLICATIONS; - API.BroadcastSystemMessage(API.BSF_POSTMESSAGE, ref recipients, API.WM_INPUTLANGCHANGEREQUEST, IntPtr.Zero, new IntPtr(layout)); - } - } - - private void SetDefaultLayout(ushort layout) { - IntPtr hkl = new IntPtr(unchecked((int)((uint)layout << 16 | (uint)layout))); - - bool ok = API.SystemParametersInfo(API.SPI_SETDEFAULTINPUTLANG, 0, new[] { hkl }, API.SPIF_SENDCHANGE); - Debug.Assert(ok); - } - - private void exitToolStripMenuItem_Click(object sender, EventArgs e) { - Close(); - } - } +using System; +using System.Collections.Generic; +using System.Windows.Forms; +using RightKeyboard.Win32; +using System.Diagnostics; +using System.Runtime.InteropServices; + +namespace RightKeyboard +{ + public partial class MainForm : Form + { + private IntPtr hCurrentDevice = IntPtr.Zero; + + private bool selectingLayout = false; + private IntPtr currentLayoutHkl; + private readonly LayoutSelectionDialog layoutSelectionDialog = new LayoutSelectionDialog(); + + private readonly Dictionary languageMappings = new Dictionary(); + + private readonly Dictionary devicesByName = new Dictionary(); + + public MainForm() + { + InitializeComponent(); + + RAWINPUTDEVICE rawInputDevice = new RAWINPUTDEVICE(1, 6, API.RIDEV_INPUTSINK, this); + bool ok = API.RegisterRawInputDevices(rawInputDevice); + if (!ok) + { + throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()); + } + Debug.Assert(ok); + + WindowState = FormWindowState.Minimized; + + LoadDeviceList(); + LoadConfiguration(); + } + + protected override void OnClosed(EventArgs e) + { + base.OnClosed(e); + SaveConfiguration(); + } + + private void SaveConfiguration() + { + try + { + var mappings = new List(); + foreach (KeyValuePair entry in devicesByName) + { + if (languageMappings.TryGetValue(entry.Value, out Layout layout)) + mappings.Add(string.Format("{0}={1}", entry.Key, layout.Hkl)); + } + Properties.Settings.Default.Mappings = string.Join(";", mappings); + Properties.Settings.Default.Save(); + } + catch (Exception err) + { + MessageBox.Show("Could not save the configuration. Reason: " + err.Message); + } + } + + private void LoadConfiguration() + { + try + { + if (string.IsNullOrWhiteSpace(Properties.Settings.Default.Mappings)) + return; + + foreach (var line in Properties.Settings.Default.Mappings.Split(';')) + { + string[] parts = line.Split('='); + Debug.Assert(parts.Length == 2); + + string deviceName = parts[0]; + var hkl = (IntPtr)Int32.Parse(parts[1]); + + if (devicesByName.TryGetValue(deviceName, out IntPtr deviceHandle)) + { + var l = new Layout((ushort)hkl, deviceName); + l.Hkl = hkl; + languageMappings.Add(deviceHandle, l); + + } + } + } + catch (Exception err) + { + MessageBox.Show("Could not load the configuration. Reason: " + err.Message); + } + } + + 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(); + } + + protected override void WndProc(ref Message message) + { + switch (message.Msg) + { + case API.WM_INPUT: + if (!selectingLayout) + { + ProcessInputMessage(message); + } + break; + + case API.WM_POWERBROADCAST: + ProcessPowerMessage(message); + break; + + default: + base.WndProc(ref message); + break; + } + } + + private void ProcessPowerMessage(Message message) + { + switch (message.WParam.ToInt32()) + { + case API.PBT_APMQUERYSUSPEND: + Debug.WriteLine("PBT_APMQUERYSUSPEND"); + break; + + case API.PBT_APMQUERYSTANDBY: + Debug.WriteLine("PBT_APMQUERYSTANDBY"); + break; + + case API.PBT_APMQUERYSUSPENDFAILED: + Debug.WriteLine("PBT_APMQUERYSUSPENDFAILED"); + break; + + case API.PBT_APMQUERYSTANDBYFAILED: + Debug.WriteLine("PBT_APMQUERYSTANDBYFAILED"); + break; + + case API.PBT_APMSUSPEND: + Debug.WriteLine("PBT_APMSUSPEND"); + break; + + case API.PBT_APMSTANDBY: + Debug.WriteLine("PBT_APMSTANDBY"); + break; + + case API.PBT_APMRESUMECRITICAL: + Debug.WriteLine("PBT_APMRESUMECRITICAL"); + break; + + case API.PBT_APMRESUMESUSPEND: + Debug.WriteLine("PBT_APMRESUMESUSPEND"); + break; + + case API.PBT_APMRESUMESTANDBY: + Debug.WriteLine("PBT_APMRESUMESTANDBY"); + break; + + case API.PBT_APMBATTERYLOW: + Debug.WriteLine("PBT_APMBATTERYLOW"); + break; + + case API.PBT_APMPOWERSTATUSCHANGE: + Debug.WriteLine("PBT_APMPOWERSTATUSCHANGE"); + break; + + case API.PBT_APMOEMEVENT: + Debug.WriteLine("PBT_APMOEMEVENT"); + break; + + case API.PBT_APMRESUMEAUTOMATIC: + Debug.WriteLine("PBT_APMRESUMEAUTOMATIC"); + break; + } + } + + private void ProcessInputMessage(Message message) + { + RAWINPUTHEADER header; + uint result = API.GetRawInputData(message.LParam, API.RID_HEADER, out header); + Debug.Assert(result != uint.MaxValue); + if (result == uint.MaxValue) + { + throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()); + } + + if (header.hDevice != hCurrentDevice) + { + hCurrentDevice = header.hDevice; + CurrentDeviceChanged(hCurrentDevice); + } + } + + private void CurrentDeviceChanged(IntPtr currentDevice) + { + Layout layout; + if (!languageMappings.TryGetValue(currentDevice, out layout)) + { + selectingLayout = true; + layoutSelectionDialog.ShowDialog(); + selectingLayout = false; + layout = layoutSelectionDialog.Layout; + languageMappings.Add(currentDevice, layout); + } + SetCurrentLayout(layout.Hkl); + SetDefaultLayout(layout.Hkl); + } + + private void SetCurrentLayout(IntPtr layout) + { + if (layout != currentLayoutHkl && layout != IntPtr.Zero) + { + currentLayoutHkl = layout; + uint recipients = API.BSM_APPLICATIONS; + API.BroadcastSystemMessage(API.BSF_POSTMESSAGE, ref recipients, API.WM_INPUTLANGCHANGEREQUEST, IntPtr.Zero, layout); + } + } + + private void SetDefaultLayout(IntPtr hkl) + { + //IntPtr hkl = new IntPtr(unchecked((int)((uint)layout << 16 | (uint)layout))); + + bool ok = API.SystemParametersInfo(API.SPI_SETDEFAULTINPUTLANG, 0, new[] { hkl }, API.SPIF_SENDCHANGE); + uint er = API.GetLastError(); + Debug.Assert(ok); + } + //private void SetDefaultLayout(ushort layout) + //{ + // IntPtr hkl = new IntPtr(unchecked((int)((uint)layout << 16 | (uint)layout))); + + // bool ok = API.SystemParametersInfo(API.SPI_SETDEFAULTINPUTLANG, 0, new[] { hkl }, API.SPIF_SENDCHANGE); + // uint er = API.GetLastError(); + // Debug.Assert(ok); + //} + + + private void exitToolStripMenuItem_Click(object sender, EventArgs e) + { + Close(); + } + } } \ No newline at end of file diff --git a/RightKeyboard/Properties/Resources.Designer.cs b/RightKeyboard/Properties/Resources.Designer.cs index 50151fd..67593f9 100644 --- a/RightKeyboard/Properties/Resources.Designer.cs +++ b/RightKeyboard/Properties/Resources.Designer.cs @@ -1,63 +1,63 @@ -//------------------------------------------------------------------------------ -// -// 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. -// -//------------------------------------------------------------------------------ - -namespace RightKeyboard.Properties { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // 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", "4.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [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("RightKeyboard.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - } -} +//------------------------------------------------------------------------------ +// +// 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. +// +//------------------------------------------------------------------------------ + +namespace RightKeyboard.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // 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", "15.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [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("RightKeyboard.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/RightKeyboard/Properties/Settings.Designer.cs b/RightKeyboard/Properties/Settings.Designer.cs index 1a80201..eff061e 100644 --- a/RightKeyboard/Properties/Settings.Designer.cs +++ b/RightKeyboard/Properties/Settings.Designer.cs @@ -1,26 +1,38 @@ -//------------------------------------------------------------------------------ -// -// 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. -// -//------------------------------------------------------------------------------ - -namespace RightKeyboard.Properties { - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { - - private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default { - get { - return defaultInstance; - } - } - } -} +//------------------------------------------------------------------------------ +// +// 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. +// +//------------------------------------------------------------------------------ + +namespace RightKeyboard.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.3.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string Mappings { + get { + return ((string)(this["Mappings"])); + } + set { + this["Mappings"] = value; + } + } + } +} diff --git a/RightKeyboard/Properties/Settings.settings b/RightKeyboard/Properties/Settings.settings index 3964565..4399f34 100644 --- a/RightKeyboard/Properties/Settings.settings +++ b/RightKeyboard/Properties/Settings.settings @@ -1,7 +1,9 @@ - - - - - - - + + + + + + + + + \ No newline at end of file diff --git a/RightKeyboard/RightKeyboard.csproj b/RightKeyboard/RightKeyboard.csproj index e76928e..5b21953 100644 --- a/RightKeyboard/RightKeyboard.csproj +++ b/RightKeyboard/RightKeyboard.csproj @@ -1,105 +1,107 @@ - - - - Debug - AnyCPU - 8.0.50727 - 2.0 - {D9A15FB8-E81F-4472-8DF4-948E083AE6BC} - WinExe - Properties - RightKeyboard - RightKeyboard - ico_input0002.ico - v2.0 - - - - - 2.0 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - Form - - - LayoutSelectionDialog.cs - - - Form - - - MainForm.cs - - - - - Designer - LayoutSelectionDialog.cs - - - Designer - MainForm.cs - - - ResXFileCodeGenerator - Resources.Designer.cs - Designer - - - True - Resources.resx - True - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - True - Settings.settings - True - - - - - - - - - - + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {D9A15FB8-E81F-4472-8DF4-948E083AE6BC} + WinExe + Properties + RightKeyboard + RightKeyboard + ico_input0002.ico + v4.5.1 + + + + + 2.0 + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + false + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + false + + + + + + + + + + + + + Form + + + LayoutSelectionDialog.cs + + + Form + + + MainForm.cs + + + + + Designer + LayoutSelectionDialog.cs + + + Designer + MainForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + + + --> \ No newline at end of file diff --git a/RightKeyboard/Win32/API.cs b/RightKeyboard/Win32/API.cs index f32af28..af56724 100644 --- a/RightKeyboard/Win32/API.cs +++ b/RightKeyboard/Win32/API.cs @@ -154,8 +154,8 @@ public static uint GetRawInputData(IntPtr hRawInput, uint uiCommand, out RAWINPU [DllImport("user32", SetLastError = true)] public static extern int BroadcastSystemMessage(uint dwFlags, ref uint lpdwRecipients, uint uiMessage, IntPtr wParam, IntPtr lParam); - - [DllImport("user32.dll")] + + [DllImport("user32.dll")] private static extern uint GetKeyboardLayoutList(int nBuff, IntPtr[] lpList); public static IntPtr[] GetKeyboardLayoutList() { @@ -165,6 +165,7 @@ public static IntPtr[] GetKeyboardLayoutList() { IntPtr[] localeHandles = new IntPtr[count]; int realCount = (int)GetKeyboardLayoutList(count, localeHandles); Debug.Assert(realCount == count); + return localeHandles; } @@ -176,9 +177,14 @@ public static IntPtr[] GetKeyboardLayoutList() { public static IntPtr LoadKeyboardLayout(ushort layout, uint flags) { return LoadKeyboardLayout(string.Format("{0:X04}{0:X04}", layout), flags); - } - - [DllImport("user32.dll")] - public static extern bool SystemParametersInfo(uint uiAction, uint uiParam, IntPtr[] pvParam, uint fWinIni); + } + + [DllImport("kernel32.dll")] + public static extern uint GetLastError(); + + + [DllImport("user32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool SystemParametersInfo(uint uiAction, uint uiParam, IntPtr[] pvParam, uint fWinIni); } } \ No newline at end of file From c5205c9d392a7fb383355fb460fd3be1d7cdd312 Mon Sep 17 00:00:00 2001 From: Guillermo Ruffino Date: Fri, 15 Sep 2017 15:15:46 -0300 Subject: [PATCH 2/5] Some fixes here and there, seems to be working when binary is copied in the Startup of Windows Start menu. It does some crazyness sometimes when using remote desktop with different keyboard layouts, but survivable --- RightKeyboard/Layout.cs | 81 +++++++----------------------- RightKeyboard/MainForm.cs | 33 ++++++++---- RightKeyboard/RightKeyboard.csproj | 1 + RightKeyboard/app.config | 15 ++++++ 4 files changed, 59 insertions(+), 71 deletions(-) create mode 100644 RightKeyboard/app.config diff --git a/RightKeyboard/Layout.cs b/RightKeyboard/Layout.cs index eb93f30..345a8ba 100644 --- a/RightKeyboard/Layout.cs +++ b/RightKeyboard/Layout.cs @@ -1,35 +1,22 @@ using System; -using System.IO; -using System.Reflection; -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; - - /// - /// Gets the layout's name - /// - public string Name { - get { - return name; - } - } +namespace RightKeyboard +{ + /// + /// Represents a keyboard layout + /// + public class Layout { + + /// + /// Gets the layout's identifier + /// + public ushort Identifier { get; } + + /// + /// Gets the layout's name + /// + public string Name { get; } public IntPtr Hkl { get; set; } @@ -39,42 +26,12 @@ public string Name { /// /// public Layout(ushort identifier, string name) { - this.identifier = identifier; - this.name = name; + this.Identifier = identifier; + Name = name; } public override string ToString() { - return name + " (" + Hkl.ToString("X8") + ")"; - } - - private static Layout[] cachedLayouts = null; - - /// - /// Gets the keyboard layouts from a ressource file - /// - /// - 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); + return Name + " (" + Hkl.ToString("X8") + ")"; } } } \ No newline at end of file diff --git a/RightKeyboard/MainForm.cs b/RightKeyboard/MainForm.cs index ea4906d..33093b3 100644 --- a/RightKeyboard/MainForm.cs +++ b/RightKeyboard/MainForm.cs @@ -81,7 +81,7 @@ private void LoadConfiguration() { var l = new Layout((ushort)hkl, deviceName); l.Hkl = hkl; - languageMappings.Add(deviceHandle, l); + languageMappings.Add(deviceHandle, l); } } @@ -212,14 +212,29 @@ private void CurrentDeviceChanged(IntPtr currentDevice) Layout layout; if (!languageMappings.TryGetValue(currentDevice, out layout)) { - selectingLayout = true; - layoutSelectionDialog.ShowDialog(); - selectingLayout = false; - layout = layoutSelectionDialog.Layout; - languageMappings.Add(currentDevice, layout); + layout = ShowGetLayoutForDeviceDialog(currentDevice); } SetCurrentLayout(layout.Hkl); - SetDefaultLayout(layout.Hkl); + + if (!SetDefaultLayout(layout.Hkl)) + { + layout = ShowGetLayoutForDeviceDialog(currentDevice); + SetCurrentLayout(layout.Hkl); + + Debug.Assert(SetDefaultLayout(layout.Hkl)); + + } + } + + private Layout ShowGetLayoutForDeviceDialog(IntPtr currentDevice) + { + Layout layout; + selectingLayout = true; + layoutSelectionDialog.ShowDialog(); + selectingLayout = false; + layout = layoutSelectionDialog.Layout; + languageMappings[currentDevice] = layout; + return layout; } private void SetCurrentLayout(IntPtr layout) @@ -232,13 +247,13 @@ private void SetCurrentLayout(IntPtr layout) } } - private void SetDefaultLayout(IntPtr hkl) + private bool SetDefaultLayout(IntPtr hkl) { //IntPtr hkl = new IntPtr(unchecked((int)((uint)layout << 16 | (uint)layout))); bool ok = API.SystemParametersInfo(API.SPI_SETDEFAULTINPUTLANG, 0, new[] { hkl }, API.SPIF_SENDCHANGE); uint er = API.GetLastError(); - Debug.Assert(ok); + return ok; } //private void SetDefaultLayout(ushort layout) //{ diff --git a/RightKeyboard/RightKeyboard.csproj b/RightKeyboard/RightKeyboard.csproj index 5b21953..ddd8a43 100644 --- a/RightKeyboard/RightKeyboard.csproj +++ b/RightKeyboard/RightKeyboard.csproj @@ -80,6 +80,7 @@ Resources.resx True + SettingsSingleFileGenerator Settings.Designer.cs diff --git a/RightKeyboard/app.config b/RightKeyboard/app.config new file mode 100644 index 0000000..c8033d7 --- /dev/null +++ b/RightKeyboard/app.config @@ -0,0 +1,15 @@ + + + + +
+ + + + + + + + + + From f9f1b5b85cd244f33686ccd9ba0e61cc4d5fb51e Mon Sep 17 00:00:00 2001 From: Pof Magicfingers Date: Wed, 1 Sep 2021 11:31:59 +0200 Subject: [PATCH 3/5] feat: Add support for unconventional keyboard layouts (us-intl, dvorak, etc) --- .gitignore | 838 ++++++++++++++++++ RightKeyboard/LayoutSelectionDialog.cs | 58 +- RightKeyboard/MainForm.Designer.cs | 98 +- RightKeyboard/MainForm.cs | 17 +- RightKeyboard/MainForm.resx | 512 +++++------ .../Properties/Resources.Designer.cs | 26 +- RightKeyboard/Properties/Settings.Designer.cs | 10 +- RightKeyboard/RightKeyboard.csproj | 2 +- RightKeyboard/app.config | 8 +- 9 files changed, 1213 insertions(+), 356 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5d8a7d4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,838 @@ + + +# Created by https://www.toptal.com/developers/gitignore/api/windows,visualstudio + +# Edit at https://www.toptal.com/developers/gitignore?templates=windows,visualstudio + + + +### Windows ### + +# Windows thumbnail cache files + +Thumbs.db + +Thumbs.db:encryptable + +ehthumbs.db + +ehthumbs_vista.db + + + +# Dump file + +*.stackdump + + + +# Folder config file + +[Dd]esktop.ini + + + +# Recycle Bin used on file shares + +$RECYCLE.BIN/ + + + +# Windows Installer files + +*.cab + +*.msi + +*.msix + +*.msm + +*.msp + + + +# Windows shortcuts + +*.lnk + + + +### VisualStudio ### + +## Ignore Visual Studio temporary files, build results, and + +## files generated by popular Visual Studio add-ons. + +## + +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + + + +# User-specific files + +*.rsuser + +*.suo + +*.user + +*.userosscache + +*.sln.docstates + + + +# User-specific files (MonoDevelop/Xamarin Studio) + +*.userprefs + + + +# Mono auto generated files + +mono_crash.* + + + +# Build results + +[Dd]ebug/ + +[Dd]ebugPublic/ + +[Rr]elease/ + +[Rr]eleases/ + +x64/ + +x86/ + +[Ww][Ii][Nn]32/ + +[Aa][Rr][Mm]/ + +[Aa][Rr][Mm]64/ + +bld/ + +[Bb]in/ + +[Oo]bj/ + +[Ll]og/ + +[Ll]ogs/ + + + +# Visual Studio 2015/2017 cache/options directory + +.vs/ + +# Uncomment if you have tasks that create the project's static files in wwwroot + +#wwwroot/ + + + +# Visual Studio 2017 auto generated files + +Generated\ Files/ + + + +# MSTest test Results + +[Tt]est[Rr]esult*/ + +[Bb]uild[Ll]og.* + + + +# NUnit + +*.VisualState.xml + +TestResult.xml + +nunit-*.xml + + + +# Build Results of an ATL Project + +[Dd]ebugPS/ + +[Rr]eleasePS/ + +dlldata.c + + + +# Benchmark Results + +BenchmarkDotNet.Artifacts/ + + + +# .NET Core + +project.lock.json + +project.fragment.lock.json + +artifacts/ + + + +# ASP.NET Scaffolding + +ScaffoldingReadMe.txt + + + +# StyleCop + +StyleCopReport.xml + + + +# Files built by Visual Studio + +*_i.c + +*_p.c + +*_h.h + +*.ilk + +*.meta + +*.obj + +*.iobj + +*.pch + +*.pdb + +*.ipdb + +*.pgc + +*.pgd + +*.rsp + +*.sbr + +*.tlb + +*.tli + +*.tlh + +*.tmp + +*.tmp_proj + +*_wpftmp.csproj + +*.log + +*.tlog + +*.vspscc + +*.vssscc + +.builds + +*.pidb + +*.svclog + +*.scc + + + +# Chutzpah Test files + +_Chutzpah* + + + +# Visual C++ cache files + +ipch/ + +*.aps + +*.ncb + +*.opendb + +*.opensdf + +*.sdf + +*.cachefile + +*.VC.db + +*.VC.VC.opendb + + + +# Visual Studio profiler + +*.psess + +*.vsp + +*.vspx + +*.sap + + + +# Visual Studio Trace Files + +*.e2e + + + +# TFS 2012 Local Workspace + +$tf/ + + + +# Guidance Automation Toolkit + +*.gpState + + + +# ReSharper is a .NET coding add-in + +_ReSharper*/ + +*.[Rr]e[Ss]harper + +*.DotSettings.user + + + +# TeamCity is a build add-in + +_TeamCity* + + + +# DotCover is a Code Coverage Tool + +*.dotCover + + + +# AxoCover is a Code Coverage Tool + +.axoCover/* + +!.axoCover/settings.json + + + +# Coverlet is a free, cross platform Code Coverage Tool + +coverage*.json + +coverage*.xml + +coverage*.info + + + +# Visual Studio code coverage results + +*.coverage + +*.coveragexml + + + +# NCrunch + +_NCrunch_* + +.*crunch*.local.xml + +nCrunchTemp_* + + + +# MightyMoose + +*.mm.* + +AutoTest.Net/ + + + +# Web workbench (sass) + +.sass-cache/ + + + +# Installshield output folder + +[Ee]xpress/ + + + +# DocProject is a documentation generator add-in + +DocProject/buildhelp/ + +DocProject/Help/*.HxT + +DocProject/Help/*.HxC + +DocProject/Help/*.hhc + +DocProject/Help/*.hhk + +DocProject/Help/*.hhp + +DocProject/Help/Html2 + +DocProject/Help/html + + + +# Click-Once directory + +publish/ + + + +# Publish Web Output + +*.[Pp]ublish.xml + +*.azurePubxml + +# Note: Comment the next line if you want to checkin your web deploy settings, + +# but database connection strings (with potential passwords) will be unencrypted + +*.pubxml + +*.publishproj + + + +# Microsoft Azure Web App publish settings. Comment the next line if you want to + +# checkin your Azure Web App publish settings, but sensitive information contained + +# in these scripts will be unencrypted + +PublishScripts/ + + + +# NuGet Packages + +*.nupkg + +# NuGet Symbol Packages + +*.snupkg + +# The packages folder can be ignored because of Package Restore + +**/[Pp]ackages/* + +# except build/, which is used as an MSBuild target. + +!**/[Pp]ackages/build/ + +# Uncomment if necessary however generally it will be regenerated when needed + +#!**/[Pp]ackages/repositories.config + +# NuGet v3's project.json files produces more ignorable files + +*.nuget.props + +*.nuget.targets + + + +# Nuget personal access tokens and Credentials + +nuget.config + + + +# Microsoft Azure Build Output + +csx/ + +*.build.csdef + + + +# Microsoft Azure Emulator + +ecf/ + +rcf/ + + + +# Windows Store app package directories and files + +AppPackages/ + +BundleArtifacts/ + +Package.StoreAssociation.xml + +_pkginfo.txt + +*.appx + +*.appxbundle + +*.appxupload + + + +# Visual Studio cache files + +# files ending in .cache can be ignored + +*.[Cc]ache + +# but keep track of directories ending in .cache + +!?*.[Cc]ache/ + + + +# Others + +ClientBin/ + +~$* + +*~ + +*.dbmdl + +*.dbproj.schemaview + +*.jfm + +*.pfx + +*.publishsettings + +orleans.codegen.cs + + + +# Including strong name files can present a security risk + +# (https://github.com/github/gitignore/pull/2483#issue-259490424) + +#*.snk + + + +# Since there are multiple workflows, uncomment next line to ignore bower_components + +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) + +#bower_components/ + + + +# RIA/Silverlight projects + +Generated_Code/ + + + +# Backup & report files from converting an old project file + +# to a newer Visual Studio version. Backup files are not needed, + +# because we have git ;-) + +_UpgradeReport_Files/ + +Backup*/ + +UpgradeLog*.XML + +UpgradeLog*.htm + +ServiceFabricBackup/ + +*.rptproj.bak + + + +# SQL Server files + +*.mdf + +*.ldf + +*.ndf + + + +# Business Intelligence projects + +*.rdl.data + +*.bim.layout + +*.bim_*.settings + +*.rptproj.rsuser + +*- [Bb]ackup.rdl + +*- [Bb]ackup ([0-9]).rdl + +*- [Bb]ackup ([0-9][0-9]).rdl + + + +# Microsoft Fakes + +FakesAssemblies/ + + + +# GhostDoc plugin setting file + +*.GhostDoc.xml + + + +# Node.js Tools for Visual Studio + +.ntvs_analysis.dat + +node_modules/ + + + +# Visual Studio 6 build log + +*.plg + + + +# Visual Studio 6 workspace options file + +*.opt + + + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) + +*.vbw + + + +# Visual Studio LightSwitch build output + +**/*.HTMLClient/GeneratedArtifacts + +**/*.DesktopClient/GeneratedArtifacts + +**/*.DesktopClient/ModelManifest.xml + +**/*.Server/GeneratedArtifacts + +**/*.Server/ModelManifest.xml + +_Pvt_Extensions + + + +# Paket dependency manager + +.paket/paket.exe + +paket-files/ + + + +# FAKE - F# Make + +.fake/ + + + +# CodeRush personal settings + +.cr/personal + + + +# Python Tools for Visual Studio (PTVS) + +__pycache__/ + +*.pyc + + + +# Cake - Uncomment if you are using it + +# tools/** + +# !tools/packages.config + + + +# Tabs Studio + +*.tss + + + +# Telerik's JustMock configuration file + +*.jmconfig + + + +# BizTalk build output + +*.btp.cs + +*.btm.cs + +*.odx.cs + +*.xsd.cs + + + +# OpenCover UI analysis results + +OpenCover/ + + + +# Azure Stream Analytics local run output + +ASALocalRun/ + + + +# MSBuild Binary and Structured Log + +*.binlog + + + +# NVidia Nsight GPU debugger configuration file + +*.nvuser + + + +# MFractors (Xamarin productivity tool) working folder + +.mfractor/ + + + +# Local History for Visual Studio + +.localhistory/ + + + +# BeatPulse healthcheck temp database + +healthchecksdb + + + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 + +MigrationBackup/ + + + +# Ionide (cross platform F# VS Code tools) working folder + +.ionide/ + + + +# Fody - auto-generated XML schema + +FodyWeavers.xsd + + + +# VS Code files for those working on multiple tools + +.vscode/* + +!.vscode/settings.json + +!.vscode/tasks.json + +!.vscode/launch.json + +!.vscode/extensions.json + +*.code-workspace + + + +# Local History for Visual Studio Code + +.history/ + + + +# Windows Installer files from build outputs + + + +# JetBrains Rider + +.idea/ + +*.sln.iml + + + +### VisualStudio Patch ### + +# Additional files built by Visual Studio + + + +# End of https://www.toptal.com/developers/gitignore/api/windows,visualstudio + diff --git a/RightKeyboard/LayoutSelectionDialog.cs b/RightKeyboard/LayoutSelectionDialog.cs index 2501800..de53b32 100644 --- a/RightKeyboard/LayoutSelectionDialog.cs +++ b/RightKeyboard/LayoutSelectionDialog.cs @@ -3,6 +3,7 @@ using System.Windows.Forms; using RightKeyboard.Win32; using System.Linq; +using Microsoft.Win32; namespace RightKeyboard { public partial class LayoutSelectionDialog : Form { @@ -22,38 +23,51 @@ private void LoadLanguageList() { foreach (var item in layoutCodes) { - // Get layout name - var key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\Keyboard Layouts\0000" + - item.ToString("X4")); - - string name; + string layout_id = item.ToString("X4"); + + RegistryKey key = null; + + // If we're using "advanced" keyboard layouts (us-intl, dvorak, etc) + if (layout_id.First() == 'F') + { + string real_layout_id = "0"+layout_id.Substring(1); + + RegistryKey all_layouts = Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\Keyboard Layouts"); + + // Get layout with layout id search + foreach (string key_name in all_layouts.GetSubKeyNames()) + { + key = all_layouts.OpenSubKey(key_name); + + if (key == null) { + continue; + } + + if(key.GetValue("Layout Id", "").ToString() == real_layout_id) + { + break; + } + } + } + else + { + // Get layout name directly + key = Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\Keyboard Layouts\0000" + layout_id); + } + + string name; if (key == null) - name = "Unknown " + item.ToString("X4"); + name = "Unknown " + layout_id; else name = key.GetValue("Layout Text").ToString(); var layout = new Layout((ushort)item, name); + // Need full hkl, if there are several for a layout here we just take one, // we can improve this by also having the language selection somehow... layout.Hkl = installedLayouts.First(h => ((h.ToInt32() >> 16) & 0xffff) == item); lbLayouts.Items.Add(layout); } - // var layouts = Layout.GetLayouts(); - - // foreach (IntPtr installedLayout in installedLayouts) - // { - // ushort languageId = unchecked((ushort)installedLayout.ToInt32()); - - // var layout = layouts.FirstOrDefault(l => l.Identifier == languageId); - - // if (layout != null) - // { - // layout.Hkl = installedLayout; - // lbLayouts.Items.Add(layout); - // } - // } - - //lbLayouts.SelectedIndex = 0; } private int recentLayoutsCount = 0; diff --git a/RightKeyboard/MainForm.Designer.cs b/RightKeyboard/MainForm.Designer.cs index 01bfaaa..a748e69 100644 --- a/RightKeyboard/MainForm.Designer.cs +++ b/RightKeyboard/MainForm.Designer.cs @@ -23,54 +23,64 @@ protected override void Dispose(bool disposing) { /// the contents of this method with the code editor. /// private void InitializeComponent() { - this.components = new System.ComponentModel.Container(); - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); - this.notifyIcon = new System.Windows.Forms.NotifyIcon(this.components); - this.contextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components); - this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.contextMenuStrip.SuspendLayout(); - this.SuspendLayout(); - // - // notifyIcon - // - this.notifyIcon.ContextMenuStrip = this.contextMenuStrip; - this.notifyIcon.Icon = ((System.Drawing.Icon)(resources.GetObject("notifyIcon.Icon"))); - this.notifyIcon.Text = "RightKeyboard (Right-click this icon to close)"; - this.notifyIcon.Visible = true; - // - // contextMenuStrip - // - this.contextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.exitToolStripMenuItem}); - this.contextMenuStrip.Name = "contextMenuStrip"; - this.contextMenuStrip.Size = new System.Drawing.Size(104, 26); - // - // exitToolStripMenuItem - // - this.exitToolStripMenuItem.Name = "exitToolStripMenuItem"; - this.exitToolStripMenuItem.Size = new System.Drawing.Size(103, 22); - this.exitToolStripMenuItem.Text = "&Exit"; - this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click); - // - // MainForm - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(206, 122); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; - this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); - this.Name = "MainForm"; - this.ShowInTaskbar = false; - this.Text = "RightKeyboard"; - this.contextMenuStrip.ResumeLayout(false); - this.ResumeLayout(false); - + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); + this.notifyIcon = new System.Windows.Forms.NotifyIcon(this.components); + this.contextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components); + this.resetConfigurationToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.contextMenuStrip.SuspendLayout(); + this.SuspendLayout(); + // + // notifyIcon + // + this.notifyIcon.ContextMenuStrip = this.contextMenuStrip; + this.notifyIcon.Icon = ((System.Drawing.Icon)(resources.GetObject("notifyIcon.Icon"))); + this.notifyIcon.Text = "RightKeyboard"; + this.notifyIcon.Visible = true; + // + // contextMenuStrip + // + this.contextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.resetConfigurationToolStripMenuItem, + this.exitToolStripMenuItem}); + this.contextMenuStrip.Name = "contextMenuStrip"; + this.contextMenuStrip.Size = new System.Drawing.Size(178, 48); + // + // resetConfigurationToolStripMenuItem + // + this.resetConfigurationToolStripMenuItem.Name = "resetConfigurationToolStripMenuItem"; + this.resetConfigurationToolStripMenuItem.Size = new System.Drawing.Size(177, 22); + this.resetConfigurationToolStripMenuItem.Text = "Reset &configuration"; + this.resetConfigurationToolStripMenuItem.Click += new System.EventHandler(this.resetConfigurationToolStripMenuItem_Click); + // + // exitToolStripMenuItem + // + this.exitToolStripMenuItem.Name = "exitToolStripMenuItem"; + this.exitToolStripMenuItem.Size = new System.Drawing.Size(177, 22); + this.exitToolStripMenuItem.Text = "&Exit"; + this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click); + // + // MainForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(206, 122); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "MainForm"; + this.ShowInTaskbar = false; + this.Text = "RightKeyboard"; + this.contextMenuStrip.ResumeLayout(false); + this.ResumeLayout(false); + } #endregion private System.Windows.Forms.NotifyIcon notifyIcon; private System.Windows.Forms.ContextMenuStrip contextMenuStrip; - private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem; - } + private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem resetConfigurationToolStripMenuItem; + } } \ No newline at end of file diff --git a/RightKeyboard/MainForm.cs b/RightKeyboard/MainForm.cs index 33093b3..53cdc2d 100644 --- a/RightKeyboard/MainForm.cs +++ b/RightKeyboard/MainForm.cs @@ -249,25 +249,20 @@ private void SetCurrentLayout(IntPtr layout) private bool SetDefaultLayout(IntPtr hkl) { - //IntPtr hkl = new IntPtr(unchecked((int)((uint)layout << 16 | (uint)layout))); - bool ok = API.SystemParametersInfo(API.SPI_SETDEFAULTINPUTLANG, 0, new[] { hkl }, API.SPIF_SENDCHANGE); uint er = API.GetLastError(); return ok; } - //private void SetDefaultLayout(ushort layout) - //{ - // IntPtr hkl = new IntPtr(unchecked((int)((uint)layout << 16 | (uint)layout))); - - // bool ok = API.SystemParametersInfo(API.SPI_SETDEFAULTINPUTLANG, 0, new[] { hkl }, API.SPIF_SENDCHANGE); - // uint er = API.GetLastError(); - // Debug.Assert(ok); - //} - private void exitToolStripMenuItem_Click(object sender, EventArgs e) { Close(); } + + private void resetConfigurationToolStripMenuItem_Click(object sender, EventArgs e) + { + languageMappings.Clear(); + SaveConfiguration(); + } } } \ No newline at end of file diff --git a/RightKeyboard/MainForm.resx b/RightKeyboard/MainForm.resx index a01e4dd..293d4f5 100644 --- a/RightKeyboard/MainForm.resx +++ b/RightKeyboard/MainForm.resx @@ -1,257 +1,257 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 17, 17 - - - 118, 17 - - - - - AAABAAIAEBAAAAAACABoBQAAJgAAACAgAAAAAAgAqAgAAI4FAAAoAAAAEAAAACAAAAABAAgAAAAAAAAB - AAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAMDAwADA3MAA8MqmAAQE - BAAICAgADAwMABEREQAWFhYAHBwcACIiIgApKSkAVVVVAE1NTQBCQkIAOTk5AIB8/wBQUP8AkwDWAP/s - zADG1u8A1ufnAJCprQAAADMAAABmAAAAmQAAAMwAADMAAAAzMwAAM2YAADOZAAAzzAAAM/8AAGYAAABm - MwAAZmYAAGaZAABmzAAAZv8AAJkAAACZMwAAmWYAAJmZAACZzAAAmf8AAMwAAADMMwAAzGYAAMyZAADM - zAAAzP8AAP9mAAD/mQAA/8wAMwAAADMAMwAzAGYAMwCZADMAzAAzAP8AMzMAADMzMwAzM2YAMzOZADMz - zAAzM/8AM2YAADNmMwAzZmYAM2aZADNmzAAzZv8AM5kAADOZMwAzmWYAM5mZADOZzAAzmf8AM8wAADPM - MwAzzGYAM8yZADPMzAAzzP8AM/8zADP/ZgAz/5kAM//MADP//wBmAAAAZgAzAGYAZgBmAJkAZgDMAGYA - /wBmMwAAZjMzAGYzZgBmM5kAZjPMAGYz/wBmZgAAZmYzAGZmZgBmZpkAZmbMAGaZAABmmTMAZplmAGaZ - mQBmmcwAZpn/AGbMAABmzDMAZsyZAGbMzABmzP8AZv8AAGb/MwBm/5kAZv/MAMwA/wD/AMwAmZkAAJkz - mQCZAJkAmQDMAJkAAACZMzMAmQBmAJkzzACZAP8AmWYAAJlmMwCZM2YAmWaZAJlmzACZM/8AmZkzAJmZ - ZgCZmZkAmZnMAJmZ/wCZzAAAmcwzAGbMZgCZzJkAmczMAJnM/wCZ/wAAmf8zAJnMZgCZ/5kAmf/MAJn/ - /wDMAAAAmQAzAMwAZgDMAJkAzADMAJkzAADMMzMAzDNmAMwzmQDMM8wAzDP/AMxmAADMZjMAmWZmAMxm - mQDMZswAmWb/AMyZAADMmTMAzJlmAMyZmQDMmcwAzJn/AMzMAADMzDMAzMxmAMzMmQDMzMwAzMz/AMz/ - AADM/zMAmf9mAMz/mQDM/8wAzP//AMwAMwD/AGYA/wCZAMwzAAD/MzMA/zNmAP8zmQD/M8wA/zP/AP9m - AAD/ZjMAzGZmAP9mmQD/ZswAzGb/AP+ZAAD/mTMA/5lmAP+ZmQD/mcwA/5n/AP/MAAD/zDMA/8xmAP/M - mQD/zMwA/8z/AP//MwDM/2YA//+ZAP//zABmZv8AZv9mAGb//wD/ZmYA/2b/AP//ZgAhAKUAX19fAHd3 - dwCGhoYAlpaWAMvLywCysrIA19fXAN3d3QDj4+MA6urqAPHx8QD4+PgA8Pv/AKSgoACAgIAAAAD/AAD/ - AAAA//8A/wAAAP8A/wD//wAA////AAoKCgoKCgoKCgoKCgoKCgoKQw4ODg4ODg4ODg4ODg4KFbvt7e3t - 7e3t7e3t7e3tChT0u7y7vLu8u7y7vLu8u0MUwuwV7BXsFXMV7BXsFZhDFPSS7O3s7XPt7O3s7eyYQxTC - 6xXsQ+wV7EPsFewVmEMU/7uSwpLCmMKYwpLCkrtDFcLCwsLCwsLCwsLCwsKYQwoiIiIiIiIiIiIiIiIi - DgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK - CgoKCgoKCgoKChQKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgr//wAAgAEAAAABAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAACAAQAA//sAAPqrAAD1VwAA9/8AAPf/AAD//wAAKAAAACAAAABAAAAAAQAIAAAA - AAAABAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAIAAAIAAAACAgACAAAAAgACAAICAAADAwMAAwNzAAPDK - pgAEBAQACAgIAAwMDAAREREAFhYWABwcHAAiIiIAKSkpAFVVVQBNTU0AQkJCADk5OQCAfP8AUFD/AJMA - 1gD/7MwAxtbvANbn5wCQqa0AAAAzAAAAZgAAAJkAAADMAAAzAAAAMzMAADNmAAAzmQAAM8wAADP/AABm - AAAAZjMAAGZmAABmmQAAZswAAGb/AACZAAAAmTMAAJlmAACZmQAAmcwAAJn/AADMAAAAzDMAAMxmAADM - mQAAzMwAAMz/AAD/ZgAA/5kAAP/MADMAAAAzADMAMwBmADMAmQAzAMwAMwD/ADMzAAAzMzMAMzNmADMz - mQAzM8wAMzP/ADNmAAAzZjMAM2ZmADNmmQAzZswAM2b/ADOZAAAzmTMAM5lmADOZmQAzmcwAM5n/ADPM - AAAzzDMAM8xmADPMmQAzzMwAM8z/ADP/MwAz/2YAM/+ZADP/zAAz//8AZgAAAGYAMwBmAGYAZgCZAGYA - zABmAP8AZjMAAGYzMwBmM2YAZjOZAGYzzABmM/8AZmYAAGZmMwBmZmYAZmaZAGZmzABmmQAAZpkzAGaZ - ZgBmmZkAZpnMAGaZ/wBmzAAAZswzAGbMmQBmzMwAZsz/AGb/AABm/zMAZv+ZAGb/zADMAP8A/wDMAJmZ - AACZM5kAmQCZAJkAzACZAAAAmTMzAJkAZgCZM8wAmQD/AJlmAACZZjMAmTNmAJlmmQCZZswAmTP/AJmZ - MwCZmWYAmZmZAJmZzACZmf8AmcwAAJnMMwBmzGYAmcyZAJnMzACZzP8Amf8AAJn/MwCZzGYAmf+ZAJn/ - zACZ//8AzAAAAJkAMwDMAGYAzACZAMwAzACZMwAAzDMzAMwzZgDMM5kAzDPMAMwz/wDMZgAAzGYzAJlm - ZgDMZpkAzGbMAJlm/wDMmQAAzJkzAMyZZgDMmZkAzJnMAMyZ/wDMzAAAzMwzAMzMZgDMzJkAzMzMAMzM - /wDM/wAAzP8zAJn/ZgDM/5kAzP/MAMz//wDMADMA/wBmAP8AmQDMMwAA/zMzAP8zZgD/M5kA/zPMAP8z - /wD/ZgAA/2YzAMxmZgD/ZpkA/2bMAMxm/wD/mQAA/5kzAP+ZZgD/mZkA/5nMAP+Z/wD/zAAA/8wzAP/M - ZgD/zJkA/8zMAP/M/wD//zMAzP9mAP//mQD//8wAZmb/AGb/ZgBm//8A/2ZmAP9m/wD//2YAIQClAF9f - XwB3d3cAhoaGAJaWlgDLy8sAsrKyANfX1wDd3d0A4+PjAOrq6gDx8fEA+Pj4APD7/wCkoKAAgICAAAAA - /wAA/wAAAP//AP8AAAD/AP8A//8AAP///wAKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK - CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK - CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCuzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs - 7Ozs7OwK7P/sCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK7Ars/+wHBwcHCgcHCgcHBwcHBwcHBwcH - CgcHCgcHBwrsCuz/7P///wcK/wcK/////////////wcK/wcK//8HCuwK7P/sCgoKCgoKCgoKCgoKCgoK - CgoKCgoKCgoKCgoK7Ars/+wHBwoHBwoHBwoHBwoHBwoHBwoHBwoHBwcHBwrsCuz/7P//Cv8HCv8HCv8H - Cv8HCv8HCv8HCv////8HCuwK7P/sCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK7Ars/+wHBwcHCgcH - CgcHCgcHCgcHCgcHCgcHCgcHBwrsCuz/7P///wcK/wcK/wcK/wcK/wcK/wcK/wcK/wcHCuwK7P/sCgoK - CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK7Ars/+wHBwoHBwoHBwoHBwoHBwoHBwoHBwoHBwoHBwrsCuz/ - 7P8HCv8HCv8HCv8HCv8HCv8HCv8HCv8HCv8HCuwK7P/s7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs - 7Ars///////////////////////////////////////sCgrs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs - 7Ozs7OwKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK - CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK - CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK - CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK - CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK+woKCgoKCgoKCgoKCgoKCgoK - CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK - CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK////////////////gAAAAQAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAHf////3////+SS - SH/5JJO/////v////7////x////z////4/////f///////////8= - - - - - AAABAAIAEBAAAAAACABoBQAAJgAAACAgAAAAAAgAqAgAAI4FAAAoAAAAEAAAACAAAAABAAgAAAAAAAAB - AAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAMDAwADA3MAA8MqmAAQE - BAAICAgADAwMABEREQAWFhYAHBwcACIiIgApKSkAVVVVAE1NTQBCQkIAOTk5AIB8/wBQUP8AkwDWAP/s - zADG1u8A1ufnAJCprQAAADMAAABmAAAAmQAAAMwAADMAAAAzMwAAM2YAADOZAAAzzAAAM/8AAGYAAABm - MwAAZmYAAGaZAABmzAAAZv8AAJkAAACZMwAAmWYAAJmZAACZzAAAmf8AAMwAAADMMwAAzGYAAMyZAADM - zAAAzP8AAP9mAAD/mQAA/8wAMwAAADMAMwAzAGYAMwCZADMAzAAzAP8AMzMAADMzMwAzM2YAMzOZADMz - zAAzM/8AM2YAADNmMwAzZmYAM2aZADNmzAAzZv8AM5kAADOZMwAzmWYAM5mZADOZzAAzmf8AM8wAADPM - MwAzzGYAM8yZADPMzAAzzP8AM/8zADP/ZgAz/5kAM//MADP//wBmAAAAZgAzAGYAZgBmAJkAZgDMAGYA - /wBmMwAAZjMzAGYzZgBmM5kAZjPMAGYz/wBmZgAAZmYzAGZmZgBmZpkAZmbMAGaZAABmmTMAZplmAGaZ - mQBmmcwAZpn/AGbMAABmzDMAZsyZAGbMzABmzP8AZv8AAGb/MwBm/5kAZv/MAMwA/wD/AMwAmZkAAJkz - mQCZAJkAmQDMAJkAAACZMzMAmQBmAJkzzACZAP8AmWYAAJlmMwCZM2YAmWaZAJlmzACZM/8AmZkzAJmZ - ZgCZmZkAmZnMAJmZ/wCZzAAAmcwzAGbMZgCZzJkAmczMAJnM/wCZ/wAAmf8zAJnMZgCZ/5kAmf/MAJn/ - /wDMAAAAmQAzAMwAZgDMAJkAzADMAJkzAADMMzMAzDNmAMwzmQDMM8wAzDP/AMxmAADMZjMAmWZmAMxm - mQDMZswAmWb/AMyZAADMmTMAzJlmAMyZmQDMmcwAzJn/AMzMAADMzDMAzMxmAMzMmQDMzMwAzMz/AMz/ - AADM/zMAmf9mAMz/mQDM/8wAzP//AMwAMwD/AGYA/wCZAMwzAAD/MzMA/zNmAP8zmQD/M8wA/zP/AP9m - AAD/ZjMAzGZmAP9mmQD/ZswAzGb/AP+ZAAD/mTMA/5lmAP+ZmQD/mcwA/5n/AP/MAAD/zDMA/8xmAP/M - mQD/zMwA/8z/AP//MwDM/2YA//+ZAP//zABmZv8AZv9mAGb//wD/ZmYA/2b/AP//ZgAhAKUAX19fAHd3 - dwCGhoYAlpaWAMvLywCysrIA19fXAN3d3QDj4+MA6urqAPHx8QD4+PgA8Pv/AKSgoACAgIAAAAD/AAD/ - AAAA//8A/wAAAP8A/wD//wAA////AAoKCgoKCgoKCgoKCgoKCgoKQw4ODg4ODg4ODg4ODg4KFbvt7e3t - 7e3t7e3t7e3tChT0u7y7vLu8u7y7vLu8u0MUwuwV7BXsFXMV7BXsFZhDFPSS7O3s7XPt7O3s7eyYQxTC - 6xXsQ+wV7EPsFewVmEMU/7uSwpLCmMKYwpLCkrtDFcLCwsLCwsLCwsLCwsKYQwoiIiIiIiIiIiIiIiIi - DgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK - CgoKCgoKCgoKChQKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgr//wAAgAEAAAABAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAACAAQAA//sAAPqrAAD1VwAA9/8AAPf/AAD//wAAKAAAACAAAABAAAAAAQAIAAAA - AAAABAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAIAAAIAAAACAgACAAAAAgACAAICAAADAwMAAwNzAAPDK - pgAEBAQACAgIAAwMDAAREREAFhYWABwcHAAiIiIAKSkpAFVVVQBNTU0AQkJCADk5OQCAfP8AUFD/AJMA - 1gD/7MwAxtbvANbn5wCQqa0AAAAzAAAAZgAAAJkAAADMAAAzAAAAMzMAADNmAAAzmQAAM8wAADP/AABm - AAAAZjMAAGZmAABmmQAAZswAAGb/AACZAAAAmTMAAJlmAACZmQAAmcwAAJn/AADMAAAAzDMAAMxmAADM - mQAAzMwAAMz/AAD/ZgAA/5kAAP/MADMAAAAzADMAMwBmADMAmQAzAMwAMwD/ADMzAAAzMzMAMzNmADMz - mQAzM8wAMzP/ADNmAAAzZjMAM2ZmADNmmQAzZswAM2b/ADOZAAAzmTMAM5lmADOZmQAzmcwAM5n/ADPM - AAAzzDMAM8xmADPMmQAzzMwAM8z/ADP/MwAz/2YAM/+ZADP/zAAz//8AZgAAAGYAMwBmAGYAZgCZAGYA - zABmAP8AZjMAAGYzMwBmM2YAZjOZAGYzzABmM/8AZmYAAGZmMwBmZmYAZmaZAGZmzABmmQAAZpkzAGaZ - ZgBmmZkAZpnMAGaZ/wBmzAAAZswzAGbMmQBmzMwAZsz/AGb/AABm/zMAZv+ZAGb/zADMAP8A/wDMAJmZ - AACZM5kAmQCZAJkAzACZAAAAmTMzAJkAZgCZM8wAmQD/AJlmAACZZjMAmTNmAJlmmQCZZswAmTP/AJmZ - MwCZmWYAmZmZAJmZzACZmf8AmcwAAJnMMwBmzGYAmcyZAJnMzACZzP8Amf8AAJn/MwCZzGYAmf+ZAJn/ - zACZ//8AzAAAAJkAMwDMAGYAzACZAMwAzACZMwAAzDMzAMwzZgDMM5kAzDPMAMwz/wDMZgAAzGYzAJlm - ZgDMZpkAzGbMAJlm/wDMmQAAzJkzAMyZZgDMmZkAzJnMAMyZ/wDMzAAAzMwzAMzMZgDMzJkAzMzMAMzM - /wDM/wAAzP8zAJn/ZgDM/5kAzP/MAMz//wDMADMA/wBmAP8AmQDMMwAA/zMzAP8zZgD/M5kA/zPMAP8z - /wD/ZgAA/2YzAMxmZgD/ZpkA/2bMAMxm/wD/mQAA/5kzAP+ZZgD/mZkA/5nMAP+Z/wD/zAAA/8wzAP/M - ZgD/zJkA/8zMAP/M/wD//zMAzP9mAP//mQD//8wAZmb/AGb/ZgBm//8A/2ZmAP9m/wD//2YAIQClAF9f - XwB3d3cAhoaGAJaWlgDLy8sAsrKyANfX1wDd3d0A4+PjAOrq6gDx8fEA+Pj4APD7/wCkoKAAgICAAAAA - /wAA/wAAAP//AP8AAAD/AP8A//8AAP///wAKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK - CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK - CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCuzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs - 7Ozs7OwK7P/sCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK7Ars/+wHBwcHCgcHCgcHBwcHBwcHBwcH - CgcHCgcHBwrsCuz/7P///wcK/wcK/////////////wcK/wcK//8HCuwK7P/sCgoKCgoKCgoKCgoKCgoK - CgoKCgoKCgoKCgoK7Ars/+wHBwoHBwoHBwoHBwoHBwoHBwoHBwoHBwcHBwrsCuz/7P//Cv8HCv8HCv8H - Cv8HCv8HCv8HCv////8HCuwK7P/sCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK7Ars/+wHBwcHCgcH - CgcHCgcHCgcHCgcHCgcHCgcHBwrsCuz/7P///wcK/wcK/wcK/wcK/wcK/wcK/wcK/wcHCuwK7P/sCgoK - CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK7Ars/+wHBwoHBwoHBwoHBwoHBwoHBwoHBwoHBwoHBwrsCuz/ - 7P8HCv8HCv8HCv8HCv8HCv8HCv8HCv8HCv8HCuwK7P/s7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs - 7Ars///////////////////////////////////////sCgrs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs - 7Ozs7OwKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK - CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK - CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK - CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK - CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK+woKCgoKCgoKCgoKCgoKCgoK - CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK - CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK////////////////gAAAAQAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAHf////3////+SS - SH/5JJO/////v////7////x////z////4/////f///////////8= - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 118, 17 + + + + + AAABAAIAEBAAAAAACABoBQAAJgAAACAgAAAAAAgAqAgAAI4FAAAoAAAAEAAAACAAAAABAAgAAAAAAAAB + AAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAMDAwADA3MAA8MqmAAQE + BAAICAgADAwMABEREQAWFhYAHBwcACIiIgApKSkAVVVVAE1NTQBCQkIAOTk5AIB8/wBQUP8AkwDWAP/s + zADG1u8A1ufnAJCprQAAADMAAABmAAAAmQAAAMwAADMAAAAzMwAAM2YAADOZAAAzzAAAM/8AAGYAAABm + MwAAZmYAAGaZAABmzAAAZv8AAJkAAACZMwAAmWYAAJmZAACZzAAAmf8AAMwAAADMMwAAzGYAAMyZAADM + zAAAzP8AAP9mAAD/mQAA/8wAMwAAADMAMwAzAGYAMwCZADMAzAAzAP8AMzMAADMzMwAzM2YAMzOZADMz + zAAzM/8AM2YAADNmMwAzZmYAM2aZADNmzAAzZv8AM5kAADOZMwAzmWYAM5mZADOZzAAzmf8AM8wAADPM + MwAzzGYAM8yZADPMzAAzzP8AM/8zADP/ZgAz/5kAM//MADP//wBmAAAAZgAzAGYAZgBmAJkAZgDMAGYA + /wBmMwAAZjMzAGYzZgBmM5kAZjPMAGYz/wBmZgAAZmYzAGZmZgBmZpkAZmbMAGaZAABmmTMAZplmAGaZ + mQBmmcwAZpn/AGbMAABmzDMAZsyZAGbMzABmzP8AZv8AAGb/MwBm/5kAZv/MAMwA/wD/AMwAmZkAAJkz + mQCZAJkAmQDMAJkAAACZMzMAmQBmAJkzzACZAP8AmWYAAJlmMwCZM2YAmWaZAJlmzACZM/8AmZkzAJmZ + ZgCZmZkAmZnMAJmZ/wCZzAAAmcwzAGbMZgCZzJkAmczMAJnM/wCZ/wAAmf8zAJnMZgCZ/5kAmf/MAJn/ + /wDMAAAAmQAzAMwAZgDMAJkAzADMAJkzAADMMzMAzDNmAMwzmQDMM8wAzDP/AMxmAADMZjMAmWZmAMxm + mQDMZswAmWb/AMyZAADMmTMAzJlmAMyZmQDMmcwAzJn/AMzMAADMzDMAzMxmAMzMmQDMzMwAzMz/AMz/ + AADM/zMAmf9mAMz/mQDM/8wAzP//AMwAMwD/AGYA/wCZAMwzAAD/MzMA/zNmAP8zmQD/M8wA/zP/AP9m + AAD/ZjMAzGZmAP9mmQD/ZswAzGb/AP+ZAAD/mTMA/5lmAP+ZmQD/mcwA/5n/AP/MAAD/zDMA/8xmAP/M + mQD/zMwA/8z/AP//MwDM/2YA//+ZAP//zABmZv8AZv9mAGb//wD/ZmYA/2b/AP//ZgAhAKUAX19fAHd3 + dwCGhoYAlpaWAMvLywCysrIA19fXAN3d3QDj4+MA6urqAPHx8QD4+PgA8Pv/AKSgoACAgIAAAAD/AAD/ + AAAA//8A/wAAAP8A/wD//wAA////AAoKCgoKCgoKCgoKCgoKCgoKQw4ODg4ODg4ODg4ODg4KFbvt7e3t + 7e3t7e3t7e3tChT0u7y7vLu8u7y7vLu8u0MUwuwV7BXsFXMV7BXsFZhDFPSS7O3s7XPt7O3s7eyYQxTC + 6xXsQ+wV7EPsFewVmEMU/7uSwpLCmMKYwpLCkrtDFcLCwsLCwsLCwsLCwsKYQwoiIiIiIiIiIiIiIiIi + DgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK + CgoKCgoKCgoKChQKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgr//wAAgAEAAAABAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACAAQAA//sAAPqrAAD1VwAA9/8AAPf/AAD//wAAKAAAACAAAABAAAAAAQAIAAAA + AAAABAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAIAAAIAAAACAgACAAAAAgACAAICAAADAwMAAwNzAAPDK + pgAEBAQACAgIAAwMDAAREREAFhYWABwcHAAiIiIAKSkpAFVVVQBNTU0AQkJCADk5OQCAfP8AUFD/AJMA + 1gD/7MwAxtbvANbn5wCQqa0AAAAzAAAAZgAAAJkAAADMAAAzAAAAMzMAADNmAAAzmQAAM8wAADP/AABm + AAAAZjMAAGZmAABmmQAAZswAAGb/AACZAAAAmTMAAJlmAACZmQAAmcwAAJn/AADMAAAAzDMAAMxmAADM + mQAAzMwAAMz/AAD/ZgAA/5kAAP/MADMAAAAzADMAMwBmADMAmQAzAMwAMwD/ADMzAAAzMzMAMzNmADMz + mQAzM8wAMzP/ADNmAAAzZjMAM2ZmADNmmQAzZswAM2b/ADOZAAAzmTMAM5lmADOZmQAzmcwAM5n/ADPM + AAAzzDMAM8xmADPMmQAzzMwAM8z/ADP/MwAz/2YAM/+ZADP/zAAz//8AZgAAAGYAMwBmAGYAZgCZAGYA + zABmAP8AZjMAAGYzMwBmM2YAZjOZAGYzzABmM/8AZmYAAGZmMwBmZmYAZmaZAGZmzABmmQAAZpkzAGaZ + ZgBmmZkAZpnMAGaZ/wBmzAAAZswzAGbMmQBmzMwAZsz/AGb/AABm/zMAZv+ZAGb/zADMAP8A/wDMAJmZ + AACZM5kAmQCZAJkAzACZAAAAmTMzAJkAZgCZM8wAmQD/AJlmAACZZjMAmTNmAJlmmQCZZswAmTP/AJmZ + MwCZmWYAmZmZAJmZzACZmf8AmcwAAJnMMwBmzGYAmcyZAJnMzACZzP8Amf8AAJn/MwCZzGYAmf+ZAJn/ + zACZ//8AzAAAAJkAMwDMAGYAzACZAMwAzACZMwAAzDMzAMwzZgDMM5kAzDPMAMwz/wDMZgAAzGYzAJlm + ZgDMZpkAzGbMAJlm/wDMmQAAzJkzAMyZZgDMmZkAzJnMAMyZ/wDMzAAAzMwzAMzMZgDMzJkAzMzMAMzM + /wDM/wAAzP8zAJn/ZgDM/5kAzP/MAMz//wDMADMA/wBmAP8AmQDMMwAA/zMzAP8zZgD/M5kA/zPMAP8z + /wD/ZgAA/2YzAMxmZgD/ZpkA/2bMAMxm/wD/mQAA/5kzAP+ZZgD/mZkA/5nMAP+Z/wD/zAAA/8wzAP/M + ZgD/zJkA/8zMAP/M/wD//zMAzP9mAP//mQD//8wAZmb/AGb/ZgBm//8A/2ZmAP9m/wD//2YAIQClAF9f + XwB3d3cAhoaGAJaWlgDLy8sAsrKyANfX1wDd3d0A4+PjAOrq6gDx8fEA+Pj4APD7/wCkoKAAgICAAAAA + /wAA/wAAAP//AP8AAAD/AP8A//8AAP///wAKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK + CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK + CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCuzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs + 7Ozs7OwK7P/sCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK7Ars/+wHBwcHCgcHCgcHBwcHBwcHBwcH + CgcHCgcHBwrsCuz/7P///wcK/wcK/////////////wcK/wcK//8HCuwK7P/sCgoKCgoKCgoKCgoKCgoK + CgoKCgoKCgoKCgoK7Ars/+wHBwoHBwoHBwoHBwoHBwoHBwoHBwoHBwcHBwrsCuz/7P//Cv8HCv8HCv8H + Cv8HCv8HCv8HCv////8HCuwK7P/sCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK7Ars/+wHBwcHCgcH + CgcHCgcHCgcHCgcHCgcHCgcHBwrsCuz/7P///wcK/wcK/wcK/wcK/wcK/wcK/wcK/wcHCuwK7P/sCgoK + CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK7Ars/+wHBwoHBwoHBwoHBwoHBwoHBwoHBwoHBwoHBwrsCuz/ + 7P8HCv8HCv8HCv8HCv8HCv8HCv8HCv8HCv8HCuwK7P/s7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs + 7Ars///////////////////////////////////////sCgrs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs + 7Ozs7OwKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK + CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK + CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK + CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK + CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK+woKCgoKCgoKCgoKCgoKCgoK + CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK + CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK////////////////gAAAAQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAHf////3////+SS + SH/5JJO/////v////7////x////z////4/////f///////////8= + + + + + AAABAAIAEBAAAAAACABoBQAAJgAAACAgAAAAAAgAqAgAAI4FAAAoAAAAEAAAACAAAAABAAgAAAAAAAAB + AAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAMDAwADA3MAA8MqmAAQE + BAAICAgADAwMABEREQAWFhYAHBwcACIiIgApKSkAVVVVAE1NTQBCQkIAOTk5AIB8/wBQUP8AkwDWAP/s + zADG1u8A1ufnAJCprQAAADMAAABmAAAAmQAAAMwAADMAAAAzMwAAM2YAADOZAAAzzAAAM/8AAGYAAABm + MwAAZmYAAGaZAABmzAAAZv8AAJkAAACZMwAAmWYAAJmZAACZzAAAmf8AAMwAAADMMwAAzGYAAMyZAADM + zAAAzP8AAP9mAAD/mQAA/8wAMwAAADMAMwAzAGYAMwCZADMAzAAzAP8AMzMAADMzMwAzM2YAMzOZADMz + zAAzM/8AM2YAADNmMwAzZmYAM2aZADNmzAAzZv8AM5kAADOZMwAzmWYAM5mZADOZzAAzmf8AM8wAADPM + MwAzzGYAM8yZADPMzAAzzP8AM/8zADP/ZgAz/5kAM//MADP//wBmAAAAZgAzAGYAZgBmAJkAZgDMAGYA + /wBmMwAAZjMzAGYzZgBmM5kAZjPMAGYz/wBmZgAAZmYzAGZmZgBmZpkAZmbMAGaZAABmmTMAZplmAGaZ + mQBmmcwAZpn/AGbMAABmzDMAZsyZAGbMzABmzP8AZv8AAGb/MwBm/5kAZv/MAMwA/wD/AMwAmZkAAJkz + mQCZAJkAmQDMAJkAAACZMzMAmQBmAJkzzACZAP8AmWYAAJlmMwCZM2YAmWaZAJlmzACZM/8AmZkzAJmZ + ZgCZmZkAmZnMAJmZ/wCZzAAAmcwzAGbMZgCZzJkAmczMAJnM/wCZ/wAAmf8zAJnMZgCZ/5kAmf/MAJn/ + /wDMAAAAmQAzAMwAZgDMAJkAzADMAJkzAADMMzMAzDNmAMwzmQDMM8wAzDP/AMxmAADMZjMAmWZmAMxm + mQDMZswAmWb/AMyZAADMmTMAzJlmAMyZmQDMmcwAzJn/AMzMAADMzDMAzMxmAMzMmQDMzMwAzMz/AMz/ + AADM/zMAmf9mAMz/mQDM/8wAzP//AMwAMwD/AGYA/wCZAMwzAAD/MzMA/zNmAP8zmQD/M8wA/zP/AP9m + AAD/ZjMAzGZmAP9mmQD/ZswAzGb/AP+ZAAD/mTMA/5lmAP+ZmQD/mcwA/5n/AP/MAAD/zDMA/8xmAP/M + mQD/zMwA/8z/AP//MwDM/2YA//+ZAP//zABmZv8AZv9mAGb//wD/ZmYA/2b/AP//ZgAhAKUAX19fAHd3 + dwCGhoYAlpaWAMvLywCysrIA19fXAN3d3QDj4+MA6urqAPHx8QD4+PgA8Pv/AKSgoACAgIAAAAD/AAD/ + AAAA//8A/wAAAP8A/wD//wAA////AAoKCgoKCgoKCgoKCgoKCgoKQw4ODg4ODg4ODg4ODg4KFbvt7e3t + 7e3t7e3t7e3tChT0u7y7vLu8u7y7vLu8u0MUwuwV7BXsFXMV7BXsFZhDFPSS7O3s7XPt7O3s7eyYQxTC + 6xXsQ+wV7EPsFewVmEMU/7uSwpLCmMKYwpLCkrtDFcLCwsLCwsLCwsLCwsKYQwoiIiIiIiIiIiIiIiIi + DgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK + CgoKCgoKCgoKChQKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgr//wAAgAEAAAABAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACAAQAA//sAAPqrAAD1VwAA9/8AAPf/AAD//wAAKAAAACAAAABAAAAAAQAIAAAA + AAAABAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAIAAAIAAAACAgACAAAAAgACAAICAAADAwMAAwNzAAPDK + pgAEBAQACAgIAAwMDAAREREAFhYWABwcHAAiIiIAKSkpAFVVVQBNTU0AQkJCADk5OQCAfP8AUFD/AJMA + 1gD/7MwAxtbvANbn5wCQqa0AAAAzAAAAZgAAAJkAAADMAAAzAAAAMzMAADNmAAAzmQAAM8wAADP/AABm + AAAAZjMAAGZmAABmmQAAZswAAGb/AACZAAAAmTMAAJlmAACZmQAAmcwAAJn/AADMAAAAzDMAAMxmAADM + mQAAzMwAAMz/AAD/ZgAA/5kAAP/MADMAAAAzADMAMwBmADMAmQAzAMwAMwD/ADMzAAAzMzMAMzNmADMz + mQAzM8wAMzP/ADNmAAAzZjMAM2ZmADNmmQAzZswAM2b/ADOZAAAzmTMAM5lmADOZmQAzmcwAM5n/ADPM + AAAzzDMAM8xmADPMmQAzzMwAM8z/ADP/MwAz/2YAM/+ZADP/zAAz//8AZgAAAGYAMwBmAGYAZgCZAGYA + zABmAP8AZjMAAGYzMwBmM2YAZjOZAGYzzABmM/8AZmYAAGZmMwBmZmYAZmaZAGZmzABmmQAAZpkzAGaZ + ZgBmmZkAZpnMAGaZ/wBmzAAAZswzAGbMmQBmzMwAZsz/AGb/AABm/zMAZv+ZAGb/zADMAP8A/wDMAJmZ + AACZM5kAmQCZAJkAzACZAAAAmTMzAJkAZgCZM8wAmQD/AJlmAACZZjMAmTNmAJlmmQCZZswAmTP/AJmZ + MwCZmWYAmZmZAJmZzACZmf8AmcwAAJnMMwBmzGYAmcyZAJnMzACZzP8Amf8AAJn/MwCZzGYAmf+ZAJn/ + zACZ//8AzAAAAJkAMwDMAGYAzACZAMwAzACZMwAAzDMzAMwzZgDMM5kAzDPMAMwz/wDMZgAAzGYzAJlm + ZgDMZpkAzGbMAJlm/wDMmQAAzJkzAMyZZgDMmZkAzJnMAMyZ/wDMzAAAzMwzAMzMZgDMzJkAzMzMAMzM + /wDM/wAAzP8zAJn/ZgDM/5kAzP/MAMz//wDMADMA/wBmAP8AmQDMMwAA/zMzAP8zZgD/M5kA/zPMAP8z + /wD/ZgAA/2YzAMxmZgD/ZpkA/2bMAMxm/wD/mQAA/5kzAP+ZZgD/mZkA/5nMAP+Z/wD/zAAA/8wzAP/M + ZgD/zJkA/8zMAP/M/wD//zMAzP9mAP//mQD//8wAZmb/AGb/ZgBm//8A/2ZmAP9m/wD//2YAIQClAF9f + XwB3d3cAhoaGAJaWlgDLy8sAsrKyANfX1wDd3d0A4+PjAOrq6gDx8fEA+Pj4APD7/wCkoKAAgICAAAAA + /wAA/wAAAP//AP8AAAD/AP8A//8AAP///wAKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK + CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK + CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCuzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs + 7Ozs7OwK7P/sCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK7Ars/+wHBwcHCgcHCgcHBwcHBwcHBwcH + CgcHCgcHBwrsCuz/7P///wcK/wcK/////////////wcK/wcK//8HCuwK7P/sCgoKCgoKCgoKCgoKCgoK + CgoKCgoKCgoKCgoK7Ars/+wHBwoHBwoHBwoHBwoHBwoHBwoHBwoHBwcHBwrsCuz/7P//Cv8HCv8HCv8H + Cv8HCv8HCv8HCv////8HCuwK7P/sCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK7Ars/+wHBwcHCgcH + CgcHCgcHCgcHCgcHCgcHCgcHBwrsCuz/7P///wcK/wcK/wcK/wcK/wcK/wcK/wcK/wcHCuwK7P/sCgoK + CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK7Ars/+wHBwoHBwoHBwoHBwoHBwoHBwoHBwoHBwoHBwrsCuz/ + 7P8HCv8HCv8HCv8HCv8HCv8HCv8HCv8HCv8HCuwK7P/s7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs + 7Ars///////////////////////////////////////sCgrs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs + 7Ozs7OwKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK + CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK + CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK + CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK + CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK+woKCgoKCgoKCgoKCgoKCgoK + CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK + CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK////////////////gAAAAQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAHf////3////+SS + SH/5JJO/////v////7////x////z////4/////f///////////8= + + \ No newline at end of file diff --git a/RightKeyboard/Properties/Resources.Designer.cs b/RightKeyboard/Properties/Resources.Designer.cs index 67593f9..aba2761 100644 --- a/RightKeyboard/Properties/Resources.Designer.cs +++ b/RightKeyboard/Properties/Resources.Designer.cs @@ -1,10 +1,10 @@ //------------------------------------------------------------------------------ // -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 +// Ce code a été généré par un outil. +// Version du runtime :4.0.30319.42000 // -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. +// Les modifications apportées à ce fichier peuvent provoquer un comportement incorrect et seront perdues si +// le code est régénéré. // //------------------------------------------------------------------------------ @@ -13,13 +13,13 @@ namespace RightKeyboard.Properties { /// - /// A strongly-typed resource class, for looking up localized strings, etc. + /// Une classe de ressource fortement typée destinée, entre autres, à la consultation des chaînes localisées. /// - // 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", "15.0.0.0")] + // Cette classe a été générée automatiquement par la classe StronglyTypedResourceBuilder + // à l'aide d'un outil, tel que ResGen ou Visual Studio. + // Pour ajouter ou supprimer un membre, modifiez votre fichier .ResX, puis réexécutez ResGen + // avec l'option /str ou régénérez votre projet VS. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { @@ -33,7 +33,7 @@ internal Resources() { } /// - /// Returns the cached ResourceManager instance used by this class. + /// Retourne l'instance ResourceManager mise en cache utilisée par cette classe. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Resources.ResourceManager ResourceManager { @@ -47,8 +47,8 @@ internal Resources() { } /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. + /// Remplace la propriété CurrentUICulture du thread actuel pour toutes + /// les recherches de ressources à l'aide de cette classe de ressource fortement typée. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Globalization.CultureInfo Culture { diff --git a/RightKeyboard/Properties/Settings.Designer.cs b/RightKeyboard/Properties/Settings.Designer.cs index eff061e..4493867 100644 --- a/RightKeyboard/Properties/Settings.Designer.cs +++ b/RightKeyboard/Properties/Settings.Designer.cs @@ -1,10 +1,10 @@ //------------------------------------------------------------------------------ // -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 +// Ce code a été généré par un outil. +// Version du runtime :4.0.30319.42000 // -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. +// Les modifications apportées à ce fichier peuvent provoquer un comportement incorrect et seront perdues si +// le code est régénéré. // //------------------------------------------------------------------------------ @@ -12,7 +12,7 @@ namespace RightKeyboard.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.3.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.0.2.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); diff --git a/RightKeyboard/RightKeyboard.csproj b/RightKeyboard/RightKeyboard.csproj index ddd8a43..1dcc5a6 100644 --- a/RightKeyboard/RightKeyboard.csproj +++ b/RightKeyboard/RightKeyboard.csproj @@ -11,7 +11,7 @@ RightKeyboard RightKeyboard ico_input0002.ico - v4.5.1 + v4.8 diff --git a/RightKeyboard/app.config b/RightKeyboard/app.config index c8033d7..e787e75 100644 --- a/RightKeyboard/app.config +++ b/RightKeyboard/app.config @@ -1,14 +1,14 @@ - -
+ +
- + - + From 06f086fb6090173fcd13e1fb97b7e97574c3a9cb Mon Sep 17 00:00:00 2001 From: Pof Magicfingers Date: Wed, 1 Sep 2021 11:49:42 +0200 Subject: [PATCH 4/5] fix: prevent crash when no layout is selected, re-ask on retry --- .../LayoutSelectionDialog.Designer.cs | 205 +++++++++--------- RightKeyboard/LayoutSelectionDialog.cs | 8 +- RightKeyboard/LayoutSelectionDialog.resx | 18 +- RightKeyboard/MainForm.cs | 18 +- 4 files changed, 133 insertions(+), 116 deletions(-) diff --git a/RightKeyboard/LayoutSelectionDialog.Designer.cs b/RightKeyboard/LayoutSelectionDialog.Designer.cs index d216b62..a309189 100644 --- a/RightKeyboard/LayoutSelectionDialog.Designer.cs +++ b/RightKeyboard/LayoutSelectionDialog.Designer.cs @@ -23,108 +23,109 @@ protected override void Dispose(bool disposing) { /// the contents of this method with the code editor. /// private void InitializeComponent() { - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(LayoutSelectionDialog)); - this.panel1 = new System.Windows.Forms.Panel(); - this.groupBox1 = new System.Windows.Forms.GroupBox(); - this.pictureBox1 = new System.Windows.Forms.PictureBox(); - this.label1 = new System.Windows.Forms.Label(); - this.lbLayouts = new System.Windows.Forms.ListBox(); - this.btOk = new System.Windows.Forms.Button(); - this.panel1.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); - this.SuspendLayout(); - // - // panel1 - // - this.panel1.BackColor = System.Drawing.SystemColors.Window; - this.panel1.Controls.Add(this.groupBox1); - this.panel1.Controls.Add(this.pictureBox1); - this.panel1.Controls.Add(this.label1); - this.panel1.Dock = System.Windows.Forms.DockStyle.Top; - this.panel1.Location = new System.Drawing.Point(0, 0); - this.panel1.Margin = new System.Windows.Forms.Padding(0); - this.panel1.Name = "panel1"; - this.panel1.Size = new System.Drawing.Size(359, 46); - this.panel1.TabIndex = 0; - // - // groupBox1 - // - this.groupBox1.Dock = System.Windows.Forms.DockStyle.Bottom; - this.groupBox1.Location = new System.Drawing.Point(0, 39); - this.groupBox1.Margin = new System.Windows.Forms.Padding(0); - this.groupBox1.Name = "groupBox1"; - this.groupBox1.Size = new System.Drawing.Size(359, 7); - this.groupBox1.TabIndex = 2; - this.groupBox1.TabStop = false; - // - // pictureBox1 - // - this.pictureBox1.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox1.Image"))); - this.pictureBox1.Location = new System.Drawing.Point(8, 7); - this.pictureBox1.Name = "pictureBox1"; - this.pictureBox1.Size = new System.Drawing.Size(32, 32); - this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; - this.pictureBox1.TabIndex = 1; - this.pictureBox1.TabStop = false; - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(50, 13); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(232, 13); - this.label1.TabIndex = 0; - this.label1.Text = "Please select the layout of the current keyboard"; - // - // lbLayouts - // - this.lbLayouts.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.lbLayouts.FormattingEnabled = true; - this.lbLayouts.IntegralHeight = false; - this.lbLayouts.Location = new System.Drawing.Point(12, 58); - this.lbLayouts.Name = "lbLayouts"; - this.lbLayouts.Size = new System.Drawing.Size(335, 115); - this.lbLayouts.TabIndex = 1; - this.lbLayouts.SelectedIndexChanged += new System.EventHandler(this.lbLayouts_SelectedIndexChanged); - this.lbLayouts.DoubleClick += new System.EventHandler(this.lbLayouts_DoubleClick); - // - // btOk - // - this.btOk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.btOk.Location = new System.Drawing.Point(272, 179); - this.btOk.Name = "btOk"; - this.btOk.Size = new System.Drawing.Size(75, 23); - this.btOk.TabIndex = 2; - this.btOk.Text = "OK"; - this.btOk.UseVisualStyleBackColor = true; - this.btOk.Click += new System.EventHandler(this.btOk_Click); - // - // LayoutSelectionDialog - // - this.AcceptButton = this.btOk; - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(359, 214); - this.ControlBox = false; - this.Controls.Add(this.btOk); - this.Controls.Add(this.lbLayouts); - this.Controls.Add(this.panel1); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; - this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "LayoutSelectionDialog"; - this.ShowIcon = false; - this.ShowInTaskbar = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "Keyboard Layout Selection"; - this.TopMost = true; - this.panel1.ResumeLayout(false); - this.panel1.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); - this.ResumeLayout(false); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(LayoutSelectionDialog)); + this.panel1 = new System.Windows.Forms.Panel(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.pictureBox1 = new System.Windows.Forms.PictureBox(); + this.label1 = new System.Windows.Forms.Label(); + this.lbLayouts = new System.Windows.Forms.ListBox(); + this.btOk = new System.Windows.Forms.Button(); + this.panel1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); + this.SuspendLayout(); + // + // panel1 + // + this.panel1.BackColor = System.Drawing.SystemColors.Window; + this.panel1.Controls.Add(this.groupBox1); + this.panel1.Controls.Add(this.pictureBox1); + this.panel1.Controls.Add(this.label1); + this.panel1.Dock = System.Windows.Forms.DockStyle.Top; + this.panel1.Location = new System.Drawing.Point(0, 0); + this.panel1.Margin = new System.Windows.Forms.Padding(0); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(359, 46); + this.panel1.TabIndex = 0; + // + // groupBox1 + // + this.groupBox1.Dock = System.Windows.Forms.DockStyle.Bottom; + this.groupBox1.Location = new System.Drawing.Point(0, 39); + this.groupBox1.Margin = new System.Windows.Forms.Padding(0); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(359, 7); + this.groupBox1.TabIndex = 2; + this.groupBox1.TabStop = false; + // + // pictureBox1 + // + this.pictureBox1.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox1.Image"))); + this.pictureBox1.Location = new System.Drawing.Point(8, 7); + this.pictureBox1.Name = "pictureBox1"; + this.pictureBox1.Size = new System.Drawing.Size(32, 32); + this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; + this.pictureBox1.TabIndex = 1; + this.pictureBox1.TabStop = false; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(50, 13); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(232, 13); + this.label1.TabIndex = 0; + this.label1.Text = "Please select the layout of the current keyboard"; + // + // lbLayouts + // + this.lbLayouts.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.lbLayouts.FormattingEnabled = true; + this.lbLayouts.IntegralHeight = false; + this.lbLayouts.Location = new System.Drawing.Point(12, 58); + this.lbLayouts.Name = "lbLayouts"; + this.lbLayouts.Size = new System.Drawing.Size(335, 115); + this.lbLayouts.TabIndex = 1; + this.lbLayouts.SelectedIndexChanged += new System.EventHandler(this.lbLayouts_SelectedIndexChanged); + this.lbLayouts.DoubleClick += new System.EventHandler(this.lbLayouts_DoubleClick); + // + // btOk + // + this.btOk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btOk.Location = new System.Drawing.Point(272, 179); + this.btOk.Name = "btOk"; + this.btOk.Size = new System.Drawing.Size(75, 23); + this.btOk.TabIndex = 2; + this.btOk.Text = "OK"; + this.btOk.UseVisualStyleBackColor = true; + this.btOk.Click += new System.EventHandler(this.btOk_Click); + // + // LayoutSelectionDialog + // + this.AcceptButton = this.btOk; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(359, 214); + this.ControlBox = false; + this.Controls.Add(this.btOk); + this.Controls.Add(this.lbLayouts); + this.Controls.Add(this.panel1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "LayoutSelectionDialog"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Keyboard Layout Selection"; + this.TopMost = true; + this.VisibleChanged += new System.EventHandler(this.LayoutSelectionDialog_VisibleChanged); + this.panel1.ResumeLayout(false); + this.panel1.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); + this.ResumeLayout(false); } diff --git a/RightKeyboard/LayoutSelectionDialog.cs b/RightKeyboard/LayoutSelectionDialog.cs index de53b32..cc10bd4 100644 --- a/RightKeyboard/LayoutSelectionDialog.cs +++ b/RightKeyboard/LayoutSelectionDialog.cs @@ -101,5 +101,11 @@ protected override void OnClosing(CancelEventArgs e) { okPressed = false; base.OnClosing(e); } - } + + private void LayoutSelectionDialog_VisibleChanged(object sender, EventArgs e) + { + lbLayouts.SelectedIndex = -1; + lbLayouts.Focus(); + } + } } \ No newline at end of file diff --git a/RightKeyboard/LayoutSelectionDialog.resx b/RightKeyboard/LayoutSelectionDialog.resx index b95bf96..bd18068 100644 --- a/RightKeyboard/LayoutSelectionDialog.resx +++ b/RightKeyboard/LayoutSelectionDialog.resx @@ -112,20 +112,20 @@ 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - + - iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAMpJREFUWEftltEK - wCAIRXvo2/uu/sxh4BBmoZTZxoLAh6Z352aV0j8WE8g5w+KU+nRYHCBBuIhQAcQLRdDUM3RaGU7ELICj - m4m5HSq4M8Wkb017wIxJ9UuGRaECSikQMRsfLBwxsG6jTgIiCDwEIIlaa1PmHYsEsDgJ8I5FAfz89o5F - AXwzellBeYcWeOIfCvDGzvMPLVjdBZK127uAbH2HBaNDSHNs9zqI553qAo6zF+M+krrpTAsiLqLbAryS - d/b/Uc91w4Ptw0svn/0ccCq5soAAAAAASUVORK5CYII= + iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 + JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAx0lEQVRYR+2QQQ7DIAwEOfD2vIufUS3K + Vm66obQBu4eMZGmxnTAi3cwm51z36A8urzXVcIlQAUKRv5HZYwxfC9inu5LJ8XzK2Y9+zbb3keHFVYQK + bNtWI+p5eQS4t706BWjlWW8CoJTSBquzFMCQC6uzFEDDq6SAhaazM89SgAt2cXbmWQqg4VVSgGAAaHs1 + W9iXAhhyYXa2hb4UQMOrpICFpsc8Qu/b7gtgaAsLKo9U71ucpQAaXvUiEFVNAFgzz2qX38SS0gOf/Rxw + vgctDAAAAABJRU5ErkJggg== diff --git a/RightKeyboard/MainForm.cs b/RightKeyboard/MainForm.cs index 53cdc2d..ad6b945 100644 --- a/RightKeyboard/MainForm.cs +++ b/RightKeyboard/MainForm.cs @@ -202,18 +202,24 @@ private void ProcessInputMessage(Message message) if (header.hDevice != hCurrentDevice) { - hCurrentDevice = header.hDevice; - CurrentDeviceChanged(hCurrentDevice); + CurrentDeviceChanged(header.hDevice); } } private void CurrentDeviceChanged(IntPtr currentDevice) { Layout layout; + if (!languageMappings.TryGetValue(currentDevice, out layout)) { layout = ShowGetLayoutForDeviceDialog(currentDevice); + + if (layout == null) + { + return; + } } + SetCurrentLayout(layout.Hkl); if (!SetDefaultLayout(layout.Hkl)) @@ -222,8 +228,9 @@ private void CurrentDeviceChanged(IntPtr currentDevice) SetCurrentLayout(layout.Hkl); Debug.Assert(SetDefaultLayout(layout.Hkl)); - } + + hCurrentDevice = currentDevice; } private Layout ShowGetLayoutForDeviceDialog(IntPtr currentDevice) @@ -233,7 +240,10 @@ private Layout ShowGetLayoutForDeviceDialog(IntPtr currentDevice) layoutSelectionDialog.ShowDialog(); selectingLayout = false; layout = layoutSelectionDialog.Layout; - languageMappings[currentDevice] = layout; + if (layout != null) + { + languageMappings[currentDevice] = layout; + } return layout; } From ee3f35e7d1153af6d013148da0742c6a37850476 Mon Sep 17 00:00:00 2001 From: Pof Magicfingers Date: Wed, 1 Sep 2021 12:03:01 +0200 Subject: [PATCH 5/5] chore: v1.2 --- RightKeyboard/Properties/AssemblyInfo.cs | 6 +- RightKeyboard/Properties/app.manifest | 73 ++++++++++++++++++++++++ RightKeyboard/RightKeyboard.csproj | 48 ++++++++++++++++ 3 files changed, 124 insertions(+), 3 deletions(-) create mode 100644 RightKeyboard/Properties/app.manifest diff --git a/RightKeyboard/Properties/AssemblyInfo.cs b/RightKeyboard/Properties/AssemblyInfo.cs index bd13973..b670e45 100644 --- a/RightKeyboard/Properties/AssemblyInfo.cs +++ b/RightKeyboard/Properties/AssemblyInfo.cs @@ -10,7 +10,7 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("RightKeyboard")] -[assembly: AssemblyCopyright("Copyright © 2007")] +[assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -29,5 +29,5 @@ // Build Number // Revision // -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: AssemblyVersion("1.2.0.0")] +[assembly: AssemblyFileVersion("1.2.0.0")] diff --git a/RightKeyboard/Properties/app.manifest b/RightKeyboard/Properties/app.manifest new file mode 100644 index 0000000..e349b32 --- /dev/null +++ b/RightKeyboard/Properties/app.manifest @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/RightKeyboard/RightKeyboard.csproj b/RightKeyboard/RightKeyboard.csproj index 1dcc5a6..83915c2 100644 --- a/RightKeyboard/RightKeyboard.csproj +++ b/RightKeyboard/RightKeyboard.csproj @@ -18,6 +18,22 @@ 2.0 + false + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 1 + 1.0.0.%2a + false + true + true true @@ -38,6 +54,24 @@ 4 false + + 3EF89A07AF60F3CAF4FE665F6A91C782AED19D57 + + + RightKeyboard_TemporaryKey.pfx + + + true + + + LocalIntranet + + + Properties\app.manifest + + + true + @@ -81,6 +115,7 @@ True + SettingsSingleFileGenerator Settings.Designer.cs @@ -93,10 +128,23 @@ + + + + False + Microsoft .NET Framework 4.8 %28x86 et x64%29 + true + + + False + .NET Framework 3.5 SP1 + false + +