Hide

SftPrintPreview/DLL 2.0 - Print Preview Control for C/C++

Display
Print

PreviewPages Sample (C++/MFC)

This sample illustrates application-generated output.

The source code is located at C:\Program Files (x86)\Softelvdm\SftPrintPreview DLL 2.0\Samples\MFC\PreviewPages\PreviewPagesView.cpp or C:\Program Files\Softelvdm\SftPrintPreview DLL 2.0\Samples\MFC\PreviewPages\PreviewPagesView.cpp (on 32-bit Windows versions).


#include "stdafx.h"
#include "PreviewPages.h"

#include "PreviewPagesDoc.h"
#include "PreviewPagesView.h"

#include "PreviewPagePrinting.h"

IMPLEMENT_DYNCREATE(CPreviewPagesView, CView)

BEGIN_MESSAGE_MAP(CPreviewPagesView, CView)
    //{{AFX_MSG_MAP(CPreviewPagesView)
    ON_COMMAND(ID_FILE_PREVIEW, OnFilePreview)
    ON_WM_VSCROLL()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

CPreviewPagesView::CPreviewPagesView()
{
    m_MainBitmap.LoadBitmap(IDB_WEBPAGE);
}

CPreviewPagesView::~CPreviewPagesView()
{
}

BOOL CPreviewPagesView::PreCreateWindow(CREATESTRUCT& cs)
{
    cs.style |= WS_VSCROLL;

    return CView::PreCreateWindow(cs);
}

BOOL CPreviewPagesView::DrawOnePage(CDC* pDC, HDC hDCPrinter, Gdiplus::Graphics* pGraphics, const RECT& ClientRect, int& counter)
{
    // starting output position on this page
    int x = ClientRect.left;
    int y = ClientRect.top;

    for ( ; ; ) {
        int w, h;

        if (counter >= (1+50)*20)
            // we have printed 1 bitmap and 50 lines 20 times, we're done
            return FALSE;

        if ((counter % (50+1)) == 0) {
            // Print a bitmap
            int wPrinter, hPrinter;

            // get bitmap size
            CSftPrintPreview::GetBitmapSize(m_MainBitmap, hDCPrinter, &wPrinter, &hPrinter, &w, &h);

            if (hDCPrinter) {
                // make sure entire image fits on remaining page
                if (y != ClientRect.top && y + hPrinter > ClientRect.bottom)
                    break;
            }

            // print bitmap, horizontally centered
            // this code does not handle if the bitmap is too large for the remaining space
            CSftPrintPreview::PrintBitmap(m_MainBitmap, pDC->m_hDC, x +(ClientRect.right-ClientRect.left-wPrinter)/2, 
                   y, wPrinter, hPrinter, w, h);

            y += hPrinter; // next available space
        } else {
            // Print line
            RECT rect, OutRect;

            pDC->SelectObject(m_PrintFont);
            pDC->SetTextColor(RGB(0,0,0));

            // get text size
            SetRectEmpty(&rect);
            pDC->DrawText(LINETEXT, &rect, DT_LEFT| DT_TOP | DT_SINGLELINE | DT_CALCRECT);

            if (hDCPrinter) {
                // make sure text fits on remaining page
                if (y + (rect.bottom-rect.top) > ClientRect.bottom)
                    break;
            }

            OutRect = ClientRect;
            OutRect.top = y;
            pDC->DrawText(LINETEXT, &OutRect, DT_CENTER| DT_TOP | DT_SINGLELINE);

            y += rect.bottom-rect.top; // next available space

        }
        ++counter;  // one more item done

        // make sure we are still on current page
        if (y >= ClientRect.bottom)
            break;
    }

    // Now add some GDI+ output - The entire page could also be drawn using just
    // GDI+ functions. In this sample, we're mixing HDC (above) and GDI+ output (below)
    // on the same page.

    if (pGraphics) {
        Gdiplus::FontFamily  fontFamily(L"Times New Roman");
        Gdiplus::Font        font(&fontFamily, 72, Gdiplus::FontStyleRegular, Gdiplus::UnitPoint);
        Gdiplus::PointF      pointF(50.0f, 3000.0f);
        Gdiplus::SolidBrush  solidBrush(Gdiplus::Color(255, 0, 0, 255));
        pGraphics->RotateTransform(-10.0f, Gdiplus::MatrixOrderAppend);  // then rotate
        pGraphics->DrawString(L"Sample with\nGDI+ Output", -1, &font, pointF, &solidBrush);  

    }
    return TRUE; // More
}

void CPreviewPagesView::OnDraw(CDC* pDC)
{
    CPreviewPagesDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);

    RECT ClientRect;
    GetClientRect(&ClientRect);

    SCROLLINFO info;
    memset(&info, 0, sizeof(info));
    info.cbSize = sizeof(info);
    GetScrollInfo(SB_VERT, &info);

    int counter = info.nPos;// we left off here

    DrawOnePage(pDC, NULL, NULL, ClientRect, counter);
}

