游戏开发基础:游戏开发基础(2)



第 2章 windows编程基础

节 引言
为了跟上潮流我们抛弃了已快被淘汰DOS操作系统所有讲解和例程都是基于微软Windows操作系统考虑到很多用户并没有Windows编程基础所以我们设置了这专门讲述、讨论Windows术语、概念部分以使这部分用户能较快地理解和掌握我们所讲述、讨论编程思想和编程思路方法部分中主要讲述是Windows中十分基本东西所以用户应根据自己情况有选择进行学习好!现在就让我们进入艰苦而又精彩有趣游戏编程的路吧!

第 2节 windows介绍
Windows应用可以采用面向过程实现思路方法也可以使用面向对象结构所有实现思路方法都集成了点击控制和弹出菜单能够运行特别为Windows编写应用
Windows是种基于图形界面多任务操作系统为这个环境开发(那些专门为Windows设计)有着相同外观和命令结构对用户来说这使得学习使用Windows应用变得容易了为了帮助开发Windows应用Windows提供了大量内建以方便地使用弹出菜单、滚动条、对话框、图标和其他些友好用户界面应该具有特性
   Windows运行应用以硬件无关方式来处理视频显示、键盘、鼠标、打印机、串行口以及系统时钟
最值得注意Windows特性就是其标准化图形用户界面界面使用图片或图标来代表磁盘驱动器、文件、子目录以及其它操作系统命令和动作用户界面也为员带来了好处例如你可以很方便地使用常见菜单和对话框内建所有菜单都具有相同风格键盘和鼠标接口是Windows而不是员在实现它
Windows多任务环境允许用户在同时刻运行多个应用或同个应用多个例子个应用可能处于激活状态激活应用是指它正接收用户输入个瞬间仅有能够被处理因此同时间也只能有个应用处于激活状态但是可以有任意个数并行运行任务
  

第 3节 windows基本概念
Windows消息和面向对象编程
   Windows实现了种仿OOP(面向对象编程)环境Windows下消息系统负责在多任务环境中分解信息从应用角度来看消息是有关发生事件通知用户可以通过按下或移动鼠标来产生这些事件也可以是通过改变窗口大小或选择个菜单项等这些事件也可以由应用本身产生Windows本身也能产生消息如“关闭Windows”消息Windows通过这个消息来通知所有应用Windows将被关闭
   内存管理
   在Windows系统中系统内存是最重要共享资源的当同时刻有多个应用在运行时为了不耗尽系统资源每个应用必须合作以共享内存同时当启动新和关闭老内存会变得碎片化通过移动内存中代码和数据块Windows能够使内存空闲空间连起来在Windows下也有可能超量使用内存例如应用可以比内存容量大Windows能够废弃当前不使用代码在以后需要时再从应用中将的读入内存Windows应用可以共享可执行文件中例程包含可共享例程文件称为动态链接库(DLL)Windows包括了运行时将DLL例程链入机制
硬件无关性
   Windows同时提供了硬件或设备无关性使你免于在生成时候不得不考虑所有可能使用显示器、打印机或输入设备在Windows下面每种硬件设备驱动只编写硬件无关性使编程对应用开发者来说更为简单应用和Windows而不是各种设备打交道
动态键接库
   动态键接库提供了更多Windows功能它们通过个有力而灵活图形用户界面增强了基本操作系统动态键接库包括些预定义它们可以在个应用被调入时和的键接(动态地)而不是在应用被创建时(静态地)动态键接库使用DLL后缀库将每员从重复开发诸如读取或格式化输出的类通用例程中解放出来员可以方便地构造它们自己库以包含更多功能比如改变字体或检验文本变为通用工具减少了冗余设计这是OOP个关键特性
Windows库是被动态地键接或者说键接器并不把拷贝到可执行文件中去相反运行时它产生对库自然这样做节约了内存不管有多少应用在运行在RAM中总是只有库份考贝而这个库可以被共享
Windows可执行文件格式
Windows具有种新可执行文件格式称为New Excutable格式它包括新型文件头能够保存有关DLL信息

第 4节 windows窗口
Windows窗口
   窗口看起来就是显示设备中个矩形区域外观和特定应用无关可是对于个应用来说窗口是屏幕上应用能够直接控制矩形区域应用能够创建并控制主窗口如大小和形状当用户启动个窗口就被创建了用户每次单击窗口应用作出响应关闭个窗口会使应用结束多窗口带给用户Windows多任务能力通过将屏幕分为区别窗口用户能够使用键盘或鼠标选择个并行运行应用以此对多任务环境中个特定进行输入Windows截取了用户输入并分配必要资源(例如微处理器)
Windows布局
   所有Windows应用都具有诸如边框、控制菜单、About对话框的类共同特征这些特征使得各个Windows应用非常类似
边框
Windows窗口被边框所包围边框由围出窗口线条组成对于新手而言边框看起来仅仅是为了将个应用屏幕视口和其它区别开但是对于熟练者边框有着区别作用例如如果将鼠标指针放在边框上并按下鼠标左键用户就可以改变窗口大小
标题条
应用名字显示在窗口顶部标题条中标题条总是在相关窗口顶部中央标题条非常有用它可以帮助你记住正在运行哪个应用活动应用标题条以区别于非活动应用颜色显示
控制图标
控制图标是每个窗口左上方小图片每个应用都使用它在控制图标上单击鼠标键会使Windows显示系统菜单


系统菜单
当用鼠标单击控制图标时就打开了控制菜单它提供了诸如RestoreMoveSizeMinimizeMaximize以及Close这样标准操作
最小化图标
每个Windows 95或Windows NT应用都在窗口右上角显示 3个图标最左边图标是段短下划线这就是最小化图标它可以使用被最小化
最大化图标
最大化图标是 3个图标中中间看起来象两个小窗口使用最大化图标可以使用应用占满整个屏幕如果选择了这个图标其它应用窗口都会被盖住
垂直滚动条
如果有必要应用可以显示个垂直滚动条垂直流动条显示在应用窗口右边在两端有两个方向相反箭头它还有个着色棒和个透明窗口块后者被用于显示当前显示内容和整个文档(着色棒)关系你可以用滚动条来选择显示哪般在任何个箭头上单击下会使显示内容移动单击向上箭头下方窗口块并拖动它会使屏幕输出快速更新到应用屏幕输出任意位置
水平滚动条
也可以显示个水平滚动条水平滚动条显示在窗口底部具有和垂直滚动条类似功能你用它来选择要显示哪些列般在任何个箭头上单击个会使显示内容移动单击向左箭头右边窗口块并拖动它会使屏幕输出快速更新到应用屏幕输出任意位置
菜单条
个可选择菜单条可以显示在标题条下方通过菜单条来选择菜单和子菜单这种选择可以通过用鼠标单击也可以用热键组合来实现热键组合经常是ALT和命令中带下划线字母组合比如File命令中“F”
用户区
通常用户区占据了窗口最大部分这是应用基本输出区域应当由应用来复杂管理用户区另外应用可以输出到用户区

第 5节 windows
窗口基本组件有助于介绍说明应用外观时候应用需要创建两个外观和表现都相似窗口WindowsPa就是个例子借助于同时运行Pa两个例子(或拷贝)Pa允许用户剪贴或拷贝图片部分然后信息就可以从个例子拷贝到另个例子Pa每个运行例子外观和表现都和其他相同这就需要每个例子创建自己外观和功能类似窗口
在这种情况下被创建外观和功能都很类似窗口被称为是属于同个窗口类但是你创建窗口可以有区别特征它们可以有区别大小区别位置区别颜色或区别标题也可以使用区别光标
每个被创建窗都基于个窗口类在用C语言开发撕于基于传统方式应用些窗口为在Windows应用进修注册应用可以注册属于自己窗口类为了能够使几个窗口在同个窗口类基础上创建Windows定义了些窗口特征如CreateWindows参数些定义窗口类结构当你注册个窗口类时候这个类可以被Windows下运行着任何所使用对于使用MFC应用来说多数注册工作已经由预定义对象完成了
具有相似外观和表现窗口可以被组合成个类以此来减少需要维护信息每个窗口类都有自己可共享类结构不需要复制不必要窗口类参数同时同类两个窗口使用相同以及相关例程这样可以节省时间和空间不存在代码复制

第 6节 windows中面向对象编程
在Windows下传统C吸收了些面向对象编程特性对象是种包含数据结构和对这些数据结构进行操作抽象数据类型而且对象接收会引起它们区别动作消息
比如个Windows图形对象是可以被作为个实体来操纵些数据集合对于用户它是可视界面部分特别地个对象意味这数据和数据功能菜单、标题条、控制块以及滚动条等都是图形对象例子部分描述些影响应用外观图形对象
图标
   图标是用来使用记住特定操作、想法或产品小图形对象比如个电子表格被最小化时可以显示个很小柱状图以提醒用户这个还在运行的中在柱状图上双击鼠标会使Windows激活这个应用图标是非常有力工具它很适合用来引起用户注意比如在发出警告或者是向用户提供选择时
