14

Is there a way to tell whether my application is active i.e. any of its windows has .IsActive=true?

I'm writing messenger app and want it to flash in taskbar when it is inactive and new message arrives.

Poma
  • 8,174
  • 18
  • 82
  • 144
  • 2
    Override the form's OnActivate and OnDeactive methods. Flashing buttons isn't the greatest user interface approach, consider a NotifyIcon instead. But only show the balloon when there has been extended inactivity. – Hans Passant Aug 13 '11 at 13:08

5 Answers5

11

Used P/Invoke and loop

[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();

private static bool IsActive(Window wnd)
{
    // workaround for minimization bug
    // Managed .IsActive may return wrong value
    if (wnd == null) return false;
    return GetForegroundWindow() == new WindowInteropHelper(wnd).Handle;
}

public static bool IsApplicationActive()
{
    foreach (var wnd in Application.Current.Windows.OfType<Window>())
        if (IsActive(wnd)) return true;
    return false;
}
Poma
  • 8,174
  • 18
  • 82
  • 144
  • Sorry, Is this could only for check current window is active or not? Or also could bring the window to the front? – qakmak Dec 02 '16 at 11:33
  • Could save the IntPtr returned by GetForegroundWindow and avoid calling on every loop iteration. – RandomEngy May 23 '18 at 06:10
8

You can subscribe to Main Window's Activated event, and then do whatever you want. Can you give it a try?

sll
  • 61,540
  • 22
  • 104
  • 156
4

You have the Activated and Deactivated events of Application.

If you want to be able to Bind to IsActive you can add a Property in App.xaml.cs

<TextBlock Text="{Binding Path=IsActive,
                          Source={x:Static Application.Current}}"/>

of course you can also access this property in code like

App application = Application.Current as App;
bool isActive = application.IsActive;

App.xaml.cs

public partial class App : Application, INotifyPropertyChanged
{
    private bool m_isActive;
    public bool IsActive
    {
        get { return m_isActive; }
        private set
        {
            m_isActive = value;
            OnPropertyChanged("IsActive");
        }
    }

    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);
        Activated += (object sender, EventArgs ea) =>
        {
            IsActive = true;
        };
        Deactivated += (object sender, EventArgs ea) =>
        {
            IsActive = false;
        };
    }


    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
Fredrik Hedblad
  • 83,499
  • 23
  • 264
  • 266
  • You have the right idea but posted code that is unlikely to work. OnStartup() is a VB.NET implementation detail, C# apps rarely use the WindowsFormsApplicationBase class. Just override the OnActivate and OnDeactivate methods. – Hans Passant Aug 13 '11 at 13:06
  • 1
    @Hans Passant: I'm not sure I understand what you mean here. If you want to get the startup arguments for example in a WPF app, you override OnStartup. Although I agree that overriding OnActivate/OnDeactivate is a prettier solution I see no reason for this not to work. Also, I didn't submit the answer before trying it and it runs just fine – Fredrik Hedblad Aug 13 '11 at 13:23
  • 1
    @Hans Passant: I think you didn't read the tags well enough this time, this is WPF and not Windows Forms :) – Fredrik Hedblad Aug 13 '11 at 13:29
3

try this, override OnActivated method in your MainForm and do whatever you want

    protected override void OnActivated(EventArgs e)
    {
        // TODO : Implement your code here.
        base.OnActivated(e);
    }

hop this help

Saber Amani
  • 6,409
  • 12
  • 53
  • 88
-3

One way (may be there would be more better ways) can be to find the Active window through Windows API then find the process name of active window.

if(yourProcessName == ActiveWindowProcessName)
{
    //your window is in focus
}

Another way could be to keep a reference of all the windows and when you want to find out whether your app is active or not just iterate through all the windows and check IsActive value

Another way could be to use OwnedWindows property of MainWindow. Whenever you are creating a new window assign main window it's owner. Then you can iterate all the OwnedWindows of MainWindow and check whether any is active or not.(never tried this approach)

Haris Hasan
  • 29,856
  • 10
  • 92
  • 122
  • Why so complicated, I do not understand why shoud we go down to the process level when in the same time we have a complete infrastructure to check Application's Window state – sll Aug 13 '11 at 11:09
  • I am not suggesting to use it I am telling all the possible ways – Haris Hasan Aug 13 '11 at 11:11