Von Haus aus bietet Visual Basic so gut wie keine direkte
Verbindung und Kommunikation eines MDI-Forms mit seinen
MDI-Child-Forms. Zwar können Sie innerhalb einer Anwendung
jederzeit aus der Forms-Sammlung
das MDI-Form und die MDI-Child-Forms herausfischen und einen
Menüpunkt im MDI-Form über das Setzen der Eigenschaft WindowList
dazu bringen, eine Liste der geöffneten Child-Forms aufzunehmen.
Aber das ist dann eigentlich schon alles.
Das Grundprinzip einer Verbindungsstruktur ist recht einfach.
Jedes Child-Form meldet sich in seinem Form_Load-Ereignis beim
MDI-Form über dort eingefügte, zusätzliche öffentliche Methoden
an (OnChildOpen) und in seinem Form-Unload-Ereignis wieder ab (OnChildClose).
Private Sub Form_Load()
MDIForm.OnChildOpen Me
End Sub
Private Sub Form_Unload(Cancel As Integer)
MDIForm.OnChildClose Me
End Sub
Allerdings muss das Child-Form dazu das MDI-Form kennen. Sie
können natürlich den Namen des MDI-Forms verwenden, den Sie diesem
in Ihrer Anwendung individuell gegeben haben. Wenn Sie Ihre
Child-Forms jedoch projektübergeifend wiederverwenden wollen, ist
ein universellerer Zugriff sinnvoller. Entweder deklarieren Sie dazu
in einem Standard-Modul eine öffentliche (und damit global
verfügbare) Variable wie etwa MDIForm, die vom MDI-Form in seinem
Form_Load-Ereignis gesetzt wird (Set MDI-Form = Me).
Oder Sie schreiben in ein Standard-Modul eine öffentliche Funktion
des (beispielsweise gleichfalls MDIForm genannt), in der das
MDI-Form aus der allgemeinen Forms-Sammlung herausgesucht wird. Da
ein MDI-Form in einer Anwendung sowieso nur ein einziges Mal
vorhanden sein kann und auch meistens als eines der ersten Forms
geladen wird, steht es nahe am Anfang der Sammlung und wird daher
ohne spürbaren Performance-Verlust sofort gefunden.
Public Function MDIForm() As Form
Dim nForm As Form
For Each nForm In Forms
If TypeOf nForm Is MDIForm Then
Set MDIForm = nForm
Exit Function
End If
Next 'nForm
End Function
Das MDI-Form hält die sich anmeldenden Child-Forms in einer
eigenen Sammlung (Collection pChildForms) fest, gibt diesem
Child-Form eine eindeutige Identitätsnummer, die dort in der
öffentlichen Variablen namens ID gespeichert wird, und entfernt es
beim Abmelden wieder aus dieser Collection. Die ID wird automatisch
immer weiter hochgezählt und dürfte als Datentyp Long für die
gesamte Laufzeit einer Anwendung ausreichend dimensioniert sein.
Im Child-Form:
Public ID As Long
Im MDI-Form:
Private mChildFormsIDs As Long
Private pChildForms As Collection
Private Sub MDIForm_Load()
Set pChildForms = New Collection
End Sub
Public Sub OnChildClose(ChildForm As Form)
pChildForms.Remove CStr(ChildForm.ID)
End Sub
Public Sub OnChildOpen(ChildForm As Form)
mChildFormsIDs = mChildFormsIDs + 1
pChildForms.Add ChildForm, CStr(mChildFormsIDs)
ChildForm.ID = mChildFormsIDs
End Sub
Die geöffneten und damit angemeldeten Child-Forms können über
eine Eigenschaft ChildForms (im MDI-Form) und der ID als Schlüssel
jederzeit abgefragt werden:
Public Property Get ChildForm(ByVal ID As Long) As Form
On Error Resume Next
Set ChildForm = pChildForms(CStr(ID))
End Property
Diesen Benachrichtigungsmechanismus können sie beliebig
erweitern. Versehen Sie das MDI-Form einfach mit weiteren
öffentlichen OnChild...-Methoden, die dann von den
Child-Forms entsprechend aufgerufen werden. Aus dem
Form_Activate-Ereignis eines Child-Forms könnten Sie beispielsweise
OnChildActivate aufrufen, um dem MDI-Form den Wechsel des gerade
aktiven ChildForms mitzuteilen. Das MDI-Form weiß zwar über seine
Eigenschaft ActiveForm immer, welches Child-Form gerade aktiv ist -
eine Benachrichtigung über einen Wechsel bekommt es von Visual
Basic jedoch nicht.
Public Sub OnChildActivate(ChildForm As Form)
' Zum Beispiel:
lblActive.Caption = "ChildForm" & ChildForm.ID
End Sub
Enthält Ihre Anwendung neben dem MDI-Form und seinen Child-Forms
noch weitere Forms, die ebenfalls geladen sind (etwa Werkzeugfenster
und dergleichen), können Sie nun die pChildForms-Collection
verwenden, um ausschließlich auf die Child-Forms zuzugreifen,
anstelle diese jedes Mal aus der allgemeinen Forms-Sammlung
herausfischen zu müssen. Beispiel:
Dim nChildForm As Form
For Each nChildForm In pChildForms
' ...
Next

|