在线等!!!winform:RichTextBox 中的文字设置成超链接

MasterLRC 2004-07-26 05:14:57


我想把RichTextBox 中的某些文本显示成链接(单击可引发LinkClicked事件的那种)

不知道怎么做,请大侠们帮忙!

...全文
1742 34 打赏 收藏 转发到动态 举报
写回复
用AI写文章
34 条回复
切换为时间正序
请发表友善的回复…
发表回复
etany 2004-08-20
  • 打赏
  • 举报
回复
做了一点改进,但是写得很蠢,不要笑我呀,请继续改良罗

这个是全部代码

using System;
using System.ComponentModel;
using System.Collections;
using System.Diagnostics;
using System.Windows.Forms;
using System.Drawing;

namespace myRichTextBox
{
/// <summary>
/// myRichTextBox 的摘要说明。
/// </summary>
public class myRichTextBox : System.Windows.Forms.RichTextBox
{
private bool boolLinkStyle=false;
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.Container components = null;

public myRichTextBox(System.ComponentModel.IContainer container)
{
///
/// Windows.Forms 类撰写设计器支持所必需的
///
container.Add(this);
InitializeComponent();

//
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//
}

public myRichTextBox()
{
///
/// Windows.Forms 类撰写设计器支持所必需的
///
InitializeComponent();

//
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//
}

/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

/// <summary>
/// 是否使用{}来判断其值为超连接
/// </summary>
public bool LinkStyle
{
get{return boolLinkStyle;}
set{boolLinkStyle = value;}
}

#region 组件设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion

protected override void OnMouseMove(MouseEventArgs e)
{
bool CursorFlag = false;
if (boolLinkStyle)
{
int intCharIndex;
int intLine;
string strLine;
char ch;

ch = this.GetCharFromPosition(new Point(e.X,e.Y));
intCharIndex = this.GetCharIndexFromPosition(new Point(e.X,e.Y));
if (ch != '【' && ch != '】')
{
intLine = this.GetLineFromCharIndex(intCharIndex);
strLine = this.Text;
if ((strLine.Substring(0,intCharIndex).LastIndexOf("【")>=0 && strLine.IndexOf("】",intCharIndex)>=0) &&
((strLine.Substring(0,intCharIndex).LastIndexOf("【")>=0 && strLine.IndexOf("【",intCharIndex)<0) ||
(strLine.IndexOf("【",intCharIndex)>strLine.IndexOf("】",intCharIndex)) &&
(strLine.IndexOf("【",intCharIndex)>=0 && (strLine.IndexOf("【",intCharIndex)>strLine.IndexOf("】",intCharIndex)))))
CursorFlag = true;
}
}
if (CursorFlag)
this.Cursor = Cursors.Hand;
else
this.Cursor = Cursors.IBeam;
base.OnMouseMove (e);
}

protected override void OnMouseDown(MouseEventArgs e)
{
if (boolLinkStyle)
{
int intCharIndex;
int intLine;
int intStart;
int intEnd=0;
string strLine;
char ch;
ch = this.GetCharFromPosition(new Point(e.X,e.Y));
intCharIndex = this.GetCharIndexFromPosition(new Point(e.X,e.Y));
if (this.Cursor == Cursors.Hand)
{
if (ch != '【' && ch != '】')
{
intLine = this.GetLineFromCharIndex(intCharIndex);
strLine = this.Text;
intStart = strLine.Substring(0,intCharIndex).LastIndexOf("【");
intEnd = strLine.IndexOf("】",intCharIndex);
if ((intEnd >= 0) && (intStart >= 0))
this.OnLinkClicked(new LinkClickedEventArgs(strLine.Substring(intStart + 1,intEnd - intStart - 1)));
}
this.Select(intEnd,0);
}
}
base.OnMouseDown (e);
}

protected override void OnTextChanged(EventArgs e)
{
if (boolLinkStyle)
{
int intCharIndex;
int intLine;
int intCurIdx;
string strLine;
char ch;
Font newFont;
Font oldFont;
Color oldColor;

oldFont = this.Font;
newFont = new Font(oldFont,FontStyle.Underline);
oldColor = this.ForeColor;
intCurIdx = this.SelectionStart;
this.SelectAll();
this.SelectionFont=oldFont;
this.SelectionColor=oldColor;

for(int i=0;i<this.TextLength;i++)
{
ch = Convert.ToChar(this.Text.Substring(i,1));
intCharIndex = i;
if (ch != '【' && ch != '】')
{
intLine = this.GetLineFromCharIndex(intCharIndex);
strLine = this.Text;
if ((strLine.Substring(0,intCharIndex).LastIndexOf("【")>=0 && strLine.IndexOf("】",intCharIndex)>=0) &&
((strLine.Substring(0,intCharIndex).LastIndexOf("【")>=0 && strLine.IndexOf("【",intCharIndex)<0) ||
(strLine.IndexOf("【",intCharIndex)>strLine.IndexOf("】",intCharIndex)) &&
(strLine.IndexOf("【",intCharIndex)>=0 && (strLine.IndexOf("【",intCharIndex)>strLine.IndexOf("】",intCharIndex)))))
{
this.Select(intCharIndex,1);
this.SelectionColor = Color.Blue;
this.SelectionFont = newFont;
}
}
}
this.Select(intCurIdx,0);
}
base.OnTextChanged (e);
}
}
}
etany 2004-08-19
  • 打赏
  • 举报
