tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトルFormのマウスドラッグ移動時に変な挙動をいたします
記事No9742
投稿日: 2009/12/24(Thu) 11:28
投稿者camputer
 こんにちは、いつも勉強させていただいておりますcamputerと申します。
VB.NET歴1年強、プログラム歴10年です。
質問させていただきます。どうぞよろしくお願いいたします。

 開発環境:VB2008+XP SP3 になります。
 Form1(Form1+その直上のPanel1(BackColor=Transparent))をドラッグした際に
Formの移動を行えるように、↓のようにコーディングいたしておりますが、
    Panelの輪郭線にMouseDown(少しクリックポイントが厳しいかもしれません)
   →そのまま少しドラッグ
   →MouseUp
といたしますと、Formが明後日の方向に飛ぶように移動することがあります。。。
もしくはFormが移動せず、悩んでおります。

    Private Sub Form1_MouseDown(ByVal sender As Object, _
        ByVal e As System.Windows.Forms.MouseEventArgs) _
        Handles MyBase.MouseDown, Panel1.MouseDown

        If (e.Button And MouseButtons.Left) = MouseButtons.Left Then
            mousePoint = New Point(e.X, e.Y) '位置を記憶
        End If
    End Sub

    Private Sub Form1_MouseMove(ByVal sender As Object, _
        ByVal e As System.Windows.Forms.MouseEventArgs) _
        Handles MyBase.MouseMove, Panel1.MouseMove

        If (e.Button And MouseButtons.Left) = MouseButtons.Left Then
            Me.Location = New Point(Me.Left + e.X - mousePoint.X, Me.Top + e.Y - mousePoint.Y)
        End If
    End Sub

 そこで、移動距離が大きいときのみ制限をかけてみて、、、
 If System.Math.Abs(e.X - mousePoint.X) < 50 Then
などと工夫したりいたしましたが、根本的に解決いたしませんorz

 少し変なご相談かもしれませんが、何かよい方法など思いつく方がいらっしゃいましたら、
是非ともアドバイスいただきたくお願い申し上げます。
どうぞよろしくお願いいたします。

[ツリー表示へ]
タイトルRe: Formのマウスドラッグ移動時に変な挙動をいたします
記事No9743
投稿日: 2009/12/24(Thu) 12:28
投稿者花ちゃん
>     Panelの輪郭線にMouseDown(少しクリックポイントが厳しいかもしれません)

Panel を移動させたいのでしょうか?
それともForm を移動させたいのでしょうか?
Form 上はクリックできないので、Panel の枠をドラッグしてForm 事移動したいなら
クライアント座標→スクリーン座標に変換して、イベント単独で使用するようにしないと
クリック位置の微妙な差が影響を与えるのではないでしょうか?

[ツリー表示へ]
タイトルRe^2: Formのマウスドラッグ移動時に変な挙動をいたします
記事No9744
投稿日: 2009/12/24(Thu) 13:02
投稿者camputer
 花ちゃん様

 どうもありがとうございます!!
HPご提供どうもありがとうございますm(_ _)m 今私のVB.NETでExcelを動かせる力は
半分以上がhanatyan.sakura.ne.jpのおかげでございます。

> Panel を移動させたいのでしょうか?
> それともForm を移動させたいのでしょうか?
 Form全体の移動になります。Panel1とForm1は相対的にくっついたままでございます。

> ここのサンプルは参考になりませんでしたか?
ご提供いただいておりますvb60logと、
http://www.google.co.jp/search?hl=ja&source=hp&q=%22mousemove%22+hanatyan&lr=&aq=f&oq=
で念のため検索させていただきましたが、もしかしてこの件もサンプルがあって
見逃しておりましたでしょうか??どこでしょう。。。
もしそうでございましたら大変失礼いたしました。
 確か同じような記述はPictureBoxか何かのスクロールに関してたくさんあった記憶が
ございますが。。。

 このような現象って皆様のForm上でも見られるものでございましょうか???
もし無いようでございましたら、自分のコーディングが下手orzなのだと思われるのですが。。。。
 お手数をおかけいたしますが、もし何か思いつかれましたらご紹介いただきたく
お願いいたします。
自分ももう一度hanatyan内のサンプルを探してまいります。


 (追記になります。↑は全部、花ちゃん様に追記していただいた
「クライアント座標→スクリーン座標」を読んでいない時点での書き込みになります。
今から検索&勉強してまいります。
どうもありがとうございますm(_ _)m  )

[ツリー表示へ]
タイトルRe^3: Formのマウスドラッグ移動時に変な挙動をいたします
記事No9748
投稿日: 2009/12/24(Thu) 17:37
投稿者花ちゃん
下記が利用出来ないかなと試したのですが、チョット混乱して
http://hanatyan.sakura.ne.jp/dotnet/mouse02.htm

