息壤网站打不开了,企业域名备案流程详细,做配单ic去什么网站好,wordpress 显示 当前位置何谓消息、消息处理函数、消息映射#xff1f;消息简单的说就是指通过输入设备向程序发出指令要执行某个操作。具体的某个操作是你的一系列代码。称为消息处理函数。在SDK中消息其实非常容易理解#xff0c;当窗口建立后便会有一个函数#xff08;窗口处理函数#xff09;开…何谓消息、消息处理函数、消息映射 消息简单的说就是指通过输入设备向程序发出指令要执行某个操作。具体的某个操作是你的一系列代码。称为消息处理函数。在SDK中消息其实非常容易理解当窗口建立后便会有一个函数窗口处理函数开始执行一个消息循环我们还可以清楚的看到消息处理的脉络。一个switch case语句就可以搞定消息循环直到遇到WM_QUIT消息才会结束其余的消息均被拦截后调用相应的处理函数。但在封装了API的MFC中消息似乎变的有些复杂了我们看不到熟悉的switch case语句了取而代之的是一个叫消息映射的东西。为什么MFC要引入消息映射机制你可以想象一下在现在的程序开发活动中你的一个程序是否拥有多个窗体主窗口就算只有一个那菜单、工具条、控件这些都是子窗口那我们需要写多少个switch case并且还要为每个消息分配一个消息处理函数这样做是多么的复杂呀。因此MFC采用了一种新的机制。利用一个数组将窗口消息和相对应的消息处理函数进行映射你可以理解成这是一个表。这种机制就是消息映射。这张表在窗口基类CWnd定义派生类的消息映射表如果你没有动作它是空的也就是说如果你不手工的增加消息处理函数则当派生窗口接受一个消息时会执行父类的消息处理函数。这样做显然是高效的。 MFC提供的消息结构 同时MFC定义了下面的两个主要结构: AFX_MSGMAP_ENTRY struct AFX_MSGMAP_ENTRY{ UINT nMessage; // Windows消息的ID号 UINT nCode; // 控制消息的通知 UINT nID; // Windows控制消息的ID UINT nLastID; //表示是一个指定范围的消息被映射的范围 UINT nSig; //表示消息的动作标识 AFX_PMSG pfn; // 指向消息处理函数的指针 }; AFX_MSGMAP struct AFX_MSGMAP{ #ifdef _AFXDLL const AFX_MSGMAP* (PASCAL* pfnGetBaseMap)(); #else const AFX_MSGMAP* pBaseMap; #endif const AFX_MSGMAP_ENTRY* lpEntries; }; ///AFX_MSGMAP可以得到基类的消息映射入口地址和得到本身的消息映射入口地址。 MFC下一个消息的处理过程是一般是这样的。 1、_AfxCbtFilterHook截获消息这是一个钩子函数 2、_AfxCbtFilterHook把窗口过程设定为AfxWndProc。 3、函数AfxWndProc接收Windows操作系统发送的消息。 4、函数AfxWndProc调用函数AfxCallWndProc进行消息处理。 5、函数AfxCallWndProc调用CWnd类的方法WindowProc进行消息处理。 如何添加自己的消息 我们已经了解了WINDOW的消息机制如何加入我们自己的消息呢好我们来看 一个标准的消息处理程序是这个样子的 在 CWnd 类中预定义了标准 Windows 消息 (WM_XXXX WM是WINDOW MESSAGE的缩写) 的默认处理程序。类库基于消息名命名这些处理程序。例如WM_PAINT 消息的处理程序在 CWnd 中被声明为 afx_msg void OnPaint(); afx_msg 关键字通过使这些处理程序区别于其他 CWnd 成员函数来表明 C virtual 关键字的作用。但是请注意这些函数实际上并不是虚拟的而是通过消息映射实现的。我们在本文的一开始便说明了为什么要这样做。 所有能够进行消息处理的类都是基于CCmdTarget类的也就是说CCmdTarget类是所有可以进行消息处理类的父类。CCmdTarget类是MFC处理命令消息的基础和核心。 若要重写基类中定义的处理程序只需在派生类中定义一个具有相同原型的函数并创建此处理程序的消息映射项。我们通过ClassWizard可以建立大多数窗口消息或自定义的消息通过ClassWizard可以自动建立消息映射和消息处理函数的框架我们只需要把我们要做的事情填空,添加你要做的事情到处理函数。这个非常简单就不细说了。但是也许我们需要添加一些ClassWizard不支持的窗口消息或自定义消息那么就需要我们亲自动手建立消息映射和消息处理的框架通常步骤如下 第一步定义消息。Microsoft推荐用户自定义消息至少是WM_USER100因为很多新控件也要使用WM_USER消息。 #define WM_MYMESSAGE (WM_USER 100) 第二步实现消息处理函数。该函数使用WPRAM和LPARAM参数并返回LPESULT。 LPESULT CMainFrame::OnMyMessage(WPARAM wParam, LPARAM lParam) { // TODO: 处理用户自定义消息填空就是要填到这里。 return 0; } 第三步在类头文件的AFX_MSG块中说明消息处理函数 // {{AFX_MSG(CMainFrame) afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam); //}}AFX_MSG DECLARE_MESSAGE_MAP() 第四步在用户类的消息块中使用ON_MESSAGE宏指令将消息映射到消息处理函数中。 ON_MESSAGE( WM_MYMESSAGE, OnMyMessage ) 可以看出用户自定义的消息和我们通过ClassWizard添加的消息一样都是利用了ON_MESSAGE宏,建立的消息映射。 其实消息类别可以分成多种上面说的只是其中之一。有三种主要的消息类别以下部分摘自MSDN 1、Windows 消息 此类消息主要包括以前缀 WM_ 开头的消息WM_COMMAND 除外。Windows 消息由窗口和视图处理。此类消息往往带有用于确定如何处理消息的参数。 2、控件通知 此类消息包括从控件和其他子窗口发送到其父窗口的 WM_COMMAND 通知消息。例如当用户在编辑控件 (Edit Control) 中执行可能更改文本的操作后该编辑控件 (Edit Control) 将向其父级发送包含 EN_CHANGE 控件通知代码的 WM_COMMAND 消息。该消息的窗口处理程序以某种适当的方式响应此通知消息例如在控件中检索该文本。 框架像传送其他 WM_ 消息一样传送控件通知消息。但是有一个例外的情况即当用户单击按钮时由按钮发送的 BN_CLICKED 控件通知消息。该消息被作为命令消息特别处理并像其他命令一样传送。 3、命令消息 此类消息包括用户界面对象菜单、工具栏按钮和快捷键发出的 WM_COMMAND 通知消息。框架处理命令的方式与处理其他消息不同可以使用更多种类的对象处理命令。 Windows 消息和控件通知消息由窗口来处理窗口是从 CWnd 类派生的类的对象。包括 CFrameWnd、CMDIFrameWnd、CMDIChildWnd、CView、CDialog 以及从这些基类派生的您自己的类。这些对象封装了 HWND——Windows 窗口的句柄。 命令消息可以由范围更广的对象文档、文档模板以及应用程序对象本身处理而不仅仅由窗口和视图处理。当某一命令直接影响到某个特定对象时应当让该对象处理此命令。例如“文件”菜单中的“打开”命令在逻辑上与应用程序相关联该应用程序接收到此命令时会打开指定的文档。因此“打开”命令的处理程序是应用程序类的成员函数。 命令消息我们比较常见的便是菜单项和工具条了大家可以看到他的消息映射宏和窗口消息不太一样一般的形式是这样的 ON_COMMAND(id,memberFxn) 第一个参数是命令ID一个ID号对应一个消息处理当然你可以让多个ID共用一个处理函数。常见的应用例如菜单项打开文档的ID和工具条按钮打开文档的ID同时使用一个处理函数或者直接将它们的ID设成相同的。 还有一种消息叫通知消息。例如树型控件的等一些复杂的控件在单击后需要传递更多的信息例如光标的位置和当前项的一个结构所以MFC为控件的每个通知消息也定义了一个宏它长成了这个样子 ON_CONTROL(EN_CHANGE,id,memberFxn) 还有很多种消息存在于MFC宏定义有区别大家可以触类旁通。 窗口消息有上百个。你可以从MSDN上查到WM_开头的或者查看CWnd的成员函数会给你列出很多别忘了还有很多非窗口消息。雷神无法一一列出也没有必要。大家查一下就行了。不过对一些常用的、新的控件消息和特殊的通知消息我还是把他们列出几个表大家做个参考吧。