📄 explorermenu.h
字号:
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 + -