1.51k likes | 1.65k Views
Chap. 8. Advanced Document/View. Contents. CDocument Internal CView Printing CView Print Preview CScrollView CCtrlView. CDocument Internal. CDocument 에서의 file 작업 MFC 4.0 GetFile(), ReleaseFile() 함수를 이용. BOOL CDocument:: OnOpenDocument (LPCTSTR lpszPathName) {
E N D
Chap. 8 Advanced Document/View
Contents • CDocument Internal • CView Printing • CView Print Preview • CScrollView • CCtrlView
CDocument Internal • CDocument에서의 file작업 • MFC 4.0 • GetFile(), ReleaseFile() 함수를 이용 BOOL CDocument::OnOpenDocument(LPCTSTR lpszPathName) { CFile* pFile = GetFile(lpszPathName, CFile::modeRead|CFile::shareDenyWrite, &fe); DeleteContents(); SetModifiedFlag(); // dirty during de-serialize Carchive loadArchive (pFile,CArchive::load|CArchive::bNoFlushOnDelete); Serialize(loadArchive); // load me loadArchive.Close(); ReleaseFile(pFile, FALSE); SetModifiedFlag(FALSE); // start off with unmodified return TRUE; }
CDocument Internal (cont’d) BOOL CDocument::OnSaveDocument(LPCTSTR lpszPathName) { CFile* pFile = NULL; pFile = GetFile(lpszPathName, CFile::modeCreate | CFile::modeReadWrite | CFile::shareExclusive, &fe); CArchive saveArchive (pFile, CArchive::store | CArchive::bNoFlushOnDelete); Serialize(saveArchive); // save me saveArchive.Close(); ReleaseFile(pFile, FALSE); SetModifiedFlag(FALSE); // back to unmodified return TRUE; // success }
CDocument Internal (cont’d) CFile* CDocument::GetFile(LPCTSTR lpszFileName, UINT nOpenFlags, CFileException* pError) { CMirrorFile* pFile = new CMirrorFile; if (!pFile->Open(lpszFileName, nOpenFlags, pError)) { delete pFile; pFile = NULL; } return pFile; }
CMirrorFile • 왜 CFile을 쓰지 않고 CMirrorFile을? • CMirrorFile class • Declaration(AFXPRIV.H) class CMirrorFile : public CFile { // Implementation public: virtual void Abort(); virtual void Close(); virtual BOOL Open(LPCTSTR lpszFileName, UINT nOpenFlags, CFileException* pError = NULL); static CString GetTempName(LPCTSTR pstrOriginalFile, BOOL bCreate); protected: CString m_strMirrorName; };
CMirrorFile (cont’d) • CMirrorFile::Open()(DOCCORE.CPP) • Read인 경우에는 원래 파일 open • Write나 truncate인 경우에는 • File 명으로 준 파일이 아닌 다른 임시파일을 open함(Mirror file)
CMirrorFile (cont’d) BOOL CMirrorFile::Open(LPCTSTR lpszFileName, UINT nOpenFlags, CFileException* pError) { m_strMirrorName.Empty(); if (nOpenFlags & CFile::modeCreate) { if (CFile::GetStatus(lpszFileName, status)) { AfxGetRoot(lpszFileName, strRoot); if (GetDiskFreeSpace(strRoot, &dwSecPerClus, &dwBytesPerSec, &dwFreeClus, &dwTotalClus)) { nBytes=dwFreeClus*dwSecPerClus* dwBytesPerSec; } if (nBytes > 2 * DWORD(status.m_size)) { m_strMirrorName = GetTempName(lpszFileName, TRUE); } } }
CMirrorFile (cont’d) if (!m_strMirrorName.IsEmpty() && CFile::Open(m_strMirrorName, nOpenFlags, pError)) { m_strFileName = lpszFileName; FILETIME ftCreate, ftAccess, ftModify; if (::GetFileTime((HANDLE)m_hFile, &ftCreate, &ftAccess, &ftModify)) { AfxTimeToFileTime(status.m_ctime, &ftCreate); SetFileTime((HANDLE)m_hFile, &ftCreate, &ftAccess, &ftModify); } DWORD dwLength = 0; PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL;
CMirrorFile (cont’d) if(GetFileSecurity(lpszFileName,DACL_SECURITY_INFORMATION, NULL, dwLength, &dwLength)) { pSecurityDescriptor = (PSECURITY_DESCRIPTOR) new BYTE[dwLength]; if (::GetFileSecurity(lpszFileName, DACL_SECURITY_INFORMATION, pSecurityDescriptor, dwLength, &dwLength)) { SetFileSecurity(m_strMirrorName, DACL_SECURITY_INFORMATION, pSecurityDescriptor); } delete[] (BYTE*)pSecurityDescriptor; } return TRUE; } m_strMirrorName.Empty(); return CFile::Open(lpszFileName, nOpenFlags, pError); }
CMirrorFile(contd.) • CMirrorFile::Close()(DOCCORE.CPP) • Mirror file을 실제 file로 copy • CMirrorFile의 이러한 기능이 마음에 들지 않으면 • CDocument::GetFile()함수를 override하면 됨
CMirrorFile(contd.) void CMirrorFile::Close() { CString m_strName = m_strFileName; //file close empties string CFile::Close(); if (!m_strMirrorName.IsEmpty()) { CFile::Remove(m_strName); CFile::Rename(m_strMirrorName, m_strName); } }
CMirrorFile(contd.) • 결론 • CMirrorFile의 역할 • 원래의 파일을 보관 • 새로운 mirror file을 생성하고 여기에 작업 • 모든 작업이 잘 끝날때 까지 원래 파일을 보존하는 효과
CView Printing • Printing overview • 작업에 관련된 virtual function • OnPreparePrinting() • Print가 시작되기 전에 호출 • CPrintInfo structure가 argument • 쪽수와 전체 범위 지정 • Document의 print할 페이지를 지정하는데 쓰임 • OnBeginPrinting() • Print가 시작되면 호출
Printing Overview • Printer device context의 pointer와 CPrintInfo structure의 pointer가 argument • 특별한 GDI resource의 할당 • Printer device context에 의존적인 작업을 할 때 이용 • OnPrint() • Document의 특정 section을 print할 때 호출 • 화면에 보이는 모습과 print되는 모습을 다르게 하고자 할 때 • 예 : Title page의 추가 • Printer device context가 argument
Printing Overview (cont’d) • OnEndPrinting() • Print가 끝난후 호출 • Clean up any resource • OnPrepareDC() • 특별한 device context의 준비 • mapping mode 의 전환 • 미리 document의 끝인지를 검사 • 프린터 부가 기능 제공 • CView::DoPreparePrinting() • Print dialog box를 보여줌 • Dialog box에서 선택된 printer의 device context의 생성
Printing Overview (cont’d) • CPrintInfo structure • Declaration(AFXEXT.H) • CPrintDialog instance와 정보를 가져오는 함수 • CPrintDialog의 instance • Print인지 print preview인지에 대한 정보 • 현재 print하는 page정보
Printing Overview (cont’d) struct CPrintInfo // Printing information structure { CPrintDialog* m_pPD; // pointer to print dialog BOOL m_bDocObject; // TRUE if printing by IPrint interface BOOL m_bPreview; // TRUE if in preview mode BOOL m_bDirect; // TRUE if bypassing Print Dialog BOOL m_bContinuePrinting;// set to FALSE to prematurely end printing UINT m_nCurPage; // Current page UINT m_nNumPreviewPages; // Desired number of preview pages CString m_strPageDesc; // Format string for page number display LPVOID m_lpUserData; // pointer to user created struct CRect m_rectDraw; // rectangle defining current usable page area void SetMinPage(UINT nMinPage); void SetMaxPage(UINT nMaxPage); UINT GetMinPage() const; UINT GetMaxPage() const; UINT GetFromPage() const; UINT GetToPage() const; UINT GetOffsetPage() const; };
CView Printing Internals • Printing steps “ViewPrnt.cpp” ON_COMMAND(ID_FILE_PRINT, Cview::OnFilePrint) // built-in
CView Printing Internals (cont’d) void CView::OnFilePrint() { CPrintInfo printInfo; if (OnPreparePrinting(&printInfo)) { // (did you remember to call DoPreparePrinting?) ASSERT(printInfo.m_pPD->m_pd.hDC != NULL); CString strTitle; CDocument* pDoc = GetDocument(); strTitle = pDoc->GetTitle(); DOCINFO docInfo; docInfo.lpszDocName = strTitle; // setup the printing DC CDC dcPrint; dcPrint.Attach(printInfo.m_pPD->m_pd.hDC); dcPrint.m_bPrinting = TRUE; OnBeginPrinting(&dcPrint, &printInfo); dcPrint.SetAbortProc(_AfxAbortProc);
CView Printing Internals (cont’d) AfxGetMainWnd()->EnableWindow(FALSE); CPrintingDialog dlgPrintStatus(this); dlgPrintStatus.ShowWindow(SW_SHOW); dlgPrintStatus.UpdateWindow(); // start document printing process dcPrint.StartDoc(&docInfo); int nStep = (nEndPage >= nStartPage) ? 1 : -1; nEndPage = (nEndPage == 0xffff) ? 0xffff : nEndPage + nStep; // begin page printing loop for (printInfo.m_nCurPage = nStartPage; printInfo.m_nCurPage != nEndPage; printInfo.m_nCurPage += nStep) { OnPrepareDC(&dcPrint, &printInfo); // check for end of print if (!printInfo.m_bContinuePrinting) break;
CView Printing Internals (cont’d) // write current page TCHAR szBuf[80]; wsprintf(szBuf, strTemp, printInfo.m_nCurPage); dlgPrintStatus.SetDlgItemText( AFX_IDC_PRINT_PAGENUM, szBuf); printInfo.m_rectDraw.SetRect(0, 0, dcPrint.GetDeviceCaps(HORZRES), dcPrint.GetDeviceCaps(VERTRES)); dcPrint.DPtoLP(&printInfo.m_rectDraw); // attempt to start the current page if (dcPrint.StartPage() < 0) { bError = TRUE; break; } OnPrint(&dcPrint, &printInfo); if (dcPrint.EndPage() < 0 || !_AfxAbortProc(dcPrint.m_hDC, 0)) { bError = TRUE; break; } } }
CView Printing Internals (cont’d) // cleanup document printing process if (!printInfo.m_bDocObject) { if (!bError) dcPrint.EndDoc(); else dcPrint.AbortDoc(); } AfxGetMainWnd()->EnableWindow(); // enable main window OnEndPrinting(&dcPrint, &printInfo); // clean up after printing dlgPrintStatus.DestroyWindow(); dcPrint.Detach(); // will be cleaned up by CPrintInfo destructor } }
CView Printing Internals (cont’d) CPrintInfo::CPrintInfo() { m_pPD = new CPrintDialog(FALSE, PD_ALLPAGES | PD_USEDEVMODECOPIES | PD_NOSELECTION); SetMinPage(1); // one based page numbers SetMaxPage(0xffff); // unknown how many pages m_nCurPage = 1; m_lpUserData = NULL; // Initialize to no user data m_bPreview = FALSE; // initialize to not preview m_bDirect = FALSE; // initialize to not direct m_bDocObject = FALSE; // initialize to not IPrint m_bContinuePrinting = TRUE; // Assume it is OK to print m_dwFlags = 0; m_nOffsetPage = 0; }
CView Printing Internals (cont’d) BOOL CView::DoPreparePrinting(CPrintInfo* pInfo) { CWinApp* pApp = AfxGetApp(); if (pInfo->m_bPreview || pInfo->m_bDirect || (pInfo->m_bDocObject && !(pInfo->m_dwFlags & PRINTFLAG_PROMPTUSER))) { if (pInfo->m_pPD->m_pd.hDC == NULL) { // if no printer set then, get default printer DC and // create DC without calling print dialog. … } } else { // otherwise, bring up the print dialog and allow user to //change things preset From-To range same as Min-Max range
CView Printing Internals (cont’d) pInfo->m_pPD->m_pd.nFromPage = (WORD)pInfo->GetMinPage(); pInfo->m_pPD->m_pd.nToPage = (WORD)pInfo->GetMaxPage(); if (pApp->DoPrintDialog(pInfo->m_pPD) != IDOK) return FALSE; // do not print } ASSERT(pInfo->m_pPD != NULL); ASSERT(pInfo->m_pPD->m_pd.hDC != NULL); if (pInfo->m_pPD->m_pd.hDC == NULL) return FALSE; pInfo->m_nNumPreviewPages = pApp->m_nNumPreviewPages; VERIFY(pInfo->m_strPageDesc.LoadString(AFX_IDS_PREVIEWPAGEDESC)); return TRUE; }
CView Printing Internals (cont’d) • 관련 함수 • CView::OnFilePrint()(VIEWPRNT.CPP) • CPrintInfo instance생성 • Print dialog 를 할당한 후 m_pPD변수에 assign • 기타 여러 변수의 값을 채움 • OnPreparePrinting()함수 호출 • Virtual function이기 때문에 CMyView::OnPreparePrinting()을 호출하게 되고 내부에서 다시 CView::DoPreparePrinting()호출
CView Printing Internals (cont’d) • DoPreparePrinting() • Print dialog를 보여주고, print DC를 생성 • Document title을 가져오고 DOCINFO structure를 생성 • Local DC를 만들고 DoPreparePrinting()과정에서 만들어진 DC handle에 attach함 • OnBeginPrinting() • DC의 수정을 가하고자 하면 override • _AfxAbortProc()의 설정 • Print도중 사용자가 cancel버튼을 누르는지 감시
CView Printing Internals (cont’d) • Main window를 disable시키고 print 진행 상황 dialog를 보여줌 • StartDoc()호출 • Printing Loop의 시작 • OnPrepareDC() • StartPage() • OnPrint() OnDraw()함수의 호출 • EndPage() • EndDoc()호출 • Main window를 enable시키고 OnEndPrinting()
CView Printing Internals (cont’d) CView::OnFilePrint() CView::OnBeginPrinting() CView::OnPreparePrinting() CView::OnPrepareDC() CView::DoPreparePrinting() CView::OnPrint() CPrintDialog::DoModal() CView::OnDraw() Another Page? Yes No CView::OnEndPrinting()
Customizing Printing • Standard printing • EndPage()가 호출될 때, Windows가 한 page를 프린트하는 데 필요한 physical band를 그린다. • Abort를 자주 체크한다. • 프린트 작업이 느려진다. • Efficient printing • Band 를 줄인다. 즉, 한 페이지당 여러 번 프린트한다. • 오버로딩 CMyView::OnFilePrint()
CView Print Preview • Question • Normal window에서 print preview window로의 변환 방법 • Page outline의 표시 방법 • Printer output을 화면에 표시하는 과정 • Toolbar는 어디에서 온건지
Print Preview Internal • Print preview steps “ViewPrev.cpp” ON_COMMAND(ID_FILE_PRINT_PREVIEW, Cview::OnFilePrintPreview) // built-in
Print Preview Internal (cont’d) void CView::OnFilePrintPreview() { CPrintPreviewState* pState = new CPrintPreviewState; if (!DoPrintPreview(AFX_IDD_PREVIEW_TOOLBAR, this, RUNTIME_CLASS(CPreviewView), pState)) { delete pState; // preview failed to initialize, delete State now } }
Print Preview Internal (cont’d) BOOL CView::DoPrintPreview(UINT nIDResource, CView* pPrintView, CRuntimeClass* pPreviewViewClass, CPrintPreviewState* pState) { CFrameWnd* pParent = AfxGetMainWnd(); CCreateContext context; context.m_pCurrentFrame = pParent; context.m_pCurrentDoc = GetDocument(); context.m_pLastView = this; // Create the preview view object CPreviewView* pView = (CPreviewView*)pPreviewViewClass->CreateObject(); pView->m_pPreviewState = pState; // save pointer pParent->OnSetPreviewMode(TRUE, pState);
Print Preview Internal (cont’d) // Create the toolbar from the dialog resource pView->m_pToolBar = new CDialogBar; if (!pView->m_pToolBar->Create(pParent, MAKEINTRESOURCE(nIDResource), CBRS_TOP,AFX_IDW_PREVIEW_BAR)) { pParent->OnSetPreviewMode(FALSE, pState); delete pView->m_pToolBar; // not autodestruct yet return FALSE; } if (!pView->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW, CRect(0,0,0,0), pParent, AFX_IDW_PANE_FIRST, &context)) { pParent->OnSetPreviewMode(FALSE, pState); pView->m_pPreviewState = NULL; delete pView; return FALSE; }
Print Preview Internal (cont’d) // Preview window shown now pState->pViewActiveOld = pParent->GetActiveView(); CView* pActiveView = pParent->GetActiveFrame()->GetActiveView(); if (pActiveView != NULL) pActiveView->OnActivateView(FALSE, pActiveView, pActiveView); if (!pView->SetPrintView(pPrintView)) { pView->OnPreviewClose(); return TRUE; } pParent->SetActiveView(pView); // update toolbar and redraw everything pView->m_pToolBar->SendMessage(WM_IDLEUPDATECMDUI, (WPARAM)TRUE); pParent->RecalcLayout(); // position and size everything pParent->UpdateWindow(); return TRUE; }
Print Preview Internal (cont’d) • CPreviewView class • AFXPRIV.H class CPreviewView : public CScrollView { DECLARE_DYNCREATE(CPreviewView) CPreviewView(); BOOL SetPrintView(CView* pPrintView); protected: CView* m_pOrigView; CView* m_pPrintView; CPreviewDC* m_pPreviewDC; // Output and attrib DCs Set, not created CDC m_dcPrint; // Actual printer DC public: virtual void OnPrepareDC(CDC* pDC, CPrintInfo* pInfo = NULL); protected: CPrintPreviewState* m_pPreviewState; // State to restore CDialogBar* m_pToolBar; // Toolbar for preview
Print Preview Internal (cont’d) struct PAGE_INFO { PAGE_INFO(); CRect rectScreen; // screen rect (screen device units) CSize sizeUnscaled; // unscaled screen rect (screen device units) CSize sizeScaleRatio; // scale ratio (cx/cy) CSize sizeZoomOutRatio; // scale ratio when zoomed out (cx/cy) }; PAGE_INFO* m_pPageInfo; // Array of page info structures PAGE_INFO m_pageInfoArray[2]; // Embedded array for the default BOOL m_bPageNumDisplayed;// Flags whether or not page number has yet UINT m_nZoomOutPages; // number of pages when zoomed out UINT m_nZoomState; UINT m_nMaxPages; // for sanity checks UINT m_nCurrentPage; UINT m_nPages; int m_nSecondPageOffset; // used to shift second page position HCURSOR m_hMagnifyCursor; CSize m_sizePrinterPPI; // printer pixels per inch CPoint m_ptCenterPoint; CPrintInfo* m_pPreviewInfo; };
Print Preview Internal (cont’d) BOOL CPreviewView::SetPrintView(CView* pPrintView) { m_pPrintView = pPrintView; m_pPreviewInfo = new CPrintInfo; m_pPreviewInfo->m_pPD->SetHelpID(AFX_IDD_PRINTSETUP); m_pPreviewInfo->m_pPD->m_pd.Flags |= PD_PRINTSETUP; m_pPreviewInfo->m_pPD->m_pd.Flags &= ~PD_RETURNDC; m_pPreviewInfo->m_bPreview = TRUE; // signal that this is preview m_pPreviewDC = new CPreviewDC; // must be created before any if (!m_pPrintView->OnPreparePrinting(m_pPreviewInfo)) return FALSE; m_dcPrint.Attach(m_pPreviewInfo->m_pPD->m_pd.hDC); m_pPreviewDC->SetAttribDC(m_pPreviewInfo->m_pPD->m_pd.hDC); m_pPreviewDC->m_bPrinting = TRUE; m_dcPrint.m_bPrinting = TRUE; m_dcPrint.SaveDC(); // Save pristine state of DC HDC hDC = ::GetDC(m_hWnd); m_pPreviewDC->SetOutputDC(hDC); m_pPrintView->OnBeginPrinting(m_pPreviewDC, m_pPreviewInfo); m_pPreviewDC->ReleaseOutputDC(); ::ReleaseDC(m_hWnd, hDC); m_dcPrint.RestoreDC(-1); // restore to untouched state
Print Preview Internal (cont’d) // Get Pixels per inch from Printer m_sizePrinterPPI.cx = m_dcPrint.GetDeviceCaps(LOGPIXELSX); m_sizePrinterPPI.cy = m_dcPrint.GetDeviceCaps(LOGPIXELSY); m_nPages = m_pPreviewInfo->m_nNumPreviewPages; if (m_nPages == 0) m_nPages = 1; else if (m_nPages > m_nMaxPages) m_nPages = m_nMaxPages; m_nZoomOutPages = m_nPages; SetScrollSizes(MM_TEXT, CSize(1, 1)); // initialize mapping mode only if (m_pPreviewInfo->GetMaxPage() < 0x8000 && m_pPreviewInfo->GetMaxPage() - m_pPreviewInfo->GetMinPage() <= 32767U) { SCROLLINFO info; info.fMask = SIF_PAGE|SIF_RANGE; info.nMin = m_pPreviewInfo->GetMinPage(); info.nMax = m_pPreviewInfo->GetMaxPage(); info.nPage = 1; if (!SetScrollInfo(SB_VERT, &info, FALSE)) SetScrollRange(SB_VERT, info.nMin, info.nMax, FALSE); } else ShowScrollBar(SB_VERT, FALSE); // if no range specified, or too SetCurrentPage(m_pPreviewInfo->m_nCurPage, TRUE); return TRUE; }
Print Preview Internal (cont’d) void CPreviewView::OnDraw(CDC* pDC) { rectPen.CreatePen(PS_SOLID, 2, GetSysColor(COLOR_WINDOWFRAME)); shadowPen.CreatePen(PS_SOLID, 3, GetSysColor(COLOR_BTNSHADOW)); for (UINT nPage = 0; nPage < m_nPages; nPage++) { pDC->SelectObject(&shadowPen); pDC->MoveTo(pRect->right + 1, pRect->top + 3); pDC->LineTo(pRect->right + 1, pRect->bottom + 1); pDC->MoveTo(pRect->left + 3, pRect->bottom + 1); pDC->LineTo(pRect->right + 1, pRect->bottom + 1); ::FillRect(pDC->m_hDC, rectFill, (HBRUSH)GetStockObject(WHITE_BRUSH)); // Display page number OnDisplayPageNumber(m_nCurrentPage, nPage + 1); m_pPrintView->OnPrint(m_pPreviewDC, m_pPreviewInfo); … }
Print Preview Internal (cont’d) • CView::OnFilePrintPreview() • VIEWPREV.CPP • CPrintPreviewState structure • Preview를 위한 정보 저장 • DoPrintPreview() 호출
Print Preview Internal (cont’d) • CView::DoPrintPreview() • VIEWPREV.CPP • CPreviewView instance를 생성(AFXPRIV.H) • 미리보기 했을 때 나오는 view임 • 내부적으로 CPreviewDC를 사용 • CFrameWnd::OnSetPreviewMode()함수 이용 • Normal window에서 print preview mode로 전환 • 원래 view의 UpdateWindow()호출 • 실제 rendering작업
Print Preview Internal (cont’d) • CPreviewView::SetPrintView() • VIEWPREV.CPP • Device context의 준비 • CDC의 두 멤버 변수 • m_hDC Screen에 대한 device context • m_hAttribDC Printer에 대한 device context • CPreviewView::OnDraw() • VIEWPREV.CPP • 각 페이지의 outline을 그리고 실제 rendering
CScrollView • 사용 과정 • CScrollView에서 view를 상속받음 • SetScrollSize()를 이용하여 setting • CScrollView class • Declaration(AFXWIN.H) • Implementation(VIEWSCRL.CPP)
CScrollView (cont’d) class CScrollView : public CView { DECLARE_DYNAMIC(CScrollView) protected: int m_nMapMode; CSize m_totalLog; // total size in logical units (no rounding) CSize m_totalDev; // total size in device units CSize m_pageDev; // per page scroll size in device units CSize m_lineDev; // per line scroll size in device units BOOL m_bCenter; // Center output if larger than total size BOOL m_bInsideUpdate; // internal state for OnSize callback void CenterOnPoint(CPoint ptCenter); void ScrollToDevicePosition(POINT ptDev); // explicit scrolling no checking protected: void UpdateBars(); // adjust scrollbars etc BOOL GetTrueClientSize(CSize& size, CSize& sizeSb); void GetScrollBarSizes(CSize& sizeSb); void GetScrollBarState(CSize sizeClient, CSize& needSb, CSize& sizeRange, CPoint& ptMove, BOOL bInsideClient);
CScrollView (cont’d) public: virtual void CalcWindowRect(LPRECT lpClientRect, UINT nAdjustType = adjustBorder); virtual void OnPrepareDC(CDC* pDC, CPrintInfo* pInfo = NULL); virtual BOOL OnScroll(UINT nScrollCode, UINT nPos, BOOL bDoScroll = TRUE); virtual BOOL OnScrollBy(CSize sizeScroll, BOOL bDoScroll = TRUE); //{{AFX_MSG(CScrollView) afx_msg void OnSize(UINT nType, int cx, int cy); afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); afx_msg BOOL OnMouseWheel(UINT fFlags, short zDelta, CPoint point); //}}AFX_MSG DECLARE_MESSAGE_MAP() };
CScrollView (cont’d) • CScrollView::SetScrollSizes() • Mapping mode설정 • Document의 scroll size설정 • Scroll bar설치를 위해 UpdateBars()함수 호출 • Mapping mode가 변경되었으면 Invalidate()함수 호출 화면 새로 그림 • CScrollView::OnPrepareDC() • 주어진 mapping mode에 따른 DC관련 준비작업 • 실제 scroll에 관련된 함수 • OnScrollBy(), ScrollToDevicePosition() • 내부적으로 ScrollWindow()함수를 이용함