• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 650
  • Last Modified:

OnFilePrint

I've a view derived from CFormView, I've override OnFilePrint, I've used CPrintDialog and then?
How can I print something? Full explanation please!
0
css
Asked:
css
1 Solution
 
stefanrCommented:
This is an extract from an actual printable form view:

class CPrintableFormView : public CFormView
{
protected: // create from serialization only
      CPrintableFormView(LPCTSTR lpszTemplateName);
      CPrintableFormView(UINT nIDTemplate);

      DECLARE_DYNAMIC(CPrintableFormView)

public:
      //{{AFX_DATA(CPrintableFormView)
            // NOTE: the ClassWizard will add data members here
      //}}AFX_DATA

// Attributes
public:

// Operations
public:
   void SetMargins(const int nLeft, const int nTop, const int nRight, const int nBottom)
      {
         m_nMarginLeft = nLeft;
         m_nMarginTop = nTop;
         m_nMarginRight = nRight;
         m_nMarginBottom = nBottom;
      }
   int GetLeftMargin() const { return m_nMarginLeft; }
   int GetTopMargin() const { return m_nMarginTop; }
   int GetRightMargin() const { return m_nMarginRight; }
   int GetBottomMargin() const { return m_nMarginBottom; }

// Overrides
      // ClassWizard generated virtual function overrides
      //{{AFX_VIRTUAL(CPrintableFormView)
      protected:
      virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
      virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
      virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
      virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
      virtual void OnPrint(CDC* pDC, CPrintInfo* pInfo);
      //}}AFX_VIRTUAL

// Implementation
public:
      virtual ~CPrintableFormView();
#ifdef _DEBUG
      virtual void AssertValid() const;
      virtual void Dump(CDumpContext& dc) const;
#endif

protected:

// Generated message map functions
protected:
      int m_nMarginBottom;
      int m_nMarginRight;
      int m_nMarginTop;
      int m_nMarginLeft;
      CBitmap* m_pOldBitmap;
      CBitmap* m_pbmMemory;
      CDC* m_pMemoryDC;
      CRect m_rectClipBox;
      //{{AFX_MSG(CPrintableFormView)
      afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
      //}}AFX_MSG
      DECLARE_MESSAGE_MAP()
private:
      void Init();
      void DeleteMemoryDC(CDC** ppDC, CBitmap** ppbm, CBitmap* pOldBitmap);
      CBitmap* CreateMemoryDC(CDC** ppDC, CBitmap** ppbm);
};

/////////////////////////////////////////////////////////////////////////////
// CPrintableFormView

IMPLEMENT_DYNAMIC(CPrintableFormView, CFormView)

