上图是我想实现的效果。
网上找的资料。利用SendMessage来给RichTextbox添加超链接,通过RichTextbox的LinkClicked事件去打开文件夹和文件。
目前的问题是:
单独实现一个打开文件夹或者打开文件都是没有问题的,但是如果想两个同时实现,第一个获取到的LinkText,,是被截取了后半部分的,导致我打开文件夹目录始终不对,但是第二个打开文件功能是正常的。由于小弟对这API实在不了解。请求大神不吝赐教!
代码下面贴出。
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
[DllImport("user32.dll ", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam,
[In, Out, MarshalAs(UnmanagedType.LPStruct)] CHARFORMAT2A lParam);
public const int CFE_LINK = 0x20;
public const int CFM_LINK = 0x20;
public const int EM_SETCHARFORMAT = 0x444;
public const int SCF_SELECTION = 1;
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
FileMsgAdd(@"打开所在文件夹", @"#" + Application.StartupPath + "\\ReceiveFile\\", richTextBox1);
this.richTextBox1.AppendText(" ");
FileMsgAdd(@"打开文件", @"#" + Application.StartupPath + "\\ReceiveFile\\22.txt", richTextBox1);
}
private void FileMsgAdd(string fileMsg, string path, RichTextBox box)
{
string insertRtf = @"{\rtf1" + TextToRtf(fileMsg) + @"\v" + TextToRtf(path) + @"\v0}";
int iniPos = box.SelectionStart;
box.SelectedRtf = insertRtf;
box.SelectionStart = iniPos;
box.SelectionLength = fileMsg.Length + path.Length;
CHARFORMAT2A vCharFormat2a = new CHARFORMAT2A();
vCharFormat2a.cbSize = Marshal.SizeOf(typeof(CHARFORMAT2A));
vCharFormat2a.dwMask = CFM_LINK;
vCharFormat2a.dwEffects = CFE_LINK;
SendMessage(box.Handle, EM_SETCHARFORMAT, SCF_SELECTION,
vCharFormat2a);
}
private string TextToRtf(string AText)
{
string vReturn = "";
foreach (char vChar in AText)
{
switch (vChar)
{
case '\\':
vReturn += @"\\";
break;
case '{':
vReturn += @"\{";
break;
case '}':
vReturn += @"\}";
break;
default:
if (vChar > (char)127)
vReturn += @"\u" + ((int)vChar).ToString() + "?";
else
vReturn += vChar;
break;
}
}
return vReturn;
}
private void richTextBox1_LinkClicked(object sender, LinkClickedEventArgs e)
{
System.Diagnostics.Process.Start(e.LinkText.Substring(e.LinkText.IndexOf('#') + 1));
}
}
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public class CHARFORMAT2A
{
public int cbSize;
public int dwMask;
public int dwEffects;
public int yHeight;
public int yOffset;
public int crTextColor;
public byte bCharSet;
public byte bPitchAndFamily;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)]
public byte[] szFaceName = new byte[0x20];
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;
}