--------SDI----------------
1.애플리케이션 클래스의 포인터를 얻을 때
CWinApp* AfxGetApp()
함수를 사용합니다.
2.메인 프레임 클래스의 포인터를 얻을 때
CWnd* AfxGetMainWnd()
함수를 사용합니다.
이들 두 함수는 MFC의 전역함수로써 프로그램을 작성하는 도중 어디에서나 사용할 수 있습니다. MFC에서는 Afx~로 시작하는 함수들은 모두 전역함수를 의미합니다.
물론 타입 캐스팅을 해야 하구요. 사용법은 다음과 같습니다.
CTestApp *pApp = (CTestApp *)AfxGetApp();
CMainFrame *pFr = (CMainFrame *)AfxGetMainWnd();
이렇게 써준 다음에는 pApp와 pFr은 각각 애플리케이션 클래스와 메인 프레임 클래스의 인스턴스 포인터를 가리키게 됩니다.
이 외에 뷰 클래스에서 그 뷰를 둘러싸고 있는 프레임 윈도우를 참조할 때는
CFrameWnd* GetParentFrame() const
함수를 사용할 수 있습니다. 물론 뷰 클래스뿐만이 아니라 일반적인 윈도우를 둘러싸는 틀로써 프레임 윈도우가 사용될 수 있기 때문에 GetParentFrame() 함수는 CWnd() 클래스의 멤버함수로 되어있습니다.
이 함수와 AfxGetMainWnd() 함수는 SDI에서는 같은 기능을 하지만, MDI에서는 메인 프레임 윈도우와 뷰를 둘러싸고 있는 프레임 윈도우가 다르기 때문에 그 각각을 구하는 역할을 합니다.
3.도큐먼트 클래스의 포인터를 얻을 때는 몇 가지 경우가 있습니다.
(a) 뷰 클래스에서 도큐먼트 클래스에 접근할 때.
이때는 말할 필요도 없이 GetDocument() 함수를 쓰면 됩니다. 뷰에 이미 정의되어 있는 함수죠. 하지만 사용자가 임의로 뷰를 추가한 경우에는 이 GetDocument() 함수가 포함되어 있지 않습니다. 이럴 경우 기존에 있는 뷰에서 GetDocument() 함수 부분을 복사해다가 넣으면 됩니다. 이 부분은 Debug 모드와 Release 모드 두 가지의 함수가 있으므로 모두 복사해 넣아야 합니다.
(b) 임의의 클래스에서 도큐먼트 클래스에 접근할 때.
CMainFrame *pFr = (CMainFrame *)AfxGetMainWnd();
CTestDoc *pDoc = (CTestDoc *)pFr->GetActiveDocument();
위와 같이 두 줄에 걸쳐 써도 되고 다음처럼 한 줄로 줄여써도 됩니다.
CTestDoc *pDoc = (CTestDoc *) ((CMainFrame *)AfxGetMainWnd())->GetActiveDocument();
4. 뷰 클래스의 포인터를 얻을 경우.
(a) 임의의 클래스에서 뷰 클래스에 접근할 때
뷰 클래스의 포인터를 얻어야 하는 경우는 대부분 다이얼로그에서 뷰에 접근하거나, 스플릿을 사용한 경우 다른 뷰 클래스에서 접근하는 경우가 대부분일 겁니다. 뭐 어떻든 상관없이 다음과 같이 하면 어디서든 뷰에 접근할 수 있습니다.
CTestView *pView = (CTestView *) ((CMainWnd *)AfxGetMainWnd())->GetActiveView();물론 위의 3번의 경우처럼 두 줄로 나누어 써도 상관이 없습니다.
(b) 도큐먼트 클래스에서 뷰 클래스에 접근을 할 때
도 큐먼트 클래스에서 뷰 클래스의 인스턴스 포인터를 얻으려면 GetFirstViewPosition() 함수와 GetNextView() 함수를 조합하여 사용해야 합니다. 이렇게 복잡해지는 이유는 도큐먼트 하나에 여러개의 뷰가 연결될 수 있기 때문입니다.
도큐먼트에는 이에 연결된 뷰가 연결 리스트 형태로 관리되고 있기 때문에 몇 번째 뷰를 얻을 것인지 선택하고 나서 위의 함수를 조합하여 사용하면 됩니다.
다음은 도큐먼트와 연결된 모든 뷰 클래스를 차례로 얻어 뷰 클래스의 멤버함수인 UpdateWindow() 함수를 호출하는 예제입니다.
POSITION pos = GetFirstViewPosition();
while(pos != NULL) {
CView *pView = GetNextView(pos);
pView->UpdateWindow();
}
물 론 이와 같은 효과를 내기 위해서 도큐먼트 클래스의 멤버함수인 UpdateAllViews(NULL) 함수를 호출해도 됩니다. 여기서 쓰이는 인자인 NULL 은 모든 뷰를 업데이트하는 것이고, NULL 대신, 신호를 보내는 뷰의 포인터를 넣어주면 신호를 보내는 뷰는 빼고 나머지 뷰만 업데이트를 합니다.
도큐먼트에 뷰가 오직 하나만 연결되어 있는 경우에는 다음과 같이 간단하게 뷰 클래스의 인슽턴스 포인터를 얻어낼 수도 있습니다. m_viewList 는 CDocument 클래스의 멤버변수로서, 뷰를 관리하는 연결 리스트입니다. 이것을 이용하여 GetHead() 함수를 호출하면 리스트에 들어있는 첫 번째 뷰가 얻어집니다.
void CTestDoc::OnRepaintViews()
{
CView *pView = m_viewList.GetHead();
pView->UpdateWindows();
}
(c) 스플리트 윈도우에서의 각 뷰 클래스에 접근할 때
동적 스플리트 윈도우라면 모든 페인에서 같은 뷰를 사용하므로 별 문제가 되지 않는데, 정적 스플리트 윈도우라면 각 페인마다 다른 뷰를 사용할 수 있으므로 각 페인별로 뷰의 인스턴스 포인터를 얻는 것이 문제가 되는 경우가 생길 수 있습니다.
이렇때는 메인 프레임 클래스에서 정의한 CSplitterWnd 클래스의 변수인 m_wndSplitter 의 멤버함수 GetPane()을 사용하면 각 페인의 뷰에 접근할 수 있습니다.
우선 메인 프레임에서 정의된 m_wndSplitter 변수를 public: 속성으로 바꾸고(외부에서 접근해야 하므로) 메인 클래스의 인스턴스 포인터를 얻은 다음, 다시 여기서 m_wndSplitter 변수에 접근하여 이 멤버변수의 멤버함수 GetPane()을 이용하면 됩니다. 다음은 GetPane()의 함수 원형입니다. 리턴값은 대부분의 경우 CView에서 파생된 클래스의 인스턴스 포인터가 됩니다.
CWnd* GetPane( int row, int col );
임의의 클래스에서 다음과 같이 사용하면 페인에 연결된 뷰의 포인터를 얻을 수 있습니다.
CTestView *pView = (CTestView *)((CMainFrame *)AfxGetMainWnd())->m_wndSplitter.GetPane(0,1);
-------- MDI ---------------
1.애플리케이션 클래스의 포인터를 얻을 때
CWinApp* AfxGetApp()
함수를 사용합니다. 이것은 SDI에서와 동일합니다. App 클래스는 MDI든 SDI든 프로그램 내에서는 하나뿐이니까요. 다음처럼 사용하면 pApp는 애플리케이션 클래스의 인스턴스 포인터를 가리키게 됩니다.
CTestApp *pApp = (CTestApp *)AfxGetApp();
2. CMDIFrameWnd의 파생클래스인 메인 프레임 클래스의 포인터를 얻을 때
CWnd* AfxGetMainWnd()
함수를 사용합니다. 사용법은 SDI에서와 동일합니다.
CMainFrame *pFr = (CMainFrame *)AfxGetMainWnd();
이렇게 써준 다음에는 pFr은 메인 프레임 클래스의 인스턴스 포인터를 가리키게 됩니다.
3. CMDIChildWnd의 파생클래스인 자식 프레임 윈도우의 포인터를 얻을 때
(a) 활성화된 자식 프레임 윈도우의 포인터를 얻을 때
virtual CFrameWnd* GetActiveFrame( );
함수를 사용합니다. MSDN에 실려있는 이 함수의 리턴값에 대한 설명을 보면, 애플리케이션이 SDI이거나 MDI 프레임 윈도우에 활성화된 도큐먼트가 없을 때, 리턴값은 묵시적인 this 포인터가 된다고 하네요.
사용법은 다음과 같습니다.
CMDIChildWnd* pChild = (CMDIChildWnd *)AfxGetMainWnd()->GetActiveFrame();
4. 뷰 / 도큐먼트 클래스의 포인터를 얻을 때
SDI 에서 구한 것과 마찬가지 방법을 사용한다. SDI에서는 메인 프레임의 포인터를 얻어 GetActiveView() 또는 GetActiveDocument() 함수를 사용했지만, MDI에서는 차일드 프레임의 포인터를 얻어 거기서 GetActiveView() / GetActiveDocument() 함수를 사용하면 된다. 사용법은 거의 동일하다.
MDI에서도 SDI와 마찬가지로 도큐먼트나 뷰가 여러 개가 연결될 수 있으므로 그점만 주의해 주면 된다.
사용법은 다음과 같다.
CMDIChildWnd* pChild = (CMDIChildWnd *)AfxGetMainWnd()->GetActiveFrame();
// 뷰 클래스의 포인터 얻기
CTestView *pView = (CTestView *)pChild->GetActiveView();
// 도큐먼트 클래스의 포인터 얻기
CTestDoc *pDoc = (CTestDoc *)pChild->GetActiveDocument();
'1.소프트웨어 이야기 > 01.MFC(Visual Studio)' 카테고리의 다른 글
[펌] DialogBar 구현 (0) | 2008.08.07 |
---|---|
클래스간 포인터 얻기 (0) | 2007.12.06 |
MFC Socket 사용시 유의점 (0) | 2007.12.06 |
C/C++의 개선으로 D는 C 코드와 호환되며 콜 인터페이스 없이 어떠한 C API와도 인터페이스 가능하다. 그러나 D는 C 코드와 완전하게 후향적 호환은 안되며 자바와 Microsoft C#의 많은 기능을 추가로 한다. D는 2001년 이후 개발되었으며 오픈 소스 공동체의 입력물을 많이 사용하였으며 http://dmoz.org/Computers/Programming/Languages/D/에 자료가 많이 있다.
브라이트는 “D는 C++ 프로그래머의 경험에 의해 개발되었으며 많은 새로운 언어처럼 어느 특정한 플랫폼을 목적으로 설계되지 않았다. D의 개념은 빠르게 배우고 코딩하고 빠르게 디버깅하며 유지 보수하는 것”이라고 말했다.
Forrester Research 분석가인 제프 함몬드는 “D가 기반을 얻기까지에는 약간의 시간이 걸릴 것이다. D 언어가 성공하려면 D 언어 기술이 좋은 것 이외에도 그에 맞는 비즈니스 모델이 있어야 될 것”이라고 말했다. 마치 리눅스가 성공한 이유가 그 당시 다른 OS 가격이 너무 고가이어서 고객들이 선택했기 때문인 것처럼 필요한 비즈니스 모델이 중요하다.
출처 : http://www.internetnews.com