winform怎么从richtextbox中获取当前的所有超链接

nkhuangyanping 2015-08-26 10:59:53
winform怎么从richtextbox中获取当前的所有超链接?
我用以下代码实现的超链接,但是现在有需求可能需要时时动态的更改超链接显示的内容,
比如显示“网页”,链接为"baidu.com",可能在某些情况下需要改为显示为"百度",链接为“baidu.com”



public partial class RichTextBoxEx : RichTextBox
{
#region Interop-Defines

[StructLayout(LayoutKind.Sequential)]
private struct CHARFORMAT2_STRUCT
{
public UInt32 cbSize;
public UInt32 dwMask;
public UInt32 dwEffects;
public Int32 yHeight;
public Int32 yOffset;
public Int32 crTextColor;
public byte bCharSet;
public byte bPitchAndFamily;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public char[] szFaceName;
public UInt16 wWeight;
public UInt16 sSpacing;
public int crBackColor; // Color.ToArgb() -> int
public int lcid;
public int dwReserved;
public Int16 sStyle;
public Int16 wKerning;
public byte bUnderlineType;
public byte bAnimation;
public byte bRevAuthor;
public byte bReserved1;
}

[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);

private const int WM_USER = 0x0400;
private const int EM_GETCHARFORMAT = WM_USER + 58;
private const int EM_SETCHARFORMAT = WM_USER + 68;

private const int SCF_SELECTION = 0x0001;
private const int SCF_WORD = 0x0002;
private const int SCF_ALL = 0x0004;

#region CHARFORMAT2 Flags
private const UInt32 CFE_BOLD = 0x0001;
private const UInt32 CFE_ITALIC = 0x0002;
private const UInt32 CFE_UNDERLINE = 0x0004;
private const UInt32 CFE_STRIKEOUT = 0x0008;
private const UInt32 CFE_PROTECTED = 0x0010;
private const UInt32 CFE_LINK = 0x0020;
private const UInt32 CFE_AUTOCOLOR = 0x40000000;
private const UInt32 CFE_SUBSCRIPT = 0x00010000; /* Superscript and subscript are */
private const UInt32 CFE_SUPERSCRIPT = 0x00020000; /* mutually exclusive */

private const int CFM_SMALLCAPS = 0x0040; /* (*) */
private const int CFM_ALLCAPS = 0x0080; /* Displayed by 3.0 */
private const int CFM_HIDDEN = 0x0100; /* Hidden by 3.0 */
private const int CFM_OUTLINE = 0x0200; /* (*) */
private const int CFM_SHADOW = 0x0400; /* (*) */
private const int CFM_EMBOSS = 0x0800; /* (*) */
private const int CFM_IMPRINT = 0x1000; /* (*) */
private const int CFM_DISABLED = 0x2000;
private const int CFM_REVISED = 0x4000;

private const int CFM_BACKCOLOR = 0x04000000;
private const int CFM_LCID = 0x02000000;
private const int CFM_UNDERLINETYPE = 0x00800000; /* Many displayed by 3.0 */
private const int CFM_WEIGHT = 0x00400000;
private const int CFM_SPACING = 0x00200000; /* Displayed by 3.0 */
private const int CFM_KERNING = 0x00100000; /* (*) */
private const int CFM_STYLE = 0x00080000; /* (*) */
private const int CFM_ANIMATION = 0x00040000; /* (*) */
private const int CFM_REVAUTHOR = 0x00008000;


private const UInt32 CFM_BOLD = 0x00000001;
private const UInt32 CFM_ITALIC = 0x00000002;
private const UInt32 CFM_UNDERLINE = 0x00000004;
private const UInt32 CFM_STRIKEOUT = 0x00000008;
private const UInt32 CFM_PROTECTED = 0x00000010;
private const UInt32 CFM_LINK = 0x00000020;
private const UInt32 CFM_SIZE = 0x80000000;
private const UInt32 CFM_COLOR = 0x40000000;
private const UInt32 CFM_FACE = 0x20000000;
private const UInt32 CFM_OFFSET = 0x10000000;
private const UInt32 CFM_CHARSET = 0x08000000;
private const UInt32 CFM_SUBSCRIPT = CFE_SUBSCRIPT | CFE_SUPERSCRIPT;
private const UInt32 CFM_SUPERSCRIPT = CFM_SUBSCRIPT;

private const byte CFU_UNDERLINENONE = 0x00000000;
private const byte CFU_UNDERLINE = 0x00000001;
private const byte CFU_UNDERLINEWORD = 0x00000002; /* (*) displayed as ordinary underline */
private const byte CFU_UNDERLINEDOUBLE = 0x00000003; /* (*) displayed as ordinary underline */
private const byte CFU_UNDERLINEDOTTED = 0x00000004;
private const byte CFU_UNDERLINEDASH = 0x00000005;
private const byte CFU_UNDERLINEDASHDOT = 0x00000006;
private const byte CFU_UNDERLINEDASHDOTDOT = 0x00000007;
private const byte CFU_UNDERLINEWAVE = 0x00000008;
private const byte CFU_UNDERLINETHICK = 0x00000009;
private const byte CFU_UNDERLINEHAIRLINE = 0x0000000A; /* (*) displayed as ordinary underline */

#endregion

#endregion

public RichTextBoxEx()
{
this.DetectUrls = false;
this.LinkClicked += new LinkClickedEventHandler(RichTextBoxEx_LinkClicked);
}

void RichTextBoxEx_LinkClicked(object sender, LinkClickedEventArgs e)
{
Console.WriteLine(e.LinkText);
}

[DefaultValue(false)]
public new bool DetectUrls
{
get { return base.DetectUrls; }
set { base.DetectUrls = value; }
}
public void InsertLink(string text)
{
InsertLink(text, this.SelectionStart);
}

public void InsertLink(string text, int position)
{
if (position < 0 || position > this.Text.Length)
throw new ArgumentOutOfRangeException("position");

this.SelectionStart = position;
this.SelectedText = text;
this.Select(position, text.Length);
this.SetSelectionLink(true);
this.Select(position + text.Length, 0);
}

public void InsertLink(string text, string hyperlink)
{
InsertLink(text, hyperlink, this.SelectionStart);
}

public void InsertLink(string text, string hyperlink, int position)
{
if (position < 0 || position > this.Text.Length)
throw new ArgumentOutOfRangeException("position");
hyperlink = position + "|" + hyperlink;
this.SelectionStart = position;
this.SelectedRtf = @"{\rtf1\ansicpg936 " + text + @"\v #"+hyperlink + @"\v0}";
this.Select(position, text.Length + hyperlink.Length + 1);
this.SetSelectionLink(true);
this.Select(position + text.Length + hyperlink.Length + 1, 0);
}

public void SetSelectionLink(bool link)
{
SetSelectionStyle(CFM_LINK, link ? CFE_LINK : 0);
}

public int GetSelectionLink()
{
return GetSelectionStyle(CFM_LINK, CFE_LINK);
}


private void SetSelectionStyle(UInt32 mask, UInt32 effect)
{
CHARFORMAT2_STRUCT cf = new CHARFORMAT2_STRUCT();
cf.cbSize = (UInt32)Marshal.SizeOf(cf);
cf.dwMask = mask;
cf.dwEffects = effect;

IntPtr wpar = new IntPtr(SCF_SELECTION);
IntPtr lpar = Marshal.AllocCoTaskMem(Marshal.SizeOf(cf));
Marshal.StructureToPtr(cf, lpar, false);

IntPtr res = SendMessage(Handle, EM_SETCHARFORMAT, wpar, lpar);

Marshal.FreeCoTaskMem(lpar);
}

private int GetSelectionStyle(UInt32 mask, UInt32 effect)
{
CHARFORMAT2_STRUCT cf = new CHARFORMAT2_STRUCT();
cf.cbSize = (UInt32)Marshal.SizeOf(cf);
cf.szFaceName = new char[32];

IntPtr wpar = new IntPtr(SCF_SELECTION);
IntPtr lpar = Marshal.AllocCoTaskMem(Marshal.SizeOf(cf));
Marshal.StructureToPtr(cf, lpar, false);

IntPtr res = SendMessage(Handle, EM_GETCHARFORMAT, wpar, lpar);

cf = (CHARFORMAT2_STRUCT)Marshal.PtrToStructure(lpar, typeof(CHARFORMAT2_STRUCT));

int state;
// dwMask holds the information which properties are consistent throughout the selection:
if ((cf.dwMask & mask) == mask)
{
if ((cf.dwEffects & effect) == effect)
state = 1;
else
state = 0;
}
else
{
state = -1;
}

Marshal.FreeCoTaskMem(lpar);
return state;
}
}


...全文
154 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
nkhuangyanping 2015-08-26
  • 打赏
  • 举报
回复
不能沉啊,再顶起来。
nkhuangyanping 2015-08-26
  • 打赏
  • 举报
回复
引用 3 楼 shingoscar 的回复:
为什么不在插入链接的时候转换?
是这样的,我的需求是先插入链接,此后需要点击链接,点击后有一些逻辑,改变链接的显示名称,这个名称不固定,谁也不知道,需要用户来决定。
Poopaye 2015-08-26
  • 打赏
  • 举报
回复
为什么不在插入链接的时候转换?
nkhuangyanping 2015-08-26
  • 打赏
  • 举报
回复
引用 1 楼 starfd 的回复:
你这个好复杂……正则吧!
正则不好获取啊。
  • 打赏
  • 举报
回复
你这个好复杂……正则吧!
Poopaye 2015-08-26
  • 打赏
  • 举报
回复
引用 4 楼 nkhuangyanping 的回复:
[quote=引用 3 楼 shingoscar 的回复:] 为什么不在插入链接的时候转换?
是这样的,我的需求是先插入链接,此后需要点击链接,点击后有一些逻辑,改变链接的显示名称,这个名称不固定,谁也不知道,需要用户来决定。[/quote] 总之插入由你来管,所以你可以把所有超链接的位置都记下来不是吗?
nkhuangyanping 2015-08-26
  • 打赏
  • 举报
回复
引用 7 楼 crystal_lz 的回复:

Regex.Matches(strText,@"https?:/+[a-zA-Z0-9_\-.]*")
上面的少了一个点
再说明一点,我点击链接可能显示名称和链接都可能更改。
crystal_lz 2015-08-26
  • 打赏
  • 举报
回复

Regex.Matches(strText,@"https?:/+[a-zA-Z0-9_\-.]*")
上面的少了一个点
crystal_lz 2015-08-26
  • 打赏
  • 举报
回复
不怎么好处理啊 如为本内容如下:

这是一个连接http://www.baidu.com 这又是一个连接www.baidu.com
继续一个连接baidu.com 又出现一个连接http://baidu.com
但是这个不是一个连接.com只是碰巧出现了.com而已
在比如www.中文域名.com怎么破
或者我在这里描述一下域名的后最有.com.net.cn.gov.....等出现了很多域名的后缀却不是域名
再比如 恰好出现了http://开头的文本 就不如这一行 怎么破
。。。。
我的话是不是有点多。。。。 要不 直接

Regex.Matches(strText,@"https?:/+[a-zA-Z0-9_\-]*")

110,525

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

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