当前位置:文档之家› mfc原理和消息映射

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;elsereturn false;}BOOL CWnd::ShowWindow(){return ShowWindow(hWnd,nCmdShow);}为了保证代码和以前的执行方式一样,Winmain()函数可以写成如下形式:int WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){CMyWnd m_wnd;m_wnd.Create();m_wnd.ShowWindow();MSG msg;while(GetMessage(&msg,NULL,0,0)){TranslateMessage(&msg);DispatchMessage(&msg);}return true;}此时,如果再写一个新的类来对剩下的代码进行封装,代码如下:class CWinApp{public:CWnd * m_pMainWnd;BOOL InitInstance();BOOL Run();CWinApp ();};CWinApp:: CWinApp (){if(InitInstance())Run();}BOOL CWinApp::InitInstance(){CWnd m_wnd;m_pMainWnd=&m_wnd;m_pMainWnd->Create();m_pMainWnd->ShowWindow();return true;}BOOL CWinApp::Run(){MSG msg;while(GetMessage(&msg,NULL,0,0)){TranslateMessage(&msg);DispatchMessage(&msg);}return true;}CWinApp theApp;int PASCAL WinMain() {}Windows消息的产生:1用户按键或者鼠标操作可以产生消息,如WM_KEYDOWN,WM_LBUTTONDOWN等;2系统可以自己产生消息,如,创建窗口的时候会产生WM_CREATE,WM_TIMER等;3应用程序间可以定义自己的消息,在应用程序间进行消息通讯;Windows消息的分类:1窗口消息(Windows Message):通常跟窗口的移动、创建,关闭等操作有关。

窗口为消息的接收对象。

如以上的WM_LBUTTONDOWN,WM_CREATE等。

2命令消息(Command Message):由用户操作菜单、按钮等资源是触发,以WM_COMMAND 形式出现。

wparam3控件通知消息(Control Notification Message):该消息是在控件相关内容或者状态改变时由控件本身通知父窗口。

4用户自定义消息:有时候用户自己需要定义自己的消息进行处理,为了跟系统消息区分,系统专门划分一段消息编号区间来让用户定义自己的消息。

#define MY_MESSAGE WM_USER + 1 // 用户自定义消息Windows32消息的结构:MSG 结构的定义如下:typedef struct tagMSG{HWND hwnd; //接收消息的窗口句柄UINT message; //消息标识(ID)WPARAM wParam; //第一个消息参数LPARAM lParam; //第二个消息参数DWORD time; //消息产生的时间POINT pt; //消息产生时鼠标的位置} MSG;回忆窗口处理函数首部,主消息循环相关重要代码。

MFC消息处理机制:所谓消息映射,简单地讲,就是让程序员指定要某个MFC类(有消息处理能力的类)处理某个消息。

MFC提供了工具ClassWizard来帮助实现消息映射,在处理消息的类中添加一些有关消息映射的内容和处理消息的成员函数。

程序员将完成消息处理函数,实现所希望的消息处理能力。

通过几个重要的宏来实现MFC消息映射,这些宏功能强大,其实现相对也比较复杂。

这里只要求我们会用就可以。

DECLARE_MESSAGE_MAP:初始化消息映射表,实际上是给所在类添加几个用于消息处理的静态成员变量和静态或虚拟函数。

BEGIN_MESSAE_MAP:开始消息映射END_MESSAE_MAP:结束消息映射。

MFC常见消息实现宏:前缀为“ON_WM_”的宏:用于Windows消息的宏,这样的宏不带参数,因为它对应的消息和消息处理函数的函数名称、函数原型是确定的。

如:ON_WM_PAINT()把消息WM_PAINT映射到OnPaint函数。

当然OnPaint可以自己定义。

ON_COMMAND宏:带有参数,需要通过参数指定命令ID和消息处理函数。

其中消息处理函数的原型是void (void),没有参数,也没有返回值。

如:ON_COMMAND(ID_EDIT_PASTE, OnEditPaste),其中第二个参数OnEditPaste的原型说明为:void CVcView::OnEditPaste()。

状态更新的ON_UPDATE_COMMAND_UI宏:参数含义同ON_COMMAND宏。

前缀为”ON_”控件通知消息宏:这类宏可能带有三个参数,如ON_CONTROL,就需要指定控制窗口ID,通知码和消息处理函数;也可能带有两个参数,如具体处理特定通知消息的宏ON_BN_CLICKED、ON_LBN_DBLCLK、ON_CBN_EDITCHANGE等,需要指定控制窗口ID和消息处理函数。

用户自定义消息宏ON_MESSAGE:MFC提供的用于对用户自定义消息进行映射的宏ON_MESSAGE(message, memberFxn)。

第一个参数为消息号,第二个参数为消息处理函数。

最主要是这些宏的使用:例1 MFC类向导(class wizard):可以使用类向导(class wizard)工具来建立消息映射处理代码,一般类向导生成的代码最好不要手动修改。

如对一个菜单项使用类向导进行消息映射:1点击右键选择class wizard,如下图:2选择合适的类,要进行映射的资源ID,和要进行映射的消息种类,使他们高亮显示如下图。

然后点击add function按钮,系统为给对应的消息处理函数起名。

如果ID名称起的合理,该函数名也会相应合理。

类向导会自动生成该函数的声明和定义。

当然,函数体一般情况是空的,需要自己定义。

3生成的函数声明、消息映射和函数定义分别如下:消息映射:函数声明:函数定义:例2手工进行消息映射:在当前类的头文件中生命消息映射DECLARE_MESSAGE_MAP(),在对应的实现文件中进行消息映射。

建立Win32应用程序空工程Win32MFC,添加如下文件:头文件://Win32MFC.hclass CMyApp:public CWinApp{public:virtual BOOL InitInstance();};class CMyWnd:public CFrameWnd{public:CMyWnd();protected:afx_msg void OnPaint(); // 手工声明消息响应函数DECLARE_MESSAGE_MAP() // 手工声明消息映射};实现文件://Win32MFC.cpp#include"Win32MFC.h"CMyApp theapp;BEGIN_MESSAGE_MAP(CMyWnd,CFrameWnd) // 消息映射开始ON_WM_PAINT() // WM_PAINT消息映射宏END_MESSAGE_MAP() // 结束消息映射BOOL CMyApp::InitInstance(){m_pMainWnd=new CMyWnd;m_pMainWnd->ShowWindow(m_nCmdShow);m_pMainWnd->UpdateWindow();return TRUE;}CMyWnd::CMyWnd(){Create(NULL,"Win32 MFC Application");}//手工定义消息响应函数,并添加函数处理代码void CMyWnd::OnPaint(){CPaintDC dc(this);CRect rect;GetClientRect(&rect);dc.DrawText("Hello everyone,I come from earth!", -1,&rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);}。

相关主题