50

Note: There's a very similar question, but it's WPF-specific; this one is not.

How can I determine if the current application is activated (i.e. has focus)?

Community
  • 1
  • 1
Cameron
  • 96,106
  • 25
  • 196
  • 225
  • Are you talking about your personal windowsform application or arbitrary? – Tigran Aug 23 '11 at 14:43
  • like this? http://stackoverflow.com/questions/2183541/c-detecting-which-application-has-focus –  Aug 23 '11 at 14:43
  • Personal -- hence "current application" ;-) – Cameron Aug 23 '11 at 14:44
  • @Code Monkey: Yes, except that I didn't want to have to intercept messages or add event listeners if possible (also, I think the accepted answer for that question would not work if there are two windows on different threads (with neither owning the other), but part of the same application -- and yes, I need to deal with that) – Cameron Aug 23 '11 at 14:51

7 Answers7

86

This works:

/// <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
    }

    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);

It has the advantage of being thread-safe, not requiring the main form (or its handle) and is not WPF or WinForms specific. It will work with child windows (even independent ones created on a separate thread). Also, there's zero setup required.

The disadvantage is that it uses a little P/Invoke, but I can live with that :-)

Cameron
  • 96,106
  • 25
  • 196
  • 225
13

The solution I found which requires neither native calls nor requires handling events is to check Form.ActiveForm. In my tests, that was null when no window in the application was focused and otherwise non-null.

var windowInApplicationIsFocused = Form.ActiveForm != null;

Ah, this is specific to winforms. But that applies to my situation ;-).

binki
  • 7,754
  • 5
  • 64
  • 110
  • 1
    This is an interesting one. An app I'm editing had code to steal focus from its own tool window on mouse-over of its main window, but this apparently occasionally also made it steal focus from other applications. Checking `Form.ActiveForm` looks like a promising way to prevent this. – Nyerguds Sep 03 '22 at 20:55
11

since it's likely that some element in your UI has contain focus for the form to be active try:

this.ContainsFocus

http://msdn.microsoft.com/en-us/library/system.windows.forms.control.containsfocus(v=vs.110).aspx

Proteux
  • 213
  • 2
  • 3
5

You can subscribe to Main Window's Activated event

genesis
  • 50,477
  • 20
  • 96
  • 125
2

First get the handle either using:

IntPtr myWindowHandle;

myWindowHandle = new WindowInteropHelper(Application.Current.MainWindow).Handle;

or

HwndSource source = (HwndSource)HwndSource.FromVisual(this);
myWindowHandle = source.Handle;

Then compare whethers it is the ForeGroundWindow:

if (myWindowHandle == GetForegroundWindow()) 
{
  // Do stuff!

}

[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
Cilvic
  • 3,417
  • 2
  • 33
  • 57
  • What if a child window is the foreground window? The application still has focus, but not the main window. – Cameron Aug 23 '11 at 14:52
  • @cameron, true but you figured that much, so sad about the downvote :-) doesn't the criticism apply to the other suggested answers as well? – Cilvic Aug 23 '11 at 15:08
  • I didn't down- or up-vote anyone, but the "activated" answers would work as long as the main window is a parent (or grand-parent) of all the others. – Cameron Aug 23 '11 at 15:13
1

In WPF the easiest way to check if a window is active is:

if(this.IsActive)
{
 //the window is active
}
Shalako Lee
  • 139
  • 1
  • 4
1

Handle the Activated event of your main application Form.

Paul Sasik
  • 79,492
  • 20
  • 149
  • 189