Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET/Win32 - event to detect when a window belonging to another app gets focus

Tags:

.net

winapi

I have a .NET application that needs to be able to detect when a specific window gets and loses focus. The specific window i'm interested in belongs to another application that I have no control over, although I do have the Window Handle.

I'm really after the best way to tackle this. So far, I can see 2 possibilities:

  1. Using a Win32 call on a timer to monitor for any changes in state. Not great, as it runs the risk of missing state changes e.g. if the window becomes active then inactive within the timer interval
  2. Using hooks (SetWindowsHookEx) to intercept the messages to the window. Sounds like it should work, but concerned that a) global-level hooks wont work from .NET code, so would need to be native and b) could this be considered virus/keylogger-type activity, so blocked by the OS?

I'm sure there are other options too, if so, i'd love to hear them!

like image 773
Paul Nearney Avatar asked Aug 22 '11 17:08

Paul Nearney


1 Answers

Simplest way is likely to use SetWinEventHook, listening for EVENT_SYSTEM_FOREGROUND events. You need to use it with the WINEVENT_OUTOFCONTEXT flag to use it in .net: when you use this flag, Windows routes the notifications back to your own process, so you don't need a separate unmanaged DLL. Note however that the code that calls this method must have a message loop running.

Quick note on how this relates to the article mentioned in the other answer: that article focuses on the SetWindowsHook API. SetWinEventHook is a separate API, but you use the same technique to set up the P/Invoke call, and to set up a delegate for the callback - though note that the two APIs use different parameters in both the API calls themselves and in the callbacks. The main advantage that SetWinEventHook has over SetWindowsHook is that for some types of hooks, SetWindowsHook requires the use of a separate unmanaged DLL, which you can't do directly in .net. SetWinEventHook however allows either type of callback, using either a separate unmanaged DLL or notifying the original process without requiring a DLL, so is more .net-friendly.

like image 158
BrendanMcK Avatar answered Sep 27 '22 22:09

BrendanMcK