using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Drawing.Drawing2D; using System.Windows.Forms; namespace WccPackTool.Controls; public class ConsoleWriteLine : Control { private MessageCollection items; #region 公有属性 [Category("WenAuto"), Description("是否显示序号"), DefaultValue(true)] public bool ShowLine { get; set; } = true; #endregion public ConsoleWriteLine() { base.SetStyle(ControlStyles.UserPaint | ControlStyles.DoubleBuffer | ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw | ControlStyles.SupportsTransparentBackColor, true); base.UpdateStyles(); this.Controls.Add(vScrollBar); vScrollBar.ValueChanged += VScrollBar_ValueChanged; this.MouseWheel += ConsoleWriteLine_MouseWheel; this.MouseEnter += ConsoleWriteLine_MouseEnter; } private void ConsoleWriteLine_MouseEnter(object sender, EventArgs e) { this.Select(); } private void ConsoleWriteLine_MouseWheel(object sender, MouseEventArgs e) { if (e.Delta < 0) { var v = vScrollBar.Value + 1; if (vScrollBar.Maximum >= v) vScrollBar.Value++; } else { var v = vScrollBar.Value - 1; if (vScrollBar.Minimum <= v) vScrollBar.Value--; } } private void VScrollBar_ValueChanged(object sender, EventArgs e) { this.Invalidate(true); } private void SetVS() { var count = (int)Math.Floor((float)this.Height / 20); if (this.Items.Count >= count) { this.vScrollBar.Maximum = this.Items.Count - count; this.vScrollBar.Value = this.Items.Count - count; } else { this.vScrollBar.Maximum = 0; this.vScrollBar.Value = 0; } } private VScrollBar vScrollBar = new VScrollBar() { Dock = DockStyle.Right, Maximum = 0, Value = 0, LargeChange = 1 }; public MessageCollection Items => items ??= new MessageCollection(this); public static StringFormat StringConters { get; set; } = new StringFormat(StringFormatFlags.NoClip | StringFormatFlags.NoWrap) { LineAlignment = StringAlignment.Center, Trimming = StringTrimming.EllipsisCharacter }; protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); Graphics g = e.Graphics; g.SmoothingMode = SmoothingMode.AntiAlias; //使绘图质量最高,即消除锯齿 g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.CompositingQuality = CompositingQuality.HighQuality; g.DrawRectangle(Pens.Black, new Rectangle(0, 0, this.Width - vScrollBar.Width - 1, this.Height - 1)); var count = (int)Math.Ceiling((float)this.Height / 20); var cuowei = count * 20 - this.Height; if (this.vScrollBar.Value == 0) { cuowei = 0; } if (count > this.Items.Count) { count = this.Items.Count; } for (int i = 0; i < count; i++) { var line = (this.vScrollBar.Value > 0 ? vScrollBar.Value - 1 : 0) + i; var item = this.Items[line]; var rec = new RectangleF(3, i * 20 - cuowei, this.Width - vScrollBar.Width - 6, 20); var text = $"{(ShowLine ? line + 1 + ". " : "")}{item.DateTime:HH:mm:ss} {item.Text}"; g.DrawString(text, Font, new SolidBrush(item.Color), rec, StringConters); } } public class MessageCollection : List { private ConsoleWriteLine owner; public MessageCollection(ConsoleWriteLine owner) { this.owner = owner; } public void Add(string text) => this.Add(text, Color.Black); public void Add(string text, Color color) { this.Add(new MessageItem(text, color)); owner.Invalidate(true); owner.SetVS(); } public new void Clear() { base.Clear(); owner.Invalidate(true); owner.SetVS(); } } public class MessageItem { public MessageItem(string text, Color color) { Text = text; Color = color; } public DateTime DateTime { get; set; } = DateTime.Now; public string Text { get; set; } = ""; public Color Color { get; set; } = Color.Black; } }