Introduction
In VBA UserForms, there is an “ultimate customization” request where developers want to hide the title bar entirely—including the title text, icon, and the “Close” button (X). This is useful when you want to prevent the user from performing any actions other than clicking specific buttons on the form, making it look like a completely modal dialog box or a custom UI design.
Such modifications to the window style can be achieved by directly calling Windows API functions. In this article, I will explain a highly advanced technique to eliminate the entire title bar by removing the “Has System Menu” attribute from the UserForm’s window style.
VBA Sample Code to Remove the Title Bar
This macro consists of Declare statements, Const (constants), and the form’s _Activate() event procedure. API-related definitions are generally written in a Standard Module.
Step 1: Write API Declarations in a Standard Module
Place the following code in a Standard Module (e.g., Module1). It includes conditional compilation to support both 64-bit and 32-bit environments.
'--- Write in a Standard Module (e.g., Module1) ---
' Compatible with both 64-bit and 32-bit
#If VBA7 Then
Public Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
Public Declare PtrSafe Function GetWindowLongPtr Lib "user32" Alias "GetWindowLongPtrA" (ByVal hwnd As LongPtr, ByVal nIndex As Long) As LongPtr
Public Declare PtrSafe Function SetWindowLongPtr Lib "user32" Alias "SetWindowLongPtrA" (ByVal hwnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
Public Declare PtrSafe Function DrawMenuBar Lib "user32" (ByVal hwnd As LongPtr) As Long
#Else
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Declare Function DrawMenuBar Lib "user32" (ByVal hwnd As Long) As Long
' Set aliases for Ptr functions in 32-bit environment
Public Const SetWindowLongPtr = SetWindowLong
Public Const GetWindowLongPtr = GetWindowLong
#End If
' Constant to retrieve/set window style
Public Const GWL_STYLE As Long = -16
' Style that has a System Menu (Title bar, Close button, etc.)
Public Const WS_SYSMENU As Long = &H80000
Step 2: Write the UserForm Event Procedure
Write this code directly in the UserForm’s code module. We use the Activate event because the window handle is guaranteed to exist when this event fires.
UserForm Code (e.g., BorderlessForm)
' Event executed when the form becomes active
Private Sub UserForm_Activate()
Dim formHandle As LongPtr
Dim currentStyle As LongPtr
' 1. Get the window handle of this form
' "ThunderDFrame" is the class name for VBA UserForms
formHandle = FindWindow("ThunderDFrame", Me.Caption)
If formHandle = 0 Then Exit Sub
' 2. Get the current window style
currentStyle = GetWindowLongPtr(formHandle, GWL_STYLE)
' 3. Remove the System Menu style from the current style
' (Turn off the specific bit using AND logic with NOT WS_SYSMENU)
SetWindowLongPtr formHandle, GWL_STYLE, currentStyle And (Not WS_SYSMENU)
' 4. Redraw the window to apply changes
DrawMenuBar formHandle
End Sub
Explanation of the Code
GetWindowLongPtr and SetWindowLongPtr API
These are the core APIs for manipulating window styles.
GetWindowLongPtr: Retrieves various information (style, extended style, etc.) about the specified window. The argumentGWL_STYLEindicates that we want to retrieve the “basic window style.”SetWindowLongPtr: Sets (changes) the information of the specified window to a new value.
currentStyle And (Not WS_SYSMENU)
The window style is a collection of bit flags that manage the on/off state of various attributes (resizable, has minimize button, etc.).
WS_SYSMENU: A constant representing the attribute “Has System Menu (Title bar, icon, close button).”Not WS_SYSMENU: TheNotoperator inverts the bits of this attribute (ON bits become OFF, OFF bits become ON).currentStyle And (...): Using theAndoperator, we mask thecurrentStyleto forcibly turn OFF (0) only the bits corresponding toWS_SYSMENU.
As a result, a new style value is generated where other styles (such as border type) remain the same, but only the “Has System Menu” attribute is removed. By setting this with SetWindowLongPtr, the title bar becomes hidden.
Important Warning: When the title bar is removed, the user can no longer drag the form to move it or close it using the “Close” button. You must place a CommandButton on the form that executes
Unload Meto allow the user to close the form.
Summary
In this article, I explained a highly advanced customization method to completely remove the UserForm title bar and “Close” button using Windows API.
- Window style information can be manipulated using
GetWindowLongPtrandSetWindowLongPtrAPIs. - The title bar and “Close” button are controlled by the
WS_SYSMENUwindow style attribute. - You can remove the title bar by turning off this attribute using bitwise operations (
AndandNot).
This technique is effective when you want to give your application a unique UI design or strictly limit user operations. However, use it carefully with a clear intent, as it removes standard usability features like moving the window.
