ReactOS 0.4.16-dev-340-g0540c21
CExplorerBand.cpp
Go to the documentation of this file.
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.sylv@gmail.com>
6 * Copyright 2020-2024 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
7 */
8
9#include "objects.h"
10
11#include <wine/debug.h>
13
14/*
15 * TODO:
16 * - Monitor correctly "external" shell interrupts (seems like we need to register/deregister them for each folder)
17 * - find and fix what cause explorer crashes sometimes (seems to be explorer that does more releases than addref)
18 * - TESTING
19 */
20
22{
23}
24
26{
27}
28
30{
31 if (!pClassID)
32 return E_POINTER;
33 *pClassID = CLSID_ExplorerBand;
34 return S_OK;
35}
36
38{
39 return CSIDL_DESKTOP;
40}
41
43{
44 // Remove TVS_SINGLEEXPAND for now since it has strange behaviour
46 TVS_HASBUTTONS | TVS_SHOWSELALWAYS | TVS_EDITLABELS /* | TVS_SINGLEEXPAND*/;
47}
48
50{
51 return 0;
52}
53
55{
56 return SHCONTF_FOLDERS;
57}
58
60{
61 return ::LoadStringW(instance, IDS_FOLDERSLABEL, pszTitle, cchTitle);
62}
63
65{
66 return TRUE;
67}
68
69// Called when the user has selected an item.
71{
72 return Invoke(pidl);
73}
74
75// Handles a user action on an item.
77{
78 /* Prevents navigation if selection is initiated inside the band */
79 if (m_mtxBlockNavigate)
80 return S_OK;
81
82 _UpdateBrowser(pidl);
83 m_hwndTreeView.SetFocus();
84 return S_OK;
85}
86
88{
89 TVSORTCB sortCallback;
90 sortCallback.hParent = hParent;
91 sortCallback.lpfnCompare = _CompareTreeItems;
92 sortCallback.lParam = (LPARAM)(PVOID)m_pDesktop; // m_pDesktop is not a pointer
93 TreeView_SortChildrenCB(m_hwndTreeView, &sortCallback, 0);
94}
95
97{
98 CItemData *info1 = (CItemData*)p1;
99 CItemData *info2 = (CItemData*)p2;
100 IShellFolder *pDesktop = (IShellFolder *)p3;
101 HRESULT hr = pDesktop->CompareIDs(0, info1->absolutePidl, info2->absolutePidl);
102 if (FAILED(hr))
103 return 0;
104 return (SHORT)HRESULT_CODE(hr);
105}
106
108{
109 HRESULT hr = CNSCBand::_CreateTreeView(hwndParent);
111 return hr;
112
113 // Insert the root node
114 m_hRoot = _InsertItem(NULL, m_pDesktop, m_pidlRoot, m_pidlRoot, FALSE);
115 if (!m_hRoot)
116 {
117 ERR("Failed to create root item\n");
118 return E_FAIL;
119 }
120 TreeView_Expand(m_hwndTreeView, m_hRoot, TVE_EXPAND);
121
122 // Navigate to current folder position
124
125 // Register browser connection endpoint
126 CComPtr<IWebBrowser2> browserService;
127 hr = IUnknown_QueryService(m_pSite, SID_SWebBrowserApp, IID_PPV_ARG(IWebBrowser2, &browserService));
129 return hr;
130
131 // Communicate via IDispatch
132 hr = AtlAdvise(browserService, dynamic_cast<IDispatch*>(this), DIID_DWebBrowserEvents, &m_adviseCookie);
134 return hr;
135
136 return hr;
137}
138
140{
141 CComPtr<IWebBrowser2> browserService;
143 IID_PPV_ARG(IWebBrowser2, &browserService));
145 return;
146
147 AtlUnadvise(browserService, DIID_DWebBrowserEvents, m_adviseCookie);
148
149 CNSCBand::_DestroyTreeView();
150}
151
152// *** IDispatch methods ***
153
155{
157 return E_NOTIMPL;
158}
159
161{
163 return E_NOTIMPL;
164}
165
167{
169 return E_NOTIMPL;
170}
171
174 DISPID dispIdMember,
175 REFIID riid,
176 LCID lcid,
177 WORD wFlags,
178 DISPPARAMS *pDispParams,
179 VARIANT *pVarResult,
180 EXCEPINFO *pExcepInfo,
181 UINT *puArgErr)
182{
183 switch (dispIdMember)
184 {
187 {
188 TRACE("dispId %d received\n", dispIdMember);
190 return S_OK;
191 }
192 }
193 TRACE("Unknown dispid requested: %08x\n", dispIdMember);
194 return E_INVALIDARG;
195}
196
198{
199 CComHeapPtr<ITEMIDLIST> pidl;
200 HRESULT hr = _GetCurrentLocation(&pidl);
202 return FALSE;
203
204 // Find PIDL into our explorer
205 ++m_mtxBlockNavigate;
208 --m_mtxBlockNavigate;
209
210 return result;
211}
212
221BOOL
224 _Out_ HTREEITEM *phItem,
225 _In_ BOOL bExpand,
227 _In_ BOOL bSelect)
228{
229 if (!phItem)
230 return FALSE;
231
232 *phItem = NULL;
233
234 HTREEITEM hItem = TreeView_GetFirstVisible(m_hwndTreeView);
235 HTREEITEM hParent = NULL, tmp;
236 while (TRUE)
237 {
238 CItemData *pItemData = GetItemData(hItem);
239 if (!pItemData)
240 {
241 ERR("Something has gone wrong, no data associated to node\n");
242 return FALSE;
243 }
244
245 // If we found our node, give it back
246 if (!m_pDesktop->CompareIDs(0, pItemData->absolutePidl, dest))
247 {
248 if (bSelect)
249 TreeView_SelectItem(m_hwndTreeView, hItem);
250 *phItem = hItem;
251 return TRUE;
252 }
253
254 // Check if we are a parent of the requested item
255 TVITEMW tvItem;
256 LPITEMIDLIST relativeChild = ILFindChild(pItemData->absolutePidl, dest);
257 if (relativeChild)
258 {
259 // Notify treeview we have children
260 tvItem.mask = TVIF_CHILDREN;
261 tvItem.hItem = hItem;
262 tvItem.cChildren = 1;
263 TreeView_SetItem(m_hwndTreeView, &tvItem);
264
265 // If we can expand and the node isn't expanded yet, do it
266 if (bExpand)
267 {
268 if (!pItemData->expanded)
269 {
270 _InsertSubitems(hItem, pItemData->absolutePidl);
271 pItemData->expanded = TRUE;
272 }
273 TreeView_Expand(m_hwndTreeView, hItem, TVE_EXPAND);
274 }
275
276 // Try to get a child
277 tmp = TreeView_GetChild(m_hwndTreeView, hItem);
278 if (tmp)
279 {
280 // We have a child, let's continue with it
281 hParent = hItem;
282 hItem = tmp;
283 continue;
284 }
285
286 if (bInsert && pItemData->expanded)
287 {
288 // Happens when we have to create a subchild inside a child
289 hItem = _InsertItem(hItem, dest, relativeChild, TRUE);
290 }
291
292 // We end up here, without any children, so we found nothing
293 // Tell the parent node it has children
294 ZeroMemory(&tvItem, sizeof(tvItem));
295 return FALSE;
296 }
297
298 // Find sibling
299 tmp = TreeView_GetNextSibling(m_hwndTreeView, hItem);
300 if (tmp)
301 {
302 hItem = tmp;
303 continue;
304 }
305
306 if (bInsert)
307 {
308 *phItem = hItem = _InsertItem(hParent, dest, ILFindLastID(dest), TRUE);
309 return TRUE;
310 }
311
312 return FALSE;
313 }
314
316}
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define ERR(fmt,...)
Definition: precomp.h:57
#define STDMETHODIMP
Definition: basetyps.h:43
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15
void _DestroyTreeView() override
static INT CALLBACK _CompareTreeItems(LPARAM p1, LPARAM p2, LPARAM p3)
STDMETHODIMP GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) override
STDMETHODIMP OnSelectionChanged(_In_ PCIDLIST_ABSOLUTE pidl) override
STDMETHODIMP GetTypeInfoCount(UINT *pctinfo) override
void _SortItems(HTREEITEM hParent) override
STDMETHODIMP GetClassID(CLSID *pClassID) override
STDMETHODIMP Invoke(_In_ PCIDLIST_ABSOLUTE pidl) override
BOOL _NavigateToPIDL(_In_ LPCITEMIDLIST dest, _Out_ HTREEITEM *phItem, _In_ BOOL bExpand, _In_ BOOL bInsert, _In_ BOOL bSelect)
BOOL _WantsRootItem() override
DWORD _GetEnumFlags() override
STDMETHODIMP GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) override
DWORD _GetTVStyle() override
INT _GetRootCsidl() override
DWORD _GetTVExStyle() override
BOOL _GetTitle(LPWSTR pszTitle, INT cchTitle) override
BOOL _NavigateToCurrentFolder()
HRESULT _CreateTreeView(HWND hwndParent) override
virtual ~CExplorerBand()
static BOOL bInsert
Definition: cmdinput.c:121
static HWND hwndParent
Definition: cryptui.c:300
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static HINSTANCE instance
Definition: main.c:40
HRESULT WINAPI AtlAdvise(IUnknown *pUnkCP, IUnknown *pUnk, const IID *iid, DWORD *pdw)
Definition: atl.c:45
HRESULT WINAPI AtlUnadvise(IUnknown *pUnkCP, const IID *iid, DWORD dw)
Definition: atl.c:73
#define CALLBACK
Definition: compat.h:35
#define FAILED_UNEXPECTEDLY(hr)
Definition: precomp.h:121
#define IDS_FOLDERSLABEL
Definition: resource.h:14
HRESULT WINAPI IUnknown_QueryService(IUnknown *, REFGUID, REFIID, LPVOID *)
Definition: ordinal.c:1501
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
GLuint64EXT * result
Definition: glext.h:11304
REFIID riid
Definition: atlbase.h:39
HRESULT CompareIDs([in] LPARAM lParam, [in] PCUIDLIST_RELATIVE pidl1, [in] PCUIDLIST_RELATIVE pidl2)
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
static char * dest
Definition: rtl.c:135
static LPOLESTR
Definition: stg_prop.c:27
static VARIANTARG static DISPID
Definition: ordinal.c:52
unsigned int UINT
Definition: ndis.h:50
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define UNREACHABLE
#define WS_CHILD
Definition: pedump.c:617
#define WS_VISIBLE
Definition: pedump.c:620
short SHORT
Definition: pedump.c:59
#define WS_CLIPSIBLINGS
Definition: pedump.c:618
#define WS_CLIPCHILDREN
Definition: pedump.c:619
LPITEMIDLIST WINAPI ILFindLastID(LPCITEMIDLIST pidl)
Definition: pidl.c:198
PUIDLIST_RELATIVE WINAPI ILFindChild(PIDLIST_ABSOLUTE pidl1, PCIDLIST_ABSOLUTE pidl2)
Definition: pidl.c:748
#define TreeView_SelectItem(hwnd, hitem)
Definition: commctrl.h:3486
#define TreeView_Expand(hwnd, hitem, code)
Definition: commctrl.h:3425
#define TreeView_GetChild(hwnd, hitem)
Definition: commctrl.h:3471
#define TVS_SHOWSELALWAYS
Definition: commctrl.h:3257
#define TVS_HASLINES
Definition: commctrl.h:3253
#define TVE_EXPAND
Definition: commctrl.h:3428
#define TreeView_GetFirstVisible(hwnd)
Definition: commctrl.h:3475
#define TreeView_GetNextSibling(hwnd, hitem)
Definition: commctrl.h:3472
#define TVS_HASBUTTONS
Definition: commctrl.h:3252
#define TreeView_SortChildrenCB(hwnd, psort, recurse)
Definition: commctrl.h:3553
#define TVS_EDITLABELS
Definition: commctrl.h:3255
#define TVIF_CHILDREN
Definition: commctrl.h:3277
#define TreeView_SetItem(hwnd, pitem)
Definition: commctrl.h:3502
#define REFIID
Definition: guiddef.h:118
DWORD LCID
Definition: nls.h:13
HRESULT hr
Definition: shlfolder.c:183
#define SID_SWebBrowserApp
Definition: shlguid.h:111
#define CSIDL_DESKTOP
Definition: shlobj.h:2173
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
#define TRACE(s)
Definition: solgame.cpp:4
HTREEITEM hItem
Definition: commctrl.h:3322
UINT mask
Definition: commctrl.h:3321
int cChildren
Definition: commctrl.h:3329
LPARAM lParam
Definition: commctrl.h:3621
HTREEITEM hParent
Definition: commctrl.h:3619
PFNTVCOMPARE lpfnCompare
Definition: commctrl.h:3620
HTREEITEM hItem
Definition: treelist.h:37
int32_t INT
Definition: typedefs.h:58
#define DISPID_NAVIGATECOMPLETE2
Definition: webchild.h:54
#define DISPID_DOWNLOADCOMPLETE
Definition: webchild.h:39
#define ZeroMemory
Definition: winbase.h:1737
_In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon.h:531
LONG_PTR LPARAM
Definition: windef.h:208
#define E_POINTER
Definition: winerror.h:2365
#define HRESULT_CODE(hr)
Definition: winerror.h:76
#define IID_PPV_ARG(Itype, ppType)
WCHAR * LPWSTR
Definition: xmlstorage.h:184