光标
   光标是Windows用来跟踪指点设备运动图形符号这种图形符号可以改变形状以指明特定Windows操作比如当标准箭头光标变为沙漏光标时介绍说明Windows正在执行个命令需要暂停
编辑光标
   应用在窗口中显示编辑光标以告诉用户在哪儿输入编辑光标和其他屏幕符号显然区别它是闪烁多数时候鼠标输入和光标相连而键盘输入和编辑光标相连但是可以用鼠标来改变编辑光标输入点
消息框
   消息框是另类Windows图形对象消息框是种包含标题、图标和消息弹出式窗口图(?)是关闭Windows Notepad时出现个标准消息框
-------------------------------------------------------------------------
| |
------------------------------------------------------------------------
Windows对话框
   对话框和消息框相似地方在于它也是种弹出式窗口但是对话框主要用于接受用户输入而不仅仅是显示些输出对话框允许应用接受输入每次个域或是个框内容而不是每次图(?)显示了个典型Windows对话框对知框图形设计由Windows为你自动完成对话框布局通常用编译器中资源编辑器完成
-----------------------------------------------------------------------
| |
-----------------------------------------------------------------------
字体
   字体是种图形对象或资源它定义了完整集合字样这些都有个特定大小和风格可以使文本具有区别外观字样是种基本属性它定义了衬线和笔画宽度
位图
位图是种显示图片(按像素组织)存储于内存当应用需要快速显示图片时可以使用位图位图直接从内存中传送所以它比用重新画出图片要快得多位图有两个基本用途首先它可以在屏幕上显示图片其次位图也用于创建刷子刷子使你可以在屏幕上画出并填充对象
   使用位图有两个缺点首先和其尺寸有关位图会占据难以预估大量内存每个被显示像素都要在内存中占据相应空间在彩色显示器上显示个像素会比在单色显示器上占据更多内存在单色显示器上只需位(bit)就可以表示出像素状态可是在可以显示16种颜色彩色显示器上需要 4位才能表示个像素特征同样地随着显示设备分辨率增加位图对内存需求也增加了位图个缺点是它只包括静态图片比如如果用位图来代表辆汽车就没有办法来访问图片区别部分如轮踏、顶盖、窗等但是如果汽车是有系列基本绘图例程来生成应用就可以改变向这些例程传送数据从而改变图片区别部分例如应用可以修饰顶蓬线并把辆轿车变为敞蓬车
画笔
   当Windows在屏幕上显示个图形时它使用当前画笔信息画笔用于画出线条或轮廊画笔具有 3个基本特征:线宽、线型(虚线、短线、实线)以及颜色Windows永远保留着用于画白线和黑线画笔任何应用可以使用它你也可以创建自己画笔
刷子
   Windows用刷子来画出颜色并以预定义样式来填充个区域刷子至少有8×8个像素大小刷子有 3个基本特征:样式和颜色由于它们至少有8×8大小刷子被称作具有样式而不象画笔称为线型样式可以是纯颜色也可以是阴影线、斜线或其它用户自定义组合
第 7节 windows消息
Windows消息
   在Windows中应用并不直接写屏幕、处理硬件中断或直接对打印机输出相反应用使用合适Windows或者等待个适当消息被发出
   Windows消息系统负责在多任务环境中分派消息从应用角度来看消息可以看作是发生事件通知有些需要作出特定反应有些就不需要这些事件可能由用户产生比如按下了鼠标或移动了鼠标改变了窗口大小或者选择了个菜单同时这些事件也可能由应用本身所产生
   这个过程使你应用必须完全面向消息处理当接收到消息时应用必须能激活并决定正确动作完成这个动作的后回到等待状态
   通过检查消息格式和来源部分将更仔细地讨论消息系统
