Archived

This topic is now archived and is closed to further replies.

Problem with CreateDIBSection

This topic is 5500 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm currently trying to implement a simple back buffer using a DIBSection. The problem I'm having is that my call to CreateDIBSection is returning a 'handle is not valid' error. I've been looking at Seamus McNally's back buffer code as well as a few other code snippets that I've found through Google to see if I could spot what my problem is, but no luck. I'm well aware that the code could be structured and optimized far more than it is, but I've been struggling with this for a while now and decided that a K.I.S.S. approach would be more condusive to locating the error than a 'proper' implementation. My gut tells me it's an obvious error in my logic, but my tired eyes can't seem to locate it. Any help would be greatly appreciated. SysOp_1101 //MiniBuffer.h
      
Struct MiniBuffer {
public:
	virtual bool Init(HWND hwnd, int width, int height, int channels = 32);
	virtual ~MiniBuffer(void);
	HWND m_hwnd;
	HDC m_dc;
	HBITMAP m_bitmap;
	HBITMAP m_bitold;
	BITMAPINFOHEADER m_bmi;
	int m_width;
	int m_height;
	int m_channels;
	int m_stride;
	unsigned char* m_bytes;
private:
	virtual void Destroy(void);
};
  

//MiniBuffer.cpp

      
#include "StdAfx.h"

bool MiniBuffer::Init(HWND hwnd, int width, int height, int channels) {
	HDC temp_dc;
        DWORD  last_error;
	LPVOID error_msg;
	
	this->Destroy();
	temp_dc          = GetDC(hwnd);
	this->m_dc       = CreateCompatibleDC(temp_dc);

        ReleaseDC(hwnd, temp_dc);

	this->m_hwnd     = hwnd;
	this->m_width    = width;
	this->m_height   = height;
	this->m_channels = channels;
	this->m_stride   = (width * channels);
	//Account for padding bytes

	while((m_stride % 4) != 0) {
		++m_stride;
	}
	//Initialize our BITMAPINFOHEADER struct

	this->m_bmi.biSize = sizeof(BITMAPINFOHEADER);
	this->m_bmi.biCompression = BI_RGB;
	this->m_bmi.biPlanes = 1;
	this->m_bmi.biBitCount = (channels << 3);
	this->m_bmi.biHeight = -(height);
	this->m_bmi.biWidth = width;
		
	this->m_bitmap = CreateDIBSection(this->m_dc, (BITMAPINFO*)&this->m_bmi,
									  DIB_RGB_COLORS, (void**)&m_bytes, 0, 0);
	
	last_error = GetLastError();

	if(this->m_bitmap == NULL) {
		this->Destroy();
		FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
					  NULL, last_error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
					  (LPTSTR) &error_msg, 0, NULL);
		MessageBox(NULL, (char*)error_msg, "Error", MB_OK|MB_ICONINFORMATION );
		LocalFree(error_msg);
		return false;
	}
	
	this->m_bitold = (HBITMAP)SelectObject(this->m_dc, this->m_bitmap);
	return true;
}

MiniBuffer::~MiniBuffer(void) {
	this->Destroy();
}

void MiniBuffer::Destroy(void) {
	memset(&this->m_bmi, 0, sizeof(BITMAPINFOHEADER));
	
	if(this->m_bitold) {
		SelectObject(this->m_dc, this->m_bitold);
		DeleteDC(this->m_dc);
	}
	this->m_hwnd     = NULL;
	this->m_dc       = NULL;
        this->m_width    = 0;
	this->m_height   = 0;
	this->m_channels = 0;
	this->m_stride   = 0;
	this->m_bitmap   = NULL;
	this->m_bitold   = NULL;
	this->m_bytes    = 0;
}
      
[edited by - SysOp_1101 on November 21, 2002 6:34:36 PM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
what is the value of m_dc prior to the call? that''s the only handle being passed to the function, so that''s likely the culprit.

just fyi, your ...CreateCompatibleDC(GetDC(hwnd)) statement may cause problems "down the road", if it''s not the problem now, as you never ReleaseDC the HDC you got via the GetDC call. DCs are a scarce resource.

also, just my analness here, but using this-> for member variables is not KISS. you don''t need it and it adds clutter.

Share this post


Link to post
Share on other sites
quote:

what is the value of m_dc prior to the call? that''s the only handle being passed to the function, so that''s likely the culprit.



The value of m_dc is non NULL before the call to CreateDIBSection.

quote:

just fyi, your ...CreateCompatibleDC(GetDC(hwnd)) statement may cause problems "down the road"...



Quite correct, and I thank you for pointing out that error as it surely would have bit me in the rear sooner or later. Chalk it up to my doing code at 5:30am when I should have been sleeping.

quote:

also, just my analness here, but using this-> for member variables is not KISS. you don''t need it and it adds clutter.



Although it may not be good for for finalized code, it''s a lot easier to let intellisense remember the names of my struct members than to try and do it myself in the early hours of the morning (in that sense it is a K.I.S.S. approach for me at least).

Even after making the suggested changes, I still have the same problem. I appreciate the help so far however, and I''m still open to suggestions.

SysOp_1101

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
sorry, nothing else. i typically set every var in the struct and i''ve never tried to negate the height, although i don''t see why it wouldn''t work (you''re doing so to "flip" the image, i assume?). other than that your call looks just like mine normally do.

just for grins, have you tried sending in an HDC from CreateCompatibleDC(NULL) ?

about all else i can offer is code from an old C function i''ve been using w/o fail for years:

  
HBITMAP BitmapTo16DIB( HBITMAP hBitmap, HDC hDC, BITMAP *pBM16 )
{
BITMAPINFO bi;
BITMAP bmBMthis, bm16;
HBITMAP hbm16, holdBmpthis, holdMemBmp;
HDC hMemDC, hDCthis;
VOID *pbits16;

HBITMAP hRetBitmap = NULL;

if( !hBitmap ) return hRetBitmap;

GetObject(hBitmap, sizeof(BITMAP), &bmBMthis);

// create a memory DC inside which we will scan the bitmap contents

if( hDC ) {
hMemDC = CreateCompatibleDC(hDC);
} else {
hMemDC = CreateCompatibleDC(0);
}
if( !hMemDC ) return hRetBitmap;

// create a 16 bit-depth bitmap and select it into the memory DC

bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biWidth = bmBMthis.bmWidth;
bi.bmiHeader.biHeight = bmBMthis.bmHeight;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 16;
bi.bmiHeader.biCompression = BI_RGB; // (0) uncompressed format

bi.bmiHeader.biSizeImage = 0;
bi.bmiHeader.biXPelsPerMeter = 0;
bi.bmiHeader.biYPelsPerMeter = 0;
bi.bmiHeader.biClrUsed = 0;
bi.bmiHeader.biClrImportant = 0;

hbm16 = CreateDIBSection(hMemDC, &bi, DIB_RGB_COLORS, &pbits16, 0, 0);
//

// other stuff of no interest...

//

}

HTH

Share this post


Link to post
Share on other sites
Thanks for the reply. I finally got the problem solved, and as you suggested in your first reply it was indeed the HDC that was the root of the trouble. It turned out that the window manager class that I was working with was calling the Init function of the buffer class before the main window was visible (no visible window, no valid DC). I''m not sure why the DC wasn''t showing up as NULL when I checked it, but no matter, I''m just happy I got it working.

Once again thank you for the help, it was greatly appreciated.

SysOp_1101

Share this post


Link to post
Share on other sites