2、使用自己的消息
在程序设计的更深层次,人们常常会发现只依赖于菜单和命令按钮产生的消息是不够的,常常因为程序运行的逻辑结构和不同视口之间数据的同步而需要使用一些自定义的消息,这样通过在相应层次上安排消息响应函数就可以实现自己的特殊需要。比如如果我们要在特定的时间间隔内通知所有数据输出视口重新取得新数据,要依靠菜单命令和按钮命令实现不够理想,比较理想的解决办法是采用定时器事件进行特定的计算操作,操作完成后再采用SendMessage发送自己的特定消息,只有当这一消息得到处理后才会返回主控程序进行下一时间计算。通过在文档层次上安排对消息的响应取得最新计算数据,而后通过UpdateAllViews()成员函数来通知所有相关视口更新数据的显示。视口通过重载OnUpdate()成员函数就可以实现特定数据的更新显示。
如果用户能够熟练使用SendMessage()函数和PostMessage()函数,那么要发送自定义消息并不难,通常有两种选择,其一是发送WM_COMMAND消息,通过消息的WORD wParam参数传递用户的命令ID,举例如下:
SendMessage(WM_COMMAND,IDC_GETDATA,0); //MFC主框架发送
然后在文档层次上安排消息映射入口:
ON_COMMAND(IDC_GETDATA, OnGetData)
同时在文档类中实现OnGetData()函数:
void CSimuDoc::OnGetData() { TRACE("Now in SimuDoc,From OnGetData\n"); UpdateAllViews(NULL); } |
注意在上中的消息映射入口需要用户手工加入,Visual C++提供的ClassWizard并不能替用户完成这一工作。上中例子没有使用PostMessage函数而使用SendMessage函数的原因是利用了SendMessage函数的特点,即它只有发送消息得到适当处理后方才
返回,这样有助于程序控制。另一种发送自定义消息的办法是直接发送命令ID,在控制层次上采用ON_MESSAGE来实现消息映射入口,注意这时的命令控制函数的原型根据Windows本身消息处理的规定必须如下:
afx_msg LONG OnCaculationOnce(WPARAM wParam,LPARAM lParam); |
相对来讲,这种机制不如上述机制简单,也就不再赘述。