keyboard - 键盘焦点的全局 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,它也没有抛出异常,但扬声器的声音消失了。不确定这是否有联系。谢谢
解决方案
推荐阅读
- java - 我在使用 RecyclerView 应用 SearchView 时遇到问题
- python - Telegram bot python 向用户发送多条消息
- json - 序列化/反序列化 js-joda LocalDate 的首选方式?
- apache-spark - Spark SQL 无法识别 \d+
- java - Android中的TextView在'/'字符后不显示任何文本
- django - vagrant + ansible 中的域问题,尝试使用 example.com 并获取 example.local
- python - sklearn中的ValueError:形状未对齐
- c - 在windows下使用c将数据传递给线程的问题
- python - 在python中计算列表中的字符串,然后过滤和匹配
- azure - 如何在 Azure Blob Storage .dotnet core 中存储 2 个同名的 pdf 文件