⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 frmlinecount.cs

📁 个人信息的源代码
💻 CS
字号:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace PublicUIComponent
{
	/// <summary>
	/// frmLineCount 的摘要说明。
	/// </summary>
	public class frmLineCount : System.Windows.Forms.Form
	{
		#region Windows 窗体设计器生成的代码

		private System.Windows.Forms.Label label1;
		private System.Windows.Forms.Label label2;
		private System.Windows.Forms.NumericUpDown updBeginNum;
		private System.Windows.Forms.NumericUpDown updSpace;
		private System.Windows.Forms.Button btnInsert;
		private System.Windows.Forms.Button btnClose;
		private System.Windows.Forms.CheckBox chkIsAll;
		private System.Windows.Forms.CheckBox chkHasStyle;
		/// <summary>
		/// 必需的设计器变量。
		/// </summary>
		private System.ComponentModel.Container components = null;

		public frmLineCount()
		{
			//
			// Windows 窗体设计器支持所必需的
			//
			InitializeComponent();

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

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

		/// <summary>
		/// 设计器支持所需的方法 - 不要使用代码编辑器修改
		/// 此方法的内容。
		/// </summary>
		private void InitializeComponent()
		{
			this.label1 = new System.Windows.Forms.Label();
			this.label2 = new System.Windows.Forms.Label();
			this.updBeginNum = new System.Windows.Forms.NumericUpDown();
			this.updSpace = new System.Windows.Forms.NumericUpDown();
			this.btnInsert = new System.Windows.Forms.Button();
			this.btnClose = new System.Windows.Forms.Button();
			this.chkIsAll = new System.Windows.Forms.CheckBox();
			this.chkHasStyle = new System.Windows.Forms.CheckBox();
			((System.ComponentModel.ISupportInitialize)(this.updBeginNum)).BeginInit();
			((System.ComponentModel.ISupportInitialize)(this.updSpace)).BeginInit();
			this.SuspendLayout();
			// 
			// label1
			// 
			this.label1.AutoSize = true;
			this.label1.Location = new System.Drawing.Point(16, 16);
			this.label1.Name = "label1";
			this.label1.Size = new System.Drawing.Size(66, 17);
			this.label1.TabIndex = 0;
			this.label1.Text = "起始行号:";
			// 
			// label2
			// 
			this.label2.AutoSize = true;
			this.label2.Location = new System.Drawing.Point(8, 48);
			this.label2.Name = "label2";
			this.label2.Size = new System.Drawing.Size(103, 17);
			this.label2.TabIndex = 1;
			this.label2.Text = "与正文间隔空格:";
			// 
			// updBeginNum
			// 
			this.updBeginNum.Location = new System.Drawing.Point(112, 16);
			this.updBeginNum.Name = "updBeginNum";
			this.updBeginNum.Size = new System.Drawing.Size(88, 21);
			this.updBeginNum.TabIndex = 2;
			this.updBeginNum.Value = new System.Decimal(new int[] {
																	  1,
																	  0,
																	  0,
																	  0});
			// 
			// updSpace
			// 
			this.updSpace.Location = new System.Drawing.Point(112, 48);
			this.updSpace.Name = "updSpace";
			this.updSpace.Size = new System.Drawing.Size(88, 21);
			this.updSpace.TabIndex = 3;
			this.updSpace.Value = new System.Decimal(new int[] {
																   2,
																   0,
																   0,
																   0});
			// 
			// btnInsert
			// 
			this.btnInsert.Location = new System.Drawing.Point(224, 16);
			this.btnInsert.Name = "btnInsert";
			this.btnInsert.Size = new System.Drawing.Size(120, 24);
			this.btnInsert.TabIndex = 4;
			this.btnInsert.Text = "插入";
			this.btnInsert.Click += new System.EventHandler(this.btnInsert_Click);
			// 
			// btnClose
			// 
			this.btnClose.Location = new System.Drawing.Point(224, 48);
			this.btnClose.Name = "btnClose";
			this.btnClose.Size = new System.Drawing.Size(120, 24);
			this.btnClose.TabIndex = 5;
			this.btnClose.Text = "关闭";
			this.btnClose.Click += new System.EventHandler(this.btnClose_Click);
			// 
			// chkIsAll
			// 
			this.chkIsAll.Location = new System.Drawing.Point(16, 80);
			this.chkIsAll.Name = "chkIsAll";
			this.chkIsAll.TabIndex = 6;
			this.chkIsAll.Text = "全文插入行号";
			// 
			// chkHasStyle
			// 
			this.chkHasStyle.Location = new System.Drawing.Point(152, 80);
			this.chkHasStyle.Name = "chkHasStyle";
			this.chkHasStyle.Size = new System.Drawing.Size(160, 24);
			this.chkHasStyle.TabIndex = 7;
			this.chkHasStyle.Text = "保留文本原有格式(慢)";
			// 
			// frmLineCount
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
			this.ClientSize = new System.Drawing.Size(368, 117);
			this.ControlBox = false;
			this.Controls.Add(this.chkHasStyle);
			this.Controls.Add(this.chkIsAll);
			this.Controls.Add(this.btnClose);
			this.Controls.Add(this.btnInsert);
			this.Controls.Add(this.updSpace);
			this.Controls.Add(this.updBeginNum);
			this.Controls.Add(this.label2);
			this.Controls.Add(this.label1);
			this.MaximizeBox = false;
			this.MinimizeBox = false;
			this.Name = "frmLineCount";
			this.Text = "插入行号";
			this.TopMost = true;
			((System.ComponentModel.ISupportInitialize)(this.updBeginNum)).EndInit();
			((System.ComponentModel.ISupportInitialize)(this.updSpace)).EndInit();
			this.ResumeLayout(false);

		}
		#endregion

		//从外界传入的RichTextBox控件
		public RichTextBox _rtf = null;

		/// <summary>
		/// 完成插入功能
		/// </summary>
		private void OnInsert()
		{
			//为正确插入行号,必须禁用WordWrap功能
			bool OldWordWrapStatus = this._rtf.WordWrap;
			if(OldWordWrapStatus)
				this._rtf.WordWrap = false;
			this.Cursor = Cursors.WaitCursor;

			if(this.chkHasStyle.Checked)
				this.InsertHasStyle();//有格式插入
			else
				this.InsertNoStyle();//无格式插入

			this.Cursor = Cursors.Default;

			//复原原先的WordWrap特性
			if(OldWordWrapStatus)
				this._rtf.WordWrap = true;
		}
		/// <summary>
		/// 获取选中部分的起始行,结束行和总行号
		/// </summary>
		/// <param name="startLine"></param>
		/// <param name="endLine"></param>
		/// <param name="totalLines"></param>
		private void GetSelectionLineInfo(ref int startLine, ref int endLine, ref int totalLines)
		{
			//获取开始和结束行数(相对全文档而言)
			startLine = this._rtf.GetLineFromCharIndex(this._rtf.SelectionStart);
			endLine = this._rtf.GetLineFromCharIndex(this._rtf.SelectionStart + this._rtf.SelectionLength - 1);

			//获取选中的总行数
			totalLines = endLine - startLine + 1;
		}
		/// <summary>
		/// 无格式插入,速度快
		/// </summary>
		private void InsertNoStyle()
		{
			if(this._rtf == null)
				return;

			if(this.chkIsAll.Checked)
			{
				this._rtf.SelectAll();//全文插入行号,则全选文档
			}
			else if(this._rtf.SelectionLength == 0)//如果是个空文档,则退出
			{
				return;
			}

			//获取选中部分的起始行号,结束行号和选中的总行数
			int startLine = 0, endLine = 0, totalLines = 0;
			this.GetSelectionLineInfo(ref startLine, ref endLine, ref totalLines);
			
			//获取最大行号的数字的位数
			int bits = (totalLines + this.updBeginNum.Value - 1).ToString().Length;

			//通过StringReader对象来修改字串
			System.IO.StringReader strReader = new System.IO.StringReader(this._rtf.SelectedText);//strReader中现在存入了所有所选的文字

			string str;			//存放从选中文本中读出的行
			string retStr = "";	//用于存放加了行号的字串
			
			//读入第一行
			str = strReader.ReadLine();
			int i = 0;
			while(!(str == null))
			{
				//给每行加上行号
				str = this.GetLineNumber((int)(this.updBeginNum.Value + i), bits) + this.Space((int)this.updSpace.Value) + str;
				i++;//行数加一
				//将修改过的字串存入retStr中。
				retStr += str + Environment.NewLine;
				//继续读下一行
				str = strReader.ReadLine();
			}

			//用加了行号的文字替换掉原先的内容
			this._rtf.SelectedText = retStr;
		}
		/// <summary>
		/// 保存原有文本的格式
		/// </summary>
		private void InsertHasStyle()
		{
			if(this._rtf == null)
				return;

			if(this.chkIsAll.Checked)
			{
				this._rtf.SelectAll();
				this.WindowState = FormWindowState.Minimized;//时间可能较长,最小化窗体先
			}
			else if(this._rtf.SelectionLength == 0)//如果是个空文档
			{
				return;
			}
			
			//开始行,结束行
			//获取开始和结束行数(相对全文档而言)
			int startLine = this._rtf.GetLineFromCharIndex(this._rtf.SelectionStart);
			int endLine = this._rtf.GetLineFromCharIndex(this._rtf.SelectionStart + this._rtf.SelectionLength - 1);
			
			//获取选中的总行数
			int totalLines = endLine - startLine + 1;

			//获取最大行号这一数字的位数
			int bits = (totalLines + this.updBeginNum.Value - 1).ToString().Length;
			//获取起始行第一个字符在整个文档中的索引
			int begin = this.GetLineStartCharIndex2(startLine);

			//给每行加上行号
			for(int i=0; i<totalLines; i++)
			{
				//防卫性编码,防止数组下标越界
				if(i >= this._rtf.Lines.GetLength(0))
					return;
				//将插入点光标移到每行开头
				this._rtf.SelectionStart = begin;
				this._rtf.SelectionLength = 0;
				this._rtf.SelectionColor = Color.Black;
				//在当前行插入行号
				this._rtf.SelectedText = this.GetLineNumber((int)(this.updBeginNum.Value + i), bits) + this.Space((int)this.updSpace.Value);
				//将插入点移到下一行的开头,之所以要加1,是因为每行最后都有一个未显示出来的换行符
				begin += this._rtf.Lines[startLine + i].Length + 1;
			}
			if(this.chkIsAll.Checked)
			{
				this.WindowState = FormWindowState.Normal;//复原窗体
				this.btnInsert.Focus();
			}
		}
		/// <summary>
		/// 返回指定数量的空格
		/// </summary>
		/// <param name="count"></param>
		/// <returns></returns>
		private string Space(int count)
		{
			string str = "";
			for(int i=0; i<count; i++)
			{
				str += " ";
			}
			return str;
		}
		/// <summary>
		/// 将第几行的数字转为以0打头的字串
		/// </summary>
		/// <param name="lineIndex">行号</param>
		/// <param name="bits">代表总行数的数字的位数</param>
		/// <returns></returns>
		private string GetLineNumber(int lineIndex, int bits)
		{
			//将行号转为字串
			string lineStr = lineIndex.ToString();

			//生成由bits个零组成的字串
			string strTemp  = "";
			for(int i=0; i<bits; i++)
			{
				strTemp += "0";
			}
			//'判断一下行号字串的长度
			if(lineStr.Length < bits)
			{
				//若行号位数较少,缺少的位上补0
				lineStr = strTemp.Substring(0, bits - lineStr.Length) + lineStr;
			}

			//向外界返回生成的行号字串
			return lineStr;
		}
		/// <summary>
		/// 获取每行第一个字符的索引
		/// </summary>
		/// <param name="lineIndex">整个文档中每行的行号,从0开始</param>
		/// <returns></returns>
		private int GetLineStartCharIndex1(int lineIndex)
		{
			//防卫性编码,防止数组下标越界
			if(lineIndex >= this._rtf.Lines.GetLength(0))
				return -1;

			//第一行第一个字符肯定是0
			if(lineIndex == 0)
				return 0;

			//以下计算行号大于0的行的首字符索引
			int charIndex = 0;
			for(int i=0; i<lineIndex; i++)
			{
				//每行最后要多加一个字符的长度
				charIndex += this._rtf.Lines[i].Length + 1;
			}
			return charIndex;
		}

		#region 第二种获取每行第一个字符索引的方法

		//通过调用Win32 API SendMessage来获取每行第一个字符的CharIndex值
		[DllImport("User32.dll")] 
		public static extern IntPtr SendMessage(IntPtr hWnd,uint msg, int wp,int lp); 

		//此常数用于SendMessage函数
		private const int EM_LINEINDEX = 0xBB;

		//第二种方法,速度快,直接调用Win32API获取每行的首字符索引
		private int GetLineStartCharIndex2(int lineIndex)
		{
			int charIndex = 0;
			//每行第一个字符的CharIndex值
			charIndex = SendMessage(this._rtf.Handle, EM_LINEINDEX, lineIndex, 0).ToInt32();

			return charIndex;
		}

		#endregion

		private void btnInsert_Click(object sender, System.EventArgs e)
		{
			this.OnInsert();
		}

		private void btnClose_Click(object sender, System.EventArgs e)
		{
			this.Hide();
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -