larrysy
asked on
synchronized window move
How do I move Form2 relative to Form1 automatically when I move Form1?
I have the following code which will move Form2 when I resize Form1, but I want to move Form2 when I move Form1 (something like Form_Move)
Private Sub Form_Load()
Form2.Show
End Sub
Private Sub Form_Resize()
Form2.Left = Me.Left
Form2.Top = Me.Top + Me.Height
End Sub
I have the following code which will move Form2 when I resize Form1, but I want to move Form2 when I move Form1 (something like Form_Move)
Private Sub Form_Load()
Form2.Show
End Sub
Private Sub Form_Resize()
Form2.Left = Me.Left
Form2.Top = Me.Top + Me.Height
End Sub
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
I tried the following code in Form2 and it works, any loopholes?
Private Sub Form_Resize()
If Me.WindowState = 1 Then HookWindow Form1.hWnd
End Sub
Private Sub Form_Resize()
If Me.WindowState = 1 Then HookWindow Form1.hWnd
End Sub
ASKER
Another question:
I put the following code in Form1 for undocking - is it correct?
Private Sub Command2_Click()
HookWindow Me.hWnd
End Sub
However, if I click on Command1 again, the docking doesnt work.
I put the following code in Form1 for undocking - is it correct?
Private Sub Command2_Click()
HookWindow Me.hWnd
End Sub
However, if I click on Command1 again, the docking doesnt work.
' -------------------------- -----
' Form1
' -------------------------- -----
Option Explicit
Private Sub Form_Load()
' center the form
Me.Left = (Screen.Width / 2) - (Me.Width / 2)
Me.Top = (Screen.Height / 2) - (Me.Height / 2)
' subclass the window
HookWindow Me.hWnd
End Sub
Private Sub Command1_Click()
Form2.Move Form1.Left, Form1.Top + Form1.Height
Form2.Show
End Sub
Private Sub Command2_Click()
HookWindow Me.hWnd
If lPrevProc <> 0 Then
If Form2.WindowState = vbNormal And Form2.Visible Then
Form2.Move Form1.Left, Form1.Top + Form1.Height
End If
End If
End Sub
Private Sub Form_Resize()
If Me.WindowState = vbNormal And Me.Visible Then
If Form2.WindowState = vbNormal And Form2.Visible Then
Form2.Move Form1.Left, Form1.Top + Form1.Height
End If
End If
End Sub
Private Sub Form_Unload(Cancel As Integer)
If lPrevProc <> 0 Then
HookWindow Me.hWnd
End If
End Sub
' -------------------------- -----
' Form2
' -------------------------- -----
Option Explicit
Private Sub Form_Resize()
If Me.WindowState = vbNormal And Me.Visible Then
If Form1.WindowState = vbNormal And Form1.Visible Then
Me.Move Form1.Left, Form1.Top + Form1.Height
End If
End If
End Sub
' -------------------------- -----
' Module1
' -------------------------- -----
Option Explicit
Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" _
(ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal msg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
(ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Const GWL_WNDPROC As Long = (-4)
Public Const WM_MOVING = &H216
Public Const WM_SIZING = &H214
Public lPrevProc As Long
Public Sub HookWindow(ByVal lHandle As Long)
If lPrevProc = 0 Then
lPrevProc = SetWindowLong(lHandle, GWL_WNDPROC, AddressOf HookProc)
Else
Call SetWindowLong(lHandle, GWL_WNDPROC, lPrevProc)
lPrevProc = 0
End If
End Sub
Public Function HookProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Select Case uMsg
Case WM_SIZING, WM_MOVING
If Form2.WindowState = vbNormal And Form2.Visible Then
Form2.Move Form1.Left, Form1.Top + Form1.Height
End If
HookProc = 1
Exit Function
End Select
HookProc = CallWindowProc(lPrevProc, hWnd, uMsg, wParam, lParam)
End Function
' Form1
' --------------------------
Option Explicit
Private Sub Form_Load()
' center the form
Me.Left = (Screen.Width / 2) - (Me.Width / 2)
Me.Top = (Screen.Height / 2) - (Me.Height / 2)
' subclass the window
HookWindow Me.hWnd
End Sub
Private Sub Command1_Click()
Form2.Move Form1.Left, Form1.Top + Form1.Height
Form2.Show
End Sub
Private Sub Command2_Click()
HookWindow Me.hWnd
If lPrevProc <> 0 Then
If Form2.WindowState = vbNormal And Form2.Visible Then
Form2.Move Form1.Left, Form1.Top + Form1.Height
End If
End If
End Sub
Private Sub Form_Resize()
If Me.WindowState = vbNormal And Me.Visible Then
If Form2.WindowState = vbNormal And Form2.Visible Then
Form2.Move Form1.Left, Form1.Top + Form1.Height
End If
End If
End Sub
Private Sub Form_Unload(Cancel As Integer)
If lPrevProc <> 0 Then
HookWindow Me.hWnd
End If
End Sub
' --------------------------
' Form2
' --------------------------
Option Explicit
Private Sub Form_Resize()
If Me.WindowState = vbNormal And Me.Visible Then
If Form1.WindowState = vbNormal And Form1.Visible Then
Me.Move Form1.Left, Form1.Top + Form1.Height
End If
End If
End Sub
' --------------------------
' Module1
' --------------------------
Option Explicit
Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" _
(ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal msg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
(ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Const GWL_WNDPROC As Long = (-4)
Public Const WM_MOVING = &H216
Public Const WM_SIZING = &H214
Public lPrevProc As Long
Public Sub HookWindow(ByVal lHandle As Long)
If lPrevProc = 0 Then
lPrevProc = SetWindowLong(lHandle, GWL_WNDPROC, AddressOf HookProc)
Else
Call SetWindowLong(lHandle, GWL_WNDPROC, lPrevProc)
lPrevProc = 0
End If
End Sub
Public Function HookProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Select Case uMsg
Case WM_SIZING, WM_MOVING
If Form2.WindowState = vbNormal And Form2.Visible Then
Form2.Move Form1.Left, Form1.Top + Form1.Height
End If
HookProc = 1
Exit Function
End Select
HookProc = CallWindowProc(lPrevProc, hWnd, uMsg, wParam, lParam)
End Function
>> Is there a way to dock Form2 to Form1 automatically when Form2 is in the vicinity of the docking area?
You would have to subclass Form2 exactly as we did with Form1. Then when the sizing or moving messages fire, you would check Form2s location in relation to Form1s and if they are close enough, dock Form2 to Form1.
~IM
You would have to subclass Form2 exactly as we did with Form1. Then when the sizing or moving messages fire, you would check Form2s location in relation to Form1s and if they are close enough, dock Form2 to Form1.
~IM
ASKER
Thanks, your code example is a big help!
One final question, if you close Form1 without clicking any buttons, the program wont end properly but hangs in HookProc. Any way to remedy this aside from using END ? Or, is it OK to use END?
One final question, if you close Form1 without clicking any buttons, the program wont end properly but hangs in HookProc. Any way to remedy this aside from using END ? Or, is it OK to use END?
Don't use the Stop button in the IDE when you have subclassed a form as this usually causes the IDE to crash. Always provided a way to close your app somehow that will result in the form being unhooked properly. When subclassing is involved, always save your work before running the application since any minor error can result in the IDE crashing. Welcome to subclassing... =\
~IM
~IM
ASKER
Thank you very much for your tiips !!
larry
larry
ASKER
Follow-up questions,
How do I prevent the error when I move Form1 after I minimize Form2?
Is there a way to dock Form2 to Form1 automatically when Form2 is in the vicinity of the docking area?