Lazarus 2.1.0 und TDBMemo -> [noch Offen]

Rund um die LCL und andere Komponenten

Lazarus 2.1.0 und TDBMemo -> [noch Offen]

Beitragvon MmVisual » 6. Feb 2019, 09:35 Lazarus 2.1.0 und TDBMemo -> [noch Offen]

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
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
Zuletzt geändert von MmVisual am 7. Feb 2019, 21:45, insgesamt 3-mal geändert.
MmVisual
 
Beiträge: 1053
Registriert: 10. Okt 2008, 22:54
OS, Lazarus, FPC: Winux (L 1.6 FPC 3) | 
CPU-Target: 32/64Bit
Nach oben

Beitragvon Michl » 6. Feb 2019, 13:56 Re: Lazarus 2.1.0 und TDBMemo

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; 
Michl
 
Beiträge: 2314
Registriert: 19. Jun 2012, 11:54
OS, Lazarus, FPC: Win7 Laz 1.7 Trunk FPC 3.1.1 Trunk | 
CPU-Target: 32Bit/64bit
Nach oben

Beitragvon MmVisual » 6. Feb 2019, 14:14 Re: Lazarus 2.1.0 und TDBMemo

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.
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
MmVisual
 
Beiträge: 1053
Registriert: 10. Okt 2008, 22:54
OS, Lazarus, FPC: Winux (L 1.6 FPC 3) | 
CPU-Target: 32/64Bit
Nach oben

Beitragvon Michl » 6. Feb 2019, 15:25 Re: Lazarus 2.1.0 und TDBMemo

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; 
Michl
 
Beiträge: 2314
Registriert: 19. Jun 2012, 11:54
OS, Lazarus, FPC: Win7 Laz 1.7 Trunk FPC 3.1.1 Trunk | 
CPU-Target: 32Bit/64bit
Nach oben

Beitragvon MmVisual » 6. Feb 2019, 15:59 Re: Lazarus 2.1.0 und TDBMemo

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

Bild2.png


Demo-Code mit ZEOS:
Test_LazV2.1.0_TDBMemo.zip


Demo-Code mit der Lazarus eigenen DB Komponente:
Test_LazV2.1.0_TDBMemoLaz.zip


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.
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
MmVisual
 
Beiträge: 1053
Registriert: 10. Okt 2008, 22:54
OS, Lazarus, FPC: Winux (L 1.6 FPC 3) | 
CPU-Target: 32/64Bit
Nach oben

Beitragvon Michl » 6. Feb 2019, 19:58 Re: Lazarus 2.1.0 und TDBMemo

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; 
Michl
 
Beiträge: 2314
Registriert: 19. Jun 2012, 11:54
OS, Lazarus, FPC: Win7 Laz 1.7 Trunk FPC 3.1.1 Trunk | 
CPU-Target: 32Bit/64bit
Nach oben

Beitragvon MmVisual » 6. Feb 2019, 20:18 Re: Lazarus 2.1.0 und TDBMemo

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.
MmVisual
 
Beiträge: 1053
Registriert: 10. Okt 2008, 22:54
OS, Lazarus, FPC: Winux (L 1.6 FPC 3) | 
CPU-Target: 32/64Bit
Nach oben

Beitragvon sstvmaster » 6. Feb 2019, 21:00 Re: Lazarus 2.1.0 und TDBMemo

@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
OS: Windows 7 32/64bit
Lazarus 2.0.0, 32bit
Lazarus 2.1.0 Trunk 3.3.1, 32bit
sstvmaster
 
Beiträge: 129
Registriert: 22. Okt 2016, 22:12
OS, Lazarus, FPC: Lazarus 2.0 + 2.1.0 Trunk 3.3.1 / Win32, Windows 7 32+64bit | 
CPU-Target: 32Bit
Nach oben

Beitragvon MmVisual » 6. Feb 2019, 21:11 Re: Lazarus 2.1.0 und TDBMemo

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?
MmVisual
 
Beiträge: 1053
Registriert: 10. Okt 2008, 22:54
OS, Lazarus, FPC: Winux (L 1.6 FPC 3) | 
CPU-Target: 32/64Bit
Nach oben

Beitragvon sstvmaster » 6. Feb 2019, 21:17 Re: Lazarus 2.1.0 und TDBMemo

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.
OS: Windows 7 32/64bit
Lazarus 2.0.0, 32bit
Lazarus 2.1.0 Trunk 3.3.1, 32bit
sstvmaster
 
Beiträge: 129
Registriert: 22. Okt 2016, 22:12
OS, Lazarus, FPC: Lazarus 2.0 + 2.1.0 Trunk 3.3.1 / Win32, Windows 7 32+64bit | 
CPU-Target: 32Bit
Nach oben

Beitragvon MmVisual » 6. Feb 2019, 21:23 Re: Lazarus 2.1.0 und TDBMemo

OK, ich habe dazu ein Bugreport geschrieben.

https://bugs.freepascal.org/view.php?id=35026
MmVisual
 
Beiträge: 1053
Registriert: 10. Okt 2008, 22:54
OS, Lazarus, FPC: Winux (L 1.6 FPC 3) | 
CPU-Target: 32/64Bit
Nach oben

Beitragvon wp_xyz » 6. Feb 2019, 23:11 Re: Lazarus 2.1.0 und TDBMemo

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...
wp_xyz
 
Beiträge: 2797
Registriert: 8. Apr 2011, 08:01

Beitragvon MmVisual » 7. Feb 2019, 08:56 Re: Lazarus 2.1.0 und TDBMemo -> Lazarus Bugreport

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!
MmVisual
 
Beiträge: 1053
Registriert: 10. Okt 2008, 22:54
OS, Lazarus, FPC: Winux (L 1.6 FPC 3) | 
CPU-Target: 32/64Bit
Nach oben

Beitragvon sstvmaster » 7. Feb 2019, 09:26 Re: Lazarus 2.1.0 und TDBMemo -> [Gelöst]

Na dann ist ja der Tag gerettet, Markus!
OS: Windows 7 32/64bit
Lazarus 2.0.0, 32bit
Lazarus 2.1.0 Trunk 3.3.1, 32bit
sstvmaster
 
Beiträge: 129
Registriert: 22. Okt 2016, 22:12
OS, Lazarus, FPC: Lazarus 2.0 + 2.1.0 Trunk 3.3.1 / Win32, Windows 7 32+64bit | 
CPU-Target: 32Bit
Nach oben

Beitragvon wp_xyz » 7. Feb 2019, 10:30 Re: Lazarus 2.1.0 und TDBMemo -> [Gelöst]

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.
wp_xyz
 
Beiträge: 2797
Registriert: 8. Apr 2011, 08:01

» Weitere Beiträge siehe nächste Seite »
Nächste

Zurück zu Komponenten und Packages



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste

porpoises-institution
accuracy-worried