マウスイベント(MouseDown)に関しての質問

タグの編集
投稿者 マウス連合  (学生) 投稿日時 2018/10/23 12:51:43
初歩的な質問で申し訳ありません。
1ヶ月奮闘しているのですが、なかなかうまくいかず投稿させていただきました。

現在、 PictureBoxを25(5×5)並べて、現在地からマウスの操作で移動するプログラムを作りました。

そこで、マウスのホイール上で上へ移動、下で下に移動、左クリックで左に移動、右クリックで右に移動、中央ボタンでEnterにする仕様にしました。

ホイールはWheelイベントを使って、上・下への移動はできました。
↓Wheelイベントに使っているプログラムです

 Private Sub Form1_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseWheel

マウスの左クリック・右クリック・中央クリックにはMouseDownイベントを使っていますが、
イベントの取得が上手くいかず、複数回クリックすればイベントを時々取得することができます。'
'↓MouseDown
 Private Sub Form1_WH_LBUTTONDOWN(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseDown
'↓左クリックの場合
f e.Button = Windows.Forms.MouseButtons.Left Then


クリックイベントを100%取得できるようにしたいです。
どうか助けてください。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2018/10/23 13:12:06
> PictureBoxを25(5×5)並べて、現在地からマウスの操作で移動するプログラムを作りました。

25 個の PictureBox の座標位置を、それぞれ入れ替えるということなのか、
それとも、25 個のコントロールすべての位置を、上下左右にずらすのか、
あるいは PictureBox 自身の位置を移動するのではなく、
PictureBox 上に描かれた画像の位置を変更したいのか、
質問文からは読み取れませんでした。

> マウスのホイール上で上へ移動、下で下に移動、
> 左クリックで左に移動、右クリックで右に移動、
> 中央ボタンでEnterにする仕様にしました。

ドラッグ & ドロップにするか、キーボードの矢印での移動の方が、
利用者にとっては分かりやすい気がしますが、それはさておき。


> 複数回クリックすればイベントを時々取得することができます。

試してはいませんが、連続したクリックが、DoubleClick イベントのために
分けて処理されてしまうからではないでしょうか。
MyBase.SetStyle(ControlStyles.StandardDoubleClick, False)
を呼び出して、Form1 のダブルクリックを無効化してみてはどうでしょう?
(PictureBox 上でもマウス操作するなら、PictureBox の SetStyle も修正)
投稿者 マウス連合  (学生) 投稿日時 2018/10/23 14:49:56
返信ありがとうございます
> PictureBoxを25(5×5)並べて、現在地からマウスの操作で移動するプログラムを作りました。
上手く説明できていなくてもうしわけありません
PictureBox上に書かれた画像の位置を変更します。
なので、現在地がPictureBox1にある場合右クリック押されるとPictureBox2に画像が移動しているようにしています。

> マウスのホイール上で上へ移動、下で下に移動、
> 左クリックで左に移動、右クリックで右に移動、
> 中央ボタンでEnterにする仕様にしました。
キーボードの矢印での移動がわかりやすいと思います。
既存の物を忠実に再現しているのでマウスでしています。ww

> 複数回クリックすればイベントを時々取得することができます。
ダブルクリックを無効化するんですね!!ありがとうございます
今、やってみたんですがまだ反応が悪くプログラムの書き方が悪いと思い、また質問させていただきました。申し訳ないです。
''マウスイベント
 Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseDown
''ダブルクリックの無効か
 MyBase.SetStyle(ControlStyles.StandardDoubleClick, False)
"左クリック押した場合
  If e.Button = Windows.Forms.MouseButtons.Left Then

上記の感じでやっているんですが、どうすればうまくいきますか。
教えてください。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2018/10/23 16:11:55
> 現在地がPictureBox1にある場合右クリック押されるとPictureBox2に画像が移動しているようにしています。

なるほど。
一つの画像を、どの PictureBox に表示させるのかを管理しているのですね。
一つの PictureBox 上で画像の描画位置を移動させるのかと思っていました。

だとするとドラッグ操作は向かないですね。


> ''ダブルクリックの無効か
> MyBase.SetStyle(ControlStyles.StandardDoubleClick, False)
これは毎回呼ぶものではありません。コンストラクタに記述してください。
Form のダブルクリックを禁止したいなら、Form のコンストラクタに。
PictureBox のダブルクリックを禁止したいなら、PictureBox のコンストラクタに。


とはいえこれは、DoubleClick イベントを抑制して、2 回目の Click イベントのままに
するだけのものであり、MouseDown に対しては影響が無いはずなんですよね…。

PictureBox を貼っていない下記の実験用フォームを用意して、
連続した MouseDown イベントが、正しく通知されているかを確認してみてください。

'実験コード。Form に ListBox だけを貼っておきます。 
Public Class Form1
    Public Sub New()
        InitializeComponent()

        '下記の行をコメントアウトすると、連続した 2 回目の 
        'Click イベントが、DoubleClick イベントに変更される 
        MyBase.SetStyle(ControlStyles.StandardDoubleClick, False)
    End Sub

    '検証用 
    Private Sub Dump(eventName As String)
        ListBox1.Items.Insert(0, Now.ToString("[HH:mm:ss.ff]") & eventName)
        ListBox1.SelectedIndex = 0
    End Sub

    Private Sub Form1_MouseDown(sender As Object, e As MouseEventArgs) Handles Me.MouseDown
        Dump("MouseDown/" & e.Button.ToString())
    End Sub
    Private Sub Form1_MouseClick(sender As Object, e As MouseEventArgs) Handles Me.MouseClick
        Dump("MouseClick/" & e.Button.ToString())
    End Sub
    Private Sub Form1_MouseUp(sender As Object, e As MouseEventArgs) Handles Me.MouseUp
        Dump("MouseUp/" & e.Button.ToString())
    End Sub
    Private Sub Form1_Click(sender As Object, e As EventArgs) Handles Me.Click
        Dump("Click/" & MouseButtons.ToString())
    End Sub
    Private Sub Form1_DoubleClick(sender As Object, e As EventArgs) Handles Me.DoubleClick
        Dump("DoubleClick/" & MouseButtons.ToString())
    End Sub
End Class
投稿者 マウス連合  (学生) 投稿日時 2018/10/24 14:40:44
ご丁寧にありがとうございます。
実験コードをすべて書いていただき、実験することで正しく通知されることがわかりました。

私は、実際に実験してみたのですが、うまくいかず魔界の仮面弁士さんのおかげでうまくいくことができました。


これを参考に一夜かけて
①formのダブルクリックを禁止するためにコンストラクタに加え
 Public Sub Form1()
        InitializeComponent()

        '下記の行をコメントアウトすると、連続した 2 回目の 
        'Click イベントが、DoubleClick イベントに変更される 
        MyBase.SetStyle(ControlStyles.StandardDoubleClick, False)
    End Sub

②自分自身のプログラムではイベントMouseDownを変更することはないと確信しました。
そこでif文でのプログラムがおかしいとおもっています。

※今までのプログラム
if e.Button = Windows.Forms.MouseButtons.Left //左クリックされた場合

※魔界の仮面弁士さんのものを参考に。
①if e.Button.ToString()=MouseButtons.Left
②if e.Button=MouseButtons.Left


以下の①②をやっても実験プログラムのように必ず反応しません。

何回もお願いして申し訳ないのですが、教えてください

投稿者 マウス連合  (学生) 投稿日時 2018/10/24 15:10:42
魔界の仮面弁士さん!!
できました

if e.Button=MouseButton.Left

の条件分岐でできました。
ずっとif文に原因があると考えていました。
しかし、クリックする場所がPictureBoxの密集している場所だった為クリックが反応しませんでした。


魔界の仮面弁士さんの実行プログラムで用意してくれたListBoxもListBox内ではクリックの表示がされず、Form内でクリックした際にListBoxに表示されていたことからヒントを頂きしっかり動くことができました。
プログラムの説明の悪さを優しく聞き直し理解してくださり、実験プログラムまで提供していただきありがとうございました。

また、わからないことがあった場合VisualBasic中学校さんの投稿に投稿させていただくので、助けてください。
今回はほんとうにありがとうございました。