tagCANDY CGI VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板 [ツリー表示へ]   [Home]
一括表示(VB6.0)
タイトル右クリックでのPopUpMenuについて
記事No15184
投稿日: 2011/05/28(Sat) 11:16
投稿者wanko108
・VB6にて

CommandButton上で右クリックが反応するのはそのボタンにFocusがあるときだけのようです。
ここに今カレンダーがあります。
各日付はCommandbuttonによって作られています。
このようなカレンダーで次のような処理をします。

1.右クリックのPopUpMenuにより休業日選択処理を開始
2.休業日となる日付ボタンを対象の数だけクリック→CommandButton.BackColor変更
3.右クリックのPopUpMenuにより選択処理を終了

このPopUpMenu表示処理は、フォーム、CommandButtonそれぞれに施してあります。
しかし、PopUpMenuが開くのはFormをクリックできる場所、そしてFocusのあるCommandButton上のみです。
MouseMoveイベントによりMouse下のCommandButtonにFocusを移動させれば常にどのボタン上でも右クリックは可能ですが見た目の動作としてあまり好ましくないように思えます。

そこで質問なのですが、CommandoButtonのイベント以外でも構わないので、フォーム上のどこでも、右クリックでPopUpMenuがひらけるような方法はないでしょうか?

[ツリー表示へ]
タイトルRe: 右クリックでのPopUpMenuについて
記事No15185
投稿日: 2011/05/29(Sun) 09:44
投稿者花ちゃん
> ・VB6にて
環境は、キチンと書くようにして下さい。
それと、wanko さんと同じ方でしょうか?

> そこで質問なのですが、CommandoButtonのイベント以外でも構わないので、フォーム上のどこでも、右クリックでPopUpMenuがひらけるような方法はないでしょうか?

本当に、[フォーム上のどこでも] が必要なのでしょうか?
Form の枠上やタイトルバー上・システムメニュー上でも右クリックを感知したいの
でしょうか?

そもそもそのような処理ならメニューにでも設定すべきかと思います。
PopUpMenu は、そのコントロールなりに関連のあるメニューだけを設定する方が自然かと
思います。
クライアント領域内で、かつ、簡単な方法なら下記を試して見てください。

Option Explicit

Private Declare Function GetAsyncKeyState Lib "user32.dll" _
   (ByVal vKey As Long) As Integer
Private Sub Form_Load()
   Me.Timer1.Interval = 100
End Sub

Private Sub Timer1_Timer()
   If GetAsyncKeyState(vbKeyRButton) < 0 Then
      MsgBox "マウスの右ボタンがクリックされました"
   End If
End Sub

後は、サブクラス化するか DirectX 等で、右クリックのメッセージをとらまえるとか、
単純に、Form 上にあるすべてのコントロールのイベントに書くとか。

検索して、下調べをしていたなら下記のような投稿も見つかっていたかと。
http://hanatyan.sakura.ne.jp/patio/read.cgi?no=228
http://hanatyan.sakura.ne.jp/vb60bbs/wforum.cgi?mode=allread&no=13596#13597

[ツリー表示へ]
タイトルRe^2: 右クリックでのPopUpMenuについて
記事No15189
投稿日: 2011/05/30(Mon) 14:15
投稿者魔界の仮面弁士
>> CommandButton上で右クリックが反応するのはそのボタンにFocusがあるときだけのようです。
手元の環境で検証してみました。

まずは、VB6 の VB.Form 上に標準ボタンである VB.CommandButton を貼っていた場合です。
この場合、ボタンにフォーカスがあるかどうかとは関係無く、ボタンの MouseUp イベントが
問題無く発生し、その中から PopupMenu メソッドを呼び出すことができました。
またこの場合、右クリックによるフォーカスの遷移は発生しませんでした。

次に、VB6 の VB.Form 上に Office VBA の MSForms.CommandButton を貼っていた場合です。
この場合は仰る通り、フォーカスが無いと MouseUp イベントが発生しませんでした。
ただしこの場合も、右クリックによるフォーカスの遷移は発生していません。

さらに、VB6 環境にて Microsoft 2.0 Forms デザイナを有効にしたうえで、
MSForms.Form 上に MSForms.CommandButton を載せて実行してみました。
この場合、フォーカスの有無とは関係無く、MouseUp イベントが発生しましたが、
上記 2 パターンとは異なり、フォーカスの遷移も行われました。


>> 2.休業日となる日付ボタンを対象の数だけクリック→CommandButton.BackColor変更
ということは、Style = グラフィックな CommandButton なのでしょうか?


>> フォーム上のどこでも、右クリックでPopUpMenuがひらけるような方法はないでしょうか?
> クライアント領域内で、かつ、簡単な方法なら下記を試して見てください。
この場合、MouseDown 時にコンテキストメニューを表示させる実装になりますね。
(MouseDown な例:VB6 開発環境のツールバーを右クリックした場合など)

応用して、MouseUp 時にコンテキストメニューを表示させてみました。
(MouseUp な例:テキストボックスや WebBrowser のコンテキストメニューなど)


Option Explicit

Private Declare Function GetAsyncKeyState Lib "user32" _
   (ByVal vKey As Long) As Integer

Private Declare Function SetCapture Lib "user32" _
   (ByVal hWnd As Long) As Long

Private Declare Function ReleaseCapture Lib "user32" _
   () As Long

Private Sub Form_Load()
    Timer1.Interval = 100
End Sub

Private Sub Timer1_Timer()
    Debug.Print GetAsyncKeyState(vbKeyRButton)
    If GetAsyncKeyState(vbKeyRButton) < 0 Then
        SetCapture Me.hWnd
    End If
End Sub

Private Sub Form_MouseUp( _
    Button As Integer, _
    Shift As Integer, _
    X As Single, _
    Y As Single)
    
    If CBool(Button And vbRightButton) Then
        ReleaseCapture
        If 0 <= X And X <= Me.ScaleWidth And _
           0 <= Y And Y <= Me.ScaleHeight Then
            
            PopupMenu mnuContext
        
        End If
    End If
End Sub



別案として、AttachMode プロパティをインフロントにした InkOverlay オブジェクトの
MouseUp イベントを使って拾うという方法も考えたのですが…この場合、
一切のマウス操作が InkOverlay に奪われてしまうので、標準のマウス操作が
コントロールに到達しないという問題を抱えてしまいました。

[ツリー表示へ]