又是编码问题,被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#来重写这个程序,可能更麻烦,所以还是继续修改。希望解决了中文编码的问题,别的应该问题不大了。