[Delphi]Procedure werkt alleen icm andere lege procedure

Pagina: 1
Acties:

  • Oscar Mopperkont
  • Registratie: Februari 2001
  • Laatst online: 03-08-2024
Met veel pijn en moeite is het me eindelijk gelukt om de inhoud van twee richedits aan elkaa te kunnen plakken mbv Memorystreams zodat ik invloed kan uitoefenen hoe er geplakt wordt (enters weghalen en toevoegen etc).

Ik heb dat eerst geoefend met TFileStreams, zodat ik kon zien wat er gebeurde. Het vreemde is nu dat de procedure met de Memorystreams alleen werkt als ik een andere lege procedure aanroep. Als ik dit neerzet:
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
37
38
39
40
41
42
43
44
45
46
47
48
procedure TfrFormulier.UpdateVoorbeeldClick(Sender: TObject);
var
  i:  integer;
  oMemoryStream1, oMemoryStream2: TMemoryStream;
  oFileStream : TFileStream;
  cAddLine: PCHAR;
  nBuffer, nLength: Integer;
begin
  rchVoorbeeld.Lines.Clear;

  oMemoryStream1 := TMemoryStream.Create;
  oMemoryStream2 := TMemoryStream.Create;
  TRichEdit(clRichEdits[0]).Lines.SaveToStream(oMemoryStream1);
  oMemoryStream1.Position:=oMemoryStream1.Position-9;

  TRichEdit(clRichEdits[0]).Lines.SaveToStream(oMemoryStream2);
  oMemoryStream2.Position := 1;
  Repeat
    oMemoryStream2.ReadBuffer(nBuffer,1);
  Until nBuffer = 123;
  oMemoryStream2.Position := oMemoryStream2.Position - 1;
  nLength := oMemoryStream2.Size-oMemoryStream2.Position-9;
  oMemoryStream1.CopyFrom(oMemoryStream2, nLength);
  oMemoryStream2.Free;
  nBuffer:=125;
  oMemoryStream1.Write(nBuffer,1);
  oMemoryStream1.Position := 0;
  rchVoorbeeld.Lines.LoadFromStream(oMemoryStream1);
  oMemoryStream1.Free;


  oFileStream := TFileStream.Create('c:\test.rtf',fmCreate);
  AddRtf(oFileStream, False);


end;

Procedure TFrformulier.AddRtf(var oFileStream: TFileStream; AddLine: Boolean);
var
   oMemoryStream1, oMemoryStream2: TMemoryStream;
   cAddLine: PCHAR;
   nBuffer, nLength: Integer;
begin

{

}
end;

Dan werkt het dus. Haall ik echter weg dat dat die oFilestream niet meer wordt gemaakt en AddRTF (waarin dus niks meer staat) dan werkt de procedure ineens niet meer. Hij loopt dan ineens vast op dit stukje:
Delphi:
1
2
3
Repeat
oMemoryStream2.ReadBuffer(nBuffer,1);
Until nBuffer = 123;

Met de volgende melding:
---------------------------
Debugger Exception Notification
---------------------------
Project ProjectGrader.exe raised exception class EReadError with message 'Stream read error'. Process stopped. Use Step or Run to continue.
---------------------------
OK Help
---------------------------
Ik snap er geen fluit van, want die commando's die ik weghaal komen sowieso pas na dat stukje waar hij op vastloopt. Wat kan er aan de hand zijn, want ik volg het even niet meer :?

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

Creepy

Tactical Espionage Splatterer

Die Readbuffer wil als eerst parameter een pointer hebben naar een variabele die in elk geval zo groot is als de readsize die je opgeeft (1) en geen integer

Je zult hier echt een pointer van moeten maken (of maak er @nbuffer van, zodat je die integer als een pointer gebruikt).

"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
Waarom werkt hij op deze manier dan ook eigenlijk?

Hoe ziet een pointer eruit dan? Dus wat voor verwijzing zou je dan krijgen? Want ik dacht dat ik hem nu gewoon telkens 1 teken liet lezen totdat hij een "{" (123) tegenkwam. En kennelijk werkt het ook, maar dat is dus toeval?

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

Creepy

Tactical Espionage Splatterer

Dat het werkt lijkt me toeval ja. Je zet er toch echt een integer in, en geen pointer.
De delphi help kan je vast wel vertellen wat @ doet. Daarnaast zou je eens moeten kijken naar ^ en pointer. in de help. Kijk dan ook meteen even naar getmem.

