csharp_폼_생성_시_메서드_호출_순서

CSharp 폼 생성 시 메서드 호출 순서

C# 폼 생성 시 메서드 호출 순서에서는 C#에서 (메인)폼이 생성되면서 호출되는 메서드들의 순서를 MFC의 다이얼로그 기반(Dialog Based) 프로그램과 비교하여 설명한다.

C#은 굉장히 편한 언어지만, MFC에서 바로 넘어가면 햇갈리는 부분이 상당히 많다. 그 중 나를 가장 혼란스럽게 만드는 것은 이벤트 핸들러(event handler)라는 개념이었다. MFC에서는 이 이벤트 핸들러 중에서 자주 사용되던 것들을 미리 멤버 함수로 정의해 두어 대충 사용하면 되었지만, C#에서는 직접 이벤트 핸들러와 메서드를 연결해야 하는 경우가 꽤 많은 것 같다.

대충 쉽게 장난감 프로그램 하나 만든다고 하면 MFC의 다이얼로그 기반 프로그램이 최고였다. 장난감용 언어의 최고봉(?)인 루비파이썬도 좋지만 아무래도 윈도우용 GUI를 만드는 것은 MFC가 그나마 편했다.

이 MFC 다이얼로그 기반 프로그램이 아무리 대충 가지고 놀기 좋다고는 해도 함수 호출 순서를 알아야 버그를 피할 수 있다. 특히 MFC(C)는 포인터 실수하기에 너무 좋다. MFC 다이얼로그 기반 프로그램의 생성 ~ 소멸까지 멤버 함수가 호출되는 순서는 다음과 같다.1)(프로그램 이름을 Test로 한 경우이다.)

  1. CTestApp theApp
    1. theApp란게 전역으로 선언되어 있다. 잘 몰라도 된다.
  2. CTestApp::CTestApp()
    1. CTestApp의 변수가 선언되었으니 바로 객체가 생성되고 생성자가 불린다.
  3. CTestApp::InitInstance()
    1. 다음으로 여기에서 각종 초기화 과정이 수행된다.
    2. 함수의 끝 부분에서 다이얼로그를 생성하고, 띄운다.(DoModal())
  4. CTestDlg::CTestDlg(…)
    1. 사실 띄우기 전에 해당 다이얼로그의 생성자가 불린다.
    2. 포인터변수 초기화는 이곳에서 하는 것이 좋다.
      1. m_pMyClass = NULL;
  5. CTestDlg::OnInitDialog()
    1. 생성자 이후에 사용자가 초기화 하는 내용은 이곳에 들어간다.
    2. 다이얼로그에서 멤버변수로 사용한 포인터를 NULL로 초기화하는 것 외에는 전부 여기서 초기화한다고 생각하자
      1. m_pMyClass = new CMyClass();
  6. Message Loop
    1. 각종 이벤트 처리를 처리한다.
    2. 실제 프로그램이 수행되는 부분이다.
      1. 버튼이 눌렸을 때 뭘 한다던가.. 키를 눌렀을 때 뭘 한다던가..
  7. CTestDlg::OnDestroy()
    1. 다이얼로그가 삭제되기 전에 호출된다.
    2. 소멸자보다는 이 쪽을 애용하자.
    3. 생성한 객체를 삭제하는 곳이 보통 여기다.
      1. delete m_pMyClass
  8. CTestApp::ExitInitance()
    1. 그냥 무시해도 된다.
    2. 아마 이걸 무시할 수 없는 프로그램을 만드는 사람이 이 글을 읽고 있지는 않을 것이다.

MFC는 이와 같이 호출되는 함수가 딱딱 명확하여 어디에서 초기화할지가 눈에 보여 편했다. 하지만 MFC를 하던 감으로 C#을 가지고 노려니 영 어색하다. C#의 메서드(?) 호출 순서는 상당히 다르다. 아니 사실 이벤트 핸들러라는 것이 생긴 C#의 개념 자체가 달라 적응이 어렵다.

처음 생성하는 폼의 이름은 기본적으로 Form1이지만 이것을 MainForm으로 수정하였다.

  1. static void Main(string[] args)
    1. 자바와 비슷하다.
    2. Program이란 클래스의 Main에서 시작한다.
  2. MainForm(), Application.Run(new MainForm())
    1. 코드는 Apllication.Run이 먼저 나오지만 어쨌건 생성자가 먼저 호출된다.
    2. 아마 보통 신경을 잘 안 써서 MainForm 대신 Form1을 볼 수 있을 것이다.
    3. 폼을 생성하면서 바로 창을 띄워버린다.
  3. MainForm.InitializeComponent()
    1. 생성자 안에 이게 있다.
    2. 각종 리소스(컨트롤)을 초기화한다.
    3. 코드편집기로 수정하지 말라고 명시돼 있다.
  4. MainForm Load
    1. 폼 생성이 완료되면 다음 순서가 이것이다. 그러나 따로 메소드가 있지는 않고 이벤트 핸들러를 추가해 주어야 한다.
    2. MainForm의 생성자에 다음 코드 추가
      1. this.Load += new EventHandler(MainForm_Load);
    3. MainForm 클래스에 다음 메소드 추가
      1. private void MainForm_Shown(object sender, EventArgs e)
  5. MainForm Shown
    1. MainForm Load와 같다.
    2. 폼 생성후에 바로 다른 폼을 여는 경우, 다른 폼을 여는 코드를 이곳에 넣어야 순서가 올바르게 적용된다.
    3. Load에 넣는 경우 다른 폼이 먼저 열리고, MainForm이 나중에 열린것과 같은 형태가 된다.
  6. 각종 이벤트 처리
    1. 실제 프로그램이 수행되는 부분이다.
    2. 버튼이 눌렸을 때 뭘 한다던가.. 키를 눌렀을 때 뭘 한다던가..
  7. 소멸 과정
    1. .NET 프레임워크가 알아서 처리한다.

~~LINKBACK~~


1)
아마 VC 6.0 기준이다. 하지만 2005에서도 그리 바뀌지 않았고, 아마 이후에도 비슷할 것이다.
댓글을 입력하세요. 위키 문법이 허용됩니다:
A C U I I