BEGIN_MESSAGE_MAP(CPrintableFormView, CFormView)
      //{{AFX_MSG_MAP(CPrintableFormView)
      ON_WM_RBUTTONDOWN()
      //}}AFX_MSG_MAP
      // Standard printing commands
      ON_COMMAND(ID_FILE_PRINT, CFormView::OnFilePrint)
      ON_COMMAND(ID_FILE_PRINT_DIRECT, CFormView::OnFilePrint)
      ON_COMMAND(ID_FILE_PRINT_PREVIEW, CFormView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CPrintableFormView construction/destruction

/////////////////////////////////////////////////////////////////////////////
// Init - initializes the object's member variables.
/////////////////////////////////////////////////////////////////////////////
void CPrintableFormView::Init()
{
      //{{AFX_DATA_INIT(CPrintableFormView)
            // NOTE: the ClassWizard will add member initialization here
      //}}AFX_DATA_INIT
      // TODO: add construction code here
   m_pMemoryDC = NULL;
   m_pbmMemory = NULL;
   m_pOldBitmap = NULL;
   m_rectClipBox = CRect(0, 0, 0, 0);
   m_nMarginBottom = 0;
   m_nMarginRight = 0;
   m_nMarginTop = 0;
   m_nMarginLeft = 0;
}

/////////////////////////////////////////////////////////////////////////////
// CPrintableFormView - constructor.
/////////////////////////////////////////////////////////////////////////////
CPrintableFormView::CPrintableFormView(LPCTSTR lpszTemplateName)
      : CFormView(lpszTemplateName)
{
   Init();
}

/////////////////////////////////////////////////////////////////////////////
// CPrintableFormView - constructor.
/////////////////////////////////////////////////////////////////////////////
CPrintableFormView::CPrintableFormView(UINT nIDTemplate)
      : CFormView(nIDTemplate)
{
   Init();
}

/////////////////////////////////////////////////////////////////////////////
// ~CPrintableFormView - destructor.
/////////////////////////////////////////////////////////////////////////////
CPrintableFormView::~CPrintableFormView()
{
   delete m_pMemoryDC;
   delete m_pbmMemory;
}

/////////////////////////////////////////////////////////////////////////////
// CreateMemoryDC - used internally to make a copy of the view as a bitmap.
/////////////////////////////////////////////////////////////////////////////
CBitmap* CPrintableFormView::CreateMemoryDC(CDC * * ppDC, CBitmap * * ppbm)
{
   ASSERT(ppDC != NULL);
   ASSERT(ppbm != NULL);
   ASSERT(*ppDC == NULL);
   ASSERT(*ppbm == NULL);

   CClientDC ClientDC(this);
   ClientDC.SetMapMode(MM_LOMETRIC);
   
   GetClientRect(m_rectClipBox);
   ClientDC.DPtoLP(m_rectClipBox);
#ifdef _DEBUG
   afxDump << "m_rectClipBox = " << m_rectClipBox << "\n";
#endif


   CDC* pDC = new CDC();
   if (!pDC->CreateCompatibleDC(&ClientDC))
   {
      TRACE("Failed to create compatible DC\n");
      delete pDC;
      return NULL;
   }

   CBitmap* pbm = new CBitmap();
   if (!pbm->CreateCompatibleBitmap(&ClientDC, m_rectClipBox.Width(), abs(m_rectClipBox.Height())))
   {
      TRACE("Failed to create compatible bitmap\n");
      delete pbm;
      delete pDC;
      return NULL;
   }

   CBitmap* pOldBitmap = pDC->SelectObject(pbm);

   pDC->SetMapMode(MM_LOMETRIC);
   UpdateWindow();
   pDC->BitBlt(0, 0, m_rectClipBox.Width(), m_rectClipBox.Height(), &ClientDC, 0, 0, SRCCOPY); // Make in-memory copy of this dialog.

   *ppbm = pbm;
   *ppDC = pDC;
   return pOldBitmap;
}

/////////////////////////////////////////////////////////////////////////////
// DeleteMemoryDC - used internally to free the resources allocated in CreateMemoryDC.
/////////////////////////////////////////////////////////////////////////////
void CPrintableFormView::DeleteMemoryDC(CDC * * ppDC, CBitmap * * ppbm, CBitmap * pOldBitmap)
{
   ASSERT(ppDC != NULL);
   ASSERT(ppbm != NULL);

   if (pOldBitmap != NULL && *ppDC != NULL)
      (*ppDC)->SelectObject(pOldBitmap);

   delete *ppDC;
   delete *ppbm;
   *ppDC = NULL;
   *ppbm = NULL;
}

/////////////////////////////////////////////////////////////////////////////
// DoDataExchange - called by the framework to do data exchange and validation.
/////////////////////////////////////////////////////////////////////////////
void CPrintableFormView::DoDataExchange(CDataExchange* pDX)
{
      CFormView::DoDataExchange(pDX);
      //{{AFX_DATA_MAP(CPrintableFormView)
            // NOTE: the ClassWizard will add DDX and DDV calls here
      //}}AFX_DATA_MAP
}

/////////////////////////////////////////////////////////////////////////////
// CPrintableFormView printing

/////////////////////////////////////////////////////////////////////////////
// OnPreparePrinting - called from OnFilePrint before the dialog is printed.
/////////////////////////////////////////////////////////////////////////////
BOOL CPrintableFormView::OnPreparePrinting(CPrintInfo* pInfo)
{
      // default preparation
      return DoPreparePrinting(pInfo);
}

/////////////////////////////////////////////////////////////////////////////
// OnBeginPrinting - called from OnFilePrint at the beginning of a print job.
/////////////////////////////////////////////////////////////////////////////
void CPrintableFormView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
{
   m_pOldBitmap = CreateMemoryDC(&m_pMemoryDC, &m_pbmMemory); // MM_LOMETRIC mapping mode is preset.
   if (NULL == m_pOldBitmap)
      return;

   const int knHorzSize = 10 * pDC->GetDeviceCaps(HORZSIZE); // MM_LOMETRIC (0.1 mm).
   const int knVertSize = 10 * pDC->GetDeviceCaps(VERTSIZE); // MM_LOMETRIC (0.1 mm).
   //TRACE("HORZSIZE = %d mm, VERTSIZE = %d mm\n", knHorzSize/10, knVertSize/10);

   SetMargins(200, 100, 200, 100); // MM_LOMETRIC (0.1 mm).

   const int knPrintWidth = knHorzSize - m_nMarginLeft - m_nMarginRight;
   const int knPrintHeight = knVertSize - m_nMarginTop - m_nMarginBottom;
   const int knMaxPage = (abs(m_rectClipBox.Width())/knPrintWidth + 1) *
                         (abs(m_rectClipBox.Height())/knPrintHeight + 1);
   //TRACE("Max Page = %d\n", knMaxPage);
   ASSERT(knPrintWidth > 0 && knPrintHeight > 0 && knMaxPage > 0);
   pInfo->SetMaxPage(knMaxPage);
}

/////////////////////////////////////////////////////////////////////////////
// OnEndPrinting - called from OnFilePrint after the form has been printed.
/////////////////////////////////////////////////////////////////////////////
void CPrintableFormView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
   DeleteMemoryDC(&m_pMemoryDC, &m_pbmMemory, m_pOldBitmap);
}

