C# 如何获取在特定点接收鼠标点击的控件/Windows句柄/AutomationElement?

C# 如何获取在特定点接收鼠标点击的控件/Windows句柄/AutomationElement?,c#,c++,winapi,ui-automation,C#,C++,Winapi,Ui Automation,我试图在给定的特定屏幕坐标上获得一个控件。现在我想知道哪个控件会收到鼠标点击。(控件位于UI自动化场景中的另一个应用程序中。) 另外,让我说一下,控件、Windows句柄和AutomationElement对我来说都是一样的,因为它们或多或少都很容易转换成另一个控件(除了一个我认为在不同过程中不起作用的控件) 有一些明显的函数,如WindowFromPoint和AutomationElement.FromPoint,但都失败了,返回了一些似乎(不可见的)自定义绘制在顶部的元素。尽管如此,我知道鼠

我试图在给定的特定屏幕坐标上获得一个控件。现在我想知道哪个控件会收到鼠标点击。(控件位于UI自动化场景中的另一个应用程序中。)

另外,让我说一下,控件、Windows句柄和AutomationElement对我来说都是一样的,因为它们或多或少都很容易转换成另一个控件(除了一个我认为在不同过程中不起作用的控件)

有一些明显的函数,如WindowFromPoint和AutomationElement.FromPoint,但都失败了,返回了一些似乎(不可见的)自定义绘制在顶部的元素。尽管如此,我知道鼠标点击会转到我想要的控件。所以有没有办法找出鼠标点击的真正目的?或者,也可以找出一个元素是否通过鼠标点击

非常感谢
安德烈亚斯

因为没有答案(或者我太不耐烦了?),所以。。这不是一个解决方案,而是我找到的一个解决办法

实际上,我想要的是一个可参数化的深度搜索(不幸的是,它不存在,尽管我认为您可以自己递归地进行)

所以。。解决办法是:我把我不想看到的窗户做成隐形的

奇怪且有趣的是,从应用程序外部很容易做到这一点,只需调用ShowWindow()函数并隐藏您不想考虑的窗口。如果不想更改目标应用程序,可以稍后将其重置为原始状态


谁有更好的解决办法:请告诉我

如果单击控件会将焦点切换到该控件,则可以使用来检索当前接收焦点的AutomationElement。然后,您可以注册一个处理焦点更改事件的方法:

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);
    }
}
AutomationFocusChangedEventHandler focusHandler=null;
/// 
///创建一个事件处理程序并注册它。
/// 
公共无效帐户更改()
{
focusHandler=新的自动FocusChangedEventHandler(OnFocusChange);
Automation.AddAutomationFocusChangedEventHandler(focusHandler);
}
/// 
///处理事件。
/// 
///引发事件的对象。
///事件参数。
私有void OnFocusChange(对象src,AutomationFocusChangedEventArgs e)
{
AutomationElement focusedElement=src作为AutomationElement;
//TODO添加事件处理代码。
//这些参数告诉您哪些元素已丢失并获得焦点。
}
/// 
///取消对事件的订阅。
/// 
公共无效取消订阅FocusChange()
{
if(focusHandler!=null)
{
自动移除自动调焦控制器(调焦控制器);
}
}

这本书很有趣,非常感谢!不过,我缺少一个选项(在windows api中)来滚动浏览几个屏幕坐标相同的窗口/控件。还是有这样的功能?(因为上面提到的函数都不是我想要的。根据脚注,如果窗口位于另一个线程中,则没有一个函数能够正确处理TranParency,而访问另一个进程对我来说正是如此。)非常感谢!我认为您的解决方案需要实际单击以更改焦点,对吗?我记不清8年前发生了什么,但我认为它应该在没有点击的情况下工作,它只是为了识别一个控件。