简体转繁体乱码(100)

  • 主题发起人 主题发起人 fuyou
  • 开始时间 开始时间
F

fuyou

Unregistered / Unconfirmed
GUEST, unregistred user!
1、重装操作系统之前编译的程序是正常的:在简体系统显示的是简体,繁体系统或英文系统显示的是繁体;用以前的程序现在运行还是正常的。2、重装操作系统之后对程序重编译后却不正常了:简体系统下使用正常,繁体系统或英文系统下就出现了乱码;3、怀疑是操作系统设置或DELPHI第三方控件不同,导致编译后的文件差异,但是什么却不知道。主要函数如下:function TSysFunc.GBToBig5(GBStr: string): string;var Len: Integer; pGBCHTChar: PChar; pGBCHSChar: PChar; pUniCodeChar: PWideChar; pBIG5Char: PChar;begin pGBCHSChar := PChar(GBStr); Len := MultiByteToWideChar(936, 0, pGBCHSChar, -1, nil, 0); GetMem(pGBCHTChar, Len * 2 + 1); ZeroMemory(pGBCHTChar, Len * 2 + 1); //GB CHS -> GB CHT LCMapString($804, LCMAP_TRADITIONAL_CHINESE, pGBCHSChar, -1, pGBCHTChar, Len * 2); GetMem(pUniCodeChar, Len * 2); ZeroMemory(pUniCodeChar, Len * 2); //GB CHT -> UniCode MultiByteToWideChar(936, 0, pGBCHTChar, -1, pUniCodeChar, Len * 2); Len := WideCharToMultiByte(950, 0, pUniCodeChar, -1, nil, 0, nil, nil); GetMem(pBIG5Char, Len); ZeroMemory(pBIG5Char, Len); //UniCode -> Big5 WideCharToMultiByte(950, 0, pUniCodeChar, -1, pBIG5Char, Len, nil, nil); Result := string(pBIG5Char); FreeMem(pBIG5Char); FreeMem(pGBCHTChar); FreeMem(pUniCodeChar);end;function TSysFunc.getDisplay(const input: string): string;//****INPUT 即为要显示的原字符begin if (GetOEMCP = 936) then begin Result := input; end else if (GetOEMCP = 950) then //繁体系统 begin Result := GBToBig5(input); end else begin Result := GBToBig5(input); end;end;
 
有知道的吗?[:)]
 
补充:DELPHI 7
 
或者是字体不对???
 
这行代码我觉得有问题: MultiByteToWideChar(936, 0, pGBCHTChar, -1, pUniCodeChar, Len * 2); 这句是假设pGBCHTChar是936(中文简体)代码页下的字符。从你程序上看,pGBCHTChar实际是从getDisplay的参数“input”传入,也是就说,当你调用getDisplay函数的时候,你假设参数“input”是中文简体下的字符编码,但实际上,可能不是。若不是的话,转换出来肯定是乱码。若你保证“input”一定是中文简体下的字符编码,那我就分析不出原因了,希望有另外的高人解答:)
 
如果代码一点都没改就不对了,那就和代码没有关了。感觉应该和unicode有关,是不是需要装个第三方控件来支持unicode,或是系统设一下,能够支持unicode。
 
这个问题只能用调试的方法去解决,重新编译一个程序,里面只显示两个汉字,比如“你好”,看看在繁体下显示成什么。“你好”在代码页936的字符编码为0xE3C4 0xC3BA;“你好”的unicode的字符编码为0x4F60 0x597D;也就是说,在函数getDisplay里加调试语句function TSysFunc.getDisplay(const input: string): string;//****INPUT 即为要显示的原字符begin assert(length(input)=4, '长度不为4'); assert(Ord(input[1])=$C4, '非中文简体编码'); assert(Ord(input[2])=$E3, '非中文简体编码'); assert(Ord(input[3])=$BA, '非中文简体编码'); assert(Ord(input[4])=$C3, '非中文简体编码'); ....end.若出现断言错误,可以确定,传入的字符串编码不是中文简体编码。若没出现断言错误,但在繁体下显示还是乱码,看看转换成unicode后的编码是否是0x4F60、0x597D。...MultiByteToWideChar(936, 0, pGBCHTChar, -1, pUniCodeChar, Len * 2);assert(Ord(pUniCodeChar[0])=$4F, '不是期望的unicode编码');assert(Ord(pUniCodeChar[1])=$60, '不是期望的unicode编码');assert(Ord(pUniCodeChar[2])=$7d, '不是期望的unicode编码');assert(Ord(pUniCodeChar[3])=$59, '不是期望的unicode编码');....这样用排除法一步步的排除原因。
 
"INPUT" 是简体,取的是ORACLE数据库中的数据(简体),但是奇怪,在英文系统下不经过转换,直接显示时是乱码
 
从逻辑上我觉得这不大可能,但从你描述的情况,这又的确发生了。这可以用调试的手段去解决。在getDisplay里,写log文件,记录每个input字符的ASCII码(最好用16进制表示),再记录每个转换后的结果result的每个字符的ASCII码。这样,可以看看是不是输入的参数(input)有错,或者是转换的结果(result)有错。如都没有错,再看看是不是显示的问题(这可能性我觉得很小,最大的可能性是输入的参数有错)
 
最后解决的办法是,在 ORASESSION 里将 CHARSET 设成 ZHS16CGB231280,就可以,但为什么以前程序没有这样设置也是可以的呢?
 

Similar threads

I
回复
0
查看
548
import
I
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
767
import
I
后退
顶部