[MFC] 다른 클래스에서 다이얼로그의 컨트롤 사용하기 ( 순환참조 피하기 )
상황은 대충 이러할 때 쓸 수 있다.
메인 다이얼로그, 송 수신 클래스가 있다.
구분을 위해 송신 '클래스', 수신 '클래스'라고 명명했지만
다이얼로그 클래스라고 생각해도 되고 다이얼로그가 연결돼있지 않은 일반 클래스라고 생각해도 된다.
본인은 메인 다이얼로그-클래스 관계로 코딩함. 자녀 다이얼로그의 클래스도 클래스이기 때문에 뭐 상관없다고 보고 그냥 포스팅
어쨌든
메인 다이얼로그(메인 클래스)에서 송신 클래스, 수신 클래스를 생성, 삭제, 조작한다.
즉, <사진 2>처럼 메인 다이얼로그는 송신 클래스와 수신 클래스를 알고 있는 상태이다.
알고 있는 상태라는 것은 당연히 메인 다이얼로그의 헤더에 각 클래스가 인클루드 된 상태라는 것
그렇다면 다이얼로그의 클래스가 아닌
다른 클래스(ChildDlg)에서 다이얼로그의 멤버 변수를 사용하거나, 컨트롤을 제어하고 싶을 때
단순히 헤더에 다이얼로그를 include 하고 멤버 변수를 꺼내 쓰면 되는 거 아닌가?라고 생각할 수 있다.
<사진 3>에서 알 수 있듯이 화살표를 보자
ChildDlg에서 메인 다이얼로그를 include하면
이미 메인 다이얼로그가 ChildDlg를 이미 알고 있는 상태이기 때문에 양방향의 화살표가 생겨버려서
순환 참조 에러가 날 수 있다.
아래 코드처럼 하면 된다.
편한 메모를 위해 부모 다이얼로그는 ParentDlg, 자녀 다이얼로그는 ChildDlg라 명명한다.
코드
<자녀 클래스>
1. 자녀 클래스에서 부모클래스를 선언해준다.
이때, 부모 다이얼로그의 헤더를 include는 하지 않는다.
// ChildDlg.h
class CParentDlg; // 클래스 생성
class CChildDlg
{
...
}
이런 식으로 따로 빼서 CParentDlg를 선언하고
2. 클래스와, 함수, 변수를 하나 씩 만든다.
// ChildDlg.h
class CParentDlg;
class CChildDlg
{
CParentDlg* m_pParent;
void Set_Wnd(CWnd* arg_pParent);
}
3. 이어서 자녀 다이얼로그의 cpp파일은 아래와 같이 작성한다.
// ChildDlg.cpp
#include <ChildDlg.h>
#include <ParentDlg.h> // 여기서(cpp파일) 부모의 헤더를 추가한다.
void CChildDlg::Set_Wnd(CWnd* arg_pParent)
{
this->m_pParent = (CParentDlg *)arg_pParent
}
이렇게 만든 Set_Wnd함수를 메인에서 사용한다면,
m_pParent로 메인 핸들을 받아와서 메인 다이얼로그의 멤버 변수나 컨트롤을 사용할 수 있다.
<부모 다이얼로그>
1. 부모 다이얼로그의 헤더에 자녀 클래스를 include한다.
// CParent.h
#include "Client.h"
2. 부모 다이얼로그에서 자녀 클래스를 선언한다.
// CParent.h
public:
CChildDlg* pChild;
3. 클래스를 생성한 뒤, Set_Wnd함수를 사용하여 자신의 핸들을 넘겨준다.
// CParent.cpp
pChild = new CChildDlg(); // 생성
pChild->Set_Wnd(this); // 넘겨주기
결과
자녀 다이얼로그에서 아래와 같이 메인 다이얼로그의 멤버 변수를 사용하면 된다.
// ChildDlg.cpp
(m_pParent->m_lst).InsertItem(nIndex, strIndex);
m_pParent->m_lst.InsertItem(nIndex, strIndex); 이런 식으로 써도 잘 작동되는데 가독성 때문에 괄호 붙였다.