Diese Seite wurde zuletzt aktualisiert am 10.09.1999
Aktuell im ABOUT Visual Basic-MagazinGrundlagenwissen und TechnologienKnow How, Tipps und Tricks rund um Visual BasicActiveX-Komponenten, Controls, Klassen und mehr...AddIns für VB, VBA und OfficeVBA-Programmierung in MS-Office und anderen AnwendungenScripting-Praxis für den Windows Scripting Host und das Scripting-ControlTools, Komponenten und Dienstleistungen des MarktesRessourcen für Programmierer (Bücher, Job-Börse)Dies&Das...

Themen und Stichwörter im ABOUT Visual Basic-Magazin
Code, Beispiele, Komponenten, Tools im Überblick, Shareware, Freeware
Ihre Service-Seite, Termine, Job-Börse
Melden Sie sich an, um in den vollen Genuss des ABOUT Visual Basic-Magazins zu kommen!
Informationen zum ABOUT Visual Basic-Magazin, Kontakt und Impressum

Zurück...

Zurück...


Anzeige

Teil 3

Das weitere ist ein schönes Beispiel für den sinnvollen Einsatz einer Klasse. Die Klasse clsPosSize sorgt sowohl für die Speicherung der einmal festgelegten Position und Größe eines Komponententyps als auch für die Positionierung anhand der gespeicherten Werte. Da ja jederzeit neue Komponententypen das Licht der VB-Welt erblicken können, vermeiden wir damit eine feste Codierung, die sich allein auf bekannte Modultypen beschränken müsste.

Die im gesamten AddIn-Modul zur Verfügung stehende Collection mPosSizes nimmt die verschiedenen Instanzen zu jedem einzelnen Komponententyp auf. Zunächst wird auf gut Glück probiert, eine Instanz der Klasse mit der entsprechenden ID als Key in der Collection ausfindig zu machen. Schlägt der Versuch fehl, wird eine neue Instanz der Klasse angelegt und über den Aufruf der Methode Init dieser Klasse initialisiert.

          On Error Resume Next
          Set nPosSize = mPosSizes(nID)
          On Error GoTo 0
          If nPosSize Is Nothing Then
            Set nPosSize = New clsPosSize
            nPosSize.Init nID
            mPosSizes.Add nPosSize, nID
          End If

Bei dieser Initialisierung wird die ermittelte ID übergeben. Springen wir an dieser Stelle in die Prozedur der Init-Methode der clsPosSize-Klasse.

Public Sub Init(iID As String)
  pID = iID
  pHeight = CLng(GetSetting(kVBEWindowControl, pID, "Height", 0))
  pWidth = CLng(GetSetting(kVBEWindowControl, pID, "Width", 0))
  pLeft = CLng(GetSetting(kVBEWindowControl, pID, "Left", 0))
  pTop = CLng(GetSetting(kVBEWindowControl, pID, "Top", 0))
End Sub

Zuerst wird die übergebene ID in der Variablen pID festgehalten. Dann werden aus der Windows-Registrierung mit GetSetting die Werte für die Größe und die Position passend zur ID gelesen. Sollten die Werte noch nicht gespeichert sein, gibt GetSetting die Vorgabe 0 zurück. Die Werte werden hier nur für die Instanz festgehalten, jedoch noch nicht weiter verwendet.

Wieder zurück im AddIn-Modul wird das DesignerWindow unsichtbar gemacht. Manche Implementierungen von ActiveX-Desiger-Modulen scheinen die Unart zu haben, sichtbar zu werden, wenn sie positioniert werden, auch wenn sie zuvor unsichtbar waren - und diese Unart pflegen die VB-eigenen Code-Module anscheinend auch.

Dann wird die Move-Methode der Klasse aufgerufen

          With nDesignerWindow
            .Visible = False
            nPosSize.Move nDesignerWindow

Zusammen mit diesem Aufruf wird das DesignerWindow übergeben.

Public Sub Move(iWindow As Window)
  If CBool(pWidth) And CBool(pHeight) Then
    With iWindow
      .Left = pLeft
      .Top = pTop
      .Width = pWidth
      .Height = pHeight
    End With
  End If
End Sub

Nur wenn für den Komponententyp bereits eine Positionierung festgelegt worden ist, enthalten pWidth und pHeight gültige Werte (> 0). Und nur dann wird das Fenster jetzt positioniert.

Falls ein neues Projekt bereits mehrere Designer-Komponenten enthalten sollte, ist es sinnvoll, nur das Fenster des ersten zu öffnen und anzuzeigen - alle weiteren sollten geschlossen bleiben.

            If Not nFirst Then
              nFirst = True
              .Visible = True
            Else
              .Visible = False
            End If
          End With
        End If
        Set nPosSize = Nothing

Dann wird die Referenz auf die Designer-Instanz der Positionierungs-Klasse wieder freigegeben. Das gleiche Spiel wiederholt sich nun für das Code-Modul des Designers, bzw. es findet nun für eine reine Code-Komponente statt (Standard-Modul, Klassen-Modul). Für diese wird das zu positionierende Fenster über die Eigenschaft CodeModule und wiederum deren Eigenschaft CodePane herangezogen. Die ID für eine reine Code-Komponente braucht nicht ermittelt zu werden - sie ist in der Konstanten kCodeWindow ("CodeWindow") festgelegt.

        Set nCodeWindow = .CodeModule.CodePane.Window
        nID = kCodeWindow
        On Error Resume Next
        Set nPosSize = mPosSizes(nID)
        On Error GoTo 0
        If nPosSize Is Nothing Then
          Set nPosSize = New clsPosSize
          nPosSize.Init nID
          mPosSizes.Add nPosSize, nID
        End If
        With nCodeWindow
          .Visible = False
          nPosSize.Move nCodeWindow
          If Not nFirst Then
            nFirst = True
            .Visible = True
          Else
            .Visible = False
          End If
        End With
      End With
    Next
  End If
