My project requires a continual loop.

In order to exit the loop I have set up a boolean variable that, when set, is used to exit the loop.

Problem is, the loop does not yield to other processes (ie being able to press the "Quit" button, which sets the boolean variable enabling a way to exit the loop).

VB has a DoEvents function which allows other processes to be carried out in a loop such as this.

Since C++ does not have DoEvents I used the following in it's place.
Code:
    while ( PeekMessage ( (LPMSG)&message, NULL, 0, 0, PM_REMOVE) )
    {
        DispatchMessage ((LPMSG)&message);
        TranslateMessage ((LPMSG)&message);
    }
    Sleep (0);

The following code compiles and runs, but crashes with the error

The instruction at "0x00000064" refrenced memort at "0x00000064". The memory could not be "read".

when the Quit button is depressed.

Can anyone spot the problem?



Code:
#define STRICT
#define WIN32_LEAN_AND_MEAN  

#include <windows.h>

#define IDB_BTN100   100
#define IDB_BTN200   200

const char g_szMainWindowClassName[] = "myMainWindowClass";
const char g_szChildWindowClassName[] = "myChildWindowClass";

LRESULT CALLBACK	MainWndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK	ChildWndProc(HWND, UINT, WPARAM, LPARAM);

HINSTANCE hInst;								

HWND hMain;
HWND hChild;
HWND hBtn100;
HWND hBtn200;

bool bQuit;


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine, int nCmdShow)
{

	WNDCLASSEX wcxM;	// for Main Window Class
    WNDCLASSEX wcxC;	// for Child Window Class
    
	MSG Msg;
	
	hInst = hInstance;	// Store instance handle in our global variable
    
	// Register the Main Window Class
		wcxM.cbSize        = sizeof(WNDCLASSEX);
		wcxM.style         = 0;
		wcxM.lpfnWndProc   = MainWndProc;
		wcxM.cbClsExtra    = 0;
		wcxM.cbWndExtra    = 0;
		wcxM.hInstance     = hInstance;
		wcxM.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
		wcxM.hCursor       = LoadCursor(NULL, IDC_ARROW);
		wcxM.hbrBackground = (HBRUSH)COLOR_APPWORKSPACE+1;
		wcxM.lpszMenuName  = NULL;
		wcxM.lpszClassName = g_szMainWindowClassName;
		wcxM.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

		if(!RegisterClassEx(&wcxM))
		{
			MessageBox(NULL, "Main Window Registration Failed!", "Error!",
				MB_ICONEXCLAMATION | MB_OK);
			return 0;
		}
	
    // Register the Child Window Class
		wcxC.cbSize			= sizeof(WNDCLASSEX); 
		wcxC.style			= CS_HREDRAW | CS_VREDRAW;
		wcxC.lpfnWndProc	= (WNDPROC)ChildWndProc;
		wcxC.cbClsExtra		= 0;
		wcxC.cbWndExtra		= 0;
		wcxC.hInstance		= hInstance;
		wcxC.hIcon			= NULL;
		wcxC.hCursor		= LoadCursor(NULL, IDC_ARROW);
		wcxC.hbrBackground	= (HBRUSH)COLOR_APPWORKSPACE+1;
		wcxC.lpszMenuName	= NULL;
		wcxC.lpszClassName	= g_szChildWindowClassName;
		wcxC.hIconSm		= NULL;
	
		if(!RegisterClassEx(&wcxC))
		{
			MessageBox(NULL, "Child Window Registration Failed!", "Error!",
				MB_ICONEXCLAMATION | MB_OK);
			return 0;
		}
 
	// Create the Main Window
		hMain = CreateWindowEx(
					NULL,                        
					g_szMainWindowClassName,
					"Graphics Test",
					WS_OVERLAPPEDWINDOW, // | WS_CLIPCHILDREN, 
					CW_USEDEFAULT, CW_USEDEFAULT, 622, 340,
					NULL, NULL, hInstance, NULL);

		if(hMain == NULL)
		{
			MessageBox(NULL, "Main Window Creation Failed!", "Error!",
				MB_ICONEXCLAMATION | MB_OK);
			return 0;
		}

	// Display the Main Window 
		ShowWindow(hMain, nCmdShow);
		UpdateWindow(hMain);

    // Create message loop
		while(GetMessage(&Msg, NULL, 0, 0) > 0)
		{
			TranslateMessage(&Msg);
			DispatchMessage(&Msg);
		}
		return static_cast<int>(Msg.wParam);
}


LRESULT CALLBACK MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

	switch (message) 
	{
		case WM_CREATE:
			//create the child window which will be the "graphic window"
			hChild = CreateWindowEx(WS_EX_CLIENTEDGE,g_szChildWindowClassName, NULL,
				WS_CHILD|WS_VISIBLE|WS_BORDER,
				15, 15, 285, 285, hWnd, NULL, hInst, NULL);
     		//create the push buttons
			hBtn100 = CreateWindow("button", "Run", WS_CHILD|WS_VISIBLE,
				320, 280, 137, 25, hWnd, (HMENU)100, hInst, NULL);
			hBtn200 = CreateWindow("button", "Quit", WS_CHILD|WS_VISIBLE,
				470, 280, 137, 25, hWnd, (HMENU)200, hInst, NULL);
			break;
		case WM_COMMAND:
			switch(wParam)
			{
				case IDB_BTN100: // Run button			
					MessageBox(NULL, "Run button", "Test", MB_OK);	
					do
					{
						// C++ equivalent to VB's DoEvents?
						while ( PeekMessage ( (LPMSG)&message, NULL, 0, 0, PM_REMOVE) )
						{
							DispatchMessage ((LPMSG)&message);
							TranslateMessage ((LPMSG)&message);
						}
					    Sleep (0);
					}
					while (bQuit == FALSE);				
					return 0;			
				case IDB_BTN200: // Quit button
					bQuit = TRUE;
					MessageBox(NULL, "Quit button", "Test", MB_OK);	
					return 0;
			}
			break;
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
	};
	return 0;
}


LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message) 
	{
		//case WM_PAINT:	
	          // break alone causes strange results
		//	break;
		case WM_MOUSEMOVE:
			break;
		case WM_LBUTTONUP:
			MessageBox(NULL, "Button pushed inside Pic Box", "Test", MB_OK);
			//InvalidateRect( hChild , NULL, TRUE );	
			break;			
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
	};
	return 0;
}