InputProcessorProfiles.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Core / CSharp / System / Windows / Input / InputProcessorProfiles.cs / 1 / InputProcessorProfiles.cs

                            //---------------------------------------------------------------------------- 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// 
// Description: Creates ITfInputProcessorProfiles instances. 
//
// History: 
//  07/30/2003 : yutakas - ported from dotnet tree.
//
//---------------------------------------------------------------------------
 
using System;
using System.Runtime.InteropServices; 
using System.Security.Permissions; 
using System.Threading;
using System.Security; 
using MS.Win32;
using MS.Internal;
using System.Diagnostics;
using System.Globalization; 
using System.Collections;
 
namespace System.Windows.Input 
{
 
    //-----------------------------------------------------
    //
    //  InputProcessorProfiles class
    // 
    //-----------------------------------------------------
 
    ///  
    /// The InputProcessorProfiles class is always associated with
    /// hwndInputLanguage class. 
    /// 
    internal class InputProcessorProfiles
    {
        //------------------------------------------------------ 
        //
        //  Constructors 
        // 
        //-----------------------------------------------------
 
        /// 
        /// InputProcessorProfiles Constructor;
        /// 
        /// Critical - as this sets the value for _ipp. 
        /// Safe - as this just initializes it to null.
        [SecurityCritical, SecurityTreatAsSafe] 
        internal InputProcessorProfiles() 
        {
            // _ipp is a ValueType, hence no need for new. 
            _ipp.Value = null;
            _cookie = UnsafeNativeMethods.TF_INVALID_COOKIE;
        }
 
        //------------------------------------------------------
        // 
        //  Internal Methods 
        //
        //------------------------------------------------------ 

        #region Internal Methods

        ///  
        /// Initialize an interface and notify sink.
        ///  
        ///  
        /// Critical - calls critical method (inputprocessorprofilesload)
        ///            calls Critical setter on _ipp.Value 
        /// 
        [SecurityCritical]
        internal bool Initialize(object o)
        { 
            Debug.Assert(Thread.CurrentThread.GetApartmentState() == ApartmentState.STA, "Initialize called on MTA thread!");
 
            Debug.Assert(_ipp.Value == null, "Initialize called twice"); 

            _ipp.Value = InputProcessorProfilesLoader.Load(); 

            if (_ipp.Value == null)
            {
                return false; 
            }
 
            AdviseNotifySink(o); 
            return true;
        } 

        /// 
        /// Initialize an interface and notify sink.
        ///  
        /// 
        /// Critical - as this calls Marshal.ReleaseComObject(), which has a LinkDemand 
        ///            Also calls setter for _ipp.Value. 
        /// Safe - as the worst that would happen is NullReference exception when _ipp is accessed.
        ///        Setting _ipp.Value to null is safe. 
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        internal void Uninitialize()
        { 
            Debug.Assert(_ipp.Value != null, "Uninitialize called without initializing");
 
            UnadviseNotifySink(); 
            Marshal.ReleaseComObject(_ipp.Value);
            _ipp.Value = null; 
        }

        #endregion Internal Methods
 
        //-----------------------------------------------------
        // 
        //  Internal Properties 
        //
        //------------------------------------------------------ 

