SftTree/DLL 7.5 - Tree Control
SftBox/OCX 5.0 - Combo Box Control
SftButton/OCX 3.0 - Button Control
SftMask/OCX 7.0 - Masked Edit Control
SftTabs/OCX 6.5 - Tab Control (VB6 only)
SftTree/OCX 7.5 - Tree Control
SftPrintPreview/DLL 2.0 - Print Preview Control (discontinued)
SftTree/DLL 7.5 - Tree Control
SftBox/OCX 5.0 - Combo Box Control
SftButton/OCX 3.0 - Button Control
SftDirectory 3.5 - File/Folder Control (discontinued)
SftMask/OCX 7.0 - Masked Edit Control
SftOptions 1.0 - Registry/INI Control (discontinued)
SftPrintPreview/OCX 1.0 - Print Preview Control (discontinued)
SftTabs/OCX 6.5 - Tab Control (VB6 only)
SftTree/OCX 7.5 - Tree Control
SftTabs/NET 6.0 - Tab Control (discontinued)
SftTree/NET 2.0 - Tree Control
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(); } }