Click here to Skip to main content
11,630,144 members (80,494 online)
Click here to Skip to main content

Print Bitmaps without Doc/View Framework

, 6 Jul 2000 142.3K 2.2K 32
Rate this:
Please Sign up or sign in to vote.
How to print a user-drawn bitmap without relying on the Doc/View's functions.

Introduction

In this article, I demonstrate how to print a user-drawn bitmap without relying on the Doc/View's functions. After reading this, you’d see every step in manually getting a printer to work. Basically, we need to deal with a few things:

  1. Get a printer device context and calculate the total number of sheets to be printed before opening the printer dialog.
  2. Calculate the portion (dimension) of the bitmap to be sent to the printer to fit into one print sheet (paper page). Avoid printing distortion.

All the code segments are contained in a function (no parameter) under View.

CDC memDC;
CClientDC dc(this);
//...
memDC.CreateCompatibleDC( &dc );
CBitmap * bitmap = new CBitmap();
bitmap->CreateCompatibleBitmap(&dc,bmpWidth, bmpHeight);
CBitmap * pOldBitmap = (CBitmap *) memDC.SelectObject( bitmap );
if (pOldBitmap == NULL) // if bitmap is very big, better check this !
{
    memDC.DeleteDC();
    delete bitmap;
    AfxMessageBox("Not enough resource for the bitmap.....");
    return;
}
//draw bitmap here, or it can be done in 
//another function outside the View

The above code draws an ellipse. For more sophisticated drawings, it can be done elsewhere, as long as we have the pointer to the bitmap. One "unusual" thing is the check on pOldBitmap. One doesn’t see this very often. However, as the warning message says, it could happen when the Windows bottle is unable to hold the big picture.

Now we drive the printer to work. First get a printer DC from the default printer, and with this DC, collect some printer information. This is for calculating the actual pages to be printed and other parameters.

CDC prtDC;
if( AfxGetApp()->GetPrinterDeviceDefaults(&printInfo.m_pPD->m_pd) )
{
    HDC hDC = printInfo.m_pPD->m_pd.hDC;
    if (hDC == NULL)
        hDC = printInfo.m_pPD->CreatePrinterDC();
    if(hDC !=NULL)
    {
        prtDC.Attach(hDC);
        //Get paper size and resolution with prtDC;
        //...
    }
    else 
    {
        AfxMessageBox("Can not find printer. 
            Please check installed/default printers.");
        return;
    }
}

Now we calculate the total pages to be printed (refer to source code file for the parameters). This way, we can activate the page info radio buttons in printer dialog:

int total_pages = (bmpWidth * ratio_x + paper_width - 1 ) / paper_width;

Finally, we stuff the printer dialog, and pop it up:

CPrintDialog prtDlg(FALSE, PD_PAGENUMS);
prtDlg.m_pd.nMinPage = 1;
prtDlg.m_pd.nMaxPage = total_pages;
prtDlg.m_pd.nFromPage = 1;
prtDlg.m_pd.nToPage = total_pages;

if(prtDlg.DoModal() == IDOK )
{
    //...
}
else
    return;  //Cancel button pressed, don't forget this!

The following code segment is responsible for starting the print job, sending data to the printer, and ending the job when all is printed. Actual printer operation (the noise) is not started until StartPage method is called, which sends data for printing one sheet (paper) only. To print more pages, repeat calling this method. In using StretchBlt method, care is taken for the last page. Unlike other bitmap portions with default width corresponding to the paper width, we need to find its width and StretchBlt it to appropriate dimensions on the paper, instead of filling the whole paper width, the latter may cause distortion.

if(prtDC.StartDoc(&di) == -1)
{
    AfxMessageBox("Printing error occurred. Unable to find printer.");
    prtDC.Detach();
    prtDC.DeleteDC();
    return;
}

prtDC.SetMapMode(MM_TEXT);  // 1 : 1 mapping

int i = 0;
for(i = 0; i < total_pages; i++)
{
    prtDC.StartPage();  
    strPageNumber.Format("%d of %d", ++printed_pages, total_print_pages );
    if( i == (total_pages - 1) && total_pages > 1 ) //last page
    {
        int last_bmpWidth = bmpWidth - paper_width / ratio_x * i;
        prtDC.StretchBlt(0, 0, last_bmpWidth * ratio_x, bmpHeight* ratio_y,
            &memDC, paper_width * i / ratio_x, 0, 
            last_bmpWidth, bmpHeight, SRCCOPY);
    }
    else
        prtDC.StretchBlt(0, 0, paper_width, bmpHeight* ratio_y, &memDC, 
            paper_width * i / ratio_x, 0, 
            paper_width / ratio_x , bmpHeight, SRCCOPY);
    prtDC.TextOut(page_info_rect.left, page_info_rect.top, strPageNumber );

    prtDC.EndPage();
}

//clean up.

That’s it. One thing I omitted (for clarity) is printing the selected pages (returned by the dialog). Also, one can add a progress dialog which shows the printing pages and gives the user a Cancel button to stop the loop. This had been well covered by other authors. See, for example, Paul DiLasci’s article in MSJ(7/98).

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Weimin Chen
Technical Lead Telvent
Canada Canada
No Biography provided

You may also be interested in...

Comments and Discussions

 
News^_*MANY ERRPRS!!! [modified] Pin
songzd12-Oct-06 17:34
membersongzd12-Oct-06 17:34 
GeneralCancelling the entire print job Pin
conacher10-Feb-06 4:53
memberconacher10-Feb-06 4:53 
GeneralPrinting to file Pin
anup_zade6-Jul-05 4:49
memberanup_zade6-Jul-05 4:49 
QuestionPrinting in tile pages?? Pin
sudhirpatel20-Jan-05 19:00
membersudhirpatel20-Jan-05 19:00 
GeneralTotal Page Bug. Pin
promanx2521-Jul-03 1:54
memberpromanx2521-Jul-03 1:54 
QuestionPrinting a large BMP in one page --scaling??? Pin
fordge9-Jan-03 1:27
memberfordge9-Jan-03 1:27 
Generalhelp me Pin
Anonymous5-Nov-02 15:15
sussAnonymous5-Nov-02 15:15 
GeneralDoes not work on an HP 940c Pin
ScorpioMidget10-Oct-02 2:29
memberScorpioMidget10-Oct-02 2:29 
GeneralRe: Does not work on an HP 940c Pin
ScorpioMidget10-Oct-02 10:26
memberScorpioMidget10-Oct-02 10:26 
GeneralRe: Does not work on an HP 940c Pin
Smhulik5-May-03 11:17
sussSmhulik5-May-03 11:17 
GeneralRe: My project does not work on an HP Laserjet1200 Pin
ikoai7424-Nov-03 1:39
memberikoai7424-Nov-03 1:39 
GeneralBitMap Printing NOT OK if Static Link Pin
cts31-Jan-02 12:52
membercts31-Jan-02 12:52 
GeneralPrinting in Monochrome Pin
GaryS30-Jan-02 14:23
memberGaryS30-Jan-02 14:23 
QuestionPrinting a bitmap from a file? Pin
Shilantra23-Feb-01 5:26
memberShilantra23-Feb-01 5:26 
AnswerRe: Printing a bitmap from a file? Pin
ramakrishna.b15-Jun-01 19:27
memberramakrishna.b15-Jun-01 19:27 
AnswerRe: Printing a bitmap from a file? Pin
hj31230-Aug-01 22:14
memberhj31230-Aug-01 22:14 
AnswerRe: Printing a bitmap from a file? Pin
Neeraj Joshi27-Feb-02 22:45
memberNeeraj Joshi27-Feb-02 22:45 
AnswerRe: Printing a bitmap from a file? Pin
Heiko12-Apr-02 1:48
memberHeiko12-Apr-02 1:48 
AnswerRe: Printing a bitmap from a file? Pin
Cristian Plesea9-Jun-03 4:51
memberCristian Plesea9-Jun-03 4:51 
GeneralRe: Printing a bitmap from a file? Pin
Vinaya16-Mar-05 22:24
memberVinaya16-Mar-05 22:24 
GeneralBUG & FIX: Wont' work on Network Pin
Scott Lloyd13-Jan-01 14:48
memberScott Lloyd13-Jan-01 14:48 
GeneralRe: BUG & FIX: Wont' work on Network Pin
stephane padovani1-Oct-02 2:55
sussstephane padovani1-Oct-02 2:55 
GeneralRe: BUG & FIX: Wont' work on Network Pin
ScorpioMidget10-Oct-02 2:54
memberScorpioMidget10-Oct-02 2:54 
GeneralRe: BUG & FIX: Wont' work on Network Pin
ScorpioMidget10-Oct-02 10:26
memberScorpioMidget10-Oct-02 10:26 
GeneralJust what I was looking for Pin
kristof10-Dec-00 22:35
memberkristof10-Dec-00 22:35 
GeneralJust what I was looking for Pin
kristof10-Dec-00 22:21
memberkristof10-Dec-00 22:21 
GeneralCan't seem to print through LAN Pin
Bob Logan25-Sep-00 15:04
sussBob Logan25-Sep-00 15:04 
GeneralRe: Can't seem to print through LAN Pin
Anonymous1-Jul-03 10:58
sussAnonymous1-Jul-03 10:58 
GeneralRe: Can't seem to print through LAN Pin
Anonymous9-Jul-03 11:29
sussAnonymous9-Jul-03 11:29 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150723.1 | Last Updated 7 Jul 2000
Article Copyright 2000 by Weimin Chen
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid