Unable to implement DIB printing with GDI (MFC)
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 13 of 13

Thread: Unable to implement DIB printing with GDI (MFC)

Threaded View

  1. #1
    Join Date
    Jan 2012

    Exclamation Unable to implement DIB printing with GDI (MFC)

    MFC doc/view architecture, GDI drawing/printing. I have a DIB backbuffer I need to display and print.

    After the long and painful road I came to the conclusion than I need to use DIB created with CreateDIBSection (rather than DDB created with CreateCompatibleBitmap), and I have to blit it onto printer dc with StretchDIBits (rather than StretchBlt).

    But i'm not able to get this thing to work.

    Here is what I do:

    In my initialization routine, I setup the backbuffer, like this:

    PHP Code:
        // Prepare device context:

    CClientDC aDC(this);

    // Setup proper backbuffer:

    _pMemDc = new CDC;


    _bitmapInfo.bmiHeader.biSize sizeof(BITMAPINFOHEADER);
    _bitmapInfo.bmiHeader.biWidth _sizeBackBuffer.cx;
    _bitmapInfo.bmiHeader.biHeight = -_sizeBackBuffer.cy// top-down
    _bitmapInfo.bmiHeader.biPlanes 1;
    _bitmapInfo.bmiHeader.biBitCount 24// Maybe 32?
    _bitmapInfo.bmiHeader.biCompression BI_RGB;

    HANDLE hMemBitmap CreateDIBSection(aDC.GetSafeHdc(), &_bitmapInfoDIB_RGB_COLORS, (void**)&_pBitmapRawBits00);

    _hOldSelBitmap = (HBITMAP)_pMemDc->SelectObject(hMemBitmap); 
    Variables with underscores are (private) member variables, declared like this:

    PHP Code:
        CDC *_pMemDc// Backbuffer memory dc
    HBITMAP _hOldSelBitmap;

    BITMAPINFO _bitmapInfo// Backbuffer DIB (header-only)
    unsigned char *_pBitmapRawBits// Pointer to pixel data of DIB

    SIZE _sizeBackBuffer// Size of backbuffer, i.e. size of that DIB 
    Now below is what I do in my OnDraw override:

    Firstly I get the area to be drawn like this (simplified code):

    PHP Code:
        CRect rectClipBoxPlayground;

        if (
    rectClipBoxPlayground _printingParams.pPrintInfo->m_rectDraw;
    Then I calculate the corresponding rect coordinates in my backbuffer, which is usually (much) larger than the DC. Details of this calculation are irrelevant here, I just say that

    CRect rectClipBoxBackBuffer;

    represents the corresponding rect of backbuffer (in pixel coordinates of backbuffer).

    Then I draw onto my backbuffer, using the _pMemDc memory dc.

    And finally comes the part where I have troubles: blitting my DIB onto target dc (screen or printer). Here is what I do:

    PHP Code:
        // Copy back buffer to screen/printer dc:

    SetBrushOrgEx(pDC->GetSafeHdc(), 000);

        //BOOL bSuccess = pDC->StretchBlt(rectClipBoxPlayground.left, rectClipBoxPlayground.top, 
        //    rectClipBoxPlayground.Width(), rectClipBoxPlayground.Height(), 
        //    _pMemDc, rectClipBoxBackBuffer.left, rectClipBoxBackBuffer.top, 
        //    rectClipBoxBackBuffer.Width(), rectClipBoxBackBuffer.Height(), SRCCOPY);

    HBITMAP hMemBitmap = (HBITMAP)_pMemDc->SelectObject(_hOldSelBitmap);

    DWORD dwLines StretchDIBits(pDC->GetSafeHdc(), 
    rectClipBoxPlayground.leftrectClipBoxPlayground.toprectClipBoxPlayground.Width(), rectClipBoxPlayground.Height(), 
    rectClipBoxBackBuffer.leftrectClipBoxBackBuffer.toprectClipBoxBackBuffer.Width(), rectClipBoxBackBuffer.Height(), 
    _pBitmapRawBits, &_bitmapInfoDIB_RGB_COLORSSRCCOPY);

    The problem is, the commented-out code of StretchBlt works flawlessly (except printing on some printers), but I can't use it because some printers have troubles with it. So I have to use StretchDIBits. Note that I firstly unselect the DIB from its memory dc temporarily, so that it is not associated with any dc. Then I use StretchDIBits but things just don't work! Output is messed up, like I give incorrect coordinates, areas are drawn off-set from where they should be drawn, and sometimes totally black. So I must be missing something (maybe something very trivial). Help! I tried changing signs of rectClipBoxBackBuffer.top and bitmapInfo.bmiHeader.biHeight, the results change, but nothing works like it should.

    What am I doing wrong??
    Last edited by TX_; January 28th, 2012 at 01:15 PM. Reason: Formatting

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts

Azure Activities Information Page

Windows Mobile Development Center

Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


HTML5 Development Center