Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7401725
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 29, 20262026-05-29T04:32:56+00:00 2026-05-29T04:32:56+00:00

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

  • 0

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:

// Prepare device context:

CClientDC aDC(this);
OnPrepareDC(&aDC);

// Setup proper backbuffer:

_pMemDc = new CDC;
_pMemDc->CreateCompatibleDC(&aDC);

memset(&_bitmapInfo, 0, sizeof(BITMAPINFO));

_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(), &_bitmapInfo, DIB_RGB_COLORS, (void**)&_pBitmapRawBits, 0, 0);

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

Variables with underscores are (private) member variables, declared like this:

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):

CRect rectClipBoxPlayground;

if (pDC->IsPrinting())
{
    rectClipBoxPlayground = _printingParams.pPrintInfo->m_rectDraw;
}
else
{
    pDC->GetClipBox(&rectClipBoxPlayground);
}

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:

// Copy back buffer to screen/printer dc:

pDC->SetStretchBltMode(HALFTONE);
SetBrushOrgEx(pDC->GetSafeHdc(), 0, 0, 0);

// BELOW COMMENTED CODE OF StretchBlt WORKS(!) INSTEAD OF StretchDIBits.
//
//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.left, rectClipBoxPlayground.top, rectClipBoxPlayground.Width(), rectClipBoxPlayground.Height(), 
    rectClipBoxBackBuffer.left, rectClipBoxBackBuffer.top, rectClipBoxBackBuffer.Width(), rectClipBoxBackBuffer.Height(), 
    _pBitmapRawBits, &_bitmapInfo, DIB_RGB_COLORS, SRCCOPY);

_pMemDc->SelectObject(hMemBitmap);

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??

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-29T04:32:58+00:00Added an answer on May 29, 2026 at 4:32 am

    Microsoft’s documentation about StretchDIBits is totally wrong. I found out that direction of Y axis has to be changed. Now following code works:

    // Copy back buffer to screen dc: 
    
    pDC->SetStretchBltMode(HALFTONE); 
    SetBrushOrgEx(pDC->GetSafeHdc(), 0, 0, 0); 
    
    HBITMAP hMemBitmap = (HBITMAP)_pMemDc->SelectObject(_hOldSelBitmap); 
    
    DWORD dwLines = StretchDIBits(pDC->GetSafeHdc(), 
        rectClipBoxPlayground.left, rectClipBoxPlayground.top, rectClipBoxPlayground.Width(), rectClipBoxPlayground.Height(),
        rectClipBoxBackBuffer.left, _sizeBackBuffer.cy - rectClipBoxBackBuffer.top - rectClipBoxBackBuffer.Height(), rectClipBoxBackBuffer.Width(), rectClipBoxBackBuffer.Height(),
        _pBitmapRawBits, &_bitmapInfo, DIB_RGB_COLORS, SRCCOPY); 
    
    _pMemDc->SelectObject(hMemBitmap);
    

    P.S.: Now it works for screen drawing and print preview, but fails for actual printing, which was my original problem discussed here: How to print DIB backbuffer on printer – GDI, MFC

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm using MFC's doc/view architecture to implement printing. I use double buffering, I draw
How do I persuade the MFC Doc/View architecture to let me simultaneously display two
MFC doc/view architecture, sdi (more precisely multiple top-level windows). In my view class, I
I'm drawing some graphics and text with GDI in my CScrollView. I need to
In a NON doc/view MFC application with office-like ribbon, with one CView, how do
I have a html-page loaded in a CDialog in an MFC application, using the
I have a multithreading MFC application. But I don't want to have hacky code
So I have this MFC dialog program I am working with. The dialogs are
I wrote a porgram with a few standard dialogs in an SDI (Doc/View enabled)
MFC CArray was Serialized and saved to a database. I need to read this

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.