Get the title of the active window

Max picture Max · Feb 21, 2013 · Viewed 8.9k times · Source

I have declared the following WinAPI calls

<DllImport("USER32.DLL", EntryPoint:="GetActiveWindow", SetLastError:=True,
    CharSet:=CharSet.Unicode, ExactSpelling:=True,
    CallingConvention:=CallingConvention.StdCall)>
Public Shared Function GetActiveWindowHandle() As System.IntPtr
End Function

<DllImport("USER32.DLL", EntryPoint:="GetWindowText", SetLastError:=True,
    CharSet:=CharSet.Unicode, ExactSpelling:=True,
    CallingConvention:=CallingConvention.StdCall)>
Public Shared Function GetActiveWindowText(ByVal hWnd As System.IntPtr, _
                                            ByVal lpString As System.Text.StringBuilder, _
                                            ByVal cch As Integer) As Integer
End Function

Then, I call this subroutine to get the text in the active window's title bar

Public Sub Test()
    Dim caption As New System.Text.StringBuilder(256)
    Dim hWnd As IntPtr = GetActiveWindowHandle()
    GetActiveWindowText(hWnd, caption, caption.Capacity)
    MsgBox(caption.ToString)
End Sub

Finally, I get the following error

Unable to find an entry point named 'GetWindowText' in DLL 'USER32.DLL'

How can I fix this issue?

Answer

Hans Passant picture Hans Passant · Feb 21, 2013
<DllImport("USER32.DLL", EntryPoint:="GetWindowText", SetLastError:=True,
    CharSet:=CharSet.Unicode, ExactSpelling:=True,

You insisted on ExactSpelling. Which is the problem, there are two versions of GetWindowText exported by user32.dll. GetWindowTextA and GetWindowTextW. The A version uses an ansi string, a legacy string format with 8-bit characters encoded in the default code page that was last used in Windows ME. The W version uses a Unicode string, encoded in utf-16, the native Windows string type. The pinvoke marshaller will try either of them, based on the CharSet but you stopped it from doing so by using ExactSpelling := True. So it cannot find GetWindowText, it doesn't exist.

Either use EntryPoint := "GetWindowTextW" or drop ExactSpelling.