侯俊杰先生说,了解Win32程序设计基本原理有助于MFC程序设计的学习。
Windows程序的进行依靠外部发生的事件来驱动。程序不断等待,等待任何可能的输入,然后做判断,然后再做判断,然后再做适当的处理。
输入是由操作系统捕捉到之后,以消息形式(一种数据结构)进入程序之中。操作系统如何捕捉外围设备(如键盘和鼠标)所发生的事件呢?USER模块掌握各个外围的驱动程序,它们各有侦测循环。
输入分为由硬件装置所产生的消息(如鼠标移动或键盘被按下)以及由windows系统或其它windows程序传送过来的消息。
程序调用GetMessage API取得一个消息,程序声明全靠它来驱动。
消息是windows内设的一种数据结构,类型为MSG。定义如下:
typedef struct tagMSG { HWND hwnd; UINT message; //表现形式为VM_*** WPARAM wParam; LPARAM lParaml; DWORD time; POINT pt; }MSG;
接受并处理消息的主角就是窗口。每一个窗口都应该有一个函数负责处理消息,程序员必须设计这个所谓的“窗口函数”,如果窗口获得一个消息,则这个窗口函数必须判断消息的类别,决定处理的方式。
Win32程序关键处有“程序进入点WinMain”,“窗口注册与产生”,“消息循环”,“窗口函数”,“对话框”,“RC文件”。
WinMain是Windows程序的进入点: int CALLBACK WinMain(HINSTANCE Hinstance, HINSTANCE hPrecInstace, LPSTR lpCmdLine, int nCmdShow) { … }
在Win32中CALLBACK被定义为_stdcall,是一种函数调用习惯,关系到参数进入到栈的次序,以及处理堆栈的责任归属。其它的函数调用习惯还有_pascal和_cdecl。四个参数由操作系统传进来。
消息循环一开始,Windows程序必须做一些初始化操作,为的是产生应用程序的工作舞台---窗口。在使用CreateWindow函数创建窗口前要设置窗口的属性及注册属性设置好的窗口,即窗口的外貌和行为。接收消息后的反应就是行为(窗口函数)。
其中,WNDCLASS类的对象的数据成员lpfnWndProc所指定的函数就是窗口的行为中枢,即所谓的窗口函数,再者CreateWindow只产生窗口不显示窗口,需要用ShowWind将产生的窗口显示在屏幕上。如果希望驱动窗口的绘图操作就调用UpdateWindow函数先传送一个WM_PAINT给窗口。
初始化完成后WinMain进入所谓的消息循环:
While (GetMessage(&msg,…)) { //转换键盘消息 TranslateMessage(&msg); //分派消息,传递消息给窗口函数 DispatchMessage(&msg); }
当消息发生时,操作系统根据当时状态为它标明了所属窗口,而窗口所属的窗口类又已经明白表示了窗口函数(lpfnWndProc指定的函数),所以DispatchMesage函数知道传递给那个窗口函数。
消息循环中的DispatchMessage通过USER模块的协助把消息分配到发生事件窗口的窗口函数上去了。窗口函数通常利用switch/case的方式 方式判断消息种类以决定处置方式。窗口函数并不会在程序中被调用,因为它是一种call back函数,它是由windows系统调用的,不必不能被显示调用。
窗口函数的形式如下:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
不论什么消息,在窗口处理函数中都要有处理方式,所以默认的DefWindowPro函数不要忘了加在default后面。
分类
1. 令其父窗口无效,直到对话框结束。这种称为modal对话框。
2. 父窗口与对话框共同运行。这种称为modeless对话框。
常用的是modal对话框。
为做出一个对话框,windows程序员需要准备两个东西:
1. 对话框模板。这是一个定义在RC文件中的对话框外貌,以各种方式决定对话框的大小、字形、内部有哪些控件、各在什么位置等等。
2. 对话框函数。其形态相似与窗口函数,它通常只处理WM_INITDLALOG和WM_COMMAND两个消息。对话框里各个控件也是小窗口,各有窗口函数。所有的控件的消息都是WM_COMMAND的,再由参数分辨是哪一个控件及哪一种消息类型。
Modal对话框
Modal对话框的激活与结束,靠的是DialogBox和EndDialog两个API函数。
这个时候再去看懂诸如《深入浅出MFC》第一章所讲解的一个Win32程序例子,对MFC的内部实现或者是理解就会加深一些,不信可以试试哦。
此次笔记记录完毕。