vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#

https://www.vbarchiv.net
Rubrik: Dialoge/Dateien   |   VB-Versionen: VB5, VB615.09.01
INI-Dateien bearbeiten und verwalten

INI-Dateien wurden verstärkt unter Windows 3.x eingesetzt - aber auch unter Win9x/NT wird noch reichlich von diesen Dateien Gebrauch gemacht. Dieser Workshop verrät, warum Sie selbst INI-Dateien verwenden sollten und wie sich mit dem Einsatz von nur zwei API-Funktionen ein komfortabler INI-Editor zur Erstellung und Bearbeitung von INI-Dateien erstellen lässt.

Autor:  Dieter OtterBewertung:  Views:  123.730 

INI-Dateien wurden verstärkt unter Windows 3.x eingesetzt - aber auch unter Win9x/NT wird noch reichlich von diesen Dateien Gebrauch gemacht. Dieser Workshop verrät, warum Sie selbst INI-Dateien verwenden sollten und wie sich mit dem Einsatz von nur zwei API-Funktionen ein komfortabler INI-Editor zur Erstellung und Bearbeitung von INI-Dateien erstellen lässt.

INI-Dateien und das Windows-API

Eine INI-Datei, das ist eine Art Konfigurationsdatei, in welcher z.B. Programm- und Benutzereinstellungen einer Anwendung gespeichert werden. INI-Dateien wurden vor allem unter Windows 3.x eingesetzt. Seit Einführung des 32-Bit Betriebssystems Windows 95 nutzten viele Programmhersteller die Windows-Registrier-Datenbank, um ihre Programm- und Benutzereinstellungen zu speichern. Meiner Meinung nach ist das aber nicht der Weg, den ALLE beschreiten sollten, denn die Windows-Registrierdatenbank wird durch die große Anzahl an installierten Programmen und demzufolge durch die in der Registry eingetragenen Anwendungseinstellungen immer größer und größer - und verlangsamt somit das gesamte System.

Ein weiterer Vorteil, der für die Verwendung von INI-Dateien spricht, ist die Datensicherung. Wenn die Anwendungseinstellungen in einer INI-Datei im Programmverzeichnis gespeichert werden, werden diese auch automatisch bei einer Datensicherung gesichert.

Aufbau von INI-Dateien
Falls Sie mit dem Begriff INI-Datei nichts anfangen können oder den Aufbau selbst gar nicht so recht kennen - hier mal ein allgemeines Beispiel für den Aufbau einer solchen INI-Datei:

[Abschnitt1]
Key1=Wert1
Key2=Wert2
Key3=Wert3
 
[Abschnitt2]
Key1=Wert1
Key2=Wert2
Key3=Wert3
 
[Abschnitt3]
Key1=Wert1
Key2=Wert2
Key3=Wert3

Beispiel für eine einfache INI-Datei
Das nachfolgende Beispiel zeigt den Aufbau einer einfachen INI-Datei, in der lediglich ein paar Pfadangaben und Benutzervorgaben gespeichert werden.

[Start]
Tagestipp=ja
Datum prüfen=nein
 
[Verzeichnisse]
Texte=..\Privat\Texte
Daten=..\Daten
 
[Anwender1]
User=Dieter
eMail=info@vbarchiv.de
 
[Anwender2]
User=Ralph
eMail=ralp@vbarchiv.de

Welche Rolle spielt nun das Windows-API?
Das Windows-API (Windows Application Interface) spielt eine sehr wesentliche Rolle bei der Verwaltung von INI-Dateien. So stellt das Windows API zwei Funktionen zur Verfügung, mit denen sich die gesamte Verwaltung der INI-Datei bewerkstelligen lässt. Hierbei handelt es sich um folgende Funktionen:

Public 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
 
Public 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

Die erste Funktion WritePrivateProfileString erledigt das Speichern und Löschen von Einträgen oder auch ganzen Abschnitten. Die zweite Funktion GetPrivateProfileString dient in erster Linie zum Lesen des Wertes eines einzelnen Eintrages. Mit dieser Funktion lassen sich aber auch alle in der INI-Datei vorhandenen Abschnittsnamen ermitteln oder auch alle Schlüsselnamen eines einzelnen Abschnittes.

Ohne die beiden Windows-API Funktionen wäre das Verwalten von INI-Dateien sehr sehr aufwendig. Um einen einzelnen Eintrag auszulesen müssten Sie die INI-Datei sequentiell öffnen und solange "zeilenweise" einlesen, bis Sie den gewünschten Eintrag erreicht haben. Das Löschen und Speichern von Einträgen oder ganzen Abschnitten würde dann sogar einen noch größeren Aufwand bedeuten.

API: WritePrivateProfileString

Die API-Funktion WritePrivateProfileString wird wie bereits erwähnt in erster Linie zum Speichern eines einzelnen neuen oder modifizierten Eintrags verwendet.

Die Syntax ist hierbei folgende:
lpApplicationNameName des Abschnittes in der (INI-)Datei.
lpKeyNameSchlüssel des Eintrags, dessen Wert gespeichert werden soll.
lpStringWert, der im Abschnitt unter dem angegebenen Schlüssel gespeichert werden soll.
lpFileNamePfadangabe der (INI-)Datei. Existiert diese Datei nicht, wird sie automatisch erstellt.

' Einzelnen Eintrag im Abschnitt "Start" speichern
Dim myIniFile As String
 
myIniFile = App.Path & "\" & App.EXEName & ".ini"
WritePrivateProfileString "Start", "Tagestipp", "ja", _
  myIniFile

Wie ebenfalls bereits erwähnt lassen sich mit der WritePrivateProfileString-Funktion aber auch einzelne Einträge oder auch ganze Abschnitte löschen.

' Löschen eines einzelnen Eintrags aus der INI-Datei
WritePrivateProfileString "Start", "Tagestipp", vbNullString, _
  myIniFile
' Löschen eines gesamten Abschnittes
WritePrivateProfileString "Start", vbNullString, "", myIniFile
' Löschen aller Abschnitte
WritePrivateProfileString vbNullString, "", "", myIniFile

Wie Sie anhand der Funktionsaufrufe sehen, können Teile der INI-Datei durch Angabe von vbNullString gelöscht werden - je nachdem, für welchen Parameter Sie vbNullString einsetzen, handelt es sich um einen einzelnen Eintrag, einen einzelnen Abschnitt oder auch um alle Abschnitte.

API: GetPrivateProfileString

Um nun gespeicherte Einträge in der INI-Datei auszulesen, wird die GetPrivateProfileString-Funktion benutzt.

Die Syntax ist hierbei folgende:
lpApplicationNameName des Abschnittes in der (INI-)Datei.
lpKeyNameSchlüssel des zu lesenden Eintrags.
nDefaultVorgabe-/Standardwert, der zurückgegeben werden soll, wenn kein Eintrag vorhanden ist.
lpReturnedStringPuffer, der den Rückgabewert enthält (muss mit ausreichend Leerstellen gefüllt sein)
nSizeGröße des Puffers in Bytes.
lpFileNamePfadangabe der (INI-)Datei

Die Funktion selbst gibt als Rückgabewert die Länge des tatsächlich gelesenen Wertes zurück.

Wichtig beim Einsatz der Funktion ist, dass Sie die Rückgabevariable lpReturnString vor dem Funktionsaufruf mit ausreichend Leerstellen füllen und die Größe der Variable dann im Parameter nSize angeben.

' Einzelnen Eintrag im Abschnitt "Start" lesen
Dim myIniFile As String
Dim sValue As String
Dim lResult As Long
 
myIniFile = App.Path & "\" & App.EXEName & ".ini"
 
' Rückgabewert mit ausreichend Leerzeichen füllen
sValue = Space$(255)
lResult = GetPrivateProfileString("Start", "Tagestipp", _
  "ja", sValue, Len(sValue), myIniFile)
 
