AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Einträge nicht nur aus Listbox entfernen
Thema durchsuchen
Ansicht
Themen-Optionen

Einträge nicht nur aus Listbox entfernen

Ein Thema von jawo3 · begonnen am 29. Aug 2010 · letzter Beitrag vom 30. Aug 2010
Antwort Antwort
Seite 1 von 2  1 2      
jawo3

Registriert seit: 15. Sep 2009
Ort: Niedersachsen
41 Beiträge
 
#1

Einträge nicht nur aus Listbox entfernen

  Alt 29. Aug 2010, 15:04
Hallo,
ich habe vor einigen Tagen schon mal eine Frage zu meinem derzeitigen Programm gestellt und ihr konntet mir schnell und kompetent weiterhelfen. Leider bin ich jetzt auf ein neues Problem gestoßen, dass wieder damit zusammenhängt, dass ich mich noch nicht so gut mit Zeigern auskenne, was sich hoffentlich bald ändern wird.

Es geht erneut um das "Vokabel-Programm" in dem Wörter abgespeichert werden sollen und diese dann in einer ListBox ausgegeben werden. Ich arbeite gerade daran, dass Wörter innerhalb der ListBox mit der Maus markiert werden, und nach Klick auf einen Button aus der ListBox entfernt werden. Das funktioniert soweit auch sehr gut. Das Problem ist nur, dass die Wörter nicht aus meiner Zeigerstruktur entfernt werden, sondern nur aus der ListBox. Das heißt, wenn ich den "Einträge Anzeigen" Button drücke, erscheinen alle EInträge erneut in meiner ListBox, inklusive derjenigen, die eigentlich schon hätten gelöscht werden sollen.

Ich weiß leider nicht sorecht, wie ich das Problem beheben kann. Vielleicht könnt ihr mir ja ein bisschen auf die Sprünge helfen, dass wäre sehr nett.

Hier mal das Programm. Die Stelle, an der ich gerade arbeite, habe ich mit einem Kommentar-Block versehen:

Delphi-Quellcode:
unit Vokabeln;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons;

type
    TForm1 = class(TForm)
      Label1: TLabel;
      EditEintragen: TEdit;
      ListBoxAnzeige: TListBox;
      ButtonEintragen: TButton;
      ButtonEntfernen: TButton;
      ButtonAnzeigen: TButton;
      RadioButtonLIFO: TRadioButton;
      RadioButtonFIFO: TRadioButton;
      ButtonLeeren: TButton;
      ButtonSpeichern: TBitBtn;
      ButtonLaden: TBitBtn;
      ButtonBeenden: TBitBtn;
      ButtonMarkieren: TButton;
      procedure ButtonBeendenClick(Sender: TObject);
      procedure ButtonEintragenClick(Sender: TObject);
      procedure ButtonEntfernenClick(Sender: TObject);
      procedure ButtonSpeichernClick(Sender: TObject);
      procedure ButtonLadenClick(Sender: TObject);
      procedure ButtonAnzeigenClick(Sender: TObject);
      procedure FormActivate(Sender: TObject);
      procedure EditEintragenKeyPress(Sender: TObject; var Key: Char);
      procedure ButtonLeerenClick(Sender: TObject);
      procedure SpeicherFreigeben;
      procedure ListBoxAnzeigeKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
      procedure RadioButtonFIFOClick(Sender: TObject);
      procedure RadioButtonLIFOClick(Sender: TObject);
    procedure ButtonMarkierenClick(Sender: TObject);
    end;
    Zeiger = ^Element; //Definition eines Zeigertyps
    tInhalt = string[15];
    Element = record
                naechster: Zeiger;
                Inhalt: tInhalt;
              end;

const Datenpfad='Vokabeln.dta'; //Hier wird die Datenbank gespeichert

var
  Form1: TForm1;
  Wurzel, z : Zeiger; //nötig um Liste aufzubauen
  f: file of tInhalt; //nötig für Speicher-/Ladevorgang

function Kontrolle:Boolean;

implementation

{$R *.dfm}

procedure TForm1.FormActivate(Sender: TObject); //Bei Programm-Start
begin
EditEintragen.SetFocus; //Fokus auf Eintragen-Textfeld setzen
Wurzel:=nil; //Wurzel markiert erstes greifbares Element und wird zunächst "geerdet"
end;

