2007年3月28日星期三

CopySourceAsHtml 插件中文出现乱码的问题

上一篇文章中,我修正了CopySourceAsHtml 插件无法用于中文的Bug。 在VS2005的项目中CopySourceAsHtml 插件工作的很好。可是在VS2005的类库中执行“Copy As Html...”命令却会出现乱码。例如,复制一个类库中的一行C#代码:

47 int i = 0; // 啊


会变成:

47 int i = 0; // 啊'b0?


在“啊”的后面对了“'b0?”这几个字母。 这是为什么呢?

查找问题原因

在执行了“Copy As Html...” 命令后,打开记事本,进行“粘贴”操作。可以看到生成的HTML代码为:


&#21834 是“啊”的Unicode码,'b0?是什么东东呢?看来还得看源代码。在CopySourceAsHtml的源代码的Connnect.cs 的Copy(bool copyNow)函数中,有这样一段代码:

373 try

374 {

375 rtf = Clipboard.GetRtf();

376 if (rtf == null)

377 {

378 MessageBox.Show(Resources.NoRtfDataOnClipboardMessage, Resources.NoRtfDataOnClipboardCaption, MessageBoxButtons.OK, MessageBoxIcon.Error);

379 return;

380 }

381 }

382 catch (ExternalException)

383 {

384 MessageBox.Show(Resources.UnableToAccessClipboardMessage, Resources.UnableToAccessClipboardCaption, MessageBoxButtons.OK, MessageBoxIcon.Error);

385 return;

386 }

387

388 html = copier.CopyAsHtml(rtf);

389

390 Clipboard.SetHtml(html);


很明显,CopySourceAsHtml的工作原理是先取得VS2005存放在剪贴板中的RTF字符串(第375行),然后将RTF字符串解析、替换成HTML标记的代码(第388行)。
那么,造成乱码的原因就可能有两个:(1) VS2005存放在剪贴板中的RTF文本有问题(毕竟只有在类库中使用CopySourceAsHtml插件会出现乱码。(2) CopySourceAsHtml插件解析RTF的代码有问题。

VS2005存放在剪贴板中的RTF文本

在VS2005中选中一个汉字,例如:"啊",按Ctrl+C进行复制,然后使用通过一段小程序即可取得VS2005 放到剪贴板中的RFT文本:

130 private void button1_Click(object sender, EventArgs e)

131 {

132 textBox1.Text = System.Windows.Forms.Clipboard.GetText(TextDataFormat.Rtf);

133 }


发现RTF文本中啊被表示成了 “... \fs18 \cf11 \uc2\u21834 \'b0\'a1}”。其中21834是“啊”的Unicode编码,b0a1是“啊”的GB2312编码。不知道为什么VS2005会同时将这两种编码全都放到RTF文本中。不过如果把这段RTF文本放到一个.RTF 文件中,会发现写字板会将\u21834 过滤掉,只留下\'b0\'a1。而CopySourceAsHtml并未进行这些过滤,结果出现了“啊'b0?”这样的结果。

修正

俺对RTF格式一点都不了解,下载了一个RTF Spec也看得头大。幸好有前辈高人已经将这个问题解决了,请见Huan-Lin's Blog的文章http://huanlin.dyndns.org/cs/blogs/huan-lins_blog/archive/2006/10/20/CopySourceAsHtml-Fix.aspx。Hua-Lin修正了多处Unicode方面的Bug,真的很佩服他。

没有评论: