有没有一种简单的方法可以做到这一点?或者至少检查控制台当前是否处于焦点状态?
想象一下像游戏这样的东西(这里不是这种情况,但类比成立) - 如果它可以自动暂停,那将会很有用。我需要类似的东西。
如果您感兴趣的窗口不是控制台窗口,则只需点击适当的焦点事件即可非常简单。但控制台窗口没有焦点事件,因此这里不提供简单的解决方法。
您可以做的是设置一个事件处理程序来接收UI 自动化服务生成的WinEvents 。每当窗口焦点改变时就会生成一个事件;您可以获取新聚焦窗口的 HWND 并将其与控制台窗口的 HWND 进行比较。如果它们匹配,你就会获得焦点;如果它们匹配,你就会获得焦点。如果他们不这样做,那么你就没有焦点(要么只是失去了焦点,要么根本就没有焦点)。
利用 UI 自动化的最便捷方法是通过System.Windows.Automation命名空间。您可以使用 设置事件处理程序AddAutomationFocusChangedEventHandler,这将为您提供一个实例,AutomationFocusChangedEventArgs您可以从中确定哪个窗口已获得焦点。
这是一些示例代码:
AutomationFocusChangedEventHandler focusHandler = OnFocusChange;
Automation.AddAutomationFocusChangedEventHandler(focusHandler);
MessageBox.Show("Listening to focus changes");
Automation.RemoveAutomationFocusChangedEventHandler(focusHandler);
Run Code Online (Sandbox Code Playgroud)
哪里OnFocusChange:
void OnFocusChange(object source, AutomationFocusChangedEventArgs e)
{
var focusedHandle = new IntPtr(AutomationElement.FocusedElement.Current.NativeWindowHandle);
var myConsoleHandle = Process.GetCurrentProcess().MainWindowHandle;
if (focusedHandle == myConsoleHandle)
{
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,为了简单起见,我假设控制台是您进程的主窗口;如果不是这种情况,您需要以其他方式获取控制台窗口的 HWND。
另请注意,为了接收自动化事件,您的进程必须运行消息循环(在本例中也称为“调度程序循环”),这又需要一个专用于运行它的线程。在上面的示例中,这会在MessageBox.Show调用时自动发生,但在一般情况下,您必须妥善处理它。