快速业务通道

对WebMatrix进行现代化改造 使其完美支持中文

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-05-20

先插一段小广告为下文做铺垫

我一直觉得WebMatrix是一个很不错的ASP.NET开发工具, 虽然这个小软件是在遥远的 v1.x 年代的产品, 但功能齐全, 使用方便, 而且个头小, 安装后总共才2.8M的个头(想想 Web Developer Express的个头), 自带一个服务器, 安装后还可以直接把程序目录拷贝到 U盘里随身携带, 非常适合那些自己没有电脑但又想学习ASP.NET开发的童鞋(我以前大学 时没买电脑前就是这么干的啦). 不过它有个很大的缺点, 就是不能很好的支持中文. 在 文本编辑器里输入中文后, 光标显示的位置不对.... 一个对策就是不输入中文就好啦, 顺便还可以锻炼英文 :-)

最近一直在研究WebMatrix, 为什么要研究它? 有几个目的和原因:

学习如何设计并实现一个结构良好且有扩展性的程序

学习如何从零开始实现一个代码编辑器

WebMatrix这个程序功能齐全, 具有一定扩展性(支持插件), 个头不大不小(核心部分 估计有50000行左右代码, 花一两个星期摸透, 非常适合进行研究 

这是微软出品的, 就算程序设计的不是很完美, 但至少不会是错误的

响应上面的小广告, 对其进行改造, 使其能够完美支持中文

我花了大概一个星期左右, 基本摸清了整个程序的结构和流程, 发现其实这个程序设 计的还是很不错的. 各模块职责分明, 配合良好, 扩展性很强也很容易进行扩展, 非常符 合 "对修改关闭, 对扩展开放" 这个软件设计思想.

对程序研究得比较清楚之后, 最主要的任务就是

对其进行改造,

使其能够完美支持中文

啦. 经研究发现, WebMatrix里的文本编辑器在输出文本时, 使用了一个固定的字符宽 度(杯具的开始), 这个固定宽度在仅仅使用英文时是没有问题的, 但是如果有中文(或其 他非拉丁系文字), 就会出problems了: 计算出来的文本宽度不对, 这个就直接导致了两 个问题:

当前文本行里的光标位置不对

被选中部分的文字显示不正常

如图:

对WebMatrix进行现代化改造 使其完美支持中文

经研究代码, 要修改的地方主要有两个:

TextView.UpdateCaretPosition(...) //目的是修正当前文本行里的光标位置

TextView.PaintTextLine(...) //目的是修正被选中文本的显示

为修正这两个问题, 我加了一个辅助函数

1: private Interop.SIZE MeasureString(char[] chars, int  startIndex, int length)
2: {
3:   IntPtr fontPtr =  this.Font.ToHfont();
4:   Graphics graphics = Graphics.FromHwnd (IntPtr.Zero);
5:   IntPtr hdc = graphics.GetHdc();
6:    Interop.SelectObject(hdc, fontPtr);
7:   Interop.SIZE size =  this.MeasureString(hdc, chars, startIndex, length);
8:    Interop.SelectObject(hdc, IntPtr.Zero);
9:   graphics.ReleaseHdc (hdc);
10:   graphics.Dispose();
11:   return size; 
12: }

然后在TextView.UpdateCaretPosition(...)   里这么修改:

1: private void UpdateCaretPosition(bool checkForFocus)
2:  {
3:   if (((this.Focused || base.Parent.Focused) || ! checkForFocus) && (this._paintFrozen == 0))
4:   {
5:      if (this._location.ColumnIndex > this._location.Line.Length)
6:      {
7:       this._location.ColumnIndex =  this._location.Line.Length;
8:     }
9:
10:    //NOTE: 修改 了更新光标位置的算法, 使其支持多字节文字
11:     //把这一句
12:      //int x = (((this._fontWidth * (this.GetViewIndex(this._location)  - this.ViewLeftIndex)) + this.MarginPadding) + this.MarginWidth) +  this._lineNumbersWidth;
13:
14:     //改成
15:      Interop.SIZE size = this.MeasureString(_location.Line.ToCharArray(),  this.ViewLeftIndex, (this.GetViewIndex(this._location) -  this.ViewLeftIndex));
16:
17:     int x = size.x +  this.MarginPadding + this.MarginWidth + this._lineNumbersWidth;
18:      int y = (this._location.LineIndex - this.ViewTopLineNumber) *  this._fontHeight;
19:     Interop.SetCaretPos(x, y);
20:   }
21:   else
22:   {
23:     this._updateCaretOnPaint =  true;
24:   }
25: }

TextView.PaintTextLine(...)函数按照此法修改, 由于有接近10处调用, 就不一一列 出来了, 有兴趣的同学可以下源码自己看.

修改完成后, 运行一下, 哈哈~ perfect~~, 如图:

对WebMatrix进行现代化改造 使其完美支持中文

然而...咚的一声, 美梦惊醒.....

对WebMatrix进行现代化改造 使其完美支持中文

2点了....我之前发了誓要2点之前睡觉的.....好吧, 预知后事如何, 请听下文分解

Written by: 麦壳

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号