Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

CreateDIBSection problem, bitmap bits respond to changes only once

Status
Not open for further replies.

smgarth

Programmer
Mar 12, 2004
20
US
when I create a DIB with CreateDIBSection, I only seem to be able to write to the bits once. I inserted calls to GdiFlush throughout the code but that doesn't seem to solve the problem. here is the test code:

Code:
#include <windows.h>

LRESULT 
WndProc(HWND, UINT, WPARAM, LPARAM);

struct dib
{
	dib(void)
	{
		init();
	}
	
	dib(int w, int h)
	{
		init();
		make(w, h);
	}	
	
	void
	init(void)
	{
		memset(&bmi, 0, sizeof(bmi));
		bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
		bmi.bmiHeader.biCompression = BI_RGB;
		bmi.bmiHeader.biPlanes = 1;
		compatible = GetDC(0);
		context = 0;
		width = height = 0;
		bits = 0;
		colors = 32;		
	}
	
	void
	clear(void)
	{
		if(context)
		{
			DeleteObject(SelectObject(context, 0));
			DeleteDC(context);
			context = 0;
		}		
		width = height = 0;
		bits = 0;
	}

	dib &
	make(int w, int h)
	{				
		clear();				
		bmi.bmiHeader.biWidth = w;
		bmi.bmiHeader.biHeight = -h;
		bmi.bmiHeader.biBitCount = colors;		
		HBITMAP bmp = CreateDIBSection(compatible, &bmi, DIB_RGB_COLORS, &bits, 0, 0);	
		if(bmp)
		{	
			context = CreateCompatibleDC(compatible);			
			SelectObject(context, bmp);	
			width = w;			
			height = h;
		} 		
		return *this;		
	}
	
	dib &
	make(void)
	{				
		return make(width, height);
	}	
	
	operator HDC () 
	{ 
		return context; 
	}
	
	~dib()
	{
		clear();
	}
	
	BITMAPINFO bmi;
	int colors;
	HDC context, compatible;
	void * bits;
	int width, height;
};


void
draw(HWND hwnd)
{	
	static dib bmp;	
	RECT rc;	
	int width, height;
	HDC hdc = GetDC(hwnd);
	GetClientRect(hwnd, &rc);
	width = rc.right - rc.left;	
	height = rc.bottom - rc.top;		
	if(bmp.width < width || bmp.height < height)
	{
		bmp.make(width, height);
	}	
	COLORREF * c = (COLORREF *)bmp.bits;
	GdiFlush();	
	for(int i = 0, max = width * height; i < max; ++i)
	{
		c[i] = RGB(i % 255, i % 255, i % 255);
	}	
	GdiFlush();	
	BitBlt(hdc, 0, 0, width, height, bmp, 0, 0, SRCCOPY);	
	GdiFlush();	
	ReleaseDC(hwnd, hdc);	
}

int
WINAPI
WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
{
	HWND hwnd;
	MSG msg; 
	WNDCLASS wc;
	memset(&wc, 0, sizeof(wc));
	wc.lpfnWndProc = (WNDPROC) WndProc; 
	wc.hInstance = instance; 
	wc.hIcon = LoadIcon((HINSTANCE) NULL, IDI_APPLICATION); 
	wc.hCursor = LoadCursor((HINSTANCE) NULL, IDC_ARROW); 
	wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 
	wc.lpszClassName = __FILE__; 
	if(!RegisterClass(&wc)) 
	{
		return 1; 
	}
	hwnd = CreateWindow(
		wc.lpszClassName, 
		"", 
		WS_OVERLAPPEDWINDOW, 
		CW_USEDEFAULT, CW_USEDEFAULT, 
		CW_USEDEFAULT, CW_USEDEFAULT, 
		(HWND)0, 
		(HMENU)0, 
		instance, 
		(LPVOID)0); 
	if(!hwnd) 
	{
		return 1;
	}
	ShowWindow(hwnd, SW_SHOW); 
	UpdateWindow(hwnd); 	
	draw(hwnd);		
	while(GetMessage(&msg, (HWND)0, 0, 0) > 0) 
	{ 
		TranslateMessage(&msg); 
		DispatchMessage(&msg); 
	}	 		
	DestroyWindow(hwnd);
	return msg.wParam;
}
   
LRESULT 
WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
	if(message == WM_CLOSE)
	{
		PostQuitMessage(0);
		return 0;
	}	
	else if(message == WM_ERASEBKGND)
	{
		return 1;
	}	
	else if(message == WM_PAINT)
	{
		draw(hwnd);
	}		
	return DefWindowProc(hwnd, message, wparam, lparam);
}

