Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Moving 2 docked forms with titlebar (VB6)

Status
Not open for further replies.

Mania

Technical User
Jan 23, 2002
11
US
doc2 is set as not movable and docks to doc1, If I use MDIForm_mouse down and move events it works great but moving with the title bar only moves doc1. I would rather move with title bar and eliminate mdiform events.. I could elimante the control box and add a picture box but I don't know how to place this above the menu, mdi forms are finicky :)

What's the best way to handle this ?
 
IMHO there would be a better solution than moving the forms together around but you asked for it so i could show up a possible solution to this particular problem... You could subclass the forms windows procedure to catch the WM_MOVE event and inform the other form from the move so it is able to reposition itself according to the new position of the other form. The code could look something like this (not good tested, just a fingertip towards the direction).

Create a project with one MDIForm, one module, one class named clsSyncMove and the two forms form1 (with button1 on it) and form2 to move together.
In the module paste:
Code:
Option Explicit
              
Private Declare Function SetWindowLong Lib "user32" Alias _
        "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex _
        As Long, ByVal dwNewLong As Long) As Long

Private 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

Const GWL_WNDPROC = (-4&)
Const WM_MOVE = &H3
Private Const WM_SYSCOMMAND = &H112

Private PrevWndProc1 As Long
Private PrevWndProc2 As Long
Private lngmHwnd1 As Long
Private lngmHwnd2 As Long
Private objmEventRouter As clsSyncMove

Public Sub Init(lngpHwnd1 As Long, lngpHwnd2 As Long, objpSyncMove As clsSyncMove)
    Set objmEventRouter = objpSyncMove
    PrevWndProc1 = SetWindowLong(lngpHwnd1, GWL_WNDPROC, AddressOf SubWndProc)
    lngmHwnd1 = lngpHwnd1
    PrevWndProc2 = SetWindowLong(lngpHwnd2, GWL_WNDPROC, AddressOf SubWndProc)
    lngmHwnd2 = lngpHwnd2
End Sub

Public Sub Terminate()
  SetWindowLong lngmHwnd1, GWL_WNDPROC, PrevWndProc1
  SetWindowLong lngmHwnd2, GWL_WNDPROC, PrevWndProc2
End Sub

Private Function SubWndProc(ByVal hwnd As Long, ByVal Msg As Long, _
                            ByVal wParam As Long, _
                            ByVal lParam As Long) As Long
    Static blnWorking As Boolean
    
    If blnWorking = False Then
        blnWorking = True
        If Msg = WM_MOVE Then
            objmEventRouter.WindowMoved hwnd
        End If
        blnWorking = False
    End If
    If hwnd = lngmHwnd1 Then
        SubWndProc = CallWindowProc(PrevWndProc1, hwnd, Msg, wParam, lParam)
    Else
        SubWndProc = CallWindowProc(PrevWndProc2, hwnd, Msg, wParam, lParam)
    End If
End Function


In the class paste
Code:
Option Explicit

Private frmmForm1 As Form
Private frmmForm2 As Form
Private blnmAlignTop As Boolean

Friend Property Get AlignTop() As Boolean
    Let AlignTop = blnmAlignTop
End Property
Friend Property Let AlignTop(blnpAlignTop As Boolean)
    Let blnmAlignTop = blnpAlignTop
End Property

Friend Property Get Form1() As Form
    Set Form1 = frmmForm1
End Property
Friend Property Set Form1(frmpForm As Form)
    Set frmmForm1 = frmpForm
End Property

Friend Property Get Form2() As Form
    Set Form2 = frmmForm2
End Property
Friend Property Set Form2(frmpForm As Form)
    Set frmmForm2 = frmpForm
End Property

Friend Sub InitAligne()
    Init Form1.hwnd, Form2.hwnd, Me
End Sub

Private Sub Class_Terminate()
    If Not frmmForm1 Is Nothing Then
        Terminate
    End If
End Sub

Public Sub WindowMoved(lngpHwnd As Long)
    Static blnWorking As Boolean
    
    If blnWorking = False Then
        blnWorking = True
        If lngpHwnd = frmmForm1.hwnd Then
            ' Form1 has been moved
            If blnmAlignTop = True Then
                frmmForm2.Top = frmmForm1.Top
                frmmForm2.Left = frmmForm1.Left + frmmForm1.Width
            Else
                frmmForm2.Left = frmmForm1.Left
                frmmForm2.Top = frmmForm1.Top + frmmForm1.Height
            End If
        Else
            ' Form2 has been moved
            If blnmAlignTop = True Then
                frmmForm1.Top = frmmForm2.Top
                frmmForm1.Left = frmmForm2.Left - frmmForm1.Width
            Else
                frmmForm1.Top = frmmForm2.Top - frmmForm1.Height
                frmmForm1.Left = frmmForm2.Left
            End If
        End If
        blnWorking = False
    End If
End Sub


In the form1 paste
Code:
Option Explicit

Private objmSyncMove As clsSyncMove
Option Explicit

Private objmSyncMove As clsSyncMove

Private Sub Command1_Click()
    objmSyncMove.AlignTop = Not objmSyncMove.AlignTop
    objmSyncMove.WindowMoved Me.hwnd
End Sub

Private Sub Form_Load()
    Set objmSyncMove = New clsSyncMove
    Set objmSyncMove.Form1 = Me
    Form2.Show
    Set objmSyncMove.Form2 = Form2
    objmSyncMove.InitAligne
    objmSyncMove.WindowMoved Me.hwnd
End Sub

Private Sub Form_Unload(Cancel As Integer)
  Terminate
End Sub

Private Sub Form_Load()
    Set objmSyncMove = New clsSyncMove
    Set objmSyncMove.Form1 = Me
    Form2.Show
    Set objmSyncMove.Form2 = Form2
    objmSyncMove.InitAligne
    objmSyncMove.WindowMoved Me.hwnd
End Sub

Private Sub Form_Unload(Cancel As Integer)
  Terminate
End Sub


In form1 past
Code:
Option Explicit

Private Sub MDIForm_Load()
    Form1.Show
End Sub


Please be aware that it's very dangerous to debug a program with subclassing in it, so I would create an ActiveX out of the Class and the module and only use it as DLL.

hope this helps
Andreas
 
Thanks Andreas,

I figured it would involve wm_move but I didn't even know where to start, I'll get this into a dll as you suggest and let you know how it works out.. BTW nice piece of code!

Charles
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top