mfc自定义消息步骤

来源:互联网 发布:rds sqlserver 编辑:程序博客网 时间:2024/04/29 12:59

第一步要声明消息:

#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);

到此,自定义消息完毕,这是好多网上文章都写的东西。大家会发现上面代码是在CMainFrame类中实现的,但是

如果要用自定义类,就没有那么简单了。显然把第四步与第五步的CMainFrame换成自定义的类名(这里我用

CMyTestObject来代表自定义类)是不能正常工作的。原因在于在发送消息的SendMessage函数中的第一个参数是

要响应消息对应的HWND类型的窗体句柄,而CMyTestObject类中的m_hWnd中在没有调用CWnd::Create之前是没有

任何意义的,也就是没有调用CWnd::Create或CWnd::CreateEx函数时,CWnd不对应任何窗体,消息处理不能正常

运作。

所以,又一个重要的结论,在自定义类能够处理任何消息之前一定要确保m_hWnd关联到一个窗体,即便这个窗体

是不可见的。那么有人说,在自定义类的构造函数中调用Create函数就行了,不错,当然也可以在别处调用,只

要确保在消息发送之前。但是,Create的调用很有说法,要注意两个地方,第一个参数是类的名称,我建议最好

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

。还有很多人问第六个参数的意义,这个参数关系不大,是子窗体ID,用于传给父窗体记录以便识别。如下是我

的自定义类的构造函数:

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();
}

 

0 0