Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi text-string aus 2. klasse aufrufen (https://www.delphipraxis.net/90258-text-string-aus-2-klasse-aufrufen.html)

danku 14. Apr 2007 09:36


text-string aus 2. klasse aufrufen
 
Ich habe 2.Klassen:
Tfmcon(klasse von tform) und TLoadsave (eigene klasse)

sobald man auf einen button in der tfmcon klickt, öffnet sich ein aufruf in der tloadsave:

Delphi-Quellcode:
unitloadsave.log(mlog,'textbsp');
//'test' dient als stringausdruck (erläuterungstext aber siehe doch unten ;) )
// besser wäre es anstatt dem 'textbsp' in der eigenen log-methode dies bereits zu vereinbaren unud diese dann zu übergeben?

in tloadsave steht dann folgende vereinbarung:

Delphi-Quellcode:
//////////////////ÄNDERUNGSLOG////////////////
procedure TLoadSave.log(tsbboxsender:TMemo; erlaeuterung:string);
begin
tsbboxsender.lines.add(datetostr(now)+' :');
end;
ich möchte den erlaeuterungs-text in einem tmemo in tfmcon anzeigen aber da gibts den crash.
wäre es angebrachter mit set und get zu arbeiten?

mkinzler 14. Apr 2007 09:40

Re: text-string aus 2. klassen aufrufen
 
Welcher Fehler tritt wo genau auf?

danku 14. Apr 2007 11:02

Re: text-string aus 2. klassen aufrufen
 
Liste der Anhänge anzeigen (Anzahl: 1)
ich sehe gerad da fehlt noch eine methode:


also ich rufe durch einen button-klick folgende methode auf:

Delphi-Quellcode:
unitloadsave.openfromfilediag(sgdat,opendialog1,edpath);
in der dazugehörigen klasse tloadsave steht:

Delphi-Quellcode:


...

implementation

var fmlog: TMemo;

...
////////////////OPENDIALOG1//////////////////////

procedure TLoadSave.openfromfilediag(sender: TStringgrid;
  opendiag: TOpendialog; edaltsender:TEdit);
var i,j:byte;
count:integer;
log_dat:string;

begin
if opendiag.Execute then
  begin

  ...

   //Log-Daten setzen
   count:= opendiag.Files.Count;
   log_dat:=inttostr(count)+' Datei(en) geladen';
   log(fmlog,log_dat);

   ...
   end;
  end;


//////////////////ÄNDERUNGSLOG////////////////
procedure TLoadSave.log(tsbboxsender:TMemo; erlaeuterung:string);
begin
tsbboxsender.lines.add(datetostr(now)+' :'); ///////////////hier ist das PROBLEM: Zugriffsverletzung//////////
end;

mkinzler 14. Apr 2007 11:06

Re: text-string aus 2. klassen aufrufen
 
-Was ist fmlog?
-Welcher Fehler?

danku 14. Apr 2007 11:18

Re: text-string aus 2. klassen aufrufen
 
der sinn war, das man in der mainclass auf einen button klickt, sodass in der anderen klasse eine methode aufgerufen wird.
hinter dieser methode verbirgt sich die formatierung eines tmemo's in der mainclass,

also es wird ein in der methode, welche in der unitloadsave.openfromfilediag() aufgerufen wird, unitloadsave.log() vorhandener string-wert in das tmemo der mainclass geschrieben.

buttonclick -> procedure TLoadSave.openfromfilediag() aufgerufen -> procedure TLoadSave.log() aufgerufen

mkinzler 14. Apr 2007 11:21

Re: text-string aus 2. klassen aufrufen
 
Welcher Fehler?

danku 14. Apr 2007 11:26

Re: text-string aus 2. klassen aufrufen
 
fehlerdatei siehe oben.
mein problem ist es, in der log-datei zu sagen, daß er das memofeld von der mainclass nehmen soll.
soll ich mit set und get arbeiten?

mkinzler 14. Apr 2007 11:28

Re: text-string aus 2. klassen aufrufen
 
Auf was zeigt fmlog?

danku 14. Apr 2007 11:30

Re: text-string aus 2. klassen aufrufen
 
im moment auf nix. ist nur als variable deklariert. aber die übergabe bereitet mir schwierigkeiten

mkinzler 14. Apr 2007 11:31

Re: text-string aus 2. klassen aufrufen
 
Das F weist auf eine private Variable hin. Existiert eine Property? Getter/Setter?

danku 14. Apr 2007 11:33

Re: text-string aus 2. klassen aufrufen
 
daran arbeite ich noch.

procedure TLoadSave.getmemo(tsbboxsender:TMemo);
begin fmlog:=tsbboxsender;
end;

weiß aber net ob das so richtig ist, und wie vor allem die set-methode arbeitet.
könntest du mal bitte einen lösungsansatz machen?

mkinzler 14. Apr 2007 11:36

Re: text-string aus 2. klassen aufrufen
 
Das ist eigentlich der Setter
Delphi-Quellcode:
procedure TLoadSave.setMemo(tsbboxsender:TMemo);
begin
    fmlog:=tsbboxsender;
end;

function TLoadSave.getMemo:TMemo;
begin
    result := fmlog;
end;

danku 14. Apr 2007 11:53

Re: text-string aus 2. klassen aufrufen
 
danke dir erst mal. und wie vereinbare ich das dann in meiner log-methode?
Delphi-Quellcode:
//////////////////ÄNDERUNGSLOG////////////////
procedure TLoadSave.log(tsbboxsender:TMemo; erlaeuterung:string);
begin
tsbboxsender.lines.add(datetostr(now)+' :');
end;
wo code ich dann, dass fmlog gleich dem tmemo aus der mainclass ist?

Jelly 14. Apr 2007 13:06

Re: text-string aus 2. klasse aufrufen
 
Ich hab das Gefühl, du hast das Konzept der OO Programmierung nicht ganz verstanden. Sinn ist es, dass Objekte eigenständig arbeiten sollen. In deinem Fall ist die Klasse TLoadSave. Und so wie es aussieht, soll die Texte in einem Memo wegloggen. Es macht dann keinen Sinn, bei jedem Aufruf deiner Log Methode das Memo mitzuübergeben. So Sachen macht man einmal, in deinem Fall würd ich es im Constructor machen. Und um bischen flexibel zu bleiben, würde ich mich nicht auf ein Memo beschränken, sondern würde im Constructor einfach eine TStrings Instanz übergeben.

Delphi-Quellcode:
unit uLoadSave;

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

type
  TLoadSave = class
  private
     FStringList: TStrings;
  public
     constructor Create (AStringList : TStrings) ; reintroduce ;
     property StringList : TStrings read FStringList write FStringList ;

     procedure Log (What : string) ;
  end;

implementation

{ TLoadSave }

constructor TLoadSave.Create(AStringList: TStrings);
begin
     inherited Create ;
     assert (assigned(AStringList) and (AStringList is TStrings),'Bitte StringList Objekt im Constructor übergeben') ;
     FStringList := AStringList ;
end;

procedure TLoadSave.Log(What: string);
begin
     FStringList.Add (What) ;
end;

end.
Der Aufruf erfolgt dann so:

Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
     LS := TLoadSave (memo1.lines) ;  // LS als Variable in deiner Form deklarieren
end;

procedure TForm1.Button1Click (Sender : TObject) ;
begin
    LS.Log ('Halleluja') ;
end ;

danku 15. Apr 2007 10:50

Re: text-string aus 2. klasse aufrufen
 
ich hab das anders gelöst.
ohne konstruktor, weil doch der standardkonstruktor von delphi zur geltung kommt, sobald man keinen angibt.

Delphi-Quellcode:
procedure TLoad.openfromfilediag(sender: TStringgrid;
  opendiag: TOpendialog; edaltsender:TEdit; sendermemo: TMemo);
var i,j:byte;

begin
if opendiag.Execute then
  begin

...

   //Log-Daten setzen
   unitlog.setmemo(sendermemo);
   unitlog.setdiag(opendiag);
   unitlog.log(unitlog.getMemo,unitlog.getdiag,1, clblack);
so geht das auch.

Jelly 15. Apr 2007 10:58

Re: text-string aus 2. klasse aufrufen
 
Zitat:

Zitat von danku
ich hab das anders gelöst.
ohne konstruktor, weil doch der standardkonstruktor von delphi zur geltung kommt, sobald man keinen angibt.

Ich hab das Schlüsselwort reintroduce hinter dem Konstruktor stehen. Damit bist du gezwungen, diesen zu verwenden mit einem Parameter. Du kannst somit kein Objekt mehr erstellen mit dem Standardkonstruktor.

Zitat:

Zitat von danku
Delphi-Quellcode:
   unitlog.setmemo(sendermemo);
   unitlog.setdiag(opendiag);
   unitlog.log(unitlog.getMemo,unitlog.getdiag,1, clblack);
so geht das auch.

Das beisst sich immer noch in meinen Augen. mir ist klar, dass man unterschiedliche Techniken haben kann, um seine Welt in Klassen zu modelieren. Aber was mich hier stört ist, dass du als erstes das Memo mit SetMemo setzt. UnitLog kennt damit also das Logmemo. Bei SetDiag genau das gleiche. Das kann man so machen, von mir aus, und muss ja nicht über den Konstruktor übergeben werden. Aber warum schreibst du dann eine Log-Methode die dann 2 Parameter benötigt, die deinem Objekt ja eh schon bekannt sind. :gruebel: Entweder du sparst dir die ersten beiden Aufrufe, oder du kürzt bei der Log-Methode die ersten 2 Parameter weg.

danku 15. Apr 2007 11:16

Re: text-string aus 2. klasse aufrufen
 
ohne
unitlog.setmemo(sendermemo);
unitlog.setdiag(opendiag);

geht das aber nicht weil dann eine zugriffsverletzung kommt.

Jelly 15. Apr 2007 11:29

Re: text-string aus 2. klasse aufrufen
 
Dann zeig doch mal deine Log Methode komplett. Du hast irgendwo den Wurm drin.

danku 15. Apr 2007 11:49

Re: text-string aus 2. klasse aufrufen
 
Delphi-Quellcode:
function TLog.log(tsbboxsender:TMemo; opendiag: TOpendialog; erlaeuterung:byte; farbe: TColor):string;

    function shortcutarray(erlaeut:LongInt):string;
    var count:integer;
    begin


    //opendialog1
    setdiag(fmdiag);
    count:= opendiag.Files.Count;

    case erlaeut of
    1:Result:= inttostr(count)+' Datei(en) geladen';
    2:Result:= 'test22';
    end;
    end;


var log_dat:string;
count,i:integer;
//erlauterung:byte;
begin



{case erlaeuterung of
1:Result:= inttostr(count)+' Datei(en) geladen';
2:Result:= 'test';
 end;          }

tsbboxsender.Font.Color:= farbe;
tsbboxsender.lines.add('['+TimeToStr(now)+'] : '+ shortcutarray((erlaeuterung)));

 for i:=0 to opendiag.files.count -1 do
   begin
   tsbboxsender.lines.add('                   -> '+ Extractfilename(opendiag.files.Strings[i]));
end;

end;

Jelly 15. Apr 2007 12:03

Re: text-string aus 2. klasse aufrufen
 
In welcher Zeile kommt den die Zurgiffsverletzung. Und was soll das hier in der ShortCutArray Funktion:
Delphi-Quellcode:
    //opendialog1 
    setdiag(fmdiag);
    count:= opendiag.Files.Count;

danku 15. Apr 2007 12:48

Re: text-string aus 2. klasse aufrufen
 
Liste der Anhänge anzeigen (Anzahl: 1)
der shortcutarray ist vielleicht von der bezeichnung her nicht treffend gewählt.

man übergibt der funktion den gewünschten wert (bspw. 1 und der rest wir halt ausgegeben)
unitlog.log(unitlog.getMemo,unitlog.getdiag,1, clblack);

das ist aber nicht das problem.

der fehler kommt bei der memoeigenschaft color.

Jelly 15. Apr 2007 13:02

Re: text-string aus 2. klasse aufrufen
 
Der Fehler deutet darauf hin, dass tsbboxsender nicht instanziert ist.
Machs, wie ich es dir vorgeschlagen hat, und du wirst die Probleme nicht mehr haben. In deinem Code geht einfach nicht klar hervor, wann du auf welche memo Komponente zugreifst.

danku 16. Apr 2007 15:59

Re: text-string aus 2. klasse aufrufen
 
Zitat:

Zitat von Jelly
Ich hab das Gefühl, du hast das Konzept der OO Programmierung nicht ganz verstanden. Sinn ist es, dass Objekte eigenständig arbeiten sollen. In deinem Fall ist die Klasse TLoadSave. Und so wie es aussieht, soll die Texte in einem Memo wegloggen. Es macht dann keinen Sinn, bei jedem Aufruf deiner Log Methode das Memo mitzuübergeben. So Sachen macht man einmal, in deinem Fall würd ich es im Constructor machen. Und um bischen flexibel zu bleiben, würde ich mich nicht auf ein Memo beschränken, sondern würde im Constructor einfach eine TStrings Instanz übergeben.

Delphi-Quellcode:
unit uLoadSave;

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

type
  TLoadSave = class
  private
     FStringList: TStrings;
  public
     constructor Create (AStringList : TStrings) ; reintroduce ;
     property StringList : TStrings read FStringList write FStringList ;

     procedure Log (What : string) ;
  end;

implementation

{ TLoadSave }

constructor TLoadSave.Create(AStringList: TStrings);
begin
     inherited Create ;
     assert (assigned(AStringList) and (AStringList is TStrings),'Bitte StringList Objekt im Constructor übergeben') ;

     FStringList := AStringList ;
end;

procedure TLoadSave.Log(What: string);
begin
     FStringList.Add (What) ;
end;

end.
Der Aufruf erfolgt dann so:

Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
     LS := TLoadSave (memo1.lines) ;  // LS als Variable in deiner Form deklarieren
end;

procedure TForm1.Button1Click (Sender : TObject) ;
begin
    LS.Log ('Halleluja') ;
end ;

nimms mir nicht übel aber mit dem LS kann ich nichts anfangen. dieser dient doch als klassenbezeichner (punkt-notation) um damit die methoden aufzurufen. es gehört trotzdem noch get und set mit in die unit oder? bei procedure TLoad.Log(What: string); kommt eine EAccessViolation Meldung

Jelly 16. Apr 2007 16:17

Re: text-string aus 2. klasse aufrufen
 
Zitat:

Zitat von danku
nimms mir nicht übel aber mit dem LS kann ich nichts anfangen. dieser dient doch als klassenbezeichner (punkt-notation) um damit die methoden aufzurufen. es gehört trotzdem noch get und set mit in die unit oder? bei procedure TLoad.Log(What: string); kommt eine EAccessViolation Meldung

Verwechsle Klasse nicht mit Objekt=Instanz einer Klasse :!:

Aber natürlich müsstest du den Code anpassen, damit deine Klasse auch vom OpenDialog Bescheid weiss. Würd ich ebenfalls entweder über den Konstruktor mit übergeben, oder im bestehenden Konstruktor eine eigenen TOpenDialog Instanz erzeugen. Ich tendiere zu letzterem, aber das ist wirklich Geschmackssache. Deshalb, weils jetzt wohl schneller so geht, doch erste Möglichkeit:

Delphi-Quellcode:
constructor Create (AStringList : TStrings; AOpenDialog : TOpenDialog) ; reintroduce ;
und die dazu gehörende Implementierung:
Delphi-Quellcode:
constructor TLoadSave.Create(AStringList: TStrings);
begin
     inherited Create ;
     assert (assigned(AStringList) and (AStringList is TStrings),'Bitte StringList Objekt im Constructor übergeben') ;
     assert (assigned(AOpenDialog) and (AOpenDialog is TOpenDialog),'Bitte OpenDaialog Objekt im Constructor übergeben') ;


     FStringList := AStringList ;
     FOpenDialog := AOpenDialog ;
end;
und die erweiterte Log Methode:
Delphi-Quellcode:
procedure TLoadSave.Log(What: string);
    function shortcutarray(erlaeut:LongInt):string;
    var
      count:integer;
    begin
       count:= FOpenDialog.Files.Count;

       case erlaeut of
           1 : Result:= inttostr(count)+' Datei(en) geladen';
           2 : Result:= 'test22';
       end;
    end;


var
  log_dat:string;
  count,i:integer;
begin
    FStringList.lines.add('['+TimeToStr(now)+'] : '+ shortcutarray((erlaeuterung)));

    for i:=0 to FOpenDialog.files.count -1 do
    begin
           FStringList.lines.add('                   -> '+ Extractfilename(FOpenDialog.files.Strings[i]));
    end;
end ;
Soll nun wirklich die Farbe mit in der Log Methode übergeben werden, so sollte eventuell wirklich anstatt einer TStringList ein TMemo im Konstruktor übergeben werden, und auch im restlichen Code daran angepasst werden.

danku 16. Apr 2007 16:42

Re: text-string aus 2. klasse aufrufen
 
ja die farbe sollte mit übernommen werden.
muss alles in den konstruktor rein, was an die mainform übergeben wird?
das ist mir ein wenig konfus. in c# gefällt mir das ein wenig besser, da hab ich nicht soviel schreibarbeit

Jelly 16. Apr 2007 21:04

Re: text-string aus 2. klasse aufrufen
 
Zitat:

Zitat von danku
muss alles in den konstruktor rein, was an die mainform übergeben wird?

Nö, müssen nicht. Aber das ist eine Methode die sicherstellt, dass der Anwender nichts vergisst. Deine Klasse ist auf 2 Parameter angewiesen, um überhaupt arbeiten zu können: Ein OpenDialog und ein Memo. Also würd ichs in den Constructor packen. Das erspart dir in den restlichen Methoden das Prüfen, ob auch ein Memo und ein Opendialog zugewiesen ist.
Zitat:

Zitat von danku
in c# gefällt mir das ein wenig besser, da hab ich nicht soviel schreibarbeit

Das musst Du mir erklären. Denn da funktioniert das genauso. Da hast du auch constructor und Methoden, und properties die du mit setter- und getter Methoden ausrüsten kannst. Was erspart dir da Tipparbeit.


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:40 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz