안녕하세요. C++를 막 시작한 쿠나입니다.. 는 훼이크고

그동안에 VB로 여러 잡다 프로그램은 많이 짜보았지만 정작 C++, 즉 API/MFC 프로그래밍을 전혀 하지 않은 터라서 그동안의 프로그래밍 실력에 큰 변화가 없게 된 듯 합니다. 그동안에 API 함수가 필요하였을 때도 단순히 API 텍스트 뷰어로 잠시 빌렸을 뿐이었죠.

그래서 앞으로 제가 MFC를 하면서 느낀 점들을 VB.net에 빗대어 설명하려고 합니다. 이 허접한 글 보아주시는 여러분들에게 조금이나마 도움이 되었으면 좋겠습니다 ^^


오늘은 간단히 MFC로 폼 프로그래밍의 기본인 폼 띄우기, 이른바 모달/모달리스 창 띄우기를 해 보겠습니다. 아마 VB.net에서는 새로운 폼을 띄울 때 이렇게 띄우셨을 것으로 생각합니다.

Dim modalfrm As New Form1
modalfrm.Show


이때 생성되는 폼의 상태를 '모달'이라고 합니다. 즉 이 Form1을 띄우게 한 상위 개체와의 통신이 가능한 상태죠

아직 이해가 안되셨다면, 밑의 소스를 보아주세요.

Dim modalessfrm As New Form1
modalessfrm.ShowDialog


위 소스와의 차이점은 바로 Show 메서드가 ShowDialog로 바뀌었다는 겁니다. 그렇습니다. 이와 같은 '모달리스'의 경우에는 상호 객체와의 통신이 불가능해지는 거죠. 조금 복잡한 개념으로는 단일 쓰레드를 이용하기 때문에 이 새로 띄운 폼의 작업이 끝나기 전까지는 다른 작업을 할 수 없게 됩니다.

그렇다면 C++, 이른바 [MFC]에서는 이 작업을 어떻게 수행할까요? 결코 어렵지는 않습니다. 차근차근 하다 보시면 그리 어렵지 않게 VB와 같은 VC를 맛보실 수 있을 거예요.

1. 새롭게 프로젝트를 만들고 형식을 C++->MFC로 합니다.

2. MFC 마법사 창에서 위와 같이 다이어로그 기반으로 만듭니다.

3. 자 이제 만들어졌으면 위와 같이 버튼 3개를 배치하고 맨 위의 버튼을 위와 같은 이름으로 만듭니다. 아직 밑의 2개 버튼은 내버려둡시다.

4. 옆의 리소스뷰에 보시면 IDC_ABOUTDLG가 보이시나요? 더블클릭해보면 이것은 하나의 폼임을 알 수 있습니다. 그럼 이제 이 폼을 띄워봅시다. 먼저 IDC_BUTTON1에 OnClick이벤트를 적용해 봅시다. 위와같이 [이벤트 >> BN_CLICKED]에 이벤트를 추가하시면 -


5. 소스코드를 입력할수 있는 부분이 나타납니다. 그럼 이제 소스코드를 입력해 봅시다.

    CAboutDlg *dlgAbout = new CAboutDlg;
    dlgAbout->DoModal();
    dlgAbout->DestroyWindow();
    delete dlgAbout;


그런데 혹시 VB.net와 비슷한 점이 보이시지 않나요?

Dim frm as Form1 = New Form1
frm.ShowDiolog
Unload frm
frm = Nothing


여기서는 굳이 필요없는 밑의 2줄을 넣었지만[VB같은 경우에는 알아서 메모리누수가 해제됩니다] 이것으로 VC도 알고보면 VB와 상당히 흡사한 구조임을 알 수 있습니다.

이제 한번 컴파일을 해 봅시다.

6. 위와 같이 금방 쉽게 만들어지는군요. 만세!


이제는 자신이 직접 폼을 추가해보고 이 폼을 띄워 봅시다.

7. 리소스뷰에서 오른쪽마우스버튼을 클릭한 뒤 다이어로그 추가 버튼을 누릅시다.


8. 다이어로그가 추가되었지만 이에 대한 아무런 소스가 존재하지 않는 이른바 '모양만 다이어로그'상태입니다. 이제 구동이 가능하도록 새 클래스를 추가해줍시다. 먼저 폼의 빈 곳에 오른쪽버튼을 누르고 클래스 추가 버튼을 누른뒤, 새롭게 추가할 클래스를 CnewDlg(VB에서 폼의 앞에 접두어 f나 frm을 붙인다면 MFC에서는 C를 붙입니다)로 정하고 상속받을 클래스 타입을 CDialog 로 합시다 [기본값으로 설정되어 있는 CHtmlDialog로 설정하실 경우 HTML기반 렌더링을 하기 때문에 약간의 문제가 생길 수 있습니다].

9. 옆의 클래스뷰를 보시면 새로운 클래스 'CnewDlg'가 추가되었음을 알 수 있군요. 그럼 이제 이 CnewDlg를 쓰기 위해서 newDlg.h파일을 메인 cpp 파일(또는 헤더파일)에 연결해 봅시다. 어떻게? #include문을 통해서!

- 메인 CPP 파일의 상단 부분에 위와 같이 코드를 입력합시다.
#include "newDlg.h"

10. 이제 준비는 거의 끝났습니다. 이제는 새로운 클래스 CnewDlg를 쓸 수 있군요. 이제 밑의 두 버튼 이름을 이렇게 바꾸고



위와 같이 각 버튼에 소스코드를 입력합니다.

11. 모든 코드가 잘 작동하는군요! 그런데 이상합니다. IDC_BUTTON3을 눌러보고 프로그램을 종료해본 뒤 디버그창을 확인해봅시다.


Detected memory leaks!
Dumping objects ->
(.. 중략)
Object dump complete.

이런. 메모리누수가 발생한 듯 하군요. MFC에서는 모달리스의 경우 자기 자신을 종료시킬 때 메모리에서 삭제시키는 구문을 따로 넣어야만 합니다. 실제로 작업관리자에서 보시면 차지하는 메모리의 양이 폼을 띄울 때마다 증가하는 것을 보실 수 있습니다.

12. newdlg.cpp 문서를 여신 뒤 [속성] 창에서 [재정의]를 선택한 뒤 PostNcDestroy를 재정의 합니다.

참고로 PostNcDestroy는 창이 소멸된 후에 호출되는 윈도우가 가장 마지막으로 남기는 메시지를 말합니다.


다시 창을 띄우시면 이제 더이상 메모리 누수 문제는 발생하지 않지만.. 모달 창을 띄울때는 문제가 발생합니다 ㅎㅎ. 즉 모달, 모달리스는 별도로 창을 만들어야 한다는 뜻이죠.


완성된 예제 첨부합니다.

댓글을 달아 주세요

  1. BlogIcon irina 2008/11/01 18:25
     addr - mod/del - rep

    저도 언젠가 C++을 해야 하는데... 영재학급 프로젝트도 프로그래밍을 해서 하기는 해야되요.

    • BlogIcon 쿠나 2008/11/02 09:45
       addr - mod/del - rep

      영재학급 프로젝트도 프로그래밍을 한다고요? 그런 소리는 처음 들어 보는데 =ㅅ=;
      저도 요새 바빠서 거의 손도 못대고 있습니다 ㅎㅎ.... 게다가 고딩되면 더 암울 흐억;; ㅠ

  2. BlogIcon Noel 2008/11/01 18:57
     addr - mod/del - rep

    만세!

< 1 ... 615 616 617 618 619 620 621 622 623 ... 832 > Top