文档库 最新最全的文档下载
当前位置:文档库 › MFC学习笔记01消息处理

MFC学习笔记01消息处理

MFC学习笔记01消息处理
MFC学习笔记01消息处理

模态对话框和非模态对话框

单线程,程序运行时,若运行了模态对话框,则线程会进入等待状态(运行模态对话框时会使线程进入一个while循环),直到模态对话框结束,在运行模态对话框期间,程序不能运行其他的对话框,运行非模态对话框时则可以。

单文档菜单消息的搜索流程是:视图类->文档类->文档模板类->框架窗口类->应用程序类。如果找不到,则将相应的界面元素变灰。

1 消息的分类

MFC 在Win32 的消息结构MSG 的基础上将消息分为三类:窗口消息、命令消息和控件消息。消息的区别在于:消息类别标识和消息的附加参数不同。消息映射:ON_COMMAND();(命令消息)ON_MESSAGE()(自定义消息);ON_WM_...(预定义消息);

1.1 窗口消息

1.1.1 基础知识

相关操作:与窗口相关的操作,例如,创建窗口、绘制窗口、移动窗口、改变窗口尺寸、鼠标在窗口区域内的各种操作等。

凡是从基类CWnd派生的类都能够处理这类消息。

形式:WM_XXX,其中WM为窗口消息类型前缀,XXX表示具体的窗口消息种类。

1.1.2 窗口消息产生途径

①窗口之间交互产生;

②系统产生的窗口消息;

③程序根据需要发送窗口消息。

1.2 命令消息

1.2.1 基础知识

相关操作:处理用户的某个请求或者执行用户的某个命令。

凡是从基类CCmdTarget 派生的类都能够处理这类消息。

形式:WM_COMMAND

主要字段:

message(消息类别)

WM_COMMAND

wParam(附加参数)

低16位为命令ID、高16位为0。

lParam(附加参数)

0L

由于wParam 的高、低16位表示不同的含义,需要分解。wParam来判断命令消息,也需要组装一个wParam用于生成命令消息。系统提供的宏可以帮助完成这些工作。

1.2.2 参数分解

HIGHWORD(wParam);获取高16位,为0表示M_COMMAND类别的消息为命令消息。

LOWWORD(wParam);获取低16位,为命令的资源ID。

例如:

菜单命令消息中:菜单项的资源ID;

工具栏按钮消息中:工具栏按钮对应的资源ID;

加速键消息中:加速键对应的资源ID。

1.2.3 参数组合

使用宏MAKEWPARAM,例如:生成一条打开文件的命

令消息,打开文件的菜单项的资源ID为ID_FILE_OPEN,消息命令为:(WM_COMMAND, MAKEWPARAM(ID_FILE_OPEN, 0), 0L)

1.2.4 命令消息产生途径

①选择菜单项;

②单击工具栏按钮;

③按加速键;

④程序根据需要发送的命令消息。

1.3 控件消息

1.3.1 相关操作

此类消息与控件窗口中的某个事件相关,例如:文本框控件窗口内的内容发生改变、列表框控件中某个选项被选择、按钮控件被单击、滑杆条的游标被移动

等,都会发出相应的控件事件消息。

1.3.2 形式

由于控件是近年来软件开发中最为活跃的,控件的种类不断增加,随之控件消息的类别也迅速增加,原来的控件消息格式越来越不能满足控件消息的描述,因此,必须寻求新的控件消息描述方法。由于历史的原因,控件消息的新旧描述形式必须并存才能兼容所有的控件消息。

1.3.3 控件消息产生途径

①由控件的各类事件发出;

②程序根据需要模拟控件事件发送通知消息。

2 自定义消息

2.1 自定义消息的步骤

①添加自定义消息,例如:

#define WM_MESSAGENAME (WM_USER+100)

(Microsoft推荐用户自定义消息至少是WM_USER+100,因为很多新控件也要使用WM_USER消息)

②在.H头文件中,添加消息响应函数,该函数有规定的格式:LONG Function_Name(WPARAM w, LPARAM l);

对于添加的自定义消息WM_MESSAGENAME的函数处理形式如下:LONG OnMessageName(WPARAM w, LPARAM l);

③添加消息响应宏

在响应该消息的类的消息响应块中,加入以下语句。

ON_MESSAGE(WM_MYMESSAGE, OnMyMessage)

④在.cpp源文件中,添加消息响应函数体。其代码如下:

LONG CMyClass::OnMessageName(WPARA w,LPARAM l)

{

}

(类向导ClassWizard不允许增加用户自定义消息,所以开发人员必须手工添加。添加后,类向导ClassWizard就可以像处理其他消息一样处理自定义消息了。) 如果用户需要整个系统唯一的消息,则可以调用SDK函数

RegisterWindowMessage()并使用ON_REGISTER_MESSAGE宏指令取代ON_MESSAGE宏指令,其余步骤同上。

⑤给窗口发送消息

SendMessage(WM_MESSAGENAME,0L,0L);

2.2 SendMessage和PostMessage

SendMessage传递消息后,需要等到消息被处理完成才能返回。

SendMessage方法:首先,应获取接收消息的CWnd类对象的指针;然后,调用CWnd的成员函数SendMessage( )。

LRESULT Res=pWnd->SendMessage(UINT Msg,WPARAM wParam, LPARAM lParam);

pWnd指针指向目标CWnd类对象。变量Msg是消息,wParam和lParam变量包含消息的参数,如鼠标单击哪里或选择了什么菜单项。目标窗口返回的消息结果放在变量Res中。发送消息到一个没有CWnd类对象的窗口,可以用下列目标窗口的句柄直接调用Windows API:LRESULT Res=::SendMessage(HWND hWnd , UINT Msg , WPARAM wParam , LPARAM lParam);这里的hWnd是目标窗口的句柄。

PostMessage传递消息后直接返回,不需要等待消息被处理。

用MFC寄送一个消息与发送一个消息几乎相同,但寄送时用PostMessage( ),而不是用SendMessage( );返回值Res也不一样,Res不是一个由目标窗口返回的值,而是一个布尔值,用来表示消息是否成功地放到消息队列中。

2.3 Windows消息值的范围

#define WM_USER 0x0400

消息值范围意义

0x0000-0x03FF Windows消息

0x0400-0x7FFF 用户自定义的消息

0x8000-0xBFFF Windows保留值

0xC000-0xFFFF 供应用使用的字符串消息

3 定时器消息

定时器消息属于系统预定义消息,可以通过ClassWizard添加定时器消息(WM_TIMER)响应函数。

对定时器进行初始化SetTimer(),使定时器失效KillTimer()。

4 消息传递方式

4.1 同步方式

同步方式(发送):发送一个消息时,直接调用窗口的窗口过程。通信是即时的,直到窗口进程为调用函数返回一个结果后,应用程序才能继续。

SendMessage采用同步方式发送消息。

SendMessage返回被处理的消息的结果值。

4.2 异步方式

异步方式(寄送):寄送一个消息时,只是把消息发送到拥有那个窗口的应用程序消息队列中。一有空闲,应用程序就搜索消息队列,并在消息队列中处理消息,即从队列中删除它们,并将它们发送到即定窗口。通信将可能延迟,直到目标应用程序获得处理消息的时间。调用函数发送消息后马上返回,但结果只是表示消息寄送成功与否,而不是被调用窗口过程的结果。

PostMessage采用异步方式发送消息。

PostMessage返回一个布尔值,指明消息是否被成功地放入到消息队列中。

5 MFC消息映射

所谓消息映射,简单地讲,就是让程序员指定要某个MFC类(有消息处理能力的类)处理某个消息。MFC提供了工具ClassWizard来帮助实现消息映射,在处理消息的类中添加一些有关消息映射的内容和处理消息的成员函数,程序员将完成消息处理函数,实现所希望的消息处理能力。消息映射就是用一个数据结构把“消息”与“响应消息函数名”串联起来。

5.1 消息映射方法

MFC内部通过一系列非常复杂的宏处理消息映射,但定义和使用消息映射表却相对简单,可通过三个步骤完成:

①在头文件的类声明中添加DECLARE_MESSAGE_MAP宏,声明消息映

射,并声明消息处理函数的原型;

②在类的定义文件(.cpp)定义消息映射表,方法是在文件的开始处添加BEIGN_MESSAGE_MAP和END_MESSAGE_MAP 这一对宏,在它们之间放置消息映射宏,定义并初始化消息映射表,将消息与处理消息的函数之间建立联系;

③在类的定义文件(.cpp)中添加消息处理函数。

5.2 消息宏的分类

5.2.1 对窗口消息的响应

消息宏ON_WM_xxx定义对标准Windows消息WM_xxx的响应,所有派生自CWnd的类均可响应这类消息,系统默认的响应函数为OnXxx,对应关系见下表:

宏名消息默认处理函数ON_WM_CHAR WM_CHAR OnChar

ON_WM_CREATE WM_CREATE OnCreate

ON_WM_LBUTTONUP WM_LBUTTONUP OnLButtonUp

①键盘消息

WM_CHAR: 该消息的处理函数是OnChar()

WM_KEYDOWN: 用户按下一个非系统键

WM_KEYUP: 在非系统键被释放时产生

②鼠标消息

WM_MOUSEMOVE,用户将鼠标移进窗口或在窗口中移动

WM_LBUTTONDOWN,用户按下左键

WM_LBUTTONUP,用户释放左键

WM_LBUTTONDBCLICK,用户双击左键

WM_RBUTTONDOWN,用户按下右键

WM_RBUTTONUP,用户释放右键

WM_RBUTTONDBCLICK,用户双击右键

③窗口消息

WM_CREATE,窗口被创建

WM_DESTROY,窗口被销毁

WM_CLOSE,窗口被关闭

WM_MOVE,窗口发生移动

WM_SIZE,窗口发生改变

WM_PAINT,窗口发生重绘

④焦点消息

WM_SETFOCUS,窗口得到焦点

WM_KILLFOCUS,窗口失去焦点

⑤定时器消息

WM_TIMER,响应定时器的定时事件。

5.2.2 对命令消息的响应

ON_COMMAND宏定义对命令消息的响应,格式为ON_COMMAND(<命令ID>,<响应函数>),举例如下:

ON_COMMAND(ID_APP_ABOUT,OnAbout)

//表示ID_APP_ABOUT消息由OnAbout()响应

//以下类似

ON_COMMAND(ID_FILE_NEW,OnFileNew)

所有由用户定义的命令消息也由ON_COMMAND定义消息映射关系。

5.2.3 对控件消息的响应

控件消息由按钮(BN_)、编辑框(EN_)、组合框(CBN_)、列表框(LBN_)等产生,在消息名前加上ON_即构成宏名,举例如下:

ON_BN_CLICKED(<按钮ID>,<响应函数>)

ON_CBN_DBCLK(<组合框ID>,<响应函数>)

ON_EN_SETFOCUS(<组合框ID>,<响应函数>)

ON_LBN_DBCLK(<列表框ID>,<响应函数>)

分别表示选择各个控件后,产生的消息由其后面定义的函数进行处理。如果利用类向导ClassWizard添加消息处理函数,系统会自动生成函数原型和函数框

架,开发人员只要添加函数体代码,可以避免一些常见错误的产生。

6 消息响应

6.1 相关函数简介

1. LRESULT CALLBACK AfxWndProc(HWND hwnd, UINT nmsg, WPARAM wParam, LPARAM lParam);

根据hwnd寻找目标窗口类对象,然后调用AfxCallWndProc。

2. LRESULT AFXAPI AfxCallWndProc(CWnd* pWnd, HWND hwnd, UINT nmsg, WPARAM wParam, LPARAM lParam);

存储消息标志符和参数,然后调用目标窗口对象的虚函数WindowProc。

3. virtual LRESULT CWnd::WindowProc(UINT message,WPARAM wParam, LPARAM lParam );

将消息发送给虚函数OnWndMsg,并接收其反馈。如果消息不能被响应,则调用DefWindowProc进行缺省处理。

4. virtual BOOL CWnd::OnWndMsg( UINT message, WPARAM wParam,

LPARAM lParam, LRESULT* pResult );

将消息分为窗口消息、命令消息和控件消息三类。

对于窗口消息调用对应不同窗口消息的响应函数,并接收这些调用的反馈。

调用OnCommand处理命令消息,并接收其反馈。

调用OnNotify处理控件消息),并接收其反馈。

