现在因需要做菜单--最近打开文件的功能。
但遇到的问题是:
在使用菜单功能“打开”、“新建”、“另存为”之后,会导致最近打开文件原本显示的全路径消失,只剩下了名称,这让我很郁闷,我想做的是想visual studio的最近打开工程或文件菜单功能那样,可以一直显示全路径的。(包括例如D:\\FOLDER...\\MYPROJECT.SLN这样中间带省略号的,也是我希望允许的。)
我用的系统默认的那个ID_FILE_MRU_RecentList1(记不清了,可能有出入),而是自定义了一个CFileRecentList类, CRecentFileList* m_pRecentListMyFiles; 并添加了UPDATE_COMMAND_UI和ON_COMMAND_EX_RANGE消息响应,以及在相应地方添加的ReadList和WriteList等操作。基本功能都是好的,就是会遇到上面的无法显示全路径的问题,这个问题在任何一个新建工程的默认“最近打开文件”功能都存在相同问题。恳请各位高手指点一二,帮小弟解决困难,不胜感激!

解决方案 »

  1.   

    你问题说的比较模糊, 最近打开文件这块我倒是修改过你要是自己处理UPDATE_COMMAND_UI的话 那么路径应该是你自己用代码设置的才对,建议你追MFC原来的代码看他是怎么生成的(这里我自己追过)
      

  2.   


    可能我说的不清楚,补充一下
    就是刚运行工程时,可以显示例如D:\\FOLDER\\MYPROJECT.SLN这样的全路径,
    但当我在运行窗口中的菜单使用打开、新建、另存为的功能时,则上面最近打开文件中显示的这个路径变为:MYPROJECT.SLN
    这样,就是我说的路径变化了,不能显示全路径了
      

  3.   


    我在UPDATE_COMMAND_UI函数里,调用了m_pRecentListMyFiles->UpdateMenu(pCmdUI); 
    我在想在这里是否能进行更改补充代码,使之可以显示全路径。不过我希望最好在不重载CRecentFileList::UpdateMenu的情况下进行。
      

  4.   


    自己另做一个是有原因的,因为程序结构要求,把菜单功能都放到了CMainFrame里了。里面不能直接调用APP类的函数。并且关键的是一些信息是写在配置文件里的,所以就自己定义了一个CRecentFileList类
      

  5.   

    MFC封装的这个功能路径是写在注册表里的
      

  6.   

    TO:向立天
    是的。。是写在注册表的,可能觉得自己说的啰嗦,就简单问:
    新建的SDI工程的“最近打开文件”菜单在使用菜单“新建”、“打开”、“另存为”之后导致诸如原本D:\\FOLDER\\MYPROJECT.SLN这样的路径,变成MYPROJECT.SLN这样的。(之于注册表里的仍然是完整的路径)
      

  7.   

    我一直在强调任何新建工程,所以说是一直没动过任何修改,如果你有空帮我看一下,就新建一个SDI工程,使用查看File菜单下的Recent File.随便试一下你就会发现Recent File菜单显示的路径存在我说的显示不全的问题。。
    其实我一直纳闷你们怎么会不明白呢,难道“新建一个工程存在这样的问题”这么难理解。
      

  8.   

    显示的名称是用_AfxAbbreviateName算出来的,其中第二个参数影响输出什么样的格式.既想得到名称的最大允许长度,CRecentFileList里传入的是m_nMaxDisplayLength变量,m_nMaxDisplayLength变量是在CRecentFileList构造时赋值的,你说是你自己的CRecentFileList那么检查构造时第五个参数你是否有传值,值为多少,假如 路径的 盘符+第一层目录的长度大于了这个值那么只会显示文件名.另外,当前工作目录也会影响显示的是全路径或者缩略名或者是只显示文件名(如果这个文件在当前工作目录下,那么也只会显示文件名). 所以,第一检查你是否有给CRecentFileList的第五个构造参数传值值为多少,第二如果最后打开文件全部在当前工作目录下,那么只显示文件名是很正常的事情.
      

  9.   

    首先,感谢你对我问题的回答,但仍存在问题。虽然在程序刚start debugging时是显示全路径的,例如“D:\\My Folder\\test.txt”,打开这个最近文件项后路径也没发生变化;但是在使用“打开”菜单功能打开另一个文件,比如说“D:\\My Folder\\abc.txt”,那么Recent File菜单里显示变成了:
    test.txt
    abc.txt我的构造函数是:
    CRecentFileList* m_pRecentMyFileList;
    m_pRecentMyFileList = new CRecentFileList( 0, _T("My Recent File List"), _T("FilePath%d"), 5, 1000);
    所以不是这个1000不够大,还请再看看,帮我解决下
      

  10.   

    当前工作路径是 GetCurrentDirectory 得到的结果.
      

  11.   

    你说的是对的。。
    的确,打开的路径不相同的文件时,原本显示为 test.txt 和 abc.txt的文件时,再打开D:\AnOther Folder\temp.txt时,显示变成:
    1 temp.txt
    2 D:\My Folder\test.txt
    3 D:\My Folder\abc.txt 本来应该算解开小子的疑惑了,但我想能否让当前打开的也显示全路径呢,这样看起来感觉更能一目了然点。我试着在UPDATE_COMMAND_UI的消息函数中进行操作,但没成功,现在的这个消息函数是:
    void CMainFrame::OnUpdateRecentFileList(CCmdUI* pCmdUI)
    {
       m_pRecentMyFileList.UpdateMenu(pCmdUI);
    }
    能否在这里面进行操作,使第一个temp.txt显示出全路径。原本我试图通过pCmdUI修改菜单显示的名称,例如修改temp,txt,但第一,路径前面的序号消失了;第二最近打开文件的最后一项菜单会变成跟第一个相同(abc.txt消失了)。所以我修改后的结果就变成了:
    D:\AnOther Folder\temp.txt
    2 D:\My Folder\test.txt
    D:\AnOther Folder\temp.txt所以还请再劳烦帮我看下
      

  12.   

    你说的是对的。。
    的确,打开的路径不相同的文件时,原本显示为 test.txt 和 abc.txt的文件时,再打开D:\AnOther Folder\temp.txt时,显示变成:
    1 temp.txt
    2 D:\My Folder\test.txt
    3 D:\My Folder\abc.txt 本来应该算解开小子的疑惑了,但我想能否让当前打开的也显示全路径呢,这样看起来感觉更能一目了然点。我试着在UPDATE_COMMAND_UI的消息函数中进行操作,但没成功,现在的这个消息函数是:
    void CMainFrame::OnUpdateRecentFileList(CCmdUI* pCmdUI)
    {
       m_pRecentMyFileList.UpdateMenu(pCmdUI);
    }
    能否在这里面进行操作,使第一个temp.txt显示出全路径。原本我试图通过pCmdUI修改菜单显示的名称,例如修改temp,txt,但第一,路径前面的序号消失了;第二最近打开文件的最后一项菜单会变成跟第一个相同(abc.txt消失了)。所以我修改后的结果就变成了:
    D:\AnOther Folder\temp.txt
    2 D:\My Folder\test.txt
    D:\AnOther Folder\temp.txt所以还请再劳烦帮我看下
      

  13.   

    从CRecentFileList派生一个新类重载CRecentFileList::UpdateMenu 函数. 你可以去查看MFC原来的代码,可以原封不动的拷贝过来,在里面有这样一句if (!GetDisplayName(strName, iMRU, szCurDir, nCurDir))  改成if (!GetDisplayName(strName, iMRU, _T(""), 0)) 就行了 ,或者将上面的GetCurrentDirectory(_MAX_PATH, szCurDir); 改成memset(szCurDir, 0 _MAX_PATH); 都可以.代码在Microsoft Visual Studio\VC98\MFC\SRC\FILELIST.CPP 你自己可以看一下,想用好MFC就要多跟踪MFC的代码.
      

  14.   

    还有一个不推荐的办法,就是在void CMainFrame::OnUpdateRecentFileList(CCmdUI* pCmdUI)
    {
      TCHAR szCurDir[_MAX_PATH];
      GetCurrentDirectory(_MAX_PATH, szCurDir);
      SetCurrentDirectory(_T("C:\\windows"), /*这里写入一个与m_pRecentMyFileList.m_arrNames 数组里任何一个文件不相同的目录*/);
      m_pRecentMyFileList.UpdateMenu(pCmdUI);
      SetCurrentDirectory(szCurDir);
    }不过这种做法我非常非常的不推荐.可能会引起其他问题.正规的做法是我前边提到的.
      

  15.   

    To:bjx_bjx
    谢谢你的回答,非常感谢。其实我一直在等你说的SetCurrentDirectory(szCurDir)这样的方法出现,但同时我自己也感觉有些不是很好,如你所说的那样可能会引起其他的一些问题。谢谢你辛苦的回答,虽然得到了一条简单的方法,但我还是会听从你的去从CRecentFileList派生一个新类重载CRecentFileList::UpdateMenu 函数。这帖子到此就结了。。能得到满意的答案我很开心。非常感谢bjx_bjx(异之意) 的帮助,感谢xianglitian(向立天)的关注,呵呵。