[VBA × Windows API] How to Use the GetClassName Function
GetClassName Function
The GetClassName function retrieves the class name of a specified window.
A window class name is an identifier used to tell different kinds of windows apart, and each application registers its own. Looking at the class name alone is enough to know “which application created this window."
The class names of applications most commonly targeted from VBA are listed below.
| Application | Window class name |
| Excel | XLMAIN |
| PowerPoint | PPTFrameClass |
| Word | OpusApp |
| Notepad | Notepad |
| File Explorer | CabinetWClass |
| UserForm | ThunderDFrame |
In VBA, window class names are most often used together with FindWindow when you want to search for a window that belongs to a specific application. GetClassName is the function that answers the question, “What class name does this application’s window have?"
Strictly speaking a UserForm isn’t an application of its own, but as the table shows it always has the class name "ThunderDFrame" — and that is true regardless of whether the UserForm was created in Excel, PowerPoint, Access, or any other VBA host.
If you need to figure out which application a particular UserForm was created in, the trick is to first call GetParent to obtain the UserForm’s parent window, and then call GetClassName on that parent. The parent’s class name will tell you which application owns the UserForm.
Usage
Before calling GetClassName, you must declare it at the top of your module.
Without the declaration the function cannot be used and will raise an error, so don’t forget it.
The declaration differs depending on whether your Office/VBA host is 32-bit or 64-bit. Place one of the following near the top of your module (just after Option Explicit) to make the function available inside that module.
Declare PtrSafe Function GetClassName Lib “user32" Alias “GetClassNameA" _
(ByVal hwnd As LongPtr, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Declare Function GetClassName Lib “user32" Alias “GetClassNameA" _
(ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
If you are not sure which one to use, paste the following block at the top of your module. It automatically selects the correct declaration at compile time.
In the VBE, the unused branch may be shown in red, but this does not affect execution.
#If VBA7 Then
Declare PtrSafe Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As LongPtr, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
#Else
Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
#End If
You can also prefix the declaration with Private or Public to control its scope.
・Public Declare PtrSafe Function … : callable from outside the module
Syntax
The syntax of the GetClassName function is as follows.
lRet = GetClassName(hWnd, lpClassName, nMaxCount)
Arguments
hWnd (64-bit: LongPtr / 32-bit: Long)
Handle to the window whose class name you want.
There are several APIs that can produce a window handle, including FindWindow, GetActiveWindow, GetNextWindow, and GetParent.
lpClassName (String)
An empty fixed-length string that the API will write the class name into.
In VBA, String variables are normally variable-length, so “fixed-length string" might sound unfamiliar. The difference is exactly what the name suggests: a fixed-length string has a predetermined size — that is, a fixed number of characters it can hold.
To declare a fixed-length string in VBA, use the form Dim x As String * 7. With that declaration the variable can hold at most 7 characters; if you assign a shorter string, the remainder is padded with null/space characters to fill all 7 slots.
So for this argument, you simply declare a fixed-length string large enough to hold the entire class name and pass it in. If the buffer is too small, the retrieved class name may be truncated, so make it generous. (A length of about 100 characters is enough for almost any class name.)
nMaxCount (Long)
The maximum number of characters of the class name to copy.
As with lpClassName, setting this too small can truncate the result, so make it generous. The common idiom in VBA is to call Len on the fixed-length buffer and pass that value here.
Return value
lRet (Long)
On success, the return value is the number of characters actually copied to the buffer.
(Note: multi-byte / full-width characters can be counted as 2 characters each, so the return value may not equal the number of “visible" characters.)
On failure, the return value is 0.
Sample Code
The sample below combines FindWindow with GetClassName to retrieve the class name of a specific window. As written, it returns the class name of the window whose caption is “Command Prompt." By replacing the caption string you can look up the class name of any other window.
Declare PtrSafe Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As LongPtr, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
Sub main()
Dim hwnd As LongPtr
Dim lRet As LongPtr
Dim sBuf As String * 100
Dim sCls As String
' Get the Command Prompt window handle
hwnd = FindWindow(vbNullString, "Command Prompt")
' Get the class name of that handle (into a fixed-length string)
lRet = GetClassName(hwnd, sBuf, Len(sBuf))
' Trim the unused buffer part
sCls = Left(sBuf, CLng(lRet))
' Print the retrieved class name to the Immediate window
Debug.Print sCls
End Sub
The most important line in this sample is the one labelled “Trim the unused buffer part."
After GetClassName returns, the fixed-length buffer sBuf holds the window’s class name — but if you inspect it in the VBE Locals window, you’ll see a trail of mysterious “・" characters padding the end. Those “・" characters are vbNullChar in VBA.
Before using the value, you need to strip those padding null characters. There are several ways to do it; in this sample we use the return value (the character count) directly with Left to slice off only the meaningful portion of the buffer.
Note that, as mentioned above, full-width characters can throw off the character count returned by GetClassName. If your class name might contain such characters, an alternative is to take “everything to the left of the first vbNullChar" — the same pattern shown on the GetWindowText page.
VBA × Windows API Index
For other Windows API functions, please also refer to the index page below.
Reference
Microsoft official: GetClassName function (winuser.h) — Win32 apps


![[VBA Extensions] Complete Guide to Calling the Windows API from VBA](https://liclog.net/wp-content/uploads/2023/07/24b09ec528d00f75524f52dc8477a1f8-100x100.png?is-pending-load=1)