End Sub

Wird nun beim Hinzufügen einer weiteren Komponente zu einem Projekt das Ereignis eVBComponentsEvents_ItemAdded ausgelöst, wird das im Prinzip gleiche Verfahren für die betreffende Komponente angewandt. Der einzige bedeutendere Unterschied besteht in der Prüfung auf die Jungfräulichkeit hin. Da eine Komponente auf mehreren Dateien aufsetzen kann, steht dementsprechend eine Sammlung (bzw. ein Array) für mehrere Dateinamen zur Verfügung. Wir brauchen hier jedoch nur nachschauen, ob es einen ersten Dateinamen gibt.

Private Sub eVBComponentsEvents_ItemAdded(ByVal VBComponent _
 As VBIDE.VBComponent)
  Dim nFirst As Boolean
  Dim nDesignerWindow As Window
  Dim nCodeWindow As Window
  Dim nPosSize As clsPosSize
  Dim nID As String

  With VBComponent
    If Len(.FileNames(1)) = 0 Then
      nID = CStr(.Type) & .DesignerID
      Set nDesignerWindow = .DesignerWindow
      If Not (nDesignerWindow Is Nothing) Then
        nID = "D" & CStr(.Type) & .DesignerID
        On Error Resume Next
        Set nPosSize = mPosSizes(nID)
        On Error GoTo 0
        If nPosSize Is Nothing Then
          Set nPosSize = New clsPosSize
          nPosSize.Init nID
          mPosSizes.Add nPosSize, nID
        End If
        With nDesignerWindow
          .Visible = False
          nPosSize.Move nDesignerWindow
          If Not nFirst Then
            nFirst = True
            .Visible = True
          Else
            .Visible = False
          End If
        End With
      End If
      Set nPosSize = Nothing
      Set nCodeWindow = .CodeModule.CodePane.Window
      nID = kCodeWindow
      On Error Resume Next
      Set nPosSize = mPosSizes(nID)
      On Error GoTo 0
      If nPosSize Is Nothing Then
        Set nPosSize = New clsPosSize
        nPosSize.Init nID
        mPosSizes.Add nPosSize, nID
      End If
      With nCodeWindow
        .Visible = False
        nPosSize.Move nCodeWindow
        If Not nFirst Then
          nFirst = True
          .Visible = True
        Else
          .Visible = False
        End If
      End With
    End If
  End With
End Sub

Nun brauchen wir nur noch ein wenig aufzuräumen, damit die Grundfunktionalität des VBEWindowControl-AddIns fertig ist. Wird ein Projekt entfernt, ist es zuvor das aktive Projekt gewesen. Der Ordnung halber wird daher beim Eintreffen des Ereignisses eProjectEvents_ItemRemoved der Ereignisempfänger eVBComponents freigegeben.

Private Sub eProjectEvents_ItemRemoved(ByVal VBProject _
 As VBIDE.VBProject)
  Set eVBComponentsEvents = Nothing
End Sub

Private Sub eProjectEvents_ItemActivated(ByVal VBProject _
 As VBIDE.VBProject)
  Set eVBComponentsEvents = mVBE.Events.VBComponentsEvents(VBProject)
End Sub

Danach trifft jedoch sogleich das Ereignis eProjectEvents_ItemActivated ein, wenn noch andere Projekte geladen sind. Dieses nutzen wir, um den Ereignisempfänger eVBComponents nun erneut für das jetzt aktive Projekt zu installieren. Sind keine Projekte mehr geladen und wird statt dessen ein komplett neues Projekt geladen, wird der Ereignisempfänger automatisch im oben beschriebenen Ereignis eProjectEvents_ItemAdded installiert.

Das totale Aufräumen findet beim Entladen des AddIns im Ereignis AddinInstance_OnDisconnection statt, unabhängig vom in RemoveMode übergebenen Wert.

Private Sub AddinInstance_OnDisconnection(ByVal RemoveMode _
 As AddInDesignerObjects.ext_DisconnectMode, _
 custom() As Variant)
  Set mPosSizes = Nothing
  Set ePjFDesignerCmdButtonEvent = Nothing
  Set ePjFCodeWindowCmdButtonEvent = Nothing
  Set ePjMCodeWindowCmdButtonEvent = Nothing
  Set ePjFRestoreDesignerCmdButtonEvent = Nothing
  Set ePjFRestoreCodeWindowCmdButtonEvent = Nothing
  Set ePjMRestoreCodeWindowCmdButtonEvent = Nothing
  Set eVBComponentsEvents = Nothing
  Set eProjectEvents = Nothing
  Set mVBE = Nothing
End Sub

Fensterplätze - Teil 2 Teil 2    Teil 4 Fensterplätze - Teil 4


AddIn-Übersicht

Zum Seitenanfang

Copyright © 1999 - 2017 Harald M. Genauck, ip-pro gmbh  /  Impressum

Zum Seitenanfang

Zurück...

Zurück...

Download Internet Explorer