GDI Back Buffer Tutorial
This tutorial shows how easy it is to set up a Back Buffer in which you can set the pixels by accessing a dword array.

This is a very simple two step process; first we'll create a 32bit DIB, then you need only Blt this onto the hDc.

Step 1
First you'll need to allocate the necessary memory for the DIB. In my code I redo this every time the window is resized, unfortunately this cerates flicker when the window is quite large. I believe this is not caused by the drawing of the DIB but rather by the allocating of the memory for it.
	One solution for this would be to allocate the maximum memory you'll need when your program first loads and then just use what you need as its resized.

As I said I used the first method here so thats the one I'll explain.

So, every time the window is resized the DIB is remade.
First the window dimensions are stored in rect

invoke GetClientRect, hWnd, addr rect

The the amount of memory that will be needed is calculated. There'll be Width*Height dwords needed for the pixels plus enough for the Bitmap Info Header

mov ecx, rect.right
mov eax, rect.bottom
xor edx, edx
mul ecx
shl eax, 2
add eax, sizeof(BITMAPINFOHEADER)
;The above code calculates ( rect.right * rect.bottom * 4 ) + sizeof(BITMAPINFOHEADER)

Then the memory allocated and the handles and pointers are stored

invoke GlobalAlloc, GMEM_MOVEABLE or GMEM_ZEROINIT, eax
mov hBuffer, eax
invoke GlobalLock, hBuffer
mov pBuffer, eax

The following fills the Bitmap Info Header with necessary information.

mov edx, pBuffer
mov (BITMAPINFOHEADER ptr [edx]).biSize, sizeof(BITMAPINFOHEADER)
mov eax, rect.right
mov (BITMAPINFOHEADER ptr [edx]).biWidth, eax
mov eax, rect.bottom
mov (BITMAPINFOHEADER ptr [edx]).biHeight, eax
mov (BITMAPINFOHEADER ptr [edx]).biPlanes, 1
mov (BITMAPINFOHEADER ptr [edx]).biBitCount, 32
mov (BITMAPINFOHEADER ptr [edx]).biCompression, BI_RGB
mov (BITMAPINFOHEADER ptr [edx]).biSizeImage, 0
mov (BITMAPINFOHEADER ptr [edx]).biXPelsPerMeter, 0
mov (BITMAPINFOHEADER ptr [edx]).biYPelsPerMeter, 0
mov (BITMAPINFOHEADER ptr [edx]).biClrUsed, 0
mov (BITMAPINFOHEADER ptr [edx]).biClrImportant, 0

Finally pBufferB is set as a pointer to the start of Bitmap Bits

mov eax, pBuffer
add eax, sizeof(BITMAPINFOHEADER)
mov pBufferB, eax

Now you have your own 32bit DIB

Step 2
This is even simpler, I used the following code when a WM_PAINT message is received to Blt the DIB onto the hDc

.if hBuffer
 invoke BeginPaint, hWnd, addr ps
	mov hDc, eax
	invoke SetDIBitsToDevice, hDc, \
		0, 0, rect.right, rect.bottom, \
		0, 0, 0, rect.bottom,\
		pBufferB, pBuffer, DIB_RGB_COLORS
	Invoke EndPaint, hWnd, addr ps
.endif

Side Note:
This is quite different to the method that I've seen used elsewhere on the net. Usually, a temporary DC is created, the DIB is selected (?) into it and a BitBlt is done to transfer it to the DC for your window.
I put the question mark there as I have no idea what actually happens when you select a DIB into a DC

Sample code:
invoke BeginPaint, hWnd, addr ps
	mov hDc, eax
	invoke CreateCompatibleDC, 0
	mov BufferDC, eax

	invoke SelectObject, BufferDC, hBuffer
	mov eax, DDt
	invoke BitBlt, hDc, 0, 0, rect.right, rect. bottom,\
		 BufferDC, 0, 0, SRCCOPY
	mov edx, hBmp

	invoke DeleteDC, BufferDC
	invoke DeleteObject, DDt
Invoke EndPaint, hWnd, addr ps

Is this method faster or slower?

Fractal
The rest of the code in the example is regarding the drawing of the fractal, I've included comments indicating the code related to the fractal so that it can be removed leaving you with a Back Buffer Shell program upon which to write your own program.

Good Luck

Zadkiel
Eóin O'Callaghan