[VBA] How to Completely Remove the UserForm Title Bar and “Close” Button

目次

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 argument GWL_STYLE indicates 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.).

  1. WS_SYSMENU: A constant representing the attribute “Has System Menu (Title bar, icon, close button).”
  2. Not WS_SYSMENU: The Not operator inverts the bits of this attribute (ON bits become OFF, OFF bits become ON).
  3. currentStyle And (...): Using the And operator, we mask the currentStyle to forcibly turn OFF (0) only the bits corresponding to WS_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 Me to 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 GetWindowLongPtr and SetWindowLongPtr APIs.
  • The title bar and “Close” button are controlled by the WS_SYSMENU window style attribute.
  • You can remove the title bar by turning off this attribute using bitwise operations (And and Not).

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.

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次