删除子菜单






3.13/5 (3投票s)
如何在 VC++ 的文档/视图程序的文件菜单中添加删除子菜单
引言
使用过 Paint Shop Pro 7.0 的人一定见过菜单栏的文件菜单中的删除子菜单,并且一定想知道如何在自己的文档/视图程序中实现相同的功能,以编程方式从程序本身删除硬盘上的当前文档并将其发送到回收站。我不知道任何正确或标准的方法来做同样的事情,但我实现了一种方法,我将在这里介绍。
先决条件
本教程假设您熟悉 Visual C++/MFC、文档/视图架构、Windows 注册表以及本教程中使用的其他技术。虽然不需要非常详细地理解它们的底层原理,但您至少应该对这些底层原理的含义有一个基本的了解。
实现
这个实现并不难。 Windows 提供了一种标准方法来实现从内存中删除任何文档到回收站。我们只需要用正确的参数调用命令 SHFileOperation
。首先,我们必须在程序的 Document
类中编写删除子菜单的菜单处理程序,并按如下所示实现它。在这个实现中,我们首先找出内存中文档的实际路径,并正确填充 SHFILEOPSTRUCT
结构,用该结构作为参数调用 SHFileOperation
命令。这将从内存中删除当前文档。还要记得关闭文档。然后我们将删除的文档文件路径写入注册表。不要忘记根据您的程序将注册表 string
更改为正确的路径。
///////////////////////////////////////////////////////////////
void CDemoDoc::OnFileDelete()
{
// OnFileDelete() Contributed by:
// <Priyank Bolia> priyank_bolia@yahoo.com
// TODO: Add your command handler code here
CString FileToDelete = GetPathName();
FileToDelete+='\0';
SHFILEOPSTRUCT sh={0};
sh.hwnd=AfxGetApp()->m_pActiveWnd->GetSafeHwnd();
sh.pFrom=FileToDelete;
sh.wFunc=FO_DELETE;
sh.fFlags=FOF_ALLOWUNDO;
if(SHFileOperation(&sh)==0 &&
sh.fAnyOperationsAborted==FALSE)
{
OnCloseDocument();
FileToDelete.TrimRight('\0');
HKEY hchildkey;
DWORD dwdispositon;
::RegCreateKeyEx(HKEY_CURRENT_USER,
"Software\\Company\\Product\\Settings",
0,NULL,REG_OPTION_NON_VOLATILE,
KEY_CREATE_SUB_KEY|KEY_ALL_ACCESS,NULL,
&hchildkey,&dwdispositon);
::RegSetValueEx(hchildkey,"FileToDelete",
0,REG_SZ,(const BYTE*)(LPCTSTR)FileToDelete,
(DWORD)FileToDelete.GetLength());
::RegCloseKey(hchildkey);
}
}
void CDemoDoc::OnUpdateFileDelete(CCmdUI* pCmdUI)
{
// OnUpdateFileDelete(CCmdUI* pCmdUI) Contributed by:
// <Priyank Bolia> priyank_bolia@yahoo.com
// TODO: Add your command update UI handler code here
CString PathName = GetPathName();
if(PathName.IsEmpty())
{
pCmdUI->Enable(FALSE);
}
}
///////////////////////////////////////////////////////////////
文档已删除并关闭,但其路径仍保留在程序的 MRU(最近使用)列表中。要将其从那里删除,只需在应用程序类中为 MRU 列表编写另一个更新菜单处理程序,并按如下所示实现它。在这里,我们从注册表中读取已删除的文件路径,并在 m_pRecentFileList
数组中匹配它,如果我们在那里找到它,然后从那里删除它。同样,不要忘记根据您的程序将注册表路径更改为正确的路径。
void CDemoApp::OnUpdateFileMru(CCmdUI* pCmdUI)
{
// <Priyank Bolia> priyank_bolia@yahoo.com
// TODO: Add your command update UI handler code here
ASSERT_VALID(this);
if (m_pRecentFileList == NULL) // no MRU files
pCmdUI->Enable(FALSE);
else
{
HKEY hresult;
if(::RegOpenKeyEx(HKEY_CURRENT_USER,
"Software\\Company\\Product\\Settings",
0,KEY_ALL_ACCESS,&hresult)==ERROR_SUCCESS)
{
BYTE value[255];
DWORD dwcount=255;
if(::RegQueryValueEx(hresult,"FileToDelete",
0,0,value,&dwcount)==ERROR_SUCCESS)
{
CString str=(LPCTSTR)value;
CString str2;
for(int i=0;i<m_pRecentFileList->GetSize();i++)
{
str2=(LPCTSTR)(*m_pRecentFileList)[i];
if(str==str2)
{
m_pRecentFileList->Remove(i);
::RegDeleteValue(hresult,"FileToDelete");
}
}
}
::RegCloseKey(hresult);
}
m_pRecentFileList->UpdateMenu(pCmdUI);
}
}
结论
这使我们结束了,我们已经了解了为我们的软件赋予专业风格是多么容易。现在,我们都可以在几秒钟内将删除子菜单添加到我们的程序中,而无需担心过多的编程负担。唯一要做的就是将代码复制到您的程序,就像“即食餐”一样。欢迎您提出宝贵意见,以使本文更好。
Copyright
此代码按“原样”提供,不提供任何明示或暗示的保证。您可以不受任何限制地使用和滥用此代码。如果您在任何商业产品中使用此源代码,则无需致谢,但将不胜感激。