WinForm 애플리케이션 핵심 파일
비주얼 스튜디오에서 WinForm 프로젝트를 생성하면 여러 가지 파일이 유기적으로 작동하여 하나의 화면을 구성하며, 이는 다음과 같다.
-
Program.cs: 모든 C# 언어 프로그램의 시작인 Main 메소드가 위치하며, 프로그램의 진입점이다.
-
Application.EnableVisualStyles() 메소드: Windows 운영체제의 최신 테마를 적용한다.
-
Application.SetCompatibleTextRenderingDefault(bool) 메소드: 텍스트 렌더링 방식을 최적화한다.
-
Application.Run(object) 메소드: 이 줄이 실행되는 순간에 프로그램은 종료되지 않고 사용자의 입력을 기다리는 무한 루프 상태로 진입하며, 이를 메시지 루프라고 한다.
-
-
Form.Designer.cs: 비주얼 스튜디오의 디자이너 도구 상자에서 컨트롤을 끌어다 놓을 때, 컴파일러가 자동으로 작성하는 C# 코드이며, InitializeComponent() 메소드를 사용하여 버튼의 크기, 위치, 텍스트 등을 선언한다.
- 주의 사항: 이 파일의 코드를 수동으로 수정하다가 문법이 틀리면 디자이너 화면이 깨질 수 있으므로, 가급적 직접 수정을 피해야 한다.
-
Form.cs: 개발자가 실제 기능을 구현하는 파일이며, partial 키워드를 사용하여 Designer.cs 파일과 실제 로직 코드를 물리적으로 분리하지만 컴파일 시에는 하나의 클래스로 합친다. 이를 통해 UI 코드와 기능 코드를 분할하여 관리할 수 있다.
Windows 메시지 루프 작동 원리
WinForm애플리케이션의 가장 중요한 특징은 아무것도 하지 않고 가만히 있는 것처럼 보이지만, 사실은 초당 수천번 이상 Windows 운영체제와 통신하고 있다는 점이다. 이를 메시지 루프(Message Loop)라고 하며, 이에 대한 설명은 다음과 같다.
-
메시지 큐(Message Queue): 사용자가 마우스를 움직이거나 키보드를 누르면, 운영체제는 해당 정보를 메시지라는 단위로 포장하여 해당 프로그램의 대기열에 넣는다.
-
GetMessage/DispatchMessage: 프로그램은 무한 루프를 돌며 큐에서 메시지를 꺼내어 해당 메시지가 어느 버튼이나 텍스트 박스에 해당하는 것인지 판별하고 실행한다.
-
단일 스레드 모델: 이 메시지 루프는 기본적으로 하나의 스레드(즉, UI 스레드)에서만 돌아간다. 따라서 특정 버튼 이벤트 안에서 너무 오래 걸리는 작업을 하면 메시지 루프가 멈추게 되고, 사용자는 프로그램이 응답하지 않음과 같은 상태 메시지를 보게 된다.
Form 클래스 상속 구조와 핵심 속성
WinForm 애플리케이션의 모든 화면은 System.Windows.Forms.Form 클래스를 상속받는다. 이 클래스는 방대한 부모 클래스들로부터 기능을 물려받으며, 이는 다음과 같다.
-
Object → MarshalByRefObject → Component → Control → ScrollableControl → ContainerControl → Form
-
Control: 화면에 그려지는 모든 요소의 부모이다.
-
ScrollableControl: 스크롤바 기능을 제공한다.
-
Form: 캡션 표시줄, 최소화/최대화, 대화 상자 등 기능을 포함한 윈도우 창이다.
-
주요 속성를 상세하게 정리한 내용은 다음과 같다.
-
StartPosition: 창이 처음 뜰 때 위치이다.
-
FormBorderStyle: 창의 테두리 모양이다.
-
TopMost: 다른 모든 프로그램 창보다 항상 위에 뜨게 할 것인지 결정한다.
-
ShowInTaskbar: 하단 작업 표시줄에 아이콘을 표시할지 여부이다.
Form 생명 주기와 이벤트
프로그램이 실행되어 종료될 때까지 Form은 정해진 순서대로 이벤트를 발생시킨다. 개발자는 이 순서를 정확히 알아야 어느 시점에 초기화 코드를 넣을지 결정할 수 있다.
-
Constructor: 객체가 메모리에 올라가는 단계이다. InitializeComponent() 메소드가 호출되어 컨트롤들이 생성된다.
-
Load: Form이 화면에 보이기 직전에 발생하며, 데이터베이스 연결이나 초기 데이터 로딩을 하기에 가장 적합한 시점이다.
-
Shown: Form이 화면에 완전히 나타난 후 발생한다.
-
Activated: 사용자가 해당 창을 클릭하여 활성화했을 때 발생한다.
-
FormClosing: 사용자가 닫기 버튼을 눌렀을 때 발생하며, 확인 창을 띄우고 종료를 취소할 수 있는 기회를 부여할 수 있다.
-
FormClosed: Form이 완전히 닫히고 메모리에서 해제되기 직전에 발생한다.
-
Deactivated: 다른 창으로 포커스를 옮길 때 발생한다.
Windows 핸들
모든 WinForm 컨트롤은 시스템으로부터 고유한 번호를 부여받는데, 이를 핸들(Handle)이라고 한다.
- this.Handle: 현재 Form의 시스템 핸들 값을 가져오며, Win32 API와 직접 통신해야 하는 고급 프로그래밍을 할 때 이 핸들 값이 주소 역할을 한다.