向WindowProc发回的反馈通知其对消息的处理情况。

5. virtual BOOL CWnd::OnCommand( WPARAM wParam, LPARAM

lParam );

如果lParam不为0,则按控件消息通知控件处理该消息,并接收其反馈。

如果lParam为0,则调用OnCmdMsg,并接收其反馈。

向OnWndMsg发回的反馈通知其对消息的处理情况。

6. virtual BOOL CWnd::OnNotify( WPARAM wParam, LPARAM lParam,

LRESULT* pResult );

通知控件处理该消息,并接收其反馈。

如果控件不能处理该消息,则调用OnCmdMsg,并接收其反馈。

向OnWndMsg发回的反馈通知其对消息的处理情况。

7. virtual BOOL CCmdTarget::OnCmdMsg( UINT nID, int nCode, void* pExtra,

AFX_CMDHANDLERINFO* pHandlerInfo );

按已规定好的路径搜索相应类的消息映射表,以便找到相应的消息处理函数并执行。

如:单文档菜单消息的搜索流程是:视图类->文档类->文档模板类->框架窗口类->应用程序类,如果找不到,则将相应的界面元素变灰。

向OnCommand或OnNotify发回的反馈通知其对消息的处理情况。

virtual BOOL OnWndMsg( UINT message, WPARAM wParam, LPARAM lParam,LRESULT* pResult );

6.2 窗口消息处理过程

实验三 MFC 消息映射编程实验

实验三MFC 消息映射编程实验 一、实验目的 (1) 熟悉Visual Studio 开发环境; (2) 掌握消息映射机制的基本原理和手工添加消息映射的方法; (3) 熟练掌握在Visual Studio 开发环境调试程序的方法。 二、实验内容 设计MFC 应用程序,手工添加消息映射,实现下面的功能: (1) 按下CTRL 键,拖动鼠标绘制矩形; (2) 按下SHIFT 键,拖动鼠标绘制椭圆。 三、实验结果 (1)总结手工添加消息映射的基本步骤; 1、在BEGIN_MESSAGE_MAP 和END_MESSAGE_MAP 之间添加消息映射宏; BEGIN_MESSAGE_MAP(CDemoView, CView) ON_MESSAGE(WM_KEYDOWN, OnKeyDown) ON_COMMAND(ID_OPER_TEST, OnOperTest) END_MESSAGE_MAP( ) 2 、在类声明中声明成员函数; 3、在类的实现部分实现成员函数。列出鼠标绘图功能的实现代码; (2)列出鼠标绘图功能的实现代码; 头文件: #include "afxwin.h" class CDemoWnd:public CFrameWnd { public: CDemoWnd(); ~CDemoWnd(); public: LRESULT OnPaint(WPARAM wParam,LPARAM lParam); LRESULT OnLButtonDown(WPARAM wParam,LPARAM lParam); LRESULT OnMouseMove(WPARAM wParam,LPARAM lParam); DECLARE_MESSAGE_MAP() public: int m_nX0; int m_nY0; int m_nX1;

java期末考试知识点总结

java知识点总结 应同学要求,特意写了一个知识点总结,因比较匆忙,可能归纳不是很准确,重点是面向对象的部分。 java有三个版本:JAVA SE 标准版\JAVA ME移动版\JAVA EE企业版 java常用命令:java, javac, appletview java程序文件名:.java, .class java的两类程序:applet, application; 特点,区别,这两类程序如何运行 java的主方法,主类,共有类;其特征 java的数据类型,注意与C++的不同,如字符型,引用型,初值 java与C++的不同之处,期中已总结 java标记符的命名规则 1)标识符有大小写字母、下划线、数字和$符号组成。 2)开头可以是大小写字母,下划线,和$符号(不能用数字开头) 3)标识符长度没有限制 4)标识符不能使关键字和保留字 面向对象的四大特征 抽象、封装、继承、多态 封装,类、对象,类与对象的关系,创建对象,对象实例变量 构造函数,默认构造函数,派生类的构造函数,构造函数的作用,初始化的顺序,构造方法的重载 构造函数:创建对象的同时将调用这个对象的构造函数完成对象的初始化工作。把若干个赋初值语句组合成一个方法在创建对象时一次性同时执行,这个方法就是构造函数。是与类同名的方法,创建对象的语句用new算符开辟了新建对象的内存空间之后,将调用构造函数初始化这个新建对象。 构造函数是类的特殊方法: 构造函数的方法名与类名相同。 构造函数没有返回类型。 构造函数的主要作用是完成对类对象的初始化工作。 构造函数一般不能由编程人员显式地直接调用。 在创建一个类的新对象的同时,系统会自动调用该类的构造函数为新对象初始化。 类的修饰符:public类VS 默认; abstract类; final类; 1)类的访问控制符只有一个:public,即公共的。公共类表明它可以被所有其他类访问和引用。 若一个类没有访问控制符,说明它有默认访问控制特性,规定该类智能被同一个包中的类访问引用(包访问控制)。 2)abstract类:用abstract修饰符修饰的类被称为抽象类,抽象类是没有具体对象的概念类,抽象类是它所有子类的公共属性集合,用抽象类可以充分利用这些公共属性来提高开发和维护效率。 3)final类:被final修饰符修饰限定的,说明这个类不能再有子类。所以abstract与final 不能同时修饰一个类。 域和方法的定义 1)域:定义一个类时,需要定义一组称之为“域”或“属性”的变量,保存类或对象的数据。

消息映射编程实验

MFC 消息映射编程实验 实 验 报 告 姓名:杨培培 班级:电气12级3班 12053307

【预备知识】 1、消息映射 消息映射本质上就是一个数组,MFC 使用消息映射建立消息和类的成员函数的对应关系。消息映射数组中存储的信息 (1) 所处理的消息; (2) 消息应用的控件ID,或者ID 范围; (3) 消息所传递的参数; (4) 消息所期望的返回值。 2、消息映射宏 下面介绍常用的两个消息映射宏: (1)ON_MESSAGE:处理任意消息 语法规则: ON_MESSAGE(ID,func) LRESULT func(WPARAM wParam, LPARAM lParam); 举例:映射鼠标左键按下消息 ON_MESSAGE(WM_LBUTTONDOWN, OnLButtonDown) LRESULT OnLButtonDown(WPARAM wParam, LPARAM lParam); (2)ON_COMMAND:处理WM_COMMAND 消息 语法规则: ON_COMMAND(ID,func) void func( ); 举例:映射菜单项命令消息

ON_COMMAND(ID_OPER_TEST, OnOperTest) void OnOperTest ( ); 3、消息映射步骤 MFC 中手工添加消息映射按照如下步骤进行: (1)在BEGIN_MESSAGE_MAP 和END_MESSAGE_MAP 之间添加消息映射 宏; BEGIN_MESSAGE_MAP(CDemoView, CView) ON_MESSAGE(WM_KEYDOWN, OnKeyDown) ON_COMMAND(ID_OPER_TEST, OnOperTest) END_MESSAGE_MAP( ) (2) 在类声明中声明成员函数; (3) 在类的实现部分实现成员函数。 【实验目的】 (1) 熟悉Visual Studio 开发环境; (2) 掌握消息映射机制的基本原理和手工添加消息映射的方法; (3) 熟练掌握在Visual Studio 开发环境调试程序的方法。【实验内容】 设计 MFC 应用程序,手工添加消息映射,实现下面的功能: (1) 按下CTRL 键,拖动鼠标绘制矩形; (2) 按下SHIFT 键,拖动鼠标绘制椭圆。 【实验报告】 (1) 总结手工添加消息映射的基本步骤;

java中常用关键字总结

Java中的关键字总结 final 关键字 1、用final修饰的类不能被继承,没有子类; 2、用final修饰的方法,方法不能被重写; 3、用final修饰变量,变量的值不能被修改,表示常量,(书写规范:全部字母都要大写;多个单词,可以使用下划线(_)分开;) 注意:如果被final修饰的变量是一个引用类型的数据,那么通过这个引用改变堆空间中的数据,不会报错;如果被final修饰的变量是一个引用类型的数据,那么通过这个引用改变堆空间中的数据,不会报错; 4、final用于成员变量表示该成员变量为常量,不能被修改,必须在变量定义时赋值。 5、final用于局部变量表示该局部变量为常量,不能被修改,可以在变量定义时赋值,也可以先定义变量后赋值。 什么时候用final关键字? 有的时候不想别人重写我的方法就使用final关键字修饰该方法; static关键字 1、static用于成员变量表示该变量只有一份,也就是说静态成员变量属于类而不属于某个具体的类实例对象,所有的类实例对象共享这个静态成员变量;静态函数是不需要对象的,直接可以使用类名来调用; 2、非静态函数可以调用静态函数;静态函数不能调用非静态函数(非静态函数都是通过对象调用的);静态函数不能使用非静态成员变量,但可以使用静态成员变量; 3、静态函数调用时不需要对象的,所以不能使用和对象有关的关键字;(this;super;) 4、构造函数不能使用static修饰(构造函数是创建对象,开辟空间,给所有成员变量赋默认值之后,有JVM调用进栈,用来给对象的成员变量赋初始值的) static用于类,这里指的是内部类,那么在别的地方就可以通过外部类名来引用这个静态的内部类。 5、static还可以用于类的代码块,叫做静态代码块,静态代码块在类加载的时候就执行完毕,而类只加载一次;是在类中独立于类成员的static语句块,可以有多个,位置可以随便放,它不在任何的方法体内,JVM加载类时会执行这些静态的代码块,如果static代码块有多个,JVM将按照它们在类中出现的先

MFC的运行机制和消息响应机制

MFC的类层次结构与运行机制 MFC的类层次结构 如图所示(子类指向父类): 其中: CObject:是MFC提供的绝大多数类的基类。该类完成动态空间的分配与回收,支持一般的诊断、出错信息处理和文档序列化等。 CCmdTarget:主要负责将系统事件(消息)和窗口事件(消息)发送给响应这些事件的对象,完成消息发送、等待和派遣调度等工作,实现应用程序的对象之间的协调运行。 CWinApp:是应用程序的主线程类,它是从CWinThread类派生而来的。CWinThread类用来完成对线程的控制,包括线程的创建、运行、终止和挂起等。 CDocument:是文档类,包含了应用程序在运行期间所用到的数据。 CWnd:是一个通用的窗口类,用来提供Windows中的所有通用特性、对话框和控件。 CFrameWnd是从CWnd类继承来的,并实现了标准的框架应用程序。 CDialog类用来控制对话框窗口。 CView:用于让用户通过窗口来访问文档。 CMDIFrameWnd和CMDIChildWnd:分别用于多文档应用程序的主框架窗口和文档子窗口的显示和管理。CMiniFrameWnd类是一种简化的框架窗口,它没有最大化和最小化窗口按钮,也没有窗口系统菜单,一般很少用到它。 MFC运行机制 在程序中,当定义一个类对象时,它会自动调用相应的构造函数。所谓"类对象",就是用该类定义的"变量",这个"变量"又称为类的一个实例。例如,theApp就是类CSimpApp的一个对象。 MFC正是利用类的这种"自动调用相应的构造函数"特性,使得WinMain()函数的调用变成了应用程序框架内部的调用,所以我们在代码中看不到每个Windows程序所必须有的WinMain()函数。 当应用程序运行到"CSimpApp theApp;"时,系统就会先调用基类CWinApp构造函数,进行一系列的内部初始化操作,然后自动调用CSimpApp的虚函数InitInstance(),该函数会进一步调用相应的函数来完成主窗口的构造和显示工作。下面来看看上述程序中InitInstance的执行过程。 首先执行的是: m_pMainWnd = new CMainFrame; 该语句用来创建从CFrameWnd类派生而来的用户框架窗口CMainFrame类对象,继而调用该类的构造函数,使得Create函数被调用,完成了窗口创建工作。

Java关键字final使用总结

