tags:

views:

47

answers:

1

I've written a c# application which automates an instance of IE. I'd like to know when internet explorer gains focus and when it looses focus.

From the SHDocVw.InternetExplorer object I can get it's HWND. From there how can I create a message hook to receive WM_KILLFOCUS and WM_FOCUS events (assuming those are the correct events to be listening for :))?

Thanks everyone!!

UPDATE: I found a way I could use to accomplish the above goal without using hooks (which I haven't quite figured out how to do in c# yet), using the .NET framework in this question.

The problem with this code

    AutomationFocusChangedEventHandler focusHandler 
       = new AutomationFocusChangedEventHandler(OnFocusChanged);
    Automation.AddAutomationFocusChangedEventHandler(focusHandler);

is that it is easy for a window to be the foreground window and that event won't fire when that window is switched to because it's waiting for a specific UI Element to be in focus. (To test this you can use a function that uses that code and prints a message everytime a new window is in focus, such as the MSDN sample TrackFocus, and then click on a webbrowser. When most webpages or a blank page is being displayed in the browser the event wont fire until the address bar or some other element is selected.) It could probably work if there was a way to modify so that it could throw the event if either no UI Element is in focus or every time an element lost focus (instead being thrown when it gains focused). Anyone have any ideas on how I could fix the above code to solve my problem?

Update 2: I just came across this (article claims you can only hook to mouse and keyboard from c#) as well which may mean I can't use hooks at all for what I'd like to do.

+1  A: 

Detailed instructions on setting up a hook from C# are here: http://support.microsoft.com/kb/318804/en-us?fr=1

CesarGon
Thanks! Am I right to assume that by following those instructions and setting up the hook I'll be able to listen for WM_KILLFOCUS and WM_FOCUS to determine when that window is in focus?
Evan
Well, I haven't tried the code myself, but I have implemented hooks from C# in the past successfully. Give it a try and let us know how it goes. Good luck!
CesarGon
OK I've gone through your example and have a better understanding of hooks - at least event hooking to windows in my application. What I need to do and am still stumped on though, is create a hook to another application. To do that can I just use SetWindowsHookEx with the handle and threadid of another window? I've been searching and I've seen a lot of people say you need to create a separate dll? Thanks!!
Evan
Yes. If you want to install a hook on a thread of another process, the hook procedure (i.e. the function that "listens" to the hook) must reside in a DLL. It doesn't need to be a *separate* DLL; it can be a DLL that is part of your app, as long as it is a DLL that can be loaded and dynamically linked by the target app. Have a look at this: http://msdn.microsoft.com/en-us/library/ms644959(v=VS.85).aspx
CesarGon
I put the MouseHookProc function in a dll and referenced the dll with my project (all in c#). I try to set the hook (inside my main program, not the dll) by passing the handle to IE and a thread id of 0. It's still failing to create the hook. Any ideas? Thanks again for all of your help.
Evan
DOn't use 0 as the thread id; that would attempt to install a global hook for all the threads in the desktop, which is not supported under .NET. You need to pass on the thread id that you want to target.
CesarGon