消息格式
   消息通知个应用发生了个事件从技术上来讲消息不仅仅是和应用相关而且是和应用特定窗口有关因此所有消息都被发往窗口
   在Windows下只有个消息系统-即系统消息队列但是每个正在Windows下运行应用都有它自己消息队列系统消息队列中每个消息最终都要被USER模块传送到应用消息队列中去应用消息队列中存储了所有窗口全部消息
   不管消息具有什么类型它们都有 4个参数:个窗口句柄个消息类型两个附加32位参数窗口消息中定义个参数是消息所关联窗口句柄
   在编写Windows应用时候经常使用句柄句柄是个唯数字它被用于标识许多类型对象如菜单、图标、画笔和刷子、内存分配、输出设备甚至窗口例子在Windows 95和Windows NT下面每个运行着拷贝叫做例子
   Windows 95和Windows NT允许你同时运行多个例子操作系统就有必要保持对这些例子追踪这是通过赋予每个运行例子个唯例子句柄来实现
   例子句柄通常被用作个内部维护着索引通过引用表中元素而不是实际内存地址Windows 95和Windows NT可以动态地调整所有资源而只需在此资源所对应表格位置中插入个新地址
   根据个应用多个例子被处理方式内存资源由Windows 95和Windows NT保存
   应用例子具有很重要作用应用例子定义了所需所有对象这包括Control控件、菜单、对话框以及更多新Windows类
   消息中第 2个参数是消息类型这是在Windows独有些头文件中定义标识符这些头文件可以通过WINDOWS.H来使用在Windows下每个消息由两个助记符开始跟着是下划线最后是个描述符
   最后两个参数提供了解释消息所需附加信息因此最后两个参数内容依赖于消息类型
产生消息
   消息传送概念使Windows能够实现多任务消息有 4个基本来源应用可以从用户那儿接受消息也可以是Windows本身应用本身或者是其它应用
   用户消息包括按键消息、鼠标移动、鼠标指点或单击、菜单选择、滚动条定位等应用必须花费大量时间来处理用户消息用户产生消息表明运行人希望改变应用表现方式
   无论何时如果状态发生改变将会有个消息被发往应用个例子是用户单击了应用图标表明他们想要将此应用变为活动应用在这种情况下Windows告诉应用主窗口被打开了大小和位置被改变了等等Windows产生消息可以被处理也可以被忽略这跟应用当前状态有关
相应消息
在传统面向过程C语言Windows应用对于遇到种消息它都有个相应过程来处理这消息区别窗口对相同消息会产生区别响应Windows把每个消息发送到应用区别窗口而区别窗口对相同消息会有区别解释不令应用需要区别过程来处理每种消息个窗口也应有区别过程来处理区别消息窗口过程集合了应用所有消息处理过程
消息循环
所有Windows应用个基本组成就是消息处理循环个C应用都在内部执行这个操作C应用包含了创建并化窗口过程随后是消息处理循环最后是结束应用所需些代码消息循环负责处理Windows发给主消息在这儿知道有了消息并且要求Windows将消息发送到合适窗口过程以供处理当消息被接受时窗口过程就执行希望动作



第 8节 windows
Windows向应用开发人员提供了数以百计这些例子包括DispatchMes-sagePostMessageRegisterWindowMessage以及SetActiveWindow对于使用基础类库C许多自动被运行
在16位Windows 3.x下声明包括个pascal修饰符这在DOS下更为有效Windows95和Windows NT下32位应用不再使用这个修饰符如你所知所有Windows参数是通过系统来传递参数从最右边参数开始向左压入栈这是标准C方式在从返回的前过程必须按原来压入栈字节数调整栈指针

第 9节 windows应用框架
Windows头文件:WINDOWS.H
WINDOWS.H头文件(以及其它相关文件)是所有内在部分传统上WINDOWS.H是所有C语言编写Windows应用必需部分当在C中使用基础类库时WINDOWS.H包括在AFXWIN.H头文件中
Windows应用组成
   在开发Windows应用过程中有些重要步骤:
   *用C语言编写WinMain和相关窗口或者在C中使用基础类比如CWinApp等
*创建菜单、对话框和其它资源并把它们放入资源描述文件
*(可选)使用Vinsual C编译器中企业编辑器来创建对话框
*(可选)使用Vinsual C编译器中企业编辑器来创建对话框
*用项目文件来编译并链接所有C/C和资源文件
Windows应用组成部分

1. WinMain
Windows 95和Windows NT需要个WinMain这是应用开始执行和结束地方
从Windows向WinMain传递 4个参数下面代码段演示了这些参数使用:
WINAPI WinMain(HINSTANCE hInst HINSTANCE hPreInst
LPSTR 1pszCmdLine nCmdShow)
个参数hInst包含了应用例子句柄当应用在Windows下运行时这个数字唯标识了应用
第 2个参数hPreInst将始终是个NULL值表明没有这个应用其它例子正在运行在Windows 95和Windows NT下每个应用都在它自己单独地址空间中运行
第 3个参数1pszCmdLine是指向个以\'/0\'结尾长指针这个串代表了应用命令行参数
WinMain第 4个参数是nCmdShow在nCmdShow中存储整数代表了Windows预定义许多常量中它决定了窗口显示方式

2. WNDCLASS
WinMain负责注册应用主窗口类每个窗口类都建立在些用户选择风格、字体、标题字、图标、大小、位置等基础上窗口类实际上是定义这些属性个模板
   基本上所有Windows类定义都使用相同标准C/C结构下面例子是个介绍说明WNDCLASSW结构typedef语句WNDCLASS是从这儿继承:
typedef struct tagWNDCLASSW
UINT style;
WNDPROC 1pfnWndProc;
cbClsExtra;
cbWndExtra;
HANDLE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBR8USH hbrBackground;
LPCWSTR 1pszMenuName;
LPCWSTR 1pszClassName;
WNDCLASSW*PWNDCLASSWNEAR*NPWNDCLASSW FAR*LPWNDCLASSW;
下面部分讨论了WNDCLASS结构中区别其中有些域可以被赋予NULL告诉Windows使用缺省预定义值
style:style域指明了类风格
   1pfnWndProc:接受个指向窗口指针它将执行所有窗口任务
   cbClsExtra:指定了必须在窗口类结构后面分配字节数它可以是NULL
   cbWndExtra:指定了必须在窗口例子后面分配字节数它可以是NULL
   hInstance:定义了注册窗口类应用例子它必须是个例子句柄不得是NULL
   hIconhIcon:划定利用窗口最小化时显示图标它可以是NULL
   hCursorhCursor:定义了应用使用光标这个句柄可以是NULL
hbrBackground:提供了背景刷子标识符
1pszMenuName:是指向个以空结尾指针这个串是菜单资源名项可以为NULL
1pszClassName:是指向个以空结尾指针这个串是窗口类名字

3.WNDCLASSEX
Windows提供了种扩展WNDCLASS定义名为WNDCLASSEX它允许应用使用小图标下面是WNDCLASSEX结构定义:
typedef struct WNDCLASSEX
UINT style;
WNDPROC 1pfnWndProc;
cbClsExtra;
cbWndExtra;
HANDLE hInstance;
HICON hIcon;
HCURSOR hbrBackground;
LPCTSTR 1pszMenuName;
LPCTSTR 1pszClassName;
HICON hIconSm;
WNDCLASSEX;
你可以看到这两个结构是相同除了WNDCLASSEX包括了hIconSm成员这是和窗口类有关小图标句柄

4.定义窗口类
应用可以定义它们自己窗口类只要先定义个合适类型结构然后用窗口类信息来填充结构
下面代码示范了如何定义并个WNDCLASS结构

char szProgName=\"ProgName\";
.
.
.
WNDCLASS wcApp;
.
.
.
wcApp.1pszClassName=szProgName;
wcApp.hInstance=hInst;
wcApp.1pfnWndProc=WndProc;
wcApp.hCursor=LoadCursor(NULLIDC-ARROW);
wcApp.hIcon=NULL;
wcApp.1pszMenuName=szAppIName;
wcApp.hbrBackground=GetStockObject(WHITE-BRUSH);
wcApp.style=CS-HREDRAW| CS-VREDRAW;
wcApp.cbClsExtra=0;
wcApp.cbWndExtra=0;
(!RegisterClass (&wcApp))
0;

WNDCLASS结构中第 2个域是wcApp.hInstance它被赋予了WinMain被激活后返回hInst这指明了应用当前例子1pfnWndProc被赋予执行所有窗口任务窗口指针地址对于大部分应用这个叫做WndProc
   注意:WndProc个用户定义而不是预定义在赋值语句的前必须给出原型
wcApp.hCursor域被赋予例子光标句柄
当wcApp.1pszMenuName被赋予NULL值时候Windows就认为这个窗口类没有菜单 如果有菜单必须有个名字它必须出现在引号里面GetStockOject返回个刷子句柄用于在这个类创建窗口用户区中画出背景色
wcApp.style窗口类风格被设为CS-HREDRAW或CS-VREDRAW
最后两个域weApp.cbClsExtra以及wcApp.cbWndExtra经常被设为0这些域可以被选用以指明窗口结构和窗口数据结构后面应该保留附加字节数
下面这段代码用于注册窗口类:


(!hpreInst)

.
.
.
(! RegisterClass(&wcApp))
FALSE;

Windows 95和Windows NT通过检查hPreInst值来确定多少个例子而hPreInst总是NULL所以就注册窗口类.

