본문 바로가기

old drawer/C, C++, MFC

[MFC] 다이얼로그 내부 Formview 생성하기

Dialog를 생성해서 내부의 화면만 계속 바꾸고 싶을 때가 있습니다. 

 

예를 들자면 Visual Studio에서 제공하는 환경설정 메뉴같은 경우입니다.

 

 

좌측의 트리 메뉴를 선택하면 우측의 메뉴가 변경되는 것을 볼 수 있습니다.

 

유사한 화면을 갖는다면 굳이 새로운 화면을 만들 필요는 없습니다.

 

컨텐츠만 바꿔주면 되기 때문입니다.

 

하지만 전혀 다른 화면을 가져야 한다면,

 

FormView를 쓰는 방법을 고려해볼 수 있습니다.

 

FormViewDialog와 같이 컨트롤들을 올려서 사용할 수 있는 View 입니다.

 

Dialog에 FormView를 올리고 다른 FormView로 교체하는 방법을 사용하면

 

마치 Dialog가 화면을 갱신하는 듯한 효과를 줄 수 있습니다.

 

일단 프로젝트를 하나 생성합니다.(이름은 SubFormView로 했습니다.)

 

 

그리고 MFC Project의 설정은 다음과 같이 변경하였습니다.

 

 

Dialog based로 프로젝트를 생성했습니다.

 

먼저 2개의 버튼을 올려 놓도록 하겠습니다.

 

나중에 이 2개의 버튼으로 FormView를 바꿔서 올리는 것을 할 예정입니다.

 

이제 FormView를 2개 만들어 보도록 하겠습니다. 

 

다음과 같이 프로젝트명 위에 마우스 오른쪽 클릭을 하고

 

Add->Class로 갑니다.

 

 

다음과 같이 뜨면 MFC Class를 누르고 Add를 누릅니다.

 

그리고 이제 클래스명과 Base class를 다음과 같이 선택해줍니다.

 

저는 CFormView1이라고 이름 지었고,  

 

Base class를 CFormView로 해줬습니다. 

 

Class name과 Base class만 적으면 밑에는 알아서 작성됩니다. 

 

필요하다면 다른 이름으로 변경해서 사용해도 괜찮습니다. 

 

설정이 끝나면 Finish 버튼을 눌러줍니다. 

 

첫 번째 FormView생성했고 두 번째도 같은 방법으로 만들어 줍니다. 

 

이번에는 CFormView2 로 명명하겠습니다. 

 

FormView를 2개 만들었습니다. 

 

2개의 FormView의 구분을 위해서 Dialog에 기본으로 올라가 있는

 

Static Control의 텍스트를 바꿉니다.

 

FormView는 다이얼로그와 유사한 View이기 때문에 Dialog를 리소스로 갖습니다.

 

 

 

다음과 같이 This is FormView1으로 바꿨습니다. 

 

FormView2는 This is FormView2로 바꿨습니다. 

 

이제 Main Dialog에 이 2개를 생성하는 작업을 추가해야 합니다.

 

일단 2개의 FormView 헤더를 추가하고 CView* 멤버 변수를 2개 추가합니다. 

 

이제 FormView를 만드는 코드를 OnInitDialog()에 추가해줍니다.

   

위에 rc에 GetClientRect로 다이얼로그 영역을 받아와서

 

위와 아래에 있는 버튼과 겹치지 않게 적당히 줄였습니다. 

 

밑에 네모로 처리된 부분이 실제 FormView를 만드는 부분입니다. 

 

여기서 RUNTIME_CLASS라는 것이 보이는데 이것은 Class의 이름에서 

 

CRuntimeClass 포인터를 받는 것으로 Class명으로 동적으로

 

객체를 생성한다고 보시면 됩니다. 

 

이것을 사용하기 위해서는 CObject를 상속받아야 하고

 

DECLARE_DYNAMIC, DECLARE_DYNCREATE 

혹은, DECLARE_SERIAL이 선언되어야 합니다.

 

CFormView1, 2의 헤더에 보시면 DECLARE_DYNCREATE가 확인 가능합니다. 

 

그리고 CFormView는 최상위에 CObject를 상속받게 되어 있기 때문에

 

RUNTIME_CLASS 매크로를 이용해서 생성이 가능한 것입니다. 

 

남은 건 이제 Create()와 OnInitialUpdate()를 호출한 것 뿐입니다. 

FormView에서는 OnInitDialog()의 기능을 하는 것이 OnInitialUpdate()입니다.

 

Create() 함수 호출 시에 에러가 날 수 있는데, 

 

이 문제는 Create() 함수의 접근 속성이 public이 아니기 때문입니다.

 

재정의를 한 이후에 public 속성으로 바꿔주시면 됩니다. 

 

이제 버튼 클릭 이벤트에 m_pFormView1->ShowWindow(SW_SHOW);

 

의 형태로 View를 숨기거나 보이게 하는 것이 가능합니다.

 

글을 길게 작성하기는 했지만 어려운 부분은 없고,

 

코드 몇 줄이면 쉽게 Dialog에 FormView를 올릴 수 있습니다.

 

아마 다양한 용도로 사용이 가능할 것입니다. 

 

SDI에서 Dialog를 띄웠을 때,  

내부에 FormView를 가질 경우 발생하는 문제

 

관한 포스팅은 이전(클릭)에 작성하였으니 확인하시기 바랍니다.