using System.Collections.Generic; using System; using System.Drawing; using System.Diagnostics; using System.Data; using System.Collections; using System.Windows.Forms; using System.Collections.Specialized; using AR; using System.Security.Policy; using System.Linq; using System.Security.Cryptography; using System.Windows.Markup; using vmsnet; namespace vmsnet { public partial class FMain { public HMI.DispCtrl DispCtrl1; private Frm_trend_Real fTrendview = null; private fLog flog = null; private bool Init = false; private HMI.BarCtrl BarCtrl1 = null; readonly ScottPlot.WinForms.FormsPlot formsPlot1; private ScottPlot.Plottables.Scatter[] Streamer1; private ToolStripLabel[] mclabels = null; private int refreshinterval = 0; List[] dataVolt = null; List[] dataTime = null; short voltlimit = 0; short timelimit = 10; /// /// 1부터시작하는 채널의 번호입니다.(인덱스가 아님) /// 채널선택화면에서 선택된 채널 번호만 들어있다. /// docuementElement1 에는 모든 그룹/채널 정보가 들어있다 /// List selectchlist = new List(); public FMain() { // 이 호출은 디자이너에 필요합니다. InitializeComponent(); //check command if (PUB.ExtCommand == "Setup") PUB.setupmode = true; //display logo if (System.IO.File.Exists("logo.jpg")) this.bt_logo.Image = Image.FromFile("logo.jpg"); else this.bt_logo.Visible = false; PUB.mainWindow = this; ////DB초기화작업 PUB.INIT(out List errorMessageList); if (errorMessageList.Any()) { foreach (var err in errorMessageList) { UTIL.MsgE(err); } } #region "InitializeComponent HMI - userControl" this.DispCtrl1 = new HMI.DispCtrl(); this.DispCtrl1.init = false; this.DispCtrl1.BorderColor = System.Drawing.Color.Gray; this.DispCtrl1.Dock = System.Windows.Forms.DockStyle.Fill; this.DispCtrl1.Font = new System.Drawing.Font("맑은 고딕", (float)(12.0F), System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.World); this.DispCtrl1.Font_Grouptitle = new System.Drawing.Font("Microsoft Sans Serif", (float)(14.25F), System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, System.Convert.ToByte(129)); this.DispCtrl1.Font_Grouptitle_Color = System.Drawing.Color.Red; this.DispCtrl1.Font_Header = new System.Drawing.Font("Microsoft Sans Serif", (float)(9.75F), System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, System.Convert.ToByte(129)); this.DispCtrl1.Font_Header_Color = System.Drawing.Color.Yellow; this.DispCtrl1.FullScreen = true; this.DispCtrl1.init = true; this.DispCtrl1.initmsg = "initializing..."; this.DispCtrl1.Location = new System.Drawing.Point(3, 3); this.DispCtrl1.Message_Warning = ""; this.DispCtrl1.Name = "DispCtrl1"; this.DispCtrl1.Padding = new System.Windows.Forms.Padding(3); this.TableLayoutPanel1.SetRowSpan(this.DispCtrl1, 3); this.DispCtrl1.ShowIndex = -1; this.DispCtrl1.Size = new System.Drawing.Size(774, 699); this.DispCtrl1.TabIndex = 3; this.DispCtrl1.Times = null; this.DispCtrl1.Values = null; this.DispCtrl1.OnAlamChange += DispCtrl1_OnAlamChangeL; this.DispCtrl1.OnChangedShowIndex += DispCtrl1_OnChangedShowIndex; this.DispCtrl1.OnClickCell += DispCtrl1_OnClickCell; this.DispCtrl1.OnClickGroup += DispCtrl1_OnClickGroup; this.DispCtrl1.OnClickPrint += DispCtrl1_OnClickPrint; this.DispCtrl1.OnNotifyData += DispCtrl1_OnNotifyData; this.DispCtrl1.OnSetNullbalance += DispCtrl1_OnSetNullbalance; this.DispCtrl1.RaiseAlarm += DispCtrl1_RaiseAlarm; this.TableLayoutPanel1.Controls.Add(this.DispCtrl1, 0, 0); formsPlot1 = new ScottPlot.WinForms.FormsPlot() { Dock = DockStyle.Fill }; formsPlot1.MouseDown += FormsPlot1_MouseDown; formsPlot1.MouseUp += FormsPlot1_MouseUp; formsPlot1.MouseMove += FormsPlot1_MouseMove; CrossHair = formsPlot1.Plot.Add.Crosshair(0, 0); CrossHair.TextColor = ScottPlot.Colors.White; CrossHair.TextBackgroundColor = CrossHair.HorizontalLine.Color; formsPlot1.Plot.YLabel("VOLTAGE"); formsPlot1.Plot.XLabel("COUNT"); formsPlot1.Plot.Axes.Bottom.MinimumSize = PUB.TREND.graph_bottom_minsize; if (PUB.TREND.y_scale_auto) formsPlot1.Plot.Axes.AutoScaleY(); else formsPlot1.Plot.Axes.SetLimitsY(PUB.TREND.graph_y_start, PUB.TREND.graph_y_end); this.formsPlot1.Plot.ShowLegend(); formsPlot1.Plot.Axes.DateTimeTicksBottom(); this.formsPlot1.Plot.Axes.ContinuouslyAutoscale = true; this.formsPlot1.Plot.RenderManager.RenderStarting += (s1, e1) => { ScottPlot.Tick[] ticks = formsPlot1.Plot.Axes.Bottom.TickGenerator.Ticks; for (int i = 0; i < ticks.Length; i++) { DateTime dt = DateTime.FromOADate(ticks[i].Position); string label = $"{dt:yy-MM-dd\nHH:mm:ss}"; ticks[i] = new ScottPlot.Tick(ticks[i].Position, label); } }; this.TableLayoutPanel1.Controls.Add(this.formsPlot1, 1, 1); this.BarCtrl1 = new HMI.BarCtrl(); this.BarCtrl1.BackColor = System.Drawing.Color.White; this.BarCtrl1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.BarCtrl1.Dock = System.Windows.Forms.DockStyle.Fill; this.BarCtrl1.Font = new System.Drawing.Font("맑은 고딕", (float)(12.0F), System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.World); this.BarCtrl1.Location = new System.Drawing.Point(783, 373); this.BarCtrl1.Name = "BarCtrl1"; this.BarCtrl1.Show_DebugMsg = false; this.BarCtrl1.Size = new System.Drawing.Size(775, 329); this.BarCtrl1.TabIndex = 6; this.TableLayoutPanel1.Controls.Add(this.BarCtrl1, 1, 2); Streamer1 = new ScottPlot.Plottables.Scatter[0]; //최대10개로한다 dataVolt = new List[0]; dataTime = new List[0]; #endregion btLog.Visible = System.Diagnostics.Debugger.IsAttached; PUB.RemoteCommandEvent += Pub_RemoteCommandEvent; mclabels = new ToolStripLabel[] { }; } #region "scott plot mouse event" ScottPlot.Plottables.Crosshair CrossHair; ScottPlot.Plottables.VerticalLine[] CursorLine; private ScottPlot.Plottables.AxisLine GetLineUnderMouse(float x, float y) { ScottPlot.CoordinateRect rect = formsPlot1.Plot.GetCoordinateRect(x, y, radius: 10); foreach (var axLine in formsPlot1.Plot.GetPlottables().Reverse()) { if (axLine.IsUnderMouse(rect)) return axLine; } return null; } /// /// 우측 그리드뷰에 표시되는 커서 값을 표시한ㄷ.ㅏ /// private void UpdateCursorVAlue() { //var c1 = this.CursorLine[0]; //if (c1 != null) //{ // var time = DateTime.FromOADate(c1.X); // //커서 좌,우측의 데이터를 구한다. // foreach (DS1.channelRow dr in this.ds1.channel.Rows) // { // if (dr.use == false) dr.c1 = ""; // else // { // var chno = dr.tidx; // if (chno >= myPlotDataX.Length) dr.c1 = "ERR"; // else // { // var plot = this.myPlots[chno]; // var times = myPlotDataX[chno]; // var samedate = times.Where(t => t == time).FirstOrDefault(); // if (samedate != default(DateTime)) // { // //해당 데이터 포인트에 값이 있다. // var index = times.IndexOf(samedate); // var volt = myPlotDataY[chno][index]; // dr.c1 = $"{volt:#0.00}"; // } // else // { // //중간값을 찾는다. // var leftdata = times.Where(t => t < time).LastOrDefault(); // var rightdata = times.Where(t => t > time).FirstOrDefault(); // if (leftdata != null && rightdata != null) // { // var indexL = times.IndexOf(leftdata); // var indexR = times.IndexOf(rightdata); // var voltL = myPlotDataY[chno][indexL]; // var voltR = myPlotDataY[chno][indexR]; // var diffvolt = Math.Abs(voltL - voltR); // if (diffvolt == 0) //Y축 변화가 없다면 그 중간의 데이터는 동일하다 // { // dr.c1 = $"{voltL:#0.00}"; // } // else // { // //X축이 변화량의 어디쯤에 있는지 확인 // var XTotal = (rightdata - leftdata).TotalSeconds; // var xPosition = (time - leftdata).TotalSeconds / XTotal; // var volt = voltL + (diffvolt * xPosition); // dr.c1 = $"{volt:#0.00}"; // } // } // else dr.c1 = "ERR"; // } // //dr["c1"] = TrendCtrl1.CHInfo[chno].C1value; // //dr["c2"] = TrendCtrl1.CHInfo[chno].C2value; // //if (TrendCtrl1.CHInfo[chno].Show) // //{ // // dr["use"] = 1; // //} // //else // //{ // // dr["use"] = 0; // //} // } // } // } //} //var c2 = this.CursorLine[1]; //if (c2 != null) //{ // var time = DateTime.FromOADate(c2.X); // //커서 좌,우측의 데이터를 구한다. // foreach (DS1.channelRow dr in this.dS1.channel.Rows) // { // if (dr.use == false) dr.c2 = ""; // else // { // var chno = dr.tidx; // if (chno >= myPlotDataX.Length) dr.c2 = "ERR"; // else // { // var plot = this.myPlots[chno]; // var times = myPlotDataX[chno]; // var samedate = times.Where(t => t == time).FirstOrDefault(); // if (samedate != default(DateTime)) // { // //해당 데이터 포인트에 값이 있다. // var index = times.IndexOf(samedate); // var volt = myPlotDataY[chno][index]; // dr.c2 = $"{volt:#0.00}"; // } // else // { // //중간값을 찾는다. // var leftdata = times.Where(t => t < time).LastOrDefault(); // var rightdata = times.Where(t => t > time).FirstOrDefault(); // if (leftdata != null && rightdata != null) // { // var indexL = times.IndexOf(leftdata); // var indexR = times.IndexOf(rightdata); // var voltL = myPlotDataY[chno][indexL]; // var voltR = myPlotDataY[chno][indexR]; // var diffvolt = Math.Abs(voltL - voltR); // if (diffvolt == 0) //Y축 변화가 없다면 그 중간의 데이터는 동일하다 // { // dr.c2 = $"{voltL:#0.00}"; // } // else // { // //X축이 변화량의 어디쯤에 있는지 확인 // var XTotal = (rightdata - leftdata).TotalSeconds; // var xPosition = (time - leftdata).TotalSeconds / XTotal; // var volt = voltL + (diffvolt * xPosition); // dr.c2 = $"{volt:#0.00}"; // } // } // else dr.c2 = "ERR"; // } // //dr["c1"] = TrendCtrl1.CHInfo[chno].C1value; // //dr["c2"] = TrendCtrl1.CHInfo[chno].C2value; // //if (TrendCtrl1.CHInfo[chno].Show) // //{ // // dr["use"] = 1; // //} // //else // //{ // // dr["use"] = 0; // //} // } // } // } //} //dv_chlist.AutoResizeColumns(); } private void FormsPlot1_MouseDown(object sender, MouseEventArgs e) { var lineUnderMouse = GetLineUnderMouse(e.X, e.Y); if (lineUnderMouse != null) { PlottableBeingDragged = lineUnderMouse; formsPlot1.Interaction.Disable(); // disable panning while dragging } } private void FormsPlot1_MouseUp(object sender, MouseEventArgs e) { PlottableBeingDragged = null; formsPlot1.Interaction.Enable(); // enable panning again formsPlot1.Refresh(); this.UpdateCursorVAlue(); } ScottPlot.Plottables.AxisLine PlottableBeingDragged = null; private void FormsPlot1_MouseMove(object sender, MouseEventArgs e) { //update cross line ScottPlot.Pixel mousePixel = new ScottPlot.Pixel(e.X, e.Y); ScottPlot.Coordinates mouseCoordinates = formsPlot1.Plot.GetCoordinates(mousePixel); if (mouseCoordinates.X is double.NaN || mouseCoordinates.Y is double.NaN || mouseCoordinates.X is double.PositiveInfinity || mouseCoordinates.Y is double.PositiveInfinity || mouseCoordinates.X is double.NegativeInfinity || mouseCoordinates.Y is double.NegativeInfinity) { return; } if (CrossHair != null) { CrossHair.Position = mouseCoordinates; var time = DateTime.FromOADate(mouseCoordinates.X); CrossHair.VerticalLine.Text = $"{time:yy-MM-dd\nHH:mm:ss}"; CrossHair.HorizontalLine.Text = $"{mouseCoordinates.Y:N2}v"; if (formsPlot1.InvokeRequired) formsPlot1.Invoke(new Action(() => formsPlot1.Refresh())); else formsPlot1.Refresh(); } // this rectangle is the area around the mouse in coordinate units ScottPlot.CoordinateRect rect = formsPlot1.Plot.GetCoordinateRect(e.X, e.Y, radius: 10); if (PlottableBeingDragged is null) { // set cursor based on what's beneath the plottable var lineUnderMouse = GetLineUnderMouse(e.X, e.Y); if (lineUnderMouse is null) Cursor = Cursors.Default; else if (lineUnderMouse.IsDraggable && lineUnderMouse is ScottPlot.Plottables.VerticalLine) Cursor = Cursors.SizeWE; else if (lineUnderMouse.IsDraggable && lineUnderMouse is ScottPlot.Plottables.HorizontalLine) Cursor = Cursors.SizeNS; } else { // update the position of the plottable being dragged if (PlottableBeingDragged is ScottPlot.Plottables.HorizontalLine hl) { hl.Y = rect.VerticalCenter; hl.Text = $"{hl.Y:0.00}v"; } else if (PlottableBeingDragged is ScottPlot.Plottables.VerticalLine vl) { vl.X = rect.HorizontalCenter; var time = DateTime.FromOADate(vl.X); //vl.Text = $"{vl.X:0.00}"; vl.Text = $"{time:yy-MM-dd\nHH:mm:ss}"; } formsPlot1.Refresh(); } } #endregion public void Frm_Main_FormClosing(object sender, System.Windows.Forms.FormClosingEventArgs e) { if (UTIL.MsgQ("프로그램을 종료하시겠습니까?") != DialogResult.Yes) { e.Cancel = true; return; } //서브윈도우 off if (PUB.subWindow != null) PUB.subWindow.Close(); //모니터링 OFF if (PUB.NotExitMonitor == false) StopWatcher(); ////현재위치정보 저장 PUB.CONFIG.win1pos = this.Left.ToString() + "," + this.Top.ToString(); PUB.CONFIG.Save(); //Stop statemachine PUB.sm.Stop(); PUB.log.Add(AR.Log.ETYPE.SHUTDOWN, "프로그램종료"); //MsgBox("창 닫을떄 쓰레드 종료하는 기능 귀찮아서 잠시꺼둠 배포시에는 켜야함") //if (Thread != null && Thread.IsAlive) //{ // this.Hide(); // this.Runbutton(); //} PUB.log.Add(AR.Log.ETYPE.SHUTDOWN, "프로그램종료-쓰레드종료완료"); PUB.log.Flush(); } /// /// 현재데이터베이스를 복제한다. /// void MakeTempDatabase() { this.documentElement1.Clear(); this.documentElement1.GRP.Merge(PUB.DS.GRP); this.documentElement1.CHANNEL.Merge(PUB.DS.CHANNEL); this.documentElement1.AcceptChanges(); this.ds1.Clear(); this.ds1.AcceptChanges(); } public void Frm_Main_Load(object sender, System.EventArgs e) { this.Show(); Application.DoEvents(); //현재데이터베이스를 복제한다. MakeTempDatabase(); ////Sleep Timeout //var drNormal = PUB.DS.NORMAL.FirstOrDefault(); //if (drNormal != null && drNormal.IsTSPEEDNull() == false) PUB.sleeplimit = drNormal.TSPEED;// System.Convert.ToInt32(pub.DS.NORMAL[0].TSPEED); // DBC.GetScalar("select TSPEED from NORMAL") //else PUB.sleeplimit = 0; //if (PUB.sleeplimit < 2) PUB.sleeplimit = 200; PUB.log.Add(AR.Log.ETYPE.STARTUP, "프로그램시작-차트초기화"); ////Chart REFRESHCHART(); ////우클릭메뉴 생성 Make_ContextMenuItem(); displayinfo(); ////하단스테이터스바 업데이트 RunWatcher(); ////Run m Watcher PUB.WindowCount = PUBC.GetWindowCount(); ////다중윈도우라면 창을 하나더 띄운다. if (PUB.WindowCount > 1) { this.bt_show2ndwindow.Visible = true; this.bt_show2ndwindow.Enabled = true; Func_OpenSubWindow(); // 서브스크린 오픈 } else { this.bt_show2ndwindow.Visible = false; } try ////이전에발생오류파일이있다면 삭제한다. { if (System.IO.File.Exists("error.xml")) { var newfn = System.IO.Path.Combine(PUB.CONFIG.bugreport, DateTime.Now.ToString("yyMMddHHmmss") + "_error.xml"); System.IO.File.Move("error.xml", newfn); } } catch (Exception ex) { PUB.log.AddE($"error move failed:{ex.Message}"); } this.bt_config.Enabled = true; this.bt_tview.Enabled = true; this.bt_tviewr.Enabled = true; this.bt_alamhistory.Enabled = true; this.bt_alamsetup.Enabled = true; this.bt_save.Enabled = true; this.bt_print.Enabled = true; DispCtrl1.FullScreen = true; ////전체보기 TableLayoutPanel1.ColumnStyles[1].Width = 0; PUB.log.Add(AR.Log.ETYPE.STARTUP, "프로그램시작-초기화완료"); PUB.StartupTime = DateTime.Now; Init = true; if (PUB.masterk.IsInit) PUB.masterk.RunMonitor(); Timer1.Start(); PUB.sm = new AR.Device.CStateMachine(); PUB.sm.SetMsgOptOff(); //모든 메세지출력을 해제한다. (이벤트는 동작함) PUB.sm.Running += SM_Loop; PUB.sm.SPS += SM_SPS; //###################################################### //########## 아래 이벤트는 _11_SM_Events.cs 파일에 정의됨 //###################################################### PUB.sm.StepChanged += SM_StepChanged; PUB.sm.Message += SM_Message; PUB.sm.InitControl += SM_InitControl; PUB.sm.StepStarted += SM_StepStarted; PUB.sm.StepCompleted += SM_StepCompleted; PUB.sm.StateProgress += SM_StateProgress; PUB.sm.Start(); //if (PUB.CONFIG.autorun) { if (!PUB.runerror) { PUB.RunMonitor(); } else { UTIL.MsgE("장치 오류로인해 모니터를 자동 실행하지 않습니다"); } } MakeMCLabels(); PUB.StartupTime = DateTime.Now; } #region WatchDog /// /// stop watchdog /// /// private void StopWatcher() { try { Process[] Prc = Process.GetProcesses(); ////현재프로세스배열을 가져온다. foreach (Process MyPrc in Prc) { if (MyPrc.ProcessName.ToUpper().IndexOf("VMSMONITOR") != -1) { MyPrc.Kill(); break; } } PUB.log.Add(AR.Log.ETYPE.NORMAL, "감시소프트웨어종료완료"); } catch (Exception ex) { PUB.log.Add(AR.Log.ETYPE.NORMAL, "감시소프트웨어종료실패:" + ex.Message.ToString()); } } /// /// run watchdog /// /// private void RunWatcher() { try { Process[] Prc = Process.GetProcesses(); ////현재프로세스배열을 가져온다. bool runmonitor1 = false; foreach (Process MyPrc in Prc) { if (MyPrc.ProcessName.ToUpper().IndexOf("VMSMONITOR") != -1) { runmonitor1 = true; break; } } if (!runmonitor1) { //Dim RunP As Process System.Diagnostics.ProcessStartInfo B = new System.Diagnostics.ProcessStartInfo(); var fi = new System.IO.FileInfo("VMSMonitor.exe"); if (fi.Exists) { try { UTIL.RunProcess(fi.FullName, windowstyle: ProcessWindowStyle.Minimized); } catch (Exception ex) { PUB.log.Add($"watch error : {ex.Message}"); } } else PUB.log.AddE($"감시프로그램없음 경로:{fi.FullName}"); } PUB.log.Add(AR.Log.ETYPE.NORMAL, "감시프로그램작동시작"); } catch (Exception ex) { PUB.log.Add(AR.Log.ETYPE.ERROR, "감시프로그램실행불가:" + ex.Message.ToString()); } } #endregion public void Frm_Main_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e) { switch (e.KeyCode) { case Keys.F1: this.bt_tview.PerformClick(); break; case Keys.F2: this.ToolStripButton2.PerformClick(); break; case Keys.F3: this.bt_alamhistory.PerformClick(); break; case Keys.F4: this.bt_alamsetup.PerformClick(); break; case Keys.F5: this.bt_save.PerformClick(); break; case Keys.F9: this.bt_print.PerformClick(); break; case Keys.Escape: this.Close(); break; } } private void Make_ContextMenuItem() { ////x축 간격 목록추가 menus_xgap.DropDownItems.Clear(); var lists = new Dictionary(); lists.Add("5초", 5); lists.Add("10초", 10); lists.Add("30초", 30); lists.Add("1분", 60 * 1); lists.Add("5분", 60 * 5); lists.Add("10분", 60 * 10); lists.Add("30분", 60 * 30); lists.Add("1시간", 3600); lists.Add("3시간", 3600 * 3); lists.Add("6시간", 3600 * 6); lists.Add("12시간", 3600 * 12); lists.Add("24시간", 3600 * 24); foreach (var TermData in lists) { int Sec = TermData.Value; ToolStripMenuItem NewItem = new ToolStripMenuItem(TermData.Key); NewItem.Tag = Sec; NewItem.CheckOnClick = true; if (Sec == PUB.CONFIG.maintv_xgap) { NewItem.Checked = true; } NewItem.Click += cmbt_x_gap_30_Click; menus_xgap.DropDownItems.Add(NewItem); } ////x축 범위 목록추가 menus_xterm.DropDownItems.Clear(); lists = new Dictionary(); lists.Add("1분", 60 * 1); lists.Add("3분", 60 * 3); lists.Add("5분", 60 * 5); lists.Add("10분", 60 * 10); lists.Add("30분", 60 * 30); lists.Add("1시간", 3600); lists.Add("2시간", 3600 * 2); lists.Add("3시간", 3600 * 3); lists.Add("6시간", 3600 * 6); lists.Add("12시간", 3600 * 12); foreach (var TermData in lists) { int Sec = TermData.Value; ToolStripMenuItem NewItem = new ToolStripMenuItem(TermData.Key); NewItem.Tag = Sec; NewItem.CheckOnClick = true; if (Sec == PUB.CONFIG.maintv_xterm) { NewItem.Checked = true; } NewItem.Click += cmbt_x_1800_Click; menus_xterm.DropDownItems.Add(NewItem); } ////Y축 표시 간격 menus_ygap.DropDownItems.Clear(); var yterms = new float[] { 0.1f, 0.2f, 0.5f, 1.0f, 1.5f, 2.0f, 2.5f, 5.0f }; foreach (var Value in yterms) { ToolStripMenuItem NewItem = new ToolStripMenuItem(Value.ToString()); NewItem.Tag = Value; NewItem.CheckOnClick = true; if (Value == PUB.CONFIG.maintv_ygap) { NewItem.Checked = true; } NewItem.Click += ToolStripMenuItem5_Click; menus_ygap.DropDownItems.Add(NewItem); } ////창크기 menus_winsize.DropDownItems.Clear(); var winsize = new int[] { 30, 40, 50, 60, 70 }; foreach (var Value in winsize) { ToolStripMenuItem NewItem = new ToolStripMenuItem(Value.ToString()); NewItem.Tag = Value; NewItem.CheckOnClick = true; if (Value == PUB.CONFIG.maintv_winsize) { NewItem.Checked = true; } NewItem.Click += Cmbt_winsize_click; menus_winsize.DropDownItems.Add(NewItem); } } private void Pub_RemoteCommandEvent(object sender, RemoteCommand e) { if (e.Command == rCommand.StateMessage) { var msg = e.Data.ToString(); if (PUB.lastStatueMessage.Equals(msg) == false) { if (this.InvokeRequired) { this.BeginInvoke(new Action(() => { lb_status.Text = $"<{msg}>"; lb_status.Invalidate(); })); } else { lb_status.Text = $"<{msg}>"; lb_status.Invalidate(); } PUB.lastStatueMessage = msg; } } else if (e.Command == rCommand.SaveGroupClass) { var fi1 = new System.IO.FileInfo("window1.grp"); PUB.SaveGroupClass(DispCtrl1.GROUPS, fi1); } else if (e.Command == rCommand.DAQConnected) { var idx = int.Parse(e.Data.ToString()); UpdateConnectionDisplayLabel(idx, ConnState.Connected); } else if (e.Command == rCommand.DAQDisconnected) { var idx = int.Parse(e.Data.ToString()); UpdateConnectionDisplayLabel(idx, ConnState.Disconnected); } else if (e.Command == rCommand.DAQTryConnect) { var idx = int.Parse(e.Data.ToString()); UpdateConnectionDisplayLabel(idx, ConnState.TryConnect); } else if (e.Command == rCommand.RefreshChart) { REFRESHCHART(false); } else if (e.Command == rCommand.ValueUpdate) { //전체화면모드에서는 실시간데이터를 표시하지 않는다. if (DispCtrl1.FullScreen == false) { //스트리머,데이터,선택된 채널 정보가 있어야 업데이트 가능하다 if (e.Data != null && this.Streamer1 != null && this.selectchlist.Any()) { var data = e.Data as List; //선택된 채널의 정보만 사용 var recvdatas = data.Where(t => selectchlist.Contains(t.chno)).Select(t => t); if (recvdatas.Any() == false) return; //대상채널데이터가 없다. //받은데이터를 화면에 추가한다. foreach (var newdata in recvdatas) { var ch = newdata.chno - 1; var val = newdata.value; var time = newdata.time; //자료가없거나 스트리머가 없는 경우 if (ch >= this.Streamer1.Length || this.Streamer1[ch] == null) continue; float value = 0; if (PUB.CONFIG.datadiv != 0 && PUB.CONFIG.datadiv != 1) value = (newdata.value) / PUB.CONFIG.datadiv; else value = (newdata.value); //채널정보를 통해서 소수점위치와 옾셋값을 가져온다 value = (float)(value / Math.Pow(10, newdata.decpos)); //최종옵셋 value += newdata.offset; //데이터 추가 if (this.Streamer1[ch].IsVisible) { var v_time = DateTime.Parse(time); this.dataTime[ch].Add(v_time.ToOADate()); this.dataVolt[ch].Add(value); var mintime = DateTime.FromOADate(dataTime[ch].First()); var maxtime = DateTime.FromOADate(dataTime[ch].Last()); var ts = (maxtime - mintime); if (ts.TotalMinutes >= this.timelimit) { //10개지운다 if (dataTime[ch].Count > 10) { dataTime[ch].RemoveRange(0, 10); dataVolt[ch].RemoveRange(0, 10); } } } } this.BeginInvoke(new Action(() => { this.formsPlot1.Refresh(); })); } this.BarCtrl1.Invalidate(); } } else PUB.ProcessDisplayControl(this.DispCtrl1, e.Command, e.Data); } private void REFRESHCHART(bool renew = false) { this.DispCtrl1.init = false; this.DispCtrl1.SuspendLayout(); this.DispCtrl1.initpercent = 100; this.DispCtrl1.initmsg = "Create Window"; this.DispCtrl1._raise_alarm = false; this.DispCtrl1._raise_alarm_pre = false; this.DispCtrl1.datadiv = PUB.CONFIG.datadiv; this.DispCtrl1.NullbalanceRealValue = PUB.CONFIG.nullbalnce; this.DispCtrl1.Sumab = PUB.CONFIG.Sumab; this.DispCtrl1.EnableKA = PUB.CONFIG.EnableKA; this.DispCtrl1.FONT_NB = PUB.GetFontFromStr(PUB.DESIGN.font_nb); this.DispCtrl1.FONT_CV = PUB.GetFontFromStr(PUB.DESIGN.font_cellvalue); this.DispCtrl1.FONT_CN = PUB.GetFontFromStr(PUB.DESIGN.font_cellname); this.DispCtrl1.Font_Header = PUB.GetFontFromStr(PUB.DESIGN.font_summary); this.DispCtrl1.FONT_CT = PUB.GetFontFromStr(PUB.DESIGN.font_celltitle); this.DispCtrl1.FONT_AV = PUB.GetFontFromStr(PUB.DESIGN.font_alarmvalue); this.DispCtrl1.FONT_KA = PUB.GetFontFromStr(PUB.DESIGN.font_kaValue); this.DispCtrl1.FONT_KU = PUB.GetFontFromStr(PUB.DESIGN.font_kaUnit); DispCtrl1_RaiseAlarm(false); ////window if (PUB.DS.WIN.Count > 0) { var dtwin = PUB.DS.WIN.Where(t => t.IDX == 1).FirstOrDefault(); HMI.CWINDOW Win = new HMI.CWINDOW(); if (dtwin != null) { Win.MATRIX = dtwin.MATRIX; Win.이름 = dtwin.TITLE; Win.IDX = 1; } else { Win.MATRIX = "1x1"; Win.이름 = "NoName"; Win.IDX = 1; } this.DispCtrl1.WINDOW = Win; } var infofile = new System.IO.FileInfo("window1.grp"); bool makeinfo = true; if (infofile.Exists) { ////복원처리 System.IO.FileStream fs = new System.IO.FileStream(infofile.FullName, System.IO.FileMode.Open); System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); try { PUB.MainGroup = (HMI.CGROUP[])(bf.Deserialize(fs)); makeinfo = false; } catch (Exception ex) { makeinfo = true; PUB.log.Add($"file read error window1.grp : {ex.Message}"); } fs.Close(); } if (!makeinfo && !renew) { DispCtrl1.SetItemDisable(); } else { this.DispCtrl1.initpercent = 0; this.DispCtrl1.initmsg = "Init Group"; var GroupRows = PUB.DS.GRP.Where(t => t.USE == 1 && t.WINDOW == 1).OrderBy(t => t.TITLE);// var GroupCount = GroupRows.Count(); //DispCtrl1.ResizeGroup(GroupCount); int GIDX = 0; HMI.CGROUP[] GroupItems = new HMI.CGROUP[GroupCount]; foreach (var GDr in GroupRows) { ////빈값오류처리 if (GDr.TITLE == "") GDr.TITLE = "Unknown"; if (GDr.MATRIX == "") GDr.MATRIX = "1*1"; if (GDr.POS == "") GDr.POS = "0/0"; if (GDr.SPAN == "") GDr.SPAN = "1/1"; if (GDr.FONT == "") GDr.FONT = "나눔고딕,8,1"; if (GDr.ALAMTYPE == "") GDr.ALAMTYPE = "MANUAL"; this.DispCtrl1.initmsg = "Create Group #" + GDr.TITLE; this.DispCtrl1.initpercent = System.Convert.ToInt32((double)(100 * (GIDX + 1)) / GroupCount); string Fontinfo = GDr.FONT; string fontname = System.Convert.ToString(Fontinfo.Split(",".ToCharArray())[0]); int fontsize = System.Convert.ToInt32(Fontinfo.Split(",".ToCharArray())[1]); int fontstyle = 0; try { fontstyle = System.Convert.ToInt32(Fontinfo.Split(",".ToCharArray())[2]); } catch (Exception) { fontstyle = 0; } FontStyle FS = (FontStyle)fontstyle; HMI.CGROUP G1 = new HMI.CGROUP(); G1.셀글꼴 = new Font(fontname, fontsize, FS); string spaninfo = GDr.SPAN; string posinfo = GDr.POS; G1.아이템배열 = GDr.MATRIX; // DReader("MATRIX") G1.이름 = GDr.TITLE; // DReader("TITLE") G1.줄병합 = System.Convert.ToInt32(spaninfo.Split("/".ToCharArray())[0]); G1.열병합 = System.Convert.ToInt32(spaninfo.Split("/".ToCharArray())[1]); G1.줄번호 = System.Convert.ToInt32(posinfo.Split("/".ToCharArray())[0]); G1.열번호 = System.Convert.ToInt32(posinfo.Split("/".ToCharArray())[1]); G1.WIDX = GDr.WINDOW; // DReader("WINDOW") '//지정된 윈도우 일련번호 G1.IDX = GDr.IDX; // DReader("IDX") '//이그룹의 일련번호 G1._ampidx = GDr.KADEVICE; // DReader("KADEVICE") G1.AlarmType = GDr.ALAMTYPE; //DReader("ALAMTYPE") G1._null_itemseq = (short)GDr.NBSEQ; // DReader("NBSEQ") G1.NullBalanceOffset = GDr.NBOFF; // DReader("NBOFF") if (G1._ampidx != "") { string gg1 = G1._ampidx.Split(",".ToCharArray())[0]; string ggU = G1._ampidx.Split(",".ToCharArray())[1]; string gg2 = G1._ampidx.Split(",".ToCharArray())[2]; ////디바이스를 열어서 순서대로 한다. var DTDEV = PUB.DS.DEVICE.Where(t => t.USE == 1).OrderBy(t => t.IDX);// short DTDEVIDX = 0; short deviceidx = (-1); foreach (DocumentElement.DEVICERow DRdev in DTDEV) { if (DRdev.IDX.ToString() == gg1) { deviceidx = DTDEVIDX; break; } DTDEVIDX++; } if (deviceidx != -1) { G1._ampunit = "KA"; G1._ampdecpos = 0; G1._ampidx = deviceidx + "," + G1._ampidx.Split(",".ToCharArray())[1] + "," + gg2; } else { G1._ampunit = "NONE"; G1._ampdecpos = (short)0; } } else { G1._ampunit = "NONE"; G1._ampdecpos = (short)0; } G1.HIGH = GDr.ALAMH; // ("ALAMH") G1.LOW = GDr.ALAML; // DReader("ALAML") G1.UP = GDr.AUTOH; // DReader("AUTOH") G1.AlarmType = GDr.ALAMTYPE; //DReader("ALAMTYPE") G1.nbh = GDr.NBH; // DReader("NBH") G1.nbl = GDr.NBL; // DReader("NBL") string maxname = ""; string maxalam = ""; string alamstr = ""; var G1item = new HMI.CITEM[(G1.RowCount * G1.ColumnCount) - 1 + 1]; ////연결된셀의정보(해당 그룹에 속해있는 아이템) var DTChannel = PUB.DS.CHANNEL.Where(t => t.GIDX == G1.IDX).OrderBy(t => t.IDX);// .Select("gidx=" + G1.IDX.ToString(), "idx") as DocumentElement.CHANNELRow[]; ////initialzing.... for (int i = 0; i <= G1item.GetUpperBound(0); i++) { this.DispCtrl1.initpercent = System.Convert.ToInt32((double)((i + 1) * 100) / G1item.Length); if ((this.DispCtrl1.initpercent) % 25 == 0) { this.DispCtrl1.Refresh(); } ////셀정보를 가져온다 DocumentElement.CHANNELRow DrChannel = null;//= default(DataRow); HMI.CITEM gi = new HMI.CITEM(); gi.seq = i; if (DTChannel.Any() && i < DTChannel.Count()) { DrChannel = DTChannel.ElementAt(i); ////이데이터가 채널정보에 없다. } string MACHINE = ""; if (DrChannel == null) { gi.알람형태 = COMM.EALAMTYPE.사용안함; gi.idx = (short)1; gi.alamh = 0; gi.alaml = 0; gi.aalamh = 0; gi.aalaml = 0; gi.이름 = ""; gi.사용 = false; gi.idx_ch = (short)(-1); gi.idx_dev = (short)(-1); gi.idx_unit = (short)(-1); gi.활성화 = false; gi.unit = ""; gi.c_color = Color.Black; gi.decpos = 0; gi.Offset = 0; MACHINE = ""; } else { gi.알람형태 = (COMM.EALAMTYPE)DrChannel.ALAMTYPE; gi.idx = DrChannel.IDX;// System.Convert.ToInt16(DrChannel["IDX"]); ////채널의 고유인덱스 gi.alamh = 0; gi.alaml = 0; gi.aalamh = 0; gi.aalaml = 0; gi.alamv = -999; gi.활성화 = false; gi.unit = DrChannel.UNIT;// System.Convert.ToString(DrChannel["UNIT"]); gi.decpos = DrChannel.DECPOS;// System.Convert.ToInt16(DrChannel["DECPOS"]); gi.Offset = DrChannel.VOFFSET; var ColorValue = DrChannel.COLOR;// System.Convert.ToString(DrChannel["COLOR"]); gi.c_color = System.Drawing.Color.FromArgb(ColorValue); if ((gi.알람형태 == COMM.EALAMTYPE.개별알람) || (gi.알람형태 == COMM.EALAMTYPE.개별알람자동)) ////직접입력이므로 데이터베이스를 사용한다. { gi.alamh = DrChannel.ALAMH;// gi.alaml = DrChannel.ALAML; gi.aalamh = DrChannel.AUTOH; gi.aalaml = DrChannel.AUTOL; } else if (gi.알람형태 == COMM.EALAMTYPE.사용안함) { gi.alamh = -999f; gi.alaml = -999f; gi.aalamh = -999f; gi.aalaml = -999f; } else if (gi.알람형태 == COMM.EALAMTYPE.그룹설정을따름) { gi.alamh = G1.HIGH; gi.alaml = G1.LOW; gi.aalamh = G1.UP; gi.aalaml = G1.UP; } gi.이름 = DrChannel.TITLE;// System.Convert.ToString(DrChannel["TITLE"]); gi.사용 = DrChannel.ENABLE > 0;// System.Convert.ToBoolean(DrChannel["ENABLE"]); MACHINE = DrChannel.MACHINE.Trim();// ["MACHINE"].ToString().Trim(); } if (!string.IsNullOrEmpty(MACHINE)) ////장비정보가 있다면 { int DEVIDX = int.Parse(MACHINE.Split(",".ToCharArray())[0]); int UNITNO = int.Parse(MACHINE.Split(",".ToCharArray())[1]); int CHNO = int.Parse(MACHINE.Split(",".ToCharArray())[2]); ////디바이스를 열어서 순서대로 한다. var DTDEV = PUB.DS.DEVICE.Where(t => t.USE == 1).OrderBy(t => t.IDX); short DTDEVIDX = 0; short deviceidx = -1; foreach (var DRdev in DTDEV) { if (DRdev.IDX == DEVIDX) { deviceidx = DTDEVIDX; break; } DTDEVIDX++; } gi.idx_dev = deviceidx; gi.idx_ch = (short)(CHNO - 1); gi.idx_unit = (short)UNITNO; gi.활성화 = false; } else ////장비정보가없는경우에는 사용을 중지한다. { gi.idx_dev = -1; gi.idx_ch = -1; gi.idx_unit = -1; gi.사용 = false; gi.활성화 = false; } alamstr = "↑" + gi.HIGH.ToString() + " ↓" + gi.LOW.ToString(); if (gi.이름.Length > maxname.Length) { maxname = gi.이름; } if (alamstr.Length > maxalam.Length) { maxalam = alamstr; } G1item[i] = gi; } G1.maxcellname = maxname; G1.maxcellvalue = "10.000"; G1.maxcellalam = "88.8.88"; G1.Items = G1item; GroupItems[GIDX] = G1;//.GROUPS[GIDX] = G1; GIDX++; } PUB.MainGroup = GroupItems; PUB.SaveGroupClass(PUB.MainGroup, infofile); } ////make channel info / groups //set UI Control this.DispCtrl1.GROUPS = PUB.MainGroup; ////장치갯수 int Devcnt = PUBC.GetUseDeviceCount(); DispCtrl1.initpercent = 100; DispCtrl1.initmsg = "Init Value Buffer"; ////값초기화 var maxmcno = PUB.DS.DEVICE.Any() ? PUB.DS.DEVICE.Max(t => t.IDX) : -1; var maxunno = PUB.DS.CHANNEL.Any() ? PUB.DS.CHANNEL.Max(t => t.IDX_U) : -1; var maxchno = PUB.DS.CHANNEL.Any() ? PUB.DS.CHANNEL.Max(t => t.IDX_C) : -1; if (maxmcno < 0) maxmcno = 0; if (maxunno < 0) maxunno = 5; if (maxchno < 0) maxchno = 59; PUB.Values = new int[maxmcno + 1, maxunno + 1, maxchno + 1]; PUB.Times = new string[maxmcno + 1, maxunno + 1, maxchno + 1]; PUB.ChNos = new int[maxmcno + 1, maxunno + 1, maxchno + 1]; PUB.ChVOffset = new float[maxmcno + 1, maxunno + 1, maxchno + 1]; PUB.ChDecPos = new byte[maxmcno + 1, maxunno + 1, maxchno + 1]; PUB.chUse = new bool[maxmcno + 1, maxunno + 1, maxchno + 1]; PUB.ChfirstSave = new bool[maxmcno + 1, maxunno + 1, maxchno + 1]; for (int c = 0; c <= maxmcno - 1; c++) { for (int i = 0; i <= maxunno; i++) { for (int k = 0; k <= maxchno; k++) { PUB.Values[c, i, k] = 0; PUB.Times[c, i, k] = ""; PUB.ChVOffset[c, i, k] = 0f; PUB.ChDecPos[c, i, k] = 0; PUB.chUse[c, i, k] = false; PUB.ChfirstSave[c, i, k] = false; } } } //채널정보에서 각 인덱스별 채널번호를 할당해준다 foreach (var dr in PUB.DS.CHANNEL.Where(t => t.IDX_M >= 0 && t.IDX_U >= 0 && t.IDX_C >= 0)) { PUB.ChNos[dr.IDX_M, dr.IDX_U, dr.IDX_C] = dr.IDX;//채널번호를 설정 PUB.ChVOffset[dr.IDX_M, dr.IDX_U, dr.IDX_C] = dr.VOFFSET;//채널번호를 설정 PUB.ChDecPos[dr.IDX_M, dr.IDX_U, dr.IDX_C] = (byte)dr.DECPOS;//채널번호를 설정 PUB.chUse[dr.IDX_M, dr.IDX_U, dr.IDX_C] = dr.USE == 1;//채널번호를 설정 } ////장치의 disable을 초기화 foreach (var Mc in PUB.DAQ) Mc.Disable = true; PUB.StatusMSG("Ready..."); this.DispCtrl1.initmsg = "Complete"; this.DispCtrl1.init = true; this.DispCtrl1.Values = PUB.Values; this.DispCtrl1.Times = PUB.Times; this.DispCtrl1.SmallSize = PUB.CONFIG.viewSize; ////개별표시모드일떄 사용하는 윈도우의 크기 this.DispCtrl1.FullScreen = true; this.DispCtrl1.Refresh(); this.DispCtrl1.ResumeLayout(); if (Devcnt == 0) { this.DispCtrl1.init = false; this.DispCtrl1.initmsg = "사용가능한 장치가 존재하지않습니다.\n환경설정을 확인하세요."; } else if (this.DispCtrl1.GroupCount < 1) { this.DispCtrl1.init = false; this.DispCtrl1.initmsg = "등록된 그룹이 없습니다.\n환경설정을 확인하세요."; } else if (this.DispCtrl1.GroupItemCount == 0) { this.DispCtrl1.init = false; this.DispCtrl1.initmsg = "셀 정보를 확인할 수 없습니다.\n환경설정을 확인하세요."; } TableLayoutPanel1.ColumnStyles[1].Width = DispCtrl1.FullScreen ? 0 : (PUB.CONFIG.maintv_winsize); formsPlot1.Plot.Clear(); CrossHair = formsPlot1.Plot.Add.Crosshair(0, 0); CrossHair.TextColor = ScottPlot.Colors.White; CrossHair.TextBackgroundColor = CrossHair.HorizontalLine.Color; formsPlot1.Refresh(); //make kaindex PUB.KA1_IndexList.Clear(); PUB.KA1_SUM = 0f; var GroupRows2 = PUB.DS.GRP.Where(t => t.USE == 1 && t.WINDOW == 1).OrderBy(t => t.TITLE);// foreach (var GDr in GroupRows2) { if (GDr.KADEVICE.isEmpty()) continue; var _ampidx = GDr.KADEVICE; // DReader("KADEVICE") var gg1 = GDr.KADEVICE.Split(",".ToCharArray())[0].toInt(); //device var ggU = GDr.KADEVICE.Split(",".ToCharArray())[1].toInt(); var gg2 = GDr.KADEVICE.Split(",".ToCharArray())[2].toInt(); ////디바이스를 열어서 순서대로 한다. var DTDEV = PUB.DS.DEVICE.Where(t => t.USE == 1).OrderBy(t => t.IDX);// short DTDEVIDX = 0; short deviceidx = (-1); foreach (DocumentElement.DEVICERow DRdev in DTDEV) { if (DRdev.IDX == gg1) { deviceidx = DTDEVIDX; break; } DTDEVIDX++; } if (deviceidx != -1) PUB.KA1_IndexList.Add($"{deviceidx},{ggU},{gg2}"); } } delegate void UpdateConnectionDisplayHandler(int idx, ConnState Value); private void UpdateConnectionDisplayLabel(int idx, ConnState Value) { if (this.InvokeRequired) { this.BeginInvoke(new UpdateConnectionDisplayHandler(UpdateConnectionDisplayLabel), idx, Value); return; } if (idx >= 0) { if (idx < this.mclabels.Length) { if (Value == ConnState.Connected) this.mclabels[idx].ForeColor = Color.Green; else if (Value == ConnState.Disconnected) this.mclabels[idx].ForeColor = Color.Red; else if (Value == ConnState.TryConnect) this.mclabels[idx].ForeColor = Color.Blue; this.mclabels[idx].Invalidate(); } } else { foreach (var item in mclabels) { if (Value == ConnState.Connected) item.ForeColor = Color.Green; else if (Value == ConnState.Disconnected) item.ForeColor = Color.Red; else if (Value == ConnState.TryConnect) item.ForeColor = Color.Blue; item.Invalidate(); } } } public void btConfig_Click(System.Object sender, System.EventArgs e) { var prestate = PUB.sm.Step == COMM.ESMStep.RUN; if (prestate == true) { var dlg = UTIL.MsgQ("모니터링을 OFF 해야 설정을 사용할 수 있습니다.\n지금 모니터링을 OFF 할까요?"); if (dlg != DialogResult.Yes) return; else PUB.RunMonitor(); } var f = new Frm_Config(); if (f.ShowDialog() == DialogResult.OK) ////설정을 갓다오면 모두 재 구성한다. { MakeTempDatabase(); displayinfo(); REFRESHCHART(true); if (PUB.CONFIG.opensubwindow) { /* 작성자: 이재웅, 작성일: 2024-10-28, 작성내용: sub 화면이 필요하지 않을때(= null) 제외한다. */ if (PUB.subWindow != null) { PUB.subWindow.MakeTempDatabase(); PUB.subWindow.REFRESHCHART(true); } } ////Sleep Timeout //var drNormal = PUB.DS.NORMAL.FirstOrDefault(); //if (drNormal != null && drNormal.IsTSPEEDNull() == false) PUB.sleeplimit = drNormal.TSPEED;// System.Convert.ToInt32(pub.DS.NORMAL[0].TSPEED); // DBC.GetScalar("select TSPEED from NORMAL") //else PUB.sleeplimit = 0; //if (PUB.sleeplimit < 2) PUB.sleeplimit = 200; MakeMCLabels(); } if (prestate) PUB.RunMonitor(); } void MakeMCLabels() { var keyname = "MCSTATE"; //var items = this.StatusStrip1.Items.Find(keyname, true); //this.StatusStrip1.Items.RemoveByKey(keyname); while (StatusStrip1.Items.ContainsKey(keyname)) { this.StatusStrip1.Items.RemoveByKey(keyname); } this.mclabels = new ToolStripLabel[PUB.DAQ.Length]; //기존에등록된 라벨을 삭제 var idx = 0; foreach (var DAQ in PUB.DAQ) { var newlbst = new ToolStripStatusLabel(); newlbst.Text = "●"; newlbst.Tag = keyname; newlbst.Name = keyname; newlbst.Alignment = ToolStripItemAlignment.Right; newlbst.ImageKey = keyname; this.StatusStrip1.Items.Add(newlbst); mclabels[idx++] = newlbst; } } private void displayinfo() { // var infodata = PUB.DS.NORMAL.FirstOrDefault(); // PUB.CONFIG.sangho = infodata == null ? "CompanyName" : infodata.SANGHO;// this.Text = $"[{PUB.CONFIG.sangho}] {Application.ProductName} Ver.{Application.ProductVersion}"; this.lb_chcount.Text = $""; ; } /// /// show subwindow /// /// private void Func_OpenSubWindow() { if (PUB.subWindow == null || PUB.subWindow.IsDisposed) { PUB.subWindow = new Frm_Sub(); } if (Screen.AllScreens.Length > 1) { PUB.subWindow.Location = new Point(System.Convert.ToInt32(Screen.AllScreens[0].WorkingArea.Width), 0); PUB.subWindow.Bounds = Screen.AllScreens[1].Bounds; PUB.subWindow.Show(); } else { PUB.subWindow.Show(); } } public void bt_show2ndwindow_Click(System.Object sender, System.EventArgs e) { Func_OpenSubWindow(); } private void DispCtrl1_OnClickCell(HMI.CITEM idx, MouseEventArgs e) { // 임의의 채널선택 if (e.Button == System.Windows.Forms.MouseButtons.Left) { PUB.log.Add(AR.Log.ETYPE.NORMAL, "셀클릭확인되어서 셀정보를 표시합니다"); using (var f = new Frm_Cell(idx)) f.ShowDialog(); } else if (e.Button == System.Windows.Forms.MouseButtons.Right) { using (var f = new Setting.fDesignSetting()) { if (f.ShowDialog() == DialogResult.OK) { PUB.RaiseRemoteCommandEvent(rCommand.RefreshChart); } } //Me.ContextMenuStrip1.Show() //Me.ContextMenuStrip1.SetBounds(e.Location.X + DispCtrl1.Left, e.Location.Y + DispCtrl1.Top, 100, 100) } } private void DispCtrl1_OnClickGroup(HMI.CGROUP idx, MouseEventArgs e) { if (e.Button == System.Windows.Forms.MouseButtons.Left) { PUB.log.Add(AR.Log.ETYPE.NORMAL, "셀그룹클릭확인되어서 셀정보를 표시합니다"); Frm_Grp F = new Frm_Grp(idx); F.ShowDialog(); var infofile = new System.IO.FileInfo("window1.grp"); PUB.SaveGroupClass(PUB.MainGroup, infofile); //REFRESHCHART(True) } } public void ToolStripButton1_Click_2(System.Object sender, System.EventArgs e) { var filename = new System.IO.FileInfo(".\\Trendviewer\\TrendViewer.exe"); if (filename.Exists == false) { UTIL.MsgE("트렌드뷰어 프로그램이 존재하지 않습니다.\n개발사에 문의 하세요"); return; } UTIL.RunProcess(filename.FullName, filename.Directory.Parent.FullName); } public void ToolStripButton2_Click_1(System.Object sender, System.EventArgs e) { var filename = new System.IO.FileInfo(".\\AlarmViewer\\AlarmViewer.exe"); if (filename.Exists == false) { UTIL.MsgE("알람뷰어 프로그램이 존재하지 않습니다.\n개발사에 문의 하세요"); return; } UTIL.RunProcess(filename.FullName, filename.Directory.Parent.FullName); //PUB.ShowForm(falarm, typeof(Frm_Alamlist)); } public void ToolStripButton1_Click_4(System.Object sender, System.EventArgs e) { using (var f = new Frm_Alam()) if (f.ShowDialog() == System.Windows.Forms.DialogResult.OK) { PUB.log.Add(AR.Log.ETYPE.NORMAL, "알람설정화면확인"); ////auto로 된 그룹의 기준값을 변경한다. this.DispCtrl1.SuspendLayout(); foreach (HMI.CGROUP c in DispCtrl1.GROUPS) { if (c.AlarmType == "AUTO") { ////이그룹을 사용하는 모든셀의 auto값을 초기화한다. foreach (HMI.CITEM i in c.Items) { i.alamv = -999; } } else if (c.AlarmType == "STOP") { c._alamcount = (short)0; c._alamcountlb = (short)0; } } this.DispCtrl1._raise_alarm_pre = true; ////혹알람이 발생되어있을지 모르니. 끄도록 발생한것 처럼 표시해준다. this.DispCtrl1.ResumeLayout(); this.DispCtrl1.Invalidate(); ////설정정보를 가져온다. PUB.SaveConfigFile("GRP"); } } private void DispCtrl1_OnAlamChangeL(int ch, COMM.EALAMRAISETYPE ison, COMM.EALAMTYPE atype, string AM, float value, float maxvalue, float minvalue) { TimeSpan ts = DateTime.Now - PUB.StartupTime; if (ts.TotalSeconds < PUB.CONFIG.Startup_DelayTime_Alam) return; bool rlt = PUB.Alarm.InsertData(DateTime.Now, ch, ison, value, atype, maxvalue, minvalue, AM, ""); PUB.log.Add(AR.Log.ETYPE.NORMAL, "알람이 발생되었습니다(ch=" + ch.ToString() + ",type=" + ison.ToString() + ", value=" + value.ToString() + ", min=:" + minvalue.ToString() + ",max=" + maxvalue.ToString() + ",atype=" + atype.ToString() + " ,am=" + AM); } private void DispCtrl1_OnSetNullbalance(HMI.CGROUP grp, float value) { ////이그룹의 널벨런스 값을 변경한다. if (!PUBC.UpdateNullBalanceOffset(grp.IDX, value)) { UTIL.MsgE("Null Balance 값 저장실패"); PUB.log.Add(Log.ETYPE.ERROR, "N/B값 저장실패 idx=" + grp.IDX.ToString() + ",value=" + value.ToString()); } else { PUB.log.Add(Log.ETYPE.NORMAL, "N/B 값 저장완료"); } } public void lb_Saved_Click(System.Object sender, System.EventArgs e) { if (SaveError.ToString() != "") { UTIL.MsgI(SaveError.ToString()); } } public void ToolStripButton1_Click_6(System.Object sender, System.EventArgs e) { var f = new Frm_About(); f.ShowDialog(); } private void DispCtrl1_RaiseAlarm(bool On) { PUB.Set_Sound(On, true); lb_alarm.ForeColor = On ? Color.Red : Color.Gray; } public void bt_save_Click(System.Object sender, System.EventArgs e) { // 저장(F5) -> current_Main.csv 저장 var buf = new System.Text.StringBuilder(); var bufdata = new System.Text.StringBuilder(); foreach (HMI.CGROUP g in this.DispCtrl1.GROUPS) { buf.Append(g.이름); string lasttime = ""; System.Text.StringBuilder valuebuffer = new System.Text.StringBuilder(); foreach (HMI.CITEM gi in g.Items) { if (string.IsNullOrEmpty(lasttime)) { lasttime = gi.측정시간; } buf.Append("," + gi.이름); valuebuffer.Append("," + gi.측정값); } buf.Append("\r\n"); buf.Append(lasttime); buf.Append(valuebuffer.ToString()); buf.Append("\r\n"); buf.Append("\r\n"); } //if (PUB.CONFIG.opensubwindow && PUB.subgroup != null) //{ // foreach (HMI.CGROUP g in PUB.subgroup) // { // buf.Append(g.이름); // string lasttime = ""; // var valuebuffer = new System.Text.StringBuilder(); // foreach (HMI.CITEM gi in g.Items) // { // if (string.IsNullOrEmpty(lasttime)) // { // lasttime = gi.측정시간; // } // buf.Append("," + gi.이름); // valuebuffer.Append("," + gi.측정값); // } // buf.Append("\r\n"); // buf.Append(lasttime); // buf.Append(valuebuffer.ToString()); // buf.Append("\r\n"); // buf.Append("\r\n"); // } //} try { var fn = UTIL.MakePath(UTIL.CurrentPath, "current_Main.csv"); System.IO.File.WriteAllText(fn, buf.ToString(), System.Text.Encoding.Default); PUB.log.Add(AR.Log.ETYPE.NORMAL, "Save Current(Main) Data CsV"); UTIL.RunExplorer(fn); } catch (Exception ex) { UTIL.MsgE($"현재데이터 저장실패\r\n{ex.Message}"); PUB.log.Add(AR.Log.ETYPE.ERROR, "현재데이터(Main) 저장실패:" + ex.Message.ToString()); } } private void DispCtrl1_OnClickPrint(HMI.CGROUP idx) { PUB.printgrp = idx; this.PrintGroup.DefaultPageSettings.Landscape = false; try { this.PPreviewDialog.ShowDialog(); } catch (Exception ex) { UTIL.MsgE(ex.Message); } } #region "Print" public void PrintDocument1_PrintPage(System.Object sender, System.Drawing.Printing.PrintPageEventArgs e) { ////출력그룹이 있야한다. if (PUB.printgrp == null) { UTIL.MsgE("선택된 그룹이 없으므로 출력을 할 수 없습니다"); return; } ////graphics capsule Point margin = new Point(30, 30); Graphics G = e.Graphics; SizeF pagesize = new SizeF(PrintGroup.DefaultPageSettings.PaperSize.Width - (margin.X * 2), PrintGroup.DefaultPageSettings.PaperSize.Height - (margin.Y * 2)); Rectangle windowRect = new Rectangle(margin.X, margin.Y, System.Convert.ToInt32(pagesize.Width), System.Convert.ToInt32(pagesize.Height)); ////G.DrawRectangle(Pens.Red, windowRect) ////G.DrawString(pagesize.ToString, Me.Font, Brushes.Red, margin.X, margin.Y) ////데이텅영역 Rectangle DataRect = new Rectangle(margin.X, margin.Y * 2, System.Convert.ToInt32(pagesize.Width), System.Convert.ToInt32(pagesize.Height - margin.Y * 2)); ////G.DrawRectangle(Pens.Blue, DataRect) ////G.DrawString(DataRect.ToString, Me.Font, Brushes.Blue, DataRect.Left, DataRect.Top) ////출력일시표시 string title = "출력일시 : " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); Font titlefont = new Font("돋움", 10, FontStyle.Bold); SizeF fontsize = G.MeasureString(title, titlefont); float Y = DataRect.Top + DataRect.Height + 10; float X = margin.X + DataRect.Width - fontsize.Width; G.DrawString(title, titlefont, Brushes.Black, X, Y); ////가운데정렬 해서 출력 title = "[" + PUB.CONFIG.sangho + "] Cell Voltage Monitoring System"; fontsize = G.MeasureString(title, titlefont); X = margin.X; G.DrawString(title, titlefont, Brushes.Black, X, Y); ////가운데정렬 해서 출력 //Dim bottommargin As Integer = 50 //Dim WindowRect As RectangleF = New RectangleF(30, Y, pagesize.Width * 0.7, pagesize.Height - Y - bottommargin) //Dim ChartRect As RectangleF = New RectangleF(WindowRect.Left + 50, WindowRect.Top + 50, WindowRect.Width - (50 * 2), WindowRect.Height - (50 * 2)) //'Dim 상호명 As String = DBC.GetScalar("select SANGHO from NORMAL") //Dim 상호font As New Font("나눔고딕", 18, FontStyle.Bold) //Dim 상호size As SizeF = G.MeasureString(상호명, 상호font) //G.DrawString(상호명, 상호font, Brushes.Black, WindowRect.Left, WindowRect.Top - 상호size.Height - 10) //Y += 상호size.Height SizeF itemsize = new SizeF(DataRect.Width, DataRect.Height); ////이미지생성해서 그린다. this.DispCtrl1.DrawGroup(G, PUB.printgrp, new Point(0, 0), itemsize, DataRect, 0, 0, true, true); G.DrawRectangle(Pens.Gray, DataRect); G.Dispose(); } public void bt_print_Click(System.Object sender, System.EventArgs e) { this.PrintWin.DefaultPageSettings.Landscape = true; this.PrintPreViewWin.ShowDialog(); } public void PrintWin_PrintPage(System.Object sender, System.Drawing.Printing.PrintPageEventArgs e) { ////현재윈도우를 화면으로 출력 ////graphics capsule Point margin = new Point(30, 30); Graphics G = e.Graphics; SizeF pagesize = new SizeF(PrintGroup.DefaultPageSettings.PaperSize.Height - (margin.X * 2), PrintGroup.DefaultPageSettings.PaperSize.Width - (margin.Y * 2)); Rectangle windowRect = new Rectangle(margin.X, margin.Y, (int)(pagesize.Width), (int)(pagesize.Height)); Rectangle DataRect = new Rectangle(margin.X, margin.Y * 2, (int)(pagesize.Width), (int)(pagesize.Height - margin.Y * 2)); ////출력일시표시 string title = "출력일시 : " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); Font titlefont = new Font("돋움", 10, FontStyle.Bold); SizeF fontsize = G.MeasureString(title, titlefont); float Y = DataRect.Top + DataRect.Height + 10; float X = margin.X + DataRect.Width - fontsize.Width; G.DrawString(title, titlefont, Brushes.Black, X, Y); ////가운데정렬 해서 출력 title = "[" + PUB.CONFIG.sangho + "] Cell Voltage Monitoring System"; fontsize = G.MeasureString(title, titlefont); X = margin.X; G.DrawString(title, titlefont, Brushes.Black, X, Y); ////가운데정렬 해서 출력 SizeF itemsize = new SizeF((float)((double)DataRect.Width / this.DispCtrl1.WINDOW.CoulumnCount), (float)((double)DataRect.Height / this.DispCtrl1.WINDOW.RowCount)); foreach (HMI.CGROUP Grp in this.DispCtrl1.GROUPS) { //MsgBox(Grp.이름) this.DispCtrl1.DrawGroup(G, Grp, new Point(0, 0), itemsize, DataRect, Grp.열번호, Grp.줄번호, true, true); } G.DrawRectangle(Pens.Gray, DataRect); G.Dispose(); } #endregion private void Refresh_전해조목록() { this.cmb_tanks.Items.Clear(); var itemlist = DispCtrl1.GROUPS.Select(t => $"[{t.IDX:00}] {t.이름}").ToArray(); if (itemlist == null) { UTIL.MsgE("선택가능한 목록이 없습니다"); return; } this.cmb_tanks.Items.AddRange(itemlist); } public void ToolStripButton2_Click(System.Object sender, System.EventArgs e) { PUB.log.Add(AR.Log.ETYPE.NORMAL, "소리끄기실행"); PUB.Set_Sound(false, true); ////disable sound from user PUB.Set_Sound(false, false); ////disable sound from user 보조화면도 소리를 끈다. if (PUB.CONFIG.alamplc && PUB.masterk.IsOpen()) { if (PUB.masterk.isValid) { if (PUB.masterk.SetOutput(PUB.CONFIG.plc_addr, false)) { PUB.log.Add("소리끄기기능에서 PLC도 끔"); } } else { PUB.log.Add("ERROR", "plc상태가 유효하지 않습니다 OFF실패"); } } } public void bt_fullscreen_Click(object sender, EventArgs e) { DispCtrl1.FullScreen = !DispCtrl1.FullScreen; DispCtrl1.bMakeRect = true; if (DispCtrl1.FullScreen) { bt_fullscreen.Text = "개별보기"; } else { this.formsPlot1.Plot.Clear(); CrossHair = formsPlot1.Plot.Add.Crosshair(0, 0); CrossHair.TextColor = ScottPlot.Colors.White; CrossHair.TextBackgroundColor = CrossHair.HorizontalLine.Color; this.Streamer1 = new ScottPlot.Plottables.Scatter[0]; this.dataVolt = new List[0]; this.dataTime = new List[0]; this.formsPlot1.Refresh(); bt_fullscreen.Text = "전체보기"; Refresh_전해조목록(); //0번 전해조 선택 if (this.cmb_tanks.Items.Count > 0) this.cmb_tanks.SelectedIndex = 0; var grpName = cmb_tanks.Text.Substring(4).Trim(); var grpNo = int.Parse(cmb_tanks.Text.Substring(1, 2)); //현재선택된 그룹의 채널목록을 추출해야한다. if (grpName.isEmpty() == false) { var drGrp = documentElement1.GRP.Where(t => t.TITLE == grpName).FirstOrDefault(); if (drGrp != null) { //채널목록을 확인한다. var chrows = documentElement1.CHANNEL.Where(t => t.GIDX == drGrp.IDX); if (chrows.Any() == true) { var uselist = ds1.channel.Where(t => t.IsuseNull() == false && t.use == true).ToList(); this.formsPlot1.Plot.Remove(); //데이터스트림삭제 this.formsPlot1.Refresh(); this.selectchlist.Clear(); if (uselist != null && uselist.Any() == true) { foreach (var item in uselist) { int idx = item.idx; //지정된 플롯의 표시여부를 변경한다. if (this.Streamer1.Length < idx) { Array.Resize(ref Streamer1, idx); Array.Resize(ref dataVolt, idx); Array.Resize(ref dataTime, idx); } if (dataTime[idx - 1] == null) dataTime[idx - 1] = new List(); if (dataVolt[idx - 1] == null) dataVolt[idx - 1] = new List(); if (Streamer1[idx - 1] == null) Streamer1[idx - 1] = formsPlot1.Plot.Add.ScatterPoints(dataTime[idx - 1], dataVolt[idx - 1]); Streamer1[idx - 1].LineWidth = 1; Streamer1[idx - 1].MarkerSize = 0; Streamer1[idx - 1].LegendText = $"CH{idx}"; Streamer1[idx - 1].IsVisible = true; selectchlist.Add(idx); //선택채널에 추가한다. } } if (CrossHair == null) { CrossHair = formsPlot1.Plot.Add.Crosshair(0, 0); CrossHair.TextColor = ScottPlot.Colors.White; CrossHair.TextBackgroundColor = CrossHair.HorizontalLine.Color; } formsPlot1.Plot.Axes.ContinuouslyAutoscale = true; this.formsPlot1.Refresh(); } } } } DispCtrl1.Invalidate(); TableLayoutPanel1.ColumnStyles[1].Width = DispCtrl1.FullScreen ? 0f : (PUB.CONFIG.maintv_winsize); } public void cmb_group_SelectedIndexChanged(object sender, EventArgs e) { if (this.cmb_tanks.SelectedIndex < 0) return; /* 작성자: 이재웅, 작성일: 2024-11-22, 내용: 차트/Scatter/Volt/Time 초기화 */ this.formsPlot1.Plot.Clear(); this.Streamer1 = new ScottPlot.Plottables.Scatter[0]; this.dataVolt = new List[0]; this.dataTime = new List[0]; /**********************************************************************/ Console.WriteLine("개별 index = " + this.cmb_tanks.SelectedIndex.ToString()); this.DispCtrl1.ShowIndex = this.cmb_tanks.SelectedIndex; this.DispCtrl1.Refresh(); //현재등록된 목록을 모두 삭제 this.ds1.channel.Clear(); this.formsPlot1.Plot.Remove(); //데이터스트림삭제 this.formsPlot1.Refresh(); var grpName = cmb_tanks.Text.Substring(4).Trim(); var grpNo = int.Parse(cmb_tanks.Text.Substring(1, 2)); var grpdr = this.documentElement1.GRP.Where(t => t.TITLE.Equals(grpName)).FirstOrDefault(); if (grpdr == null) return; var chlist = this.documentElement1.CHANNEL.Where(t => t.GIDX == grpdr.IDX); if (chlist.Any() == false) return; // 미리저장된 목록을 확인한다. var chstr = ""; if (grpNo == 0) chstr = PUB.CONFIG.grp0chlist; else if (grpNo == 1) chstr = PUB.CONFIG.grp1chlist; else if (grpNo == 2) chstr = PUB.CONFIG.grp2chlist; else if (grpNo == 3) chstr = PUB.CONFIG.grp3chlist; else if (grpNo == 4) chstr = PUB.CONFIG.grp4chlist; else if (grpNo == 5) chstr = PUB.CONFIG.grp5chlist; else if (grpNo == 6) chstr = PUB.CONFIG.grp6chlist; else if (grpNo == 7) chstr = PUB.CONFIG.grp7chlist; else if (grpNo == 8) chstr = PUB.CONFIG.grp8chlist; else if (grpNo == 9) chstr = PUB.CONFIG.grp9chlist; var chbuf = chstr.Split((char[])(new[] { ',' }), StringSplitOptions.RemoveEmptyEntries); //목록은 추가하지만 스트립을 추가하지 않으니 최초 선택시에는 데이터가 나오지 않는다. //사용자는 채널 선택을 사용해야 데이터가 보인다. this.ds1.channel.Clear(); this.selectchlist.Clear(); foreach (var dr in chlist) { var newdr = ds1.channel.NewchannelRow(); newdr.idx = dr.IDX; newdr.use = chbuf.Contains(dr.IDX.ToString()) ? true : false; newdr.c1 = ""; newdr.c2 = ""; newdr.cname = dr.TITLE; newdr.cc = dr.COLOR; ds1.channel.AddchannelRow(newdr); } ds1.channel.AcceptChanges(); formsPlot1.Refresh(); } private void DispCtrl1_OnChangedShowIndex(int index) { ////개별표시일때 표시되는 인덱스가 바뀐경우에 처리해야할 사항 ////트렌드뷰가 해당 데이터를 표시할 수 있도록 설정을 변경해줘야한다. //If Not Init Then Return if (DispCtrl1.FullScreen || DispCtrl1.GROUPS == null) return; HMI.CGROUP Grp = DispCtrl1.GROUPS[index]; this.BarCtrl1.Group = Grp; this.BarCtrl1.bMakeBarRect = true; } /// /// 메인화면의 데이터가 업데이트된 후 발생함 /// /// private void DispCtrl1_OnNotifyData(DateTime Currenttime) { } public void DataPointToolStripMenuItem_Click(object sender, EventArgs e) { } public void DebugMsgToolStripMenuItem_Click(object sender, EventArgs e) { } public void GraphReSetToolStripMenuItem_Click(object sender, EventArgs e) { formsPlot1.Plot.Axes.AutoScale(); formsPlot1.Refresh(); } #region Contenxt Menu Item Events /// /// Y축 표시간격 /// /// /// /// private void ToolStripMenuItem5_Click(object sender, EventArgs e) { //////메뉴하단의 모든 아이템의 체크를 해제한다. //foreach (ToolStripMenuItem item in this.menus_ygap.DropDownItems) //{ // item.Checked = false; //} //ToolStripMenuItem Ctl = (ToolStripMenuItem)sender; //string txt = Ctl.Tag.ToString().Trim(); //float SngVal = 0; //if (float.TryParse(txt, out SngVal)) //{ // formsPlot1.Style.YGap = SngVal; // formsPlot1.Set_Refresh(); // formsPlot1.Refresh(); // PUB.CONFIG.maintv_ygap = SngVal;//.ToString(); // Ctl.Checked = true; //} //else //{ // UTIL.MsgE("입력값이 잘못되었습니다"); //} } /// /// X축 표시범위 버튼 /// /// /// /// private void cmbt_x_1800_Click(object sender, EventArgs e) { //////메뉴하단의 모든 아이템의 체크를 해제한다. //foreach (ToolStripMenuItem item in this.menus_xterm.DropDownItems) //{ // item.Checked = false; //} //ToolStripMenuItem Ctl = (ToolStripMenuItem)sender; //string txt = Ctl.Tag.ToString().Trim(); //if (int.TryParse(txt, out int SngVal)) //{ // formsPlot1.Style.X표시범위 = SngVal; // formsPlot1.Set_Refresh(); // formsPlot1.Refresh(); // if (PUB.CONFIG.opensubwindow) // { // PUB.subWindow.TrendCtrlII1.Style.X표시범위 = SngVal; // PUB.subWindow.TrendCtrlII1.Set_Refresh(); // PUB.subWindow.TrendCtrlII1.Refresh(); // } // Ctl.Checked = true; // PUB.CONFIG.maintv_xterm = SngVal; //} //else //{ // UTIL.MsgE("입력값이 잘못되었습니다"); //} } /// /// X축 간격버튼 /// /// /// /// private void cmbt_x_gap_30_Click(object sender, EventArgs e) { //////메뉴하단의 모든 아이템의 체크를 해제한다. //foreach (ToolStripMenuItem item in this.menus_xgap.DropDownItems) //{ // item.Checked = false; //} //ToolStripMenuItem Ctl = (ToolStripMenuItem)sender; //string txt = Ctl.Tag.ToString().Trim(); //if (int.TryParse(txt, out int SngVal)) //{ // formsPlot1.Style.XGap = SngVal; // formsPlot1.Set_Refresh(); // formsPlot1.Refresh(); // if (PUB.CONFIG.opensubwindow) // { // PUB.subWindow.TrendCtrlII1.Style.XGap = SngVal; // PUB.subWindow.TrendCtrlII1.Set_Refresh(); // PUB.subWindow.TrendCtrlII1.Refresh(); // } // PUB.CONFIG.maintv_xgap = SngVal; // Ctl.Checked = true; //} //else //{ // UTIL.MsgE("입력값이 잘못되었습니다"); //} } private void Cmbt_winsize_click(object sender, EventArgs e) { ////메뉴하단의 모든 아이템의 체크를 해제한다. foreach (ToolStripMenuItem item in this.menus_winsize.DropDownItems) { item.Checked = false; } ToolStripMenuItem Ctl = (ToolStripMenuItem)sender; string txt = Ctl.Tag.ToString().Trim(); if (int.TryParse(txt, out int SngVal)) { TableLayoutPanel1.ColumnStyles[1].Width = System.Convert.ToSingle(DispCtrl1.FullScreen ? 0 : SngVal); if (PUB.CONFIG.opensubwindow) { PUB.subWindow.TableLayoutPanel1.ColumnStyles[1].Width = System.Convert.ToSingle(DispCtrl1.FullScreen ? 0 : SngVal); } PUB.CONFIG.maintv_winsize = SngVal; Ctl.Checked = true; } else { UTIL.MsgE("입력값이 잘못되었습니다"); } } public void Timer1_Tick(object sender, EventArgs e) { this.lbMonitor.Text = PUB.sm.Step == COMM.ESMStep.RUN ? "" : ""; string intervalFormatted = refreshinterval.ToString().PadLeft(6); this.lb_msec.Text = $""; if (SaveErrCount == 0) { this.lb_Saved.Text = $""; this.lb_Saved.ForeColor = Color.Black; } else { this.lb_Saved.Text = $""; this.lb_Saved.ForeColor = Color.Red; } DispCtrl1.MonitorOn = PUB.sm.Step == COMM.ESMStep.RUN; /* 작성자: 김치균, 작성일: 2024-09-10, 작성내용: Pause 문구 갱신속도 개선 */ DispCtrl1.Invalidate(); if (PUB.masterk != null && PUB.masterk.IsOpen()) { this.lbPLC.ForeColor = Color.Black; } else if (PUB.CONFIG.plc_port.isEmpty()) { this.lbPLC.ForeColor = Color.Gray; } else this.lbPLC.ForeColor = Color.Red; if (PUB.indicator != null && PUB.indicator.IsOpen) { this.lbINDI.ForeColor = Color.Black; } else if (PUB.CONFIG.indicator_port.isEmpty()) { this.lbINDI.ForeColor = Color.Gray; } else { this.lbINDI.ForeColor = Color.Red; } if (PUB.indicator.IsOpen) this.lbINDI.Text = $""; else this.lbINDI.Text = ""; bt_show2ndwindow.Enabled = !PUB.CONFIG.opensubwindow; } public void Button1_Click(object sender, EventArgs e) { //채널선택 var grpName = cmb_tanks.Text.Substring(4).Trim(); var grpNo = int.Parse(cmb_tanks.Text.Substring(1, 2)); //현재선택된 그룹의 채널목록을 추출해야한다. if (grpName.isEmpty()) { UTIL.MsgE("채널 그룹을 선택하세요"); return; } var drGrp = documentElement1.GRP.Where(t => t.TITLE == grpName).FirstOrDefault(); if (drGrp == null) { UTIL.MsgE("선택된 채널 그룹 정보가 없습니다"); return; } //채널목록을 확인한다. var chrows = documentElement1.CHANNEL.Where(t => t.GIDX == drGrp.IDX); if (chrows.Any() == false) { UTIL.MsgE("해당 그룹에 등록된 채널정보가 없습니다"); return; } //현재 등록된 채널정보를 토대로 데이터를 선택한다 using (var f = new Frm_SelectCH(ds1.channel)) { if (f.ShowDialog() == DialogResult.OK) { //현재등록된 목록을 모두 삭제 this.formsPlot1.Plot.Remove(); //데이터스트림삭제 this.formsPlot1.Refresh(); this.selectchlist.Clear(); //기존에 선택된 자료 선택하제 foreach (var item in ds1.channel.Where(t => t.use)) { item.use = false; } ds1.channel.AcceptChanges(); foreach (ListViewItem item in f.CheckedListBox1.Items) { int idx = int.Parse(item.Tag.ToString()); //.SubItems(0).Text) //지정된 플롯의 표시여부를 변경한다. if (this.Streamer1.Length < idx) { Array.Resize(ref Streamer1, idx); Array.Resize(ref dataVolt, idx); Array.Resize(ref dataTime, idx); } if (dataTime[idx - 1] == null) dataTime[idx - 1] = new List(); if (dataVolt[idx - 1] == null) dataVolt[idx - 1] = new List(); if (Streamer1[idx - 1] == null) Streamer1[idx - 1] = this.formsPlot1.Plot.Add.ScatterPoints(dataTime[idx - 1], dataVolt[idx - 1]); Streamer1[idx - 1].LineWidth = 1; Streamer1[idx - 1].MarkerSize = 0; Streamer1[idx - 1].LegendText = $"CH{idx}"; Streamer1[idx - 1].IsVisible = item.Checked; var dr = ds1.channel.Where(t => t.idx == idx).FirstOrDefault(); if (dr != null) { dr.use = item.Checked; dr.EndEdit(); } if (item.Checked) selectchlist.Add(idx); //선택채널에 추가한다. } //사용자목록에 저장한다 string chstr = string.Join(",", selectchlist.ToArray()); if (grpNo == 0) PUB.CONFIG.grp0chlist = chstr; else if (grpNo == 1) PUB.CONFIG.grp1chlist = chstr; else if (grpNo == 2) PUB.CONFIG.grp2chlist = chstr; else if (grpNo == 3) PUB.CONFIG.grp3chlist = chstr; else if (grpNo == 4) PUB.CONFIG.grp4chlist = chstr; else if (grpNo == 5) PUB.CONFIG.grp5chlist = chstr; else if (grpNo == 6) PUB.CONFIG.grp6chlist = chstr; else if (grpNo == 7) PUB.CONFIG.grp7chlist = chstr; else if (grpNo == 8) PUB.CONFIG.grp8chlist = chstr; else if (grpNo == 9) PUB.CONFIG.grp9chlist = chstr; PUB.CONFIG.Save(); if (CrossHair == null) { CrossHair = formsPlot1.Plot.Add.Crosshair(0, 0); CrossHair.TextColor = ScottPlot.Colors.White; CrossHair.TextBackgroundColor = CrossHair.HorizontalLine.Color; } formsPlot1.Plot.Axes.ContinuouslyAutoscale = true; this.formsPlot1.Refresh(); } } } public void ToolStripButton3_Click(object sender, EventArgs e) { UTIL.ShowForm(fTrendview, typeof(Frm_trend_Real), DispCtrl1); } #endregion private void toolStripButton3_Click_1(object sender, EventArgs e) { PUB.RunMonitor(); } private void bt_logo_Click(object sender, EventArgs e) { UTIL.RunExplorer(UTIL.CurrentPath); } private void toolStripButton3_Click_2(object sender, EventArgs e) { UTIL.ShowForm(flog, typeof(fLog)); } private void toolStripButton3_Click_3(object sender, EventArgs e) { var dt = DateTime.Now; var path = System.IO.Path.Combine(PUB.CONFIG.GetDatabasePath(), "Database", "Volt", dt.Year.ToString("0000"), dt.Month.ToString("00")); var di = new System.IO.DirectoryInfo(path); if (di.Exists == false) { UTIL.MsgE("저장 폴더가 존재하지 않습니다\n" + di.FullName); } else UTIL.RunExplorer(di.FullName); } } }