5.创建窗口
窗口通过CreateWindow来创建这个过程对所有版本Windows都是窗口类定义了窗口般特征允许同个窗口类被用于多个区别窗口,CreateWin-dow参数指明了有关窗口更详细信息
CreateWindow参数信息包括以下内容:窗口类、窗口标题、窗口风格、幕位置、窗口父句柄、菜单句柄、例子句柄以及32位附加信息在大部分应用这个会是下面这个样子:
hWnd=CreateWindow(szProgName\"Simple Windows Program\"
WS-OVERLAPPEDWINDOWCW-USEDEFAULT
CW-USEDEFAULTCW-USEDEFAULT
CW-USEDEFAULT(HWND)NULL(HMENU)NULL
(HANDLE)hInst(LPSTR)NULL);
个域szProgName(已赋过值)定义了窗口后面是窗口标题条上使用标题窗口风格是第 3个参数
下面 6个参数代表了窗口x、y坐标和x、y方向大小然后是父窗口句柄和窗口菜单句柄每个域都被赋予个缺省值hInst域包含了例子句柄后面是个附加参数(NULL)
显示和更新窗口
   在Windows下ShowWindow被用来实际显示个窗口下面代码示范了这个:
Show Window(hWndnCmdShow);
CreateWindow时生成窗口句柄被用作hWnd参数ShowWindow第 2个参数是nCmdShow决定了窗口被如何显示这个显示状态也被称为窗口可视状态
显示窗口最后步是WindowsUpdate Window

UpdateWindow(hWnd);

6.消息循环
Win-Main并显示了窗口应用就需要个消息处理循环最常用实现思路方法是使用个标准while循环:
while (GetMessage (&lpMsgNULL00))
{
TranslateMessage(&lpMsg);
DispatchMessage(&lpMsg);
}

GETMESSAGE:应用要处理个消息可以通过WindowsGetMessage来取得
NULL参数指示取回这个应用任何窗口任何消息最后两个参数0和0告诉GetMessage不要使用任何消息过滤器消息过滤器能够将接收到消息限制在个明确范围的内如键盘消息或鼠标消息等
般应用应该确认通向消息循环所有步骤都已经正确地执行过了这包括确认每个窗口类都已经注册过都已经被创建否则旦进入了消息循环只有个消息能够结束这个循环无论何时处理了WM-QUIT消息返回值是FALSE这会引发主循环关闭例程WM-QUIT消息是应用退出消息循环途径
TRANSLATEMESSAGE:通过TranslateMessage虚拟消息可以被转换为消息
DISPATCHMESSAGE:Windows通过DispatchMessage将当前消息发送到正确窗口过程
******* 窗口
所有应用都必须包括个WinMain个回调窗口Win-dows应用从不直接访问任何窗口每个应用都必须向Windows提出请求以执行规定操作
个回调在Windows中注册当Windows要对个窗口进行操作时它就被各个应用回调实际代码长度会大不相同窗口本身可以非常小只处理个或两个消息也可以非常大而且复杂
下面代码段(不完整应用介绍说明语句)显示了在应用回调窗口WndProc个范例:

LRESULT CALLBACK WndProc(HWND hWndUNIT messgWPARAM wParamLPARAM 1Param)

HDC hdc;
PAINTSTRUCT ps;
switch(messg)

WM-PAINT:
hdc=BeginPa(hWnd&ps);
.
.
.
ValidateRect(hWndNULL);
EndPa(hWnd&ps);

WM-DESTROY:
postQuitMessage(0);

default:
(DefWindowProc(hWndmessgwParam1param));

(0);

Windows希望窗口类结构定义中wcApp1pfnWndProc域名字能够和回调
字匹配后面用这个窗口类创建所有窗口回调都应该用WndProc名字
下面代码段讨论个窗口类结构中回调位置和赋值:
.
.
.
wcApp.1pszClassName=szProgName;
wcApp.hInstance=hInst;
wcApp.1pfnWndProc=WndProc;
.
.
.
Windows有向百个消息可以发送给窗口这些消息用“WM-”打头标识符来
标识
WndProc个参数是hWndhWnd包含了Windows发送消息窗口句柄
第 2个参数messg按WINUSER.H中定义指明了即将被处理实际消息最后两个参数wParam以及1Param指明了处理每个消息所需附加信息
WndProc继续定义了两个变量:hdc指明了显示设备句柄ps指明了存储用户区
信息所需个PAINTSTRUCT结构
回调被用于检查将被处理消息并选择执行适当动作这个选择过程通常在个标准C语言switch语句中完成
模块定义文件
正如你在前面学到LINK提供了所有Windows应用需要模块定义文件在命令行方式下替代品模块定义文件向链接器提供有关定义和描述信息这样链接器就可以知道如何来组织Windows应用可执行文件这些信息已经成为新执行文件格式文件头部分
注意:在Windows 95和Windows NT下面你不太可能需要创建个模块定义文件这些信息是为了完整性和向后兼容




