------ #### ryControls V3.0.2109.0301 - *.[改进]RichTextBox2控件现在可以自由选择字符区间。 - *.[改进]RichTextBox2控件改用Courier New等宽字体。
308 lines
11 KiB
C#
308 lines
11 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Diagnostics;
|
|
using System.Drawing;
|
|
using System.Linq;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
using System.Windows.Forms;
|
|
|
|
namespace ryControls.Controls
|
|
{
|
|
/// <summary>
|
|
/// 增强富文本控件
|
|
/// </summary>
|
|
public partial class RichTextBox2 : RichTextBox
|
|
{
|
|
/// <summary>
|
|
/// 开始更新
|
|
/// </summary>
|
|
public void BeginUpdate()
|
|
{
|
|
SendMessage(this.Handle, WM_SETREDRAW, (IntPtr)0, IntPtr.Zero);
|
|
}
|
|
/// <summary>
|
|
/// 结束更新
|
|
/// </summary>
|
|
public void EndUpdate()
|
|
{
|
|
SendMessage(this.Handle, WM_SETREDRAW, (IntPtr)1, IntPtr.Zero);
|
|
this.Invalidate();
|
|
}
|
|
[DllImport("user32.dll")]
|
|
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
|
|
private const int WM_SETREDRAW = 0x0b;
|
|
[DllImport("user32.dll")]
|
|
private static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, ref Rectangle lParam);//
|
|
private const int EM_SETRECT = 0x00b3;
|
|
/// <summary>
|
|
/// RichTextBox
|
|
/// </summary>
|
|
public RichTextBox2():base()
|
|
{
|
|
//this.SetStyle(ControlStyles.DoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true); this.UpdateStyles();
|
|
InitializeComponent();
|
|
this.DetectUrls = false;
|
|
this.AutoWordSelection = false;
|
|
this.Multiline = true;
|
|
this.WordWrap = false;
|
|
this.Font = new Font("Courier New",10, FontStyle.Regular);
|
|
//this.contextMenuStripRichText1.Opening += ContextMenuStripRichText1_Opening;
|
|
}
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="e"></param>
|
|
protected override void OnHandleCreated(EventArgs e)
|
|
{
|
|
base.OnHandleCreated(e);
|
|
if (this.DesignMode) return;
|
|
|
|
// The following operations should not recreate the handle
|
|
// Workaround for .NET bug:
|
|
// AutoWordSelection remembers the value of the property
|
|
// correctly, but incorrectly sends a message as follows:
|
|
// SendMessage(EM_SETOPTIONS, value ? ECOOP_OR : ECOOP_XOR,
|
|
// ECO_AUTOWORDSELECTION);
|
|
// So, when setting AutoWordSelection to false, the control
|
|
// style is toggled instead of turned off (the internal value
|
|
// is updated correctly)
|
|
bool bAutoWord = this.AutoWordSelection; // Internal, no message
|
|
if (!bAutoWord) // Only 'false' needs workaround
|
|
{
|
|
// Ensure control style is on (currently we're in a
|
|
// random state, as it could be set to false multiple
|
|
// times; e.g. base.OnHandleCreated does the following:
|
|
// 'this.AutoWordSelection = this.AutoWordSelection;')
|
|
this.AutoWordSelection = true;
|
|
|
|
// Toggle control style to false
|
|
this.AutoWordSelection = false;
|
|
Rectangle rect2 = new Rectangle(this.ClientRectangle.Left + 7, this.ClientRectangle.Top + 5, this.ClientRectangle.Width - 14, this.ClientRectangle.Height - 10);
|
|
SendMessage(this.Handle, EM_SETRECT, IntPtr.Zero, ref rect2);
|
|
}
|
|
}
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="e"></param>
|
|
protected override void OnHScroll(EventArgs e)
|
|
{
|
|
base.Invalidate();
|
|
base.OnHScroll(e);
|
|
}
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="e"></param>
|
|
protected override void OnVScroll(EventArgs e)
|
|
{
|
|
base.Invalidate();
|
|
base.OnVScroll(e);
|
|
}
|
|
/// <summary>
|
|
/// 在自带菜单弹出前激发
|
|
/// </summary>
|
|
[Description("在自带菜单弹出前激发")]
|
|
public event CancelEventHandler OnMenuOpening;
|
|
private void ContextMenuStripRichText1_Opening(object sender, CancelEventArgs e)
|
|
{
|
|
OnMenuOpening?.Invoke(sender,e);
|
|
}
|
|
/// <summary>
|
|
/// 根据标签获得菜单项
|
|
/// </summary>
|
|
/// <param name="tag"></param>
|
|
/// <returns></returns>
|
|
public ToolStripItem GetMenuItem(string tag)
|
|
{
|
|
for (int i = 0; i < contextMenuStripRichText1.Items.Count; i++)
|
|
{
|
|
var item = contextMenuStripRichText1.Items[i];
|
|
if (item.Tag == null) { continue; }
|
|
if(tag== item.Tag.ToString())
|
|
{
|
|
return item;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
/// <summary>
|
|
/// 只允许输入文本(只对设置之后的人工输入有效)
|
|
/// </summary>
|
|
[Description("只允许输入文本(只对设置之后的人工输入有效)")]
|
|
public bool OnlyInputText { get; set; } = false;
|
|
/// <summary>
|
|
/// 按下按键
|
|
/// </summary>
|
|
/// <param name="e"></param>
|
|
protected override void OnKeyDown(KeyEventArgs e)
|
|
{
|
|
if (OnlyInputText && e.Control && e.KeyCode == Keys.V)
|
|
{
|
|
e.SuppressKeyPress = true;
|
|
this.Paste(DataFormats.GetFormat(DataFormats.Text));
|
|
return;
|
|
}
|
|
base.OnKeyDown(e);
|
|
}
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="e"></param>
|
|
protected override void OnLostFocus(EventArgs e)
|
|
{
|
|
base.Invalidate();
|
|
base.OnLostFocus(e);
|
|
}
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="e"></param>
|
|
protected override void OnEnter(EventArgs e)
|
|
{
|
|
if (base.Text.Length == 0)
|
|
{
|
|
base.Invalidate();
|
|
}
|
|
base.OnEnter(e);
|
|
}
|
|
//private bool _Selecting = false;
|
|
//private int _StartPosition = 0;
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="e"></param>
|
|
protected override void OnMouseMove(System.Windows.Forms.MouseEventArgs e)
|
|
{
|
|
//if (_Selecting)
|
|
//{
|
|
// int charPosition = base.GetCharIndexFromPosition(new System.Drawing.Point(e.X, e.Y));
|
|
// int length = 0;
|
|
// if (charPosition >= _StartPosition)
|
|
// {
|
|
// length = charPosition - _StartPosition + 1;
|
|
// this.Select(_StartPosition, length);
|
|
// }
|
|
// else
|
|
// {
|
|
// length = _StartPosition - charPosition;
|
|
// this.Select(charPosition, length);
|
|
// }
|
|
//}
|
|
|
|
base.OnMouseMove(e);
|
|
}
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="e"></param>
|
|
protected override void OnMouseLeave(EventArgs e)
|
|
{
|
|
if (base.Text.Length == 0)
|
|
{
|
|
base.Invalidate();
|
|
}
|
|
base.OnMouseLeave(e);
|
|
}
|
|
/// <summary>
|
|
/// 鼠标按下
|
|
/// </summary>
|
|
/// <param name="e"></param>
|
|
protected override void OnMouseDown(MouseEventArgs e)
|
|
{
|
|
//this._Selecting = true;
|
|
//_StartPosition = base.GetCharIndexFromPosition(new System.Drawing.Point(e.X, e.Y));
|
|
if (e.Button==MouseButtons.Right && this.ContextMenuStrip==null)
|
|
{
|
|
contextMenuStripRichText1.Show(this, e.Location);
|
|
}
|
|
base.OnMouseDown(e);
|
|
}
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="e"></param>
|
|
protected override void OnMouseUp(System.Windows.Forms.MouseEventArgs e)
|
|
{
|
|
//this._Selecting = false;
|
|
base.OnMouseUp(e);
|
|
}
|
|
private const UInt32 WM_USER = 0x0400;
|
|
private const UInt32 EM_SETBKGNDCOLOR = (WM_USER + 67);
|
|
private const UInt32 WM_KILLFOCUS = 0x0008;
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="m"></param>
|
|
protected override void WndProc(ref Message m)
|
|
{
|
|
base.WndProc(ref m);
|
|
if (m.Msg == 0xf || m.Msg == 0x133)
|
|
{
|
|
if (this.BorderStyle == BorderStyle.None)
|
|
{
|
|
System.Drawing.Pen pen = new Pen(SkinHelp.DefalutBorderColor, 1);
|
|
Graphics g = Graphics.FromHwnd(m.HWnd);
|
|
g.DrawRectangle(pen, 0, 0, this.Width - 1, this.Height - 1);
|
|
pen.Dispose();
|
|
//m.Result = IntPtr.Zero;
|
|
}
|
|
if(!base.Focused && this.Text.Length==0)
|
|
{
|
|
Graphics g = Graphics.FromHwnd(m.HWnd);
|
|
Brush brush = new SolidBrush(Color.FromArgb(175, 185, 200));
|
|
g.DrawString(EmptyText,Font, brush, 3, 7);
|
|
brush.Dispose();
|
|
}
|
|
//返回结果
|
|
m.Result = IntPtr.Zero;
|
|
}
|
|
if (m.Msg == EM_SETBKGNDCOLOR) //color disabled background
|
|
{
|
|
Invalidate();
|
|
}
|
|
|
|
if (m.Msg == WM_KILLFOCUS) //set border back to normal on lost focus
|
|
{
|
|
Invalidate();
|
|
}
|
|
|
|
}
|
|
/// <summary>
|
|
/// 当文本框为空时,显示的内容。
|
|
/// </summary>
|
|
[Description("当文本框为空时,显示的内容。")]
|
|
public string EmptyText
|
|
{
|
|
get { return _EmptyText; }
|
|
set
|
|
{
|
|
_EmptyText = value;
|
|
base.Invalidate();
|
|
}
|
|
}
|
|
private string _EmptyText = "";
|
|
/// <summary>
|
|
/// 添加菜单分隔线
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public ToolStripSeparator AddSeparatorMenu()
|
|
{
|
|
return contextMenuStripRichText1.AddSeparatorMenu();
|
|
}
|
|
/// <summary>
|
|
/// 添加菜单
|
|
/// </summary>
|
|
/// <param name="name"></param>
|
|
/// <param name="tag"></param>
|
|
/// <returns></returns>
|
|
public ToolStripMenuItem AddMenu(string name, string tag)
|
|
{
|
|
return contextMenuStripRichText1.AddMenu(name, tag);
|
|
}
|
|
}
|
|
}
|