オーソドックスな方法を試してみましたとりあえずと言う事で。
(動作確認するだけに試したコードなのでもっといい方法や綺麗な書き方があるかも、
後で時間がとれれば、確認して修正します。)

Public Class Form1

Private MsLoc As Point
Private Spos As Point
Private Epos As Point
Private Sub Panel1_MouseDown(ByVal sender As Object, _
            ByVal e As System.Windows.Forms.MouseEventArgs) Handles Panel1.MouseDown
  If (e.Button And MouseButtons.Left) = MouseButtons.Left Then
      MsLoc = Me.Location
      Spos = Cursor.Position
  End If
End Sub
Private Sub Panel1_MouseMove(ByVal sender As Object, _
            ByVal e As System.Windows.Forms.MouseEventArgs) Handles Panel1.MouseMove
  If (e.Button And MouseButtons.Left) = MouseButtons.Left Then
      Epos = Cursor.Position
      Dim x1 As Integer = Epos.X - Spos.X
      Dim y1 As Integer = Epos.Y - Spos.Y
      Me.Left = MsLoc.X + x1
      Me.Top = MsLoc.Y + y1
  End If
End Sub

End Class

[ツリー表示へ]
タイトルRe^3: Formのマウスドラッグ移動時に変な挙動をいたします
記事No9750
投稿日: 2009/12/24(Thu) 18:22
投稿者camputer
 ご報告になります。
コードを一通りスクリーン座標に直したりして色々とテストいたしておりますが、
  Panel1とForm1の境界線にMouseDown:MouseDownを検知できていないので、
  初期座標mousePoint.Xが取れない(花ちゃん様に教えていただいたとおり)。
       ↓
  そのままMouseMoveするとPanel1もしくはForm1の領域に入るのでMouseMoveイベント発動
  Form1.Location = New Point(Me.Left + Cursor.Position.X - mousePoint.X _
                              , Me.Top + Cursor.Position.Y - mousePoint.Y)
    のmousePoint.Xに変な値が入っているのでFormが飛ぶ。
といった現象のような感じでございます。
そこでmousePoint.X(とmousePoint.Y)をMouseMove中に移動すれば・・・と
試してみましたが、マウスドラッグが速いとmousePoint.X代入値とForm位置とが
かなりずれてしまいます。

 そこで今、Form上のどこをMouseDownされても取れるように・・・などと考えまして
検索いたしまして、
  Me.Capture = True

    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        MyBase.WndProc(m)
        Dim MouseD_X As Integer = 0
        Dim MouseD_Y As Integer = 0
        If m.Msg = &H202 Then '&H202:マウスの左ボタンMouseDown
            MouseD_X = Cursor.Position.X
            MouseD_Y = Cursor.Position.Y
         :
         :
と書いている途中で、これだとForm1上にあるドラッグされたくないコントロール
(Button1など)もドラッグされてしまうのでは・・・orz などと
気づいたところでございます^^;

おそらく「Form1の上にPanel1とButton1がある状況で、
     Form1  :ドラッグ可
     Panel1 :ドラッグ可
     Button1:ドラッグ不可
    を保ったまま、Form1とPanel1の境界のMouseDownを検知する方法 」
を探すことになりそうでございます。
Button1:ドラッグ不可 の条件がついてきそうでございます。
後出しになってしまい申し訳ございませんm(_ _)m

 もう少し粘ってがんばってみます。
もしお暇な時間でもございましたら、ちらっとアドバイスしてやっていただけると
光栄でございます。
どうぞよろしくお願いいたします。





(追記になります。↑の書き込みを終えた後で、花ちゃん様からのアドバイスを
読ませていただきました。
たびたび同じことをやらかしてどうもすみません^^;)

 アドバイスどうもありがとうございます!
