ASE Home Page Products Download Purchase Support About ASE
ChartDirector General
Forum HomeForum Home   SearchSearch

Message ListMessage List     Post MessagePost Message

  Get a CBitmap/HBITMAP
Posted by Jonas Gauffin on Jan-23-2007 18:09
I'm making my own MFC control to display the images created by ChartDirector.
I'm having problems working with the bitmap returned from the library, all I get when drawing the bitmap is a blank picture.

I've tried saving the bitmap to a file to check what's going wrong, but I get a valid, but blank, bitmap file..

Nothing is wrong with the chart generation, it works fine with CChartViewer, it's my bitmap handling that is incorrect.

Here is my code to generate the HBITMAP.

//pChart is a wrapper class that I've made.
MemBlock m = pChart->CreateChart();
memcpy(&m_bmpInfoHeader, m.data+14, sizeof(BITMAPINFOHEADER));

CDC *cdc = GetDC();
m_hBitmap = CreateDIBitmap(
cdc->m_hDC,
&m_bmpInfoHeader,
CBM_INIT,
m.data + *(int *)(m.data + 10),
(const struct tagBITMAPINFO *)(m.data + 14),
DIB_RGB_COLORS);
ReleaseDC(cdc);
SaveBitmap("C:\\\\temp2.bmp", m_hBitmap);

And SaveBitmap:

FILE *pFile = fopen(filename, "wb");
if(pFile == NULL)
{
AfxMessageBox("Failed to create file");
return;
}

BITMAPFILEHEADER bmfh;
int nBitsOffset = sizeof(BITMAPFILEHEADER) + m_bmpInfoHeader.biSize;
LONG lImageSize = m_bmpInfoHeader.biSizeImage;
LONG lFileSize = nBitsOffset + lImageSize;
bmfh.bfType = 'B'+('M'<<8);
bmfh.bfOffBits = nBitsOffset;
bmfh.bfSize = lFileSize;
bmfh.bfReserved1 = bmfh.bfReserved2 = 0;
//Write the bitmap file header

BYTE* pDrawingSurfaceBits = 0;
HBITMAP hDrawingSurface;

CDC* pDC = GetDC();
hDrawingSurface = CreateDIBSection(
pDC->GetSafeHdc(),
(CONST BITMAPINFO*)&m_bmpInfoHeader,
DIB_RGB_COLORS,
(void**)&pDrawingSurfaceBits,
NULL,
0);

UINT nWrittenFileHeaderSize = fwrite(&bmfh, 1,
sizeof(BITMAPFILEHEADER), pFile);
//And then the bitmap info header
UINT nWrittenInfoHeaderSize = fwrite(&m_bmpInfoHeader,
1, sizeof(BITMAPINFOHEADER), pFile);
//Finally, write the image data itself
//-- the data represents our drawing
UINT nWrittenDIBDataSize =
fwrite(pDrawingSurfaceBits, 1, lImageSize, pFile);

fclose(pFile);
ReleaseDC(pDC);

  Re: Get a CBitmap/HBITMAP
Posted by Peter Kwan on Jan-24-2007 02:36
Hi Jonas,

I have not actually tried your code, so I am not sure what is the issue. One potential issue is may be you should not copy the m_bmpInfoHeader at all. I am not too sure, but I think the bitmap data is expected to follow the bitmap header. So if you just copy the header, where is the bitmap data?

There is in fact a standard sample code in ChartDirector that creates HBITMAP. It is in the "CChartViewer.cpp" in the "setChart" function. The code is:

CDC *cdc = GetDC();

//output chart as Device Indpendent Bitmap with file headers
MemBlock m = c->makeChart(Chart::BMP);

// MFC expects HBITMAP, so convert from DIB to HBITMAP.
HBITMAP chartBMP = CreateDIBitmap(
    cdc->m_hDC,
    (const struct tagBITMAPINFOHEADER *)(m.data + 14),
    CBM_INIT,
    m.data + *(int *)(m.data + 10),
    (const struct tagBITMAPINFO *)(m.data + 14),
    DIB_RGB_COLORS);

ReleaseDC(cdc);

The CChartViewer internally actually converts the DIB into HBITMAP in order to display it on screen, so the above code is sure to work.

Regards
Peter Kwan