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

📄 explorermenu.h

📁 一个使用wtl写的完整的多窗口浏览器
💻 H
📖 第 1 页 / 共 2 页
字号:
		menu.InsertMenuItem(nInsertPoint++, TRUE, &mii);
	}


	struct _DefaultMenuItemCompare : public std::binary_function<const CMenuItemInfo&, const CMenuItemInfo&, bool>
	{
		CExplorerMenuImpl<T>* _expmenu;

		_DefaultMenuItemCompare(CExplorerMenuImpl<T>& m) : _expmenu(&m)
		{
		}

		bool operator()(const CMenuItemInfo& x, const CMenuItemInfo& y)
		{
			CString strPathA = _expmenu->_GetFilePath(x);
			CString strPathB = _expmenu->_GetFilePath(y);

			bool bDirA = MtlIsDirectoryPath(strPathA);
			bool bDirB = MtlIsDirectoryPath(strPathB);

			if (bDirA == bDirB)
				return strPathA < strPathB;
			else {
				if (bDirA)
					return true;
				else
					return false;
			}
		}
	};

	struct _SetupMenuItemInfoToArray : public std::unary_function<const CString&, void>
	{
		CSimpleArray<CMenuItemInfo>* array;
		CExplorerMenuImpl<T>* expmenu;

		_SetupMenuItemInfoToArray(CSimpleArray<CMenuItemInfo>& a, CExplorerMenuImpl<T>& m)
			: array(&a), expmenu(&m)
		{
		}
		
		void operator()(const CString& strPath, bool bDir)
		{
			if (bDir){
				CString strDirectoryPath2 = strPath;
				if (expmenu->m_arrIgnoredPath.Find(strDirectoryPath2) != -1)
					return;

				CMenuHandle menuSub;
				menuSub.CreatePopupMenu();

				// add to map and array of menus
				expmenu->_SaveDirectoryPath(menuSub.m_hMenu, strPath);
				expmenu->m_arrMenuHandle.Add(menuSub.m_hMenu);

				LPTSTR lpstrText = new TCHAR[strPath.GetLength() + 1];
				::lstrcpy(lpstrText, strPath);

				CMenuItemInfo mii;
				mii.fMask = MIIM_SUBMENU | MIIM_TYPE;
				mii.fType = MFT_STRING;
				mii.hSubMenu = menuSub.m_hMenu;
				mii.dwTypeData = lpstrText;
				array->Add(mii);
			}
			else {
				CString strFilePath2 = strPath;
				if (expmenu->m_arrIgnoredPath.Find(strFilePath2) != -1)
					return;

				LPTSTR lpstrText = new TCHAR[strPath.GetLength() + 1];
				::lstrcpy(lpstrText, strPath);

				CMenuItemInfo mii;
				mii.fMask = MIIM_ID | MIIM_TYPE;
				mii.fType = MFT_STRING;
				mii.wID = ++expmenu->m_nCurrentMenuID;
				mii.dwTypeData = lpstrText;

				if (expmenu->m_nCurrentMenuID < expmenu->m_nMaxID) {
					// add to command map
					expmenu->m_mapID.Add(expmenu->m_nCurrentMenuID, strPath);
					array->Add(mii);
				}
			}

		}
	};

	void _Explore(CMenuHandle menuPopup, int nInsertPoint, const CString& strDirectoryPath)
	{
		int nOldInsertPoint = nInsertPoint;
		int nBreakCount = nInsertPoint;

		if ((m_dwStyle & EMS_ADDITIONALMENUITEM) && MtlIsFileExist(strDirectoryPath))
			_AddAdditionalMenuItem(menuPopup, nInsertPoint, nBreakCount, strDirectoryPath);

		CSimpleArray<CMenuItemInfo> infos;
		MtlForEachObject_OldShell(strDirectoryPath, _SetupMenuItemInfoToArray(infos, *this));

		// setup menu item info
		T* pT = static_cast<T*>(this);
		pT->OnMenuItemInitialUpdate(strDirectoryPath, infos);

		int i;
		// shorten text size
		for (i = 0; i < infos.GetSize(); ++i) {
			CMenuItemInfo& info = infos[i];
			LPTSTR lpsz = info.dwTypeData;
			CString str = _GetMenuItemText(lpsz);
			delete [] lpsz;
			lpsz = new TCHAR[str.GetLength() + 1];
			::lstrcpy(lpsz, str);
			info.dwTypeData = lpsz;
		}

		// insert menu items
		std::for_each(_begin(infos), _end(infos), _MenuItemInserter(menuPopup, nInsertPoint, nBreakCount, m_nMaxMenuBreakCount));

		// add "none" menu item
		if (infos.GetSize() == 0)
			_AddNoneMenuItem(menuPopup, nInsertPoint);

		// clean up texts
		for (i = 0; i < infos.GetSize(); ++i)
			delete [] infos[i].dwTypeData;
	}

	void _AddAdditionalMenuItem(CMenuHandle menuDest, int& nInsertPoint, int& nBreakCount, const CString& strDirectory)
	{
		CString strDirectoryPath = strDirectory;
		MtlMakeSureTrailingBackSlash(strDirectoryPath);

		CMenuItemInfo mii;
		mii.fMask = MIIM_ID | MIIM_TYPE;
		mii.fType = MFT_STRING;
		mii.wID = ++m_nCurrentMenuID;
		mii.dwTypeData = (LPTSTR)(LPCTSTR)m_strAdditional;
		menuDest.InsertMenuItem(nInsertPoint++, TRUE, &mii);
		++nBreakCount;

		if (m_nCurrentMenuID < m_nMaxID) {
			m_mapID.Add(m_nCurrentMenuID, strDirectoryPath);
		}
		else {
			ATLASSERT(FALSE);
//			::MessageBeep(MB_ICONEXCLAMATION);
		}

		if (!(m_dwStyle & EMS_ADDITIONALMENUITEMNOSEP))
			_InsertSeparator(menuDest, nInsertPoint);
	}

	void _InsertSeparator(CMenuHandle menuDest, int& nInsertPoint)
	{
		CMenuItemInfo mii;
		mii.fMask = MIIM_TYPE;
		mii.fType = MF_SEPARATOR;
		menuDest.InsertMenuItem(nInsertPoint++, TRUE, &mii);
	}

	struct _MenuItemInserter
	{
		CMenuHandle _menu;
		int& _nInsertPoint;
		int& _nBreakCount;
		int _nMaxMenuBreakCount;

		_MenuItemInserter(CMenuHandle menu, int& nInsertPoint, int& nBreakCount, int nMaxMenuBreakCount)
			: _menu(menu), _nInsertPoint(nInsertPoint), _nBreakCount(nBreakCount),
			  _nMaxMenuBreakCount(nMaxMenuBreakCount)
		{
		}

		void operator()(CMenuItemInfo& mii)
		{
			if (_nBreakCount + 1 > _nMaxMenuBreakCount) {// what a difficult algorithm...
				_nBreakCount = 0;// reset
				mii.fType |= MFT_MENUBREAK;
			}

			++_nBreakCount;

			epmTRACE(_T("InsertMenuItem(%s, %d)\n"), mii.dwTypeData, _nInsertPoint);
			_menu.InsertMenuItem(_nInsertPoint++, TRUE, &mii);
		}
	};

	static void _DeleteAllMenuItems(CMenuHandle menu)
	{
		for (int i = 0; i < menu.GetMenuItemCount(); ++i) {
			CMenuHandle menuSub = menu.GetSubMenu(i);
			if (menuSub.m_hMenu) {
				_DeleteAllMenuItems(menuSub.m_hMenu);
				MTLVERIFY(menuSub.DestroyMenu());
			}
		}

		while (menu.DeleteMenu(0, MF_BYPOSITION))
			;
	}

	void _SaveDirectoryPath(CMenuHandle menu, const CString& strPath)
	{
		m_mapSubMenu.Add(menu.m_hMenu, strPath);
//		m_mapSubMenu[menu.m_hMenu] = strPath;
	}

	CString _LoadDirectoryPath(CMenuHandle menu)
	{
//		return m_mapSubMenu[menu.m_hMenu];
		return m_mapSubMenu.Lookup(menu.m_hMenu);
	}

	int _FindInsertPoint(CMenuHandle menu)
	{
		int nItems = menu.GetMenuItemCount();
//		epmTRACE(_T("_FindInsertPoint ItemCount=%d : %s\n"), nItems, m_strTestText);	

		int nInsertPoint;
		for (nInsertPoint = 0; nInsertPoint < nItems; ++nInsertPoint) {
			CMenuItemInfo mii;
			mii.fMask = MIIM_ID;
			menu.GetMenuItemInfo(nInsertPoint, TRUE, &mii);
			if (mii.wID == m_nInsertPointMenuItemID)
				break;
		}
	
		if (nInsertPoint >= nItems)// not found
			return -1;

		ATLASSERT(nInsertPoint < nItems && "You need a menu item with an ID = m_nInsertPointMenuItemID");
		return nInsertPoint;
	}

	void _DeleteInsertPointMenuItem()
	{
//		epmTRACE(_T("_DeleteInsertPointMenuItem(%d) : %s\n"), m_nInsertPointMenuItemID, m_strTestText);		
		m_menu.DeleteMenu(m_nInsertPointMenuItemID, MF_BYCOMMAND);
	}

	CString _GetMenuItemText(const CString& strPath)
	{
		T* pT = static_cast<T*>(this);
		return pT->OnGetMenuItemText(strPath);
	}

	void _RestoreOriginalMenu()
	{
		epmTRACE(_T("_RestoreOriginalMenu\n"));	

		while (m_menu.GetMenuItemCount() > m_nOriginalMenuItemCountExceptInsertPointMenuItem) {
			CMenuHandle menuSub = m_menu.GetSubMenu(m_nOriginalInsertPoint);
			if (menuSub.m_hMenu) {
				epmTRACE(_T(" DestroyMenu\n"));
				_DeleteAllMenuItems(menuSub.m_hMenu);
				MTLVERIFY(menuSub.DestroyMenu());
			}
			m_menu.DeleteMenu(m_nOriginalInsertPoint, MF_BYPOSITION);
		}

		m_menu.InsertMenu(m_nOriginalInsertPoint, MF_BYPOSITION, m_nInsertPointMenuItemID, _T("Insert Point"));

//		epmTRACE(_T("_RestoreOriginalMenu(%s) : restored to ItemCount = %d\n"), m_strTestText, m_menu.GetMenuItemCount());	
	}

	CString _GetFilePath(const CMenuItemInfo& mii)
	{
		CString str = m_mapID.Lookup(mii.wID);
		if (str.IsEmpty()) {// dir path
			str = m_mapSubMenu.Lookup(mii.hSubMenu);
		}

		ATLASSERT(!str.IsEmpty());
		return str;
	}
};


class CExplorerMenu : public CExplorerMenuImpl<CExplorerMenu>
{
public:
	void OnExecute(const CString& strFilePath)
	{
		::ShellExecute(NULL, _T("open"), strFilePath, NULL, NULL, SW_SHOWNORMAL);
	}
};
/*
template <class T>
class CExplorerMenuPropertyPage : public CPropertyPageImpl<CExplorerMenuPropertyPage>,
	public CWinDataExchange<CExplorerMenuPropertyPage>
{
public:
// Constants
	enum { IDD = IDD_PROPPAGE_EXPMENU };

// Data members
	int m_nAdditionalCheck;
	int m_nMaxMenuItemTextLength;
	int m_nMaxMenuBreakCount;
	T* m_pT;
	HWND m_hWndLinkBar;

// DDX map
	BEGIN_DDX_MAP(CExplorerMenuPropertyPage)
		DDX_CHECK(IDC_CHECK_EXPMENU_ADDITIONAL, m_nAdditionalCheck)
		DDX_INT_RANGE(IDC_EDIT_EXPMENU_ITEMTEXTMAX, m_nMaxMenuItemTextLength, 1, 255)
		DDX_INT_RANGE(IDC_EDIT_EXPMENU_BREAKCOUNTMAX, m_nMaxMenuBreakCount, 2, 5000)
	END_DDX_MAP()

// Constructor
	CExplorerMenuPropertyPage(T* pT, HWND hWndToRefresh)
		: m_pT(pT)
	{
		m_nAdditionalCheck = (m_pT->GetStyle() & EMS_ADDITIONALMENUITEM) ? 1 : 0;
		m_nMaxMenuItemTextLength = m_pT->GetMaxMenuItemTextLength();
		m_nMaxMenuBreakCount = m_pT->GetMaxMenuBreakCount();
		m_hWndLinkBar = hWndToRefresh;
	}

// Overrides
	BOOL OnSetActive()
	{
		SetModified(TRUE);
		return DoDataExchange(FALSE);
	}

	BOOL OnKillActive()
	{
		return DoDataExchange(TRUE);
	}

	BOOL OnApply()
	{
		if (DoDataExchange(TRUE)) {
			DWORD dwStyle = 0;
			if (m_nAdditionalCheck == 1)
				dwStyle |= EMS_ADDITIONALMENUITEM;

			m_pT->SetStyle(dwStyle);
			m_pT->SetMaxMenuItemTextLength(m_nMaxMenuItemTextLength);
			m_pT->SetMaxMenuBreakCount(m_nMaxMenuBreakCount);
			::PostMessage(m_hWndLinkBar, WM_COMMAND, ID_VIEW_REFRESH_LINKBAR, 0);
			return TRUE;
		}
		else 
			return FALSE;
	}

// Message map and handlers
	BEGIN_MSG_MAP(CExplorerMenuPropertyPage)
		CHAIN_MSG_MAP(CPropertyPageImpl<CExplorerMenuPropertyPage>)
	END_MSG_MAP()
};


template <class _Profile, class _ExplorerMenu>
void MtlGetProfileExpMenu(_Profile& __profile, _ExplorerMenu& __expmenu)
{
	DWORD dwStyle, dwLength, dwCount;
	LONG lRet = __profile.QueryValue(dwStyle, _T("Style"));
	if (lRet != ERROR_SUCCESS)
		dwStyle = 0;

	lRet = __profile.QueryValue(dwLength,  _T("Max_Text_Length"));
	if (lRet != ERROR_SUCCESS)
		dwLength = 55;

	lRet = __profile.QueryValue(dwCount,  _T("Max_Break_Count"));
	if (lRet != ERROR_SUCCESS)
		dwCount = 5000;

	__expmenu.SetStyle(dwStyle);
	__expmenu.SetMaxMenuItemTextLength(dwLength);
	__expmenu.SetMaxMenuBreakCount(dwCount);
}

template <class _Profile, class _ExplorerMenu>
void MtlWriteProfileExpMenu(_Profile& __profile, _ExplorerMenu& __expmenu)
{
	__profile.SetValue(__expmenu.GetStyle(), _T("Style"));
	__profile.SetValue(__expmenu.GetMaxMenuItemTextLength(), _T("Max_Text_Length"));
	__profile.SetValue(__expmenu.GetMaxMenuBreakCount(), _T("Max_Break_Count"));
}
*/

⌨️ 快捷键说明

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