📄 favtreeviewctrl.h
字号:
#include "OleDragDropExpTreeViewCtrl.h"
#include "ChevronHandler.h"
// Options
#define ETV_EX_MYCOMPUTER 0x00010000L
#define ETV_EX_FAVORITES 0x00020000L
#define ETV_EX_FAVORITEGROUP 0x00040000L
#define ETV_EX_USERDEFINED 0x00080000L
#define ETV_EX_FOLDERS ETV_EX_MYCOMPUTER | ETV_EX_FAVORITES | ETV_EX_FAVORITEGROUP | ETV_EX_USERDEFINED
#define ETV_EX_SHELLEXECUTE 0x00100000L
class CFavoritesTreeViewCtrl :
public COleDragDrogExplorerTreeViewCtrlImpl<CFavoritesTreeViewCtrl>
{
public:
DECLARE_WND_SUPERCLASS(_T("Mtl_FavTreeViewCtrl"), GetWndClassName())
typedef COleDragDrogExplorerTreeViewCtrlImpl<CFavoritesTreeViewCtrl> baseClass;
typedef CFavoritesTreeViewCtrl thisClass;
// Constants
enum { s_nIDOpenAll = 10, };
// Ctor/dtor
// Attributes
bool _IsNeedFavoritesFix()
{
if (_check_flag(ETV_EX_FAVORITES, GetExplorerTreeViewExtendedStyle()) || _check_flag(ETV_EX_USERDEFINED, GetExplorerTreeViewExtendedStyle()))
return true;
else
return false;
}
// Overrides
void OnExplorerTreeViewInit()
{
baseClass::OnExplorerTreeViewInit();
_GetProfile();
}
void OnExplorerTreeViewTerm()
{
baseClass::OnExplorerTreeViewTerm();
_WriteProfile();
}
CItemIDList OnInitRootFolder()
{
if (_check_flag(ETV_EX_MYCOMPUTER, GetExplorerTreeViewExtendedStyle())) {
CItemIDList idl;
HRESULT hr = ::SHGetSpecialFolderLocation(m_hWnd, CSIDL_DESKTOP, &idl);
ATLASSERT(SUCCEEDED(hr));
return idl;
}
else if (_check_flag(ETV_EX_FAVORITEGROUP, GetExplorerTreeViewExtendedStyle())) {
CString strDir = DonutGetFavoriteGroupFolder();
return strDir;
}
else if (_check_flag(ETV_EX_USERDEFINED, GetExplorerTreeViewExtendedStyle())) {
return CFavoritesMenuOption::GetUserDirectory();
}
else {
CString strDir; MtlGetFavoritesFolder(strDir);
return strDir;
}
}
void OnInitialUpdateTreeItems(CSimpleArray<TV_INSERTSTRUCT>& items, LPCITEMIDLIST pidl)
{
ATLASSERT(pidl != NULL);
DWORD dwStyle = CFavoritesMenuOption::GetStyle();
if (_check_flag(EMS_ORDER_FAVORITES, dwStyle) && _check_flag(ETV_EX_FAVORITES, GetExplorerTreeViewExtendedStyle())) {
CFavoritesOrder order;
MtlGetFavoritesOrder(order, CItemIDList(pidl).GetPath());
std::sort(_begin(items), _end(items), _FavoritesTreeItemCompare<thisClass>(order, this));
}
else {
baseClass::OnInitialUpdateTreeItems(items, pidl);
}
}
// void OnOpenTreeItem(HTREEITEM hItem, LPITEMIDLIST pidl)
// {
// if (_check_flag(ETV_EX_MYCOMPUTER, GetExplorerTreeViewExtendedStyle())) {
// MtlShellExecute(m_hWnd, pidl);
// return;
// }
// CItemIDList idl(pidl);
// if (!idl.IsNull())
// DonutOpenFile(m_hWnd, idl.GetPath(), DonutGetStdOpenFlag());
// }
void OnTreeItemClicked(HTREEITEM hTreeItem, UINT uFlags)
{
if ( !_check_flag(ETV_EX_FAVORITEGROUP, GetExplorerTreeViewExtendedStyle()) &&
( _check_flag(ETV_EX_SHELLEXECUTE, GetExplorerTreeViewExtendedStyle()) || _check_flag(ETV_EX_MYCOMPUTER, GetExplorerTreeViewExtendedStyle()) ) ) {
MtlShellExecute(m_hWnd, _GetItemIDList(hTreeItem));
return;
}
CItemIDList idl = _GetItemIDList(hTreeItem);
if (!idl.IsNull())
DonutOpenFile(m_hWnd, idl.GetPath(), DonutGetStdOpenFlag());
}
bool OnGetInfoToolTip(HTREEITEM hItem, CString& strTip, int cchTextMax)
{
if (_IsItemFolder(hItem))
return false;
CItemIDList idl = _GetItemIDList(hItem);
if (idl.IsNull())
return false;
CString strPath = idl.GetPath();
if (strPath.IsEmpty())
return false;
CString strUrl = MtlGetInternetShortcutUrl(strPath);
if (strUrl.IsEmpty())
strUrl = strPath;
CString strName;
if (!GetItemText(hItem, strName))
return false;
strTip = MtlMakeFavoriteToolTipText(strName, strUrl, cchTextMax);
return true;
}
bool OnCmdContextMenu(HTREEITEM hTreeItem, int nID)
{
if (nID != s_nIDOpenAll)
return false;
MtlForEachFile(_GetItemIDList(hTreeItem), _Function_OpenFile(m_hWnd));
return true;
}
struct _Function_OpenFile
{
HWND _hWnd;
_Function_OpenFile(HWND hWnd) : _hWnd(hWnd) { }
void operator()(IShellFolder* pFolder, const CItemIDList& idlFolder, const CItemIDList& idlFile)
{
CItemIDList idlFull = idlFolder + idlFile;
if (!idlFull.IsNull())
DonutOpenFile(_hWnd, idlFull.GetPath());
}
};
UINT OnPrepareMenuForContext(HTREEITEM hTreeItem, CMenuHandle menu, int& nPos)
{
bool bFolder = _IsItemFolder(hTreeItem);
UINT uFlags = CMF_CANRENAME;
if (bFolder)
uFlags |= CMF_EXPLORE | CMF_NODEFAULT;
else
uFlags |= CMF_NORMAL;
if (!_IsNeedFavoritesFix())
return uFlags;
// set up for favorites
if (bFolder) {
if (_IsItemExpanded(hTreeItem))
menu.AppendMenu(MF_ENABLED|MF_STRING, s_nIDCollapse, _T("Coll&apse"));
else
menu.AppendMenu(MF_ENABLED|MF_STRING, s_nIDExpand, _T("Exp&and"));
menu.AppendMenu(MF_ENABLED|MF_STRING, s_nIDOpenAll, _T("Open All &Inside"));
menu.AppendMenu(MF_ENABLED|MF_STRING, s_nIDNewFolder, _T("Ne&w Folder"));
menu.AppendMenu(MF_SEPARATOR);
nPos += 4;
}
else {
}
return uFlags;
}
void OnPrepareMenuForPopup(HTREEITEM hTreeItem, CMenuHandle menu)
{
if (!_IsNeedFavoritesFix())
return;
int nCmdID = MtlGetCmdIDFromAccessKey(menu, _T("&S"));// remove "create shortcut" menu item
if (nCmdID != -1)
menu.RemoveMenu(nCmdID, MF_BYCOMMAND);
if (!_IsItemFolder(hTreeItem)) {
int nCmdID = MtlGetCmdIDFromAccessKey(menu, _T("&O"), false);// remove original "open" menu item
if (nCmdID != -1)
menu.RemoveMenu(nCmdID, MF_BYCOMMAND);
menu.InsertMenu(0, MF_BYPOSITION|MF_STRING, s_nIDNewFolder, _T("Ne&w Folder"));
menu.InsertMenu(0, MF_BYPOSITION|MF_STRING, s_nIDOpen, _T("&Open"));
menu.SetMenuDefaultItem(s_nIDOpen, FALSE);
}
}
template <class _This>
struct _FavoritesTreeItemCompare : public std::binary_function<const TV_INSERTSTRUCT&, const TV_INSERTSTRUCT&, bool>
{
CFavoritesOrder& _order;
_This* _pThis;
_FavoritesTreeItemCompare(CFavoritesOrder& order, _This* pThis) : _order(order), _pThis(pThis) { }
bool operator()(const TV_INSERTSTRUCT& x, const TV_INSERTSTRUCT& y)
{
CItemIDList idlA = (LPCITEMIDLIST)x.item.lParam; ATLASSERT(!idlA.IsNull());
CItemIDList idlB = (LPCITEMIDLIST)y.item.lParam; ATLASSERT(!idlB.IsNull());
const int enough = 10000;
CString strA = MtlGetFileName(idlA.GetPath());
CString strB = MtlGetFileName(idlB.GetPath());
ATLASSERT(!strA.IsEmpty() && !strB.IsEmpty());
int itA = _order.Lookup(strA);
int itB = _order.Lookup(strB);
if (itA == -1 || itA == FAVORITESORDER_NOTFOUND)// fixed by fub, thanks.
itA = enough;
if (itB == -1 || itB == FAVORITESORDER_NOTFOUND)
itB = enough;
if (itA == enough && itB == enough) {
bool bParentA = (x.item.cChildren == 1);
bool bParentB = (y.item.cChildren == 1);
if (bParentA == bParentB) {
return strA < strB;
}
else {
if (bParentA)
return true;
else
return false;
}
}
else
return itA < itB;
}
CString _GetFileName(const TV_INSERTSTRUCT& tvi)
{
bool bDir = (tvi.item.cChildren == 1);
if (bDir) {
return tvi.item.pszText;
}
CItemIDList idl = (LPCITEMIDLIST)tvi.item.lParam;
CString str = idl.GetPath();
if (str.IsEmpty())
return CString();
int nIndex = str.ReverseFind(_T('\\'));
str = str.Right(str.GetLength() - nIndex - 1);
return str;
}
CString _GetFilePath(const TV_INSERTSTRUCT& tvi)
{
CItemIDList idl = (LPCITEMIDLIST)tvi.item.lParam;
CString str = idl.GetPath();
return str;
}
FILETIME _GetFileTime(const CString& strPath_)
{
CString strPath(strPath_);
MtlRemoveTrailingBackSlash(strPath);
WIN32_FIND_DATA data;
HANDLE h = ::FindFirstFile(strPath, &data);
ATLASSERT(h != INVALID_HANDLE_VALUE);
::FindClose(h);
return data.ftCreationTime;
}
};
void _GetProfile()
{
CIniSection pr;
CString strSection = _T("FavTree");
pr.Open(_szIniFileName, strSection);
DWORD dwStyle = ETV_EX_FAVORITES | ETV_EX_SINGLEEXPAND;// default
pr.QueryValue(dwStyle, _T("Style"));
pr.Close();
SetExplorerTreeViewExtendedStyle(dwStyle);
}
void _WriteProfile()
{
CIniSection pr;
CString strSection = _T("FavTree");
pr.Open(_szIniFileName, strSection);
pr.SetValue(GetExplorerTreeViewExtendedStyle(), _T("Style"));
pr.Close();
}
};
template <class T, class TBase = CWindow, class TWinTraits = CControlWinTraits>
class CDonutFavoritesBarImpl :
public CWindowImpl< T, TBase, TWinTraits >,
public CChevronHandler<CDonutFavoritesBarImpl>,
public CUpdateCmdUI<CDonutFavoritesBarImpl>
{
public:
DECLARE_WND_CLASS_EX(NULL, 0, -1)
typedef CDonutFavoritesBarImpl<T, TBase, TWinTraits> thisClass;
// Constants
enum
{
s_cxyBorder = 2,
s_cxyBtnOffset = 1,
s_cxyViewGap = 1,
};
// Data members
CToolBarCtrl m_wndToolBar;
CReBarCtrl m_wndReBar;
CFavoritesTreeViewCtrl m_view;
int m_cxyHeader;
CMenu m_menuPlacement;
// Ctor
CDonutFavoritesBarImpl()
{
m_menuPlacement.LoadMenu(IDR_MENU_FAVTREE_BAR);
}
// Overrides
HMENU OnGetDropDownMenu(int nCmdID, HMENU& hMenuDestroy)
{
return m_menuPlacement.GetSubMenu(0);
}
// Methods
BYTE PreTranslateMessage(MSG* pMsg)
{
UINT msg = pMsg->message;
int vKey = pMsg->wParam;
if (msg == WM_SYSKEYDOWN || msg == WM_SYSKEYUP || msg == WM_KEYDOWN) {
if (pMsg->hwnd == m_view.GetEditControl())
return _MTL_TRANSLATE_WANT;// pass to rename edit ctrl
if (pMsg->hwnd != m_view.m_hWnd || !m_view.IsWindowVisible())
return _MTL_TRANSLATE_PASS;
if (vKey == VK_LEFT || vKey == VK_RIGHT || vKey == VK_DOWN || vKey == VK_UP ||
vKey == VK_RETURN || vKey == VK_SPACE) {
return _MTL_TRANSLATE_WANT;// pass to control
}
}
return _MTL_TRANSLATE_PASS;
}
// Message map and handlers
BEGIN_MSG_MAP(CDonutFavoritesBarImpl)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
MESSAGE_HANDLER(WM_SIZE, OnSize)
MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
MESSAGE_HANDLER(WM_PAINT, OnPaint)
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
COMMAND_ID_HANDLER(ID_FAVORITE_PLACEMENT, OnFavoritePlacement)
COMMAND_ID_HANDLER(ID_VIEW_REFRESH_FAVBAR, OnFavoritePlacement)
COMMAND_ID_HANDLER(ID_FAVTREE_BAR_STANDARD, OnFavTreeStandard)
COMMAND_ID_HANDLER(ID_FAVTREE_BAR_GROUP, OnFavTreeGroup)
COMMAND_ID_HANDLER(ID_FAVTREE_BAR_USER, OnFavTreeUser)
COMMAND_ID_HANDLER(ID_FAVTREE_BAR_MYCOMPUTER, OnFavTreeMyComputer)
COMMAND_ID_HANDLER(ID_FAVTREE_BAR_SHELLEXECUTE, OnFavTreeShellExecute)
COMMAND_ID_HANDLER(ID_FAVTREE_BAR_LOADREMOTEICON, OnFavTreeLoadRemoteIcon)
COMMAND_ID_HANDLER(ID_FAVTREE_BAR_SINGLEEXPAND, OnFavTreeSingleExpand)
NOTIFY_CODE_HANDLER(TBN_DROPDOWN, OnTbnDropDown)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -