using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Linq; using System.Text; using System.Windows.Forms; using System.Threading; namespace arCtl { public partial class LogTextBox : RichTextBox { delegate void AddMsgHandler(DateTime tm, string Gubun, string Msg, Color fColor); /// /// 타이머를 이용하여 로그를 표시할 것인가를 설정합니다. (데이터량이 너무 많다면 이기능을사용하세요. 버퍼오버가 되면 프로그램이 멈출수 있습니다) /// public Boolean EnableDisplayTimer { get { return tm.Enabled; } set { tm.Enabled = value; if (value) tm.Start(); else tm.Stop(); } } /// /// 날짜의 포맷방식 기본 (yy-MM-dd HH:mm:ss) /// public string DateFormat { get; set; } /// /// 데이터의 String.Format 기본값([{0}] {1}), 0번은 시간, 1번은 메세지 , 2번은 구분 /// public string ListFormat { get; set; } /// /// 최대 데이터의 줄수 , 지정값을 넘어서면 초기화 됩니다. /// public UInt16 MaxListCount { get; set; } public UInt32 MaxTextLength { get; set; } private sLogMessageColor[] _ColorList = new sLogMessageColor[] { }; /// /// 메세지버퍼동기화를 위해서 추가함 /// private System.Threading.AutoResetEvent ar = new System.Threading.AutoResetEvent(true); ManualResetEvent mre = new ManualResetEvent(true); object lock_work = new object(); /// /// 메세지를 표시하는 내부 타이머의 간격입니다. 기본값 100 /// public int MessageInterval { get { return tm.Interval; } set { tm.Interval = value; //tm.Change(1000, value); } } /// /// 각 데이터라인을 컬러로 구분짓습니다. /// public Boolean EnableGubunColor { get; set; } public System.Windows.Forms.Timer tm; public new void Dispose() { this.tm.Stop(); tm.Tick -= tm_Tick; base.Dispose(); } /// /// 구분별로 색상을 입력합니다. 이 색상은 EnableGUbunColor 가 활성하되어야합니다. 비활성화시에는 DefaultColor를 사용합니다. /// public sLogMessageColor[] ColorList { get { return _ColorList; } set { _ColorList = value; } } public LogTextBox() { InitializeComponent(); EnableGubunColor = true; DateFormat = "yy-MM-dd HH:mm:ss"; ListFormat = "[{0}] {1}"; MaxListCount = 200; MaxTextLength = 4000; this.DefaultColor = Color.LightGray; this.BackColor = Color.FromArgb(24, 24, 24); this.Font = new Font("Consolas", 9, FontStyle.Regular); // this.waitsEvent = new EventWaitHandle[] { waitEvent, closeAllEvent }; tm = new System.Windows.Forms.Timer(); // System.Threading.Timer(tm_Tick, ar, 1000, 3000); // tm = new Timer(); tm.Interval = 50; tm.Tick += tm_Tick; this.EnableDisplayTimer = true; tm.Start(); } [Description("기본 글자 색상")] [Browsable(true)] public Color DefaultColor { get; set; } public void AddMsg(DateTime tm, string Gubun, string Msg) { Boolean useColor = false; Color fcolor = DefaultColor; if (EnableGubunColor) { if (ColorList != null && ColorList.Length > 0) { foreach (var cdata in ColorList) { if (Gubun.StartsWith(cdata.gubun)) { useColor = true; fcolor = cdata.color; break; } } } //사용자 컬러리스트를 조회해서 없다면 시스템으로 한다. if (!useColor) { var sColorList = new sLogMessageColor[] { new sLogMessageColor("ERR",Color.Red) , new sLogMessageColor("ATT",Color.Orange) , new sLogMessageColor("INFO",Color.DeepSkyBlue) , new sLogMessageColor("NET",Color.Magenta) }; foreach (var cdata in sColorList) { if (Gubun.StartsWith(cdata.gubun)) { fcolor = cdata.color; break; } } } } AddMsg(tm, Gubun, Msg, fcolor); } struct sMessageData { public DateTime date; public string msg; public Color fcolor; } public int BufferCount { get { return messagebuffer.Count; } } void tm_Tick(object sender, EventArgs e) { //ar.WaitOne(); //ar.Reset(); if (!mre.WaitOne(2000)) return; mre.Reset(); lock (lock_work) { if (messagebuffer.Count > 0) { var data = (sMessageData)messagebuffer.Dequeue(); //messagebuffer.RemoveAt(0); AppendMessge(data.msg, data.fcolor); //if (!this.IsDisposed && !this.Disposing) //{ // //색상변경 // int StartIndex = this.TextLength; // this.AppendText(data.msg + "\r\n"); // this.Select(StartIndex, data.msg.Length); // this.SelectionColor = data.fcolor; // this.ScrollToCaret(); //} } } mre.Set(); // AppendMessge(DateTime.Now.ToString("HH:mm:ss.fff"),Color.White); // ar.Set(); } delegate void AppedMessageHandler(string msg, Color fColor); void AppendMessge(string ListStr, Color fColor) { if (!this.Disposing && !this.IsDisposed) { if (this.InvokeRequired) { this.BeginInvoke(new AppedMessageHandler(AppendMessge), new object[] { ListStr, fColor }); } else { if (this.TextLength > MaxTextLength) this.Clear(); int StartIndex = this.TextLength; this.AppendText(ListStr + "\r\n"); this.Select(StartIndex, ListStr.Length); this.SelectionColor = fColor; this.ScrollToCaret(); } } } System.Collections.Queue messagebuffer = new System.Collections.Queue(); public void AddMsg(DateTime tm, string Gubun, string Msg, Color fColor) { //시간포맷 string _TimeFormat = this.DateFormat; if (string.IsNullOrEmpty(_TimeFormat)) _TimeFormat = "yy-MM-dd HH:mm:ss"; //데이터포맷 string _ListFormat = this.ListFormat; if (string.IsNullOrEmpty(_ListFormat)) _ListFormat = "[{0}] {1}"; string TimeStr = tm.ToString(_TimeFormat); string ListStr = string.Format(_ListFormat, TimeStr, Msg); //ar.WaitOne(); //ar.Reset(); if (!mre.WaitOne(2000)) return; mre.Reset(); lock (lock_work) { ///최대줄수를 넘어서면 오류 if (this.messagebuffer.Count > MaxListCount) { messagebuffer.Clear(); //this.Clear(); } if (!EnableDisplayTimer) { AppendMessge(ListStr, fColor); } else { sMessageData newmsg = new sMessageData(); newmsg.msg = ListStr; newmsg.date = tm; newmsg.fcolor = fColor; messagebuffer.Enqueue(newmsg); } mre.Set(); } //ar.Set(); ////색상변경 //int StartIndex = this.TextLength; //this.AppendText(ListStr + "\r\n"); //this.Select(StartIndex, ListStr.Length); //this.SelectionColor = fColor; //this.ScrollToCaret(); } public void AddMsg(DateTime tm, string Gubun, string[] Msg) { foreach (string m in Msg) AddMsg(tm, Gubun, m); } public void AddMsg(string Gubun, string Msg) { AddMsg(DateTime.Now, Gubun, Msg); } public void AddMsg(string Gubun, string[] Msg) { foreach (string m in Msg) AddMsg(DateTime.Now, Gubun, m); } public void AddMsg(string Msg) { AddMsg(DateTime.Now, "NORMAL", Msg); } public void AddMsg(string[] Msg) { foreach (string m in Msg) AddMsg(DateTime.Now, "NORMAL", m); } } [TypeConverterAttribute(typeof(ExpandableObjectConverter))] public class sLogMessageColor { public string gubun { get; set; } public Color color { get; set; } public sLogMessageColor() { this.gubun = "NOR"; this.color = Color.White; } public sLogMessageColor(string g, Color c) { this.gubun = g; this.color = c; } } }