I want to move a picturebox using the mouse. I know how to do this but in this case the picturebox I want to move lies under another picturebox. So, Picture1 is top and Picture2 is under Picture1. When I mouse down on Picture1 I want that mouse click transferred to Picture2 so that Picture2 moves with the mouse instead of Picture1. any tricks of the trade to do this
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Any) As Long
Private Declare Function ReleaseCapture Lib "user32" () As Long
Private Const WM_NCLBUTTONDOWN = &HA1
Private Const WM_NCRBUTTONDOWN = &HA4
Private Const HTCAPTION = 2
Private Sub Picture1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
ReleaseCapture
SendMessage Picture2.hWnd, WM_NCLBUTTONDOWN, HTCAPTION, 0&
End Sub
That works very nice however it doesn't give me a MouseUp event which I need to enter.
What I need is something like this
Code:
Private Sub Picture1_MouseDown_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
Static lx As Single, ly As Single
If Button = 0 Then
lx = X
ly = Y
ElseIf Button = vbLeftButton Then
ReleaseCapture
Picture2.ZOrder 0
Picture2.Left = Picture2.Left + X - lx
Picture2.Top = Picture2.Top + Y - ly
End If
End Sub
Private Sub Picture2_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
If Button = vbLeftButton Then
'
' Do something
'
End If
End Sub
When I apply it to the above code Picture2 does not move nor Picture1.
Now the problem I have with your code is when Picture2 moves and is dropped somewhere I can get it's Left and Top but I can't move it unless I mouse down on Picture1 again. How do I be able to move Picture2 without using Picture1
Last edited by Code Dummy; May 18th, 2019 at 07:13 PM.
OK, I found an easy way - all you have to do is make Picture1 disabled
Code:
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Any) As Long
Private Declare Function ReleaseCapture Lib "user32" () As Long
Private Const WM_NCLBUTTONDOWN = &HA1
Private Const WM_NCRBUTTONDOWN = &HA4
Private Const HTCAPTION = 2
Private Sub Picture1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
ReleaseCapture
SendMessage Picture2.hWnd, WM_NCLBUTTONDOWN, HTCAPTION, 0&
MsgBox "MouseUp" & vbCrLf & "Picture2.Left = " & Picture2.Left & vbCrLf & "Picture2.Top = " & Picture2.Top
End Sub
Doesn't matter about what you do following the SendMessage you still can't move Picture2 later without mouse down on Picture1 and that is not a good thing
Option Explicit
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Any) As Long
Private Declare Function ReleaseCapture Lib "user32" () As Long
Private Const WM_NCLBUTTONDOWN = &HA1
Private Const HTCAPTION = 2
Private Sub Command1_Click()
Picture2.Top = Picture2.Top + 100
End Sub
Private Sub Picture1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
MovePic2
End Sub
Private Sub Picture2_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
MovePic2
End Sub
Private Sub MovePic2()
ReleaseCapture
SendMessage Picture2.hWnd, WM_NCLBUTTONDOWN, HTCAPTION, 0&
MsgBox "MouseUp" & vbCrLf & "Picture2.Left = " & Picture2.Left & vbCrLf & "Picture2.Top = " & Picture2.Top
End Sub
Last edited by Eduardo-; May 18th, 2019 at 09:50 PM.
Option Explicit
Private m_DragBoxIndex As Long
Private m_DragX As Single
Private m_DragY As Single
Private Sub Picture1_MouseDown(Index As Integer, Button As Integer, Shift As Integer, X As Single, Y As Single)
Select Case Button
Case vbLeftButton
m_DragX = X
m_DragY = Y
End Select
End Sub
Private Sub Picture1_MouseMove(Index As Integer, Button As Integer, Shift As Integer, X As Single, Y As Single)
Select Case Button
Case vbLeftButton
With Me.Picture1(m_DragBoxIndex)
.Move .Left + (X - m_DragX), _
.Top + (Y - m_DragY)
m_DragX = X
m_DragY = Y
End With
End Select
End Sub
Private Sub Picture1_MouseUp(Index As Integer, Button As Integer, Shift As Integer, X As Single, Y As Single)
Select Case Button
Case vbLeftButton
m_DragX = 0
m_DragY = 0
End Select
End Sub
On a form with 2 PictureBoxes in a control array, you can click and drag on either and only the PictureBox at Index m_DragBoxIndex will be moved.
Here's the simplest way I found. Picture2 is under Picture1 and Picture1 is disabled so all mouse clicks go through Picture1 to Picture2. I could even simplify it more by removing Picture2.MouseDown
@Eduardo
I don't want to use a CommandButton to manipulate Picture2
Code:
Private Sub Picture2_Mousedown(Button As Integer, Shift As Integer, X As Single, Y As Single)
If Button = vbLeftButton Then
Picture2.ZOrder 0
End If
End Sub
Private Sub Picture2_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
Static lx As Single, ly As Single
If Button = 0 Then
lx = X
ly = Y
ElseIf Button = vbLeftButton Then
Picture2.Left = Picture2.Left + X - lx
Picture2.Top = Picture2.Top + Y - ly
End If
End Sub
Private Sub Picture2_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
If Button = vbLeftButton Then
Picture1.ZOrder 0
End If
End Sub
Here's the simplest way I found. Picture2 is under Picture1 and Picture1 is disabled so all mouse clicks go through Picture1 to Picture2. I could even simplify it more by removing Picture2.MouseDown
@Eduardo
I don't want to use a CommandButton to manipulate Picture2
Code:
Private Sub Picture2_Mousedown(Button As Integer, Shift As Integer, X As Single, Y As Single)
If Button = vbLeftButton Then
Picture2.ZOrder 0
End If
End Sub
Private Sub Picture2_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
Static lx As Single, ly As Single
If Button = 0 Then
lx = X
ly = Y
ElseIf Button = vbLeftButton Then
Picture2.Left = Picture2.Left + X - lx
Picture2.Top = Picture2.Top + Y - ly
End If
End Sub
Private Sub Picture2_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
If Button = vbLeftButton Then
Picture1.ZOrder 0
End If
End Sub
I updated the sample in #7 after you read it. It is very simple. You just need to move the picture from both pictures, not just from Picture1.
OK, now that's a lot better. However, the reason I'm not using the ReleaseCapture and SendMessage method is because I can't track the mouse movements while I'm moving Picture2 around. It appears that only after Picture2 has been dropped can you get the current positions which in most cases that would be OK, otherwise your version 3 is really nice. Maybe I'll do some changes to my project so I can implement version 3. Thanks for all your help
Ah, OK. If you need to track the position while dragging then use jpbro's code.
You need to try to understand the code, because changing from the example of post #5 to the example of post #7 was very easy and quite obvious.
(you only needed to copy the code that moved the picture of the MouseDown code of Picture1 to the MouseDown code of Picture2. -I actually moved the code to a new procedure and call it from both events, but it is the same-)
If you don't understand the logic of programming you'll always need someone to do the things for you.
Last edited by Eduardo-; May 18th, 2019 at 11:03 PM.
If you are programming only code in the events of Picture2, how do you expect it to also work handling events of Picture1?
Of course with that code you'll will be able to move Picture2 by dragging on Picture2, but not by dragging on Picture1 because the code only works by clicking on Picture2.
If you want to add the ability to move Picture2 also from Picture1, you need to add the code in the events of Picture1.
Picture1 is only a cover, it needs no mouse events. Only Picture2 is to be moved. With this in mind I think my code will give me exactly what I need I just didn't know about making Picture1 disabled when I first started this thread.
I misunderstood what you were asking. I thought that you wanted to move Picture2 by dragging in any place of Picture1, but I see now that you instead wanted to move Picture2 only when clicking in the rectangle over Picture2 (not anywhere on Picture1).
Actually I misunderstood my own post Sorry about that
The problem is that Picture2 is not under Picture1, it is positioned somewhere else but when I click on Picture1 I want Picture2 to appear above Picture1 and have it be moved instead of Picture1
So, in view of this your example from post #7 appears to work the best
Code:
Option Explicit
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Any) As Long
Private Declare Function ReleaseCapture Lib "user32" () As Long
Private Const WM_NCLBUTTONDOWN = &HA1
Private Const HTCAPTION = 2
Private Sub Picture1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
Picture2.Move Picture1.Left, Picture1.Top
Picture2.ZOrder 0
MovePic2
End Sub
Private Sub Picture2_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
MovePic2
End Sub
Private Sub MovePic2()
ReleaseCapture
SendMessage Picture2.hWnd, WM_NCLBUTTONDOWN, HTCAPTION, 0&
Picture1.ZOrder 0
MsgBox "MouseUp" & vbCrLf & "Picture2.Left = " & Picture2.Left & vbCrLf & "Picture2.Top = " & Picture2.Top
End Sub