首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

VC++ 多組 MRU(最近使用檔案)清單管理:依副檔名分類儲存至不同選單

     編輯:VC 教學

前言

Visual Studio 擁有「最近開啟的專案」與「最近開啟的檔案」兩組獨立 MRU 清單。MFC 預設僅支援單一 `CRecentFileList`(`m_pRecentFileList`)。本文示範如何在 `CWinApp` 衍生類別中**新增第二組 `CRecentFileList`**,依副檔名自動分流,選單資源定義獨立命令 ID 範圍,命令處理、UI 更新、讀寫登錄檔完整實作。

一、應用程式類別擴充


class CMyApp : public CWinApp
{
public:
    CRecentFileList* m_pRecentFiles;      // 預設清單(如 .doc)
    CRecentFileList* m_pRecentProjects;   // 新增清單(如 .prj)

    // 命令處理
    afx_msg void OnOpenRecentProject(UINT nID);
    // UI 更新
    afx_msg void OnUpdateRecentProjectMenu(CCmdUI* pCmdUI);
    // 覆寫 AddToRecentFileList 分流
    virtual void AddToRecentFileList(LPCTSTR lpszPathName);

    DECLARE_MESSAGE_MAP()
};

二、初始化與登錄檔讀寫


BOOL CMyApp::InitInstance()
{
    // ... 標準初始化 ...

    // 1. 預設清單(MFC 自動管理 m_pRecentFileList)
    // 若需自訂參數:
    m_pRecentFiles = new CRecentFileList(10, _T("Recent Files"), _T("File%d"), 10);
    m_pRecentFiles->ReadList();

    // 2. 新增專案清單
    m_pRecentProjects = new CRecentFileList(5, _T("Recent Projects"), _T("Project%d"), 15);
    m_pRecentProjects->ReadList();

    return TRUE;
}

int CMyApp::ExitInstance()
{
    if (m_pRecentFiles) { m_pRecentFiles->WriteList(); delete m_pRecentFiles; }
    if (m_pRecentProjects) { m_pRecentProjects->WriteList(); delete m_pRecentProjects; }
    return CWinApp::ExitInstance();
}

三、選單資源定義


// .rc 檔
IDR_MAINFRAME MENU ...
BEGIN
    POPUP "&File"
    BEGIN
        // 預設 MRU:ID_FILE_MRU_FILE1 ~ ID_FILE_MRU_FILE10
        MENUITEM "Recent &Files", ID_FILE_MRU_FILE1, GRAYED
        MENUITEM SEPARATOR
        // 新增 MRU:自訂 ID 範圍
        MENUITEM "Recent &Projects", ID_FILE_MRU_PROJECT1, GRAYED
    END
END

字串表需加入 `ID_FILE_MRU_PROJECT1` ~ `ID_FILE_MRU_PROJECT5`(或更多),內容可留空(由 `UpdateMenu` 填入)。

四、命令範圍映射與處理


BEGIN_MESSAGE_MAP(CMyApp, CWinApp)
    ON_COMMAND_EX_RANGE(ID_FILE_MRU_PROJECT1, ID_FILE_MRU_PROJECT5, OnOpenRecentProject)
    ON_UPDATE_COMMAND_UI_RANGE(ID_FILE_MRU_PROJECT1, ID_FILE_MRU_PROJECT5, OnUpdateRecentProjectMenu)
END_MESSAGE_MAP()

void CMyApp::OnOpenRecentProject(UINT nID)
{
    int nIndex = nID - ID_FILE_MRU_PROJECT1;
    if (nIndex >= 0 && nIndex < m_pRecentProjects->GetSize())
    {
        CString strPath = (*m_pRecentProjects)[nIndex];
        if (!OpenDocumentFile(strPath))
            m_pRecentProjects->Remove(nIndex); // 檔案不存在則移除
    }
}

void CMyApp::OnUpdateRecentProjectMenu(CCmdUI* pCmdUI)
{
    m_pRecentProjects->UpdateMenu(pCmdUI); // 自動填入檔名、啟用/禁用、灰顯
}

五、依副檔名自動分流


void CMyApp::AddToRecentFileList(LPCTSTR lpszPathName)
{
    CString strPath = lpszPathName;
    int nPos = strPath.ReverseFind(_T('.'));
    if (nPos != -1)
    {
        CString strExt = strPath.Mid(nPos + 1);
        strExt.MakeUpper();
        if (strExt == _T("PRJ") || strExt == _T("PROJ")) // 專案檔副檔名
        {
            if (m_pRecentProjects)
            {
                TCHAR szFull[_MAX_PATH];
                AfxFullPath(szFull, lpszPathName);
                m_pRecentProjects->Add(szFull);
            }
            return; // 不加入預設清單
        }
    }
    // 其他副檔名走預設流程
    CWinApp::AddToRecentFileList(lpszPathName);
}

六、結語

關鍵點:多實例 `CRecentFileList` → 不同登錄區段 → 不同選單 ID 範圍 → `ON_COMMAND_EX_RANGE`/`ON_UPDATE_COMMAND_UI_RANGE` → 覆寫 `AddToRecentFileList` 分流。此架構可無限擴充(如最近資料庫連線、最近 FTP 站台),每組清單獨立持久化、獨立選單顯示、獨立命令處理,完美支援類 VS 多 MRU 需求。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved