MFC 정리가 필요해서 끄적끄적 작성하고 코드로 쳐보고 해보았습니다. 추가해야하는 부분은 점차 수정해나가겠습니다.
MFC 로 프로젝트 생성하였다는 가정하에 정리합니다. 프로젝트명 Test
CTestApp(CWinApp 상속) - 프로그램의 생성을 담당하는 영역, 프로그램 초기화관련
CMainFrame(CFrameWnd상속)- 겉 프레임을 윈도우 담당하는 클래스
CTestDoc(CDocument상속) - 문서의 저장 열기 등등, 문서 담당하는 클래스
CTestView(CView상속) - 화면을 담당하는 클래스
CTestDlg(CDialog상속) - 도움말 대화상자 클래스
● CTestApp 포인터 얻어오기
CTestApp은 CWinApp를 상속받는다.
어느곳에서나 CTestApp의 포인터를 얻고자 한다면 AfxGetApp() 전역함수를 사용한다.
CTestApp *pApp = AfxGetApp();
하지만 위와같이 사용하면 에러가 발생한다.
error C2440: 'initializing' : connot convert from 'class CWinApp *' to 'class CTestApp *'
에러를 보면, CWinApp*를 CTestApp *로 변환할 수 없다는 것이다. AfxGetApp()의 함수 원형이
CWinApp* AfxGetApp()
이기 때문이다. 문제해결을 위해서는 형변환을 해주어야한다.
CTestApp *pApp = (CTestApp*)AfxGetApp();
이제는 컴파일 에러없이 잘 될 것이다. 그리고 발생하는 에러중에
error C2065: 'CTestApp' : undeclared identifier
이 에러는 CTestApp 클래스의 선언 부분이 포함(include)되지 않았다는 것이다. 이럴 때는 CTestApp 클래스의 선언을 포함시켜야한다.
#include "Test.h"
이제 pApp는 생성된 CTestApp의 객체 포인터이기 때문에, CTestApp 객체에 접근이 가능하다. CTestApp에 int nIndex 변수가 있었다고 가정하자
pApp->nIndex = 10;
이런방식으로 접근이 가능하다. 단 public 접근자에만 접근이 가능하다.
● CMainFrame 포인터얻어오기
CMainFrame 는 CFrameWnd를 상속받는다.
AfxGetMainWnd()
CWinThread::m_pMainWnd 를 직접 참조하지 않고 포인터로 참조하는 방식이다.
CMainFame *pFrame = AfxGetMainWnd();
두 가지 에러와 만나게 된다.
첫 번째, CMainFrame에 대해서 컴파일러가 모르겠다는 에러이다.
error C2065: 'CMainFrame' : undeclared identifier
이 에러를 수정하기 위해서는 CMainFrame 클래스가 선언되어있는 헤더파일을 포함시키면 된다. 포함 시키는 위치도 순서에 맞추는 것이 좋다. Test.h와 TestDoc.h 사이가 좋다.
#include "stdafx.h"
#include "Test.h"
#include "MainFrm.h"
#include "TestDoc.h"
#include "TestView.h"
이 에러를 해결하고 나면, CTestApp에서 발생했던 에러가 발생한다.
error C2440: 'initializing' : cannot convert from 'class CWnd *' to 'class CMainFrame *'
에러를 보면, Cwnd* 를 CMainFrame* 으로 변환할 수 없다는 것이다. AfxGetMainWnd()원형이
CWnd* AfxGetMainWnd();
이기 때문이다. 이 문제를 해결하기 위해서는 형변환을 해주어야한다.
CMainFrame *pFrame = (CMainFrame*)AfxGetMainWnd();
이제는 컴파일 에러 없이 잘 될 것이다.
CMainFrame()객체는 CFrameWnd을 상속받았고 CFrameWnd 객체는 CWnd을 상속받았기 때문에 pFrame포인터를 통해서 CFrameWnd클래스와 CWnd클래스의 맴버를 모두 호출가능하다. 만약 윈도우의 타이틀을 바꾸고 싶다면
pFrame->SetWindowText(_T("이름바꿔버리기"));
처럼 사용하면 된다.
CMainFrame*는 또 다른 이유로 자주 사용하게 되는데, 그 이유는 도큐먼트(CTestDoc)와 뷰(CTestView)클레스에 접근하기 위해서이다. CMainFrame 클래스는 뷰에 접근하는 GetActiveView() 함수와 문서에 접근하는 GetActiveDocument() 함수를 제공한다.
우리가 어느 특정 클래스를 만들어서 사용하고, 이 클래스가 뷰에 접근해야한다면 다음과 같은 문장을 사용해야한다.
CMainFrame *pFrame = (CMainFrame*)AfxGetMainWnd();
CTestView *pView = (CTestView*)pFrame->GetActiveView();
또한 도큐먼트 클래스에 접근하기 위해서는 아래와 같이 작성한다.
CMainFrame *pFrame = (CMainFrame*)AfxGetMainWnd();
CTestDoc *pDoc = (CTestDoc*)pDoc->GetActiveDocument();
물론 이 때는 헤더파일을 포함시켜야 한다.
#include "MainFrm.h"
#include "CTestDoc.h"
#include "CTestView.h"
만약 대화 상자에서 도큐먼트 클래스에 접근하려면 어떻게 할 것인가?? 방법은 위와 같다.
다음은 뷰에서 도큐먼트에 접근하는 것과 도큐먼트에서 뷰에 접근하는 것에 대해 알아보자
CTestDoc *pDoc = (CTestDoc*)GetDocument();
를 호출하면 된다. 물론 View클래스에는 GetDocument()함수가 존재해야한다. 일반적으로 이 함수는 MFC로 프로젝트 생성시 기본으로 있다. 하지만 만약 직접 만든 새로운 클래스라면 GetDocument() 함수를 직접 만들어 주어야한다. 직접 만들기가 귀찮다면 ,다음과 같이 사용해도 된다.
CTestDoc* pDocument = (CTestDoc*)m_pDocument;
m_pDocument는 CTestView 클래스의 맴버이며, 다음과 같이 선언되어 있다.
CDocument *m_pDocument;
그리고, 도큐먼트에 뷰 클래스를 참조 하려면 아래와 같이 해야한다.
POSITION pos = GetFirstViewPosition();
CTestView* pView = (CTestView*)GetNextView(pos);
도큐먼트는 뷰 클래스를 내부적으로 링크드리스트를 사용해서 관리하고 있다. 그러므로 GetFirstViewPosition() 함수를 통해 POSITION을 얻어온 다음, GetNextView()함수를 통해 뷰의 포인터를 얻어오면 된다. 만양 창 분할에 의해 뷰가 여러개 존재한다면, 다음과 같이 얻어올 수 있다. 만약 컴파일 에러가 발생하면,
#include "TestView.h" 처럼 해서 헤더 파일을 포함하는 것도 잊지 말자.
POSITION pos = GetFirstViewPosition();
CTestView1 *pView1 = (CTestView1*)GetNextView(pos);
CTestView2 *pView2 = (CTestView2*)GetNextView(pos);
CTestView3 *pView3 = (CTestView3*)GetNextView(pos);
CTestView4 *pView4 = (CTestView4*)GetNextView(pos);
.....
그렇다면 CTestApp 클래스에서 뷰(CTestView) 클래스는 어떻게 얻어올 수 있을까? 쉽게 응용할 수 있지만 머리가 꽉 막힐 수도 있다. 이곳에서 혹시 에러가 나면 헤더 파일을 잘 추가해야 할 것이다.
CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
CTestView* pView = (CTestView*)pFrame->GetActiveView();
뷰(CTestView) 클래스에서 CMainFrame에 접근할 수 있는데 AfxGetMainWnd()함수 외에도
CMainFrame* pFrame = (CMainFrame*)GetParentFrame();
이렇게 사용 가능하다.
▲ 참조
'훈, IT 공부 > C,C++,MFC' 카테고리의 다른 글
[MFC] DC, CDC 관련하여 정리 (2) | 2018.05.01 |
---|---|
[MFC] MFC 실행순서( 생성 ~ 소멸 ) (1) | 2018.04.30 |
[MFC]Document Template (0) | 2018.04.28 |
[C++ STL]vector 백터란 (0) | 2018.04.21 |
[프로그램]강아지와 병아리 ( 다리개수 ) +손코딩연습 (0) | 2018.02.28 |
댓글