Windows游戏开发学习笔记之二
要编写Windows环境下运行的3D游戏,需要先了解基本的Windows应用程序编程思想。一个完整的Windows程序,主要需要完成以下工作:
1、创建一个Windows窗口类;
2、创建一个事件处理程序,即一个回调函数;
3、注册Windows窗口类;
4、用创建的Windows窗口类创建一个窗口;
5、创建一个能够向事件处理程序传递Windows信息的主事件循环。
下面的demo是《Windows游戏编程大师技巧》里的一个基本Windows程序。已经添加了详细的注释,这里就不在赘述。难点主要在Windows消息处理机制,下面这个博客对Windows消息编程有详细的讲解,个人觉得写得很好。
Windows消息编程:http://www.vckbase.com/index.php/wv/1593
一个基本Windows程序代码:
1 /******************************************* 2 * 文件名称:《Windows游戏编程大师》demo2_3 3 * 完成作者:JackyLiu 4 * 完成时间:2013.5.4 5 *******************************************/ 6 7 //头文件 8 #include <Windows.h> 9 #include <WindowsX.h> 10 #include <stdio.h> 11 #include <math.h> 12 13 //宏定义 14 #define WINDOWS_CLASS_NAME "WINCLASS1" 15 16 /** 17 * 函数功能:回调函数,即事件处理程序,当事件发生时,Windows从主事件循环中调用的回调函数 18 * @param HWND hwnd: 窗口句柄,只有当使用同一个窗口类建立多个窗口时才会用到 19 * UINT msg: WinProc处理的消息标识符 20 * WPARAM wparam: 进一步匹配或分类发送到msg参数中的消息 21 * LPARAM lparam: 同上 22 */ 23 LRESULT CALLBACK WindowProc(HWND hwnd, 24 UINT msg, WPARAM wparam, LPARAM lparam) 25 { 26 PAINTSTRUCT ps; //用于窗口重绘的结构体 27 HDC hdc; //图形设备环境句柄 28 29 switch(msg) 30 { 31 case WM_CREATE: 32 { 33 //在这里放置初始化代码 34 return 0; 35 }break; 36 case WM_PAINT: 37 { 38 hdc = BeginPaint(hwnd, &ps); //激活窗口的客户区 39 //在这里可以进行窗口重绘 40 EndPaint(hwnd, &ps); 41 return 0; 42 }break; 43 case WM_DESTROY: 44 { 45 PostQuitMessage(0); //发送终止应用程序的消息 46 return 0; 47 }break; 48 default: 49 break; 50 } 51 //缺省函数处理不关心的消息 52 return (DefWindowProc(hwnd, msg, wparam, lparam)); 53 } 54 55 /** 56 * 函数功能:WinMain函数,Windows程序的入口函数 57 */ 58 int WINAPI WinMain( HINSTANCE hinstance, 59 HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow) 60 { 61 WNDCLASSEX winclass; //定义Windows窗口类 62 HWND hwnd; //定义一般窗口句柄 63 MSG msg; //定义一般消息结构体 64 65 ///////////////设计窗口类/////////////// 66 winclass.cbSize = sizeof(WNDCLASSEX); //WNDCLASSEX结构体本身的大小 67 winclass.style = CS_DBLCLKS | CS_OWNDC //描述窗口一般属性的样式信息标志 68 | CS_HREDRAW | CS_VREDRAW; 69 winclass.lpfnWndProc = WindowProc; //指向事件处理程序的函数指针,即回调函数 70 winclass.cbClsExtra = 0; 71 winclass.cbWndExtra = 0; 72 winclass.hInstance = hinstance; //启动时传给WinMain()函数的hInstance 73 winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); //装载一个标准的应用程序图标 74 winclass.hCursor = LoadCursor(NULL, IDC_ARROW); //装载标准箭头的光标资源 75 winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); //获取Windows系统画刷句柄,用于绘制或刷新一个窗口 76 winclass.lpszMenuName = NULL; 77 winclass.lpszClassName = (WINDOWS_CLASS_NAME); 78 winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); //装载一个自定义最小应用程序图标 79 80 ///////////注册窗口类////////////// 81 if(!RegisterClassEx(&winclass)) 82 return 0; 83 84 ///////////创建窗口/////////////// 85 if(!(hwnd = CreateWindowEx(NULL, //扩展样式 86 WINDOWS_CLASS_NAME, //所创建窗口的基础类名 87 ("Your Basic Window"), //窗口标题的空值终止字符串 88 WS_OVERLAPPEDWINDOW | WS_VISIBLE, //窗口外观和行为的通用窗口标志 89 0,0, //窗口左上角位置的像素坐标 90 400,400, //窗口的宽度和高度 91 NULL, //指向父窗口的句柄 92 NULL, //指向附属于该窗口菜单的句柄 93 hinstance, //应用程序的实例 94 NULL))) //其他高级特性 95 return 0; 96 97 ///////////主事件循环///////////// 98 while(GetMessage(&msg, NULL, 0, 0)) //从应用程序线程消息队列中获取下一个消息 99 { 100 //虚拟加速键翻译 101 TranslateMessage(&msg); 102 103 //将消息回传给系统,由操作系统调用窗口过程函数对消息进行处理(将消息结构体MSG中的前四个参数作为一个参数传递给函数) 104 DispatchMessage(&msg); 105 } 106 107 return msg.wParam; 108 }
如果链接时出现无法解析GetMessage等符号的错误时,主要是缺少某些Windows库文件,如user32.lib、gdi32.lib。
运行结果:
当你心中只有一个目标时,全世界都会给你让路!Read more! Write more! Practise more!
新浪微博:liu_军