熬之滴水穿石:一切从windows编程开始(3)

来源:互联网 发布:ubuntu备份文件命令 编辑:程序博客网 时间:2024/04/28 04:15

                       3--对于windows的任务处理模型的认识

要想真正的掌握windows编程,实际上还是需要从winodws的任务处理架构开始的。

在windows操作系统中有许多程序在运行,它提供了一个多任务可运行的架构,实际上就是采取事件驱动的模式。这种模式诠释起来就是有特定的事件发生时,操作系统是需要知道在它管辖范围内哪些程序可以处理这个事件的。所以系统和程序之间的是需要一样东西来维系,而这个东西被我们称为消息(Message)。操作系统其实就是分派消息给程序去处理的。这些消息都是通过数据结构来装载的。

typedef struct tagMSG {
           HWND hwnd;
           UINT message;
           WPARAM wParam;
           LPARAM lParam;
           DWORD time;
           POINT pt;
         } MSG;

在这个package里有好几个字段,这些字段都是最为重要和关键的。我们可以想象在一个装载数个应用程序的系统里,所有处理机制就依靠着这些package的信息来处理的。这个消息结构里面,WPARAM和LPARAM存储的就是除事件之外的一些信息,这些信息能够保证该条消息能够正常的处理。例如像输入字符,或者记录鼠标所在位置之类的信息就可以存储在该字段中了。当以事件为驱动的windows机制,在事件触发后就会转换成相关的message内容保存下来,这里面最为重要的一个参数就是HWND,该参数就是个句柄,这个句柄可以让系统知道,该消息从哪来又知道他能到哪去。当然处理这些消息最为核心的机制还是消息队列,我们常说的MESSAGE QUENE。这个队列就是用来装载在系统里漫天飞舞的消息,并且让他们根据请求时间形成有序。等待它们的相应的程序来处理,这样一来消息就不会被丢弃。

关于上面提起的消息结构体,实际上这种介质在windows里是普遍存在的。在windows系统里,窗口是主要表现形式,所以对于窗口信息的保存其实也是一个package.

看看窗口消息结构

typedef struct tagWNDCLASSA {

  UINT style;

  WNDPROC lpfnWndProc;

  int cbClsExtra;

  int cbWndExtra;

  HINSTANCE hInstance;

  HICON hIcon;

  HCURSOR hCursor;

  HBRUSH hbrBackground;

  LPCSTR lpszMenuName;

  LPCSTR lpszClassName;

  };

和之前看到的message一样,它也是由各个字段组成的,每个字段都有特定的意义。像style该字段就是说窗口样式的,其它的像窗口的位置、大小、颜色、光标使用的颜色等参数!这些都可以在上述描述的字段中找出来!注意第一个字段lpszClassName,这个字段很有意义,它是用于窗口创建时向系统环境注册的标识。也就是说窗口创建之初就会在系统环境中进行注册,注册后就会形成了标识。当事件处理时能够通过 lpszClassName 的值在注册信息表里找到窗口的句柄,从而派发消息。windows系统提供了许许多多的函数来处理各类消息,但是消息处理都是step的方式,那么怎么让windows系统知道下一步调用的方法了,这里就涉及到了一个我们在处理问题经常用到的一个方法:回调!当然具备这个方法的函数被称为回调函数。


不过,在这个字段中最为重要的还是处理这个窗口的消息地址了,也就是常说的回调函数!回调函数最为关键的还是原型的函数,在windows系统最为重要的就是它的参数格式了。我们通过tagWNDCLASSA 可以看到有一个叫lpfnWndProc的参数,该参数实际上就是一个指针,用来存储函数的地址。那么这个回调函数是怎样的一个样子呢:LRESULT CALLBACK WindowProc (HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);其中hwnd是窗口的句柄。uMsg:消息类型。wParam和IParam装载相关的窗体信息。在tagWNDCLASSA 中有这个可回调的字段,可以这么理解,当程序遵照约定把消息装载了lpfnWndProc字段后,那么应用程序就等待着这个窗口事件发生后去执行系统的调用了,回调函数是有返回结果的。所有的消息MESSAGE都是有属于自己的唯一ID的,像窗口创建,窗口销毁这样的消息了。所以windows系统的消息有一大堆的枚举,我们所做的事情就是需知道消息ID代表着什么意思,就可以去写相应的代码了。

说了这么多,也许并未把问题描述清楚。其实掌握WINDOWS的处理机制,关键知道其生命周期。世间万事万物都有一个规律,有开始便会有结束!抓住这样一条主线,任何框架都会掌握。那么我就以一个应用程序窗口为例,从开始到结束走一遭吧,以程序的思路。

1)程序在创建时就会注册窗口信息,注册窗口类名信息存储在windowsclassinfo中。

方法:RegisterClass(CONST WNDCLASS *lpWndClass);

      CreateWindow(LPCTSTR lpClassName,LPCTSTR lpWindowName,DWORD dwStyle,int x,int y,int nWidth,int nHeight,HWND hWndParent,HMENU hMenu,HANDLE hlnstance,LPVOID lpParam)

2)当程序要创建窗口时,操作系统便已在注册的类中windowclassinfo中的lpszclassinfo的信息。

3)根据lpszclassinfo的信息查找到此窗口的数据结构然后创建属于该数据特征的窗口。

4)当操作系统产生事件后,便根据消息MESSAGE中的hwnd字段,查找windowclassinfo的数据结构

然后再回调该结构上的lpfnWndProc字段进行回调。

如果对以上步骤熟悉了,我觉得windows编程基本上奠定了基础,当然要成为精通之类的coder还是需要知道更多API

                                                                  (未完待续..........)

原创粉丝点击