/* file: winmain.c Skeletel Win32 program Just the basics, no functionality Sets up for a maximum frame-rate, looping, game/multimedia style app. Quits on ESC or close. Comments make a few pseudocode suggestions for application calls to implement. license: public domain by Mike linkovich link@spacejack.org ------------------ To compile this app with MinGW (GCC) from the command prompt use: gcc winmain.c -o winmain.exe -mwindows or: g++ winmain.c -o winmain.exe -mwindows */ #define WIN32_LEAN_AND_MEAN #include /* * Globals */ /* * Windows required functions: */ /* * WndProc() * * App's Window message handler callback. Windows will * call this function if there is a message waiting to * be passed to your application. * * The system will only get the opportunity to pass * messages to your application when you call PeekMessage * (or GetMessage, which will *wait* for a message, so you * usually want to use PeekMessage). You should call * PeekMessage once every frame (see WinMain() function). * * One might describe the processing handled by WndProc() * as the "event-driven" part of your app, while the * WinMain() is the "real-time" part of your app. */ LRESULT CALLBACK WndProc( HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam ) { HDC hdc; PAINTSTRUCT ps; /* POINT mpos; */ /* Respond to message from Windows... */ switch( iMsg ) { /* case WM_CREATE: return 0; */ case WM_PAINT: hdc = BeginPaint( hWnd, &ps ); EndPaint( hWnd, &ps ); return 0; /* case WM_MOUSEMOVE: GetCursorPos( &mpos ); if( mpos.x != CENTREX || mpos.y != CENTREY ) { dx = mpos.x - CENTREX; // "infinite mouse" trick dy = mpos.y - CENTREY; hypotheticalScene->pan( dx, dy ); SetCursorPos( CENTREX, CENTREY ); } break; */ case WM_KEYDOWN: switch( LOWORD( wParam )) { case VK_ESCAPE: /* Pressing esc quits */ PostQuitMessage( 0 ); break; /* case MY_KEYS: hypotheticalScene->sendMessage(KEYDOWN...); */ } break; case WM_DESTROY: PostQuitMessage( 0 ); break; } return DefWindowProc( hWnd, iMsg, wParam, lParam ); } /* * WinMain() */ int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow ) { static char szAppName[] = "Win32 App"; HWND hWnd; MSG msg; WNDCLASSEX wndClass; BOOL bQuit = TRUE; unsigned long thisTick, prevTick, deltaT; /* Timers */ /* * Windows Class setup: * (nothing to do with C++ classes) */ wndClass.cbSize = sizeof( wndClass ); wndClass.style = CS_HREDRAW | CS_VREDRAW; wndClass.lpfnWndProc = WndProc; wndClass.cbClsExtra = 0; wndClass.cbWndExtra = 0; wndClass.hInstance = hInstance; wndClass.hIcon = LoadIcon( NULL, IDI_APPLICATION ); wndClass.hCursor = LoadCursor( NULL, IDC_ARROW ); wndClass.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH ); wndClass.lpszMenuName = NULL; wndClass.lpszClassName = szAppName; wndClass.hIconSm = LoadIcon( NULL, IDI_APPLICATION ); RegisterClassEx( &wndClass ); hWnd = CreateWindow( szAppName, "Win32 App", WS_OVERLAPPEDWINDOW, 0, 0, 512, 384, NULL, NULL, hInstance, NULL ); ShowWindow( hWnd, iCmdShow ); UpdateWindow( hWnd ); /* * Application Inits * (eg graphics API, sound API, etc.) here ... * ... */ bQuit = FALSE; /* If we get here, we assume we're ok. * Otherwise, use "goto quitNow" on critical init fail. * (goto?! yep, IMHO a valid method, unless you want * to use exception handling) */ /* * Message Loop */ prevTick = GetTickCount(); /* Main loop */ while( !bQuit ) { while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); if( msg.message == WM_QUIT ) bQuit = TRUE; } if( !bQuit ) { /* Do a frame! */ thisTick = GetTickCount(); /* crude timer */ deltaT = thisTick - prevTick; /* hypotheticalScene->update(deltaT); * hypotheticalScene->paint(); */ prevTick = thisTick; /* remember for next time around */ Sleep(100); /* <-- Remove this! Once you turn it into a * "real" app you will probably want max performance. * This just keeps this app (which does nothing) * from hogging the CPU. */ } } /* * Can "goto" to this point at any time, * should any of the Application Inits fail. */ quitNow: /* Free all resources allocated previous * to main loop, exit program */ return msg.wParam; }