首页 > 解决方案 > 键盘焦点的全局 UI 跟踪

问题描述

有兴趣了解关于使用什么 API/应用程序类型来跟踪 Windows 桌面上的键盘焦点的意见。我已经从网络框架中针对 .NET 4.7.2 的示例中尝试了FocusTracker。它使用 Automation.AddAutomationFocusChangedEventHandler(OnFocusChanged) 事件。这主要是有效的,但在将焦点设置到 FireFox 时会出现问题。它将开始丢失跟踪,之后不再报告 FireFox 焦点或任何其他焦点,最终会引发异常。忽略该异常,它将重新开始在除 FireFox 之外的应用程序上运行。

那么哪一个应该使用 .Net、win32 api、WPF、UWP 等 API 集。

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

这里要求的是代码片段:

 /// <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)
            {
            }

        }

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

标签: keyboardfocus

解决方案


推荐阅读