[문제] 클릭시 원과 네모를 출력하고 데이터를 추가한다. (p504 참고)
1. 프로젝트 - 단일문서(SDI), 문서뷰 구조, CFormView 사용
2. View는 좌/우 마우스 버튼 클릭시 원과 네모 그리기
3. FormView는 ListBox에 원/네모의 타입과 좌표를 텍스트로 출력
[과제] 게임맵을 그려보자. (벽과 바닥 비트맵으로 표시)
1. 왼쪽은 일반 CView -> CImageList (비트맵 24bit)로 그림 추가, 클릭시 그려진다.
2. 오른쪽은 CFormView -> ListBox에 데이터 추가, Radio 버튼으로 이미지 종류 선택
3. 파일로 저장했다가 불러와서 다시 그려져야 한다.
CArray<CPoint, CPoint> m_point; // 이미지 좌표
CArray<int, int> m_ImageType; // 이미지 종류
* 왼쪽에서 클릭 할 경우 오른쪽에 어떻게 데이터를 전송할 수 있을까?
- 양쪽에서 상대편의 객체 포인터 멤버변수를 선언한다.
- 상대편 객체의 포인터를 넘겨준다. 이 부분은 Create()부분이나, OnInitializeUpdate()부분이나, 초기화부분에서 this로 넘겨줄 수 있다. 또는 직접 포인터를 얻을 수 있다.
- 상대편 핸들을 사용한다.
윈프책에서 비모드형 다이얼로그 (p457) 부분에서 보면 Dialog 와 View 사이처럼 핸들을 이용해 접근하는 방법
서로 상대편 멤버변수를 선언하고 뷰객체 주소를 넘겨주어 서로 접근 가능하게 할 수 있다.
| ModelessDialogView 부분 | MyDialog 부분 |
class CMyDialog; // 참조할 클래스 선언
class CModelessDialogView : public CView { // 특성입니다. public: CMyDialog* m_pDlg; // 대화 상자 객체의 주소 저장 CString m_str; int m_font; | class CModelessDialogView; // 참조할 클래스 선언
class CMyDialog : public CDialog { // 특성입니다. public: CModelessDialogView* m_pView; // 뷰객체 주소저장 CString m_str; int m_font; |
void CModelessDialogView::OnLButtonDown(UINT nFlags, CPoint point) { if (m_pDlg != NULL) m_pDlg->SetFocus(); else { m_pDlg = new CMyDialog(); m_pDlg->m_pView = this; // 뷰객체 주소를 준다. m_pDlg->m_str = m_str; m_pDlg->m_font = m_font;의 초깃값 m_pDlg->Create(IDD_DIALOG1); m_pDlg->ShowWindow(SW_SHOW); } } | void CMyDialog::OnBnClickedApply() { UpdateData(TRUE); m_pView->m_str = m_str; // 뷰객체에 접근 가능 m_pView->m_font = m_font; m_pView->Invalidate(); } |
그럼 Splitter에서는 어떻게 할까?
다음과 같이 GetPane(0,0) 등으로 현재 위치의 View 포인터를 얻을 수 있다.
예를 들면)
CSplitterView* view = (CSplitterView*)m_wndSplitter.GetPane(0, 0);
그밖에 다른 예제들을 살펴보자.
| 핸들 얻기 | 코드 |
| Splitter 에서 View 핸들 얻는 방법 | CTestApp *pApp = (CTestApp *)AfxGetApp(); CTestDoc *pDoc = (CTestDoc *)pApp->pDocTemplate->OpenDocumentFile(csTVDataFilePath);
CMainFrame* pFrame = (CMainFrame *) AfxGetMainWnd(); CChildFrame *pChild = (CChildFrame *) pFrame->GetActiveFrame(); // MDI 인 경우
CTestView1 *pFView = (CTestView1 *)pChild->GetFirstViewPane(); // 첫번째 View 핸들 얻기 CTestView2 *pSView = (CTestView2 *)pChild->GetSecondViewPane(); // 두번째 View 핸들 얻기
// 이 아래는 ChildFrm class 안에 함수 추가한 것 CTestView1* CChildFrame::GetFirstViewPane() { CWnd* pWnd = m_wndSplitter.GetPane(0, 0); CTestView2* pView = DYNAMIC_DOWNCAST(CTestView1, pWnd); return pView; }
CTestView2* CChildFrame::GetSecondViewPane() { CWnd* pWnd = m_wndSplitter.GetPane(0, 1); CTestView1* pView = DYNAMIC_DOWNCAST(CTestView2, pWnd); return pView; } |
| Doc에서 View 핸들을 얻는 방법 | void CMyDoc:: OnRepaintAllViews() { POSITION pos= GetFirstViewPosition(); while(pos!=NULL) { CView * pView=GetNextView(pos); pView->UpdateWindow(); } }
또는
POSITION pos = GetFirstViewPosition(); CTestView1* pView1 = (CTestView1*)GetNextView( pos ); CTestView2* pView2 = (CTestView2*)GetNextView( pos ); CTestView3* pView3 = (CTestView3*)GetNextView( pos ); CTestView4* pView4 = (CTestView4*)GetNextView( pos ); ... |
다양한 핸들(포인터) 얻는 방법을 살펴보자.
| 구분 | 포인터 얻기 |
| SDI | 1. MainFrame 얻기 - CMainFrame *pFrame = (CmainFrame *) AfxGetMainWnd();
2. App 포인터 얻기 - CTestApp *pApp = (CtestApp *) AfxGetApp();
3. Document 포인터 얻기 - CMainFrame *pFrame = (CMainFrame *)AfxGetMainWnd(); CTestDoc *pDoc = (CTestDoc *)pFrame->GetActiveDocument(); - CTestDoc *pDoc = ((CMainFrame *)AfxGetMainWnd())->GetActiveDocument();
4. View 포인터 얻기 - CMainFrame *pFrame = (CMainFrame *)AfxGetMainWnd(); CTestView *pView = (CTestView *)pFrame->GetActiveView(); - CTestView *pView = ((CMainFrame *)AfxGetMainWnd())->GetActiveView(); |
| MDI | 1. ChildFrame 포인터 얻기 - CMainFrame *pFrame = (CMainFrame *)AfxGetMainWnd(); CChildFrame *pChild = (CChildFrame *)pFrame->GetActiveFrame(); - CChildFrame *pChild = ((CMainFrame *)AfxGetMainWnd())->GetActiveFrame();
2. Document 포인터 얻기 - CMainFrame *pFrame = (CMainFrame)AfxGetMainWnd(); CChildFrame *pChild = (CChildFrame *)pFrame->GetActiveFrame(); CMdiTestDoc *pDoc = (CMdiTestDoc *)pChild->GetActiveDocument(); - CMdiTestDoc *pDoc = (((CMainFrame *)AfxGetMainWnd())->GetActiveFrame())->GetActiveDocument();
3. View 포인터 얻기 - CCainFrame *pFrame = (CMainFrame)AfxGetMainWnd(); CChildFrame *pChild = (CChildFrame *)pFrame->GetActiveFrame(); CMdiTestView *pView = (CMdiTestDoc *)pChild->GetActiveView(); - CMdiTestView *pView = (((CMainFrame *)AfxGetMainWnd())->GetActiveFrame())->GetActiveView(); |
학생들 작품
2024-1학기 이종혁09 (20)
2022-1학기 유정재