' tatsächliche Länge des Rückgabewertes
sValue = Left$(sValue, lResult)

Eine kleine Hilfsfunktion
Für den obigen Code ist es sinnvoll eine Funktion zu erstellen, in der eben dieser Code ausgeführt wird. Der Vorteil ist, dass Sie zukünftig einen Eintrag aus der INI-Datei mit einer einzigen Zeile Code auslesen können!

' Eintrag aus INI-Datei lesen
Public Function GetIniString(ByVal Sektion As String, _
  ByVal Titel As String, ByVal Vorgabe As String, _
  ByVal INIFile As String, _
  Optional ByVal nSize As Integer = 256) As String
 
  Dim lResult As Long
  Dim sValue As String
 
  sValue = Space$(nSize)
  lResult = GetPrivateProfileString(Sektion, Titel, _
    Vorgabe, sValue, nSize, INIFile)
  GetIniString = Left$(sValue, lResult)
End Function

Um nun den Eintrag "Tagestipp" im Abschnitt "Start" auszulesen, verwenden Sie also zukünftig einfach folgenden Funktionsaufruf:

' Einzelnen Eintrag im Abschnitt "Start" lesen
Dim sValue As String
sValue = GetIniString("Start", "Tagestipp", ja, myIniFile)

Die Funktion GetPrivateProfileString lässt sich aber auch dazu verwenden, um:

  • alle Schlüsselnamen eines einzelnen Abschnittes zu ermitteln
  • alle in der INI-Datei vorhandenen Abschnittsnamen zu ermitteln

Analog zur WritePrivateProfileString-Funktion müssen Sie hierfür die Konstante vbNullString als Parameter einsetzen:

' Alle Schlüsselnamen im Abschnitts "Start" ermitteln
Dim sKeyNames As String
sKeyNames = GetIniString("Start", vbNullString, "", _
  myIniFile, 32767)
' oder: alle vorhandenen Abschnittsnamen ermitteln
Dim sSectionNames As String
sSectionNames = GetIniString(vbNullString, "", "", _
  myIniFile, 32767)

Als Rückgabe erhalten Sie die Bezeichnungen aller Schlüssel bzw. Abschnitte - getrennt durch ein vbNullChar-Zeichen. Um die einzelnen Bezeichner nun z.B. in einer ListBox anzuzeigen, verwenden Sie einfach die Split-Funktion (erst ab VB6 verfügbar!):

' Alle Abschnittsnamen ermitteln und in
' einer Listbox anzeigen
Dim sSections as String
Dim Section() As String
Dim I As Integer
 
' Rückgabe-String vorbereiten
sSections = Space$(32767)
 
' vbNullString übergeben, um alle gespeicherten
' Abschnittsnamen zu ermitteln
lResult = GetIniString(vbNullString, "", "", _
 sSections, myIniFile, Len(sSections))
 
' Sind überhaupt Abschnitte vorhanden?
If sSections <> "" Then
 
  ' Rückgabestring "splitten"
  Section = Split(sSections, vbNullChar)
 
  ' Alle Abschnitt der ListBox hinzufügen
  With List1
    For I = 0 To UBound(Section) - 1
      .AddItem Section(I)
    Next I
  End With
End If

Projekt: Ein INIFile-Editor

Mit den in den vorigen Abschnitten besprochenen und vorgestellten Code-Routinen soll nun ein kleiner INI-Editor erstellt werden. Die Aufgabe des INI-Editors soll es sein, den Inhalt einer beliebigen INI-Datei übersichtlich in einem Formular (Fenster) anzuzeigen. Hierbei sollen alle vorhandenen Abschnittsnamen in einer ListBox erscheinen. Beim Auswählen eines Abschnittes sollen dann alle in diesem Abschnitt gespeicherten Schlüsselnamen und deren Werte in einer weiteren (rechts daneben befindlichen) Liste dargestellt werden. Das ist aber noch nicht alles - denn dann wäre es ja nur eine Art "Viewer". Zusätzlich soll die Möglichkeit bestehen, neue Abschnitte zu erstellen bzw. einzelne Abschnitte per Knopfdruck zu löschen. Ebenfalls stellen wir die Anforderung, dass sich einem Abschnitt ein neuer Eintrag hinzufügen, bearbeiten oder löschen lässt. Auf eine Suchroutine soll erst einmal verzichtet werden.

