Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / WinForms / Managed / System / WinForms / InputLanguage.cs / 1305376 / 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 = unchecked( (int) (long)currentHandle) & 0xffff; int device = (unchecked( (int) (long)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 == unchecked( (int) (long)currentHandle) || (encodingValue & 0x0FFFFFFF) == (unchecked( (int) (long)currentHandle) & 0x0FFFFFFF) || (encodingValue & 0xFFFF) == language) { currentHandle = (IntPtr)Convert.ToInt32((string)substitutions.GetValue(encoding), 16); language = unchecked( (int) (long)currentHandle) & 0xFFFF; device = (unchecked( (int) (long)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 ((unchecked( (int) (long)lang.handle) & 0xFFFF) == lcid) { return lang; } } return null; } ///Returns the input language associated with the specified /// culture. ////// /// public override int GetHashCode() { return unchecked( (int) (long)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
- Double.cs
- ServiceOperationUIEditor.cs
- AssertFilter.cs
- LocatorBase.cs
- LinkClickEvent.cs
- ConnectorRouter.cs
- WebPartCatalogCloseVerb.cs
- ObfuscateAssemblyAttribute.cs
- TagElement.cs
- HealthMonitoringSection.cs
- _ConnectOverlappedAsyncResult.cs
- ReadingWritingEntityEventArgs.cs
- XmlNamespaceMappingCollection.cs
- AnimationLayer.cs
- WebPart.cs
- SerTrace.cs
- DynamicPropertyReader.cs
- Module.cs
- WebRequestModuleElement.cs
- StructuredTypeInfo.cs
- OleDbErrorCollection.cs
- ParagraphVisual.cs
- PointUtil.cs
- MimePart.cs
- BitmapEffectrendercontext.cs
- ExpressionList.cs
- Win32Exception.cs
- CqlParser.cs
- ObjectFullSpanRewriter.cs
- ArraySubsetEnumerator.cs
- NamespaceQuery.cs
- AddressUtility.cs
- XmlProcessingInstruction.cs
- TypeReference.cs
- ComplusEndpointConfigContainer.cs
- CompilationUtil.cs
- InternalControlCollection.cs
- ViewStateAttachedPropertyFeature.cs
- CalloutQueueItem.cs
- MiniModule.cs
- TcpSocketManager.cs
- DispatcherExceptionEventArgs.cs
- PropertySourceInfo.cs
- FixedPageProcessor.cs
- SchemaNames.cs
- SerializationSectionGroup.cs
- RouteParameter.cs
- SystemGatewayIPAddressInformation.cs
- HwndKeyboardInputProvider.cs
- BamlTreeMap.cs
- UrlMappingCollection.cs
- FlowLayoutSettings.cs
- DataBinder.cs
- DefaultCompensation.cs
- RemotingConfigParser.cs
- DiscoveryClientElement.cs
- WebPartAuthorizationEventArgs.cs
- ComponentEditorPage.cs
- BodyWriter.cs
- SQLChars.cs
- BuildProviderAppliesToAttribute.cs
- IntegerValidator.cs
- LinqDataSourceHelper.cs
- SemaphoreFullException.cs
- XhtmlBasicValidationSummaryAdapter.cs
- UserControlCodeDomTreeGenerator.cs
- TemplateXamlTreeBuilder.cs
- EncodingNLS.cs
- PropertyNames.cs
- WpfXamlType.cs
- TypeConverter.cs
- documentation.cs
- MergeFilterQuery.cs
- ColorTransformHelper.cs
- SurrogateEncoder.cs
- SecurityPermission.cs
- OpenTypeLayout.cs
- PointUtil.cs
- SoapTypeAttribute.cs
- SettingsPropertyNotFoundException.cs
- WebPartVerb.cs
- CompilerCollection.cs
- FilteredAttributeCollection.cs
- XmlMapping.cs
- XmlSchemaType.cs
- PropertyBuilder.cs
- AssemblyNameProxy.cs
- SHA256.cs
- GenericPrincipal.cs
- CodeBlockBuilder.cs
- VariableAction.cs
- BamlVersionHeader.cs
- MustUnderstandSoapException.cs
- PopupRoot.cs
- ConfigurationSection.cs
- _NestedSingleAsyncResult.cs
- WebScriptEndpoint.cs
- HttpApplicationFactory.cs
- ZipIOCentralDirectoryBlock.cs
- ZipIOZip64EndOfCentralDirectoryBlock.cs