程序下载地址:http://download.csdn.net/source/1805161 核心代码: namespace TXTReader { public partial class TXTReader : UserControl { #region 内部变量 private Encoding l_enc; private Color l_border_color; private Font l_Font; private string l_fp = ""; private int l_margin = 0; private int l_border = 0; private int l_location = 0; private int l_Maximum = 0; private float l_progress = 0; private int l_LinesPerScreen = 0; private bool l_ShowProgress = false; private int AllLines = 0; private int AllWords = 0; private int curIndex = 0; private int startLine = 0; private bool l_stoppaint = false; private long FileSize = 0; private float LineHeight; private int TextAreaWidth; private int TextAreaHeight; private int DisplayAreaHeight; private ArrayList TextAll = new ArrayList(); private ArrayList TextHeight = new ArrayList(); private ArrayList TextLines = new ArrayList(); private bool IsBusy = false; private bool IsError = false; private string ErrorMsg = ""; private System.Windows.Forms.Timer tm = new System.Windows.Forms.Timer(); private long StartTime = 0; #endregion #region 事件定义 public delegate void PositionChangedEventHandler(object sender, PositionChangedEventArgs e); public event PositionChangedEventHandler PositionChanged; public class PositionChangedEventArgs : EventArgs { private int position; public PositionChangedEventArgs(int p) { position = p; } public int Position { get { return position; } } } protected virtual void OnPositionChanged(PositionChangedEventArgs e) { if (PositionChanged != null) { PositionChanged(this, e); } } #endregion #region 构造函数 public TXTReader() { InitializeComponent(); SetStyle(ControlStyles.AllPaintingInWmPaint, true); SetStyle(ControlStyles.CacheText, true); SetStyle(ControlStyles.OptimizedDoubleBuffer, true); SetStyle(ControlStyles.ResizeRedraw, true); SetStyle(ControlStyles.UserPaint, true); l_border_color = Color.DarkGray; l_enc = Encoding.GetEncoding(936); l_Font = new Font("宋体", 10); } #endregion #region 属性定义 /// <summary> /// 当前状态 /// </summary> public bool Busying { get { return IsBusy; } } /// <summary> /// 文件路径 /// </summary> public string FileName { get { return l_fp; } set { l_fp = value; } } /// <summary> /// 字体 /// </summary> public override Font Font { get { return l_Font; } set { l_Font = value; getTextHeight(); this.Invalidate(); } } /// <summary> /// 编码 /// </summary> public Encoding Encoding { get { return l_enc; } set { l_enc = value; if (l_fp.Length > 0) { Open(curIndex); } } } /// <summary> /// 边框线色 /// </summary> public Color BorderColor { get { return l_border_color; } set { l_border_color = value; this.Invalidate(); } } public int BorderWidth { get { return l_border; } set { l_border = value; getTextHeight(); this.Invalidate(); } } /// <summary> /// 边距 /// </summary> public int MarginWidth { get { return l_margin; } set { l_margin = value; getTextHeight(); this.Invalidate(); } } public int Maximum { get { return l_Maximum; } //set { } } public int LinesPerScreen { get { return l_LinesPerScreen; } } /// <summary> /// 状态 /// </summary> public bool StopPainting { get { return l_stoppaint; } set { l_stoppaint = value; } } /// <summary> /// 状态 /// </summary> public bool ShowProgress { get { return l_ShowProgress; } set { l_ShowProgress = value; } } /// <summary> /// 书签 /// </summary> public int BookMark { get { return curIndex; } } /// <summary> /// 当前文件总字数 /// </summary> public int WordsCount { get { return AllWords; } } /// <summary> /// 当前文件的总行数 /// </summary> public int LineCount { get { return AllLines; } } /// <summary> /// 阅读位置 /// </summary> public int Position { get { return l_location; } set { int len = 0; int len_all = 0; int newvalue = value; try { if (LineHeight.Equals(0)) return; if (newvalue <= 0) newvalue = 1; if (newvalue > l_Maximum) newvalue = l_Maximum; if (l_location == newvalue) return; l_location = newvalue; for (int i = 0; i < TextLines.Count; i++) { len = len_all; len_all += Convert.ToInt32(TextLines[i]); if (len_all >= l_location) { curIndex = i; startLine = l_location - len - 1; break; } } this.Invalidate(); OnPositionChanged(new PositionChangedEventArgs(l_location)); } catch (Exception ex) { setError(ex.Message); } } } #endregion 属性定义 #region 函数定义 /// <summary> /// 错误定义 /// </summary> /// <param name="emsg"></param> public void setError(string emsg) { IsError = true; ErrorMsg = emsg; this.Invalidate(); } /// <summary> /// 打开 /// </summary> public void Open() { Open(0); } /// <summary> /// 打开文件 /// </summary> /// <param name="BookMark">书签位置</param> public void Open(int BookMark) { try { if (l_fp.Length == 0) return; if (l_stoppaint) return; if (IsBusy) return; IsError = false; IsBusy = true; this.Invalidate(); Thread t = new Thread(new ThreadStart(ReadFile)); t.Start(); while (t.IsAlive) { Application.DoEvents(); Thread.Sleep(100); }; getTextHeight(); int l_loc = 1; for (int i = 0; i < BookMark && i < TextAll.Count; i++) { l_loc += Convert.ToInt32(TextLines[i]); } Position = l_loc; this.Invalidate(); } catch (Exception ex) { setError(ex.Message); } finally { IsBusy = false; } } /// <summary> /// 读入文件内容 /// </summary> private void ReadFile() { try { l_stoppaint = true; int l_CurIndex = 0; string l_curLine = ""; StreamReader sr = new StreamReader(l_fp, l_enc); FileSize = new FileInfo(l_fp).Length; TextAll.Clear(); while (!sr.EndOfStream) { l_curLine = sr.ReadLine(); l_CurIndex = TextAll.Add(l_curLine); } sr.Close(); } catch (Exception ex) { setError(ex.Message); } finally { l_stoppaint = false; } } /// <summary> /// 获取文本高度 /// </summary> private void getTextHeight() { float CurHeight = 0; float AllHeight = 0; int CurLines = 0; int CurWords = 0; int ErrLine = 0; Graphics g = this.CreateGraphics(); TextAreaWidth = this.Width - 2 * l_margin - 1; DisplayAreaHeight = this.Height - 2 * l_margin - 1; try { int len = TextAll.Count; if (len <= 0) return; LineHeight = l_Font.GetHeight(g); AllLines = 0; AllWords = 0; TextAreaHeight = 0; Size DisplayArea = new Size(TextAreaWidth, 655350); TextHeight.Clear(); TextLines.Clear(); for (int i = 0; i < len; i++) { ErrLine = i; CurHeight = g.MeasureString(TextAll[i].ToString(), l_Font, DisplayArea, new StringFormat(), out CurWords, out CurLines).Height; TextHeight.Add(CurHeight); TextLines.Add(CurLines); AllHeight += CurHeight; AllLines += CurLines; AllWords += CurWords; l_progress = (float)(i * 1.0 / len); } l_LinesPerScreen = (int)Math.Ceiling(DisplayAreaHeight / LineHeight); l_Maximum = AllLines - l_LinesPerScreen + 4; if (l_Maximum < 0) l_Maximum = 1; TextAreaHeight = (int)Math.Ceiling(AllHeight); } catch (Exception ex) { setError(ex.Message + "/n" + CurHeight + "/n" + CurLines + "/n ERROR LINE = " + ErrLine); } finally { g.Dispose(); } } private void DrawProgress(Graphics g) { try { if (l_margin < 10) return; float p = (float)(l_location * 1.0 / l_Maximum); Rectangle rtBottom = new Rectangle(0, this.ClientRectangle.Height - 2 * l_margin + 2, TextAreaWidth, 6); Rectangle rtTop = new Rectangle(0, this.ClientRectangle.Height - 2 * l_margin + 2, (int)(TextAreaWidth * p), 6); g.FillRectangle(Brushes.Blue, rtBottom); g.FillRectangle(Brushes.Yellow, rtTop); g.DrawRectangle(new Pen(Brushes.Blue,1), rtBottom); } finally { } } private bool inProgressArea(int x, int y) { Rectangle rtBottom = new Rectangle(0, this.ClientRectangle.Height - 2 * l_margin + 3, TextAreaWidth, 7); return rtBottom.Contains(x - l_margin, y - l_margin); } public void ShowAbout() { lblPName.Visible = true; lblVer.Visible = true; lblAuthor.Visible = true; lblEmail.Visible = true; lblMSN.Visible = true; lblQQ.Visible = true; lblNew.Visible = true; lblNewInfo.Visible = false; pnlAbout.Visible = true; tm.Interval = 100; StartTime = DateTime.Now.Ticks; tm.Enabled = true; } #endregion #region 系统函数 protected override bool IsInputKey(Keys keyData) { if ((keyData & Keys.Alt) == Keys.Alt) { return false; } switch ((keyData & Keys.KeyCode)) { case Keys.Up: case Keys.Down: case Keys.Left: case Keys.Right: return true; } return base.IsInputKey(keyData); } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); Graphics g = e.Graphics; int CurDispAreaHeight = 0; int CurRectTop = 0; try { g.Clear(this.BackColor); g.TranslateTransform(l_margin, l_margin); if (IsError) { g.DrawString(ErrorMsg, l_Font, Brushes.Red, 5, 5); } else if (!l_stoppaint && TextAll.Count != 0 && TextHeight.Count != 0 && TextLines.Count != 0 && curIndex < TextAll.Count) { Rectangle curRect; CurRectTop = (int)(-startLine * LineHeight); curRect = new Rectangle(0, CurRectTop, TextAreaWidth, Convert.ToInt32(TextHeight[curIndex])); CurDispAreaHeight = Convert.ToInt32(TextHeight[curIndex]) + CurRectTop; g.DrawString(TextAll[curIndex].ToString(), l_Font, new SolidBrush(this.ForeColor), curRect); for (int i = 1; CurDispAreaHeight <= DisplayAreaHeight && i < TextHeight.Count - curIndex; i++) { CurDispAreaHeight += Convert.ToInt32(TextHeight[curIndex + i]); //当前屏幕所显示的所有字段的高度 CurRectTop += Convert.ToInt32(TextHeight[curIndex + i - 1]); //当前段所显示的纵坐标 curRect = new Rectangle(0, CurRectTop, TextAreaWidth, Convert.ToInt32(TextHeight[curIndex + i])); //创建显示区域 g.DrawString(TextAll[curIndex + i].ToString(), l_Font, new SolidBrush(this.ForeColor), curRect); //显示当前段落内容 } Rectangle RT = new Rectangle(-l_margin, -l_margin, this.Width, l_margin); Rectangle RB = new Rectangle(-l_margin, DisplayAreaHeight, this.Width, l_margin + 2); g.FillRectangle(new SolidBrush(this.BackColor), RT); g.FillRectangle(new SolidBrush(this.BackColor), RB); } if (l_border > 0) { g.DrawRectangle(new Pen(l_border_color, l_border), new Rectangle(0, 0, TextAreaWidth, DisplayAreaHeight)); } } catch (Exception ex) { string errinfo = "当前文件:" + l_fp + "/n"; errinfo += "文字总段数:=" + TextAll.Count.ToString() + "/n"; errinfo += "startLine=" + startLine.ToString(); errinfo += "curIndex=" + curIndex.ToString(); setError(ex.Message); MessageBox.Show(ex.Message); } } protected override void OnResize(EventArgs e) { try { TextAreaWidth = this.Width - 2 * l_margin - 1; DisplayAreaHeight = this.Height - 2 * l_margin - 1; if (TextAll.Count > 0) { l_stoppaint = true; getTextHeight(); int l_loc = 0; if (l_Maximum == 0) l_loc = 0; else { for (int i = 0; i < curIndex; i++) { l_loc += Convert.ToInt32(TextLines[i]); } l_loc += startLine + 1; } l_stoppaint = false; Position = l_loc; } } catch (Exception ex) { setError(ex.Message); } finally { base.OnResize(e); } } protected override void OnMouseDown(MouseEventArgs e) { if (e.Button == MouseButtons.Left && inProgressArea(e.X , e.Y )) { float l = (float)((e.X - l_margin) * 1.0 / TextAreaWidth); int p = (int)(l_Maximum * l); Position = p; } else { base.OnMouseDown(e); } this.Focus(); } protected override void OnMouseMove(MouseEventArgs e) { if(e.Button == MouseButtons.None || !inProgressArea(e.X,e.Y)) { base.OnMouseMove(e); } } #endregion } }