Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / VB12

C# / VB.NET and WinAPI: How to Access Window of Other Application

4.74/5 (17 votes)
30 Jan 2015CPOL2 min read 107.9K   2.3K  
Using FindWindow() and WindowFromPoint() to identify window, and SetWindowText(), MoveWindow(), SetForegroundWindow(), EnableWindow() to interact with it

How to Access ANY Window

Unfortunately, you can't use .NET to access other application windows. But you can use in your .NET application more lower-level library - Windows API (WinAPI).

Absolutely any window on Windows creating and managing by a set of libraries WinAPI. High-level object-oriented libraries, such as Winforms, MFC, Qt (in Windows version) are just high-level covers for WinAPI. No matter what framework you use. In any case, you can access windows using WinAPI.

WinAPI isn't an object-oriented library. Therefore, it uses numerical identifiers for "objects", e.g. windows and others. Any window has a unique numerical identifier (handle) which is generated by the system accidentally when it creates. This identifier is hWnd (handle of window) and represents a certain long value (or, what equivalent in .NET, a IntPtr value). This identifier does not change throughout all life of the window - until it is closed and a new window created.

You can import from WinAPI library "user32.dll" any function to work with windows and access ANY window by using its hWnd.

For example (SetWindowText() function changes window title to custom text):

C#
C#
using System.Runtime.InteropServices; // to other usings
...
// into class, not method
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool SetWindowText(IntPtr hWnd, String lpString);
...
// or long-value version
// [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
// public static extern bool SetWindowText(long hWnd, String lpString);
...
IntPtr hWnd = ...; // any window's hWnd
//or long hWnd = ...;      // any window's hWnd

SetWindowText(hWnd, "Lorem ipsum");
VB.NET
VB.NET
Imports System.Runtime.InteropServices ' to other imports
...
' into class, not method
<DllImport("user32.dll", SetLastError := True, CharSet := CharSet.Auto)> _
Public Shared Function SetWindowText(hWnd As IntPtr, lpString As String) As Boolean
End Function
...
' or long-value version
' <DllImport("user32.dll", SetLastError := True, CharSet := CharSet.Auto)> _
' Public Shared Function SetWindowText(hWnd As Long, lpString As String) As Boolean
' End Function
...
Dim hWnd As IntPtr = ... ' any window's hWnd
//or Dim hWnd As Long = ...    ' any window's hWnd

SetWindowText(hWnd, "Lorem ipsum")

Optionally, you can use your form's hWnd:

C#
C#
IntPtr hWnd = this.Handle;
VB.NET
VB.NET
Dim hWnd As IntPtr = Me.Handle

How to Get hWnd of Needed Window?

There are at least 3 methods - and all also using WinAPI:

1. Get hWnd by window's title text using WinAPI FindWindow function.

C#
C#
using System.Runtime.InteropServices;
...
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
..
//MoveWindow changes window's top, left, width and height...
//...even if it do not want to change their dimensions and haves fixed edges!
[DllImport("user32.dll", SetLastError = true)]
static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
...
IntPtr hWnd = FindWindow(null, "Calculator"); // Calculator is Windows calc title text
MoveWindow(hWnd, 100, 200, 300, 400, true);
VB.NET
VB.NET
Imports System.Runtime.InteropServices
...
<DllImport("user32.dll", SetLastError := True)> _
Private Shared Function FindWindow(lpClassName As String, lpWindowName As String) As IntPtr
End Function
...
'MoveWindow changes window's top, left, width and height...
'...even if it do not want to change their dimensions and haves fixed edges!
<DllImport("user32.dll", SetLastError := True)> _
Private Shared Function MoveWindow(hWnd As IntPtr, X As Integer, Y As Integer, _
    nWidth As Integer, nHeight As Integer, bRepaint As Boolean) As Boolean
End Function
...
Dim hWnd As IntPtr = FindWindow(Nothing, "Calculator") ' Calculator is Windows calc title text
MoveWindow(hWnd, 100, 200, 300, 400, True)

2. Get hWnd by window at point of screen using WinAPI WindowFromPoint function.

Warning: Point coordinates must compare with window's frame, not client area!

C#
C#
using System.Runtime.InteropServices;
...
[DllImport("user32.dll")]
static extern IntPtr WindowFromPoint(int xPoint, int yPoint);
...
// SetForegroundWindow brings window to front
[DllImport("user32.dll")]
static extern bool SetForegroundWindow(IntPtr hWnd);
...
IntPtr hWnd = WindowFromPoint(100, 100); // X, Y
SetForegroundWindow(hWnd);
VB.NET
VB.NET
Imports System.Runtime.InteropServices
...
<DllImport("user32.dll")> _
Private Shared Function WindowFromPoint(xPoint As Integer, yPoint As Integer) As IntPtr
End Function
...
' SetForegroundWindow brings window to front
<DllImport("user32.dll")> _
Private Shared Function SetForegroundWindow(hWnd As IntPtr) As Boolean
End Function
...
Dim hWnd As IntPtr = WindowFromPoint(100, 100) ' X, Y
SetForegroundWindow(hWnd)

3. Get hWnd by window's class name using WinAPI FindWindow function.

Window does not have hWnd (long) identifier only. It also has a string identifier, class name. Class name (class) is a permanent identifier. It does not change when window recreates. It is not generated randomly, it is not given by programmer.

First, you can get any window class name by using WinAPI GetClassName function.

Next, you can use this class name in your application to accurately identify this window.

C#
C#
using System.Runtime.InteropServices;
...
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
...
// Disables or enables window!!!
[DllImport("user32.dll")]
static extern bool EnableWindow(IntPtr hWnd, bool bEnable);
...
IntPtr hWnd = FindWindow("Notepad", null); // Notepad - class name of Windows Notepad
EnableWindow(hWnd, false);
VB.NET
VB.NET
Imports System.Runtime.InteropServices
...
<DllImport("user32.dll", SetLastError := True)> _
Private Shared Function FindWindow(lpClassName As String, lpWindowName As String) As IntPtr
End Function
...
' Disables or enables window!!!
<DllImport("user32.dll")> _
Private Shared Function EnableWindow(hWnd As IntPtr, bEnable As Boolean) As Boolean
End Function
...
Dim hWnd As IntPtr = FindWindow("Notepad", Nothing) ' Notepad - class name of Windows Notepad
EnableWindow(hWnd, False)

References for Other WinAPI Functions and Interfaces

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)