又是编码问题,被delphi折磨了两天

前两天又在改象棋桥(XQStudio)的delphi代码,由于代码是用老旧的delphi 5.0编写的,不支持unicode,也缺少很多别的功能,所以就想用delphi 2009(支持Unicode,泛型)来编译。界面的中文显示解决了,但是棋谱的注解文字保存后却变成了乱码,查阅了很多资料,调试了大约一天半多,本来已经差不多要打退堂鼓了,但总有些不甘心,终于又调试下去,好在总算搞定。

原来的代码是:

function dTXqfStream.Write(const Buffer; Count: Longint): Longint;
var
  ByteBuf: PByte;
  p      : PByte;
  i, iPos: Integer;
  KeyByte: Byte;
begin
  Result := 0;
  if Count < 1 then Exit;
  if (Count > 1024) then
  begin
    GetMem(ByteBuf, Count);
  end
  else
  begin
    ByteBuf := @FBuf1024;
  end;
  Move(Buffer, ByteBuf^, Count);
  iPos := Self.Position;
  p    := ByteBuf;
  for i:=0 to Count-1 do
  begin
    KeyByte := F32Keys[(iPos mod 32) + 1];
    P^ := P^ + KeyByte;
    Inc(p);
    Inc(iPos);
  end;
  Result := inherited Write(ByteBuf^, Count);
  if (Count > 1024) then FreeMem(ByteBuf);
end;

调用的代码是:

iBytes := Length(pt.Remark.Text);
fs.Write(PChar(pt.Remark.Text)^, iBytes);

开始改成

fs.Write(PChar(UTF8Encode(pt.Remark.Text))^, iBytes);

然后读出时使用UTF8Decode解码,中文基本显示正常了,但也不完美,末尾的几个字符仍然不正常。而且这样一来,就无法兼容老版本文件。

调试了半天,发现似乎指针位移有问题,但是把PChar改成PByte,又修改了Move函数的调用参数,仍然不行。最后只好用笨办法解决:

function dTXqfStream.WriteRemark(fbt: TBytes; Count: Longint): Longint;
var
  i, iPos: Integer;
  KeyByte: Byte;
begin
  Result := 0;
  iPos := Self.Position;
  for i:=0 to Count - 1 do
  begin
    KeyByte := F32Keys[(iPos mod 32) + 1];
    fbt[i] := fbt[i] + KeyByte;
    Inc(iPos);
  end;
  for i := 0 to Count - 1 do
      inherited Write(fbt[i], 1); 
  Result := 0;
end;

也就是不用指针,强制一个一个字节写,就可以了。

delphi大概现在用的人少,资料不容易查。api文档实在实在垃圾!!几乎找不到什么有用的东西。ide还算不错,当然没有visual studio好用。调试时有时会出现某些断点无法达到,需要在文件开头加上编译选项{$O-}才行。方法先要声明,然后再写实现。一大堆begin, end,写法极其罗嗦。反正各种不好用。只是觉得如果自己用C#来重写这个程序,可能更麻烦,所以还是继续修改。希望解决了中文编码的问题,别的应该问题不大了。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章