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