Keyboard 键盘焦点的全局UI跟踪

Keyboard 键盘焦点的全局UI跟踪,keyboard,focus,Keyboard,Focus,有兴趣了解有关在windows桌面上跟踪键盘焦点所使用的API/应用程序类型的意见。我已经尝试了中针对.NET4.7.2的示例中的FocusTracker。它使用Automation.AddAutomationFocusChangedEventHandler(OnFocusChanged)事件。这主要起作用,但在将焦点设置为FireFox时出现问题。它将开始迷失方向,不再报告FireFox focus或任何其他焦点,并最终抛出异常。忽略这个异常,它将在FireFox以外的应用程序上重新开始工作

有兴趣了解有关在windows桌面上跟踪键盘焦点所使用的API/应用程序类型的意见。我已经尝试了中针对.NET4.7.2的示例中的FocusTracker。它使用Automation.AddAutomationFocusChangedEventHandler(OnFocusChanged)事件。这主要起作用,但在将焦点设置为FireFox时出现问题。它将开始迷失方向,不再报告FireFox focus或任何其他焦点,并最终抛出异常。忽略这个异常,它将在FireFox以外的应用程序上重新开始工作

那么谁应该使用.Net、win32 api、WPF、UWP等api集呢

这里的目标是使用RGB LED键盘,使其以特定颜色点亮热键,包括修改器(shift、ctrl、alt)热键。这将提醒您注意不同CAD工具之间的热键。因此,使用Logitech SDK,可以动态设置关键灯光颜色。不过要跟踪键盘焦点,然后在按下修改器热键时更新所选的按键灯光颜色。Logitech的工具已经允许您自定义每个所需应用程序的关键灯光颜色。只是不允许基于修改器关键点的自定义。谢谢


根据要求,以下是代码片段:

 /// <summary>
        ///     Initialization.
        /// </summary>
        private void Startup()
        {
            Automation.AddAutomationFocusChangedEventHandler(OnFocusChanged);
        }

        /// <summary>
        ///     Retrieves the top-level window that contains the specified
        ///     UI Automation element.
        /// </summary>
        /// <param name="element">The contained element.</param>
        /// <returns>The  top-level window element.</returns>
        private AutomationElement GetTopLevelWindow(AutomationElement element)
        {
            var walker = TreeWalker.ControlViewWalker;
            AutomationElement elementParent;
            var node = element;
            try // In case the element disappears suddenly, as menu items are 
                // likely to do.
            {
                if (node == AutomationElement.RootElement)
                {
                    return node;
                }
                // Walk up the tree to the child of the root.
                while (true)
                {
                    elementParent = walker.GetParent(node);
                    if (elementParent == null)
                    {
                        return null;
                    }
                    if (elementParent == AutomationElement.RootElement)
                    {
                        break;
                    }
                    node = elementParent;
                }
            }
            catch (ElementNotAvailableException)
            {
                node = null;
            }
            catch (ArgumentNullException)
            {
                node = null;
            }
            return node;
        }

        /// <summary>
        ///     Handles focus-changed events. If the element that received focus is
        ///     in a different top-level window, announces that. If not, just
        ///     announces which element received focus.
        /// </summary>
        /// <param name="src">Object that raised the event.</param>
        /// <param name="e">Event arguments.</param>
        private void OnFocusChanged(object src, AutomationFocusChangedEventArgs e)
        {
            try
            {
                var elementFocused = src as AutomationElement;
                var topLevelWindow = GetTopLevelWindow(elementFocused);
                if (topLevelWindow == null)
                {
                    return;
                }

                // If top-level window has changed, announce it.
                if (topLevelWindow != _lastTopLevelWindow)
                {
                    _lastTopLevelWindow = topLevelWindow;
                    Console.WriteLine("Focus moved to top-level window:");
                    Console.WriteLine("  " + topLevelWindow.Current.Name);
                    Console.WriteLine();
                }
                else
                {
                    // Announce focused element.
                    Console.WriteLine("Focused element: ");
                    Console.WriteLine("  Type: " +
                                      elementFocused.Current.LocalizedControlType);
                    Console.WriteLine("  Name: " + elementFocused.Current.Name);
                    Console.WriteLine();
                }
            }
            catch (ElementNotAvailableException)
            {
            }

        }
//
///初始化。
/// 
私有void启动()
{
Automation.AddAutomationFocusChangedEventHandler(OnFocusChanged);
}
/// 
///检索包含指定属性的顶级窗口
///UI自动化元素。
/// 
///包含的元素。
///顶层窗口元素。
私有AutomationElement GetToLevel窗口(AutomationElement元素)
{
var walker=TreeWalker.ControlViewWalker;
AutomationElement元素父级;
var节点=元素;
尝试//以防元素突然消失,因为菜单项
//很可能。
{
if(node==AutomationElement.RootElement)
{
返回节点;
}
//沿着这棵树走到树根下。
while(true)
{
elementParent=walker.GetParent(节点);
if(elementParent==null)
{
返回null;
}
if(elementParent==AutomationElement.RootElement)
{
打破
}
node=elementParent;
}
}
捕获(ElementNotAvailableException)
{
node=null;
}
捕获(异常)
{
node=null;
}
返回节点;
}
/// 
///处理焦点更改事件。如果接收到焦点的元素是
///在另一个顶级窗口中,宣布。如果没有,就
///宣布哪个元素获得焦点。
/// 
///引发事件的对象。
///事件参数。
私有void OnFocusChanged(对象src,AutomationFocusChangedEventArgs e)
{
尝试
{
var elementFocused=src作为AutomationElement;
var topLevelWindow=GetToLevel窗口(elementFocused);
如果(topLevelWindow==null)
{
返回;
}
//如果顶层窗口已更改,请宣布它。
如果(topLevelWindow!=\u lastTopLevelWindow)
{
_lastTopLevelWindow=topLevelWindow;
WriteLine(“焦点移到顶层窗口:”);
Console.WriteLine(“+topLevelWindow.Current.Name”);
Console.WriteLine();
}
其他的
{
//宣布重点元素。
Console.WriteLine(“聚焦元素:”);
Console.WriteLine(“类型:”+
elementFocused.Current.LocalizedControl类型);
Console.WriteLine(“Name:+elementFocused.Current.Name”);
Console.WriteLine();
}
}
捕获(ElementNotAvailableException)
{
}
}

更新:我确实再次运行了这段代码一段时间,即使是Firefox这次也没有引发异常,但扬声器的声音消失了。不确定这是否链接。谢谢

您能提供您正在使用的代码片段吗?不清楚您到底在尝试什么。根据要求,以下是代码片段: