Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - StringReplace ersetzt nicht #10 in einem RichEdit


Hochhaus - Mi 06.06.12 14:11
Titel: StringReplace ersetzt nicht #10 in einem RichEdit
Hallo allerseits !

es hat mich viele Stunden gekostet zu sehen, dass der folgende Quellcodebefehl nicht funktioniert:

Delphi-Quelltext
1:
     RichEdit1.Text := StringReplace(Richedit1.Text,#10,'',[rfReplaceAll]);                    

Weiss jemand Rat ? Das RichEdit wird nicht geändert, die #10 - Zeichen bleiben erhalten. Das Problem tritt unter Delphi XE2 auf - ob vorher auch, weiss ich nicht.


Gruss,

Hochhaus

Moderiert von user profile iconNarses: Topic aus Sonstiges (Delphi) verschoben am Mi 06.06.2012 um 14:40
Moderiert von user profile iconNarses: Titel geändert, war: "Korrektheit der Ausführung einer Delphi-Quellcodezeile !".


DonManfred - Mi 06.06.12 17:00

Sicher das das #10 stehen bleibt oder kann es nicht doch sein das das was du da noch siehst ein #13 ist? Normal ist ein Zeilenumbruch ja #13+#10...


bummi - Mi 06.06.12 17:16

Der Text wird ja nicht in Delphi verwaltet sondern an ein Wincontrol übergeben, diese wertet #10#13 oder #10 oder #13 als Zeilenumbruch aus, bei der Rückgabe bekommst Du für jeden Zeilenumbruch ein #13#10.

Was passiert sieht man mit diesem "Provokationstest"


Delphi-Quelltext
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:
procedure TForm5.Button1Click(Sender: TObject);
begin
 RichEdit1.Text := 'Hallo'#13#10'Nase';
 Caption := IntToStr(Length(RichEdit1.Text));
 RichEdit1.Text := StringReplace(Richedit1.Text,#13#10,#10#13,[rfReplaceAll]);
  Caption := Caption +'-' +IntToStr(Length(RichEdit1.Text));
end;

procedure TForm5.Button2Click(Sender: TObject);
begin
 Memo1.Text := 'Hallo'#13#10'Nase';
 Caption := IntToStr(Length(Memo1.Text));
 Memo1.Text := StringReplace(Memo1.Text,#13#10,#10#13,[rfReplaceAll]);
  Caption := Caption +'-' +IntToStr(Length(Memo1.Text));
end;

procedure TForm5.Button3Click(Sender: TObject);
begin
// Label mit Wordwrap
 Label1.Caption := 'Hallo'#13#10'Nase';
 Caption := IntToStr(Length(Label1.Caption));
 Label1.Caption := StringReplace(Label1.Caption,#13#10,#10#13,[rfReplaceAll]);
  Caption := Caption +'-' +IntToStr(Length(Label1.Caption));

end;


IhopeonlyReader - Mi 06.06.12 17:26

Vielleicht was ganz einfaches wie, dass Wordwrap von dem Richedit an ist? so würde, falls der text länger als das Richedit ist ein Zeilenumbruch hinzugefügt :D Vielleicht ist das folgende Abfolge:
- 'Hallo'+#10#13+'Zeile2' //dann zeilenumbruch durch nichts ersetzen
- 'HalloZeile2' //RicheditWordWrap schaltet sich ein
- 'Hallo'+#10#13+'Zeile2'

Eventuell machst du mal sowas

Showmessage(StringReplace(richedit1.text,#10#13,'',[rfReplaceAll]));


Hochhaus - Mi 06.06.12 20:22

user profile iconbummi hat folgendes geschrieben Zum zitierten Posting springen:
Der Text wird ja nicht in Delphi verwaltet sondern an ein Wincontrol übergeben, diese wertet #10#13 oder #10 oder #13 als Zeilenumbruch aus, bei der Rückgabe bekommst Du für jeden Zeilenumbruch ein #13#10.


Danke für Eure Beiträge. Mit einem TMemo treten die Schwierigkeiten nicht mehr auf. Dafür kriege ich die Zeile und Spalte im Editor nicht mehr hin:


Delphi-Quelltext
1:
2:
3:
  Zeile := 0;
  Zeile := Memo1.Perform(EM_LineFromChar, Zeile-10) + 1;
  Column:= Memo1.SelStart - Memo1.Perform(EM_LINEINDEX, Zeile-10) + 1;


...funktioniert nicht mehr.

Gruss,


Hochhaus


jaenicke - Do 07.06.12 06:40

Naja, wie wäre es, wenn du nicht die Zeile von Zeichen -1 ermittelst, sondern die von Memo1.SelStart? :zwinker:
Da du Zeile mit 0 initialisierst...
user profile iconHochhaus hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
2:
3:
  Zeile := 0;
  Zeile := Memo1.Perform(EM_LineFromChar, Zeile-10) + 1;
  Column:= Memo1.SelStart - Memo1.Perform(EM_LINEINDEX, Zeile-10) + 1;


Hochhaus - Do 07.06.12 06:51

Moderiert von user profile iconNarses: Komplett-Zitat des letzten Beitrags entfernt.

Dies ist nicht das Problem. Ich habe schlicht und einfach vergessen, die Prozedur auszuführen ... Sorry, mein Fehler !


Hochhaus


jaenicke - Do 07.06.12 07:11

Das kann so aber trotzdem keine korrekten Ergebnisse liefern... :gruebel:


Hochhaus - Do 07.06.12 07:26

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Das kann so aber trotzdem keine korrekten Ergebnisse liefern... :gruebel:


Ok. Wie würdest Du es besser machen ?

Hochhaus


jaenicke - Do 07.06.12 09:05

Ok, das war mir nicht klar:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb761609.aspx hat folgendes geschrieben:
If this parameter is –1, EM_LINEFROMCHAR retrieves either the line number of the current line (the line containing the caret) or, if there is a selection, the line number of the line containing the beginning of the selection.
Aber dann kannst du es auch direkt schreiben:

Delphi-Quelltext
1:
2:
  Zeile := Memo1.Perform(EM_LineFromChar, -10) + 1;
  Column:= Memo1.SelStart - Memo1.Perform(EM_LINEINDEX, Zeile-10) + 1;


Hochhaus - Do 07.06.12 11:19

Moderiert von user profile iconNarses: Komplett-Zitat des letzten Beitrags entfernt.

Geht nicht !

--> [DCC Fehler] CHILD.PAS(336): E1012 Konstantenausdruck verletzt untere Grenzen

Deshalb der Trick mit der Zeile ...


Sybok Factor - Fr 08.06.12 13:51


Delphi-Quelltext
1:
2:
Spalte := Memo1.CaretPos.X;
Zeile := Memo1.CaretPos.Y;


Funktioniert das unter XE2 nicht mehr oder habe ich was falsch verstanden?
Viele Grüße
Sybok Factor


Hochhaus - Fr 08.06.12 16:38

Moderiert von user profile iconNarses: Komplett-Zitat des letzten Beitrags entfernt.

Dies funktioniert für kleine Zeilenzahlen. Wenn ich aber über 100'000 Zeilen in einer Datei habe, funktioniert es nicht mehr. Ich habe es mit meinem Texteditor ausprobiert ...


Gruss,


Hochhaus


jaenicke - Fr 08.06.12 18:11

user profile iconHochhaus hat folgendes geschrieben Zum zitierten Posting springen:
Geht nicht !

--> [DCC Fehler] CHILD.PAS(336): E1012 Konstantenausdruck verletzt untere Grenzen
Argh, stimmt, die hatten da ja bei XE2 die Parameter auf Cardinal verschlimmbessert. Bis XE klappt das noch.
Du kannst aber einfach SendMessage nehmen. Damit geht es. ;-)

user profile iconHochhaus hat folgendes geschrieben Zum zitierten Posting springen:
Dies funktioniert für kleine Zeilenzahlen. Wenn ich aber über 100'000 Zeilen in einer Datei habe, funktioniert es nicht mehr. Ich habe es mit meinem Texteditor ausprobiert ...
Ein Fehler, den es schon seit mindestens Delphi 5 oder so gibt. Aber leider noch nicht behoben. Der entsprechende QC-Report:
http://qc.embarcadero.com/wc/qcmain.aspx?d=65093