1 /* 2 * PROJECT: ReactOS shdocvw 3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) 4 * PURPOSE: Explorer bar 5 * COPYRIGHT: Copyright 2016 Sylvain Deverre <deverre dot sylv at gmail dot com> 6 * Copyright 2020-2024 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com> 7 */ 8 9 #pragma once 10 11 #define WM_USER_SHELLEVENT (WM_USER + 88) 12 13 class CExplorerBand : 14 public CComCoClass<CExplorerBand, &CLSID_ExplorerBand>, 15 public CComObjectRootEx<CComMultiThreadModelNoCS>, 16 public IDeskBand, 17 public IObjectWithSite, 18 public IInputObject, 19 public IPersistStream, 20 public IOleCommandTarget, 21 public IServiceProvider, 22 public IBandNavigate, 23 public IWinEventHandler, 24 public INamespaceProxy, 25 public IDispatch, 26 public IDropSource, 27 public IDropTarget, 28 public CWindowImpl<CExplorerBand, CWindow, CControlWinTraits> 29 { 30 private: 31 class NodeInfo 32 { 33 public: 34 LPITEMIDLIST absolutePidl; 35 LPITEMIDLIST relativePidl; 36 BOOL expanded; 37 }; 38 39 // *** BaseBarSite information *** 40 CComPtr<IUnknown> m_pSite; 41 CComPtr<IShellFolder> m_pDesktop; 42 43 // *** tree explorer band stuff *** 44 BOOL m_fVisible; 45 BYTE m_mtxBlockNavigate; // A "lock" that prevents internal selection changes to initiate a navigation to the newly selected item. 46 BOOL m_bFocused; 47 DWORD m_dwBandID; 48 BOOL m_isEditing; 49 HIMAGELIST m_hImageList; 50 HTREEITEM m_hRoot; 51 HTREEITEM m_oldSelected; 52 LPITEMIDLIST m_pidlCurrent; // Note: This is NULL until the first user navigation! 53 54 // *** notification cookies *** 55 DWORD m_adviseCookie; 56 ULONG m_shellRegID; 57 58 // *** Drop target information *** 59 CComPtr<IDropTarget> m_pDropTarget; 60 HTREEITEM m_childTargetNode; 61 CComPtr<IDataObject> m_pCurObject; 62 63 void InitializeExplorerBand(); 64 void DestroyExplorerBand(); 65 HRESULT ExecuteCommand(CComPtr<IContextMenu>& menu, UINT nCmd); 66 67 // *** notifications handling *** 68 BOOL OnTreeItemExpanding(LPNMTREEVIEW pnmtv); 69 void OnSelectionChanged(LPNMTREEVIEW pnmtv); 70 BOOL OnTreeItemDeleted(LPNMTREEVIEW pnmtv); 71 void OnTreeItemDragging(LPNMTREEVIEW pnmtv, BOOL isRightClick); 72 73 // *** ATL event handlers *** 74 LRESULT OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 75 LRESULT ContextMenuHack(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 76 LRESULT OnShellEvent(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 77 LRESULT OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 78 LRESULT OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 79 LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); 80 81 // *** Helper functions *** 82 NodeInfo* GetNodeInfo(HTREEITEM hItem); 83 HRESULT UpdateBrowser(LPITEMIDLIST pidlGoto); 84 HTREEITEM InsertItem( 85 _In_opt_ HTREEITEM hParent, 86 _Inout_ IShellFolder *psfParent, 87 _In_ LPCITEMIDLIST pElt, 88 _In_ LPCITEMIDLIST pEltRelative, 89 _In_ BOOL bSort); 90 HTREEITEM InsertItem( 91 _In_opt_ HTREEITEM hParent, 92 _In_ LPCITEMIDLIST pElt, 93 _In_ LPCITEMIDLIST pEltRelative, 94 _In_ BOOL bSort); 95 BOOL InsertSubitems(HTREEITEM hItem, NodeInfo *pNodeInfo); 96 BOOL NavigateToPIDL(LPCITEMIDLIST dest, HTREEITEM *item, BOOL bExpand, BOOL bInsert, BOOL bSelect); 97 BOOL NavigateToCurrentFolder(); 98 HRESULT GetCurrentLocation(PIDLIST_ABSOLUTE &pidl); 99 HRESULT IsCurrentLocation(PCIDLIST_ABSOLUTE pidl); 100 void OnChangeNotify( 101 _In_opt_ LPCITEMIDLIST pidl0, 102 _In_opt_ LPCITEMIDLIST pidl1, 103 _In_ LONG lEvent); 104 void Refresh(); 105 void RefreshRecurse(_In_ HTREEITEM hItem); 106 BOOL IsTreeItemInEnum(_In_ HTREEITEM hItem, _In_ IEnumIDList *pEnum); 107 BOOL TreeItemHasThisChild(_In_ HTREEITEM hItem, _In_ PCITEMID_CHILD pidlChild); 108 HRESULT GetItemEnum(_Out_ CComPtr<IEnumIDList>& pEnum, _In_ HTREEITEM hItem); 109 BOOL ItemHasAnyChild(_In_ HTREEITEM hItem); 110 111 // *** Tree item sorting callback *** 112 static int CALLBACK CompareTreeItems(LPARAM p1, LPARAM p2, LPARAM p3); 113 114 public: 115 CExplorerBand(); 116 virtual ~CExplorerBand(); 117 118 // *** IOleWindow methods *** 119 STDMETHOD(GetWindow)(HWND *lphwnd) override; 120 STDMETHOD(ContextSensitiveHelp)(BOOL fEnterMode) override; 121 122 // *** IDockingWindow methods *** 123 STDMETHOD(CloseDW)(DWORD dwReserved) override; 124 STDMETHOD(ResizeBorderDW)(const RECT *prcBorder, IUnknown *punkToolbarSite, BOOL fReserved) override; 125 STDMETHOD(ShowDW)(BOOL fShow) override; 126 127 // *** IDeskBand methods *** 128 STDMETHOD(GetBandInfo)(DWORD dwBandID, DWORD dwViewMode, DESKBANDINFO *pdbi) override; 129 130 // *** IObjectWithSite methods *** 131 STDMETHOD(SetSite)(IUnknown *pUnkSite) override; 132 STDMETHOD(GetSite)(REFIID riid, void **ppvSite) override; 133 134 // *** IOleCommandTarget methods *** 135 STDMETHOD(QueryStatus)(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText) override; 136 STDMETHOD(Exec)(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut) override; 137 138 // *** IServiceProvider methods *** 139 STDMETHOD(QueryService)(REFGUID guidService, REFIID riid, void **ppvObject) override; 140 141 // *** IInputObject methods *** 142 STDMETHOD(UIActivateIO)(BOOL fActivate, LPMSG lpMsg) override; 143 STDMETHOD(HasFocusIO)() override; 144 STDMETHOD(TranslateAcceleratorIO)(LPMSG lpMsg) override; 145 146 // *** IPersist methods *** 147 STDMETHOD(GetClassID)(CLSID *pClassID) override; 148 149 // *** IPersistStream methods *** 150 STDMETHOD(IsDirty)() override; 151 STDMETHOD(Load)(IStream *pStm) override; 152 STDMETHOD(Save)(IStream *pStm, BOOL fClearDirty) override; 153 STDMETHOD(GetSizeMax)(ULARGE_INTEGER *pcbSize) override; 154 155 // *** IWinEventHandler methods *** 156 STDMETHOD(OnWinEvent)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult) override; 157 STDMETHOD(IsWindowOwner)(HWND hWnd) override; 158 159 // *** IBandNavigate methods *** 160 STDMETHOD(Select)(long paramC) override; 161 162 // *** INamespaceProxy *** 163 STDMETHOD(GetNavigateTarget)( 164 _In_ PCIDLIST_ABSOLUTE pidl, 165 _Out_ PIDLIST_ABSOLUTE ppidlTarget, 166 _Out_ ULONG *pulAttrib) override; 167 STDMETHOD(Invoke)(_In_ PCIDLIST_ABSOLUTE pidl) override; 168 STDMETHOD(OnSelectionChanged)(_In_ PCIDLIST_ABSOLUTE pidl) override; 169 STDMETHOD(RefreshFlags)( 170 _Out_ DWORD *pdwStyle, 171 _Out_ DWORD *pdwExStyle, 172 _Out_ DWORD *dwEnum) override; 173 STDMETHOD(CacheItem)(_In_ PCIDLIST_ABSOLUTE pidl) override; 174 175 // *** IDispatch methods *** 176 STDMETHOD(GetTypeInfoCount)(UINT *pctinfo) override; 177 STDMETHOD(GetTypeInfo)(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) override; 178 STDMETHOD(GetIDsOfNames)(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) override; 179 STDMETHOD(Invoke)(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) override; 180 181 // *** IDropTarget methods *** 182 STDMETHOD(DragEnter)(IDataObject *pObj, DWORD glfKeyState, POINTL pt, DWORD *pdwEffect) override; 183 STDMETHOD(DragOver)(DWORD glfKeyState, POINTL pt, DWORD *pdwEffect) override; 184 STDMETHOD(DragLeave)() override; 185 STDMETHOD(Drop)(IDataObject *pObj, DWORD glfKeyState, POINTL pt, DWORD *pdwEffect) override; 186 187 // *** IDropSource methods *** 188 STDMETHOD(QueryContinueDrag)(BOOL fEscapePressed, DWORD grfKeyState) override; 189 STDMETHOD(GiveFeedback)(DWORD dwEffect) override; 190 191 DECLARE_REGISTRY_RESOURCEID(IDR_EXPLORERBAND) 192 DECLARE_NOT_AGGREGATABLE(CExplorerBand) 193 194 DECLARE_PROTECT_FINAL_CONSTRUCT() 195 196 BEGIN_COM_MAP(CExplorerBand) 197 COM_INTERFACE_ENTRY_IID(IID_IDispatch, IDispatch) 198 COM_INTERFACE_ENTRY_IID(IID_IWinEventHandler, IWinEventHandler) 199 COM_INTERFACE_ENTRY_IID(IID_IBandNavigate, IBandNavigate) 200 COM_INTERFACE_ENTRY_IID(IID_INamespaceProxy, INamespaceProxy) 201 COM_INTERFACE_ENTRY2_IID(IID_IOleWindow, IOleWindow, IDeskBand) 202 COM_INTERFACE_ENTRY2_IID(IID_IDockingWindow, IDockingWindow, IDeskBand) 203 COM_INTERFACE_ENTRY_IID(IID_IDeskBand, IDeskBand) 204 COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite, IObjectWithSite) 205 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget, IOleCommandTarget) 206 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider) 207 COM_INTERFACE_ENTRY_IID(IID_IInputObject, IInputObject) 208 COM_INTERFACE_ENTRY2_IID(IID_IPersist, IPersist, IPersistStream) 209 COM_INTERFACE_ENTRY_IID(IID_IPersistStream, IPersistStream) 210 END_COM_MAP() 211 212 BEGIN_MSG_MAP(CExplorerBand) 213 MESSAGE_HANDLER(WM_CONTEXTMENU, OnContextMenu) 214 MESSAGE_HANDLER(WM_USER_SHELLEVENT, OnShellEvent) 215 MESSAGE_HANDLER(WM_RBUTTONDOWN, ContextMenuHack) 216 MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus) 217 MESSAGE_HANDLER(WM_TIMER, OnTimer) 218 // MESSAGE_HANDLER(WM_KILLFOCUS, OnKillFocus) 219 END_MSG_MAP() 220 }; 221