在RICHEDIT中,如何自动显示繁体?

xuv2002 2003-03-20 04:19:00
在其Font属性中把Charset设置为CHINESEBIG5_CHARSET,没有用!多谢各位!
...全文
77 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
好久没有来csdn了,最近主要忙着项目开发,这么旧没有来,想想不能空手而来,所以带来了一篇文章,也是我在项目开发中遇到的问题,希望大家会喜欢。

Unicode已经成为Windows字符的主要编码方式,我想这也是大势所趋,现在软件越来越倾向国际化,而国际化主要的编码方式就是Unicode,不管是单字节英文字符,还是双字节汉字,在Unicode编码格式下都能正常显示。在Windows2000中大到Word,小到Notepad,都能很好的显示Unicode格式的文本文件。可是在我最近的项目中却发现VCL中的TMemo类不支持它,例如如下16进制显示的Unicode文本文件

66 00 67 00 68 00 69 00

在WindowsXP自带的Notepad中显示为:



但是在C++ builder6中的TMemo控件中则显示为:



除了把第一个字符显示出来,其他的字符都被忽略了,这在设计应用中是绝对不允许的,究其原因,原来是TMemo类的Lines属性不支持Unicode,Lines属性是TStings类,TMemo是通过TStrings的LoadFormFile方法代开文件并显示的,在VCL源代码中,我们可以找到如下函数

procedure TStrings.LoadFromFile(const FileName: string);
var
Stream: TStream;
begin
Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
LoadFromStream(Stream);
finally
Stream.Free;
end;
end;

procedure TStrings.LoadFromStream(Stream: TStream);
var
Size: Integer;
S: string;
begin
BeginUpdate;
try
Size := Stream.Size - Stream.Position;
SetString(S, nil, Size);
Stream.Read(Pointer(S)^, Size);
SetTextStr(S);
finally
EndUpdate;
end;
end;

最后来到SetTextStr函数,由于这个函数的处理,使得Unicode被忽略了

procedure TStrings.SetTextStr(const Value: string);
var
P, Start: PChar;
S: string;
begin
BeginUpdate;
try
Clear;
P := Pointer(Value);
if P <> nil then
while P^ <> #0 do
begin
Start := P;
while not (P^ in [#0, #10, #13]) do Inc(P);
SetString(S, Start, P - Start);
Add(S);
if P^ = #13 then Inc(P);
if P^ = #10 then Inc(P);
end;
finally
EndUpdate;
end;
end;

以上代码片断我们可以清楚的看出Unicode是如何被忽略了,对于Unicode,它的编码方式是不管单字节还是双字节都是都是以双字节编码,单字节的英文则以0来补高位,但是很可惜,在以上函数中只要遇到0就退出了,所以在上面的例子中我们看到了‘f’这唯一的幸存者。

原因找到了,解决起来就倒是很容易,在判断字符串结束时不要以0来定界,而是实际的字符长度,这样就可以解决了,如下代码:

Clear;
P := Pointer(S);
if P <> nil then
begin
iPos := 0;
while (iPos < Size) do // (P^ <> #0) do
begin
Start := P;
while not (P^ in [#0, #10, #13]) do
begin
Inc(P);
Inc(iPos);
end;
SetString(S1, Start, P - Start);
Add(S1);
if (P^ = #13) then
begin
Inc(P);
Inc(iPos);
end;
if (P^ = #10) then
begin
Inc(P);
Inc(iPos);
end;
if (P^ = #0) then
begin
Inc(P);
Inc(iPos);
end;
end;
end;
finally
EndUpdate;
end;
end;

这样TStrings就能很好的支持Unicode字符集了。

写在最后:

其实在C++ Builder中对Unicode支持的还是很好的,VCL提供了WideString类封装了w_char*,而且还提供很多有用的方法用于Ansi与Unicode的相互转换,可能是TMemo太老了,它还来不及改正,说道太老了,VCL里很多控件都应该升级了,比如TRichEdit还是用的Richedit1.0,VCL的界面外观还不能应用XP的外观。

Borland公司的产品推出速度却是“惊人”,很多都还没有用过Delphi6,Delphi7就快要出来了,Borland公司只是在技术上推出新产品,但在服务上却始终不见前进,在这点上Borland要多学习Microsoft,做一个产品要很踏实,升级太平凡会显得“落后的”,记得以前Borland C++ 就是因为过快的发布,而没有足够的测试,导致出现很多Bug,很多用户转向了Microsoft的Visual C++,要不是Delphi力挽狂澜,Borland早就Game Over了,希望Borland不要重蹈覆辙,相信很多和我一样的Borland忠实用户都不希望看到这样。
xuv2002 2003-04-02
  • 打赏
  • 举报
回复
17:30
结贴,来着前面10个每人10分
sprewellkobe 2003-04-02
  • 打赏
  • 举报
回复
强烈关注!没遇到过这问题
bacer 2003-04-02
  • 打赏
  • 举报
回复
明白你的意思了,呵呵。
GBK里面有简体编码的繁体文字,虽然看上去和big5的文字一样,但是编码不同。一般的简体系统都可以正常识别。
如果系统支持gbk字符集应该没问题了
xuv2002 2003-04-02
  • 打赏
  • 举报
回复
好象这个问题没有解决方案了
今天下班前偶就揭贴
来者有份啦!!!!
  • 打赏
  • 举报
回复
在简体中文下是不能的呀
因为它不支持统一编码
xuv2002 2003-03-24
  • 打赏
  • 举报
回复
可能问题我说的不是很清楚,不好意思:)

我的意思是
首先我的系统是简体win2000,什么繁体字库呀肯定都有
我在richedit里面的lines 里面输入(其实也就是用某个软件将我输入的简体字转换为繁体字,然后Ctrl+c Ctrl+v罢了)
不论我把richedit 的font 的charset改成gb_2312 还是big5 或是别的都只是繁体显示(在简体系统那就乱码)
但是假如是在Label或是TEdit等控件里面类似操作就可以自动显示出繁体字
不知为何?
还请大家多多帮忙!

多谢诸位了:)
yhec 2003-03-24
  • 打赏
  • 举报
回复
楼上的意思可能想用GBK的繁体显示(非大五的)
qiuafa 2003-03-24
  • 打赏
  • 举报
回复
up
xuv2002 2003-03-20
  • 打赏
  • 举报
回复
简体2000下其它不变,即系统不变,大家不妨试一试.多谢bacer(键盘制造) ,不过我说的不是那个意思.
bacer 2003-03-20
  • 打赏
  • 举报
回复
2000不用设置,98是不是么安装繁体字库?

604

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder VCL组件使用和开发
社区管理员
  • VCL组件使用和开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