VC++如何处理自定义消息

  • Post author:
  • Post category:其他

在SDK编程中,对消息的获取与分发是通过消息循环来完成。而在MFC编程中则是通过采取消息映射的方式对其进行处理。相比而言,这样的处理方式要简单得多,这也是符合面向对象编程中尽可能隐含实现细节的原则。一个完整MFC消息映射包括对消息处理函数的原型声明、实现以及存在于消息映射中的消息入口。一般情况下出了对自定义的消息响应外,对于标准Windows消息的映射处理可以借助ClassWizard向导来完成。

 

自定义消息可分为四步:

 

第一步:定义消息。开发Windows95应用程序时,Microsoft推荐用户自定义消息至少是WM_USER+100,因为很多新控件也要使用WM_USER消息。

 

第二步:实现消息处理函数。该函数使用WPRAM和LPARAM参数并返回LPESULT。

LPESULT CMainFrame::OnMyMessage(WPARAM wParam, LPARAM lParam)
{
// TODO: 处理用户自定义消息

return 0;
}


第三步:在类头文件的AFX_MSG块中说明消息处理函数:

class CMainFrame:public CMDIFrameWnd
{

// 一般消息映射函数
protected:
// {{AFX_MSG(CMainFrame)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnTimer(UINT nIDEvent);
afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
}
第四步:在用户类的消息块中,使用ON_MESSAGE宏指令将消息映射到消息处理函数中。

BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
ON_WM_CREATE()
ON_WM_TIMER()
ON_MESSAGE(WM_MY_MESSAGE, OnMyMessage)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

如果用户需要一个整个系统唯一的消息,可以调用SDK函数RegisterWindowMessage并使用ON_REGISTER_MESSAGE宏指令取代ON_MESSAGE宏指令,其余步骤同上。

 

附:

消息循环结构一般入下:

 

while (GetMessage(&msg, (HWND) NULL, 0, 0))

{

  //从消息队列得到消息

  if (hwndDlgModeless == (HWND) NULL ||   !IsDialogMessage(hwndDlgModeless, &msg) &&   !TranslateAccelerator(hwndMain, haccel, &msg))

  {

  TranslateMessage(&msg);

  DispatchMessage(&msg); //发送消息

  }

}

 

2. MFC还提供了其他一些用于消息映射的宏,详情可参见下表:

宏名 说明
DECLARE_MESSAGE_MAP 在头文件声明源文件中所含有的消息映射
BEGIN_MESSAGE_MAP 标记源文件消息映射的开始
END_MESSAGE_MAP 标记源文件消息映射的结束
ON_COMMAND 将特定命令的处理委派给类的一个成员函数
ON_CONTROL 映射一个函数到一个定制控制通知消息。其中,定制控制通知消息是从一个控制发送到其父窗口的消息。
ON_CONTROL_RANGE 将一个控制ID的范围映射到一个消息处理函数
ON_CONTROL_REFLECT 映射一个由父窗口反射回控制的通知消息
ON_MESSAGE 将一个用户自定义消息映射到一消息处理函数
ON_NOTIFY  映射一个控制消息到一个函数
ON_NOTIFY_RANGE 映射一个控制ID范围内的控制消息到一个函数
ON_NOTIFY_EX 映射一个控制消息到一个函数,该成员函数返回FALSE或TRUE来表明通知是否应被传送到下一个对象以进行其他反应。
ON_NOTIFY_EX_RANGE 映射一个控制ID范围内的控制消息到一个函数,该成员函数返回FALSE或TRUE来表明通知是否应被传送到下一个对象以进行其他反应
ON_NOTIFY_REFLECT 映射一个控制消息到一个函数。该消息将会被控制的父窗口反射回来。
ON_REGISTERED_MESSAGE 映射一个唯一的消息到一个将要处理该注册消息的函数上。该消息是由RegisterWindowMessage()函数注册的。
ON_UPDATE_COMMAND_UI  映射一个函数来处理一个用户接口更新命令消息
ON_UPDATE_COMMAND_UI_RANGE 映射一个命令ID的范围到一个更新消息处理函数

3. 宏工作原理

前面给出了消息映射的一般形式,下面就对消息映射的工作原理做更深入的分析。任何使用了MFC应用程序框架的Windows程序都含有一个从CWinApp派生的应用程序类对象,成员函数Run()将被隐含调用,其调用的CWinThread类成员函数Run()将通过对GetMessage()、TranslateMessage()和DispatchMessage()等函数的调用完成同WinMain()类似的消息循环。在消息处理中,几乎所有的窗口对象都使用AfxWndProc()窗口处理函数,并通过一个包含了窗口句柄和对象指针等信息的列表而获取到一个指向对象的指针,由此可以调用CWnd的虚函数WindowProc()。WindowProc()函数调用了CWnd的另一个成员函数OnWndMsg(),该函数首先检查到达的究竟是消息,命令还是通知(Notify),如果是消息就通过消息映射宏DECLARE_MESSAGE_MAP

 

 

 

 

 

 

 

 


版权声明:本文为chaozi2008原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。