[转载]修补SynEdit CVS 中文问题

SynEdit是SourceForge.net上顶级的语法高亮度显示组件。

Open Source,Delphi的源码。质量和效果都没得说。很多商业和非商业的软件包中都有使用。

用它你可以非常方便的实现一个自己的代码编辑器来。支持众多的语法,支持RTF和HTML输出。非常的方便。

http://community.csdn.net/Expert/TopicView.asp?id=3068979

CSDN的Freicin雪客最近发布的一个小软件,估计就是基于SynEdit的.(纯粹猜测啊!)

美中不足的是中文的处理上有些瑕疵。但凡国外的东西都有这样的毛病,只好自己动手丰衣足食!

经过简短的追踪,调试。很快就找到了问题的关键所在! 

source/SynEditExport.pas 的450行左右,下面这个函数的实现有点问题。

function TSynCustomExporter.ReplaceReservedChars(AToken: string;

  var IsSpace: boolean): string;

var

  I, ISrc, IDest, SrcLen, DestLen: integer;

  Replace: string;

  c: char;                              //mh 2000-10-10

begin

  IsSpace := TRUE;

  if AToken <> '' then begin

    SrcLen := Length(AToken);

    ISrc := 1;

    DestLen := SrcLen;

    IDest := 1;

    SetLength(Result, DestLen);

    while ISrc <= SrcLen do begin

      c := AToken[ISrc];

      IsSpace := IsSpace and (c = ' ');

 

//Chinese charactor patch by cker begin. 2004-06-17

{$IFDEF SYN_MBCSSUPPORT}

      if (ByteType(AToken,ISrc)= mbLeadByte) and (ISrc <= SrcLen) and (ByteType(AToken,ISrc + 1)= mbTrailByte) then begin

        Replace := ReplaceMBCS(AToken[ISrc], AToken[ISrc + 1]);

        Inc(ISrc, 2);

      end else

{$ENDIF}

//Chinese charactor patch by cker end. 2004-06-17

 

      if fReplaceReserved[c] <> nil then begin

        Replace := StrPas(fReplaceReserved[c]);

        Inc(ISrc);

{$IFDEF SYN_MBCSSUPPORT}

