?
Solved

C++ / MFC, rendering to a local CPaintDC and saving to file

Posted on 2015-01-05
1
Medium Priority
?
306 Views
Last Modified: 2015-02-09
So, as I said in an earlier post I've been trying to write some MFC C++ code to (1) create a CPaintDC, (2) render to it, and (3) save it to file as a BMP or DIB.  And I haven't been able to get this to work, surprisingly.

The code I've cobbled together from doc and samples is below, but for some reason it just outputs a black/null square.  (I should be drawing a green square.)

Can anyone see any problems with this code?

Thanks *very* much for any help.


void CMFCApplication_TestDIBDlg::OnBnClickedButton1()
{
    CPaintDC dc(this);
    CRect rc;
    GetClientRect(rc);
    dc.FillSolidRect(rc, 0x0000FF00);  // aarrggbb ; green

    HBITMAP m_hBmp;
    LPBYTE pBits;

    BITMAPINFO bmi;
    memset(&bmi, 0, sizeof(BITMAPINFO));
    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmi.bmiHeader.biWidth = rc.Width();
    bmi.bmiHeader.biHeight = -rc.Height(); // top-down
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biBitCount = 32;
    bmi.bmiHeader.biCompression = BI_RGB;

    m_hBmp = CreateDIBSection(dc, &bmi, DIB_RGB_COLORS, (void**)&pBits, NULL, NULL);

    CImage image;
    image.Attach(m_hBmp);
    image.Save(L"c:\\dum.bmp", Gdiplus::ImageFormatBMP);

    MessageBox(L"Done", L"debug", 0);
}

Open in new window

0
Comment
Question by:RonMexico
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
1 Comment
 
LVL 35

Accepted Solution

by:
sarabande earned 2000 total points
ID: 40535336
the main problem of your code above is that the BITMAPINFO is sized with 1 RGBQUAD element only:

typedef struct tagBITMAPINFO {
  BITMAPINFOHEADER bmiHeader;
  RGBQUAD          bmiColors[1];
} BITMAPINFO, *PBITMAPINFO;

Open in new window


the structure is a c struct and not c++. to support dynamical bitmap sizes you need to allocate additional memory such that the bmiColors array is properly sized:

size_t sizBmiColors = rc.Width()*-rc.Height();
BITMAPINFO * pbmi = (BITMAPINFO *) new char[sizeof(BITMAPINFOHEADER) + sizBmiColors];
memset(pbmi, 0, sizeof(BITMAPINFOHEADER) + sizBmiColors);
pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
...

Open in new window


Sara
0

Featured Post

NFR key for Veeam Backup for Microsoft Office 365

Veeam is happy to provide a free NFR license (for 1 year, up to 10 users). This license allows for the non‑production use of Veeam Backup for Microsoft Office 365 in your home lab without any feature limitations.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

When you upgrade from Windows 8 to 8.1 or to Windows 10 or if you are like me you are on the Insider Program you may find yourself with many 450MB recovery partitions.  With a traditional disk that may not be a problem but with relatively smaller SS…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
Windows 8 comes with a dramatically different user interface known as Metro. Notably missing from the new interface is a Start button and Start Menu. Many users do not like it, much preferring the interface of earlier versions — Windows 7, Windows X…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question