Lazarus 2.1.0 und TDBMemo -> [noch Offen]

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

Lazarus 2.1.0 und TDBMemo -> [noch Offen]

Beitrag von MmVisual »

Hallo,

Ich habe das Problem dass in TDBMemo seit Lazarus V2.x der Text anhand dem OnGetText von TField angezeigt wird und nicht mehr direkt aus der Datenbank.

Wie kann ich das abstellen, damit der Text so wie bei Lazarus 1.8.4 angezeigt wird?

Der Grund:
Im TDBGrid will ich den Text ohne Zeilenumbruch zeigen, damit man da auch was sinnvolles sieht, jedoch im Memo muss der so stehen wie es jemand eingibt. Hier Bilder damit man das versteht wie ich meine und Code was im OnGetText drin steht:

Code: Alles auswählen

procedure TfrmMain.qBeschreibungGetText(Sender: TField; var aText: string; DisplayText: boolean);
var s: string;
begin
  s := StringReplace(Sender.AsString, LineEnding, '¶', [rfReplaceAll]);
  s := StringReplace(s, #13, '¶', [rfReplaceAll]);
  s := StringReplace(s, #10, '', [rfReplaceAll]);
  if Length(s) > 250 then
    aText := UTF8Copy(s, 1, 250) + '...'
  else  aText := s;
end;

Bild1.png

Bild2.png


Dankeschön, grüße Markus
Zuletzt geändert von MmVisual am Do 7. Feb 2019, 21:45, insgesamt 3-mal geändert.
EleLa - Elektronik Lagerverwaltung - www.elela.de

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

Re: Lazarus 2.1.0 und TDBMemo

Beitrag von Michl »

Habe es eben mal nachgestellt. Mir fällt im Moment nur ein, daß man für das DataSet regulär kein OnGetText definiert, sondern nur dann, wenn das TDBGrid gezeichnet wird. Z.B.:

Code: Alles auswählen

  { TDBGrid }
 
  TDBGrid = class(DBGrids.TDBGrid)
  private
    procedure FieldsGetText(Sender: TField; var aText: string; DisplayText: Boolean);
  protected
    procedure Paint; override;
  end;   
...
procedure TDBGrid.FieldsGetText(Sender: TField; var aText: string; DisplayText: Boolean);
begin
  // hier was auch immer
end;
 
procedure TDBGrid.Paint;
var
  i: Integer;
begin
  for i := 0 to DataSource.DataSet.Fields.Count - 1 do
    DataSource.DataSet.Fields[i].OnGetText := @FieldsGetText;
  inherited Paint;
  for i := 0 to DataSource.DataSet.Fields.Count - 1 do
    DataSource.DataSet.Fields[i].OnGetText := nil;
end;

Code: Alles auswählen

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

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

Re: Lazarus 2.1.0 und TDBMemo

Beitrag von MmVisual »

Nein das ist anders. Anbei ein Screenshot wo man das "OnGetText" benutzt.
Es ist eine Ereignis von z.B. TMemoField (eigentlich allen TField).
Bild1.png


Ich denke es ist ein Bug, denn in der Feature/Change Liste von Lazarus V2 konnte ich dazu nichts finden.

Das TDBMemo soll den Text von TField.AsString verwenden und nicht von TField.DisplayText. Denn DisplayText ruft noch im Hintergrund "OnGetText" auf und AsString bringt den String direkt ohne OnGetText.
EleLa - Elektronik Lagerverwaltung - www.elela.de

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

Re: Lazarus 2.1.0 und TDBMemo

Beitrag von Michl »

Wie kommt man zu dem TMemoField? Ich kann hier z.B. ZQuery rechts klicken und die Felder bearbeiten. Dann wird für diese aber für das Memo und Grid gleichzeitig OnGetText aufgerufen (nicht erst seit 2.0.0 auch schon in 1.8.0).

Code: Alles auswählen

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

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

Re: Lazarus 2.1.0 und TDBMemo

Beitrag von MmVisual »

Wenn man in der Datenbank ein Feld Typ "TEXT" anlegt, und TZConnection/TZQuery mit der Datenbank im Designer aktiviert, so kann man mit Rechtsklick in der noch leeren Liste "Felder hinzufügen" auswählen und es wird eine Liste der verfügbaren Felder angezeigt, die man hinzufügen kann. So kann man sehr einfach alle Felder auf einmal anlegen ohne diese manuell rein zu fummeln. Dabei werden auch die korrekten Feldtypen wie z.B. TFloatField, TMemoField usw. angelegt.

Nein bei Lazarus 1.8.4 war es noch anders... Anbei ein Demo-Code und Screenshots:
Bild1.png
Bild1.png (9.02 KiB) 3013 mal betrachtet

Bild2.png
Bild2.png (9.1 KiB) 3013 mal betrachtet


Demo-Code mit ZEOS:
Test_LazV2.1.0_TDBMemo.zip
(910.82 KiB) 111-mal heruntergeladen


Demo-Code mit der Lazarus eigenen DB Komponente:
Test_LazV2.1.0_TDBMemoLaz.zip
(911.04 KiB) 115-mal heruntergeladen


Demo-Code:
DLL (64 Bit) und Demo DB als SQLite sind im ZIP
Beide Demo-Codes funktionieren gleich schlecht, es liegt also auch nicht am ZEOS.
EleLa - Elektronik Lagerverwaltung - www.elela.de

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

Re: Lazarus 2.1.0 und TDBMemo

Beitrag von Michl »

MmVisual hat geschrieben:Wenn man in der Datenbank ein Feld Typ "TEXT" anlegt
Das war die mir fehlende Info, ich hatte hier nur "VARCHAR" getestet.

Danke für das Testprojekt. Das Verhalten kommt mit Revision 57598 https://bugs.freepascal.org/view.php?id=33498. Evtl. kann wp da mehr sagen?!

Code: Alles auswählen

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

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

Re: Lazarus 2.1.0 und TDBMemo

Beitrag von MmVisual »

Ich habe den Bugreport mal gelesen. Das war wohl ein Schuss in den Ofen ...

BrunoK wollte wohl erreichen dass er per "OnGetText" die Codepage der Datenbank konvertierten kann damit es mit der Darstellung im TDBMemo klappt.
Das ist jedoch der völlig falsche Ansatz.

Wenn die Datenbank CP_1252 codiert ist und Lazarus UTF-8, dann muss die Datenbank Komponente dies anhand der Datenbank selbst erkennen und die Konvertierung durchführen. Denn es ist echt mühsam wenn das jeder Progger selbst erfinden muss, zumal es hunterte von Kodierungen gibt und fast jedes Land hat da was eigenes. Wenn jeder Progger das selbst machen muss, dann werden ganz viele buggy Programme entstehen und es wird echt schwer internationale funktionierende Software zu schreiben.

Wie es richtig gemacht wird:
Bei der ZEOS Datenbankkomponente macht das Zeos schon alleine im Hintergrund. Zeos liest von der Datenbank die Codierung aus und wandelt es automatisch in die Codierung der Programmierumgebung, bei Lazarus in UTF8. Da hat EgonHugeist richtig gute Arbeit geleistet (ZeosDevTeam)

Was nach dem Fix jedenfalls fehlt: Es fehlt in der TDBMemo Komponente eine Option wo man das berücksichtigen von "OnGetText" aktiviert, was defaultmäßig deaktiviert ist wegen der Abwärtskompatibilität.
EleLa - Elektronik Lagerverwaltung - www.elela.de

sstvmaster
Beiträge: 575
Registriert: Sa 22. Okt 2016, 23:12
OS, Lazarus, FPC: W10, L 2.2.6
CPU-Target: 32+64bit
Wohnort: Dresden

Re: Lazarus 2.1.0 und TDBMemo

Beitrag von sstvmaster »

@MmVisual

C:\fpcupdeluxe\lazarus\lcl\include\dbmemo.inc

Code: Alles auswählen

@ 246
- Lines.Text := FDataLink.Field.Text
+ Lines.Text := FDataLink.Field.AsString


Jetzt IDE neu übersetzen dann geht es wieder so wie unter 1.8.4
LG Maik

Windows 10,
- Lazarus 2.2.6 (stable) + fpc 3.2.2 (stable)
- Lazarus 2.2.7 (fixes) + fpc 3.3.1 (main/trunk)

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

Re: Lazarus 2.1.0 und TDBMemo

Beitrag von MmVisual »

Kommt das noch in die Lazarus Sourcen rein?

Sollte nicht besser das TDBMemo mit einem neuen Parameter ausgestattet werden:

Boolean: TDBMemo.UseFieldGetSetText

Wobei FALSE als Default hinterlegt ist wegen Abwärtskompatibilität?
EleLa - Elektronik Lagerverwaltung - www.elela.de

sstvmaster
Beiträge: 575
Registriert: Sa 22. Okt 2016, 23:12
OS, Lazarus, FPC: W10, L 2.2.6
CPU-Target: 32+64bit
Wohnort: Dresden

Re: Lazarus 2.1.0 und TDBMemo

Beitrag von sstvmaster »

Nein das sollte eigentlich nur ein Hinweis drauf sein wo das herkommt.

Was nun geändert werden soll weiss ich auch nicht, habe nur rum probiert.
LG Maik

Windows 10,
- Lazarus 2.2.6 (stable) + fpc 3.2.2 (stable)
- Lazarus 2.2.7 (fixes) + fpc 3.3.1 (main/trunk)

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

Re: Lazarus 2.1.0 und TDBMemo

Beitrag von MmVisual »

OK, ich habe dazu ein Bugreport geschrieben.

https://bugs.freepascal.org/view.php?id=35026
EleLa - Elektronik Lagerverwaltung - www.elela.de

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

Re: Lazarus 2.1.0 und TDBMemo

Beitrag von wp_xyz »

Michl hat geschrieben:Evtl. kann wp da mehr sagen?!

So weit reicht mein Gedächtnis nicht zurück, da muss ich mich erst wieder reindenken...

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

Re: Lazarus 2.1.0 und TDBMemo -> Lazarus Bugreport

Beitrag von MmVisual »

Vom Lazarus Team kam eine Antwort, wie man das neu programmieren muss, damit es im TDBGrid sowie im TDBMemo richtig geht:

Code: Alles auswählen

procedure TfrmMain.qBeschreibungGetText(Sender: TField; var aText: string; DisplayText: boolean);
var s: string;
begin
  IF DisplayText Then // << Diese Abfrage ist TRUE bei TDBGrid uns FALSE bei TDBMemo
  Begin
    s := StringReplace(Sender.AsString, LineEnding, '¶', [rfReplaceAll]);
    s := StringReplace(s, #13, '¶', [rfReplaceAll]);
    s := StringReplace(s, #10, '', [rfReplaceAll]);
    if Length(s) > 250 then
      aText := UTF8Copy(s, 1, 250) + '...'
    else
      aText := s;
  End Else Begin
    aText := Sender.AsString;
  end;
end;


Dankeschön für die schnelle Hilfe!
EleLa - Elektronik Lagerverwaltung - www.elela.de

sstvmaster
Beiträge: 575
Registriert: Sa 22. Okt 2016, 23:12
OS, Lazarus, FPC: W10, L 2.2.6
CPU-Target: 32+64bit
Wohnort: Dresden

Re: Lazarus 2.1.0 und TDBMemo -> [Gelöst]

Beitrag von sstvmaster »

Na dann ist ja der Tag gerettet, Markus!
LG Maik

Windows 10,
- Lazarus 2.2.6 (stable) + fpc 3.2.2 (stable)
- Lazarus 2.2.7 (fixes) + fpc 3.3.1 (main/trunk)

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

Re: Lazarus 2.1.0 und TDBMemo -> [Gelöst]

Beitrag von wp_xyz »

Nö, das bittere Ende kommt noch.

Dieses Verhalten ("Diese Abfrage ist TRUE bei TDBGrid und FALSE bei TDBMemo") ist nicht kompatibel zu Delphi, und es besteht die Gefahr, dass ein bösartiger Lazarus-Entwickler das ändert. Daher würde ich mich nicht darauf verlassen, dass das immer so bleibt. Eine kompatiblere Lösung wäre, zu dem Memo-Feld ein berechnetes String-Feld zu erzeugen, das den bisher im OnGetText-Event verwendeten Code im OnCalcFields-Event des Dataset ausführt. Damit könnte das DBMemo weiterhin das Memo-Feld verwenden, und die Grid-Spalte das berechnete Feld. - Siehe Beispiel im Bug-Report.

Antworten