void CPreviewPagesView::OnPrintInitialize(CDC* pDC, LPSFTPRINTPREVIEW_DRAWINFO lpInfo)
{
    int height = MulDiv(10, GetDeviceCaps(lpInfo->hDCPrinter, LOGPIXELSY), 72);// 10 point font
    m_PrintFont.CreateFont(- height, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET,
            OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_DONTCARE|DEFAULT_PITCH,
            _T("Arial"));
    _ASSERT(m_PrintFont.m_hObject);
}

void CPreviewPagesView::OnPrintTerminate(CDC* pDC, LPSFTPRINTPREVIEW_DRAWINFO lpInfo)
{
    m_PrintFont.DeleteObject();
}

void CPreviewPagesView::OnPrintOnePage(CDC* pDC, LPSFTPRINTPREVIEW_DRAWINFO lpInfo)
{
    // Print one page (can occur multiple times)
    // lpInfo->absPage has the absolute page # to print (0..n)
    // lpInfo->previousVisitedPageInfo contains the value you returned in
    // lpInfo->visitedPageInfo when you finished printing the previous page
    // This allows you to simply restart where you left off.
    // The information you return in lpInfo->visitedPageInfo is of type
    // SFTPRINTPREVIEW_DWORD_PTR, so it can be a simple counter or
    // even a pointer to stored, cached information.

    // In this example we print 1 bitmap, then 50 lines of text,
    // 20 times

    // We use lpInfo->previousVisitedPageInfo to resume printing.
    // We simply start at 0 and add 1 for each bitmap or line we
    // printed. Using a simple formula, we can determine where we
    // left off.  In an application, the concept remains the same, but
    // instead of a simple counter, you could use lpInfo->visitedPageInfo
    // to store a pointer to cached information.

    int counter = (int) lpInfo->previousVisitedPageInfo;// we left off here on the previos page

    if (!DrawOnePage(pDC, lpInfo->hDCPrinter, (Gdiplus::Graphics*) lpInfo->pGraphics, lpInfo->OutputRectDisplayPix, counter)) {
        // we have printed 1 bitmap and 50 lines 20 times, we're done
        lpInfo->lastPage = lpInfo->absPage; // return that this is the last page
    }

    lpInfo->visitedPageInfo = counter; // we left off here

}

void CPreviewPagesView::OnPrintClearCache(CDC* pDC, LPSFTPRINTPREVIEW_DRAWINFO lpInfo)
{
}

/////////////////////////////////////////////////////////////////////////////
// CPreviewPagesView diagnostics

#ifdef _DEBUG
void CPreviewPagesView::AssertValid() const
{
    CView::AssertValid();
}

void CPreviewPagesView::Dump(CDumpContext& dc) const
{
    CView::Dump(dc);
}

CPreviewPagesDoc* CPreviewPagesView::GetDocument() // non-debug version is inline
{
    ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CPreviewPagesDoc)));
    return (CPreviewPagesDoc*)m_pDocument;
}
#endif //_DEBUG

void CPreviewPagesView::OnFilePreview() 
{
    FilePrintPreview(this, RUNTIME_CLASS(CPreviewPagePrinting), NULL);
}

void CPreviewPagesView::OnInitialUpdate() 
{
    CView::OnInitialUpdate();
    
    SCROLLINFO info;
    memset(&info, 0, sizeof(info));
    info.cbSize = sizeof(info);
    info.fMask = SIF_ALL;
    info.nMin = 0;
    info.nMax = (1+50)*20; // total # of lines (bitmaps + text lines)
    info.nPos = 0;
    SetScrollInfo(SB_VERT, &info, TRUE);
}

void CPreviewPagesView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
    SCROLLINFO info;
    memset(&info, 0, sizeof(info));
    info.cbSize = sizeof(info);
    GetScrollInfo(SB_VERT, &info);
    nPos = info.nPos;

    switch(nSBCode) {
    case SB_BOTTOM:
        nPos = info.nMax - 1;
        break;
    case SB_LINEDOWN:
        ++nPos;
        break;        
    case SB_LINEUP:
        --nPos;
        break;        
    case SB_PAGEDOWN:
        nPos += 10;
        break;        
    case SB_PAGEUP:
        nPos -= 10;
        break;
    case SB_TOP:
        nPos = 0;
        break;
    case SB_ENDSCROLL:
        nPos = nPos;
        break;
    case SB_THUMBPOSITION:
    case SB_THUMBTRACK:
        nPos = info.nTrackPos;
        break;
    default:
        CView::OnVScroll(nSBCode, nPos, pScrollBar);
        return;
    }

    info.fMask = SIF_POS;
    nPos = min(info.nMax, max(info.nMin, (int)nPos));

    if (info.nPos != (int) nPos) {
        info.nPos = nPos;
        SetScrollInfo(SB_VERT, &info, TRUE);
        Invalidate();
    }
}

Last Updated 08/13/2020 - (email)
© 2024 Softel vdm, Inc.