        /// 
        /// Get the current input language of the current thread.
        ///  
        /// 
        /// Critical - calls unmanaged code to set the input language 
        /// TreatAsSafe - it is OK to set the input language, APIs check 
        ///                 to make sure the lang is available.
        ///  
        internal short CurrentInputLanguage
        {
            [SecurityCritical, SecurityTreatAsSafe]
            set 
            {
                if (_ipp.Value != null) 
                { 
                    if (_ipp.Value.ChangeCurrentLanguage(value) != 0)
                    { 
                        //
                        // Under WinXP or W2K3, ITfInputProcessorProfiles::ChangeCurrentLanguage() fails
                        // if there is no thread manager in the current thread. This is Cicero's bug and fixed
                        // for Longhorn. 
                        // We need to try ActivateKeyboardLayout() for the case.
                        // 
                        IntPtr[] hklList = null; 

                        int count = (int)SafeNativeMethods.GetKeyboardLayoutList(0, null); 
                        if (count > 1)
                        {
                            hklList = new IntPtr[count];
 
                            count = SafeNativeMethods.GetKeyboardLayoutList(count, hklList);
 
                            int i; 
                            for (i = 0; (i < hklList.Length) && (i < count); i++)
                            { 
                                if (value == (short)hklList[i])
                                {
                                    SafeNativeMethods.ActivateKeyboardLayout(new HandleRef(this,hklList[i]), 0);
                                    break; 
                                }
                            } 
                        } 
                    }
                } 
            }
        }

        ///  
        /// Get the list of the input languages that are available in the
        /// current thread. 
        ///  
        /// 
        /// Critical - calls unmanaged code to query the languages on the system 
        /// TreatAsSafe - it is OK to disclose the available languages on the system
        /// 
        internal ArrayList InputLanguageList
        { 
            [SecurityCritical, SecurityTreatAsSafe]
             get 
             { 
                 int nCount;
                 IntPtr langids; 

                 // ITfInputProcessorProfiles::GetLanguageList returns the pointer that was allocated by
                 // CoTaskMemAlloc().
                 _ipp.Value.GetLanguageList(out langids, out nCount); 

                 ArrayList arrayLang = new ArrayList(); 
 
                 int sizeOfShort = Marshal.SizeOf(typeof(short));
 
                 for (int i = 0; i < nCount; i++)
                 {
                     // Unmarshal each langid from short array.
                     short langid = (short)Marshal.PtrToStructure((IntPtr)((Int64)langids + sizeOfShort * i), typeof(short)); 
                     arrayLang.Add(new CultureInfo(langid));
                 } 
 
                 // Call CoTaskMemFree().
                 Marshal.FreeCoTaskMem(langids); 

                 return arrayLang;
             }
        } 

 
        //----------------------------------------------------- 
        //
        //  Private Methods 
        //
        //-----------------------------------------------------

        ///  
        /// This advices the input language notify sink to
        /// ITfInputProcessorProfile. 
        ///  
        /// 
        ///     Critical: This calls into ITfSource which is an interop COM call 
        /// 
        [SecurityCritical]
        private void AdviseNotifySink(object o)
        { 
            Debug.Assert(_cookie == UnsafeNativeMethods.TF_INVALID_COOKIE, "Cookie is already set.");
 
            UnsafeNativeMethods.ITfSource source = _ipp.Value as UnsafeNativeMethods.ITfSource; 

            // workaround because I can't pass a ref to a readonly constant 
            Guid guid = UnsafeNativeMethods.IID_ITfLanguageProfileNotifySink;

            source.AdviseSink(ref guid, o, out _cookie);
        } 

        ///  
        /// This unadvises the sink. 
        /// 
        ///  
        /// Critical - As this elevates to invoke UnadviseSink on ITfSource.
        /// Safe - as the worst that'll happen is that we'll lose some text framework notifications.
        ///        Note that _ipp is marked SecurityCritical for set.
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        private void UnadviseNotifySink() 
        { 
            Debug.Assert(_cookie != UnsafeNativeMethods.TF_INVALID_COOKIE, "Cookie is not set.");
 
            UnsafeNativeMethods.ITfSource source = _ipp.Value as UnsafeNativeMethods.ITfSource;

            source.UnadviseSink(_cookie);
 
            _cookie = UnsafeNativeMethods.TF_INVALID_COOKIE;
        } 
 
        //-----------------------------------------------------
        // 
        //  Private Fields
        //
        //------------------------------------------------------
 
        // The reference to ITfInputProcessorProfile.
        private SecurityCriticalDataForSet _ipp; 
 
        // The cookie for the advised sink.
        private int _cookie; 
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//---------------------------------------------------------------------------- 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// 
// Description: Creates ITfInputProcessorProfiles instances. 
//
// History: 
//  07/30/2003 : yutakas - ported from dotnet tree.
//
//---------------------------------------------------------------------------
 
using System;
using System.Runtime.InteropServices; 
using System.Security.Permissions; 
using System.Threading;
using System.Security; 
using MS.Win32;
using MS.Internal;
using System.Diagnostics;
using System.Globalization; 
using System.Collections;
 
namespace System.Windows.Input 
{
 
    //-----------------------------------------------------
    //
    //  InputProcessorProfiles class
    // 
    //-----------------------------------------------------
 
    ///  
    /// The InputProcessorProfiles class is always associated with
    /// hwndInputLanguage class. 
    /// 
    internal class InputProcessorProfiles
    {
        //------------------------------------------------------ 
        //
        //  Constructors 
        // 
        //-----------------------------------------------------
 
        /// 
        /// InputProcessorProfiles Constructor;
        /// 
        /// Critical - as this sets the value for _ipp. 
        /// Safe - as this just initializes it to null.
        [SecurityCritical, SecurityTreatAsSafe] 
        internal InputProcessorProfiles() 
        {
            // _ipp is a ValueType, hence no need for new. 
            _ipp.Value = null;
            _cookie = UnsafeNativeMethods.TF_INVALID_COOKIE;
        }
 
        //------------------------------------------------------
        // 
        //  Internal Methods 
        //
        //------------------------------------------------------ 

        #region Internal Methods

        ///  
        /// Initialize an interface and notify sink.
        ///  
        ///  
        /// Critical - calls critical method (inputprocessorprofilesload)
        ///            calls Critical setter on _ipp.Value 
        /// 
        [SecurityCritical]
        internal bool Initialize(object o)
        { 
            Debug.Assert(Thread.CurrentThread.GetApartmentState() == ApartmentState.STA, "Initialize called on MTA thread!");
 
            Debug.Assert(_ipp.Value == null, "Initialize called twice"); 

            _ipp.Value = InputProcessorProfilesLoader.Load(); 

            if (_ipp.Value == null)
            {
                return false; 
            }
 
            AdviseNotifySink(o); 
            return true;
        } 

        /// 
        /// Initialize an interface and notify sink.
        ///  
        /// 
        /// Critical - as this calls Marshal.ReleaseComObject(), which has a LinkDemand 
        ///            Also calls setter for _ipp.Value. 
        /// Safe - as the worst that would happen is NullReference exception when _ipp is accessed.
        ///        Setting _ipp.Value to null is safe. 
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        internal void Uninitialize()
        { 
            Debug.Assert(_ipp.Value != null, "Uninitialize called without initializing");
 
            UnadviseNotifySink(); 
            Marshal.ReleaseComObject(_ipp.Value);
            _ipp.Value = null; 
        }

        #endregion Internal Methods
 
        //-----------------------------------------------------
        // 
        //  Internal Properties 
        //
        //------------------------------------------------------ 

        /// 
        /// Get the current input language of the current thread.
        ///  
        /// 
        /// Critical - calls unmanaged code to set the input language 
        /// TreatAsSafe - it is OK to set the input language, APIs check 
        ///                 to make sure the lang is available.
        ///  
        internal short CurrentInputLanguage
        {
            [SecurityCritical, SecurityTreatAsSafe]
            set 
            {
                if (_ipp.Value != null) 
                { 
                    if (_ipp.Value.ChangeCurrentLanguage(value) != 0)
                    { 
                        //
                        // Under WinXP or W2K3, ITfInputProcessorProfiles::ChangeCurrentLanguage() fails
                        // if there is no thread manager in the current thread. This is Cicero's bug and fixed
                        // for Longhorn. 
                        // We need to try ActivateKeyboardLayout() for the case.
                        // 
                        IntPtr[] hklList = null; 

                        int count = (int)SafeNativeMethods.GetKeyboardLayoutList(0, null); 
                        if (count > 1)
                        {
                            hklList = new IntPtr[count];
 
                            count = SafeNativeMethods.GetKeyboardLayoutList(count, hklList);
 
                            int i; 
                            for (i = 0; (i < hklList.Length) && (i < count); i++)
                            { 
                                if (value == (short)hklList[i])
                                {
                                    SafeNativeMethods.ActivateKeyboardLayout(new HandleRef(this,hklList[i]), 0);
                                    break; 
                                }
                            } 
                        } 
                    }
                } 
            }
        }

