int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pScmdline, int iCmdshow) { SystemClass* System; bool result; // Create the system object. System = new SystemClass; if(!System) { return0; }
// Initialize and run the system object. result = System->Initialize(); if(result) { System->Run(); }
// Shutdown and release the system object. System->Shutdown(); delete System; System = 0;
return0; }
正如您所见,我们保持了 WinMain 函数的简单性。我们创建 SystemClass,然后初始化它。如果初始化没有问题,那么我们调用 SystemClass 的 Run 函数。
boolSystemClass::Initialize() { int screenWidth, screenHeight; bool result;
// Initialize the width and height of the screen to zero before sending the variables into the function. screenWidth = 0; screenHeight = 0;
// Initialize the windows api. InitializeWindows(screenWidth, screenHeight);
// Create the input object. This object will be used to handle reading the keyboard input from the user. m_Input = new InputClass; if(!m_Input) { returnfalse; }
// Initialize the input object. m_Input->Initialize();
// Create the graphics object. This object will handle rendering all the graphics for this application. m_Graphics = new GraphicsClass; if(!m_Graphics) { returnfalse; }
// Initialize the graphics object. result = m_Graphics->Initialize(screenWidth, screenHeight, m_hwnd); if(!result) { returnfalse; } returntrue; }
// Initialize the message structure. ZeroMemory(&msg, sizeof(MSG)); // Loop until there is a quit message from the window or the user. done = false; while(!done) { // Handle the windows messages. if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); }
// If windows signals to end the application then exit out. if(msg.message == WM_QUIT) { done = true; } else { // Otherwise do the frame processing. result = Frame(); if(!result) { done = true; } }
LRESULT CALLBACK SystemClass::MessageHandler(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam) { switch(umsg) { // Check if a key has been pressed on the keyboard. case WM_KEYDOWN: { // If a key is pressed send it to the input object so it can record that state. m_Input->KeyDown((unsignedint)wparam); return0; }
// Check if a key has been released on the keyboard. case WM_KEYUP: { // If a key is released then send it to the input object so it can unset the state for that key. m_Input->KeyUp((unsignedint)wparam); return0; }
// Any other messages send to the default message handler as our application won't make use of them. default: { returnDefWindowProc(hwnd, umsg, wparam, lparam); } } }
// Determine the resolution of the clients desktop screen. screenWidth = GetSystemMetrics(SM_CXSCREEN); screenHeight = GetSystemMetrics(SM_CYSCREEN);
// Setup the screen settings depending on whether it is running in full screen or in windowed mode. if(FULL_SCREEN) { // If full screen set the screen to maximum size of the users desktop and 32bit. memset(&dmScreenSettings, 0, sizeof(dmScreenSettings)); dmScreenSettings.dmSize = sizeof(dmScreenSettings); dmScreenSettings.dmPelsWidth = (unsignedlong)screenWidth; dmScreenSettings.dmPelsHeight = (unsignedlong)screenHeight; dmScreenSettings.dmBitsPerPel = 32; dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
// Change the display settings to full screen. ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN);
// Set the position of the window to the top left corner. posX = posY = 0; } else { // If windowed then set it to 800x600 resolution. screenWidth = 800; screenHeight = 600;
// Place the window in the middle of the screen. posX = (GetSystemMetrics(SM_CXSCREEN) - screenWidth) / 2; posY = (GetSystemMetrics(SM_CYSCREEN) - screenHeight) / 2; }
// Create the window with the screen settings and get the handle to it. m_hwnd = CreateWindowEx(WS_EX_APPWINDOW, m_applicationName, m_applicationName, WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_POPUP, posX, posY, screenWidth, screenHeight, NULL, NULL, m_hinstance, NULL);
// Bring the window up on the screen and set it as main focus. ShowWindow(m_hwnd, SW_SHOW); SetForegroundWindow(m_hwnd); SetFocus(m_hwnd);
LRESULT CALLBACK WndProc(HWND hwnd, UINT umessage, WPARAM wparam, LPARAM lparam) { switch(umessage) { // Check if the window is being destroyed. case WM_DESTROY: { PostQuitMessage(0); return0; }
// Check if the window is being closed. case WM_CLOSE: { PostQuitMessage(0); return0; }
// All other messages pass to the message handler in the system class. default: { return ApplicationHandle->MessageHandler(hwnd, umessage, wparam, lparam); } } }
Inputclass.h
为了保持教程的简单,我暂时使用 Windows 系统自带的消息输入系统,直到我完成 DirectInput 的教程(DirectInput 是更好的选择)。