Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Delete Sub Menu

0.00/5 (No votes)
27 Apr 2004 1  
How to add delete submenu to the file menu of Document/View program in VC++

Introduction

Those who have worked on Paint Shop Pro 7.0 must have seen the delete submenu in the file menu of the menubar, and must be wondering how to implement the same, in their Document/View program to delete the current document from the hard-disk and send it to the Recycle Bin programmatically from the program itself. I don't know any correct or standard method to do the same, but I have implemented a method that I will be presenting here.

Prerequisite

This tutorial assumes that you are familiar with Visual C++/MFC, Document/View architecture, Windows Registry and other technologies used in this tutorial. Though there is no need to understand their underpinnings in great details, you should at least have a working knowledge of what these underpinnings mean.

Implementation

This implementation is not very hard. Windows provides a standard method to implement the deletion of any document from the memory to the Recycle Bin. Only, we have to call the command SHFileOperation with proper parameters. First of all, we have to write the menu handlers for the delete submenu in the Document class of the program and implement it as shown below. In this implementation, we first find out the actual path of the document in memory and fill up the SHFILEOPSTRUCT structure properly, calling the SHFileOperation command with the structure as parameter. This will delete the current document from the memory. Remember also to close the document. Then we have written the deleted document file path to the registry. Don't forget to change the registry string to a proper path according to your program.

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

The document has been deleted and closed, but still its path resides in MRU (Most Recently Used) list of the program. To remove it from there also, just write another Update menu handler for the MRU list in the application class and implement it as shown below. Here, we read the deleted file path from the registry and match it in the m_pRecentFileList array, if we found it there, then remove it from there. Don't forget here also to change the registry path to a proper one according to your program.

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

Conclusion

This brings us to an end, we have learned how easy it is to give our software a professional touch. Now, we can all add delete submenu to our programs, within a matter of few seconds, without bothering about excessive burden of programming. The only thing to do, is to copy the code to your program, "Ready to eat meal". Your valuable suggestions are always welcome, to make this article better.

Copyright

This code is provided "as is" with no expressed or implied warranty. You can use and abuse this code without any restriction. If you use this source code in any commercial product, acknowledgment is not required but would be appreciated.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here