Files
Open-Shell-Menu/Src/StartMenu/StartMenuDLL/ProgramsTree.h
Xenhat f4dd56155b Rebrand to Open-Shell (#36) (#58)
* Rebrand to Open-Shell

* Slight installer branding improvement
2018-08-05 15:22:10 -04:00

223 lines
8.7 KiB
C++

// Classic Shell (c) 2009-2017, Ivo Beltchev
// Open-Shell (c) 2017-2018, The Open-Shell Team
// Confidential information of Ivo Beltchev. Not for disclosure or distribution without prior written consent from the author
#pragma once
#include "ItemManager.h"
#include "DragDrop.h"
class CMenuContainer;
class CProgramsTree: public IDropTarget, public CWindowImpl<CProgramsTree>
{
public:
enum {
TVM_REFRESH=WM_APP+1,
TIMER_HOVER=1,
};
struct CTreeItem
{
CString name;
unsigned int nameHashProg; // hash if the item is directly in the Programs folder
unsigned int nameHash; // hash if the item is not directly in the Programs folder
const CItemManager::ItemInfo *pItemInfo1;
const CItemManager::ItemInfo *pItemInfo2;
bool bFolder;
bool bEmpty;
bool bApps; // the Apps folder item
bool bApp; // App inside the Apps folder
bool bAutoSort;
bool bPrograms; // this item is directly in the Programs folder
bool bNew;
int order;
unsigned int folderHash; // only if bFolder
CTreeItem( void ) { nameHash=nameHashProg=0; pItemInfo1=pItemInfo2=NULL; bFolder=bEmpty=bApps=bApp=bAutoSort=bPrograms=bNew=false; order=0; folderHash=0; }
void SetName( const wchar_t *_name, bool bNoExtensions )
{
if (bNoExtensions)
{
const wchar_t *end=wcsrchr(_name,'.');
if (end)
{
name=CString(_name,(int)(end-_name));
return;
}
}
name=_name;
}
bool operator==( const CTreeItem &item ) const { return pItemInfo1==item.pItemInfo1 && pItemInfo2==item.pItemInfo2 && name==item.name && bFolder==item.bFolder && (bFolder || bNew==item.bNew); }
unsigned int GetNameHash( void ) const { return bPrograms?nameHashProg:nameHash; }
};
BEGIN_MSG_MAP( CProgramsTree )
MESSAGE_HANDLER( WM_DESTROY, OnDestroy )
MESSAGE_HANDLER( WM_KEYDOWN, OnKeyDown )
MESSAGE_HANDLER( WM_SYSKEYDOWN, OnSysKeyDown )
MESSAGE_HANDLER( WM_CHAR, OnChar )
MESSAGE_HANDLER( WM_SETFOCUS, OnSetFocus )
MESSAGE_HANDLER( WM_MOUSEMOVE, OnMouseMove )
MESSAGE_HANDLER( WM_MOUSELEAVE, OnMouseLeave )
MESSAGE_HANDLER( WM_NCMOUSEMOVE, OnNcMouseMove )
MESSAGE_HANDLER( WM_NCMOUSELEAVE, OnNcMouseLeave )
MESSAGE_HANDLER( WM_MOUSEACTIVATE, OnMouseActivate )
MESSAGE_HANDLER( WM_NCLBUTTONDOWN, OnNcLButtonDown)
MESSAGE_HANDLER( WM_TIMER, OnTimer )
MESSAGE_HANDLER( WM_ERASEBKGND, OnEraseBkgnd )
MESSAGE_HANDLER( WM_PAINT, OnPaint )
MESSAGE_HANDLER( WM_CONTEXTMENU, OnContextMenu )
MESSAGE_HANDLER( WM_HSCROLL, OnScroll )
MESSAGE_HANDLER( WM_VSCROLL, OnScroll )
MESSAGE_HANDLER( WM_MOUSEWHEEL, OnScroll )
MESSAGE_HANDLER( TVM_SETINSERTMARK, OnSetInsertMark )
MESSAGE_HANDLER( TVM_REFRESH, OnRefresh )
REFLECTED_NOTIFY_CODE_HANDLER( TVN_DELETEITEM, OnDeleteItem )
REFLECTED_NOTIFY_CODE_HANDLER( TVN_ITEMEXPANDING, OnItemExpanding )
REFLECTED_NOTIFY_CODE_HANDLER( TVN_SINGLEEXPAND, OnSingleExpand )
REFLECTED_NOTIFY_CODE_HANDLER( TVN_BEGINDRAG, OnBeginDrag )
REFLECTED_NOTIFY_CODE_HANDLER( TVN_BEGINRDRAG, OnBeginDrag )
REFLECTED_NOTIFY_CODE_HANDLER( TVN_BEGINLABELEDIT, OnBeginLabelEdit )
REFLECTED_NOTIFY_CODE_HANDLER( TVN_ENDLABELEDIT, OnEndLabelEdit )
REFLECTED_NOTIFY_CODE_HANDLER( TVN_GETINFOTIP, OnGetInfoTip )
REFLECTED_NOTIFY_CODE_HANDLER( NM_CLICK, OnClick )
REFLECTED_NOTIFY_CODE_HANDLER( NM_RCLICK, OnRClick )
END_MSG_MAP()
CProgramsTree( void );
~CProgramsTree( void )
{
Assert(m_RefCount==0);
}
void Create( CMenuContainer *pOwner );
virtual WNDPROC GetWindowProc( void ) { return CustomWindowProc; }
static LRESULT CALLBACK CustomWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
void DeleteAllItems( void );
void CreateItems( void );
void SelectItem( int y );
void SelectFirst( void );
void SelectLast( void );
void ClearAllNew( void );
// reorders the tree elements and saves the order in registry
void OrderElements( HTREEITEM hChild, HTREEITEM hParent, const std::vector<unsigned int> &order, bool bAutoSort, bool bResort );
// saves the item order by replacing the item with the new info
void SaveRenamedOrder( HTREEITEM hItem, const CItemManager::ItemInfo *pNewInfo );
// IUnknown
virtual STDMETHODIMP QueryInterface( REFIID riid, void **ppvObject )
{
Assert(0);
*ppvObject=NULL;
return E_FAIL;
}
virtual ULONG STDMETHODCALLTYPE AddRef( void )
{
return InterlockedIncrement(&m_RefCount);
}
virtual ULONG STDMETHODCALLTYPE Release( void )
{
long nTemp=InterlockedDecrement(&m_RefCount);
if (!nTemp) delete this;
return nTemp;
}
// IDropTarget
virtual HRESULT STDMETHODCALLTYPE DragEnter( IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect );
virtual HRESULT STDMETHODCALLTYPE DragOver( DWORD grfKeyState, POINTL pt, DWORD *pdwEffect );
virtual HRESULT STDMETHODCALLTYPE DragLeave( void );
virtual HRESULT STDMETHODCALLTYPE Drop( IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect );
static void DrawScrollbarBackground( HDC hdc, int iPartId, int iStateId, LPCRECT pRect );
void DrawTree( HDC hdc, const RECT &drawRect );
protected:
LRESULT OnDestroy( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnKeyDown( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnSysKeyDown( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnChar( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnSetFocus( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnMouseMove( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnMouseLeave( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnNcMouseMove( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnNcMouseLeave( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnMouseActivate( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnNcLButtonDown( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnTimer( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnPaint( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnEraseBkgnd( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) { return 1; }
LRESULT OnContextMenu( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnScroll( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnSetInsertMark( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnRefresh( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );
LRESULT OnDeleteItem( int idCtrl, LPNMHDR pnmh, BOOL& bHandled );
LRESULT OnItemExpanding( int idCtrl, LPNMHDR pnmh, BOOL& bHandled );
LRESULT OnSingleExpand( int idCtrl, LPNMHDR pnmh, BOOL& bHandled );
LRESULT OnBeginDrag( int idCtrl, LPNMHDR pnmh, BOOL& bHandled );
LRESULT OnBeginLabelEdit( int idCtrl, LPNMHDR pnmh, BOOL& bHandled );
LRESULT OnEndLabelEdit( int idCtrl, LPNMHDR pnmh, BOOL& bHandled );
LRESULT OnGetInfoTip( int idCtrl, LPNMHDR pnmh, BOOL& bHandled );
LRESULT OnClick( int idCtrl, LPNMHDR pnmh, BOOL& bHandled );
LRESULT OnRClick( int idCtrl, LPNMHDR pnmh, BOOL& bHandled );
virtual void OnFinalMessage( HWND ) { Release(); }
private:
DWORD m_RefCount;
CMenuContainer *m_pOwner;
HIMAGELIST m_ImageList;
bool m_bHoverTimer;
bool m_bTrackMouse;
bool m_bRefreshPosted;
bool m_bAutoSort;
bool m_bDragApps;
bool m_bInsertAfter;
POINT m_LastMousePos;
int m_RootX;
int m_MinX;
int m_MaxX;
HTREEITEM m_InsertMark;
HTHEME m_TreeTheme;
HTHEME m_ScrollTheme;
enum TDropLocation
{
DROP_NOWHERE,
DROP_INSIDE,
DROP_BEFORE,
DROP_AFTER,
DROP_LAST,
};
TDropLocation m_DropLocation;
HTREEITEM m_DragItem;
HTREEITEM m_DropTarget;
HTREEITEM m_HoverItem;
CComPtr<CDropTargetProxy> m_pDropTargetProxy;
const CTreeItem *GetSelectedItem( HTREEITEM &hItem );
void AddFirstFolder( std::vector<CTreeItem*> &items, IShellItem *pParent, bool bPrograms );
void AddSecondFolder( std::vector<CTreeItem*> &items, IShellItem *pParent, bool bPrograms );
void AddMetroApps( std::vector<CTreeItem*> &items );
void GetFolderItems( std::vector<CTreeItem*> &items, HTREEITEM hParent );
void CreateFolderItems( IShellItem *pParent1, IShellItem *pParent2, HTREEITEM hParent );
void CreateFolderItems( HTREEITEM hParent );
void PostRefreshMessage( const CItemManager::ItemInfo *pSelectItem=NULL );
void RefreshTree( HTREEITEM hParent, const CItemManager::ItemInfo *pSelectItem );
void GetDragEffect( DWORD &grfKeyState, DWORD *pdwEffect );
void DrawTreeItem( HDC hdc, HDC hsrc, HTREEITEM hItem, const RECT &itemRect, bool bHot ) const;
bool GetInsertRect( RECT &rc ) const;
void ClearAllNewRec( HTREEITEM hParent );
static bool s_bFoldersFirst;
static bool CmpTreeItems( const CTreeItem *item1, const CTreeItem *item2 );
static int CALLBACK CmpTreeItemsCB( LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort );
};