// For sake of clarity, we define these basic constants here. They will be
// when we create our application window.
const char *kClassName = "Hello";
const int	kWidth = 640; 
const int	kHeight = 480;

bool createWindow( LPSTR strTitle, HINSTANCE hInstance, HWND &hwnd, 
				   const char* strClassname, int Width, int Height);
LRESULT CALLBACK WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam );

// The WinMain the main entry point for a Win32 application. Here you are supposed
// to initialize your applicantion and implement your main application loop.
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
					 LPSTR lpCmdLine, int nCmdShow)
	HWND	hWindow;	// Here we keep our Window Handle
	MSG		msg;		// And here we keep the messages we get from the
						// message pipe

	// Now we attempt to create our application window
	if (!createWindow("Hello World!", hInstance, hWindow, kClassName, kWidth, kHeight) ) 
		// If we failed to do so, alert the user and finish the application
		MessageBox(NULL, "Error", "Failed to initialize the application", MB_OK);
		return -1;

	// Now that we have our application window, we start listening for messages
	// and processing them. This is our main application loop.
	while (GetMessage(&msg, NULL, 0, 0)) // Wait until we have a message to process.
										// When we have one, it will be stored inside
										// the 'msg' variable.
		if (!TranslateMessage(&msg))    // Translate keyboard messages
			DispatchMessage(&msg);		// Return control to Windows

	// When we leave the main loop, we are supposed to finish the application.
	return msg.wParam;

// This function creates our application window.
bool createWindow( LPSTR title, HINSTANCE hInstance, HWND &hWindow, 
				   const char* strClassname, int Width, int Height )
	// First we need a WNDCLASSEX structure to hold our initialization data

	// initialize the WNDCLASSEX structure.  Initially set all to zero.
	memset( &wcTestApp, 0, sizeof( WNDCLASSEX ) );
	// Now we fill in all data Win32 needs to create the window.

	// 1. The size of this struct
	wcTestApp.cbSize		= sizeof( WNDCLASSEX );
	// 2. The name of our Window Class
	wcTestApp.lpszClassName = strClassname;

	// 3. The name of our Window Procedure
	wcTestApp.lpfnWndProc	= WindowProc;

	// 4. The color of our window's background
	wcTestApp.hbrBackground	= (HBRUSH)GetStockObject(WHITE_BRUSH);

	// 5. Our application instance handle
	wcTestApp.hInstance		= hInstance;

	// 6. What will be default the cursor type for our window
	wcTestApp.hCursor		= LoadCursor( NULL, IDC_ARROW );

	// 7. The icon for this window
	wcTestApp.hIcon			= LoadIcon(NULL, IDI_APPLICATION);   

	// 8. The small (system) icon for this window
	wcTestApp.hIconSm		= LoadIcon(NULL, IDI_WINLOGO);

	// 9. The resource name of the pull down menu we want for this window
	wcTestApp.lpszMenuName	= NULL;

	// 10. What styles we want for this window			= CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;

	// Now we try to register this class.
	if (!RegisterClassEx(&wcTestApp))
		// If we fail, we alert the user and return false
		MessageBox(NULL, "Failed To Register The Window Class.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
		return false;

	// Now that the class is registered, create the window:
	hWindow = CreateWindowEx(WS_EX_CLIENTEDGE,				// Extended Window Style
							strClassname,					// Name of window class
							title,							// Title of window
							WS_MINIMIZEBOX|WS_VISIBLE,		// Window style
							(GetSystemMetrics(SM_CXSCREEN) / 2) - (Width / 2),
							(GetSystemMetrics(SM_CYSCREEN) / 2) - (Height / 2),
							Width,							// Width
							Height,							// Height
							NULL,							// Desktop is the parent window
							NULL,							// No menus
							hInstance,						// Handle of this instance of the program
							0);								// No additional arguments

	// Now that the window is created, we now need to show it
	ShowWindow(hWindow, SW_NORMAL);

	return true;

// The WindowProc function is an application-defined function that processes
// messages sent to a window. Windows will call this function every time there
// is a new message to be processed.
	switch (uMsg)					// What kind of message did we receive?
        case WM_CLOSE:				// Was it a WM_CLOSE message?
            DestroyWindow( hWnd );	// Destroy our application window
            PostQuitMessage(0);		// Post a quit message (this cause our main
									// loop to break)
            return 0;

		case WM_QUIT:
		case WM_DESTROY:
			PostQuitMessage(1) ;
			return 0;

	// The DefWindowProc function calls the default window procedure to provide 
	// default processing for any window messages that an application does not
	// process. This function ensures that every message is processed. 
	// DefWindowProc is called with the same parameters received by 
	// the window procedure. 
	return DefWindowProc(hWnd, uMsg, wParam, lParam);