| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 3522 人关注过本帖, 1 人收藏
标题:[转载] Read Events 的奥秘
只看楼主 加入收藏
xinjie
Rank: 7Rank: 7Rank: 7
等 级:贵宾
威 望:19
帖 子:274
专家分:520
注 册:2007-8-11
结帖率:80%
收藏(1)
 问题点数:0 回复次数:7 
[转载] Read Events 的奥秘
转自:http://www.gz9f.com/bbs/dispbbs.asp?boardID=1&ID=273673&page=2
作者:古金楠

我的上一封帖子《小聊致命错误C0000005》,自己主观来判断,至少有80%的网友没有足够的耐心完整地阅读之。这次,我吸取了教训,将本贴的中心思想写在文章的开始:
VFP 3.0 的 Read Events 命令机制,实际上是为 FoxPro2.5/2.6 for Windows 程序员提供一种选择权:
是通过自己的 Do While + Do Case 语句结构 所构成的 基于事件响应的机制来编写应用程序,还是将消息循环与事件响应 通过 Read Events 语句 来交给VFP和Windows 自动去处理。

本贴正文开始……

以下是引用qyqmhh在2005-3-18 17:54:06的发言:
大家都知道,运行vfp表单后,必须紧跟read event语句,否则编译后就是一闪而过, 可是我就是不明白,vfp为什么要这样设计。其他语言都不需要这么做的。 欢迎大家深入讨论!!!

问这个问题的人是真正具备程序员思想境界的人,将来毕竟是位了不起的高人。因此我愿意花时间来详细解释。将来你成为大师了,甭多,送给我辆奔驰,我就知足了:)
这件事说来话长。
我将首先告诉你Read Events命令在C代码中是如何做到的(VFP早期版本是用C语言编写的,后期版本逐渐增加了些C++代码);在本贴的后面,将向你详细解释VFP开发小组为什么要这样设计。

解释VFP中的Read Events命令机制一直以来是个难题,就像数学中证明1+1=2一样。因为多数VFP程序员不了解 C语言、和Windows消息机制。如果很不幸,你恰好就是这样的话,那么看本贴的时候一直要硬着头皮读下去,千万不要中途放弃。
Read Events在底层是通过调用Windows API 函数 GetMessage 和 DispatchMessage来实现的,当你在VFP中写下Read Events命令时,在程序运行期间,这段代码将被解释器中的如下C代码来解释:

While(GetMessage(&MSG,<其它参数>)){
TranslateMessage(&MSG);
DispatchMessage(&MSG);
}

你可以通过从VFPxR.DLL导出Windows API函数的方式看到上面的API函数,它们的宿主库是USER32.DLL。
C for Windows 程序员都知道上面代码的涵义,该While语句用于开始响应Windows消息循环,参数MSG是个结构体(C语言中的结构体实际上就是VFP中的数组),该结构体的第一个成员记录了一个窗口的句柄,Windows操作系统会通过该句柄查找相对应窗口的窗体过程函数。
如果你是个 C 程序员的话,你不妨作个试验:在VC中随便打开一个已存在的工程,除控制台应用程序外,每个有Windows界面的WIN32应用程序都存在上面的C代码(对于MFC程序而言,上面的代码被CWinApp类的成员函数Run()封装了起来),请找到这些代码,然后将其注释掉,重新编译EXE。
再运行后,你将会发现VFP经典的“一闪而过”的问题在VC中重现了!按下组合键Ctrl+Alt+Delete打开Windows任务管理器,你会发现该应用程序实际上仍在运行中,这种症状真的和缺少Read Events命令的VFP应用程序一摸一样!
VFP中的CLEAR EVENTS命令,在底层是调用Windows API函数PostQuitMessage来实现的,用于结束Windows窗口消息循环。
如果上面的解释你看不懂,没有关系,你只需要知道一点就可以了:对于所有需要Windows界面的应用程序而言,都需要有响应Windows消息循环的代码。
接下来该解释为什么VFP3.0开发小组要这样设计了。
的确,对于幸运的VB、Delphi程序员来讲,他们不存在这样的烦恼。因为应用程序底层当遇到窗体对象时,便会自动加上响应消息循环的代码。那么为什么惟独VFP要这样“个色”呢?
如果你了解FoxPro的历史,就不难想象其中的奥秘。
我们知道,当年所诞生的Delphi和VB,就像时下的C#一样,不存在历史代码兼容性的负担。VB和Basic一点也不一样,但VFP就不同了。从面向过程的FoxPro for Dos到面向对象的VFP3.0之间,存在两个过渡的版本FoxPro2.5/2.6 for Windows。
在折中性的版本for WIN2.5/2.6中,如果想将应用程序设计成基于事件响应的模式,你就必须这样设计你的代码:

DEFINE WINDOW ……
ACTIVE WINDOW ……
DO WHILE .T.
DO CASE
CASE 鼠标滑动
则……
CASE 鼠标左键单击
则……
CASE 鼠标左键双击
则……
CASE INKEY(0)
则……
CASE INKEY(27)
则…………

(当然,上述代码在for DOS2.5/2.6版本中同样有效。)
在你打开VFP帮助文件,找到DEFINE WINDOW命令时,你会惊讶地发现该命令甚至比DEFINE CLASS AS FORM 命令还要丰富。
当年FoxPro程序员多如牛毛,其历史遗留下来的代码不计其数。理想总要对现实进行妥协,如果换做我们是微软的决策者,那么我们当年是否也会决定兼容老版本的代码呢?
Read Events机制提供了一种灵活性,使你依旧可以按照传统的基于事件响应的方式编程(即用Do While + Do Case语句来代替Read Events),这就实现了VFP3.0开发小组的诺言:从老版本升级到3.0,您不用修改一行代码。
换句话说:VFP3.0的Read Events命令机制,实际上是为FoxPro2.5/2.6 for Windows程序员提供一种选择权:是通过自己的Do While + Do Case 语句结构所构成的基于事件响应的机制来编写应用程序,还是将消息循环与事件响应通过Read Events语句来交给VFP和Windows自动去处理。
这样一来,Read Events就成了VFP的传统,就像当年3.0需要兼容老版本代码一样,现在的8.0/9.0新版,反而要考虑兼容Read Events机制了 :)
搜索更多相关主题的帖子: Events Read 
2007-09-15 00:24
baichuan
Rank: 7Rank: 7Rank: 7
等 级:贵宾
威 望:37
帖 子:953
专家分:589
注 册:2006-3-13
收藏
得分:0 
没说明白!

2007-09-15 08:14
hu9jj
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:红土地
等 级:贵宾
威 望:400
帖 子:11857
专家分:43421
注 册:2006-5-13
收藏
得分:0 

感谢楼主的详细介绍!以前只知道作用,但不知道为什么。


活到老,学到老!http://www.(该域名已经被ISP盗卖了)E-mail:hu-jj@
2007-09-15 21:15
xs591222
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:28
帖 子:682
专家分:1299
注 册:2009-3-1
收藏
得分:0 
还是雾里看花了眼
2011-12-23 19:38
ZJH_88
Rank: 1
等 级:新手上路
帖 子:4
专家分:0
注 册:2012-9-2
收藏
得分:0 
精辟,民间还是有高人。
2012-09-02 11:57
xcmzl
Rank: 1
等 级:新手上路
帖 子:8
专家分:3
注 册:2012-7-27
收藏
得分:0 
雾里看花
2012-09-27 08:38
daidai120
Rank: 1
等 级:新手上路
帖 子:14
专家分:0
注 册:2013-11-10
收藏
得分:0 
提示: 该帖被管理员或版主屏蔽
2013-11-10 14:13
Sam38
Rank: 1
等 级:新手上路
帖 子:19
专家分:0
注 册:2007-5-12
收藏
得分:0 
果然说明得很详细!

我的邮箱:Dahong38@ 我的QQ号:362879662 中国VFP专业论坛:www.
2016-12-14 11:12
快速回复:[转载] Read Events 的奥秘
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.037293 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved