MyRichTextBox
using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Windows; using System.Windows.Forms; class MyRichTextBox : RichTextBox { public bool mouseDown; public int selCurrent; public int selOrigin; public int selStart; public int selEnd; public int selTrough; public int selPeak; private int WM_SETFOCUS = 0x0007; private UInt32 EM_SETSEL = 0x00B1; [DllImport("user32.dll", CharSet = CharSet.Auto)] static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, int wParam, int lParam); public MyRichTextBox() { this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.rtb_MouseDown); this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.rtb_MouseMove); this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.rtb_MouseUp); this.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.rtb_KeyPress); } protected override void WndProc(ref Message m) { // Let everything through except for the WM_SETFOCUS message if (m.Msg != WM_SETFOCUS) base.WndProc(ref m); } public void rtb_MouseDown(object sender, MouseEventArgs e) { mouseDown = true; // reset all the selection stuff selOrigin = selStart = selEnd = selPeak = selTrough = GetCharIndexFromPosition(e.Location); highlightSelection(1, Text.Length - 1, false); } public void rtb_MouseUp(object sender, MouseEventArgs e) { mouseDown = false; } public void rtb_MouseMove(object sender, MouseEventArgs e) { if (mouseDown) { selCurrent = GetCharIndexFromPosition(e.Location); // First determine the selection direction // Note the +1 when selecting backwards because GetCharIndexFromPosition // uses the left edge of the nearest character if (selCurrent < selOrigin + 1) { // If the current selection is smaller than the previous selection, // recolour the now unselected stuff back to the default colour if (selCurrent > selTrough) { highlightSelection(selTrough, selCurrent, false); } selTrough = selCurrent; selEnd = selOrigin + 1; selStart = selCurrent; } else { // If the current selection is smaller than the previous selection, // recolour the now unselected stuff back to the default colour if (selCurrent < selPeak) { highlightSelection(selPeak, selCurrent, false); } selPeak = selCurrent; selStart = selOrigin; selEnd = selCurrent; } highlightSelection(selStart, selEnd); } } private void highlightSelection(int start, int end, bool highlight = true) { selectText(start, end); SelectionBackColor = highlight ? System.Drawing.Color.FromArgb(0,120,215) : this.BackColor; SelectionColor = highlight ? Color.White : this.ForeColor; } private void selectText(int start, int end) { SendMessage(Handle, EM_SETSEL, start, end); } private void InitializeComponent() { this.SuspendLayout(); this.ResumeLayout(false); } private void rtb_KeyPress(object sender, KeyPressEventArgs e) { if (e.KeyChar == 0x03) // ctrl + C { Clipboard.SetText(this.Text.Substring(this.selStart, this.selEnd - this.selStart)); } } }
锁屏,滚动
private delegate void AddTalkMessageDelegate(string message); /// <summary> /// 在聊天对话框(txt_Message)中追加聊天信息 /// </summary> /// <param name="message"></param> private void AddTalkMessage(string message) { if (myRichTextBox1.InvokeRequired) { AddTalkMessageDelegate d = new AddTalkMessageDelegate(AddTalkMessage); myRichTextBox1.Invoke(d, new object[] { message }); } else { if (runflag) { //设置光标的位置到文本尾 myRichTextBox1.Select(myRichTextBox1.TextLength, 0); //滚动到控件光标处 myRichTextBox1.ScrollToCaret(); } myRichTextBox1.AppendText(message); } } bool runflag = true; private void button3_Click(object sender, EventArgs e) { runflag = false; } private void button2_Click(object sender, EventArgs e) { runflag = true; }
参考资料:https://www.codeproject.com/Articles/361161/How-to-Csharp-Prevent-RichTextBox-from-auto-scroll
我放弃了,改为内部调用网页的形式展现