はじめに
VBAのユーザーフォームで、ユーザーにフォーム上のボタン以外の操作を一切させたくない場合、タイトルバー自体(タイトル、アイコン、「閉じる」ボタンを含む全て)を非表示にしたい、という究極のカスタマイズ要求があります。これにより、フォームを完全にモーダルなダイアログボックスのように見せたり、独自のUIデザインに近づけたりすることが可能になります。
このようなウィンドウ自体のスタイル変更は、Windows API関数を直接呼び出すことで実現できます。この記事では、ユーザーフォームのウィンドウスタイルから「システムメニューを持つ」という属性を削除することで、タイトルバー全体を消去する、非常に高度なテクニックを解説します。
タイトルバーを消去するVBAサンプルコード
このマクロは、Declare
ステートメント、Const
(定数)、およびフォームの _Activate()
イベントプロシージャで構成されます。API関連の定義は、標準モジュールに記述するのが一般的です。
ステップ1: API宣言を標準モジュールに記述
'--- 標準モジュール (例: Module1) に記述 ---
' 64bit/32bit両対応
#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
' 32bit環境ではPtr系関数のエイリアスを設定
Public Const SetWindowLongPtr = SetWindowLong
Public Const GetWindowLongPtr = GetWindowLong
#End If
' ウィンドウスタイルを取得/設定するための定数
Public Const GWL_STYLE As Long = -16
' システムメニュー(タイトルバー、閉じるボタンなど)を持つスタイル
Public Const WS_SYSMENU As Long = &H80000
ステップ2: ユーザーフォームのイベントプロシージャを記述
このコードは、ユーザーフォームのコードモジュールに直接記述します。ウィンドウの存在が確実な Activate
イベントを使用します。
【ユーザーフォーム: BorderlessForm
】
' フォームがアクティブになったときに実行されるイベント
Private Sub UserForm_Activate()
Dim formHandle As LongPtr
Dim currentStyle As LongPtr
' 1. このフォームのウィンドウハンドルを取得
formHandle = FindWindow("ThunderDFrame", Me.Caption)
If formHandle = 0 Then Exit Sub
' 2. 現在のウィンドウスタイルを取得
currentStyle = GetWindowLongPtr(formHandle, GWL_STYLE)
' 3. 現在のスタイルから、システムメニュースタイルを削除
' (Not WS_SYSMENU との And演算で、該当ビットをオフにする)
SetWindowLongPtr formHandle, GWL_STYLE, currentStyle And (Not WS_SYSMENU)
' 4. ウィンドウの変更を再描画して適用
DrawMenuBar formHandle
End Sub
コードの解説
GetWindowLongPtr
と SetWindowLongPtr
API
これらが、ウィンドウスタイルを操作する核心的なAPIです。
GetWindowLongPtr
: 指定したウィンドウの様々な情報(スタイル、拡張スタイルなど)を取得します。引数GWL_STYLE
は、「基本的なウィンドウスタイルを取得したい」ということを示します。SetWindowLongPtr
: 指定したウィンドウの情報を新しい値に設定(変更)します。
currentStyle And (Not WS_SYSMENU)
ウィンドウスタイルは、様々な属性(サイズ変更可能、最小化ボタンを持つなど)のオン/オフを管理するビットフラグの集合体です。
WS_SYSMENU
: 「システムメニュー(タイトルバー、アイコン、閉じるボタン)を持つ」という属性を表す定数です。Not WS_SYSMENU
:Not
演算子で、この属性のビットを反転させます(オンのビットがオフに、オフのビットがオンになります)。currentStyle And (...)
:And
演算子を使って、現在のスタイルcurrentStyle
から、WS_SYSMENU
の属性ビットだけを強制的にオフ(0)にします。
結果として、他のスタイル(枠線の種類など)はそのままに、「システムメニューを持つ」という属性だけが取り除かれた、新しいスタイル値が生成されます。これを SetWindowLongPtr
で設定することで、タイトルバーが非表示になります。
注意点
タイトルバーを消去すると、ユーザーはフォームをマウスでドラッグして移動させたり、「閉じる」ボタンで閉じたりすることができなくなります。必ず、フォーム上にフォームを閉じるためのコマンドボタン(Unload Me
を実行するボタン)を配置しておく必要があります。
まとめ
今回は、Windows APIを駆使して、ユーザーフォームのタイトルバーと「閉じる」ボタンを完全に消去する、非常に高度なカスタマイズ方法を解説しました。
- ウィンドウのスタイル情報は、
GetWindowLongPtr
とSetWindowLongPtr
APIで操作できる。 - タイトルバーや「閉じる」ボタンは、
WS_SYSMENU
というウィンドウスタイル属性によって制御されている。 - ビット演算(
And
とNot
)を使って、この属性だけをオフにすることで、タイトルバーを消去できる。
このテクニックは、アプリケーションのUIを独自のデザインにしたい場合や、ユーザーの操作を極限まで制限したい場合に有効ですが、標準的な操作性を損なう可能性もあるため、明確な意図を持って慎重に利用しましょう。