Wie kann man mehrzeilige Texte im Programm ablegen?!

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.
Lorca
Beiträge: 196
Registriert: Di 3. Nov 2020, 12:25

Wie kann man mehrzeilige Texte im Programm ablegen?!

Beitrag von Lorca »

Moin zusammen, :)

wie kann ich Texte in meinem eigenen Lazarus Programm ablegen??
Will sagen, diese Texte sollen mit dem Programm kompiliert werden.

Das Ablegen über eine TStringlist in eine externe Datei ist für mich inakzeptabel.
Ein TMemo währe denkbar, ist jedoch ebenfalls nicht nicht akzeptabel, da diese immer mit VISIBLE = False während der Laufzeit verborgen werden müssen.

Bis jetzt lege ich immer konstanten UNITs an wo ich dann meine Texte hinterlege.
Das ist aber sehr umständlich wenn es sich um Zeilen übergreifende Texte handelt.
Beispiel:
CONST
_Text_Beliebig = 'Dies ist ein Test zur Anzeige ' +
'zur Anzeige von mehrzeiligen ' +
'Texten.';

So etwas sieht nicht nur unschön aus, es ist auch nervig immer mit den Pluszeichen zu arbeiten.
Außerdem wird so eine UNIT sehr schnell unübersichtlich.

Gibt es eine Komponente die man im Datenmodul ablegen kann, und wie z.B. TMemo verwendet werden kann?
Oder ...
Hat jemand von euch eine Idee dazu?

Viele Grüße
Lorca :)

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2641
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Wie kann man mehrzeilige Texte im Programm ablegen?!

Beitrag von m.fuchs »

Also ich gehe auch immer über Konstanten, dann habe ich alles gut im Quellcode beisammen.
Wenn es zuviel wird, lagere ich die Konstanten auch ein eine eigene Unit aus.

Damit es beim Tippen nicht zu aufwändig wird mit den Pluszeichen und LineEndings, etc. habe ich mir einen Codegenrator gebastelt.
Da kommt dann einfach nur der mehrzeilige Text rein und auf Knopfdruck wirft er die fertige Konstantendeklaration heraus.

Einfach hier: https://sourceforge.net/projects/ypa-to ... n%20Tools/ die ZIP herunterladen, das beiligende Lazarusprojekt öffnen und kompilieren.
Der StringConstBuilder baut die dann deine Kostanten.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

wp_xyz
Beiträge: 4895
Registriert: Fr 8. Apr 2011, 09:01

Re: Wie kann man mehrzeilige Texte im Programm ablegen?!

Beitrag von wp_xyz »