回复
layershow(绿叶兄)是高手,令我茅塞顿开
我正在参照 layershow(绿叶兄) 的写OnTextChanged
我觉得写的很好,string判断应该没有问题
但是我改了一部分,到时候一起发上来

dsclub 2004-08-17
  • 打赏
  • 举报
回复


大家都说不能,干脆想想别的办法吧,何必非这样呢?
帮顶!

layershow 2004-08-17
  • 打赏
  • 举报
回复
嗯,应该还是可以实现的.
刚才试了一下,计算的我有点晕,懒的再弄了.

1.在项目里添加一个用户
继承RichTextBox, 改个名字叫MyRichTextBox吧
public class MyRichTextBox : System.Windows.Forms.RichTextBox
2.可以加一个属性方便控制
private bool boolLinkStyle;
public bool LinkStyle
{
get{return boolLinkStyle;}
set{boolLinkStyle = value;}
}
3.需要重载 OnMouseDown OnMouseMove OnTextChanged

OnMouseDown 判断是不是点击了需要的内容
this.OnLinkClicked(内容,单词);

OnMouseMove 判断鼠标是不是在单词上,出现手状

OnTextChanged 把要设成链接样式的内容 设成链接样式吧 蓝色,下划线,等等

protected override void OnMouseMove(MouseEventArgs e)
{
bool CursorFlag = false;
if (boolLinkStyle)
{
int intCharIndex;
int intCharLineIndex;
int intLine;
int intStart;
int intEnd;
string strLine;
char ch;
ch = this.GetCharFromPosition(new Point(e.X,e.Y));
intCharIndex = this.GetCharIndexFromPosition(new Point(e.X,e.Y));
if (ch != '{' && ch != '}')
{
intLine = this.GetLineFromCharIndex(intCharIndex);
strLine = this.Lines[intLine];
int j=0;
for(int i=0;i < intLine;i++)
{
j+= this.Lines[i].Length + 1;
}
intCharLineIndex = intCharIndex - j;
intStart = strLine.Substring(0,intCharLineIndex).LastIndexOf("{");
intEnd = strLine.IndexOf("}",intCharLineIndex);
if ((intEnd >= 0) && (intStart >= 0))
CursorFlag = true;
}
}
if (CursorFlag)
this.Cursor = Cursors.Hand;
else
this.Cursor = Cursors.IBeam;
base.OnMouseMove (e);
}
protected override void OnMouseDown(MouseEventArgs e)
{
if (boolLinkStyle)
{
int intCharIndex;
int intCharLineIndex;
int intLine;
int intStart;
int intEnd;
string strLine;
char ch;
ch = this.GetCharFromPosition(new Point(e.X,e.Y));
intCharIndex = this.GetCharIndexFromPosition(new Point(e.X,e.Y));
if (ch != '{' && ch != '}')
{
intLine = this.GetLineFromCharIndex(intCharIndex);
strLine = this.Lines[intLine];
int j=0;
for(int i=0;i < intLine;i++)
{
j+= this.Lines[i].Length + 1;
}
intCharLineIndex = intCharIndex - j;
intStart = strLine.Substring(0,intCharLineIndex).LastIndexOf("{");
intEnd = strLine.IndexOf("}",intCharLineIndex);
if ((intEnd >= 0) && (intStart >= 0))
this.OnLinkClicked(new LinkClickedEventArgs(strLine.Substring(intStart + 1,intEnd - intStart - 1)));
}
}
base.OnMouseDown (e);
}


OnTextChanged 没写 (判断应该设为链接样式的地方设置样式)

这样在窗口上用MyRichTextBox就行了,因为是继承的RichTextBox,用法都一样
把LinkStyle设成true

仍然是处理LinkClicked,可得到被点击的内容
private void myRichTextBox1_LinkClicked(object sender, System.Windows.Forms.LinkClickedEventArgs e)
{
MessageBox.Show("Process " + e.LinkText);
}

还是怀疑我对string的计算不太对,哪位有更好的办法可以改进一下
楼主花点心思,处理好了一劳永逸,大家都多出出主意
Crazyrebel 2004-08-16
  • 打赏
  • 举报
回复
就是,这个问题也捆饶了我好久
http://www.codeguru.com/Cpp/controls/richedit/article.php/c5371/

给个参考,我还没研究出来,哪位研究出来了,麻烦发扬一下共享精神
lookfeng 2004-08-14
  • 打赏
  • 举报
回复
可以的.
Class Test
{
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto, Pack=4)]
public class CHARFORMAT2
{
public int cbSize = Marshal.SizeOf(typeof(CHARFORMAT2));
public int dwMask;
public int dwEffects;
public int yHeight;
public int yOffset;
public int crTextColor;
public byte bCharSet;
public byte bPitchAndFamily;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)]
public string szFaceName;
public short wWeight;
public short sSpacing;
public int crBackColor;
public int lcid;
public int dwReserved;
public short sStyle;
public short wKerning;
public byte bUnderlineType;
public byte bAnimation;
public byte bRevAuthor;
public byte bReserved1;
}

[DllImportAttribute("user32", CharSet=CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, [In, Out, MarshalAs(UnmanagedType.LPStruct)] CHARFORMAT2 lParam);

public static void SetSelectAttr(RichTextBox rtb, bool link)
{
if (rtb == null)
{
throw new ArgumentNullException("rtb");
}
HARFORMAT2 charformat;
charformat = new NativeMethods.CHARFORMAT2();
charformat.dwMask = 0x00000020;//CFM_LINK
charformat.dwEffects = link ? 0x20/*CFE_LINK*/ : 0;
SendMessage(rtb.Handle, WinMessage.EM_SETCHARFORMAT, 1/*SCF_SELECTION*/, charformat);
}

}

//说明,先用RichTextBox.Select方法选中需要设为链接的文本,然后调用SetSelectAttr集可。
张海霖 2004-08-14
  • 打赏
  • 举报
回复
关键是没有人做过。
hxhbluestar 2004-08-14
  • 打赏
  • 举报
回复
呵呵,QQ都做出来了,肯定可以的
etany 2004-08-12
  • 打赏
  • 举报
回复
真的不行了吗?
MasterLRC 2004-07-29
  • 打赏
  • 举报
回复
to:
jinwanna(菜菜星)

没这个必要吧,你{}里的内容如果格式不对也没法跳转啊?如果格式对了,不用{}也可以啊,呵呵

------------------------------------------------------------------------------
我不是想跳转IE浏览.

我做的是一个词典程序,{}内的是查询结果的参考词汇

我是想通过 LinkClicked() 事件 读取用户点击的单词的内容,然后在词典里查这个词
winxieddd 2004-07-29
  • 打赏
  • 举报
回复
up
bestfuture 2004-07-28
  • 打赏
  • 举报
回复
不可以的吧!
jinwanna 2004-07-28
  • 打赏
  • 举报
回复
没这个必要吧,你{}里的内容如果格式不对也没法跳转啊?如果格式对了,不用{}也可以啊,呵呵
MasterLRC 2004-07-28
  • 打赏
  • 举报
回复
我想把非"http://www.xxx.xxx"格式的内容变成链接 如{}中的内容
jinwanna 2004-07-28
  • 打赏
  • 举报
回复
没什么必要啊,反正是http://www.xxx.xxx格式的都会自动变成超连接啊?

然后在事件里写上
private void yourTextbox_LinkedClick(object sender,System.Windows.Forms.linkClickEventArgs e)
{
System.Diagnostics.Process.Start(e.LinkText);
}

就可以了。
MasterLRC 2004-07-28
  • 打赏
  • 举报
回复
那大侠有什么好的类似的方法吗?
jinwanna 2004-07-28
  • 打赏
  • 举报
回复
能是绝对能的,不过肯定很麻烦,你要重写微软的richtextbox才可以,而且你不知道richtextbox的原代码,所以基本上等于不行。
MasterLRC 2004-07-28
  • 打赏
  • 举报
回复
个位老大,来呀!


如果真是不能实现,也请给个准信儿!谢谢!
MasterLRC 2004-07-27
  • 打赏
  • 举报
回复
RTF 格式是这样的:

public static string FmtRTF(string str)
{
string txt = str.Replace("{"," \\cf1\\ul ");
string txt1 = txt.Replace("}"," \\cf0\\ulnone ");
string rpKind1 = txt1.Replace("<"," \\cf2\\ul ");
string rpKind2 = rpKind1.Replace(">"," \\cf0\\ulnone ");
string txt2 = "{\\rtf1\\ansi{\\colortbl ;\\red0\\green0\\blue255;\\red0\\green255\\blue0;}\r\n";
txt2 += rpKind2;
txt2 += "\r\n}";
return txt2;
}

=============================================

这样做可以出现超链接的样式,但是不能出现可点击的链接小手

即然 URL 可以实现,我相信别的词也是可以实现的!
zhengjiang 2004-07-27
  • 打赏
  • 举报
回复
不行,不能这样做.........
加载更多回复(14)

110,561

社区成员

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

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

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