Das hört sich jetzt nach ganz schön viel Arbeit an - meinen Sie nicht auch?
Ist aber gar nicht so viel

Das Modul basINI.bas
Die in den vorigen Abschnitten vorgestellten Deklarationen und Funktionen "packen" wir in ein eigenes Modul: basINI.bas

Option Explicit
 
' zunächst die benötigten API-Deklarationen (INI)
Public 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
 
Public 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
 
' Eintrag aus INI-Datei lesen
Public Function GetIniString(ByVal Sektion As String, _
  ByVal Titel As String, ByVal Vorgabe As String, _
  ByVal INIFile As String, _
  Optional ByVal nSize As Integer = 256) As String
 
  Dim lResult As Long
  Dim sValue As String
 
  sValue = Space$(nSize)
  lResult = GetPrivateProfileString(Sektion, Titel, _
    Vorgabe, sValue, nSize, INIFile)
  GetIniString = Left$(sValue, lResult)
End Function

Vorbereitung: Das Formular-Layout
Wenn Sie die Aufgabenstellung aufmerksam duchgelesen haben, wissen Sie auch, welche Steuerelemente wir alles benötigen:

  • Dateiauswahlfeld für die Auswahl der INI-Datei (TextBox mit Button zum Abrufen des Dateidialogs - verknüpft mit dem CommonDialog-Control)
  • ListBox (für die Anzeige der Abschnittsnamen)
  • weitere ListBox rechts daneben (für die Anzeige der Schlüsselnamen und deren Werte)
  • Zwei Schaltflächen für das Hinzufügen und Löschen von Abschnitten
  • Nochmals drei Schaltflächen für das Hinzufügen, Bearbeiten und Löschen von Einträgen innerhalb eines Abschnittes

Die Optik könnte dann der des Registrier-Datenbank-Editors ähneln (RegEdit). Und was verwendet "RegEdit" für die Anzeige der Schlüsselnamen und deren Werte? Genau! Nicht die Standard-ListBox, sondern ein ListView-Control, da man hier Spalten definieren kann - und wir brauchen schliesslich ebenfalls zwei Spalten: Eine für den Schlüsselnamen und eine weitere (rechts daneben) für den jeweiligen Wert.

Also erstellen Sie ein Formular und plazieren die benötigten Steuerelemente darauf. Das sollte dann in etwa so aussehen:

Der Formular-Entwurf

Und hier die Eigenschaften der Steuerelemente

txtINIFile (TextBox)
Locked   True

cmdOpen (CommandButton)
Caption   ""
PictureOrdner-Symbol 16x16
Style1 - Grafisch

lstSections (ListBox)
Sorted   True

lvwKeys (ListView)
FullRowSelectTrue
GridLinesTrue
HideSelectionsFalse
SortedTrue
SortOrder0
View3 -lvwReport

Unterhalb der linken ListBox plaziern Sie dann die beiden Schaltflächen cmdSectionsAdd und cmdSectionsDelete. Unterhalb des ListView-Controls fügen Sie weitere drei Schaltflächen ein: cmdEdit, cmdAdd und cmdDelete.

INI-Datei auswählen und Inhalt anzeigen

1. Auswahl der INI-Datei per CommonDialog-Control
Da wir für die TextBox txtINIFile die Eigenschaft Locked = True gesetzt haben, kann die Auswahl der INI-Datei nicht direkt durch Eingabe des Dateinamens erfolgen. Vielmehr soll die Auswahl über den Windows-Standard-Dialog vorgenommen werden. Dieser wird aufgerufen, wenn der Anwender auf die kleine grafische Schaltfläche rechts neben der TextBox klickt:

Private Sub cmdOpen_Click()
  ' INI-Datei auswählen
  On Local Error Resume Next
  With CommonDialog1
    .CancelError = True
    .Filter = "INI-Datei (*.ini)|*.ini"
    .ShowOpen
    If Err = 0 Then
      txtINIFile.Text = .FileName
      INIFile = .FileName
 
      ' INI-Datei auslesen und anzeigen
      Init_Sections INIFile
    End If
  End With
End Sub

Der ausgewählte Dateiname wird - falls der Dialog nicht abgebrochen wurde - in der TextBox txtINIFile angezeigt. Gleichzeitig speichern wir den Dateinamen zusätzlich in der Form-Globalen Variable INIFile.

2. Alle Abschnittsnamen auslesen und in der linken ListBox anzeigen
Im nächsten Schritt erfolgt das Auslesen der in der INI-Datei vorhandenen Abschnitte. Dies erledigt die Prozedur Init_Sections:

' INI-Datei auslesen (alle Abschnitte ermitteln und
' in "lstSections" anzeigen)
Private Sub Init_Sections(ByVal INIFile As String)
  Dim strSections As String
  Dim Section() As String
  Dim I As Integer
 
  ' ListBoxen löschen
  lstSections.Clear
  lvwKeys.ListItems.Clear
 
  ' vbNullString übergeben, um alle gespeicherten
  ' Abschnittsnamen zu ermitteln
  strSections = GetIniString(vbNullString, "", "", _
    INIFile, 32767)
 
  ' Sind überhaupt Abschnitte vorhanden?
  strSections = Left$(strSections, lResult)
  If strSections <> "" Then
 
    ' Rückgabestring "splitten"
    Section = Split(strSections, Chr$(0))
 
    ' Alle Abschnitt der ListBox hinzufügen
    With lstSections
      For I = 0 To UBound(Section) - 1
        .AddItem Section(I)
      Next I
 
      ' Ersten Eintrag markieren
      ' (und autom. die gespeicherten Keys anzeigen)
      ' (wird in lstSections_Click erledigt)
      If .ListCount > 0 Then .ListIndex = 0
      .Enabled = True
    End With
  End If
End Sub

3. Alle Einträge des selektierten Abschnittes im ListView-Control anzeigen
Über die Zuweisung .ListIndex = 0 wird der erste Eintrag der ListBox markiert. Dies löst bekanntlich automatisch das ListBox_Click-Ereignis aus. Also müssen wir in dieser Ereignis-Prozedur das ListView-Control mit den entsprechenden Daten füllen:

' Abschnitt ausgewählt, d.h. jetzt alle Einträge des
' Abschnittes in der zweiten ListBox anzeigen
Private Sub lstSections_Click()
  With lstSections
    ' Ist überhaupt ein Eintrag ausgewählt?
    If .ListIndex > -1 Then
      Init_Keys .List(.ListIndex), INIFile
    End If
  End With
End Sub
 
' Alle Schlüsselwörter eines Abschnittes auslesen
' und in der zweiten ListBox anzeigen
Private Sub Init_Keys(ByVal strSection As String, _
  ByVal INIFile As String)
 
  Dim strKeys As String
  Dim Key() As String
  Dim I As Integer
  Dim itemX As ListItem
 
  ' ListView löschen
  lvwKeys.ListItems.Clear
 
  ' vbNullString übergeben, um alle gespeicherten
  ' Keys zu ermitteln
  strKeys = GetIniString(strSection, vbNullString, _
    "", INIFile, 32767)
 
  ' Sind überhaupt Einträge vorhanden?
  If strKeys <> "" Then
 
    ' Rückgabestring "splitten"
    Key = Split(strKeys, Chr$(0))
 
    ' Alle Einträge der ListBox hinzufügen
    With lvwKeys.ListItems
      For I = 0 To UBound(Key) - 1
        Set itemX = .Add(, , Key(I))
        itemX.SubItems(1) = GetIniString(strSection, _
          Key(I), "", INIFile)
      Next I
    End With
 
    With lvwKeys
      ' Ersten Eintrag markieren
      If .ListItems.Count > 0 Then
        Set .SelectedItem = .ListItems(1)
      End If
      .Enabled = True
    End With
  End If
