Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Control in Focus in Other Processes

0.00/5 (No votes)
1 Apr 2009 1  
Retrieve the hWnd of focused controls in other applications.

FocusedControlInOtherProcess

Introduction

This article will describe how you can retrieve the unique handle of any focusable control in any Windows application by simply focusing it. We will do this through a series of P/Invokes to the Win32 API in user32.dll.

Background

People using the Win32 API function GetFocus may have noticed that it will only return the handle (hWnd) of controls in your own application, and if you try focusing in another process, you will get NULL. This is because GetFocus only returns the window with the keyboard focus for the current thread's message queue. And, since our application is not in the same thread, you will get nothing.

Using the code

To get the currently focused control hWnd in another process, we can attach our thread's message queue to a window in another thread, using the AttachThreadInput function.

This is how it's done:

  1. Use the GetForegroundWindow function to get the window with which the user is currently working.
  2. Use the GetWindowThreadProcessId function to get the ID of both this window and yours.
  3. Use the AttachThreadInput function to temporarily associate your thread's message queue with the thread owning the other window.
  4. Use the GetFocus function to get the hWnd!
  5. Use the AttachThreadInput function again to disconnect from the other thread.
using System.Runtime.InteropServices;

public partial class FormMain : Form
{
    [DllImport("user32.dll")]
    static extern IntPtr GetForegroundWindow();

    [DllImport("user32.dll")]
    static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId);

    [DllImport("user32.dll")]
    static extern IntPtr AttachThreadInput(IntPtr idAttach, 
                         IntPtr idAttachTo, bool fAttach);

    [DllImport("user32.dll")]
    static extern IntPtr GetFocus();

    public FormMain()
    {
        InitializeComponent();
    }

    private void timerUpdate_Tick(object sender, EventArgs e)
    {
        labelHandle.Text = "hWnd: " + 
                           FocusedControlInActiveWindow().ToString();
    }

    private IntPtr FocusedControlInActiveWindow()
    {
        IntPtr activeWindowHandle = GetForegroundWindow();

        IntPtr activeWindowThread = 
          GetWindowThreadProcessId(activeWindowHandle, IntPtr.Zero);
        IntPtr thisWindowThread = GetWindowThreadProcessId(this.Handle, IntPtr.Zero);

        AttachThreadInput(activeWindowThread, thisWindowThread, true);
        IntPtr focusedControlHandle = GetFocus();
        AttachThreadInput(activeWindowThread, thisWindowThread, false);

        return focusedControlHandle;
    }
}

Requirements for the code, which can be done with the Visual Studio designer:

  • Add a timer with the name timerUpdate and add the timerUpdate_Tick method to the Tick event. Set Interval to 100 and Enabled to true.
  • Add a Label to the form with the name labelHandle.
  • Set FormMain's TopMost property to true.

History

  • 1.0 (1 April 2009) - Initial release.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here