コーディングを試していただけたということで、お忙しいかもしれませんのに
誠にありがとうございます。すべてスクリーン座標でのものでございますね。
まだ細かいところまで読ませていただいておりませんが、
お礼だけ先にさせていただきますm(_ _)m

 今から自分のコーディングと比較してまいります!(`ー´ゞ

[ツリー表示へ]
タイトルこれならどちらをドラッグしてもOK
記事No9752
投稿日: 2009/12/24(Thu) 19:14
投稿者花ちゃん
Public Class Form1

Private meSL As Point
Private Spos As Point
Private Sub Form1_MouseDown(ByVal sender As Object, _
                  ByVal e As System.Windows.Forms.MouseEventArgs) _
                              Handles Me.MouseDown, Panel1.MouseDown
  If (e.Button And MouseButtons.Left) = MouseButtons.Left Then
      meSL = Me.Location      'Form の現在座標値
      Spos = Cursor.Position  'ドラッグの開始位置
  End If
End Sub

Private Sub Form1_MouseMove(ByVal sender As Object, _
            ByVal e As System.Windows.Forms.MouseEventArgs) _
                                 Handles Me.MouseMove, Panel1.MouseMove
  If (e.Button And MouseButtons.Left) = MouseButtons.Left Then
      'Me.Left =Form のスタート位置 + 移動量
      Me.Left = meSL.X + (Cursor.Position.X - Spos.X)
      Me.Top = meSL.Y + (Cursor.Position.Y - Spos.Y)
  End If

End Sub
End Class

[ツリー表示へ]
タイトルRe: これならどちらをドラッグしてもOK
記事No9753
投稿日: 2009/12/24(Thu) 20:10
投稿者camputer
 どうもありがとうございます!!^^
(IPアドレスが弱冠変わっていると思われますが今,
研究所→家に帰ってまいりました.camputerでございます)

 コーディングを試していただき誠にありがとうございます.
(度々お手元で試していただきどうもすみません..VB花ちゃんは
超上級者→上級&中級者へアドバイスだけして成り立つイメージが
ありますので...それだけ私の理解がおそ略orz)

 今から自分のコードと比較&試させていただきます.
後で再度お礼&ご報告させていただきます!

[ツリー表示へ]
タイトルRe: Formのマウスドラッグ移動時に変な挙動をいたします
記事No9749
投稿日: 2009/12/24(Thu) 17:50
投稿者YuO
単純に,Panel内の相対座標とForm内の相対座標で演算しているために起きているのではないでしょうか。
MSDN: MouseEventArgs.X プロパティ (System.Windows.Forms)
http://msdn.microsoft.com/ja-jp/library/system.windows.forms.mouseeventargs.x.aspx
> たとえば、Control.MouseMove イベントが処理されるとき、マウスの座標の値はイベントを発生させたコントロールを起点とする相対座標になります。

計算時に全てスクリーン座標に変換してから計算すれば,camputerさんの書かれているようなことは起きないと思いますよ。

[ツリー表示へ]
タイトルRe^2: Formのマウスドラッグ移動時に変な挙動をいたします
記事No9751
投稿日: 2009/12/24(Thu) 19:01
投稿者camputer
 YuO様

 どうもありがとうございます!!
ご活躍拝見いたしております。
この度はご閲覧いただき誠にありがとうございます。camputerと申します。m(_ _)m

 > たとえば、Control.MouseMove イベントが処理されるとき、マウスの座標の値はイベントを発生させたコントロールを起点とする相対座標になります。

 リンクをどうもありがとうございます。かなりドンピシャな説明のようでございますね。
(早くこういう情報を自分で見つけられるようにな略orz)

 先ほど花ちゃん様にもスクリーン座標の存在を教えていただきまして、
一通りコーディングいたしましたつもりでございますが、まだ同様な現象が
生じております。コーディングミスも十分(orz)考えられますので
>コントロールを起点とする相対座標になります
も含めて整理しなおしてみます。
 まずお礼だけになってしまいますが、またご報告させていただきます!

[ツリー表示へ]
タイトル思考錯誤中でございます.
記事No9759
投稿日: 2009/12/27(Sun) 17:21
投稿者camputer
 こんばんは,camputerでございます.m(_ _)m
スクリーン座標にして挙動がかなり改善いたしましたが,Panel1輪郭部を
MouseDownされた際に反応できないため,まだ変な挙動が残っておりますのと,
連携しております他のFormの挙動も(稀にですが)弱冠変わってきておりますので
思考錯誤いたしている最中でございます.

 (助けてくださいではなく)しばらくテストするお時間をいただきたい
次第でございます(VBのForm挙動に関するバグ取りは大好きです^^)
スクリーン座標表示用のラベルを追加いたしまして変な挙動時の
スクリーニングを行っております.納得がいくまで試してみたい
次第でございます. どうぞよろしくお願いいたします.

   ...φ(`_´)

[ツリー表示へ]
タイトル御報告
記事No9799
投稿日: 2010/01/20(Wed) 12:21
投稿者camputer

 こんにちは、ご報告させていただきますm(_ _)m
 結局、Panel外周上のMouseDownを検知する方法を考案しようと
いたしましたができませんでした。。

 問題だった現象でございますが、
  Formのどこかを正常にドラッグしてForm移動(この時点で問題なし)
  →境界にMouseDown(これが検知されていないので、
           前回のドラッグ終了時のマウス位置が残ったまま)
  →マウスドラッグして直下のForm領域内に入ると
   MyBase.MouseMoveのコードの
       マウスの位置 = 旧座標 + 移動距離
   における「旧座標」に前回のドラッグ終了時点の座標が入っておりました。
   さらに質問前段階ではそこにクライアント座標が代入されておりましたため
   現象が複雑になっておりました。

    あと大きいFormをたくさん扱う必要から、複数のFormが
   輪郭を消して重なっておりまして、毎回起動するMyBase.MouseMoveが
   異なりましたこととが、現象を複雑化させておりました。。。

 そこで、(重くなるのを覚悟で)Form全体のスクリーンショットを
Form.BackGroundImageに貼り付けてから
Panel.BorderStyleをすべてNoneにいたしました。
これからFormの形状変更のたびに貼り付けなおすことになりますが。。。。orz

 花ちゃん様とYuO様からスクリーン座標に直せとアドバイスいただけて
リンク先も読ませていただいたおかげで、その後は挙動がシンプルになり
分かりやすくなりましたので現象解明はけっこう早くできました。
輪郭のMouseDownの検知がどうしてもできませんが。。。。orz

 今回もまた問題解決のみならず、知識とできることが増えました。
重ね重ねお礼申し上げます。
いつもご親切に教えていただける自分は幸せものです。m(_ _)m 
 どうもありがとうございました!!!

[ツリー表示へ]
タイトルRe: 御報告
記事No9800
投稿日: 2010/01/20(Wed) 12:45
投稿者花ちゃん
> 輪郭のMouseDownの検知がどうしてもできませんが。。。。orz

メッセージを監視する事で取得できると思うのですが?
http://tokyo.cool.ne.jp/kanain/APIHTM/GetMsg.html

上記の中の該当のメッセージを下記のように監視して
http://hanatyan.sakura.ne.jp/vbnetbbs/wforum.cgi?mode=allread&no=9785&page=0

[ツリー表示へ]
タイトルRe^2: 御報告
記事No9801
投稿日: 2010/01/20(Wed) 13:08
投稿者camputer
 花ちゃん 様
 どうもありがとうございます!!

> http://tokyo.cool.ne.jp/kanain/APIHTM/GetMsg.html
なんとこんなことができますとは。。何でもできそうですねー。流石VB。

今回の場合、
Public Const WM_LBUTTONDOWN = &H201 '左のマウスボタンを押した
と座標の判定でございましょうか?
 例えばForm1(ドラッグ可)にPanel1(ドラッグ可)と
              TextBox1(ドラッグ不可)とがある場合、
マウスボタンを押した際の位置(クライアント座標)で
TextBox1より外かどうかを判定する必要があるように思うのでございますが。。。

 とんちんかんなことを申しておりましたら申し訳ございません。
何かこのような際によさそうな考え方などございましたら、
是非ともアドバイスいただきたくどうぞお願いいたします。
(さんざんいただいておりますが。。m(_ _)m )

[ツリー表示へ]
タイトルRe^3: 御報告
記事No9802
投稿日: 2010/01/20(Wed) 14:58
投稿者花ちゃん
Public Const WM_NCHITTEST = &H84 '非クライアント領域のどの部分でマウスが操作されたか調べる
上記のリンク内に上記のようなものがあったかと思うのですが、それらを使って
マウスポインターの位置を監視する事ができます。

上記のリンク先のもの以外でも色々あり、例えば、
Private Const HTRIGHT = 11          '可変枠の右辺境界線上にある(P868)
のようにマウスポインターがどこにあるのかを取得したりもできます。
下記のサンプルを紹介した方がよかったかな。

http://hanatyan.sakura.ne.jp/vbnetbbs/wforum.cgi?no=8372&reno=8222&oya=8209&mode=msgview&page=0

上記のリンク内のコード中の同様の定数が色々記載されているのでその意味等を
調べてみたり、そのコードを解析すれば、応用もできるかと。
又、貴方が取得した輪郭とやらに流れているメッセージを spy++ 等で調べてみると
色々取得する方法が見つかるかと思います。
(細部については、あまり詳しくないのでこの辺で。)

簡単なサンプルなら、下記にも(何処かで見たと思って探していたのですが)
http://rucio.groupsite.jp/commu/ThreadDetail.aspx?ThreadId=9527

[ツリー表示へ]
タイトルRe^4: 御報告
記事No9803
投稿日: 2010/01/20(Wed) 15:22
投稿者camputer
 どうもありがとうございます!!

>(細部については、あまり詳しくないのでこの辺で。)
いえ方針をご提示いただけるだけで十分でございます。
どうもありがとうございます。

>Private Const HTRIGHT = 11
>Public Const WM_NCHITTEST = &H84
 もしこれができるようになればさらに良いソフトになります^^
(何より自分がこれらを理解できる力がつきますし)

 今から頑張ってまいります!!
どうもありがとうございました!`-´ゞ

[ツリー表示へ]