自定义RichTextBox链接样式

在.NET框架中,RichTextBox控件提供了一种方便的属性DetectUrls,当设置此属性时,控件会自动检测并格式化文本中的URL。但是,这个功能仅限于识别以http:、file:、mailto:等标准协议开头的链接。如果需要添加不以这些协议开头的链接,标准的RichTextBox控件就无法满足需求了。幸运的是,.NET的RichTextBox控件实际上是Win32RichEdit控件的包装,可以通过发送特定的消息来扩展其功能。

RichTextBox控件的DetectUrls属性虽然方便,但它只能识别以特定协议开头的链接。这意味着,如果需要添加自定义的链接样式,比如内部文档链接或者特定应用程序的链接,标准的RichTextBox控件就无能为力了。

RichEdit控件的样式管理

RichEdit控件定义了两组消息,一组是EM_GETCHARFORMAT和EM_SETCHARFORMAT,用于设置和查询字符范围内的格式选项;另一组是EM_GETPARAFORMAT和EM_SETPARAFORMAT,用于设置和查询整个段落的格式选项,比如对齐方式。将使用第一组消息来设置所需的样式。

在查阅EM_SETCHARFORMAT的文档时,会发现它使用了一个CHARFORMAT结构来传递格式化信息。对于RichEdit控件的较新版本(2.0及以上),这个结构被扩展为CHARFORMAT2结构,包含了更多的信息。这个结构的定义如下:

typedef struct _charformat2 { UINT cbSize; DWORD dwMask; DWORD dwEffects; LONG yHeight; LONG yOffset; COLORREF crTextColor; BYTE bCharSet; BYTE bPitchAndFamily; TCHAR szFaceName[LF_FACESIZE]; WORD wWeight; SHORT sSpacing; COLORREF crBackColor; LCID lcid; DWORD dwReserved; SHORT sStyle; WORD wKerning; BYTE bUnderlineType; BYTE bAnimation; BYTE bRevAuthor; BYTE bReserved1; } CHARFORMAT2;

这个结构中包含了两个成员,dwMask和dwEffects,它们分别用于指定是否要设置/查询某个格式化选项,以及实际的值。其中,CFE_LINK标志正是所需要的,它可以让文本的一部分具有链接的外观和行为。

封装结构和消息

要告诉RichEdit控件想要为文本的一部分分配特定的字符格式,需要向控件发送Windows消息EM_SETCHARFORMAT。如果对Win32结构的封装和SendMessage()的声明感兴趣,可以查看源代码。

使用扩展的RichTextBox

当使用扩展的RichTextBox时,将有几个新的方法可用:

public void InsertLink(string text); public void InsertLink(string text, int position);

这些方法可以在指定位置(或者如果没有指定,则在当前插入位置)插入链接。如果链接文本由于LinkClicked事件的结果而不适合(例如,如果有多个相同的链接文本,但想引用不同的超链接),还有两个额外的方法,可以指定一个额外的超链接字符串:

public void InsertLink(string text, string hyperlink); public void InsertLink(string text, string hyperlink, int position);

它们的行为类似于前两个方法,但在链接文本本身之后,会添加一个不可见的超链接字符串,用井号('#')分隔。例如,调用:

InsertLink("在线帮助", "myHelpFile.chm");

将在LinkClickedEventArgs中给出"在线帮助#myHelpFile.chm"。这样,就可以独立管理链接文本和超链接。

注意事项

有一个细节需要注意。默认情况下,标准RichTextBox的DetectUrls属性是设置的,所以输入的任何内容都会被自动重新格式化。扩展默认情况下将此属性关闭,因为它可能会干扰以编程方式添加的链接。当DetectUrls属性设置为true并且修改了链接旁边的文本时,链接格式将会丢失。当DetectUrls设置为false时,不会发生这种情况,所以建议将其关闭。

可能的扩展

就像添加了对CFE_LINK的支持一样,添加对其他格式化标志的支持也应该很容易(例如,CFE_SUBSCRIPT或CFE_SUPERSCRIPT)以添加新的格式化选项。必要的标志定义已经包含在源代码中,所以不必在平台SDK中查找它们了。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485