先上代码:
systemclass.h
1 #pragma once 2 #include"graphicsclass.h" 3 const bool FULLSCREEN = true; 4 class systemclass 5 { 6 public: 7 systemclass(); 8 ~systemclass(); 9 bool Initialize(); 10 void Run(); 11 void Shutdown(); 12 private: 13 graphicsclass *m_graphics; 14 HWND m_hwnd; 15 bool InitializeWindow(int screenwidth=800, int screenheight=600); 16 static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 17 };
从这个类头文件里可以看到,这个类有:
- 3个公有方法:前面mian.cpp里都调用了它们
- 1个私有方法:这是用来初始化窗口的函数,在公有方法Initialize()里调用
- 1个静态私有方法:这是windows窗口的消息回掉函数,只是windows程序规定要有的,其实没有做任何事
- 2个数据成员,一个graphicsclass对象,一个窗口句柄
systemclass.cpp
1 #include "systemclass.h" 2 3 systemclass::systemclass() 4 { 5 } 6 7 systemclass::~systemclass() 8 { 9 } 10 bool systemclass::Initialize() 11 { 12 int screenwidth, screenheight; 13 screenheight = 0; 14 screenwidth = 0; 15 InitializeWindow(); 16 17 m_graphics = new graphicsclass; 18 19 if (!m_graphics) 20 { 21 return false; 22 } 23 bool result = m_graphics->Initialize(m_hwnd); 24 if (!result) 25 { 26 MessageBox(m_hwnd, L"graphics initialize failed!", 0, MB_OK); 27 } 28 29 return true; 30 } 31 void systemclass::Run() 32 { 33 MSG msg; 34 bool flag = true; 35 while (flag) 36 { 37 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 38 { 39 TranslateMessage(&msg); 40 DispatchMessage(&msg); 41 } 42 43 if (msg.message == WM_QUIT) 44 { 45 flag = false; 46 } 47 flag=m_graphics->Frame(); 48 } 49 } 50 void systemclass::Shutdown() 51 { 52 if (m_graphics) 53 { 54 m_graphics->Shutdown(); 55 delete m_graphics; 56 m_graphics = 0; 57 } 58 if (m_hwnd) 59 { 60 m_hwnd = 0; 61 } 62 } 63 bool systemclass::InitializeWindow(int screenwidth, int screenheight) 64 { 65 WNDCLASSEX wc; 66 67 int posX, posY; 68 posX = 0; 69 posY = 0; 70 int screenWidth = screenwidth; 71 int screenHeight = screenheight; 72 73 HINSTANCE hinstance = GetModuleHandle(NULL); 74 75 LPCWSTR applicationName = L"Engine"; 76 77 wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; 78 wc.lpfnWndProc = WndProc; 79 wc.cbClsExtra = 0; 80 wc.cbWndExtra = 0; 81 wc.hInstance = hinstance; 82 wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); 83 wc.hIconSm = wc.hIcon; 84 wc.hCursor = LoadCursor(NULL, IDC_ARROW); 85 wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); 86 wc.lpszMenuName = NULL; 87 wc.lpszClassName = applicationName; 88 wc.cbSize = sizeof(WNDCLASSEX); 89 90 RegisterClassEx(&wc); 91 if (FULLSCREEN==true) 92 { 93 screenWidth = GetSystemMetrics(SM_CXSCREEN); 94 screenHeight = GetSystemMetrics(SM_CYSCREEN); 95 } 96 97 m_hwnd = CreateWindowEx(WS_EX_APPWINDOW, applicationName, applicationName, 98 WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_POPUP, 99 posX, posY, screenWidth, screenHeight, NULL, NULL, hinstance, NULL); 100 101 ShowWindow(m_hwnd, SW_SHOW); 102 103 return true; 104 } 105 LRESULT CALLBACK systemclass::WndProc(HWND hwnd, UINT umessage, WPARAM wparam, LPARAM lparam) 106 { 107 switch (umessage) 108 { 109 case WM_DESTROY: 110 { 111 PostQuitMessage(0); 112 return 0; 113 } 114 case WM_CLOSE: 115 { 116 PostQuitMessage(0); 117 return 0; 118 } 119 default: 120 return DefWindowProc(hwnd, umessage, wparam, lparam); 121 } 122 return 0; 123 }
Public:
Initialize()函数:调用了InitializeWindow()函数,生成了graphicsclass对象,调用了graphics类的Initialize()方法
Run()函数:windows消息循环,循环里调用了graphics类的Frame()方法,只要该方法的返回值不为false就一直循环。这其实是经典windows窗口程序有的一部分,本来peekMessage()部分是很重要的一部分,但是在本程序中它并没有作用,如果读者还有疑问,可以参考windows窗口程序相关资料。这里只要知道它是不断循环调用graphics类的Frame()方法就好了。
Shutdown()函数:清理生成的graphicsclass对象。相当于是虚析构函数。
private:
InitialilzeWindow()函数:这是systemclass所做的比较实质性的工作,生成一个windows窗口,我们来看它的流程:
- 声明一个WNDCLASS数据结构wc,这是描述你要生成的窗口的数据结构
- 获取当前程序的实例句柄hinstance,它是程序的一个标识,在这个程序中使用它的地方不多,我就不详细介绍它了
- 填充wc数据结构,重要的部分有style:窗口风格;lpfnWndProc,消息回掉函数;hInstance,程序实例句柄;lpszClassName,窗口类名字;cbSize,wndclass数据结构的大小
- 注册窗口
- 调用windowsAPI:CreateWindowEx()创建窗口,获得一个窗口句柄
- 显示窗口
WndProc()函数:这是消息回掉函数,响应操作系统通知的消息,没有实质性作用
我们可以看到,systemclass主要工作就是创建一个窗口并添加消息循环,另外就是生成一个graphicsclass对象,调用graphicsclass对象的Initialize方法和Frame方法。 我们可以猜到,涉及到图形渲染的工作的部分还藏在graphicclass里。