/////////////////////////////////////////////////////////////////////////////
// OnPrint - called from OnFilePrint to print a page of the form.
/////////////////////////////////////////////////////////////////////////////
void CPrintableFormView::OnPrint(CDC* pDC, CPrintInfo* pInfo)
{
   ASSERT(pDC != NULL);
   ASSERT(pInfo != NULL);
   ASSERT(m_pMemoryDC != NULL);

   const int knHorzSize = 10 * pDC->GetDeviceCaps(HORZSIZE); // MM_LOMETRIC (0.1 mm).
   const int knVertSize = 10 * pDC->GetDeviceCaps(VERTSIZE); // MM_LOMETRIC (0.1 mm).

   pDC->SetMapMode(MM_LOMETRIC);

   const int knPrintWidth = knHorzSize - m_nMarginLeft - m_nMarginRight;
   const int knPrintHeight = knVertSize - m_nMarginTop - m_nMarginBottom;
   const int knMaxPageX = (abs(m_rectClipBox.Width())/knPrintWidth + 1);
   const int knMaxPageY = (abs(m_rectClipBox.Height())/knPrintHeight + 1);

   ASSERT(knPrintWidth > 0 && knPrintHeight > 0);

   int x = m_nMarginLeft;
   int y = -m_nMarginTop;
   int nWidth = knPrintWidth;
   int nHeight = -knPrintHeight;
   int xSrc = ((pInfo->m_nCurPage-1) % knMaxPageX) * knPrintWidth;
   int ySrc = ((pInfo->m_nCurPage-1) / knMaxPageX) * knPrintHeight;
   ySrc = -ySrc;

   if (abs(m_rectClipBox.Width() - xSrc) < abs(nWidth))
      nWidth = m_rectClipBox.Width() - xSrc;
   if (abs(m_rectClipBox.Height() - ySrc) < abs(nHeight))
      nHeight = m_rectClipBox.Height() - ySrc;

   pDC->BitBlt(x, y, nWidth, nHeight, m_pMemoryDC, xSrc, ySrc, SRCCOPY);
}

/////////////////////////////////////////////////////////////////////////////
// CPrintableFormView diagnostics

#ifdef _DEBUG
void CPrintableFormView::AssertValid() const
{
      CFormView::AssertValid();
}

void CPrintableFormView::Dump(CDumpContext& dc) const
{
      CFormView::Dump(dc);
}
#endif

/////////////////////////////////////////////////////////////////////////////
// CPrintableFormView message handlers

/////////////////////////////////////////////////////////////////////////////
// OnRButtonDown - message handler for the WM_RBUTTONDOWN Windows message. Creates a pop-up menu with a print command.
/////////////////////////////////////////////////////////////////////////////
void CPrintableFormView::OnRButtonDown(UINT nFlags, CPoint point)
{
   CMenu menu;

   CString strMenuItemPrint;
   strMenuItemPrint.LoadString(YFX_IDS_MENUITEM_FILE_PRINT);

   if (menu.CreatePopupMenu())
   {
      menu.AppendMenu(MF_STRING | MF_ENABLED, ID_FILE_PRINT, strMenuItemPrint);

      CPoint pointClient = point;
      ClientToScreen(&pointClient);
      menu.TrackPopupMenu(TPM_CENTERALIGN | TPM_LEFTBUTTON, pointClient.x, pointClient.y, this, NULL);
   }

   CFormView::OnRButtonDown(nFlags, point);
}

0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: MCSA MCSE Windows Server 2012

This course teaches how to install and configure Windows Server 2012 R2.  It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

Tackle projects and never again get stuck behind a technical roadblock.
Join Now