Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 449
  • Last Modified:

How do i print a bitmap to my printer from my Formview

Hello, i have two big problems:
i'm using a derived formview class and i have lots of problems printing some basic stuff to paper.
I can print text easily, but the printing of bitmaps just never happens grrr whyyy?????
someone please help me on this.. it has destroyed my whole weekend now..
The other problem is i can't use the default print/print preview menu commands in my formviews. They are disabled.. Why?? And how do i enable them and get them to work?? thanks!

my code:

void CSD2View::OnPrint(CDC* pDC, CPrintInfo*)
{
      //The Following code scales the image based on printer resolution.
      pDC->SetMapMode(MM_ANISOTROPIC);
      pDC->SetWindowExt(m_pMemDC->GetDeviceCaps(LOGPIXELSX),m_pMemDC->GetDeviceCaps(LOGPIXELSY));
      pDC->SetViewportExt(pDC->GetDeviceCaps(LOGPIXELSX),pDC->GetDeviceCaps(LOGPIXELSY));
      //pDC->StretchBlt(0,0,m_rect.Width(),m_rect.Height(),m_pMemDC,0,0,m_rect.Width(),m_rect.Height(),SRCCOPY);
            CString test_address = "Romeinsestraat 810\r\nResearch park Haasrode\r\nB-3001 HEVERLEE\r\nBelgium";
            TEXTMETRIC tm;
            pDC->GetTextMetrics(&tm); //get the size of a text char.
            int YInterval = tm.tmHeight;
            CRect fig = CRect(50,250,600,1000);
            pDC->DrawText(test_address,fig,DT_LEFT);
            CBitmap bitmapResource;
            bitmapResource.LoadBitmap(MAKEINTRESOURCE(IDB_PRINTLOGO));
            BITMAP bmResource;
            bitmapResource.GetBitmap(&bmResource);
            
            CDC memClientDC;
            memClientDC.CreateCompatibleDC(pDC);
            CBitmap *pOldBitmapResource = (CBitmap *)memClientDC.SelectObject(bitmapResource);
            if (pOldBitmapResource == NULL)
            {
                  memClientDC.DeleteDC();
                  return ;
            }
            
            CDC memPrinterDC;
            memPrinterDC.CreateCompatibleDC(pDC);
            
            CBitmap bitmapPrinter;
            bitmapPrinter.CreateCompatibleBitmap(&memPrinterDC, bmResource.bmWidth, bmResource.bmHeight);
            CBitmap *pOldBitmapPrinter = (CBitmap *) memPrinterDC.SelectObject(bitmapPrinter);
            if (pOldBitmapPrinter == NULL)
            {
                  memClientDC.DeleteDC();
                  memPrinterDC.DeleteDC();
                  return ;
            }
            
            memPrinterDC.BitBlt(0,0,bmResource.bmWidth, bmResource.bmHeight, &memClientDC, 0,0, SRCCOPY);
            pDC->StretchBlt(0, 0, bmResource.bmWidth, bmResource.bmHeight, &memPrinterDC, 0, 0, bmResource.bmWidth, bmResource.bmHeight, SRCCOPY);
            
}

void CSD2View::OnBeginPrinting(CDC* pDC, CPrintInfo* /*pInfo*/)
{
      if (m_pMemDC->GetSafeHdc()) m_pMemDC->DeleteDC();
      m_pMemDC->CreateCompatibleDC(pDC);
      
      CClientDC dc(this);
      CRect rect;
      GetClientRect(rect);
      m_pMemDC->SetMapMode(MM_ANISOTROPIC);
      m_pMemDC->SetWindowExt(dc.GetDeviceCaps(LOGPIXELSX),dc.GetDeviceCaps(LOGPIXELSY));
      m_pMemDC->SetViewportExt(m_pMemDC->GetDeviceCaps(LOGPIXELSX),m_pMemDC->GetDeviceCaps(LOGPIXELSY));
      
      if (m_pBm->GetSafeHandle()) m_pBm->DeleteObject();
      m_pBm->CreateCompatibleBitmap(&dc,rect.Width(),rect.Height());
      m_pMemDC->SelectObject(m_pBm);
      dc.DPtoLP(rect); //Convert to Logical Coordinates
      m_rect = rect;   //Save Logical Coordinates
      m_pMemDC->BitBlt(0,0,rect.Width(),rect.Height(),&dc,0,0,SRCCOPY);
      //CFormView::OnBeginPrinting(pDC, pInfo);
}

