码迷,mamicode.com
首页 > Windows程序 > 详细

DirectX API 编程起步 #02 窗口的诞生

时间:2015-08-31 21:17:14      阅读:291      评论:0      收藏:0      [点我收藏+]

标签:

先用 windows API 制作一个窗口出来,以后我们用 DirectX API 渲染的东西就会显示在这里,控制台那黑白的画面肯定是没法用的。

每次的代码都会更新到Github 

 

首先贴出来目前为止的文件结构图,由上到下表示#include“XXXXX”关系

系统头文件的调用不包含在内

由于.h和.cpp都是对应出现的,我就不写的那么详细了

技术分享

Main.cpp 是调用 SoftwareClass 类的主函数。

 

那么我们从上往下开始吧。

Main.cpp

由于只用调用接下来的类成员函数就行,所以这个代码非常简单。

 1 ////////////////
 2 // Main.cpp //
 3 ////////////////
 4 #include"SoftwareClass.h"
 5 
 6 /*********************************
 7 这里是整个程序的入口函数
 8 WinMain
 9 仅适用于Win32编程
10 **********************************/
11 
12 int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR pScmdline,int nCmdshow)
13 {
14     //新建类指针
15     SoftwareClass *Software;
16     //new一个类出来
17     Software = new SoftwareClass;
18     //初始化、运行、结束该程序
19     if (Software->Initialize())
20     {
21         Software->Run();
22     }
23     Software->Shutdown();
24     //删除并清理类指针
25     delete Software;
26     Software = NULL;
27     return 0;
28 }

 

SoftwareClass

接下来就是重点的主要类SoftwareClass,它管理着这个程序的生杀大权,并调用InputClass(记录输入的类)和GraphicsClass(渲染图形的类)来完成更高级的操作。

 首先是他的header

SoftwareClass.h

 1 ////////////////////////
 2 // SoftwareClass.h //
 3 ///////////////////////
 4 
 5 /*******************************
 6 该类包含整个程序运行所需的功能
 7 ********************************/
 8 
 9 #ifndef _SOFTWARECLASS_H_
10 #define _SOFTWARECLASS_H_
11 
12 //////////////
13 // include //
14 //////////////
15 #include<Windows.h>
16 
17 //////////////////
18 // File include //
19 //////////////////
20 #include"InputClass.h"
21 #include"GraphicsClass.h"
22 
23 /////////////////////////
24 // Class Declaration //
25 /////////////////////////
26 class SoftwareClass
27 {
28 public:
29     //默认构造,复制,析构函数
30     SoftwareClass();
31     SoftwareClass(const SoftwareClass&);
32     ~SoftwareClass();
33 
34     bool Initialize();//初始化
35     void Shutdown();//关闭
36     void Run();//运行
37 
38     //主要消息处理函数
39     //系统级消息丢给另外的一个WndProc
40     //比如窗口的关闭等消息
41     LRESULT CALLBACK MessageHandler(HWND, UINT, WPARAM, LPARAM);
42 
43 //以下为私有成员函数
44 private:
45     bool Frame();
46     //创建窗口最重要的函数
47     void InitializeWindows(int&, int&);
48     void ShutdownWindows();
49 //以下为私有数据成员
50 private:
51     //创建窗口程序需要的参数,无需过度关心
52     LPCWSTR m_SoftwareName;
53     HINSTANCE m_hinstance;
54     HWND m_hwnd;
55 
56     //m_* 代表成员数据
57     InputClass *m_Input;
58     GraphicsClass *m_Graphics;
59 };
60 
61 ////////////////////////
62 // Static Function //
63 ///////////////////////
64 
65 //次要消息处理函数
66 //用于处理系统级消息
67 static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
68 
69 /////////////
70 // Global //
71 /////////////
72 
73 //用于消息处理函数的调用
74 //因为我们有两个
75 //所以需要这个静态变量指向该类
76 static SoftwareClass *SoftwareHandle = NULL;
77 
78 #endif

 

SoftwareClass.cpp

接着是他的.cpp

  1 ///////////////////////////
  2 // SoftwareClass.cpp //
  3 //////////////////////////
  4 #include "SoftwareClass.h"
  5 
  6 //////////////////////////////////////////////////////////
  7 SoftwareClass::SoftwareClass()
  8 {
  9     m_hinstance = NULL;
 10     m_hwnd = NULL;
 11     m_SoftwareName = NULL;
 12 
 13     m_Input = NULL;
 14 }
 15 SoftwareClass::SoftwareClass(const SoftwareClass &other)
 16 {
 17 }
 18 SoftwareClass::~SoftwareClass()
 19 {
 20 }
 21 //////////////////////////////////////////////////////////
 22 
 23 bool SoftwareClass::Initialize()
 24 {
 25     int screenWidth, screenHeight;
 26     bool result;
 27 
 28     screenHeight = 0;
 29     screenWidth = 0;
 30     InitializeWindows(screenWidth, screenHeight);
 31 
 32     //new一个输入处理类
 33     m_Input = new InputClass;
 34     if (!m_Input)
 35     {
 36         return false;
 37     }
 38     m_Input->Initialize();
 39 
 40     //new一个图形处理类
 41     m_Graphics = new GraphicsClass;
 42     if (!m_Graphics)
 43     {
 44         return false;
 45     }
 46 
 47     //由于图形类涉及到窗口的创建
 48     //容易失败
 49     //因此测试一下new是否成功
 50     result = m_Graphics->Initialize(screenWidth, screenHeight, m_hwnd);
 51     if (!result)
 52     {
 53         return false;
 54     }
 55 
 56     return true;
 57 }
 58 
 59 //先清除输入类和图形类
 60 //再关闭窗口程序
 61 void SoftwareClass::Shutdown()
 62 {
 63     if (m_Graphics)
 64     {
 65         m_Graphics->Shutdown();
 66         delete m_Graphics;
 67         m_Graphics = NULL;
 68     }
 69 
 70     if (m_Input)
 71     {
 72         delete    m_Input;
 73         m_Input = NULL;
 74     }
 75 
 76     ShutdownWindows();
 77 }
 78 
 79 //消息的翻译分配在此
 80 void SoftwareClass::Run()
 81 {
 82     MSG msg;
 83     bool done, result;
 84     done = false;
 85 
 86     ZeroMemory(&msg, sizeof(MSG));
 87 
 88     //程序的最主要循环
 89     //不停地渲染、输出画面
 90     while (!done)
 91     {
 92         //消息队列的查找
 93         if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
 94         {
 95             TranslateMessage(&msg);
 96             DispatchMessage(&msg);
 97         }
 98         
 99         //这说明PostQuitMessage被调用了
100         if (msg.message == WM_QUIT)
101         {
102             done = true;
103         }
104         else
105         {
106             result = Frame();
107             if (!result)
108             {
109                 done = true;
110             }
111         }
112     }
113 }
114 
115 LRESULT SoftwareClass::MessageHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
116 {
117     switch (msg)
118     {
119     case WM_KEYDOWN:
120         m_Input->KeyDown((unsigned int)wParam);
121 
122         //当ESC被按下时,退出程序
123         if (wParam == VK_ESCAPE)
124         {
125             PostQuitMessage(0);
126         }
127         return 0;
128     case WM_KEYUP:
129         m_Input->KeyUp((unsigned int)wParam);
130         return 0;
131     default:
132         return DefWindowProc(hwnd, msg, wParam, lParam);
133     }
134 }
135 
136 bool SoftwareClass::Frame()
137 {
138     bool result;
139 
140     result = m_Graphics->Frame();
141     if (!result)
142     {
143         return false;
144     }
145     return true;
146 }
147 
148 //窗口程序的创建,注册,显示
149 void SoftwareClass::InitializeWindows(int &screenWidth, int &screenHeight)
150 {
151     WNDCLASSEX wc = {};
152     DEVMODE dmScreenSettings;
153     int posX, posY;
154 
155     //赋值那个静态变量
156     //指向该类
157     SoftwareHandle = this;
158     //别管
159     m_hinstance = GetModuleHandle(NULL);
160     //由于Unicode的原因
161     //所有字符串要用 TEXT() 括起来
162     m_SoftwareName = TEXT("MyShabbyEngine");
163 
164     //填写对象wc的有关信息
165     wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
166     //该窗口的消息处理函数
167     wc.lpfnWndProc = WndProc;
168     //以下全部不用管
169     wc.cbClsExtra = 0;
170     wc.cbWndExtra = 0;
171     wc.hInstance = m_hinstance;
172     wc.hIcon = NULL;
173     wc.hIconSm = NULL;
174     wc.hCursor = NULL;
175     wc.lpszMenuName = NULL;
176     //设置程序窗口背景
177     wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
178     //类名,意义不明
179     wc.lpszClassName = m_SoftwareName;
180     //这步绝不能漏了
181     wc.cbSize = sizeof(WNDCLASSEX);
182 
183     //向系统注册该窗口
184     RegisterClassEx(&wc);
185 
186     //从系统得到显示的分辨率
187     screenWidth = GetSystemMetrics(SM_CXSCREEN);
188     screenHeight = GetSystemMetrics(SM_CYSCREEN);
189 
190     //如果GraphicsClass文件里设置为全屏
191     if (FULL_SCREEN)
192     {
193         memset(&dmScreenSettings, 0, sizeof(dmScreenSettings));
194         dmScreenSettings.dmSize = sizeof(dmScreenSettings);
195         dmScreenSettings.dmPelsWidth = (unsigned long)screenWidth;
196         dmScreenSettings.dmPelsHeight = (unsigned long)screenHeight;
197         dmScreenSettings.dmBitsPerPel = 32;
198         dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
199 
200         ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN);
201 
202         posX = posY = 0;
203     }
204     else
205     {
206         screenWidth = 800;
207         screenHeight = 600;
208 
209         posX = (GetSystemMetrics(SM_CXSCREEN) - screenWidth) / 2;
210         posY = (GetSystemMetrics(SM_CYSCREEN) - screenHeight) / 2;
211     }
212 
213     //在显示屏创建窗口
214     //无边框
215     m_hwnd = CreateWindowEx(WS_EX_APPWINDOW,
216         m_SoftwareName, m_SoftwareName,
217         WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_POPUP,
218         posX, posY, screenWidth, screenHeight,
219         NULL, NULL, m_hinstance, NULL);
220 
221     //将窗口显示出来
222     ShowWindow(m_hwnd, SW_SHOW);
223     SetFocus(m_hwnd);
224 
225     ShowCursor(false);
226 }
227 
228 void SoftwareClass::ShutdownWindows()
229 {
230     //显示鼠标指针
231     ShowCursor(true);
232 
233     if (FULL_SCREEN)
234     {
235         ChangeDisplaySettings(NULL, 0);
236     }
237 
238     DestroyWindow(m_hwnd);
239     m_hwnd = NULL;
240 
241     UnregisterClass(m_SoftwareName, m_hinstance);
242     m_hinstance = NULL;
243 
244     SoftwareHandle = NULL;
245 }
246 
247 LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
248 {
249     switch (Msg)
250     {
251     case WM_DESTROY:
252     case WM_CLOSE:
253         PostQuitMessage(0);
254         return 0;
255     default:
256         return SoftwareHandle->MessageHandler(hWnd, Msg, wParam, lParam);
257     }
258 }

 

InputClass

该类监控并记录哪些键被按下

InputClass.h

 1 ////////////////////
 2 // InputClass.h //
 3 ///////////////////
 4 
 5 /******************************
 6 该类包含记录输入按键的功能
 7 ******************************/
 8 
 9 #ifndef _INPUTCLASS_H_
10 #define _INPUTCLASS_H_
11 
12 /////////////////////////
13 // Class Declaration //
14 /////////////////////////
15 class InputClass
16 {
17 public:
18     //默认构造、复制、析构函数
19     InputClass();
20     ~InputClass();
21     InputClass(const InputClass&);
22     //初始化
23     void Initialize();
24     //当按键被按下或抬起时调用
25     void KeyDown(unsigned int);
26     void KeyUp(unsigned int);
27     //检测某键是否被按下
28     bool IsKeyDown(unsigned int);
29 private:
30     //储存哪些键被按下
31     //true表示正被按下
32     bool m_keys[256];
33 };
34 
35 #endif

Input.cpp

 1 ////////////////////
 2 // InputClass.cpp //
 3 ///////////////////
 4 #include "InputClass.h"
 5 
 6 InputClass::InputClass()
 7 {
 8 }
 9 InputClass::~InputClass()
10 {
11 }
12 InputClass::InputClass(const InputClass &other)
13 {
14 }
15 
16 //初始化按键表
17 void InputClass::Initialize()
18 {
19     int i;
20     for (i = 0; i < 256; i++)
21     {
22         m_keys[i] = false;
23     }
24 }
25 
26 void InputClass::KeyDown(unsigned int input)
27 {
28     //将该键设为true
29     m_keys[input] = true;
30 }
31 
32 void InputClass::KeyUp(unsigned int input)
33 {
34     //将该键设为false
35     m_keys[input] = false;
36 }
37 
38 bool InputClass::IsKeyDown(unsigned int key)
39 {
40     return m_keys[key];
41 }

 

GraphicsClass

最后是GraphicsClass,由于目前只做了窗口的显示,其实还并未涉及到任何 DirectX 的代码,所以这个类基本上是空的。

GraphicsClass.h

 1 /////////////////////////
 2 // GraphicsClass.h //
 3 ///////////////////////
 4 
 5 /***********************
 6 该类处理图像
 7 ********************/
 8 
 9 #ifndef _GRAPHICSCLASS_H_
10 #define _GRAPHICSCLASS_H_
11 
12 //////////////
13 // include //
14 //////////////
15 #include<Windows.h>
16 
17 /////////////
18 // Global //
19 /////////////
20 
21 //是否全屏显示
22 const bool FULL_SCREEN = false;
23 //是否垂直同步
24 const bool VSYNC_ENABLED = true;
25 //场景相关数据
26 const float SCREEN_DEPTH = 1000.0;
27 const float SCREEN_NEAR = 0.1f;
28 
29 /////////////////////////
30 // Class Declaration //
31 ////////////////////////
32 class GraphicsClass
33 {
34 public:
35     GraphicsClass();
36     GraphicsClass(const GraphicsClass&);
37     ~GraphicsClass();
38 
39     bool Initialize(int, int, HWND);
40     void Shutdown();
41     bool Frame();
42 private:
43     bool Render();
44 };
45 
46 #endif

 

GraphicsClass.cpp

 1 ///////////////////////////
 2 // GraphicsClass.cpp //
 3 //////////////////////////
 4 #include "GraphicsClass.h"
 5 
 6 
 7 
 8 GraphicsClass::GraphicsClass()
 9 {
10 }
11 
12 GraphicsClass::GraphicsClass(const GraphicsClass &other)
13 {
14 }
15 
16 
17 GraphicsClass::~GraphicsClass()
18 {
19 }
20 
21 bool GraphicsClass::Initialize(int screenWidth, int screenHeight, HWND hWnd)
22 {
23     return true;
24 }
25 
26 void GraphicsClass::Shutdown()
27 {
28 }
29 
30 bool GraphicsClass::Frame()
31 {
32     return true;
33 }
34 
35 bool GraphicsClass::Render()
36 {
37     return true;
38 }

 

 最后程序正确运行后,会在屏幕中间产生一个黑色的矩形,没有边框,也没有鼠标指针。按ESC可退出。

我知道。。。光贴代码屁用没有。。。。。日后补上注释

DirectX API 编程起步 #02 窗口的诞生

标签:

原文地址:http://www.cnblogs.com/makejeffer/p/4774006.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!