[Delphi] Meerdere RichEdits in 1 RTF file opslaan

Pagina: 1
Acties:
  • 122 views sinds 30-01-2008
  • Reageer

  • Oscar Mopperkont
  • Registratie: Februari 2001
  • Laatst online: 03-08-2024
Ik heb een formulier met daarop verschillende Richedits, nu wil ik echter de inhoud van die RichEdits opslaan in 1 file. Dus dat die tekst wordt samengevoegd tot 1 geheel.

Hoe ik de inhoud van 1 richedit opsla weet ik wel:
Delphi:
1
RichEdit1.Lines.SaveToFile (FileName);

Maar hoe voeg ik nu toe?

En alvast als vervolgvraag. Als ik toevoeg zal de tekst wel direct aan elkaar geplakt worden, hoe krijg ik er dan een enter tussen?

Ik kan er niks over vinden, want vrijwel altijd gaat het om een enkele richedit die wordt opgeslagen en dan heb je mijn "probleem" dus niet :)

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 18:05

Creepy

Tactical Espionage Splatterer

Je kan beter eerst alle richedits aan elkaar plakken en dan in 1 keer opslaan als een file.

Delphi:
1
2
Richedit1.lines.add(''); // een lege regel
Richedit1.lines.addlines(Richedit2.lines)

Ongeveer op deze manier. De method addlines klopt denk ik qua naamgeving niet maar ik heb hier ff geen delphi bij de hand ;)

Daarnaast zou je ook alle richedits in een TStringList kunnen stoppen op dezelde manier als hierboven en daarna opslaan. (.lines is een TStringList).

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • Cypher87
  • Registratie: Oktober 2004
  • Laatst online: 23-01 17:24
De goede manier is:

Delphi:
1
RichEdit1.Lines.AddStrings(Richedit2.Lines);

Verwijderd

Vind het een beetje een smerige oplossing, aangezien je op die manier je richedits wel verpest, als je ze bv. nog goed wil laten weergeven hierna, moet je daarna alles weer ongedaan maken.

Waarom niet de inhoud van de richedits kopieren naar een stringlist, en die opslaan?

code:
1
2
3
4
5
6
7
8
9
10
11
12
var
  oContent: TStringlist;
begin
  oContent := TStringlist.Create;
  Try
    oContent.AddStrings(RichEdit1.Lines);
    oContent.AddStrings(RichEdit2.Lines);
    oContent.SaveToFile(cFileName);
  Finally
    oContent.Free;
  end;
end;

  • Oscar Mopperkont
  • Registratie: Februari 2001
  • Laatst online: 03-08-2024
@De Generaal, je hebt helemaal gelijk, ik wil namelijk niet dat ik de richedits daarna weer moet herstellen, of ik zou gebruik moeten maken van een "derde" richedit, die ik voor plakken gebruik.

Blijft de opmaak trouwens staan in een TStringList? Ik ga het zo proberen overigens.

Overigens bedankt voor de snelle reacties :)

[ Voor 10% gewijzigd door Oscar Mopperkont op 11-12-2004 13:51 ]


Verwijderd

Voor zover ik weet is de lines property van die richedit ook een tstrings.

Anders kun je dit doen (is eigenlijk nog mooier)

code:
1
2
3
4
5
6
7
  oStream := TFileStream.Create('c:\test.txt',fmCreate);
  try
    RichEdit1.Lines.SaveToStream(oStream);
    RichEdit2.Lines.SaveToStream(oStream);
  finally
    oStream.Free;
  end;

  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 15-05 12:58

Tomatoman

Fulltime prutser

Volgens mij is het probleem bij alle gegeven oplossingen dat de opmaak verloren gaat bij het kopiëren. Je zult daarom de rauwe data - inclusief opmaak - moeten aanspreken. Dat kun je doen met de EM_GETTEXTEX message.

Een goede grap mag vrienden kosten.


Verwijderd

tomatoman schreef op zaterdag 11 december 2004 @ 13:55:
Volgens mij is het probleem bij alle gegeven oplossingen dat de opmaak verloren gaat bij het kopiëren. Je zult daarom de rauwe data - inclusief opmaak - moeten aanspreken. Dat kun je doen met de EM_GETTEXTEX message.
Bij de stream methode niet hoor.. ik heb het even getest, in die test.txt staat het volgende:

code:
1
2
3
4
5
6
7
8
{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil MS Sans Serif;}}
\viewkind4\uc1\pard\f0\fs16 RichEdit1
\par 
\par }
 {\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil MS Sans Serif;}}
\viewkind4\uc1\pard\f0\fs16 RichEdit1
\par 
\par }


De tedit.lines.savetofile roept overigens gewoon de savetofile aan van de lines property, oftewel van een tstrings. Ik zie dan ook niet in hoe de opmaak daarbij bewaard kan blijven, en bij een gewone tstrings.savetofile niet?

//edit
even met de vorige code getest, en daarbij gaat inderdaad de opmaak verloren. Dan is die tfilestream de enige juiste optie imo. Daarbij gaat de opmaak niet verloren, het is goed leesbaar en je hoeft geen truuks uit te halen.

[ Voor 10% gewijzigd door Verwijderd op 11-12-2004 14:00 ]


  • charlie
  • Registratie: Oktober 2000
  • Laatst online: 07-03 11:08

charlie

?*?

Overbodige post

[ Voor 97% gewijzigd door charlie op 11-12-2004 14:02 . Reden: overbodig ]


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 15-05 12:58

Tomatoman

Fulltime prutser

Verwijderd schreef op zaterdag 11 december 2004 @ 13:58:
[...]
Bij de stream methode niet hoor..
Hé, dat is mooi. Er is echter wel een andere valkuil, namelijk dat de eerste regel van het RTF-bestand bij het aan elkaar plakken van de verschillende teksten ook middenin in het uiteindelijke bestand terecht komt; zie regel 1 en 5. Waarschijnlijk is het gewoon een opmaakregel, maar het zou ook een header kunnen zijn. Je zou eigenlijk in de RTF-specificatie moeten opzoeken hoe dat zit (ik denk dat het geen probleem is).

[ Voor 2% gewijzigd door Tomatoman op 11-12-2004 15:26 . Reden: typo's ]

Een goede grap mag vrienden kosten.


Verwijderd

tomatoman schreef op zaterdag 11 december 2004 @ 15:06:
[...]
Hé, dat is mooi. Er is echter wel een andere valkuil, namelijk dat de eerste regel van het RTF-bestand bij het aan elkaar plakken van de verschillende teksten ook middenin in het uiteindelijke bestand terecht komt; zie regel 1 en 5. Waarschijnlijk is het gewoon een opmaakregel, maar het zou ook een header kunnen zijn. Je zou eigenlijk in de RTF-specificatie moeten opzoeken hoe dat zit (ik denk dat het geen probleem is).
Mocht dat het probleem zijn (niet getest) kun je ook deze uit de tstream filteren..

  • Oscar Mopperkont
  • Registratie: Februari 2001
  • Laatst online: 03-08-2024
@De Generaal

Als ik je code uit deze post gebruik [rml]De Generaal in "[ Delphi] Meerdere RichEdits in 1 RTF fil..."[/rml]

dan komt alleen de tekst uit de tweede richedit in het bestand te staan. Hij overschrijft hem dus volgens mij.

Als je de file opslaat als rtf file en hem dus opent dan zie je alleen staan wat er in de tweede richedit stond. Je moet dus inderdaad de "header" eruit halen? Zoja hoe doe je dat?

[ Voor 28% gewijzigd door Oscar Mopperkont op 11-12-2004 15:58 ]


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 18:05

Creepy

Tactical Espionage Splatterer

Oscar: kijk eens naar tomatoman's opmerking over een valkuil. De stream wordt in elk geval niet overschreven :)

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • Oscar Mopperkont
  • Registratie: Februari 2001
  • Laatst online: 03-08-2024
Creepy schreef op zaterdag 11 december 2004 @ 15:56:
Oscar: kijk eens naar tomatoman's opmerking over een valkuil. De stream wordt in elk geval niet overschreven :)
Ik had het inmiddels gezien en ook naat een tekstfile gesaved om het te zien :)

Maar je kunt het dus in 1 stream krijgen, maar dan ben je er dus nog niet...

[ Voor 13% gewijzigd door Oscar Mopperkont op 11-12-2004 16:00 ]


Verwijderd

Oscar Mopperkont schreef op zaterdag 11 december 2004 @ 15:59:
Ik had het inmiddels gezien en ook naat een tekstfile gesaved om het te zien :)

Maar je kunt het dus in 1 stream krijgen, maar dan ben je er dus nog niet...
Momentje zal het even voor je in elkaar flansen schrijven :P

Verwijderd

Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
var
  oFileStream: TFileStream;
  oMemoryStream: TMemoryStream;
  nLength,nBuffer: Integer;
begin
  oFileStream := TFileStream.Create('c:\test3.txt',fmCreate);
  oMemoryStream := TMemoryStream.Create;
  try
    RichEdit1.Lines.SaveToStream(oFileStream);
    // sluittag 1e rtf verwijderen
    oFileStream.Position:=oFileStream.Position-9;
    RichEdit2.Lines.SaveToStream(oMemoryStream);
    // 2e { opzoeken in stream (=einde header)
    oMemoryStream.Position:=1;
    Repeat
      oMemoryStream.ReadBuffer(nBuffer,1);
    Until chr(nBuffer)='{';
    oMemoryStream.Position:=oMemoryStream.Position-1;
    nLength:=oMemoryStream.Size-oMemoryStream.Position-9;
    // gedeelte na header kopieren
    oFileStream.CopyFrom(oMemoryStream,nLength);
    nBuffer:=Ord('}');
    oFileStream.Write(nBuffer,1);
  finally
    oFileStream.Free;
    oMemoryStream.Free;
  end;
end;


//edit
hij liet nog een witregel staan aan het eind, nu niet meer.

Uitleg.. oorspronkelijk kregen we deze output:
code:
1
2
3
4
5
6
7
8
{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil MS Sans Serif;}}
\viewkind4\uc1\pard\f0\fs16 RichEdit1
\par 
\par }
 {\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil MS Sans Serif;}}
\viewkind4\uc1\pard\f0\fs16 RichEdit1
\par 
\par }


Terwijl we dit willen hebben:
code:
1
2
3
4
5
6
{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil MS Sans Serif;}}
\viewkind4\uc1\pard\f0\fs16 RichEdit1
\par 
{\fonttbl{\f0\fnil MS Sans Serif;}}
\viewkind4\uc1\pard\f0\fs16 RichEdit1
\par }


Verschil:

• aan het einde van de 1e rtf stond nog een \par }, die hebben we weggehaald (laatste 9 bytes stream, vandaar die position=position-9)
• aan het begin van de 2e rtf stond nog een header ('\rtf1 etc), die hebben we weggehaald (stuk waar de 2e { wordt opgezocht)
• aan het einde van het bestand kwam 2x \par te staan, met als gevolg een lege regel, die halen we dus weg (vandaar dat de lengte -9 wordt gedaan).

[ Voor 57% gewijzigd door Verwijderd op 11-12-2004 20:11 ]


  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 15-05 14:44

_Thanatos_

Ja, en kaal

Ik denk dat je een heel eind kan komen met het TOM (Text Object Model). Volgens mij kun je daarmee wel van de ene naar de andere richedit kopiëren, alsmede andere dingen die via de tradionele weg niet gaan.

Enige "nadeel" is dat Richedit 2.0 vereist is.

日本!🎌


Verwijderd

Nog wat verfraaid:

Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Procedure AddRtf(var oFileStream: TFileStream; oRichEdit: TRichEdit);
var
  oMemoryStream: TMemoryStream;
  nLength,nBuffer: Integer;
begin
  If oFileStream.Size=0 then
      begin
        oRichEdit.Lines.SaveToStream(oFileStream);
        oFileStream.Position := oFileStream.Position-9;
        nBuffer := Ord('}');
        oFileStream.Write(nBuffer,1);
      end
    else
      begin
        // laatste '}' eraf
        oFileStream.Position := oFileStream.Position-1;
        oMemoryStream := TMemoryStream.Create;
        try
          oRichEdit.Lines.SaveToStream(oMemoryStream);
          oMemoryStream.Position := 1;
          Repeat
            oMemoryStream.ReadBuffer(nBuffer,1);
          Until chr(nBuffer) = '{';
          oMemoryStream.Position := oMemoryStream.Position-1;
          nLength := oMemoryStream.Size-oMemoryStream.Position-9;
          // gedeelte na header kopieren
          oFileStream.CopyFrom(oMemoryStream,nLength);
          // laatste '}' er aan
          nBuffer := Ord('}');
          oFileStream.Write(nBuffer,1);
        finally
          oMemoryStream.Free
        end;
      end;
end;


Nu kun je gewoon doen:

Delphi:
1
2
3
4
5
6
7
  oFileStream := TFileStream.Create('c:\test.rtf',fmCreate);
  try
    AddRtf(oFileStream,RichEdit1);
    AddRtf(oFileStream,RichEdit2);
  finally
    oFileStream.Free;
  end;

[ Voor 20% gewijzigd door Verwijderd op 11-12-2004 21:22 ]


  • Oscar Mopperkont
  • Registratie: Februari 2001
  • Laatst online: 03-08-2024
@De Generaal:

_/-\o_ Thnx! Ik kan het nu niet proberen (zit niet thuis), maar ik geloof zo dat het werkt natuurlijk :)

Weet je trouwens ook hoe je er een enter in kan gooien? Zodat de tekst niet rechtstreeks aanelkaar zit, danwel dat er maar 1 enter tussen zit als ik er twee wil?

[ Voor 41% gewijzigd door Oscar Mopperkont op 11-12-2004 20:21 ]


Verwijderd

Oscar Mopperkont schreef op zaterdag 11 december 2004 @ 20:20:
@De Generaal:

_/-\o_ Thnx! Ik kan het nu niet proberen (zit niet thuis), maar ik geloof zo dat het werkt natuurlijk :)

Weet je trouwens ook hoe je er een enter in kan gooien? Zodat de tekst niet rechtstreeks aanelkaar zit, danwel dat er maar 1 enter tussen zit als ik er twee wil?
Door er een /par tussen te plakken.. zal dat zo nog even in de code verwerken, maar ben nu aan het koken ;)

[ Voor 8% gewijzigd door Verwijderd op 11-12-2004 20:26 ]


Verwijderd

Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
Procedure AddRtf(var oFileStream: TFileStream; oRichEdit: TRichEdit; AddLine: Boolean);
  var
    oMemoryStream: TMemoryStream;
    cAddLine: PCHAR;
    nBuffer: Integer;
  begin
    cAddLine := '\par '+chr(13);
    If oFileStream.Size = 0 then
        begin
          oRichEdit.Lines.SaveToStream(oFileStream);
          oFileStream.Position:=oFileStream.Position-9;
        end
      else
        begin
          // laatste '}' eraf
          oFileStream.Position := oFileStream.Position-1;
          oMemoryStream := TMemoryStream.Create;
          try
            oRichEdit.Lines.SaveToStream(oMemoryStream);
            oMemoryStream.Position := 1;
            Repeat
              oMemoryStream.ReadBuffer(nBuffer,1);
            Until nBuffer = 125;
            oMemoryStream.Position := oMemoryStream.Position-1;
            nLength := oMemoryStream.Size-oMemoryStream.Position-9;
            // gedeelte na header kopieren
            oFileStream.CopyFrom(oMemoryStream,nLength);
          finally
            oMemoryStream.Free
          end;
        end;
    If AddLine then oFileStream.Write(cAddLine^,SizeOf(cAddLine));
    // laatste '}' er aan
    nBuffer := 125;
    oFileStream.Write(nBuffer,1);
  end;


Aanroepen met:

Delphi:
1
2
3
4
5
6
7
 oFileStream := TFileStream.Create('c:\test.rtf',fmCreate);
  try
    AddRtf(oFileStream,RichEdit1, True);
    AddRtf(oFileStream,RichEdit2, False);
  finally
    oFileStream.Free;
  end;


De boolean addline kun je dan gebruiken om aan te geven of je er al dan niet een lege regel tussen wilt.

[ Voor 15% gewijzigd door Verwijderd op 11-12-2004 23:40 ]


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 18:05

Creepy

Tactical Espionage Splatterer

En kijk ff uit dat de color en fonts in de color- en fonttables genummerd zijn (f0, f1 etc). Ik heb geen idee wat een rtf parser doet als jij voor de tweede keer een font table tegenkomt, maar ik kan me voorstellen dat er rtf parsers zijn die hier de mist mee ingaan, zeker als de fonts in beide font tables niet overeenkomen. Hetzelfde geld voor de color tables.

