MFC中的自定义消息


MFC中的消息类型:

普通消息:也就是以WM_开头,除了WM_COMMAND以外的消息,这类消息在WM_USER以下的是系统消息,WM_USER以上的可以由 用户自己定义

命令消息:就是WM_COMMAND,也就是一些菜单、工具栏中的消息,包括快捷键,这类消息处理的机制与其他以WM_开头的消息处理 机制不同,它具有一条层次明确的消息流动路径


1.如果一个类要响应消息,应该具备什么条件?

答:能够响应消息的类必须都从CCmdTarget类中派生,因为只有以这个类中提供了消息的框架和处理机制。

而CWnd类,CWinApp类、CDocument类、CDocTemplate类等都是CCmdTarget的派生类,即子类;而CFrameWnd类、CView类、CDialog类等都是从CWnd中派生的,其实也是CCmdTarget的子孙,所以都能够响应消息,但是响应消息的种类不太相同。

          如果该类要求响应普通的Windows消息,那就要求自定义的类必须从CWnd中派生。  

如果该类要求响应命令消息,那么自定义的类可以从CCmdTarget中派生


2.普通消息的处理机制是怎样的?

答:消息发出者直接发给对应CWnd的窗体句柄,由CWnd负责消息的响应。

所以这类消息必须同一个CWnd类对应,更精确的说必须与一个HWND类型的窗体句柄相对应。

CWnd类或其子类没有调用CWnd::Create或CWnd::CreateEx函数时,CWnd类不对应任何窗体,消息处理不能正常运作。


3.如何自定义MFC消息?

答:在.h中做的工作:

第一步要声明消息:

#define WM_MYMSG WM_USER+8

第二步要在类声明中声明消息映射:

DECLARE_MESSAGE_MAP()

第三步要在类声明中定义消息处理函数:

afx_msg LRESULT MyMsgHandler(WPARAM,LPARAM);

在.cpp中做的工作:

第四步要实现消息映射:

BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
ON_MESSAGE(WM_MYMSG,OnMyMsgHandler)
END_MESSAGE_MAP()

第五步要实现消息处理函数(当然可以不实现):

LRESULT CMainFrame::OnMyMsgHandler(WPARAM w,LPARAM l)
{
AfxMessageBox("Hello,World!");
return 0; 
}

在引发或发出消息的地方只用写上

::SendMessge(::AfxGetMainWnd()->m_hWnd,WM_MYMSG,0,0);



4.以上是继承自CWnd类的自定义消息处理,如何自定义一个由CObject类派生的类来处理消息呢?

答:一个重要的结论,在自定义类能够处理任何消息之前一定要确保m_hWnd关联到一个窗体,即便这个窗体是不可见的。

在自定义类的构造函数中调用Create函数,当然也可以在别处调用,只要确保在消息发送之前。

Create的调用,要注意两个地方,第一个参数是类的名称,最好设为NULL,

第五个参数是父窗体对象的指针,这个函数指定的对象一定要存在,最好为整个程序的主窗体。

程序实例:

CMyTestObject::CMyTestObject()
{
CWnd::Create(NULL,"MyTestObject",WS_CHILD,CRect(0,0,0,0),::AfxGetMainWnd(),1234);
}    //一定要在生成主窗体后使用,在主窗体完成OnCreate消息的处理后

CMyTestObject::CMyTestObject(CWnd *pParent)
{
CWnd::Create(NULL,"MyTestObject",WS_CHILD,CRect(0,0,0,0),pParent,1234);
}


不能如下调用Create,因为此时CMyTestObject不关联任何窗体,所以this中的m_hWnd无效:

CWnd::Create(NULL,"MyTestObject",WS_CHILD,CRect(0,0,0,0),this,1234);


映射自定义消息函数:

BEGIN_MESSAGE_MAP(CMyTestObject, CWnd)
ON_MESSAGE(WM_MYMSG,OnMyMsgHandler)
END_MESSAGE_MAP()

LRESULT CMyTestObject::OnMyMsgHandler(WPARAM w,LPARAM l)
{
AfxMessageBox("My Messge Handler in My Self-Custom Class!");
return 0; 
}


在类外部发出消息:

CMyTestObject *test=new CMyTestObject();
::SendMessage(test->m_hWnd,WM_MYMSG,0,0);


在类内部某个成员函数(方法)中发出消息:

::SendMessage(m_hWnd,WM_MYMSG,0,0);


最后一个问题便是容易产生警告错误的窗体回收,自定义的类要显式调用窗体销毁,析构函数如下:

CMyTestObject::~CMyTestObject()
{
CWnd::DestroyWindow();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值