文档库 最新最全的文档下载
当前位置:文档库 › MFC消息映射的实现

MFC消息映射的实现

MFC消息映射的实现
MFC消息映射的实现

实验三 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;

消息映射编程实验

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) 总结手工添加消息映射的基本步骤;

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函数被调用,完成了窗口创建工作。

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。

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)。

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 如有侵权请联系告知删除,感谢你们的配合! 精品

MFC课后简答题(1~11章)

第一章 1、什么是Windows SDK程序? 使用SDK开发出来的Windows应用程序,叫做Windows SDK程序 2、什么是Windows API函数? 为了设计Windows 应用程序,Windows 提供了大量预定义的用C语言编写的函数 3、查看windows.h文件,说明Windows系统的句柄的类型。 整型 4、窗口句柄、当前程序应用实例句柄、设备环境句柄 5、什么是事件?试举例说明。 能触发程序作出相应反映的刺激叫做事件,例如在键盘上按下一个键 6、如何显示和更新窗口? 调用函数ShowWindow显示窗口,调用函数UpdateWindow更新窗口 7、什么是消息循环? 在创建了窗口的应用程序中,应用程序将要不断地从消息队列中获取消息,并将消息指派给指定的窗口处理函数来处理,然后再回来从消息队列中获取消息,这个不断重复的工作过程叫做消息循环 8、Windows应用程序的主函数有哪3个主要任务? 注册窗口类、创建应用程序的窗口和建立消息循环 (注:如果题目问有哪2个主要任务,应该答后两个) 9、说明Windows应用程序的主函数,窗口函数与Windows系统之间的关系。 主函数和窗口函数都是Windows系统调用的函数; 主函数是应用程序启动后,系统首先调用的函数; 窗口函数是主函数在消息循环中获得消息并把消息发送给系统之后,由系统调用函数。 第二章 1、在窗口类CFrameWnd中需要封装哪些成员? 窗口句柄,窗口类的定义,注册窗口类,创建窗口和显示更新窗口 (注:对应书上P16 //窗体类的声明这一段代码) 2、应用程序类CWinApp应该具备哪些主要功能? 注册、创建、显示应用程序的窗口;建立消息循环 3、在MFC程序设计中,如果要建立拥有自己的风格的主窗口,应该重写什么函数? 在CWinApp的派生类中重写InitInstance函数 4、什么是消息映射表? 在MFC中,能够根据消息取得消息处理函数的表,叫做消息映射表。(我自己概括的) ////消息映射就是消息与消息处理函数一对一的联系 第三章 1、CObject is the principal base class for the MFC Library. (最“基”的一个类) 2、功能: CObject类:为其派生类提供了支持序列化、调试信息、运行期类型消息等一些通用功能。 CCmdTArget类:支持消息处理。 CWnd类:为所有子窗口类提供通用属性和方法。

消息映射的实现

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

MFC中的消息发送与响应

MFC中的消息发送与响应 1. 主窗口向子窗口发送消息: https://www.wendangku.net/doc/7911574948.html,/phenixyf/article/details/9300425 从主窗口向子窗口发送消息,可以在子窗口中添加自定义的消息,然后在主窗口中需要地方呼叫该消息。 呼叫方法: 1.将子窗口添加为主窗口的成员变量; 2.主窗口呼叫该消息,成员变量名.SendMessage(UM_PROGRESS); 子窗口添加自定义消息步骤如下: 1、定义消息。 在Windows中,所有的消息都用一个特定的整数值来表示,为了避免自定义消息与已存在的其他消息发生冲突,应该利用Windows提供的一个常量:WM_USER,小于这个常量的是系统保留的。即用户自定义的消息至少为WM_USER+1,注意最后表示的消息的数值不要超过0x7FFF。在开发Windows95应用程序时,Microsoft推荐用户自定义消息至少是WM_USER+100,因为很多新控件也要使用WM_USER消息。 #define UM_PROGRESS WM_USER + 100 将上句添加到子窗口类的头文件(.h)中。 2、在子窗口类头文件的AFX_MSG块中声明消息处理函数:

class CMainFrame:public CFrameWnd{ protected: //{{AFX_MSG(CMainFrame) afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnTimer(UINT nIDEvent); afx_msg LRESULT OnProgress(WPARAM wParam, LPARAM lParam); //}}AFX_MSG DECLARE_MESSAGE_MAP() 3、在子窗口类的实现文件(.cpp)中,使用ON_MESSAGE宏指令将消息映射到消息处理表中。 BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) //{{AFX_MSG_MAP(CMainFrame) ON_WM_CREATE() ON_WM_TIMER() ON_MESSAGE(UM_PROGRESS, OnProgress)//注意这条语句的后面没有分号 //}}AFX_MSG_MAP END_MESSAGE_MAP() 4、实现消息处理函数。该函数使用WPRAM和LPARAM参数并返回LPESULT。 LRESULT CMainFrame::OnProgress(WPARAM wParam,LPARAM lParam){ CRect rect; m_wndStatusBar.GetItemRect(2,&rect); //获得窗格区域 //创建进度栏,注意第三个参数为CWnd* pParentWnd,根据情况选择父窗体 m_progress.Create(WS_CHILD|WS_VISIBLE|PBS_VERTICAL,rect,this,123); m_progress.SetPos(50); return 0; } 5、在适当的时候发送自定义消息,进行消息处理。需要注意使用SendMessage还是PostMessage进行处理:SendMessage是消息处理完毕后再返回;而PostMessage则是把消息放到消息队列后立即返回。 SendMessage(UM_PROGRESS); PostMessage(UM_PROGRESS); 如果用户需要整个系统唯一的消息,可以调用SDK函数RegisterWindowMessage并使用ON_REGISTER_MESSAGE宏指令取代ON_MESSAGE宏指令,其余步骤同上。 2. 子窗口向主窗口发送消息:

中国石油大学(华东)VC 实验报告实验三_MFC消息映射编程实验

实验三 MFC消息映射编程实验 一、实验目的 (1) 熟悉 Visual Studio开发环境; (2) 掌握消息映射机制的基本原理和手工添加消息映射的方法; (3) 熟练掌握在 Visual Studio开发环境调试程序的方法。 二、实验内容 设计 MFC应用程序,手工添加消息映射,实现下面的功能: (1) 按下 CTRL键,拖动鼠标绘制矩形; (2) 按下 SHIFT键,拖动鼠标绘制椭圆。 三、总结手工添加消息映射的基本步骤 1.在BEGIN_MESSAGE_MAP和END_MESSAGE_MAP之间添加消息映射宏;BEGIN_MESSAGE_MAP(CDemoView,CView) ON_MESSAGE(WM_LBUTTONDOWN,OnLButtonDown) ON_COMMAND(ID_OPER_TEST,OnOperTest) END_MESSAGE_MAP() ······ 2.在类声明中声明成员函数; DECLARE_MESSAGE_MAP() 3.在类的实现部分实现成员函数; 四、鼠标绘图功能的实现代码 1.头文件 #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; int m_nY1; }; class CDemoApp:public CWinApp { public: BOOL InitInstance(); }; CDemoApp thisApp; //全局应用程序对象2.源文件 #include "Demo.h" CDemoWnd::CDemoWnd() // 构造函数 { m_nX0 = 0; m_nY0 = 0; m_nX1 = 0; m_nY1 = 0; } CDemoWnd::~CDemoWnd() // 析构函数 { } BEGIN_MESSAGE_MAP(CDemoWnd,CFrameWnd)

MFC实验报告

VC++ 实 验 报 告 姓名: 学号: 学院: 专业: 指导老师: 2012年6 月1日

计算机与信息技术学院综合性、设计性实验报告专业:计算机科学与技术年级/班级:网络工程 2011-2012 学年第二学期 课程名称VC++程序设计实验指导教师本组成员 学号姓名 实验地点计算机机房实验时间5月8日上午8:00-11:30 5月15日上午8:00-11:30 5月22日上午8:00-11:30 项目名称MFC基本应用程序的建立实验类型综合性 (一)实验目的: 1. 理解windows编程的特点 2. 了解MFC应用程序的消息映射、数据映射、运行时类型检查和诊断信息转化机制。 3. 掌握用APPWizard(exe)创建SDI,MDI以及基于对话框的应用程序的方法 4. 了解SDI、MDI在编程、功能等方面的异同。 5. 掌握使用项目工作区窗口的CLASS VIEW页面为一个类添加成员的方法。 6. 掌握用CLASS WIZARD映射消息的方法。 (二)实验仪器或设备: 操作系统:Windows XP SP3 处理器:Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz 2.50GHz 内存:8.00GB(7.85GB可用) 显卡:ATI HD6770 1G GDDR5独立显卡 硬盘:500G VC ++6.0环境 (三)总体设计(设计方案、设计流程及原理等) 设计思想:启动Visual C++6.0;调入并运行Ex_HelloMFC.cpp;创建一个单文档应用程序Ex_MySDI;用ClassWizard映射消息;创建一个多文档应用程序Ex_MyMDI;向类添加成员函数和成员变量,设置断点并控制程序运行。 (四)实验步骤(包括主要步骤、代码分析等) 1〉首先建立一个MFC单文本文档,编译运行能输出一个text空白文本文档,关闭文本文档,展开项目工作区窗口Class View中的所有类结点,然后 单击CEx_SDIVew类结点,从弹出的快捷菜单中选择“Add Member Variable”添加两个成员变量,都设置为int型,两个分别命名为 m_nLButton和m_nRButton,如下图:

消息映射及MFC入门

MFC消息映射及MFC入门 一、MFC消息映射机制 在前面Win32Class工程中,我们进行了Win32环境下的“消息映射”。其实,通过前面的过程,我们已经不知不觉的接触到了MFC消息映射的核心。 MFC环境下的消息映射,其原理和我们讲解过的Win32下的消息映射是类似的。简单地讲,就是让程序员指定要某个MFC类(有消息处理能力的类)处理某个消息。MFC提供了工具ClassWizard来帮助实现消息映射,在处理消息的类中添加一些有关消息映射的内容和处理消息的成员函数。程序员负责编写消息处理函数的代码,实现所希望的功能。 可以通过如下的3个重要的宏来实现MFC消息映射,这些宏功能强大,其实现相对也比较复杂。这里只要求我们会用就可以。稍后我们会用其实际代码替换这些宏,就能理解了。 ●DECLARE_MESSAGE_MAP:初始化消息映射表,实际上是给所在类添加几个用 于消息处理的静态成员变量和静态或虚拟函数。 ●BEGIN_MESSAE_MAP:开始消息映射。 ●END_MESSAE_MAP:结束消息映射。 其他常见的、用于实现MFC消息的宏还有: ●前缀为“ON_WM_”的宏:用于Windows消息的宏(不带参数)如:ON_WM_PAINT() 把消息WM_PAINT映射到OnPaint函数。 ●ON_COMMAND宏:通过参数指定命令ID和消息处理函数。 如ON_COMMAND(ID_EDIT_PASTE, OnEditPaste),其中第二个参数OnEditPaste 的原型说明为:void CView::OnEditPaste()。 ●ON_UPDA TE_COMMAND_UI宏:用于更新菜单的状态。 ●前缀为”ON_”控件通知消息宏:这类宏可能带有三个参数,如ON_CONTROL,就 需要指定控制窗口ID,通知码和消息处理函数;也可能带有两个参数,如具体处 理特定通知消息的宏ON_BN_CLICKED、ON_LBN_DBLCLK、 ON_CBN_EDITCHANGE等,需要指定控制窗口ID和消息处理函数。 ●实现用户自定义消息的ON_MESSAGE宏:ON_MESSAGE(message, memberFxn)。 第一个参数为消息号,第二个参数为消息处理函数。 二、手工进行消息映射 上面是使用类向导工具自动进行的消息映射,下面我们通过手工的方式来实现同样的功能,以加深对消息映射的理解。 手工映射的主要步骤是: ●在.h头文件中:声明消息响应函数、声明消息映射。如: afx_msg void OnPaint(); //声明消息响应函数 DECLARE_MESSAGE_MAP() //声明消息映射 ●在.cpp文件中:进行消息映射。如: BEGIN_MESSAGE_MAP(CMyWnd,CFrameWnd)//消息映射开始 ON_WM_PAINT()//WM_PAINT消息映射宏 END_MESSAGE_MAP()//结束消息映射

深入分析理解MFC

默认情况下,C语言一般都有main函数,可是在MFC程序里面我们一般会发现不了main 函数,其实这个是有的。 注意:默认情况下。如在嵌入式领域,无论怎么启动,最终都会跳到一个循环程序,当出现正常退出或者异常才会退出这个循环,线程处理函数一样,所以main还是_tmain都是我们定义的入口函数,当然OS或者库也可以定义其他的,这个主函数其实只是一个入口点。看一个简单的c程序 [cpp]view plain copy print? 1.int main(int argc, char *argv[]) 2.{ 3. printf("hello\n"); 4. 5.return 0; 6.} 这里会有传入参数,执行循环体,返回语句 当然在Window SDK编程中也会出现这个的,因为SDK编程一般都是自己创建窗口,以下在VS2012自动生成的代码,在绘图处理代码中加入了hello的显示 [cpp]view plain copy print? 1.// Hello.cpp : 定义应用程序的入口点。 2.// 3. 4.#include "stdafx.h" 5.#include "Hello.h" 6. 7.#define MAX_LOADSTRING 100 8. 9.// 全局变量: 10.HINSTANCE hInst; // 当前实例 11.TCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本 12.TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名 13. 14.// 此代码模块中包含的函数的前向声明: 15.ATOM MyRegisterClass(HINSTANCE hInstance); 16.BOOL InitInstance(HINSTANCE, int); 17.LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 18.INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); 19. 20.int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, 21. _In_opt_ HINSTANCE hPrevInstance, 22. _In_ LPTSTR lpCmdLine, 23. _In_ int nCmdShow)

深入理解mfc消息

SPYXX是Visual Studio附带的一个非常有用的工具,可以很方便的查看到窗口的句柄,类,进程,线程,窗口消息等信息。在很多时候,我们要对一些外部程序的控件进行控制,例如变灰,变为可用状态等等,通常可以使用SPYXX来获取到控件的句柄,然后自己写个程序调用EnableWindow等这些函数来让控件变为可用状态,但是窗口一重新出现,句柄就会改变,这个时候就会很麻烦,试想一下,如果在SPYXX上添加这样一些功能,那岂不是很方便吗? 下面我们就来自己实现这样一些功能。 在开始动手之前,我们有必要了解一下MFC的消息响应相关知识,或许,你很会使用Visual Studio为你的应用程序添加一个消息响应函数,但你并不知道VS在编译消息响应的时候做了什么事,虽然我们使用Class Wizard添加一段消息响应十分简单,但MFC在处理这段消息响应的时候是非常复杂的,例如,一个按钮被单击的时候,将会产生以下一连串的函数调用: CWinThread::PumpMessage -> CWnd::PretranslateMessage -> CWnd::WWalkPreTranslateMessate -> CD1Dlg::PreTranslateMessage -> CDialog::PreTranslateMessage -> CWnd::PreTranslateInput -> CWnd::IsDialogMessageA -> USER32内核-> AfxWndProcBase -> AfxWndProc -> AfxCallWndProc -> CWnd::WindowProc -> CWnd::OnWndMsg -> CWnd::OnCommand -> CDialog::OnCmdMsg -> CCmdTarget::OnCmdMsg -> _AfxDispatchCmdMsg -> CD1Dlg::OnButton1() 当然,这很多调用都是对别的函数进行了一些简单的封装,在这里,我们要跟踪的2个比较重要的函数是_AfxDispatchCmdMsg 和CCmdTarget::OnCmdMsg ,_AfxDispatchCmdMsg的主要作用是调用我们自己编写的消息处理函数,而CCmdTarget::OnCmdMsg则是在当前的类以及父类里面查找消息的处理函数,如果找到处理函数,将调用_AfxDispatchCmdMsg来分发消息,如果没有找到,就返回,并在上级调用默认的消息处理函数。 以下是代码来自VS2005的MFC源代码: BOOL CCmdTarget::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) { #ifndef _AFX_NO_OCC_SUPPORT // OLE control events are a special case if (nCode == CN_EVENT) { ENSURE(afxOccManager != NULL); return afxOccManager->OnEvent(this, nID, (AFX_EVENT*)pExtra, pHandlerInfo); } #endif // !_AFX_NO_OCC_SUPPORT // determine the message number and code (packed into nCode) const AFX_MSGMAP* pMessageMap; const AFX_MSGMAP_ENTRY* lpEntry; UINT nMsg = 0; #ifndef _AFX_NO_DOCOBJECT_SUPPORT if (nCode == CN_OLECOMMAND) {

相关文档