TMemo - Wie Wort bei Cursor-Position auslesen? [gelöst]

Rund um die LCL und andere Komponenten
Antworten
MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

TMemo - Wie Wort bei Cursor-Position auslesen? [gelöst]

Beitrag von MmVisual »

Hallo,

Ich habe folgenden Code um das Wort zu finden das mit Strg+Mausklick im Memo ausgewählt wird:

Code: Alles auswählen

procedure TfrmMain.MemoMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: integer);
var  s: string;
begin
  if not (ssCtrl in Shift) then  Exit;
  s := GetSelWordMemo(TMemo(Sender)); 
 : :
 
// Gibt das Wort bei Cursorposition zurück
function GetSelWordMemo(Memo: TMemo): string;
var
  s: string;
  i: integer;
begin
  i := Memo.SelStart;
  s := '';
  Result := '';
  repeat
    Result := s + Result;
    s := Copy(Memo.Text, i, 1);
    Dec(i);
  until (s <= ' ') or (i < 0);
  i := Memo.SelStart + 1;
  s := '';
  repeat
    Result := Result + s;
    s := Copy(Memo.Text, i, 1);
    Inc(i);
  until (s <= ' ') or (s = '');
  If Assigned(frmMain) Then
    frmMain.DoLog('FindWord: ' + Result); // *DEBUG
end;
Nur leider funktioniert das ganze nicht richtg. Sobald zu vor Umlaute stehen, haben diese 2 Byte im Speicher und das ganze SelStart passt nicht mehr zu der Klick-Position und die Routine gibt mir das falsche Wort zurück.

Weiß jemand wie ich das richtig mache?

Grüße Markus.
Zuletzt geändert von MmVisual am Fr 13. Jan 2012, 08:22, insgesamt 1-mal geändert.
EleLa - Elektronik Lagerverwaltung - www.elela.de

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

Re: TMemo - Wie Wort bei Cursor-Position auslesen?

Beitrag von theo »

Könnte man z.B. so lösen:

Code: Alles auswählen

function GetSelWordMemo(Memo: TMemo): string;
var
  i: integer;
  txt, s, res:WideString;
begin
  txt:=UTF8Decode(Memo.Text);
  i := Memo.SelStart;
  s := '';
  Res := '';
  repeat
    Res := s + Res;
    s := Copy(txt, i, 1);
    Dec(i);
  until (s <= ' ') or (i < 0);
  i := Memo.SelStart + 1;
  s := '';
  repeat
    Res := Res + s;
    s := Copy(txt, i, 1);
    Inc(i);
  until (s <= ' ') or (s = '');
  Result:=UTF8Encode(Res);
end;

MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: TMemo - Wie Wort bei Cursor-Position auslesen?

Beitrag von MmVisual »

Vielen Dank, theo!
Es klappt.
EleLa - Elektronik Lagerverwaltung - www.elela.de

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: TMemo - Wie Wort bei Cursor-Position auslesen? [gelöst]

Beitrag von mschnell »

D.H. "Selstart" ist in "sichtbaren" Charactern angegeben. was logisch sein könnte, weil es ja irgendwie eine "Bildschirmn-Position" ist.

Gilt das für Windows und für Linux ?

Gibt es keine Funktion für UTF-8 Strings in der RTL, die Position in Bytes und die Position in sichtbaren Zeichen in einander umzurechnen, ohne gleich den ganzen String umzucodieren ? Das ist doch eine "Standard-Aufgabe" und relativ wenig Aufwand.

-Michael
Zuletzt geändert von mschnell am Fr 13. Jan 2012, 12:48, insgesamt 1-mal geändert.

MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: TMemo - Wie Wort bei Cursor-Position auslesen? [gelöst]

Beitrag von MmVisual »

Ich habe das gerade unter Linux auch ausprobiert, theo's Vorschlag klappt dort auch.

Ja, ich finde es auch irgendwie umständlich, dass man die Zeichen erst wandeln muss.
Es sollte vielleicht ein "SelStartChar" und ein "SelStartByte" geben, damit hätte man das Problem gelöst.

Nicht ohne Grund haben die Delphi-Programmierer alles mit WideChar gelöst, ist viel leichter zu rechnen, auch wenn es mehr Speicher braucht.
EleLa - Elektronik Lagerverwaltung - www.elela.de

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

Re: TMemo - Wie Wort bei Cursor-Position auslesen? [gelöst]

Beitrag von theo »

