鼠标悬停控制并显示其句柄 [英] Mouseover controls and display its handle

查看:61
本文介绍了鼠标悬停控制并显示其句柄的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道,我可以为表单中的每个组件编写一个函数作为事件来执行某些操作(例如,当鼠标悬停时).是否还有可能在不将事件链接到特定组件的情况下调用事件函数,而是针对应用程序中的所有组件?

I know, that I can write a function as an event for each component in a form to do something (e.g. when hovering with the mouse). Is there also a possibility to call an event function without linking the event to the specific component but for all of them in an application?

我想要实现的是显示例如只需将鼠标悬停在任何组件上即可获得句柄 (Control.Handle) 或更多信息.

What I want to achieve is to display e.g. the handle (Control.Handle) or more information about any component by just hovering the mouse over it.

提前致谢.

推荐答案

你可以试试UI自动化的方式.
UI 自动化 AutomationElement.FromPoint() 方法允许随时确定鼠标指针下的 Control.
此方法返回标识的 AutomationElement 对象以及许多有用的详细信息.如有必要,其他可以通过其他方式检索.

You can try the UI Automation way.
The UI Automation AutomationElement.FromPoint() method allows to determine which Control is under the Mouse Pointer at any time.
This method returns the AutomationElement object identified, along with many useful details. Other can be retrieved with other means, if necessary.

检查 AutomationElementAutomationElement.Current 详细信息以查看内容属性直接可用.
当然,你也可以使用每个AutomationElement的特定模式与 UI 元素交互或检索 其他属性.

Check the AutomationElement and AutomationElement.Current details to see what properties are directly available.
Of course, you can also use use each AutomationElement's specific Patterns to interact with the UI Elements or retrieve other properties.

使用 Timer 调用 AutomationElement.FromPoint() 方法,承载此过程的窗口不需要具有焦点:您可以检查任何其他窗口的 UI 元素,不一定属于到同一个进程.

Using a Timer to call the AutomationElement.FromPoint() method, the Window that hosts this procedure doesn't need to have focus: you can inspect UI Elements of any other Window, not necessarily belonging to the same Process.

此代码需要项目引用:
UIAutoamtionClient
UIAutomationTypes
WindowBase

This code requires a Project reference to:
UIAutoamtionClient
UIAutomationTypes
WindowBase

using System.Diagnostics;
using System.Windows.Automation;
using System.Windows.Forms;
using wPoint = System.Windows.Point;

public partial class frmUIExplorer : Form
{
    private Timer locationTimer = null;
    private AutomationElement uiaElement = null;

    public frmUIExplorer()
    {
        InitializeComponent();
        if (this.components == null) this.components = new Container();

        locationTimer = new Timer() { Interval = 200 };
        this.components.Add(locationTimer);
        locationTimer.Tick += OnTimerTick;
    }

    private void OnTimerTick(object sender, EventArgs e)
    {
        var pt = MousePosition;
        try {
            var currentElement = AutomationElement.FromPoint(new wPoint(pt.X, pt.Y));
            if (currentElement.Equals(uiaElement)) return;
            uiaElement = currentElement;

            Console.WriteLine($"Control Type: {currentElement.Current.ControlType.ProgrammaticName.Replace("ControlType.", "")}");
            // FrameworkId returns, e.g., Win32, WinForm, WPF, DirectUI etc.
            Console.WriteLine($"Framework: {currentElement.Current.FrameworkId}");
            Console.WriteLine($"Handle: 0x{currentElement.Current.NativeWindowHandle.ToString("X2")}");
            Console.WriteLine($"Class Name: {currentElement.Current.ClassName}");

            Console.WriteLine($"Bounds: {currentElement.Current.BoundingRectangle}");

            if (currentElement.TryGetClickablePoint(out wPoint p)) {
                Console.WriteLine($"Clickable Point: {p}");
            }

            Console.WriteLine($"Process Id: {currentElement.Current.ProcessId}");

            if (currentElement.Current.ProcessId > 4) {
                using (var proc = Process.GetProcessById(currentElement.Current.ProcessId)) {
                    Console.WriteLine($"Process Name: {proc.ProcessName}");
                    Console.WriteLine($"Process Main Window: {proc.MainWindowHandle}");
                    Console.WriteLine($"Process Window Title: {proc.MainWindowTitle}");
                }
            }
        }
        // An exception may be thrown when an UI Element become unavailable
        // for some reason. This is expected, nothing to do here.
        catch (Exception ex) { Console.WriteLine($"Exception: {ex.Message}"); };
    }

    protected override void OnShown(EventArgs e) => locationTimer.Start();

    protected override void OnFormClosing(FormClosingEventArgs e)
    {
        locationTimer.Stop();
        locationTimer.Tick -= OnTimerTick;
        uiaElement = null;
        base.OnFormClosing(e);
    }
}

这篇关于鼠标悬停控制并显示其句柄的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