making the window larger than previous seems to update the bitmap, but that's because the dib is being resized (and recreated).

am I missing something here?
 
here is the code updated to fix a memory leak:

Code:
#include <windows.h>

LRESULT 
WndProc(HWND, UINT, WPARAM, LPARAM);

struct dib
{
	dib(void)
	{
		init();
	}
	
	dib(int w, int h)
	{
		init();
		make(w, h);
	}	
	
	void
	init(void)
	{
		memset(&bmi, 0, sizeof(bmi));
		bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
		bmi.bmiHeader.biCompression = BI_RGB;
		bmi.bmiHeader.biPlanes = 1;
		compatible = GetDC(0);
		context = 0;
		bmp = 0;
		width = height = 0;
		bits = 0;
		colors = 32;		
	}
	
	void
	clear(void)
	{
		if(context)
		{
			DeleteObject(bmp);
			DeleteDC(context);
			context = 0;
			bmp = 0;
		}		
		width = height = 0;
		bits = 0;
	}

	dib &
	make(int w, int h)
	{				
		clear();				
		bmi.bmiHeader.biWidth = w;
		bmi.bmiHeader.biHeight = -h;
		bmi.bmiHeader.biBitCount = colors;		
		bmp = CreateDIBSection(compatible, &bmi, DIB_RGB_COLORS, &bits, 0, 0);	
		if(bmp)
		{	
			context = CreateCompatibleDC(compatible);			
			SelectObject(context, bmp);	
			width = w;			
			height = h;
		} 		
		return *this;		
	}
	
	dib &
	make(void)
	{				
		return make(width, height);
	}	
	
	operator HDC () 
	{ 
		return context; 
	}
	
	~dib()
	{
		clear();
	}
	
	BITMAPINFO bmi;
	int colors;
	HDC context, compatible;
	HBITMAP bmp;
	void * bits;
	int width, height;
};

void
draw(HWND hwnd)
{			
	static dib bmp;
	RECT rc;	
	int width, height;
	HDC hdc = GetDC(hwnd);
	GetClientRect(hwnd, &rc);
	width = rc.right - rc.left;	
	height = rc.bottom - rc.top;		
	if(bmp.width < width || bmp.height < height)
	{
		bmp.make(width, height);
	}	
	COLORREF * c = (COLORREF *)bmp.bits;
	GdiFlush();	
	for(int i = 0, max = width * height; i < max; ++i)
	{
		c[i] = RGB(i % 255, i % 255, i % 255);
	}	
	GdiFlush();	
	BitBlt(hdc, 0, 0, width, height, bmp, 0, 0, SRCCOPY);	
	GdiFlush();	
	ReleaseDC(hwnd, hdc);	
}

int
WINAPI
WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
{
	HWND hwnd;
	MSG msg; 
	WNDCLASS wc;
	memset(&wc, 0, sizeof(wc));
	wc.lpfnWndProc = (WNDPROC) WndProc; 
	wc.hInstance = instance; 
	wc.hIcon = LoadIcon((HINSTANCE) NULL, IDI_APPLICATION); 
	wc.hCursor = LoadCursor((HINSTANCE) NULL, IDC_ARROW); 
	wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 
	wc.lpszClassName = __FILE__; 
	if(!RegisterClass(&wc)) 
	{
		return 1; 
	}
	hwnd = CreateWindow(
		wc.lpszClassName, 
		"", 
		WS_OVERLAPPEDWINDOW, 
		CW_USEDEFAULT, CW_USEDEFAULT, 
		CW_USEDEFAULT, CW_USEDEFAULT, 
		(HWND)0, 
		(HMENU)0, 
		instance, 
		(LPVOID)0); 
	if(!hwnd) 
	{
		return 1;
	}
	ShowWindow(hwnd, SW_SHOW); 
	UpdateWindow(hwnd); 	
	while(GetMessage(&msg, (HWND)0, 0, 0) > 0) 
	{ 
		TranslateMessage(&msg); 
		DispatchMessage(&msg); 
	}     		
	DestroyWindow(hwnd);
	return msg.wParam;
}
   
LRESULT 
WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
	if(message == WM_CLOSE)
	{
		PostQuitMessage(0);
		return 0;
	}	
	else if(message == WM_ERASEBKGND)
	{
		return 1;
	}	
	else if(message == WM_PAINT)
	{
		draw(hwnd);
	}		

	return DefWindowProc(hwnd, message, wparam, lparam);
}
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top