第十节 VC提供windows编程工具
Visual C编译器包含几个资源编辑器单独编辑器可以通过编译器主菜单中Insert Resource菜单来运行图形对象都是资源象图标、光标、消息框、对话框、字体、位图、画笔、刷子等资源代表应用可执行文件中包含数据
   资源编译器RC.EXE是个Windows资源编译器
   资源以及附加编译器使用增加了应用开发复杂性但是它容易在项目工具中使用
项目文件
   项目文件提供了概览资源和代码编译过程手段同时也可以使应用可执行版本保持最新它们跟踪源文件日期和时间以实现这些增强功能项目文件包含了有关特定编译链过程信息项目文件是在集成C或C编辑环境中创建项目文件还支持增强编译和链接
资源
   当你使用VisualC编译器提供资源编辑器时用自己图标、指针和位图来定制Windows应用非常容易这些编辑器给你提供了个开发图形资源完整环境这些编辑器同时也能帮助你开发菜单和对话框-Windows下数据输入基本手段这些编辑器还能帮你操纵单独位图、加速键和
资源编辑器
   每种编辑器都在VisualC环境中提供都是编译器个集成部分这样每种编辑器都是在Windows下运行完全集成资源开发工具你可以通过选择Insert Resource来启动每种编辑器
下面我们将通过教程演示资源编辑器使用请单击返回然后运行教程
? 第十节 MFC基本概念
基础类库为你提供了易于使用对象将Windows和C联系起来是很自然这样就可以充分利用面向对象技术优点MFC开发组实现了大量Windows应用编程接口(API)这个C库在些可重用类中封装了最重要数据结构和API
   类似MFC这样类库比起前面两章讨论C员使用库有很多优点
下面列出了C些优点比如:
   *用类对数据和代码进行封装
   *继承性
   *消除和变量名冲突
   *类是语言自然扩展
   *通常精心设计库减少了代码量
   利用基础类库创建个窗口所需代码大约只占传统应用 3分的这就可以使员只用花很少时间和Windows打交道把更多精力集中在开发自己代码上
22.2 MFC设计考虑
   基础类库设计小组定义了严格设计规则在设计MFC库时必须遵循这些规则这些规则和方针如下:
   *利用C威力但不能把员吓倒
   *使从标准API到类库转换尽可能简单
   *允许混合使用传统和新类库
   *在设计类库时候综合考虑功能和效率
   *建成类库必须能够方便地在区别平台间移植如Windows 95和Windows NT
设计小组感到要开发高质量代码必须从MFC库本身开始C基础类库必须又小又快简单性使它易于使用而执行速度和庞大C库接近
   这些类设计方式应该让熟练Windows员不必重新学习各种名字通过仔细命名和设计可以实现这Microsoft认为这点是MFC区别于其它类库个特征
MFC小组还把基础类库设计为是允许以混合方式编程这就是说在同个源文件里既可以使用类也可以使用传统即使是在使用MFC时类似SetCursor和GetMetrics这样还是需要直接
Microsoft也知道类库必须方便使用其它厂商提供些类库设计得太抽象按Microsoft说法这些笨重类企图生成又大又慢应用MFC库提供了合理抽象保证代码很小
开发小组将原始MFC库设计为动态而不是静态动态结构是这些类可以适应我们现在使用Windows 95和Windows NT环境
22.3 MFC库关键特性
从其它编译器厂商那儿也可以获得Windows类库但Microsoft宣称他们MFC类库具有许多真正优点:
   *全面支持所有Windows、Control控件、消息、GDI(图形设备接口)绘图原语、菜单以及对话框
   *使用和Windows API相同命名约定因此从名字上就可以直接知道类功能
   *消除了即大量switch/语句所有消息都被映射到类成员这种消息-思路方法映射思路方法应用于所有消息
   *能够把对象信息输出到文件这提供了更好诊断支持同时还提供了验证成员变量能力
   *增强例外处理设计使得代码失败可能性更小能够解决“内存不足”以及其它些问题
   *可以在运行时决定数据对象类型这允许对类域进行动态操纵
   *小而快速代码前面已经提到MFC库只添加了很少些代码执行起来几乎和传统C语言Windows应用样快
