개발자 '쑥말고인절미'

[MFC] 다른 cpp에 있는 멤버 변수 호출해서 사용하기(mfc view 포인터 얻기) 본문

STUDY/C++ & MFC

[MFC] 다른 cpp에 있는 멤버 변수 호출해서 사용하기(mfc view 포인터 얻기)

쑥말고인절미 2022. 4. 19. 12:34

Seminar01View.cpp에 있는 CListCtrl형 변수 m_List를 MainFrm.cpp에서 사용하려고 했는데 도저히 내가 아는 지식으로는 해결이 안돼서 책임님께 여쭤봐서 구현할 수 있었다.

 

혼자서 구글링 해서 extern도 해보고 static도 써봤지만 사실 메모리도 이해가 잘 안갔고 왜 이렇게 쓰는지 왜 사용하는지 이해를 잘 못했다.

 

책임님께서 'mfc view 포인터 얻기'라는 키워드로 검색을 해보라 하셨고 단번에 해결책을 찾을 수 있었는데 참고했던 링크는 아래에 첨부했다.

 

CxxxView* pView = (CxxxView*)((CMainFrame*)(AfxGetApp()->m_pMainWnd))->GetActiveView();

참고링크를 보면 여러 소스가 있는데 그 중 위 부분만 사용했다.

사실 나는 아무 생각 없이 옮겨서 내 소스에 적용하고 있었는데 옆에 지켜보시던 책임님께서 "소스가 한 줄로 길게 있으면 가독성이 떨어지기 때문에 두 줄로 나눠서 작성하는게 좋겠다"고 하셨다.

내 소스에서는 다음과 같이 수정해서 작성했다.

//CMainFrame* pMain = (CMainFrame*)AfxGetApp()->m_pMainWnd; // == this
CSeminar01View* pView = (CSeminar01View*)GetActiveView();

 

참고링크 소스를 보면 ((CMainFrame*)(AfxGetApp()->m_pMainWnd)) 요 부분이 의미하는 바가 MainFrame을 의미하는 건데 나는 MainFrame의 MainFrm.cpp에 소스를 작성 중이었기 때문에 결국 자기 자신을 의미하는 것이다. 결국 저 긴 문장이 this와 동일한 것이다. 그래서 그 부분은 지웠다.

CMainFrame* pMain = (CMainFrame*)AfxGetApp()->m_pMainWnd; // == this
CSeminar01View* pView = (CSeminar01View*)pMain->GetActiveView();

//위 소스와 아래 소스는 동일한 의미이고 동일하게 작동한다.

//CMainFrame* pMain = (CMainFrame*)AfxGetApp()->m_pMainWnd; // == this
CSeminar01View* pView = (CSeminar01View*)GetActiveView(); // 최종 문장

GetActiveView()라는 메소드는 활성화 된 뷰를 얻어온다고 한다. 내 프로젝트는 단일 문서로 설정했기 때문에 저 문장이 아무런 문제가 없이 잘 돌아가지만 다중 문서로 설정했을 시에는 활성화 된 뷰가 여러 개이기 때문에 뷰를 얻어오는 방법이 다르다고 한다. 

 

AfcGetApp()이라는 메소드는 App클래스에서 뭔가를 얻어온다고 하셨는데 아래 클래스 뷰를 보면 CSeminar01App에서 동작?하는 거라고 하셨다. 사실 기억이 잘 안난다...

클래스 뷰

 

사실 저렇게 pView를 얻고 난 뒤에 저걸 어떻게 사용해야 하는지 감이 안잡혔는데 '->'를 사용해서 작성하면 된다고 알려주셨다. 나는 m_List.InsertItem(i, m_Grade[i]); 이렇게 작성했다면 pView만 앞에 붙여주면 내가 원하는대로 구현이 된다. 아래 소스를 참고하자

//원래 내 소스에 클래스 포인터 pView를 만들어준 상태이다.
void CMainFrame::OnButtonAdd()
{
	CString m_Grade[] = { _T("2"), _T("3"), _T("1") };
	CString m_Name[] = { _T("한지수"), _T("김유리"), _T("박지형") };
	CString m_Korean[] = { _T("70"), _T("85"), _T("95") };
	CString m_Math[] = { _T("85"), _T("90"), _T("100") };
	CString m_English[] = { _T("75"), _T("90"), _T("80") };

	CSeminar01View* pView = (CSeminar01View*)GetActiveView();

	for (int i = 0; i < 3; i++) {
		m_List.InsertItem(i, m_Grade[i]);
		m_List.SetItemText(i, 1, m_Name[i]);
		m_List.SetItemText(i, 2, m_Korean[i]);
		m_List.SetItemText(i, 3, m_Math[i]);
		m_List.SetItemText(i, 4, m_English[i]);
	}
}

//위처럼 작성되어 있는 코드를 아래 처럼 m_List앞에 pView-> 만 추가해주면 된다.

//완성~
void CMainFrame::OnButtonAdd()
{
	CString m_Grade[] = { _T("2"), _T("3"), _T("1") };
	CString m_Name[] = { _T("한지수"), _T("김유리"), _T("박지형") };
	CString m_Korean[] = { _T("70"), _T("85"), _T("95") };
	CString m_Math[] = { _T("85"), _T("90"), _T("100") };
	CString m_English[] = { _T("75"), _T("90"), _T("80") };

	CSeminar01View* pView = (CSeminar01View*)GetActiveView();

	for (int i = 0; i < 3; i++) {
		pView->m_List.InsertItem(i, m_Grade[i]);
		pView->m_List.SetItemText(i, 1, m_Name[i]);
		pView->m_List.SetItemText(i, 2, m_Korean[i]);
		pView->m_List.SetItemText(i, 3, m_Math[i]);
		pView->m_List.SetItemText(i, 4, m_English[i]);
	}
}

 

하여튼 저런 방식으로 클래스 포인터를 얻어와 다른 cpp에 있는 변수를 사용할 수 있었다.

아래에 m_List가 들어간 부분은 모조리 첨부했다.

 

//Seminar01View.h
class CSeminar01View : public CFormView{
	...
public:
...
	CListCtrl m_List;
};

//-------------------------------------------------------------------------------
//Seminar01View.cpp
void CSeminar01View::DoDataExchange(CDataExchange* pDX)
{
	...
	DDX_Control(pDX, IDC_LIST, m_List);
}

void CSeminar01View::OnInitialUpdate()
{
	...
	m_List.InsertColumn(0, _T("학년"), LVCFMT_LEFT, 80);
	m_List.InsertColumn(1, _T("이름"), LVCFMT_LEFT, 80);
	m_List.InsertColumn(2, _T("국어"), LVCFMT_LEFT, 80);
	m_List.InsertColumn(3, _T("수학"), LVCFMT_LEFT, 80);
	m_List.InsertColumn(4, _T("영어"), LVCFMT_LEFT, 80);
}

//-------------------------------------------------------------------------------
//MainFrm.cpp
void CMainFrame::OnButtonAdd()
{
	CString m_Grade[] = { _T("2"), _T("3"), _T("1") };
	CString m_Name[] = { _T("한지수"), _T("김유리"), _T("박지형") };
	CString m_Korean[] = { _T("70"), _T("85"), _T("95") };
	CString m_Math[] = { _T("85"), _T("90"), _T("100") };
	CString m_English[] = { _T("75"), _T("90"), _T("80") };

	CSeminar01View* pView = (CSeminar01View*)GetActiveView();

	for (int i = 0; i < 3; i++) {
		pView->m_List.InsertItem(i, m_Grade[i]);
		pView->m_List.SetItemText(i, 1, m_Name[i]);
		pView->m_List.SetItemText(i, 2, m_Korean[i]);
		pView->m_List.SetItemText(i, 3, m_Math[i]);
		pView->m_List.SetItemText(i, 4, m_English[i]);
	}
}

 

참고링크

http://printf.egloos.com/v/1940633

 

It's my life : MFC :: MainFrame,Doc,View의 포인터 얻기

# MainFrame,Doc,View의 포인터 얻기※ 주의할점 : 얻어올 포인터의 헤더 정보를 include하여야 하며 순서에 유의하자!※ CMainFrame* pFrame = (CMainFrame*)AfxGetApp()->GetMainWnd(); 1. MainFrame 포인터 얻기 CMainFrame *fra

printf.egloos.com