开发者

How to get Control/Windows Handle/AutomationElement that receives mouseclicks at specific point?

I am trying to get a control at a specific screen coordinate which I have given. Now I want to开发者_JAVA技巧 know which control would receive a mouse-click. (The control is in another application in an UI Automation scenario.)

Also, let me say, that Control, Windows Handle and AutomationElement are all the same to me, since they are more or less easily convertible into one another (apart from maybe a Control which I think does not work in a different process).

There are the obvious functions like WindowFromPoint and AutomationElement.FromPoint, but both fail, returning some element that seems to be (invisibly) custom drawn on top. Still, I know that the mouse clicks go to the control I desire. So.. is there a way to find out where the mouse clicks are really going? Maybe alternatively to find out whether an element passes mouse-clicks through?

Many thanks Andreas


If you are in a situation where clicking the control would switch focus to it, you can use AutomationFocusChangeEventHandler to retrieve the AutomationElement that currently receives the focus. Then you can register a method that will handle focus-changed events:

AutomationFocusChangedEventHandler focusHandler = null;

/// <summary>
/// Create an event handler and register it.
/// </summary>
public void SubscribeToFocusChange()
{
    focusHandler = new AutomationFocusChangedEventHandler(OnFocusChange);
    Automation.AddAutomationFocusChangedEventHandler(focusHandler);
}

/// <summary>
/// Handle the event.
/// </summary>
/// <param name="src">Object that raised the event.</param>
/// <param name="e">Event arguments.</param>
private void OnFocusChange(object src, AutomationFocusChangedEventArgs e)
{
    AutomationElement focusedElement = src as AutomationElement;

    // TODO Add event handling code.
    // The arguments tell you which elements have lost and received focus.
}

/// <summary>
/// Cancel subscription to the event.
/// </summary>
public void UnsubscribeFocusChange()
{
    if (focusHandler != null)
    {
        Automation.RemoveAutomationFocusChangedEventHandler(focusHandler);
    }
}


Since there are no answers (or am I too impatient?), there is.. not a solution but rather a workaround I have found.

Actually, what I would have wanted is a deep search that is parameterizable (which unfortunately does not exist, though I suppose you could do it recursively yourself).

So.. the workaround is: I make the windows I don't want invisible.

Strangely and interestingly enough, this is easily doable from outside your application, simply call the ShowWindow ( http://www.pinvoke.net/default.aspx/user32/ShowWindow.html ) function and hide the window that you don't want to take into account. You could reset it later to its original state if you don't want to change the target application.

Anybody who has a better solution: by all means, please tell me!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