Dus mocht je het zelf parsen van rtf verder willen vermijden: Maak een in memory TRichEdit aan en voeg hier alle anderen in samen. Zo laat je het genereren van de RTF over aan de TRichEdit en zit je ook niet meer met dubbele headers, font en color tables.

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Verwijderd

Creepy schreef op zondag 12 december 2004 @ 00:41:
En kijk ff uit dat de color en fonts in de color- en fonttables genummerd zijn (f0, f1 etc). Ik heb geen idee wat een rtf parser doet als jij voor de tweede keer een font table tegenkomt, maar ik kan me voorstellen dat er rtf parsers zijn die hier de mist mee ingaan, zeker als de fonts in beide font tables niet overeenkomen. Hetzelfde geld voor de color tables.

Dus mocht je het zelf parsen van rtf verder willen vermijden: Maak een in memory TRichEdit aan en voeg hier alle anderen in samen. Zo laat je het genereren van de RTF over aan de TRichEdit en zit je ook niet meer met dubbele headers, font en color tables.
Is misschien wel de fraaiste oplossing idd, bovenstaande werkt wel maar is - min of meer - een hack. Op zich kan het wel netjes, als je het wat verder uitwerkt, dus wat meer begrip voor het format zelf aanbrengt.

  • Dala
  • Registratie: November 2000
  • Laatst online: 21:59
maar hoe meer begrip voor het formaat je gaat implementeren.. hoe meer je in de buurt komt van een RTF parser...

dus kun je net zo goed de ingebouwde al gebruiken.

  • Oscar Mopperkont
  • Registratie: Februari 2001
  • Laatst online: 03-08-2024
Hezik, ik ben zo vrij geweest om je code proberen te gebruiken om twee of meerdere richedits samen te voegen in 1 RichEdit (dus zonder dat er iets naar schijf geschreven wordt). Ik weet dat er een simperlere methode is met dat addlines, maar ik wil zelf ook nog andere tekst toe gaan voegen ed en dan is dit denk ik het makkelijkste.

Ik heb er dit van gemaakt:
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
procedure TfrFormulier.UpdateVoorbeeldClick(Sender: TObject);
var
  i:  integer;
  oMemoryStream1, oMemoryStream2: TMemoryStream;
  cAddLine: PCHAR;
  nBuffer, nLength: Integer;
begin
  rchVoorbeeld.Lines.Clear;
  cAddLine := '\par '+chr(13);

  oMemoryStream1 := TMemoryStream.Create;

  TRichEdit(clRichEdits[0]).Lines.SaveToStream(oMemoryStream1);
  oMemoryStream1.Position := oMemoryStream1.Position -9;
  for i := 1 to clRichEdits.Count-1 do
  begin
    oMemoryStream1.Position := oMemoryStream1.Position -1;
    oMemoryStream2 := TMemoryStream.Create;
    TRichEdit(clRichEdits[i]).Lines.SaveToStream(oMemoryStream2);
    oMemoryStream2.Position := 0;
    Repeat
      oMemoryStream2.ReadBuffer(nBuffer,1);
    Until nBuffer = 125;
    oMemoryStream2.Position := oMemoryStream2.Position-1;
    nLength := oMemoryStream2.Size-oMemoryStream2.Position-9;
    // gedeelte na header kopieren
    oMemoryStream1.CopyFrom(oMemoryStream2,nLength);
    oMemoryStream2.Free;
  end;

  oMemoryStream1.Position:=0;
  rchVoorbeeld.Lines.LoadFromStream(oMemoryStream1);
end;

Maar het werkt dus niet.... Ik weet ook niet goed hoe je met deze dingen debugt, want hij laat geen waardes zien van memorystreams. Ik weet wel dat hij de eerste memorystream doet en dat hij bezig gaat met toevoegen, maar kennelijk wordt er niks toegevoegd, danwel op de verkeerder positie of iets dergelijks.

[ Voor 8% gewijzigd door Oscar Mopperkont op 16-01-2005 17:57 ]


  • Oscar Mopperkont
  • Registratie: Februari 2001
  • Laatst online: 03-08-2024
Subtiel schopje ;)
Pagina: 1