|
Forum: "Kennt jemand Delphi 6?"
Bitte beachte die Netiquette! Doppeleinträge werden von der Redaktion gelöscht.
|
| Kennt jemand Delphi 6? | | von: cath1
erstellt: 18.06.2014 19:53:15 |
Hallo, meine Tochter hockt seit 3 Wochen über einer Aufgabe, kommt jedoch nicht wirklich weiter. Nachfragen in Foren zum Programm und im Bekanntenkreis führten zu keiner Erkenntnis. Habt ihr vielleicht einen Tipp?
Hier die Erklärungen meiner Tochter:
Wir haben in der Schule die Aufgabe bekommen ein Programm mit Delphi 6 selbst zu schreiben, uns blieb dabei überlassen, welche Art von Programm wir erstellen.
Ich habe mich für eine Art Vokabeltrainer entschieden, allerdings mit Geschichtsjahreszahlen/-ereignissen.
Ich habe bereits mit dem Schreiben des Quelltextes begonnen und möchte einmal kurz umreißen, wie ich mir das Programm vorgestellt habe
Ich habe eine separate Textdatei (war Pflicht bzw. eine typisierte Datei), deren Inhalt ich in die ListBox hochlade. Der Inhalt besteht aus geschichtlichen Ereignissen, wie z.B. 1806;Rheinbund. Die ListBox ist beim Ausführen des Programms nicht sichtbar. Eine Zeile der Textdatei wird zufällig in das Panel geladen und zu diesem Ereignis muss dann später die passende Jahreszahl eingegeben werden (Edit-Feld).
Durch Klick auf den "Neues Ereignis" Button soll zufällig ein neues Ereignis aus der Textdatei in das Panel geladen werden.
Durch Klick auf den "Ok"-Button soll geprüft werden, ob die eingegebene Jahreszahl mit dem Ereignis übereinstimmt.
Mein bisheriger Quelltext lautet:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, ExtCtrls;
type
TForm1 = class(TForm)
Panel1: TPanel;
AbbruchButton: TBitBtn;
JahreszahlEdit: TEdit;
Label1: TLabel;
Label2: TLabel;
BitBtn1: TBitBtn;
EreignisButton: TBitBtn;
AnleitungButton: TBitBtn;
ListBox1: TListBox;
EreignisPanel: TPanel;
procedure AbbruchButtonClick(Sender: TObject);
procedure BitBtn1Click(Sender: TObject);
procedure AnleitungButtonClick(Sender: TObject);
procedure EreignisButtonClick(Sender: TObject);
private
{ Private-Deklarationen }
FJahr:String;
public
{ Public-Deklarationen }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
var Jahreszahl:Integer;
Datei: file of byte;
procedure Trennung(text:String; var TAntwort,TFrage:String);
const
Frage_Antwort='Rheinbund;1806';
Trenner=';';
var Frage, Antwort:String;
iPos,zufall:integer;
begin
iPos:=Pos(';','Rheinbund;1806');
if iPos > 0 then
begin
Frage:=Copy('Rheinbund;1806',0, iPos+1);
Antwort:=Copy('Rheinbund;1806',0, iPos-1);
end;
end;
procedure TForm1.AbbruchButtonClick(Sender: TObject);
begin
close
end;
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
Jahreszahl:=StrToInt(JahreszahlEdit.Text);
if Frage=Jahreszahl then
begin
ShowMessage('Das war richtig!');
end;
procedure TForm1.AnleitungButtonClick(Sender: TObject);
begin
ShowMessage('Wie funktioniert dieser Trainer?'+#13+'Durch das Klicken auf den Button "Neues Ereignis" wird zufällig ein geschichtliches Ereignis ausgewählt'+#13+ 'und unter dem Wort "Ereignis" angezeigt. Ihre Aufgabe ist es nun die richtige Jahreszahl des angezeigten Ereignisses anzugeben,indem sie die Jahreszahl in das Feld unterhalb der Wörter "Gesuchte Jahreszahl" eingeben.'+#13+'Mit Klick auf den "Ok"-Button bestätigen Sie Ihre Eingabe und Sie werden darüber informiert, ob Ihre Eingabe richtig war.'+#13+'Mit einem erneuten Klick auf den "Neues Ereignis"-Button wird das nächste Ereignis angezeigt.');
end;
procedure TForm1.EreignisButtonClick(Sender: TObject);
var zufall:Integer;
Ereignis:String;
begin
ListBox1.Items.LoadFromFile('TextEreignis.txt');
randomize;
zufall:=random(ListBox1.Items.Count);
Trennung(ListBox1.Items.Strings[Zufall], FJahr, Ereignis);
EreignisPanel.Caption:=Ereignis;
end;
end.
Folgende Fragen/Probleme bleiben für mich allerdings offen:
1) „Frage“ ist beim OnClick des Ok-Buttons undefiniert. Muss ich die Variable trotzdem als String deklarieren, oder ist es mir irgendwie möglich in dem Zusammenhang die Prozedur aufzurufen, da sich die Frage ja an sich darauf bezieht?
2) Es soll später möglich sein, die Textdatei um Ereignisse zu erweitern, welche Schritte aus der Prozedur müsste ich da wiederholen und wo deklariere ich diese?
3) Wenn ich die Zeile " if Frage=Jahreszahl then“ weglassen, läuft das Programm soweit, aber es passiert eben nicht. Es wird kein Ereignis aus der Textdatei geladen. Wo liegt mein grundlegender Fehler, dass nicht auf die Textdatei zugegriffen wird und ein Ereignis in das Panel geladen wird? Auch wenn ich mit „EreignisPanel.Caption:=ListBox1.Items.Strings[Zufall];“ arbeite, passiert nichts.
4) Beim Ereignis-Button gibt es die Zeile „Trennung(ListBox1.Items.Strings[Zufall], FJahr, Ereignis);“, wo ja die Prozedur aufgerufen wird, wofür steht aber FJahr (private Deklaration)? Mir wurde geraten mit einer privaten Deklaration zu arbeiten, aber allerdings verstehe ich den Sinn dahinter nicht? Was genau macht FJahr in Verbindung mit dieser Zeile?
Falls es weitere Fehler/Anmerkungen gibt, wäre ich sehr froh über Hilfe! |
| ... | | von: cath1
erstellt: 19.06.2014 14:31:02 |
Hallo rwx,
danke für deine Hilfe!
Nachdem ich "Frage" im privaten Teil deklariert habe,
funktioniert dies nun soweit!
Zu 2)
Nein, nicht zur Laufzeit. Wenn ich später weitere Zeilen in
der Textdatei ergänze, soll es möglichst einfach sein, die
jeweiligen Fragen und Antworten im Quelltext hinzuzufügen.
Sobald die Prozedur soweit funktioniert, dass Frage und
Antwort (in der Textdatei durch ein Semikolon getrennt)
durch Pos entsprechend getrennt werden, soll es möglich
sein, genau dasselbe Trennverfahren für alle weiteren
Fragen/Antworten anzuwenden.
So, dass es am Ende möglich sein sollte, durch ein Klick auf
den "Ok"-Button zu vergleichen, ob die eingegebene
Jahreszahl der entspricht, die laut Textdatei vorgegeben
ist.
Hilft dir diese Antwort soweit, dass du eventuell zu 3),4)
und 5) Vermutungen anstellen könntest?
MfG |
| . | | von: rwx
erstellt: 19.06.2014 16:42:44 |
Gestern um fast Mitternacht war wohl zu spät. Ich hatte auf alle Fragen geantwortet, aber die Antworten sind abhanden gekommen.
zu 2)
Ich verstehe es nicht, aber ich glaube zu 4) löst das Problem mit
zu 3) Wenn ich die Zeile " if Frage=Jahreszahl then“ weglassen, läuft das Programm soweit, aber es passiert eben nicht. Es wird kein Ereignis aus der Textdatei geladen.
Gleiches Problem, Frage ist in dieser Prozedur gar nicht definiert, ergo leer und der Vergleich schlägt fehl.
Ändern in von
if Frage=Jahreszahl
zu
if FJahr=Jahreszahl
Zusätzlich Änderungen aus zu 4) durchführen
zu 4) Beim Ereignis-Button gibt es die Zeile „Trennung(ListBox1.Items.Strings[Zufall], FJahr, Ereignis);“, wo ja die Prozedur aufgerufen wird, wofür steht aber FJahr (private Deklaration)? Mir wurde geraten mit einer privaten Deklaration zu arbeiten, aber allerdings verstehe ich den Sinn dahinter nicht? Was genau macht FJahr in Verbindung mit dieser Zeile?
FJahr ist eine globale (für das gesamte Programm definierte) Variable, diese wird im Programm aber nirgends gesetzt, Ergeinis ist eine lokale Variable die ebenfalls leer ist. Zufall wird im Aufruf groß geschrieben, bei der Deklaration klein, das sieht auch nicht gut aus.
Lösung:
Variablennamen immer identisch schreiben
Ereignis analog zu FJahr global deklarieren.
Die Prozedur Trennung wie folgt ändern
procedure Trennung(Ereignis_Jahr:String;);
Trenner=';';
begin
iPos:=Pos(';',Ereignis_Jahr);
if iPos > 0 then
begin
Ereignis:=Copy(Ereignis_Jahr,0, iPos+1);
FJahr:=Copy(Ereignis_Jahr,0, iPos-1);
end;
Die Zeilen
zufall:=random(ListBox1.Items.Count);
Trennung(ListBox1.Items.Strings[Zufall], FJahr, Ereignis);
EreignisPanel.Caption:=Ereignis;
ändern in
zufall:=random(ListBox1.Items.Count);
Trennung(ListBox1.Items.Strings[zufall]);
EreignisPanel.Caption:=Ereignis;
Alles ohne Gewähr und aus dem Kopf |
| . | | von: cath1
erstellt: 19.06.2014 17:25:43 |
Ich hab versucht alle deiner Verbesserungen zu übernehmen;
private
{ Private-Deklarationen }
FJahr, Ereignis:String;
Frage,Antwort:String;
public
{ Public-Deklarationen }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
var Jahreszahl:Integer;
procedure Trennung(Ereignis_Jahr:String);
const
Frage_Antwort='Rheinbund;1806';
Trenner=';';
var Frage, Antwort:String;
iPos,zufall:integer;
begin
iPos:=Pos(';',Ereignis_Jahr);
if iPos > 0 then
begin
Ereignis:=Copy(Ereignis_Jahr,0, iPos+1);
FJahr:=Copy(Ereignis_Jahr,0, iPos-1);
end;
end;
procedure TForm1.AbbruchButtonClick(Sender: TObject);
begin
close
end;
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
Jahreszahl:=StrToInt(JahreszahlEdit.Text);
if FJahr=Jahreszahl then
begin
ShowMessage('Das war richtig!');
end;
end;
procedure TForm1.AnleitungButtonClick(Sender: TObject);
begin
ShowMessage('Wie funktioniert dieser Trainer?'+#13+'Durch
das Klicken auf den Button "Neues Ereignis" wird zufällig
ein geschichtliches Ereignis ausgewählt'+#13+ 'und unter dem
Wort "Ereignis" angezeigt. Ihre Aufgabe ist es nun die
richtige Jahreszahl des angezeigten Ereignisses
anzugeben,indem sie die Jahreszahl in das Feld unterhalb der
Wörter "Gesuchte Jahreszahl" eingeben.'+#13+'Mit Klick auf
den "Ok"-Button bestätigen Sie Ihre Eingabe und Sie werden
darüber informiert, ob Ihre Eingabe richtig war.'+#13+'Mit
einem erneuten Klick auf den "Neues Ereignis"-Button wird
das nächste Ereignis angezeigt.');
end;
procedure TForm1.EreignisButtonClick(Sender: TObject);
var zufall:Integer;
begin
ListBox1.Items.LoadFromFile('TextEreignis.txt');
randomize;
zufall:=random(ListBox1.Items.Count);
Trennung(ListBox1.Items.Strings[zufall]);
EreignisPanel.Caption:=Ereignis;
end;
end.
Dennoch zeigt mir Delphi folgenden Fehler an:
In der Zeile "if FJahr=Jahreszahl then" wird mir angezeigt,
dass FJahr(String) und Jahreszahl(Integer) inkompatibel
sind. Das leuchtet mir auch soweit ein.
Aber was soll ich jetzt dem anderen entsprechend anpassen?
Als Jahreszahl habe ich ja das deklariert, was der Benutzer
in das Editfeld schreiben soll - und das ist ja eine ganze
Zahl (z.B. 1806).
Desweiteren ist es beim Programmstart nicht möglich,
Ereignisse aus der Textdatei zu laden, das Panel bleibt
leer.
Und sobald ich versuche etwas in das Editfeld zu schreiben,
hängt sich das Programm auf.
Wo liegen da die Probleme? Was habe ich nicht/falsch
deklariert?
Nochmal zu 2)
Ich habe eine separate Textdatei mit momentanen Inhalt
"Rheinbund;1806
Code Civil;1804
Hambacher Fest;1832"
Es soll später möglich sein die Textdatei zu erweitern - mit
entsprechenden Ereignissen und Jahreszahlen.
Nun soll mein Programm ja auf der Textdatei basierende
Ereignisse und Jahreszahlen trennen (dafür die Funktion Copy
und Pos sowie das Semikolon als Trenner).
Die Prozedur Trennung soll es ermöglichen mit einer
(zufällige) Zeile der Textdatei zu arbeiten - indem in der
Prozedur Ereignis und Jahreszahl der Textdatei getrennt
werden (Demnach soll ja auch auf dieser Basis ein Ereignis
der Textdatei in das Panel geladen werden und die dem
Ereignis entsprechende Jahreszahl soll der Benutzer im
Editfeld eingeben.) Da ich nun aber mehrere Ereignisse und
Jahreszahlen habe, muss ich im Programm zuerst festlegen
welche Jahreszahl zu welchem Ereignis gehört (oder?).
Meine Frage bezog sich daher darauf, welche Zeilen ich
jeweils wiederholen muss, damit Jahreszahl und Ereignis
jeweils getrennt und richtig zugeordnet werden.
|
| , | | von: cath1
erstellt: 19.06.2014 22:15:11 |
Ich habs leider auf den Weg mit der Umwandlung zu IntToStr
nicht hinbekommen,denn da wurde mir gesagt, dass das bei
diesem Typ nicht möglich ist. Ich hab jetzt FJahr einen
Integer Wert zugewiesen - das ändert doch nichts an der
ganzen Sache, oder?
"Woher stammt denn dieser Code:
ListBox1.Items.LoadFromFile('TextEreignis.txt');
Hier könnte es evtl schon helfen den vollen Pfad zu
TextEreignis.txt anzugeben"
Der ist speziell für die ListBox, damit wird der Inhalt der
Textdatei in die ListBox geladen. Anders weiß ich nicht, wie
es mir möglich ist, auf die Textdatei zuzugreifen; daher
wüsste ich auch nicht, wie ich den vollständigen Pfad
anzugeben hätte.
"und was genau heißt hängt sich auf? "
Wenn das Programm läuft lassen sich alle Buttons klicken,
bis auf den Ok-Button. Wenn ich diesen klicke, friert das
Programm sozusagen ein, es lässt sich nirgendwo mehr klicken
und ich muss es "unsanft" beenden.
"D.h. jedesmal wenn jemand auf den Ereignis-Button klickt
wird ListBox1 neu befüllt und ein zufälliges Ereignis
ausgewählt. Das ist imho dass was du haben möchtest.
Es würde auch reichen ListBox1 nur einmal zu befüllen, statt
bei jedem Ereignis neu."
Wenn das so funktionieren würde, wäre ich froh. Es wird zwar
der Inhalt in die ListBox geladen, aber kein Ereignis in das
Panel. Das funktioniert bei mir nur mit der Zeile
EreignisPanel.Caption:=ListBox1.Items.Strings[Zufall];
die ich allerdings nicht im Quelltext stehen habe, weil ich
nicht wusste, ob sich das nicht mit der Prozedur
überschneidet, die direkt eine Zeile darüber steht.
Und woher kann ich mir sicher sein, dass die Prozedur genau
das macht, was sie soll? Ich habe keine Möglichkeit während
der Laufzeit zu schauen, ob Ereignis und FJahr getrennt
wurden.
Ich habe auch das Gefühl, dass nach diesen Zeilen
iPos:=Pos(';',Ereignis_Jahr);
if iPos > 0 then
begin
Ereignis:=Copy(Ereignis_Jahr,0, iPos+1);
FJahr:=Copy(Ereignis_Jahr,0, iPos-1);
irgendetwas in der Prozedur fehlt, um Ereignis und Jahr
definitiv voneinander zu trennen? Bzw. Jahr und Ereignis
separat voneinander zu speichern/nutzen?
Zur Vollständigkeit nochmal mein Quelltext:
private
{ Private-Deklarationen }
FJahr:Integer;
Ereignis:String;
Frage,Antwort:String;
public
{ Public-Deklarationen }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
var Jahreszahl:Integer;
procedure Trennung(Ereignis_Jahr:String);
const
Frage_Antwort='Rheinbund;1806';
Trenner=';';
var Ereignis,FJahr:String;
iPos,zufall:integer;
begin
iPos:=Pos(';',Ereignis_Jahr);
if iPos > 0 then
begin
Ereignis:=Copy(Ereignis_Jahr,0, iPos+1);
FJahr:=Copy(Ereignis_Jahr,0, iPos-1);
end;
end;
procedure TForm1.AbbruchButtonClick(Sender: TObject);
begin
close
end;
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
Jahreszahl:=StrToInt(JahreszahlEdit.Text);
JahreszahlEdit.Text:=IntToStr(Jahreszahl);
if FJahr=Jahreszahl then
begin
ShowMessage('Das war richtig!');
end;
end;
procedure TForm1.AnleitungButtonClick(Sender: TObject);
begin
ShowMessage('Wie funktioniert dieser Trainer?'+#13+'Durch
das Klicken auf den Button "Neues Ereignis" wird zufällig
ein geschichtliches Ereignis ausgewählt'+#13+ 'und unter dem
Wort "Ereignis" angezeigt. Ihre Aufgabe ist es nun die
richtige Jahreszahl des angezeigten Ereignisses
anzugeben,indem sie die Jahreszahl in das Feld unterhalb der
Wörter "Gesuchte Jahreszahl" eingeben.'+#13+'Mit Klick auf
den "Ok"-Button bestätigen Sie Ihre Eingabe und Sie werden
darüber informiert, ob Ihre Eingabe richtig war.'+#13+'Mit
einem erneuten Klick auf den "Neues Ereignis"-Button wird
das nächste Ereignis angezeigt.');
end;
procedure TForm1.EreignisButtonClick(Sender: TObject);
var zufall:Integer;
begin
ListBox1.Items.LoadFromFile('TextEreignis.txt');
randomize;
JahreszahlEdit.SetFocus;
zufall:=random(ListBox1.Items.Count);
Trennung(ListBox1.Items.Strings[zufall]);
EreignisPanel.Caption:=Ereignis;
end;
end.
Dankeschön! |
| . | | von: rwx
erstellt: 20.06.2014 10:39:53 |
Ich habs leider auf den Weg mit der Umwandlung zu IntToStr
nicht hinbekommen,denn da wurde mir gesagt, dass das bei
diesem Typ nicht möglich ist. Ich hab jetzt FJahr einen
Integer Wert zugewiesen - das ändert doch nichts an der
ganzen Sache, oder?
Nein, solange beide Variablen unterschiedliche Datentypen haben wird das nichts. Man muss also mindestens einen konvertieren, IntToStr sollte eigentlich aus einem Integer einen String machen.
ListBox1.Items.LoadFromFile('TextEreignis.txt');
Hier könnte es evtl schon helfen den vollen Pfad zu
TextEreignis.txt anzugeben"
Der ist speziell für die ListBox, damit wird der Inhalt der
Textdatei in die ListBox geladen. Anders weiß ich nicht, wie
es mir möglich ist, auf die Textdatei zuzugreifen; daher
wüsste ich auch nicht, wie ich den vollständigen Pfad
anzugeben hätte.
Was der Code tun soll ist mir schon klar, es ging mir mehr darum, ob er aus einem Beispiel o.Ä. stammt. Vollständiger Pfad wäre z.B. (auf Windows) 'C:\MeinVerzeichnis\Irgendwas\TextEreignis.txt'
Wenn das Programm läuft lassen sich alle Buttons klicken,
bis auf den Ok-Button. Wenn ich diesen klicke, friert das
Programm sozusagen ein, es lässt sich nirgendwo mehr klicken
und ich muss es "unsanft" beenden.
Das klingt als wäre in einem Handler eine Endlosschleife. Ich sehe da aber im Code nichts, evtl. hilft hier auch ein Debugger weiter.
Wenn das so funktionieren würde, wäre ich froh. Es wird zwar
der Inhalt in die ListBox geladen, aber kein Ereignis in das
Panel. Das funktioniert bei mir nur mit der Zeile
EreignisPanel.Caption:=ListBox1.Items.Strings[Zufall];
die ich allerdings nicht im Quelltext stehen habe, weil ich
nicht wusste, ob sich das nicht mit der Prozedur
überschneidet, die direkt eine Zeile darüber steht.
EreignisPanel.Caption:=Ereignis;
sollte reichen, wenn ListBox1 ordentlich gefüllt ist und Trennung tut was es soll.
Und woher kann ich mir sicher sein, dass die Prozedur genau
das macht, was sie soll? Ich habe keine Möglichkeit während
der Laufzeit zu schauen, ob Ereignis und FJahr getrennt
wurden.
Ich habe auch das Gefühl, dass nach diesen Zeilen
Hat die Entwicklungsumgebung keine Debugger mit dem man schrittweise durch das Programm laufen kann?
Falls nicht hilft es Zwischenergebnisse ausgeben zu lassen (ShowMessage, o.Ä.) |
Beitrag (nur Mitglieder) |
|
|