Maintaining the MRU
尽管 WTL 提供了对视图类的支持 , 但它没有 MFC 中文档类的概念 . 如果想在你的 WTL 应用程序中支持文档 / 视图模式的话 , 你得自己去实现 . 我们写了一系列提供基本文档功能的类 , 你可以在你的应用程序中使用 , 这些类在本书的 WTLDocView 示例中 .
如果你做文档工作 , 你总是希望在文件菜单中有最近使用文件列表 (MRU) 的支持 . 虽然 WTL 不支持文档 , 它却提供 CRecentDocumentList 类 (atlmisc.h 中定义 ) 完整地支持 MRU, 这多少有些令人惊奇 . 主框架窗口通常管理一个 CRecentDocumentList 类对象实例 . 在其 WM_CREATE 消息映射函数中用一个文件菜单句柄初始化 CRecentDocumentList 对象 , 然后调用 CRecentDocumentList::ReadFromRegistry() 成员函数 , 在既定的注册表键下查询 最多 16 个入口来填充 MRU. 默认情况 , MRU 文档数上限值为 4 个 , 你可以调用 CRecentDocumentList::SetMaxEntries() 成员函数来改变此上限值 .
LRESULT CMainFrame::OnCreate(UINT, WPARAM, LPARAM, BOOL&) {
…
m_mru.SetMenuHandle(GetMenu().GetSubMenu(0));
m_mru.ReadFromRegistry(_T("Software//MyCompany//MyCoolApp"));
m_mru.SetMaxEntries(16);
…
}
第一次为 MRU 列表添加文档 , 可以调用 CrecentDocumentList::AddToList() :
LRESULT CMainFrame::OnFileOpen(WORD, WORD, HWND, BOOL&)
{
if (m_dlgOpen.DoModal(m_hWnd) == IDOK) {
// Try to open file
…
if (bFileOpened) {
USES_CONVERSION;
m_mru.AddToList(OLE2T(m_dlgOpen.m_bstrName));
}
}
return 0;
}
你可以添加的 MRU 菜单项范围是 ID_FILE_MRU_FIRST 到 ID_FILE_MRU_LAST ( 在 atlres.h 中定义 ), 并通过范围消息映射宏 COMMAND_RANGE_HANDLER 来处理 . 当用户点击 MRU 其中一个菜单项时 , 消息处理程序调用 CrecentDocumentList::GetFromList() 获取文档名称 . 文档打开后 , 调用 CRecentDocumentList::MoveToTop() 或者 CrecentDocumentList::RemoveFromList() 指示对文档是否打开的处理 .
LRESULT CMainFrame::OnOpenUsingMRU(WORD, WORD wID, HWND, BOOL&) {
<!--[if !vml]--><!--[endif]--> TCHAR szDocument[MAX_PATH];
m_mru.GetFromList(wID, szDocument);
// Try to open the file specified by the menu item
…
if (bFileOpened) m_mru.MoveToTop(wID);
else m_mru.RemoveFromList(wID);
return 0;
}
最后 , 关闭应用程序之前你需要调用 CrecentDocumentList::WriteToRegistry() 把菜单标签组添加到注册表 .
void CMainFrame::OnFinalMessage(HWND /*hWnd*/)
{
m_mru.WriteToRegistry(_T("Software//MyCompany//MyCoolApp"));
::PostQuitMessage(0);
}
Multi-SDI
To be continued...