ABOUT Visual Basic Programmieren Programmierung Download Downloads Tips & Tricks Tipps & Tricks Know-How Praxis VB VBA Visual Basic for Applications VBS VBScript Scripting Windows ActiveX COM OLE API ComputerPC Microsoft Office Microsoft Office 97 Office 2000 Access Word Winword Excel Outlook Addins ASP Active Server Pages COMAddIns ActiveX-Controls OCX UserControl UserDocument Komponenten DLL EXE
Diese Seite wurde zuletzt aktualisiert am 05.11.2001

Diese Seite wurde zuletzt aktualisiert am 05.11.2001
Aktuell im ABOUT Visual Basic-MagazinGrundlagenwissen und TechnologienKnow How, Tipps und Tricks rund um Visual BasicActiveX-Komponenten, Controls, Klassen und mehr...AddIns für die Visual Basic-IDE und die VBA-IDEVBA-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...

Lichtausmacher

Zurück...


Anzeige

(-hg) mailto:hg_secureflag@aboutvb.de

"Der Letzte macht das Licht aus!" - dieser Spruch impliziert wohl auch, dass niemand das Licht ausmachen soll, solange noch jemand im Raum ist. Programmiertechnisch bedeutet dies, dass beispielsweise eine Sperrvariable (Flag) von mehreren Stellen aus im Code gesetzt werden kann, die Freigabe aber erst dann erfolgen soll, nachdem alle Stellen, die zuvor eine Sperrung veranlasst haben, die Sperrung auch tatsächlich wieder zurück genommen haben. Wichtig wird eine solche "sichere" Sperrung bei mehrstufig verschachtelten Aufrufen. Das folgende einfache Beispiel zeigt, dass es bei zunehmender Komplexität eines Programmes leicht zu unbeabsichtigten Seiteneffekten kommen kann, wenn eine solche Sperrvariable einfach direkt gesetzt oder freigegeben würde:

Private mFlag As Boolean

Private Sub ProzedurA()
  mFlag = True
  List1.ListIndex = List1.ListCount
  mFlag = False
End Sub

Private Sub List1_Click()
  If mFlag Then
    MsgBox "OK"
  End If
End Sub

Beabsichtigt ist, dass die MessageBox nur dann erscheint, wenn der ListIndex der ListBox List1 per Code, beispielsweise in der Prozedur ProzedurA geändert worden ist.

Es könnte aber auch noch eine zweite Prozedur (ProzedurB) existieren, in der ebenfalls der ListIndex jener ListBox geändert werden soll (hier sogar mehrfach), und die MessageBox im Click-Ereignis der MessageBox ebenfalls erscheinen soll. Nun bringt die Komplexität des Programms es mit sich, dass zwischen dem mehrfachen Setzen des ListIndexes in dieser Prozedur eine ProzedurC aufgerufen wird, in der "zufällig" auch die ProzedurA aufgerufen wird.

Private Sub ProzedurB()
  mFlag = True
  List1.ListIndex = -1
  ProzedurC
  List1.ListIndex = 10
  mFlag = False
End Sub

Private Sub ProzedurC()
  ' ...
  ProzedurA
  ' ...
End Sub

Der unbeabsichtigte Effekt ist, dass durch den verdeckten Aufruf der ProzedurA die Sperrvariable bereits zurückgesetzt worden ist, wenn in ProzedurB die weitere Änderung des ListIndexes der ListBox erfolgt. Da die Sperrung ja jetzt aufgehoben ist, wird die MessageBox fälschlicherweise nun nicht mehr angezeigt.

Wie wäre denn Abhilfe zu schaffen? Beispielsweise könnten Sie zur Absicherung bei jedem Setzen der Sperrvariablen prüfen, ob sie bereits gesetzt ist, dies dann festhalten und dadurch ein versehentliches Zurücksetzen vermeiden:

Private mFlag As Boolean

Sub XY()
  Dim nFlagPrevious As Boolean

  nFlagPrevious = mFlag
  mFlag = True
'  ...
  If Not nFlagPrevious Then
    mFlag = False
  End If
End Sub

Das ist natürlich nicht sehr komfortabel, da Sie diesen zusätzlichen Code an jeder möglichen Stelle, an der die Sperrvariable gesetzt bzw. freigegeben werden soll, einbringen müssen. Alternativ könnten Sie jedoch auch eine Zählvariable verwenden:

Private mFlag As Long

Sub XY()
  mFlag = mFlag + 1
'  ...
  mFlag = mFlag - 1
End Sub

Der erste Unterschied besteht schon darin, dass Sie die Sperrvariable nicht mehr so schön eindeutig als Boolean deklarieren können. Der zweite Unterschied liegt in der Prüfung:

If CBool(mFlag) Then ...

Sicher könnten Sie sich das CBool schenken. Aber statt dessen wäre es sinnvoll zu prüfen, ob der Wert der Sperrvariablen noch über 0 liegt - sie könnte ja "zufällig" öfter freigegeben worden sein, als sie gesetzt worden ist (was ja unterm Strich trotzdem eine Freigabe bedeuten dürfte):

If mFlag > 0 Then ...

Die Zähl-Variante ist schon erheblich sicherer. Und eine komfortable Handhabung ist auch möglich, wenn Sie die Variable als Eigenschaft verwalten (bei globaler Gültigkeit in einem Standard-Modul, z.B. modSecureFlagSimple.bas).

Private mSecureFlag As Long

Public Property Get SecureFlag() As Boolean
  SecureFlag = CBool(mSecureFlag)
End Property

Public Property Let SecureFlag(New_SecureFlag As Boolean)
  Select Case New_SecureFlag
    Case False
      mSecureFlag = mSecureFlag - 1
      If mSecureFlag < 0 Then
        mSecureFlag = 0
      End If
    Case True
      mSecureFlag = mSecureFlag + 1
  End Select
End Property

Sicherheitshalber können Sie noch die Prozedur ResetSecureFlag hinzu fügen, die die Sperrvariable in jedem Fall zurück setzt.

Public Sub ResetSecureFlag()
  mSecureFlag = 0
End Sub

Beachten Sie, dass Sie selbstverständlich für mehrere, zu unterschiedlichen Zwecken verwendete Sperrvariablen die oben stehende Verwaltung jeweils separat mit unterschiedlichen Variablen- und Prozedurennamen anlegen müssen.

Die Verwendung selbst ist nun wieder ganz einfach:

Sub ABC()
  SecureFlag = True
'  ...
  SecureFlag = False
End Sub

Sub XY()
  SecureFlag = True
'  ...
  ABC
'  ...
  SecureFlag = False
End Sub

Auch wenn diese Lösung schon sehr sicher ist und in den meisten Fällen auch ausreichen sollte - so ganz befriedigend ist sie jedoch noch nicht. Denn bei zunehmender Komplexität des Geschehens könnte ja auch versehentlich eine Freigabe vergessen bzw. übersprungen werden - etwa durch ein vorzeitiges Verlassen einer Prozedur vor der Freigabe.

Abhilfe schafft hier ein Objekt (Klasse clsSecureFlag), das Sie für den Gültigkeitsbereich, in dem das Flag gesetzt werden soll, instanzieren. Dieses Objekt sorgt zunächst selbsttätig für das Erhöhen des Flagzählers. Beim Verlassen des Gültigkeitsbereiches wird das Objekt wieder zerstört und erniedrigt damit auch wieder selbsttätig den, wie oben dargestellt, als Eigenschaft (nun auf jeden Fall in einem Standard-Modul, z.B. modSecureFlag.bas) verwalteten Flagzähler.

Die Klasse clsSecureFlag sieht so aus:

Private Sub Class_Initialize()
  SecureFlag = True
End Sub

Private Sub Class_Terminate()
  SecureFlag = False
End Sub

Der Einsatz der Klasse erfolgt folgendermaßen:

Sub XY()
  Dim nFlag As clsSecureFlag

'  ...
  Set nFlag = New clsSecureFlag
'  ...
End Sub

Wie gesagt, wird die in nFlag abgelegte Instanz der Klasse clsSecureFlag mit dem Verlassen der Prozedur automatisch zerstört. Diese gibt damit die Sperrvariable aus ihrer Sicht frei. Natürlich können Sie die Sperrung auch vorzeitig, also vor dem Verlassen der Prozedur und dem damit verbundenen automatischen Zerstören des Objekts aufheben - Sie brauchen die Variable (nFlag) lediglich auf Nothing zu setzen:

'  ...
  Set nFlag = Nothing
'  ...
End Sub

Die verschachtelte Verwendung bereitet auch keine Probleme mehr:

Sub ABC()
  Dim nFlag As clsSecureFlag

  Set nFlag = New clsSecureFlag
'  ...
End Sub

Sub XY()
  Dim nFlag As clsSecureFlag

  Set nFlag = New clsSecureFlag
'  ...
  ABC
'  ...
End Sub

Hüten Sie sich jedoch davor, die explizite Instanzierung sparen zu wollen und die Klasse clsSecureFlag gleich in der Deklaration instanzieren zu wollen - etwa:

  Dim nFlag = New clsSecureFlag

So wird nämlich die gewünschte Funktion ausbleiben. Das Initialize-Ereignis der Klasse wird bei dieser Form der Instanzierung nicht automatisch aufgerufen, sondern erst beim ersten Zugriff auf eine Methode oder Eigenschaft - und clsSecureFlag verfügt weder über Methoden noch über Eigenschaften!


Module und Klasse SecureFlag (secureflag.zip - ca. 1,8 KB)


Artikel
Zum Download-Bereich dieses Artikel
Mail an den Autor dieses Artikels

KnowHow
Zur KnowHow-Übersicht

KnowHow-Themen
Themen - Allgemeines
Themen - Entwicklungsumgebung (VB-IDE)
Themen - Forms
Themen - Steuerelemente (Controls)
Themen - Grafik
Themen - Dateien
Themen - UserControls
Themen - Einsteiger-Tipps
Themen - Wussten Sie...?

Übersicht nach Titeln in alphabetischer Reihenfolge
Übersicht nach Erscheinungsdatum

Schnellsuche




Zum Seitenanfang

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

Zum Seitenanfang

Zurück...

Zurück...

Download Internet Explorer