Maar stap eens rustig door je code heen en bekijk eens per stap de inhoudt van nBuffer. Dan zie je vanzelf of het klopt wat ik zeg

[ Voor 6% gewijzigd door Creepy op 19-01-2005 16:46 ]

"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
Als ik kijk naar de inhoud van de nBuffer dan geeft hij gewoon een integer weer.


Verder ben ik nu verder gegaan met de code en heb nu dit:
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
37
38
39
40
41
42
procedure TfrFormulier.UpdateVoorbeeldClick(Sender: TObject);
var
  i:  integer;
  oMemoryStream1, oMemoryStream2: TMemoryStream;
  oFileStream : TFileStream;
  nBuffer, nLength: Integer;
begin
  //Eerst leegmaken
  rchVoorbeeld.Lines.Clear;

  //De stream aanmaken waar alles inkomt
  oMemoryStream1 := TMemoryStream.Create;

  //De aanhef erin zetten
  rchAanhef.Lines.SaveToStream(oMemoryStream1);
  oMemoryStream1.Position:=oMemoryStream1.Position-9;


  //De opmerkingen over de groep erin
  for i:=0 to clRichEdits.Count-1 do
  begin
    oMemoryStream2 := TMemoryStream.Create;
    TRichEdit(clRichEdits[i]).Lines.SaveToStream(oMemoryStream2);

    oMemoryStream2.Position := 1;
    Repeat
      oMemoryStream2.ReadBuffer(nBuffer,1);
    Until nBuffer = 123;
    oMemoryStream2.Position := oMemoryStream2.Position - 1;
    nLength := oMemoryStream2.Size-oMemoryStream2.Position-9;
    oMemoryStream1.CopyFrom(oMemoryStream2, nLength);
    oMemoryStream2.Free;
  end;

  nBuffer:=125;
  oMemoryStream1.Write(nBuffer,1);
  oMemoryStream1.Position := 0;
  rchVoorbeeld.Lines.LoadFromStream(oMemoryStream1);
  oMemoryStream1.Free;


end;

En nu maakt het niet meer uit als ik dat stuk weghaal. :?

Kennelijk is het "toeval" dat het nu nog werkt, maar hij lijkt wel te doen wat ie moet doen (voorlopig). Ik snap alleen nog niks van je pointer en @ verhaal. Maar ik ga eens de help doorlezen (waar ik voorlopig nog niet veel zie staan dat het me duidelijk maakt)

Verwijderd

Ten eerste: je mag blij zijn dat je maar een buffer van 1 karakter gebruikt, en dat de adressen 123 en 125 in jouw testcase soms vrij waren, maar dat heeft Creepy al aardig uitgelegd.

Maar bij het verwerken van variabele data als RTF is 't niet handig om ReadBuffer te gebruiken. Uit de online help:
Use ReadBuffer to read Count bytes from the stream into a buffer in cases where the number of bytes is known and fixed, for example when reading in structures.
In jouw geval, met een 1-char buffer, gaat dat wel goed (als die nBuffer naar een geldige buffer verwijst), maar 't vertraagt de boel enorm.

Vandaar dat iedere TStream afgeleide een Read method kent:
Read is used in cases where the number of bytes to read from the stream is not necessarily fixed. It attempts to read up to Count bytes into buffer and returns the number of bytes actually read.
Maar afgezien daarvan, houd er wanneer je meerdere lettertypes gebruikt in je RTF controls rekening mee dat die lettertypes geindexeerd worden (f1 kan in control1 Arial zijn, en in control2 Times Roman, etc.). Wanneer je de verschillende RTF-jes zomaar aan elkaar plakt gaat dat gegarandeerd fout. Volgens mij staat de RTF-standaard het zelfs niet toe dat binnen 1 document van fonttable wordt gewisseld (weet ik niet zeker, moet ik nakijken).

  • RefleXion
  • Registratie: Februari 2004
  • Laatst online: 23:12
Waarom doe je niet gewoon:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
procedure TForm1.Button1Click(Sender: TObject);

Var
  T : Integer;
  Temp : String;

begin
  For T := 0 to RichEdit1.Lines.Count-1 do
  Begin
    Temp := RichEdit1.Lines[T];
    //Doe met deze lijn wat je wilt
    RichEdit3.Lines.Add(Temp);
  End;
  For T := 0 to RichEdit2.Lines.Count-1 do
  Begin
    Temp := RichEdit2.Lines[T];
    //Doe met deze lijn wat je wilt
    RichEdit3.Lines.Add(Temp);
  End;
end;


Dan kun je ook zo lege lijnen toevoegen (lege string adden).

58x PV Enphase IQ8+, 16x PV SolarEdge, 2x PV los, 9x Marstek Venus E V3, Peugeot e-208


  • Oscar Mopperkont
  • Registratie: Februari 2001
  • Laatst online: 03-08-2024
Verwijderd schreef op woensdag 19 januari 2005 @ 23:59:
Ten eerste: je mag blij zijn dat je maar een buffer van 1 karakter gebruikt, en dat de adressen 123 en 125 in jouw testcase soms vrij waren, maar dat heeft Creepy al aardig uitgelegd.
123 en 125 zijn geen adressen, maar tekens en wel { en }. Hij leest volgens mij gewoon elke keer een teken uit de memorystream en kijkt vervolgens of of het teken dat hij leest een { is (vandaar de 123). Uiteindelijk moet een stream van de TRichEdit eindigen met een }, dus die plak er op het laatste moment weer aan. Die 123 en 125 hebben volgens mij dus niks met adressen te maken.

  • Oscar Mopperkont
  • Registratie: Februari 2001
  • Laatst online: 03-08-2024
RefleXion schreef op donderdag 20 januari 2005 @ 00:08:
Waarom doe je niet gewoon:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
procedure TForm1.Button1Click(Sender: TObject);

Var
  T : Integer;
  Temp : String;

begin
  For T := 0 to RichEdit1.Lines.Count-1 do
  Begin
    Temp := RichEdit1.Lines[T];
    //Doe met deze lijn wat je wilt
    RichEdit3.Lines.Add(Temp);
  End;
  For T := 0 to RichEdit2.Lines.Count-1 do
  Begin
    Temp := RichEdit2.Lines[T];
    //Doe met deze lijn wat je wilt
    RichEdit3.Lines.Add(Temp);
  End;
end;


Dan kun je ook zo lege lijnen toevoegen (lege string adden).
Mijn grootste probleem is eigenlijk dat als je twee RichEdits aan elkaar plakt, dat hij op de standaard manier (dus met add....) er een enter tussen staat. Ik wil dat er alleen een spatie tussen staat. En met deze plakmethode heb je dat probleem niet.

Even voorbeeldje:
Ik heb 2 RichEdits

RIchEdit1:
Hier staat een zin

RichEdit2:
Hier staat nog een zin

Als ik die met addstrings aan elkaar plak dan krijg ik:
RichEdit3:
Hier staat een zin
Hier staat nog een zin

Terwijl ik wil:
Hier staat een zin. Hier staat nog een zin.

Verder vond ik het wel handig dat ik makkelijk enters zou kunnen toevoegen, maar dat kan neem ik aan ook op jouw manier.

@Afterlife:
Ik heb net geprobeerd om verschillende RichEdits met verschillende opmaak, ander lettertype, andere grootte en bold, niet bold, italic niet italic, aan elkaar te plakken en in een nieuwe RichEdit te zetten. Dat ging gewoon goed, dus ik snap je opmerking niet helemaal dat dat gegarandeerd fout zou moeten gaan.
Ik heb mijn procedure overigens gebaseerd op die van Hezik (toen nog de Generaal) uit dit topic:
[rml][ Delphi] Meerdere RichEdits in 1 RTF file opslaan[/rml]

Creepy zei toen al dat het beter zou zijn om alles in een Rich Edit samen te voegen die ik alleen in het geheugen heb. Dan zou ik alles aan die Rich Edits zelf kunnen overlaten. Maar dan zit ik dus met dat "enter" verhaal. Of iemand moet mij daar de oplossing voor geven, zonder dat ik moet "parsen".

[ Voor 23% gewijzigd door Oscar Mopperkont op 20-01-2005 10:24 ]


  • RefleXion
  • Registratie: Februari 2004
  • Laatst online: 23:12
Het kan wel op een soortgelijke manier met de richedit.text waarde.

newRichEdit.text := richEdit1.Text + richEdit2.Text;

58x PV Enphase IQ8+, 16x PV SolarEdge, 2x PV los, 9x Marstek Venus E V3, Peugeot e-208

Pagina: 1