For now i need to add this to get a printjob started (linked to a button)
void CSD2View::OnFilePrint()
{
      // get default print info
      CPrintInfo printInfo;
      //ADDED
      //printInfo.m_bPreview = TRUE;
      ASSERT(printInfo.m_pPD != NULL);    // must be set
      
      DoPreparePrinting(&printInfo);
      
      if (OnPreparePrinting(&printInfo))
      {
            // hDC must be set (did you remember to call DoPreparePrinting?)
            ASSERT(printInfo.m_pPD->m_pd.hDC != NULL);
            
            // gather file to print to if print-to-file selected
            CString strOutput;
            if (printInfo.m_pPD->m_pd.Flags & PD_PRINTTOFILE && !printInfo.m_bDocObject)
            {
                  // construct CFileDialog for browsing
                  CString strDef(MAKEINTRESOURCE(AFX_IDS_PRINTDEFAULTEXT));
                  CString strPrintDef(MAKEINTRESOURCE(AFX_IDS_PRINTDEFAULT));
                  CString strFilter(MAKEINTRESOURCE(AFX_IDS_PRINTFILTER));
                  CString strCaption(MAKEINTRESOURCE(AFX_IDS_PRINTCAPTION));
                  CFileDialog dlg(FALSE, strDef, strPrintDef,
                        OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, strFilter);
                  dlg.m_ofn.lpstrTitle = strCaption;
                  
                  if (dlg.DoModal() != IDOK)
                        return;
                  
                  // set output device to resulting path name
                  strOutput = dlg.GetPathName();
            }
            
            // set up document info and start the document printing process
            CString strTitle;
            CDocument* pDoc = GetDocument();
            GetParentFrame()->GetWindowText(strTitle);
            if (strTitle.GetLength() > 31)
                  strTitle.ReleaseBuffer(31);
            DOCINFO docInfo;
            memset(&docInfo, 0, sizeof(DOCINFO));
            docInfo.cbSize = sizeof(DOCINFO);
            docInfo.lpszDocName = strTitle;
            CString strPortName;
            int nFormatID;
            if (strOutput.IsEmpty())
            {
                  docInfo.lpszOutput = NULL;
                  strPortName = printInfo.m_pPD->GetPortName();
                  nFormatID = AFX_IDS_PRINTONPORT;
            }
            else
            {
                  docInfo.lpszOutput = strOutput;
                  nFormatID = AFX_IDS_PRINTTOFILE;
            }
            
            // setup the printing DC
            CDC dcPrint;
            OnBeginPrinting(&dcPrint, &printInfo);
            dcPrint.Attach(printInfo.m_pPD->m_pd.hDC);  // attach printer dc
            dcPrint.m_bPrinting = TRUE;
            // disable main window while printing & init printing status dialog
            AfxGetMainWnd()->EnableWindow(FALSE);
            
            // start document printing process
            if (!printInfo.m_bDocObject && 
                  dcPrint.StartDoc(&docInfo) == SP_ERROR)
            {
                  // enable main window before proceeding
                  AfxGetMainWnd()->EnableWindow(TRUE);
                  
                  // cleanup and show error message
                  OnEndPrinting(&dcPrint, &printInfo);
                  dcPrint.Detach();   // will be cleaned up by CPrintInfo destructor
                  AfxMessageBox(AFX_IDP_FAILED_TO_START_PRINT);
                  return;
            }
            
            BOOL bError = FALSE;
            printInfo.m_nCurPage = 1;
            OnPrepareDC(&dcPrint, &printInfo);
            // set up drawing rect to entire page (in logical coordinates)
            printInfo.m_rectDraw.SetRect(0, 0,
                  dcPrint.GetDeviceCaps(HORZRES),
                  dcPrint.GetDeviceCaps(VERTRES));
            dcPrint.DPtoLP(&printInfo.m_rectDraw);
            // page successfully started, so now render the page
            OnPrint(&dcPrint, &printInfo);
            // cleanup document printing process
            dcPrint.EndDoc();
            AfxGetMainWnd()->EnableWindow();    // enable main window
            OnEndPrinting(&dcPrint, &printInfo);    // clean up after printing
            dcPrint.Detach();   // will be cleaned up by CPrintInfo destructor
      }
}
0
Joeriw
Asked:
Joeriw
  • 5
  • 3
