VBのポップアップメニューで...


今回は、VBで右クリックメニューを表示するときの落とし穴(?)ってことで。

アプリケーションで、独自の右クリックメニュー(ポップアップメニュー)を表示したい、ってことはよくあると思います。
そういう場合いちばん簡単なのはメニューエディタでメニューコントロールを編集して表示する方法だと思うのですが。

たとえば、下の図のように、モードが違うと、表示される右クリのメニューを変えたい場合。

 
こういう場合は、下の図のように、メニューエディタで、右クリック時に表示するメニューをあらかじめ作成しておきますよね。



そして、フォーム上でのMouseUpイベントに以下のようなコードを記述して、モード1とモード2の場合わけをすると思うのですが。
1    Private Sub Form_MouseUp(Button As Integer, Shift As Integer, 
                              X As Single, Y As Single)
2
3        ' 右クリック時の処理
4        If Button = vbRightButton Then
5            ' 現在のモードをチェック(オプションボタンの値で判断)
6            If optMode(0).Value = True Then
7                ' モード1の時の処理
8                mnuPopupMode1.Visible = True
9                mnuPopupMode2.Visible = False
10            
11          Else
12              ' モード2の時の処理
13              mnuPopupMode1.Visible = False
14              mnuPopupMode2.Visible = True
15          End If
16          ' 右クリックメニューの表示'
17          Call Form1.PopupMenu(mnuPopup)
18        
19      ' ここ以降は、右クリ以外の操作があれば記述する
20      Else
21    
22      End If
23  End Sub
・・・正直、コレであってると思ってました。
でも実際に実行してみると、モード2にして右クリックした場合、13行目で
実行時エラー"387"「’Visible'プロパティはこのコントロールでは設定できません」が発生します。
あれ。。。と思ってヘルプでエラー詳細を見ると、「このプロパティは参照できません」となっているし。。。
なぜだ。Visibleプロパティが参照できないなんてことなかったし。しかもモード1の時はすんなり通るのに。
そんな感じで悩むこと20分ほど。

こういうときって、解決してしまえば、なんでこんな簡単なことに気づかないのか。。。と思うのですがw
結論から言えば、上記ソースの13行目と14行目を入れ替えて、
12              ' モード2の時の処理
13              mnuPopupMode2.Visible = True
14              mnuPopupMode1.Visible = False
に変えるとエラーは発生しなくなります。

なぜかというと、修正前のソースだと、13行目を通る際に、mnuPopupMode1もmnuPopupMode2も
両方ともVisibleがFalseになってしまうのですね。
つまりメニューオブジェクトは必ずひとつは表示できる状態になっていないとダメだということで。

今回の例のように、条件分岐(モード1やモード2)も少なく、表示すべきメニューも少ないと気づきやすいのですが、
いくつも条件分岐してて、かつ、「このメニューは表示、これは非表示・・・」ってことを何行もやっていると、
ついうっかりすべてのvisibleがFalseになってた、なんてことが起こりそうです。

右クリのメニューを編集するときは、Visible=True の処理から順にやっていく。
単純なことだけどすぐ忘れそうなので、ちゃんと覚えておかなくちゃw
creation date:2004年某日