可以实现自己的特殊需 要。比如如果我们要在特定的时间间隔内通知所有数据输出视口重新取得新数据, 要依靠菜单命令和按钮命令实现不够理想,比较理想的解决办法是采用定时器事件 进行特定的计算操作,操作完成后再采用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);
相对来讲,这种机制不如上述机制简单,也就不再赘述。
七、使用不带文挡-视结构的MFC应用
文档-视结构的功能是非常强大的,可以适合于大多数应用程序,但是有时我们只需 要非常简单的程序,为了减少最终可执行文件尺寸和提高运行速度,我们没有必要 使用文挡-视结构,典型的有简单SDI应用和基于对话框的应用。
1、简单SDI应用
此时只需要使用CWinApp和CFrameWnd两个类就完全可以了。由于CWinApp类封装了 WinMain函数和消息处理循环,因此任何使用MFC进行编程的程序都不能脱离开该 类。实际上使用CWinApp类非常简单,主要是派生一个用户自己的应用类,如 CMyApp,然后只需重载CWinApp类的InitInstance()函数:
BOOL CMyApp::InitInstance()
{
m_pMainWnd=new CMainFrame();
ASSERT(m_pMainWnd!=NULL); //error checking only
m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow();
return TRUE;
}
至于所需要的主框架类,则可以直接使用ClassWizard实用程序生成,该类的头文件 与实现代码可以与CMyApp类的头文件和实现代码放在一起。注意,这里由一个技 巧,由于ClassWizard的使用需要有相应的CLW文件存在,而收工建代码时没有对应 的CLW文件,因此不能直接使用,解决办法是进入App Studio实用工具后使用 ClassWizard,此时系统会发觉不存在相应的CLW文件,系统将提示你重建CLW文件并 弹出相应对话框,这时候你不需要选择任何文件就直接选择OK按钮,这样系统将为 你产生一个空的CLW文件,这样就可以使用ClassWizard实用工具了。为了将CWinApp 和CFrameWnd的派生类有机地结合在一起,只需在CFrameWnd派生类的构造函数中进 行窗口创建即可。典型代码如下:
CMainFrame::CMainFrame()
{
Create(NULL,"DDE Client Application",WS_OVERLAPPEDWINDOW,rectDefault, NULL,MAKEINTRESOURCE(IDR_MAINFRAME));
}
采用ClassWizard实用程序生成相关类代码后,所有的类的其它实现和维护就同普通由AppWizard实用程序产生的代码一样了。
2、基于对话框的