Windows应用
![](/icons/71145chengxu.gif)
![](/icons/71145de.gif)
面向对象认识
面向对象作为
![](/icons/71145yi.gif)
种思路方法学
![](/icons/71145dou.gif)
要求将
![](/icons/71145chengxu.gif)
中
![](/icons/71145de.gif)
数据和操作(代码)归结到某些对象名下
![](/icons/71145dou.gif)
将数据看作对象
![](/icons/71145de.gif)
属性
![](/icons/71145dou.gif)
要改变这些属性
![](/icons/71145dou.gif)
必须通过操作来进行
![](/icons/71145dou2.gif)
进行面向对象
![](/icons/71145de.gif)
![](/icons/71145chengxu.gif)
设计最好使用面向对象
![](/icons/71145de.gif)
语言
![](/icons/71145dou.gif)
如C
![](/icons/71145jiajia.gif)
![](/icons/71145dou.gif)
SamllTalk等
![](/icons/71145dou2.gif)
面向对象
![](/icons/71145de.gif)
语言
![](/icons/71145de.gif)
语言所起
![](/icons/71145de.gif)
作用
![](/icons/71145dou.gif)
就是给
![](/icons/71145chengxu.gif)
员们提供
![](/icons/71145yi.gif)
些进行面向对象
![](/icons/71145de.gif)
![](/icons/71145chengxu.gif)
设计时必需
![](/icons/71145de.gif)
约束
![](/icons/71145dou.gif)
使数据和操作
![](/icons/71145de.gif)
衔接有
![](/icons/71145yi.gif)
种显式
![](/icons/71145de.gif)
描述
![](/icons/71145dou.gif)
并进行
![](/icons/71145yi.gif)
些技术性
![](/icons/71145de.gif)
事务管理
![](/icons/71145dou2.gif)
但是
![](/icons/71145dou.gif)
如果我们能理解面向对象
![](/icons/71145chengxu.gif)
设计
![](/icons/71145de.gif)
原理和思路方法
![](/icons/71145dou.gif)
即使不使用面向对象
![](/icons/71145de.gif)
语言
![](/icons/71145dou.gif)
也能实现面向对象
![](/icons/71145de.gif)
![](/icons/71145chengxu.gif)
设计
![](/icons/71145dou2.gif)
Windows本身并不是
![](/icons/71145yi.gif)
个面向对象
![](/icons/71145de.gif)
![](/icons/71145chengxu.gif)
设计环境
![](/icons/71145dou.gif)
但Windows
![](/icons/71145de.gif)
某些部分还是明显地受到面向对象
![](/icons/71145de.gif)
软件Software
![](/icons/71145de.gif)
概念
![](/icons/71145de.gif)
影响
![](/icons/71145dou2.gif)
从某种程度上说
![](/icons/71145dou.gif)
在进行Windows
![](/icons/71145chengxu.gif)
设计时
![](/icons/71145dou.gif)
![](/icons/71145chengxu.gif)
员是在进行面向对象
![](/icons/71145de.gif)
![](/icons/71145chengxu.gif)
设计
![](/icons/71145dou2.gif)
理解Windows
![](/icons/71145de.gif)
面向对象
![](/icons/71145de.gif)
思想和应用
![](/icons/71145chengxu.gif)
设计
![](/icons/71145de.gif)
面向对象思路方法对设计结构合理
![](/icons/71145de.gif)
应用
![](/icons/71145chengxu.gif)
会有很大
![](/icons/71145de.gif)
帮助
![](/icons/71145dou2.gif)
前面已给出了对象
![](/icons/71145de.gif)
定义:每个对象包含有数据和代码
![](/icons/71145dou.gif)
代码描述了对象可执行
![](/icons/71145de.gif)
![](/icons/71145yi.gif)
系列预定义
![](/icons/71145de.gif)
动作
![](/icons/71145dou.gif)
而数据是对象私有
![](/icons/71145de.gif)
![](/icons/71145dou.gif)
它们由相关
![](/icons/71145de.gif)
可执行代码存取
![](/icons/71145dou2.gif)
预定义
![](/icons/71145de.gif)
动作和私有数据
![](/icons/71145de.gif)
结合称为封装
![](/icons/71145dou2.gif)
在C中
![](/icons/71145dou.gif)
我们使用
![](/icons/71145yi.gif)
个
![](/icons/71145hanshu.gif)
来封装
![](/icons/71145yi.gif)
个对象
![](/icons/71145de.gif)
私有数据和动作
![](/icons/71145dou.gif)
使用switch语句来定义预定义
![](/icons/71145de.gif)
动作
![](/icons/71145dou.gif)
这些动作只存取为该
![](/icons/71145hanshu.gif)
本身所知道
![](/icons/71145de.gif)
数据
![](/icons/71145dou2.gif)
Windows和Windows应用
![](/icons/71145chengxu.gif)
是怎样发送消息
![](/icons/71145de.gif)
呢?在Windows及其应用
![](/icons/71145chengxu.gif)
中
![](/icons/71145dou.gif)
消息被表示为
![](/icons/71145yi.gif)
个数据结构
![](/icons/71145dou.gif)
并能在对象的间传递
![](/icons/71145dou2.gif)
发送消息等价于执行其参数表示消息数据
![](/icons/71145de.gif)
![](/icons/71145hanshu.gif)
![](/icons/71145diaoyong.gif)
![](/icons/71145dou.gif)
参数的
![](/icons/71145yi.gif)
是
![](/icons/71145yi.gif)
个标识该消息
![](/icons/71145de.gif)
预定义
![](/icons/71145de.gif)
消息标识符
![](/icons/71145dou.gif)
当
![](/icons/71145yi.gif)
个对象接受到
![](/icons/71145yi.gif)
条消息时
![](/icons/71145dou.gif)
消息标识符决定该对象执行何种动作
![](/icons/71145dou2.gif)
消息传递是以
![](/icons/71145hanshu.gif)
![](/icons/71145diaoyong.gif)
![](/icons/71145de.gif)
形式来实现
![](/icons/71145de.gif)
![](/icons/71145dou.gif)
这种
![](/icons/71145diaoyong.gif)
可以发生在
![](/icons/71145chengxu.gif)
![](/icons/71145de.gif)
任何地方
![](/icons/71145dou2.gif)
Windows
![](/icons/71145chengxu.gif)
员必须清楚用消息引发动作
![](/icons/71145de.gif)
技术
![](/icons/71145dou2.gif)
区别
![](/icons/71145de.gif)
对象能以区别
![](/icons/71145de.gif)
动作响应同样
![](/icons/71145de.gif)
消息
![](/icons/71145dou2.gif)
这样
![](/icons/71145dou.gif)
![](/icons/71145yi.gif)
个特定
![](/icons/71145de.gif)
消息可代表
![](/icons/71145yi.gif)
个通用事件
![](/icons/71145dou2.gif)
例如
![](/icons/71145dou.gif)
按键操作、移动鼠标或绘制用户区等;而任何
![](/icons/71145yi.gif)
个特定
![](/icons/71145de.gif)
消息可以在区别
![](/icons/71145de.gif)
对象中引发区别
![](/icons/71145de.gif)
动作
![](/icons/71145dou.gif)
例如
![](/icons/71145dou.gif)
区别
![](/icons/71145de.gif)
窗口对象以区别
![](/icons/71145de.gif)
动作处理同样
![](/icons/71145de.gif)
WM_KEYDOWN、WM_MOUSEMOVE或WM_PAINT消息
![](/icons/71145yi.gif)
个消息可以有
![](/icons/71145yi.gif)
个对象发送到另
![](/icons/71145yi.gif)
个对象
![](/icons/71145dou.gif)
或由Windows发送到某个对象
![](/icons/71145dou2.gif)
例如
![](/icons/71145dou.gif)
WM_KEY_DOWN的类
![](/icons/71145de.gif)
消息是由Windows产生
![](/icons/71145de.gif)
![](/icons/71145dou2.gif)
有些消息在对象
![](/icons/71145de.gif)
窗口
![](/icons/71145hanshu.gif)
对其处理完毕后就消失了
![](/icons/71145dou.gif)
而有些消息在处理时有产生新
![](/icons/71145de.gif)
消息:
![](/icons/71145yi.gif)
个对象通过向其它对象或自己发送
![](/icons/71145yi.gif)
条或多条消息来处理
![](/icons/71145yi.gif)
条消息
![](/icons/71145dou2.gif)
这样
![](/icons/71145dou.gif)
Windows应用
![](/icons/71145chengxu.gif)
![](/icons/71145de.gif)
控制流程不象MS-DOS应用
![](/icons/71145chengxu.gif)
那样易于跟踪
![](/icons/71145dou.gif)
![](/icons/71145chengxu.gif)
![](/icons/71145de.gif)
调试也比MS-DOS应用
![](/icons/71145chengxu.gif)
困难
![](/icons/71145dou2.gif)
除了个别消息以外
![](/icons/71145dou.gif)
对象接受消息
![](/icons/71145de.gif)
顺序是不可预知
![](/icons/71145de.gif)
![](/icons/71145dou.gif)
但对象处理每条消息所采取
![](/icons/71145de.gif)
动作是显式定义在窗口
![](/icons/71145hanshu.gif)
中
![](/icons/71145de.gif)
![](/icons/71145dou2.gif)
对象并不显式地定义所有可能消息
![](/icons/71145de.gif)
动作
![](/icons/71145dou.gif)
对于不显示处理
![](/icons/71145de.gif)
消息
![](/icons/71145dou.gif)
都交由DefWindowProc进行缺省处理
![](/icons/71145dou2.gif)
消息传递
![](/icons/71145de.gif)
途径很简单:从
![](/icons/71145yi.gif)
个对象传递到另
![](/icons/71145yi.gif)
对象
![](/icons/71145dou.gif)
但由于DefWindowProc对有些消息提供了缺省处理
![](/icons/71145dou.gif)
因此
![](/icons/71145dou.gif)
![](/icons/71145chengxu.gif)
员在设计
![](/icons/71145chengxu.gif)
时必须考虑在
![](/icons/71145yi.gif)
个窗口
![](/icons/71145hanshu.gif)
中捕获某条消息时是否还应交给DefWindowProc
![](/icons/71145hanshu.gif)
作进
![](/icons/71145yi.gif)
步
![](/icons/71145de.gif)
处理
![](/icons/71145dou2.gif)
DefWindowProc能处理所有
![](/icons/71145de.gif)
消息
![](/icons/71145dou.gif)
但对大部消息只是简单地废弃的
![](/icons/71145dou.gif)
不作具有实际意义
![](/icons/71145de.gif)
处理
![](/icons/71145dou.gif)
在窗口
![](/icons/71145hanshu.gif)
捕获这些废弃消息是安全
![](/icons/71145de.gif)
;若要捕获其它消息
![](/icons/71145dou.gif)
则必须了解DefWindowProc是怎样处理这条消息
![](/icons/71145de.gif)
![](/icons/71145dou.gif)
并在窗口
![](/icons/71145hanshu.gif)
![](/icons/71145de.gif)
处理代码中能提供类似
![](/icons/71145de.gif)
处理(或将该消息交由DefWindowProc作进
![](/icons/71145yi.gif)
步
![](/icons/71145de.gif)
处理)
![](/icons/71145dou2.gif)
现在我们讨论窗口
![](/icons/71145hanshu.gif)
对对象
![](/icons/71145de.gif)
私有数据
![](/icons/71145de.gif)
处理问题
![](/icons/71145dou2.gif)
窗口类也介绍说明了对象
![](/icons/71145de.gif)
私有数据
![](/icons/71145dou.gif)
当
![](/icons/71145diaoyong.gif)
CreateWindow创建
![](/icons/71145yi.gif)
个窗口对象时
![](/icons/71145dou.gif)
Windows为创建
![](/icons/71145de.gif)
窗口对象分配私有数据存储区
![](/icons/71145dou.gif)
其中存储有窗口
![](/icons/71145de.gif)
例子句柄、父窗口句柄、窗口
![](/icons/71145hanshu.gif)
![](/icons/71145de.gif)
地址和其它Windows用于管理窗口对象
![](/icons/71145de.gif)
数据
![](/icons/71145dou2.gif)
对这些私有数据
![](/icons/71145de.gif)
![](/icons/71145de.gif)
操作只能使用GetWindowWord/GetWindowLong等
![](/icons/71145hanshu.gif)
![](/icons/71145dou2.gif)
对于
![](/icons/71145chengxu.gif)
中介绍说明
![](/icons/71145de.gif)
变量
![](/icons/71145dou.gif)
如何在窗口
![](/icons/71145hanshu.gif)
中将它们和相关
![](/icons/71145de.gif)
对象衔接在
![](/icons/71145yi.gif)
起就比较复杂
![](/icons/71145dou.gif)
![](/icons/71145yinwei.gif)
窗口
![](/icons/71145hanshu.gif)
为该类
![](/icons/71145de.gif)
所有对象共享
![](/icons/71145dou.gif)
该类
![](/icons/71145de.gif)
所有对象在接收到消息时都执行相同
![](/icons/71145de.gif)
代码
![](/icons/71145dou2.gif)
在过去
![](/icons/71145dou.gif)
Windows推荐使用
![](/icons/71145de.gif)
![](/icons/71145chengxu.gif)
设计语言是C
![](/icons/71145dou.gif)
由于C语言不具备将
![](/icons/71145yi.gif)
个对象
![](/icons/71145de.gif)
私有数据和操作这些私有数据
![](/icons/71145de.gif)
代码衔接在
![](/icons/71145yi.gif)
起
![](/icons/71145de.gif)
语言成份(面向对象
![](/icons/71145de.gif)
语言
![](/icons/71145de.gif)
事务性工作的
![](/icons/71145yi.gif)
就是为
![](/icons/71145chengxu.gif)
完成这个工作)
![](/icons/71145dou.gif)
这个工作只能由
![](/icons/71145chengxu.gif)
员来作
![](/icons/71145dou2.gif)
![](/icons/71145chengxu.gif)
员心中必须清楚
![](/icons/71145chengxu.gif)
中所介绍说明或分配
![](/icons/71145de.gif)
变量私有于哪个对象
![](/icons/71145dou.gif)
并采用合适
![](/icons/71145de.gif)
数据结构来表示它们
![](/icons/71145dou.gif)
以便
![](/icons/71145chengxu.gif)
在使用它们时
![](/icons/71145dou.gif)
能根据区别
![](/icons/71145de.gif)
对象将它们区别开来
![](/icons/71145dou2.gif)
有几种思路方法可用于区分对象
![](/icons/71145de.gif)
私有数据:
![](/icons/71145chengxu.gif)
员编制额外
![](/icons/71145de.gif)
代码来判断
![](/icons/71145yi.gif)
个对象应使用哪些数据
![](/icons/71145dou2.gif)
使用窗口附加字节
使用属性表
当使用第
![](/icons/71145yi.gif)
种思路方法时
![](/icons/71145dou.gif)
![](/icons/71145chengxu.gif)
实际是使用对象句柄作索引来检索和该对象相关
![](/icons/71145de.gif)
私有数据
![](/icons/71145dou.gif)
Windows也使用这种思路方法使用句柄来检索
![](/icons/71145yi.gif)
张表
![](/icons/71145dou.gif)
这个表中存储着该句柄所标识
![](/icons/71145de.gif)
对象
![](/icons/71145de.gif)
私有数据
![](/icons/71145dou2.gif)
Windows
![](/icons/71145de.gif)
许多
![](/icons/71145hanshu.gif)
需要
![](/icons/71145yi.gif)
个对象
![](/icons/71145de.gif)
句柄作为第
![](/icons/71145yi.gif)
参数
![](/icons/71145dou.gif)
其原因就是为区分对象
![](/icons/71145de.gif)
私有数据
![](/icons/71145dou.gif)
以便使用相同
![](/icons/71145de.gif)
![](/icons/71145hanshu.gif)
处理区别
![](/icons/71145de.gif)
对象(
![](/icons/71145de.gif)
数据)
![](/icons/71145dou2.gif)
后两种思路方法和第
![](/icons/71145yi.gif)
种思路方法本质是
![](/icons/71145yi.gif)
样
![](/icons/71145de.gif)
(我们会将在后面
![](/icons/71145de.gif)
章节对其进行介绍)
![](/icons/71145dou.gif)
只是Windows提供了
![](/icons/71145yi.gif)
些相关
![](/icons/71145de.gif)
![](/icons/71145hanshu.gif)
来简化
![](/icons/71145chengxu.gif)
![](/icons/71145de.gif)
工作
![](/icons/71145dou2.gif)
由于C没有继承这种语言成分
![](/icons/71145dou.gif)
![](/icons/71145yinwei.gif)
![](/icons/71145dou.gif)
也就不能形成对象
![](/icons/71145de.gif)
等级结构
![](/icons/71145dou2.gif)
继承是面向对象语言
![](/icons/71145de.gif)
另
![](/icons/71145yi.gif)
个重要成分
![](/icons/71145dou2.gif)
继承使得
![](/icons/71145chengxu.gif)
中
![](/icons/71145de.gif)
对象形成
![](/icons/71145yi.gif)
个分层次
![](/icons/71145de.gif)
对象结构
![](/icons/71145dou.gif)
低层次
![](/icons/71145de.gif)
对象可以将它不处理
![](/icons/71145de.gif)
消息发送到高层对象上进行缺省处理
![](/icons/71145dou2.gif)
由于在C中不能(或说很难)建立对象
![](/icons/71145de.gif)
这种等级结构
![](/icons/71145dou.gif)
但为了简化应用
![](/icons/71145chengxu.gif)
![](/icons/71145de.gif)
设计
![](/icons/71145dou.gif)
又必须要求支持消息
![](/icons/71145de.gif)
缺省处理(否则应用
![](/icons/71145chengxu.gif)
要定义
![](/icons/71145yi.gif)
个窗口对象可能接收到
![](/icons/71145de.gif)
所有消息
![](/icons/71145de.gif)
处理代码)
![](/icons/71145dou.gif)
因此只能使用DefWindowProc提供消息
![](/icons/71145de.gif)
缺省处理
![](/icons/71145dou2.gif)
这就要求对
![](/icons/71145yi.gif)
个窗口对象所有消息
![](/icons/71145de.gif)
处理定义在
![](/icons/71145yi.gif)
个
![](/icons/71145hanshu.gif)
中
![](/icons/71145dou.gif)
就带来了定义窗口
![](/icons/71145hanshu.gif)
![](/icons/71145de.gif)
返回值和参数类型时使用了
![](/icons/71145yi.gif)
种较难为人理解
![](/icons/71145de.gif)
思路方法
![](/icons/71145dou2.gif)
![](/icons/71145yinwei.gif)
区别
![](/icons/71145de.gif)
消息可以带有区别类型和个数
![](/icons/71145de.gif)
参数
![](/icons/71145dou.gif)
并且返回数据
![](/icons/71145de.gif)
类型也不相同
![](/icons/71145dou.gif)
Windows
![](/icons/71145de.gif)
设计者采用了
![](/icons/71145yi.gif)
个折中
![](/icons/71145de.gif)
思路方法:为消息规定
![](/icons/71145yi.gif)
个十 6位
![](/icons/71145de.gif)
参数和
![](/icons/71145yi.gif)
个32位
![](/icons/71145de.gif)
参数
![](/icons/71145dou.gif)
将返回类型指定为LRESULT
![](/icons/71145dou.gif)
这种类型
![](/icons/71145de.gif)
长度能容下C中所有预定义类型
![](/icons/71145de.gif)
数据
![](/icons/71145dou2.gif)
由于区别类
![](/icons/71145de.gif)
窗口对象定义有自己
![](/icons/71145de.gif)
窗口
![](/icons/71145hanshu.gif)
![](/icons/71145dou.gif)
但C语言不具备根据接受消息
![](/icons/71145de.gif)
对象自动决定
![](/icons/71145diaoyong.gif)
该对象
![](/icons/71145de.gif)
窗口
![](/icons/71145hanshu.gif)
![](/icons/71145de.gif)
能力(在面向对象
![](/icons/71145de.gif)
语言中
![](/icons/71145dou.gif)
这种能力被称为多态性)
![](/icons/71145dou2.gif)
因此
![](/icons/71145dou.gif)
向区别
![](/icons/71145de.gif)
窗口对象发送消息时使用
![](/icons/71145hanshu.gif)
SendMessage对窗口
![](/icons/71145hanshu.gif)
作间接
![](/icons/71145diaoyong.gif)
![](/icons/71145dou.gif)
由Windows根据该
![](/icons/71145hanshu.gif)
![](/icons/71145diaoyong.gif)
中所使用
![](/icons/71145de.gif)
对象标识符来
![](/icons/71145diaoyong.gif)
该对象
![](/icons/71145de.gif)
窗口
![](/icons/71145hanshu.gif)
![](/icons/71145dou2.gif)
在
![](/icons/71145chengxu.gif)
设计中由于窗口
![](/icons/71145hanshu.gif)
![](/icons/71145de.gif)
限制
![](/icons/71145dou.gif)
需经常进行各种各样
![](/icons/71145de.gif)
数据类型转换
![](/icons/71145dou2.gif)
例如:
SendMessage(hwnd, WM_USER, (WPARAM)5, MAKELPARAM(89, 3267));
在这个例子中
![](/icons/71145dou.gif)
为了组建
![](/icons/71145yi.gif)
个LPARAM类型
![](/icons/71145de.gif)
数据
![](/icons/71145dou.gif)
使用了宏MAKEPARAM
![](/icons/71145dou2.gif)
它将两个十 6位
![](/icons/71145de.gif)
数据组装成
![](/icons/71145yi.gif)
个32位
![](/icons/71145de.gif)
数据(低位字为MAKEPARAM
![](/icons/71145de.gif)
第
![](/icons/71145yi.gif)
个参数
![](/icons/71145dou.gif)
高位字为第 2个参数)
![](/icons/71145dou2.gif)
当需要从
![](/icons/71145yi.gif)
个LPARAM类型
![](/icons/71145de.gif)
数据中分离出低位字和高位字时
![](/icons/71145dou.gif)
使用宏LOWORD和HIWORD
![](/icons/71145dou2.gif)
例如
![](/icons/71145dou.gif)
处理上个例子中所发送
![](/icons/71145de.gif)
WM_USER消息
![](/icons/71145de.gif)
窗口
![](/icons/71145hanshu.gif)
![](/icons/71145de.gif)
代码可能为:
WORD wStart = LOWORD(lParam);
WORD wStart = LOWORD(lParam);
宏MAKELRESULT和MAKELPARAM类似
![](/icons/71145dou.gif)
它被用于装配LRESULT类型
![](/icons/71145de.gif)
数据
![](/icons/71145dou2.gif)
宏MAKELONG用于装配LONG类型
![](/icons/71145de.gif)
数据
![](/icons/71145dou.gif)
当需要从LRESULT或LONG类型
![](/icons/71145de.gif)
数据中分离出高位字和低位字时
![](/icons/71145dou.gif)
使用宏HIWORD和LOWORD
![](/icons/71145dou2.gif)
基于上面
![](/icons/71145de.gif)
介绍
![](/icons/71145dou.gif)
我们在设计Windows应用
![](/icons/71145chengxu.gif)
时
![](/icons/71145dou.gif)
要明确
![](/icons/71145chengxu.gif)
中存在哪些对象
![](/icons/71145dou.gif)
对象的间是如何通过消息传递
![](/icons/71145chengxu.gif)
控制
![](/icons/71145de.gif)
![](/icons/71145dou.gif)
哪些数据是对所有对象公有
![](/icons/71145de.gif)
![](/icons/71145dou.gif)
哪些数据是私有于某
![](/icons/71145yi.gif)
个对象
![](/icons/71145de.gif)
![](/icons/71145dou.gif)
公有数据和对象
![](/icons/71145de.gif)
私有数据必须是存储在静态生存期
![](/icons/71145de.gif)
变量中(局部生存期
![](/icons/71145de.gif)
变量在窗口
![](/icons/71145hanshu.gif)
返回后就消失了
![](/icons/71145dou.gif)
不能在下次
![](/icons/71145diaoyong.gif)
该
![](/icons/71145hanshu.gif)
时保存上次
![](/icons/71145de.gif)
值
![](/icons/71145dou2.gif)
换句话说
![](/icons/71145dou.gif)
存储对象
![](/icons/71145de.gif)
数据
![](/icons/71145de.gif)
变量
![](/icons/71145de.gif)
生存期不应小于对象
![](/icons/71145de.gif)
生存期)
![](/icons/71145dou2.gif)
由于Windows应用
![](/icons/71145chengxu.gif)
各个模块的间主要是通过消息传递控制
![](/icons/71145dou.gif)
因此
![](/icons/71145dou.gif)
Windows应用
![](/icons/71145chengxu.gif)
![](/icons/71145de.gif)
逻辑结构就区别于MS-DOS应用
![](/icons/71145chengxu.gif)
![](/icons/71145de.gif)
逻辑结构
![](/icons/71145dou.gif)
如图1-1所示
![](/icons/71145dou2.gif)
从图1-1可以看出
![](/icons/71145dou.gif)
Windows应用
![](/icons/71145chengxu.gif)
![](/icons/71145de.gif)
各个模块通过消息传递被联系在
![](/icons/71145yi.gif)
起
![](/icons/71145dou.gif)
因此
![](/icons/71145dou.gif)
如果正确地组织
![](/icons/71145chengxu.gif)
![](/icons/71145dou.gif)
![](/icons/71145chengxu.gif)
![](/icons/71145de.gif)
模块性和结构较MS-DOS应用
![](/icons/71145chengxu.gif)
要好
![](/icons/71145dou2.gif)
![](http://www.crazycoder.cn/WebFiles/20099/49c6238d-0efe-482d-9947-0d101b62a6a6.jpg)
图1-1 DOS应用
![](/icons/71145chengxu.gif)
和Windows应用
![](/icons/71145chengxu.gif)
逻辑结构
![](/icons/71145de.gif)
比较示意介绍说明
Windows
![](/icons/71145chengxu.gif)
![](/icons/71145de.gif)
组织
将1.9节介绍
![](/icons/71145de.gif)
![](/icons/71145chengxu.gif)
按照C/C
![](/icons/71145jiajia.gif)
语言
![](/icons/71145de.gif)
要求组织起来
![](/icons/71145dou.gif)
就得到
![](/icons/71145yi.gif)
个完整
![](/icons/71145de.gif)
Windows
![](/icons/71145chengxu.gif)
![](/icons/71145dou2.gif)
![](/icons/71145yi.gif)
个Windows
![](/icons/71145chengxu.gif)
必须有
![](/icons/71145yi.gif)
个名为WinMain
![](/icons/71145de.gif)
主
![](/icons/71145hanshu.gif)
![](/icons/71145dou2.gif)
// 1-1.c 代码片段
#
<windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
PASCAL WinMain(
HINSTANCE hInstance, // 应用![](/icons/71145chengxu.gif)
例子句柄
HINSTANCE hPrevInstance, // 该应用
前
个例子
句柄
LPSTR lpszCmdLine, // 命令行参数串
nCmdShow) //
在
化时如何显示窗口
{
char szAppName
= "Window";
HWND hwnd;
MSG msg;
WNDCLASS wnd
;
(!hPrevInstance) {
// 该例子是![](/icons/71145chengxu.gif)
第
个例子
注册窗口类
wnd
.style = CS_VREDRAW | CS_HREDRAW;
wnd
.lpfnWndProc = WndProc;
wnd
.cbClsExtra = 0;
wnd
.cbWndExtra = 0;
wnd
.hInstance = hInstance;
wnd
.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
wnd
.hCursor = LoadCursor(NULL, IDC_ARROW);
wnd
.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wnd
.lpszMenuName = NULL;
wnd
.lpszClassName = szAppName;
(!RegisterClass(&wnd
))
// 如果注册失败
FALSE;
}
// 对每个例子
创建
个窗口对象
hwnd = CreateWindow(
szAppName,
"Sample Program",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
msg.wParam;
}
WinMain
![](/icons/71145hanshu.gif)
是Windows应用
![](/icons/71145chengxu.gif)
开始执行时
![](/icons/71145de.gif)
入口点
![](/icons/71145dou.gif)
它
![](/icons/71145de.gif)
返回类型为
![](/icons/71145int.gif)
![](/icons/71145dou2.gif)
WinMain
![](/icons/71145hanshu.gif)
![](/icons/71145de.gif)
作用十分类似于MS-DOS中
![](/icons/71145de.gif)
C应用
![](/icons/71145chengxu.gif)
![](/icons/71145de.gif)
![](/icons/71145main.gif)
![](/icons/71145hanshu.gif)
![](/icons/71145dou2.gif)
WinMain带有 4个参数
![](/icons/71145dou2.gif)
参数hInstance和hPrevInstance是
![](/icons/71145chengxu.gif)
![](/icons/71145de.gif)
例子句柄
![](/icons/71145dou2.gif)
在Windows环境下
![](/icons/71145dou.gif)
可以运行同
![](/icons/71145yi.gif)
个
![](/icons/71145chengxu.gif)
![](/icons/71145de.gif)
多个拷贝
![](/icons/71145dou.gif)
每
![](/icons/71145yi.gif)
个拷贝都是该应用
![](/icons/71145chengxu.gif)
![](/icons/71145de.gif)
![](/icons/71145yi.gif)
个句柄
![](/icons/71145dou.gif)
每个例子使用
![](/icons/71145yi.gif)
个例子句柄进行标识
![](/icons/71145dou2.gif)
hInstance是标识当前
![](/icons/71145chengxu.gif)
![](/icons/71145de.gif)
例子
![](/icons/71145de.gif)
句柄
![](/icons/71145dou.gif)
它
![](/icons/71145de.gif)
值不会为NULL
![](/icons/71145dou2.gif)
如果在此的前Windows中已经运行了该
![](/icons/71145chengxu.gif)
![](/icons/71145de.gif)
另
![](/icons/71145yi.gif)
个例子
![](/icons/71145dou.gif)
则这个例子
![](/icons/71145de.gif)
句柄由参数hPrevInstace给出
![](/icons/71145dou2.gif)
如果在运行该
![](/icons/71145chengxu.gif)
时
![](/icons/71145dou.gif)
Windows环境中不存在该
![](/icons/71145chengxu.gif)
![](/icons/71145de.gif)
另
![](/icons/71145yi.gif)
个例子
![](/icons/71145dou.gif)
则hPrevInstance为NULL
![](/icons/71145dou2.gif)
我们曾经说过
![](/icons/71145dou.gif)
对同
![](/icons/71145yi.gif)
个类
![](/icons/71145dou.gif)
不能向Windows注册
![](/icons/71145yi.gif)
次以上
![](/icons/71145dou2.gif)
在这个
![](/icons/71145chengxu.gif)
中
![](/icons/71145dou.gif)
通过判别hPrevInstance
![](/icons/71145de.gif)
值是否为NULL
![](/icons/71145dou.gif)
来决定是否应向Windows注册窗口类
![](/icons/71145dou2.gif)
这样
![](/icons/71145de.gif)
![](/icons/71145chengxu.gif)
逻辑保证了只在该
![](/icons/71145chengxu.gif)
![](/icons/71145de.gif)
第
![](/icons/71145yi.gif)
个例子中注册窗口类
![](/icons/71145dou2.gif)
参数lpszCmdLine中包含有运行
![](/icons/71145chengxu.gif)
时传递给
![](/icons/71145chengxu.gif)
![](/icons/71145de.gif)
命令行参数
![](/icons/71145dou2.gif)
例如
![](/icons/71145dou.gif)
若以这样
![](/icons/71145de.gif)
命令运行该
![](/icons/71145chengxu.gif)
![](/icons/71145dou2.gif)
Sample.exe Programming Windows
![](/icons/71145dou2.gif)
则lpszCmdLine将指向
![](/icons/71145zifu.gif)
串“Programming Windows”
![](/icons/71145dou2.gif)
最后
![](/icons/71145yi.gif)
个参数nCmdShow是
![](/icons/71145yi.gif)
个
![](/icons/71145int.gif)
类型
![](/icons/71145de.gif)
整数
![](/icons/71145dou.gif)
用以介绍说明在
![](/icons/71145chengxu.gif)
被装如内存时
![](/icons/71145dou.gif)
Windows以何种方式显示这个
![](/icons/71145chengxu.gif)
![](/icons/71145de.gif)
窗口
![](/icons/71145dou2.gif)
根据运行
![](/icons/71145chengxu.gif)
![](/icons/71145de.gif)
方式区别
![](/icons/71145dou.gif)
该参数被设置为SW_SHOWNORMAL或SW_SHOWMINNOACTIVE
![](/icons/71145dou.gif)
SW
![](/icons/71145de.gif)
含义是“Show Window”(显示窗口)
![](/icons/71145dou.gif)
这两个参数
![](/icons/71145de.gif)
含义在后面介绍
![](/icons/71145dou2.gif)
在
![](/icons/71145chengxu.gif)
Sample.CPP中
![](/icons/71145dou.gif)
有几个
![](/icons/71145hanshu.gif)
我们未曾介绍
![](/icons/71145dou2.gif)
表1-3给出了这些
![](/icons/71145hanshu.gif)
![](/icons/71145de.gif)
介绍说明
![](/icons/71145dou2.gif)
表1-3-1 ShowWindow
![](/icons/71145hanshu.gif)
用 途 显示或改变给定
![](/icons/71145de.gif)
窗口
原 型 BOOL ShowWindow(
HWND hWnd, 指定
![](/icons/71145yi.gif)
个窗口对象
![](/icons/71145int.gif)
nCmdShow 指定窗口
![](/icons/71145de.gif)
显示方式
);
返回值 返回该窗口更新前
![](/icons/71145de.gif)
窗口状态
![](/icons/71145dou2.gif)
对先前可见
![](/icons/71145de.gif)
窗口
![](/icons/71145dou.gif)
其值为非零
![](/icons/71145dou2.gif)
对先前隐藏
![](/icons/71145de.gif)
窗口
![](/icons/71145dou.gif)
其值为零
显示方式(nCmdShow)可以是下列常量的
![](/icons/71145yi.gif)
:
类型 介绍说明
SW_HIDE 隐藏该窗口(并是另
![](/icons/71145yi.gif)
个窗口激活)
SW_MINIMIZE 使窗口变成图标(并激活窗口管理表
![](/icons/71145de.gif)
顶层窗口)
SW_SHOW 激活
![](/icons/71145yi.gif)
个窗口
![](/icons/71145dou.gif)
并根据其当前
![](/icons/71145de.gif)
尺寸和位置显示该窗口
SW_SHOWMAXIMIZED 激活并以全屏方式显示
![](/icons/71145yi.gif)
个窗口
SW_SHOWMINIMIZED 激活并以图标方式显示
![](/icons/71145yi.gif)
个窗口
SW_SHOWMINNOACTIVE 以图标方式显示
![](/icons/71145yi.gif)
个窗口
![](/icons/71145dou.gif)
当前活动
![](/icons/71145de.gif)
窗口仍保持活动
SW_SHOWNA 以当前状态显示
![](/icons/71145yi.gif)
个窗口
![](/icons/71145dou.gif)
当前活动
![](/icons/71145de.gif)
窗口仍保持活动
SW_SHOWNOACTIVE 以最近
![](/icons/71145de.gif)
大小和位置显示
![](/icons/71145yi.gif)
个窗口
![](/icons/71145dou.gif)
当前活动
![](/icons/71145de.gif)
窗口仍保持活动
SW_SHOWNORMAL 激活并显示
![](/icons/71145yi.gif)
个窗口
![](/icons/71145dou.gif)
若其为图标或全屏方式显示
![](/icons/71145dou.gif)
则恢复为它
![](/icons/71145de.gif)
原始大小和位置
SW_RESTORE 同SH_SHOWNORMAL
表1-3-2 UpdateWindow
![](/icons/71145hanshu.gif)
用 途 若应用
![](/icons/71145chengxu.gif)
![](/icons/71145de.gif)
消息队列中存在WM_PAINT消息(绘制用户区消息)
![](/icons/71145dou.gif)
则该
![](/icons/71145hanshu.gif)
使Windows立即
![](/icons/71145diaoyong.gif)
窗口
![](/icons/71145hanshu.gif)
![](/icons/71145dou.gif)
向其传递WM_PAINT
![](/icons/71145dou2.gif)
否则该
![](/icons/71145hanshu.gif)
不作为任何动作
原 型 VOID UpdateWindow(
HWND hWnd, 标识被刷新
![](/icons/71145de.gif)
窗口
![](/icons/71145de.gif)
句柄
);
返回值 无
表1-3-3 GetMessage
![](/icons/71145hanshu.gif)
用 途 从应用
![](/icons/71145chengxu.gif)
中
![](/icons/71145de.gif)
消息队列中检索
![](/icons/71145yi.gif)
条消息
原 型 BOOL GetMessage(
LPMSG lpMsg, 指向MSG类型
![](/icons/71145de.gif)
变量
![](/icons/71145de.gif)
远指针
![](/icons/71145dou.gif)
它包含有从应用
![](/icons/71145chengxu.gif)
消息队列中检索到
![](/icons/71145de.gif)
![](/icons/71145yi.gif)
条消息
![](/icons/71145de.gif)
数据
HWND hWnd, 指定为哪个窗口检索消息
![](/icons/71145dou.gif)
如果hWnd为NULL
![](/icons/71145dou.gif)
则检索
![](/icons/71145diaoyong.gif)
该
![](/icons/71145hanshu.gif)
![](/icons/71145de.gif)
应用
![](/icons/71145chengxu.gif)
![](/icons/71145de.gif)
所有
![](/icons/71145de.gif)
消息(不检索属于其它应用
![](/icons/71145chengxu.gif)
![](/icons/71145de.gif)
消息)
UINT wMin,
UINT wMax 以下两个基本参数指定检索在wMin和wMax范围内
![](/icons/71145de.gif)
消息
![](/icons/71145dou2.gif)
如果这两个参数都为零
![](/icons/71145dou.gif)
该
![](/icons/71145hanshu.gif)
检索所有
![](/icons/71145de.gif)
可用
![](/icons/71145de.gif)
消息
);
返回值 在检索出WM_QUIT消息时
![](/icons/71145dou.gif)
返回零值
![](/icons/71145dou.gif)
在其它情况下返回非零值
表1-3-4 DispatchMessage
![](/icons/71145hanshu.gif)
用 途 将消息发送到指定
![](/icons/71145de.gif)
窗口对象上(窗口
![](/icons/71145hanshu.gif)
被
![](/icons/71145diaoyong.gif)
)
原 型 LRESULT DispatchMessage(
LPCMSG lpMsg 指向MSG类型变量
![](/icons/71145de.gif)
远指针
![](/icons/71145dou.gif)
该变量中存储有来自应用
![](/icons/71145chengxu.gif)
消息队列中
![](/icons/71145de.gif)
消息
);
返回值 若有
![](/icons/71145yi.gif)
个WM_CHAR消息被放到应用
![](/icons/71145chengxu.gif)
![](/icons/71145de.gif)
消息队列中
![](/icons/71145dou.gif)
返回非零
![](/icons/71145dou.gif)
否则返回零
![](/icons/71145dou2.gif)
该
![](/icons/71145hanshu.gif)
不改变lpMsg所指向
![](/icons/71145de.gif)
变量中存储
![](/icons/71145de.gif)
消息数据
Windows
![](/icons/71145de.gif)
主
![](/icons/71145hanshu.gif)
都是首先以
![](/icons/71145chushi.gif)
化(注册类、创建对象等)这
![](/icons/71145yi.gif)
步开始
![](/icons/71145dou.gif)
而且紧跟着就是消息循环运行这
![](/icons/71145yi.gif)
步
![](/icons/71145dou2.gif)
这些步骤对所有
![](/icons/71145de.gif)
Windows应用
![](/icons/71145chengxu.gif)
都大同小异
![](/icons/71145dou2.gif)
Windows应用
![](/icons/71145chengxu.gif)
主要
![](/icons/71145de.gif)
区别点在窗口
![](/icons/71145hanshu.gif)
![](/icons/71145de.gif)
定义上
![](/icons/71145dou.gif)
由于
![](/icons/71145yi.gif)
个应用
![](/icons/71145chengxu.gif)
所解决
![](/icons/71145de.gif)
任务区别
![](/icons/71145dou.gif)
它
![](/icons/71145de.gif)
窗口
![](/icons/71145hanshu.gif)
对消息
![](/icons/71145de.gif)
处理方式也就不相同
![](/icons/71145dou.gif)
因而每个应用
![](/icons/71145chengxu.gif)
需要定义区别
![](/icons/71145de.gif)
窗口
![](/icons/71145hanshu.gif)
![](/icons/71145dou2.gif)
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
WM_DESTROY:
PostQuitMessage(0):
0;
}
DefWindowProc(hwnd, message, wParam, lParam);
}
这个窗口
![](/icons/71145hanshu.gif)
仅处理
![](/icons/71145yi.gif)
条WM_DESTROY消息
![](/icons/71145dou2.gif)
这条消息是在用户关闭了屏幕上
![](/icons/71145de.gif)
窗口时
![](/icons/71145dou.gif)
Windows发送给窗口对象
![](/icons/71145de.gif)
![](/icons/71145dou2.gif)
该
![](/icons/71145hanshu.gif)
对这条消息
![](/icons/71145de.gif)
处理只是简单地
![](/icons/71145diaoyong.gif)
Windows
![](/icons/71145hanshu.gif)
PostQuitMessage
![](/icons/71145dou2.gif)
表1-4给出了
![](/icons/71145hanshu.gif)
PostQuitMessage
![](/icons/71145de.gif)
介绍说明
![](/icons/71145dou2.gif)
当主
![](/icons/71145hanshu.gif)
![](/icons/71145de.gif)
消息循环中
![](/icons/71145de.gif)
GetMessage
![](/icons/71145hanshu.gif)
检索出WM_QUIT消息时
![](/icons/71145dou.gif)
![](/icons/71145hanshu.gif)
GetMessage返回零
![](/icons/71145dou.gif)
这样
![](/icons/71145dou.gif)
消息循环终止
![](/icons/71145dou.gif)
![](/icons/71145chengxu.gif)
也随的被终止
![](/icons/71145dou2.gif)
存储消息数据
![](/icons/71145de.gif)
变量msg
![](/icons/71145de.gif)
wParam域
![](/icons/71145de.gif)
值是在
![](/icons/71145diaoyong.gif)
![](/icons/71145hanshu.gif)
PostQuitMessage时所提供
![](/icons/71145de.gif)
实参
![](/icons/71145de.gif)
值
![](/icons/71145dou2.gif)
如果
![](/icons/71145chengxu.gif)
正常结束
![](/icons/71145dou.gif)
![](/icons/71145diaoyong.gif)
PostQuitMessage
![](/icons/71145hanshu.gif)
时使用零作为该
![](/icons/71145hanshu.gif)
![](/icons/71145de.gif)
参数
![](/icons/71145dou.gif)
如果需要表示
![](/icons/71145chengxu.gif)
由于出现了异常或
![](/icons/71145cuowu.gif)
而必须终止时
![](/icons/71145dou.gif)
使用非零值(
![](/icons/71145yi.gif)
般使用-1)作为该
![](/icons/71145hanshu.gif)
![](/icons/71145de.gif)
参数
![](/icons/71145dou2.gif)
在
![](/icons/71145diaoyong.gif)
PostQuitMessage使用
![](/icons/71145de.gif)
参数值被主
![](/icons/71145hanshu.gif)
用语句:
![](/icons/71145return.gif)
msg.wParam;
返回给Windows
![](/icons/71145dou.gif)
供Windows或其它应用
![](/icons/71145chengxu.gif)
使用
![](/icons/71145dou2.gif)
因此
![](/icons/71145dou.gif)
我们也称PostQuitMessage使用
![](/icons/71145de.gif)
参数为
![](/icons/71145chengxu.gif)
![](/icons/71145de.gif)
退出码
![](/icons/71145dou2.gif)
表1-4 PostQuitMessage
![](/icons/71145hanshu.gif)
用 途 通知Windows
![](/icons/71145dou.gif)
应用
![](/icons/71145chengxu.gif)
希望中止
![](/icons/71145dou2.gif)
它
![](/icons/71145yi.gif)
般用于响应WM_DESTROY消息
![](/icons/71145dou2.gif)
该
![](/icons/71145hanshu.gif)
将消息WM_QUIT消息放入应用
![](/icons/71145chengxu.gif)
![](/icons/71145de.gif)
消息队列中
原 型 PostQuitMessage(
![](/icons/71145int.gif)
nExitCode 指定应用
![](/icons/71145chengxu.gif)
![](/icons/71145de.gif)
退出代码
![](/icons/71145dou.gif)
它用作WM_QUIT消息
![](/icons/71145de.gif)
wParam参数
);
返回值 无
小结
首先介绍了图形用户界面
![](/icons/71145de.gif)
优点和面向对象
![](/icons/71145de.gif)
![](/icons/71145chengxu.gif)
设计思路方法
![](/icons/71145dou2.gif)
从某种意义上说
![](/icons/71145dou.gif)
Windows是面向对象
![](/icons/71145de.gif)
![](/icons/71145dou.gif)
它主要建立在把窗口作为
![](/icons/71145yi.gif)
个对象
![](/icons/71145de.gif)
概念上
![](/icons/71145dou2.gif)
窗口的间通过消息进行消息传递
![](/icons/71145dou2.gif)
Windows支持直接操作技术
![](/icons/71145dou2.gif)
直接操作是对屏幕对象
![](/icons/71145de.gif)
操作
![](/icons/71145dou.gif)
数据和
![](/icons/71145hanshu.gif)
![](/icons/71145de.gif)
封装允许该对象自己响应它们接收到
![](/icons/71145de.gif)
消息
![](/icons/71145dou2.gif)
在用户界面上发生
![](/icons/71145de.gif)
任何事件被作为消息发送给窗口对象
![](/icons/71145dou2.gif)
![](/icons/71145chengxu.gif)
员在设计
![](/icons/71145chengxu.gif)
时
![](/icons/71145dou.gif)
只须关心
![](/icons/71145yi.gif)
个对象要接受哪些消息和怎样处理这些消息
![](/icons/71145dou2.gif)
消息传递工作由Windows负责
![](/icons/71145dou2.gif)
因而
![](/icons/71145dou.gif)
使用Windows操作环境可以极大地方便
![](/icons/71145chengxu.gif)
开发用户界面
![](/icons/71145de.gif)
工作
![](/icons/71145dou.gif)
并使
![](/icons/71145chengxu.gif)
![](/icons/71145de.gif)
结构合理、模块化
![](/icons/71145chengxu.gif)
高
![](/icons/71145dou2.gif)
更重要
![](/icons/71145de.gif)
是
![](/icons/71145dou.gif)
支持直接操作技术
![](/icons/71145de.gif)
Windows支持用户进行有创造性
![](/icons/71145de.gif)
界面设计
延伸阅读
最新评论