Pixtack紫陽花の方がうまくいかないからちょっと別のテスト
基本
ラベルとPictureBoxをマウスドラッグで移動
Labelをマウスドラッグで動かしてPictureBoxのサイズと位置を変化させている
よくある動きだけど、今回はじめてできた!
Pixtack紫陽花やPixtrimの時にも挑戦したけど
範囲選択でできたのは右下の点だけでの動きだけだった
今回は8個のすべての点で期待通りに動いている
今までうまく動かなかった原因の一つが
サイズ変更にマウスドラッグしているものを中心に考えていたから
今回でもそうだけどマウスドラッグしているのは
Labelコン
トロール(Labelオブジェクト?)
これの位置を判定してそこからPictureBoxのサイズと位置を変更しようとしていた
今回はマウスの移動距離を中心にして考えたっていうか計算した
移動距離と移動方向からPictureBoxのサイズと位置を設定して
それからLabelの位置を設定
つまりLabelはマウスで直接動かしている様に見えているけど本当は間接的に動かしている
基本から
最低限必要なイベントはMouseDownとMouseMoveのふたつ
Private Click_初期クリック位置 As Point
Private Sub Label1_MouseDown(sender As Object, e As MouseEventArgs) Handles Label1.MouseDown
If e.Button = Windows.Forms.MouseButtons.Left Then
Click_初期クリック位置 = e.Location
End If
End Sub
Private Sub Label1_MouseMove(sender As Object, e As MouseEventArgs) Handles Label1.MouseMove
If e.Button = Windows.Forms.MouseButtons.Left Then
Dim mp移動先座標 As New Point(
e.X - Click_初期クリック位置.X + sender.location.x,
e.Y - Click_初期クリック位置.Y + sender.location.y)
sender.location = mp移動先座標
End If
End Sub
移動させるならこれだけ
内容とは関係無けどコードの途中で改行させたいとき、半角スペースとアンダーバーを使わなくてもできる場合があることを今日知ったのは↓から
今までも特に不便だと思っていなかったんだけど使ってみたらたしかに見やすくなる
内容に戻って、
Label1をマウスでクリックしたっていうMouseDownイベントで
クリックした位置はe.Locationでわかる、このクリックした位置ってのはLabel1の中の位置なのでLabel1のギリギリ左上をクリックした場合は(1,1)とかになる、
でそれを「Click_初期クリック位置」に記憶
Click_初期クリック位置 = e.Location
次はマウスを動かしたイベントのMouseMove
これもe.Locationで動いたマウスカーソルの位置がわかる
e.Xならx座標、e.Yはy座標がわかる
あとは引き算で
e.X - Click_初期クリック位置.X
e.Y - Click_初期クリック位置.Y
これでそれぞれマウスのx,yの移動距離がわかる
次はこの移動距離をLabel1のx,yにそれぞれ足し算すればいいだけ
e.X - Click_初期クリック位置.X + sender.location.x
e.Y - Click_初期クリック位置.Y + sender.location.y
senderはMouseMoveイベントの主、なので今回はLabel1になる
これでLabel1の移動先の位置が判明
マウスドラッグしているものしか動かさないないならこれでいいんだけど
連動していろいろ動かしたりサイズを変えたりする時は後回しにして
うまくいったのが今回
重要なのは動かしているものよりもマウスの移動距離だった
PictureBoxのサイズをマウスドラッグで変更
マウスの移動に対してPictureBoxをどう動かしたら辻褄が合うのか
「逆」ってあるのが+と-を入れ替えるってこと
「順」はそのままつかうってことで
「0」は必ず0をしていするってこと
PictureBoxやその他のコン
トロール全部の座標の基準は左上になっているので
左と上方向にサイズを変更する時は位置も変更しないとおかしな動きになる
ボタン(Label)で言うとR、RD、D以外の5つのボタンを使って左と上方向にサイズ変更する時は移動が必要
マウスの移動距離と動かしているLabelの組み合わせでPictureBoxのサイズと位置を設定してから
PictureBoxのサイズと位置を元にLabelの位置を決定
Pixtrimの時でもできなくて諦めて妥協した感じになっているから直したいけど
直せるかなあ
↓スッキリかけたと思い込んでいい気分になっている全文
Public Class Form1
Private Click_初期クリック位置 As Point
Private mp移動距離 As Point
Private list_Label As New Generic.List(Of Label)
Private lbl動かしているラベル As Label
Private Sub Label1_MouseDown(sender As Object, e As MouseEventArgs) Handles Label1.MouseDown, PictureBox1.MouseDown
If e.Button = Windows.Forms.MouseButtons.Left Then
Click_初期クリック位置 = e.Location
End If
End Sub
Private Sub Label1_MouseMove(sender As Object, e As MouseEventArgs) Handles Label1.MouseMove, PictureBox1.MouseMove
If e.Button = Windows.Forms.MouseButtons.Left Then
Dim mp移動先座標 As New Point(
e.X - Click_初期クリック位置.X + sender.location.x,
e.Y - Click_初期クリック位置.Y + sender.location.y)
sender.location = mp移動先座標
End If
End Sub
Private Sub MouseDownマウスクリック初期位置(sender As Object, e As MouseEventArgs)
Click_初期クリック位置 = e.Location
lbl動かしているラベル = sender
End Sub
Private Sub MouseMoveマウスドラッグでPictureBoxサイズと位置を変更(sender As Object, e As MouseEventArgs)
If e.Button = Windows.Forms.MouseButtons.Left Then
mp移動距離 = New Point(
e.X - Click_初期クリック位置.X,
e.Y - Click_初期クリック位置.Y)
Call PictureBoxの大きさ変更(sender)
Dim ps = ラベルの位置配列(Me.PictureBox1)
Dim lName() As String = {"LU", "LD", "RU", "RD", "U", "D", "L", "R"}
For i As Integer = 0 To UBound(lName)
Me.Controls(lName(i)).Location = ps(i)
Next
End If
End Sub
Private Sub ラベル表示()
Call ラベル非表示()
Dim ps = ラベルの位置配列(Me.PictureBox1)
Dim lSize As Integer = 10
Dim lName() As String = {"LU", "LD", "RU", "RD", "U", "D", "L", "R"}
For i As Integer = 0 To UBound(ps)
Dim L As New Label
With L
.Location = ps(i)
.Name = lName(i)
.Width = lSize
.Height = lSize
.BackColor = Color.LimeGreen
.Cursor = Cursors.Hand
End With
Me.Controls.Add(L)
L.BringToFront()
list_Label.Add(L)
AddHandler L.MouseDown, AddressOf MouseDownマウスクリック初期位置
AddHandler L.MouseMove, AddressOf MouseMoveマウスドラッグでPictureBoxサイズと位置を変更
Next
Me.Controls("RD").BringToFront()
End Sub
Private Sub ラベル非表示()
If list_Label.Count = 0 Then Exit Sub
For i As Integer = 0 To list_Label.Count - 1
Me.Controls.Remove(list_Label.Item(i))
list_Label.Item(i).Dispose()
Next
list_Label.Clear()
End Sub
Private Sub PictureBoxの大きさ変更(L As Label)
Dim x移動距離 As Integer = mp移動距離.X
Dim y移動距離 As Integer = mp移動距離.Y
Dim soサイズ加算値 As New Point(0, 0)
Dim ps画像サイズ As New Point(Me.PictureBox1.Size)
Dim mo画像移動加算値 As New Point(0, 0)
Dim pp画像位置 As New Point(Me.PictureBox1.Location)
Select Case L.Name
Case "U"
soサイズ加算値 = New Point(0, -y移動距離)
mo画像移動加算値 = New Point(0, y移動距離)
Case "D"
soサイズ加算値 = New Point(0, y移動距離)
mo画像移動加算値 = New Point(0, 0)
Case "L"
soサイズ加算値 = New Point(-x移動距離, 0)
mo画像移動加算値 = New Point(x移動距離, 0)
Case "R"
soサイズ加算値 = New Point(x移動距離, 0)
mo画像移動加算値 = New Point(0, 0)
Case "LU"
soサイズ加算値 = New Point(-x移動距離, -y移動距離)
mo画像移動加算値 = New Point(x移動距離, y移動距離)
Case "RU"
soサイズ加算値 = New Point(x移動距離, -y移動距離)
mo画像移動加算値 = New Point(0, y移動距離)
Case "RD"
soサイズ加算値 = New Point(x移動距離, y移動距離)
mo画像移動加算値 = New Point(0, 0)
Case "LD"
soサイズ加算値 = New Point(-x移動距離, y移動距離)
mo画像移動加算値 = New Point(x移動距離, 0)
End Select
If ps画像サイズ.X + soサイズ加算値.X < 1 Or ps画像サイズ.Y + soサイズ加算値.Y < 1 Then
soサイズ加算値 = New Point(0, 0)
mo画像移動加算値 = New Point(0, 0)
End If
ps画像サイズ.Offset(soサイズ加算値)
pp画像位置.Offset(mo画像移動加算値)
Me.PictureBox1.Size = ps画像サイズ
Me.PictureBox1.Location = pp画像位置
End Sub
Private Function ラベルの位置配列(pb As PictureBox) As Point()
Dim picL As Integer = pb.Left
Dim picT As Integer = pb.Top
Dim picW As Integer = pb.Width
Dim picH As Integer = pb.Height
Dim pLU As New Point(Me.PictureBox1.Location)
Dim pLD As New Point(picL, picT + picH)
Dim pRU As New Point(picL + picW, picT)
Dim pRD As New Point(picL + picW, picT + picH)
Dim pU As New Point(picL + (picW / 2), picT)
Dim pD As New Point(picL + (picW / 2), picT + picH)
Dim pL As New Point(picL, picT + (picH / 2))
Dim pR As New Point(picL + picW, picT + (picH / 2))
Dim ps() As Point = {pLU, pLD, pRU, pRD, pU, pD, pL, pR}
Return ps
End Function
End Class
こうしてみると長いな
画像だとこう、画像の大きさ1025x5148
実行ファイルとソースダウンロード先1
8年後