        ///  
        /// Get the list of the input languages that are available in the
        /// current thread. 
        ///  
        /// 
        /// Critical - calls unmanaged code to query the languages on the system 
        /// TreatAsSafe - it is OK to disclose the available languages on the system
        /// 
        internal ArrayList InputLanguageList
        { 
            [SecurityCritical, SecurityTreatAsSafe]
             get 
             { 
                 int nCount;
                 IntPtr langids; 

                 // ITfInputProcessorProfiles::GetLanguageList returns the pointer that was allocated by
                 // CoTaskMemAlloc().
                 _ipp.Value.GetLanguageList(out langids, out nCount); 

                 ArrayList arrayLang = new ArrayList(); 
 
                 int sizeOfShort = Marshal.SizeOf(typeof(short));
 
                 for (int i = 0; i < nCount; i++)
                 {
                     // Unmarshal each langid from short array.
                     short langid = (short)Marshal.PtrToStructure((IntPtr)((Int64)langids + sizeOfShort * i), typeof(short)); 
                     arrayLang.Add(new CultureInfo(langid));
                 } 
 
                 // Call CoTaskMemFree().
                 Marshal.FreeCoTaskMem(langids); 

                 return arrayLang;
             }
        } 

 
        //----------------------------------------------------- 
        //
        //  Private Methods 
        //
        //-----------------------------------------------------

        ///  
        /// This advices the input language notify sink to
        /// ITfInputProcessorProfile. 
        ///  
        /// 
        ///     Critical: This calls into ITfSource which is an interop COM call 
        /// 
        [SecurityCritical]
        private void AdviseNotifySink(object o)
        { 
            Debug.Assert(_cookie == UnsafeNativeMethods.TF_INVALID_COOKIE, "Cookie is already set.");
 
            UnsafeNativeMethods.ITfSource source = _ipp.Value as UnsafeNativeMethods.ITfSource; 

            // workaround because I can't pass a ref to a readonly constant 
            Guid guid = UnsafeNativeMethods.IID_ITfLanguageProfileNotifySink;

            source.AdviseSink(ref guid, o, out _cookie);
        } 

        ///  
        /// This unadvises the sink. 
        /// 
        ///  
        /// Critical - As this elevates to invoke UnadviseSink on ITfSource.
        /// Safe - as the worst that'll happen is that we'll lose some text framework notifications.
        ///        Note that _ipp is marked SecurityCritical for set.
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        private void UnadviseNotifySink() 
        { 
            Debug.Assert(_cookie != UnsafeNativeMethods.TF_INVALID_COOKIE, "Cookie is not set.");
 
            UnsafeNativeMethods.ITfSource source = _ipp.Value as UnsafeNativeMethods.ITfSource;

            source.UnadviseSink(_cookie);
 
            _cookie = UnsafeNativeMethods.TF_INVALID_COOKIE;
        } 
 
        //-----------------------------------------------------
        // 
        //  Private Fields
        //
        //------------------------------------------------------
 
        // The reference to ITfInputProcessorProfile.
        private SecurityCriticalDataForSet _ipp; 
 
        // The cookie for the advised sink.
        private int _cookie; 
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK