C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: タブページをドラッグしてウインドウを動かす方法


(過去ログ 138 を表示中)

[トピック内 11 記事 (1 - 11 表示)]  << 0 >>

■80963 / inTopicNo.1)  タブページをドラッグしてウインドウを動かす方法
  
□投稿者/ よっしー (1回)-(2016/08/22(Mon) 21:27:38)

分類:[VB.NET/VB2005 以降] 



VBでフォームあるいはタブページをドラッグすることでウインドウが動かせるような仕様にしたいと考えています。
フォームをドラッグして動かす方法は以下のページに書かれていました。
http://homepage1.nifty.com/rucio/main/dotnet/Samples/Sample067MoveForm.htm
これを応用して以下のようにタブページをドラッグして動かすコードを作成しました。

Private Declare Function SendMessage Lib "User32.dll" Alias "SendMessageA" (ByVal hWnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Long
Private Declare Sub ReleaseCapture Lib "User32.dll" ()

Const WM_NCLBUTTONDOWN = &HA1
Const HTCAPTION = 2

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

If e.Button = MouseButtons.Left Then
Call ReleaseCapture()
Call SendMessage(Me.Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0&)
End If

End Sub

しかし、この方法だとタブページ一つ一つに設定する必要があり、
タブページを増やしたり減らしたりする場合に
作り替える必要があり面倒です。

全てのタブページ上記の設定を反映させる方法があれば教えてください。




引用返信 編集キー/
■80964 / inTopicNo.2)  Re[1]: タブページをドラッグしてウインドウを動かす方法
□投稿者/ よっしー (2回)-(2016/08/22(Mon) 21:29:11)
間違ってフォームの移動のコードを貼ってしまいました。
こちらがタブページ移動のコードです。
Private Declare Function SendMessage Lib "User32.dll" Alias "SendMessageA" (ByVal hWnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Long
Private Declare Sub ReleaseCapture Lib "User32.dll" ()

Const WM_NCLBUTTONDOWN = &HA1
Const HTCAPTION = 2


Private Sub TabPage1_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs) Handles TabPage1.MouseMove

If e.Button = MouseButtons.Left Then
Call ReleaseCapture()
Call SendMessage(Me.Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0&)
End If

End Sub
引用返信 編集キー/
■80966 / inTopicNo.3)  Re[2]: タブページをドラッグしてウインドウを動かす方法
□投稿者/ Azulean (689回)-(2016/08/22(Mon) 22:04:37)
AddHandler で動的に割り当てればよいと思います。

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    For Each Page As TabPage In TabControl1.TabPages
        AddHandler Page.MouseMove, AddressOf TabPage_MouseMove
    Next
End Sub

Private Sub TabPage_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)

    If e.Button = MouseButtons.Left Then
        Call ReleaseCapture()
        Call SendMessage(Me.Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0&)
    End If

End Sub

引用返信 編集キー/
■80967 / inTopicNo.4)  Re[3]: タブページをドラッグしてウインドウを動かす方法
□投稿者/ よっしー (5回)-(2016/08/22(Mon) 22:24:42)
ありがとうございます。
うまくいきました。

あと、できれば、全てのLabelやGroupBoxをドラッグした時にも
フォームが移動するようにしたいのですがどうすれば良いですか?

コレクション型でない場合には
どうすれば良いでしょうか?


引用返信 編集キー/
■80969 / inTopicNo.5)  Re[4]: タブページをドラッグしてウインドウを動かす方法
□投稿者/ Azulean (690回)-(2016/08/22(Mon) 23:24:37)
No80967 (よっしー さん) に返信
> あと、できれば、全てのLabelやGroupBoxをドラッグした時にも
> フォームが移動するようにしたいのですがどうすれば良いですか?
>
> コレクション型でない場合には
> どうすれば良いでしょうか?

TabPage は TabControl に所有されている関係のように、Label や GroupBox も Form などに所有されているのでそれらの Controls プロパティでループすれば良いかと。
ただし、Form が持っているのは Form に直接貼られているものだけなので、Panel の中に貼り付けたもの、TabPage の中に貼り付けたものは、それらの Controls プロパティを見に行かなければなりません。
「すべて」を満たすためには、再帰処理にする必要があります。


// 面倒くさい場合、Application.AddMessageFilter を利用する、別のアプローチもありかもしれない。
引用返信 編集キー/
■80970 / inTopicNo.6)  Re[5]: タブページをドラッグしてウインドウを動かす方法
□投稿者/ よっしー (7回)-(2016/08/22(Mon) 23:29:05)
ありがとうございます。

Application.AddMessageFilter
というものに関して調べてみたのですが
使い方がよく分かりませんでした。
具体的なコードをお教えいただけないでしょうか?
よろしくお願いいたします。
 
引用返信 編集キー/
■80972 / inTopicNo.7)  Re[6]: タブページをドラッグしてウインドウを動かす方法
□投稿者/ Azulean (691回)-(2016/08/22(Mon) 23:57:35)
No80970 (よっしー さん) に返信
> Application.AddMessageFilter
> というものに関して調べてみたのですが
> 使い方がよく分かりませんでした。
> 具体的なコードをお教えいただけないでしょうか?

書いておきながら難ですが、調べてもよくわからないという状態であるなら、触らない方がいいです。
すべてのウィンドウメッセージが来ますので、下手にコードを書くと、アプリケーションのパフォーマンスが落ちるなどの問題が発生する可能性がありますので、上級者向けと言えます。

正攻法の Controls プロパティの再帰処理を考えてみてください。
引用返信 編集キー/
■80974 / inTopicNo.8)  Re[7]: タブページをドラッグしてウインドウを動かす方法
□投稿者/ よっしー (9回)-(2016/08/23(Tue) 00:17:54)


For Each Label As Control In Me.Controls
AddHandler Label.MouseMove, AddressOf Form_Move
Next

これでタブページの外側の全てのコントロールをドラッグ移動できるようになったのですが
タブページの中を再帰処理するにはどうしたら良いですか?

あと、ComboboxやTextboxを除外したいのですがどうすれば良いですか?
 
引用返信 編集キー/
■80977 / inTopicNo.9)  Re[8]: タブページをドラッグしてウインドウを動かす方法
□投稿者/ Azulean (692回)-(2016/08/23(Tue) 06:52:10)
No80974 (よっしー さん) に返信
> これでタブページの外側の全てのコントロールをドラッグ移動できるようになったのですが
> タブページの中を再帰処理するにはどうしたら良いですか?

Controls プロパティと TabPage プロパティと名前が違うので、同じメソッドにはできませんね。
TabControl 用のコードを別途書くしかないわけですが、1 個しか TabControl がないのであればベタに書けば良いでしょう。


> あと、ComboboxやTextboxを除外したいのですがどうすれば良いですか?

GetType と If を使えばよさそうですが、イメージがつきませんか?
イメージがつかない場合は、"VB.NET Controls GetType" のキーワードでいくつかページを見て回ってください。
引用返信 編集キー/
■80978 / inTopicNo.10)  Re[9]: タブページをドラッグしてウインドウを動かす方法
□投稿者/ よっしー (10回)-(2016/08/23(Tue) 07:57:17)
再帰処理でうまくいきました
どうもありがとうございます。
 
解決済み
引用返信 編集キー/
■80988 / inTopicNo.11)  Re[2]: タブページをドラッグしてウインドウを動かす方法
□投稿者/ 魔界の仮面弁士 (839回)-(2016/08/23(Tue) 11:27:34)
2016/08/23(Tue) 18:53:11 編集(投稿者)

# New Message() から Message.Create() なコードに差し替えました


No80964 (よっしー さん) に返信
> Private Sub TabPage1_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs) Handles TabPage1.MouseMove
>   If e.Button = MouseButtons.Left Then
>     Call ReleaseCapture()
>     Call SendMessage(Me.Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0&)
>   End If
> End Sub

参考までに、Declare 宣言無しで記述する方法も書いておきます。

Private Sub DragMove(ByVal sender As Object, ByVal e As MouseEventArgs)
  If e.Button = MouseButtons.Left Then
    ' Call ReleaseCapture()
    DirectCast(sender, Control).Capture = False

    ' Call SendMessage(Me.Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0&)
    WndProc(Message.Create(Handle, &HA1, New IntPtr(2), IntPtr.Zero))
  End If
End Sub


ついでに、コントロールを再帰的に列挙する例も載せておきます。
NumericUpDown 内の UpDownButtons などといった
非公開の内部コントロールも列挙されますので御注意下さい。


' Iterator Function を使うには、VB2012 以降が必要です
Private Iterator Function EnumControls(owner As Control) As IEnumerable(Of Control)
  Yield owner
  For Each c In owner.Controls.Cast(Of Control).SelectMany(AddressOf EnumControls)
    Yield c
  Next
End Function



No80974 (よっしー さん) に返信
> あと、ComboboxやTextboxを除外したいのですがどうすれば良いですか?

Dim q = From c In EnumControls(Me) _
    Where TypeOf c IsNot TextBoxBase AndAlso _
       TypeOf c IsNot ComboBox AndAlso _
       TypeOf c IsNot TrackBar AndAlso _
       TypeOf c IsNot Splitter AndAlso _
       TypeOf c IsNot SplitContainer

For Each c In q
  AddHandler c.MouseMove, AddressOf DragMove
Next


・WebBrowser は MouseMove イベントを通知しないため、
 この方法は使えません。WebBrowser でマウス操作を
 取得する方法については、下記を参照して下さい。
 http://dobon.net/vb/bbs/log3-37/22769.html

・TrackBar は、つまみ以外の場所はドラッグ可能に
 したかったのですが、判定条件が分かりませんでした…。

・DataGridView についても、列や行のリサイズを可能にしている場合、
 座標判定して、リサイズ時は除外するなどの必要が生じるかと思います。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -