⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 recentdocumentlistfixed.h

📁 一个使用wtl写的完整的多窗口浏览器
💻 H
字号:
template <class T, int t_cchItemLen = INTERNET_MAX_PATH_LENGTH>
class CRecentDocumentListFixedBase
{
public:
// Declarations
	struct _DocEntry
	{
		TCHAR szDocName[t_cchItemLen];
		bool operator==(const _DocEntry& de) const
		{ return (lstrcmpi(szDocName, de.szDocName) == 0); }
	};

	enum
	{
		m_nMaxEntries_Min = 2,
		m_nMaxEntries_Max = ID_FILE_MRU_LAST - ID_FILE_MRU_FIRST + 1,
		m_cchMaxItemLen_Min = 6,
		m_cchMaxItemLen_Max = t_cchItemLen
	};

// Data members
	CSimpleArray<_DocEntry> m_arrDocs;
	int m_nMaxEntries;	// default is 4
	HMENU m_hMenu;

	TCHAR m_szNoEntries[t_cchItemLen];

	int m_cchMaxItemLen;

// Constructor
	CRecentDocumentListFixedBase() : m_hMenu(NULL), m_nMaxEntries(4), m_cchMaxItemLen(100)
	{
		ATLASSERT(t_cchItemLen > m_cchMaxItemLen_Min);
	}

// Attributes
	HMENU GetMenuHandle() const
	{
		return m_hMenu;
	}
	void SetMenuHandle(HMENU hMenu)
	{
		ATLASSERT(hMenu == NULL || ::IsMenu(hMenu));
		m_hMenu = hMenu;
		if(m_hMenu == NULL || (::GetMenuString(m_hMenu, ID_FILE_MRU_FIRST, m_szNoEntries, t_cchItemLen, MF_BYCOMMAND) == 0))
			lstrcpy(m_szNoEntries, _T("(empty)"));
	}
	int GetMaxEntries() const
	{
		return m_nMaxEntries;
	}
	void SetMaxEntries(int nMaxEntries)
	{
		ATLASSERT(nMaxEntries > m_nMaxEntries_Min && nMaxEntries < m_nMaxEntries_Max);
		if(nMaxEntries < m_nMaxEntries_Min)
			nMaxEntries = m_nMaxEntries_Min;
		else if(nMaxEntries > m_nMaxEntries_Max)
			nMaxEntries = m_nMaxEntries_Max;
		m_nMaxEntries = nMaxEntries;
	}
	int GetMaxItemLength() const
	{
		return m_cchMaxItemLen;
	}
	void SetMaxItemLength(int cchMaxLen)
	{
		ATLASSERT((cchMaxLen >= m_cchMaxItemLen_Min && cchMaxLen <= m_cchMaxItemLen_Max) || cchMaxLen == -1);
		if(cchMaxLen != -1)
		{
			if(cchMaxLen < m_cchMaxItemLen_Min)
				cchMaxLen = m_cchMaxItemLen_Min;
			else if(cchMaxLen > m_cchMaxItemLen_Max)
				cchMaxLen = m_cchMaxItemLen_Max;
		}
		m_cchMaxItemLen = cchMaxLen;
		T* pT = static_cast<T*>(this);
		pT->UpdateMenu();
	}

// Operations
	BOOL AddToList(LPCTSTR lpstrDocName)
	{
		_DocEntry de;
		if(lstrcpy(de.szDocName, lpstrDocName) == NULL)
			return FALSE;

		for(int i = 0; i < m_arrDocs.GetSize(); i++)
		{
			if(lstrcmpi(m_arrDocs[i].szDocName, lpstrDocName) == 0)
			{
				m_arrDocs.RemoveAt(i);
				break;
			}
		}

		if(m_arrDocs.GetSize() == m_nMaxEntries)
			m_arrDocs.RemoveAt(0);

		BOOL bRet = m_arrDocs.Add(de);
		if(bRet)
		{
			T* pT = static_cast<T*>(this);
			bRet = pT->UpdateMenu();
		}
		return bRet;
	}
	BOOL GetFromList(int nItemID, LPTSTR lpstrDocName)
	{
		int nIndex = m_arrDocs.GetSize() - (nItemID - ID_FILE_MRU_FIRST) - 1;
		if(nIndex < 0 || nIndex >= m_arrDocs.GetSize())
			return FALSE;
		return (lstrcpy(lpstrDocName, m_arrDocs[nIndex].szDocName) != NULL);
	}
	BOOL RemoveFromList(int nItemID)
	{
		int nIndex = m_arrDocs.GetSize() - (nItemID - ID_FILE_MRU_FIRST) - 1;
		BOOL bRet = m_arrDocs.RemoveAt(nIndex);
		if(bRet)
		{
			T* pT = static_cast<T*>(this);
			bRet = pT->UpdateMenu();
		}
		return bRet;
	}
	BOOL MoveToTop(int nItemID)
	{
		int nIndex = m_arrDocs.GetSize() - 1 - (nItemID - ID_FILE_MRU_FIRST);
		if(nIndex < 0 || nIndex >= m_arrDocs.GetSize())
			return FALSE;
		_DocEntry de;
		de = m_arrDocs[nIndex];
		m_arrDocs.RemoveAt(nIndex);
		BOOL bRet = m_arrDocs.Add(de);
		if(bRet)
		{
			T* pT = static_cast<T*>(this);
			bRet = pT->UpdateMenu();
		}
		return bRet;
	}

	BOOL ReadFromIniFile()
	{
		CIniSection pr;
		pr.Open(_szIniFileName, _T("Recent Document List"));

		DWORD dwRet;
		LONG lRet = pr.QueryValue(dwRet, _T("DocumentCount"));
		if(lRet == ERROR_SUCCESS || dwRet > 0 && dwRet < (ID_FILE_MRU_LAST - ID_FILE_MRU_FIRST + 1))
			m_nMaxEntries = dwRet;

		m_arrDocs.RemoveAll();

		TCHAR szRetString[t_cchItemLen];
		_DocEntry de;

		for(int nItem = m_nMaxEntries; nItem > 0; nItem--)
		{
			TCHAR szBuff[11];
			wsprintf(szBuff, _T("Document%i"), nItem);
			DWORD dwCount = t_cchItemLen * sizeof(TCHAR);
			lRet = pr.QueryValue(szRetString, szBuff, &dwCount);
			if(lRet == ERROR_SUCCESS && (lstrcpy(de.szDocName, szRetString) != NULL))
				m_arrDocs.Add(de);
		}

		pr.Close();

		T* pT = static_cast<T*>(this);
		return pT->UpdateMenu();
	}
	BOOL WriteToIniFile()
	{
		CIniSection pr;
		pr.Open(_szIniFileName, _T("Recent Document List"));

		LONG lRet = pr.SetValue(m_nMaxEntries, _T("DocumentCount"));
		ATLASSERT(lRet == ERROR_SUCCESS);

		// set new values
		int nItem;
		for(nItem = m_arrDocs.GetSize(); nItem > 0; nItem--)
		{
			TCHAR szBuff[11];
			wsprintf(szBuff, _T("Document%i"), nItem);
			TCHAR szDocName[t_cchItemLen];
			GetFromList(ID_FILE_MRU_FIRST + nItem - 1, szDocName);
			lRet = pr.SetValue(szDocName, szBuff);
			ATLASSERT(lRet == ERROR_SUCCESS);
		}

		// delete unused keys
		for(nItem = m_arrDocs.GetSize() + 1; nItem < (ID_FILE_MRU_LAST - ID_FILE_MRU_FIRST + 1); nItem++)
		{
			TCHAR szBuff[11];
			wsprintf(szBuff, _T("Document%i"), nItem);
			pr.DeleteValue(szBuff);
		}

		pr.Close();
		return TRUE;
	}

// Implementation
	BOOL UpdateMenu()
	{
		if(m_hMenu == NULL)
			return FALSE;
		ATLASSERT(::IsMenu(m_hMenu));

		int nItems = ::GetMenuItemCount(m_hMenu);
		int nInsertPoint;
		for(nInsertPoint = 0; nInsertPoint < nItems; nInsertPoint++)
		{
			MENUITEMINFO mi;
			mi.cbSize = sizeof(MENUITEMINFO);
			mi.fMask = MIIM_ID;
			::GetMenuItemInfo(m_hMenu, nInsertPoint, TRUE, &mi);
			if (mi.wID == ID_FILE_MRU_FIRST)
				break;
		}
		ATLASSERT(nInsertPoint < nItems && "You need a menu item with an ID = ID_FILE_MRU_FIRST");

		int nItem;
		for(nItem = ID_FILE_MRU_FIRST; nItem < ID_FILE_MRU_FIRST + m_nMaxEntries; nItem++)
		{
			// keep the first one as an insertion point
			if (nItem != ID_FILE_MRU_FIRST)
				::DeleteMenu(m_hMenu, nItem, MF_BYCOMMAND);
		}

		CString strOut;
		int nSize = m_arrDocs.GetSize();
		nItem = 0;
		if(nSize > 0)
		{
			for(nItem = 0; nItem < nSize; nItem++)
			{
				if(m_cchMaxItemLen == -1)
				{
					CString strIn(m_arrDocs[nSize - 1 - nItem].szDocName);
					strIn.Replace(_T("&"), _T("&&"));
					int nLen = strIn.GetLength();
					wsprintf(strOut.GetBufferSetLength(nLen + 8), _T("&%i %s"), nItem + 1, strIn);
				}
				else
				{
					CString strIn(m_arrDocs[nSize - 1 - nItem].szDocName);
					TCHAR szBuff[t_cchItemLen];
					T* pT = static_cast<T*>(this);
					pT;	// avoid level 4 warning
					bool bRet = pT->CompactDocumentName(szBuff, strIn, m_cchMaxItemLen);
					strIn = szBuff;
					strIn.Replace(_T("&"), _T("&&"));
					bRet;	// avoid level 4 warning
					ATLASSERT(bRet);
					int nLen = strIn.GetLength();
					wsprintf(strOut.GetBufferSetLength(nLen + 8), _T("&%i %s"), nItem + 1, strIn);
				}
				strOut.ReleaseBuffer();
				::InsertMenu(m_hMenu, nInsertPoint + nItem, MF_BYPOSITION | MF_STRING, ID_FILE_MRU_FIRST + nItem, strOut);
			}
		}
		else	// empty
		{
			::InsertMenu(m_hMenu, nInsertPoint, MF_BYPOSITION | MF_STRING, ID_FILE_MRU_FIRST, m_szNoEntries);
			::EnableMenuItem(m_hMenu, ID_FILE_MRU_FIRST, MF_GRAYED);
			nItem++;
		}
		::DeleteMenu(m_hMenu, nInsertPoint + nItem, MF_BYPOSITION);

		return TRUE;
	}

// Overrideable
	// override to provide a different method of compacting document names
	static bool CompactDocumentName(LPTSTR lpstrOut, LPCTSTR lpstrIn, int cchLen)
	{
		return AtlCompactPathFixed(lpstrOut, lpstrIn, cchLen);
	}
};

class CRecentDocumentListFixed : public CRecentDocumentListFixedBase<CRecentDocumentListFixed>
{
public:
};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -