消息(事件)驱动的程序设计
消息(事件)驱动的程序设计
主要内容 Vindows简介 ■消息驱动的程序结构 基于Vindows API的过程式Windows应 用程序设计 基于MFC和“文档一视”结构的面向对象 Windows应用程序设计
主要内容 ◼ Windows简介 ◼ 消息驱动的程序结构 ◼ 基于Windows API的过程式Windows应 用程序设计 ◼ 基于MFC和“文档-视”结构的面向对象 Windows应用程序设计
WVindows简介 Vindows是一种基于图形界面的多任务操作系 统。 ·系统中可以同时运行多个应用程序。 每个应用程序通过各自的“窗口”与用户进行交互。 用户通过鼠标的单击/双击/拖放、菜单选择以及键 盘输入来进行操作。 Windows的功能以两种方式提供: 工具(应用程序):资源管理器、记事本、画图 供用户使用。 函数库:作为Windows的应用程序接口(API) 以C语言函数形式提供(在windows.h等头文件中 申明)八,提供给应用程序使用
Windows简介 ◼ Windows是一种基于图形界面的多任务操作系 统。 • 系统中可以同时运行多个应用程序。 • 每个应用程序通过各自的“窗口”与用户进行交互。 • 用户通过鼠标的单击/双击/拖放、菜单选择以及键 盘输入来进行操作。 ◼ Windows的功能以两种方式提供: • 工具(应用程序):资源管理器、记事本、画图、 ......,供用户使用。 • 函数库:作为Windows的应用程序接口(API), 以C语言函数形式提供(在windows.h等头文件中 申明),提供给应用程序使用
Windows应用程序的类型 ■ 单文档应用 ·只能对一个文档的数据进行操作 ·必须首先结束当前文档的所有操作之后,才能进行下一个文 档的操作。 多文档应用 同时可以对多个文档的数据进行操作。 不必等到一个文档的所有操作结束,就可以对其它文档进行 操作,对不同文档的操作是在不同的子窗口中进行的。 对话框应用 以对话框的形式操作一个文档数据。 对文档数据的操作以各种“控件”(control)来实现。 程序以按或等按钮来结束
Windows应用程序的类型 ◼ 单文档应用 • 只能对一个文档的数据进行操作。 • 必须首先结束当前文档的所有操作之后,才能进行下一个文 档的操作。 ◼ 多文档应用 • 同时可以对多个文档的数据进行操作。 • 不必等到一个文档的所有操作结束,就可以对其它文档进行 操作,对不同文档的操作是在不同的子窗口中进行的。 ◼ 对话框应用 • 以对话框的形式操作一个文档数据。 • 对文档数据的操作以各种“控件”(control)来实现。 • 程序以按或等按钮来结束
消息驱动的程序结构 Vindows应用程序的结构属于消息(事件)驱动的 结构: 。程序的任何一个动作都是在接收到一条消息后发生的。 Windows的消息有: VM KEYDOWN/WM KEYUP(键盘按键 NM CHAR(字符) WM LBUTTONDOWN/WM LBUTTONUP/WM LBUT TONDBLCLK/NM MOUSEMOVE(鼠标按键 WM_COMMAND(菜单) NM PAINT(窗口内容刷新 WM TIMER(定时器消息)
消息驱动的程序结构 ◼ Windows应用程序的结构属于消息(事件)驱动的 结构: • 程序的任何一个动作都是在接收到一条消息后发生的。 ◼ Windows的消息有: • WM_KEYDOWN/WM_KEYUP(键盘按键) • WM_CHAR(字符) • WM_LBUTTONDOWN/WM_LBUTTONUP/WM_LBUT TONDBLCLK/WM_MOUSEMOVE (鼠标按键) • WM_COMMAND(菜单) • WM_PAINT(窗口内容刷新) • WM_TIMER(定时器消息) •
每个Windows应用程序都有一个消息队列: ·Windows系统会把属于各个应用程序的消息放入 各自的消息队列。 大部分的消息都关联到某个窗口。 ·每个窗口都有一个消息处理函数。 Vindows应用程序不断地从自己的消息队列 中获取消息并调用相应窗口的消息处理函数 来处理获得的消息。 这个“取消息-处理消息”的过程构成了消息循环。 当取到某个特定消息(NM QUIT)后,消息循 环结束
◼ 每个Windows应用程序都有一个消息队列。 • Windows系统会把属于各个应用程序的消息放入 各自的消息队列。 ◼ 大部分的消息都关联到某个窗口。 • 每个窗口都有一个消息处理函数。 ◼ Windows应用程序不断地从自己的消息队列 中获取消息并调用相应窗口的消息处理函数 来处理获得的消息。 • 这个“取消息-处理消息”的过程构成了消息循环。 • 当取到某个特定消息(WM_QUIT)后,消息循 环结束
消息队列: 消息 (Windows) 主程序: /初始化 /进入消息循环 while(取消息) 消息处理函数: 处理消息 注意:每个消息的处理时间不宜太长, 否则会造成程序“假死”现象 (程序不响应其它消息)
主程序: //初始化 ...... //进入消息循环 while (取消息) { ...... 处理消息 } 消息队列: 消息处理函数: ...... 注意:每个消息的处理时间不宜太长, 否则会造成程序“假死”现象 (程序不响应其它消息)。 消息 (Windows)
基于Vindows API的过程式 Vindows应用程序设计 每个Vindows应用程序都必须提供一个主函数 WinMain,其主要功能是: 注册窗口类(窗口的基本信息) 窗口类信息包括:窗口类的名字、窗口的基本风格、消息处理函 数名、图标、光标、背景颜色以及菜单等。 每类窗口(不是每个窗口)都需要注册。 创建应用程序的主窗口其它窗口等到需要时再创建) 进入消息循环,直到接收到WM_QUT消息时,消息循环 结束。 程序还要为每类窗口提供一个消息处理函数,用于处 理发送到它的消息
◼ 每个Windows应用程序都必须提供一个主函数 WinMain,其主要功能是: • 注册窗口类(窗口的基本信息): ◼ 窗口类信息包括:窗口类的名字、窗口的基本风格、消息处理函 数名、图标、光标、背景颜色以及菜单等。 ◼ 每类窗口(不是每个窗口)都需要注册。 • 创建应用程序的主窗口(其它窗口等到需要时再创建)。 • 进入消息循环,直到接收到WM_QUIT消息时,消息循环 结束。 ◼ 程序还要为每类窗口提供一个消息处理函数,用于处 理发送到它的消息。 基于Windows API的过程式 Windows应用程序设计
消息队列: WinMain(...) 消息 {/注册窗口类 (Windows) 。11 /创建主窗口 ”01g /进入消息循环 消息处理函数: while (GetMessage(...)) WindowProc(...,message,...) switch(message) case...: DispatchMessage(...); case...: 011.10
WinMain(...) { //注册窗口类 ...... //创建主窗口 ...... //进入消息循环 while (GetMessage(...)) { ...... DispatchMessage(...); } } 消息队列: 消息处理函数: WindowProc(...,message,...) { switch(message) { case ...: case ...: ...... } } 消息 (Windows)
/Windows应用程序的主函数 #include/Vindows,所提供的API声明文件。 int APIENTRY WinMain(HINSTANCE hInstance,/本实例标识(Handle HINSTANCE hPrevInstance,/上一个实例标识 LPSTR IpCmdLine,/命令行参数 int nCmdShow)/主窗口显示方式 {/注册窗口类(下面是个示意,函数参数实际为一个结构WNDCLASS) RegisterClass(...,WindowProc,"my_window_class");// /创建并显示主窗口 HWND hWnd; hWnd=CreateWindow("my_window_class",...,x,y,width,height,...); ShowWindow(hWnd,nCmdShow); /消息循环,直到接收到WM QUIT消息 while(GetMessage(&msg,NULL,O,O)/从消息队列中取消息。 { DispatchMessage(&msg);/把消息发送到程序相应的窗口。 return msg.wParam;
//Windows应用程序的主函数 #include //Windows所提供的API声明文件。 int APIENTRY WinMain(HINSTANCE hInstance, //本实例标识(Handle) HINSTANCE hPrevInstance, //上一个实例标识 LPSTR lpCmdLine, //命令行参数 int nCmdShow ) //主窗口显示方式 { //注册窗口类(下面是个示意,函数参数实际为一个结构WNDCLASS) RegisterClass(..., WindowProc, "my_window_class"); //示意 ...... //创建并显示主窗口 HWND hWnd; hWnd=CreateWindow("my_window_class",…,x,y,width,height,...); ShowWindow(hWnd, nCmdShow); ...... //消息循环,直到接收到WM_QUIT消息 while (GetMessage(&msg, NULL, 0, 0)) //从消息队列中取消息。 { ...... DispatchMessage(&msg); //把消息发送到程序相应的窗口。 } return msg.wParam; }