function Kontrolle; //Test auf gängigste IO-Fehler
begin
  result := false;
  case IOResult of
     0: result := true;
     2: begin showmessage ('Datei nicht vorhanden.' +#13+ 'Datei wird angelegt');
          rewrite(f);
          result := true;
        end;
     3: showmessage ('Ungueltiger Dateiname/Pfad');
     5: showmessage ('Dateizugriff verweigert.');
    21: showmessage ('Laufwerk nicht bereit!');
  end;
end;

procedure TForm1.EditEintragenKeyPress(Sender: TObject; var Key: Char); //Eintragen über Enter Taste
begin
if (Key=#13) and (length(EditEintragen.Text)<>0) then
  begin
      Key:=#0;
      ButtonEintragenClick(Sender); //Wenn "Enter" gedrückt wird dann eintragen
      ButtonAnzeigenClick(Sender); //Neue Liste anzeigen
      EditEintragen.SetFocus; //Fokus auf Textfeld setzen
  end;
end;

procedure TForm1.ButtonEintragenClick(Sender: TObject); //Vokabeln eintragen
begin
if length(EditEintragen.Text)<>0 then //Wenn Textfeld nicht leer ist
begin
    New(z); //Erzeugen eines neuen Listenelements
    z^.Inhalt:= EditEintragen.Text; //Record wird befüllt
    z^.naechster:=Wurzel; //Zeiger "naechster" wird bisheriger Wurzelwert zugewiesen
    Wurzel:=z; //Zeiger Wurzel wird auf z "verbogen"
    EditEintragen.Text:=''; //Textfeld wieder leeren
    ButtonAnzeigenClick(Sender); //Neue Liste anzeigen
    EditEintragen.SetFocus; //Fokus auf Textfeld setzen
end;
end;

procedure TForm1.RadioButtonFIFOClick(Sender: TObject);
begin
ButtonAnzeigenClick(Sender); //Neue Liste anzeigen
end;

procedure TForm1.RadioButtonLIFOClick(Sender: TObject);
begin
ButtonAnzeigenClick(Sender); //Neue Liste anzeigen
end;

procedure TForm1.ButtonAnzeigenClick(Sender: TObject); //Prozedur zum Anzeigen der Vokabelliste
begin
if RadioButtonFIFO.Checked then //Wenn FIFO-Modus aktiviert...
begin
  ListBoxAnzeige.Items.Clear; //Listbox wird zunächst geleert...
  z:=Wurzel;
  while z<>nil do //...und mit neuer Liste befüllt
    begin
    ListBoxAnzeige.Items.Insert(0,z^.Inhalt);
    z:=z^.naechster;
    end;
end
else if RadioButtonLIFO.Checked then //Wenn LIFO-Modus aktiviert...
begin
  ListBoxAnzeige.Items.Clear; //Listbox wird zunächst geleert...
  z:=Wurzel;
  while z<>nil do //...und mit neuer Liste befüllt
    begin
    ListBoxAnzeige.Items.Add(z^.Inhalt);
    z:=z^.naechster;
    end;
end;
end;

procedure TForm1.ButtonLeerenClick(Sender: TObject); //Listbox wird geleert
begin
ListBoxAnzeige.Items.Clear;
end;

procedure TForm1.ListBoxAnzeigeKeyDown(Sender: TObject; var Key: Word; //Entfernen mit Hilfe der "Delete" Taste
  Shift: TShiftState);
begin
if (Key=VK_DELETE) then ButtonEntfernenClick(Sender); //Entfernen-Button klicken
end;

procedure TForm1.ButtonMarkierenClick(Sender: TObject); //Prozedur markiert alle Einträge der Listbox
var min, max: integer;
begin
max:=ListBoxAnzeige.Count;
for min:=1 to max do ListBoxAnzeige.Selected[min-1]:=true;
end;

procedure TForm1.ButtonEntfernenClick(Sender: TObject); //Button entfernt markierte Einträge aus der Liste
var ii : integer;
    letzter : integer;
begin
if ListBoxAnzeige.Count<>0 then
begin
  with ListBoxAnzeige do
  begin
    for ii := -1 + Items.Count downto 0 do
    if Selected[ii] then
    begin
      Items.Delete(ii);
      letzter:=ii;
    end;
  end;
  if ListBoxAnzeige.Count<=letzter then dec(letzter); //Eintrag an der Stelle der letzten Löschung wird markiert
  ListBoxAnzeige.Selected[letzter]:=true;

//-------------------------------------------------------------------------------------
//----------------------->Schleife, die Änderungen in die Zeigerstruktur übernimmt
//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
end;
end;

procedure TForm1.SpeicherFreigeben; // Speicher für den Zeiger wird freigegeben
var DelPointer : Zeiger;
begin
  while Wurzel <> nil do begin
    DelPointer:=Wurzel;
    Wurzel:=Wurzel^.naechster;
    dispose(DelPointer);
  end;
  Wurzel:=nil;
end;

procedure TForm1.ButtonSpeichernClick(Sender: TObject); //Vokabeldatenbank speichern
var RunPointer : Zeiger;
begin
  Assignfile(f, Datenpfad);
  try
    rewrite(f);
    RunPointer:=Wurzel;
    while RunPointer <> nil do
    begin
      write(f, RunPointer^.Inhalt);
      RunPointer:=RunPointer^.naechster;
    end;
    showmessage('Vokabel-Verzeichnis erfolgreich gespeichert'); //Erfolgsmeldung ausgeben
  finally
    closefile(f);
  end;
end;

procedure TForm1.ButtonLadenClick(Sender: TObject); //Vokabeldatenbank laden
var NewPointer, OldPointer : Zeiger;
begin
  SpeicherFreigeben;
  Assignfile (f, Datenpfad);
  try
    reset(f);
    OldPointer:=nil;
    while not eof(f) do //Auslesen bis Ende der Datei erreicht wird
    begin
      new(NewPointer);
      read(f, NewPointer^.Inhalt);
      NewPointer^.naechster:=nil;
      if OldPointer <> nil then
        OldPointer^.naechster:=NewPointer;
      if Wurzel = nil then
        Wurzel:=NewPointer;
      OldPointer:=NewPointer;
    end;
    ButtonAnzeigenClick(Sender); //Geladene Liste anzeigen
    showmessage('Datenbank erfolgreich geladen'); //Erfolgsmeldung ausgeben
  finally
    closefile(f);
  end;
end;

procedure TForm1.ButtonBeendenClick(Sender: TObject); //Programm beenden
begin
  close;
end;

end.
Vielen Dank im Voraus
jawo3
Jan
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.542 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Einträge nicht nur aus Listbox entfernen

  Alt 29. Aug 2010, 15:46
Eine Frage vorweg: handelt es sich um eine Hausaufgabe, oder wieso verwendest Du eine einfach verkettete Liste? Da es sich ja eh nur um Strings handelt, könntest Du sonst genausogut eine TStringlist verwenden, das wäre um Längen einfacher. Der Vollständigkeit halber aber hier die Vorgehensweise:
- Durchiterieren der Liste
- wenn Nachfolgeelement das gesuchte ist, dessen Nachfolger merken (1)
- Zeiger auf das Nachfolgeelement merken (2)
- Nachfolger des aktuellen Elements auf gemerkten (1) setzen
- gemerkten Zeiger (2) freigeben

Schau einmal in der Tutorials-Sparte, IIRC gibt es da auch ein Tut dazu, das das Ganze detaillierter beschreibt.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
jawo3

Registriert seit: 15. Sep 2009
Ort: Niedersachsen
41 Beiträge
 
#3

AW: Einträge nicht nur aus Listbox entfernen

  Alt 30. Aug 2010, 15:09
Hi,
danke für die Antwort. Ja, die einfach verkettete Liste war eine Vorgabe.
Ich werde mal versuchen, das von dir Beschriebene umzusetzen.

Ich melde mich dann nachher nochmal.

Gruß
jawo3
Jan
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.542 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Einträge nicht nur aus Listbox entfernen

  Alt 30. Aug 2010, 15:28
Ich würde es übrigens andersherum machen: zuerst aus der verketteten Liste löschen und dann die Listbox komplett neu aus dieser Liste füllen, dann sieht man auch, ob alles funktioniert hat. Wenn es sich nicht um allzuviele Einträge handelt und man BeginUpdate/EndUpdate beim Befüllen der ListBox verwendet, sollte das auch ausreichend performant sein.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#5

AW: Einträge nicht nur aus Listbox entfernen

  Alt 30. Aug 2010, 15:39
Guck mal hier: http://www.michael-puff.de/Programmi...orials/Listen/
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
jawo3

Registriert seit: 15. Sep 2009
Ort: Niedersachsen
41 Beiträge
 
#6

AW: Einträge nicht nur aus Listbox entfernen

  Alt 30. Aug 2010, 15:43
Ich schau mir das mal an danke...
Jan
  Mit Zitat antworten Zitat
jawo3

Registriert seit: 15. Sep 2009
Ort: Niedersachsen
41 Beiträge
 
#7

AW: Einträge nicht nur aus Listbox entfernen

  Alt 30. Aug 2010, 15:56
Ich habe mir das jetzt so gedacht für den Entfernen-Button, aber leider funktionier das nicht.
Ich erhalte die Fehlermeldung: Invalid Pointer Operation.

Hier der Quelltext zum Entfernen Button:
Delphi-Quellcode:
procedure TForm1.ButtonEntfernenClick(Sender: TObject); //Button entfernt markierte Einträge aus der Liste
var ii: integer;
    letzter : integer;
begin
  if ListBoxAnzeige.Count<>0 then
  begin
  with ListBoxAnzeige do
      begin
        for ii := -1 + Items.Count downto 0 do
        if Selected[ii] then
        begin
          z:=Wurzel;
            while z<>nil do //Schleife, die Änderung in die Zeigerstruktur übernimmt
              begin
                z:=z^.naechster;
                z^.naechster:=z^.naechster.naechster;
                Dispose(z);
              end;
          Items.Delete(ii);
          letzter:=ii;
        end;
      if ListBoxAnzeige.Count<=letzter then dec(letzter); //Eintrag an der Stelle der letzten Löschung wird markiert
      ListBoxAnzeige.Selected[letzter]:=true;
      end;
  end;
end;
Vielen Dank im Voraus
jawo3
Jan
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.542 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Einträge nicht nur aus Listbox entfernen

  Alt 30. Aug 2010, 16:00
Du willst innerhalb der For-Schleife die komplette verkettete Liste bis auf die Wurzel freigeben?
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
jawo3

Registriert seit: 15. Sep 2009
Ort: Niedersachsen
41 Beiträge
 
#9

AW: Einträge nicht nur aus Listbox entfernen

  Alt 30. Aug 2010, 16:04
Eigentlich nicht

Ich muss also noch einschränken und abgleichen, ob das markierte Element dem aktuellen Zeiger entspricht?
Jan
  Mit Zitat antworten Zitat
jawo3

Registriert seit: 15. Sep 2009
Ort: Niedersachsen
41 Beiträge
 
#10

AW: Einträge nicht nur aus Listbox entfernen

  Alt 30. Aug 2010, 16:08
Dieser Versuch ist leider auch kläglich gescheitert:

Delphi-Quellcode:
procedure TForm1.ButtonEntfernenClick(Sender: TObject); //Button entfernt markierte Einträge aus der Liste
var ii: integer;
    letzter : integer;
begin
  if ListBoxAnzeige.Count<>0 then
  begin
  with ListBoxAnzeige do
      begin
        for ii := -1 + Items.Count downto 0 do
        if Selected[ii] then
        begin
          z:=Wurzel;
            while z<>nil do //Schleife, die Änderung in die Zeigerstruktur übernimmt
              begin
                z:=z^.naechster;
                if ListBoxAnzeige.Items[ii]=z^.Inhalt then
                begin
                  z^.naechster:=z^.naechster.naechster;
                  Dispose(z);
                end;
              end;
          Items.Delete(ii);
          letzter:=ii;
        end;
      if ListBoxAnzeige.Count<=letzter then dec(letzter); //Eintrag an der Stelle der letzten Löschung wird markiert
      ListBoxAnzeige.Selected[letzter]:=true;
      end;
  end;
end;
Jan
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:13 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz