Which is better Double Buffering or assigning to a Static Control. I would like an example of double buffering or both.
This is my bitmap code.

#include <windows.h>
#include <tchar.h>
#include <stdlib.h>
#include <string.h>
#include "Menu.h"
#include "Icon.h"
 
 
 
LPCTSTR		ClsName = L"App";											// Class name
LPCTSTR		WndName = L"WindowsAPI";									// Window title
HWND        hwnd;														// Handle to our main window
 
 
 
////////////////////////////////////////////////////
 
LRESULT CALLBACK WndProcedure(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam);
 
 
////////////////////////////////////////////////////
 
 
				   INT WINAPI WinMain(HINSTANCE hInstance, 
				   HINSTANCE,
                   LPSTR lpCmdLine, 
				   int nCmdShow)
{
	MSG        Msg;														// Structure to hold messages for our WinProc
	WNDCLASSEX WndClsEx;												// Our WNDCLASSEX structure used to define a window
 
	// Define our window
	WndClsEx.cbSize			 = sizeof(WNDCLASSEX);									// The size in bytes of the structure
	WndClsEx.style			 = CS_HREDRAW | CS_VREDRAW;								// Style flags: CS_HREDRAW | CS_VREDRAW redraws the window on resize
	WndClsEx.lpfnWndProc	 = WndProcedure;										// Pointer to the windows procedure
	WndClsEx.cbClsExtra		 = 0;													// Extra bytes to allocate the window class structure
	WndClsEx.cbWndExtra		 = 0;													// Extra bytes to allocate the window instance structure
	WndClsEx.hIcon			 = LoadIcon(hInstance, (LPCTSTR)IDI_ICON);				// A handle to the window class's icon 
	WndClsEx.hCursor		 = LoadCursor(NULL, IDC_ARROW);							// A handle to the window class's cursor, this uses default
	WndClsEx.hbrBackground	 = (HBRUSH)GetStockObject(WHITE_BRUSH);					// A handle to the brush used to paint the background, we use white
	WndClsEx.lpszMenuName	 = MAKEINTRESOURCE(IDR_MAIN_MENU);						// We use the menu we created (IDR_MAIN_MENU)		
	WndClsEx.lpszClassName	 = ClsName;												// Class name
	WndClsEx.hInstance		 = hInstance;											// handle to the instance that contains the WinProc for the class
	WndClsEx.hIconSm		 = LoadIcon(WndClsEx.hInstance, (LPCTSTR)IDI_ICON);		// A handle to the window class's small icon 
	// If register class fails, exit with error message
 
	    if (!RegisterClassEx(&WndClsEx))
    {
        MessageBox(NULL,L"Call to RegisterClassEx failed!",L"Win32 Guided Tour",NULL);
 
        return 1;
    }
 
	// Create the window 
	hwnd = CreateWindowEx(0,
						  ClsName, WndName,								// Class name, Window title
						  WS_OVERLAPPEDWINDOW,							// Window style, WS_OVERLAPPEDWINDOW allows resizing
                          100, 100,										// x coord , y coord				
						  600, 500,										// Width, Height
						  NULL,											// Parent (if child)
						  NULL,											// hMenu
						  hInstance,									// Instance
						  NULL);										// Additional info not needed
 
 
 
	// Actually display the window
	ShowWindow(hwnd, nCmdShow);
	UpdateWindow(hwnd);
 
	// Decode and treat the messages
	while(GetMessage(&Msg, NULL, 0, 0))
	{
		TranslateMessage(&Msg);
		DispatchMessage(&Msg);
	}
 
	return Msg.wParam;
}
 
 
bool LoadAndBlitBitmap(HDC hWinDC, LPCWSTR szFileName, int x, int y)
{
	// Load the bitmap image file
	HBITMAP hBitmap;

	hBitmap = (HBITMAP)::LoadImage(NULL, szFileName, IMAGE_BITMAP, 0, 0,
		LR_LOADFROMFILE);
	// Verify that the image was loaded
	if (hBitmap == NULL) {
		::MessageBox(NULL, __T("LoadImage Failed"), __T("Error"), MB_OK);
		return false;
	}
 
	// Create a device context that is compatible with the window
	HDC hLocalDC;
	hLocalDC = ::CreateCompatibleDC(hWinDC);
	// Verify that the device context was created
	if (hLocalDC == NULL) {
		::MessageBox(NULL, __T("CreateCompatibleDC Failed"), __T("Error"), MB_OK);
		return false;
	}
 
	// Get the bitmap's parameters and verify the get
	BITMAP qBitmap;
	int iReturn = GetObject(reinterpret_cast<HGDIOBJ>(hBitmap), sizeof(BITMAP),
		reinterpret_cast<LPVOID>(&qBitmap));
	if (!iReturn) {
		::MessageBox(NULL, __T("GetObject Failed"), __T("Error"), MB_OK);
		return false;
	}
 
	// Select the loaded bitmap into the device context
	HBITMAP hOldBmp = (HBITMAP)::SelectObject(hLocalDC, hBitmap);
	if (hOldBmp == NULL) {
		::MessageBox(NULL, __T("SelectObject Failed"), __T("Error"), MB_OK);
		return false;
	}
 
	// Blit the dc which holds the bitmap onto the window's dc
	BOOL qRetBlit = ::BitBlt(hWinDC, x, y, qBitmap.bmWidth, qBitmap.bmHeight,
		hLocalDC, 0, 0, SRCCOPY);
	if (!qRetBlit) {
		::MessageBox(NULL, __T("Blit Failed"), __T("Error"), MB_OK);
		return false;
	}
 
	// Unitialize and deallocate resources
	::SelectObject(hLocalDC, hOldBmp);
	::DeleteDC(hLocalDC);
	::DeleteObject(hBitmap);
	return true;
}
 
////////////////////////////////////////////////////
 struct
{
    int x, y;
} pos = {0};
LRESULT CALLBACK WndProcedure(HWND hwnd,			// Handle to our main window
							  UINT Msg,				// Our message that needs to be processed
							  WPARAM wParam,		// Extra values of message (Mouse for example might have x and y coord values)
							  LPARAM lParam)		// Extra values of message (Mouse for example might have x and y coord values)
{
		PAINTSTRUCT ps;
    HDC hdc;
	
    switch(Msg)
	{
		case WM_DESTROY:								// If a close message is sent to the message loop
			PostQuitMessage(WM_QUIT);					// Exit
			break;
			case WM_KEYDOWN:
{
    switch (wParam) {
        case VK_LEFT:
        {
			pos.x--;
			InvalidateRect(hwnd, NULL, TRUE);
            break;
        }
		case VK_RIGHT:
			{
                    pos.x++;
                    InvalidateRect(hwnd, NULL, TRUE);
                    break;
			}
		case VK_UP:
			{
			pos.y--;
			InvalidateRect(hwnd, NULL, TRUE);
			break;
			}
		case VK_DOWN:
			{
				pos.y++;
				InvalidateRect(hwnd, NULL, TRUE);
				break;
			}
    }
    break;
}
			case WM_CLOSE:
    if (MessageBox(hwnd, L"Really quit?", L"My application", MB_YESNO|MB_ICONQUESTION) == IDYES)
    {
        DestroyWindow(hwnd);
    }
    // Else: User canceled. Do nothing.
    return 0;
	break;
				case WM_INITDIALOG:
		return TRUE;
			case WM_PAINT:
 
				{
 
 
    hdc = BeginPaint(hwnd, &ps);
 
 
 
LoadAndBlitBitmap(hdc, __T("Rocket.bmp"), 0, 0);
LoadAndBlitBitmap(hdc, __T("Rocket2.bmp"), pos.x, pos.y);
HPEN hPenOld;
 
// Draw a red line
HPEN hLinePen;
COLORREF qLineColor;
qLineColor = RGB(255, 0, 0);
hLinePen = CreatePen(PS_SOLID, 7, qLineColor);
hPenOld = (HPEN)SelectObject(hdc, hLinePen);
 
MoveToEx(hdc, 500, 100, NULL);
LineTo(hdc, 100, 250);
 
MoveToEx(hdc, 100, 100, NULL);
LineTo(hdc, 500, 250);
 
SelectObject(hdc, hPenOld);
DeleteObject(hLinePen);
    break;
				}
		// This message is sent when the user selects a command item from a menu,
		// when a control sends a message to its parent window, 
		// or when an accelerator keystroke is translated.
		case WM_COMMAND:
		{
			// Value of the low-order word of wParam. 
			// Specifies the identifier of the menu item, control, or accelerator. 
			switch(LOWORD(wParam))
			{
				case IDM_EXIT:
					if (MessageBox(hwnd, L"Really quit?", L"My application", MB_YESNO|MB_ICONQUESTION) == IDYES)
    {
        DestroyWindow(hwnd);
    }
    // Else: User canceled. Do nothing.
    return 0;
	break;
					case IDM_ABOUT:
			{
				::MessageBox(hwnd, _T("This is the start of a game") , _T("About"), MB_OK|MB_ICONASTERISK);
				break;
			}
			}
		}
		break;
 
		default:										// Handle all other messages in a normal way
			return DefWindowProc(hwnd, Msg, wParam, lParam);
	}
 
    return 0;
}

In the end I used double buffering. I added a

case WM_ERASEBKGND:
			{
				return 1;
				break;
			}

To the case section. I changed

InvalidateRect(hwnd, NULL, TRUE);

to

InvalidateRect(hwnd, NULL, FALSE);

and I added

RECT rcClient;
GetClientRect(hwnd,&rcClient);
 //Create a device context that is compatible with the window
HDC hMemDC;
hMemDC = ::CreateCompatibleDC(hdc);
// Verify that the device context was created
if (hMemDC == NULL) {
		::MessageBox(NULL, __T("CreateCompatibleDC Failed"), __T("Error"), MB_OK);
		return false;
	}
HBITMAP hBitmap = CreateCompatibleBitmap(hdc,rcClient.right, rcClient.bottom);
 int savedDC = SaveDC(hMemDC);

SelectObject(hMemDC,hBitmap);
LoadAndBlitBitmap(hMemDC, __T("Rocket.bmp"), 0, 0);
LoadAndBlitBitmap(hMemDC, __T("Rocket2.bmp"), pos.x, pos.y);;RestoreDC(hMemDC,savedDC);

DeleteObject(hBitmap);
DeleteObject(hMemDC);
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.