//      end else if ByteType(AToken, ISrc) <> mbSingleByte then begin

      end else if (AToken[ISrc] in LeadBytes) and (AToken[ISrc + 1] <> #0) then //mh 2000-10-10

      begin

        Replace := ReplaceMBCS(AToken[ISrc], AToken[ISrc + 1]);

        Inc(ISrc, 2);

{$ENDIF}

      end else begin

        if IDest > DestLen then begin

          Inc(DestLen, 32);

          SetLength(Result, DestLen);

        end;

        Result[IDest] := c;

        Inc(ISrc);

        Inc(IDest);

        continue;

      end;

      if IDest + Length(Replace) - 1 > DestLen then begin

        Inc(DestLen, Max(32, IDest + Length(Replace) - DestLen));

        SetLength(Result, DestLen);

      end;

      for I := 1 to Length(Replace) do begin

        Result[IDest] := Replace[I];

        Inc(IDest);

      end;

    end;

    SetLength(Result, IDest - 1);

  end else

    Result := '';

end;

 

其实原本作者已经意识到了多字节文本的处理,但可能毕竟不是CJK语系的,对此没有太大的兴趣,所以,还是需要自己动手。不管怎样现在我们的SynEdit可以工作了,HTML输出中文的时候再没有乱码了!

如果就此结束的话,还有一个小毛病,就是转换出来默认的CodePage不是中文而是ISO8859-1,这样你需要先手动选择才可以正确的显示中文。

修改也很简单.

SynEditExportHTML.pas 330行左右:

这里修改很方便,就不说了。

function TSynExporterHTML.GetHeader: string;

const

  DescriptionSize = 105;

  HeaderSize = 47;

  FooterSize1 = 58;

  FooterSize2 = 24;

  NativeHeader = 'Version:0.9'#13#10 +

                 'StartHTML:%.10d'#13#10 +

                 'EndHTML:%.10d'#13#10 +

                 'StartFragment:%.10d'#13#10 +

                 'EndFragment:%.10d'#13#10;

HTMLAsTextHeader = '<?xml version="1.0" encoding="iso-8859-1"?>'#13#10 +

                     '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'#13#10 +

                     '<html xmlns="http://www.w3.org/1999/xhtml">'#13#10 +

                     '<head>'#13#10 +

                     '<title>%s</title>'#13#10 +

                     '<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />'#13#10 +

                     '<meta name="generator" content="SynEdit HTML exporter" />'#13#10 +

                     '<style type="text/css">'#13#10 +

                     '<!--'#13#10 +

                     'body { color: %s; background-color: %s; }'#13#10 +

                     '%s' +

                     '-->'#13#10 +

                     '</style>'#13#10 +

                     '</head>'#13#10 +

                     '<body>'#13#10;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
========== SynEdit Studio Readme==========谢谢使用SynEdit Studio;此控件包基于基于SynEdit加强,增加了一些第三方的SynEdit控件和自己写的控件;原SynEdit控件包开发者:Pieter Zijlstra;增强修改包作者:姚乔锋 [email protected]最近的版本请关注www.delphibox.com和www.delphifans.com;========== SynEdit Studio History==========修改版本 2005.05.20 01.TSynAutoCorrect,改正控件原先不支持中文输入的特点; 02.TSynEdit,增加一个属性ActiveLine,类属性,具体参考TSynActiveLine; 03.TSynEdit,增加一个属性LineDivider,类属性,具体参考TSynLineDivider; 04.TSynEdit,增加一个属性WordWrap,类属性,具体参考TSynWordWrap; 05.TSynEdit,增加一个属性RightEdge,类属性,具体参考TSynRightEdge; 06.TSynEdit,修改高亮当前行的方式,在自动换行的情况也只高亮一行; 07.TSynEdit,当行间距大于零时,原本文本会显示于靠上,现修改于垂直中间对齐; 08.TSynEdit,增加一个属性LineSpacing,可指定行间距; 09.TSynEdit,增加一个属性LineSpacingRule,可指定行间距类型; 10.TSynEdit,修正当控件是在一个子窗口上时,若是焦点转回到主窗口中某个控件后再转回来时会不能显示光标的BUG; 11.TSynEdit,修正当第一列显示的字符是双字节字符的第二个字节时,在高亮当前行情况下会把第一个字节显示在行号区上的BUG; 12.TSynEdit,修正了DoCaseChange,加快转换字母大小写的处理速度和精简代码,也避免出现一些双字节字符的丢失; 13.TSynEdit,修正画右边线的代码,避免有时右边线颜色显示出错; 14.TSynEdit,修正了改变属性TEXT后不能UNDO的特性; 15.TSynEditSource,新添加的自己写的控件,用于存储Synedit的属性,详细请查看单元SynEditSource; 16.TSynEditSearcher,新添加的自己写的类,用于简化Synedit搜索,详细请查看单元SynEditSearcher; 17.TSynUniSyn,新添加的修改过的第三方控件,一个通用的Highlighter,详细请查看单元SynUniHighlighter; 18.TSynSpellCheck,新添加的第三方控件,一个拼写检查控件,详细请查看单元SynSpellCheck; 19.TSynEditor,新增加的TSynEdit的继承控件,增加对编辑文档管理的支持和一些增强型功能 20.SynMsgDialog,一个消息框单元,参照Dialogs中MessageDlg的代码进行改进并重写; 21.SynEditStrRes,一个字符串常量声明单元,存储增加的自定义的控件中用到的字符串;未来期待 下一版本中我将会加入一系列的Action,以方便大家编写程序. 若大家还想增加什么功能的话,请给我写信,当然不要用英文写了,英文我不是很好.
修改 姚乔锋 [email protected]修改的地方: 1.高亮当前行的方式,在自动换行的情况也只高亮一行 2.增强高亮当前的功能,可以选择于行号区显示指示器,可以选择当前行背景与前景 3.当行间距大于零时,原本文本会显示于靠上,现修改于垂直中间对齐 4.可以选择显示行间分隔线,增加可选择线的类型 5.当SynEdit位于MDI中的当前子窗口时,若是焦点转回到主窗口中某个控件后再转回来时会不能显示光标 6.当SynEdit第一列显示的字符是双字节字符的第二个字节时,在高亮当前行情况下会把第一个字节显示在行号区上 7.修改了DoCaseChange, 加快转换字母大小写的处理速度和精简代码,也避免出现一些双字节字符的丢失 8.对画右边线轻微修改,避免有时右边线颜色显示出错 9.修改了属性TEXT, 修正以前改变TEXT后不能UNDO的特性 10.(new) 增加可指定换行类型和换行列,但不能保证没有BUG 11.还有什么BUG请向我说声,谢谢!修改日期于2005.5.15----------以下为TCustomSynEdit类新增的属性---------- TCustomSynEdit = class property ActiveLine : TSynActiveLine; property Background: TColor; property Foreground: TColor; property Indicator : TSynGlyph; property Visible: boolean; property LineDivider : TSynLineDivider; property Visible : Boolean; property Color : TColor; property Style : TPenStyle; property RightEdge : TSynRightEdge; property Visible : Boolean; property Position : Integer; property Color : TColor; property Style : TPenStyle; property LineSpacing : integer; property LineSpacingRule : TLineSpacingRule; property BlockIndent : integer; property WordWrap : TSynWordWrap; property Enabled : Boolean; property Position : Integer; property Style : TSynWordWrapStyle; property Indicator : TSynGlyph; end;----------注:在修改增加自动换行的类型和可指定位置换行时,我遇到很多的困难,不论怎么修改总是存在BUG,于是就有一段时间跑去玩游戏,自到这几天重新研究代码时才把自动换行的那些BUG去掉,所以这个版本发布隔了比较久.
谢谢使用SynEdit增强修改包SynEdit Studio,此控件包基于SynEdit加强.原SynEdit开发者Pieter Zijlstra修改者信息 - 作者 姚乔锋 - 邮箱 [email protected] - QQ  276704780最近的版本请关注www.delphibox.com和www.delphifans.com;SynEditStudio更新 ---------- v2.4(2005.07.29) ---------- - 01.对所有非Delphi6的包去掉SynSpellCheck的注册; - 02.TSynEdit,再次轻微修改一些BUG; - 03.修改Demo,增加类似于IDE的代码补充的功能; ---------- ---------- v2.3(2005.06.25) ---------- - 01.TSynEdit,再次修改了缓冲技术的代码和删除了用API锁定的画面; - 02.TSynEdit,修正了控件自动换行后使用书签时会出面的异常; ---------- ---------- v2.2(2005.06.8) ---------- - 01.SynEditActions,修正若是Action放在工具条上时会不断的闪烁的Bug; - 02.TSynEdit,修正了控件出现'has no parent window'异常的可能,未经测试; ---------- ---------- v2.1(2005.06.1) ---------- - 01.TSynEdit,修改滚动条不现示的BUG; - 02.TSynEdit,修改控件可能会出现错误的异常; - 03.SynEditActions,基本完成,更新注册,并重做了个Demo; ---------- ---------- v1.2(2005.05.29) ---------- - 01.TSynEdit,稍稍修改使用缓冲技术后可能出现的异常; - 02.SynEditActions,一个包含各种synedit动作的单元,目前只提供测试,没有注册单元; ---------- ---------- v1.1(2005.05.23) ---------- - 01.SynSpellReg,修正了这个单元注册时会找不到dcr文件的错误; - 02.TSynEdit,修正了按END键到下一行开头等其它键类似的定位错误; - 03.TSynEdit,修正了快速录入大量文本闪烁问题,使用缓冲技术和API锁定; ---------- ---------- v1.0(2005.05.20) ---------- - 01.TSynAutoCorrect,改正控件原先不支持中文输入的特点; - 02.TSynEdit,增加一个属性ActiveLine,类属性,具体参考TSynActiveLine; - 03.TSynEdit,增加一个属性LineDivider,类属性,具体参考TSynLineDivider; - 04.TSynEdit,增加一个属性WordWrap,类属性,具体参考TSynWordWrap; - 05.TSynEdit,增加一个属性RightEdge,类属性,具体参考TSynRightEdge; - 06.TSynEdit,修改高亮当前行的方式,在自动换行的情况也只高亮一行; - 07.TSynEdit,当行间距大于零时,原本文本会显示于靠上,现修改于垂直中间对齐; - 08.TSynEdit,增加一个属性LineSpacing,可指定行间距; - 09.TSynEdit,增加一个属性LineSpacingRule,可指定行间距类型; - 10.TSynEdit,修正当控件是在一个子窗口上时,若是焦点转回到主窗口中某个控件后再转回来时会不能显示光标的BUG; - 11.TSynEdit,修正当第一列显示的字符是双字节字符的第二个字节时,在高亮当前行情况下会把第一个字节显示在行号区上的BUG; - 12.TSynEdit,修正了DoCaseChange,加快转换字母大小写的处理速度和精简代码,也避免出现一些双字节字符的丢失; - 13.TSynEdit,修正画右边线的代码,避免有时右边线颜色显示出错; - 14.TSynEdit,修正了改变属性TEXT后不能UNDO的特性; - 15.TSynEditSource,新添加的自己写的控件,用于存储Synedit的属性,详细请查看单元SynEditSource; - 16.TSynEditSearcher,新添加的自己写的类,用于简化Synedit搜索,详细请查看单元SynEditSearcher; - 17.TSynUniSyn,新添加的修改过的第三方控件,一个通用的Highlighter,详细请查看单元SynUniHighlighter; - 18.TSynSpellCheck,新添加的第三方控件,一个拼写检查控件,详细请查看单元SynSpellCheck; - 19.TSynEditor,新增加的TSynEdit的继承控件,增加对编辑文档管理的支持和一些增强型功能 - 20.SynMsgDialog,一个消息框单元,参照Dialogs中MessageDlg的代码进行改进并重写; - 21.SynEditStrRes,一个字符串常量声明单元,存储增加的自定义的控件中用到的字符串; ---------- ---------- 编译环境 ---------- - 系统 - Windows2000 (Build 2195: Service Pack 3) - 工具 - Borland Delphi 6 (Build 6.240) Update Pack 2 - 无错编译通过,并测试正常. ----------

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值