当用户进行了输入或是窗口的状态发生改变时,系统都会发送消息 到某一个窗口。例如当选中某菜单命令之后会发送WM COMMAND消息, NPARAMI的高字(HIWORD(wParam)中是命令的ID号,对菜单来讲 就是菜单D。当然用户也可以定义自己的消息名称,并利用自定义消息 来发送通知和传送数据。 一个消息必须由一个窗口接收。在窗口的过程(NDPROC)中可 以对消息进行分析,对自己感兴趣的消息进行处理。例如你希望对菜单 选择进行处理,那么你可以定义对NM COMMAND消息进行处理的代 码;如果希望在窗口中进行图形输出,就必须对VM PAINT消息进行处 理。 Microsoft为窗口编写了默认的窗口过程,该过程负责处理那些你不 处理的消息。正因为有了这个默认窗口过程,我们才可以利用Windows 的窗口进行开发而不必过多关注窗口各种消息的处理。例如窗口在被拖 动时会发送很多消息,而我们都可以不予理睬,让系统自己去处理。 说到消息就不能不说窗口句柄。系统通过窗口句柄在整个系统中唯 一标识一个窗口,发送一个消息时必须指定一个窗口句柄,表明该消息 由那个窗口接收。每个窗口都有自己的窗口过程,所以用户的输入就会 被正确地处理
⚫ 当用户进行了输入或是窗口的状态发生改变时,系统都会发送消息 到某一个窗口。例如当选中某菜单命令之后会发送WM_COMMAND消息, WPARAM的高字(HIWORD(wParam)中是命令的ID号,对菜单来讲 就是菜单ID。当然用户也可以定义自己的消息名称,并利用自定义消息 来发送通知和传送数据。 ⚫ 一个消息必须由一个窗口接收。在窗口的过程( WNDPROC)中可 以对消息进行分析,对自己感兴趣的消息进行处理。例如你希望对菜单 选择进行处理,那么你可以定义对WM_ COMMAND消息进行处理的代 码;如果希望在窗口中进行图形输出,就必须对WM_PAINT消息进行处 理。 ⚫ Microsoft为窗口编写了默认的窗口过程,该过程负责处理那些你不 处理的消息。正因为有了这个默认窗口过程,我们才可以利用Windows 的窗口进行开发而不必过多关注窗口各种消息的处理。例如窗口在被拖 动时会发送很多消息,而我们都可以不予理睬,让系统自己去处理。 ⚫ 说到消息就不能不说窗口句柄。系统通过窗口句柄在整个系统中唯 一标识一个窗口,发送一个消息时必须指定一个窗口句柄,表明该消息 由那个窗口接收。每个窗口都有自己的窗口过程,所以用户的输入就会 被正确地处理
。下面有一段伪代码演示如何在窗口过程中处理消息: LONG WndProc(HWND hwnd,UINT MessageType,WPARAM LPARAM switch (MessageType) {/∥使用SWITCH语句将各种消息分开 case (WM PAINT): do YourWindow(.);∥在窗口需要重新绘制时进行输出 break case(WM LBUTTONDOWN): do Your Work(..)∥在鼠标左键被按下时进行处理 break; default: callDefault WndProc(.);∥对于其他情况就让系统自己 处理 break;
⚫ 下面有一段伪代码演示如何在窗口过程中处理消息: ⚫ LONG WndProc(HWND hwnd , UINT MessageType ,WPARAM , LPARAM) ⚫ { ⚫ switch(MessageType) ⚫ {// 使用SWITCH语句将各种消息分开 ⚫ case(WM_PAINT): ⚫ doYourWindow(…); // 在窗口需要重新绘制时进行输出 ⚫ break ; ⚫ case (WM_LBUTTONDOWN): ⚫ doYourWork(…)//在鼠标左键被按下时进行处理 ⚫ break ; ⚫ default: ⚫ callDefaultWndProc(…) ; // 对于其他情况就让系统自己 处理 ⚫ break; ⚫ } }
系统将维护一个或多个消息队列,所有产生的消息都会被放 入或是插入队列中。系统会在队列中取出每一条消息,根据消息 的接收句柄将该消息发送给拥有该窗口的程序的消息循环。每一 个运行的程序都有自己的消息循环,在循环中得到属于自己的消 息并根据接收窗口的句柄调用相应的窗口过程。而在没有消息时 消息循环就将控制权交给系统,所以Windows可以同时进行多个 任务。下面的伪代码演示了消息循环的用法: While (1) id=getMessage if (id==quit) break: translateMessage (...) 当该程序没有消息通知时,getMessage就不会返回,也就不会占用系 统的CPU时间
系统将维护一个或多个消息队列,所有产生的消息都会被放 入或是插入队列中。系统会在队列中取出每一条消息,根据消息 的接收句柄将该消息发送给拥有该窗口的程序的消息循环。每一 个运行的程序都有自己的消息循环,在循环中得到属于自己的消 息并根据接收窗口的句柄调用相应的窗口过程。而在没有消息时 消息循环就将控制权交给系统,所以Windows可以同时进行多个 任务。下面的伪代码演示了消息循环的用法: While(1) { id=getMessage(…); if(id==quit) break; translateMessage(…); } 当该程序没有消息通知时,getMessage就不会返回,也就不会占用系 统的CPU时间
。二、协同式多任务与抢先式多任务系统 在16位的操作系统中只有一个消息队列,所以系统必须等待当 前任务处理消息后才可以发送下一消息到相应程序,如果一个 程序陷入死循环或是操作超时,系统就得不到控制权。这种多 任务系统被称为协同式多任务系统。Windows3x就是这种系 统。 而32位的系统中每一个运行的程序都会有一个消息队列,所以 系统可以在多个消息队列中转换,而不必等待当前程序完成消 息处理才可以得到控制权。这种多任务系统就是所谓的抢先式 多任务系统。Wndows2000系列以及以前的Wndows95/98/ NT都属于这种系统
⚫ 二、协同式多任务与抢先式多任务系统 ⚫ 在16位的操作系统中只有一个消息队列,所以系统必须等待当 前任务处理消息后才可以发送下一消息到相应程序,如果一个 程序陷入死循环或是操作超时,系统就得不到控制权。这种多 任务系统被称为协同式多任务系统。 Windows 3.x就是这种系 统。 ⚫ 而32位的系统中每一个运行的程序都会有一个消息队列,所以 系统可以在多个消息队列中转换,而不必等待当前程序完成消 息处理才可以得到控制权。这种多任务系统就是所谓的抢先式 多任务系统。 Wndows 2000系列以及以前的Wndows 95/98/ NT都属于这种系统
第三节 Windows 应用程序设计特点 在过去,进行Windows程序设计是一件痛苦异常的事情 原因是那时候还没有现在这些设计精美的应用程序开发工 在今天,即便是一个对Windows程序内部运行机制几乎一无 所知的初学者,只需要通过不到一天的学习,也可以使用 Visual Basic之类的程序开发工具创建出功能完整的Window 应用程序来。从某种角度说,Windows7程序不是编出来的, 而是由程序员画出来的。但是要知道,一个出色的Window 的应用程序并不仅在于在屏幕上绘出程序的各个窗口和在 口中恰当地安排每一个控件。对于具有一定基础的程序员 言,更重要的内容在于知道Windows和Windows,应用程序的 运行机制,以及它们之间以何种方式来进行通信。换句话 我们需要透过Windows漂亮的图形用户界面,认清在底层列 发生的每一件事情
第三节 Windows 应用程序设计特点 ⚫ 在过去,进行Windows程序设计是一件痛苦异常的事情, 原因是那时候还没有现在这些设计精美的应用程序开发工具。 在今天,即便是一个对Windows程序内部运行机制几乎一无 所知的初学者,只需要通过不到一天的学习,也可以使用如 Visual Basic之类的程序开发工具创建出功能完整的Windows 应用程序来。从某种角度说,Windows程序不是编出来的, 而是由程序员画出来的。但是要知道,一个出色的Windows 的应用程序并不仅在于在屏幕上绘出程序的各个窗口和在窗 口中恰当地安排每一个控件。对于具有一定基础的程序员而 言,更重要的内容在于知道Windows和Windows应用程序的 运行机制,以及它们之间以何种方式来进行通信。换句话说, 我们需要透过Windows漂亮的图形用户界面,认清在底层所 发生的每一件事情