Как я могу определить, когда окно консоли моего приложения получает или теряет фокус?

1

Есть ли простой способ сделать это? Или, по крайней мере, проверьте, находится ли консоль в настоящее время в фокусе?

Представьте себе что-то вроде игры (это не так, но здесь есть аналогия) - было бы полезно, если бы она могла автоматически приостанавливаться. Мне нужно что-то подобное.

Теги:
console

2 ответа

4
Лучший ответ

Если интересующее вас окно не было консольным окном, это было бы очень просто сделать, просто нажав на соответствующее событие фокуса. Но в консольных окнах нет событий фокуса, поэтому простой выход здесь недоступен.

Что вы можете сделать, так это настроить обработчик событий для получения WinEvents, сгенерированных службами автоматизации пользовательского интерфейса. Событие генерируется всякий раз, когда изменяется фокус окна; вы можете получить HWND недавно сфокусированного окна и сравнить его с окном консоли. Если они совпадают, вы просто сосредоточены; если они этого не делают, у вас нет фокуса (либо просто потерял его, либо никогда не имел его для начала).

Самый удобный способ использования автоматизации пользовательского интерфейса - через System.Windows.Automation имен System.Windows.Automation. Вы можете настроить обработчик событий с помощью AddAutomationFocusChangedEventHandler, который даст вам экземпляр AutomationFocusChangedEventArgs из которого вы можете определить, какое окно получило фокус.

Вот пример кода:

AutomationFocusChangedEventHandler focusHandler = OnFocusChange;
Automation.AddAutomationFocusChangedEventHandler(focusHandler);
MessageBox.Show("Listening to focus changes");
Automation.RemoveAutomationFocusChangedEventHandler(focusHandler);

где OnFocusChange:

void OnFocusChange(object source, AutomationFocusChangedEventArgs e)
{
    var focusedHandle = new IntPtr(AutomationElement.FocusedElement.Current.NativeWindowHandle);
    var myConsoleHandle = Process.GetCurrentProcess().MainWindowHandle;

    if (focusedHandle == myConsoleHandle)
    {
        // ...
    }
}

Обратите внимание, что я предполагаю, что консоль - это главное окно процесса для простоты; если это не так, вам нужно получить HWND в окне консоли другим способом.

Также обратите внимание, что для получения событий автоматизации ваш процесс должен запускать цикл сообщений (в данном случае также известный как "цикл диспетчера"), который, в свою очередь, требует, чтобы поток был предназначен для его запуска. В приведенном выше примере это происходит автоматически, когда вызывается MessageBox.Show, но в общем случае вам нужно будет позаботиться об этом.

  • 0
    Serial downvoter, что-то не так с этим ответом?
  • 0
    Спасибо, это похоже на то, что мне нужно. Понятия не имею, почему / кто проголосовал
1

Я не могу добавить комментарий, поэтому мне просто нужно отправить ответ. Вы можете проверить теорию, опубликованную DJ KRAZE, следующим образом:

    /// <summary>Returns true if the current application has focus, false otherwise</summary>
public static bool ApplicationIsActivated()
{
    var activatedHandle = GetForegroundWindow();
    if (activatedHandle == IntPtr.Zero) {
        return false;       // No window is currently activated
    }else{
Console.WriteLine("Application is focused!"); 
}

    var procId = Process.GetCurrentProcess().Id;
    int activeProcId;
    GetWindowThreadProcessId(activatedHandle, out activeProcId);

    return activeProcId == procId;
}


[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
private static extern IntPtr GetForegroundWindow();

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern int GetWindowThreadProcessId(IntPtr handle, out int processId);

Поэтому, если он не возвращает false, тогда он будет печатать "Приложение сосредоточено!" в приложении. Вы всегда можете добавить что-то, где "return false" должно делать что-то, когда оно не сфокусировано.

  • 0
    Это на самом деле не отвечает на вопрос. Вопрос в том, «как мне спать / ждать, пока я не сосредоточен», а не в том, «как определить, сосредоточен ли я»?
  • 0
    Я видел это. В любом случае, спасибо, если бы я этого не сделал, это приблизило бы меня!
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню