using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Text; using System.Windows.Forms; using System.Drawing.Drawing2D; using static System.Windows.Forms.VisualStyles.VisualStyleElement.TaskBand; using System.Linq; using System.Data.SqlTypes; using System.Diagnostics; using vmsnet.Attributes; using vmsnet.Configures; using AR; using ScottPlot.TickGenerators.TimeUnits; namespace vmsnet.HMI { public enum RelayControl { [Coil(address: 10)] mKA } public enum ESTATUS { 가동, 이상, 대기, 기타, 미사용 } public enum EDRAGTYPE { GROUP } public enum EBUTTONTYPE { CELL, GROUP, NBZERO, NBRESET, PRINT, SELGROUP, } public partial class DispCtrl : UserControl { public bool MonitorOn { get; set; } public CMouseinfo Mouseinfo; //마우스위치정보 //그룹데이터 public CGROUP[] GROUPS = new CGROUP[0]; public CWINDOW WINDOW = new CWINDOW(); object grplock = new object(); public void ResizeGroup(int newsize) { lock (grplock) { if (newsize > this.GROUPS.Length) { Array.Resize(ref GROUPS, newsize); } } } public void SetItemDisable() { lock (grplock) { foreach (var g in GROUPS) { foreach (var gi in g.Items) { gi.활성화 = false; gi._onalamh = false; gi._onalaml = false; gi._onalamover = false; gi._p_onalamh = false; gi._p_onalaml = false; gi._p_onalamover = false; gi.mtime = ""; } } } } public int GroupCount { get { if (GROUPS == null) return 0; if (GROUPS.Any() == false) return 0; return GROUPS.Length; } } public int GroupItemCount { get { if (GROUPS == null) return 0; if (GROUPS.Any() == false) return 0; return GROUPS[0].Items.Length; } } //public void SetGroupItem(CGROUP[] grp) //{ // lock (grplock) // { // GROUPS = grp; // } //} //public void SetGroupItem(int idx, CGROUP item) //{ // lock (grplock) // { // GROUPS[idx] = item; // } //} //public CGROUP[] GetGroupItem() //{ // lock (grplock) // { // return this.GROUPS; // } //} private int[,,] values; private String[,,] times; private Boolean _init = false; //그리드초기화완료여부 private String _initmsg = "initializing..."; public int initpercent = 0; //미정리 public int ZoneMarginX = 0; public int ZoneMarginY = 50; public Font Font_Nav = new Font("arial", 9); private Font FONT_NANUM_20_BOLD = new Font("나눔고딕", 20, FontStyle.Bold); private Font FONT_TAHOMA_80_BOLD = new Font("tahoma", 80, FontStyle.Bold); /// /// 데이터가 지정된 시간이 넘어가면 이벤트를 이용해서 알림을함(외부의 트렌드뷰에서 사용하려고함) /// public int NotifyDataSecond = 2; private DateTime LastNotifyTime = DateTime.Now.AddSeconds(-60); //alam1 blick private short blink1 = 0; private short blink2 = 0; private Boolean A1 = false; private Boolean A2 = false; public int SmallSize = 300; //140829 데이터분주 추가 (arin) public int datadiv = 1; public Font FONT_NB = new Font("Tahoma", 30, FontStyle.Bold); public Font FONT_CN = new Font("Tahoma", 8, FontStyle.Bold); public Font FONT_CV = new Font("Tahoma", 9, FontStyle.Bold); public Font FONT_CT = new Font("Tahoma", 8, FontStyle.Bold); public Font FONT_AV = new Font("Tahoma", 7, FontStyle.Bold); public Font FONT_KA = new Font("Arial", 40, FontStyle.Bold); //ka-value public Font FONT_KU = new Font("Arial", 10, FontStyle.Bold); //ka-unit public bool EnableKA { get; set; } = false; /// /// 개별보기일때 현재 표시해야할 아이템의 값이 변한경우 /// public event OnChangedShowIndexHandler OnChangedShowIndex; public delegate void OnChangedShowIndexHandler(int index); public event OnNotifyDataHandler OnNotifyData; public delegate void OnNotifyDataHandler(DateTime datetCurrenttime); //MY EVENT public event OnClickPrintHandler OnClickPrint; //click print public delegate void OnClickPrintHandler(CGROUP idx); public event OnClickProbeSensorHandler OnClickCell; //셀클릭 public delegate void OnClickProbeSensorHandler(CITEM idx, MouseEventArgs e); public event OnClickGroupHandler OnClickGroup; //그룹클릭 public delegate void OnClickGroupHandler(CGROUP idx, MouseEventArgs e); public event OnSetNBHandler OnSetNullbalance; //그룹클릭 public delegate void OnSetNBHandler(CGROUP grp, Single value); public event OnAlamChangeHHandler OnAlamChange; //알람이 변경되었을경우(활성/비활성) public delegate void OnAlamChangeHHandler(int ch, COMM.EALAMRAISETYPE raisetype, COMM.EALAMTYPE atype, String AM, Single value, Single maxvalue, Single minvalue, string remark); public event OnRaiseAlamChangeHHandler RaiseAlarm; //알람이 변경되었을경우(활성/비활성) public delegate void OnRaiseAlamChangeHHandler(Boolean On); public Boolean _raise_alarm = false; //알람발생여부 public Boolean _raise_alarm_pre = false; //알람발생여부(이전) private short _raise_alarm_count = 0; //셀알람발생카운트(모든그룹의합) private short _raise_alarm_nbcount = 0; //셀알람발생카운트(모든그룹의합) private short _pre_raise_alarm_count = 0; //이전알람발생시 만들어진 카운터 private short _pre_raise_alarm_nbcount = 0; //이전알람발생시 만들어진 널밸런트 카운터 public Boolean NullbalanceRealValue = true; public Boolean Sumab = false; //150320 //private CTrendData TrendData = new CTrendData(); //화면디자인관련 private Color bordercolor; //테두리 색상 private Cursor cursor = Cursors.Default; //현재커서의모양 private SolidBrush SB_White_200 = new SolidBrush(Color.FromArgb(200, Color.White)); private SolidBrush SB_WhiteSmoke_200 = new SolidBrush(Color.FromArgb(200, Color.WhiteSmoke)); private SolidBrush SB_Black_150 = new SolidBrush(Color.FromArgb(200, Color.Black)); public Color design_backcolor_start; public Color design_backcolor_normal; private string Warn_msg = ""; //경고메세지(화면 최상단중앙에 표시됨) private Font Warn_Font; private Font alamfont = new Font("Arial", 8, FontStyle.Bold); //ALAMICON_01 //기타설정' // public Rectangle[] GroupRect; //그룹머릿글 // public Rectangle headRect; //머릿부분 // public Rectangle ItemRect; //아이템표시영역(전체) // public Rectangle[] ItemsRect; //세부아이템표시영역(MATRIX 값에따라서 갯수가 변경된다) // public Rectangle[] NBRects; //nullbalance Area (그룹갯수별로 잇기때문에 여러개가된다) public RectangleF WindowRect; //윈도우데이터가표시되는 영역 // public RectangleF BarRect; //바그래프가 표시되는 영역 // public RectangleF TrendRect; //트렌드뷰가 표시되는 영역 // public RectangleF NavRect; //네비게이션이 표시되는 영역 private Font font_grouptitle = new Font("나눔고딕", 20, FontStyle.Bold); private Font font_header = new Font("나눔고딕", 10, FontStyle.Bold); private Color font_grouptitle_color = Color.Red; private Color font_header_color = Color.Yellow; //private List Buttons = new List(0); //private List Buttonstag = new List(0); //private List Buttonstype = new List(0); private List Buttons = new List(); public Boolean bMakeRect = true; /// /// 개별보기? 전체보기? /// private Boolean _FullScreen; public Boolean FullScreen { get { return _FullScreen; } set { _FullScreen = value; if (!_FullScreen) { ShowIndex = 0; } else ShowIndex = -1; } } private int _showindex = -1; /// /// 개별보기 모드일때 현재 화면에 표시할 그룹의 인덱스 /// public int ShowIndex { get { return _showindex; } set { if (FullScreen) { //전체홤녀일경우에는 사용하지 않는다. _showindex = -1; } else { if (value != -1 && value != _showindex) { _showindex = value; if (OnChangedShowIndex != null) OnChangedShowIndex(_showindex); } } } } #region *** Constructors *** public int[,,] Values { get { return this.values; } set { this.values = value; } } public String[,,] Times { get { return this.times; } set { this.times = value; } } public Color Font_Grouptitle_Color { get { return this.font_grouptitle_color; } set { this.font_grouptitle_color = value; } } public Color Font_Header_Color { get { return this.font_header_color; } set { this.font_header_color = value; } } public Font Font_Grouptitle { get { return this.font_grouptitle; } set { this.font_grouptitle = value; } } public Font Font_Header { get { return this.font_header; } set { this.font_header = value; } } public DispCtrl() { InitializeComponent(); // Initialize Variables // Set Optimized Double Buffer to reduce flickering this.SetStyle(ControlStyles.UserPaint, true); this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); // Redraw when resized this.SetStyle(ControlStyles.ResizeRedraw, true); this.Font = SystemInformation.MenuFont; this.Warn_Font = new Font("나눔고딕", 20, FontStyle.Bold); this.Font_Grouptitle = new Font("나눔고딕", 25, FontStyle.Bold); this.Font_Header = new Font("나눔고딕", 20, FontStyle.Bold); this.bordercolor = Color.LightGray; this.Warn_msg += ("메세지가 없습니다"); this.design_backcolor_normal = Color.DarkBlue; this.design_backcolor_start = Color.Black; this.FullScreen = false; } private void InitializeComponent() { this.Name = "DispCtrl"; this.Size = new System.Drawing.Size(287, 321); this.Load += new System.EventHandler(this.DispCtrl_Load); this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.DispCtrl_MouseDown); this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.DispCtrl_MouseMove); this.Resize += arLabel_Resize; } void arLabel_Resize(object sender, EventArgs e) { Invalidate(); } public Boolean init { get { return this._init; } set { this._init = value; } } private void DispCtrl_Load(object sender, EventArgs e) { } #endregion #region *** Properties *** /// /// 경고메세지를 반환합니다. /// public string Message_Warning { get { return this.Warn_msg.ToString(); } set { if (value == null || string.IsNullOrEmpty(value)) Warn_msg = ""; else Warn_msg += (value) + "\r\n"; } } /// /// 테두리색상 /// public Color BorderColor { get { return this.bordercolor; } set { bordercolor = value; Update(); } } #endregion private RectangleF[] GetRectangleTitle(Graphics g, RectangleF ItemRect, CGROUP grp, Boolean isprint) { Font applyfont = this.FONT_CT;// grp.셀글꼴; if (isprint) applyfont = new Font(applyfont.FontFamily, 6, FontStyle.Bold); String Cellno = grp.maxcellname; SizeF CellNoSize = g.MeasureString(Cellno, applyfont); SizeF CellAlSize = g.MeasureString("88/88", applyfont); //------------- | ----------- | ------------ // cell pv alarm //------------- | ----------- | ------------ Single H = (Single)(CellNoSize.Height * 2.5); //높이값 Single NameSize = (Single)(CellNoSize.Width * 1.05); //살짝더크게 Single PvSize = ItemRect.Width - (Single)(CellNoSize.Width * 1.05) - (Single)(CellAlSize.Width); Single AlamSize = ItemRect.Width - NameSize - PvSize; RectangleF CellNoRect = new RectangleF(ItemRect.Left, ItemRect.Top, NameSize, H); RectangleF CellPvRect = new RectangleF(CellNoRect.Left + CellNoRect.Width, ItemRect.Top, PvSize, H); RectangleF CellALRect = new RectangleF(CellPvRect.Left + CellPvRect.Width, ItemRect.Top, AlamSize, H); return new RectangleF[3] { CellNoRect, CellPvRect, CellALRect }; } private void DrawItem(Graphics g, CGROUP grp, RectangleF R, short CellGroupidx, Boolean isprint, Boolean isVisible) { RectangleF[] CellTitleRect = DrawCellTitle(g, R, grp, isprint); //0번은 title label ,1 번은 value label grp._cell_title_width = CellTitleRect[0].Width; //셀의 제목표시줄(번호)의 너비값 grp._cell_value_width = CellTitleRect[1].Width; //셀의 제목표시줄(값)의 너비값 grp._cell_alam_width = CellTitleRect[2].Width; //셀의 알람표시줄의 너비값 Single height = R.Height - CellTitleRect[0].Height; //채널표시영역의 옾이값 //실제채널이 표시되는 데이터 표시 RectangleF channelarea = new RectangleF(R.Left, R.Top + CellTitleRect[0].Height, R.Width, height); if (isVisible) DrawCellMatrix(g, channelarea, grp, CellGroupidx, isprint); //vertical line Single lx = R.Left + grp._cell_title_width; if (isVisible) g.DrawLine(Pens.Silver, lx, R.Top, lx, R.Top + R.Height); lx += grp._cell_value_width; if (isVisible) g.DrawLine(Pens.Silver, lx, R.Top, lx, R.Top + R.Height); if (isVisible) g.DrawLine(Pens.Silver, lx, R.Top + (CellTitleRect[2].Height / 2), lx + grp._cell_alam_width, R.Top + (CellTitleRect[2].Height / 2)); //lx += grp._cell_alam_width / 2; //if (isVisible) g.DrawLine(Pens.Silver, lx, R.Top + (CellTitleRect[2].Height / 2), lx, R.Top + R.Height); } private RectangleF[] DrawCellTitle(Graphics g, RectangleF ItemRect, CGROUP grp, Boolean isprint) { Font applyfont = this.FONT_CT;// grp.셀글꼴; if (isprint) applyfont = new Font(applyfont.FontFamily, 6, FontStyle.Bold); String Cellno = grp.maxcellname; SizeF CellNoSize = g.MeasureString(Cellno, applyfont); SizeF CellAlSize = g.MeasureString("88/88", applyfont); //------------- | ----------- | ------------ // cell pv alarm //------------- | ----------- | ------------ Single H = (Single)(CellNoSize.Height * 2.5); //높이값 Single NameSize = (Single)(CellNoSize.Width * 1.05); //살짝더크게 Single PvSize = ItemRect.Width - (Single)(CellNoSize.Width * 1.05) - (Single)(CellAlSize.Width); Single AlamSize = ItemRect.Width - NameSize - PvSize; RectangleF CellNoRect = new RectangleF(ItemRect.Left, ItemRect.Top, NameSize, H); RectangleF CellPvRect = new RectangleF(CellNoRect.Left + CellNoRect.Width, ItemRect.Top, PvSize, H); RectangleF CellALRect = new RectangleF(CellPvRect.Left + CellPvRect.Width, ItemRect.Top, AlamSize, H); Color gbclor; if (grp.AlarmType == "AUTO") gbclor = Color.SkyBlue; else if (grp.AlarmType == "MANUAL") gbclor = Color.LightGray; else gbclor = Color.Pink; //stop RectangleF TITLERECT = new RectangleF(ItemRect.Left, ItemRect.Top, ItemRect.Width, H - 2); g.FillRectangle(new SolidBrush(gbclor), TITLERECT); //DRAW UNDERLINE g.DrawLine(Pens.DimGray, TITLERECT.Left, TITLERECT.Top + TITLERECT.Height, TITLERECT.Left + TITLERECT.Width, TITLERECT.Top + TITLERECT.Height); //g.DrawRectangle(Pens.Red, TITLERECT.Left, TITLERECT.Top, TITLERECT.Width, TITLERECT.Height); g.DrawString("Cell", applyfont, Brushes.Black, CellNoRect.Left + CellNoRect.Width / 2 - CellNoSize.Width / 2, CellNoRect.Top + CellNoRect.Height / 2 - CellNoSize.Height / 2); Cellno = "PV"; CellNoSize = g.MeasureString(Cellno, applyfont); g.DrawString(Cellno, applyfont, Brushes.Black, CellPvRect.Left + CellPvRect.Width / 2 - CellNoSize.Width / 2, CellPvRect.Top + CellPvRect.Height / 2 - CellNoSize.Height / 2); Cellno = "Alarm"; CellNoSize = g.MeasureString(Cellno, applyfont); String SH = "H", SL = "L"; if (grp.AlarmType == "AUTO") { SH = "+"; SL = "-"; } SizeF a, h, l; a = g.MeasureString("ALM", applyfont); h = g.MeasureString(SH, applyfont); l = g.MeasureString(SL, applyfont); //Single y = 0, x = 0; g.DrawString("ALM", applyfont, Brushes.Black, CellALRect.Left + CellALRect.Width / 2 - a.Width / 2, CellALRect.Top + CellALRect.Height / 4 - a.Height / 2); var alrecthl = new RectangleF(CellALRect.X, CellALRect.Y + CellALRect.Height / 2f, CellALRect.Width, CellALRect.Height / 2f); g.DrawString($"{SH}/{SL}", applyfont, Brushes.Black, alrecthl, new StringFormat { LineAlignment = StringAlignment.Center, Alignment = StringAlignment.Center }); return new RectangleF[3] { CellNoRect, CellPvRect, CellALRect }; } public String initmsg { get { return this._initmsg; } set { this._initmsg = value; this.Refresh(); } } /// /// 화면에 표시되는 내용중 실제 셀의 내용이다. 세부내역은 이곳에서 작성됨 /// /// /// /// /// private void DrawCellMatrix(Graphics g, RectangleF srcrect, CGROUP grp, short cidx, Boolean isprint) { try { Single height = (Single)srcrect.Height / grp.RowCount; //지정한 갯수를 나눈다. Single newx = srcrect.Left; for (short j = 0; j < grp.RowCount; j++) { int idx = cidx * grp.RowCount + j; Single newy = j * height; RectangleF R = new RectangleF(newx + 1, newy + srcrect.Top, grp.Cell_Title_Width + grp.Cell_Value_Width + grp.Cell_Alam_Width - 1, height - 2); //번호와 영역을 재계산한다. if (grp.Items.GetUpperBound(0) < idx) Array.Resize(ref grp.itemarray, idx + 1); //항목초기화 if (grp.Items[idx] == null) { grp.Items[idx] = new CITEM() { 이름 = "--", 알람형태 = COMM.EALAMTYPE.사용안함, alamh = -999, alaml = -999, aalamh = -999, aalaml = -999, alamv = -999, Onset = false, //firstsave = true, }; } CITEM Item = grp.Items[idx]; //Single Alamh=0,AlamL=0; switch (Item.알람형태) { case COMM.EALAMTYPE.그룹설정을따름: Item.alamh = grp.HIGH; Item.alaml = grp.LOW; Item.aalamh = grp.UP; Item.aalaml = grp.UP; //Item.alamv = -999; /* 작성자: 이재웅, 작성일: 2025-06-11, 작성내용: 알람발생 원인으로 의심 -> 'Item.alamv = -999' 주석해제 했다가 다시 원복 */ break; case COMM.EALAMTYPE.사용안함: Item.alamh = -999; Item.alaml = -999; Item.aalamh = -999; Item.aalaml = -999; Item.alamv = -999; break; case COMM.EALAMTYPE.개별알람자동: //원본값을 그대로 사용한다. case COMM.EALAMTYPE.개별알람: //원본값을 그대로 사용한다. break; } Item.row = j; Item.column = cidx; Item.rect = R; //기본배경색상(그라디언트) Color BackColor = Color.WhiteSmoke; var ApplyFont_CN = this.FONT_CN;// grp.셀글꼴; var ApplyFont_CV = this.FONT_CV; var ApplyFont_AV = this.FONT_AV; if (isprint) { //출력상태에서는 작게 출력한다. ApplyFont_CN = new Font(ApplyFont_CN.FontFamily, 6, FontStyle.Bold); ApplyFont_CV = new Font(ApplyFont_CV.FontFamily, 6, FontStyle.Bold); ApplyFont_AV = new Font(ApplyFont_AV.FontFamily, 6, FontStyle.Bold); } SizeF Fontsize_CN = g.MeasureString(Item.이름, ApplyFont_CN); Single fnewx = R.Left + grp.Cell_Title_Width / 2 - Fontsize_CN.Width / 2; Single fnewy = R.Top + R.Height / 2 - Fontsize_CN.Height / 2; //알람발생여부초기화 Item._p_onalamh = Item.onalamh; //이전값기록 Item._p_onalaml = Item.onalaml; //이전값기록 Item.onalamh = false; //현재알람초기화 Item.onalaml = false; //현재알람초기화 //데이터표시 String ValueStr = ""; Item.CurValue = 0; Item.CurValue1 = 0; //140829 String TimeStr = ""; //글자표시색상 Color BrColor = grp.셀글꼴색상; //값의 저장소가 아에없다면? //Boolean OverDATA = false; var alarmRemark = string.Empty; if (this.Values == null) { Item.value2 = 0; Item.CurValue = 0f; Item.CurValue1 = 0f; TimeStr = "Null Error"; BrColor = Color.LightGray; } else { Single Offset = 0; //수동으로입력된 옾셋 if (!Item.사용) //사용여부자체를 설정한다. { Item.value2 = 0; Item.alamv = -999; Item.CurValue = 0f; //미설정상태라면 값을 표시하지 않는다. Item.CurValue1 = 0f; TimeStr = "Not USE"; grp._unusedcount += 1; BackColor = Color.LightGray; BrColor = Color.Gray; } else //정상상태이다. { //Br = new SolidBrush(Color.Black); Offset = Item.Offset; //수동으로입력된 옾셋 var u1 = this.Values.GetUpperBound(0); var u2 = this.Values.GetUpperBound(1); var u3 = this.Values.GetUpperBound(2); if (Item.idx_dev >= 0 && Item.idx_unit >= 0 && Item.idx_ch >= 0 && Item.idx_dev <= u1 && Item.idx_unit <= u2 && Item.idx_ch <= u3) { Item.value2 = this.Values[Item.idx_dev, Item.idx_unit, Item.idx_ch]; //측정값 TimeStr = this.Times[Item.idx_dev, Item.idx_unit, Item.idx_ch]; //측정시간 } else { Item.value2 = 0; TimeStr = ""; } if (!Item.활성화) grp._disccount += 1; } //backgroun Color if (Offset != 0) BrColor = Color.Blue; //OVER DATA if (Item.value2 >= 32000 || Item.value2 >= 65000) { Item._onalamover = true; //CurValue = (Single)(Item.value2 / (Math.Pow(10, Item.decpos))) + Offset; //Over aalam if (TimeStr != "" && TimeStr != "Not USE" && Item._p_onalamover == false) { String alamtimes = DateTime.Parse(TimeStr).ToString("yy-MM-dd HH:mm:ss"); OnAlamChange(Item.idx, COMM.EALAMRAISETYPE.OVER_ON, Item.알람형태, "--", Item.CurValue, Item.alamh, Item.alaml, "over 32000"); Item._p_onalamover = true; } Item.CurValue = 0f; Item.CurValue1 = 0f; } else { Item._onalamover = false; //if(Item.value2 != 9999) //Over aalam if (TimeStr != "" && TimeStr != "Not USE" && Item._p_onalamover == true) { String alamtimes = DateTime.Parse(TimeStr).ToString("yy-MM-dd HH:mm:ss"); OnAlamChange(Item.idx, COMM.EALAMRAISETYPE.OVER_OFF, Item.알람형태, "--", Item.CurValue, Item.alamh, Item.alaml, ""); Item._p_onalamover = false; } } //현재값 Item.CurValue = (Single)(Item.value2 / (Math.Pow(10, Item.decpos))) + Offset; Item.CurValue1 = Item.CurValue; //데이터분주가 들어있지않은 값이다. //140828 데이터분주값입력 if (datadiv != 0 && datadiv != 1) Item.CurValue = (Single)(Item.CurValue / (Single)datadiv); //최대,최소,합계VOLT 누적 if (Item.사용 && Item.활성화) { //if (Item.CurValue > 0) Debugger.Break(); if (Item.CurValue >= grp.Maxvolt) { grp._maxvolt = Item.CurValue; grp._maxitem = Item; } if (Item.CurValue <= grp.Minvolt) { grp._minvolt = Item.CurValue; grp._minitem = Item; } grp._sumvolt += Item.CurValue1; //분주되기전의 sum값 140829 grp._sumvolt1 += Item.CurValue; //분주된후의 sum값 140829 } //알람활성화여부(오버데이터는 알람설정하지 않는다) if (!Item._onalamover && Item.알람형태 != COMM.EALAMTYPE.사용안함 && Item.사용) { switch (Item.알람형태) { case COMM.EALAMTYPE.그룹설정을따름: if (grp.AlarmType == "AUTO") { //if (Item.alamv == -999) Item.alamv = Item.CurValue; /* 작성자: 이재웅, 작성일: 2025-06-17, 작성내용: 'Item.alamv == 0' OR조건 추가 */ if (Item.alamv == -999 || Item.alamv == 0) Item.alamv = Item.CurValue; Item.적용형태 = "AUTO"; if (Item.CurValue > Item.alamv) //큰값이 있을경우 상한선을 확인한다. { Single gap = Math.Abs(Item.CurValue - Item.alamv); if (gap >= Math.Abs(Item.aalamh)) { Item.onalamh = true; Item.onalaml = false; BackColor = Color.Orange; //BackColor0 = Color.LightPink; alarmRemark = $"ref({Item.alamv})"; } } else if (Item.CurValue < Item.alamv) { Single gap = Math.Abs(Item.CurValue - Item.alamv); if (gap >= Math.Abs(Item.aalaml)) { Item.onalamh = false; Item.onalaml = true; BackColor = Color.SkyBlue; //BackColor0 = Color.LightBlue; alarmRemark = $"ref({Item.alamv})"; } } } else if (grp.AlarmType == "MANUAL") { Item.적용형태 = "MANUAL"; if (Item.CurValue >= Item.alamh) { Item.onalamh = true; Item.onalaml = false; BackColor = Color.Orange;// BackColor0 = Color.LightPink; alarmRemark = $"ref({Item.alamh})"; } else if (Item.CurValue < Item.alaml) { Item.onalamh = false; Item.onalaml = true; BackColor = Color.SkyBlue; //BackColor0 = Color.LightBlue; alarmRemark = $"ref({Item.alaml})"; } } else { Item.적용형태 = "STOP"; Item.onalamh = false; Item.onalaml = false; } break; case COMM.EALAMTYPE.개별알람: Item.적용형태 = "MANUAL"; if (Item.CurValue >= Item.alamh) { Item.onalamh = true; Item.onalaml = false; BackColor = Color.Orange; //BackColor0 = Color.LightPink; alarmRemark = $"ref({Item.alamh})"; } else if (Item.CurValue < Item.alaml) { Item.onalamh = false; Item.onalaml = true; BackColor = Color.SkyBlue;// BackColor0 = Color.LightBlue; alarmRemark = $"ref({Item.alaml})"; } break; case COMM.EALAMTYPE.개별알람자동: Item.적용형태 = "AUTO"; //if (Item.alamv == -999) Item.alamv = Item.CurValue; // 이전 코드 /* 작성자: 이재웅, 작성일: 2025-06-17, 작성내용: 'Item.alamv == 0' OR조건 추가 */ if (Item.alamv == -999 || Item.alamv == 0) Item.alamv = Item.CurValue; if (Item.CurValue > Item.alamv) //큰값이 있을경우 상한선을 확인한다. { Single gap = Math.Abs(Item.CurValue - Item.alamv); if (gap >= Math.Abs(Item.aalamh)) { Item.onalamh = true; Item.onalaml = false; BackColor = Color.Orange; //BackColor0 = Color.LightPink; alarmRemark = $"ref({Item.alamv})"; } } else if (Item.CurValue < Item.alamv) { Single gap = Math.Abs(Item.CurValue - Item.alamv); if (gap >= Math.Abs(Item.aalaml)) { Item.onalamh = false; Item.onalaml = true; BackColor = Color.SkyBlue; //BackColor0 = Color.LightBlue; alarmRemark = $"ref({Item.alamv})"; } } break; } } //CurValue = (Single)Math.Round(CurValue, 3); } if (Item.활성화 && init == true && (Item.onalaml != Item._p_onalaml || Item._p_onalamh != Item.onalamh)) //이전과 알람상태가 변경된경우다. { String alamtimes = ""; if (TimeStr != "" && TimeStr != "Not USE") alamtimes = DateTime.Parse(TimeStr).ToString("yy-MM-dd HH:mm:ss"); else alamtimes = ""; Single AH, AL; if (Item.적용형태 == "AUTO") { AH = Item.aalamh; AL = Item.aalaml; } else { AH = Item.alamh; AL = Item.alaml; } if (Item.onalamh && !Item._p_onalamh) { OnAlamChange(Item.idx, COMM.EALAMRAISETYPE.HIGH_ON, Item.알람형태, Item.적용형태, Item.CurValue, AH, AL, alarmRemark); Item._p_onalamh = true; } else if (Item.onalaml && !Item._p_onalaml) { OnAlamChange(Item.idx, COMM.EALAMRAISETYPE.LOW_ON, Item.알람형태, Item.적용형태, Item.CurValue, AH, AL, alarmRemark); Item._p_onalaml = true; } else if (!Item.onalamh && Item._p_onalamh) { OnAlamChange(Item.idx, COMM.EALAMRAISETYPE.HIGH_OFF, Item.알람형태, Item.적용형태, Item.CurValue, AH, AL, ""); Item._p_onalamh = false; } else if (!Item.onalaml && Item._p_onalaml) { OnAlamChange(Item.idx, COMM.EALAMRAISETYPE.LOW_OFF, Item.알람형태, Item.적용형태, Item.CurValue, AH, AL, ""); Item._p_onalamh = false; } } if (!Item.활성화 && Item.사용) { Item._onalamover = false; Item._onalamh = false; Item._onalaml = false; Item._p_onalamh = false; Item._p_onalaml = false; Item._p_onalamover = false; BackColor = Color.WhiteSmoke; //BackColor0 = Color.LightGray; BrColor = (Color.Gray); } if (Item._onalamover) { ValueStr = $"{Item.CurValue:0.000}"; BrColor = (Color.DarkMagenta); grp._errorcount += 1; } else if (!Item.활성화) { ValueStr = "--"; } else ValueStr = $"{Item.CurValue:0.000}"; //초기화전상태라면 초기화된걸로 확인시킨다. if (!Item.Onset) Item.Onset = true; //Draw Cell Background using (var br = new SolidBrush(BackColor)) g.FillRectangle(br, R); //Border using (var pen = new Pen(Color.LightGray)) { g.DrawLine(pen, R.Left + grp.Cell_Title_Width, R.Top, R.Left + grp.Cell_Title_Width, R.Top + R.Height); g.DrawLine(pen, R.Left + grp.Cell_Title_Width + grp.Cell_Value_Width, R.Top, R.Left + grp.Cell_Title_Width + grp.Cell_Value_Width, R.Top + R.Height); } //Cell 제목줄 표시 if (Item.사용) { Color cc; if (Item.ismin) cc = BrColor = Color.Blue; // <-- Color.DarkBlue; else if (Item.ismax) cc = BrColor = Color.Red; else cc = BrColor; using (var br = new SolidBrush(cc)) g.DrawString(Item.이름, ApplyFont_CN, br, fnewx, fnewy); } Item.Value = ValueStr; Item.mtime = TimeStr; if (idx < grp._null_itemseq) { if (Item.사용 && Item.활성화) { grp._sumvoltA += Item.CurValue1; if (Item.알람형태 != COMM.EALAMTYPE.사용안함) { if (NullbalanceRealValue) grp._null_valueL += Item.CurValue1; //알람이 오프된경우라면 처리하지않게한다. else grp._null_valueL += Item.CurValue; //알람이 오프된경우라면 처리하지않게한다. } } } else { if (Item.사용 && Item.활성화) { grp._sumvoltB += Item.CurValue1; if (Item.알람형태 != COMM.EALAMTYPE.사용안함) { if (NullbalanceRealValue) grp._null_valueR += Item.CurValue1; else grp._null_valueR += Item.CurValue; } } } Fontsize_CN = g.MeasureString(ValueStr, ApplyFont_CV); fnewx = R.Left + grp.Cell_Title_Width + grp.Cell_Value_Width / 2 - Fontsize_CN.Width / 2; fnewy = R.Top + R.Height / 2 - Fontsize_CN.Height / 2; if (this.WINDOW.Debug) ValueStr += cidx.ToString(); //Cell Value 표시 if (Item.사용) { using (var Br = new SolidBrush(BrColor)) g.DrawString(ValueStr, ApplyFont_CV, Br, fnewx, fnewy); } //display alam String AlamstrH = ""; String AlamstrL = ""; switch (Item.알람형태) { case COMM.EALAMTYPE.사용안함: //직접사용안함 BrColor = Color.Gray; AlamstrH = "OFF"; AlamstrL = "OFF"; break; case COMM.EALAMTYPE.그룹설정을따름: BrColor = Color.Black; if (grp.AlarmType == "AUTO") { AlamstrH = Item.aalamh.ToString(); AlamstrL = Item.aalaml.ToString(); } else if (grp.AlarmType == "MANUAL") { AlamstrH = Item.alamh.ToString(); AlamstrL = Item.alaml.ToString(); } else //그룹설정이 OFF된경우 { AlamstrH = "OFF"; AlamstrL = "OFF"; } break; case COMM.EALAMTYPE.개별알람: BrColor = (Color.Blue); AlamstrH = "↑" + Item.alamh.ToString(); AlamstrL = "↓" + Item.alaml.ToString(); break; case COMM.EALAMTYPE.개별알람자동: BrColor = (Color.Magenta); AlamstrH = "+" + Item.aalamh.ToString(); AlamstrL = "-" + Item.aalaml.ToString(); break; } Fontsize_CN = g.MeasureString(AlamstrH, ApplyFont_AV); SizeF fontsize2 = g.MeasureString(AlamstrL, ApplyFont_AV); fnewy = R.Top + R.Height / 2 - Fontsize_CN.Height / 2; if (Item.사용) { if (Item.활성화) { if (Item._onalamh || Item._onalaml) grp._alamcount += 1; } Color SSBColor = BrColor; if (!Item.활성화) SSBColor = Color.Gray; using (var SSB = new SolidBrush(SSBColor)) { fnewx = R.Left + grp.Cell_Title_Width + grp.Cell_Value_Width + (grp.Cell_Alam_Width / 2 - Fontsize_CN.Width) / 2; g.DrawString($"{AlamstrH}/{AlamstrL}", ApplyFont_AV, SSB, fnewx, fnewy); } } //Cell 테두리 ////g.DrawRectangle(new Pen(Color.Gray), R.Left, R.Top, R.Width - 1, R.Height); //Cell Underbar g.DrawLine(Pens.Gray, R.Left, (R.Top + R.Height), R.Left + R.Width, (R.Top + R.Height)); //버튼할당을위한 값할당 this.Buttons.Add(new CButton(R, Item, EBUTTONTYPE.CELL)); } } catch (NullReferenceException ex1) { // 예외 메시지, 파일명, 행 번호를 로그에 기록 var stackTrace = new System.Diagnostics.StackTrace(ex1, true); var frame = stackTrace.GetFrame(0); string fileName = frame.GetFileName(); int lineNumber = frame.GetFileLineNumber(); // UI 디스플레이 중, 예외발생 문제 PUB.log.AddE($"NullReferenceException Message={ex1.Message}, 파일명={fileName}, 행번호={lineNumber}"); return; } catch (Exception ex2) { // 예외 메시지, 파일명, 행 번호를 로그에 기록 var stackTrace = new System.Diagnostics.StackTrace(ex2, true); var frame = stackTrace.GetFrame(0); string fileName = frame.GetFileName(); int lineNumber = frame.GetFileLineNumber(); // Else Error !!! PUB.log.AddE($"Exception Message={ex2.Message}, 파일명={fileName}, 행번호={lineNumber}"); return; } } private void DrawDebugInfo(Graphics g) { } public void DrawGroup(Graphics g, CGROUP grp, Point margin, SizeF ItemSize, RectangleF WinRect, int 열번호, int 줄번호, Boolean isprint, bool IsVisible) { SizeF Fontsize; grp._minitem = null; grp._maxitem = null; try { //그룹내의정보를 설정 Single newx = WinRect.Left + 열번호 * ItemSize.Width; Single newy = WinRect.Top + 줄번호 * ItemSize.Height; grp.R = new RectangleF(newx + 4, newy + 4, ItemSize.Width * grp.열병합 - 8, ItemSize.Height * grp.줄병합 - 8); //그룹타이틀 newy = grp.R.Top; SizeF FontHeight = g.MeasureString(grp.이름, this.Font_Grouptitle); Single newheigth = (FontHeight.Height * 4); grp.Rect_Title = new RectangleF(grp.R.Left, newy, grp.R.Width, newheigth); newy += newheigth; //전체아이템너비 newy += 0; newheigth = grp.R.Height + grp.R.Top - newy; grp.Rect_body = new RectangleF(grp.R.Left, newy, grp.R.Width, newheigth); //각 셀그룹의 영역을 설정함 Single LastX = 0; int Gap = 6; grp.CellGroup_Width = (grp.Rect_body.Width / grp.ColumnCount) - ((Gap * (grp.ColumnCount - 1) / grp.ColumnCount)); grp.CellGroup_Height = grp.Rect_body.Height; grp.CellGroup = new RectangleF[grp.ColumnCount]; for (int ii = 1; ii <= grp.ColumnCount; ii++) { if (ii == 1) { //처음개체 grp.CellGroup[ii - 1] = new RectangleF(grp.Rect_body.Left, grp.Rect_body.Top, grp.CellGroup_Width, grp.CellGroup_Height); LastX = grp.CellGroup[ii - 1].Left + grp.CellGroup[ii - 1].Width + Gap; } else { //이후개체 grp.CellGroup[ii - 1] = new RectangleF(LastX, grp.Rect_body.Top, grp.CellGroup_Width, grp.CellGroup_Height); LastX += grp.CellGroup_Width + Gap; } } // RectangleF GrpRect = new RectangleF(grp.R.Left + margin.X, grp.R.Top + margin.Y, grp.R.Width, grp.R.Height); //그룹제목표시줄(title) Single MaxTitleWidth = 0; Color GroupBackColor = Color.DarkMagenta; if (this.WINDOW.IDX > 1) GroupBackColor = Color.DarkGreen; RectangleF newbackgrounrect = new RectangleF(grp.Rect_Title.Left + margin.X, grp.Rect_Title.Top + margin.Y, grp.Rect_Title.Width, grp.Rect_Title.Height); if (IsVisible) { using (var lgb = new LinearGradientBrush(newbackgrounrect, Color.Black, GroupBackColor, LinearGradientMode.BackwardDiagonal)) g.FillRectangle(lgb, newbackgrounrect); } Fontsize = g.MeasureString(grp.이름, this.font_grouptitle); newx = grp.Rect_Title.Left + 10 + margin.X; newy = grp.Rect_Title.Top + 7 + margin.Y;// -Fontsize.Height / 2 + grp.Rect_Title.Height / 2; //g.DrawString(grp.이름 + this.Buttons.Count.ToString(), this.font_grouptitle, Brushes.Black, newx + 2, newy + 2); if (IsVisible) g.DrawString(grp.이름, this.font_grouptitle, Brushes.Yellow, newx, newy); if (Fontsize.Width > MaxTitleWidth) MaxTitleWidth = Fontsize.Width; //그룹명클릭시에 그룹설정을 오픈하기위해서 버튼을 할당한다. RectangleF GrpTITLE = new RectangleF(newx, newy, Fontsize.Width, Fontsize.Height); if (IsVisible) this.Buttons.Add(new CButton(GrpTITLE, grp, EBUTTONTYPE.GROUP)); //this.Buttonstag.Add(grp); //this.Buttonstype.Add(EBUTTONTYPE.GROUP); //셀의 갯수를 표시 newy += Fontsize.Height + 1f; int usechcount = grp.Items.Length - grp._unusedcount; String Cellcount = "NO ITEMS"; Cellcount = (grp.Items.Length - grp._unusedcount).ToString() + " Cell\n" + grp._disccount.ToString() + " Disc.\n" + (grp._errorcount).ToString() + " Over"; using (Font CellCountfont = new Font(this.font_grouptitle.Name, this.font_grouptitle.Size - 5)) { Fontsize = g.MeasureString(Cellcount, CellCountfont); //g.DrawString(Cellcount, CellCountfont, Brushes.Black, newx + 2, newy + 2); //shadow if (IsVisible) g.DrawString(Cellcount, CellCountfont, Brushes.Yellow, newx, newy); newy += Fontsize.Height + 1.5f; Fontsize = g.MeasureString("Print", CellCountfont); //프린터버튼추가 RectangleF printbutrect = new RectangleF(newx, newy, (Single)(Fontsize.Width * 1.5), Fontsize.Height); if (IsVisible) g.DrawString("Print", CellCountfont, Brushes.White, printbutrect.Left + (printbutrect.Width - Fontsize.Width) / 2, printbutrect.Top + (printbutrect.Height - Fontsize.Height) / 2); if (IsVisible) g.DrawRectangle(Pens.White, new Rectangle((int)newx, (int)newy, (int)(Fontsize.Width * 1.5), (int)Fontsize.Height)); if (IsVisible) Buttons.Add(new CButton(printbutrect, grp, EBUTTONTYPE.PRINT)); } if (Fontsize.Width > MaxTitleWidth) MaxTitleWidth = Fontsize.Width; //그룹의정보(header) Single HeaderWidth = (Single)(grp.Rect_Title.Width - MaxTitleWidth - 20); Single HeaderHeigth = (Single)(grp.Rect_Title.Height * 0.8); //헤더정보를 표시 newx = grp.Rect_Title.Left + margin.X + (grp.Rect_Title.Width - HeaderWidth) - 5; newy = grp.Rect_Title.Top + margin.Y + (grp.Rect_Title.Height - HeaderHeigth) / 2; grp.Rect_Header = new RectangleF(newx, newy, HeaderWidth, HeaderHeigth); //그림자//g.FillRectangle(new SolidBrush(Color.FromArgb(50,Color.Black)), grp.Rect_Header.Left+2,grp.Rect_Header.Top+2,grp.Rect_Header.Width,grp.Rect_Header.Height); if (IsVisible) g.FillRectangle(new SolidBrush(Color.FromArgb(50, Color.Black)), grp.Rect_Header); if (IsVisible) g.DrawRectangle(Pens.Black, grp.Rect_Header.Left, grp.Rect_Header.Top, grp.Rect_Header.Width, grp.Rect_Header.Height); //표시영역(body) //셀아이템하위 그룹을 표시한다. short gidx = 0; grp._maxvolt = -999; grp._minvolt = 999; grp._avgvolt = 0; grp._sumvolt = 0; grp._sumvolt1 = 0; grp._sumvoltA = 0; grp._sumvoltB = 0; grp._unusedcount = 0; //미사용채널수 grp._null_valueL = 0; grp._null_valueR = 0; grp._errorcount = 0; grp._disccount = 0; grp._alamcount = 0; //알람발생셀수 grp._alamcountlb = 0; foreach (RectangleF R in grp.CellGroup) { //해당그룹의 셀을 표시 DrawItem(g, grp, new RectangleF(R.Left + margin.X, R.Top + margin.Y, R.Width - 1, R.Height), gidx, isprint, IsVisible); //border if (IsVisible) g.DrawRectangle(Pens.DarkGray, (int)R.Left + margin.X, (int)R.Top + margin.Y, (int)R.Width - 1, (int)R.Height); gidx += 1; //g.DrawString(this.window.disconnecttime.ToString(), this.Font, Brushes.Red, R.Left,R.Top); } grp._amp = 0; if (grp._ampidx != "" && grp._ampidx != null) { var buff = grp._ampidx.Split(new char[] { ',' }); int di1 = int.Parse(buff[0]); int di2 = int.Parse(buff[1]); int di3 = int.Parse(buff[2]); try { grp._ampdecpos = 3; grp._amp = (float)(this.Values[di1, di2, di3 - 1] / (Math.Pow(10, grp._ampdecpos))); } catch { grp._amp = -1f; } } if (usechcount == 0) grp._avgvolt = 0; else grp._avgvolt = grp.Sumvolt1 / usechcount; Single nullvalue = (grp._null_valueR - grp._null_valueL) + grp.NullBalanceOffset; String HeaderStr = $"▣ SUM : {grp.Sumvolt:#0.0}"; if (Sumab) { HeaderStr += $"\n▣ SUMA : {grp._sumvoltA:#0.000}"; HeaderStr += $"\n▣ SUMB : {grp._sumvoltB:#0.000}"; } HeaderStr += $"\n▣ AVG : {grp.Avgvolt:#0.000}"; if (!Sumab) { HeaderStr += $"\n▣ MAX : {grp.Maxvolt:#0.000}"; HeaderStr += $"\n▣ MIN : {grp.Minvolt:#0.000}"; } //집계데이터출력 Fontsize = g.MeasureString(HeaderStr, this.font_header); newy = grp.Rect_Header.Top + 5; // -Fontsize.Height / 2 + grp.Rect_Header.Height / 2; if (IsVisible) g.DrawString(HeaderStr, this.font_header, Brushes.White, grp.Rect_Header.Left + 5, newy); //NB데이터와의 SPLITER newx = grp.Rect_Header.Left + 5 + Fontsize.Width + 5; Single SpliiterY = newy; Single SplliterH = newy + grp.Rect_Header.Height - (newy - grp.Rect_Header.Top) * 2; if (IsVisible) g.DrawLine(Pens.Black, newx, newy, newx, SplliterH); //NB데이터출력 newx += 3; //NB용 알람표시 Single imgwidth = 30; Single imgheight = 30; if (!(grp.nbh == 0 && grp.nbl == 0)) { //if (Math.Abs(nullvalue) > grp.nbl) // a2영역보다 크다면 /* 작성자: 이재웅, 작성일: 2025-06-17, 작성내용: 'a2영역 절대값보다 클 경우'로 변경 */ if (Math.Abs(nullvalue) > Math.Abs(grp.nbl)) // a2영역 절대값보다 크다면 { grp._nbalam_l = true; //a2 on if (!grp._pre_nbalam_l) { if (grp.AlarmType != "STOP") OnAlamChange(grp.IDX, COMM.EALAMRAISETYPE.A2_ON, COMM.EALAMTYPE.사용안함, "NB", (Single)nullvalue, (Single)grp.nbl, (Single)grp.nbl, $"> {grp.nbl}"); grp._pre_nbalam_l = true; A2 = false; blink2 = 0; } else //게속발생중이다. { if (A2 == false) { if (blink2 >= 1) { A2 = true; blink2 = 0; } else blink2 += 1; } else { if (blink2 >= 1) { A2 = false; blink2 = 0; } else blink2 += 1; } } } else // a2영역보다는 낮으므로 a2를 해제한다. { grp._nbalam_l = false; //a2 off if (grp._pre_nbalam_l) //이전에 a2알람이 켜져잇엇다면 알람을 끈다. { OnAlamChange(grp.IDX, COMM.EALAMRAISETYPE.A2_OFF, COMM.EALAMTYPE.사용안함, "NB", (Single)nullvalue, (Single)grp.nbl, (Single)grp.nbl, ""); grp._pre_nbalam_l = false; blink1 = 0; } //if (Math.Abs(nullvalue) > grp.nbh) // a1영역보다 크다면 /* 작성자: 이재웅, 작성일: 2025-06-17, 작성내용: 'a1영역 절대값보다 클 경우'로 변경 */ if (Math.Abs(nullvalue) > Math.Abs(grp.nbh)) // a1영역 절대값보다 크다면 { grp._nbalam_h = true; if (!grp._pre_nbalam_h) //이전에 발생안햇다면 { if (grp.AlarmType != "STOP") OnAlamChange(grp.IDX, COMM.EALAMRAISETYPE.A1_ON, COMM.EALAMTYPE.사용안함, "NB", (Single)nullvalue, (Single)grp.nbh, (Single)grp.nbh, $"> {grp.nbh}"); grp._pre_nbalam_h = true; blink1 = 0; } else { if (A1 == false) { if (blink1 >= 1) { A1 = true; blink1 = 0; } else blink1 += 1; } else { if (blink1 >= 1) { A1 = false; blink1 = 0; } else blink1 += 1; } } } else //둘다적용안되는구역이다. { grp._nbalam_h = false; //a1 off if (grp._pre_nbalam_h) //이전에 a1알람이 켜져잇엇다면 알람을 끈다. { OnAlamChange(grp.IDX, COMM.EALAMRAISETYPE.A1_OFF, COMM.EALAMTYPE.사용안함, "NB", (Single)nullvalue, (Single)grp.nbl, (Single)grp.nbl, ""); grp._pre_nbalam_h = false; } blink1 = 0; blink2 = 0; } } } if (grp.AlarmType == "STOP") //그룹설정이 OFF인경우에는 모두 끈다. { grp._nbalam_h = false; grp._nbalam_l = false; } Bitmap B1; if (grp._nbalam_h) { grp._alamcountlb += 1; if (A1) B1 = vmsnet.Properties.Resources.Orange_Ball; else B1 = vmsnet.Properties.Resources.Red_Ball; } else B1 = vmsnet.Properties.Resources.Blue_Ball; Bitmap B2; if (grp._nbalam_l) { grp._alamcountlb += 1; if (A2) B2 = vmsnet.Properties.Resources.Orange_Ball; else B2 = vmsnet.Properties.Resources.Red_Ball; } else B2 = vmsnet.Properties.Resources.Blue_Ball; if (!isprint || WINDOW.CoulumnCount <= 2) { if (IsVisible) g.DrawImage(B1, newx + 25 * 0, newy, imgwidth, imgheight); Fontsize = g.MeasureString("A1", alamfont); if (IsVisible) g.DrawString("A1", alamfont, Brushes.Black, (newx + 25 * 0) + imgwidth / 2 - Fontsize.Width / 2, newy + imgheight / 2 - Fontsize.Height / 2); if (IsVisible) g.DrawImage(B2, newx + 25 * 1, newy, imgwidth, imgheight); Fontsize = g.MeasureString("A2", alamfont); if (IsVisible) g.DrawString("A2", alamfont, Brushes.Black, (newx + 25 * 1) + imgwidth / 2 - Fontsize.Width / 2, newy + imgheight / 2 - Fontsize.Height / 2); //ADJEST if (IsVisible) g.DrawImage(vmsnet.Properties.Resources.Clear_Green_Button, newx + 25 * 0, newy + 2 + imgheight, imgwidth, imgheight); if (IsVisible) Buttons.Add(new CButton(new RectangleF(newx + 25 * 0, newy + 2 + imgheight, imgwidth, imgheight), grp, EBUTTONTYPE.NBZERO)); //RESET if (IsVisible) g.DrawImage(vmsnet.Properties.Resources.Backup_Green_Button, newx + 25 * 1, newy + imgheight, imgwidth, imgheight); if (IsVisible) Buttons.Add(new CButton(new RectangleF(newx + 25 * 1, newy + imgheight, imgwidth, imgheight), grp, EBUTTONTYPE.NBRESET)); } //끝부분에 KA 를 표시한다. String Kaunit = grp._ampunit;// +grp._ampidx.ToString() + "/" + grp._ampdecpos.ToString(); /* 작성자: 이재웅, 작성일: 2024-12-04, 작성내용: {전류량[KA] × 100} 변경 */ String MaxKA = (grp._amp * 10f).ToString("#0.00"); //Console.WriteLine($"{grp.이름} : {MaxKA} {grp._ampunit}"); Fontsize = g.MeasureString(MaxKA, FONT_KA); SizeF FontSizeu = g.MeasureString(Kaunit, FONT_KU); RectangleF KARECT = new RectangleF(grp.Rect_Header.Left + grp.Rect_Header.Width - Fontsize.Width, grp.Rect_Header.Top + (grp.Rect_Header.Height - Fontsize.Height), Fontsize.Width, Fontsize.Height); if (EnableKA == false) KARECT = new RectangleF(grp.Rect_Header.Right, KARECT.Top, 0, 0); //g.FillRectangle(Brushes.Black, KARECT); if (IsVisible && KARECT.IsEmpty == false) { g.DrawString(MaxKA.ToString(), FONT_KA, Brushes.Black, KARECT.Left + 2, KARECT.Top + 2); g.DrawString(MaxKA.ToString(), FONT_KA, Brushes.Yellow, KARECT.Left, KARECT.Top); g.DrawString(Kaunit, FONT_KU, Brushes.Yellow, KARECT.Left + KARECT.Width - FontSizeu.Width - 10, KARECT.Top - 10); } //NullBalance Display if (!isprint || WINDOW.CoulumnCount <= 2) { newx = newx + 30 * 2; String nullstring = nullvalue.ToString("#0.00"); RectangleF rect_nullb = new RectangleF(newx, newy, KARECT.Left - newx, grp.Rect_Header.Height - 10); Fontsize = g.MeasureString(nullstring, FONT_NB); Single center = rect_nullb.Left + rect_nullb.Width / 2; Single px = ((rect_nullb.Width / 2) * Math.Abs(nullvalue) / 5); if (nullvalue < -5) { px = (rect_nullb.Width * (0) / (5 + 5)) - 1; } else if (nullvalue > 5) { px = (rect_nullb.Width * (5 + 5) / (5 + 5)) - 1; } else px = (rect_nullb.Width * (nullvalue + 5) / (5 + 5)) - 1; Color nbcolor = Color.White; if (grp._nbalam_h) nbcolor = Color.Orange; else if (grp._nbalam_l) nbcolor = Color.Red; else nbcolor = Color.White; if (IsVisible) g.DrawString(nullstring, FONT_NB, new SolidBrush(Color.FromArgb(230, nbcolor)), newx + rect_nullb.Width / 2 - Fontsize.Width / 2, rect_nullb.Top + rect_nullb.Height / 2 - Fontsize.Height / 2); Color NewSBColor; if (grp.NullBalanceOffset != 0) NewSBColor = Color.FromArgb(180, Color.DarkBlue); else NewSBColor = Color.FromArgb(180, Color.Red); using (SolidBrush NewSB = new SolidBrush(NewSBColor)) { if (IsVisible) g.DrawLine(Pens.Red, px + rect_nullb.Left, rect_nullb.Top, px + rect_nullb.Left, rect_nullb.Top + rect_nullb.Height); if (IsVisible) g.DrawLine(Pens.Red, px + rect_nullb.Left + 1, rect_nullb.Top, px + rect_nullb.Left + 1, rect_nullb.Top + rect_nullb.Height); PointF[] sqp = new PointF[3]; sqp[0] = new PointF(px + rect_nullb.Left - 10, rect_nullb.Top); sqp[1] = new PointF(px + rect_nullb.Left, rect_nullb.Top + 10); sqp[2] = new PointF(px + rect_nullb.Left + 10, rect_nullb.Top); if (IsVisible) g.FillPolygon(Brushes.Red, sqp); NewSB.Dispose(); } //null balance 테두리 그림 if (IsVisible) g.DrawRectangle(Pens.Orange, rect_nullb.Left, rect_nullb.Top, rect_nullb.Width, rect_nullb.Height); var term = rect_nullb.Width / 10f; for (int i = 1; i < 10; i++) { var x = rect_nullb.Left + (i * term); var y = (rect_nullb.Top + (rect_nullb.Height * 0.8f)); var y2 = rect_nullb.Top + rect_nullb.Height; if (IsVisible) g.DrawLine(Pens.Orange, x - 1, y, x - 1, y2); //String str = (i - 5).ToString(); } newx = newx + rect_nullb.Width + 3; if (IsVisible) g.DrawLine(Pens.Black, newx, SpliiterY, newx, SplliterH); } else { if (IsVisible) { String nullstring = "NB=" + nullvalue.ToString("#0.00"); using (var nullbfont = new Font(FONT_NB.FontFamily, 10)) { g.DrawString(nullstring, nullbfont, SB_White_200, KARECT.Left, KARECT.Top - 10); } } } //현그룹의 테두리 그림 //g.DrawRectangle(Pens.Black, (int)grp.R.Left, (int)grp.R.Top, (int)grp.R.Width+1, (int)grp.R.Height); //grp.Showinfo = true; //추가헤더정보 if (!isprint && grp.Showinfo && IsVisible) { using (var ifont = new Font(this.font_header, FontStyle.Bold)) { String nbstr = $"▣ {grp.이름} - NULL BALANCE ▣"; nbstr += "\n\n▶L:" + grp._null_valueL.ToString("#0.00") + "v"; nbstr += ",R:" + grp._null_valueR.ToString("#0.00") + "v"; nbstr += " ▶DEV(R-L):" + (grp._null_valueR - grp._null_valueL).ToString("#0.00") + "v"; nbstr += " ▶Adj. Offset:" + (grp.NullBalanceOffset).ToString("#0.00") + "v"; nbstr += "\n\n▶Null Balance : " + (grp._null_valueR - grp._null_valueL + grp.NullBalanceOffset).ToString("#0.00") + "v"; nbstr += "\n▶Null Balance Alarm: A1(" + grp.nbh.ToString("#0.00") + "),A2(" + grp.nbl.ToString("#0.00") + ")"; nbstr += "\n\n * 막대그래프의 구간은 -5v ~ 5v 입니다."; nbstr += "\n * 막대그래프의 색상이 하늘색일경우에는 Adj.Offset 이 적용된 값입니다."; SizeF fs = g.MeasureString(nbstr, ifont); Single tx, ty, tw, th, Margin = 0; tx = grp.Rect_Header.Left + 10; ty = grp.Rect_Header.Top + grp.Rect_Header.Height - 6; tw = (fs.Width * 1.1f); th = (fs.Height * 1.1f + 60); RectangleF infoboxb = new RectangleF(tx + 1, ty + 1, tw, th); RectangleF infoboxf = new RectangleF(tx, ty, tw, th); RectangleF intoboxs = new RectangleF(tx + Margin + 3, ty + Margin, tw - (Margin * 2), th - (Margin * 2)); //SolidBrush BRB = new SolidBrush(Color.FromArgb(150, Color.Black)); //SolidBrush BRF = new SolidBrush(Color.FromArgb(200, Color.White)); g.FillRectangle(SB_Black_150, infoboxb); g.FillRectangle(SB_White_200, infoboxf); g.DrawString(nbstr, ifont, Brushes.Black, intoboxs.Left + 1, intoboxs.Top + 3); // g.DrawString(nbstr, this.font_header, Brushes.Orange, intoboxs.Left, intoboxs.Top + intoboxs.Height / 2 - fs.Height / 2); Single Imagey = intoboxs.Top + fs.Height + 10; g.DrawImage(vmsnet.Properties.Resources.Clear_Green_Button, intoboxs.Left, Imagey, imgwidth, imgheight); g.DrawString("현재 Null Balance 값을 Adj.Offset 으로 설정하여 '0'이 되게 합니다.", ifont, Brushes.Black, intoboxs.Left + 35, Imagey + 5); Imagey += 25; g.DrawImage(vmsnet.Properties.Resources.Backup_Green_Button, intoboxs.Left, Imagey, imgwidth, imgheight); g.DrawString("입력된 Adj.Offset 을 제거하여 원래의 Null Balance가 보이게 합니다.", ifont, Brushes.Black, intoboxs.Left + 35, Imagey + 5); //BRF.Dispose(); } } _raise_alarm_count += grp._alamcount; _raise_alarm_nbcount += grp._alamcountlb; if (grp._maxitemp != null) { grp._maxitemp.ismax = false; } if (grp._minitemp != null) grp._minitemp.ismin = false; if (grp._maxitem != null) { grp._maxitem.ismax = true; grp._maxitemp = grp._maxitem; } if (grp._minitem != null) { grp._minitem.ismin = true; grp._minitemp = grp._minitem; } } catch (NullReferenceException ex1) { // 예외 메시지, 파일명, 행 번호를 로그에 기록 var stackTrace = new System.Diagnostics.StackTrace(ex1, true); var frame = stackTrace.GetFrame(0); string fileName = frame.GetFileName(); int lineNumber = frame.GetFileLineNumber(); // UI 디스플레이 중, 예외발생 문제 PUB.log.AddE($"NullReferenceException Message={ex1.Message}, 파일명={fileName}, 행번호={lineNumber}"); return; } catch (Exception ex2) { // 예외 메시지, 파일명, 행 번호를 로그에 기록 var stackTrace = new System.Diagnostics.StackTrace(ex2, true); var frame = stackTrace.GetFrame(0); string fileName = frame.GetFileName(); int lineNumber = frame.GetFileLineNumber(); // Else Error !!! PUB.log.AddE($"Exception Message={ex2.Message}, 파일명={fileName}, 행번호={lineNumber}"); return; } } private void DrawGroups(Graphics g) { _raise_alarm_count = 0; //알람카운트 _raise_alarm_nbcount = 0; //윈도우크기를 설정해준다(개체의크기와 같다) if (!FullScreen) { //개별표시면모드 150313 //현재화면에 1개의 그룹만 표시한다. this.WINDOW._itemwidth = this.WindowRect.Width; // / this.window.CoulumnCount; this.WINDOW._itemheight = WindowRect.Height; // / this.window.RowCount; } else { //전체화면 모드이므로 지정된 갯수만큼 사이즈를 조절한다. this.WINDOW._itemwidth = WindowRect.Width / this.WINDOW.CoulumnCount; this.WINDOW._itemheight = WindowRect.Height / this.WINDOW.RowCount; } if (this.GROUPS.Length < 1) { g.DrawString("NO Group", this.Font, Brushes.Red, WindowRect.Left, WindowRect.Top); } else { //150313 //if (FullScreen) //{ var idx = 0; CGROUP infogrp = null; //if (GROUPS[0].이름 == "EL2500E") Debugger.Break(); foreach (CGROUP grp in this.GROUPS) { var visible = true; var 열번호 = grp.열번호; var 줄번호 = grp.줄번호; //전체화면이 아닌경우라면 지정된 그룹만 표시한다 if (FullScreen == false) { if (ShowIndex < 0 || ShowIndex > this.GROUPS.GetUpperBound(0)) visible = false; //인덱스오류체크 else visible = (idx == ShowIndex); 열번호 = 0; 줄번호 = 0; } //마우스를 올린경우 추가정보 표시 if (grp.Showinfo) infogrp = grp; //else //{ DrawGroup(g, grp, new Point(0, 0), new SizeF(WINDOW.ITEMWIDTH, WINDOW.ITEMHEIGHT), WindowRect, 열번호, 줄번호, false, visible); //} idx += 1; } if (infogrp != null) { var colnum = infogrp.열번호; var rownum = infogrp.줄번호; if (FullScreen == false) { colnum = 0; rownum = 0; } DrawGroup(g, infogrp, new Point(0, 0), new SizeF(WINDOW.ITEMWIDTH, WINDOW.ITEMHEIGHT), WindowRect, colnum, rownum, false, true); } //end group //} //else //{ // //개별표시모드이므로 지정된 index 그룹만 표시한다. // if (ShowIndex < 0 || ShowIndex > this.GROUPS.GetUpperBound(0)) // { // //인덱스값이 잘못된경우이므로 처리할 수 없다 // g.DrawString("개별그룹보기 인덱스 오류 index=" + ShowIndex.ToString(), this.Font, Brushes.Red, 100, 200); // } // else // { // CGROUP grp = this.GROUPS[ShowIndex]; // DrawGroup(g, grp, new Point(0, 0), new SizeF(WINDOW.ITEMWIDTH, WINDOW.ITEMHEIGHT), WindowRect, 0, 0, false); // } //} } if (_raise_alarm_count > 0 || _raise_alarm_nbcount > 0) _raise_alarm = true; //현재알람이 켜져야한다. else _raise_alarm = false; //g.DrawString(_raise_alarm_count.ToString(), this.font_grouptitle, Brushes.White, 100, 100); //g.DrawString(_raise_alarm_nbcount.ToString(), this.font_grouptitle, Brushes.White, 100, 200); //알람의강제오프기능이 활성화되었다면? //현재 알람이 활성화되어있다면 알람을 해제한다. //이전알람과비교해서 달라졌다면 알람을 발생시켜준다. //단 상태가 같은데 현재 알람카운터가 이전알람카운터보다 클경우에는 알람을 다시 발생한다. if (_raise_alarm && !_raise_alarm_pre) { RaiseAlarm(true); _raise_alarm_pre = true; } //이전에는 발생안했다가 새로 발생한경우 if (!_raise_alarm && _raise_alarm_pre) { RaiseAlarm(false); _raise_alarm_pre = false; } //이전에 발생했다가 끄는경우 if ((_raise_alarm_count > _pre_raise_alarm_count || _pre_raise_alarm_nbcount > _raise_alarm_nbcount) && _raise_alarm) //알람이켜져잇는상태에서 알람카운터가 증가했다면 재 알람 { RaiseAlarm(true); _raise_alarm_pre = true; } _pre_raise_alarm_count = _raise_alarm_count; _pre_raise_alarm_nbcount = _raise_alarm_nbcount; } /// Override OnPaint method protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); this.SuspendLayout(); try { ///각영역을 새로 만들어야하는경우이다. if (bMakeRect) { if (FullScreen) { WindowRect = new RectangleF(Padding.Left, Padding.Top, this.Width - Padding.Left - Padding.Right, this.Height - Padding.Top - Padding.Bottom); //TrendRect = new RectangleF(0,0,0,0); // BarRect = new RectangleF(0, 0, 0, 0); // NavRect = new RectangleF(0, 0, 0, 0); } else { WindowRect = new RectangleF(Padding.Left, Padding.Top, this.Width - Padding.Left - Padding.Right, this.Height - Padding.Top - Padding.Bottom); //개별화면일경우 // int WindowWidth = SmallSize; // (int)((this.Width - Padding.Left - Padding.Right) * 0.4); // int halfHeight = (int)((this.Height- Padding.Top - Padding.Bottom - 50-10) * 0.5); // WindowRect = new RectangleF(Padding.Left, Padding.Top, WindowWidth, this.Height - Padding.Top - Padding.Bottom); // NavRect = new RectangleF(WindowRect.Right + 10, WindowRect.Top, this.Width - WindowRect.Right - 10 - 1, 50); // TrendRect = new RectangleF(NavRect.Left, WindowRect.Top + 50, this.Width - WindowRect.Right - 10 - 1, halfHeight); // BarRect = new RectangleF(NavRect.Left, TrendRect.Bottom + 10, TrendRect.Width, halfHeight); } bMakeRect = false; } Buttons = new List(0); //Buttonstag = new List(0); //Buttonstype = new List(0); Boolean isnull = false; if (!init) isnull = true; else { if (this.WINDOW == null || this.GROUPS == null) isnull = true; if (isnull && this.GROUPS.Length == 0) isnull = true; } //표시아이템이없다면 오류를 낸다. if (isnull) { //progress int bw = (int)(this.Width * 0.8); int bh = 30; Rectangle rr = new Rectangle((this.Width - bw) / 2, (this.Height - bh) / 2, bw, bh); Rectangle FullRect = new Rectangle(0, 0, this.Width, this.Height); using (var gradientBrush = new LinearGradientBrush(FullRect, Color.White, Color.White, LinearGradientMode.Vertical)) { e.Graphics.FillRectangle(gradientBrush, FullRect); SizeF initsize = e.Graphics.MeasureString(initmsg, FONT_NANUM_20_BOLD); e.Graphics.DrawString(initmsg, FONT_NANUM_20_BOLD, Brushes.Black, this.Width / 2 - initsize.Width / 2, this.Height / 2 - initsize.Height / 2 - bh - 20); } using (var lb = new LinearGradientBrush(rr, Color.LightBlue, Color.SkyBlue, LinearGradientMode.Vertical)) { if (initpercent > 100) initpercent = 100; int perc = (int)(rr.Width * initpercent / 100); e.Graphics.FillRectangle(lb, new Rectangle(rr.Left, rr.Top, perc, rr.Height)); e.Graphics.DrawRectangle(Pens.DarkGray, rr); e.Graphics.DrawRectangle(Pens.DarkGoldenrod, FullRect.Left, FullRect.Top, FullRect.Width - 1, FullRect.Height - 1); } this.ResumeLayout(); return; } // AntiAliasing e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; //그룹목록 DrawGroups(e.Graphics); /* GROUPS 화면 Display !!! */ //monitor off display if (MonitorOn == false) { e.Graphics.FillRectangle(SB_WhiteSmoke_200, DisplayRectangle); e.Graphics.DrawString("MONITOR PAUSE", FONT_TAHOMA_80_BOLD, Brushes.Gray, DisplayRectangle, new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center, }); } //if (!FullScreen && ShowIndex >= 0) { //트렌드뷰용채널데이터를 새로 만드는경우 //if (bMakeTrendViewChData) MakeTrendViewChData(); //마지막데이터와 2초의 차이가 있다면 데이터를 생성해준다. DateTime NOwdate = DateTime.Now; TimeSpan ts = NOwdate - LastNotifyTime; if (ts.TotalSeconds >= NotifyDataSecond) { //알림 if (OnNotifyData != null) OnNotifyData(NOwdate); LastNotifyTime = NOwdate; } } } catch (NullReferenceException ex1) { // 예외 메시지, 파일명, 행 번호를 로그에 기록 var stackTrace = new System.Diagnostics.StackTrace(ex1, true); var frame = stackTrace.GetFrame(0); string fileName = frame.GetFileName(); int lineNumber = frame.GetFileLineNumber(); // UI 디스플레이 중, 예외발생 문제 PUB.log.AddE($"NullReferenceException Message={ex1.Message}, 파일명={fileName}, 행번호={lineNumber}"); return; } catch (Exception ex2) { // 예외 메시지, 파일명, 행 번호를 로그에 기록 var stackTrace = new System.Diagnostics.StackTrace(ex2, true); var frame = stackTrace.GetFrame(0); string fileName = frame.GetFileName(); int lineNumber = frame.GetFileLineNumber(); // Else Error !!! PUB.log.AddE($"Exception Message={ex2.Message}, 파일명={fileName}, 행번호={lineNumber}"); return; } } protected override void OnResize(EventArgs e) { base.OnResize(e); bMakeRect = true; //bMakeBarRect = true; Invalidate(); } private int Check_GroupHeader(MouseEventArgs e, Boolean resetshowinfo = false) { if (this.GROUPS == null) return -1; for (int i = 0; i < this.GROUPS.Length; i++) { RectangleF rect = this.GROUPS[i].Rect_Header; if (resetshowinfo) this.GROUPS[i].Showinfo = false; //현재위치가 해당 Rectagle 안이라면 속해있다. if (e.X > rect.X && e.X < rect.X + rect.Width) { if (e.Y > rect.Y && e.Y < rect.Y + rect.Height) { //전체화면이 아닌경우에는 선택된 그룹번호를 반환 if (this.FullScreen == false) { if (this.ShowIndex < 0 || this.ShowIndex >= this.GroupCount) return -1; else return this.ShowIndex; } else return i; } } } return -1; } private int Check_Group(MouseEventArgs e) { if (this.GROUPS == null) return -1; for (int i = 0; i < this.GROUPS.Length; i++) { RectangleF rect = this.GROUPS[i].R; //현재위치가 해당 Rectagle 안이라면 속해있다. if (e.X > rect.X && e.X < rect.X + rect.Width) { if (e.Y > rect.Y && e.Y < rect.Y + rect.Height) return i; } } return -1; } private int check_buttons(MouseEventArgs e) { if (this.Buttons == null) return -1; for (int i = 0; i < this.Buttons.Count; i++) { RectangleF rect = this.Buttons[i].Rect; //현재위치가 해당 Rectagle 안이라면 속해있다. if (e.X > rect.X && e.X < rect.X + rect.Width) { if (e.Y > rect.Y && e.Y < rect.Y + rect.Height) return i; } } return -1; } private void DispCtrl_MouseDown(object sender, MouseEventArgs e) { //현재마우스위치의 아이템을 찾ㄴ은다. int idx = check_buttons(e); if (idx != -1) { CButton But = Buttons[idx]; //Object tt = this.Buttonstag[idx]; //EBUTTONTYPE BT = this.Buttonstype[idx]; switch (But.ButtonType) { case EBUTTONTYPE.SELGROUP: ShowIndex = ((CGROUP)But.Tag).IDX - 1; //bMakeTrendViewChData = true; //bMakeBarRect = true; // MakeTrendViewChData(); break; case EBUTTONTYPE.CELL: OnClickCell((CITEM)But.Tag, e); break; case EBUTTONTYPE.GROUP: OnClickGroup((CGROUP)But.Tag, e); break; case EBUTTONTYPE.NBRESET: //MessageBox.Show("NBRESET" + idx.ToString() ); ((CGROUP)But.Tag).NullBalanceOffset = 0; this.OnSetNullbalance((CGROUP)(But.Tag), 0f); this.Refresh(); break; case EBUTTONTYPE.NBZERO: //MessageBox.Show("NBZERO" + idx.ToString()); Single Offset = ((CGROUP)But.Tag)._null_valueR - ((CGROUP)But.Tag)._null_valueL; ((CGROUP)But.Tag).NullBalanceOffset = -1 * Offset; this.OnSetNullbalance((CGROUP)(But.Tag), (Single)(-1 * Offset)); this.Refresh(); break; case EBUTTONTYPE.PRINT: OnClickPrint(((CGROUP)But.Tag)); break; } } } private void DispCtrl_MouseMove(object sender, MouseEventArgs e) { //마우스위치를 저장한다. if (this.Mouseinfo == null) this.Mouseinfo = new CMouseinfo(new PointF(e.X - WindowRect.Left, e.Y - WindowRect.Top)); else this.Mouseinfo.Position = new PointF(e.X - WindowRect.Left, e.Y - WindowRect.Top); //스피드체크영역이라면 마우스를 핸드로 변경한다. Mouseinfo.Hand = false; Mouseinfo.Cross = false; Mouseinfo.Move = false; //이동중인데 마우스가 눌려있다면 DRAG다 if (e.Button == MouseButtons.Left) Mouseinfo.Drag = true; else Mouseinfo.Drag = false; if (Mouseinfo.Drag) //드래그중이다 { if (Mouseinfo.DragType != EDRAGTYPE.GROUP) Mouseinfo.Move = true; //화면이동으로 else Mouseinfo.Hand = true; //잡은형태 } //if (this.FullScreen) //{ /* 작성자: 이재웅, 작성일: 2024-12-04, 작성내용: '전체보기' 상태일 때만 그룹헤더의 [Null Balance] 팝업 정보가 표시되도록 변경 */ //마우스가 현재 그룹헤더에 존재하는지확인 (헤더에 올경우 특정 정보를 표시) if (!Mouseinfo.Hand && !Mouseinfo.Move) { int tpidx = Check_GroupHeader(e, true); if (tpidx != -1) { Mouseinfo.Hand = true; this.GROUPS[tpidx].Showinfo = true; //this.showHeaderInfo = true; } } //마우스가 현재 그룹에 존재하는지? if (!Mouseinfo.Hand && !Mouseinfo.Move) { int tpidx = Check_Group(e); if (tpidx != -1) { Mouseinfo.Hand = true; } } //} if (Mouseinfo.Hand) this.Cursor = Cursors.Hand; if (Mouseinfo.Cross) this.Cursor = Cursors.Cross; this.Refresh(); } } //end class } //end namespace