Dafür könntest du den TJvStrHolder aus JVCL verwenden. Den kannst du aufs Datenmodul klicken und ihm dann per Doppelklick wie in einem Memo Strings zuordnen. (https://wiki.freepascal.org/JVCL_Components#JvCmp)

Ich hab's gerade ausprobiert, scheint zu funktionieren, allerdings habe ich Probleme, dass zur Laufzeit Änderungen im bereits befüllten StrHolder nicht in die lfm-Datei übernommen werden - da müsste "man" mal genauer hinschauen...

Zum Installieren: JVCL gibt es im OPM, aber es reicht, wenn du in der Liste nur das Package JvCmpD markierst

In der RX-Library gibt es ebenfalls einen StringHolder, im Package rx_laz; den habe ich aber noch nicht ausprobiert.
Zuletzt geändert von wp_xyz am Di 15. Aug 2023, 18:50, insgesamt 1-mal geändert.

Benutzeravatar
theo
Beiträge: 10500
Registriert: Mo 11. Sep 2006, 19:01

Re: Wie kann man mehrzeilige Texte im Programm ablegen?!

Beitrag von theo »

War da nicht mal was mit Ressourcen?
Habe ich allerdings auch länger nicht gemacht.
Müsste aber mit Texten auch gehen, oder?

https://wiki.lazarus.freepascal.org/lazres
https://wiki.lazarus.freepascal.org/Lazarus_Resources

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Wie kann man mehrzeilige Texte im Programm ablegen?!

Beitrag von Socke »

theo hat geschrieben:
Do 20. Apr 2023, 12:02
War da nicht mal was mit Ressourcen?
Habe ich allerdings auch länger nicht gemacht.
Müsste aber mit Texten auch gehen, oder?
Wenn die Texte zur Anzeige im Programm gedacht sind (und keine Daten), dann wären Resource Strings die bessere Wahl. Diese kann man im Programm auch in verschieden Sprachen übersetzen. Die Syntax ist aber ähnlich zu CONST.

Mit den von dir verlinkten Free Pascal Resources kann man prinzipiell auch lange und kurze Texte einbinden. Die Zusammenstellung und der Zugriff aus dem Programm heraus ist aber deutlich aufwändiger. Eine Übersetzung funktioniert hier über Ressourcen in Bibliotheken, sodass ma je nach Sprache eine andere Bibliothek lädt (ist in Windows weit verbreitet, ob es unter Linux funktioniert, weiß ich nicht).
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Mathias
Beiträge: 6210
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Wie kann man mehrzeilige Texte im Programm ablegen?!

Beitrag von Mathias »

wie kann ich Texte in meinem eigenen Lazarus Programm ablegen??
Will sagen, diese Texte sollen mit dem Programm kompiliert werden.
Was ich in Lazarus vermisse, ist eine Funktion in dieser Art:

Code: Alles auswählen

var
  s:string;
begin
  s:={$includestring text.txt}; 
Nach meiner Meinung, wäre dies ein grosser Mehrwert für Lazarus.
Man könnte so auch als OpenGL-Coder sehr einfach Shader-Dateien direkt ins Programm kompilieren.
War da nicht mal was mit Ressourcen?
Das mit den Resourcen ist doch auch so ein Geflicke. Ich hatte dies mal in einer Package probiert, das hatte ich nicht mal hingekriegt.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6217
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Wie kann man mehrzeilige Texte im Programm ablegen?!

Beitrag von af0815 »

Mathias hat geschrieben:
Do 20. Apr 2023, 17:13
Nach meiner Meinung, wäre dies ein grosser Mehrwert für Lazarus.
Und es wird noch unübersichtlicher.

Die Lösung von m.fuchs kannst du ja in eine include Datei setzen, dann hast du in etwas das was du machen willst.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
theo
Beiträge: 10500
Registriert: Mo 11. Sep 2006, 19:01

Re: Wie kann man mehrzeilige Texte im Programm ablegen?!

Beitrag von theo »

Die Resourcen waren mir auch immer etwas zu mühsam.
Deshalb hatte ich mir vor etwa 150 Jahren eine Unit gebastelt, die immer noch funktioniert.
http://www.theo.ch/lazarus/EncodeforUnit.pas

Das geht so: Man macht sich ein kleines Programm mit EncodeforUnit in der uses und so einem Code.

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
begin
  if OpenDialog1.Execute then
    Memo1.text:=EncodeFileForUnit(OpenDialog1.Filename);
end;    
Dort kann man alle Dateisorten hineinwursten, auch Bilder etc.
Was im Memo1 heraus kommt, ist eine Konstante, die man sich in die Unit pasten kann.

Die Konstante kann man dann z.B. so entpacken:

Code: Alles auswählen

 ShowMessage(DecodeBase64(TestC));  
Wenn es Binärdaten sind, kann man sie mit DecodeFileFromUnit in einen Memorystream laden.

Ist mir nur gerade wieder eingefallen... :)

PascalDragon
Beiträge: 834
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: Wie kann man mehrzeilige Texte im Programm ablegen?!

Beitrag von PascalDragon »

Mathias hat geschrieben:
Do 20. Apr 2023, 17:13
wie kann ich Texte in meinem eigenen Lazarus Programm ablegen??
Will sagen, diese Texte sollen mit dem Programm kompiliert werden.
Was ich in Lazarus vermisse, ist eine Funktion in dieser Art:

Code: Alles auswählen

var
  s:string;
begin
  s:={$includestring text.txt}; 
Nach meiner Meinung, wäre dies ein grosser Mehrwert für Lazarus.
1. ist das nicht Teil von Lazarus, sondern von FPC
2. gibt es dafür bereits einen Patch, der Hauptteil, der noch fehlt ist die korrekte Behandlung der Textkodierung
Mathias hat geschrieben:
Do 20. Apr 2023, 17:13
War da nicht mal was mit Ressourcen?
Das mit den Resourcen ist doch auch so ein Geflicke. Ich hatte dies mal in einer Package probiert, das hatte ich nicht mal hingekriegt.
Dann hast du sie einfach nur noch nicht entsprechend genutzt.
FPC Compiler Entwickler

wp_xyz
Beiträge: 4895
Registriert: Fr 8. Apr 2011, 09:01

Re: Wie kann man mehrzeilige Texte im Programm ablegen?!

Beitrag von wp_xyz »

Mathias hat geschrieben:
Do 20. Apr 2023, 17:13
War da nicht mal was mit Ressourcen?
Das mit den Resourcen ist doch auch so ein Geflicke. Ich hatte dies mal in einer Package probiert, das hatte ich nicht mal hingekriegt.
Also soooo schlimm ist es auch wieder nicht:
- Text in einer Datei speichern
- Projekt-Einstellungen > Ressourcen > Hinzufügen, die Text-Datei auswählen. Die Datei wird als Eintrag in einer Liste angezeigt, in der Spalte Typ steht wahrscheinlich RCDATA und in der Spalte Ressource der Dateiname. Diese Information brauchen wir im nächsten Schritt.
- Im OnCreate Handler des Formulars (oder halt wenn der Text benötigt wird), die Datei aus der Ressource in einen TResourceStream einlesen und von dort z.B. in einem Memo anzeigen, oder was auch immer mit dem Text getan werden soll:

Code: Alles auswählen

uses
  LCLType;  // wegen RT_RCDATA

procedure TForm1.FormCreate(Sender: TObject);
var
  s: TResourceStream;
  resName: String;
begin
  resName := '<name der Ressource so wie angezeigt>';
  s := TResourceStream.Create(HINSTANCE, resName, RT_RCDATA);    // oder statt RT_RCDATA: RT_<typ der ressource>
  try
    Memo1.Lines.LoadFromStream(s);
  finally
    s.Free;
  end;
end; 
Zuletzt geändert von wp_xyz am Fr 21. Apr 2023, 11:29, insgesamt 1-mal geändert.

Lorca
Beiträge: 196
Registriert: Di 3. Nov 2020, 12:25

Re: Wie kann man mehrzeilige Texte im Programm ablegen?!

Beitrag von Lorca »

Hallo zusammen, :)

ganz herzlichen Dank für eure Mühen und Kommentare.
Der Vorschlag von wp_xyz ist genau das, was ich gesucht habe.
Euch allen nochmals herzlichen Dank. :)

Ein echt cooles Tool, *freu*

Gruß
Lorca

wp_xyz
Beiträge: 4895
Registriert: Fr 8. Apr 2011, 09:01

Re: Wie kann man mehrzeilige Texte im Programm ablegen?!

Beitrag von wp_xyz »

Lorca hat geschrieben:
Fr 21. Apr 2023, 10:46
Ein echt cooles Tool, *freu*
Du meinst den StringHolder? Hast du schon mal versucht, bereits eingegebene Strings zu ändern? Hier tut sich bei mir gar nichts

Benutzeravatar
theo
Beiträge: 10500
Registriert: Mo 11. Sep 2006, 19:01

Re: Wie kann man mehrzeilige Texte im Programm ablegen?!

Beitrag von theo »

wp_xyz hat geschrieben:
Do 20. Apr 2023, 22:48
- Projekt-Einstellungen > Ressourcen > Hinzufügen, die Text-Datei auswählen. Die Datei wird als Eintrag in einer Liste angezeigt, in der Spalte Typ steht wahrscheinlich RCDATA und in der Spalte Ressource der Dateiname. Diese Information brauchen wir im nächsten Schritt.
Ja, so geht's natürlich leicht.
Das hatte gar nicht auf dem Schirm, dass das in den Projekt-Einstellungen geht.
Danke!