End Sub

Abschnitte und Einträge bearbeiten

Der bisherige Code funktioniert bereits. Starten Sie das Projekt und probieren Sie es einmal aus. In der linken ListBox werden alle Abschnittsnamen der ausgewählten INI-Datei angezeigt, wohingegen die rechte Liste alle Einträge des ausgewählten Abschnittes enthält (Schlüsselnamen und Werte).

Was jetzt noch fehlt, sind die Bearbeitungsfunktionen!

4. Neuen Abschnitt hinzufügen
Über die Schaltfläche cmdSectionAdd soll die Möglichkeit bestehen, einen neuen Abschnitt zu erstellen. Für die Eingabe der Abschnitt-Bezeichnung verwenden wir einfach die Visual Basic InputBox. Jedoch sollte überprüft werden, ob die eingegebene Bezeichnung bereit existiert - und wenn ja ein entsprechender Hinweis erscheinen. All dies erledigt die Prozedur cmdSectionAdd_Click:

' Neuen Abschnitt erstellen
Private Sub cmdSectionAdd_Click()
  Dim strSection As String
 
  ' Frage nach Bezeichnung
  strSection = InputBox("Bezeichnung des neuen Abschnittes:", _
    "Neuer Abschnitt", "")
 
  If strSection <> "" Then
    ' Prüfen, ob Abschnitt bereits existiert
    If IsInListe(lstSections, strSection) >= 0 Then
      MsgBox "Dieser Abschnitt existiert bereits!", 64
    Else
      ' Abschnitt hinzufügen
      With lstSections
        .AddItem strSection
        .ListIndex = IsInListe(lstSections, strSection)
      End With
    End If
  End If
End Sub

5. Abschnitt mit allen zugehörigen Einträgen löschen
Das Löschen eines gesamten Abschnittes mit allen zugehörigen Untereinträgen erfolgt beim Klicken auf die Schaltfläche cmdSectionDelete. Aber Achtung! Eine Sicherheitsabfrage wäre nicht schlecht, so dass ein versehentliches Löschen vermieden werden kann.

' Gesamten INI-Abschnitt löschen
Private Sub cmdSectionDelete_Click()
  Dim strSection As String
  Dim iIndex As Integer
 
  If MsgBox("Markierten Abschnitt wirklich löschen?", _
    vbYesNo, "Löschen") = vbYes Then
 
    ' Das Löschen erfolgt durch Übergabe von
    ' vbNullString im Paramater "lpKeyName"
    With lstSections
      iIndex = .ListIndex
      strSection = .List(iIndex)
      WritePrivateProfileString strSection, vbNullString, _
        "", INIFile
 
      ' Abschnitt aus der Listbox entfernen
      .RemoveItem iIndex
 
      ' Nachfolgenden Abschnitt markieren
      If iIndex > .ListCount - 1 Then _
        iIndex = .ListCount - 1
      .ListIndex = iIndex
    End With
  End If
End Sub

Nach dem Löschen des Abschnittes aus der INI-Datei wird der entsprechende Eintrag auch aus der ListBox entfernt und der nachfolgende Eintrag (sollte es noch einen geben) automatisch selektiert.

