さて、それでは、今回はExcel UserForm にWin32APIを使い

UserFormにメニューバーを追加する方法も見ていきましょう。

実際のところ、Excel VBA の ツールボックスには、その追加機能としてツールバーを作成

する機能はあるようです。ツール→その他の機能からMicrosoft ToolBar Control

を追加すればUserFormにToolBarを追加することは可能なようです。

Webで検索すれば、この方法は出てきます。



イメージ 1



 ただ、ファイル(F)から始まるようなメニューを持ったBarは、

Excel VBAのUserFormには、取り付ける事ができないのでしょうか。

そのような追加コマンドはないものなのでしょうか。見つかりません。

そこで、今回Win32APIを使ってメニューバーを取り付ける方法を考えて見ました。

イメージ 2


今回は、コマンドボタン1を押すとポップメニューとしてコピーと貼付の

メニューを持った編集メニューUserFormに追加される。

コマンドボタン2をクリックすると、追加したメニューが削除されるように、

マクロを組んでみました。モチロン、TextBox1の中の文字を選択しコピーメニューを

クリックするとクリップボードにコピーされ、貼付メニューをクリックすると

TextBox1にクリップボードの内容を転写します。

メニューバー作成のマクロ


 メニューバーの形を作る関数を見てみましょう。

この関数は今回はUserFormプロシージャのGeneral部に記入してみました。

Function MyPopupMenu3() As Long
 Dim Mymenu1 As Long
 Dim Mymenu2 As Long
   Mymenu1 = CreateMenu     '(1)
   Mymenu2 = CreatePopupMenu
   
    AppendMenu Mymenu2, MF_STRING, 116, "コピー(&C)" + " " + "Ctrl+C" '(2)
    AppendMenu Mymenu2, MF_STRING, 118, "貼付(&V)" + " " + "Ctrl+V"
    
    AppendMenu Mymenu1, MF_POPUP Or MF_STRING, Mymenu2, "編集"  '(3)
 
   MyPopupMenu3 = Mymenu1
End Function

(1)ポップアップメニューを作成するときは、CreatePopupMenuを使用しました。

 メニューを作成する場合はCreateMenu関数を使います。

(2)マズ、ポップアップメニュー(Mymenu2)にコピーと貼付のメニューをAppendMenu関数

 を使って作成します。

(3)メニュー(Mymenu1)にMF_POPUP(Mymenu2)とMF_STRING(編集)を加え、

Mymenu1にMymenu2をポップアップとして結合しています。

MyPopupMenu3の返値はMymenu1のWindowハンドルとなります。

それでは、今回出てきたWin32API関数のCreateMenuと次に出てくるSetMenu

を標準モジュールで定義しました。

Public Declare Function CreateMenu Lib "user32" _
    () As Long
Public Declare Function SetMenu Lib "user32" _
    (ByVal hwnd As Long, _
    ByVal hMenu As Long) As Long

コマンドボタンのマクロ


 CommandButton1_Clickのイベントマクロは、メニューバーをUserFormに追加します。

CommandButton2_ClickはUserFormに表示されたメニューバーを削除します。

それでは、それぞれのマクロを見てみましょう。

Private Sub CommandButton1_Click()
    Dim SubMen As Long
    Dim ret As Long
    Dim hwnd As Long  'ウィンドウのハンドルを収納する
    hwnd = GetHwnd
    SubMen = MyPopupMenu3
    ret = SetMenu(hwnd, SubMen)
    SetOn
End Sub

Private Sub CommandButton2_Click()
 Dim hwnd As Long  'ウィンドウのハンドルを収納する
    hwnd = GetHwnd
    SetMenu hwnd, 0
    SetOff
End Sub

Function GetHwnd() As Long
     Dim strClassName As String
     strClassName = "ThunderDFrame"
     GetHwnd = FindWindow(strClassName, _
                              Me.Caption)
End Function

 SetMenu関数は親となるWindowハンドルに、作成したメニューのWindowハンドルを

Setしてやれば、メニューバーを追加します。hMenuに0をSetすれば、メニューバー

を削除します。GetHwnd関数はUserFormのハンドルを取得する自作関数です。

 なお、SetOn,SetOffはサブクラス化のお話となりますが、

これからは、次回としましょう。