Benutzeravatar
Lincoln Six Echo
Beiträge: 138
Registriert: Di 26. Aug 2014, 16:42
OS, Lazarus, FPC: Win10, Debian
CPU-Target: I7/I9/Q9650/u.a.
Wohnort: Hamburg

Re: Wie kann man mehrzeilige Texte im Programm ablegen?!

Beitrag von Lincoln Six Echo »

Wenn es nicht als Resource sein soll dann einfach eine eigene Component-Class mit der property TStrings schreiben. Die property muß published sein, dann kannst du im Objectinspector mehrzeilige Texte eingeben die dann auch mit dem Programm compiliert werden.

Benutzeravatar
KodeZwerg
Beiträge: 103
Registriert: Mo 6. Feb 2023, 11:04

Re: Wie kann man mehrzeilige Texte im Programm ablegen?!

Beitrag von KodeZwerg »

Da ich eh nur unter Windows dinge herbeizauber, geh ich auch über den komfortablen Resourcen weg.
Nichts desto trotz war ich schon ein paar mal gezwungen es als include datei zu haben.
Hier ist meine sehr simple variante plus eine methode um das ganze auch wieder lesbar zu bekommen über eine Stringliste.

Code: Alles auswählen

function CreateStringListFromConst(const ABytes: array of byte): TStrings;
  function ConstToBytes(const ABytes: array of byte): TBytes;
  var
    i: Integer;
  begin
    SetLength(Result, High(ABytes));
    for i := 0 to High(ABytes) do
      Result[i] := ABytes[i];
  end;
var
  bytes: TBytes;
  stream: TStream;
begin
  if High(ABytes) <= 0 then
    Exit;
  Result := TStringList.Create;
  bytes := ConstToBytes(ABytes);
  stream := TBytesStream.Create(bytes);
  try
    Result.LoadFromStream(stream);
  finally
    stream.Free;
  end;
end;

function Bin2Inc(const AInputFile: String; const AOutputFile: string = ''): Boolean;
  function FileToBytes(const AFilename: string): TBytes;
  var
    FileStream: TFileStream;
  begin
    FileStream := TFileStream.Create(AFileName, fmOpenRead or fmShareDenyWrite);
    try
      SetLength(Result, FileStream.Size);
      FileStream.ReadBuffer(Result[0], FileStream.Size);
    finally
      FileStream.Free;
    end;
  end;
var
  bytes: TBytes;
  sl: TStrings;
  s: AnsiString;
  i: Integer;
  cnt: Integer;
begin
  Result := False;
  if (not FileExists(AInputFile)) then
    Exit;
  bytes := FileToBytes(AInputFile);
  if High(bytes) = 0 then
    Exit;
  sl := TStringList.Create;
  try
    cnt := 0;
    s := '';
    sl.Add('const ' + Copy(ExtractFilename(AInputFile), 1, Length(ExtractFilename(AInputFile)) - Length(ExtractFileExt(AInputFile))) + ': array[0..' + IntToStr(High(bytes)) + '] of byte = (');
    for i := 0 to High(bytes) do
      begin
        if cnt < 85 then
          begin
            if i = High(bytes) then
              s := s + ' $' + IntToHex(bytes[i], 2) + ');'
            else
              s := s + ' $' + IntToHex(bytes[i], 2) + ',';
            Inc(cnt, 1);
          end;
        if cnt = 85 then
          begin
            sl.Add(s);
            cnt := 0;
            s := '';
          end;
      end;
    if (s <> '') then
      sl.Add(s);
    if (AOutputFile = '') then
      sl.SaveToFile(ChangeFileExt(AInputFile, '.inc'))
    else
      sl.SaveToFile(AOutputFile);
  finally
    sl.Free;
  end;
end;
Nicht vergessen die erzeugte Liste auch wieder freizugeben.

Ich hoffe es hilft.
Zuletzt geändert von KodeZwerg am Sa 39. Okt 6043, 29:87, insgesamt 43-mal geändert.

Antworten