한 명이 그런 말을 했을 때는, 분명히 다른 이유가 있을 것이라고 생각했다. 그런데 그런 말을 하는 사람이 점점 늘어났다. 그렇지만, 찌질한 내 어플리케이션 때문에 Windows(Window XP)를 종료할 수 없다는 게 말이나 되나?
언제 마지막으로 껐는지 기억나지 않는 내 컴퓨터의 종료아이콘을 클릭했다. 다른 프로그램들이 죽어도 나의 찌질이는 죽지 않고, Windows도 종료되지 않았다. 젠장~
쓰레드를 죽이지 않아서? 트레이아이콘에 내가 모르는 뭔가가…? 문제는 FormClosing이벤트에 있었다.
다음은 폼의 종료아이콘을 클릭할 경우 폼을 숨기고, 트레이아이콘의 메뉴를 클릭할 경우 폼을 진짜로 종료하는 ‘아주 일반적이라고 생각했던’ 코드이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
public partial class MainForm : Form { private bool closeForm = false; private void MainForm_FormClosing(object sender, FormClosingEventArgs e) { if (closeForm) { } else { e.Cancel = true; this.Visible = false; this.ShowInTaskbar = false; } } private void exitToolStripMenuItem_Click(object sender, EventArgs e) { closeForm = true; Close(); } // The rest is omitted // ... } |
혼자서 테스트 할 때는 잘 됐다. 문제는, Windows를 종료해보는 테스트까지는 해보지 않았다는 거… 그리고, 그런 건 당연히 종료되어야 하는 거 아냐?
문제는 FormClosing이벤트의 파라미터인 FormClosingEventArgs에 CloseReason이라는 멤버를 몰랐다는 것이다. 이는 폼이 어떻게 해서 종료요청을 받았는지를 알려주며, 그 중에는 WindowsShutDown이라는게 있어서, Windows가 요청했는지도 알 수 있다. 사용자가 명시적으로 폼을 닫을 경우에는 CloseReason이 UserClosing가 된다.
코드를 다음과 같이 수정하니, 윈도우가 무사히 종료된다.
1 2 3 4 5 6 7 8 9 |
private void MainForm_FormClosing(object sender, FormClosingEventArgs e) { if (e.CloseReason == CloseReason.UserClosing && closeForm == false) { e.Cancel = true; this.Visible = false; this.ShowInTaskbar = false; } } |
일단, 이렇게 문제가 일단락 되기는 했지만…, Windows란 놈, 생각보다 약하다.