이전 게시글에는 반도체 증착 공정 및 Burn in 테스트 설비를 작성하기 위한 예광탄을 소개했어요.
이번 게시글은 설비를 화면에 시각화하고 제어하기 위한 설비 컨트롤을 만들기 위한 예광탄 만들기예요.
1. 앞에서 작성한 소스 코드를 이용하여 설비 라이브러리를 만드세요.
- 클래스 라이브러리(.NET Framework) 프로젝트틀 생성하세요.
- 기본으로 제공하는 Class1.cs 파일은 제거합니다.
- 이전 게시글에 있는 소스 코드 중에 Program.cs를 제외한 나머지 소스 코드를 추가합니다.
- 빌드
2. 설비 예광탄 프로젝트를 Windows Forms(.NET Framework)으로 생성하세요.
- 1에서 만든 설비 라이브러리를 참조 추가합니다.
3. 설비 예광탄 프로젝트에 사용자 정의 컨트롤(DPMachineControl)을 추가합니다.
4. 추가한 DPMachineControl에 자식 컨트롤을 배치합니다.
-lb로 시작하는 컨트롤은 Label
-btn로 시작하는 컨트롤은 Button
-nud로 시작하는 컨트롤은 NumericUnpdownControl
-cb로 시작하는 컨트롤은 ComboBox
-pb로 시작하는 컨트롤은 PictureBox
각 버튼의 클릭 이벤트 핸들러를 추가합니다. 두 개의 콤보 박스의 선택항목 변경 이벤트 핸들러도 추가합니다.
DPMachineControl.Designer.cs
namespace DPMachineControl_예광탄
{
partial class DPMachineControl
{
/// <summary>
/// 필수 디자이너 변수입니다.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 사용 중인 모든 리소스를 정리합니다.
/// </summary>
/// <param name="disposing">관리되는 리소스를 삭제해야 하면 true이고, 그렇지 않으면 false입니다.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region 구성 요소 디자이너에서 생성한 코드
/// <summary>
/// 디자이너 지원에 필요한 메서드입니다.
/// 이 메서드의 내용을 코드 편집기로 수정하지 마세요.
/// </summary>
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.lb_type = new System.Windows.Forms.Label();
this.lb_source = new System.Windows.Forms.Label();
this.nud_source = new System.Windows.Forms.NumericUpDown();
this.btn_add = new System.Windows.Forms.Button();
this.btn_test = new System.Windows.Forms.Button();
this.btn_start = new System.Windows.Forms.Button();
this.btn_stop = new System.Windows.Forms.Button();
this.label6 = new System.Windows.Forms.Label();
this.lb_now = new System.Windows.Forms.Label();
this.lb_proper = new System.Windows.Forms.Label();
this.label9 = new System.Windows.Forms.Label();
this.pb_now = new System.Windows.Forms.PictureBox();
this.cb_result = new System.Windows.Forms.ComboBox();
this.cb_product = new System.Windows.Forms.ComboBox();
this.pb_product = new System.Windows.Forms.PictureBox();
((System.ComponentModel.ISupportInitialize)(this.nud_source)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pb_now)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pb_product)).BeginInit();
this.SuspendLayout();
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(93, 38);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(59, 21);
this.label1.TabIndex = 0;
this.label1.Text = "타입:";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(23, 87);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(129, 21);
this.label2.TabIndex = 1;
this.label2.Text = "소스 페이지:";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(23, 134);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(129, 21);
this.label3.TabIndex = 2;
this.label3.Text = "페이지 추가:";
//
// lb_type
//
this.lb_type.AutoSize = true;
this.lb_type.Location = new System.Drawing.Point(160, 38);
this.lb_type.Name = "lb_type";
this.lb_type.Size = new System.Drawing.Size(72, 21);
this.lb_type.TabIndex = 3;
this.lb_type.Text = "[타입]";
//
// lb_source
//
this.lb_source.AutoSize = true;
this.lb_source.Location = new System.Drawing.Point(160, 87);
this.lb_source.Name = "lb_source";
this.lb_source.Size = new System.Drawing.Size(60, 21);
this.lb_source.TabIndex = 4;
this.lb_source.Text = "[No.]";
//
// nud_source
//
this.nud_source.Location = new System.Drawing.Point(158, 134);
this.nud_source.Name = "nud_source";
this.nud_source.Size = new System.Drawing.Size(94, 32);
this.nud_source.TabIndex = 5;
//
// btn_add
//
this.btn_add.Enabled = false;
this.btn_add.Location = new System.Drawing.Point(258, 133);
this.btn_add.Name = "btn_add";
this.btn_add.Size = new System.Drawing.Size(89, 32);
this.btn_add.TabIndex = 6;
this.btn_add.Text = "추가";
this.btn_add.UseVisualStyleBackColor = true;
this.btn_add.Click += new System.EventHandler(this.btn_add_Click);
//
// btn_test
//
this.btn_test.Enabled = false;
this.btn_test.Location = new System.Drawing.Point(23, 474);
this.btn_test.Name = "btn_test";
this.btn_test.Size = new System.Drawing.Size(324, 32);
this.btn_test.TabIndex = 8;
this.btn_test.Text = "Burn In 테스트";
this.btn_test.UseVisualStyleBackColor = true;
this.btn_test.Click += new System.EventHandler(this.btn_test_Click);
//
// btn_start
//
this.btn_start.Enabled = false;
this.btn_start.Location = new System.Drawing.Point(395, 29);
this.btn_start.Name = "btn_start";
this.btn_start.Size = new System.Drawing.Size(128, 30);
this.btn_start.TabIndex = 9;
this.btn_start.Text = "가동";
this.btn_start.UseVisualStyleBackColor = true;
this.btn_start.Click += new System.EventHandler(this.btn_start_Click);
//
// btn_stop
//
this.btn_stop.Enabled = false;
this.btn_stop.Location = new System.Drawing.Point(551, 29);
this.btn_stop.Name = "btn_stop";
this.btn_stop.Size = new System.Drawing.Size(128, 30);
this.btn_stop.TabIndex = 10;
this.btn_stop.Text = "멈춤";
this.btn_stop.UseVisualStyleBackColor = true;
//
// label6
//
this.label6.AutoSize = true;
this.label6.Location = new System.Drawing.Point(395, 87);
this.label6.Name = "label6";
this.label6.Size = new System.Drawing.Size(178, 21);
this.label6.TabIndex = 11;
this.label6.Text = "가동 중인 페이퍼:";
//
// lb_now
//
this.lb_now.AutoSize = true;
this.lb_now.Location = new System.Drawing.Point(579, 87);
this.lb_now.Name = "lb_now";
this.lb_now.Size = new System.Drawing.Size(60, 21);
this.lb_now.TabIndex = 12;
this.lb_now.Text = "[No.]";
//
// lb_proper
//
this.lb_proper.AutoSize = true;
this.lb_proper.Location = new System.Drawing.Point(579, 134);
this.lb_proper.Name = "lb_proper";
this.lb_proper.Size = new System.Drawing.Size(60, 21);
this.lb_proper.TabIndex = 14;
this.lb_proper.Text = "[No.]";
//
// label9
//
this.label9.AutoSize = true;
this.label9.Location = new System.Drawing.Point(493, 133);
this.label9.Name = "label9";
this.label9.Size = new System.Drawing.Size(80, 21);
this.label9.TabIndex = 13;
this.label9.Text = "진행률:";
//
// pb_now
//
this.pb_now.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.pb_now.Location = new System.Drawing.Point(399, 190);
this.pb_now.Name = "pb_now";
this.pb_now.Size = new System.Drawing.Size(280, 248);
this.pb_now.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.pb_now.TabIndex = 15;
this.pb_now.TabStop = false;
//
// cb_result
//
this.cb_result.FormattingEnabled = true;
this.cb_result.Location = new System.Drawing.Point(399, 474);
this.cb_result.Name = "cb_result";
this.cb_result.Size = new System.Drawing.Size(280, 29);
this.cb_result.TabIndex = 16;
this.cb_result.SelectedIndexChanged += new System.EventHandler(this.cb_result_SelectedIndexChanged);
//
// cb_product
//
this.cb_product.FormattingEnabled = true;
this.cb_product.Location = new System.Drawing.Point(27, 172);
this.cb_product.Name = "cb_product";
this.cb_product.Size = new System.Drawing.Size(280, 29);
this.cb_product.TabIndex = 17;
this.cb_product.SelectedIndexChanged += new System.EventHandler(this.cb_product_SelectedIndexChanged);
//
// pb_product
//
this.pb_product.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.pb_product.Location = new System.Drawing.Point(27, 207);
this.pb_product.Name = "pb_product";
this.pb_product.Size = new System.Drawing.Size(280, 248);
this.pb_product.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.pb_product.TabIndex = 18;
this.pb_product.TabStop = false;
//
// DPMachineControl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(11F, 21F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.pb_product);
this.Controls.Add(this.cb_product);
this.Controls.Add(this.cb_result);
this.Controls.Add(this.pb_now);
this.Controls.Add(this.lb_proper);
this.Controls.Add(this.label9);
this.Controls.Add(this.lb_now);
this.Controls.Add(this.label6);
this.Controls.Add(this.btn_stop);
this.Controls.Add(this.btn_start);
this.Controls.Add(this.btn_test);
this.Controls.Add(this.btn_add);
this.Controls.Add(this.nud_source);
this.Controls.Add(this.lb_source);
this.Controls.Add(this.lb_type);
this.Controls.Add(this.label3);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.DoubleBuffered = true;
this.Font = new System.Drawing.Font("굴림", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
this.Margin = new System.Windows.Forms.Padding(5);
this.Name = "DPMachineControl";
this.Size = new System.Drawing.Size(713, 509);
((System.ComponentModel.ISupportInitialize)(this.nud_source)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.pb_now)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.pb_product)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label lb_type;
private System.Windows.Forms.Label lb_source;
private System.Windows.Forms.NumericUpDown nud_source;
private System.Windows.Forms.Button btn_add;
private System.Windows.Forms.Button btn_test;
private System.Windows.Forms.Button btn_start;
private System.Windows.Forms.Button btn_stop;
private System.Windows.Forms.Label label6;
private System.Windows.Forms.Label lb_now;
private System.Windows.Forms.Label lb_proper;
private System.Windows.Forms.Label label9;
private System.Windows.Forms.PictureBox pb_now;
private System.Windows.Forms.ComboBox cb_result;
private System.Windows.Forms.ComboBox cb_product;
private System.Windows.Forms.PictureBox pb_product;
}
}
5. DPMachineControl에 각 이벤트 핸들러를 구현합니다.
DPMachineControl.cs
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using 증착_공정_및_Burn_in_테스트_설비_콘솔_예광탄;
namespace DPMachineControl_예광탄
{
public partial class DPMachineControl : UserControl
{
public DPMachineControl()
{
InitializeComponent();
}
DepositionMachine dpmachine;
public DepositionMachine DPMachine
{
get
{
return dpmachine;
}
set
{
if (value == null)
{
return;
}
dpmachine = value;
btn_start.Enabled = true;
btn_stop.Enabled = false;
btn_add.Enabled = true;
btn_test.Enabled = true;
SetProperty();
dpmachine.OnDPCell += Dpmachine_OnDPCell;
dpmachine.OnDPPaper += Dpmachine_OnDPPaper;
dpmachine.OnEndJob += Dpmachine_OnEndJob;
dpmachine.OnAddSource += Dpmachine_OnAddSource;
dpmachine.OnStart += Dpmachine_OnStart;
}
}
private void Dpmachine_OnStart(object sender, EventArgs e)
{
SetStartStop(false);
}
private void Dpmachine_OnAddSource(object sender, DPMachileLib.AddSourceEventArgs e)
{
lb_source.Text = e.TotalCount.ToString();
}
private void Dpmachine_OnEndJob(object sender, EndJobEventArgs e)
{
if (this.InvokeRequired)
{
EndJobEventHandler dele = Dpmachine_OnEndJob;
object[] objs = new object[] { sender, e };
this.Invoke(dele, objs);
}
else
{
SetStartStop(true);
}
}
private void SetStartStop(bool sflag)
{
btn_stop.Enabled = !sflag;
btn_start.Enabled = sflag;
btn_test.Enabled = sflag;
}
List<Image> images = new List<Image>();//증착 완료한 이미지 컬렉션
private void Dpmachine_OnDPPaper(object sender, EndPaperDPEventArgs e)
{
if (this.InvokeRequired)
{
EndPaperDPEventHandler dele = Dpmachine_OnDPPaper;
object[] objs = new object[] { sender, e };
this.Invoke(dele,objs);
}
else
{
images.Add(pb_now.Image);
pb_now.Image = new Bitmap(100, 100);
lb_now.Text = (e.PNum + 1).ToString();
lb_proper.Text = "0";
cb_product.Items.Add(e.PNum);
cb_product.SelectedItem = e.PNum;
}
}
private void Dpmachine_OnDPCell(object sender, EndCellDPEventArgs e)
{
if (this.InvokeRequired)
{
EndCellDPEventHandler dele = Dpmachine_OnDPCell;
object[] objs = new object[] { sender, e };
this.Invoke(dele, objs);
}
else
{
lb_proper.Text = e.CNum.ToString();
int x = (e.CNum-1) % 10 * 10 + 2;
int y = (e.CNum-1) / 10 * 10 + 2;
Image image = pb_now.Image;
Graphics graphics = Graphics.FromImage(image);
Rectangle rect = new Rectangle(x, y, 6, 6);
if (e.Quality)
{
graphics.DrawRectangle(Pens.Red, rect);
}
else
{
graphics.DrawRectangle(Pens.Blue, rect);
}
pb_now.Invalidate();
}
}
private void SetProperty()
{
if(dpmachine==null)
{
return;
}
lb_type.Text = dpmachine.DT.ToString();
lb_source.Text = dpmachine.PCnt.ToString();
lb_now.Text = "1";
lb_proper.Text = "0";
pb_now.Image = new Bitmap(100, 100);
images.Clear();
cb_result.Items.Clear();
cb_result.Text = string.Empty;
cb_product.Items.Clear();
cb_product.Text =string.Empty;
pb_product.Image = new Bitmap(100, 100);
}
private void btn_start_Click(object sender, EventArgs e)
{
SetStartStop(false);
dpmachine.Start();
}
private void btn_add_Click(object sender, EventArgs e)
{
int pcnt = (int)nud_source.Value;
dpmachine.AddPaper(pcnt);
lb_source.Text = dpmachine.PCnt.ToString();
nud_source.Value = 0;
}
private void btn_test_Click(object sender, EventArgs e)
{
List<int> result = dpmachine.BurnInTest();
for(int i = cb_result.Items.Count;i<result.Count;i++)
{
cb_result.Items.Add(string.Format("{0}번 페이퍼 품질:{1}", i + 1, result[i]));
}
}
private void btn_stop_Click(object sender, EventArgs e)
{
dpmachine.Stop();
SetStartStop(true);
}
private void cb_product_SelectedIndexChanged(object sender, EventArgs e)
{
if (cb_product.SelectedIndex == -1)
{
return;
}
pb_product.Image = images[cb_product.SelectedIndex];
if(cb_product.SelectedIndex<cb_result.Items.Count)
{
cb_result.SelectedIndex = cb_product.SelectedIndex;
}
}
private void cb_result_SelectedIndexChanged(object sender, EventArgs e)
{
if(cb_result.SelectedIndex==-1)
{
return;
}
cb_product.SelectedIndex = cb_result.SelectedIndex;
}
}
}
6. Form1에 자식 컨트롤을 배치합니다.
증착 방법을 설정하는 세 개의 버튼 클릭 이벤트 핸들러를 추가합니다.
Form1.Designer.cs
namespace DPMachineControl_예광탄
{
partial class Form1
{
/// <summary>
/// 필수 디자이너 변수입니다.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 사용 중인 모든 리소스를 정리합니다.
/// </summary>
/// <param name="disposing">관리되는 리소스를 삭제해야 하면 true이고, 그렇지 않으면 false입니다.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form 디자이너에서 생성한 코드
/// <summary>
/// 디자이너 지원에 필요한 메서드입니다.
/// 이 메서드의 내용을 코드 편집기로 수정하지 마세요.
/// </summary>
private void InitializeComponent()
{
this.dpcon = new DPMachineControl_예광탄.DPMachineControl();
this.btn_pvd = new System.Windows.Forms.Button();
this.btn_cvd = new System.Windows.Forms.Button();
this.btn_ald = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// dpcon
//
this.dpcon.Font = new System.Drawing.Font("굴림", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
this.dpcon.Location = new System.Drawing.Point(174, 14);
this.dpcon.Margin = new System.Windows.Forms.Padding(5);
this.dpcon.Name = "dpcon";
this.dpcon.Size = new System.Drawing.Size(713, 509);
this.dpcon.TabIndex = 0;
//
// btn_pvd
//
this.btn_pvd.Font = new System.Drawing.Font("굴림", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
this.btn_pvd.Location = new System.Drawing.Point(13, 86);
this.btn_pvd.Name = "btn_pvd";
this.btn_pvd.Size = new System.Drawing.Size(114, 31);
this.btn_pvd.TabIndex = 1;
this.btn_pvd.Text = "PVD설정";
this.btn_pvd.UseVisualStyleBackColor = true;
this.btn_pvd.Click += new System.EventHandler(this.btn_pvd_Click);
//
// btn_cvd
//
this.btn_cvd.Font = new System.Drawing.Font("굴림", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
this.btn_cvd.Location = new System.Drawing.Point(13, 146);
this.btn_cvd.Name = "btn_cvd";
this.btn_cvd.Size = new System.Drawing.Size(114, 31);
this.btn_cvd.TabIndex = 2;
this.btn_cvd.Text = "CVD설정";
this.btn_cvd.UseVisualStyleBackColor = true;
this.btn_cvd.Click += new System.EventHandler(this.btn_cvd_Click);
//
// btn_ald
//
this.btn_ald.Font = new System.Drawing.Font("굴림", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
this.btn_ald.Location = new System.Drawing.Point(13, 195);
this.btn_ald.Name = "btn_ald";
this.btn_ald.Size = new System.Drawing.Size(114, 31);
this.btn_ald.TabIndex = 3;
this.btn_ald.Text = "ALD설정";
this.btn_ald.UseVisualStyleBackColor = true;
this.btn_ald.Click += new System.EventHandler(this.btn_ald_Click);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(901, 532);
this.Controls.Add(this.btn_ald);
this.Controls.Add(this.btn_cvd);
this.Controls.Add(this.btn_pvd);
this.Controls.Add(this.dpcon);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
private DPMachineControl dpcon;
private System.Windows.Forms.Button btn_pvd;
private System.Windows.Forms.Button btn_cvd;
private System.Windows.Forms.Button btn_ald;
}
}
7. Form1에 추가한 이벤트 핸들러를 구현합니다.
Form1.cs
using System;
using System.Windows.Forms;
using 증착_공정_및_Burn_in_테스트_설비_콘솔_예광탄;
namespace DPMachineControl_예광탄
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btn_pvd_Click(object sender, EventArgs e)
{
SetDPMachine(DeposType.PVD);
}
private void SetDPMachine(DeposType dt)
{
dpcon.DPMachine = new DepositionMachine(dt);
}
private void btn_cvd_Click(object sender, EventArgs e)
{
SetDPMachine(DeposType.CVD);
}
private void btn_ald_Click(object sender, EventArgs e)
{
SetDPMachine(DeposType.ALD);
}
}
}
'언어 자료구조 알고리즘 > 프로그래밍 실습' 카테고리의 다른 글
[python] 도서 관리 프로그램 (리스트 사용, 클래스 사용X) (0) | 2020.10.26 |
---|---|
[python] 함수 실습 (0) | 2020.10.23 |
[python] 제어문 실습 (0) | 2020.10.22 |
[C# 실습,통신 제어] 반도체 증착공정 및 Burn in 테스트 설비 시뮬레이션 (0) | 2020.10.13 |
[C# 실습,공장 UI 구현] 반도체 증착공정 및 Burn in 테스트 설비 시뮬레이션 (0) | 2020.10.12 |
[C# 실습,예광탄] 반도체 증착공정 및 Burn in 테스트 설비 시뮬레이션 (0) | 2020.10.08 |
[C# 실습, 시나리오] 반도체 증착공정 및 Burn in 테스트 설비 시뮬레이션 (0) | 2020.10.08 |
[C# 실습] 레코드 코팅 - 기계(서버)와 제어기(클라이언트) (0) | 2020.10.07 |
[C# 실습] 레코드 코팅 - 기계 구현(Windows Forms) (0) | 2020.10.07 |
[C# 실습, 사용자 정의 컨트롤 제작 예광탄] 레코드 코팅 (0) | 2020.10.06 |