如何在WPF中记录单击控件的名称/路径?

时间:2011-03-16 09:35:41

标签: wpf

我使用以下代码记录 WinForms 应用程序中的每次点击。本质上,它从 HWND 中查找控件,然后打印控件及其所有父项的类型和名称。类似 MainForm“myWindow”> TabPanel“mainTab”>按钮“保存”

internal class ClickLogger : IMessageFilter
{
    private const int WM_LBUTTONDOWN = 0x0201;
    private const int WM_LBUTTONDBLCLK = 0x0203;
    private const int WM_RBUTTONDOWN = 0x0204;        
    private const int MaxRecurseDepth = 30;

    private readonly ILogger _log;

    public ClickLogger(ILogger logger)
    {
        _log = logger;
    }

    [DebuggerStepThrough]
    public bool PreFilterMessage(ref Message message)
    {
        if (message.Msg == WM_LBUTTONDOWN
            || message.Msg == WM_RBUTTONDOWN
            || message.Msg == WM_LBUTTONDBLCLK)
        {
            string path = "Unknown";

            Control ctl = Control.FromHandle(message.HWnd);
            if (ctl != null)
            {
                path = PathFromControl(ctl, MaxRecurseDepth).ToString();
            }

            string logEntry = string.Format("{0} Click on {1}",
                WndMsgToClickName(message.Msg), path);

            if (_log.IsInfoEnabled)
            {
                _log.Info(logEntry);
            }
        }

        return false;
    }

    private StringBuilder PathFromControl(Control control, int maxDepth)
    {
        if(maxDepth == 0)
        {
            _log.Warn("Max recursion {0} reached whilst resolving path of control", MaxRecurseDepth);
            return new StringBuilder("ERR");
        }

        string name = control.GetType().Name;
        if (control.Name.IsNotBlank())
        {
            name = name + "\"" + control.Name + "\"";
        }

        if (control.Parent != null && control.Parent != control)
        {
            return PathFromControl(control.Parent, maxDepth - 1).Append(">").Append(name);
        }

        return new StringBuilder(name);
    }

    public void Initialize()
    {
        Application.AddMessageFilter(this);
    }

    private static string WndMsgToClickName(int msgId)
    {
        switch (msgId)
        {
            case WM_LBUTTONDOWN:
                return "Left";
            case WM_LBUTTONDBLCLK:
                return "Double";
            case WM_RBUTTONDOWN:
                return "Right";
            default:
                return "0x" + Convert.ToString(msgId, 16);
        }
    }
}

最近我们开始混合使用 WPF WinForms ,上面的点击记录器只是为 WPF上的任何点击打印“未知”控制。

有没有办法可以为 WPF 控件执行类似的技巧?一种跨技术的方法会很棒。

1 个答案:

答案 0 :(得分:1)

嗯,它并不完全适用于各种技术,但对于wpf,您可以使用this的组合来获取点击以及this问题中的任何帮助程序来循环访问父项以获取路径。