*对组件对象模型(COM)支持
有经验Windows员会立刻喜欢上其中两个特性:熟悉命名约定和消息-思路方法映射机制如果你重新检查下在第 2十章中开发应用源代码你会看到大量用于处理switch/语句还应该注意这些应用了大量API当你使用MFC库时候这两种现象都消失或减少了
专业员肯定会欣赏在MFC库中实现更好诊断和很小代码现在员就可以利用MFC库好处而不必担心他们应用代码大小了
最后MFC是唯真正有用类库
22.4 切从CObject类开始
类似MFC这样类库通常都来自很少几个基类然后另外类就可以从这些基类中继承而来CObject是在开发Windows应用时大量使用个基类在MFC/INCLUDE子目录下提供MFC库头文件包括了许多类定义信息
我们来简单地看CObject它在头文件AFXH中有定义:
///////////////
// CObject is the root of all compliant objects
CObject

public:
//Object model(typesdestructionallocation)
virtual CRuntimeClass*GetRuntimeClass const;
virtual~CObject;//virtual destructors are necessary
//Diagnostic allocations
void*PASCAL operator (size-t nSize);
void*pascal operator (size-tvoid*p);
void PASCAL operator delete(void*p);
# d(-DEBUG)&&!d(-AFX-NO-DEBUG-CRT)
//for file name/line number tracking using DEBUG-NEW
void* PASCAL operator (size-t nSizeLPCSTR 1pszFileName nLine);
//Disable the copy constructor and assignment by default
//so you will get compiler errors instead of unexpected
//behavior you pass objects by value or assign objects.
protected:
CObject



private:
CObject(const CObject& objectSrc);//no implementation
void operator=(const CObject& objectSrc);

//Attributes
public:
BOOL IsSerializableconst;
BOOL IsKindOf(const CRuntimeClass*pClass)const;
//Overridables
virtual void Serialize (CArchive& ar);
//Diagnostic Support
virtual void AssertValidconst;
virtual void Dump(CDumpContext& dc)const;
//Implementation
public:
const AFX-DATA CRuntimeClass CObject;
#def-AFXDLL
CRuntimeClass*PASCAL-GetBaseClass
#end

为了清楚起见对这段代码作了些细微改动但和你在头文件AFX.H可以找到代码基本
检查CObject代码注意构成这个类定义成分首先CObject被分为公有、保护和私有 3个部分CObject还提供了和动态类型检查以及串行化功能回忆动态类型检查使你可以在运行时确定对象类型借助于永久性概念对象状态可以被保存到存储介质中比如磁盘对象永久性使对象成员也可以是永久允许对象数据恢复
子类从基类继承而来例如CGdiObject是个从CObject类继承来这儿是AFXWINH中找到CGdiObject类定义同样为了清楚起见对其作了些改动
//////////////////////
//CGdiObjet abstract for CDC SelectObject
CGdiObject:public CObject

DECLARE-DYNCREATE(CGdiObject)
public:
//Attributes
HGDIOBJ m-hObject;//must be first data member
operator HGDIOBJconst;
CGdiObject*PASCAL FromHandle(HGDIOBJ hObject);
void PASCAL Delete TempMap
BOOL Attach (HGDIOBJ hObject);
HGDIOBJ Detach
//Constructors
CGdiobject;//must create a derived object
BOOL DeleteObject
//Operations
GetObject ( nCountLPVOID 1pObject)const;
UINT GetObjectTypeconst;
BOOL CreateStockObject( nIndex);
BOOL UnrealizeObject
BOOL operator(const CGdiObject& obj)const;
BOOL operator!=(const CGdiObject& obj)const;
//Implementation
public:
virtual~CGdiObject
#def-DEBUG
virtual void Dump(CDumpContext& dc)const;
virtual void AssertValidconst;
#end

CGdiObject和它成员允许在Windows应用中创建并使用绘画对象如自定义画笔、刷子和字体等诸如CPen的类类是进步从CGdiObject类继承而来
Microsoft提供了MFC库全部源代码以尽可能地增加编程灵活性但是对于初学者没有必要去了解区别类是如何定义
例如在传统C语言Windows应用DeleteObject按下面语法:
DeleteObject(hBRUSH);/*hBRUSH is the brush handle*/
在C利用MFC库可以按下面语法访问类成员以实现同样:
brush.DeleteObject;// brush is current brush
正如你可以看到从C语言Windows转向类库对象是简单Microsoft在开发所有Windows类时候都使用这种思路方法使得从传统到继承类库对象转移非常简单

Tags:  网页游戏开发 网络游戏开发 游戏开发 游戏开发基础

延伸阅读

最新评论

发表评论