DefaultTextStore.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / System / Windows / Input / DefaultTextStore.cs / 1407647 / DefaultTextStore.cs

                            //---------------------------------------------------------------------------- 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// Description: the default text store that allows default TSF enabling. 
// 
// History:
//  11/17/2003 : yutakas 
//
//---------------------------------------------------------------------------

using System; 
using System.Runtime.InteropServices;
using System.Windows; 
using System.Windows.Threading; 
using System.Threading;
using System.Diagnostics; 
using System.Security;
using MS.Internal;
using MS.Internal.PresentationCore;                        // SecurityHelper
using System.Security.Permissions; 
using MS.Win32;
 
namespace System.Windows.Input 
{
    // This class has the default text store implementation. 
    // DefaultTextStore is a TextStore to be shared by any element of the Dispatcher.
    // When the keyboard focus is on the element, Cicero input goes into this by default.
    // This DefaultTextStore will be used unless an Element (such as TextBox) set
    // the focus on the document manager for its own TextStore. 
    internal class DefaultTextStore :  UnsafeNativeMethods.ITfContextOwner,
                                       UnsafeNativeMethods.ITfContextOwnerCompositionSink, 
                                       UnsafeNativeMethods.ITfTransitoryExtensionSink 
    {
        //----------------------------------------------------- 
        //
        //  Constructors
        //
        //----------------------------------------------------- 

        #region Constructors 
 
        // Creates a DefaultTextStore instance.
        internal DefaultTextStore(Dispatcher dispatcher) 
        {
            // Save the target Dispatcher.
            _dispatcher = dispatcher;
 
            _editCookie = UnsafeNativeMethods.TF_INVALID_COOKIE;
            _transitoryExtensionSinkCookie = UnsafeNativeMethods.TF_INVALID_COOKIE; 
        } 

        #endregion Constructors 

        //------------------------------------------------------
        //
        //  Public Methods - ITfContextOwner 
        //
        //----------------------------------------------------- 
 
        #region ITfContextOwner
 

        //
        //  ITfContextOwner implementation for Cicero's default text store.
        // 

        public void GetACPFromPoint(ref UnsafeNativeMethods.POINT point, UnsafeNativeMethods.GetPositionFromPointFlags flags, out int position) 
        { 
            position = 0;
        } 

        public void GetTextExt(int start, int end, out UnsafeNativeMethods.RECT rect, out bool clipped)
        {
            rect = new UnsafeNativeMethods.RECT(); 
            clipped = false;
        } 
 
        public void GetScreenExt(out UnsafeNativeMethods.RECT rect)
        { 
            rect = new UnsafeNativeMethods.RECT();
        }

        public void GetStatus(out UnsafeNativeMethods.TS_STATUS status) 
        {
            status = new UnsafeNativeMethods.TS_STATUS(); 
        } 

        public void GetWnd(out IntPtr hwnd) 
        {
            hwnd = IntPtr.Zero;
        }
 
        public void GetValue(ref Guid guidAttribute, out object varValue)
        { 
            varValue = null; 
        }
 
        #endregion ITfContextOwner


        //------------------------------------------------------ 
        //
        //  Public Methods - ITfContextOwnerCompositionSink 
        // 
        //------------------------------------------------------
 
        #region ITfContextOwnerCompositionSink

        /// 
        /// Critical - UnsafeNativeMethods.ITfCompositionView is a critical type. 
        /// Safe     - The method does nothing with the critical Input parameter.
        ///  
        [SecuritySafeCritical] 
        public void OnStartComposition(UnsafeNativeMethods.ITfCompositionView view, out bool ok)
        { 
            // Return true in ok to start the composition.
            ok = true;
        }
 
        /// 
        /// Critical - UnsafeNativeMethods.ITfCompositionView & UnsafeNativeMethods.ITfRange are critical types. 
        /// Safe     - The method does nothing. 
        /// 
        [SecuritySafeCritical] 
        public void OnUpdateComposition(UnsafeNativeMethods.ITfCompositionView view, UnsafeNativeMethods.ITfRange rangeNew)
        {
        }
 
        /// 
        /// Critical - UnsafeNativeMethods.ITfCompositionView is a critical type. 
        /// Safe     - The method does nothing. 
        /// 
        [SecuritySafeCritical] 
        public void OnEndComposition(UnsafeNativeMethods.ITfCompositionView view)
        {
        }
 
        #endregion ITfContextOwnerCompositionSink
 
        //----------------------------------------------------- 
        //
        //  Public Methods - ITfTransitoryExtensionSink 
        //
        //------------------------------------------------------

        #region ITfTransitoryExtensionSink 

        // Transitory Document has been updated. 
        // This is the notification of the changes of the result string and the composition string. 
        ///
        ///     Critical: This code acceses critical data in the form of TextCompositionManager 
        ///     TreatAsSafe: There exists a demand for unmanaged code.
        ///
        [SecurityCritical,SecurityTreatAsSafe]
        public void OnTransitoryExtensionUpdated(UnsafeNativeMethods.ITfContext context, int ecReadOnly, UnsafeNativeMethods.ITfRange rangeResult, UnsafeNativeMethods.ITfRange rangeComposition, out bool fDeleteResultRange) 
        {
            SecurityHelper.DemandUnmanagedCode(); 
 
            fDeleteResultRange = true;
 
            TextCompositionManager compmgr = InputManager.Current.PrimaryKeyboardDevice.TextCompositionManager;

            if (rangeResult != null)
            { 
                string result = StringFromITfRange(rangeResult, ecReadOnly);
                if (result.Length > 0) 
                { 
                    if (_composition == null)
                    { 

                        // We don't have the composition now and we got the result string.
                        // The result text is result and automatic termination is true.
                        _composition = new DefaultTextStoreTextComposition(InputManager.Current, Keyboard.FocusedElement, result, TextCompositionAutoComplete.On); 
                        TextCompositionManager.StartComposition(_composition);
 
                        // relese composition. 
                        _composition = null;
                        } 
                    else
                    {
                        // Finalize the composition.
                        _composition.SetCompositionText(""); 
                        _composition.SetText(result);
 
                        // We don't call _composition.Complete() here. We just want to generate 
                        // TextInput events.
                        TextCompositionManager.CompleteComposition(_composition); 

                        // relese composition.
                        _composition = null;
                    } 
                }
            } 
 
            if (rangeComposition != null)
            { 
                string comp = StringFromITfRange(rangeComposition, ecReadOnly);
                if (comp.Length > 0)
                {
                if (_composition == null) 
                    {
 
                        // Start the new composition. 
                        _composition = new DefaultTextStoreTextComposition(InputManager.Current, Keyboard.FocusedElement, "", TextCompositionAutoComplete.Off);
                        _composition.SetCompositionText(comp); 
                        TextCompositionManager.StartComposition(_composition);
                    }
                    else
                    { 
                        // Update the current composition.
                        _composition.SetCompositionText(comp); 
                        _composition.SetText(""); 
                        TextCompositionManager.UpdateComposition(_composition);
                    } 
                }
            }
        }
 
        #endregion ITfTransitoryExtensionSink
 
        //----------------------------------------------------- 
        //
        //  Public Properties 
        //
        //-----------------------------------------------------

        //----------------------------------------------------- 
        //
        //  Public Events 
        // 
        //------------------------------------------------------
 
        //-----------------------------------------------------
        //
        //  Protected Methods
        // 
        //------------------------------------------------------
 
        //------------------------------------------------------ 
        //
        //  Internal Methods 
        //
        //-----------------------------------------------------

        // Return the text services host associated with the current Dispatcher. 
        internal static DefaultTextStore Current
        { 
            get 
            {
                // DefaultTextStore is per Dispatcher and the cached referrence is stored in InputMethod class. 
                DefaultTextStore defaulttextstore = InputMethod.Current.DefaultTextStore;

                if(defaulttextstore == null)
                { 
                    defaulttextstore = new DefaultTextStore(Dispatcher.CurrentDispatcher);
                    InputMethod.Current.DefaultTextStore = defaulttextstore; 
 
                    defaulttextstore.Register();
                } 
                return defaulttextstore;
            }
        }
 
        //------------------------------------------------------
        // 
        //  Internal Properties 
        //
        //----------------------------------------------------- 

        // Pointer to ITfDocumentMgr interface.
        /// 
        ///     Critical: This exposes ITfDocumentMgr that has methods with SuppressUnmanagedCodeSecurity. 
        /// 
        internal UnsafeNativeMethods.ITfDocumentMgr DocumentManager 
        { 
            [SecurityCritical]
            get { return _doc.Value;} 
            set { _doc = new SecurityCriticalData(value); }
        }

        // EditCookie for ITfContext. 
        internal int EditCookie
        { 
            // get { return _editCookie; } 
            set { _editCookie = value; }
        } 

        internal int TransitoryExtensionSinkCookie
        {
            get { return _transitoryExtensionSinkCookie; } 
            set { _transitoryExtensionSinkCookie = value; }
        } 
 
        //
        // Get Transitory's DocumentMgr from GUID_COMPARTMENT_TRANSITORYEXTENSION_DOCUMENTMANAGER. 
        //
        /// 
        ///     Critical: This code acceses ITfDocumentMgr, ItfCompartment and ITfCompartmentMgr
        ///     TreatAsSafe: There exists a demand for unmanaged code 
        /// 
        internal UnsafeNativeMethods.ITfDocumentMgr TransitoryDocumentManager 
        { 
            [SecurityCritical,SecurityTreatAsSafe]
            get 
            {
                SecurityHelper.DemandUnmanagedCode();

                UnsafeNativeMethods.ITfDocumentMgr doc; 
                UnsafeNativeMethods.ITfCompartmentMgr compartmentMgr;
                UnsafeNativeMethods.ITfCompartment compartment; 
 
                // get compartment manager of the parent doc.
                compartmentMgr = (UnsafeNativeMethods.ITfCompartmentMgr)DocumentManager; 

                // get compartment.
                Guid guid = UnsafeNativeMethods.GUID_COMPARTMENT_TRANSITORYEXTENSION_DOCUMENTMANAGER;
                compartmentMgr.GetCompartment(ref guid, out compartment); 

                // get value of the compartment. 
                object obj; 
                compartment.GetValue(out obj);
                doc = obj as UnsafeNativeMethods.ITfDocumentMgr; 

                Marshal.ReleaseComObject(compartment);
                return doc;
            } 
        }
 
 
        //-----------------------------------------------------
        // 
        //  Internal Events
        //
        //-----------------------------------------------------
 
        //------------------------------------------------------
        // 
        //  Private Methods 
        //
        //----------------------------------------------------- 

        // get the text from ITfRange.
        /// 
        /// Critical - calls unmanaged code (GetExtent) 
        /// 
        [SecurityCritical] 
        private string StringFromITfRange(UnsafeNativeMethods.ITfRange range, int ecReadOnly) 
        {
            // Transitory Document uses ther TextStore, which is ACP base. 
            UnsafeNativeMethods.ITfRangeACP rangeacp = (UnsafeNativeMethods.ITfRangeACP)range;
            int start;
            int count;
            int countRet; 
            rangeacp.GetExtent(out start, out count);
            char[] text = new char[count]; 
            rangeacp.GetText(ecReadOnly, 0, text, count, out countRet); 
            return new string(text);
        } 

        // This function calls TextServicesContext to create TSF document and start transitory extension.
        /// 
        /// Critical - directly access the text store 
        /// TreatAsSafe - registers "this" as a text store (safe operation)
        ///  
        [SecurityCritical, SecurityTreatAsSafe] 
        private void Register()
        { 
            // Create TSF document and advise the sink to it.
            TextServicesContext.DispatcherCurrent.RegisterTextStore(this);
        }
 
        //------------------------------------------------------
        // 
        //  Private Properties 
        //
        //------------------------------------------------------ 

        //-----------------------------------------------------
        //
        //  Private Fields 
        //
        //------------------------------------------------------ 
 
        // Dispatcher for this text store
        private readonly Dispatcher _dispatcher; 

        // The current active composition.
        private TextComposition _composition;
 
        // The TSF document object.  This is a native resource.
        ///  
        ///     Critical: UnsafeNativeMethods.ITfDocumentMgr has methods with SuppressUnmanagedCodeSecurity. 
        /// 
        private SecurityCriticalData _doc; 

        // The edit cookie TSF returns from CreateContext.
        private int _editCookie;
 
        // The transitory extension sink cookie.
        private int _transitoryExtensionSinkCookie; 
    } 
}

// 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