6. Einzelnen Eintrag bearbeiten
Formular zur Eingabe des Schlüsselnamens und Wertes
Das Bearbeiten eines einzelnen Eintrags erfolgt über die Schaltfläche cmdEdit. Es soll die Möglichkeit bestehen, sowohl den Schlüsselnamen, als auch den zugewiesenen Wert ändern zu können. Aus diesem Grund eignet sich die Standard InputBox nicht sonderlich gut, da hier ja immer nur eine einzige Eingabe vorgenommen werden kann. Also erstellen wir ein kleines zusätzliches Formular mit zwei Eingabefeldern (TextBoxen) und nennen dieses frmKey. Die TextBoxen benennen wir txtKey und txtValue. Weiterhin benötigen wir für das Formular noch zwei Schaltflächen: cmdOK und cmdCancel. Die Eigenschaft Enabled von cmdOK setzen Sie bitte standardmässig auf False.

Und hier der gesamte Code für das Eingabeformular

Option Explicit
 
Private Sub cmdCancel_Click()
  ' Abbrechen
  Me.Tag = False
  Me.Hide
End Sub
 
Private Sub cmdOK_Click()
  ' OK
  Me.Tag = True
  Me.Hide
End Sub
 
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
  ' Schließen
  If UnloadMode <> 1 Then
    Cancel = True
    cmdCancel.Value = True
  End If
End Sub
 
Private Sub Form_Unload(Cancel As Integer)
  Set frmKey = Nothing
End Sub
 
Private Sub txtKey_Change()
  ' Prüfen
  cmdOK.Enabled = (Trim$(txtKey.Text) <> "")
End Sub

Über die Tag-Eigenschaft der Form merken wir uns, ob auf OK oder auf Abbrechen bzw. auf das Schliessen-Symbol der Form geklickt wurde.

In der Prozedur cmdEdit_Click im Hauptformular benötigen wir folgenden Code:

' Schlüssel / Wert bearbeiten
Private Sub cmdEdit_Click()
  Dim strSection As String
  Dim itemX As ListItem
 
  ' Zunächst benötigte Infos ermitteln
  Set itemX = lvwKeys.SelectedItem
 
  ' Form laden
  Load frmKey
  With frmKey
    ' bisherige Daten im Formular anzeigen
    .txtKey.Text = itemX.Text
    .txtValue.Text = itemX.SubItems(1)
 
    ' Form anzeigen
    .Show 1
    If .Tag = True Then
      ' Geänderten Eintrag speichern
      strSection = lstSections.List(lstSections.ListIndex)
 
      ' Was hat sich geändert?
      If Trim$(.txtKey.Text) <> itemX.Text Then
        ' Schlüsselnamen hat sich geändert
        ' also alten Schüssel zunächst löschen
        WritePrivateProfileString strSection, _
          itemX.Text, vbNullString, INIFile
      End If
 
      ' Neuen Schlüssel/Wert speichern
      WritePrivateProfileString strSection, _
        Trim$(.txtKey.Text), .txtValue.Text, INIFile
 
      ' ListView aktualisieren
      itemX.Text = Trim$(.txtKey.Text)
      itemX.SubItems(1) = .txtValue
    End If
  End With
  Unload frmKey
End Sub

7. Neuen Eintrag hinzufügen
Für das Hinzufügen eines neuen Eintrags verwenden wir ebenfalls wieder das Zusatz-Formular frmKey:

' Neuen Schlüssel hinzufügen
Private Sub cmdNew_Click()
  Dim strSection As String
  Dim itemX As ListItem
 
  ' Form anzeigen
  Load frmKey
  With frmKey
    .Show 1
    If .Tag = True Then
      ' Neuen Eintrag speichern
      strSection = lstSections.List(lstSections.ListIndex)
      WritePrivateProfileString strSection, _
        Trim$(.txtKey.Text), .txtValue.Text, INIFile
 
      ' ListView aktualisieren
      Set itemX = lvwKeys.ListItems.Add(, , _
        Trim$(.txtKey.Text))
      itemX.SubItems(1) = .txtValue
 
      ' Eintrag suchen und markieren
      Set lvwKeys.SelectedItem = itemX
    End If
  End With
  Unload frmKey
