如何设计和驱动多任务执行环境(摘抄自inside Vcl)

如何设计和驱动多任务执行环境

这一节描述,一个单任务的操作系统,以一个大型的循环(loop),不断的检查每一个应用程序是否触发了特定的事件,如鼠标,键盘。然后否定其运行效率及反应速度
( ?) 这里所说的事件驱动式操作系统是如何运作,是不是也由一个loop来检测机器的当前事件,然后将事件转化成消息(Message),然后分派给正确的应用程序来处理。

消息结构:
MyMessage = packed record
  Hwnd :HWND; //消息触发窗口句柄
  MessageID : Longint; //事件id
  wParam : Longint; // 封装事件额外信息
  lParam : Longint; // 封装事件额外信息
  time : Longint; //事件发生事件
  pt : TPont; //存储鼠标的全域坐标
end;

这节作者提出了3个问题
1. 应用程序可能拥有多个窗口,如何把触发的消息分派给正确的窗口区处理?
2. 把消息分派给应用程序或者窗口是如何办到的?
3. 分派了消息给窗口之后,窗口药如何处理此消息?

解答:
1.仔细看上面的消息结构MyMessage, 窗口句柄解决了第一个问题,由于句柄的唯一性.所以根据得到的消息触发窗口句柄,可以知道消息所对应的窗口.
我们的执行环境为每个应用程序建立一个消息队列(Message Queue),当事件发生时,执行环境久把代表他的消息分派到此消息队列中,等待应用程序从其中取出并处理.如此,程序就可以应付快速产生的数个事件而不会丢失消息.

2.窗口信息数据结构:
MyWindowClassInfo =packed record
  Style:UINT; //窗口的类型
  iWidth:integer; //窗口的宽
  iHeight:integer; //窗口的高
  lpfnWndProc:Pointer; //回调函数,窗体消息处理函数的指针
  hIcon:HICON;
  hCursor:HCURSOR; //窗口使用的光标种类
  hbrBackground:HBRUSH;//背景颜色
  lpszMenuName:PAnsiChar; //
  lpszClassName:PAnsiChar; //窗体类名
  hIconSm:HICON;
end;
当窗口发生事件并由执行环境转换为消息后,接下来就是要应用程序中对应的窗口来处理这个消息了,要让窗口处理消息最简单的方法就是让执行环境调用窗口提供的函数,并且传递消息给此函数来处理,但问题时要如何方窗口提供函数给执行环境,执行环境才能够知道在消息产生后要调用什么函数.
MyWindowClassInfo数据结构中有一个lpfnWndProc字段是一个Pointer类型的字段,代表应用程序可以把任何的函数地址指定给此字段以代表可以处理此窗口消息的函数.由于这个函数会有执行环境调用,这种函数也被称为回调函数(Callback Routine).
由于执行环境在调用应用程序提供的回调函数时必须传递和消息相关的信息给此函数,因此执行环境必须定义此函数的原型(Prototype):
function WindowProc(
  Window:HWnd; //窗口句柄
  AMessage:UNIT; //分派的消息
  Wparam:WPARAM;
  Lparam:LPARAM
): LRESULT;stdcall;export;

当应用程序遵照回调函数的原型,提供了适当的处理窗体消息函数并指定给MyWindowClassInfo中的lpfnWindProc字段,那么应用程序就可以在窗体事件触发后自动调用这个回调函数来处理消息了

3.这个问题由如下源代码实现:
case AMessage of
  WM_PAINT //窗体重画
  .. .. ..
  WM_DESTROY//窗体销毁
  .. .. ..

posted on 2004-06-15 17:37  khan  阅读(765)  评论(0编辑  收藏  举报

导航