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
It Is Possible to Copy All the Properties of a Certain Control? (C# Window Forms)
How to Draw a Rounded Rectangle as the Border for a Rounded Form
Convert Linq Query Result to Dictionary
.Net Timezoneinfo from Olson Time Zone
Why Does the Lock Object Have to Be Static
How to Specify a Generic Type in Xaml (Pre .Net 4 Framework)
Suppress Warning Cs1998: This Async Method Lacks 'Await'
How to Set Conditional Breakpoints in Visual Studio
How to Conditionally Compile My C# for Mono VS. Microsoft .Net
How to Forcefully Propagate Role Changes to Users with ASP.NET Identity 2.0.1
Count the Number of Times a String Appears Within a String
Display Unicode Characters in Converting HTML to PDF
Duck Typing in the C# Compiler