End Sub

8. Eintrag löschen
Zu guter letzt brauchen wir jetzt noch den Code, um einen vorhandenen Eintrag aus dem selektierten Abschnitt löschen zu können. Auch hier zeigen wir vorher eine zusätzliche Sicherheitsabfrage, so dass ein Eintrag nicht versehentlich gelöscht werden kann

' Schlüssel löschen
Private Sub cmdDelete_Click()
  Dim lIndex As Long
  Dim strSection As String
 
  If MsgBox("Schlüssel wirklich löschen?", _
    vbYesNo, "Löschen") = vbYes Then
 
    strSection = lstSections.List(lstSections.ListIndex)
    With lvwKeys
      lIndex = .SelectedItem.Index
 
      ' Eintrag wird per vbNullString im Parameter
      ' "sText" gelöscht
      WritePrivateProfileString strSection, _
        .SelectedItem.Text, vbNullString, INIFile
 
      ' Eintrag aus dem ListView entfernen
      .ListItems.Remove lIndex
 
      ' Nächsten Eintrag selektieren
      If lIndex > .ListItems.Count Then _
        lIndex = .ListItems.Count
      If lIndex > 0 Then _
        Set .SelectedItem = .ListItems(lIndex)
    End With
  End If
End Sub

Im Code-Abschnitt, bei dem innerhalb der ListBox nach einem bereits existierenden Eintrag gesucht wird, wird auf die Funktion IsInListe verwiesen. Hierbei handelt es sich um keine VB-Standardfunktion, vielmehr erfolgt die Suche anhand der schnellen Windows-API Funktion. Fügen Sie demnach noch nachfolgenden Codeabschnitt im Allgemein Teil der Form ein:

' Schnelle Suche innerhalb einer ListBox
Private Declare Function SendMessage Lib "user32" _
  Alias "SendMessageA" ( _
  ByVal hwnd As Long, _
  ByVal wMsg As Long, _
  ByVal wParam As Long, _
  ByVal lParam As String) As Long
 
Private Const LB_FINDSTRING = &H18F

Und nun noch die Funktion IsInListe:

' Prüft, ob ein Wert in einer ListBox enthalten ist
' und gibt als Ergebnis den ListIndex zurück
' (-1, wenn nicht vorhanden)
Public Function IsInListe(Liste As ListBox, _
  ByVal Item As String) As Integer
 
  IsInListe = SendMessage(Liste.hwnd, _
    LB_FINDSTRING, -1, Item)
End Function

Das Projekt ist fertig

Mit relativ wenig Aufwand haben wir jetzt einen vollvertigen INIFile-Editor erstellt. Mit diesem kleinen Programm können Sie von nun an Ihre INI-Dateien komfortabel erstellen und bearbeiten. Lediglich eine Suchfunktion fehlt noch - dann wäre der INIFile-Editor absolut perfekt

Vielleicht haben Sie ja Lust, das Projekt um eine solche Suchfunktion zu erweitern?
Wir würden uns über Lösungsvorschläge diesbezüglich sehr freuen und die besten Lösungen dann auch hier mit abdrucken.

 infovbarchiv.de



Anzeige

Kauftipp Unser Dauerbrenner!Diesen und auch alle anderen Workshops finden Sie auch auf unserer aktuellen vb@rchiv  Vol.6
(einschl. Beispielprojekt!)

Ein absolutes Muss - Geballtes Wissen aus mehr als 8 Jahren vb@rchiv!
- nahezu alle Tipps & Tricks und Workshops mit Beispielprojekten
- Symbol-Galerie mit mehr als 3.200 Icons im modernen Look
Weitere Infos - 4 Entwickler-Vollversionen (u.a. sevFTP für .NET), Online-Update-Funktion u.v.m.
 
 
Copyright ©2000-2024 vb@rchiv Dieter OtterAlle Rechte vorbehalten.


Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.