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
- WinInetCache.cs
- XmlSyndicationContent.cs
- NetNamedPipeBinding.cs
- ActivationServices.cs
- CapabilitiesPattern.cs
- DataGridColumnCollection.cs
- CustomAttribute.cs
- PersonalizablePropertyEntry.cs
- VarRemapper.cs
- Command.cs
- ClientSettingsProvider.cs
- infer.cs
- ProviderUtil.cs
- SocketAddress.cs
- ReferentialConstraint.cs
- Geometry3D.cs
- SessionEndingCancelEventArgs.cs
- FileSystemInfo.cs
- Property.cs
- PointAnimationBase.cs
- TransformedBitmap.cs
- MouseButtonEventArgs.cs
- Repeater.cs
- GridViewCancelEditEventArgs.cs
- SiteMapDesignerDataSourceView.cs
- ExceptionUtil.cs
- ClientApiGenerator.cs
- FixedSOMTextRun.cs
- UnmanagedMemoryStreamWrapper.cs
- Rfc4050KeyFormatter.cs
- FormViewDeletedEventArgs.cs
- MasterPageBuildProvider.cs
- SoapWriter.cs
- SqlMethods.cs
- ActivitiesCollection.cs
- MachineSettingsSection.cs
- ResourceAssociationSet.cs
- SafeBitVector32.cs
- JoinTreeSlot.cs
- RecordManager.cs
- IconBitmapDecoder.cs
- GenericWebPart.cs
- PassportAuthenticationModule.cs
- GridItemProviderWrapper.cs
- ChannelBinding.cs
- WeakReferenceKey.cs
- AsymmetricAlgorithm.cs
- Double.cs
- OdbcConnectionStringbuilder.cs
- ColumnResult.cs
- AesManaged.cs
- CompilerCollection.cs
- MyContact.cs
- InplaceBitmapMetadataWriter.cs
- FocusWithinProperty.cs
- CRYPTPROTECT_PROMPTSTRUCT.cs
- selecteditemcollection.cs
- ProfileParameter.cs
- LeftCellWrapper.cs
- TreeViewDesigner.cs
- XmlSchemaValidationException.cs
- ParallelForEach.cs
- FrameDimension.cs
- TcpConnectionPoolSettings.cs
- ModuleBuilder.cs
- BulletChrome.cs
- Calendar.cs
- FtpCachePolicyElement.cs
- DocobjHost.cs
- HtmlImage.cs
- RuleCache.cs
- PointHitTestParameters.cs
- ClientSideProviderDescription.cs
- DefinitionBase.cs
- HwndHostAutomationPeer.cs
- CharKeyFrameCollection.cs
- ToolStripPanelRow.cs
- ToolStripPanelRenderEventArgs.cs
- SamlAuthorizationDecisionClaimResource.cs
- ContentWrapperAttribute.cs
- AnalyzedTree.cs
- TcpAppDomainProtocolHandler.cs
- Point.cs
- EnumValidator.cs
- ValidationPropertyAttribute.cs
- Attributes.cs
- Label.cs
- ToolboxCategoryItems.cs
- CacheMode.cs
- EdmEntityTypeAttribute.cs
- LostFocusEventManager.cs
- StringUtil.cs
- PropertyGridView.cs
- AccessedThroughPropertyAttribute.cs
- PageWrapper.cs
- COSERVERINFO.cs
- StreamWriter.cs
- Timer.cs
- X509Certificate2Collection.cs
- BamlTreeNode.cs