硬件/系统
自定义消息获取消息
1. 自定义消息
(1) 手工定义消息,可以这么写 #define WM_MY_MESSAGE(WM_USER+100), MS 推荐的至
少是 WM_USER+100;
(2)写消息处理函数,用 WPARAM,LPARAM返回LRESULT.
LRESULT CMainFrame::OnMyMessage(WPARAM wparam,LPARAM lParam)
{
//加入你的处理函数
}
(3) 在类的 AFX_MSG处进行声明,也就是常说的"宏映射"
//-----------------------------------------------------------------------
2. 获取有关窗口正在处理的当前消息的信息
调用CWnd: : GetCurrentMessage 可以获取一个MSG指针。例如,可以使用ClassWizard
将几个菜单项处理程序映射到一个函数中,然后调用GetCurrentMessage 来确定所选中
的菜单项。
viod CMainFrame : : OnCommmonMenuHandler ( )
{
//Display selected menu item in debug window .
TRACE ("Menu item %u was selected . \n" ,
GetCruuentMessage ( ) ―> wParam );
}
//-----------------------------------------------------------------------
3.窗口最大化、最小化及关闭的消息是什么
最大化、最小化将发送WM_SYSCOMMAND消息。要处理该消息,可以这么做:
(1)、在Form的头文件中添加:
void __fastcall RestrictMinimizeMaximize(TMessage &Msg);
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_SYSCOMMAND, TMessage, RestrictMinimizeMaximize)
END_MESSAGE_MAP(TForm)
(2)、在Form的单元文件中添加:
void __fastcall TForm1::RestrictMinimizeMaximize(TMessage& Msg)
{
if (Msg.WParam == SC_MINIMIZE)
{
//catches minimize...
}
else if (Msg.WParam == SC_MAXIMIZE)
{
//catches maximize...
}
TForm::Dispatch(&Msg);
// or "else TForm::Dispatch(&Msg)" to trap
}
关闭窗口的消息为WM_CLOSE,C++Builder提供了OnClose事件
//-----------------------------------------------------------------------
消息映射的定义和实现
MFC处理的三类消息
根据处理函数和处理过程的不同, MFC主要处理三类消息:
Windows 消息,前缀以“WM_”打头,WM_COMMAND例外。Windows消息直接送给MFC窗口过程处理,窗口过程调用对应的消息处理函数。一般,由窗口对象来处理这类消息,也就是说,这类消息处理函数一般是MFC窗口类的成员函数。
控制通知消息,是控制子窗口送给父窗口的 WM_COMMAND通知消息。窗口过程调用对应的消息处理函数。一般,由窗口对象来处理这类消息,也就是说,这类消息处理函数一般是MFC窗口类的成员函数。
需要指出的是,Win32使用新的WM_NOFITY来处理复杂的通知消息。WM_COMMAND类型的通知消息仅仅能传递一个控制窗口句柄(lparam)、控制窗ID和通知代码(wparam)。WM_NOTIFY能传递任意复杂的信息。
命令消息,这是来自菜单、工具条按钮、加速键等用户接口对象的WM_COMMAND通知消息,属于应用程序自己定义的消息。通过消息映射机制,MFC框架把命令按一定的路径分发给多种类型的对象(具备消息处理能力)处理,如文档、窗口、应用程序、文档模板等对象。能处理消息映射的类必须从CCmdTarget类派生。
在讨论了消息的分类之后,应该是讨论各类消息如何处理的时候了。但是,要知道怎么处理消息,首先要知道如何映射消息。
MFC消息映射的实现方法
MFC 使用ClassWizard帮助实现消息映射,它在源码中添加一些消息映射的内容,并声明和实现消息处理函数。现在来分析这些被添加的内容。
在类的定义(头文件)里,它增加了消息处理函数声明,并添加一行声明消息映射的宏 DECLARE_MESSAGE_MAP。
在类的实现(实现文件)里,实现消息处理函数,并使用 IMPLEMENT_MESSAGE_MAP宏实现消息映射。一般情况下,这些声明和实现是由MFC的ClassWizard自动来维护的。看一个例子:
在 AppWizard产生的应用程序类的源码中,应用程序类的定义(头文件)包含了类似如下的代码:
//{{AFX_MSG(CTttApp)
afx_msg void OnAppAbout();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
应用程序类的实现文件中包含了类似如下的代码:
BEGIN_MESSAGE_MAP(CTApp, CWinApp)
//{{AFX_MSG_MAP(CTttApp)
ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
头文件里是消息映射和消息处理函数的声明,实现文件里是消息映射的实现和消息处理函数的现。它表示让应用程序对象处理命令消息 ID_APP_ABOUT,消息处理函数是OnAppAbout。
为什么这样做之后就完成了一个消息映射?这些声明和实现到底作了些什么呢?接着,将讨论这些问题。
在声明与实现的内部
DECLARE_MESSAGE_MAP宏:
首先,看DECLARE_MESSAGE_MAP宏的内容:
#ifdef _AFXDLL
#define DECLARE_MESSAGE_MAP() private: static const AFX_MSGMAP_ENTRY _messageEntries[]; protected: static AFX_DATA const AFX_MSGMAP messageMap; static const AFX_MSGMAP* PASCAL _GetBaseMessageMap(); virtual const AFX_MSGMAP* GetMessageMap() const;
#else
#define DECLARE_MESSAGE_MAP() private: static const AFX_MSGMAP_ENTRY _messageEntries[]; protected: static AFX_DATA const AFX_MSGMAP messageMap; virtual const AFX_MSGMAP* GetMessageMap() const;
#endif
DECLARE_MESSAGE_MAP 定义了两个版本,分别用于静态或者动态链接到MFC DLL的情形。
BEGIN_MESSAE_MAP宏
然后,看BEGIN_MESSAE_MAP宏的内容:
#ifdef _AFXDLL
#define BEGIN_MESSAGE_MAP(theClass, baseClass) const AFX_MSGMAP* PASCAL theClass::_GetBaseMessageMap() { return &baseClass::messageMap; } const AFX_MSGMAP* theClass::GetMessageMap() const { return &theClass::messageMap; } AFX_DATADEF const AFX_MSGMAP theClass::messageMap = { &theClass::_GetBaseMessageMap, &theClass::_messageEntries[0] }; const AFX_MSGMAP_ENTRY theClass::_messageEntries[] = {
#else
#define BEGIN_MESSAGE_MAP(theClass, baseClass) const AFX_MSGMAP* theClass::GetMessageMap() const { return &theClass::messageMap; } AFX_DATADEF const AFX_MSGMAP theClass::messageMap = { &baseClass::messageMap, &theClass::_messageEntries[0] }; const AFX_MSGMAP_ENTRY theClass::_messageEntries[] = {
#endif
#define END_MESSAGE_MAP() {0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 } }; 对应地, BEGIN_MESSAGE_MAP定义了两个版本,分别用于静态或者动态链接到MFC DLL的情形。END_MESSAGE_MAP相对简单,就只有一种定义。
ON_COMMAND宏
最后,看ON_COMMAND宏的内容:
#define ON_COMMAND(id, memberFxn) {WM_COMMAND,CN_COMMAND,(WORD)id,(WORD)id,AfxSig_vv,(AFX_PMSG)memberFxn};
消息映射声明的解释
在清楚了有关宏的定义之后,现在来分析它们的作用和功能。
消息映射声明的实质是给所在类添加几个静态成员变量和静态或虚拟函数,当然它们是与消息映射相关的变量和函数。
CSDN VC编程经验总结