//------------------------------------------------------
        //
        //  Constructors
        //
        //------------------------------------------------------

        #region Constructors

        internal CalloutQueueItem(Delegate clientCallback, UiaCoreApi.UiaCacheResponse cacheResponse, AutomationEventArgs e, UiaCoreApi.UiaCacheRequest cacheRequest)
        {
            _clientCallback = clientCallback;
            _cacheResponse  = cacheResponse;
            _e            = e;
            _cacheRequest = cacheRequest;
        }
        //------------------------------------------------------
        //
        //  Internal Methods
        //
        //------------------------------------------------------

        #region Internal Methods

        internal static AutomationElement BuildAutomationElementsFromResponse(
            UiaCoreApi.UiaCacheRequest cacheRequest,
            UiaCoreApi.UiaCacheResponse response)
        {
            if (response.TreeStructure == null)
            {
                Debug.Assert(response.RequestedData == null, "both RequestedData and TreeStructure should be null or non-null");
                return(null);
            }

            // FrozenCacheRequest should not be null one new AE code, but may
            // still be null on old code paths - eg. top level window events - where
            // prefetching is not yet enabled.
            if (cacheRequest == null)
            {
                cacheRequest = CacheRequest.DefaultUiaCacheRequest;
            }

            // ParseTreeDescription is the method that parses the returned data
            // and builds up the tree, setting properties on each node as it goes along...
            // index and propIndex keep track of where it is, and we check afterwards
            // that all are pointing to the end, to ensure that everything matched
            // up as expected.
            int  index               = 0;
            int  propIndex           = 0;
            bool askedForChildren    = (cacheRequest.TreeScope & TreeScope.Children) != 0;
            bool askedForDescendants = (cacheRequest.TreeScope & TreeScope.Descendants) != 0;
            AutomationElement root   = ParseTreeDescription(response.TreeStructure, response.RequestedData,
                                                            ref index,
                                                            ref propIndex,
                                                            cacheRequest,
                                                            askedForChildren,
                                                            askedForDescendants);

            if (index != response.TreeStructure.Length)
            {
                Debug.Assert(false, "Internal error: got malformed tree description string (extra chars at end)");
                return(null);
            }

            if (response.RequestedData != null && propIndex != response.RequestedData.GetLength(0))
            {
                Debug.Assert(false, "Internal error: mismatch between count of property buckets and nodes claiming them");
                return(null);
            }

            // Properties are wrapped (eg. pattern classes inserted in front of interface) as
            // they are being returned to the caller, in the AutomationElement accessors, not here.

            return(root);
        }
示例#3
0
        // Unmanaged DLL calls back on this to notify a UIAccess client of an event.
        internal void OnEvent(IntPtr argsAddr, object[,] requestedData, string treeStructure)
        {
            AutomationEventArgs e = UiaCoreApi.GetUiaEventArgs(argsAddr);
            if (e.EventId == AutomationElement.AutomationFocusChangedEvent)
            {
                uint eventTime = SafeNativeMethods.GetTickCount();
                if (eventTime == 0) // 0 is used as a marker value, so bump up to 1 if we get it.
                    eventTime = 1;

                // There's no FocusChangedEventArgs in core, but clients expect one, so substitute if needed...
                // (otherwise the cast in InvokeHandlers will fail...)
                e = new InternalAutomationFocusChangedEventArgs(0, 0, eventTime);
            }
            UiaCoreApi.UiaCacheResponse cacheResponse = new UiaCoreApi.UiaCacheResponse(requestedData, treeStructure, _eventListener.CacheRequest);
            // Invoke the listener's callback but not on this thread.  Queuing this onto a worker thread allows
            // OnEvent to return (which allows the call on the server-side to complete) and avoids a deadlock
            // situation when the client accesses properties on the source element.
            ClientEventManager.CBQ.PostWorkItem(new CalloutQueueItem(_clientCallback, cacheResponse, e, _eventListener.CacheRequest));
        }
示例#4
0
        // Unmanaged DLL calls back on this to notify a UIAccess client of an event.
        internal void OnEvent(IntPtr argsAddr, object[,] requestedData, string treeStructure)
        {
            AutomationEventArgs e = UiaCoreApi.GetUiaEventArgs(argsAddr);

            if (e.EventId == AutomationElement.AutomationFocusChangedEvent)
            {
                uint eventTime = SafeNativeMethods.GetTickCount();
                if (eventTime == 0) // 0 is used as a marker value, so bump up to 1 if we get it.
                {
                    eventTime = 1;
                }

                // There's no FocusChangedEventArgs in core, but clients expect one, so substitute if needed...
                // (otherwise the cast in InvokeHandlers will fail...)
                e = new InternalAutomationFocusChangedEventArgs(0, 0, eventTime);
            }
            UiaCoreApi.UiaCacheResponse cacheResponse = new UiaCoreApi.UiaCacheResponse(requestedData, treeStructure, _eventListener.CacheRequest);
            // Invoke the listener's callback but not on this thread.  Queuing this onto a worker thread allows
            // OnEvent to return (which allows the call on the server-side to complete) and avoids a deadlock
            // situation when the client accesses properties on the source element.
            ClientEventManager.CBQ.PostWorkItem(new CalloutQueueItem(_clientCallback, cacheResponse, e, _eventListener.CacheRequest));
        }
        //------------------------------------------------------
        //
        //  Internal Methods
        //
        //------------------------------------------------------

        #region Internal Methods

        internal override void Process()
        {
            // Grab properties for cache request here...
            AutomationElement src;

            if (_srcEl == null)
            {
                src = null;
            }
            else
            {
                UiaCoreApi.UiaCacheResponse response = UiaCoreApi.UiaGetUpdatedCache(_srcEl.RawNode, _request, UiaCoreApi.NormalizeState.View, null);
                src = CacheHelper.BuildAutomationElementsFromResponse(_request, response);
            }

            // We need to find out why this situation should occur at (aside from a window closed event) and
            // handle the cause.
            if (!(src == null && _e.EventId == AutomationElement.AutomationFocusChangedEvent))
            {
                InvokeHandlers.InvokeClientHandler(_clientCallback, src, _e);
            }
        }
示例#6
0
        //------------------------------------------------------
        //
        //  Internal Methods
        //
        //------------------------------------------------------

        #region Internal Methods

        internal override void Process()
        {
            // Grab properties for cache request here...
            AutomationElement src;

            if (_srcEl == null)
            {
                src = null;
            }
            else
            {
                UiaCoreApi.UiaCacheResponse response = UiaCoreApi.UiaGetUpdatedCache(_srcEl.RawNode, _request, UiaCoreApi.NormalizeState.View, null);
                src = CacheHelper.BuildAutomationElementsFromResponse(_request, response);
            }

            //

            if (!(src == null && _e.EventId == AutomationElement.AutomationFocusChangedEvent))
            {
                InvokeHandlers.InvokeClientHandler(_clientCallback, src, _e);
            }
        }