【VBA×WindowsAPI】UserFormに最大化・最小化・サイズ可変の情報を設定する
VBAのUserFormは通常のウィンドウとは違い、拡大/縮小や最大化/最小化といったウィンドウサイズの変更をすることはできません。このときWindowsAPIを使うことで通常のウィンドウと同じように最大化/最小化ボタンを付与したり、サイズをドラッグで変更できるようにしたりすることができます。
内容は少し難しく感じるかもしれませんがUserFormサイズの可変化はサンプルコードのコピペだけで実現可能なので、コードの内容はどうでもいいという場合でもすぐに実装できるようになっています。
UserFormに最大化・最小化・サイズ可変の情報を設定
UserFormはデフォルトではウィンドウの境界をドラッグしてサイズを拡張したり、タイトルバーに最小化、最大化ボタンは付与されていませんが、WindowsAPIを使うことで上画像のようにウィンドウサイズの可変や最小化/最大化のボタンを設定することが可能になります。
Windowsのウィンドウはウィンドウスタイルという、そのウィンドウの見た目や振る舞いが定義された内部的な情報を持っています。VBAのUserFormのデフォルト時のウィンドウスタイルは下画像の通りで、たとえば「WS_CAPTION」はタイトルバーが有ることを表し、「WS_VISIBLE」は画面上に表示されていることを表します。(その他のスタイルについてはウィンドウスタイルを参照下さい)
このとき、ウィンドウサイズが可変であるかや最小化/最大化ボタンを含むかもこのウィンドウスタイルに含まれます。つまり、現在のウィンドウスタイルを取得した後、ウィンドウサイズの可変、最小化/最大化ボタンのスタイルを追加することでUserFormにそれら機能を実装させることが出来ます。
VBAでUserFormに最大化・最小化・サイズ可変のウィンドウスタイルを設定するには下記のWindows APIを利用します。それぞれ関数のより詳細な使い方の解説は各関数のリンクページを参照下さい。
FindWindow関数 :指定のウィンドウのハンドルを取得する
GetWindowLongPtr関数 :指定されたウィンドウに関する情報を取得する
SetWindowLongPtr関数 :指定されたウィンドウの属性を変更する
「そもそもWindows APIって何?」という方はコチラ(メインページ)も併せて参照下さい。
UserForm可変化サンプルコード
下記はUserFormに最小化/最大化ボタンを付与してウィンドウサイズの可変を可能にするためのサンプルコードです。UserForm上にはほとんどの場合、コントロールが存在するためサンプルコードでは上画像のようにウィンドウのサイズにコントロールが追従する内容も実装されています。下記コード記載のUserFormに対して「UserForm.Show vbModeless」を実行することで設定を施した状態にして起動することができます。(※予めUserForm上にCommandButtonを作成しておく必要があります)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
Option Explicit Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr Private Declare PtrSafe Function GetWindowLongPtr Lib "user32" Alias "GetWindowLongPtrA" (ByVal hWnd As LongPtr, ByVal nIndex As Long) As LongPtr Private Declare PtrSafe Function SetWindowLongPtr Lib "user32" Alias "SetWindowLongPtrA" (ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr Private Declare PtrSafe Function DrawMenuBar Lib "user32" (ByVal hWnd As LongPtr) As Long Private Const GWL_STYLE = -16 Private Const WS_MAXIMIZEBOX = &H10000 '最大化ボタン Private Const WS_MINIMIZEBOX = &H20000 '最小化ボタン Private Const WS_THICKFRAME = &H40000 'サイズ可変 Private Sub UserForm_Initialize() Dim hWnd As LongPtr Dim hStyle As LongPtr 'ウィンドウハンドル取得 hWnd = FindWindow("ThunderDFrame", Me.Caption) 'ウィンドウスタイル取得 hStyle = GetWindowLongPtr(hWnd, GWL_STYLE) 'ウィンドウスタイルにサイズ可変,最大化ボタン,最小化ボタン情報を付与 hStyle = hStyle Or WS_THICKFRAME Or WS_MAXIMIZEBOX Or WS_MINIMIZEBOX 'ウィンドウスタイルを適用 Call SetWindowLongPtr(hWnd, GWL_STYLE, hStyle) End Sub Private Sub UserForm_Resize() 'CommandButtonサイズの追従(If文はサイズが0以下になる発生するエラー対策) If Me.width > 100 Then Me.CommandButton1.width = Me.width - 40 If Me.height > 100 Then Me.CommandButton1.height = Me.height - 55 End Sub |
コード解説
UserFormのウィンドウハンドルを取得
ウィンドウにはそれぞれウィンドウハンドルと呼ばれる、ウィンドウを識別するためのID情報のようなものが付与されています。このウィンドウハンドルを取得することで、”どの”ウィンドウに対して処理を行うのかを簡単に指示することができます。(Windows APIでは頻出ワードです)
UserFormもウィンドウの1つであるため一意のウィンドウハンドルを持ちます。ウィンドウハンドルを取得するための関数はいくつも存在しますがここでは常套手段のFindWindow関数を使ってウィンドウハンドルを取得しています。FindWindow関数は下記のように記載することで指定のクラス名もしくはウィンドウ名から該当のウィンドウへのハンドルを取得することができます。
hWnd = FindWindow(“クラス名”, “ウィンドウ名”)
UserFormはクラス名が”ThunderDFrame”で、ウィンドウ名はMe.Captionとなります。いずれか片方を入力してもう一方の引数をvbNullStringとしても取得可能ですが、サンプルコードではどちらの引数も入力して確実にUserFormが取得できるようにしています。
ウィンドウスタイルの取得
UserFormのウィンドウハンドルが取得できたらそのハンドルからウィンドウスタイルを取得します。ウィンドウスタイルはGetWindowLongPtr関数を使い下記のように記載します。
hStyle = GetWindowLongPtr(hWnd, GWL_STYLE)
第1引数の「hWnd」にはUserFormのウィンドウハンドル、第2引数には取得する情報がウィンドウスタイルであることを表す定数値「GWL_STYLE」をそれぞれ入力することで、戻り値として入力したウィンドウが持つウィンドウスタイルを取得することができます。
取得したウィンドウスタイルに追加設定
ウィンドウスタイルが取得できたらウィンドウサイズ可変、最大化/最小化ボタンを表すウィンドウスタイル情報を追加します。ウィンドウスタイルの追加はOr演算子を使い、下記のように記載します。
hStyle = hStyle Or WS_THICKFRAME Or WS_MAXIMIZEBOX Or WS_MINIMIZEBOX
このとき、この3種の設定はすべて同時に行う必要はありません。たとえばサイズ可変の設定のみしたければ「hStyle = hStyle Or WS_THICKFRAME」と記載することで最大化/最小化ボタンを設定せずにサイズ可変のみの設定をすることができます。
UserFormにウィンドウスタイルを再設定
ウィンドウスタイルの追加設定ができたらその情報をUserFormに再設定します。ウィンドウスタイルの設定はSetWindowLongPtr関数を使って下記のように記載します。
Call SetWindowLongPtr(hWnd, GWL_STYLE, hStyle)
第1引数の「hWnd」にはUserFormのウィンドウハンドル、第2引数には設定する情報がウィンドウスタイルであることを表す定数値「GWL_STYLE」、第3引数の「hStyle」には設定するウィンドウスタイル(前項で追加設定したもの)をそれぞれ入力します。
これによりUserFormに最大化/最小化ボタンが付与されサイズ変更も可能になります。
関連情報
VBA×WindowsAPIまとめページ
その他のWindowsAPI関数は下記ページにまとまっているので合わせて参照下さい。