// include files
#include <windows.h>
#include <stdio.h>
#include <stdarg.h>
//Main Application instances
HINSTANCE g_hInst; //Global instance handle
HWND g_hWnd; //Global window handle
//Application window dimensions, type, class, and window name
#define WNDWIDTH 400
#define WNDHEIGHT 400
#define WNDTYPE WS_OVERLAPPEDWINDOW
const char g_szClass[] = "FrameClass";
const char g_szCaption[] ="FrameCaption";
//Main Application Prototypes
//Entry Point
int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev,
LPSTR szCmdLine, int nCmdShow);
// Function to display an error message
void AppError(BOOL Fatal, char *Text, ...);
// Message Procedure
long FAR PASCAL WindowProc(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam);
// Functions to register and unregister windows' classes
BOOL RegisterWindowClasses(HINSTANCE hInst);
BOOL UnregisterWindowClasses(HINSTANCE hInst);
// Function to create the application window
HWND CreateMainWindow(HINSTANCE hInst);
//Functions to init, shutdown, and handle per frame functions
BOOL DoInit();
BOOL DoShutdown();
BOOL DoPreFrame();
BOOL DoFrame();
BOOL DoPostFrame();
int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev,
LPSTR szCmdLine, int nCmdShow)
{
MSG Msg;
//save application instance
g_hInst = hInst;
//Register window classes - return on FALSE
if(RegisterWindowClasses(hInst)== FALSE)
return FALSE;
//Create window - return on FALSE
if((g_hWnd = CreateMainWindow(hInst)) == NULL)
return FALSE;
//Do application initialization - return on FALSE
if(DoInit() ==TRUE) {
//Enter the Message Pump
ZeroMemory(&Msg, sizeof(MSG));
while(Msg.message != WM_QUIT) {
//Handle Windows Messages (if any)
if(PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&Msg);
DispatchMessage(&Msg);
} else {
//do pre-frame processing, break on FALSE return Value
if(DoPreFrame() == FALSE)
break;
//Do pre-fram processing, breeak on a FALSE return value
if(DoFrame() == FALSE)
break;
//Do post - Frame processing, break on a FALSE reurn value
if(DoPostFrame() == FALSE)
break;
}
}
}
//Do shutdown function
DoShutdown();
// Unregister window
UnregisterWindowClasses(hInst);
return TRUE;
}
BOOL RegisterWindowClasses(HINSTANCE hInst)
{
WNDCLASSEX wcex;
//Create the window class here and register it
wcex.cbSize = sizeof(wcex);
wcex.style = CS_CLASSDC;
wcex.lpfnWndProc = WindowProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInst;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = NULL;
wcex.lpszMenuName = NULL;
wcex.lpszClassName = g_szClass;
wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wcex))
return FALSE;
return TRUE;
}
BOOL UnregisterWindowClasses(HINSTANCE hInst)
{
// unregister the window class
UnregisterClass(g_szClass, hInst);
return TRUE;
}
HWND CreateMainWindow(HINSTANCE hInst)
{
HWND hWnd;
// Create the main Window
hWnd = CreateWindow(g_szClass, g_szCaption,
WNDTYPE, 0, 0, WNDWIDTH, WNDHEIGHT,
NULL, NULL, hInst, NULL);
if(!hWnd)
return NULL;
//show and update the window
ShowWindow(hWnd, SW_NORMAL);
UpdateWindow(hWnd);
// Return the window handle
return hWnd;
}
void AppError(BOOL Fatal, char *Text, ...)
{
char CaptionText[12];
char ErrorText[2048];
va_list valist;
//Build the message box caption based on fatal flag
if(Fatal == FALSE)
strcpy(CaptionText, "Error");
else
strcpy(CaptionText, "Fatal Error");
//build variabl text buffer
va_start(valist, Text);
vsprintf(ErrorText, Text, valist);
va_end(valist);
//display the message box
MessageBox(NULL, ErrorText, CaptionText,
MB_OK | MB_ICONEXCLAMATION);
//post a quit message if error is fatal
if(Fatal == TRUE)
PostQuitMessage(0);
}
// the message procedure - empty except for the destroy message
long FAR PASCAL WindowProc(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam)
{
switch(uMsg) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
BOOL DoInit()
{
//preform application initialization functions here
//such as those that set up graphics, sound, etc.
// return the value of TRUE for sucess, FALSE otherwise.
return TRUE;
}
BOOL DoShutdown()
{
// preform application shutdown function here
// such as those that sgutdown graphics, sound, etc.
//return a value of TRUE for success, FALSE otherwise.
return TRUE;
}
BOOL DoPreFrame()
{
// preform pre-frame processing here, such as settign up a timer.
//return TRUE on success, FALSE otherwise.
return TRUE;
}
BOOL DoFrame()
{
// preform per frame processing here, such as rendering
// return TRUE for sucess, FALSE otherwise.
return TRUE;
}
BOOL DoPostFrame()
{
//preform post frame processing, such as time synching, etc
//return TRUE for success, FALSE for otherwise.
return TRUE;
}