1 / 151

Advanced Document/View

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) {

Download Presentation

Advanced Document/View

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Chap. 8 Advanced Document/View

  2. Contents • CDocument Internal • CView Printing • CView Print Preview • CScrollView • CCtrlView

  3. 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; }

  4. 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 }

  5. 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; }

  6. 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; };

  7. CMirrorFile (cont’d) • CMirrorFile::Open()(DOCCORE.CPP) • Read인 경우에는 원래 파일 open • Write나 truncate인 경우에는 • File 명으로 준 파일이 아닌 다른 임시파일을 open함(Mirror file)

  8. 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); } } }

  9. 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;

  10. 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); }

  11. CMirrorFile(contd.) • CMirrorFile::Close()(DOCCORE.CPP) • Mirror file을 실제 file로 copy • CMirrorFile의 이러한 기능이 마음에 들지 않으면 • CDocument::GetFile()함수를 override하면 됨

  12. 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); } }

  13. CMirrorFile(contd.) • 결론 • CMirrorFile의 역할 • 원래의 파일을 보관 • 새로운 mirror file을 생성하고 여기에 작업 • 모든 작업이 잘 끝날때 까지 원래 파일을 보존하는 효과

  14. CView Printing • Printing overview • 작업에 관련된 virtual function • OnPreparePrinting() • Print가 시작되기 전에 호출 • CPrintInfo structure가 argument • 쪽수와 전체 범위 지정 • Document의 print할 페이지를 지정하는데 쓰임 • OnBeginPrinting() • Print가 시작되면 호출

  15. 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

  16. 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의 생성

  17. Printing Overview (cont’d) • CPrintInfo structure • Declaration(AFXEXT.H) • CPrintDialog instance와 정보를 가져오는 함수 • CPrintDialog의 instance • Print인지 print preview인지에 대한 정보 • 현재 print하는 page정보

  18. 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; };

  19. CView Printing Internals • Printing steps “ViewPrnt.cpp” ON_COMMAND(ID_FILE_PRINT, Cview::OnFilePrint) // built-in

  20. 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);

  21. 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;

  22. 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; } } }

  23. 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 } }

  24. 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; }

  25. 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

  26. 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; }

  27. CView Printing Internals (cont’d) • 관련 함수 • CView::OnFilePrint()(VIEWPRNT.CPP) • CPrintInfo instance생성 • Print dialog 를 할당한 후 m_pPD변수에 assign • 기타 여러 변수의 값을 채움 • OnPreparePrinting()함수 호출 • Virtual function이기 때문에 CMyView::OnPreparePrinting()을 호출하게 되고 내부에서 다시 CView::DoPreparePrinting()호출

  28. 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버튼을 누르는지 감시

  29. CView Printing Internals (cont’d) • Main window를 disable시키고 print 진행 상황 dialog를 보여줌 • StartDoc()호출 • Printing Loop의 시작 • OnPrepareDC() • StartPage() • OnPrint()  OnDraw()함수의 호출 • EndPage() • EndDoc()호출 • Main window를 enable시키고 OnEndPrinting()

  30. 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()

  31. CView Printing Internals (cont’d)

  32. Customizing Printing • Standard printing • EndPage()가 호출될 때, Windows가 한 page를 프린트하는 데 필요한 physical band를 그린다. • Abort를 자주 체크한다. • 프린트 작업이 느려진다. • Efficient printing • Band 를 줄인다. 즉, 한 페이지당 여러 번 프린트한다. • 오버로딩 CMyView::OnFilePrint()

  33. CView Print Preview • Question • Normal window에서 print preview window로의 변환 방법 • Page outline의 표시 방법 • Printer output을 화면에 표시하는 과정 • Toolbar는 어디에서 온건지

  34. Print Preview Internal • Print preview steps “ViewPrev.cpp” ON_COMMAND(ID_FILE_PRINT_PREVIEW, Cview::OnFilePrintPreview) // built-in

  35. 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 } }

  36. 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);

  37. 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; }

  38. 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; }

  39. 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

  40. 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; };

  41. 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

  42. 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; }

  43. 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); … }

  44. Print Preview Internal (cont’d) • CView::OnFilePrintPreview() • VIEWPREV.CPP • CPrintPreviewState structure • Preview를 위한 정보 저장 • DoPrintPreview() 호출

  45. 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작업

  46. 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

  47. CScrollView • 사용 과정 • CScrollView에서 view를 상속받음 • SetScrollSize()를 이용하여 setting • CScrollView class • Declaration(AFXWIN.H) • Implementation(VIEWSCRL.CPP)

  48. 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);

  49. 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() };

  50. 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()함수를 이용함

More Related