Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / ndp / fx / src / WinForms / Managed / System / WinForms / InputLanguage.cs / 1 / InputLanguage.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Windows.Forms { using System.Text; using System.Runtime.InteropServices; using System.Runtime.Remoting; using System.Security.Permissions; using System.Diagnostics; using System; using Microsoft.Win32; using System.Globalization; using System.ComponentModel; using System.Drawing; ////// /// public sealed class InputLanguage { ////// Provides methods and fields to manage the input language. /// ////// /// The HKL handle. /// ///private readonly IntPtr handle; /// /// /// ///internal InputLanguage(IntPtr handle) { this.handle = handle; } /// /// /// public CultureInfo Culture { get { return new CultureInfo((int)handle & 0xFFFF); } } ////// Returns /// the culture of the current input language. /// ////// /// public static InputLanguage CurrentInputLanguage { get { Application.OleRequired(); // note we can obtain the KeyboardLayout for a given thread... return new InputLanguage(SafeNativeMethods.GetKeyboardLayout(0)); } set { IntSecurity.AffectThreadBehavior.Demand(); // (NDPWhidbey 8362) OleInitialize needs to be called before we can call ActivateKeyboardLayout. Application.OleRequired(); if (value == null) { value = InputLanguage.DefaultInputLanguage; } IntPtr handleOld = SafeNativeMethods.ActivateKeyboardLayout(new HandleRef(value, value.handle), 0); if (handleOld == IntPtr.Zero) { throw new ArgumentException(SR.GetString(SR.ErrorBadInputLanguage), "value"); } } } ////// Gets or sets the input language for the current thread. /// ////// /// public static InputLanguage DefaultInputLanguage { get { IntPtr[] data = new IntPtr[1]; UnsafeNativeMethods.SystemParametersInfo(NativeMethods.SPI_GETDEFAULTINPUTLANG, 0, data, 0); return new InputLanguage(data[0]); } } ////// Returns the default input language for the system. /// ////// /// public IntPtr Handle { get { return handle; } } ////// Returns the handle for the input language. /// ////// /// public static InputLanguageCollection InstalledInputLanguages { get { int size = SafeNativeMethods.GetKeyboardLayoutList(0, null); IntPtr[] handles = new IntPtr[size]; SafeNativeMethods.GetKeyboardLayoutList(size, handles); InputLanguage[] ils = new InputLanguage[size]; for (int i = 0; i < size; i++) ils[i] = new InputLanguage(handles[i]); return new InputLanguageCollection(ils); } } ////// Returns a list of all installed input languages. /// ////// /// public string LayoutName { get { // There is no good way to do this in Win32... GetKeyboardLayoutName does what we want, // but only for the current input language; setting and resetting the current input language // would generate spurious InputLanguageChanged events. /* HKL is a 32 bit value. HIWORD is a Device Handle. LOWORD is Language ID. HKL +------------------------+-------------------------+ | Device Handle | Language ID | +------------------------+-------------------------+ 31 16 15 0 bit Language ID +---------------------------+-----------------------+ | Sublanguage ID | Primary Language ID | +---------------------------+-----------------------+ 15 10 9 0 bit WORD LangId = MAKELANGID(primary, sublang) BYTE primary = PRIMARYLANGID(LangId) BYTE sublang = PRIMARYLANGID(LangID) How Preload is interpreted: example US-Dvorak Look in HKEY_CURRENT_USER\Keyboard Layout\Preload Name="4" (may vary) Value="d0000409" -> Language ID = 0409 Look in HKEY_CURRENT_USER\Keyboard Layout\Substitutes Name="d0000409" Value="00010409" Look in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layouts\00010409 "Layout File": name of keyboard layout DLL (KBDDV.DLL) "Layout Id": ID of this layout (0002) Win32k will change the top nibble of layout ID to F, which makes F002. Combined with Language ID, the final HKL is F0020409. */ string layoutName = null; IntPtr currentHandle = handle; int language = (int)currentHandle & 0xffff; int device = ((int)currentHandle >> 16) & 0x0fff; // SECREVIEW : We have to get the input information from the registry. These two // : keys only contain keyboard information. This is safe to do. // new RegistryPermission(PermissionState.Unrestricted).Assert(); try { if (device == language || device == 0) { // Default keyboard for language string keyName = Convert.ToString(language, 16); keyName = PadWithZeroes(keyName, 8); RegistryKey key = Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\" + keyName); // Attempt to extract the localized keyboard layout name // using the SHLoadIndirectString API... layoutName = GetLocalizedKeyboardLayoutName(key.GetValue("Layout Display Name") as string); // Default back to our legacy codepath and obtain the name // directly through the registry value if (layoutName == null) { layoutName = (string) key.GetValue("Layout Text"); } key.Close(); } else { // Look for a substitution // RegistryKey substitutions = Registry.CurrentUser.OpenSubKey("Keyboard Layout\\Substitutes"); string[] encodings = null; if (substitutions != null) { encodings = substitutions.GetValueNames(); foreach (string encoding in encodings) { int encodingValue = Convert.ToInt32(encoding, 16); if (encodingValue == (int)currentHandle || (encodingValue & 0x0FFFFFFF) == ((int)currentHandle & 0x0FFFFFFF) || (encodingValue & 0xFFFF) == language) { currentHandle = (IntPtr)Convert.ToInt32((string)substitutions.GetValue(encoding), 16); language = (int)currentHandle & 0xFFFF; device = ((int)currentHandle >> 16) & 0xFFF; break; } } substitutions.Close(); } RegistryKey layouts = Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts"); if (layouts != null) { encodings = layouts.GetSubKeyNames(); // Check to see if the encoding directly matches the handle -- some do. // foreach (string encoding in encodings) { Debug.Assert(encoding.Length == 8, "unexpected key in registry: hklm\\SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\" + encoding); if (currentHandle == (IntPtr)Convert.ToInt32(encoding, 16)) { RegistryKey key = layouts.OpenSubKey(encoding); // Attempt to extract the localized keyboard layout name // using the SHLoadIndirectString API... layoutName = GetLocalizedKeyboardLayoutName(key.GetValue("Layout Display Name") as string); // Default back to our legacy codepath and obtain the name // directly through the registry value if (layoutName == null) { layoutName = (string) key.GetValue("Layout Text"); } key.Close(); break; } } } if (layoutName == null) { // No luck there. Match the language first, then try to find a layout ID // foreach (string encoding in encodings) { Debug.Assert(encoding.Length == 8, "unexpected key in registry: hklm\\SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\" + encoding); if (language == (0xffff & Convert.ToInt32(encoding.Substring(4,4), 16))) { RegistryKey key = layouts.OpenSubKey(encoding); string codeValue = (string) key.GetValue("Layout Id"); if (codeValue != null) { int value = Convert.ToInt32(codeValue, 16); if (value == device) { // Attempt to extract the localized keyboard layout name // using the SHLoadIndirectString API... layoutName = GetLocalizedKeyboardLayoutName(key.GetValue("Layout Display Name") as string); // Default back to our legacy codepath and obtain the name // directly through the registry value if (layoutName == null) { layoutName = (string) key.GetValue("Layout Text"); } } } key.Close(); if (layoutName != null) { break; } } } } layouts.Close(); } } finally { System.Security.CodeAccessPermission.RevertAssert(); } if (layoutName == null) { layoutName = SR.GetString(SR.UnknownInputLanguageLayout); } return layoutName; } } ////// Returns /// the name of the current keyboard layout as it appears in the Windows Regional Settings on the computer. /// ////// Attempts to extract the localized keyboard layout name using the /// SHLoadIndirectString API (only on OSVersions >= 5). Returning /// null from this method will force us to use the legacy codepath /// (pulling the text directly from the registry). /// private static string GetLocalizedKeyboardLayoutName(string layoutDisplayName) { if (layoutDisplayName != null && Environment.OSVersion.Version.Major >= 5) { StringBuilder sb = new StringBuilder(512); uint res = UnsafeNativeMethods.SHLoadIndirectString(layoutDisplayName, sb, (uint)sb.Capacity, IntPtr.Zero); if (res == NativeMethods.S_OK) { return sb.ToString(); } } return null; } ////// /// Creates an InputLanguageChangedEventArgs given a windows message. /// ///internal static InputLanguageChangedEventArgs CreateInputLanguageChangedEventArgs(Message m) { return new InputLanguageChangedEventArgs(new InputLanguage(m.LParam), unchecked((byte)(long)m.WParam)); } /// /// /// Creates an InputLanguageChangingEventArgs given a windows message. /// ///internal static InputLanguageChangingEventArgs CreateInputLanguageChangingEventArgs(Message m) { InputLanguage inputLanguage = new InputLanguage(m.LParam); // NOTE: by default we should allow any locale switch // bool localeSupportedBySystem = !(m.WParam == IntPtr.Zero); return new InputLanguageChangingEventArgs(inputLanguage, localeSupportedBySystem); } /// /// /// public override bool Equals(object value) { if (value is InputLanguage) { return(this.handle == ((InputLanguage)value).handle); } return false; } ///Specifies whether two input languages are equal. ////// /// public static InputLanguage FromCulture(CultureInfo culture) { // KeyboardLayoutId is the LCID for built-in cultures, but it // is the CU-preferred keyboard language for custom cultures. int lcid = culture.KeyboardLayoutId; foreach(InputLanguage lang in InstalledInputLanguages) { if (((int)lang.handle & 0xFFFF) == lcid) { return lang; } } return null; } ///Returns the input language associated with the specified /// culture. ////// /// public override int GetHashCode() { return (int)handle; } private static string PadWithZeroes(string input, int length) { return "0000000000000000".Substring(0, length - input.Length) + input; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ //Hash code for this input language. ///// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Windows.Forms { using System.Text; using System.Runtime.InteropServices; using System.Runtime.Remoting; using System.Security.Permissions; using System.Diagnostics; using System; using Microsoft.Win32; using System.Globalization; using System.ComponentModel; using System.Drawing; ////// /// public sealed class InputLanguage { ////// Provides methods and fields to manage the input language. /// ////// /// The HKL handle. /// ///private readonly IntPtr handle; /// /// /// ///internal InputLanguage(IntPtr handle) { this.handle = handle; } /// /// /// public CultureInfo Culture { get { return new CultureInfo((int)handle & 0xFFFF); } } ////// Returns /// the culture of the current input language. /// ////// /// public static InputLanguage CurrentInputLanguage { get { Application.OleRequired(); // note we can obtain the KeyboardLayout for a given thread... return new InputLanguage(SafeNativeMethods.GetKeyboardLayout(0)); } set { IntSecurity.AffectThreadBehavior.Demand(); // (NDPWhidbey 8362) OleInitialize needs to be called before we can call ActivateKeyboardLayout. Application.OleRequired(); if (value == null) { value = InputLanguage.DefaultInputLanguage; } IntPtr handleOld = SafeNativeMethods.ActivateKeyboardLayout(new HandleRef(value, value.handle), 0); if (handleOld == IntPtr.Zero) { throw new ArgumentException(SR.GetString(SR.ErrorBadInputLanguage), "value"); } } } ////// Gets or sets the input language for the current thread. /// ////// /// public static InputLanguage DefaultInputLanguage { get { IntPtr[] data = new IntPtr[1]; UnsafeNativeMethods.SystemParametersInfo(NativeMethods.SPI_GETDEFAULTINPUTLANG, 0, data, 0); return new InputLanguage(data[0]); } } ////// Returns the default input language for the system. /// ////// /// public IntPtr Handle { get { return handle; } } ////// Returns the handle for the input language. /// ////// /// public static InputLanguageCollection InstalledInputLanguages { get { int size = SafeNativeMethods.GetKeyboardLayoutList(0, null); IntPtr[] handles = new IntPtr[size]; SafeNativeMethods.GetKeyboardLayoutList(size, handles); InputLanguage[] ils = new InputLanguage[size]; for (int i = 0; i < size; i++) ils[i] = new InputLanguage(handles[i]); return new InputLanguageCollection(ils); } } ////// Returns a list of all installed input languages. /// ////// /// public string LayoutName { get { // There is no good way to do this in Win32... GetKeyboardLayoutName does what we want, // but only for the current input language; setting and resetting the current input language // would generate spurious InputLanguageChanged events. /* HKL is a 32 bit value. HIWORD is a Device Handle. LOWORD is Language ID. HKL +------------------------+-------------------------+ | Device Handle | Language ID | +------------------------+-------------------------+ 31 16 15 0 bit Language ID +---------------------------+-----------------------+ | Sublanguage ID | Primary Language ID | +---------------------------+-----------------------+ 15 10 9 0 bit WORD LangId = MAKELANGID(primary, sublang) BYTE primary = PRIMARYLANGID(LangId) BYTE sublang = PRIMARYLANGID(LangID) How Preload is interpreted: example US-Dvorak Look in HKEY_CURRENT_USER\Keyboard Layout\Preload Name="4" (may vary) Value="d0000409" -> Language ID = 0409 Look in HKEY_CURRENT_USER\Keyboard Layout\Substitutes Name="d0000409" Value="00010409" Look in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layouts\00010409 "Layout File": name of keyboard layout DLL (KBDDV.DLL) "Layout Id": ID of this layout (0002) Win32k will change the top nibble of layout ID to F, which makes F002. Combined with Language ID, the final HKL is F0020409. */ string layoutName = null; IntPtr currentHandle = handle; int language = (int)currentHandle & 0xffff; int device = ((int)currentHandle >> 16) & 0x0fff; // SECREVIEW : We have to get the input information from the registry. These two // : keys only contain keyboard information. This is safe to do. // new RegistryPermission(PermissionState.Unrestricted).Assert(); try { if (device == language || device == 0) { // Default keyboard for language string keyName = Convert.ToString(language, 16); keyName = PadWithZeroes(keyName, 8); RegistryKey key = Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\" + keyName); // Attempt to extract the localized keyboard layout name // using the SHLoadIndirectString API... layoutName = GetLocalizedKeyboardLayoutName(key.GetValue("Layout Display Name") as string); // Default back to our legacy codepath and obtain the name // directly through the registry value if (layoutName == null) { layoutName = (string) key.GetValue("Layout Text"); } key.Close(); } else { // Look for a substitution // RegistryKey substitutions = Registry.CurrentUser.OpenSubKey("Keyboard Layout\\Substitutes"); string[] encodings = null; if (substitutions != null) { encodings = substitutions.GetValueNames(); foreach (string encoding in encodings) { int encodingValue = Convert.ToInt32(encoding, 16); if (encodingValue == (int)currentHandle || (encodingValue & 0x0FFFFFFF) == ((int)currentHandle & 0x0FFFFFFF) || (encodingValue & 0xFFFF) == language) { currentHandle = (IntPtr)Convert.ToInt32((string)substitutions.GetValue(encoding), 16); language = (int)currentHandle & 0xFFFF; device = ((int)currentHandle >> 16) & 0xFFF; break; } } substitutions.Close(); } RegistryKey layouts = Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts"); if (layouts != null) { encodings = layouts.GetSubKeyNames(); // Check to see if the encoding directly matches the handle -- some do. // foreach (string encoding in encodings) { Debug.Assert(encoding.Length == 8, "unexpected key in registry: hklm\\SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\" + encoding); if (currentHandle == (IntPtr)Convert.ToInt32(encoding, 16)) { RegistryKey key = layouts.OpenSubKey(encoding); // Attempt to extract the localized keyboard layout name // using the SHLoadIndirectString API... layoutName = GetLocalizedKeyboardLayoutName(key.GetValue("Layout Display Name") as string); // Default back to our legacy codepath and obtain the name // directly through the registry value if (layoutName == null) { layoutName = (string) key.GetValue("Layout Text"); } key.Close(); break; } } } if (layoutName == null) { // No luck there. Match the language first, then try to find a layout ID // foreach (string encoding in encodings) { Debug.Assert(encoding.Length == 8, "unexpected key in registry: hklm\\SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\" + encoding); if (language == (0xffff & Convert.ToInt32(encoding.Substring(4,4), 16))) { RegistryKey key = layouts.OpenSubKey(encoding); string codeValue = (string) key.GetValue("Layout Id"); if (codeValue != null) { int value = Convert.ToInt32(codeValue, 16); if (value == device) { // Attempt to extract the localized keyboard layout name // using the SHLoadIndirectString API... layoutName = GetLocalizedKeyboardLayoutName(key.GetValue("Layout Display Name") as string); // Default back to our legacy codepath and obtain the name // directly through the registry value if (layoutName == null) { layoutName = (string) key.GetValue("Layout Text"); } } } key.Close(); if (layoutName != null) { break; } } } } layouts.Close(); } } finally { System.Security.CodeAccessPermission.RevertAssert(); } if (layoutName == null) { layoutName = SR.GetString(SR.UnknownInputLanguageLayout); } return layoutName; } } ////// Returns /// the name of the current keyboard layout as it appears in the Windows Regional Settings on the computer. /// ////// Attempts to extract the localized keyboard layout name using the /// SHLoadIndirectString API (only on OSVersions >= 5). Returning /// null from this method will force us to use the legacy codepath /// (pulling the text directly from the registry). /// private static string GetLocalizedKeyboardLayoutName(string layoutDisplayName) { if (layoutDisplayName != null && Environment.OSVersion.Version.Major >= 5) { StringBuilder sb = new StringBuilder(512); uint res = UnsafeNativeMethods.SHLoadIndirectString(layoutDisplayName, sb, (uint)sb.Capacity, IntPtr.Zero); if (res == NativeMethods.S_OK) { return sb.ToString(); } } return null; } ////// /// Creates an InputLanguageChangedEventArgs given a windows message. /// ///internal static InputLanguageChangedEventArgs CreateInputLanguageChangedEventArgs(Message m) { return new InputLanguageChangedEventArgs(new InputLanguage(m.LParam), unchecked((byte)(long)m.WParam)); } /// /// /// Creates an InputLanguageChangingEventArgs given a windows message. /// ///internal static InputLanguageChangingEventArgs CreateInputLanguageChangingEventArgs(Message m) { InputLanguage inputLanguage = new InputLanguage(m.LParam); // NOTE: by default we should allow any locale switch // bool localeSupportedBySystem = !(m.WParam == IntPtr.Zero); return new InputLanguageChangingEventArgs(inputLanguage, localeSupportedBySystem); } /// /// /// public override bool Equals(object value) { if (value is InputLanguage) { return(this.handle == ((InputLanguage)value).handle); } return false; } ///Specifies whether two input languages are equal. ////// /// public static InputLanguage FromCulture(CultureInfo culture) { // KeyboardLayoutId is the LCID for built-in cultures, but it // is the CU-preferred keyboard language for custom cultures. int lcid = culture.KeyboardLayoutId; foreach(InputLanguage lang in InstalledInputLanguages) { if (((int)lang.handle & 0xFFFF) == lcid) { return lang; } } return null; } ///Returns the input language associated with the specified /// culture. ////// /// public override int GetHashCode() { return (int)handle; } private static string PadWithZeroes(string input, int length) { return "0000000000000000".Substring(0, length - input.Length) + input; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.Hash code for this input language. ///
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- CompatibleComparer.cs
- WindowsAltTab.cs
- WebPartVerbCollection.cs
- HwndProxyElementProvider.cs
- InheritedPropertyChangedEventArgs.cs
- ZipIOLocalFileBlock.cs
- Queue.cs
- BatchServiceHost.cs
- RowToParametersTransformer.cs
- MenuAdapter.cs
- CancellationHandlerDesigner.cs
- ConnectionManagementElement.cs
- SqlProviderServices.cs
- DropDownButton.cs
- PostBackOptions.cs
- EventHandlersDesigner.cs
- ArraySortHelper.cs
- Assert.cs
- GridViewActionList.cs
- SEHException.cs
- Array.cs
- ResourceExpressionBuilder.cs
- WebHttpBindingElement.cs
- StringAttributeCollection.cs
- TextEndOfParagraph.cs
- Html32TextWriter.cs
- Memoizer.cs
- CornerRadiusConverter.cs
- InfocardClientCredentials.cs
- ControlCodeDomSerializer.cs
- EditCommandColumn.cs
- TextAdaptor.cs
- EntitySqlQueryBuilder.cs
- CompositionAdorner.cs
- EntryPointNotFoundException.cs
- Calendar.cs
- CodeExpressionCollection.cs
- SystemResourceHost.cs
- AstNode.cs
- ZipIOExtraFieldZip64Element.cs
- QueryOptionExpression.cs
- ContentWrapperAttribute.cs
- DefaultBinder.cs
- PEFileEvidenceFactory.cs
- ConfigurationSectionCollection.cs
- GB18030Encoding.cs
- WebMessageBodyStyleHelper.cs
- ImportDesigner.xaml.cs
- Encoding.cs
- _HeaderInfo.cs
- DataSysAttribute.cs
- ValueProviderWrapper.cs
- SingleSelectRootGridEntry.cs
- CompiledRegexRunnerFactory.cs
- TextSpanModifier.cs
- SqlConnectionManager.cs
- ConfigXmlText.cs
- ApplicationHost.cs
- ServiceOperationViewControl.cs
- PairComparer.cs
- JapaneseLunisolarCalendar.cs
- ConnectionOrientedTransportManager.cs
- FunctionImportMapping.cs
- ValueUtilsSmi.cs
- WebPartEditorCancelVerb.cs
- TextEditorCopyPaste.cs
- ConstructorNeedsTagAttribute.cs
- TdsParserHelperClasses.cs
- MsmqAppDomainProtocolHandler.cs
- DocumentXPathNavigator.cs
- RectAnimationUsingKeyFrames.cs
- ControlType.cs
- DiscreteKeyFrames.cs
- DesigntimeLicenseContext.cs
- TdsEnums.cs
- TdsParserHelperClasses.cs
- CachedBitmap.cs
- SqlMethodAttribute.cs
- XamlTypeMapper.cs
- BitmapSourceSafeMILHandle.cs
- IdentifierService.cs
- CompModSwitches.cs
- Overlapped.cs
- FileLogRecord.cs
- AsyncPostBackErrorEventArgs.cs
- TypeConverterAttribute.cs
- GridViewColumn.cs
- PersonalizableTypeEntry.cs
- SortDescription.cs
- PreloadedPackages.cs
- DataGridViewAccessibleObject.cs
- HtmlTableRowCollection.cs
- AdCreatedEventArgs.cs
- TokenDescriptor.cs
- TraceListener.cs
- SqlDataReader.cs
- Ticks.cs
- LinkButton.cs
- UTF32Encoding.cs
- HttpPostedFile.cs