본문 바로가기

Programming/Win32&MFC&COM

Dialog 내부에 FormView 추가하기

반응형

Dialog를 생성하고 내부의 화면만 계속 변경하고 싶을 때가 있습니다.

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

좌측의 트리 형태의 메뉴를 선택하면 우측이 변경되는 모습을 확인할 수 있습니다.

이것을 구현하기 위해서 FormView 활용하는 방법을 고려할 수 있습니다.

FormView는 Dialog과 유사하게 다른 컨트롤을 추가해서 사용할 수 있는 View입니다.

필요에 따라 FormView를 작성하고 교체하는 방법을 사용하면 됩니다.

먼저 MFC 프로젝트를 생성합니다.

Dialog based로 변경하고 그 외에 필요한 설정을 합니다.

나머지는 기본 설정으로 그냥 두고 생성하도록 하겠습니다.

기본 Dialog에 버튼 2개를 추가합니다.

이 버튼을 누르면 각각 다른 FormView가 보이게 할 예정입니다.

그리고 PROJECT-> Add Class 메뉴로 FormView를 2개 추가합니다.

먼저 처음 클래스는 Class name은 CFormView1으로 Base class는 CFormView로 했습니다.

작성하면 아래 부분은 자동으로 입력됩니다.

두 번째도 동일한 방식으로 하고 이름을 CFormView2로 해서 생성합니다.

화면을 구분하기 위해서 각각의 Dialog의 텍스트를 구분이 가능하게 변경합니다.

그리고 Main Dialog에 이것을 생성하는 코드를 작성해야 합니다.

여기서는 SubFormViewDlg.h에 아래와 같이 헤더를 추가합니다.

#include "FormView1.h"
#include "FormView2.h"

그리고 클래스의 선언 내부에 다음 코드를 추가합니다.

public:
	CView* m_pFormView1;
	CView* m_pFormView2;

OnInitDialog()에 FormView를 실제 생성하는 코드를 추가합니다.

	// TODO: Add extra initialization here

	CRect rc;
	GetClientRect(&rc);
	rc.left += 100;

	CCreateContext cc;

	CView* pView = (CView*)RUNTIME_CLASS(CFormView1)->CreateObject();
	ZeroMemory(&cc, sizeof(cc));
	pView->Create(nullptr, nullptr, WS_CHILD, rc, this, IDD_FORMVIEW1, &cc);
	pView->OnInitialUpdate();
	m_pFormView1 = pView;

	pView = (CView*)RUNTIME_CLASS(CFormView2)->CreateObject();
	ZeroMemory(&cc, sizeof(cc));
	pView->Create(nullptr, nullptr, WS_CHILD, rc, this, IDD_FORMVIEW2, &cc);
	pView->OnInitialUpdate();
	m_pFormView2 = pView;

	m_pFormView1->ShowWindow(SW_SHOW);

Dialog의 크기를 받아와서 왼쪽의 버튼과 겹치지 않도록 위치를 조정했습니다.

RUNTIME_CLASS를 사용했는데 클래스의 이름에서 CRuntimeClass 포인터를 받습니다.

클래스 이름을 통해서 동적으로 객체를 생성하는 역할을 합니다.

이것을 사용하기 위해서는 몇 가지 제약이 존재합니다.

먼저 CObject를 상속받아야 합니다.

그리고 DECLARE_DYNAMIC, DECLARE_DYNCREATE, 혹은 DECLARE_SERIAL이 선언되어야 합니다.

생성된 FormView의 헤더에서 DECLARE_DYNCREATE를 확인할 수 있습니다.

그리고 Create()와 OnInitialUpdate()를 통해서 생성하면 됩니다.

주의할 점은 m_pFormView1, 2는 delete로 해제하면 안된다는 점입니다.

내부에서 호출이 되기 때문에 두 번 호출되면서 에러가 발생합니다.

Create()에서 에러가 날 경우에는 Create()를 public으로 오버라이드 하면 됩니다.

마지막으로 버튼 클릭 이벤트를 추가해서 다른 FormView가 보이게 코드를 추가하면 됩니다.

void CSubFormViewDlg::OnBnClickedButton1()
{
	m_pFormView1->ShowWindow(SW_SHOW);
	m_pFormView2->ShowWindow(SW_HIDE);
}

void CSubFormViewDlg::OnBnClickedButton2()
{
	m_pFormView2->ShowWindow(SW_SHOW);
	m_pFormView1->ShowWindow(SW_HIDE);
}

컴파일 이후에 실행하면 버튼을 누를 때마다 변경되는 것을 확인할 수 있습니다.

전체 소스 코드는 아래의 링크를 통해서 확인할 수 있습니다.

SubFormView.zip

이것으로 다양한 화면을 가지는 Dialog를 쉽게 작성할 수 있습니다.

반응형