home *** CD-ROM | disk | FTP | other *** search
/ Supercompiler 1997 / SUPERCOMPILER97.iso / MS_VC.50 / VC / MFC / SRC / VIEWPREV.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-02  |  32.3 KB  |  1,159 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1997 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "stdafx.h"
  12.  
  13. #ifdef AFX_PRINT_SEG
  14. #pragma code_seg(AFX_PRINT_SEG)
  15. #endif
  16.  
  17. #ifdef _DEBUG
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21.  
  22. BOOL CALLBACK _AfxPreviewCloseProc(CFrameWnd* pFrameWnd);
  23.  
  24. /////////////////////////////////////////////////////////////////////////////
  25. // CPrintPreviewState helper structure
  26.  
  27. CPrintPreviewState::CPrintPreviewState()
  28. {
  29.     // set defaults
  30.     nIDMainPane = AFX_IDW_PANE_FIRST;
  31.     dwStates = AFX_CONTROLBAR_MASK(AFX_IDW_STATUS_BAR);
  32.                         // status bar visible if available
  33.     lpfnCloseProc = _AfxPreviewCloseProc;
  34.                         // set frame hook so closing the frame window
  35.                         //  when in preview state will just end the mode
  36.     hMenu = NULL;
  37.     pViewActiveOld = NULL;
  38.     hAccelTable = NULL;
  39. }
  40.  
  41. /////////////////////////////////////////////////////////////////////////////
  42. // CView's OnPrintPreview.  Here to force linkage
  43.  
  44. void CView::OnFilePrintPreview()
  45. {
  46.     // In derived classes, implement special window handling here
  47.     // Be sure to Unhook Frame Window close if hooked.
  48.  
  49.     // must not create this on the frame.  Must outlive this function
  50.     CPrintPreviewState* pState = new CPrintPreviewState;
  51.  
  52.     // DoPrintPreview's return value does not necessarily indicate that
  53.     // Print preview succeeded or failed, but rather what actions are necessary
  54.     // at this point.  If DoPrintPreview returns TRUE, it means that
  55.     // OnEndPrintPreview will be (or has already been) called and the
  56.     // pState structure will be/has been deleted.
  57.     // If DoPrintPreview returns FALSE, it means that OnEndPrintPreview
  58.     // WILL NOT be called and that cleanup, including deleting pState
  59.     // must be done here.
  60.  
  61.     if (!DoPrintPreview(AFX_IDD_PREVIEW_TOOLBAR, this,
  62.                             RUNTIME_CLASS(CPreviewView), pState))
  63.     {
  64.         // In derived classes, reverse special window handling here for
  65.         // Preview failure case
  66.  
  67.         TRACE0("Error: DoPrintPreview failed.\n");
  68.         AfxMessageBox(AFX_IDP_COMMAND_FAILURE);
  69.         delete pState;      // preview failed to initialize, delete State now
  70.     }
  71. }
  72.  
  73. BOOL CView::DoPrintPreview(UINT nIDResource, CView* pPrintView,
  74.     CRuntimeClass* pPreviewViewClass, CPrintPreviewState* pState)
  75. {
  76.     ASSERT_VALID_IDR(nIDResource);
  77.     ASSERT_VALID(pPrintView);
  78.     ASSERT(pPreviewViewClass != NULL);
  79.     ASSERT(pPreviewViewClass->IsDerivedFrom(RUNTIME_CLASS(CPreviewView)));
  80.     ASSERT(pState != NULL);
  81.  
  82.     CFrameWnd* pParent;
  83.     CWnd* pNaturalParent = pPrintView->GetParentFrame();
  84.     pParent = DYNAMIC_DOWNCAST(CFrameWnd, pNaturalParent);
  85.     if (pParent == NULL || pParent->IsIconic())
  86.         pParent = (CFrameWnd*)AfxGetThread()->m_pMainWnd;
  87.  
  88.     ASSERT_VALID(pParent);
  89.     ASSERT_KINDOF(CFrameWnd, pParent);
  90.  
  91.     CCreateContext context;
  92.     context.m_pCurrentFrame = pParent;
  93.     context.m_pCurrentDoc = GetDocument();
  94.     context.m_pLastView = this;
  95.  
  96.     // Create the preview view object
  97.     CPreviewView* pView = (CPreviewView*)pPreviewViewClass->CreateObject();
  98.     if (pView == NULL)
  99.     {
  100.         TRACE0("Error: Failed to create preview view.\n");
  101.         return FALSE;
  102.     }
  103.     ASSERT_KINDOF(CPreviewView, pView);
  104.     pView->m_pPreviewState = pState;        // save pointer
  105.  
  106.     pParent->OnSetPreviewMode(TRUE, pState);    // Take over Frame Window
  107.  
  108. #ifdef _MAC
  109.     if (nIDResource == AFX_IDD_PREVIEW_TOOLBAR)
  110.     {
  111.         HINSTANCE hInst = AfxFindResourceHandle(
  112.             MAKEINTRESOURCE(AFX_IDD_PREVIEW_TOOLBAR), RT_DIALOG);
  113.         HRSRC hResource = FindResource(hInst,
  114.             MAKEINTRESOURCE(AFX_IDD_PREVIEW_TOOLBAR), RT_DIALOG);
  115.  
  116.         HGLOBAL hdt = NULL;
  117.         if (hResource != NULL)
  118.             hdt = LoadResource(hInst, hResource);
  119.  
  120.         DLGTEMPLATE* pdt = NULL;
  121.         if (hdt != NULL)
  122.             pdt = (DLGTEMPLATE*)LockResource(hdt);
  123.  
  124.         if (pdt != NULL)
  125.         {
  126.             CRect rectParent;
  127.             pParent->GetClientRect(&rectParent);
  128.  
  129.             int cxToolbar = MulDiv(LOWORD(GetDialogBaseUnits()), pdt->cx, 4);
  130.  
  131.             if (cxToolbar > rectParent.Width())
  132.                 nIDResource = AFX_IDD_PREVIEW_SHORTTOOLBAR;
  133.  
  134.             UnlockResource(hdt);
  135.             FreeResource(hdt);
  136.         }
  137.     }
  138. #endif
  139.  
  140.     // Create the toolbar from the dialog resource
  141.     pView->m_pToolBar = new CDialogBar;
  142.     if (!pView->m_pToolBar->Create(pParent, MAKEINTRESOURCE(nIDResource),
  143.         CBRS_TOP, AFX_IDW_PREVIEW_BAR))
  144.     {
  145.         TRACE0("Error: Preview could not create toolbar dialog.\n");
  146.         pParent->OnSetPreviewMode(FALSE, pState);   // restore Frame Window
  147.         delete pView->m_pToolBar;       // not autodestruct yet
  148.         pView->m_pToolBar = NULL;
  149.         pView->m_pPreviewState = NULL;  // do not delete state structure
  150.         delete pView;
  151.         return FALSE;
  152.     }
  153.     pView->m_pToolBar->m_bAutoDelete = TRUE;    // automatic cleanup
  154.  
  155.     // Create the preview view as a child of the App Main Window.  This
  156.     // is a sibling of this view if this is an SDI app.  This is NOT a sibling
  157.     // if this is an MDI app.
  158.  
  159.     if (!pView->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
  160.         CRect(0,0,0,0), pParent, AFX_IDW_PANE_FIRST, &context))
  161.     {
  162.         TRACE0("Error: couldn't create preview view for frame.\n");
  163.         pParent->OnSetPreviewMode(FALSE, pState);   // restore Frame Window
  164.         pView->m_pPreviewState = NULL;  // do not delete state structure
  165.         delete pView;
  166.         return FALSE;
  167.     }
  168.  
  169.     // Preview window shown now
  170.  
  171.     pState->pViewActiveOld = pParent->GetActiveView();
  172.     CView* pActiveView = pParent->GetActiveFrame()->GetActiveView();
  173.     if (pActiveView != NULL)
  174.         pActiveView->OnActivateView(FALSE, pActiveView, pActiveView);
  175.  
  176.     if (!pView->SetPrintView(pPrintView))
  177.     {
  178.         pView->OnPreviewClose();
  179.         return TRUE;            // signal that OnEndPrintPreview was called
  180.     }
  181.  
  182.     pParent->SetActiveView(pView);  // set active view - even for MDI
  183.  
  184.     // update toolbar and redraw everything
  185.     pView->m_pToolBar->SendMessage(WM_IDLEUPDATECMDUI, (WPARAM)TRUE);
  186.     pParent->RecalcLayout();            // position and size everything
  187.     pParent->UpdateWindow();
  188.  
  189.     return TRUE;
  190. }
  191.  
  192. BOOL CALLBACK _AfxPreviewCloseProc(CFrameWnd* pFrameWnd)
  193. {
  194.     ASSERT_VALID(pFrameWnd);
  195.  
  196.     CPreviewView* pView = (CPreviewView*) pFrameWnd->GetDlgItem(AFX_IDW_PANE_FIRST);
  197.     ASSERT_KINDOF(CPreviewView, pView);
  198.  
  199.     pView->OnPreviewClose();
  200.     return FALSE;
  201. }
  202.  
  203. /////////////////////////////////////////////////////////////////////////////
  204. // Preview View
  205.  
  206. BEGIN_MESSAGE_MAP(CPreviewView, CScrollView)
  207.     //{{AFX_MSG_MAP(CPreviewView)
  208.     ON_WM_SIZE()        // overriding CScrollView
  209.     ON_WM_CREATE()
  210.  
  211.     ON_COMMAND(AFX_ID_PREVIEW_CLOSE, OnPreviewClose)
  212.     ON_COMMAND(AFX_ID_PREVIEW_NUMPAGE, OnNumPageChange)
  213.     ON_COMMAND(AFX_ID_PREVIEW_NEXT, OnNextPage)
  214.     ON_COMMAND(AFX_ID_PREVIEW_PREV, OnPrevPage)
  215.     ON_COMMAND(AFX_ID_PREVIEW_PRINT, OnPreviewPrint)
  216.     ON_COMMAND(AFX_ID_PREVIEW_ZOOMIN, OnZoomIn)
  217.     ON_COMMAND(AFX_ID_PREVIEW_ZOOMOUT, OnZoomOut)
  218.  
  219.     ON_UPDATE_COMMAND_UI(AFX_ID_PREVIEW_NUMPAGE, OnUpdateNumPageChange)
  220.     ON_UPDATE_COMMAND_UI(AFX_ID_PREVIEW_NEXT, OnUpdateNextPage)
  221.     ON_UPDATE_COMMAND_UI(AFX_ID_PREVIEW_PREV, OnUpdatePrevPage)
  222.     ON_UPDATE_COMMAND_UI(AFX_ID_PREVIEW_ZOOMIN, OnUpdateZoomIn)
  223.     ON_UPDATE_COMMAND_UI(AFX_ID_PREVIEW_ZOOMOUT, OnUpdateZoomOut)
  224.  
  225.     ON_WM_VSCROLL()
  226.     ON_WM_HSCROLL()
  227.     ON_WM_LBUTTONDOWN()
  228.     ON_WM_ERASEBKGND()
  229.     ON_WM_SETCURSOR()
  230.     //}}AFX_MSG_MAP
  231. END_MESSAGE_MAP()
  232.  
  233. CPreviewView::CPreviewView()
  234. {
  235.     m_pPrintView = NULL;
  236.     m_pOrigView = NULL;
  237.     m_pPreviewInfo = NULL;
  238.     m_pPreviewDC = NULL;
  239.     m_pPreviewState = NULL;
  240.     m_hMagnifyCursor = NULL;
  241.     m_bPageNumDisplayed = FALSE;
  242.     m_nZoomState = ZOOM_OUT;
  243.  
  244.     // default to pointing to embedded array.  Allows for 2 pages
  245.     m_pPageInfo = m_pageInfoArray;
  246.     m_nMaxPages = 2;
  247.  
  248.     // initialize CScrollView members
  249.     m_bCenter = TRUE;                   // Center Zoomed output in Scrollview
  250.     m_nMapMode = MM_TEXT;
  251. }
  252.  
  253. CPreviewView::~CPreviewView()
  254. {
  255.     m_dcPrint.Detach();         // print DC is deleted by CPrintInfo destructor
  256.  
  257.     delete m_pPreviewInfo;      // get rid of preview info
  258.     delete m_pPreviewState;     // Get rid of preview state
  259.     delete m_pPreviewDC;        // Get rid of preview DC object
  260.  
  261.     if (m_hMagnifyCursor != NULL)
  262.     {
  263.         // make sure that m_hMagnifyCursor isn't the current cursor when we destroy it
  264.         ::SetCursor(::LoadCursor(NULL, IDC_ARROW));
  265.         DestroyCursor(m_hMagnifyCursor);
  266.     }
  267. }
  268.  
  269. int CPreviewView::OnCreate(LPCREATESTRUCT lpCreateStruct)
  270. {
  271.     int retVal = CView::OnCreate(lpCreateStruct);
  272.     if (retVal == -1)
  273.         return -1;      // if -1 bag out
  274.  
  275.     CCreateContext* pContext = (CCreateContext*)lpCreateStruct->lpCreateParams;
  276.  
  277.     m_pOrigView = pContext->m_pLastView;
  278.     ASSERT(m_pOrigView != NULL);
  279.     ASSERT_KINDOF(CView, m_pOrigView);
  280.  
  281.     return retVal;
  282. }
  283.  
  284. #ifdef _MAC
  285. void CPreviewView::CalcWindowRect(LPRECT lpClientRect)
  286. {
  287.     CView::CalcWindowRect(lpClientRect);
  288.  
  289.     // The preview view is created with the WS_BORDER style, and when
  290.     // the view is repositioned, these borders will by default be placed
  291.     // outside the main monitor. If there are other monitors adjacent to
  292.     // the main monitor, the border shows up on those monitors, which looks
  293.     // sloppy. To prevent this we resize the window rect as necessary to
  294.     // keep the borders inside the MDI parent frame window's client area.
  295.  
  296.     // Also note that we can't just get rid of the borders entirely because
  297.     // this looks bad on a PowerBook where the edges of the screen are
  298.     // white instead of black - if there aren't any borders, there's no
  299.     // dividing line between the edge of the preview view's scrollbars
  300.     // and the non-drawing areas of the screen.
  301.  
  302.     CWnd* pParent = GetParent();
  303.     if (pParent->IsKindOf(RUNTIME_CLASS(CMDIFrameWnd)))
  304.     {
  305.         RECT rect;
  306.  
  307.         pParent->GetClientRect(&rect);
  308.         if (lpClientRect->left < rect.left)
  309.             lpClientRect->left = rect.left;
  310.         if (lpClientRect->right > rect.right)
  311.             lpClientRect->right = rect.right;
  312.         if (lpClientRect->bottom > rect.bottom)
  313.             lpClientRect->bottom = rect.bottom;
  314.  
  315.         // top not needed because it will be adjacent to the print
  316.         // preview toolbar
  317.     }
  318. }
  319. #endif
  320.  
  321. BOOL CPreviewView::SetPrintView(CView* pPrintView)
  322. {
  323.     ASSERT_VALID(pPrintView);
  324.  
  325.     m_pPrintView = pPrintView;
  326.  
  327.     // allocate preview info
  328.     m_pPreviewInfo = new CPrintInfo;
  329.     m_pPreviewInfo->m_pPD->SetHelpID(AFX_IDD_PRINTSETUP);
  330.     m_pPreviewInfo->m_pPD->m_pd.Flags |= PD_PRINTSETUP;
  331.     m_pPreviewInfo->m_pPD->m_pd.Flags &= ~PD_RETURNDC;
  332.  
  333.     m_pPreviewInfo->m_bPreview = TRUE;  // signal that this is preview
  334.     ASSERT(m_pPreviewInfo->m_pPD != NULL);
  335.  
  336.     m_pPreviewDC = new CPreviewDC;      // must be created before any
  337.                                         // possible error returns
  338.  
  339.     if (!m_pPrintView->OnPreparePrinting(m_pPreviewInfo))
  340.         return FALSE;
  341.  
  342. #ifdef _DEBUG
  343.     if (m_pPreviewInfo->m_pPD->m_pd.hDC == NULL)
  344.     {
  345.         TRACE0("Error: hDC not set for printing --\n");
  346.         TRACE0("\tDid you remember to call DoPreparePrinting?\n");
  347.         ASSERT(FALSE);      // common mistake gets trapped here
  348.     }
  349. #endif //_DEBUG
  350.  
  351.     m_dcPrint.Attach(m_pPreviewInfo->m_pPD->m_pd.hDC);
  352.     m_pPreviewDC->SetAttribDC(m_pPreviewInfo->m_pPD->m_pd.hDC);
  353.     m_pPreviewDC->m_bPrinting = TRUE;
  354.     m_dcPrint.m_bPrinting = TRUE;
  355.  
  356.     m_dcPrint.SaveDC();     // Save pristine state of DC
  357.  
  358.     HDC hDC = ::GetDC(m_hWnd);
  359.     m_pPreviewDC->SetOutputDC(hDC);
  360.     m_pPrintView->OnBeginPrinting(m_pPreviewDC, m_pPreviewInfo);
  361.     m_pPreviewDC->ReleaseOutputDC();
  362.     ::ReleaseDC(m_hWnd, hDC);
  363.  
  364.     m_dcPrint.RestoreDC(-1);    // restore to untouched state
  365.  
  366.     // Get Pixels per inch from Printer
  367.     m_sizePrinterPPI.cx = m_dcPrint.GetDeviceCaps(LOGPIXELSX);
  368.     m_sizePrinterPPI.cy = m_dcPrint.GetDeviceCaps(LOGPIXELSY);
  369.  
  370.     m_nPages = m_pPreviewInfo->m_nNumPreviewPages;
  371.     if (m_nPages == 0)
  372.         m_nPages = 1;
  373.     else if (m_nPages > m_nMaxPages)
  374.         m_nPages = m_nMaxPages;     // Sanity Check!
  375.  
  376.     m_nZoomOutPages = m_nPages;
  377.  
  378.     SetScrollSizes(MM_TEXT, CSize(1, 1));   // initialize mapping mode only
  379.  
  380.     if (m_pPreviewInfo->GetMaxPage() < 0x8000 &&
  381.         m_pPreviewInfo->GetMaxPage() - m_pPreviewInfo->GetMinPage() <= 32767U)
  382.         SetScrollRange(SB_VERT, m_pPreviewInfo->GetMinPage(),
  383.                 m_pPreviewInfo->GetMaxPage(), FALSE);
  384.     else
  385.         ShowScrollBar(SB_VERT, FALSE);      // if no range specified, or too
  386.                                             // large don't show
  387.  
  388.     SetCurrentPage(m_pPreviewInfo->m_nCurPage, TRUE);
  389.     return TRUE;
  390. }
  391.  
  392. void CPreviewView::OnSize(UINT nType, int cx, int cy)
  393. {
  394.     // CScrollView handles everything if zoomed in.
  395.     if (m_nZoomState == ZOOM_OUT)
  396.     {
  397.         // Force recalc of scale ratios on next draw
  398.         for (UINT i = 0; i < m_nMaxPages; i++)
  399.             m_pPageInfo[i].sizeScaleRatio.cx = 0;           // zero scale ratios
  400.  
  401.         CView::OnSize(nType, cx, cy);       // No scroll functionality
  402.     }
  403.     else
  404.     {
  405.         // adjust scroll size to size of page
  406.         m_pageDev.cx = cx;
  407.         m_pageDev.cy = cy;
  408.         m_lineDev.cx = cx / 10;
  409.         m_lineDev.cy = cy / 10;
  410.         CScrollView::OnSize(nType, cx, cy);
  411.     }
  412. }
  413.  
  414. void CPreviewView::OnActivateView(BOOL bActivate, CView*, CView*)
  415. {
  416.     if (bActivate)
  417.     {
  418.         CWnd* pFocusWnd = GetFocus();
  419.         if (pFocusWnd == NULL ||
  420.             (m_pToolBar != NULL && !m_pToolBar->IsChild(pFocusWnd)))
  421.         {
  422.             // focus is not already on a toolbar button - set it to one
  423.             m_pToolBar->GetDlgItem(AFX_ID_PREVIEW_PRINT)->SetFocus();
  424.         }
  425.     }
  426.  
  427. #ifdef _MAC
  428.         // Make sure the preview frame's activation matches that of the frame
  429.         // window so that scroll bars are drawn with the correct visibility.
  430.         SendMessage(WM_NCACTIVATE, bActivate, 0);
  431. #endif
  432. }
  433.  
  434. void CPreviewView::OnPreviewClose()
  435. {
  436.     m_pToolBar->DestroyWindow();
  437.     m_pToolBar = NULL;
  438.  
  439.     m_pPreviewInfo->m_nCurPage = m_nCurrentPage;
  440.     m_pOrigView->OnEndPrintPreview(m_pPreviewDC, m_pPreviewInfo,
  441.                                     CPoint(0, 0), this);
  442. }
  443.  
  444. #define PREVIEW_MARGIN  8
  445. #define PREVIEW_PAGEGAP 8
  446.  
  447. // Return is actually the fraction cx/cy. Simply using CSize for convenience
  448. CSize CPreviewView::CalcScaleRatio(CSize screenSize, CSize actualSize)
  449. {
  450.     // Test ratio based on vertical dimension to see if it is the one to use
  451.     int nNum = screenSize.cy;
  452.     int nDen = actualSize.cy;
  453.  
  454.     // If scaled width too large, choose width as primary dimension
  455.     if (MulDiv(actualSize.cx, nNum, nDen) > screenSize.cx)
  456.     {
  457.         // wrong ratio--base on width
  458.         nNum = screenSize.cx;
  459.         nDen = actualSize.cx;
  460.     }
  461.     CSize ratio(nNum, nDen);
  462.     return ratio;
  463. }
  464.  
  465. // Position Page...
  466. // Generate a Screen MM_TEXT rectangle to enclose each page.  Dimensions
  467. // of the rectangle must be 1 pixel Above and Left of the top/left corner
  468. // of the page and the rectangle width and height must be THREE pixels
  469. // larger than page in order to provide the correct placement of the
  470. // two pixel border.
  471. //
  472. // This routine is called once for each page with the preview DC set up for
  473. // that page
  474.  
  475. void CPreviewView::PositionPage(UINT nPage)
  476. {
  477.     CSize windowSize = CalcPageDisplaySize();
  478.  
  479.     VERIFY(m_dcPrint.Escape(GETPHYSPAGESIZE, 0, NULL,
  480.             (LPVOID)&m_pPageInfo[nPage].sizeUnscaled));
  481.  
  482.     CSize* pSize = &m_pPageInfo[nPage].sizeUnscaled;
  483.  
  484.     // Convert page size to screen coordinates
  485.     pSize->cx = MulDiv(pSize->cx, afxData.cxPixelsPerInch, m_sizePrinterPPI.cx);
  486.     pSize->cy = MulDiv(pSize->cy, afxData.cyPixelsPerInch, m_sizePrinterPPI.cy);
  487.  
  488.     m_pPageInfo[nPage].sizeZoomOutRatio = CalcScaleRatio(windowSize, *pSize);
  489.  
  490.     SetScaledSize(nPage);
  491. }
  492.  
  493. CSize CPreviewView::CalcPageDisplaySize()
  494.     // calculate the current page size
  495.     //  set 'm_nSecondPageOffset' to start of second page
  496.     // return size of current page less margins
  497. {
  498.     CSize windowSize, scrollSize;
  499.     GetTrueClientSize(windowSize, scrollSize);
  500.  
  501.     // subtract out vertical scrollbar if zoomed out and page range is known
  502.     // and there is more than one page.
  503.     if (m_nZoomState == ZOOM_OUT && (m_pPreviewInfo->GetMaxPage() != 0xffff) &&
  504.         (m_pPreviewInfo->GetMaxPage() - m_pPreviewInfo->GetMinPage() != 0))
  505.         windowSize.cx -= scrollSize.cx;
  506.  
  507.     m_nSecondPageOffset = (windowSize.cx - PREVIEW_MARGIN) / 2;
  508.  
  509.     windowSize.cx = (m_nPages == 2) ? (windowSize.cx - 3*PREVIEW_MARGIN) / 2 :
  510.                                     windowSize.cx - 2*PREVIEW_MARGIN;
  511.  
  512.     windowSize.cy -= 2*PREVIEW_MARGIN;
  513.     return windowSize;
  514. }
  515.  
  516. void CPreviewView::SetScaledSize(UINT nPage)
  517. {
  518.     CSize* pSize = &m_pPageInfo[nPage].sizeUnscaled;
  519.     CSize* pRatio = &m_pPageInfo[nPage].sizeScaleRatio;
  520.     CSize* pZoomOutRatio = &m_pPageInfo[nPage].sizeZoomOutRatio;
  521.     CSize windowSize = CalcPageDisplaySize();
  522.     BOOL bPaperLarger = pZoomOutRatio->cx < pZoomOutRatio->cy;
  523.         // whether the paper is larger than the screen, or vice versa
  524.  
  525.     switch (m_nZoomState)
  526.     {
  527.     case ZOOM_OUT:
  528.         *pRatio = *pZoomOutRatio;
  529.         break;
  530.  
  531.     case ZOOM_MIDDLE:
  532.         // the middle zoom state is a ratio between cx/cy and
  533.         // 1/1 (or cy/cy).  It is, therefore:
  534.         //
  535.         // (cx + cy)/2
  536.         // -----------
  537.         //     cy
  538.         //
  539.         // if the paper is larger than the screen, or
  540.         //
  541.         // (3*cx - cy)/2
  542.         // -------------
  543.         //      cy
  544.         //
  545.         // if the paper is smaller than the screen.
  546.         if (bPaperLarger)
  547.         {
  548.             pRatio->cy = pZoomOutRatio->cy;
  549.             pRatio->cx = (pZoomOutRatio->cx + pRatio->cy) / 2;
  550.         }
  551.         else
  552.         {
  553.             pRatio->cy = pZoomOutRatio->cy;
  554.             pRatio->cx = (3*pZoomOutRatio->cx - pRatio->cy) / 2;
  555.         }
  556.         break;
  557.  
  558.     case ZOOM_IN:
  559.         if (bPaperLarger)
  560.             pRatio->cx = pRatio->cy = 1;
  561.         else
  562.         {
  563.             // if the paper is smaller than the screen space we're displaying
  564.             // it in, then using a ratio of 1/1 will result in a smaller image
  565.             // on the screen, not a larger one. To get a larger image in this
  566.             // case we double the zoom out ratio.
  567.             pRatio->cy = pZoomOutRatio->cy;
  568.             pRatio->cx = 2*pZoomOutRatio->cx - pZoomOutRatio->cy;
  569.         }
  570.         break;
  571.  
  572.     default:
  573.         ASSERT(FALSE);
  574.     }
  575.  
  576.     // Convert to scaled size
  577.     CSize scaledSize;
  578.     scaledSize.cx = MulDiv(pSize->cx, pRatio->cx, pRatio->cy);
  579.     scaledSize.cy = MulDiv(pSize->cy, pRatio->cx, pRatio->cy);
  580.  
  581.     CRect* pRect = &m_pPageInfo[nPage].rectScreen;
  582.     pRect->SetRect(PREVIEW_MARGIN, PREVIEW_MARGIN,
  583.                    scaledSize.cx + PREVIEW_MARGIN + 3,
  584.                    scaledSize.cy + PREVIEW_MARGIN + 3);
  585.  
  586.     if (m_nZoomState == ZOOM_OUT)
  587.     {
  588.         pRect->OffsetRect((windowSize.cx - pRect->Size().cx) / 2 - 1,
  589.                           (windowSize.cy - pRect->Size().cy) / 2 - 1);
  590.  
  591.         if (nPage == 1)
  592.             pRect->OffsetRect(m_nSecondPageOffset, 0);
  593.     }
  594.     else
  595.     {
  596.         // set up scroll size
  597.  
  598.         SetScrollSizes(MM_TEXT, pRect->Size() +
  599.                 CSize(PREVIEW_MARGIN * 2, PREVIEW_MARGIN * 2), windowSize);
  600.     }
  601. }
  602.  
  603. // Only use the PrepareDC from CScrollView if we are zoomed in
  604. void CPreviewView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)
  605. {
  606.     ASSERT_VALID(pDC);
  607.  
  608.     if (m_nZoomState == ZOOM_OUT)
  609.         CView::OnPrepareDC(pDC, pInfo);
  610.     else if (m_pPageInfo[0].sizeScaleRatio.cx != 0)
  611.         CScrollView::OnPrepareDC(pDC, pInfo);
  612. }
  613.  
  614. BOOL CPreviewView::OnEraseBkgnd(CDC* pDC)
  615. {
  616.     ASSERT_VALID(pDC);
  617.  
  618.     // Fill background with APPWORKSPACE
  619.     CBrush backBrush(GetSysColor(COLOR_APPWORKSPACE));
  620.     CBrush* pOldBrush = pDC->SelectObject(&backBrush);
  621.     CRect rect;
  622.     pDC->GetClipBox(&rect);     // Erase the area needed
  623.  
  624.     pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATCOPY);
  625.     pDC->SelectObject(pOldBrush);
  626.     return TRUE;
  627. }
  628.  
  629. void CPreviewView::OnDraw(CDC* pDC)
  630. {
  631.     ASSERT_VALID(pDC);
  632.  
  633.     // don't do anything if not fully initialized
  634.     if (m_pPrintView == NULL || m_dcPrint.m_hDC == NULL)
  635.         return;
  636.  
  637.     CPoint ViewportOrg = pDC->GetViewportOrg();
  638.  
  639.     CPen rectPen;
  640.     rectPen.CreatePen(PS_SOLID, 2, GetSysColor(COLOR_WINDOWFRAME));
  641.     CPen shadowPen;
  642.     shadowPen.CreatePen(PS_SOLID, 3, GetSysColor(COLOR_BTNSHADOW));
  643.  
  644.     m_pPreviewInfo->m_bContinuePrinting = TRUE;     // do this once each paint
  645.  
  646.     for (UINT nPage = 0; nPage < m_nPages; nPage++)
  647.     {
  648.         int nSavedState = m_dcPrint.SaveDC();       // Save pristine state of DC
  649.  
  650.         // Use paint DC for print preview output
  651.         m_pPreviewDC->SetOutputDC(pDC->GetSafeHdc());
  652.  
  653.         m_pPreviewInfo->m_nCurPage = m_nCurrentPage + nPage;
  654.  
  655.         // Only call PrepareDC if within page range, otherwise use default
  656.         // rect to draw page rectangle
  657.         if (m_nCurrentPage + nPage <= m_pPreviewInfo->GetMaxPage())
  658.             m_pPrintView->OnPrepareDC(m_pPreviewDC, m_pPreviewInfo);
  659.  
  660.         // Set up drawing rect to entire page (in logical coordinates)
  661.         m_pPreviewInfo->m_rectDraw.SetRect(0, 0,
  662.             m_pPreviewDC->GetDeviceCaps(HORZRES),
  663.             m_pPreviewDC->GetDeviceCaps(VERTRES));
  664.         m_pPreviewDC->DPtoLP(&m_pPreviewInfo->m_rectDraw);
  665.  
  666.         // Draw empty page on screen
  667.  
  668.         pDC->SaveDC();          // save the output dc state
  669.  
  670.         CSize* pRatio = &m_pPageInfo[nPage].sizeScaleRatio;
  671.         CRect* pRect = &m_pPageInfo[nPage].rectScreen;
  672.  
  673.         if (pRatio->cx == 0)
  674.         {   // page position has not been determined
  675.             PositionPage(nPage);    // compute page position
  676.             if (m_nZoomState != ZOOM_OUT)
  677.                 ViewportOrg = -GetDeviceScrollPosition();
  678.         }
  679.  
  680.         pDC->SetMapMode(MM_TEXT);   // Page Rectangle is in screen device coords
  681.         pDC->SetViewportOrg(ViewportOrg);
  682.         pDC->SetWindowOrg(0, 0);
  683.  
  684.         pDC->SelectStockObject(HOLLOW_BRUSH);
  685.         pDC->SelectObject(&rectPen);
  686.         pDC->Rectangle(pRect);
  687.  
  688.         pDC->SelectObject(&shadowPen);
  689.  
  690.         pDC->MoveTo(pRect->right + 1, pRect->top + 3);
  691.         pDC->LineTo(pRect->right + 1, pRect->bottom + 1);
  692.         pDC->MoveTo(pRect->left + 3, pRect->bottom + 1);
  693.         pDC->LineTo(pRect->right + 1, pRect->bottom + 1);
  694.  
  695.         // erase background to white (most paper is white)
  696.         CRect rectFill = *pRect;
  697.         rectFill.left += 1;
  698.         rectFill.top += 1;
  699.         rectFill.right -= 2;
  700.         rectFill.bottom -= 2;
  701.         ::FillRect(pDC->m_hDC, rectFill, (HBRUSH)GetStockObject(WHITE_BRUSH));
  702.  
  703.         pDC->RestoreDC(-1);     // restore to synchronized state
  704.  
  705.         if (!m_pPreviewInfo->m_bContinuePrinting ||
  706.                 m_nCurrentPage + nPage > m_pPreviewInfo->GetMaxPage())
  707.         {
  708.             m_pPreviewDC->ReleaseOutputDC();
  709.             m_dcPrint.RestoreDC(nSavedState);   // restore to untouched state
  710.  
  711.             // if the first page is not displayable, back up one page
  712.             // but never go below 1
  713.             if (nPage == 0 && m_nCurrentPage > 1)
  714.                 SetCurrentPage(m_nCurrentPage - 1, TRUE);
  715.             break;
  716.         }
  717.  
  718.         // Display page number
  719.         OnDisplayPageNumber(m_nCurrentPage, nPage + 1);
  720.  
  721.         // Set scale ratio for this page
  722.         m_pPreviewDC->SetScaleRatio(pRatio->cx, pRatio->cy);
  723.  
  724.         CSize PrintOffset;
  725.         VERIFY(m_pPreviewDC->Escape(GETPRINTINGOFFSET, 0, NULL, (LPVOID)&PrintOffset));
  726.         m_pPreviewDC->PrinterDPtoScreenDP((LPPOINT)&PrintOffset);
  727.         PrintOffset += (CSize)pRect->TopLeft();
  728.         PrintOffset += CSize(1, 1);
  729.         PrintOffset += (CSize)ViewportOrg;  // For Scrolling
  730.  
  731.         m_pPreviewDC->SetTopLeftOffset(PrintOffset);
  732.  
  733.         m_pPreviewDC->ClipToPage();
  734.         m_pPrintView->OnPrint(m_pPreviewDC, m_pPreviewInfo);
  735.  
  736.         m_pPreviewDC->ReleaseOutputDC();
  737.  
  738.         m_dcPrint.RestoreDC(nSavedState);   // restore to untouched state
  739.  
  740.     }
  741.  
  742.     rectPen.DeleteObject();
  743.     shadowPen.DeleteObject();
  744. }
  745.  
  746. void CPreviewView::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
  747. {
  748.     if (m_nZoomState != ZOOM_OUT)
  749.         CScrollView::OnHScroll(nSBCode, nPos, pScrollBar);
  750. }
  751.  
  752. void CPreviewView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
  753. {
  754.     if (m_nZoomState != ZOOM_OUT)
  755.     {
  756.         CScrollView::OnVScroll(nSBCode, nPos, pScrollBar);
  757.         return;
  758.     }
  759.  
  760.     switch (nSBCode)
  761.     {
  762.     case SB_BOTTOM:
  763.         SetCurrentPage(m_pPreviewInfo->GetMaxPage(), TRUE);
  764.         break;
  765.  
  766.     case SB_TOP:
  767.         SetCurrentPage(m_pPreviewInfo->GetMinPage(), TRUE);
  768.         break;
  769.  
  770.     case SB_PAGEDOWN:
  771.         SetCurrentPage(m_nCurrentPage +
  772.             (m_pPreviewInfo->GetMaxPage() - m_pPreviewInfo->GetMinPage() + 9) / 10, TRUE);
  773.         break;
  774.  
  775.     case SB_PAGEUP:
  776.         SetCurrentPage(m_nCurrentPage -
  777.             (m_pPreviewInfo->GetMaxPage() - m_pPreviewInfo->GetMinPage() + 9) / 10, TRUE);
  778.         break;
  779.  
  780.     case SB_LINEDOWN:
  781.         SetCurrentPage(m_nCurrentPage + 1, TRUE);
  782.         break;
  783.  
  784.     case SB_LINEUP:
  785.         SetCurrentPage(m_nCurrentPage - 1, TRUE);
  786.         break;
  787.  
  788.     case SB_THUMBPOSITION:
  789.         SetCurrentPage(nPos, TRUE);
  790.         break;
  791.     }
  792. }
  793.  
  794. void CPreviewView::OnNumPageChange()
  795. {
  796.     ASSERT(m_nPages == 1 || m_nPages == 2);
  797.     m_nPages = 3 - m_nPages;    // Toggle between 1 and 2
  798.     AfxGetApp()->m_nNumPreviewPages = m_nPages;
  799.     m_nZoomOutPages = m_nPages;
  800.  
  801.     // Just do this to set the status correctly and invalidate
  802.     SetCurrentPage(m_nCurrentPage, TRUE);
  803. }
  804.  
  805. void CPreviewView::OnNextPage()
  806. {
  807.     SetCurrentPage(m_nCurrentPage + 1, TRUE);
  808. }
  809.  
  810. void CPreviewView::OnPrevPage()
  811. {
  812.     SetCurrentPage(m_nCurrentPage - 1, TRUE);
  813. }
  814.  
  815. void CPreviewView::OnPreviewPrint()
  816. {
  817.     CView* pOrigView = m_pOrigView;
  818.     OnPreviewClose();               // force close of Preview
  819.  
  820.     // cause print (can be overridden by catching the command)
  821.     CWnd* pMainWnd = AfxGetThread()->m_pMainWnd;
  822.     ASSERT_VALID(pMainWnd);
  823.     pMainWnd->SendMessage(WM_COMMAND, ID_FILE_PRINT);
  824. }
  825.  
  826. // Finds page pointed to and convert to 1:1 screen device units
  827. BOOL CPreviewView::FindPageRect(CPoint& point, UINT& nPage)
  828. {
  829.     if (m_nZoomState != ZOOM_OUT)
  830.         point += (CSize)GetDeviceScrollPosition();
  831.  
  832.     for (nPage = 0; nPage < m_nPages; nPage++)
  833.     {
  834.         if (m_pPageInfo[nPage].rectScreen.PtInRect(point))
  835.         {
  836.             // adjust point for page position
  837.             point -= (CSize)m_pPageInfo[nPage].rectScreen.TopLeft();
  838.  
  839.             // convert to 1:1
  840.             point.x = MulDiv(point.x, m_pPageInfo[nPage].sizeScaleRatio.cy,
  841.                                     m_pPageInfo[nPage].sizeScaleRatio.cx);
  842.             point.y = MulDiv(point.y, m_pPageInfo[nPage].sizeScaleRatio.cy,
  843.                                     m_pPageInfo[nPage].sizeScaleRatio.cx);
  844.             return TRUE;
  845.         }
  846.     }
  847.     return FALSE;
  848. }
  849.  
  850.  
  851. void CPreviewView::OnLButtonDown(UINT, CPoint point)
  852. {
  853.     UINT nPage;
  854.     if (!FindPageRect(point, nPage))
  855.         return;                         // Didn't click on a page
  856.  
  857.     // Set new zoom state
  858.     SetZoomState((m_nZoomState == ZOOM_IN) ? ZOOM_OUT : m_nZoomState + 1,
  859.                                 nPage, point);
  860. }
  861.  
  862. void CPreviewView::SetZoomState(UINT nNewState, UINT nPage, CPoint point)
  863. {
  864.     if (m_nZoomState != nNewState)
  865.     {
  866.         m_nZoomState = nNewState;
  867.         DoZoom(nPage, point);
  868.     }
  869. }
  870.  
  871. void CPreviewView::OnZoomIn()
  872. {
  873.     if (m_nZoomState != ZOOM_IN)
  874.         SetZoomState(m_nZoomState + 1, 0, CPoint(0, 0));
  875. }
  876.  
  877. void CPreviewView::OnZoomOut()
  878. {
  879.     if (m_nZoomState != ZOOM_OUT)
  880.         SetZoomState(m_nZoomState - 1, 0, CPoint(0, 0));
  881. }
  882.  
  883. // Actual zoom code.
  884. void CPreviewView::DoZoom(UINT nPage, CPoint point)
  885. {
  886.     if (m_nZoomState == ZOOM_OUT)
  887.     {
  888.         // taking over scroll bars
  889.         m_nPages = m_nZoomOutPages;
  890.         ShowScrollBar(SB_HORZ, FALSE);      //hide the horizontal bar
  891.  
  892.         BOOL bShowBar = m_pPreviewInfo->GetMaxPage() < 0x8000 &&
  893.             m_pPreviewInfo->GetMaxPage() -
  894.             m_pPreviewInfo->GetMinPage() <= 32767U;
  895.  
  896.         ShowScrollBar(SB_VERT, bShowBar);       //Show the vertical bar
  897.  
  898.         if (bShowBar)
  899.         {
  900.             SetScrollRange(SB_VERT, m_pPreviewInfo->GetMinPage(),
  901.                                 m_pPreviewInfo->GetMaxPage(), FALSE);
  902.  
  903.             SetScrollPos(SB_VERT, m_nCurrentPage, TRUE);
  904.         }
  905.  
  906.         SetCurrentPage(m_nCurrentPage, TRUE);
  907.     }
  908.     else
  909.     {
  910.         m_nPages = 1;       // only one page in zoomed states
  911.  
  912.         m_pPageInfo[0].sizeZoomOutRatio = m_pPageInfo[nPage].sizeZoomOutRatio;
  913.         m_pPageInfo[0].sizeUnscaled = m_pPageInfo[nPage].sizeUnscaled;
  914.  
  915.         // Sets the printer page
  916.         SetCurrentPage(m_nCurrentPage + nPage, FALSE);
  917.  
  918.         SetScaledSize(0);
  919.  
  920.         CSize* pRatio = &m_pPageInfo[nPage].sizeScaleRatio;
  921.  
  922.         // convert Hit Point from screen 1:1
  923.         point.x = MulDiv(point.x, pRatio->cx, pRatio->cy);
  924.         point.y = MulDiv(point.y, pRatio->cx, pRatio->cy);
  925.  
  926.         // Adjust point for page position
  927.         point += (CSize)m_pPageInfo[0].rectScreen.TopLeft();
  928.  
  929.         // Scroll to center
  930.         CenterOnPoint(point);
  931.     }
  932. }
  933.  
  934. void CPreviewView::SetCurrentPage(UINT nPage, BOOL bClearRatios)
  935. {
  936.     m_nCurrentPage = nPage;
  937.     if (m_nCurrentPage > m_pPreviewInfo->GetMaxPage())
  938.         m_nCurrentPage = m_pPreviewInfo->GetMaxPage();
  939.     if (m_nCurrentPage < m_pPreviewInfo->GetMinPage())
  940.         m_nCurrentPage = m_pPreviewInfo->GetMinPage();
  941.  
  942.  
  943.     if (m_nZoomState == ZOOM_OUT)
  944.         SetScrollPos(SB_VERT, m_nCurrentPage);
  945.  
  946.     if (bClearRatios)
  947.     {
  948.         // Force Recalc of layout
  949.         for (UINT i = 0; i < m_nMaxPages; i++)
  950.             m_pPageInfo[i].sizeScaleRatio.cx = 0;           // zero scale ratios
  951.     }
  952.  
  953.     Invalidate(TRUE);
  954. }
  955.  
  956. void CPreviewView::OnDisplayPageNumber(UINT nPage, UINT nPagesDisplayed)
  957. {
  958.     UINT nEndPage = nPage + nPagesDisplayed - 1;
  959.  
  960.     CFrameWnd* pParent = (CFrameWnd*)AfxGetThread()->m_pMainWnd;
  961.     ASSERT_VALID(pParent);
  962.     ASSERT_KINDOF(CFrameWnd, pParent);
  963.  
  964.     int nSubString = (nPagesDisplayed == 1) ? 0 : 1;
  965.  
  966.     CString s;
  967.     if (AfxExtractSubString(s, m_pPreviewInfo->m_strPageDesc, nSubString))
  968.     {
  969.         TCHAR szBuf[80];
  970.         if (nSubString == 0)
  971.             wsprintf(szBuf, s, nPage);
  972.         else
  973.             wsprintf(szBuf, s, nPage, nEndPage);
  974.         pParent->SendMessage(WM_SETMESSAGESTRING, 0, (LPARAM)(LPVOID)szBuf);
  975.     }
  976.     else
  977.     {
  978.         TRACE1("Malformed Page Description string. Could not get string %d.\n",
  979.             nSubString);
  980.     }
  981. }
  982.  
  983.  
  984. void CPreviewView::OnUpdateNumPageChange(CCmdUI* pCmdUI)
  985. {
  986.     // set text of button to opposite of current state
  987.     CString text;
  988.     UINT nPages = m_nZoomState == ZOOM_OUT ? m_nPages : m_nZoomOutPages;
  989.     VERIFY(text.LoadString(nPages == 1 ? AFX_IDS_TWOPAGE : AFX_IDS_ONEPAGE));
  990.     pCmdUI->SetText(text);
  991.  
  992.     // enable it only if valid to display another page and not zoomed
  993.     pCmdUI->Enable(m_nZoomState == ZOOM_OUT && m_nMaxPages != 1 &&
  994.         (m_pPreviewInfo->GetMaxPage() > 1 || m_nPages > 1));
  995. }
  996.  
  997. void CPreviewView::OnUpdateNextPage(CCmdUI* pCmdUI)
  998. {
  999.     // enable if not showing last page
  1000.     pCmdUI->Enable(m_nCurrentPage+m_nPages-1 < m_pPreviewInfo->GetMaxPage());
  1001. }
  1002.  
  1003. void CPreviewView::OnUpdatePrevPage(CCmdUI* pCmdUI)
  1004. {
  1005.     // enable if not showing First page
  1006.     pCmdUI->Enable(m_nCurrentPage > m_pPreviewInfo->GetMinPage());
  1007. }
  1008.  
  1009. void CPreviewView::OnUpdateZoomIn(CCmdUI* pCmdUI)
  1010. {
  1011.     pCmdUI->Enable(m_nZoomState != ZOOM_IN);
  1012. }
  1013.  
  1014. void CPreviewView::OnUpdateZoomOut(CCmdUI* pCmdUI)
  1015. {
  1016.     pCmdUI->Enable(m_nZoomState != ZOOM_OUT);
  1017. }
  1018.  
  1019. BOOL CPreviewView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
  1020. {
  1021.     if (nHitTest != HTCLIENT)
  1022.         return CScrollView::OnSetCursor(pWnd, nHitTest, message);
  1023.  
  1024.     CPoint point;
  1025.     ::GetCursorPos(&point);
  1026.     ScreenToClient(&point);     // client coordinates of mouse position
  1027.  
  1028.     UINT nPage;
  1029.     if (m_nZoomState != ZOOM_IN && FindPageRect(point, nPage))
  1030.     {                       // On a page and not zoomed all the way in
  1031.         if (m_hMagnifyCursor == NULL)
  1032.         {
  1033.             HINSTANCE hInst = AfxFindResourceHandle(
  1034.                 MAKEINTRESOURCE(AFX_IDC_MAGNIFY), RT_GROUP_CURSOR);
  1035.             m_hMagnifyCursor = ::LoadCursor(hInst,
  1036.                 MAKEINTRESOURCE(AFX_IDC_MAGNIFY));
  1037.         }
  1038.         ::SetCursor(m_hMagnifyCursor);
  1039.     }
  1040.     else
  1041.     {
  1042.         ::SetCursor(::LoadCursor(NULL, IDC_ARROW));
  1043.     }
  1044.     return 0;
  1045. }
  1046.  
  1047. /////////////////////////////////////////////////////////////////////////////
  1048. // CPreviewView diagnostics
  1049.  
  1050. #ifdef _DEBUG
  1051. void CPreviewView::AssertValid() const
  1052. {
  1053.     CView::AssertValid();
  1054.     ASSERT_VALID(&m_dcPrint);
  1055.     if (m_pPreviewDC != NULL)
  1056.         ASSERT_VALID(m_pPreviewDC);
  1057.  
  1058.     switch (m_nZoomState)
  1059.     {
  1060.     case ZOOM_OUT:
  1061.     case ZOOM_IN:
  1062.     case ZOOM_MIDDLE:
  1063.         break;
  1064.     default:
  1065.         ASSERT(FALSE); // unknown zoom state
  1066.     }
  1067.  
  1068.     switch (m_nMapMode)
  1069.     {
  1070.     case MM_TEXT:
  1071.     case MM_LOMETRIC:
  1072.     case MM_HIMETRIC:
  1073.     case MM_LOENGLISH:
  1074.     case MM_HIENGLISH:
  1075.     case MM_TWIPS:
  1076.     case MM_ISOTROPIC:
  1077.     case MM_ANISOTROPIC:
  1078.         break;
  1079.     default:
  1080.         ASSERT(FALSE); // unknown mapping mode
  1081.     }
  1082. }
  1083.  
  1084. void CPreviewView::Dump(CDumpContext& dc) const
  1085. {
  1086.     CView::Dump(dc);
  1087.  
  1088.     dc << "m_pPrintView = " << m_pPrintView;
  1089.     dc << "\nm_pOrigView = " << m_pOrigView;
  1090.     dc << "\nm_bPageNumDisplayed = " << m_bPageNumDisplayed;
  1091.     dc << "\nm_bCenter = " << m_bCenter;
  1092.     dc << "\nm_nPages = " << m_nPages;
  1093.     dc << "\nm_nCurrentPage " << m_nCurrentPage;
  1094.     dc << "\nm_nSecondPageOffset " << m_nSecondPageOffset;
  1095.     dc << "\nm_nMaxPages = " << m_nMaxPages;
  1096.     dc << "\nm_sizePrinterPPI = " << m_sizePrinterPPI;
  1097.     dc << "\nm_ptCenterPoint = " << m_ptCenterPoint;
  1098.     dc << "\nm_nZoomState = ";
  1099.     switch (m_nZoomState)
  1100.     {
  1101.     case ZOOM_OUT:
  1102.         dc << "ZOOM_OUT";
  1103.         break;
  1104.     case ZOOM_IN:
  1105.         dc << "ZOOM_IN";
  1106.         break;
  1107.     case ZOOM_MIDDLE:
  1108.         dc << "ZOOM_MIDDLE";
  1109.         break;
  1110.     default:
  1111.         dc << "*unknown*";
  1112.         break;
  1113.     }
  1114.     dc << "\nm_nMapMode = ";
  1115.     switch (m_nMapMode)
  1116.     {
  1117.     case MM_TEXT:
  1118.         dc << "MM_TEXT";
  1119.         break;
  1120.     case MM_LOMETRIC:
  1121.         dc << "MM_LOMETRIC";
  1122.         break;
  1123.     case MM_HIMETRIC:
  1124.         dc << "MM_HIMETRIC";
  1125.         break;
  1126.     case MM_LOENGLISH:
  1127.         dc << "MM_LOENGLISH";
  1128.         break;
  1129.     case MM_HIENGLISH:
  1130.         dc << "MM_HIENGLISH";
  1131.         break;
  1132.     case MM_TWIPS:
  1133.         dc << "MM_TWIPS";
  1134.         break;
  1135.     case MM_ISOTROPIC:
  1136.         dc << "MM_ISOTROPIC";
  1137.         break;
  1138.     case MM_ANISOTROPIC:
  1139.         dc << "MM_ANISOTROPIC";
  1140.         break;
  1141.     default:
  1142.         dc << "*unknown*";
  1143.         break;
  1144.     }
  1145.     dc << "\nm_dcPrint = " << &m_dcPrint;
  1146.     dc << "\nm_pPreviewDC = " << m_pPreviewDC;
  1147.  
  1148.     dc << "\n";
  1149. }
  1150. #endif //_DEBUG
  1151.  
  1152. #ifdef AFX_INIT_SEG
  1153. #pragma code_seg(AFX_INIT_SEG)
  1154. #endif
  1155.  
  1156. IMPLEMENT_DYNCREATE(CPreviewView, CScrollView)
  1157.  
  1158. /////////////////////////////////////////////////////////////////////////////
  1159.