Maintaining a recent files list
Asked Answered
B

2

7

I would like to maintain a simple recent files list on my MFC application that shows the 4 most recently used file names.

I have been playing with an example from Eugene Kain's "The MFC Answer Book" that can programmatically add strings to the Recent Files list for an application based on the standard Document/View architecture: (see "Managing the Recent Files List (MRU)") :

http://www.nerdbooks.com/isbn/0201185377

My application is a fairly lightweight utility that does not use the Document/View architecture to manage data, file formats and so on. I am not sure if the same principles used in the above example would be applicable here.

Does anyone have any examples of how they go about maintaining a recent files list that is displayed in the File menu, and can be stored in a file / registry setting somewhere? More than anything, it's my lack of knowledge and understanding that is holding me back.

Update: I have recently found this CodeProject article to be quite useful...

http://www.codeproject.com/KB/dialog/rfldlg.aspx

Bonnes answered 17/12, 2009 at 11:51 Comment(0)
L
5

I recently did that using MFC, so since you seems to be using MFC as well maybe it will help:

in:

BOOL MyApp::InitInstance()
{
    // Call this member function from within the InitInstance member function to 
    // enable and load the list of most recently used (MRU) files and last preview 
    // state.
    SetRegistryKey("MyApp"); //I think this caused problem with Vista and up if it wasn't there
                                 //, not really sure now since I didn't wrote a comment at the time
    LoadStdProfileSettings();
}

//..

//function called when you save or load a file
void MyApp::addToRecentFileList(boost::filesystem::path const& path)
{
    //use file_string to have your path in windows native format (\ instead of /)
    //or it won't work in the MFC version in vs2010 (error in CRecentFileList::Add at
    //hr = afxGlobalData.ShellCreateItemFromParsingName)
    AddToRecentFileList(path.file_string().c_str());
}

//function called when the user click on a recent file in the menu
boost::filesystem::path MyApp::getRecentFile(int index) const
{
    return std::string((*m_pRecentFileList)[index]);
}

//...

//handler for the menu
BOOL MyFrame::OnCommand(WPARAM wParam, LPARAM lParam)
{
    BOOL answ = TRUE;

    if(wParam >= ID_FILE_MRU_FILE1 && wParam <= ID_FILE_MRU_FILE16)
    {
        int nIndex = wParam - ID_FILE_MRU_FILE1;

        boost::filesystem::path path = getApp()->getRecentFile(nIndex);
        //do something with the recent file, probably load it

        return answ;
    }
}

You only need that your application is derived from CWinApp (and I use a class derived from CFrameWnd to handle the menu, maybe you do the same?).

Tell me if that works for you. Not sure if I have everything.

Loganloganberry answered 17/12, 2009 at 15:59 Comment(1)
I have recently discovered in parallel one or two of the things you mention, particularly the LoadStdProfileSettings and AddToRecentFileList which are essential (+1).Bonnes
H
5

You can use the boost circular buffer algorithm to maintain the list while the program is running, and then save it to the registry (should be trivial) every time it's updated, and load it when the program first starts.

Homey answered 17/12, 2009 at 12:45 Comment(2)
Why a circular buffer algoritm, a simple vector or array with 4 places will do the trick just fine. Saving to the registry or local file for storage purposesChopper
Because boost's circular buffer automatically erases the first element inserted when it runs out of space. It was designed exactly for stuff like a recent file list. With a vector with 4 places you will have to identify the oldest element and delete it if it's full; with boost it's all done automatically!Homey
L
5

I recently did that using MFC, so since you seems to be using MFC as well maybe it will help:

in:

BOOL MyApp::InitInstance()
{
    // Call this member function from within the InitInstance member function to 
    // enable and load the list of most recently used (MRU) files and last preview 
    // state.
    SetRegistryKey("MyApp"); //I think this caused problem with Vista and up if it wasn't there
                                 //, not really sure now since I didn't wrote a comment at the time
    LoadStdProfileSettings();
}

//..

//function called when you save or load a file
void MyApp::addToRecentFileList(boost::filesystem::path const& path)
{
    //use file_string to have your path in windows native format (\ instead of /)
    //or it won't work in the MFC version in vs2010 (error in CRecentFileList::Add at
    //hr = afxGlobalData.ShellCreateItemFromParsingName)
    AddToRecentFileList(path.file_string().c_str());
}

//function called when the user click on a recent file in the menu
boost::filesystem::path MyApp::getRecentFile(int index) const
{
    return std::string((*m_pRecentFileList)[index]);
}

//...

//handler for the menu
BOOL MyFrame::OnCommand(WPARAM wParam, LPARAM lParam)
{
    BOOL answ = TRUE;

    if(wParam >= ID_FILE_MRU_FILE1 && wParam <= ID_FILE_MRU_FILE16)
    {
        int nIndex = wParam - ID_FILE_MRU_FILE1;

        boost::filesystem::path path = getApp()->getRecentFile(nIndex);
        //do something with the recent file, probably load it

        return answ;
    }
}

You only need that your application is derived from CWinApp (and I use a class derived from CFrameWnd to handle the menu, maybe you do the same?).

Tell me if that works for you. Not sure if I have everything.

Loganloganberry answered 17/12, 2009 at 15:59 Comment(1)
I have recently discovered in parallel one or two of the things you mention, particularly the LoadStdProfileSettings and AddToRecentFileList which are essential (+1).Bonnes

© 2022 - 2024 — McMap. All rights reserved.