Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Easy MDI Child Forms from DLL with Visual Basic (VB6)

1,090 views
Skip to first unread message

Kent Bolton

unread,
Mar 6, 2002, 1:15:42 AM3/6/02
to
I have been researching how to pull up child MDI forms from external
dlls. Every post had similar issues: If you make a form in a dll a MDI
Child, it complains that there is not parent MDI Form. You cannot
change the property of a form to MDI Child during runtime etc etc etc.

An easy way to do this is:

1. Create your dll forms as MDIChild=False
2. Create a container MDI Child form with a Private WithEvents
m_frmDLL As Form
3. Load the dll form (You can use Forms.Add "FormName" if you can
get the DLL's Forms collection - pretty much undocumented but
useful if you have a data driven framework !)
4. Create a new instance of the container MDI Child form
5. Set the parent of the dll form to the container form
6. Set the Window Style to Visible, with no Extended styles using
the API
7. Make the app a litle more bullet proof by setting everything
back to normal in both the dllForm_QueryUnload and QueryUnload
events in the container form.


Sample code below:

In a module:
------------
Public Declare Function SetParent& Lib "user32" (ByVal hWndChild As
Long, ByVal hWndNewParent As Long)
Public Declare Function SetWindowLong& Lib "user32" Alias
"SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal
dwNewLong As Long)
Declare Function LockWindowUpdate Lib "user32" (ByVal hwndLock As
Long) As Long

Public Const WS_CHILD& = &H40000000
Public Const WS_CHILDWINDOW& = (WS_CHILD)
Public Const WS_EX_MDICHILD& = &H40&
Public Const GWL_EXSTYLE& = (-20)
Public Const GWL_STYLE& = (-16)
Public Const WS_VISIBLE& = &H10000000

In your framework:
------------------

Dim DLLBusinessLogic As Object
Dim DLLForms As Object
Dim frmContainer As frmContainer
Dim frmDLL As Form

Set DLLBusinessLogic = CreateObject("Project2.class1")

Set DLLForms = DLLBusinessLogic.getforms

Set frmDLL = DLLForms.Add("form1") ' This loads a form named Form1 -
neat !
Set frmContainer = New frmContainer
Set frmContainer.DLLForm = frmDLL
Set frmDLL = Nothing


In your generic container MDI Child form:
-----------------------------------------

Option Explicit

Private WithEvents m_frmDLL As Form

Public Property Set DLLForm(RHS As Form)
' Set up our DLL Form
Set m_frmDLL = RHS

' Stop drawing of the form
LockWindowUpdate m_frmDLL.hWnd

' Set my parent as the container form
SetParent m_frmDLL.hWnd, Me.hWnd

' Clear all styles
SetWindowLong m_frmDLL.hWnd, GWL_STYLE, WS_VISIBLE
SetWindowLong m_frmDLL.hWnd, GWL_EXSTYLE, 0&

' Move and redraw the form
m_frmDLL.Move 0, 0, Me.ScaleWidth, Me.ScaleHeight
LockWindowUpdate 0&
m_frmDLL.Refresh
End Property

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
' If closing the container form, make sure we reset everything back
' to how it was for VB
m_frmDLL.Visible = False
SetParent m_frmDLL.hWnd, 0&
Unload m_frmDLL
End Sub

Private Sub Form_Resize()
' Resize our dll form
If Not m_frmDLL Is Nothing Then
m_frmDLL.Move 0, 0, Me.ScaleWidth, Me.ScaleHeight
End If
End Sub

Private Sub m_frmDLL_QueryUnload(Cancel As Integer, UnloadMode As
Integer)
' If for some reason the dll form is going to be unloaded,
' unload the container form as well !
Unload Me
End Sub

In your DLL Form:
-----------------

* Standard form MDIChild=False
* Anything you want ... or so far this is the case !
* Just do not Do not resize the form itself - just the controls inside
it !

0 new messages