WinForms: как определить, что окно больше не активно (ни одно дочернее окно не имеет фокуса)?

Мое приложение использует несколько окон

Я хочу скрыть одно конкретное окно на случай, если приложение потеряет фокус (когда активное окно не является окном приложения) исходный код

Я обрабатываю событие Deactivate моей основной формы.

    private void MainForm_Deactivate(object sender, EventArgs e) 
    {
      Console.WriteLine("deactivate");
      if (GetActiveWindow() == this.Handle) 
      {
        Console.WriteLine("isactive=true");
      }
      else
      {
        Console.WriteLine("isactive=false");
      }
    }

[DllImport("user32.dll")]
static extern IntPtr GetActiveWindow();

Выход всегда

deactivate
isactive=true

Я наблюдал такое же поведение, если новое окно в моем приложении получает фокус, а также если я нажимаю на другое приложение.

Я ожидал, что GetActiveWindow вернет дескриптор нового активного окна при вызове из обработчика Deactivate. Вместо этого он всегда возвращает дескриптор окна моего приложения.

Как это возможно? Не обрабатывается ли событие Деактивировать "слишком рано"? (пока активна основная форма?).

Как я могу определить, что мое приложение потеряло фокус (окно моего приложения не является активным окном), а другое приложение получило его без запуска GetActiveWindow по таймеру?


person Marek    schedule 25.03.2010    source источник
comment
Мы говорим о приложении MDI?   -  person Bobby    schedule 25.03.2010
comment
нет, это не приложение MDI   -  person Marek    schedule 25.03.2010


Ответы (2)


Из того, что я вижу, GetActiveWindow получает активное окно для вызывающего потока, то есть ваше приложение, поэтому оно всегда будет возвращать текущее окно вашего приложения. Я думаю, что, возможно, вы ищете GetForegroundWindow, который вернет дескриптор окна, которое в настоящее время активно у пользователя.

person Lazarus    schedule 25.03.2010
comment
Хорошая точка зрения. Кстати, имейте в виду, что GetForegroundWindow может возвращать NULL в некоторых ситуациях (например, переключение фокуса нажатием кнопки на панели задач). - person Thomas; 25.03.2010
comment
@Thomas, хорошая практика программирования для проверки на NULL, даже если вы этого не ожидаете, но хорошо бы выделить это (+1) - person Lazarus; 25.03.2010

Я наблюдаю такое же поведение (.NET 3.5, Visual Studio 2008). Документация туманная:

Происходит, когда форма теряет фокус и больше не является активной формой.

Однако контраст между названиями событий (Активировать d и Деактивировать) предполагает, что событие действительно происходит до фактической деактивации.

person Thomas    schedule 25.03.2010