Lazarus中文社区

 找回密码
 立即注册(注册审核可向QQ群索取)

QQ登录

只需一步,快速开始

Lazarus IDE and 组件 下载地址版权申明
查看: 6344|回复: 5

lazarus Tdbf TDBGrid控件显示Foxpro表格乱码完美解决方案

[复制链接]

该用户从未签到

发表于 2014-11-10 16:54:58 | 显示全部楼层 |阅读模式
本帖最后由 cp8001 于 2015-3-29 21:36 编辑

2015.3.29 看了lazarus的实例代码'C:\lazarus\examples\dbeditmask',终于找到了比较好的解决方法.

FFieldArray:array of TStringField;    //如果存在多种类型的字段,可定义为array of TField;

procedure TForm1.FormCreate(Sender: TObject);
var
  i:integer;
  FDefs:TFieldDefs;
begin
  dbf1.Open;                          //打开表,取得表的字段定义.
  FDefs:=TFieldDefs.Create(nil);
  Fdefs.Assign(dbf1.FieldDefs);
  dbf1.Close;                         //表必须关闭,才能添加字段.
  setlength(FFieldArray,Fdefs.Count);
  for i:=0 to Fdefs.Count-1 do begin
      FFieldArray:=TStringField.Create(dbf1);
      with FFieldArray do begin
          DataSet:=dbf1;
          FIeldKind:=fkData;
          FieldName:=Fdefs.Name;
          DisplayWidth:=Fdefs.Size;
          Size:=255;     //不设置此值,过长的中文字段可能显示不完整.
          OnGetText:=@FieldGetText;   
          OnSetText:=@FieldSetText;
          ProviderFlags := [pfInUpdate, pfInWhere];
          Index:=i;
      end;
  end;
  dbf1.Open;
  FDefs.Free;
end;


procedure TForm1.FieldGetText(Sender: TField; var aText: string;
  DisplayText: Boolean);
var
  str:string;
begin
  aText:=ansitoutf8(sender.AsString);     //当存在多种类型的字段时,在这里处理.
end;


procedure TForm1.FieldSetText(Sender: TField; const aText: string);
begin
  Sender.AsString:=UTF8TOansi(aText);
end;  

***********************************************************************************
{lazarus Tdbf  TDBGrid控件显示Foxpro表格乱码解决.注:lazarus1.2采用UTF8,foxpro表为ansi编码,代码页936}
{在Linux Windows下面均通过测试能正确显示汉字。}

1.修改表格控件TDBGrid (Grids单元)
unit Grids
uses  {加入} LConvEncoding{字符编码转换单元};
{增加TCodePage定义}
TCodePage=(cdNormal,cdCP936,cdCP1253,cdCP1255);  {定义TCodePage,仅测试,只用到了cdCP936}  
{TCustomGrid Private加入变量FCodePage存储代码页标志}
private   FCodePage:TCodePage;
public   
      Property CodePage:TCodePage read FCodePage Write FcodePage;   {加入CodePage属性}
{修改过程}
procedure TCustomGrid.DrawCellText(aCol, aRow: Integer; aRect: TRect;
  aState: TGridDrawState; aText: String);
begin
  with ARect do begin    dec(Right, constCellPadding);
    case Canvas.TextStyle.Alignment of
      Classes.taLeftJustify: Inc(Left, constCellPadding);
      Classes.taRightJustify: Dec(Right, 1);
    end;
    case Canvas.TextStyle.Layout of
      tlTop: Inc(Top, constCellPadding);
      tlBottom: Dec(Bottom, constCellPadding);
    end;

    if Right<Left then
      Right:=Left;
    if Left>Right then
      Left:=Right;
    if Bottom<Top then
      Bottom:=Top;
    if Top>Bottom then
      Top:=Bottom;
    {添加字符转换代码}
    if FCodePage=cdCP936 then
       aText:=CP936ToUtf8(aText);
   {添加部分}
    if (Left<>Right) and (Top<>Bottom) then
      Canvas.TextRect(aRect,Left,Top, aText);
  end;
end;
2.修改表格控件TDBGrid (DBGrids单元)
unit DBGrids;
uses    LConvEncoding{加入字符编码转换单元};
{修改函数,表格中编辑后仍能正确显示和存储中文字符}
function TCustomDBGrid.GetEditText(aCol, aRow: Longint): string;
var
  aField: TField;
begin
  if FDataLink.Active then begin
    aField := GetFieldFromGridColumn(aCol);
    if aField<>nil then begin
      {根据ANSI代码页转换}
      if self.CodePage=cdCP936 then
         Result:=CP936TOUtf8(aField.Text)
      else
      Result := aField.Text;
    end;
  end;
end;      

procedure TCustomDBGrid.SetEditText(ACol, ARow: Longint; const Value: string);
begin
  {表格单元格值改变后写入}
  if self.CodePage=cdCP936 then
     FTempText :=UTF8ToCP936( Value)
  else
     FTempText:=Value;
end;         

3.在使用TDBGrid的单元中设置CodePage属性.      
dbgrid1.CodePage:=cdCP936;  {foxpro dbf数据表}
也可以在dbgrids单元修改
unit DBGrids

TDBGrid=class(TCustomDBGrid)  
published
    property CodePage; {继承自TCustomGrid,添加在些以便能在面板上使用}      
然后重新构建连编lazarus .重启后,TDBGrid控件在面板上就出现CodePage属性了,可以选择代码页类型.此处只演示了cdCP936的转换.



回复

使用道具 举报

该用户从未签到

发表于 2014-11-11 13:06:01 | 显示全部楼层
谢谢分享
回复 支持 反对

使用道具 举报

  • TA的每日心情
    开心
    2017-3-1 22:40
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    发表于 2014-11-12 11:18:41 | 显示全部楼层
    感谢分享,正好有这个需要
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2017-3-1 22:40
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    发表于 2014-12-27 11:31:08 | 显示全部楼层
    有改好的grids.pas吗?
    回复 支持 反对

    使用道具 举报

    该用户从未签到

     楼主| 发表于 2014-12-29 16:34:00 | 显示全部楼层
    clxer 发表于 2014-12-27 11:31
    有改好的grids.pas吗?

    实践总结,要显示CP936 代码页的foxpro dbf文件,可以先把表转换成UTF8编码,再存储,显示,处理.会方便得多.
    而且重装lazarus,也不用再去改grids.pas了.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2017-3-1 22:40
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    发表于 2014-12-31 21:38:34 | 显示全部楼层
    改过的grid显示utf8会乱码
    回复 支持 反对

    使用道具 举报

    *滑块验证:

    本版积分规则

    QQ|手机版|小黑屋|Lazarus中国|Lazarus中文社区 ( 鄂ICP备16006501号-1 )

    GMT+8, 2024-6-23 21:36 , Processed in 0.029630 second(s), 9 queries , Redis On.

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表