MmVisual hat geschrieben: Nicht ohne Grund haben die Delphi-Programmierer alles mit WideChar gelöst, ist viel leichter zu rechnen, auch wenn es mehr Speicher braucht.
Das ist leider auch nur für den BMP so (Basic Multilingual Plane, 16 Bit-Basis des Unicode-Zeichensatzes).
Die von mir vorgeschlagene Lösung ist auch nicht ganz sauber, aber diese Diskussion wollen wir jetzt nicht wieder aufwärmen. :mrgreen:

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: TMemo - Wie Wort bei Cursor-Position auslesen? [gelöst]

Beitrag von mse »

MmVisual hat geschrieben: Nicht ohne Grund haben die Delphi-Programmierer alles mit WideChar gelöst,
MSEide+MSEgui benützt ebenfalls UnicodeChar. :-)
Übrigens sollte UnicodeString statt WideString benutzt werden, sonst bekommt man unter Windows nicht-Referenz-gezählte OLE strings.

Martin

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

Re: TMemo - Wie Wort bei Cursor-Position auslesen? [gelöst]

Beitrag von theo »

Es geht auch ohne Umwandlung und für den gesamten Unicode Range.
Am einfachsten mit meinem UTF8Scanner. http://wiki.lazarus.freepascal.org/Theodp" onclick="window.open(this.href);return false;

Code: Alles auswählen

uses utf8scanner;
 
function GetSelWordMemo(Memo: TMemo): string;
var
  s: string;
  i,ss: integer;
  usc:TUTF8Scanner;
begin
  usc:=TUTF8Scanner.Create(Memo.Text);
  ss := Memo.SelStart;
  i:=ss;
  s := '';
  Result := '';
  repeat
    Result := s + Result;
    s := usc[i];
    Dec(i);
  until (s <= ' ') or (i < 0);
  i := ss + 1;
  s := '';
  repeat
    Result := Result + s;
    s := usc[i];
    Inc(i);
  until (s <= ' ') or (s = '');
  usc.free;
end;

Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

Re: TMemo - Wie Wort bei Cursor-Position auslesen? [gelöst]

Beitrag von Aliobaba »

Hallo,

bitte entschuldigt, wenn ich ein etwas älteres Thema nochmal "aufwärme".

Ich möchte gerne ein Wort in einem Memo-Text als Link verwenden.
Mit Wörtern, die keine Umlaute enthalten funktioniert das hervorragend.
Wörter mit Umlauten werden auch in "Edit1.text" korrekt dargestellt. Wenn ich aber dieses Wort (mit Umlauten) als Link verwenden will, funktioniert das nicht.

Was muss ich tun?

Aliobaba

<<<<<<<<<<<<<<<<<<<<<<<<<<<

Code: Alles auswählen

 
procedure TForm1.F4;
  var
    i: integer;
    txt, s, res:WideString;
begin
   res := '';
   if DBMemoText.Focused=true then
   begin
      txt:=UTF8Decode(DBMemoText.Text);
      i := DBMemoText.SelStart;
      s := '';
      repeat
        Res := s + Res;
        s := Copy(txt, i, 1);
        Dec(i);
      until (s <= ' ') or (i < 0);
      i := DBMemoText.SelStart + 1;
      s := '';
      repeat
        Res := Res + s;
        s := Copy(txt, i, 1);
        Inc(i);
      until (s <= ' ') or (s = '');
   end;
   Edit1.Text:=UTF8Encode(Res);
   if res <> '' then Shellexecute(form1.handle, 'open', pchar( UTF8Encode(Res) ), nil,nil, sw_show);
end;
 
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: TMemo - Wie Wort bei Cursor-Position auslesen? [gelöst]

Beitrag von Michl »

Eigentlich sollte es reichen, die Umwandlung in UTF8 weg zu lassen, also

Code: Alles auswählen

   if res <> '' then Shellexecute(form1.handle, 'open', pchar( Res ), nil,nil, sw_show);
statt

Code: Alles auswählen

   if res <> '' then Shellexecute(form1.handle, 'open', pchar( UTF8Encode(Res) ), nil,nil, sw_show);
Wenn Res als UTF8 vorliegt, müsstest du das in Ansi umwandeln z.B.

Code: Alles auswählen

  Res:=UTF8toAnsi(Res); 
[Edit] sehe gerade, dass Res ein Widestring ist, müsstest also wie folgt umwandeln:

Code: Alles auswählen

   if res <> '' then Shellexecute(form1.handle, 'open', pchar( AnsiString( Res ) ), nil,nil, sw_show);

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

Re: TMemo - Wie Wort bei Cursor-Position auslesen? [gelöst]

Beitrag von Aliobaba »

Danke, Michl!!!
funktoniert :D
... kompliziert ist dieses Thema mit den verschiedenen String-Fomen und Kodierungen ja schon :shock:

Aliobaba
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Antworten