I have a basic Windows interface and a graphical display (rendered using the
SetPixel () function).
SetPixel is an extremely inefficient way to render your display. If you need to manipulate pixels, a better method is to create a dib section (which gives you access to the pixel data) and BitBlt it to the window when required. This approach will be an order of magnitude faster than using SetPixel.
You create a dib-section with the CreateDIBSection function. The following sample creates a 32bpp bitmap WIDTH x HEIGHT (WIDTH and HEIGHT are assumed to be constants defined by you) and selects it into a memory device context:
Code:
BITMAPINFO bmp = { 0 };
DWORD* pBits = NULL;
HBITMAP hBmp = NULL;
HDC hdcMem = NULL;
bmp.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmp.bmiHeader.biWidth = WIDTH;
bmp.bmiHeader.biHeight = HEIGHT;
bmp.bmiHeader.biPlanes = 1;
bmp.bmiHeader.biBitCount = 32;
bmp.bmiHeader.biCompression = BI_RGB;
hBmp = CreateDIBSection(NULL, &bmp, DIB_RGB_COLORS, &pBits, NULL, 0);
hdcMem = CreateCompatibleDC(NULL);
SelectObject(hdcMem, hBmp);
Then you can manipulate pixels in the bitmap. This shows how to set a pixel at x,y to blue. You could create a macro to simplify pixel indexing.
Code:
pBits[(y * WIDTH) + x] = RGB(0, 0, 0xFF);
When you receive a WM_PAINT message, you need to blit the bitmap to the window:
Code:
case WM_PAINT:
{
PAINTSTRUCT ps = { 0 };
BeginPaint(hwnd, &ps);
BitBlt(ps.hdc, 0, 0, WIDTH, HEIGHT, hdcMem, 0, 0, SRCCOPY);
EndPaint(hwnd, &ps);
break;
}
When the window needs updating, for example, after you have manipulated the pixels in your WM_TIMER handler, you should let Windows know by calling InvalidateRect. This will cause Windows to post a WM_PAINT message.
Code:
InvalidateRect(hwnd, NULL, FALSE);