11

好吧,有时我在打字,很少发生某些事情会转移注意力,我阅读了一些解决方案(甚至是 VB 手表),但它们不适用于我。是否有任何窗口范围的“句柄”可以处理任何焦点更改?

使用哪种语言,C、C++、VB.NET、C#、任何 .NET 或 Windows 相关的语言、批处理、PoweShell、VBS 脚本都没有关系……只要我能够监控每个焦点变化并将其记录到文件/cmd 窗口/可视窗口。

就像是:

   void event_OnWindowsFocusChange(int OldProcID, int NewProcID);

会很有用。或者也许已经有工具(我找不到?)

4

2 回答 2

19

一种方法是使用 Windows UI 自动化 API。它公开了一个全局焦点更改事件。这是我想出的一个快速示例(在 C# 中)。注意,您需要添加对 UIAutomationClient 和 UIAutomationTypes 的引用。

using System.Windows.Automation;
using System.Diagnostics;

namespace FocusChanged
{
    class Program
    {
        static void Main(string[] args)
        {
            Automation.AddAutomationFocusChangedEventHandler(OnFocusChangedHandler);
            Console.WriteLine("Monitoring... Hit enter to end.");
            Console.ReadLine();
        }

        private static void OnFocusChangedHandler(object src, AutomationFocusChangedEventArgs args)
        {
            Console.WriteLine("Focus changed!");
            AutomationElement element = src as AutomationElement;
            if (element != null)
            {
                string name = element.Current.Name;
                string id = element.Current.AutomationId;
                int processId = element.Current.ProcessId;
                using (Process process = Process.GetProcessById(processId))
                {
                    Console.WriteLine("  Name: {0}, Id: {1}, Process: {2}", name, id, process.ProcessName);
                }
            }
        }
    }
}
于 2012-07-29T21:04:15.247 回答
2

您可以使用挂钩监控焦点变化。SetWindowsHookEx(),使用 WH_SHELL 钩子完成它。回调获取 HSHELL_WINDOWACTIVATED 通知。

这并不容易,尤其是在托管语言中,因为它需要一个可以注入的 DLL。您也无法可靠地分辨出预期的焦点更改或进程推开窗口并偷走了焦点之间的区别。Windows 试图阻止,但有一个名为 AttachThreadInput() 的后门可以欺骗该代码。

永远不难分辨是什么过程做到了这一点。毕竟,它试图激活它的一个窗口。卸载该程序是最简单且最好的解决方法。

于 2012-07-29T18:13:36.330 回答