Dos的过程驱动与Windows的事件驱动
在讲本程序的消息循环之前,我想先谈一下Dos与Windows驱动机制的区别:
DOS程序主要使用顺序的,过程驱动的程序设计方法。顺序的,过程驱动的程序有一个明显的开始,明显的过程及一个明显的结束,因此程序能直接控制程序事件或过程的顺序。虽然在顺序的过程驱动的程序中也有很多处理异常的方法,但这样的异常处理也仍然是顺序的,过程驱动的结构。
而Windows的驱动方式是事件驱动,就是不由事件的顺序来控制,而是由事件的发生来控制,所有的事件是无序的,所为一个程序员,在你编写程序时,你并不知道用户先按哪个按纽,也不知道程序先触发哪个消息。你的任务就是对正在开发的应用程序要发出或要接收的消息进行排序和管理。事件驱动程序设计是密切围绕消息的产生与处理而展开的,一条消息是关于发生的事件的消息。
Windows编程的特点:C语言编程至少有一个主程序,其名字是main()。Windows程序则至少两个主程序,一个是WinMain(),
int WINAPI WinMain( HINSTANCE hInstance, // handle to current instance HINSTANCE hPrevInstance, // handle to previous instance LPSTR lpCmdLine, // pointer to command line int nCmdShow // show state of window );另一个是窗口过程函数WindowProc,它的函数原型为:
LRESULT CALLBACK WindowProc( HWND hwnd, // handle to window UINT uMsg, // message identifier WPARAM wParam, // first message parameter LPARAM lParam // second message parameter );Windows应用程序的编程就围绕这两个部份进行的。其中WinMain函数为应用程序的入口点,它的名字一定要是WinMain。
在Windows中,应用程序通过要求Windows完成指定操作,而承担这项通信任务的API函数就是Windows的相应窗口函数WindowProc。在dos里,程序能直接控制事件的发生顺序,结果等。而在Windows里,应用程序不直接调用任何窗口函数,而是等待Windows调用窗口函数,请求完成任务或返回信息。为保证Windows调用这个窗口函数,这个函数必须先向Windows登记,然后在Windows实施相应操作时回调,所以窗口函数又称为回调函数。WindowProc是一个主回调函数,Windows至少有一个回调函数。
回调函数WindowProc在哪里定义的呢,请看这个语句:wc.lpfnWndProc = WindowProc ;将在第七讲里详谈.
实例:在Windows中,能多次同时运行同一个应用程序,即运行多个副本,每个副本叫做一个“实例”。
现在让我们把这个程序层层剥解开来,我把自己的理解慢慢地展示给你:
Win32编程步骤:我把这个程序支解为四块:(一)建立,注册窗口类.(二)创建窗口.(三)显示和更新窗口.(四)创建消息循环.(五)终止应用程序.(六)窗口过程.(七)处理消息.
(一)注册窗口类:(1)建立窗口类
WinMain()是程序的入口,它相当于一个中介人的角色,把应用程序(指小窗口)介绍给windows.首要的一步是登记应用程序的窗口类.
窗口种类是定义窗口属性的模板,这些属性包括窗口式样,鼠标形状,菜单等等,窗口种类也指定处理该类中所有窗口消息的窗口函数.只有先建立窗口种类,才能根据窗口种类来创建Windows应用程序的一个或多个窗口.创建窗口时,还可以指定窗口独有的附加特性.窗口种类简称窗口类,窗口类不能重名.在建立窗口类后,必须向Windows登记.
建立窗口类就是用WNDCLASS结构定义一个结构变量,在这个程序中就是指 WNDCLASS wc ;然后用自己设计的窗口属性的信息填充结构变量wc的域.
要WinMain登记窗口类,首先要填写一个WNDCLASS结构,其定义如下所示:
typedef struct _WNDCLASSA { UINT style ; //窗口类风格 WNDPROC lpfnWndProc ; //指向窗口过程函数的指针 int cbClsExtra ; //窗口类附加数据 int cbWndExtra ; //窗口附加数据 HINSTANCE hInstance ; //拥有窗口类的实例句柄 HICON hIcon ; //最小窗口图标 HCURSOR hCursor ; //窗口内使用的光标 HBRUSH hbrBackground ; //用来着色窗口背景的刷子 LPCSTR lpszMenuName ; //指向菜单资源名的指针 LPCSTR lpszClassName ; // 指向窗口类名的指针 }WNDCLASS; // 加强版 typedef struct _WNDCLASSEX { UINT cbSize; UINT style; WNDPROC lpfnWndProc; int cbClsExtra; int cbWndExtra; HANDLE hInstance; HICON hIcon; HCURSOR hCursor; HBRUSH hbrBackground; LPCTSTR lpszMenuName; LPCTSTR lpszClassName; HICON hIconSm; } WNDCLASSEX;在VC6.0里面,把光标定位在WNDCLASS上,按F1,即可启动MSDN,在MSDN里你可看到这个结构原形.在下节讲解这些参数在本程序中的具体用法.
(2)注册窗口类