├── .gitignore
├── README.md
├── assets
├── mockup
│ ├── Main Window [Balsamiq].png
│ └── Main Window [Balsamiq].xml
├── usage-guide-favorites.png
└── usage-guide.png
└── src
├── UnicodeKeyboard.sln
└── UnicodeKeyboard
├── Interaction
├── CharacterSearchResult.cs
└── CommandGateway.cs
├── Program.cs
├── Properties
├── AssemblyInfo.cs
├── Resources.Designer.cs
├── Resources.resx
├── Resources.ru.resx
├── Resources.uk.resx
├── Settings.Designer.cs
└── Settings.settings
├── References
└── Gma.UserActivityMonitor.dll
├── ResourceWrappers
├── LocalizationHelper.cs
├── SingleAssemblyComponentResourceManager.cs
└── UnicodeCharacterDatabase.cs
├── Resources
├── CharacterNames.txt
├── CharacterNamesCompressed.dat
├── Crosshair.png
├── CrosshairCursor.cur
├── KeyShortcutAddToFavorites.png
├── KeyShortcutCopyToClipboard.png
├── KeyShortcutInsertCharacter.png
├── KeyboardSmall.ico
├── KeyboardSmall.png
├── MouseShortcutInsertCharacter.png
└── Wrench.png
├── Settings
└── UserSettings.cs
├── Tools
└── ILMerge.exe
├── UI
├── AboutForm.Designer.cs
├── AboutForm.cs
├── AboutForm.resx
├── AboutForm.ru.resx
├── AboutForm.uk.resx
├── AddToFavoritesForm.Designer.cs
├── AddToFavoritesForm.cs
├── AddToFavoritesForm.resx
├── AddToFavoritesForm.ru.resx
├── AddToFavoritesForm.uk.resx
├── CapturedWindow.cs
├── CharacterLookupForm.Designer.cs
├── CharacterLookupForm.cs
├── CharacterLookupForm.resx
├── CharacterLookupForm.ru.resx
├── CharacterLookupForm.uk.resx
├── IKeyboardShortcutTranscriber.cs
├── KeyboardShortcutEditor.cs
├── KeyboardShortcutTranscriber.cs
├── MainForm.Designer.cs
├── MainForm.cs
├── MainForm.resx
├── MainForm.ru.resx
├── MainForm.uk.resx
├── OptionsForm.Designer.cs
├── OptionsForm.cs
├── OptionsForm.resx
├── OptionsForm.ru.resx
├── OptionsForm.uk.resx
├── UIHelper.cs
├── WindowFinder.Designer.cs
├── WindowFinder.cs
└── WindowFinder.resx
├── UnicodeKeyboard.csproj
└── WindowsIntegration
├── NativeMethods.cs
├── NativeStructs.cs
└── UnicodeCharSender.cs
/.gitignore:
--------------------------------------------------------------------------------
1 | # Build Folders (you can keep bin if you'd like, to store dlls and pdbs)
2 | [Bb]in/
3 | [Oo]bj/
4 |
5 | # mstest test results
6 | TestResults
7 |
8 | ## Ignore Visual Studio temporary files, build results, and
9 | ## files generated by popular Visual Studio add-ons.
10 |
11 | # User-specific files
12 | *.suo
13 | *.user
14 | *.sln.docstates
15 |
16 | # Build results
17 | [Dd]ebug/
18 | [Rr]elease/
19 | x64/
20 | *_i.c
21 | *_p.c
22 | *.ilk
23 | *.meta
24 | *.obj
25 | *.pch
26 | *.pdb
27 | *.pgc
28 | *.pgd
29 | *.rsp
30 | *.sbr
31 | *.tlb
32 | *.tli
33 | *.tlh
34 | *.tmp
35 | *.log
36 | *.vspscc
37 | *.vssscc
38 | .builds
39 |
40 | # Visual C++ cache files
41 | ipch/
42 | *.aps
43 | *.ncb
44 | *.opensdf
45 | *.sdf
46 |
47 | # Visual Studio profiler
48 | *.psess
49 | *.vsp
50 | *.vspx
51 |
52 | # Guidance Automation Toolkit
53 | *.gpState
54 |
55 | # ReSharper is a .NET coding add-in
56 | _ReSharper*
57 | *.DotSettings
58 |
59 | # NCrunch
60 | *.ncrunch*
61 | .*crunch*.local.xml
62 |
63 | # Installshield output folder
64 | [Ee]xpress
65 |
66 | # DocProject is a documentation generator add-in
67 | DocProject/buildhelp/
68 | DocProject/Help/*.HxT
69 | DocProject/Help/*.HxC
70 | DocProject/Help/*.hhc
71 | DocProject/Help/*.hhk
72 | DocProject/Help/*.hhp
73 | DocProject/Help/Html2
74 | DocProject/Help/html
75 |
76 | # Click-Once directory
77 | publish
78 |
79 | # Publish Web Output
80 | *.Publish.xml
81 |
82 | # NuGet Packages Directory
83 | packages
84 |
85 | # Windows Azure Build Output
86 | csx
87 | *.build.csdef
88 |
89 | # Windows Store app package directory
90 | AppPackages/
91 |
92 | # Others
93 | [Bb]in
94 | [Oo]bj
95 | sql
96 | TestResults
97 | [Tt]est[Rr]esult*
98 | *.Cache
99 | ClientBin
100 | [Ss]tyle[Cc]op.*
101 | ~$*
102 | *.dbmdl
103 | Generated_Code #added for RIA/Silverlight projects
104 |
105 | # Backup & report files from converting an old project file to a newer
106 | # Visual Studio version. Backup files are not needed, because we have git ;-)
107 | _UpgradeReport_Files/
108 | Backup*/
109 | UpgradeLog*.XML
110 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Unicode Virtual Keyboard
2 |
3 | A Windows utility (powered by Win32 API and .NET 2.0 Windows Forms)
4 | that simplifies the input of Unicode characters
5 | by displaying a handy on-demand virtual keyboard via a global keyboard hook.
6 |
7 | Customizable global keyboard shortcuts and multiple UI languages are supported.
8 |
9 | ## How To Use
10 |
11 | ### Entering Unicode Characters
12 |
13 | 
14 |
15 | ### Favorites
16 |
17 | Unicode Virtual Keyboard supports up to 10 customizable slots
18 | for frequently used characters.
19 |
20 | 
21 |
--------------------------------------------------------------------------------
/assets/mockup/Main Window [Balsamiq].png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YuriyGuts/unicode-virtual-keyboard/d677ceceb2019c64f4b8de76118c6562b5cbf625/assets/mockup/Main Window [Balsamiq].png
--------------------------------------------------------------------------------
/assets/usage-guide-favorites.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YuriyGuts/unicode-virtual-keyboard/d677ceceb2019c64f4b8de76118c6562b5cbf625/assets/usage-guide-favorites.png
--------------------------------------------------------------------------------
/assets/usage-guide.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YuriyGuts/unicode-virtual-keyboard/d677ceceb2019c64f4b8de76118c6562b5cbf625/assets/usage-guide.png
--------------------------------------------------------------------------------
/src/UnicodeKeyboard.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 11.00
3 | # Visual Studio 2010
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnicodeKeyboard", "UnicodeKeyboard\UnicodeKeyboard.csproj", "{231F802E-F52E-4150-BE44-AC26D6D43873}"
5 | EndProject
6 | Global
7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
8 | Debug|x86 = Debug|x86
9 | Release|x86 = Release|x86
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {231F802E-F52E-4150-BE44-AC26D6D43873}.Debug|x86.ActiveCfg = Debug|x86
13 | {231F802E-F52E-4150-BE44-AC26D6D43873}.Debug|x86.Build.0 = Debug|x86
14 | {231F802E-F52E-4150-BE44-AC26D6D43873}.Release|x86.ActiveCfg = Release|x86
15 | {231F802E-F52E-4150-BE44-AC26D6D43873}.Release|x86.Build.0 = Release|x86
16 | EndGlobalSection
17 | GlobalSection(SolutionProperties) = preSolution
18 | HideSolutionNode = FALSE
19 | EndGlobalSection
20 | EndGlobal
21 |
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/Interaction/CharacterSearchResult.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace YuriyGuts.UnicodeKeyboard.Interaction
4 | {
5 | ///
6 | /// Represents the results of interaction with the character lookup form.
7 | ///
8 | public class CharacterSearchResult
9 | {
10 | public CharacterSearchAction Action { get; set; }
11 |
12 | public ushort CharacterCode { get; set; }
13 |
14 | public bool KeepApplicationActive { get; set; }
15 | }
16 |
17 | ///
18 | /// Represents the possible actions that can be performed on the character lookup form.
19 | ///
20 | public enum CharacterSearchAction
21 | {
22 | None,
23 | Cancel,
24 | InsertCharacter,
25 | CopyCharacterToClipboard,
26 | AddCharacterToFavorites,
27 | }
28 |
29 | public class CharacterSearchResultEventArgs : EventArgs
30 | {
31 | public CharacterSearchResult Result { get; set; }
32 |
33 | public CharacterSearchResultEventArgs(CharacterSearchResult result)
34 | {
35 | Result = result;
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using System.Threading;
4 | using System.Windows.Forms;
5 | using YuriyGuts.UnicodeKeyboard.Settings;
6 | using YuriyGuts.UnicodeKeyboard.UI;
7 |
8 | namespace YuriyGuts.UnicodeKeyboard
9 | {
10 | static class Program
11 | {
12 | private const string ApplicationMutexName = "UnicodeKeyboard-CFDD1D58-58AA-4B32-85D1-527EB2B5890F";
13 |
14 | ///
15 | /// The main entry point for the application.
16 | ///
17 | [STAThread]
18 | public static void Main()
19 | {
20 | RunApplicationPreservingSingleInstance();
21 | }
22 |
23 | private static void RunApplicationPreservingSingleInstance()
24 | {
25 | Mutex mutex = AcquireMutex();
26 | if (mutex == null)
27 | {
28 | return;
29 | }
30 |
31 | try
32 | {
33 | RunApplication();
34 | }
35 | finally
36 | {
37 | mutex.ReleaseMutex();
38 | }
39 | }
40 |
41 | private static Mutex AcquireMutex()
42 | {
43 | Mutex appGlobalMutex = new Mutex(false, ApplicationMutexName);
44 | if (!appGlobalMutex.WaitOne(3000))
45 | {
46 | return null;
47 | }
48 | return appGlobalMutex;
49 | }
50 |
51 | private static void RunApplication()
52 | {
53 | LoadUserSettings();
54 | SetUILanguage(UserSettings.Instance.Language);
55 |
56 | Application.EnableVisualStyles();
57 | Application.SetCompatibleTextRenderingDefault(false);
58 | Application.Run(MainForm.Instance);
59 | }
60 |
61 | private static void LoadUserSettings()
62 | {
63 | UserSettings.Instance.Load();
64 | }
65 |
66 | private static void SetUILanguage(string languageCode)
67 | {
68 | Thread.CurrentThread.CurrentUICulture = new CultureInfo(languageCode);
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | // General Information about an assembly is controlled through the following
5 | // set of attributes. Change these attribute values to modify the information
6 | // associated with an assembly.
7 | [assembly: AssemblyTitle("Unicode Virtual Keyboard")]
8 | [assembly: AssemblyDescription("Shell-integrated Unicode character input utility")]
9 | [assembly: AssemblyConfiguration("")]
10 | [assembly: AssemblyCompany("Yuriy Guts")]
11 | [assembly: AssemblyProduct("Unicode Virtual Keyboard")]
12 | [assembly: AssemblyCopyright("Copyright © Yuriy Guts, 2010-2011")]
13 | [assembly: AssemblyTrademark("")]
14 | [assembly: AssemblyCulture("")]
15 |
16 | // Setting ComVisible to false makes the types in this assembly not visible
17 | // to COM components. If you need to access a type in this assembly from
18 | // COM, set the ComVisible attribute to true on that type.
19 | [assembly: ComVisible(false)]
20 |
21 | // The following GUID is for the ID of the typelib if this project is exposed to COM
22 | [assembly: Guid("6d602768-71b8-4a49-a111-65f06215bd4e")]
23 |
24 | // Version information for an assembly consists of the following four values:
25 | //
26 | // Major Version
27 | // Minor Version
28 | // Build Number
29 | // Revision
30 | //
31 | // You can specify all the values or you can default the Build and Revision Numbers
32 | // by using the '*' as shown below:
33 | // [assembly: AssemblyVersion("1.0.*")]
34 | [assembly: AssemblyVersion("1.0.2.28")]
35 | [assembly: AssemblyFileVersion("1.0.2.28")]
36 |
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | http://unicode.org/ucd/
122 |
123 |
124 | Русский (Russian)
125 |
126 |
127 | (unknown)
128 |
129 |
130 | Invalid primary shortcut. Please choose another one.
131 |
132 |
133 | 1.1
134 |
135 |
136 | http://famfamfam.com/lab/icons/silk/
137 |
138 |
139 | You have to restart the application for the new language settings to take effect. Restart the application now?
140 |
141 |
142 | Error
143 |
144 |
145 | The primary and secondary shortcuts must be different.
146 |
147 |
148 |
149 | ..\Resources\KeyboardSmall.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
150 |
151 |
152 | Failed to send the character to the target window.
153 |
154 |
155 | Українська (Ukrainian)
156 |
157 |
158 | Failed to start Character Map because of an error.
159 |
160 |
161 | Copyright © Yuriy Guts, 2010-2013
162 |
163 |
164 | ..\Resources\CharacterNamesCompressed.dat;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
165 |
166 |
167 | English
168 |
169 |
170 | Details
171 |
172 |
173 | http://www.codeproject.com/KB/cs/globalhook.aspx
174 |
175 |
176 | ..\Resources\Wrench.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
177 |
178 |
179 | ..\Resources\KeyboardSmall.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
180 |
181 |
182 | Unicode Virtual Keyboard
183 |
184 |
185 | Invalid secondary shortcut. Please choose another one.
186 |
187 |
188 | ..\Resources\Crosshair.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
189 |
190 |
191 | ..\resources\crosshaircursor.cur;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
192 |
193 |
194 | ..\Resources\KeyShortcutAddToFavorites.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
195 |
196 |
197 | ..\Resources\KeyShortcutCopyToClipboard.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
198 |
199 |
200 | ..\Resources\KeyShortcutInsertCharacter.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
201 |
202 |
203 | ..\Resources\MouseShortcutInsertCharacter.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
204 |
205 |
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/Properties/Resources.ru.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | Виртуальная Юникод-клавиатура
122 |
123 |
124 | Подробности
125 |
126 |
127 | Ошибка
128 |
129 |
130 | Не удалось запустить Таблицу символов в связи с ошибкой.
131 |
132 |
133 | Не удалось отправить символ окну-адресату.
134 |
135 |
136 | (неизвестно)
137 |
138 |
139 | Первичная комбинация клавиш должна отличаться от вторичной.
140 |
141 |
142 | Недопустимая первичная комбинация клавиш. Пожалуйста, задайте другую комбинацию.
143 |
144 |
145 | Недопустимая вторичная комбинация клавиш. Пожалуйста, задайте другую комбинацию.
146 |
147 |
148 | Языковые настройки вступят в силу только после перезапуска приложения. Перезапустить приложение сейчас?
149 |
150 |
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/Properties/Resources.uk.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | Віртуальна Юнікод-клавіатура
122 |
123 |
124 | Подробиці
125 |
126 |
127 | Помилка
128 |
129 |
130 | Не вдалося запустити Таблицю Символів в зв'язку з помилкою.
131 |
132 |
133 | Не вдалося відправити символ вікну-адресату.
134 |
135 |
136 | (невідомо)
137 |
138 |
139 | Первинна комбінація клавіш повинна відрізнятися від вторинної.
140 |
141 |
142 | Недопустима первинна комбінація клавіш. Будь ласка, задайте іншу комбінацію.
143 |
144 |
145 | Недопустима вторинна комбінація клавіш. Будь ласка, задайте іншу комбінацію.
146 |
147 |
148 | Для того, щоб налаштування мови набули чинності, потрібно перезапустити програму. Перезапустити зараз?
149 |
150 |
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.237
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace YuriyGuts.UnicodeKeyboard.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/References/Gma.UserActivityMonitor.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YuriyGuts/unicode-virtual-keyboard/d677ceceb2019c64f4b8de76118c6562b5cbf625/src/UnicodeKeyboard/References/Gma.UserActivityMonitor.dll
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/ResourceWrappers/LocalizationHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Windows.Forms;
4 | using YuriyGuts.UnicodeKeyboard.Properties;
5 |
6 | namespace YuriyGuts.UnicodeKeyboard.ResourceWrappers
7 | {
8 | ///
9 | /// Provides common routines for UI localization.
10 | ///
11 | internal static class LocalizationHelper
12 | {
13 | private static SingleAssemblyComponentResourceManager globalResourceManager = new SingleAssemblyComponentResourceManager(typeof(Resources));
14 | private static Dictionary resourceManagerCache = new Dictionary();
15 |
16 | ///
17 | /// Loads the specified string resource from the resource storage.
18 | ///
19 | /// Owning object (typically, a form).
20 | /// Resource key.
21 | /// Localized string that corresponds to the given key.
22 | public static string GetResource(Control resourceNamespaceOwner, string key)
23 | {
24 | if (resourceNamespaceOwner == null)
25 | {
26 | return GetGlobalResource(key);
27 | }
28 | return GetGlobalResource(string.Concat(resourceNamespaceOwner.Name, "_", key));
29 | }
30 |
31 | public static string GetObjectInternalResource(Type componentType, string key)
32 | {
33 | if (!resourceManagerCache.ContainsKey(componentType))
34 | {
35 | resourceManagerCache.Add(componentType, new SingleAssemblyComponentResourceManager(componentType));
36 | }
37 | return resourceManagerCache[componentType].GetString(key);
38 | }
39 |
40 | ///
41 | /// Loads the specified string resource from the application-wide resource storage.
42 | ///
43 | ///
44 | /// Localized string that corresponds to the given key.
45 | public static string GetGlobalResource(string key)
46 | {
47 | return globalResourceManager.GetString(key);
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/ResourceWrappers/SingleAssemblyComponentResourceManager.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.ComponentModel;
4 | using System.Globalization;
5 | using System.IO;
6 | using System.Resources;
7 |
8 | namespace YuriyGuts.UnicodeKeyboard.ResourceWrappers
9 | {
10 | ///
11 | /// Enables the standard resource fallback mechanisms for ILMerge'd satellite resource assemblies.
12 | /// Code taken from http://stackoverflow.com/questions/1952638/
13 | ///
14 | internal class SingleAssemblyComponentResourceManager : ComponentResourceManager
15 | {
16 | private Type contextTypeInfo;
17 | private CultureInfo neutralResourcesCulture;
18 |
19 | public SingleAssemblyComponentResourceManager(Type type)
20 | : base(type)
21 | {
22 | contextTypeInfo = type;
23 | }
24 |
25 | protected override ResourceSet InternalGetResourceSet(CultureInfo culture, bool createIfNotExists, bool tryParents)
26 | {
27 | ResourceSet resourceSet = (ResourceSet)ResourceSets[culture];
28 | if (resourceSet == null)
29 | {
30 | // Lazy-load default language (without caring about duplicate assignment in race conditions, no harm done);
31 | if (neutralResourcesCulture == null)
32 | {
33 | neutralResourcesCulture = GetNeutralResourcesLanguage(MainAssembly);
34 | }
35 |
36 | // If we're asking for the default language, then ask for the invariant (non-specific) resources.
37 | if (neutralResourcesCulture.Equals(culture))
38 | {
39 | culture = CultureInfo.InvariantCulture;
40 | }
41 |
42 | string resourceFileName = GetResourceFileName(culture);
43 | Stream store = MainAssembly.GetManifestResourceStream(contextTypeInfo, resourceFileName);
44 |
45 | // If we found the appropriate resources in the local assembly...
46 | if (store != null)
47 | {
48 | resourceSet = new ResourceSet(store);
49 | // Save for later.
50 | AddResourceSet(ResourceSets, culture, ref resourceSet);
51 | }
52 | else
53 | {
54 | resourceSet = base.InternalGetResourceSet(culture, createIfNotExists, tryParents);
55 | }
56 | }
57 | return resourceSet;
58 | }
59 |
60 | // Private method in framework, had to be re-implemented here.
61 | private static void AddResourceSet(Hashtable localResourceSets, CultureInfo culture, ref ResourceSet resourceSet)
62 | {
63 | lock (localResourceSets)
64 | {
65 | ResourceSet localResourceSet = (ResourceSet)localResourceSets[culture];
66 | if (localResourceSet != null)
67 | {
68 | if (!Equals(localResourceSet, resourceSet))
69 | {
70 | resourceSet.Dispose();
71 | resourceSet = localResourceSet;
72 | }
73 | }
74 | else
75 | {
76 | localResourceSets.Add(culture, resourceSet);
77 | }
78 | }
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/ResourceWrappers/UnicodeCharacterDatabase.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Globalization;
3 | using System.IO;
4 | using System.IO.Compression;
5 | using System.Text.RegularExpressions;
6 | using YuriyGuts.UnicodeKeyboard.Properties;
7 |
8 | namespace YuriyGuts.UnicodeKeyboard.ResourceWrappers
9 | {
10 | ///
11 | /// Represents the memory-cached Unicode character database.
12 | ///
13 | public static class UnicodeCharacterDatabase
14 | {
15 | private static bool isInitialized;
16 | private static Dictionary characterNames;
17 |
18 | private static void EnsureInitialized()
19 | {
20 | if (isInitialized)
21 | {
22 | return;
23 | }
24 | Initialize();
25 | isInitialized = true;
26 | }
27 |
28 | private static void Initialize()
29 | {
30 | characterNames = new Dictionary(16000);
31 |
32 | // Decompressing the character name list.
33 | using (MemoryStream compressedStream = new MemoryStream(Resources.CharacterNamesCompressed))
34 | {
35 | // Creating a memory stream for decompressed text.
36 | using (MemoryStream decompressedStream = new MemoryStream())
37 | {
38 | // Creating inflater.
39 | using (DeflateStream decompressor = new DeflateStream(compressedStream, CompressionMode.Decompress))
40 | {
41 | byte[] buffer = new byte[4096];
42 | int bytesRead;
43 | while ((bytesRead = decompressor.Read(buffer, 0, buffer.Length)) > 0)
44 | {
45 | decompressedStream.Write(buffer, 0, bytesRead);
46 | }
47 | }
48 |
49 | // Reading character names and storing them into a dictionary.
50 | decompressedStream.Position = 0;
51 | using (StreamReader reader = new StreamReader(decompressedStream))
52 | {
53 | while (!reader.EndOfStream)
54 | {
55 | string entry = reader.ReadLine();
56 | if (entry != null)
57 | {
58 | characterNames.Add
59 | (
60 | ushort.Parse(entry.Substring(0, 4), NumberStyles.HexNumber),
61 | entry.Substring(5)
62 | );
63 | }
64 | }
65 | }
66 | }
67 | }
68 | }
69 |
70 | ///
71 | /// Gets the name of the Unicode character by its code.
72 | ///
73 | /// Character code.
74 | /// The name of the character.
75 | public static string GetCharacterName(ushort charCode)
76 | {
77 | EnsureInitialized();
78 | string characterName;
79 | return characterNames.TryGetValue(charCode, out characterName) ? characterName : null;
80 | }
81 |
82 | ///
83 | /// Searches for Unicode characters by a string representation of the character code.
84 | ///
85 | /// String representation of the character code.
86 | /// The list of all found items.
87 | public static List> FindCharactersByCodeString(string codeString)
88 | {
89 | if (codeString.Length != 4)
90 | {
91 | return null;
92 | }
93 |
94 | ushort charCode;
95 | bool isParseSuccessful = ushort.TryParse(codeString, NumberStyles.HexNumber, CultureInfo.CurrentCulture, out charCode);
96 |
97 | if (isParseSuccessful && characterNames.ContainsKey(charCode))
98 | {
99 | return new List>
100 | {
101 | new KeyValuePair(charCode, characterNames[charCode])
102 | };
103 | }
104 | return null;
105 | }
106 |
107 | ///
108 | /// Searches for Unicode characters whose names match the specified filter.
109 | ///
110 | /// Character name filter.
111 | /// Whether to match only the beginning of the name.
112 | /// The list of all found items.
113 | public static List> FindCharactersByName(string nameFilter, bool matchBeginningOnly)
114 | {
115 | EnsureInitialized();
116 | List> result = new List>();
117 | foreach (KeyValuePair pair in characterNames)
118 | {
119 | bool pairMatches =
120 | string.IsNullOrEmpty(nameFilter)
121 | || (matchBeginningOnly && pair.Value.StartsWith(nameFilter))
122 | || (!matchBeginningOnly && pair.Value.Contains(nameFilter));
123 |
124 | if (pairMatches)
125 | {
126 | result.Add(pair);
127 | }
128 | }
129 | return result;
130 | }
131 |
132 | ///
133 | /// Searches for Unicode characters whose names match the specified regex.
134 | ///
135 | /// Regex pattern.
136 | /// The list of all found items.
137 | public static List> FindCharactersByNameRegex(string regexPattern)
138 | {
139 | EnsureInitialized();
140 | List> result = new List>();
141 | Regex matchRegex = new Regex(regexPattern);
142 |
143 | foreach (KeyValuePair pair in characterNames)
144 | {
145 | if (matchRegex.IsMatch(pair.Value))
146 | {
147 | result.Add(pair);
148 | }
149 | }
150 | return result;
151 | }
152 | }
153 | }
154 |
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/Resources/CharacterNamesCompressed.dat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YuriyGuts/unicode-virtual-keyboard/d677ceceb2019c64f4b8de76118c6562b5cbf625/src/UnicodeKeyboard/Resources/CharacterNamesCompressed.dat
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/Resources/Crosshair.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YuriyGuts/unicode-virtual-keyboard/d677ceceb2019c64f4b8de76118c6562b5cbf625/src/UnicodeKeyboard/Resources/Crosshair.png
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/Resources/CrosshairCursor.cur:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YuriyGuts/unicode-virtual-keyboard/d677ceceb2019c64f4b8de76118c6562b5cbf625/src/UnicodeKeyboard/Resources/CrosshairCursor.cur
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/Resources/KeyShortcutAddToFavorites.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YuriyGuts/unicode-virtual-keyboard/d677ceceb2019c64f4b8de76118c6562b5cbf625/src/UnicodeKeyboard/Resources/KeyShortcutAddToFavorites.png
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/Resources/KeyShortcutCopyToClipboard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YuriyGuts/unicode-virtual-keyboard/d677ceceb2019c64f4b8de76118c6562b5cbf625/src/UnicodeKeyboard/Resources/KeyShortcutCopyToClipboard.png
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/Resources/KeyShortcutInsertCharacter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YuriyGuts/unicode-virtual-keyboard/d677ceceb2019c64f4b8de76118c6562b5cbf625/src/UnicodeKeyboard/Resources/KeyShortcutInsertCharacter.png
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/Resources/KeyboardSmall.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YuriyGuts/unicode-virtual-keyboard/d677ceceb2019c64f4b8de76118c6562b5cbf625/src/UnicodeKeyboard/Resources/KeyboardSmall.ico
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/Resources/KeyboardSmall.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YuriyGuts/unicode-virtual-keyboard/d677ceceb2019c64f4b8de76118c6562b5cbf625/src/UnicodeKeyboard/Resources/KeyboardSmall.png
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/Resources/MouseShortcutInsertCharacter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YuriyGuts/unicode-virtual-keyboard/d677ceceb2019c64f4b8de76118c6562b5cbf625/src/UnicodeKeyboard/Resources/MouseShortcutInsertCharacter.png
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/Resources/Wrench.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YuriyGuts/unicode-virtual-keyboard/d677ceceb2019c64f4b8de76118c6562b5cbf625/src/UnicodeKeyboard/Resources/Wrench.png
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/Settings/UserSettings.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.IO;
4 | using System.Reflection;
5 | using System.Windows.Forms;
6 | using System.Xml.Serialization;
7 | using Microsoft.Win32;
8 |
9 | namespace YuriyGuts.UnicodeKeyboard.Settings
10 | {
11 | ///
12 | /// Represents the user-specific application settings manager.
13 | ///
14 | [Serializable]
15 | [XmlRoot("UnicodeKeyboard")]
16 | public class UserSettings
17 | {
18 | private static UserSettings instance;
19 |
20 | private string language;
21 | private Keys primaryApplicationShortcut;
22 | private Keys secondaryApplicationShortcut;
23 | private bool showIconInSystemTray;
24 | private bool minimizeOnFocusLost;
25 | private bool terminateOnClose;
26 | private bool launchOnWindowsStartup;
27 | private ushort[] favorites;
28 |
29 | ///
30 | /// Initializes a new instance of the UserSettings class and fills it with default values.
31 | ///
32 | public UserSettings()
33 | {
34 | language = "en";
35 | primaryApplicationShortcut = Keys.Alt | Keys.Add;
36 | secondaryApplicationShortcut = Keys.Alt | Keys.Subtract;
37 | showIconInSystemTray = true;
38 | minimizeOnFocusLost = false;
39 | terminateOnClose = false;
40 | launchOnWindowsStartup = false;
41 | favorites = new ushort[] { 0x2014, 0x00A9, 0x00AB, 0x00BB, 0x2122, 0x00D7, 0x00B0, 0x2022, 0x2248, 0x2260 };
42 | }
43 |
44 | ///
45 | /// Singleton pattern implementation.
46 | ///
47 | [XmlIgnore]
48 | public static UserSettings Instance
49 | {
50 | get { return instance ?? (instance = new UserSettings()); }
51 | }
52 |
53 | ///
54 | /// User interface language code.
55 | ///
56 | public string Language
57 | {
58 | get { return language; }
59 | set { language = value; }
60 | }
61 |
62 | ///
63 | /// Application's primary magic keystroke.
64 | ///
65 | [XmlIgnore]
66 | public Keys PrimaryApplicationShortcut
67 | {
68 | get { return primaryApplicationShortcut; }
69 | set { primaryApplicationShortcut = value; }
70 | }
71 |
72 | ///
73 | /// Application's primary magic keystroke represented as integer (for internal use).
74 | ///
75 | [XmlElement("PrimaryApplicationShortcut")]
76 | public int PrimaryApplicationShortcutInt
77 | {
78 | get { return (int)primaryApplicationShortcut; }
79 | set { primaryApplicationShortcut = (Keys)value; }
80 | }
81 |
82 | ///
83 | /// Application's secondary magic keystroke.
84 | ///
85 | [XmlIgnore]
86 | public Keys SecondaryApplicationShortcut
87 | {
88 | get { return secondaryApplicationShortcut; }
89 | set { secondaryApplicationShortcut = value; }
90 | }
91 |
92 | ///
93 | /// Application's secondary magic keystroke represented as integer (for internal use).
94 | ///
95 | [XmlElement("SecondaryApplicationShortcut")]
96 | public int SecondaryApplicationShortcutInt
97 | {
98 | get { return (int)SecondaryApplicationShortcut; }
99 | set { SecondaryApplicationShortcut = (Keys)value; }
100 | }
101 |
102 | ///
103 | /// Whether to show the application icon in Windows system tray.
104 | ///
105 | public bool ShowIconInSystemTray
106 | {
107 | get { return showIconInSystemTray; }
108 | set { showIconInSystemTray = value; }
109 | }
110 |
111 | ///
112 | /// Whether to minimize the main window after it loses focus.
113 | ///
114 | public bool MinimizeOnFocusLost
115 | {
116 | get { return minimizeOnFocusLost; }
117 | set { minimizeOnFocusLost = value; }
118 | }
119 |
120 | ///
121 | /// Whether to terminate the application whenthe main window is closed.
122 | ///
123 | public bool TerminateOnClose
124 | {
125 | get { return terminateOnClose; }
126 | set { terminateOnClose = value; }
127 | }
128 |
129 | ///
130 | /// Whether to launch the application automatically after user logon.
131 | ///
132 | public bool LaunchOnWindowsStartup
133 | {
134 | get { return launchOnWindowsStartup; }
135 | set { launchOnWindowsStartup = value; }
136 | }
137 |
138 | ///
139 | /// Codes of all Favorite characters.
140 | ///
141 | public ushort[] Favorites
142 | {
143 | get { return favorites; }
144 | set { favorites = value; }
145 | }
146 |
147 | private XmlSerializer CreateSerializer()
148 | {
149 | XmlSerializer result = new XmlSerializer(GetType());
150 | return result;
151 | }
152 |
153 | private string GetSettingsFileName()
154 | {
155 | string globalAppDataDirectoryName = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
156 | string appSettingsDirectoryName = Path.Combine(globalAppDataDirectoryName, "UnicodeKeyboard");
157 | if (!Directory.Exists(appSettingsDirectoryName))
158 | {
159 | Directory.CreateDirectory(appSettingsDirectoryName);
160 | }
161 | return Path.Combine(appSettingsDirectoryName, "UserSettings.xml");
162 | }
163 |
164 | private void SerializeToFile(string fileName)
165 | {
166 | using (FileStream serializationStream = new FileStream(fileName, FileMode.Create))
167 | {
168 | CreateSerializer().Serialize(serializationStream, this);
169 | }
170 | }
171 |
172 | private void DeserializeFromFile(string fileName)
173 | {
174 | using (FileStream serializationStream = new FileStream(fileName, FileMode.Open))
175 | {
176 | UserSettings deserializedSettings;
177 | try
178 | {
179 | deserializedSettings = (UserSettings)CreateSerializer().Deserialize(serializationStream);
180 | }
181 | catch (Exception ex)
182 | {
183 | Trace.WriteLine("Unable to deserialize user settings: " + ex);
184 | deserializedSettings = new UserSettings();
185 | }
186 | instance = deserializedSettings;
187 | }
188 | }
189 |
190 | private void SaveExtendedOptions()
191 | {
192 | RegisterAppInWindowsStartup(LaunchOnWindowsStartup);
193 | }
194 |
195 | private void RegisterAppInWindowsStartup(bool autorun)
196 | {
197 | try
198 | {
199 | RegistryKey runKey = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run", true);
200 | if (runKey != null)
201 | {
202 | if (!autorun)
203 | {
204 | runKey.DeleteValue("Unicode Virtual Keyboard", false);
205 | }
206 | else
207 | {
208 | runKey.SetValue
209 | (
210 | "Unicode Virtual Keyboard",
211 | string.Format("\"{0}\"", Assembly.GetExecutingAssembly().Location),
212 | RegistryValueKind.String
213 | );
214 | }
215 | }
216 | }
217 | catch (Exception ex)
218 | {
219 | Trace.WriteLine("Failed to set app startup mode in Windows Registry: " + ex);
220 | }
221 | }
222 |
223 | ///
224 | /// Saves the user settings into default location.
225 | ///
226 | /// Whether to save the parameters that include heavyweight or uncommon tasks.
227 | public void Save(bool saveExtendedOptions)
228 | {
229 | try
230 | {
231 | Save(GetSettingsFileName(), saveExtendedOptions);
232 | }
233 | catch (Exception ex)
234 | {
235 | Trace.WriteLine("Failed to save user settings!" + Environment.NewLine + ex, "Error");
236 | }
237 | }
238 |
239 | ///
240 | /// Saves the user settings into a specific file.
241 | ///
242 | /// Settings file name.
243 | /// Whether to save the options that involve some heavyweight or uncommon operations while saving.
244 | public void Save(string fileName, bool saveExtendedOptions)
245 | {
246 | try
247 | {
248 | // This is a dirty solution but I really don't want to invoke the Windows Registry
249 | // every time the user saves his Favorites or closes the application.
250 | if (saveExtendedOptions)
251 | {
252 | SaveExtendedOptions();
253 | }
254 | SerializeToFile(fileName);
255 | }
256 | catch (Exception ex)
257 | {
258 | Trace.WriteLine("Failed to save user settings!" + Environment.NewLine + ex, "Error");
259 | }
260 | }
261 |
262 | ///
263 | /// Loads the user settings from default location.
264 | ///
265 | public void Load()
266 | {
267 | try
268 | {
269 | Load(GetSettingsFileName());
270 | }
271 | catch (Exception ex)
272 | {
273 | Trace.WriteLine("Failed to load user settings!" + Environment.NewLine + ex, "Error");
274 | }
275 | }
276 |
277 | ///
278 | /// Loads the user settings from a specific file
279 | ///
280 | /// Settings file name.
281 | public void Load(string fileName)
282 | {
283 | try
284 | {
285 | DeserializeFromFile(fileName);
286 | }
287 | catch (Exception ex)
288 | {
289 | Trace.WriteLine("Failed to load user settings!" + Environment.NewLine + ex, "Error");
290 | }
291 | }
292 | }
293 | }
294 |
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/Tools/ILMerge.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YuriyGuts/unicode-virtual-keyboard/d677ceceb2019c64f4b8de76118c6562b5cbf625/src/UnicodeKeyboard/Tools/ILMerge.exe
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/UI/AboutForm.Designer.cs:
--------------------------------------------------------------------------------
1 | using YuriyGuts.UnicodeKeyboard.ResourceWrappers;
2 |
3 | namespace YuriyGuts.UnicodeKeyboard.UI
4 | {
5 | partial class AboutForm
6 | {
7 | ///
8 | /// Required designer variable.
9 | ///
10 | private System.ComponentModel.IContainer components = null;
11 |
12 | ///
13 | /// Clean up any resources being used.
14 | ///
15 | /// true if managed resources should be disposed; otherwise, false.
16 | protected override void Dispose(bool disposing)
17 | {
18 | if (disposing && (components != null))
19 | {
20 | components.Dispose();
21 | }
22 | base.Dispose(disposing);
23 | }
24 |
25 | #region Windows Form Designer generated code
26 |
27 | ///
28 | /// Required method for Designer support - do not modify
29 | /// the contents of this method with the code editor.
30 | ///
31 | private void InitializeComponent()
32 | {
33 | SingleAssemblyComponentResourceManager resources = new SingleAssemblyComponentResourceManager(typeof(AboutForm));
34 | this.lblApplicationName = new System.Windows.Forms.Label();
35 | this.lblVersion = new System.Windows.Forms.Label();
36 | this.lblCopyright = new System.Windows.Forms.Label();
37 | this.lblThirdPartyLibraryNotice = new System.Windows.Forms.Label();
38 | this.lnkUserActivityMonitor = new System.Windows.Forms.LinkLabel();
39 | this.pnlLine = new System.Windows.Forms.Panel();
40 | this.lnkSilkIcons = new System.Windows.Forms.LinkLabel();
41 | this.lnkUnicodeCharacterDatabase = new System.Windows.Forms.LinkLabel();
42 | this.SuspendLayout();
43 | //
44 | // lblApplicationName
45 | //
46 | resources.ApplyResources(this.lblApplicationName, "lblApplicationName");
47 | this.lblApplicationName.ForeColor = System.Drawing.Color.SteelBlue;
48 | this.lblApplicationName.Name = "lblApplicationName";
49 | //
50 | // lblVersion
51 | //
52 | resources.ApplyResources(this.lblVersion, "lblVersion");
53 | this.lblVersion.ForeColor = System.Drawing.Color.Black;
54 | this.lblVersion.Name = "lblVersion";
55 | //
56 | // lblCopyright
57 | //
58 | resources.ApplyResources(this.lblCopyright, "lblCopyright");
59 | this.lblCopyright.ForeColor = System.Drawing.Color.Black;
60 | this.lblCopyright.Name = "lblCopyright";
61 | //
62 | // lblThirdPartyLibraryNotice
63 | //
64 | resources.ApplyResources(this.lblThirdPartyLibraryNotice, "lblThirdPartyLibraryNotice");
65 | this.lblThirdPartyLibraryNotice.ForeColor = System.Drawing.Color.Black;
66 | this.lblThirdPartyLibraryNotice.Name = "lblThirdPartyLibraryNotice";
67 | //
68 | // lnkUserActivityMonitor
69 | //
70 | this.lnkUserActivityMonitor.ActiveLinkColor = System.Drawing.Color.Blue;
71 | resources.ApplyResources(this.lnkUserActivityMonitor, "lnkUserActivityMonitor");
72 | this.lnkUserActivityMonitor.LinkColor = System.Drawing.Color.SteelBlue;
73 | this.lnkUserActivityMonitor.Name = "lnkUserActivityMonitor";
74 | this.lnkUserActivityMonitor.TabStop = true;
75 | this.lnkUserActivityMonitor.VisitedLinkColor = System.Drawing.Color.SteelBlue;
76 | this.lnkUserActivityMonitor.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.lnkUserActivityMonitor_LinkClicked);
77 | //
78 | // pnlLine
79 | //
80 | this.pnlLine.BackColor = System.Drawing.Color.LightSteelBlue;
81 | resources.ApplyResources(this.pnlLine, "pnlLine");
82 | this.pnlLine.Name = "pnlLine";
83 | //
84 | // lnkSilkIcons
85 | //
86 | this.lnkSilkIcons.ActiveLinkColor = System.Drawing.Color.Blue;
87 | resources.ApplyResources(this.lnkSilkIcons, "lnkSilkIcons");
88 | this.lnkSilkIcons.LinkColor = System.Drawing.Color.SteelBlue;
89 | this.lnkSilkIcons.Name = "lnkSilkIcons";
90 | this.lnkSilkIcons.TabStop = true;
91 | this.lnkSilkIcons.VisitedLinkColor = System.Drawing.Color.SteelBlue;
92 | this.lnkSilkIcons.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.lnkSilkIcons_LinkClicked);
93 | //
94 | // lnkUnicodeCharacterDatabase
95 | //
96 | this.lnkUnicodeCharacterDatabase.ActiveLinkColor = System.Drawing.Color.Blue;
97 | resources.ApplyResources(this.lnkUnicodeCharacterDatabase, "lnkUnicodeCharacterDatabase");
98 | this.lnkUnicodeCharacterDatabase.LinkColor = System.Drawing.Color.SteelBlue;
99 | this.lnkUnicodeCharacterDatabase.Name = "lnkUnicodeCharacterDatabase";
100 | this.lnkUnicodeCharacterDatabase.TabStop = true;
101 | this.lnkUnicodeCharacterDatabase.VisitedLinkColor = System.Drawing.Color.SteelBlue;
102 | this.lnkUnicodeCharacterDatabase.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.lnkUnicodeCharacterDatabase_LinkClicked);
103 | //
104 | // AboutForm
105 | //
106 | resources.ApplyResources(this, "$this");
107 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
108 | this.Controls.Add(this.lnkUnicodeCharacterDatabase);
109 | this.Controls.Add(this.lnkSilkIcons);
110 | this.Controls.Add(this.lnkUserActivityMonitor);
111 | this.Controls.Add(this.lblThirdPartyLibraryNotice);
112 | this.Controls.Add(this.pnlLine);
113 | this.Controls.Add(this.lblCopyright);
114 | this.Controls.Add(this.lblVersion);
115 | this.Controls.Add(this.lblApplicationName);
116 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
117 | this.MaximizeBox = false;
118 | this.MinimizeBox = false;
119 | this.Name = "AboutForm";
120 | this.ShowIcon = false;
121 | this.ShowInTaskbar = false;
122 | this.ResumeLayout(false);
123 |
124 | }
125 |
126 | #endregion
127 |
128 | private System.Windows.Forms.Label lblApplicationName;
129 | private System.Windows.Forms.Label lblVersion;
130 | private System.Windows.Forms.Label lblCopyright;
131 | private System.Windows.Forms.Label lblThirdPartyLibraryNotice;
132 | private System.Windows.Forms.LinkLabel lnkUserActivityMonitor;
133 | private System.Windows.Forms.Panel pnlLine;
134 | private System.Windows.Forms.LinkLabel lnkSilkIcons;
135 | private System.Windows.Forms.LinkLabel lnkUnicodeCharacterDatabase;
136 | }
137 | }
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/UI/AboutForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.Windows.Forms;
4 | using YuriyGuts.UnicodeKeyboard.ResourceWrappers;
5 |
6 | namespace YuriyGuts.UnicodeKeyboard.UI
7 | {
8 | public partial class AboutForm : Form
9 | {
10 | ///
11 | /// Initializes a new instance of AboutForm.
12 | ///
13 | public AboutForm()
14 | {
15 | InitializeComponent();
16 | }
17 |
18 | ///
19 | /// Shows the About form with the specified owner window.
20 | ///
21 | /// Owner window.
22 | public static void Execute(IWin32Window owner)
23 | {
24 | using (AboutForm aboutForm = new AboutForm())
25 | {
26 | aboutForm.ShowDialog(owner);
27 | }
28 | }
29 |
30 | protected override void OnLoad(EventArgs e)
31 | {
32 | base.OnLoad(e);
33 | InitializeMUI();
34 | }
35 |
36 | private void InitializeMUI()
37 | {
38 | lblApplicationName.Text = LocalizationHelper.GetGlobalResource("ApplicationName");
39 | lblCopyright.Text = LocalizationHelper.GetGlobalResource("Copyright");
40 | lblVersion.Text += @" " + LocalizationHelper.GetGlobalResource("ApplicationVersion");
41 | }
42 |
43 | private void OpenURLFromStringResource(string resourceKey)
44 | {
45 | string url = LocalizationHelper.GetResource(this, resourceKey);
46 | if (!string.IsNullOrEmpty(url))
47 | {
48 | Process.Start(url);
49 | }
50 | }
51 |
52 | private void lnkUserActivityMonitor_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
53 | {
54 | OpenURLFromStringResource("UserActivityMonitorURL");
55 | }
56 |
57 | private void lnkSilkIcons_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
58 | {
59 | OpenURLFromStringResource("SilkIconsURL");
60 | }
61 |
62 | private void lnkUnicodeCharacterDatabase_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
63 | {
64 | OpenURLFromStringResource("UnicodeCharacterDatabaseURL");
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/UI/AboutForm.ru.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | Виртуальная Юникод-клавиатура
122 |
123 |
124 | Версия
125 |
126 |
127 | Этот продукт использует следующие компоненты:
128 |
129 |
130 | О программе
131 |
132 |
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/UI/AboutForm.uk.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | Віртуальна Юнікод-клавіатура
122 |
123 |
124 | Версія
125 |
126 |
127 | Цей продукт використовує наступні компоненти:
128 |
129 |
130 | Про програму
131 |
132 |
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/UI/AddToFavoritesForm.Designer.cs:
--------------------------------------------------------------------------------
1 | using YuriyGuts.UnicodeKeyboard.ResourceWrappers;
2 |
3 | namespace YuriyGuts.UnicodeKeyboard.UI
4 | {
5 | partial class AddToFavoritesForm
6 | {
7 | ///
8 | /// Required designer variable.
9 | ///
10 | private System.ComponentModel.IContainer components = null;
11 |
12 | ///
13 | /// Clean up any resources being used.
14 | ///
15 | /// true if managed resources should be disposed; otherwise, false.
16 | protected override void Dispose(bool disposing)
17 | {
18 | if (disposing && (components != null))
19 | {
20 | components.Dispose();
21 | }
22 | base.Dispose(disposing);
23 | }
24 |
25 | #region Windows Form Designer generated code
26 |
27 | ///
28 | /// Required method for Designer support - do not modify
29 | /// the contents of this method with the code editor.
30 | ///
31 | private void InitializeComponent()
32 | {
33 | SingleAssemblyComponentResourceManager resources = new SingleAssemblyComponentResourceManager(typeof(AddToFavoritesForm));
34 | System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle4 = new System.Windows.Forms.DataGridViewCellStyle();
35 | System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();
36 | System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle();
37 | System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle3 = new System.Windows.Forms.DataGridViewCellStyle();
38 | this.pnlBottom = new System.Windows.Forms.Panel();
39 | this.btnOK = new System.Windows.Forms.Button();
40 | this.btnCancel = new System.Windows.Forms.Button();
41 | this.pnlTop = new System.Windows.Forms.Panel();
42 | this.lblUsageHint = new System.Windows.Forms.Label();
43 | this.lblCharacterName = new System.Windows.Forms.Label();
44 | this.lblCharacterPreview = new System.Windows.Forms.Label();
45 | this.pnlMiddle = new System.Windows.Forms.Panel();
46 | this.gridFavorites = new System.Windows.Forms.DataGridView();
47 | this.colIndex = new System.Windows.Forms.DataGridViewTextBoxColumn();
48 | this.colCharacterCode = new System.Windows.Forms.DataGridViewTextBoxColumn();
49 | this.colCharacterGlyph = new System.Windows.Forms.DataGridViewTextBoxColumn();
50 | this.colCharacterName = new System.Windows.Forms.DataGridViewTextBoxColumn();
51 | this.pnlBottom.SuspendLayout();
52 | this.pnlTop.SuspendLayout();
53 | this.pnlMiddle.SuspendLayout();
54 | ((System.ComponentModel.ISupportInitialize)(this.gridFavorites)).BeginInit();
55 | this.SuspendLayout();
56 | //
57 | // pnlBottom
58 | //
59 | resources.ApplyResources(this.pnlBottom, "pnlBottom");
60 | this.pnlBottom.Controls.Add(this.btnOK);
61 | this.pnlBottom.Controls.Add(this.btnCancel);
62 | this.pnlBottom.Name = "pnlBottom";
63 | //
64 | // btnOK
65 | //
66 | resources.ApplyResources(this.btnOK, "btnOK");
67 | this.btnOK.Name = "btnOK";
68 | this.btnOK.UseVisualStyleBackColor = true;
69 | this.btnOK.Click += new System.EventHandler(this.btnOK_Click);
70 | //
71 | // btnCancel
72 | //
73 | resources.ApplyResources(this.btnCancel, "btnCancel");
74 | this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
75 | this.btnCancel.Name = "btnCancel";
76 | this.btnCancel.UseVisualStyleBackColor = true;
77 | this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
78 | //
79 | // pnlTop
80 | //
81 | resources.ApplyResources(this.pnlTop, "pnlTop");
82 | this.pnlTop.Controls.Add(this.lblUsageHint);
83 | this.pnlTop.Controls.Add(this.lblCharacterName);
84 | this.pnlTop.Controls.Add(this.lblCharacterPreview);
85 | this.pnlTop.Name = "pnlTop";
86 | //
87 | // lblUsageHint
88 | //
89 | resources.ApplyResources(this.lblUsageHint, "lblUsageHint");
90 | this.lblUsageHint.Name = "lblUsageHint";
91 | //
92 | // lblCharacterName
93 | //
94 | resources.ApplyResources(this.lblCharacterName, "lblCharacterName");
95 | this.lblCharacterName.AutoEllipsis = true;
96 | this.lblCharacterName.Name = "lblCharacterName";
97 | //
98 | // lblCharacterPreview
99 | //
100 | resources.ApplyResources(this.lblCharacterPreview, "lblCharacterPreview");
101 | this.lblCharacterPreview.BackColor = System.Drawing.Color.WhiteSmoke;
102 | this.lblCharacterPreview.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
103 | this.lblCharacterPreview.Name = "lblCharacterPreview";
104 | //
105 | // pnlMiddle
106 | //
107 | resources.ApplyResources(this.pnlMiddle, "pnlMiddle");
108 | this.pnlMiddle.Controls.Add(this.gridFavorites);
109 | this.pnlMiddle.Name = "pnlMiddle";
110 | //
111 | // gridFavorites
112 | //
113 | resources.ApplyResources(this.gridFavorites, "gridFavorites");
114 | this.gridFavorites.AllowUserToAddRows = false;
115 | this.gridFavorites.AllowUserToDeleteRows = false;
116 | this.gridFavorites.AllowUserToResizeColumns = false;
117 | this.gridFavorites.AllowUserToResizeRows = false;
118 | this.gridFavorites.BackgroundColor = System.Drawing.SystemColors.Window;
119 | this.gridFavorites.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
120 | this.gridFavorites.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
121 | this.colIndex,
122 | this.colCharacterCode,
123 | this.colCharacterGlyph,
124 | this.colCharacterName});
125 | this.gridFavorites.Cursor = System.Windows.Forms.Cursors.Hand;
126 | dataGridViewCellStyle4.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
127 | dataGridViewCellStyle4.BackColor = System.Drawing.SystemColors.Window;
128 | dataGridViewCellStyle4.Font = new System.Drawing.Font("Tahoma", 8.25F);
129 | dataGridViewCellStyle4.ForeColor = System.Drawing.SystemColors.ControlText;
130 | dataGridViewCellStyle4.SelectionBackColor = System.Drawing.SystemColors.Window;
131 | dataGridViewCellStyle4.SelectionForeColor = System.Drawing.SystemColors.ControlText;
132 | dataGridViewCellStyle4.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
133 | this.gridFavorites.DefaultCellStyle = dataGridViewCellStyle4;
134 | this.gridFavorites.GridColor = System.Drawing.Color.WhiteSmoke;
135 | this.gridFavorites.MultiSelect = false;
136 | this.gridFavorites.Name = "gridFavorites";
137 | this.gridFavorites.ReadOnly = true;
138 | this.gridFavorites.RowHeadersVisible = false;
139 | this.gridFavorites.RowTemplate.Height = 30;
140 | this.gridFavorites.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
141 | this.gridFavorites.CellMouseEnter += new System.Windows.Forms.DataGridViewCellEventHandler(this.gridFavorites_CellMouseEnter);
142 | this.gridFavorites.CellMouseLeave += new System.Windows.Forms.DataGridViewCellEventHandler(this.gridFavorites_CellMouseLeave);
143 | this.gridFavorites.SelectionChanged += new System.EventHandler(this.gridFavorites_SelectionChanged);
144 | //
145 | // colIndex
146 | //
147 | this.colIndex.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None;
148 | dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
149 | dataGridViewCellStyle1.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
150 | this.colIndex.DefaultCellStyle = dataGridViewCellStyle1;
151 | resources.ApplyResources(this.colIndex, "colIndex");
152 | this.colIndex.Name = "colIndex";
153 | this.colIndex.ReadOnly = true;
154 | this.colIndex.Resizable = System.Windows.Forms.DataGridViewTriState.False;
155 | this.colIndex.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
156 | //
157 | // colCharacterCode
158 | //
159 | this.colCharacterCode.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None;
160 | dataGridViewCellStyle2.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
161 | this.colCharacterCode.DefaultCellStyle = dataGridViewCellStyle2;
162 | resources.ApplyResources(this.colCharacterCode, "colCharacterCode");
163 | this.colCharacterCode.Name = "colCharacterCode";
164 | this.colCharacterCode.ReadOnly = true;
165 | this.colCharacterCode.Resizable = System.Windows.Forms.DataGridViewTriState.False;
166 | this.colCharacterCode.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
167 | //
168 | // colCharacterGlyph
169 | //
170 | this.colCharacterGlyph.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.None;
171 | dataGridViewCellStyle3.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
172 | this.colCharacterGlyph.DefaultCellStyle = dataGridViewCellStyle3;
173 | resources.ApplyResources(this.colCharacterGlyph, "colCharacterGlyph");
174 | this.colCharacterGlyph.Name = "colCharacterGlyph";
175 | this.colCharacterGlyph.ReadOnly = true;
176 | this.colCharacterGlyph.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
177 | //
178 | // colCharacterName
179 | //
180 | this.colCharacterName.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
181 | resources.ApplyResources(this.colCharacterName, "colCharacterName");
182 | this.colCharacterName.Name = "colCharacterName";
183 | this.colCharacterName.ReadOnly = true;
184 | this.colCharacterName.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
185 | //
186 | // AddToFavoritesForm
187 | //
188 | this.AcceptButton = this.btnOK;
189 | resources.ApplyResources(this, "$this");
190 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
191 | this.CancelButton = this.btnCancel;
192 | this.Controls.Add(this.pnlMiddle);
193 | this.Controls.Add(this.pnlTop);
194 | this.Controls.Add(this.pnlBottom);
195 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow;
196 | this.Name = "AddToFavoritesForm";
197 | this.ShowIcon = false;
198 | this.ShowInTaskbar = false;
199 | this.Load += new System.EventHandler(this.FormAddToFavorites_Load);
200 | this.pnlBottom.ResumeLayout(false);
201 | this.pnlTop.ResumeLayout(false);
202 | this.pnlTop.PerformLayout();
203 | this.pnlMiddle.ResumeLayout(false);
204 | ((System.ComponentModel.ISupportInitialize)(this.gridFavorites)).EndInit();
205 | this.ResumeLayout(false);
206 |
207 | }
208 |
209 | #endregion
210 |
211 | private System.Windows.Forms.Panel pnlBottom;
212 | private System.Windows.Forms.Panel pnlTop;
213 | private System.Windows.Forms.Panel pnlMiddle;
214 | private System.Windows.Forms.DataGridView gridFavorites;
215 | private System.Windows.Forms.Button btnOK;
216 | private System.Windows.Forms.Button btnCancel;
217 | private System.Windows.Forms.Label lblCharacterPreview;
218 | private System.Windows.Forms.Label lblCharacterName;
219 | private System.Windows.Forms.Label lblUsageHint;
220 | private System.Windows.Forms.DataGridViewTextBoxColumn colIndex;
221 | private System.Windows.Forms.DataGridViewTextBoxColumn colCharacterCode;
222 | private System.Windows.Forms.DataGridViewTextBoxColumn colCharacterGlyph;
223 | private System.Windows.Forms.DataGridViewTextBoxColumn colCharacterName;
224 | }
225 | }
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/UI/AddToFavoritesForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.Drawing;
4 | using System.Windows.Forms;
5 | using YuriyGuts.UnicodeKeyboard.ResourceWrappers;
6 | using YuriyGuts.UnicodeKeyboard.Settings;
7 |
8 | namespace YuriyGuts.UnicodeKeyboard.UI
9 | {
10 | ///
11 | /// Represents the form used for adding a character to the Favorites.
12 | ///
13 | public partial class AddToFavoritesForm : Form
14 | {
15 | private static readonly Color gridNormalColor = SystemColors.Window;
16 | private static readonly Color gridHoverColor = Color.LightSteelBlue;
17 | private static readonly Color gridFavoriteColor = Color.LemonChiffon;
18 | private static readonly Color gridFavoriteHoverColor = Color.Khaki;
19 |
20 | ///
21 | /// Executes the Add To Favorites Form for the specified character.
22 | ///
23 | /// Character code.
24 | /// Owner window.
25 | ///
26 | public static int? Execute(ushort charCode, Control owner)
27 | {
28 | int? result = null;
29 | using (AddToFavoritesForm frmAddToFavorites = new AddToFavoritesForm())
30 | {
31 | frmAddToFavorites.CharacterCode = charCode;
32 | DialogResult dialogResult = frmAddToFavorites.ShowDialog(owner);
33 | if (dialogResult == DialogResult.OK)
34 | {
35 | result = frmAddToFavorites.SelectedIndex;
36 | }
37 | }
38 | return result;
39 | }
40 |
41 | private ushort characterCode;
42 |
43 | ///
44 | /// Gets or sets the code of the character to be placed into the Favorites panel.
45 | ///
46 | [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
47 | public ushort CharacterCode
48 | {
49 | get { return characterCode; }
50 | set
51 | {
52 | characterCode = value;
53 | lblCharacterPreview.Text = ((char)characterCode).ToString();
54 | lblCharacterName.Text = UnicodeCharacterDatabase.GetCharacterName(characterCode) ?? "(?)";
55 | }
56 | }
57 |
58 | private int? selectedIndex;
59 |
60 | ///
61 | /// Gets the index of the currently selected placeholder.
62 | ///
63 | [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
64 | public int? SelectedIndex
65 | {
66 | get { return selectedIndex; }
67 | }
68 |
69 | ///
70 | /// Initializes a new instance of AddToFavoritesForm.
71 | ///
72 | public AddToFavoritesForm()
73 | {
74 | InitializeComponent();
75 | InitializeComponentCustom();
76 | }
77 |
78 | private void InitializeComponentCustom()
79 | {
80 | lblCharacterPreview.Font = UIHelper.UnicodeCharacterFont;
81 | colCharacterGlyph.DefaultCellStyle.Font = UIHelper.UnicodeCharacterFont;
82 | gridFavorites.DefaultCellStyle.SelectionBackColor = gridFavoriteColor;
83 | }
84 |
85 | private void LoadFavorites()
86 | {
87 | gridFavorites.RowCount = UserSettings.Instance.Favorites.Length;
88 | for (int i = 0; i < gridFavorites.RowCount; i++)
89 | {
90 | ushort charCode = UserSettings.Instance.Favorites[i];
91 | gridFavorites[colIndex.Index, i].Value = i;
92 | PlaceCharacterIntoRow(i, charCode);
93 | }
94 | gridFavorites.ClearSelection();
95 | }
96 |
97 | private void PlaceCharacterIntoRow(int rowIndex, ushort charCode)
98 | {
99 | gridFavorites[colCharacterCode.Index, rowIndex].Value = charCode != 0 ? charCode.ToString("X4") : string.Empty;
100 | gridFavorites[colCharacterGlyph.Index, rowIndex].Value = charCode != 0 ? ((char)charCode).ToString() : string.Empty;
101 | gridFavorites[colCharacterName.Index, rowIndex].Value = charCode != 0 ? UnicodeCharacterDatabase.GetCharacterName(charCode) : string.Empty;
102 | }
103 |
104 | private void SetRowBackgroundColor(int rowIndex, Color newBackColor)
105 | {
106 | for (int i = 0; i < gridFavorites.ColumnCount; i++)
107 | {
108 | gridFavorites[i, rowIndex].Style.BackColor = newBackColor;
109 | }
110 | }
111 |
112 | private void FormAddToFavorites_Load(object sender, EventArgs e)
113 | {
114 | LoadFavorites();
115 | btnOK.Enabled = false;
116 | }
117 |
118 | private void gridFavorites_CellMouseEnter(object sender, DataGridViewCellEventArgs e)
119 | {
120 | if (e.RowIndex >= 0)
121 | {
122 | SetRowBackgroundColor(e.RowIndex, selectedIndex != e.RowIndex ? gridHoverColor : gridFavoriteHoverColor);
123 | }
124 | }
125 |
126 | private void gridFavorites_CellMouseLeave(object sender, DataGridViewCellEventArgs e)
127 | {
128 | if (e.RowIndex >= 0)
129 | {
130 | SetRowBackgroundColor(e.RowIndex, selectedIndex != e.RowIndex ? gridNormalColor : gridFavoriteColor);
131 | }
132 | }
133 |
134 | private void gridFavorites_SelectionChanged(object sender, EventArgs e)
135 | {
136 | bool selectionExists = gridFavorites.SelectedRows.Count > 0;
137 |
138 | // Discard the previously selected placeholder.
139 | if (selectedIndex != null)
140 | {
141 | PlaceCharacterIntoRow(selectedIndex.Value, UserSettings.Instance.Favorites[selectedIndex.Value]);
142 | SetRowBackgroundColor(selectedIndex.Value, gridNormalColor);
143 | }
144 | selectedIndex = selectionExists ? gridFavorites.SelectedRows[0].Index : (int?)null;
145 |
146 | // Apply new selection.
147 | if (selectionExists)
148 | {
149 | PlaceCharacterIntoRow(selectedIndex.Value, CharacterCode);
150 | }
151 |
152 | // Refresh background colors.
153 | for (int i = 0; i < gridFavorites.Rows.Count; i++)
154 | {
155 | SetRowBackgroundColor(i, i != selectedIndex ? gridNormalColor : gridFavoriteColor);
156 | }
157 |
158 | btnOK.Enabled = selectionExists;
159 | }
160 |
161 | private void btnOK_Click(object sender, EventArgs e)
162 | {
163 | DialogResult = DialogResult.OK;
164 | }
165 |
166 | private void btnCancel_Click(object sender, EventArgs e)
167 | {
168 | DialogResult = DialogResult.Cancel;
169 | }
170 | }
171 | }
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/UI/AddToFavoritesForm.ru.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | Отмена
122 |
123 |
124 |
125 | 197, 13
126 |
127 |
128 | Выберите ячейку для этого символа:
129 |
130 |
131 | №
132 |
133 |
134 | Код
135 |
136 |
137 | Название
138 |
139 |
140 | Добавить на панель быстрого доступа
141 |
142 |
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/UI/AddToFavoritesForm.uk.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | Скасувати
122 |
123 |
124 |
125 | 196, 13
126 |
127 |
128 | Оберіть клітинку для цього символу:
129 |
130 |
131 | №
132 |
133 |
134 | Код
135 |
136 |
137 | Назва
138 |
139 |
140 | Додати до панелі швидкого доступу
141 |
142 |
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/UI/CapturedWindow.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using System.Windows.Forms;
4 | using YuriyGuts.UnicodeKeyboard.WindowsIntegration;
5 |
6 | namespace YuriyGuts.UnicodeKeyboard.UI
7 | {
8 | ///
9 | /// Represents the window captured by the Window Finder tool.
10 | /// Portions Copyright (c) 2005 Corneliu I. Tusnea [http://hawkeye.codeplex.com/].
11 | ///
12 | internal class CapturedWindow : IDisposable
13 | {
14 | private IntPtr handle = IntPtr.Zero;
15 | private readonly Pen highlightPen = new Pen(Brushes.Red, 2);
16 |
17 | private object selectedObject;
18 |
19 | public IntPtr Handle
20 | {
21 | get { return handle; }
22 | }
23 |
24 | public object ActiveObject
25 | {
26 | get { return selectedObject; }
27 | }
28 |
29 | public object ActiveWindow
30 | {
31 | get
32 | {
33 | if (handle != IntPtr.Zero)
34 | {
35 | return Control.FromHandle(handle);
36 | }
37 | return null;
38 | }
39 | }
40 |
41 | public string ClassName
42 | {
43 | get
44 | {
45 | if (!IsValid)
46 | {
47 | return null;
48 | }
49 | return NativeMethods.GetClassName(handle);
50 | }
51 | }
52 |
53 | public bool IsManagedByClassName
54 | {
55 | get
56 | {
57 | string className = ClassName;
58 | if (className != null && className.StartsWith("WindowsForms10"))
59 | {
60 | return true;
61 | }
62 | return false;
63 | }
64 | }
65 |
66 | public bool IsValid
67 | {
68 | get { return handle != IntPtr.Zero; }
69 | }
70 |
71 | public bool IsManaged
72 | {
73 | get { return ActiveWindow != null; }
74 | }
75 |
76 | internal bool SetWindowHandle(IntPtr hWnd)
77 | {
78 | Refresh();
79 | handle = hWnd;
80 |
81 | Refresh();
82 | Highlight();
83 |
84 | bool changed = false;
85 | object activeWindow = ActiveWindow;
86 | if (activeWindow != selectedObject)
87 | {
88 | changed = true;
89 | selectedObject = activeWindow;
90 | }
91 |
92 | return changed;
93 | }
94 |
95 | public void Refresh()
96 | {
97 | if (!IsValid)
98 | {
99 | return;
100 | }
101 |
102 | IntPtr windowToRedraw = handle;
103 | IntPtr parentWindow = NativeMethods.GetParent(windowToRedraw);
104 | if (parentWindow != IntPtr.Zero)
105 | {
106 | windowToRedraw = parentWindow;
107 | }
108 |
109 | NativeMethods.InvalidateRect(windowToRedraw, IntPtr.Zero, true);
110 | NativeMethods.UpdateWindow(windowToRedraw);
111 | NativeMethods.RedrawWindow
112 | (
113 | windowToRedraw,
114 | IntPtr.Zero,
115 | IntPtr.Zero,
116 | NativeStructs.RDW.RDW_FRAME
117 | | NativeStructs.RDW.RDW_INVALIDATE
118 | | NativeStructs.RDW.RDW_UPDATENOW
119 | | NativeStructs.RDW.RDW_ERASENOW
120 | | NativeStructs.RDW.RDW_ALLCHILDREN
121 | );
122 | }
123 |
124 | public void Highlight()
125 | {
126 | NativeStructs.RECT windowRect = new NativeStructs.RECT(0, 0, 0, 0);
127 | NativeMethods.GetWindowRect(handle, ref windowRect);
128 |
129 | IntPtr windowDC = NativeMethods.GetWindowDC(handle);
130 | if (windowDC != IntPtr.Zero)
131 | {
132 | Graphics graph = Graphics.FromHdc(windowDC, handle);
133 | graph.DrawRectangle(highlightPen, 1, 1, windowRect.Width - 2, windowRect.Height - 2);
134 | graph.Dispose();
135 | NativeMethods.ReleaseDC(handle, windowDC);
136 | }
137 | }
138 |
139 | #region IDisposable Members
140 |
141 | public void Dispose()
142 | {
143 | Refresh();
144 | highlightPen.Dispose();
145 | }
146 |
147 | #endregion
148 | }
149 | }
150 |
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/UI/CharacterLookupForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Drawing;
5 | using System.Globalization;
6 | using System.Windows.Forms;
7 | using YuriyGuts.UnicodeKeyboard.Interaction;
8 | using YuriyGuts.UnicodeKeyboard.ResourceWrappers;
9 |
10 | namespace YuriyGuts.UnicodeKeyboard.UI
11 | {
12 | ///
13 | /// Represents the character search form.
14 | ///
15 | public partial class CharacterLookupForm : Form
16 | {
17 | private readonly char[] namePartSeparators = { ' ' };
18 |
19 | private string searchQuery;
20 | private List> lastSearchResults;
21 |
22 | ///
23 | /// Gets or sets the current character name filter.
24 | ///
25 | [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
26 | public string SearchQuery
27 | {
28 | get
29 | {
30 | return searchQuery;
31 | }
32 | set
33 | {
34 | searchQuery = value;
35 | PerformSearch();
36 | }
37 | }
38 |
39 | public event EventHandler ResultSubmitted;
40 |
41 | ///
42 | /// Initializes a new instance of CharacterLookupForm.
43 | ///
44 | public CharacterLookupForm()
45 | {
46 | InitializeComponent();
47 | InitializeComponentCustom();
48 | }
49 |
50 | private void InitializeComponentCustom()
51 | {
52 | colCharacterGlyph.DefaultCellStyle.Font = UIHelper.UnicodeCharacterFont;
53 | }
54 |
55 | public void SubmitResult(CharacterSearchResult result)
56 | {
57 | if (result.Action != CharacterSearchAction.None)
58 | {
59 | Hide();
60 | }
61 | OnResultSubmitted(new CharacterSearchResultEventArgs(result));
62 | }
63 |
64 | protected virtual void OnResultSubmitted(CharacterSearchResultEventArgs e)
65 | {
66 | if (ResultSubmitted != null)
67 | {
68 | ResultSubmitted(this, e);
69 | }
70 | }
71 |
72 | private void PerformSearch()
73 | {
74 | UseWaitCursor = true;
75 |
76 | // Try to search by character code first...
77 | lastSearchResults = UnicodeCharacterDatabase.FindCharactersByCodeString(SearchQuery);
78 |
79 | // ...If that fails, search characters by name.
80 | if (lastSearchResults == null || lastSearchResults.Count == 0)
81 | {
82 | if (SearchQuery.Contains(" ") && SearchQuery.Trim().Length > 0)
83 | {
84 | string[] filterParts = SearchQuery.Split(namePartSeparators, StringSplitOptions.RemoveEmptyEntries);
85 | string regexPattern = string.Join(@".*?", filterParts);
86 | lastSearchResults = UnicodeCharacterDatabase.FindCharactersByNameRegex(regexPattern);
87 | }
88 | else
89 | {
90 | lastSearchResults = UnicodeCharacterDatabase.FindCharactersByName(SearchQuery, false);
91 | }
92 | }
93 |
94 | gridResultDisplayer.Rows.Clear();
95 | gridResultDisplayer.RowCount = lastSearchResults.Count;
96 | if (!Focused)
97 | {
98 | gridResultDisplayer.ClearSelection();
99 | }
100 |
101 | UseWaitCursor = false;
102 | }
103 |
104 | private ushort GetSelectedCharacter()
105 | {
106 | ushort result = 0;
107 | if (gridResultDisplayer.SelectedRows.Count == 1)
108 | {
109 | result = GetCharacterCodeFromRow(gridResultDisplayer.SelectedRows[0].Index);
110 | }
111 | return result;
112 | }
113 |
114 | private ushort GetCharacterCodeFromRow(int rowIndex)
115 | {
116 | string cellValueHex = gridResultDisplayer.Rows[rowIndex].Cells[colCharacterCode.Index].Value.ToString();
117 | return ushort.Parse(cellValueHex, NumberStyles.HexNumber);
118 | }
119 |
120 | private static bool KeyHasNoModifiers(KeyEventArgs args)
121 | {
122 | return !args.Alt && !args.Control && !args.Shift;
123 | }
124 |
125 | private static bool KeyHasControlModifierOnly(KeyEventArgs args)
126 | {
127 | return !args.Alt && args.Control && !args.Shift;
128 | }
129 |
130 | private void CharacterLookupForm_Activated(object sender, EventArgs e)
131 | {
132 | gridResultDisplayer.DefaultCellStyle.SelectionBackColor = Color.LightSteelBlue;
133 | if (gridResultDisplayer.RowCount > 0)
134 | {
135 | gridResultDisplayer.Rows[gridResultDisplayer.FirstDisplayedScrollingRowIndex].Selected = true;
136 | }
137 | }
138 |
139 | private void CharacterLookupForm_Deactivate(object sender, EventArgs e)
140 | {
141 | gridResultDisplayer.DefaultCellStyle.SelectionBackColor = Color.Gainsboro;
142 | }
143 |
144 | private void CharacterLookupForm_Shown(object sender, EventArgs e)
145 | {
146 | if (SearchQuery != null)
147 | {
148 | PerformSearch();
149 | }
150 | }
151 |
152 | private void gridResultDisplayer_KeyDown(object sender, KeyEventArgs e)
153 | {
154 | // Esc: close form.
155 | if (KeyHasNoModifiers(e) && e.KeyCode == Keys.Escape)
156 | {
157 | e.Handled = e.SuppressKeyPress = true;
158 | SubmitResult(new CharacterSearchResult
159 | {
160 | Action = CharacterSearchAction.Cancel,
161 | CharacterCode = 0,
162 | });
163 | }
164 |
165 | // Enter: insert character.
166 | if ((KeyHasNoModifiers(e) || KeyHasControlModifierOnly(e)) && e.KeyCode == Keys.Enter)
167 | {
168 | ushort charCode = GetSelectedCharacter();
169 | if (charCode != 0)
170 | {
171 | SubmitResult(new CharacterSearchResult
172 | {
173 | Action = CharacterSearchAction.InsertCharacter,
174 | CharacterCode = charCode,
175 | KeepApplicationActive = KeyHasControlModifierOnly(e),
176 | });
177 | }
178 | }
179 |
180 | // Ctrl + C: copy selected character to clipboard.
181 | if (KeyHasControlModifierOnly(e) && e.KeyCode == Keys.C)
182 | {
183 | e.Handled = e.SuppressKeyPress = true;
184 | SubmitResult(new CharacterSearchResult
185 | {
186 | Action = CharacterSearchAction.CopyCharacterToClipboard,
187 | CharacterCode = GetSelectedCharacter(),
188 | });
189 | }
190 |
191 | // Ctrl + D: add selected character to Favorites.
192 | if (KeyHasControlModifierOnly(e) && e.KeyCode == Keys.D)
193 | {
194 | e.Handled = e.SuppressKeyPress = true;
195 | SubmitResult(new CharacterSearchResult
196 | {
197 | Action = CharacterSearchAction.AddCharacterToFavorites,
198 | CharacterCode = GetSelectedCharacter(),
199 | });
200 | }
201 |
202 | // Backspace, Delete: return the focus to the owner.
203 | if (KeyHasNoModifiers(e) && (e.KeyCode == Keys.Back || e.KeyCode == Keys.Delete))
204 | {
205 | if (Owner != null)
206 | {
207 | gridResultDisplayer.ClearSelection();
208 | Owner.Focus();
209 | }
210 | }
211 | }
212 |
213 | private void gridResultDisplayer_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
214 | {
215 | if (lastSearchResults.Count > e.RowIndex)
216 | {
217 | KeyValuePair dataEntry = lastSearchResults[e.RowIndex];
218 |
219 | if (e.ColumnIndex == colCharacterCode.Index)
220 | {
221 | e.Value = dataEntry.Key.ToString("X4");
222 | }
223 | else if (e.ColumnIndex == colCharacterGlyph.Index)
224 | {
225 | e.Value = (char)dataEntry.Key;
226 | }
227 | else if (e.ColumnIndex == colCharacterName.Index)
228 | {
229 | e.Value = dataEntry.Value;
230 | }
231 | }
232 | }
233 |
234 | private void gridResultDisplayer_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
235 | {
236 | if (e.RowIndex >= 0)
237 | {
238 | ushort charCode = GetCharacterCodeFromRow(e.RowIndex);
239 | SubmitResult(new CharacterSearchResult
240 | {
241 | Action = CharacterSearchAction.InsertCharacter,
242 | CharacterCode = charCode,
243 | });
244 | }
245 | }
246 |
247 | private void tmrSearchTimeout_Tick(object sender, EventArgs e)
248 | {
249 | PerformSearch();
250 | }
251 | }
252 | }
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/UI/CharacterLookupForm.ru.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | Код
122 |
123 |
124 | Название
125 |
126 |
127 | Добавить в Быстрый доступ
128 |
129 |
130 | Копировать в буфер обмена
131 |
132 |
133 | Вставить символ
134 |
135 |
136 | Поиск символов
137 |
138 |
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/UI/CharacterLookupForm.uk.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | Код
122 |
123 |
124 | Назва
125 |
126 |
127 |
128 | 103, 29
129 |
130 |
131 | Додати до швидкого доступу
132 |
133 |
134 | Скопіювати до буфера обміну
135 |
136 |
137 | Вставити символ
138 |
139 |
140 | Пошук символів
141 |
142 |
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/UI/IKeyboardShortcutTranscriber.cs:
--------------------------------------------------------------------------------
1 | using System.Windows.Forms;
2 |
3 | namespace YuriyGuts.UnicodeKeyboard.UI
4 | {
5 | ///
6 | /// Provides user-friendly keyboard shortcut transcription services.
7 | ///
8 | public interface IKeyboardShortcutTranscriber
9 | {
10 | ///
11 | /// Provides a user-friendly string representation of an instance of Keys.
12 | ///
13 | /// An instance of the Keys enumeration.
14 | /// String representation of the specified Keys instance.
15 | string GetKeyboardShortcutDisplayText(Keys key);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/UI/KeyboardShortcutEditor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.Drawing;
4 | using System.Windows.Forms;
5 |
6 | namespace YuriyGuts.UnicodeKeyboard.UI
7 | {
8 | public class KeyboardShortcutEditor : TextBox
9 | {
10 | protected Keys value;
11 |
12 | public KeyboardShortcutEditor()
13 | {
14 | ReadOnly = true;
15 | ValidShortcutColor = Color.Green;
16 | InvalidShortcutColor = Color.Red;
17 | }
18 |
19 | [Category("Appearance")]
20 | public Color ValidShortcutColor { get; set; }
21 |
22 | [Category("Appearance")]
23 | public Color InvalidShortcutColor { get; set; }
24 |
25 | [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
26 | public virtual Keys Value
27 | {
28 | get
29 | {
30 | return value;
31 | }
32 | set
33 | {
34 | if (this.value != value)
35 | {
36 | this.value = value;
37 | Text = GetKeystrokeDisplayText(value);
38 | bool isValid = OnValidateShortcut(value);
39 | ForeColor = isValid ? ValidShortcutColor : InvalidShortcutColor;
40 | OnValueChanged();
41 | }
42 | }
43 | }
44 |
45 | [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
46 | public IKeyboardShortcutTranscriber Transcriber { get; set; }
47 |
48 | protected override void OnReadOnlyChanged(EventArgs e)
49 | {
50 | base.OnReadOnlyChanged(e);
51 |
52 | // Do not allow the TextBox to become editable because we always supply our own Text.
53 | ReadOnly = true;
54 | }
55 |
56 | protected override void OnKeyDown(KeyEventArgs e)
57 | {
58 | base.OnKeyDown(e);
59 |
60 | Keys keys = e.KeyData;
61 | Keys preProcessedKey = PreProcessKeystroke(keys);
62 | Value = preProcessedKey;
63 |
64 | e.Handled = true;
65 | e.SuppressKeyPress = true;
66 | }
67 |
68 | private bool IsModifierSourceKey(Keys keys)
69 | {
70 | bool isAltKey = (keys & Keys.Menu) == Keys.Menu && (keys & ~Keys.Modifiers) == Keys.Menu;
71 | bool isControlKey = (keys & Keys.ControlKey) == Keys.ControlKey && (keys & ~Keys.Modifiers) == Keys.ControlKey;
72 | bool isShiftKey = (keys & Keys.ShiftKey) == Keys.ShiftKey && (keys & ~Keys.Modifiers) == Keys.ShiftKey;
73 |
74 | bool result = isAltKey || isControlKey || isShiftKey;
75 | return result;
76 | }
77 |
78 | protected virtual Keys PreProcessKeystroke(Keys keys)
79 | {
80 | Keys result = keys;
81 |
82 | // Do not allow the Menu, ControlKey and ShiftKey keys to show up.
83 | if (IsModifierSourceKey(keys))
84 | {
85 | // Leave modifiers only (for better visual feedback) and clear the actual keys.
86 | result = keys & Keys.Modifiers;
87 | }
88 | return result;
89 | }
90 |
91 | private string GetKeystrokeDisplayText(Keys keys)
92 | {
93 | string result;
94 | if (Transcriber != null)
95 | {
96 | result = Transcriber.GetKeyboardShortcutDisplayText(keys);
97 | }
98 | else
99 | {
100 | result = keys.ToString();
101 | }
102 | return result;
103 | }
104 |
105 | #region Events
106 |
107 | public event EventHandler ValueChanged;
108 | public event EventHandler ValidateShortcut;
109 |
110 | protected virtual void OnValueChanged()
111 | {
112 | EventHandler handler = ValueChanged;
113 | if (handler != null)
114 | {
115 | handler(this, EventArgs.Empty);
116 | }
117 | }
118 |
119 | protected virtual bool OnValidateShortcut(Keys shortcut)
120 | {
121 | bool result = true;
122 |
123 | EventHandler handler = ValidateShortcut;
124 | if (handler != null)
125 | {
126 | foreach (Delegate currentHandler in handler.GetInvocationList())
127 | {
128 | KeyboardShortcutValidationEventArgs args = new KeyboardShortcutValidationEventArgs(shortcut);
129 | currentHandler.DynamicInvoke(this, args);
130 |
131 | result &= args.IsValid;
132 | if (!result)
133 | {
134 | break;
135 | }
136 | }
137 | }
138 |
139 | return result;
140 | }
141 |
142 | #endregion Events
143 | }
144 |
145 | public class KeyboardShortcutValidationEventArgs : EventArgs
146 | {
147 | public Keys Keys { get; set; }
148 | public bool IsValid { get; set; }
149 |
150 | public KeyboardShortcutValidationEventArgs(Keys keys)
151 | {
152 | Keys = keys;
153 | IsValid = true;
154 | }
155 | }
156 | }
157 |
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/UI/KeyboardShortcutTranscriber.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Windows.Forms;
3 |
4 | namespace YuriyGuts.UnicodeKeyboard.UI
5 | {
6 | public class KeyboardShortcutTranscriber : IKeyboardShortcutTranscriber
7 | {
8 | protected Dictionary keyNameSubstitutionDictionary;
9 |
10 | ///
11 | /// Singleton implementation.
12 | ///
13 | private static KeyboardShortcutTranscriber instance;
14 | public static KeyboardShortcutTranscriber Instance
15 | {
16 | get { return instance ?? (instance = new KeyboardShortcutTranscriber()); }
17 | }
18 |
19 | public string GetKeyboardShortcutDisplayText(Keys keys)
20 | {
21 | if (keyNameSubstitutionDictionary == null)
22 | {
23 | InitializeKeyNameSubstitutionDictionary();
24 | }
25 |
26 | List parts = new List();
27 |
28 | // Append modifier prefixes.
29 | if ((keys & Keys.Control) == Keys.Control)
30 | {
31 | parts.Add("Ctrl");
32 | }
33 | if ((keys & Keys.Alt) == Keys.Alt)
34 | {
35 | parts.Add("Alt");
36 | }
37 | if ((keys & Keys.Shift) == Keys.Shift)
38 | {
39 | parts.Add("Shift");
40 | }
41 |
42 | // Append the meaningful key itself.
43 | Keys meaningfulKey = keys & ~Keys.Modifiers;
44 | if (meaningfulKey != Keys.None)
45 | {
46 | string meaningfulKeyName = meaningfulKey.ToString();
47 | if (keyNameSubstitutionDictionary != null && keyNameSubstitutionDictionary.ContainsKey(meaningfulKeyName))
48 | {
49 | meaningfulKeyName = keyNameSubstitutionDictionary[meaningfulKeyName];
50 | }
51 | parts.Add(meaningfulKeyName);
52 | }
53 |
54 | string result = string.Join(" + ", parts.ToArray());
55 | return result;
56 | }
57 |
58 | protected virtual void InitializeKeyNameSubstitutionDictionary()
59 | {
60 | keyNameSubstitutionDictionary = new Dictionary
61 | {
62 | { "D0", "0" },
63 | { "D1", "1" },
64 | { "D2", "2" },
65 | { "D3", "3" },
66 | { "D4", "4" },
67 | { "D5", "5" },
68 | { "D6", "6" },
69 | { "D7", "7" },
70 | { "D8", "8" },
71 | { "D9", "9" },
72 | { "Add", "'NumPad +'" },
73 | { "Subtract", "'NumPad -'" },
74 | { "Multiply", "'NumPad *'" },
75 | { "Divide", "'NumPad /'" },
76 | { "Decimal", "'NumPad .'" },
77 | { "Back", "Backspace" },
78 | { "Next", "PageDown" },
79 | { "Return", "Enter" },
80 | { "Oem1", "OEM 1" },
81 | { "Oem102", "OEM 102" },
82 | { "Oem2", "OEM 2" },
83 | { "Oem3", "OEM 3" },
84 | { "Oem4", "OEM 4" },
85 | { "Oem5", "OEM 5" },
86 | { "Oem6", "OEM 6" },
87 | { "Oem7", "OEM 7" },
88 | { "Oem8", "OEM 8" },
89 | { "OemBackslash", "OEM '\\'" },
90 | { "OemCloseBrackets", "OEM ']'" },
91 | { "OemMinus", "OEM '-'" },
92 | { "OemOpenBrackets", "OEM '['" },
93 | { "OemPeriod", "OEM '.'" },
94 | { "OemPipe", "OEM '|'" },
95 | { "OemQuotes", "OEM Quote" },
96 | { "OemQuestion", "OEM '?'" },
97 | { "OemSemicolon", "OEM ';'" },
98 | { "Oemcomma", "OEM ','" },
99 | { "Oemplus", "OEM '+'" },
100 | { "Oemtilde", "OEM '~'" },
101 | };
102 | }
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/UI/OptionsForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Data;
3 | using System.Windows.Forms;
4 | using YuriyGuts.UnicodeKeyboard.ResourceWrappers;
5 | using YuriyGuts.UnicodeKeyboard.Settings;
6 |
7 | namespace YuriyGuts.UnicodeKeyboard.UI
8 | {
9 | ///
10 | /// Application options form.
11 | ///
12 | public partial class OptionsForm : Form
13 | {
14 | private string oldLanguageCode;
15 | private DataTable languageTable;
16 |
17 | private const string LanguageCodeColumn = "LanguageCode";
18 | private const string LanguageNameColumn = "LanguageName";
19 |
20 | ///
21 | /// Initializes a new instance of the OptionsForm class.
22 | ///
23 | public OptionsForm()
24 | {
25 | InitializeComponent();
26 | InitializeComponentCustom();
27 | }
28 |
29 | private void InitializeComponentCustom()
30 | {
31 | languageTable = new DataTable();
32 | languageTable.Columns.Add(LanguageCodeColumn, typeof(string));
33 | languageTable.Columns.Add(LanguageNameColumn, typeof(string));
34 |
35 | languageTable.Rows.Add("en", "English");
36 | languageTable.Rows.Add("ru", "Russian");
37 | languageTable.Rows.Add("uk", "Ukrainian");
38 | }
39 |
40 | ///
41 | /// Opens the Options form with the specified owner window.
42 | ///
43 | /// Owner window.
44 | /// DialogResult of the OptionsForm.
45 | public static DialogResult Execute(IWin32Window owner)
46 | {
47 | DialogResult result;
48 | using (OptionsForm optionsForm = new OptionsForm())
49 | {
50 | result = optionsForm.ShowDialog(owner);
51 | }
52 | return result;
53 | }
54 |
55 | protected override void OnLoad(EventArgs e)
56 | {
57 | base.OnLoad(e);
58 | InitializeMUI();
59 | LoadData();
60 | }
61 |
62 | private void InitializeMUI()
63 | {
64 | languageTable.Rows[0][LanguageNameColumn] = LocalizationHelper.GetGlobalResource("Language_EN_US");
65 | languageTable.Rows[1][LanguageNameColumn] = LocalizationHelper.GetGlobalResource("Language_RU_RU");
66 | languageTable.Rows[2][LanguageNameColumn] = LocalizationHelper.GetGlobalResource("Language_UK_UA");
67 | }
68 |
69 | private void LoadData()
70 | {
71 | oldLanguageCode = UserSettings.Instance.Language;
72 | cmbInterfaceLanguage.DisplayMember = LanguageNameColumn;
73 | cmbInterfaceLanguage.ValueMember = LanguageCodeColumn;
74 | cmbInterfaceLanguage.DataSource = languageTable;
75 | cmbInterfaceLanguage.SelectedValue = UserSettings.Instance.Language;
76 |
77 | kbdPrimaryShortcut.Transcriber = KeyboardShortcutTranscriber.Instance;
78 | kbdSecondaryShortcut.Transcriber = KeyboardShortcutTranscriber.Instance;
79 |
80 | kbdPrimaryShortcut.Value = UserSettings.Instance.PrimaryApplicationShortcut;
81 | kbdSecondaryShortcut.Value = UserSettings.Instance.SecondaryApplicationShortcut;
82 |
83 | chkShowIconInSystemTray.Checked = UserSettings.Instance.ShowIconInSystemTray;
84 | chkMinimizeOnFocusLost.Checked = UserSettings.Instance.MinimizeOnFocusLost;
85 | chkExitOnClose.Checked = UserSettings.Instance.TerminateOnClose;
86 | chkLaunchOnWindowsStartup.Checked = UserSettings.Instance.LaunchOnWindowsStartup;
87 | }
88 |
89 | private bool ValidateData()
90 | {
91 | if (kbdPrimaryShortcut.Value == kbdSecondaryShortcut.Value)
92 | {
93 | ShowValidationErrorMessage(LocalizationHelper.GetResource(this, "msgDuplicateKeyboardShortcuts"));
94 | return false;
95 | }
96 | if (!IsKeyboardShortcutValid(kbdPrimaryShortcut.Value))
97 | {
98 | ShowValidationErrorMessage(LocalizationHelper.GetResource(this, "msgInvalidPrimaryShortcut"));
99 | return false;
100 | }
101 | if (!IsKeyboardShortcutValid(kbdSecondaryShortcut.Value))
102 | {
103 | ShowValidationErrorMessage(LocalizationHelper.GetResource(this, "msgInvalidSecondaryShortcut"));
104 | return false;
105 | }
106 |
107 | return true;
108 | }
109 |
110 | private void ShowValidationErrorMessage(string message)
111 | {
112 | MessageBox.Show
113 | (
114 | this,
115 | message,
116 | LocalizationHelper.GetGlobalResource("Error"),
117 | MessageBoxButtons.OK,
118 | MessageBoxIcon.Exclamation
119 | );
120 | }
121 |
122 | private void ApplyAndSaveSettings()
123 | {
124 | UserSettings.Instance.Language = cmbInterfaceLanguage.SelectedValue.ToString();
125 |
126 | UserSettings.Instance.PrimaryApplicationShortcut = kbdPrimaryShortcut.Value;
127 | UserSettings.Instance.SecondaryApplicationShortcut = kbdSecondaryShortcut.Value;
128 |
129 | UserSettings.Instance.ShowIconInSystemTray = chkShowIconInSystemTray.Checked;
130 | UserSettings.Instance.MinimizeOnFocusLost = chkMinimizeOnFocusLost.Checked;
131 | UserSettings.Instance.TerminateOnClose = chkExitOnClose.Checked;
132 | UserSettings.Instance.LaunchOnWindowsStartup = chkLaunchOnWindowsStartup.Checked;
133 |
134 | UserSettings.Instance.Save(true);
135 | }
136 |
137 | private void CheckIfLanguageChangedAndOfferRestart()
138 | {
139 | if (cmbInterfaceLanguage.SelectedValue.ToString().ToLower() != oldLanguageCode.ToLower())
140 | {
141 | DialogResult restartConfirmationResult = MessageBox.Show
142 | (
143 | this,
144 | LocalizationHelper.GetResource(this, "msgLanguageSettingsAppRestartConfirmation"),
145 | Text,
146 | MessageBoxButtons.YesNo,
147 | MessageBoxIcon.Question
148 | );
149 |
150 | if (restartConfirmationResult == DialogResult.Yes)
151 | {
152 | Application.Restart();
153 | }
154 | }
155 | }
156 |
157 | private void btnOK_Click(object sender, EventArgs e)
158 | {
159 | if (ValidateData())
160 | {
161 | ApplyAndSaveSettings();
162 | CheckIfLanguageChangedAndOfferRestart();
163 | DialogResult = DialogResult.OK;
164 | }
165 | }
166 |
167 | private void btnCancel_Click(object sender, EventArgs e)
168 | {
169 | DialogResult = DialogResult.Cancel;
170 | }
171 |
172 | private void kbdPrimaryShortcut_ValidateShortcut(object sender, KeyboardShortcutValidationEventArgs e)
173 | {
174 | e.IsValid = IsKeyboardShortcutValid(e.Keys);
175 | }
176 |
177 | private void kbdSecondaryShortcut_ValidateShortcut(object sender, KeyboardShortcutValidationEventArgs e)
178 | {
179 | e.IsValid = IsKeyboardShortcutValid(e.Keys);
180 | }
181 |
182 | private bool IsKeyboardShortcutValid(Keys keys)
183 | {
184 | return (keys & ~Keys.Modifiers) != Keys.None;
185 | }
186 | }
187 | }
188 |
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/UI/OptionsForm.ru.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 |
122 | 10, 189
123 |
124 |
125 | Сворачивать окно при потере фокуса
126 |
127 |
128 | 10, 210
129 |
130 |
131 | Завершать программу при закрытии окна
132 |
133 |
134 | 10, 231
135 |
136 |
137 | Запускать программу при старте Windows
138 |
139 |
140 | 101, 16
141 |
142 |
143 | Язык интерфейса:
144 |
145 |
146 | Отмена
147 |
148 |
149 | 0, 263
150 |
151 |
152 | 0, 262
153 |
154 |
155 | 10, 168
156 |
157 |
158 | Показывать значок в области уведомлений
159 |
160 |
161 | 1, 83
162 |
163 |
164 | 1, 54
165 |
166 |
167 | 255, 29
168 |
169 |
170 | Вторичная глобальная комбинация клавиш:
171 | (вставка символов из панели быстрого доступа)
172 |
173 |
174 | 1, 29
175 |
176 |
177 | 232, 29
178 |
179 |
180 | Первичная глобальная комбинация клавиш:
181 | (вызов программы)
182 |
183 |
184 | 307, 112
185 |
186 |
187 | 327, 262
188 |
189 |
190 | 327, 307
191 |
192 |
193 |
194 | AAABAAEAEBAAAAAAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAA
195 | AAD///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
196 | /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
197 | /wH///8B////AerFpOvnwJ//47ya/+C3lf/dso//2a6K/9aphf/TpX//0KB7/82cdv/KmXL/yJZu/8aT
198 | a//EkGn/xJBo/8SQaOvuy6v/6NXI/+jUxf/n0sP/5dDB/+XOvv/jzLz/48q5/+LJt//hx7X/4MWz/9/E
199 | sf/fxLD/3sKv/97Crv/EkGj/8tCx/+rYzP/8/Pz/2rqk//z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz8//z8
200 | /P/8/Pz/zKGC//z8/P/fw7D/xZJq//XUtv/s3ND/3sOv/92/q//bvaf/2bqj/9i3n//WtJz/1bGX/9Ou
201 | lP/Rq4//0KiM/8+miP/No4X/4MWz/8eVbv/42Lv/7d7U//z8/P/8/Pz/3sKu//z8/P/bvKb//Pz8/9i2
202 | nv/8/Pz/1bCX//z8/P/8/Pz//Pz8/+HItv/KmXL/+ty//+7g1v/jy7r/4sm4/+DGtP/fxLH/3sKt/9y/
203 | qv/avKb/2bmi/9e2nv/Ws5r/6dbK//z8/P/jy7r/zp13//zewf/v4tj//Pz8/+TMvP/8/Pz/4cm3//z8
204 | /P/fw7D//Pz8/9y+qf/8/Pz/2bih//z8/P/38/D/5c6+/9Giff/83sH/7+LY/+/i2P/v4tj/7uHX/+7g
205 | 1v/u39T/7d3S/+zc0f/r2s7/6tjM/+rXyv/o1cf/59PF/+fRwv/VqIP//N7B4/zewf+7ubb/s7Gu//rb
206 | vv/42Lv/9tW3//PSs//wzq7/7cmq/+rFpP/nwJ//47ya/+C3lf/dso//2a6K4////wH///8BxMTE/by8
207 | vLWzs7MR////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AdDQ
208 | 0PnJycn5wsLCZ////wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
209 | /wHZ2dln1NTU98/Pz+/IyMjlwMDA2be3t8Ourq6TpKSkfZubm2+RkZFJh4eHBf///wH///8B////Af//
210 | /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
211 | /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
212 | /wH///8BAAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA
213 | //8AAP//AAD//w==
214 |
215 |
216 |
217 | Настройки
218 |
219 |
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/UI/OptionsForm.uk.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 |
122 | 10, 189
123 |
124 |
125 | Згортати вікно при втраті фокусу
126 |
127 |
128 | 10, 210
129 |
130 |
131 | Завершувати програму при закритті вікна
132 |
133 |
134 | 10, 231
135 |
136 |
137 | Запускати програму при старті Windows
138 |
139 |
140 | 97, 16
141 |
142 |
143 | Мова інтерфейсу:
144 |
145 |
146 | 0, 263
147 |
148 |
149 | Скасувати
150 |
151 |
152 | 0, 262
153 |
154 |
155 | 327, 262
156 |
157 |
158 | 10, 168
159 |
160 |
161 | Показувати значок в області оповіщень
162 |
163 |
164 | 307, 112
165 |
166 |
167 | 1, 83
168 |
169 |
170 | 1, 54
171 |
172 |
173 | 243, 29
174 |
175 |
176 | Вторинна глобальна комбінація клавіш:
177 | (вставка символів з панелі швидкого доступу)
178 |
179 |
180 | 1, 29
181 |
182 |
183 | 208, 29
184 |
185 |
186 | Первинна глобальна комбінація клавіш:
187 | (виклик програми)
188 |
189 |
190 | 327, 307
191 |
192 |
193 |
194 | AAABAAEAEBAAAAAAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAA
195 | AAD///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
196 | /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
197 | /wH///8B////AerFpOvnwJ//47ya/+C3lf/dso//2a6K/9aphf/TpX//0KB7/82cdv/KmXL/yJZu/8aT
198 | a//EkGn/xJBo/8SQaOvuy6v/6NXI/+jUxf/n0sP/5dDB/+XOvv/jzLz/48q5/+LJt//hx7X/4MWz/9/E
199 | sf/fxLD/3sKv/97Crv/EkGj/8tCx/+rYzP/8/Pz/2rqk//z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz8//z8
200 | /P/8/Pz/zKGC//z8/P/fw7D/xZJq//XUtv/s3ND/3sOv/92/q//bvaf/2bqj/9i3n//WtJz/1bGX/9Ou
201 | lP/Rq4//0KiM/8+miP/No4X/4MWz/8eVbv/42Lv/7d7U//z8/P/8/Pz/3sKu//z8/P/bvKb//Pz8/9i2
202 | nv/8/Pz/1bCX//z8/P/8/Pz//Pz8/+HItv/KmXL/+ty//+7g1v/jy7r/4sm4/+DGtP/fxLH/3sKt/9y/
203 | qv/avKb/2bmi/9e2nv/Ws5r/6dbK//z8/P/jy7r/zp13//zewf/v4tj//Pz8/+TMvP/8/Pz/4cm3//z8
204 | /P/fw7D//Pz8/9y+qf/8/Pz/2bih//z8/P/38/D/5c6+/9Giff/83sH/7+LY/+/i2P/v4tj/7uHX/+7g
205 | 1v/u39T/7d3S/+zc0f/r2s7/6tjM/+rXyv/o1cf/59PF/+fRwv/VqIP//N7B4/zewf+7ubb/s7Gu//rb
206 | vv/42Lv/9tW3//PSs//wzq7/7cmq/+rFpP/nwJ//47ya/+C3lf/dso//2a6K4////wH///8BxMTE/by8
207 | vLWzs7MR////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AdDQ
208 | 0PnJycn5wsLCZ////wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
209 | /wHZ2dln1NTU98/Pz+/IyMjlwMDA2be3t8Ourq6TpKSkfZubm2+RkZFJh4eHBf///wH///8B////Af//
210 | /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
211 | /wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af//
212 | /wH///8BAAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA
213 | //8AAP//AAD//w==
214 |
215 |
216 |
217 | Параметри
218 |
219 |
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/UI/UIHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 |
4 | namespace YuriyGuts.UnicodeKeyboard.UI
5 | {
6 | ///
7 | /// Provides helper functions for common UI tasks.
8 | ///
9 | public static class UIHelper
10 | {
11 | private static bool isInitialized;
12 | private static Font unicodeCharacterFont;
13 |
14 | private const string universalFontFamily = "Arial Unicode MS";
15 | private const string minimumFontFamily = "Arial";
16 | private const float emSize = 15.75F;
17 |
18 | ///
19 | /// Font used for displaying Unicode characters.
20 | ///
21 | public static Font UnicodeCharacterFont
22 | {
23 | get { EnsureInitialized(); return unicodeCharacterFont; }
24 | }
25 |
26 | private static void EnsureInitialized()
27 | {
28 | if (isInitialized)
29 | {
30 | return;
31 | }
32 | string fontFamilyToUse = IsFontInstalled(universalFontFamily) ? universalFontFamily : minimumFontFamily;
33 | unicodeCharacterFont = new Font(fontFamilyToUse, emSize);
34 | isInitialized = true;
35 | }
36 |
37 | private static bool IsFontInstalled(string fontName)
38 | {
39 | using (Font testFont = new Font(fontName, 8))
40 | {
41 | return 0 == string.Compare(fontName, testFont.Name, StringComparison.InvariantCultureIgnoreCase);
42 | }
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/UI/WindowFinder.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace YuriyGuts.UnicodeKeyboard.UI
2 | {
3 | partial class WindowFinder
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | DisposeCustom();
19 | components.Dispose();
20 | }
21 | base.Dispose(disposing);
22 | }
23 |
24 | #region Component Designer generated code
25 |
26 | ///
27 | /// Required method for Designer support - do not modify
28 | /// the contents of this method with the code editor.
29 | ///
30 | private void InitializeComponent()
31 | {
32 | this.SuspendLayout();
33 | //
34 | // WindowFinder
35 | //
36 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
37 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
38 | this.BackColor = System.Drawing.SystemColors.Control;
39 | this.BackgroundImage = global::YuriyGuts.UnicodeKeyboard.Properties.Resources.Crosshair;
40 | this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center;
41 | this.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
42 | this.DoubleBuffered = true;
43 | this.Name = "WindowFinder";
44 | this.Size = new System.Drawing.Size(22, 22);
45 | this.ResumeLayout(false);
46 |
47 | }
48 |
49 | #endregion
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/UI/WindowFinder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.Drawing;
4 | using System.IO;
5 | using System.Windows.Forms;
6 | using YuriyGuts.UnicodeKeyboard.Properties;
7 | using YuriyGuts.UnicodeKeyboard.WindowsIntegration;
8 |
9 | namespace YuriyGuts.UnicodeKeyboard.UI
10 | {
11 | ///
12 | /// Crosshair control for selecting windows on the desktop.
13 | /// Portions Copyright (c) 2005 Corneliu I. Tusnea [http://hawkeye.codeplex.com/].
14 | ///
15 | [DefaultEvent("ActiveWindowChanged")]
16 | internal partial class WindowFinder : UserControl
17 | {
18 | public event EventHandler ActiveWindowChanged;
19 | public event EventHandler ActiveWindowSelected;
20 |
21 | private bool isSearching;
22 | private readonly CapturedWindow window;
23 | private readonly Cursor crosshairCursor;
24 |
25 | public WindowFinder()
26 | {
27 | window = new CapturedWindow();
28 | crosshairCursor = new Cursor(new MemoryStream(Resources.CrosshairCursor));
29 |
30 | InitializeComponent();
31 |
32 | MouseDown += WindowFinder_MouseDown;
33 | MouseUp += WindowFinder_MouseUp;
34 | }
35 |
36 | public CapturedWindow Window
37 | {
38 | get { return window; }
39 | }
40 |
41 | public object SelectedObject
42 | {
43 | get { return window.ActiveObject; }
44 | }
45 |
46 | [Browsable(false)]
47 | [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
48 | public IntPtr SelectedHandle
49 | {
50 | get { return window.Handle; }
51 | set
52 | {
53 | window.SetWindowHandle(value);
54 | InvokeActiveWindowChanged();
55 | }
56 | }
57 |
58 | public void StartSearch()
59 | {
60 | Cursor.Current = crosshairCursor;
61 | isSearching = true;
62 | Capture = true;
63 | MouseMove += WindowFinder_MouseMove;
64 | }
65 |
66 | public void EndSearch()
67 | {
68 | MouseMove -= WindowFinder_MouseMove;
69 | Capture = false;
70 | isSearching = false;
71 | Cursor.Current = Cursors.Default;
72 |
73 | Window.Refresh();
74 | if (ActiveWindowSelected != null)
75 | {
76 | ActiveWindowSelected(this, EventArgs.Empty);
77 | }
78 | }
79 |
80 | private void InvokeActiveWindowChanged()
81 | {
82 | if (ActiveWindowChanged != null)
83 | {
84 | ActiveWindowChanged(this, EventArgs.Empty);
85 | }
86 | }
87 |
88 | private void WindowFinder_MouseDown(object sender, MouseEventArgs e)
89 | {
90 | if (!isSearching)
91 | {
92 | StartSearch();
93 | }
94 | }
95 |
96 | private void WindowFinder_MouseMove(object sender, MouseEventArgs e)
97 | {
98 | if (!isSearching)
99 | {
100 | EndSearch();
101 | }
102 |
103 | // Grab the window from the screen location of the mouse.
104 | Point newPoint = PointToScreen(new Point(e.X, e.Y));
105 | NativeStructs.POINT windowPoint = NativeStructs.POINT.FromPoint(newPoint);
106 | IntPtr foundWindow = NativeMethods.WindowFromPoint(windowPoint);
107 |
108 | // Do we have a valid window handle?
109 | if (foundWindow != IntPtr.Zero)
110 | {
111 | // Give it another try, it might be a child window (disabled, hidden, etc.).
112 | // Offset the point to be a client point of the active window.
113 | if (NativeMethods.ScreenToClient(foundWindow, ref windowPoint))
114 | {
115 | // Check if there is some hidden/disabled child window at this point.
116 | IntPtr childWindow = NativeMethods.ChildWindowFromPoint(foundWindow, windowPoint);
117 | if (childWindow != IntPtr.Zero)
118 | {
119 | // Great, we have the inner child.
120 | foundWindow = childWindow;
121 | }
122 | }
123 | }
124 |
125 | // Is this the same window as the last detected one?
126 | if (window.Handle != foundWindow)
127 | {
128 | if (window.SetWindowHandle(foundWindow))
129 | {
130 | InvokeActiveWindowChanged();
131 | }
132 | }
133 | }
134 |
135 | private void WindowFinder_MouseUp(object sender, MouseEventArgs e)
136 | {
137 | EndSearch();
138 | }
139 |
140 | private void DisposeCustom()
141 | {
142 | window.Dispose();
143 | crosshairCursor.Dispose();
144 | }
145 | }
146 | }
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/UI/WindowFinder.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/UnicodeKeyboard.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 9.0.30729
7 | 2.0
8 | {231F802E-F52E-4150-BE44-AC26D6D43873}
9 | WinExe
10 | Properties
11 | YuriyGuts.UnicodeKeyboard
12 | UnicodeKeyboard
13 | v2.0
14 | 512
15 | Resources\KeyboardSmall.ico
16 |
17 |
18 | 3.5
19 |
20 |
21 |
22 | true
23 | full
24 | false
25 | bin\Debug\
26 | DEBUG;TRACE
27 | prompt
28 | 4
29 | AllRules.ruleset
30 |
31 |
32 | pdbonly
33 | true
34 | bin\Release\
35 | TRACE
36 | prompt
37 | 4
38 | AllRules.ruleset
39 |
40 |
41 | true
42 | bin\x86\Debug\
43 | DEBUG;TRACE
44 | full
45 | x86
46 | true
47 | GlobalSuppressions.cs
48 | prompt
49 | AllRules.ruleset
50 |
51 |
52 |
53 |
54 | bin\x86\Release\
55 | TRACE
56 | true
57 | pdbonly
58 | x86
59 | true
60 | GlobalSuppressions.cs
61 | prompt
62 | AllRules.ruleset
63 |
64 |
65 |
66 | False
67 | References\Gma.UserActivityMonitor.dll
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 | Form
81 |
82 |
83 | AboutForm.cs
84 |
85 |
86 | Form
87 |
88 |
89 | AddToFavoritesForm.cs
90 |
91 |
92 | Form
93 |
94 |
95 | CharacterLookupForm.cs
96 |
97 |
98 |
99 |
100 | Component
101 |
102 |
103 | Form
104 |
105 |
106 | MainForm.cs
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 | AboutForm.cs
116 |
117 |
118 | AboutForm.cs
119 |
120 |
121 | AboutForm.cs
122 |
123 |
124 | AddToFavoritesForm.cs
125 |
126 |
127 | AddToFavoritesForm.cs
128 |
129 |
130 | AddToFavoritesForm.cs
131 |
132 |
133 | CharacterLookupForm.cs
134 |
135 |
136 | CharacterLookupForm.cs
137 |
138 |
139 | CharacterLookupForm.cs
140 |
141 |
142 | MainForm.cs
143 | Designer
144 |
145 |
146 | ResXFileCodeGenerator
147 | Resources.Designer.cs
148 | Designer
149 |
150 |
151 | True
152 | Resources.resx
153 | True
154 |
155 |
156 | MainForm.cs
157 |
158 |
159 | MainForm.cs
160 |
161 |
162 | OptionsForm.cs
163 |
164 |
165 | OptionsForm.cs
166 |
167 |
168 | OptionsForm.cs
169 |
170 |
171 | WindowFinder.cs
172 |
173 |
174 | SettingsSingleFileGenerator
175 | Settings.Designer.cs
176 |
177 |
178 | True
179 | Settings.settings
180 | True
181 |
182 |
183 | Form
184 |
185 |
186 | OptionsForm.cs
187 |
188 |
189 |
190 |
191 | UserControl
192 |
193 |
194 | WindowFinder.cs
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
240 |
241 | :: Is it a Release build?
242 | if "$(ConfigurationName)"=="Release" (
243 | :: If the output directory does not exists, creating it
244 | if not exist "$(SolutionDir)Release\$(PlatformName)" md "$(SolutionDir)Release\$(PlatformName)"
245 | if not exist "$(SolutionDir)Release\$(PlatformName)\Temp" md "$(SolutionDir)Release\$(PlatformName)\Temp"
246 | :: Merging the libraries with the main executable
247 | "$(ProjectDir)Tools\ILMerge.exe" /target:winexe /copyattrs /allowMultiple /out:"$(SolutionDir)Release\$(PlatformName)\Temp\UnicodeKeyboard.exe" "$(TargetDir)UnicodeKeyboard.exe" "$(TargetDir)Gma.UserActivityMonitor.dll" "$(TargetDir)ru\UnicodeKeyboard.resources.dll"
248 | "$(ProjectDir)Tools\ILMerge.exe" /target:winexe /copyattrs /allowMultiple /out:"$(SolutionDir)Release\$(PlatformName)\UnicodeKeyboard.exe" "$(SolutionDir)Release\$(PlatformName)\Temp\UnicodeKeyboard.exe" "$(TargetDir)uk\UnicodeKeyboard.resources.dll"
249 | del /Q "$(SolutionDir)Release\$(PlatformName)\Temp\UnicodeKeyboard.*"
250 | rd "$(SolutionDir)Release\$(PlatformName)\Temp"
251 | )
252 |
253 |
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/WindowsIntegration/NativeMethods.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 | using System.Text;
4 |
5 | namespace YuriyGuts.UnicodeKeyboard.WindowsIntegration
6 | {
7 | ///
8 | /// Provides managed wrappers for some of the WinAPI functions.
9 | ///
10 | internal static class NativeMethods
11 | {
12 | public const int INPUT_MOUSE = 0;
13 | public const int INPUT_KEYBOARD = 1;
14 | public const int INPUT_HARDWARE = 2;
15 |
16 | public const UInt32 KEYEVENTF_EXTENDEDKEY = 0x0001;
17 | public const UInt32 KEYEVENTF_KEYUP = 0x0002;
18 | public const UInt32 KEYEVENTF_UNICODE = 0x0004;
19 | public const UInt32 KEYEVENTF_SCANCODE = 0x0008;
20 |
21 | public const UInt32 WM_KEYDOWN = 0x0100;
22 | public const UInt32 WM_KEYUP = 0x0101;
23 | public const UInt32 WM_CHAR = 0x0102;
24 |
25 | [DllImport("user32.dll")]
26 | public static extern IntPtr GetForegroundWindow();
27 |
28 | [DllImport("user32.dll")]
29 | [return: MarshalAs(UnmanagedType.Bool)]
30 | public static extern bool SetForegroundWindow(IntPtr hWnd);
31 |
32 | [DllImport("user32.dll")]
33 | private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
34 |
35 | [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
36 | public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpResult, int nMaxCount);
37 |
38 | [DllImport("user32.dll", SetLastError = true)]
39 | public static extern IntPtr GetParent(IntPtr hWnd);
40 |
41 | [DllImport("user32.dll")]
42 | public static extern IntPtr GetWindowDC(IntPtr hWnd);
43 |
44 | [DllImport("user32.dll")]
45 | public static extern IntPtr GetWindowRect(IntPtr hwnd, ref NativeStructs.RECT rc);
46 |
47 | [DllImport("user32.dll")]
48 | public static extern bool InvalidateRect(IntPtr hWnd, IntPtr lpRect, bool bErase);
49 |
50 | [DllImport("user32.dll")]
51 | public static extern bool ScreenToClient(IntPtr hWnd, ref NativeStructs.POINT lpPoint);
52 |
53 | [DllImport("user32.dll")]
54 | public static extern IntPtr WindowFromPoint(NativeStructs.POINT Point);
55 |
56 | [DllImport("user32.dll")]
57 | public static extern IntPtr ChildWindowFromPoint(IntPtr hWndParent, NativeStructs.POINT Point);
58 |
59 | [DllImport("user32.dll")]
60 | public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
61 |
62 | [DllImport("user32.dll")]
63 | public static extern bool RedrawWindow(IntPtr hWnd, IntPtr lpRect, IntPtr hrgnUpdate, uint flags);
64 |
65 | [DllImport("user32.dll")]
66 | public static extern bool UpdateWindow(IntPtr hWnd);
67 |
68 | [DllImport("user32.dll", SetLastError = true)]
69 | public static extern UInt32 SendInput(UInt32 nInputs, ref NativeStructs.INPUT pInputs, int cbSize);
70 |
71 |
72 | public static string GetParentWindowTitle(IntPtr hWnd)
73 | {
74 | IntPtr parentWindow = hWnd;
75 | while (true)
76 | {
77 | IntPtr newParent = GetParent(parentWindow);
78 | if (newParent == IntPtr.Zero)
79 | {
80 | break;
81 | }
82 | parentWindow = newParent;
83 | }
84 |
85 | StringBuilder buffer = new StringBuilder(256);
86 | GetWindowText(parentWindow, buffer, buffer.Capacity);
87 | return buffer.ToString();
88 | }
89 |
90 | public static string GetClassName(IntPtr hWnd)
91 | {
92 | StringBuilder buffer = new StringBuilder(256);
93 | GetClassName(hWnd, buffer, buffer.Capacity);
94 | return buffer.ToString();
95 | }
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/WindowsIntegration/NativeStructs.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using System.Runtime.InteropServices;
4 |
5 | namespace YuriyGuts.UnicodeKeyboard.WindowsIntegration
6 | {
7 | internal static class NativeStructs
8 | {
9 | public class RDW
10 | {
11 | public const uint RDW_INVALIDATE = 0x0001;
12 | public const uint RDW_INTERNALPAINT = 0x0002;
13 | public const uint RDW_ERASE = 0x0004;
14 |
15 | public const uint RDW_VALIDATE = 0x0008;
16 | public const uint RDW_NOINTERNALPAINT = 0x0010;
17 | public const uint RDW_NOERASE = 0x0020;
18 |
19 | public const uint RDW_NOCHILDREN = 0x0040;
20 | public const uint RDW_ALLCHILDREN = 0x0080;
21 |
22 | public const uint RDW_UPDATENOW = 0x0100;
23 | public const uint RDW_ERASENOW = 0x0200;
24 |
25 | public const uint RDW_FRAME = 0x0400;
26 | public const uint RDW_NOFRAME = 0x0800;
27 | }
28 |
29 | public struct KEYBDINPUT
30 | {
31 | public ushort wVk;
32 | public ushort wScan;
33 | public UInt32 dwFlags;
34 | public UInt32 time;
35 | public IntPtr dwExtraInfo;
36 | }
37 |
38 | [StructLayout(LayoutKind.Explicit, Size = 28)]
39 | public struct INPUT
40 | {
41 | [FieldOffset(0)]
42 | public int type;
43 |
44 | [FieldOffset(4)]
45 | public KEYBDINPUT input;
46 | }
47 |
48 | [StructLayout(LayoutKind.Sequential)]
49 | public struct POINT
50 | {
51 | public readonly int x;
52 | public readonly int y;
53 |
54 | public POINT(int x, int y)
55 | {
56 | this.x = x;
57 | this.y = y;
58 | }
59 |
60 | public POINT ToPoint()
61 | {
62 | return new POINT(x, y);
63 | }
64 |
65 | public static POINT FromPoint(Point pt)
66 | {
67 | return new POINT(pt.X, pt.Y);
68 | }
69 |
70 | public override bool Equals(object other)
71 | {
72 | if (other is POINT)
73 | {
74 | POINT that = (POINT)other;
75 | return that.x == x && that.y == y;
76 | }
77 | return false;
78 | }
79 |
80 | public override int GetHashCode()
81 | {
82 | return (x ^ y);
83 | }
84 |
85 | public override string ToString()
86 | {
87 | return string.Format("{{X={0}, Y={1}}}", x, y);
88 | }
89 | }
90 |
91 | [Serializable, StructLayout(LayoutKind.Sequential)]
92 | public struct RECT
93 | {
94 | public int Left;
95 | public int Top;
96 | public int Right;
97 | public int Bottom;
98 | public RECT(int Left, int Top, int Right, int Bottom)
99 | {
100 | this.Left = Left;
101 | this.Top = Top;
102 | this.Right = Right;
103 | this.Bottom = Bottom;
104 | }
105 |
106 | public int Height
107 | {
108 | get { return (Bottom - Top); }
109 | }
110 |
111 | public int Width
112 | {
113 | get { return (Right - Left); }
114 | }
115 |
116 | public Size Size
117 | {
118 | get { return new Size(Width, Height); }
119 | }
120 |
121 | public Point Location
122 | {
123 | get { return new Point(Left, Top); }
124 | }
125 |
126 | public Rectangle ToRectangle()
127 | {
128 | return Rectangle.FromLTRB(Left, Top, Right, Bottom);
129 | }
130 |
131 | public static RECT FromRectangle(Rectangle rectangle)
132 | {
133 | return new RECT(rectangle.Left, rectangle.Top, rectangle.Right, rectangle.Bottom);
134 | }
135 | }
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/src/UnicodeKeyboard/WindowsIntegration/UnicodeCharSender.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.Runtime.InteropServices;
4 |
5 | namespace YuriyGuts.UnicodeKeyboard.WindowsIntegration
6 | {
7 | ///
8 | /// Responsible for sending Unicode input to native windows.
9 | ///
10 | public static class UnicodeCharSender
11 | {
12 | ///
13 | /// Activates a window and sends a Unicode character with the specified code to it.
14 | ///
15 | /// Target window handle.
16 | /// Unicode character code.
17 | public static void Send(IntPtr hTargetWindow, ushort charCode)
18 | {
19 | NativeMethods.SetForegroundWindow(hTargetWindow);
20 | NativeStructs.INPUT input = new NativeStructs.INPUT
21 | {
22 | type = NativeMethods.INPUT_KEYBOARD,
23 | input = new NativeStructs.KEYBDINPUT
24 | {
25 | wVk = 0,
26 | wScan = charCode,
27 | dwFlags = NativeMethods.KEYEVENTF_UNICODE,
28 | time = 0,
29 | dwExtraInfo = IntPtr.Zero
30 | }
31 | };
32 |
33 | Trace.WriteLine(string.Format("Sending {0:X4} to {1:X8}", charCode, hTargetWindow.ToInt32()));
34 | NativeMethods.SendInput(1, ref input, Marshal.SizeOf(typeof(NativeStructs.INPUT)));
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------