Jeff
Jeff

Reputation: 1800

UIAutomation - unbinding event in event handler

I am using the C wrapper of UIAutomation to listen for events.

Specifically, I'm looking for a focus event. When that focus event happens, I'm simply logging to the console, and unbinding the event.

Problem is - the program seems to stall/"die" on the automation.RemoveAllEventHandlers() call. The line below that never gets executed (doesn't print to console, breakpoint doesn't get hit.)

My guess is this is a threading issue - automationis created on a thread, but the event gets called on a different thread, and a big issue ensues. Is this the problem? If so/if not - what is and how do I fix it?

Below is the code:

public class FocusListener
    {
        private readonly CUIAutomation _automation;

        public FocusListener()
        {
            _automation = new CUIAutomation();

            _automation.AddFocusChangedEventHandler(null, new FocusChangeHandler(this));
            Console.WriteLine("Added a focus event!");
        }

        public void On_WindowClicked()
        {
            Console.WriteLine("Window clicked!");
            _automation.RemoveAllEventHandlers(); // program seems to die right here..
            Console.WriteLine("Focus event removed"); // this line never gets executed..
        }
    }

    public class FocusChangeHandler : IUIAutomationFocusChangedEventHandler
    {
        private readonly FocusListener _listener;

        public FocusChangeHandler(FocusListener listener)
        {
            _listener = listener;
        }

        public void HandleFocusChangedEvent(IUIAutomationElement sender)
        {
            if (sender.CurrentControlType == UIA_ControlTypeIds.UIA_WindowControlTypeId)
            {
                _listener.On_WindowClicked();
            }
        }
    }

Upvotes: 2

Views: 946

Answers (1)

galamdring
galamdring

Reputation: 313

According to: https://msdn.microsoft.com/en-us/library/windows/desktop/ee671692%28v=vs.85%29.aspx

It is safe to make UI Automation calls in a UI Automation event handler, >because the event handler is always called on a non-UI thread. However, when >subscribing to events that may originate from your client application UI, you >must make the call to IUIAutomation::AddAutomationEventHandler, or a related >method, on a non-UI thread (which should also be an MTA thread). Remove event >handlers on the same thread.

Upvotes: 1

Related Questions