VB -38: INI-Dateien bearbeiten

Einstellungen speichern und laden

Jedes gute Programm merkt sich die Grundeinstellungen beim Beenden, damit der Benutzer nicht immer alles neu auswählen muß, das soll bei Mathe-Max nicht anders sein.

Wir wollen uns merken, an welcher Stelle des Bildschirms unser Hauptfenster zuletzt war und welche Übung zuletzt aktiv war. Das wollen wir dann auch noch gleich in Abhängigkeit vom Benutzer festhalten, falls mehrere Altersklassen mit MatheMax trainieren.

Dazu müssen wir zunächst mal eine Möglichkeit schaffen, den Benutzernamen einzugeben. Wir nehmen unsere Druckerauswahl aus unserem Menü wieder raus (es ist für unser Programm sicher nur selten von Interesse) und bauen stattdessen einen Punkt "Benutzer ändern" (denn es soll auch im laufenden Programm möglich sein) mit dem Namen mnuBenutzer ein:

     Private Sub mnuBenutzer_Click()
        BenutzerSpeichern                'letzten Benutzer speichern
        Benutzername = InputBox("Hallo, wie heißt Du?")    'Namen erfragen
        Benutzername = UCase$(Left$(Benutzername, 1)) & _
         LCase$(Right$(Benutzername, Len(Benutzername) - 1))              
         'Groß-/Kleinschreibung
        Unsichtbar                       
        'evtl vorhandene Aufgaben verschwinden lassen
        BenutzerLaden                    
        'Nachsehen ob für den Benutzer schon Daten vorhanden sind
        Me.Caption = "Mathe-Max       [ " & Benutzername & " ]"     
        'Fenstertitel anpassen
     End Sub
 

Immer wenn der Benutzer geändert wird, sollen die Einstellungen des letzten Benutzers festgehalten werden. Dann fragen wir nach dem Namen des neuen Anwenders. Wir benutzen dazu der Einfachheit halber die Inputbox, die speziell dazu da ist, kurze Texteingaben abzufragen. Sie funktioniert ganz ähnlich wie eine MsgBox und benötigt auch keine eigene Form-Definition.

Da wir nicht sicher sein können, daß unser kleiner Benutzer schon fit in Groß-/Kleinschreibung ist, wandeln wir vorsichtshalber den ersten Buchstaben in Groß- den Rest in Kleinbuchstaben um (das muß nicht immer richtig sein, z.B. bei Hans-Jürgen geht's schief ). Damit man stets sieht, wer an der Reihe ist, blenden wir den Namen in der Titelzeile ein.

Den Benutzernamen machen wir modulweit bekannt:

     Dim Benutzername As String      'aktueller Benutzername modulweit bekannt machen
 

Das eigentliche Laden und Speichern lagern wir in je eine Unterroutine aus, da wir diese Funktion auch beim Starten und Beenden benutzen wollen. Um Einstellungen zu speichern und wieder zu laden, bietet sich eine Ini-Datei an. Jeder von Euch hat schonmal einen Blick in eine solche Datei geworfen, der grundsätzliche Aufbau ist immer gleich:

[Abschnitt2]
Schluessel1= Wert
Schluessel2= Wert
Schluessel3= Text

[Abschnitt2]
.
.

AbschnittX und SchluesselX sind hier Platzhalter und werden durch sprechendere Bezeichnungn ersetzt. Nun könnte man solche Ini-Dateien natürlich durch simple Lese-/Schreiboperation mit Zeichenkettenverarbeitung erzeugen, das ist aber eher mühsam. Windows bietet uns für solche Standard-Ini-Dateien einige recht handliche API-Funktionen:

Schreiben in eine Ini-Datei:

     Declare Function WritePrivateProfileString Lib "kernel32" _
     Alias "WritePrivateProfileStringA" (ByVal lpApplicationName _
     As String, ByVal lpKeyName As Any, ByVal lpString As Any, _
     ByVal lpFileName As String) As Long
 

Lesen einer Zeichenkette aus einer Ini-Datei:

     Declare Function GetPrivateProfileString Lib "kernel32" _
     Alias "GetPrivateProfileStringA" (ByVal lpApplicationName _
     As String, ByVal lpKeyName As Any, ByVal lpDefault As String, _
     ByVal lpReturnedString As String, ByVal nSize As Long, ByVal _
     lpFileName As String) As Long
 

Lesen eines Integerwertes aus einer Ini-Datei:

     Declare Function GetPrivateProfileInt Lib "kernel32" _
     Alias "GetPrivateProfileIntA" (ByVal lpApplicationName _
     As String, ByVal lpKeyName As String, ByVal nDefault As _
     Long, ByVal lpFileName As String) As Long
 

Anmerkung: Jede Declaration ist ein langer Satz (den wir natürlich auch durch Fortsetzungszeichen aufteilen können).

Die 3 Funktionen sind sehr ähnlich. Die Variablen in den Klammern haben folgende Bedeutung:

Mit diesem Wissen können wir jetzt munter drauf los speichern und lesen:

     Private Sub BenutzerSpeichern()
        WritePrivateProfileString Benutzername, "aktiveUebung", _
        aktiveUebung, App.Path & "\MatheMax.ini"
        WritePrivateProfileString Benutzername, "MaxErgebnisWert", _
        Str$(MaxErgebnisWert), App.Path & "\MatheMax.ini"
        WritePrivateProfileString Benutzername, "MinErgebnisWert", _
        Str$(MinErgebnisWert), App.Path & "\MatheMax.ini"
        WritePrivateProfileString Benutzername, "MaxFaktor", _
        Str$(MaxFaktor), App.Path & "\MatheMax.ini"
     End Sub
 

Wenn für eine private Ini-Datei kein Pfad angegeben wird, landet sie automatisch im Windows-Verzeichnis. Das wollen wir aber nicht unnötig zumüllen und geben deshalb den Pfad unserer Anwendung mit an (App.Path).

Beim Beenden des Programms soll zusätzlich die Fensterposition gespeichert werden:

     Private Sub Form_Unload(Cancel As Integer)
        WritePrivateProfileString "Fenster", "linkerRand", _
         Str$(Me.Left), App.Path & "\MatheMax.ini"
        WritePrivateProfileString "Fenster", "obererRand", _
         Str$(Me.Top), App.Path & "\MatheMax.ini"

        BenutzerSpeichern
     End Sub
 

Das Laden geht genauso einfach:

    Private Sub Form_Load()
     Dim i As Integer
        For i = 1 To 8             'rote Kugeln
            Load imgKugelX(i)      'benötigte Anzahl Kugeln laden
            imgKugelX(i).Left = imgKugelX(i - 1).Left + imgKugelX(i).Width * 1.2
            'Kugeln positionieren
        Next
        For i = 1 To 8             'blaue Kugeln
            Load imgKugelY(i)      'benötigte Anzahl Kugeln laden
            imgKugelY(i).Left = imgKugelY(i - 1).Left + imgKugelY(i).Width * 1.2
            'Kugeln positionieren
        Next

        Me.Left = GetPrivateProfileInt("Fenster", "linkerRand", 200, _
         App.Path & "\MatheMax.ini")
        Me.Top = GetPrivateProfileInt("Fenster", "obererRand", 100, _
         App.Path & "\MatheMax.ini")

     End Sub

     Private Sub BenutzerLaden()
     Dim Uebung As String, laenge As Long

        Uebung = Space$(15)          'Variable initialisieren
        laenge = GetPrivateProfileString(Benutzername, "aktiveUebung", _
         "", Uebung, 15, App.Path & "\MatheMax.ini")
        aktiveUebung = Left$(Uebung, laenge)
        If aktiveUebung = "" Then
            Verzoegerung 1
            MsgBox "Bitte wähle eine Übung aus!", vbInformation
        End If

        MaxErgebnisWert = GetPrivateProfileInt(Benutzername, "MaxErgebnisWert", _
         10, App.Path & "\MatheMax.ini")
        MinErgebnisWert = GetPrivateProfileInt(Benutzername, "MinErgebnisWert", _
         1, App.Path & "\MatheMax.ini")
        MaxFaktor = GetPrivateProfileInt(Benutzername, "MaxFaktor", 10, _
         App.Path & "\MatheMax.ini")

        UebungWaehlen
     End Sub
 

Eine Zeichenkettenvariable, die in einer GetPrivateProfileString benutzt wird, sollte stets vorher initialisiert werden, damit man nicht Schiffbruch erleidet. Wir füllen die Variable "Uebung" daher mit Leerzeichen (Space$()).

Beim Lesen mit GetPrivateProfileString erhalten wir als Rückgabewert die tatsächliche Länge der Zeichenkette (die kann ja unterschiedlich sein). Wir nutzen das und wandeln sie mit

        aktiveUebung = Left$(Uebung, laenge)
    

um. Falls aktiveUebung leer ist, dann hat unser neuer Benutzer noch nicht mit MatheMax gearbeitet und wir fordern ihn mit einer MessageBox auf, eine Übung auszuwählen. Ist unser Benutzer schon bekannt, fahren wir am Ende der Prozedur gleich mit der ersten Übung fort. Ich habe dazu die Auswahl der Übung aus unserem Form_KeyPress-Ereignis ausgelagert und eine eigene Prozedur draus gemacht:

     Private Sub UebungWaehlen()
        Select Case aktiveUebung
        Case "Zählen"
            Zaehlen                  'nächste Zählübung
        Case "SymbAddition"
            SymbAddition             'nächste symb. Addition
        Case "Addition"
            Addition                 'nächste Addition
        Case "Subtraktion"
            Subtraktion              'nächste Subtraktion
        Case "Multiplikation"
            Multiplikation           'nächste Multplikation
        Case "Division"
            Division                 'nächste Division
        End Select
     End Sub
 

Auch im Activate-Ereignis nehmen wir noch eine kleine Anpassung vor:

     Private Sub Form_Activate()
     Static gestartet As Boolean

        If gestartet Then Exit Sub  'Abfrage ob schonmal gestartet

        AutoRedraw = True
        Me.PaintPicture picTafel.Image, (Me.ScaleWidth - picTafel.Width) _
         \ 2, (Me.ScaleHeight - picTafel.Height) \ 2
        AutoRedraw = False

        CurrentX = 1500      'positioniert den nachfolgenden Printbefehl X-Achse
        CurrentY = 2000      'positioniert den nachfolgenden Printbefehl Y-Achse
        Print "Viel Spaß mit Mathe-Max!"  'druckt Text direkt auf die Form

        Verzoegerung 1
        mnuBenutzer_Click
        Cls

        gestartet = True
     End Sub
 

Statt der MessageBox legen wir gleich mit der ersten Übung los (mnuBenutzer_Click).

Beispielprojekt laden

Unsere MatheMax.ini könnte dann nach einem Lauf so aussehen:

[Fenster]
linkerRand= 200
obererRand= 100

[Michael]
aktiveUebung=Addition
MaxErgebnisWert=10
MinErgebnisWert=2
MaxFaktor=10

[Jutta]
aktiveUebung=Zählen
MaxErgebnisWert=10
MinErgebnisWert=1
MaxFaktor=10

Das war's jetzt aber auch. Verwirrt ? Guckt's Euch Schritt für Schritt an...

zurück Index weiter


© Copyright 1998-2000 J.Behling EMail schreiben ABC-Ware's Homepage
Weitergabe und Druck (auch in Teilen, mit Ausnahme von Privatgebrauch) ohne ausdrückliche Genehmigung der Autorin untersagt.