📄 viewprev.cpp
字号:
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1998 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#include "stdafx.h"
#ifdef AFX_PRINT_SEG
#pragma code_seg(AFX_PRINT_SEG)
#endif
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
BOOL CALLBACK _AfxPreviewCloseProc(CFrameWnd* pFrameWnd);
/////////////////////////////////////////////////////////////////////////////
// CPrintPreviewState helper structure
CPrintPreviewState::CPrintPreviewState()
{
// set defaults
nIDMainPane = AFX_IDW_PANE_FIRST;
dwStates = AFX_CONTROLBAR_MASK(AFX_IDW_STATUS_BAR);
// status bar visible if available
lpfnCloseProc = _AfxPreviewCloseProc;
// set frame hook so closing the frame window
// when in preview state will just end the mode
hMenu = NULL;
pViewActiveOld = NULL;
hAccelTable = NULL;
}
/////////////////////////////////////////////////////////////////////////////
// CView's OnPrintPreview. Here to force linkage
void CView::OnFilePrintPreview()
{
// In derived classes, implement special window handling here
// Be sure to Unhook Frame Window close if hooked.
// must not create this on the frame. Must outlive this function
CPrintPreviewState* pState = new CPrintPreviewState;
// DoPrintPreview's return value does not necessarily indicate that
// Print preview succeeded or failed, but rather what actions are necessary
// at this point. If DoPrintPreview returns TRUE, it means that
// OnEndPrintPreview will be (or has already been) called and the
// pState structure will be/has been deleted.
// If DoPrintPreview returns FALSE, it means that OnEndPrintPreview
// WILL NOT be called and that cleanup, including deleting pState
// must be done here.
if (!DoPrintPreview(AFX_IDD_PREVIEW_TOOLBAR, this,
RUNTIME_CLASS(CPreviewView), pState))
{
// In derived classes, reverse special window handling here for
// Preview failure case
TRACE0("Error: DoPrintPreview failed.\n");
AfxMessageBox(AFX_IDP_COMMAND_FAILURE);
delete pState; // preview failed to initialize, delete State now
}
}
BOOL CView::DoPrintPreview(UINT nIDResource, CView* pPrintView,
CRuntimeClass* pPreviewViewClass, CPrintPreviewState* pState)
{
ASSERT_VALID_IDR(nIDResource);
ASSERT_VALID(pPrintView);
ASSERT(pPreviewViewClass != NULL);
ASSERT(pPreviewViewClass->IsDerivedFrom(RUNTIME_CLASS(CPreviewView)));
ASSERT(pState != NULL);
CFrameWnd* pParent = STATIC_DOWNCAST(CFrameWnd, AfxGetMainWnd());
ASSERT_VALID(pParent);
CCreateContext context;
context.m_pCurrentFrame = pParent;
context.m_pCurrentDoc = GetDocument();
context.m_pLastView = this;
// Create the preview view object
CPreviewView* pView = (CPreviewView*)pPreviewViewClass->CreateObject();
if (pView == NULL)
{
TRACE0("Error: Failed to create preview view.\n");
return FALSE;
}
ASSERT_KINDOF(CPreviewView, pView);
pView->m_pPreviewState = pState; // save pointer
pParent->OnSetPreviewMode(TRUE, pState); // Take over Frame Window
// 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))
{
TRACE0("Error: Preview could not create toolbar dialog.\n");
pParent->OnSetPreviewMode(FALSE, pState); // restore Frame Window
delete pView->m_pToolBar; // not autodestruct yet
pView->m_pToolBar = NULL;
pView->m_pPreviewState = NULL; // do not delete state structure
delete pView;
return FALSE;
}
pView->m_pToolBar->m_bAutoDelete = TRUE; // automatic cleanup
// Create the preview view as a child of the App Main Window. This
// is a sibling of this view if this is an SDI app. This is NOT a sibling
// if this is an MDI app.
if (!pView->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
CRect(0,0,0,0), pParent, AFX_IDW_PANE_FIRST, &context))
{
TRACE0("Error: couldn't create preview view for frame.\n");
pParent->OnSetPreviewMode(FALSE, pState); // restore Frame Window
pView->m_pPreviewState = NULL; // do not delete state structure
delete pView;
return FALSE;
}
// 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; // signal that OnEndPrintPreview was called
}
pParent->SetActiveView(pView); // set active view - even for MDI
// update toolbar and redraw everything
pView->m_pToolBar->SendMessage(WM_IDLEUPDATECMDUI, (WPARAM)TRUE);
pParent->RecalcLayout(); // position and size everything
pParent->UpdateWindow();
return TRUE;
}
BOOL CALLBACK _AfxPreviewCloseProc(CFrameWnd* pFrameWnd)
{
ASSERT_VALID(pFrameWnd);
CPreviewView* pView = (CPreviewView*) pFrameWnd->GetDlgItem(AFX_IDW_PANE_FIRST);
ASSERT_KINDOF(CPreviewView, pView);
pView->OnPreviewClose();
return FALSE;
}
/////////////////////////////////////////////////////////////////////////////
// Preview View
BEGIN_MESSAGE_MAP(CPreviewView, CScrollView)
//{{AFX_MSG_MAP(CPreviewView)
ON_WM_SIZE() // overriding CScrollView
ON_WM_CREATE()
ON_COMMAND(AFX_ID_PREVIEW_CLOSE, OnPreviewClose)
ON_COMMAND(AFX_ID_PREVIEW_NUMPAGE, OnNumPageChange)
ON_COMMAND(AFX_ID_PREVIEW_NEXT, OnNextPage)
ON_COMMAND(AFX_ID_PREVIEW_PREV, OnPrevPage)
ON_COMMAND(AFX_ID_PREVIEW_PRINT, OnPreviewPrint)
ON_COMMAND(AFX_ID_PREVIEW_ZOOMIN, OnZoomIn)
ON_COMMAND(AFX_ID_PREVIEW_ZOOMOUT, OnZoomOut)
ON_UPDATE_COMMAND_UI(AFX_ID_PREVIEW_NUMPAGE, OnUpdateNumPageChange)
ON_UPDATE_COMMAND_UI(AFX_ID_PREVIEW_NEXT, OnUpdateNextPage)
ON_UPDATE_COMMAND_UI(AFX_ID_PREVIEW_PREV, OnUpdatePrevPage)
ON_UPDATE_COMMAND_UI(AFX_ID_PREVIEW_ZOOMIN, OnUpdateZoomIn)
ON_UPDATE_COMMAND_UI(AFX_ID_PREVIEW_ZOOMOUT, OnUpdateZoomOut)
ON_WM_VSCROLL()
ON_WM_HSCROLL()
ON_WM_LBUTTONDOWN()
ON_WM_ERASEBKGND()
ON_WM_SETCURSOR()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
CPreviewView::CPreviewView()
{
m_pPrintView = NULL;
m_pOrigView = NULL;
m_pPreviewInfo = NULL;
m_pPreviewDC = NULL;
m_pPreviewState = NULL;
m_hMagnifyCursor = NULL;
m_bPageNumDisplayed = FALSE;
m_nZoomState = ZOOM_OUT;
// default to pointing to embedded array. Allows for 2 pages
m_pPageInfo = m_pageInfoArray;
m_nMaxPages = 2;
// initialize CScrollView members
m_bCenter = TRUE; // Center Zoomed output in Scrollview
m_nMapMode = MM_TEXT;
}
CPreviewView::PAGE_INFO::PAGE_INFO()
{
}
CPreviewView::~CPreviewView()
{
m_dcPrint.Detach(); // print DC is deleted by CPrintInfo destructor
delete m_pPreviewInfo; // get rid of preview info
delete m_pPreviewState; // Get rid of preview state
delete m_pPreviewDC; // Get rid of preview DC object
if (m_hMagnifyCursor != NULL)
{
// make sure that m_hMagnifyCursor isn't the current cursor when we destroy it
::SetCursor(::LoadCursor(NULL, IDC_ARROW));
DestroyCursor(m_hMagnifyCursor);
}
}
int CPreviewView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
int retVal = CView::OnCreate(lpCreateStruct);
if (retVal == -1)
return -1; // if -1 bag out
CCreateContext* pContext = (CCreateContext*)lpCreateStruct->lpCreateParams;
m_pOrigView = pContext->m_pLastView;
ASSERT(m_pOrigView != NULL);
ASSERT_KINDOF(CView, m_pOrigView);
return retVal;
}
BOOL CPreviewView::SetPrintView(CView* pPrintView)
{
ASSERT_VALID(pPrintView);
m_pPrintView = pPrintView;
// allocate preview info
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
ASSERT(m_pPreviewInfo->m_pPD != NULL);
m_pPreviewDC = new CPreviewDC; // must be created before any
// possible error returns
if (!m_pPrintView->OnPreparePrinting(m_pPreviewInfo))
return FALSE;
#ifdef _DEBUG
if (m_pPreviewInfo->m_pPD->m_pd.hDC == NULL)
{
TRACE0("Error: hDC not set for printing --\n");
TRACE0("\tDid you remember to call DoPreparePrinting?\n");
ASSERT(FALSE); // common mistake gets trapped here
}
#endif //_DEBUG
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
// 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; // Sanity Check!
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
// large don't show
SetCurrentPage(m_pPreviewInfo->m_nCurPage, TRUE);
return TRUE;
}
void CPreviewView::OnSize(UINT nType, int cx, int cy)
{
// CScrollView handles everything if zoomed in.
if (m_nZoomState == ZOOM_OUT)
{
// Force recalc of scale ratios on next draw
for (UINT i = 0; i < m_nMaxPages; i++)
m_pPageInfo[i].sizeScaleRatio.cx = 0; // zero scale ratios
CView::OnSize(nType, cx, cy); // No scroll functionality
}
else
{
// adjust scroll size to size of page
m_pageDev.cx = cx;
m_pageDev.cy = cy;
m_lineDev.cx = cx / 10;
m_lineDev.cy = cy / 10;
CScrollView::OnSize(nType, cx, cy);
}
}
void CPreviewView::OnActivateView(BOOL bActivate, CView*, CView*)
{
if (bActivate)
{
CWnd* pFocusWnd = GetFocus();
if (pFocusWnd == NULL ||
(m_pToolBar != NULL && !m_pToolBar->IsChild(pFocusWnd)))
{
// focus is not already on a toolbar button - set it to one
m_pToolBar->GetDlgItem(AFX_ID_PREVIEW_PRINT)->SetFocus();
}
}
}
void CPreviewView::OnPreviewClose()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -