Determine If Current Application Is Activated (Has Focus)

Determine if current application is activated (has focus)

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

How to determine whether my application is active (has focus)

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

Check if Form has focus or is active

if (Form.ActiveForm != yourform)
{
//form not active
//do something
}
else
{
// form active
// do something
}

How can I check which program is in focus?

You're comparing an IntPtr returned by GetForegroundWindow() to an Process[].
As the name suggests, Process.GetProcessesByName can return multiple processes and as such you'll need to treat it as an array.

Save Process.GetProcessesByName("Hearthstone") into a variable, and iterate over each entry to see if it is the one that's focused.
Also, you assume that the handle is the process ID; which probably isn't the case. The following code is untested.

...
var processes = Process.GetProcessesByName("Hearthstone");
foreach(Process p in processes) {
if(activedHandle == p.Handle) {
//A instance of the process Hearthstone is currently focused.
...
} else {
...
}
}

C#: Detecting which application has focus

Take a look at Application.AddMessageFilter, and look for WM_ACTIVATEAPP messages, which will tell you when an app is activated, i.e. receives focus.

Check if window has focus

var has_focus = true;

function loading_time() {
$(":focus").each(function() {
if($(this).attr("id")=="iframeID") has_focus = true;
});

if(has_focus==true) alert('page has focus');
else alert('page has not focus');

setTimeout("loading_time()", 2000);
}

window.onblur = function(){
has_focus=false;
}
window.onfocus = function(){
has_focus=true;
}

$(window).load(function(){
setTimeout("loading_time()", 2000);
});

To make it more efficient, you need to var has_focus = false; and make the user click somewhere on the page.

How do I check if a certain process has focus?

You can determine this quite easily using the GetForegroundWindow() and GetWindowThreadProcessId() WinAPI functions.

First call GetForegroundWindow to get the window handle of the currently focused window, then call GetWindowThreadProcessId in order to retrieve the process id of that window. Finally get it as a Process class instance by calling Process.GetProcessById()

Public NotInheritable Class ProcessHelper
Private Sub New() 'Make no instances of this class.
End Sub

<DllImport("user32.dll", SetLastError:=True)> _
Private Shared Function GetForegroundWindow() As IntPtr
End Function

<DllImport("user32.dll", SetLastError:=True)> _
Private Shared Function GetWindowThreadProcessId(ByVal hWnd As IntPtr, ByRef lpdwProcessId As UInteger) As Integer
End Function

Public Shared Function GetActiveProcess() As Process
Dim FocusedWindow As IntPtr = GetForegroundWindow()
If FocusedWindow = IntPtr.Zero Then Return Nothing

Dim FocusedWindowProcessId As UInteger = 0
GetWindowThreadProcessId(FocusedWindow, FocusedWindowProcessId)

If FocusedWindowProcessId = 0 Then Return Nothing
Return Process.GetProcessById(CType(FocusedWindowProcessId, Integer))
End Function
End Class

Usage example:

Dim ActiveProcess As Process = ProcessHelper.GetActiveProcess()

If ActiveProcess IsNot Nothing AndAlso _
String.Equals(ActiveProcess.ProcessName, "javaw", StringComparison.OrdinalIgnoreCase) Then
MessageBox.Show("A 'javaw.exe' process has focus!")
End If

Hope this helps!

Determine if document ACTUALLY has focus

It is possible only using WinAPI.

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

bool WordHasFocus {
get {
IntPtr wordHandle = Process.GetCurrentProcess().MainWindowHandle;
IntPtr focusedWindow = GetForegroundWindow() ;
return wordHandle == focusedWindow;
}
}

It shows you only that word has focus. If you want to check about given document, you additionally need to ensure that given document is active document.

How can I determine when my application's console window gets or loses focus?

If the window you were interested in were not a console window, this would have been very simple to do by just tapping into the appropriate focus event. But console windows don't have focus events, so the easy way out is not available here.

What you can do is set up an event handler to receive WinEvents generated by the UI Automation services. An event is generated whenever the window focus changes; you can get the HWND of the newly focused window and compare it to that of your console window. If they match, you just got focus; if they don't, you don't have focus (either just lost it or never had it to begin with).

The most convenient way to tap into UI Automation is through the System.Windows.Automation namespace. You can set up the event handler with AddAutomationFocusChangedEventHandler, which will give you an instance of AutomationFocusChangedEventArgs from which you can determine which window has received focus.

Here's some sample code:

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

where OnFocusChange is:

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

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

Note that I am assuming the console is your process's main window for simplicity; if that's not the case, you need to get a HWND to the console window some other way.

Also note that in order to receive automation events, your process must be running a message loop (in this case also known as a "dispatcher loop"), which in turn requires a thread being dedicated to running it. In the example above this happens automatically when MessageBox.Show is called, but in the general case you will have to take proper care of it.

Detect when none of app windows is active/focused

Form has a ContainsFocus property that indicates whether the form, or one of its child controls has the input focus. You can check this property for all open forms to detect if the application contains focus or not:

var isActive = Application.OpenForms.Cast<Form>().Any(x=>x.ContainsFocus);

Also as another option:

var isActive = (Form.ActiveForm != null)

If you want to be notified of the state of the application you can handle Activate and Deactivate event of your forms for all forms.

private void f_Deactivate(object sender, EventArgs e)
{
BeginInvoke(new Action(() =>
{
if (Form.ActiveForm == null)
Text = "App Deactivated.";
else
Text = "Still Active";
}));
}


Related Topics



Leave a reply



Submit