// AdvancedPreviewView.cpp
#include "stdafx.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
IMPLEMENT_DYNCREATE(CAdvancedPreviewView, CView)
BEGIN_MESSAGE_MAP(CAdvancedPreviewView, CView)
//{{AFX_MSG_MAP(CAdvancedPreviewView)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, OnFilePrintPreview)
//}}AFX_MSG_MAP
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()
CAdvancedPreviewView::CAdvancedPreviewView()
{
m_rectClipOrg.SetRectEmpty();
m_nCurPageOld = 0;
}
CAdvancedPreviewView::~CAdvancedPreviewView()
{
}
void CAdvancedPreviewView::OnDraw(CDC* pDC)
{
CAdvancedPreviewDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
}
BOOL CAdvancedPreviewView::OnPreparePrinting(CPrintInfo* pInfo)
{
return DoPreparePrinting(pInfo);
}
#ifdef _DEBUG
void CAdvancedPreviewView::AssertValid() const
{
CView::AssertValid();
}
void CAdvancedPreviewView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CAdvancedPreviewDoc* CAdvancedPreviewView::GetDocument()
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CAdvancedPreviewDoc)));
return (CAdvancedPreviewDoc*)m_pDocument;
}
#endif //_DEBUG
// override MFC
void CAdvancedPreviewView::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(ExtPreviewView), 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
pState = NULL;
}
}
extern CAdvancedPreviewApp theApp;
// override MFC
BOOL CAdvancedPreviewView::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;
CWnd* pNaturalParent = pPrintView->GetParentFrame();
pParent = DYNAMIC_DOWNCAST(CFrameWnd, pNaturalParent);
if (pParent == NULL || pParent->IsIconic())
// pParent = (CFrameWnd*)AfxGetThread()->m_pMainWnd;
pParent = (CFrameWnd*)theApp.m_pMainWnd;
ASSERT_VALID(pParent);
ASSERT_KINDOF(CFrameWnd, 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();
ExtPreviewView* pView = (ExtPreviewView*)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
#ifdef _MAC
if (nIDResource == AFX_IDD_PREVIEW_TOOLBAR)
{
HINSTANCE hInst = AfxFindResourceHandle(
MAKEINTRESOURCE(AFX_IDD_PREVIEW_TOOLBAR), RT_DIALOG);
HRSRC hResource = FindResource(hInst,
MAKEINTRESOURCE(AFX_IDD_PREVIEW_TOOLBAR), RT_DIALOG);
HGLOBAL hdt = NULL;
if (hResource != NULL)
hdt = LoadResource(hInst, hResource);
DLGTEMPLATE* pdt = NULL;
if (hdt != NULL)
pdt = (DLGTEMPLATE*)LockResource(hdt);
if (pdt != NULL)
{
CRect rectParent;
pParent->GetClientRect(&rectParent);
int cxToolbar = MulDiv(LOWORD(GetDialogBaseUnits()), pdt->cx, 4);
if (cxToolbar > rectParent.Width())
nIDResource = AFX_IDD_PREVIEW_SHORTTOOLBAR;
UnlockResource(hdt);
FreeResource(hdt);
}
}
#endif
// 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))
CBRS_TOP, AFX_IDD_PREVIEW_TOOLBAR))
{
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;
pView = NULL;
return FALSE;
}
pView->m_pToolBar->m_bAutoDelete = TRUE; // automatic cleanup
// pView->m_pToolBar->SetBarStyle(pView->m_pToolBar->GetBarStyle() | CBRS_TOOLTIPS);
// 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;
pView = NULL;
return FALSE;
}
// Preview window shown now
pState->pViewActiveOld = pParent->GetActiveView();
// CView* pActiveView = pParent->GetActiveFrame()->GetActiveView();
CAdvancedPreviewView* pActiveView = (CAdvancedPreviewView*)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);
pView->m_pToolBar->SetBarStyle(pView->m_pToolBar->GetBarStyle() | CBRS_TOOLTIPS);
pParent->RecalcLayout(); // position and size everything
pParent->UpdateWindow();
return TRUE;
}
LPBITMAPINFO pbmi;
PBYTE lpvBits;
void CAdvancedPreviewView::DIBfromDDB(HDC hDC, HBITMAP hBmp, HBITMAP& hDIB, HPALETTE& hPal)
{
int iBitCount = ::GetDeviceCaps(hDC, BITSPIXEL);
ULONG sizBMI;
int iNumClr;
switch (iBitCount)
{
case 16:
case 32:
sizBMI = sizeof(BITMAPINFOHEADER) + sizeof(DWORD) * 3;
break;
case 24:
sizBMI = sizeof(BITMAPINFOHEADER);
break;
default:
iNumClr = (1 << iBitCount);
sizBMI = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * iNumClr;
break;
}
pbmi = (LPBITMAPINFO) new char [sizBMI];
ZeroMemory(pbmi, sizBMI);
pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pbmi->bmiHeader.biBitCount = 0;
pbmi->bmiHeader.biCompression = BI_RGB;
pbmi->bmiHeader.biSizeImage = 0;
pbmi->bmiHeader.biXPelsPerMeter = 0;
pbmi->bmiHeader.biYPelsPerMeter = 0;
pbmi->bmiHeader.biClrUsed = 0;
pbmi->bmiHeader.biClrImportant = 0;
BITMAP bm;
::GetObject(hBmp, sizeof(BITMAP), &bm);
::GetDIBits(hDC, hBmp, 0, bm.bmHeight, NULL, pbmi, DIB_RGB_COLORS);
::GetDIBits(hDC, hBmp, 0, pbmi->bmiHeader.biHeight, lpvBits, pbmi, DIB_RGB_COLORS);
hDIB = ::CreateDIBSection(hDC, pbmi, DIB_RGB_COLORS, (void**)NULL, NULL, 0);
}
void CAdvancedPreviewView::OnPrint(CDC* pDC, CPrintInfo* pInfo)
{
CView::OnPrint(pDC, pInfo);
CRect rectClip;
rectClip.SetRectEmpty();
pDC->GetClipBox(&rectClip);
CFrameWnd* pParent = (CFrameWnd*)theApp.m_pMainWnd;
ExtPreviewView* pPreviewView = (ExtPreviewView*)pParent->GetActiveFrame()->GetActiveView();
if (pDC->IsKindOf(RUNTIME_CLASS(CPreviewDC))) {
// first time this view be created, m_nCurPage might be 0
if (pInfo->m_nCurPage != m_nCurPageOld) {
CDC mDC;
mDC.CreateCompatibleDC(pDC);
((CDC&)mDC).SetAttribDC(pInfo->m_pPD->m_pd.hDC);
int iMapModeOld2 = ((CDC&)mDC).SetMapMode(MM_ANISOTROPIC);
::SetWindowExtEx(mDC.m_hDC, pPreviewView->m_sizeVxWinExt.cx,
pPreviewView->m_sizeVxWinExt.cy, NULL);
::SetViewportExtEx(mDC.m_hDC, pPreviewView->m_sizeVxVpExt.cx,
pPreviewView->m_sizeVxVpExt.cy, NULL);
::SetWindowExtEx(mDC.m_hAttribDC, pPreviewView->m_sizeVxWinExt.cx,
pPreviewView->m_sizeVxWinExt.cy, NULL);
::SetViewportExtEx(mDC.m_hAttribDC, pPreviewView->m_sizeVxVpExt.cx,
pPreviewView->m_sizeVxVpExt.cy, NULL);
CRect rTmp(m_rectClipOrg);
rTmp.NormalizeRect();
CRect rMem;
rMem = rectClip;
pDC->LPtoDP(rMem);
mDC.DPtoLP(rMem);
if (m_BitmapMem.operator HBITMAP())
::DeleteObject(m_BitmapMem.Detach());
if (m_PalMem.operator HPALETTE())
::DeleteObject(m_PalMem.Detach());
if (!m_BitmapMem.operator HBITMAP())
{
CBitmap ddb;
CRect rBmp(pPreviewView->m_pVxPageInfo->rectScreen);
rBmp.NormalizeRect();
ddb.CreateCompatibleBitmap((CDC*)CDC::FromHandle(mDC.m_hDC), rBmp.Width(), rBmp.Height());
HBITMAP hDib = NULL;
HPALETTE hPal = NULL;
DIBfromDDB(mDC.m_hDC, ddb.operator HBITMAP(), hDib, hPal);
ddb.DeleteObject();
m_BitmapMem.Attach(hDib);
pDC->DPtoLP(rBmp);
m_rectClipOrg = rBmp;
}
CBitmap* pOldBitmap = (CBitmap*)CGdiObject::FromHandle(::SelectObject(mDC.m_hDC, m_BitmapMem.m_hObject));
mDC.PatBlt(0, 0, m_rectClipOrg.Width(), m_rectClipOrg.Height(), WHITENESS);
int iSave = mDC.SaveDC();
int iMapModeOld3 = ((CDC&)mDC).SetMapMode(MM_TEXT);
// drawing things
CRect rect;
GetClientRect(&rect);
CString str1("Mm");
LOGFONT lf;
ZeroMemory(&lf, sizeof(lf));
lf.lfHeight = 800;
CopyMemory(lf.lfFaceName, "Times New Roman", sizeof(lf.lfFaceName));
CFont font;
font.CreatePointFontIndirect(&lf, &mDC);
CFont* pFont = mDC.SelectObject(&font);
CSize sizeStr;
::GetTextExtentPoint32(mDC.m_hDC, str1, str1.GetLength(), &sizeStr);
CRect rStr;
rStr.SetRect((rect.Width() - sizeStr.cx) / 2,
(rect.Height() - sizeStr.cy) /2,
rect.right - (rect.Width() - sizeStr.cx) / 2,
rect.bottom - (rect.Height() - sizeStr.cy) /2);
mDC.DrawText(str1, -1, rStr, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
mDC.SelectObject(pFont);
CString str2("123456789"), str3("987654321");
LOGFONT lfSuper;
ZeroMemory(&lfSuper, sizeof(lfSuper));
lfSuper.lfHeight = 800 * 54 / 100;
lfSuper.lfPitchAndFamily = OEM_CHARSET;
CopyMemory(lfSuper.lfFaceName, "Times New Roman", sizeof(lfSuper.lfFaceName));
CFont fontSuper;
fontSuper.CreatePointFontIndirect(&lfSuper, &mDC);
mDC.SelectObject(&fontSuper);
CSize sizeStrSuper;
::GetTextExtentPoint32(mDC.m_hDC, str2, str2.GetLength(), &sizeStrSuper);
// Superscript
CRect rStrSuper;
rStrSuper.SetRect(rStr.right,
rStr.top,
rStr.right + sizeStrSuper.cx,
rStr.top + sizeStrSuper.cy);
mDC.DrawText(str2, -1, rStrSuper, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
// Subscript
CRect rStrSub;
rStrSub.SetRect(rStr.right,
rStr.bottom - sizeStrSuper.cy,
rStr.right + sizeStrSuper.cx,
rStr.bottom);
mDC.DrawText(str3, -1, rStrSub, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
mDC.SelectObject(pFont);
::DeleteObject (font.Detach ());
::DeleteObject (fontSuper.Detach ());
mDC.SelectObject(pFont);
::DeleteObject (font.Detach ());
::DeleteObject (fontSuper.Detach ());
// ((CDC&)mDC).SetMapMode(iMapModeOld3);
// iMapModeOld3 = mDC.SetMapMode(MM_HIMETRIC);
CFont fontMem;
mDC.RestoreDC(iSave);
pDC->BitBlt(rectClip.left, rectClip.top,
rectClip.Width(), rectClip.Height(),
&mDC,
rMem.left, rMem.top, SRCCOPY);
mDC.SetMapMode(iMapModeOld3);
// mDC.SetMapMode(iMapModeOld2);
((CDC&)mDC).SelectObject(pOldBitmap);
mDC.DeleteDC();
m_nCurPageOld = pInfo->m_nCurPage;
return;
}
else
{
CDC mDC;
mDC.CreateCompatibleDC(pDC);
mDC.SetAttribDC(pInfo->m_pPD->m_pd.hDC);
CBitmap* pOldBitmap = mDC.SelectObject(&m_BitmapMem);
int iMapModeOld2 = ((CDC&)mDC).SetMapMode(MM_ANISOTROPIC);
::SetWindowExtEx(mDC.m_hDC, pPreviewView->m_sizeVxWinExt.cx,
pPreviewView->m_sizeVxWinExt.cy, NULL);
::SetViewportExtEx(mDC.m_hDC, pPreviewView->m_sizeVxVpExt.cx,
pPreviewView->m_sizeVxVpExt.cy, NULL);
CRect rMem;
rMem = rectClip;
pDC->LPtoDP(rMem);
mDC.DPtoLP(rMem);
pDC->PatBlt(rectClip.left, rectClip.top, rectClip.Width(), rectClip.Height(), WHITENESS);
pDC->BitBlt(rectClip.left, rectClip.top,
rectClip.Width(), rectClip.Height(),
&mDC,
rMem.left, rMem.top, SRCCOPY);
mDC.SetMapMode(iMapModeOld2);
mDC.SelectObject(pOldBitmap);
mDC.DeleteDC();
return;
}
}
}
void CAdvancedPreviewView::OnInitialUpdate()
{
CView::OnInitialUpdate();
OnFilePrintPreview();
((CChildFrame*)GetParentFrame())->MDIMaximize();
}