【问题标题】:Microsoft UI Automation/Get The Item That The User ClicksMicrosoft UI 自动化/获取用户单击的项目
【发布时间】:2022-04-26 06:14:54
【问题描述】:

我试图找出用户单击了哪些项目(例如文档、网页选项卡、窗口、图片、文件夹)。当我检测到全局鼠标左键单击时,我首先使用以下代码:

System.Drawing.Point MousePoint = System.Windows.Forms.Cursor.Position;
AutomationElement AutomationElement = AutomationElement.FromPoint(new System.Windows.Point(MousePoint.X, MousePoint.Y));
Console.WriteLine(AutomationElement.Current.Name);

这似乎在大多数情况下都能正常工作。但是,例如,我需要(如果可能)在 Windows 资源管理器中获取文档/图像/文件夹的名称。当我单击 Windows 资源管理器(不是树视图)右侧窗格中的文档时返回的值是“名称”。反正有没有得到实际的文件名称?出于某种原因,单击树视图中的子文件夹会返回文件夹的名称,这正是我想要的。

我还注意到,如果 Windows 资源管理器视图设置为图标(中、大或特大),则单击该代码时似乎会显示文档/图像/文件夹名称。为什么其他视图返回“名称”或空字符串,而中、大和超大图标返回实际文档/图像/文件夹名称?它与单击的对象的大小有关吗?如果可能的话,我真的可以解决这个问题吗?

抱歉,我是 UI 自动化的新手,我真的想要一种方法来查找用户单击的对象(文件、文件夹、文档、图片、网页选项卡等)的名称。任何人都可以提供的任何帮助都会很棒。

【问题讨论】:

  • 值可能比名称更有用。 UIAutomation 本质上并不知道用户与之交互的“事物”代表一个文件,并且您依赖资源管理器以可预测的方式表现其命名,而它似乎没有这样做 - 它是否显示已知文件类型的扩展名?对于资源管理器,有更好的方法来查询当前选择(ShellWindows)
  • @AlexK。我找不到AutomationElement.Current.Value 字段?
  • 我编辑了这个问题的标签以删除不应使用的microsoft标签,如标签wiki中所述(尽管它的继续存在本身就是有问题的);这是对这里提出的元问题的进一步说明:meta.stackoverflow.com/q/293754/82548。我还请您考虑-我不熟悉 c#-hook 标签是否添加了与您的问题相关的任何内容。我怀疑它没有,但我不确定。

标签: c# winforms user-interface automation hook


【解决方案1】:

您需要监听InvokePattern.InvokedEvent UI 自动化事件。

示例

以下示例假定您有一个打开的 Windows“计算器”应用程序实例。然后,如果您运行应用程序,当您单击计算器中的任何按钮时,我们会处理单击事件并显示单击了哪个按钮。

[DllImport("user32.dll")]
private extern static IntPtr FindWindow(string lpClassName, string lpWindowName);
protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    var proc = System.Diagnostics.Process.GetProcessesByName("Calculator")
                        .FirstOrDefault();
    if (proc != null)
    {
        var mainHwnd = FindWindow(null, "Calculator");
        var mainWndElement = AutomationElement.FromHandle(mainHwnd);
        Automation.AddAutomationEventHandler(
            InvokePattern.InvokedEvent, mainWndElement,
            TreeScope.Subtree, (s1, e1) =>
            {
                var element = s1 as AutomationElement;
                MessageBox.Show($"'{element.Current.Name}' clicked by user!");
            });
    }
}
protected override void OnFormClosing(FormClosingEventArgs e)
{
    Automation.RemoveAllEventHandlers();
    base.OnFormClosing(e);
}

您需要添加对UIAutomationClientUIAutomationTypes 程序集的引用。

注意

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-13
    • 2015-12-15
    • 2015-09-01
    • 2010-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多