Java关键字final使用总结 一、final 根据程序上下文环境,Java关键字final有“这是无法改变的”或者“终态的”含义,它可以修饰非抽象类、非抽象类成员方法和变量。你可能出于两种理解而需要阻止改变:设计或效率。 final类不能被继承,没有子类,final类中的方法默认是final的。 final方法不能被子类的方法覆盖,但可以被继承。 final成员变量表示常量,只能被赋值一次,赋值后值不再改变。 final不能用于修饰构造方法。 注意:父类的private成员方法是不能被子类方法覆盖的,因此private 类型的方法默认是final类型的。 1、final类 final类不能被继承,因此final类的成员方法没有机会被覆盖,默认都是final的。在设计类时候,如果这个类不需要有子类,类的实现细节不允许改变,并且确信这个类不会载被扩展,那么就设计为final类。 2、final方法 如果一个类不允许其子类覆盖某个方法,则可以把这个方法声明为final 方法。 使用final方法的原因有二: 第一、把方法锁定,防止任何继承类修改它的意义和实现。 第二、高效。编译器在遇到调用final方法时候会转入内嵌机制,大大提高执行效率。 例如:

3、final变量(常量) 用final修饰的成员变量表示常量,值一旦给定就无法改变! final修饰的变量有三种:静态变量、实例变量和局部变量,分别表示三种类型的常量。 从下面的例子中可以看出,一旦给final变量初值后,值就不能再改变了。 另外,final变量定义的时候,可以先声明,而不给初值,这中变量也称为final空白,无论什么情况,编译器都确保空白final在使用之前必须被初始化。但是,final空白在final关键字final的使用上提供了更大的灵活性,为此,一个类中的final 数据成员就可以实现依对象而有所不同,却有保持其恒定不变的特征。

MFC消息映射机制

由于工作需要,这几天学了一点MFC,在AFX里看到很多熟悉的东西,如类型信息,序列化,窗口封装和消息分派。几乎每个界面库都必须提供这些基础服务,但提供的手法却千差万别。MFC大量地借用了宏,映射表来实现,而VCL则更多的在语言级别上给与支持。这其实是很容易理解的,因为C++是一个标准,不会因某个应用而随便扩展语言;相反Delphi完全由一个公司掌握,因此每支持一项新技术,变化最大的往往是语言本身。 学习MFC的代码,再对照VCL的实现,这真是一个很有意思的过程,其中可以看到两个框架在一些设计思想上是殊途同归的,所不同的是表现手法,以及封装的程度。我计划将这段时间阅读MFC的心得写成一系列文章,其中可能会穿插与VCL的对比,不管你熟悉VCL还是MFC,通过这些文章或许可从另一个角度来看待自己熟悉的框架。 这是第一篇:消息分派。 消息处理函数表 MFC和VCL在对消息进行封装的时候,都没有使用虚函数机制。原因是虚函数带来了不必要的空间开销。那么它们用什么来代替虚函数,即可减少空间浪费,也可实现类似虚函数的多态呢?让我们从一个例子开始。 假设父类ParentWnd处理了100个消息,并且将这100个处理函数声明为虚函数;此时有一个子类ChildWnd它只需要处理2个消息,另外98个交由ParentWnd默认处理,但是ChildWnd的虚表仍然占有100个函数指针,其中2个指向自己的实现,另外98个指向父类的实现,情况大概像下面这样: 指向父类实现的函数指针浪费了空间,当控件类非常多的时候,这种浪费就非常明显。因此必须走另一条路,将不必要的函数指针去掉,如下图所示:

ChildWnd去掉函数指针之后,当有一个消息需要Fun100处理时,ChildWnd就束手无策了。需要一个方法让ChildWnd能够找到父类的表,我们再对这个数据结构进行改进如下: 现在看来好多了,如果ChildWnd有一个消息需要Fun1处理,则查找ChildWnd的MsgHandlers,找到Fun1函数指针调用之;如果需要Fun100处理,发现ChildWnd的MsgHandlers没有Fun100,则通过ParentTable找到父类的MsgHandlers继续查找。如此一直查找,到最后再找不到,就调用DefWindowProc作默认处理。 MFC和VCL都是通过类似的方法实现消息分派的。只是VCL有编译器的支持,直接将这个表放到VMT中,因此实现起来非常简单,只需在控件类里作如下声明: procedure WMMButtonDown(var Message: TWMMButtonDown); message WM_MBUTTONDOWN; TObject.Dispatch会将WM_MBUTTONDOWN正确分派到WMMButtonDown。

常用java技巧总结

面向对象的思想特点 A:是一种更符合我们思想习惯的思想 B:可以将复杂的事情简单化 C:将我们从执行者变成了指挥者 面向对象: 我们怎么才能更符合面向对象思想呢? A:有哪些类呢? B:每个类有哪些东西呢? C:类与类直接的关系是什么呢? 开发,设计,特征 面向对象开发 就是不断的创建对象,使用对象,指挥对象做事情。 面向对象设计 其实就是在管理和维护对象之间的关系。 面向对象特征 封装(encapsulation) 继承(inheritance) 多态(polymorphism) 继承:把多个类中相同的成员给提取出来定义到一个独立的类中。然后让这多个类和该独立的类产生一个关系,这多个类就具备了这些内容。这个关系叫继承。 继承的好处: A:提高了代码的复用性 B:提高了代码的维护性 C:让类与类产生了一个关系,是多态的前提 继承的弊端: A:让类的耦合性增强。这样某个类的改变,就会影响其他和该类相关的类。 原则:低耦合,高内聚。 耦合:类与类的关系 内聚:自己完成某件事情的能力 B:打破了封装性 Java中继承的特点 A:Java中类只支持单继承 B:Java中可以多层(重)继承(继承体系) 继承的注意事项: A:子类不能继承父类的私有成员 B:子类不能继承父类的构造方法,但是可以通过super去访问 C:不要为了部分功能而去继承

多态:同一个对象在不同时刻体现出来的不同状态。 多态前提: A:有继承或者实现关系。 B:有方法重写。 C:有父类或者父接口引用指向子类对象。 多态中的成员访问特点 A:成员变量 编译看左边,运行看左边 B:构造方法 子类的构造都会默认访问父类构造 C:成员方法 编译看左边,运行看右边 D:静态方法 编译看左边,运行看左边 多态的好处 提高了程序的维护性(由继承保证) 提高了程序的扩展性(由多态保证) 多态的弊端 不能访问子类特有功能 静态的特点: A:随着类的加载而加载 B:优先与对象存在 C:被类的所有对象共享 这其实也是我们判断该不该使用静态的依据。 D:可以通过类名调用 静态变量和成员变量的区别 A:所属不同 静态变量:属于类,类变量 成员变量:属于对象,对象变量,实例变量 B:内存位置不同 静态变量:方法区的静态区 成员变量:堆内存 C:生命周期不同 静态变量:静态变量是随着类的加载而加载,随着类的消失而消失 成员变量:成员变量是随着对象的创建而存在,随着对象的消失而消失D:调用不同 静态变量:可以通过对象名调用,也可以通过类名调用 成员变量:只能通过对象名调用

Java期末知识点整理总结

Java期末知识点整理总结 计科2班苏锐师编号47 学号201330551464 第一章 Java语言概述 1. Java语言发展历史和现状及前景 2. Java语言的特点: 简单、面向对象、分布式、健壮性、结构中立、 安全性、可移植、解释的、高性能、多线程、多态性 3. Java虚拟机概念(JVM),Java程序的执行过程 4. Java应用程序分类:Application和Applet 5. Java程序的开发环境:JDK,IDE 第二章 Java数据类型及其运算 1. 标识符与保留字 1.2 标识符命名语法规则与Java推荐的标识符命名规则 1.3 Java中的关键字 2. 数据类型byte, short, int long, char, float, double, boolean 注意点:Java中所有数据类型是确定的,与平台无关,没有sizeof操作,其中特别注意char 类型是2字节Unicode编码,与C++ 不同;知道基本类型都有对应的默认值。 整型数的十进制、八进制、十六进制值的表示。 实型数的十进制、十六进制与科学计数法表示,注意实型常量默认类型为double型。 3. 运算符与表达式算术运算符: + - * / % ++ -- 关系运算符:> >= < <= == != 逻辑运算符:&& || !& | 注意短路计算与非短路计算的差别 位运算符: >> << >>> & | ^ ~ 要认识异或(^)与按位取反(~)运算符 赋值运算符: += -= *= /= %= &= |= ^= <<= >>= >>>= 要注意赋值运算符中包含了强制转换: 若: int k = 1; k += 44.232D; 则相当于: k = (int) ( k + 44.232D); 条件运算符:exp ?stat1 :stat2 要注意stat1与stat2要求类型相兼容且不能为void类型。运算符的优先级:算术运算 > 关系运算> 逻辑运算

MFC消息映射机制如何运用ClassWizard

M F C消息映射机制如何 运用C l a s s W i z a r d The Standardization Office was revised on the afternoon of December 13, 2020

画图的基本应用: Point的应用,在mfc中的很多的位置都要用到。只是当前点的信息,xy坐标,MoveToEx 移动位置函数The MoveToEx function updates the current position to the specified point and optionally returns the previous position. LineTo 画直线的函数 CDC类,作图相关的操作 GetDC,cwnd::getdc 以及cdc的释放(区别hdc),两者的范围不同,调用方式不同 CClientDC 不需要显示地调用getdc和releasedc,只需要声明类的定义和类的调用。 Cliendc对象里利用view指针构造,但是调用的时候用的是对象的点调用方式。 Cwnd::getparent 获得父窗口的指针,view的父窗口是frame。注意区别view 和framework的客户区域。 Cwindowdc类和clientdc一样自动调用getdc和releasedc。了解他的访问客户区的范围。 Getdesktopwindow 获得桌面窗口。 创建画笔: CPen 类,设置画笔的属性,包括一些类型宽度,颜色。 CDC::SelectObject 用的过程中要保存原来的画笔指针。 创建一个阴影线的笔只能是1或更小。(其他的注意情况看msdn)。

JAVA重点知识总结

CoreJava部分 1简述下java基本数据类型及所占位数,java基本数据类型:4类8种 整数类型:byte(1byte),short(2byte),int(4byte),long(8byte) 浮点类型:float(4byte),double(8byte) 字符类型:char(2byte) 逻辑类型:boolean(false/true1byte) 2说出5个启动时异常 ------RunTimeException ------NullPointerException ------ArrayIndexOutOfBoundsException ------ClassCastException ------NumberFormatException 3HashMap和HashTable的区别: 1HashMap允许空键值对,HashTable不允许 2HashMap不是线程安全的,HashTable是 3HashMap直接实现Map接口,HashTable继承Dictionary类 4.ArrayList,Vector,LinkedList存储性能和区别 它们都实现了List接口 ArrayList和Vector都是基于数组实现的 LinkedList基于双向循环链表(查找效率低,添加删除容易) ArrayList不是线程安全的而Vector是线程安全的,所有速度上ArrayList高于Vector 5.Collection和Collections的区别 Collection是集合类的上级接口,继承与他的接口主要有Set和List Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全等操作。 6List、Map、Set三个接口,存取元素时,各有什么特点? List以特定次序来持有元素,可有重复元素。 Set无法持有重复元素,内部排序 Map保存key-value值,value可多值。 7final,finally,finalize的区别 Final用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承Finally是异常处理语句结构的一部分,表示总是执行 Finalize是Object类的一个方法,在垃圾收集时的其他资源回收,例如关闭文件等。8Overload和Override的区别。Overload的方法是否可以改变返回值的类型? 方法的重写Override和重载Overload是Java多态的不同表现。 重写Overriding是父类与子类之间多态的一种表现,方法名,参数列表返回值类型都得与父类的方法一致。 重载Overloading是一种类中多态的一种表现。重载的方法是可以改变返回值类型的。9用一句话总结一下冒泡排序 依次比较相邻的两个数,将小数放在前面,大数放在后面。 10实现线程安全的两种方式 1)synchronized方法:通过在方法声明加入synchronized关键字来声明synchronized方法

JAVA编程关键字和常用单词

Java基础常见英语词汇(共70个) OO: object-oriented ,面向对象 OOP: object-oriented programming,面向对象编程 JDK:Java development kit, java开发工具包 JVM:java virtual machine ,java虚拟机 Compile:编绎 Run:运行 Class:类 Object:对象 System:系统 out:输出 print:打印 line:行 variable:变量 type:类型 operation:操作,运算 array:数组 parameter:参数 method:方法 function:函数 member-variable:成员变量 member-function:成员函数 get:得到 set:设置 public:公有的 private:私有的 protected:受保护的 default:默认 access:访问 package:包 import:导入 static:静态的 void:无(返回类型) extends:继承 parent class:父类 base class:基类 super class:超类 child class:子类

derived class:派生类 override:重写,覆盖 overload:重载 final:最终的,不能改变的 abstract:抽象 interface:接口 implements:实现 exception:异常 Runtime:运行时 ArithmeticException:算术异常ArrayIndexOutOfBoundsException:数组下标越界异常NullPointerException:空引用异常ClassNotFoundException:类没有发现异常NumberFormatException:数字格式异常(字符串不能转化为数字) Catch:捕捉 Finally:最后 Throw:抛出 Throws: (投掷)表示强制异常处理 Throwable:(可抛出的)表示所有异常类的祖先类 Lang:language,语言 Util:工具 Display:显示 Random:随机 Collection:集合 ArrayList:(数组列表)表示动态数组 HashMap: 散列表,哈希表 Swing:轻巧的 Awt:abstract window toolkit:抽象窗口工具包 Frame:窗体 Size:尺寸 Title:标题 Add:添加 Panel:面板 Layout:布局 Scroll:滚动 Vertical:垂直 Horizonatal:水平 Label:标签 TextField:文本框 TextArea:文本域 Button:按钮

mfc原理和消息映射

MFC思想 win32程序中创建一个窗口的过程:设计窗口阶段(由WNDCLASS结构描述部分)、窗口的注册及创建显示过程、消息循环部分。win32用标准的C语言代码实现,是面向过程的。在MFC中采用了面向对象的思想,即用面向对象的C++思想对以上代码进行了封装,也就是说将一些对窗口进行操作的API的函数封装到了一个类中,以下我将用简短的代码来演示一下这个过程: class CWnd { public: HWND m_hWnd; BOOL Create(); BOOL ShowWindow(); }; BOOL CWnd::Create() { WNDCLASS wndClass; wndClass.style=CS_HREDRAW; wndClass.lpfnWndProc=(WNDPROC)DefWndProc; wndClass.cbClsExtra=0; wndClass.cbWndExtra=0; wndClass.hInstance=hInstance; wndClass.hIcon=LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1)); wndClass.hCursor=LoadCursor(hInstance,MAKEINTRESOURCE(IDC_CURSOR1)); LOGBRUSH lgbr; lgbr.lbStyle=BS_SOLID; lgbr.lbColor=RGB(192,192,0); lgbr.lbHatch=0; wndClass.hbrBackground=CreateBrushIndirect(&lgbr); wndClass.lpszMenuName=NULL; wndClass.lpszClassName="mycls"; RegisterClass(&wndClass); HWND hWnd; m_hWnd=CreateWindow("mycls","窗口标题", WS_OVERLAPPEDWINDOW,0,NULL,NULL,hInstance,NULL); if(m_hWnd!=NULL) return true; else return false; } BOOL CWnd::ShowWindow() { return ShowWindow(hWnd,nCmdShow); } 为了保证代码和以前的执行方式一样,Winmain()函数可以写成如下形式:

MFC消息映射

消息映射的实现 Windows消息概述 Windows应用程序的输入由Windows系统以消息的形式发送给应用程序的窗口。这些窗口通过窗口过程来接收和处理消息,然后把控制返还给Windows。 消息的分类 队列消息和非队列消息 从消息的发送途径上看,消息分两种:队列消息和非队列消息。队列消息送到系统消息队列,然后到线程消息队列;非队列消息直接送给目的窗口过程。 这里,对消息队列阐述如下: Windows维护一个系统消息队列(System message queue),每个GUI线程有一个线程消息队列(Thread message queue)。 鼠标、键盘事件由鼠标或键盘驱动程序转换成输入消息并把消息放进系统消息队列,例如 WM_MOUSEMOVE、WM_LBUTTONUP、WM_KEYDOWN、WM_CHAR等等。Windows每次从系统消息队列移走一个消息,确定它是送给哪个窗口的和这个窗口是由哪个线程创建的,然后,把它放进窗口创建线程的线程消息队列。线程消息队列接收送给该线程所创建窗口的消息。线程从消息队列取出消息,通过Windows把它送给适当的窗口过程来处理。 除了键盘、鼠标消息以外,队列消息还有WM_PAINT、WM_TIMER和WM_QUIT。 这些队列消息以外的绝大多数消息是非队列消息。 系统消息和应用程序消息 从消息的来源来看,可以分为:系统定义的消息和应用程序定义的消息。 系统消息ID的范围是从0到WM_USER-1,或0X80000到0XBFFFF;应用程序消息从WM_USER (0X0400)到0X7FFF,或0XC000到0XFFFF;WM_USER到0X7FFF范围的消息由应用程序自己使用;0XC000到0XFFFF范围的消息用来和其他应用程序通信,为了ID的唯一性,使 用::RegisterWindowMessage来得到该范围的消息ID。 消息结构和消息处理 消息的结构 为了从消息队列获取消息信息,需要使用MSG结构。例如,::GetMessage函数(从消息队列得到消息并从队列中移走)和::PeekMessage函数(从消息队列得到消息但是可以不移走)都使用了该结构来保存获得的消息信息。 MSG结构的定义如下: typedef struct tagMSG { // msg HWND hwnd; UINT message; WPARAM wParam; LPARAM lParam; DWORD time; POINT pt; } MSG; 该结构包括了六个成员,用来描述消息的有关属性: 接收消息的窗口句柄、消息标识(ID)、第一个消息参数、第二个消息参数、消息产生的时间、消息产生时鼠标的位置。 应用程序通过窗口过程来处理消息 如前所述,每个“窗口类”都要登记一个如下形式的窗口过程: LRESULT CALLBACK MainWndProc (

4.MFC消息映射机制如何运用ClassWizard

. 画图的基本应用: Point的应用,在mfc中的很多的位置都要用到。只是当前点的信息,xy坐标,MoveToEx 移动位置函数The MoveToEx function updates the current position to the specified point and optionally returns the previous position. LineTo 画直线的函数 CDC类,作图相关的操作 GetDC,cwnd::getdc 以及cdc的释放(区别hdc),两者的范围不同,调用方式不同CClientDC 不需要显示地调用getdc和releasedc,只需要声明类的定义和类的调用。Cliendc对象里利用view指针构造,但是调用的时候用的是对象的点调用方式。Cwnd::getparent 获得父窗口的指针,view的父窗口是frame。注意区别view和framework 的客户区域。 Cwindowdc类和clientdc一样自动调用getdc和releasedc。了解他的访问客户区的范围。Getdesktopwindow 获得桌面窗口。 创建画笔: CPen 类,设置画笔的属性,包括一些类型宽度,颜色。 CDC::SelectObject 用的过程中要保存原来的画笔指针。 创建一个阴影线的笔只能是1或更小。(其他的注意情况看msdn)。 创建画刷: CBrush 类的方法 FillRect填充矩形的区域。 CRect类,几种不同的方法。 用位图填充画刷。CBitmap 的构造函数,没有参数。调用之前必需初始化。 透明画刷的创建: dc.Rectangle(); 画出矩形。 空画刷:GetStockObject CBrush::FromeHandle 空画刷的实现方法: CBrush *brush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH)); CBrush *oldbrush=dc.SelectObject(brush); dc.Rectangle(CRect(org,point)); dc.SelectObject(oldbrush); 理解 消息响应的知识: MouseMove 如有侵权请联系告知删除,感谢你们的配合! 精品

何小伟-高手总结java常用API

Java常用API的运用,效率及技巧 1. Java面向对象基本概念 2. System 3. String, StringBuffer 4. 数值,字符,布尔对象与简单类型的操作 5. Class, ClassLoader 6. Java IO系统 7. Java集合类 8. ResourceBundle, Properties 9. Exceptions 10. JDBC类库 11. 常用设计模式 1. Java面向对象基本概念 Java基本上是面向对象的程序设计语言,除了一些简单类型(primitive)的变量以外,一切都是对象,程序是对象的组合,每个对象都有自己的空间,并且每个对象都有一种类型,同一类所有对象都能接受相同的消息。下面只对Java中对象的结构作简单的说明: 类(class): class是定义类的关键字,类中包含类变量,方法,内部类,内部接口等。由class可以生成类的实例,即一个个对象。如果一个类的成员被定义 成static的,则这个成员不专属于任何对象,而是属于这个类,所有的对象共享这 个成员。 抽象类(abstract class): 抽象类不能直接生成一个实例,抽象类中必需有方法是abstract的,抽象类的意思就是它实现了一部分的方法,而定义为abstract的方法 则需要在它的字类中去实现。 接口(interface): 接口可以理解为纯抽象的类,它的每个方法都是未实现的,它可以有成员变量,但必须是static的。一个类如果从这个接口继承(implements) 则它必须实现这个接口的所有方法。 继承类用关键字:extends,继承接口用关键字:implements。一个类只能从一个类继承下来,但可以从多个接口继承(类似于C++的多重继承)。字类可以覆盖父类的方法(method),但不能覆盖父类的成员变量(field)。如果父类的方法为final或static的则不能被覆盖。类的初始化顺序是,如果有父类,则先初始化父类的field,然后执行父类的构造函数,如果子类没有显式的去调父类的构造函数则缺省的会去调父类的无参数构造函数。然后是子类的field 与构造函数的初始化。 public interface SuperInterface { public staitc String SOME_FLAG = “1”; public void someMethod(); } public Class SuperClass { { System.out.println(“init SuperClass field”);} public SuperClass() {System.out.println(“init SuperClass Constructor”); } public void runMethod() { System.out.println(“run SuperClass runMethod()”); } }

java中常用关键字总结

Java中的关键字总结 final关键字 1、用final修饰的类不能被继承,没有子类; 2、用final修饰的方法,方法不能被重写; 3、用final修饰变量,变量的值不能被修改,表示常量,(书写规范:全部字母都要大写;多个单词,可以使用下划线(_)分开;) 注意:如果被final修饰的变量是一个引用类型的数据,那么通过这个引用改变堆空间中的数据,不会报错;如果被final修饰的变量是一个引用类型的数据,那么通过这个引用改变堆空间中的数据,不会报错; 4、final用于成员变量表示该成员变量为常量,不能被修改,必须在变量定义时赋值。 5、final用于局部变量表示该局部变量为常量,不能被修改,可以在变量定义时赋值,也可以先定义变量后赋值。 什么时候用final关键字? 有的时候不想别人重写我的方法就使用final关键字修饰该方法; static关键字 1、static用于成员变量表示该变量只有一份,也就是说静态成员变量属于类而不属于某个具体的类实例对象,所有的类实例对象共享这个静态成员变量;静态函数是不需要对象的,直接可以使用类名来调用; 2、非静态函数可以调用静态函数;静态函数不能调用非静态函数(非静态函数都是通过对象调用的);静态函数不能使用非静态成员变量,但可以使用静态成员变量; 3、静态函数调用时不需要对象的,所以不能使用和对象有关的关键字;(this;super;) 4、构造函数不能使用static修饰(构造函数是创建对象,开辟空间,给所有成员变量赋默认值之后,有JVM调用进栈,用来给对象的成员变量赋初始值的) static用于类,这里指的是内部类,那么在别的地方就可以通过外部类名来引用这个静态的内部类。 5、static还可以用于类的代码块,叫做静态代码块,静态代码块在类加载的时候就执行完毕,而类只加载一次;是在类中独立于类成员的static语句块,可以有多个,位置可以随便放,它不在任何的方法体内,JVM加载类时会执行这些静态的代码块,如果static代码块有多个,JVM将按照它们在类中出现的先

Java常见关键字及用法总结

Java常见关键字及用法总结 关键字目录 abstract - 1 - boolean - 2 - break - 2 - byte - 2 - case - 3 - catch - 3 - char - 4 - class - 4 - continue - 5 - default - 5 - do - 6 - double - 6 - else - 6 - extends - 6 - false - 7 - final - 7 - finally - 7 - float - 8 - for - 8 - if - 8 - implements - 9 - import - 9 - instanceof - 9 - int - 9 - interface - 10 - long - 10 - native - 10 -

new - 11 - null - 11 - package - 11 - private - 11 - protected - 12 - public - 12 - return - 13 - short - 13 - static - 13 - super - 14 - switch - 14 - synchronized - 15 - this - 16 - throw - 16 - throws - 16 - transient - 17 - try - 17 - true - 18 - void - 18 - volatile - 18 - while - 18 - 1.abstract abstract 关键字可以修改类或方法。 abstract 类可以扩展(增加子类),但不能直接实例化。 abstract 方法不在声明它的类中实现,但必须在某个子类中重写。-示例- public abstract class MyClass{ } public abstract String myMethod();

相关文档