《WINDOWS 游戏编程大师技巧》学习笔记--windows编程模型小结
“Windows编程就像去见牙科医生:虽然明明知道最自己是有益处的,可还是没人喜欢总是找牙医。”记得很早的时候,看了一下MFC,还根本不知道窗口啊,按钮啊,菜单啊,现在读这一章才看到的Windows的真面目了。
1. 传说中的“匈牙利符号表示法”,早有耳闻此法,但未曾一见啊,最是头痛的就属看帮助文档的,尤其是MSDN了,不过要想阅读Microsoft的一些代码,还真的懂此法呀。
* 匈牙利符号表示法前缀代码
前缀 | 数据类型(基础类型) |
c | Char字符 |
by | BYTE字节(无符号字符) |
n | Short短整数和整数(表示一个数) |
i | int整数 |
x,y | Short短整数(通常用于x和y坐标) |
cx,cy | short短整数(通常用于x和y的长度;c表示计数) |
b | BOOL(整数) |
w | UINT(无符号数)和WORD(无符号字) |
l | LONG(长整数) |
dw | DWORD(无符号长整数) |
fn | 函数指针 |
s | 字符串 |
sz,str | 以一个字节的0(空值)终止的字符串 |
lp | 32位指针 |
h | 编号(常用于表示Windows对象) |
msg | 消息 |
*变量的命名
变量的命名应用匈牙利符号表示法,变量可用上表中的前缀代码表示。另外,变量由一个或几个子名构成时,每一个子名都要大写字母开头。
例如: char *szFileName; // a null terminated string
int *lpiData; //a 32-bit pointer to a int
还有一点就是,全局变量以g_或g开头。
*函数命名
函数命名和变量命名规则相同,但是没有前缀。也就是说,只需要子名的第一个字母要大写。
而且函数名中使用下划线是非法的。例如,下面的函数名表示是无效的匈牙利符号表示法:
int Get_Pixel(int ix,int iy);
*类型和常量的命名
所有的类型和常量都是大写的字母,但名字中可以允许使用下划线。
*类的命名
所有c++的类必须使用大写的C为前缀。类名字的每一个子名的第一个字母要大写。
*参数的命名
函数的参数命名和标准变量命名约定相同。
2.怎样创建一个完全实用的Windows程序,也就是那个我们经常见面的那个窗口。你只需要下面几步:
1.创建一个Windows类。
2.创建一个事件句柄或WinProc。
3.用Windows注册Windows类。
4.用前面创建的Windows类创建一个窗口。
5.创建一个能够从事件句柄获得或向事件句柄传递Windows信息的主事件循环。
2.1 Windows类
“ Windows中的每一个窗口、控件、列表框、对话框和小部件等等实际上都是一个窗口。区别它们的就是定义它们的类。一个Windows类就是Windows能够操作的一个窗口类型的描述。”
“控制Windows类信息的数据结构有两个:WNDCLASS和WNDCLASSEX。WNDCLASS是比较古老的一个,可能不久将废弃,因此我们应当使用新的扩展版WNDCLASSEX。”
typedef struct _WNDCLASSEX { UNIT cbsize; UINT style; WNDPROC lpfnWndProc; int cbClsExtra; int cbWndExtra; HANDLE hInstance; HICON hIcon; HCURSON hCoursor; HBRUSH hbrBackground; LPCTSTR lpszMenuName; LPCTSTR lpszClassName; HICON hIconSm; }WNDCLASSEX;
创建一个这样的结构,然后就是填写里面所有的成员变量:WNDCLASSEX winclass;
2.2事件句柄
这里所说的句柄(exent handler)就是当事件发生时Windows从主事件循环调用的回调
函数。对于创建的任何一个Windows类,都有一个独立的事件句柄,我们称呼它为WinProc,当用户
和Windows运行任务时,你的窗口和/或其他的应用程序窗口产生事件和消息。所有的消息都进入一
个队列,而你的窗口的消息发送你的窗口专用队列中。然后主事件循环检索这些消息,并且将它们发
送到你的窗口的WinProc中来处理。
WinProc原型:
LRESULT CALLBACK WindowProc(
HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam );
2.3注册Windows类
Windows类已经定义并且存放在Windsclass中,必须将新的类通知Windows。该功能通过
RegisterClassEx()函数实现,使用一个指向新类定义的指针来实现。如下:
RegisterClassEx(&winclass);
2.4创建窗口
创建窗口使用CreateWindow()或CreateWindowEx()函数。
2.5主事件循环
while(TRUE)
{
// test if there is a message in queue, if so get it
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
// test if this is a quit
if (msg.message == WM_QUIT)
break;
// translate any accelerator keys
TranslateMessage(&msg);
// send the message to the window proc
DispatchMessage(&msg);
} // end if
// main game processing goes here
Game_Main();
} // end while