Recent

Author Topic: [Solved] How to modify OnGetText method in TDBf  (Read 4958 times)

xaver13

  • Jr. Member
  • **
  • Posts: 92
[Solved] How to modify OnGetText method in TDBf
« on: September 16, 2012, 08:17:45 pm »
need to use OnGetText method to convert 1251 code page DBF fields to utf8
I was inspired here:
http://www.lazarus.freepascal.org/index.php?topic=11213.0
I tried the code:
Code: [Select]
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, db, dbf, FileUtil, Forms, Controls, Graphics, Dialogs,
  DBGrids, DbCtrls, StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Datasource1: TDatasource;
    Dbf1: TDbf;
    DBGrid1: TDBGrid;
    DBNavigator1: TDBNavigator;
    Label1: TLabel;
    procedure Dbf1AfterOpen(DataSet: TDataSet);
    procedure DBGrid1GetCellHint(Sender: TObject; Column: TColumn;
      var AText: String);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

//type
//Tmethod = procedure() of object;

Procedure Konv(Sender:Tfield; var aText:String; DisplayText: Boolean = true);
begin
  //aText:=Trim(Sender.AsString);
  aText:=Utf8ToAnsi(Sender.AsString);
end;


procedure TForm1.Dbf1AfterOpen(DataSet: TDataSet);
  var i:integer;
      aText: String;
  // var m:Tmethod;
  begin
  For i:=0 to Dbf1.FieldCount-1 do
      If Dbf1.Fields[i].DataType=ftString then
      //label1.caption:=label1.caption+'s';
      Dbf1.Fields[i].OnGetText:=@Konv;
  end;
end.   
But I am getting an error
Code: [Select]
unit1.pas(57,33) Error: Incompatible types: got "<address of procedure(TField,var AnsiString,Boolean="TRUE");Register>" expected "<procedure variable type of procedure(TField,var AnsiString,Boolean) of object;Register>"
on
Code: [Select]
Dbf1.Fields[i].OnGetText:=@Konv;
line.
Thank You very much for  help.
Regards,
« Last Edit: September 17, 2012, 09:38:33 am by xaver13 »
--
Jiri Cvrk

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7359
Re: How to modify OnGetText method in TDBf
« Reply #1 on: September 16, 2012, 09:12:19 pm »
The main problem is that you declared a procedure, not a method.

A potentially secondary problem might be the default parameter (  DisplayText: Boolean = true), I don't know if the compiler accepts that.

xaver13

  • Jr. Member
  • **
  • Posts: 92
Re: How to modify OnGetText method in TDBf
« Reply #2 on: September 16, 2012, 09:27:39 pm »
Thank you very much.
As I wrote in first post I was inspired here http://www.lazarus.freepascal.org/index.php?topic=11213.0
in this forum. O.K. this is wrong.

Now I tried:
Code: [Select]
Function Konv(Sender:Tfield; var aText:String; DisplayText: Boolean = true):string;
begin
  Konv:=Utf8ToAnsi(Sender.AsString);
end;   

but the Error on
Code: [Select]
Dbf1.Fields[i].OnGetText:=@Konv; Incompatible types: got "<address of function(TField,var AnsiString,Boolean="TRUE"):AnsiString;Register>" expected "<procedure variable type of procedure(TField,var AnsiString,Boolean) of object;Register>"

remains the same :( .

Coud you please tell me how to declare and use such method correctly or where to find correct answer?
« Last Edit: September 16, 2012, 10:16:53 pm by xaver13 »
--
Jiri Cvrk

taazz

  • Hero Member
  • *****
  • Posts: 5363
Re: How to modify OnGetText method in TDBf
« Reply #3 on: September 16, 2012, 10:46:11 pm »
Two problems I see in your code.

1) Konv is declared as a function while the OngetText events expects a procedure.
2) It is not a method of an object.

Using your code from your first post here are the modifications.

Code: [Select]
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, db, dbf, FileUtil, Forms, Controls, Graphics, Dialogs,
  DBGrids, DbCtrls, StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Datasource1: TDatasource;
    Dbf1: TDbf;
    DBGrid1: TDBGrid;
    DBNavigator1: TDBNavigator;
    Label1: TLabel;
    procedure Dbf1AfterOpen(DataSet: TDataSet);
    procedure DBGrid1GetCellHint(Sender: TObject; Column: TColumn;
      var AText: String);
  private
    { private declarations }
  public
    { public declarations }
    Procedure Convert(Sender:Tfield; var aText:String; DisplayText: Boolean);
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

//type
//Tmethod = procedure() of object;

Procedure Konv(Sender:Tfield; var aText:String; DisplayText: Boolean = true);
begin
  //aText:=Trim(Sender.AsString);
  aText:=Utf8ToAnsi(Sender.AsString);
end;


procedure TForm1.Dbf1AfterOpen(DataSet: TDataSet);
  var i:integer;
      aText: String;
  // var m:Tmethod;
  begin
  For i:=0 to Dbf1.FieldCount-1 do
      If Dbf1.Fields[i].DataType=ftString then
      //label1.caption:=label1.caption+'s';
      Dbf1.Fields[i].OnGetText:=@Convert;
  end;
end.   

Procedure TForm1.Convert(Sender:Tfield; var aText:String; DisplayText: Boolean);
begin
  if DisplayText then
    aText:=Utf8ToAnsi(Sender.AsString)
  else
    aText := Sender.AsString;
end;
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

xaver13

  • Jr. Member
  • **
  • Posts: 92
Re: How to modify OnGetText method in TDBf
« Reply #4 on: September 17, 2012, 09:37:36 am »
Thank you, taazz! :)

Working code bellow. I had to move declarations of methods from public section some lines up - to Tform class, why?

Code: [Select]
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, db, dbf, FileUtil, Forms, Controls, Graphics, Dialogs,
  DBGrids, DbCtrls, StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Datasource1: TDatasource;
    Dbf1: TDbf;
    DBGrid1: TDBGrid;
    DBNavigator1: TDBNavigator;
    Label1: TLabel;
    procedure Dbf1AfterOpen(DataSet: TDataSet);
    Procedure Convert(Sender:Tfield; var aText:String; DisplayText: Boolean);

  Private
    { private declarations }
  Public
    { public declarations }
//    Procedure Convert(Sender:Tfield; var aText:String; DisplayText: Boolean);
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

Procedure TForm1.Convert(Sender:Tfield; var aText:String; DisplayText: Boolean=True);
begin
  if DisplayText then
    aText:=AnsiToUtf8(Sender.AsString)
    else
    aText:=AnsiToUtf8(Sender.AsString)
 end;



procedure TForm1.Dbf1AfterOpen(DataSet: TDataSet);
  var i:integer;
      aText: String;
  begin
    For i:=0 to Dbf1.FieldCount-1 do
      If Dbf1.Fields[i].DataType=ftString then
        Dbf1.Fields[i].OnGetText:=@Convert;
  end;


end.
           
[code]
--
Jiri Cvrk