1 Solution
 
DanRollinsCommented:
You are not checking the return from
       bitmapResource.LoadBitmap(MAKEINTRESOURCE(IDB_PRINTLOGO));

That's the first thing to try.  The next thing to try is to remove all scaling logic, in case it is flawed (I did not check it)
-- Dan


0
 
JoeriwAuthor Commented:
it returns fine, it also previews fine, it just doesnt print. Anyhow i already solved in a very 'long' way the bitmap painting to a printer, if someone can just help me now on enabling those print menu commands in the File menu for a CFormView (yes, i've read they arent implemented in the cformview), i'll be glad to donate him 200pts
0
 
JoeriwAuthor Commented:
ps for those with same bitmap problem goto http://www.codeproject.com/printing/printingtricksandtips.asp?target=ddbtodib for help
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
DanRollinsCommented:
There is good info and code here:
     http://codeguru.earthweb.com/printing/print_preview.shtml

I recall finding printing difficult at first.  What I did was disect the simplest print-capable CView -- the CEditView class.  I noticed the print-related functions that the AppWizard placed in the view code, and I single-stepped through that code that takes place during printing.  It's not tremendously complicated, but not simple either.  The view needs to cooperate with the frame in some parts of the process.

The problem with printing a CFormView revolves around the difficulty of prining each of its controls.  Some controls are built for on-screen display and "printing to paper" simply makes no sense.  For example, a ComboBox -- there is no place to print all of the items in the drop-down list.  Or a CListView -- some stuff may be below the bottom or off to the right of the on-screen rectangle.

The final solution is to *not* print the form itself, but to print the information that the user wants and needs, in a custom report format.  Drawing the contents of the form itself is normally a waste of time.

-- Dan
0
 
JoeriwAuthor Commented:
i know that, i override the OnDraw with an OnPrint anyway. All i need is to let the user print from the menubar. And preview from it too. I could consider using a separate ID_ instead of ID_FILE_PRINT and invoke the procedure in the same way as i did for the "Print" button.
I will read through your links in the morning. Thanks, i hope i can solve them now.
And indeed, i underestimated the printing part too :)
0
 
JoeriwAuthor Commented:
i had 2 real problems here:
the first one i found the solution to myself (see above) and the second one still noone was able to answer, and i meanwhile have found an answer for that one too. I'd like thus a refund so i can use it as an extra for my current difficult problem of printing from win98 to a laserjet ( http://www.experts-exchange.com/Programming/Programming_Languages/Cplusplus/Q_20567923.html )
0
 
DanRollinsCommented:
For info on how to get a refund, see:
    http://www.apollois.com/EE/Help/Closing_Questions.htm#AnsMyOwnQues
0
 
JoeriwAuthor Commented:
i know Dan, i had to add the comment before i could get the refund. I hope you agree with my decision. Next month i'll start working for a bigger company, i'll try to get a subscription then :)
0
 
SpideyModCommented:
PAQ'd and all 200 points refunded.

SpideyMod
Community Support Moderator @Experts Exchange
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

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