ReactOS 0.4.15-dev-7942-gd23573b
explorerband.cpp
Go to the documentation of this file.
1/*
2 * ReactOS Explorer
3 *
4 * Copyright 2016 Sylvain Deverre <deverre dot sylv at gmail dot com>
5 * Copyright 2020 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#include "precomp.h"
23#include <commoncontrols.h>
24#include <undocshell.h>
25
26#if 1
27#undef UNIMPLEMENTED
28
29#define UNIMPLEMENTED DbgPrint("%s is UNIMPLEMENTED!\n", __FUNCTION__)
30#endif
31
32/*
33 * TODO:
34 * - Monitor correctly "external" shell interrupts (seems like we need to register/deregister them for each folder)
35 * - find and fix what cause explorer crashes sometimes (seems to be explorer that does more releases than addref)
36 * - TESTING
37 */
38
39typedef struct _PIDLDATA
40{
44
45#define PT_GUID 0x1F
46#define PT_SHELLEXT 0x2E
47#define PT_YAGUID 0x70
48
50{
51 LPPIDLDATA lpPData = (LPPIDLDATA)&pidl->mkid.abID;
52
53 return (pidl &&
54 ((lpPData && (PT_GUID == lpPData->type || PT_SHELLEXT== lpPData->type ||
55 PT_YAGUID == lpPData->type)) || (pidl && pidl->mkid.cb == 0x00)));
56}
57
59{
60 IShellFolder *pShellFolder = NULL;
61 LPCITEMIDLIST pidlRelative = NULL;
62 STRRET str;
63 HRESULT hr;
64
65 if (pidlDirectory == NULL || szDisplayName == NULL)
66 {
67 return E_FAIL;
68 }
69
70 hr = SHBindToParent(pidlDirectory, IID_PPV_ARG(IShellFolder, &pShellFolder), &pidlRelative);
71
72 if (SUCCEEDED(hr))
73 {
74 hr = pShellFolder->GetDisplayNameOf(pidlRelative,uFlags,&str);
75 if (SUCCEEDED(hr))
76 {
77 hr = StrRetToBuf(&str,pidlDirectory,szDisplayName,cchMax);
78 }
79 pShellFolder->Release();
80 }
81 return hr;
82}
83
84/*
85 This is a Windows hack, because shell event messages in Windows gives an
86 ill-formed PIDL stripped from useful data that parses incorrectly with SHGetFileInfo.
87 So we need to re-enumerate subfolders until we find one with the same name.
88 */
90{
91 HRESULT hr;
94 CComPtr<IEnumIDList> pEnumIDList;
95 LPITEMIDLIST childPidl;
96 LPITEMIDLIST correctChild;
97 LPITEMIDLIST correctParent;
98 ULONG fetched;
99 DWORD EnumFlags;
100
101
102 EnumFlags = SHCONTF_FOLDERS | SHCONTF_INCLUDEHIDDEN;
103 hr = SHBindToParent(buggyPidl, IID_PPV_ARG(IShellFolder, &folder), (LPCITEMIDLIST*)&childPidl);
104 *cleanPidl = NULL;
105 if (!SUCCEEDED(hr))
106 {
107 ERR("Can't bind to parent folder\n");
108 return hr;
109 }
110 hr = folder->QueryInterface(IID_PPV_ARG(IPersistFolder2, &persist));
111 if (!SUCCEEDED(hr))
112 {
113 ERR("PIDL doesn't belong to the shell namespace, aborting\n");
114 return hr;
115 }
116
117 hr = persist->GetCurFolder(&correctParent);
118 if (!SUCCEEDED(hr))
119 {
120 ERR("Unable to get current folder\n");
121 return hr;
122 }
123
124 hr = folder->EnumObjects(NULL,EnumFlags,&pEnumIDList);
125 // avoid broken IShellFolder implementations that return null pointer with success
126 if (!SUCCEEDED(hr) || !pEnumIDList)
127 {
128 ERR("Can't enum the folder !\n");
129 return hr;
130 }
131
132 while(SUCCEEDED(pEnumIDList->Next(1, &correctChild, &fetched)) && correctChild && fetched)
133 {
134 if (!folder->CompareIDs(0, childPidl, correctChild))
135 {
136 *cleanPidl = ILCombine(correctParent, correctChild);
137 ILFree(correctChild);
138 goto Cleanup;
139 }
140 ILFree(correctChild);
141 }
142Cleanup:
143 ILFree(correctParent);
144 return hr;
145}
146
148 : m_pSite(NULL)
149 , m_fVisible(FALSE)
150 , m_bNavigating(FALSE)
151 , m_dwBandID(0)
152 , m_isEditing(FALSE)
153 , m_pidlCurrent(NULL)
154{
155}
156
158{
159 if (m_pidlCurrent)
160 {
162 }
163}
164
166{
167 // Init the treeview here
168 HRESULT hr;
169 LPITEMIDLIST pidl;
170 CComPtr<IWebBrowser2> browserService;
172
175 return;
176
177 hr = SHGetFolderLocation(m_hWnd, CSIDL_DESKTOP, NULL, 0, &pidl);
179 return;
180
181 IImageList * piml;
184 return;
185
187
188 // Insert the root node
189 m_hRoot = InsertItem(0, m_pDesktop, pidl, pidl, FALSE);
190 if (!m_hRoot)
191 {
192 ERR("Failed to create root item\n");
193 return;
194 }
195
196 NodeInfo* pNodeInfo = GetNodeInfo(m_hRoot);
197
198 // Insert child nodes
199 InsertSubitems(m_hRoot, pNodeInfo);
201
202 // Navigate to current folder position
204
205 // Register shell notification
206 shcne.pidl = pidl;
207 shcne.fRecursive = TRUE;
209 m_hWnd,
213 1,
214 &shcne);
215 if (!m_shellRegID)
216 {
217 ERR("Something went wrong, error %08x\n", GetLastError());
218 }
219 // Register browser connection endpoint
220 hr = IUnknown_QueryService(m_pSite, SID_SWebBrowserApp, IID_PPV_ARG(IWebBrowser2, &browserService));
222 return;
223
224 hr = AtlAdvise(browserService, dynamic_cast<IDispatch*>(this), DIID_DWebBrowserEvents, &m_adviseCookie);
226 return;
227
228 ILFree(pidl);
229}
230
232{
233 HRESULT hr;
234 CComPtr <IWebBrowser2> browserService;
235
236 TRACE("Cleaning up explorer band ...\n");
237
238 hr = IUnknown_QueryService(m_pSite, SID_SWebBrowserApp, IID_PPV_ARG(IWebBrowser2, &browserService));
240 return;
241
242 hr = AtlUnadvise(browserService, DIID_DWebBrowserEvents, m_adviseCookie);
243 /* Remove all items of the treeview */
244 RevokeDragDrop(m_hWnd);
247 m_hRoot = NULL;
248 TRACE("Cleanup done !\n");
249}
250
252{
253 TVITEM tvItem;
254
255 tvItem.mask = TVIF_PARAM;
256 tvItem.hItem = hItem;
257
258 if (!TreeView_GetItem(m_hWnd, &tvItem))
259 return 0;
260
261 return reinterpret_cast<NodeInfo*>(tvItem.lParam);
262}
263
265{
266 CComPtr<IOleWindow> pBrowserOleWnd;
267 CMINVOKECOMMANDINFO cmi;
268 HWND browserWnd;
269 HRESULT hr;
270
273 return hr;
274
275 hr = pBrowserOleWnd->GetWindow(&browserWnd);
277 return hr;
278
279 ZeroMemory(&cmi, sizeof(cmi));
280 cmi.cbSize = sizeof(cmi);
281 cmi.lpVerb = MAKEINTRESOURCEA(nCmd);
282 cmi.hwnd = browserWnd;
283 if (GetKeyState(VK_SHIFT) & 0x8000)
284 cmi.fMask |= CMIC_MASK_SHIFT_DOWN;
285 if (GetKeyState(VK_CONTROL) & 0x8000)
286 cmi.fMask |= CMIC_MASK_CONTROL_DOWN;
287
288 return menu->InvokeCommand(&cmi);
289}
290
292{
293 CComPtr<IShellBrowser> pBrowserService;
294 HRESULT hr;
295
296 hr = IUnknown_QueryService(m_pSite, SID_STopLevelBrowser, IID_PPV_ARG(IShellBrowser, &pBrowserService));
298 return hr;
299
300 hr = pBrowserService->BrowseObject(pidlGoto, SBSP_SAMEBROWSER | SBSP_ABSOLUTE);
302 return hr;
303
304 if (m_pidlCurrent)
305 {
307 m_pidlCurrent = ILClone(pidlGoto);
308 }
309 return hr;
310}
311
312// *** notifications handling ***
314{
315 NodeInfo *pNodeInfo;
316
317 if (pnmtv->action == TVE_COLLAPSE) {
318 if (pnmtv->itemNew.hItem == m_hRoot)
319 {
320 // Prenvent root from collapsing
321 pnmtv->itemNew.mask |= TVIF_STATE;
322 pnmtv->itemNew.stateMask |= TVIS_EXPANDED;
323 pnmtv->itemNew.state &= ~TVIS_EXPANDED;
324 pnmtv->action = TVE_EXPAND;
325 return TRUE;
326 }
327 }
328 if (pnmtv->action == TVE_EXPAND) {
329 // Grab our directory PIDL
330 pNodeInfo = GetNodeInfo(pnmtv->itemNew.hItem);
331 // We have it, let's try
332 if (pNodeInfo && !pNodeInfo->expanded)
333 if (!InsertSubitems(pnmtv->itemNew.hItem, pNodeInfo)) {
334 // remove subitem "+" since we failed to add subitems
335 TV_ITEM tvItem;
336
337 tvItem.mask = TVIF_CHILDREN;
338 tvItem.hItem = pnmtv->itemNew.hItem;
339 tvItem.cChildren = 0;
340
341 TreeView_SetItem(m_hWnd, &tvItem);
342 }
343 }
344 return FALSE;
345}
346
348{
349 /* Destroy memory associated to our node */
350 NodeInfo* ptr = GetNodeInfo(pnmtv->itemOld.hItem);
351 if (ptr)
352 {
353 ILFree(ptr->relativePidl);
354 ILFree(ptr->absolutePidl);
355 delete ptr;
356 }
357 return TRUE;
358}
359
361{
362 NodeInfo* pNodeInfo = GetNodeInfo(pnmtv->itemNew.hItem);
363
364 /* Prevents navigation if selection is initiated inside the band */
365 if (m_bNavigating)
366 return;
367
368 UpdateBrowser(pNodeInfo->absolutePidl);
369
370 SetFocus();
371 // Expand the node
372 //TreeView_Expand(m_hWnd, pnmtv->itemNew.hItem, TVE_EXPAND);
373}
374
376{
377 if (!pnmtv->itemNew.lParam)
378 return;
379
380 NodeInfo* pNodeInfo = GetNodeInfo(pnmtv->itemNew.hItem);
381
382 HRESULT hr;
383 CComPtr<IShellFolder> pSrcFolder;
384 LPCITEMIDLIST pLast;
385 hr = SHBindToParent(pNodeInfo->absolutePidl, IID_PPV_ARG(IShellFolder, &pSrcFolder), &pLast);
386 if (!SUCCEEDED(hr))
387 return;
388
389 SFGAOF attrs = SFGAO_CANCOPY | SFGAO_CANMOVE | SFGAO_CANLINK;
390 pSrcFolder->GetAttributesOf(1, &pLast, &attrs);
391
392 DWORD dwEffect = 0;
393 if (attrs & SFGAO_CANCOPY)
394 dwEffect |= DROPEFFECT_COPY;
395 if (attrs & SFGAO_CANMOVE)
396 dwEffect |= DROPEFFECT_MOVE;
397 if (attrs & SFGAO_CANLINK)
398 dwEffect |= DROPEFFECT_LINK;
399
401 hr = pSrcFolder->GetUIObjectOf(m_hWnd, 1, &pLast, IID_IDataObject, 0, (LPVOID*)&pObj);
402 if (!SUCCEEDED(hr))
403 return;
404
405 DoDragDrop(pObj, this, dwEffect, &dwEffect);
406}
407
408// *** ATL event handlers ***
410{
412 NodeInfo *info;
413 HMENU treeMenu;
414 WORD x;
415 WORD y;
416 CComPtr<IShellFolder> pFolder;
417 CComPtr<IContextMenu> contextMenu;
418 HRESULT hr;
419 UINT uCommand;
420 LPITEMIDLIST pidlChild;
421
422 treeMenu = NULL;
423 item = TreeView_GetSelection(m_hWnd);
424 bHandled = TRUE;
425 if (!item)
426 {
427 goto Cleanup;
428 }
429
430 x = LOWORD(lParam);
431 y = HIWORD(lParam);
432 if (x == -1 && y == -1)
433 {
434 // TODO: grab position of tree item and position it correctly
435 }
436
438 if (!info)
439 {
440 ERR("No node data, something has gone wrong !\n");
441 goto Cleanup;
442 }
443 hr = SHBindToParent(info->absolutePidl, IID_PPV_ARG(IShellFolder, &pFolder),
444 (LPCITEMIDLIST*)&pidlChild);
445 if (!SUCCEEDED(hr))
446 {
447 ERR("Can't bind to folder!\n");
448 goto Cleanup;
449 }
450 hr = pFolder->GetUIObjectOf(m_hWnd, 1, (LPCITEMIDLIST*)&pidlChild, IID_IContextMenu,
451 NULL, reinterpret_cast<void**>(&contextMenu));
452 if (!SUCCEEDED(hr))
453 {
454 ERR("Can't get IContextMenu interface\n");
455 goto Cleanup;
456 }
457
458 IUnknown_SetSite(contextMenu, (IDeskBand *)this);
459
460 treeMenu = CreatePopupMenu();
461 hr = contextMenu->QueryContextMenu(treeMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST,
462 CMF_EXPLORE);
463 if (!SUCCEEDED(hr))
464 {
465 WARN("Can't get context menu for item\n");
466 DestroyMenu(treeMenu);
467 goto Cleanup;
468 }
470 x, y, 0, m_hWnd, NULL);
471
472 ExecuteCommand(contextMenu, uCommand);
473
474Cleanup:
475 if (contextMenu)
476 IUnknown_SetSite(contextMenu, NULL);
477 if (treeMenu)
478 DestroyMenu(treeMenu);
482 return TRUE;
483}
484
486{
487 bHandled = FALSE;
488 if (uMsg == WM_RBUTTONDOWN)
489 {
491 info.pt.x = LOWORD(lParam);
492 info.pt.y = HIWORD(lParam);
493 info.flags = TVHT_ONITEM;
494 info.hItem = NULL;
495
496 // Save the current location
498
499 // Move to the item selected by the treeview (don't change right pane)
500 TreeView_HitTest(m_hWnd, &info);
502 TreeView_SelectItem(m_hWnd, info.hItem);
504 }
505 return FALSE; /* let the wndproc process the message */
506}
507
509{
511 LPITEMIDLIST clean;
512 HTREEITEM pItem;
513
515 /* TODO: handle shell notifications */
516 switch(lParam & ~SHCNE_INTERRUPT)
517 {
518 case SHCNE_MKDIR:
519 if (!SUCCEEDED(_ReparsePIDL(dest[0], &clean)))
520 {
521 ERR("Can't reparse PIDL to a valid one\n");
522 return FALSE;
523 }
524 NavigateToPIDL(clean, &pItem, FALSE, TRUE, FALSE);
525 ILFree(clean);
526 break;
527 case SHCNE_RMDIR:
528 DeleteItem(dest[0]);
529 break;
531 if (!SUCCEEDED(_ReparsePIDL(dest[1], &clean)))
532 {
533 ERR("Can't reparse PIDL to a valid one\n");
534 return FALSE;
535 }
536 if (NavigateToPIDL(dest[0], &pItem, FALSE, FALSE, FALSE))
537 RenameItem(pItem, clean);
538 ILFree(clean);
539 break;
540 case SHCNE_UPDATEDIR:
541 // We don't take care of this message
542 TRACE("Directory updated\n");
543 break;
544 default:
545 TRACE("Unhandled message\n");
546 }
547 return TRUE;
548}
549
551{
553 IUnknown_OnFocusChangeIS(m_pSite, reinterpret_cast<IUnknown*>(this), TRUE);
554 bHandled = FALSE;
555 return TRUE;
556}
557
559{
560 IUnknown_OnFocusChangeIS(m_pSite, reinterpret_cast<IUnknown*>(this), FALSE);
561 bHandled = FALSE;
562 return TRUE;
563}
564
565// *** Helper functions ***
567{
568 TV_INSERTSTRUCT tvInsert;
569 HTREEITEM htiCreated;
570
571 /* Get the attributes of the node */
572 SFGAOF attrs = SFGAO_STREAM | SFGAO_HASSUBFOLDER;
573 HRESULT hr = psfParent->GetAttributesOf(1, &pEltRelative, &attrs);
575 return NULL;
576
577 /* Ignore streams */
578 if (attrs & SFGAO_STREAM)
579 {
580 TRACE("Ignoring stream\n");
581 return NULL;
582 }
583
584 /* Get the name of the node */
585 WCHAR wszDisplayName[MAX_PATH];
586 STRRET strret;
587 hr = psfParent->GetDisplayNameOf(pEltRelative, SHGDN_INFOLDER, &strret);
589 return NULL;
590
591 hr = StrRetToBufW(&strret, pEltRelative, wszDisplayName, MAX_PATH);
593 return NULL;
594
595 /* Get the icon of the node */
596 INT iIcon = SHMapPIDLToSystemImageListIndex(psfParent, pEltRelative, NULL);
597
598 NodeInfo* pChildInfo = new NodeInfo;
599 if (!pChildInfo)
600 {
601 ERR("Failed to allocate NodeInfo\n");
602 return FALSE;
603 }
604
605 // Store our node info
606 pChildInfo->absolutePidl = ILClone(pElt);
607 pChildInfo->relativePidl = ILClone(pEltRelative);
608 pChildInfo->expanded = FALSE;
609
610 // Set up our treeview template
611 tvInsert.hParent = hParent;
612 tvInsert.hInsertAfter = TVI_LAST;
614 tvInsert.item.cchTextMax = MAX_PATH;
615 tvInsert.item.pszText = wszDisplayName;
616 tvInsert.item.iImage = tvInsert.item.iSelectedImage = iIcon;
617 tvInsert.item.cChildren = (attrs & SFGAO_HASSUBFOLDER) ? 1 : 0;
618 tvInsert.item.lParam = (LPARAM)pChildInfo;
619
620 htiCreated = TreeView_InsertItem(m_hWnd, &tvInsert);
621
622 if (bSort)
623 {
624 TVSORTCB sortCallback;
625 sortCallback.hParent = hParent;
626 sortCallback.lpfnCompare = CompareTreeItems;
627 sortCallback.lParam = (LPARAM)this;
628 SendMessage(TVM_SORTCHILDRENCB, 0, (LPARAM)&sortCallback);
629 }
630
631 return htiCreated;
632}
633
634/* This is the slow version of the above method */
636{
637 CComPtr<IShellFolder> psfFolder;
638 HRESULT hr = SHBindToParent(pElt, IID_PPV_ARG(IShellFolder, &psfFolder), NULL);
640 return NULL;
641
642 return InsertItem(hParent, psfFolder, pElt, pEltRelative, bSort);
643}
644
646{
647 CComPtr<IEnumIDList> pEnumIDList;
648 LPITEMIDLIST pidlSub;
650 SHCONTF EnumFlags;
651 HRESULT hr;
652 ULONG fetched;
653 ULONG uItemCount;
654 CComPtr<IShellFolder> pFolder;
655 TVSORTCB sortCallback;
656
657 entry = pNodeInfo->absolutePidl;
658 fetched = 1;
659 uItemCount = 0;
660 EnumFlags = SHCONTF_FOLDERS;
661
662 hr = SHGetFolderLocation(m_hWnd, CSIDL_DESKTOP, NULL, 0, &pidlSub);
663 if (!SUCCEEDED(hr))
664 {
665 ERR("Can't get desktop PIDL !\n");
666 return FALSE;
667 }
668
669 if (!m_pDesktop->CompareIDs(NULL, pidlSub, entry))
670 {
671 // We are the desktop, so use pDesktop as pFolder
672 pFolder = m_pDesktop;
673 }
674 else
675 {
676 // Get an IShellFolder of our pidl
677 hr = m_pDesktop->BindToObject(entry, NULL, IID_PPV_ARG(IShellFolder, &pFolder));
678 if (!SUCCEEDED(hr))
679 {
680 ILFree(pidlSub);
681 ERR("Can't bind folder to desktop !\n");
682 return FALSE;
683 }
684 }
685 ILFree(pidlSub);
686
687 // TODO: handle hidden folders according to settings !
688 EnumFlags |= SHCONTF_INCLUDEHIDDEN;
689
690 // Enum through objects
691 hr = pFolder->EnumObjects(NULL,EnumFlags,&pEnumIDList);
692
693 // avoid broken IShellFolder implementations that return null pointer with success
694 if (!SUCCEEDED(hr) || !pEnumIDList)
695 {
696 ERR("Can't enum the folder !\n");
697 return FALSE;
698 }
699
700 /* Don't redraw while we add stuff into the tree */
702 while(SUCCEEDED(pEnumIDList->Next(1, &pidlSub, &fetched)) && pidlSub && fetched)
703 {
704 LPITEMIDLIST pidlSubComplete;
705 pidlSubComplete = ILCombine(entry, pidlSub);
706
707 if (InsertItem(hItem, pFolder, pidlSubComplete, pidlSub, FALSE))
708 uItemCount++;
709 ILFree(pidlSubComplete);
710 ILFree(pidlSub);
711 }
712 pNodeInfo->expanded = TRUE;
713 /* Let's do sorting */
714 sortCallback.hParent = hItem;
715 sortCallback.lpfnCompare = CompareTreeItems;
716 sortCallback.lParam = (LPARAM)this;
717 SendMessage(TVM_SORTCHILDRENCB, 0, (LPARAM)&sortCallback);
718
719 /* Now we can redraw */
721
722 return (uItemCount > 0) ? TRUE : FALSE;
723}
724
734 BOOL bSelect)
735{
737 HTREEITEM tmp;
739 NodeInfo *nodeData;
740 LPITEMIDLIST relativeChild;
741 TVITEM tvItem;
742
743 if (!item)
744 return FALSE;
745
747 parent = NULL;
748 while (TRUE)
749 {
750 nodeData = GetNodeInfo(current);
751 if (!nodeData)
752 {
753 ERR("Something has gone wrong, no data associated to node !\n");
754 *item = NULL;
755 return FALSE;
756 }
757 // If we found our node, give it back
758 if (!m_pDesktop->CompareIDs(0, nodeData->absolutePidl, dest))
759 {
760 if (bSelect)
762 *item = current;
763 return TRUE;
764 }
765
766 // Check if we are a parent of the requested item
767 relativeChild = ILFindChild(nodeData->absolutePidl, dest);
768 if (relativeChild != 0)
769 {
770 // Notify treeview we have children
771 tvItem.mask = TVIF_CHILDREN;
772 tvItem.hItem = current;
773 tvItem.cChildren = 1;
774 TreeView_SetItem(m_hWnd, &tvItem);
775
776 // If we can expand and the node isn't expanded yet, do it
777 if (bExpand)
778 {
779 if (!nodeData->expanded)
780 InsertSubitems(current, nodeData);
782 }
783
784 // Try to get a child
785 tmp = TreeView_GetChild(m_hWnd, current);
786 if (tmp)
787 {
788 // We have a child, let's continue with it
789 parent = current;
790 current = tmp;
791 continue;
792 }
793
794 if (bInsert && nodeData->expanded)
795 {
796 // Happens when we have to create a subchild inside a child
797 current = InsertItem(current, dest, relativeChild, TRUE);
798 }
799 // We end up here, without any children, so we found nothing
800 // Tell the parent node it has children
801 ZeroMemory(&tvItem, sizeof(tvItem));
802 *item = NULL;
803 return FALSE;
804 }
805
806 // Find sibling
807 tmp = TreeView_GetNextSibling(m_hWnd, current);
808 if (tmp)
809 {
810 current = tmp;
811 continue;
812 }
813 if (bInsert)
814 {
816 *item = current;
817 return TRUE;
818 }
819 *item = NULL;
820 return FALSE;
821 }
823}
824
826{
827 LPITEMIDLIST explorerPidl;
828 CComPtr<IBrowserService> pBrowserService;
829 HRESULT hr;
831 BOOL result;
832 explorerPidl = NULL;
833
834 hr = IUnknown_QueryService(m_pSite, SID_STopLevelBrowser, IID_PPV_ARG(IBrowserService, &pBrowserService));
835 if (!SUCCEEDED(hr))
836 {
837 ERR("Can't get IBrowserService !\n");
838 return FALSE;
839 }
840
841 hr = pBrowserService->GetPidl(&explorerPidl);
842 if (!SUCCEEDED(hr) || !explorerPidl)
843 {
844 ERR("Unable to get browser PIDL !\n");
845 return FALSE;
846 }
848 /* find PIDL into our explorer */
849 result = NavigateToPIDL(explorerPidl, &dummy, TRUE, FALSE, TRUE);
851 return result;
852}
853
855{
856 HTREEITEM toDelete;
857 TVITEM tvItem;
858 HTREEITEM parentNode;
859
860 if (!NavigateToPIDL(idl, &toDelete, FALSE, FALSE, FALSE))
861 return FALSE;
862
863 // TODO: check that the treeview item is really deleted
864
865 parentNode = TreeView_GetParent(m_hWnd, toDelete);
866 // Navigate to parent when deleting child item
867 if (!m_pDesktop->CompareIDs(0, idl, m_pidlCurrent))
868 {
869 TreeView_SelectItem(m_hWnd, parentNode);
870 }
871
872 // Remove the child item
873 TreeView_DeleteItem(m_hWnd, toDelete);
874 // Probe parent to see if it has children
875 if (!TreeView_GetChild(m_hWnd, parentNode))
876 {
877 // Decrement parent's child count
878 ZeroMemory(&tvItem, sizeof(tvItem));
879 tvItem.mask = TVIF_CHILDREN;
880 tvItem.hItem = parentNode;
881 tvItem.cChildren = 0;
882 TreeView_SetItem(m_hWnd, &tvItem);
883 }
884 return TRUE;
885}
886
888{
889 WCHAR wszDisplayName[MAX_PATH];
890 TVITEM itemInfo;
891 LPCITEMIDLIST relPidl;
892 NodeInfo *treeInfo;
893 TVSORTCB sortCallback;
895
896 ZeroMemory(&itemInfo, sizeof(itemInfo));
897 itemInfo.mask = TVIF_PARAM;
898 itemInfo.hItem = toRename;
899
900 // Change PIDL associated to the item
901 relPidl = ILFindLastID(newPidl);
902 TreeView_GetItem(m_hWnd, &itemInfo);
903 if (!itemInfo.lParam)
904 {
905 ERR("Unable to fetch lParam\n");
906 return FALSE;
907 }
909 treeInfo = (NodeInfo*)itemInfo.lParam;
910 ILFree(treeInfo->absolutePidl);
911 ILFree(treeInfo->relativePidl);
912 treeInfo->absolutePidl = ILClone(newPidl);
913 treeInfo->relativePidl = ILClone(relPidl);
914
915 // Change the display name
916 GetDisplayName(newPidl, wszDisplayName, MAX_PATH, SHGDN_INFOLDER);
917 ZeroMemory(&itemInfo, sizeof(itemInfo));
918 itemInfo.hItem = toRename;
919 itemInfo.mask = TVIF_TEXT;
920 itemInfo.pszText = wszDisplayName;
921 TreeView_SetItem(m_hWnd, &itemInfo);
922
923 if((child = TreeView_GetChild(m_hWnd, toRename)) != NULL)
924 {
925 RefreshTreePidl(child, newPidl);
926 }
927
928 // Sorting
929 sortCallback.hParent = TreeView_GetParent(m_hWnd, toRename);
930 sortCallback.lpfnCompare = CompareTreeItems;
931 sortCallback.lParam = (LPARAM)this;
932 SendMessage(TVM_SORTCHILDRENCB, 0, (LPARAM)&sortCallback);
934 return TRUE;
935}
936
938{
939 HTREEITEM tmp;
940 NodeInfo *pInfo;
941
942 // Update our node data
943 pInfo = GetNodeInfo(tree);
944 if (!pInfo)
945 {
946 WARN("No tree info !\n");
947 return FALSE;
948 }
949 ILFree(pInfo->absolutePidl);
950 pInfo->absolutePidl = ILCombine(pidlParent, pInfo->relativePidl);
951 if (!pInfo->absolutePidl)
952 {
953 WARN("PIDL allocation failed\n");
954 return FALSE;
955 }
956 // Recursively update children
957 if ((tmp = TreeView_GetChild(m_hWnd, tree)) != NULL)
958 {
959 RefreshTreePidl(tmp, pInfo->absolutePidl);
960 }
961
962 tmp = TreeView_GetNextSibling(m_hWnd, tree);
963 while(tmp != NULL)
964 {
965 pInfo = GetNodeInfo(tmp);
966 if(!pInfo)
967 {
968 WARN("No tree info !\n");
969 continue;
970 }
971 ILFree(pInfo->absolutePidl);
972 pInfo->absolutePidl = ILCombine(pidlParent, pInfo->relativePidl);
973 tmp = TreeView_GetNextSibling(m_hWnd, tmp);
974 }
975 return TRUE;
976}
977
978// *** Tree item sorting callback ***
980{
981 /*
982 * We first sort drive letters (Path root), then PIDLs and then regular folder
983 * display name.
984 * This is not how Windows sorts item, but it gives decent results.
985 */
986 NodeInfo *info1;
987 NodeInfo *info2;
988 CExplorerBand *pThis;
989 WCHAR wszFolder1[MAX_PATH];
990 WCHAR wszFolder2[MAX_PATH];
991
992 info1 = (NodeInfo*)p1;
993 info2 = (NodeInfo*)p2;
994 pThis = (CExplorerBand*)p3;
995
996 GetDisplayName(info1->absolutePidl, wszFolder1, MAX_PATH, SHGDN_FORPARSING);
997 GetDisplayName(info2->absolutePidl, wszFolder2, MAX_PATH, SHGDN_FORPARSING);
998 if (PathIsRoot(wszFolder1) && PathIsRoot(wszFolder2))
999 {
1000 return lstrcmpiW(wszFolder1,wszFolder2);
1001 }
1002 if (PathIsRoot(wszFolder1) && !PathIsRoot(wszFolder2))
1003 {
1004 return -1;
1005 }
1006 if (!PathIsRoot(wszFolder1) && PathIsRoot(wszFolder2))
1007 {
1008 return 1;
1009 }
1010 // Now, we compare non-root folders, grab display name
1011 GetDisplayName(info1->absolutePidl, wszFolder1, MAX_PATH, SHGDN_INFOLDER);
1012 GetDisplayName(info2->absolutePidl, wszFolder2, MAX_PATH, SHGDN_INFOLDER);
1013
1015 {
1016 return -1;
1017 }
1019 {
1020 return 1;
1021 }
1023 {
1024 HRESULT hr;
1025 hr = pThis->m_pDesktop->CompareIDs(0, info1->absolutePidl, info2->absolutePidl);
1026 if (!hr) return 0;
1027 return (hr > 0) ? -1 : 1;
1028 }
1029 return StrCmpLogicalW(wszFolder1, wszFolder2);
1030}
1031
1032// *** IOleWindow methods ***
1034{
1035 if (!lphwnd)
1036 return E_INVALIDARG;
1037 *lphwnd = m_hWnd;
1038 return S_OK;
1039}
1040
1042{
1044 return E_NOTIMPL;
1045}
1046
1047
1048// *** IDockingWindow methods ***
1050{
1051 // We do nothing, we don't have anything to save yet
1052 TRACE("CloseDW called\n");
1053 return S_OK;
1054}
1055
1056HRESULT STDMETHODCALLTYPE CExplorerBand::ResizeBorderDW(const RECT *prcBorder, IUnknown *punkToolbarSite, BOOL fReserved)
1057{
1058 /* Must return E_NOTIMPL according to MSDN */
1059 return E_NOTIMPL;
1060}
1061
1063{
1064 m_fVisible = fShow;
1065 ShowWindow(fShow);
1066 return S_OK;
1067}
1068
1069
1070// *** IDeskBand methods ***
1072{
1073 if (!pdbi)
1074 {
1075 return E_INVALIDARG;
1076 }
1077 this->m_dwBandID = dwBandID;
1078
1079 if (pdbi->dwMask & DBIM_MINSIZE)
1080 {
1081 pdbi->ptMinSize.x = 200;
1082 pdbi->ptMinSize.y = 30;
1083 }
1084
1085 if (pdbi->dwMask & DBIM_MAXSIZE)
1086 {
1087 pdbi->ptMaxSize.y = -1;
1088 }
1089
1090 if (pdbi->dwMask & DBIM_INTEGRAL)
1091 {
1092 pdbi->ptIntegral.y = 1;
1093 }
1094
1095 if (pdbi->dwMask & DBIM_ACTUAL)
1096 {
1097 pdbi->ptActual.x = 200;
1098 pdbi->ptActual.y = 30;
1099 }
1100
1101 if (pdbi->dwMask & DBIM_TITLE)
1102 {
1103 if (!LoadStringW(_AtlBaseModule.GetResourceInstance(), IDS_FOLDERSLABEL, pdbi->wszTitle, _countof(pdbi->wszTitle)))
1105 }
1106
1107 if (pdbi->dwMask & DBIM_MODEFLAGS)
1108 {
1109 pdbi->dwModeFlags = DBIMF_NORMAL | DBIMF_VARIABLEHEIGHT;
1110 }
1111
1112 if (pdbi->dwMask & DBIM_BKCOLOR)
1113 {
1114 pdbi->dwMask &= ~DBIM_BKCOLOR;
1115 }
1116 return S_OK;
1117}
1118
1119
1120// *** IObjectWithSite methods ***
1122{
1123 HRESULT hr;
1124 HWND parentWnd;
1125
1126 if (pUnkSite == m_pSite)
1127 return S_OK;
1128
1129 TRACE("SetSite called \n");
1130 if (!pUnkSite)
1131 {
1133 DestroyWindow();
1134 m_hWnd = NULL;
1135 }
1136
1137 if (pUnkSite != m_pSite)
1138 {
1139 m_pSite = NULL;
1140 }
1141
1142 if(!pUnkSite)
1143 return S_OK;
1144
1145 hr = IUnknown_GetWindow(pUnkSite, &parentWnd);
1146 if (!SUCCEEDED(hr))
1147 {
1148 ERR("Could not get parent's window ! Status: %08lx\n", hr);
1149 return E_INVALIDARG;
1150 }
1151
1152 m_pSite = pUnkSite;
1153
1154 if (m_hWnd)
1155 {
1156 // Change its parent
1157 SetParent(parentWnd);
1158 }
1159 else
1160 {
1162 WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | TVS_HASLINES | TVS_HASBUTTONS | TVS_SHOWSELALWAYS | TVS_EDITLABELS /* | TVS_SINGLEEXPAND*/ , // remove TVS_SINGLEEXPAND for now since it has strange behaviour
1163 0, 0, 0, 0, parentWnd, NULL, _AtlBaseModule.GetModuleInstance(), NULL);
1164
1165 // Subclass the window
1166 SubclassWindow(wnd);
1167
1168 // Initialize our treeview now
1170 RegisterDragDrop(m_hWnd, dynamic_cast<IDropTarget*>(this));
1171 }
1172 return S_OK;
1173}
1174
1176{
1177 if (!ppvSite)
1178 return E_POINTER;
1179 *ppvSite = m_pSite;
1180 return S_OK;
1181}
1182
1183
1184// *** IOleCommandTarget methods ***
1185HRESULT STDMETHODCALLTYPE CExplorerBand::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText)
1186{
1188 return E_NOTIMPL;
1189}
1190
1191HRESULT STDMETHODCALLTYPE CExplorerBand::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
1192{
1194 return E_NOTIMPL;
1195}
1196
1197
1198// *** IServiceProvider methods ***
1200{
1201 /* FIXME: we probably want to handle more services here */
1203}
1204
1205
1206// *** IInputObject methods ***
1208{
1209 if (fActivate)
1210 {
1211 //SetFocus();
1213 }
1214 // TODO: handle message
1215 if(lpMsg)
1216 {
1217 TranslateMessage(lpMsg);
1218 DispatchMessage(lpMsg);
1219 }
1220 return S_OK;
1221}
1222
1224{
1225 return m_bFocused ? S_OK : S_FALSE;
1226}
1227
1229{
1230 if (lpMsg->hwnd == m_hWnd ||
1231 (m_isEditing && IsChild(lpMsg->hwnd)))
1232 {
1233 TranslateMessage(lpMsg);
1234 DispatchMessage(lpMsg);
1235 return S_OK;
1236 }
1237
1238 return S_FALSE;
1239}
1240
1241// *** IPersist methods ***
1243{
1244 if (!pClassID)
1245 return E_POINTER;
1246 memcpy(pClassID, &CLSID_ExplorerBand, sizeof(CLSID));
1247 return S_OK;
1248}
1249
1250
1251// *** IPersistStream methods ***
1253{
1255 return E_NOTIMPL;
1256}
1257
1259{
1261 return E_NOTIMPL;
1262}
1263
1265{
1267 return E_NOTIMPL;
1268}
1269
1271{
1272 // TODO: calculate max size
1274 return E_NOTIMPL;
1275}
1276
1277
1278// *** IWinEventHandler methods ***
1280{
1281 BOOL bHandled;
1283
1284 if (uMsg == WM_NOTIFY)
1285 {
1286 NMHDR *pNotifyHeader = (NMHDR*)lParam;
1287 switch (pNotifyHeader->code)
1288 {
1289 case TVN_ITEMEXPANDING:
1291 if (theResult)
1292 *theResult = result;
1293 break;
1294 case TVN_SELCHANGED:
1296 break;
1297 case TVN_DELETEITEM:
1299 break;
1300 case NM_RCLICK:
1301 OnContextMenu(WM_CONTEXTMENU, (WPARAM)m_hWnd, GetMessagePos(), bHandled);
1302 if (theResult)
1303 *theResult = 1;
1304 break;
1305 case TVN_BEGINDRAG:
1306 case TVN_BEGINRDRAG:
1308 break;
1310 {
1311 // TODO: put this in a function ? (mostly copypasta from CDefView)
1312 DWORD dwAttr = SFGAO_CANRENAME;
1315 LPCITEMIDLIST pChild;
1316 HRESULT hr;
1317
1318 if (theResult)
1319 *theResult = 1;
1320 NodeInfo *info = GetNodeInfo(dispInfo->item.hItem);
1321 if (!info)
1322 return E_FAIL;
1323 hr = SHBindToParent(info->absolutePidl, IID_PPV_ARG(IShellFolder, &pParent), &pChild);
1324 if (!SUCCEEDED(hr) || !pParent.p)
1325 return E_FAIL;
1326
1327 hr = pParent->GetAttributesOf(1, &pChild, &dwAttr);
1328 if (SUCCEEDED(hr) && (dwAttr & SFGAO_CANRENAME))
1329 {
1330 if (theResult)
1331 *theResult = 0;
1332 m_isEditing = TRUE;
1333 }
1334 return S_OK;
1335 }
1336 case TVN_ENDLABELEDITW:
1337 {
1339 NodeInfo *info = GetNodeInfo(dispInfo->item.hItem);
1340 HRESULT hr;
1341
1343 if (theResult)
1344 *theResult = 0;
1345 if (dispInfo->item.pszText)
1346 {
1347 LPITEMIDLIST pidlNew;
1349 LPCITEMIDLIST pidlChild;
1350
1351 hr = SHBindToParent(info->absolutePidl, IID_PPV_ARG(IShellFolder, &pParent), &pidlChild);
1352 if (!SUCCEEDED(hr) || !pParent.p)
1353 return E_FAIL;
1354
1355 hr = pParent->SetNameOf(0, pidlChild, dispInfo->item.pszText, SHGDN_INFOLDER, &pidlNew);
1356 if(SUCCEEDED(hr) && pidlNew)
1357 {
1358 CComPtr<IPersistFolder2> pPersist;
1359 LPITEMIDLIST pidlParent, pidlNewAbs;
1360
1362 if(!SUCCEEDED(hr))
1363 return E_FAIL;
1364
1365 hr = pPersist->GetCurFolder(&pidlParent);
1366 if(!SUCCEEDED(hr))
1367 return E_FAIL;
1368 pidlNewAbs = ILCombine(pidlParent, pidlNew);
1369
1370 // Navigate to our new location
1371 UpdateBrowser(pidlNewAbs);
1372
1373 ILFree(pidlParent);
1374 ILFree(pidlNewAbs);
1375 ILFree(pidlNew);
1376 if (theResult)
1377 *theResult = 1;
1378 }
1379 return S_OK;
1380 }
1381 }
1382 default:
1383 break;
1384 }
1385 }
1386 return S_OK;
1387}
1388
1390{
1391 return (hWnd == m_hWnd) ? S_OK : S_FALSE;
1392}
1393
1394// *** IBandNavigate methods ***
1396{
1398 return E_NOTIMPL;
1399}
1400
1401// *** INamespaceProxy ***
1402HRESULT STDMETHODCALLTYPE CExplorerBand::GetNavigateTarget(long paramC, long param10, long param14)
1403{
1405 return E_NOTIMPL;
1406}
1407
1409{
1411 return E_NOTIMPL;
1412}
1413
1415{
1417 return E_NOTIMPL;
1418}
1419
1420HRESULT STDMETHODCALLTYPE CExplorerBand::RefreshFlags(long paramC, long param10, long param14)
1421{
1423 return E_NOTIMPL;
1424}
1425
1427{
1429 return E_NOTIMPL;
1430}
1431
1432// *** IDispatch methods ***
1434{
1436 return E_NOTIMPL;
1437}
1438
1440{
1442 return E_NOTIMPL;
1443}
1444
1446{
1448 return E_NOTIMPL;
1449}
1450
1451HRESULT STDMETHODCALLTYPE CExplorerBand::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1452{
1453 switch (dispIdMember)
1454 {
1457 TRACE("DISPID_NAVIGATECOMPLETE2 received\n");
1459 return S_OK;
1460 }
1461 TRACE("Unknown dispid requested: %08x\n", dispIdMember);
1462 return E_INVALIDARG;
1463}
1464
1465// *** IDropTarget methods ***
1467{
1468 ERR("Entering drag\n");
1469 m_pCurObject = pObj;
1471 return DragOver(glfKeyState, pt, pdwEffect);
1472}
1473
1475{
1477 CComPtr<IShellFolder> pShellFldr;
1478 NodeInfo *nodeInfo;
1479 //LPCITEMIDLIST pChild;
1480 HRESULT hr;
1481
1482 info.pt.x = pt.x;
1483 info.pt.y = pt.y;
1484 info.flags = TVHT_ONITEM;
1485 info.hItem = NULL;
1486 ScreenToClient(&info.pt);
1487
1488 // Move to the item selected by the treeview (don't change right pane)
1489 TreeView_HitTest(m_hWnd, &info);
1490
1491 if (info.hItem)
1492 {
1494 TreeView_SelectItem(m_hWnd, info.hItem);
1496 // Delegate to shell folder
1497 if (m_pDropTarget && info.hItem != m_childTargetNode)
1498 {
1500 }
1501 if (info.hItem != m_childTargetNode)
1502 {
1503 nodeInfo = GetNodeInfo(info.hItem);
1504 if (!nodeInfo)
1505 return E_FAIL;
1506#if 0
1507 hr = SHBindToParent(nodeInfo->absolutePidl, IID_PPV_ARG(IShellFolder, &pShellFldr), &pChild);
1508 if (!SUCCEEDED(hr))
1509 return E_FAIL;
1510 hr = pShellFldr->GetUIObjectOf(m_hWnd, 1, &pChild, IID_IDropTarget, NULL, reinterpret_cast<void**>(&pDropTarget));
1511 if (!SUCCEEDED(hr))
1512 return E_FAIL;
1513#endif
1514 if(_ILIsDesktop(nodeInfo->absolutePidl))
1515 pShellFldr = m_pDesktop;
1516 else
1517 {
1518 hr = m_pDesktop->BindToObject(nodeInfo->absolutePidl, 0, IID_PPV_ARG(IShellFolder, &pShellFldr));
1519 if (!SUCCEEDED(hr))
1520 {
1521 /* Don't allow dnd since we couldn't get our folder object */
1522 ERR("Can't bind to folder object\n");
1523 *pdwEffect = DROPEFFECT_NONE;
1524 return E_FAIL;
1525 }
1526 }
1527 hr = pShellFldr->CreateViewObject(m_hWnd, IID_PPV_ARG(IDropTarget, &m_pDropTarget));
1528 if (!SUCCEEDED(hr))
1529 {
1530 /* Don't allow dnd since we couldn't get our drop target */
1531 ERR("Can't get drop target for folder object\n");
1532 *pdwEffect = DROPEFFECT_NONE;
1533 return E_FAIL;
1534 }
1535 hr = m_pDropTarget->DragEnter(m_pCurObject, glfKeyState, pt, pdwEffect);
1536 m_childTargetNode = info.hItem;
1537 }
1538 if (m_pDropTarget)
1539 {
1540 hr = m_pDropTarget->DragOver(glfKeyState, pt, pdwEffect);
1541 }
1542 }
1543 else
1544 {
1547 *pdwEffect = DROPEFFECT_NONE;
1548 }
1549 return S_OK;
1550}
1551
1553{
1558 if (m_pCurObject)
1559 {
1561 }
1562 return S_OK;
1563}
1564
1566{
1567 if (!m_pDropTarget)
1568 return E_FAIL;
1569 m_pDropTarget->Drop(pObj, glfKeyState, pt, pdwEffect);
1570 DragLeave();
1571 return S_OK;
1572}
1573
1574// *** IDropSource methods ***
1576{
1577 if (fEscapePressed)
1578 return DRAGDROP_S_CANCEL;
1579 if ((grfKeyState & MK_LBUTTON) || (grfKeyState & MK_RBUTTON))
1580 return S_OK;
1581 return DRAGDROP_S_DROP;
1582}
1583
1585{
1587}
BOOL _ILIsDesktop(LPCITEMIDLIST pidl)
Definition: CBandSite.h:24
HRESULT WINAPI SHGetDesktopFolder(IShellFolder **psf)
UINT cchMax
HWND hWnd
Definition: settings.c:17
BOOL GetDisplayName(LPCTSTR ServiceName)
Definition: name.c:12
#define STDMETHODCALLTYPE
Definition: bdasup.h:9
#define UNIMPLEMENTED
Definition: debug.h:115
#define WARN(fmt,...)
Definition: debug.h:112
#define ERR(fmt,...)
Definition: debug.h:110
return
Definition: dirsup.c:529
EXTERN_C ULONG WINAPI SHChangeNotifyRegister(HWND hwnd, INT fSources, LONG wEventMask, UINT uMsg, INT cItems, SHChangeNotifyEntry *lpItems)
LPITEMIDLIST relativePidl
Definition: explorerband.h:50
LPITEMIDLIST absolutePidl
Definition: explorerband.h:49
HTREEITEM InsertItem(HTREEITEM hParent, IShellFolder *psfParent, LPITEMIDLIST pElt, LPITEMIDLIST pEltRelative, BOOL bSort)
HTREEITEM m_hRoot
Definition: explorerband.h:65
STDMETHOD() GetSite(REFIID riid, void **ppvSite) override
BOOL OnTreeItemExpanding(LPNMTREEVIEW pnmtv)
STDMETHOD() Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut) override
STDMETHOD() UIActivateIO(BOOL fActivate, LPMSG lpMsg) override
HTREEITEM m_oldSelected
Definition: explorerband.h:66
STDMETHOD() ResizeBorderDW(const RECT *prcBorder, IUnknown *punkToolbarSite, BOOL fReserved) override
void DestroyExplorerBand()
STDMETHOD() Save(IStream *pStm, BOOL fClearDirty) override
STDMETHOD() Select(long paramC) override
void OnSelectionChanged(LPNMTREEVIEW pnmtv)
STDMETHOD() IsWindowOwner(HWND hWnd) override
STDMETHOD() Invoke(long paramC) override
HRESULT ExecuteCommand(CComPtr< IContextMenu > &menu, UINT nCmd)
STDMETHOD() ShowDW(BOOL fShow) override
LRESULT OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
STDMETHOD() SetSite(IUnknown *pUnkSite) override
STDMETHOD() OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult) override
STDMETHOD() GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) override
BOOL m_bNavigating
Definition: explorerband.h:60
STDMETHOD() HasFocusIO() override
STDMETHOD() Drop(IDataObject *pObj, DWORD glfKeyState, POINTL pt, DWORD *pdwEffect) override
void InitializeExplorerBand()
STDMETHOD() CloseDW(DWORD dwReserved) override
STDMETHOD() IsDirty() override
HTREEITEM m_childTargetNode
Definition: explorerband.h:75
STDMETHOD() GetWindow(HWND *lphwnd) override
DWORD m_dwBandID
Definition: explorerband.h:62
static int CALLBACK CompareTreeItems(LPARAM p1, LPARAM p2, LPARAM p3)
STDMETHOD() TranslateAcceleratorIO(LPMSG lpMsg) override
STDMETHOD() RefreshFlags(long paramC, long param10, long param14) override
STDMETHOD() Load(IStream *pStm) override
STDMETHOD() GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) override
BOOL DeleteItem(LPITEMIDLIST toDelete)
HRESULT UpdateBrowser(LPITEMIDLIST pidlGoto)
BOOL NavigateToCurrentFolder()
STDMETHOD() CacheItem(long paramC) override
STDMETHOD() GetSizeMax(ULARGE_INTEGER *pcbSize) override
STDMETHOD() GetTypeInfoCount(UINT *pctinfo) override
LPITEMIDLIST m_pidlCurrent
Definition: explorerband.h:67
STDMETHOD() QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText) override
STDMETHOD() GetBandInfo(DWORD dwBandID, DWORD dwViewMode, DESKBANDINFO *pdbi) override
STDMETHOD() QueryService(REFGUID guidService, REFIID riid, void **ppvObject) override
CComPtr< IDataObject > m_pCurObject
Definition: explorerband.h:76
void OnTreeItemDragging(LPNMTREEVIEW pnmtv, BOOL isRightClick)
CComPtr< IUnknown > m_pSite
Definition: explorerband.h:55
DWORD m_adviseCookie
Definition: explorerband.h:70
BOOL RefreshTreePidl(HTREEITEM tree, LPITEMIDLIST pidlParent)
LRESULT OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
NodeInfo * GetNodeInfo(HTREEITEM hItem)
STDMETHOD() QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState) override
BOOL NavigateToPIDL(LPITEMIDLIST dest, HTREEITEM *item, BOOL bExpand, BOOL bInsert, BOOL bSelect)
STDMETHOD() ContextSensitiveHelp(BOOL fEnterMode) override
STDMETHOD() GiveFeedback(DWORD dwEffect) override
LRESULT OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
LRESULT ContextMenuHack(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
CComPtr< IShellFolder > m_pDesktop
Definition: explorerband.h:56
BOOL OnTreeItemDeleted(LPNMTREEVIEW pnmtv)
CComPtr< IDropTarget > m_pDropTarget
Definition: explorerband.h:74
STDMETHOD() DragOver(DWORD glfKeyState, POINTL pt, DWORD *pdwEffect) override
ULONG m_shellRegID
Definition: explorerband.h:71
STDMETHOD() DragEnter(IDataObject *pObj, DWORD glfKeyState, POINTL pt, DWORD *pdwEffect) override
STDMETHOD() GetClassID(CLSID *pClassID) override
LRESULT OnShellEvent(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
BOOL InsertSubitems(HTREEITEM hItem, NodeInfo *pNodeInfo)
virtual ~CExplorerBand()
STDMETHOD() GetNavigateTarget(long paramC, long param10, long param14) override
BOOL RenameItem(HTREEITEM toRename, LPITEMIDLIST newPidl)
STDMETHOD() DragLeave() override
virtual _Must_inspect_result_ NTSTATUS QueryInterface(__in FxQueryInterfaceParams *Params)
Definition: fxobject.cpp:255
static BOOL bInsert
Definition: cmdinput.c:121
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
#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
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
UINT uFlags
Definition: api.c:59
#define IDS_FOLDERSLABEL
Definition: resource.h:127
#define MAX_PATH
Definition: compat.h:34
#define CALLBACK
Definition: compat.h:35
#define FAILED_UNEXPECTEDLY(hr)
Definition: precomp.h:121
HRESULT WINAPI RegisterDragDrop(HWND hwnd, LPDROPTARGET pDropTarget)
Definition: ole2.c:557
HRESULT WINAPI DoDragDrop(IDataObject *pDataObject, IDropSource *pDropSource, DWORD dwOKEffect, DWORD *pdwEffect)
Definition: ole2.c:753
HRESULT WINAPI RevokeDragDrop(HWND hwnd)
Definition: ole2.c:639
HRESULT WINAPI SHGetFolderLocation(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwReserved, LPITEMIDLIST *ppidl)
Definition: shellpath.c:3124
HRESULT WINAPI IUnknown_QueryService(IUnknown *, REFGUID, REFIID, LPVOID *)
Definition: ordinal.c:1497
HRESULT WINAPI IUnknown_GetWindow(IUnknown *lpUnknown, HWND *lphWnd)
Definition: ordinal.c:1332
HRESULT WINAPI IUnknown_OnFocusChangeIS(LPUNKNOWN lpUnknown, LPUNKNOWN pFocusObject, BOOL bFocus)
Definition: ordinal.c:4767
HRESULT WINAPI IUnknown_SetSite(IUnknown *obj, IUnknown *site)
Definition: ordinal.c:1407
INT WINAPI StrCmpLogicalW(LPCWSTR lpszStr, LPCWSTR lpszComp)
Definition: string.c:2304
HRESULT WINAPI StrRetToBufW(LPSTRRET src, const ITEMIDLIST *pidl, LPWSTR dest, UINT len)
Definition: string.c:1530
static const WCHAR Cleanup[]
Definition: register.c:80
#define pt(x, y)
Definition: drawing.c:79
r parent
Definition: btrfs.c:3010
static IShellFolder IShellItem **static IBindCtx LPITEMIDLIST SFGAOF
Definition: ebrowser.c:83
struct _PIDLDATA * LPPIDLDATA
struct _PIDLDATA PIDLDATA
#define PT_GUID
HRESULT _ReparsePIDL(LPITEMIDLIST buggyPidl, LPITEMIDLIST *cleanPidl)
HRESULT GetDisplayName(LPCITEMIDLIST pidlDirectory, TCHAR *szDisplayName, UINT cchMax, DWORD uFlags)
static BOOL _ILIsSpecialFolder(LPCITEMIDLIST pidl)
#define PT_YAGUID
#define PT_SHELLEXT
#define WM_USER_SHELLEVENT
Definition: explorerband.h:24
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
FxObject * pParent
Definition: fxdpcapi.cpp:86
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLuint64EXT * result
Definition: glext.h:11304
int WINAPI SHMapPIDLToSystemImageListIndex(IShellFolder *sh, LPCITEMIDLIST pidl, int *pIndex)
Definition: iconcache.cpp:766
REFIID riid
Definition: atlbase.h:39
const DWORD DROPEFFECT_NONE
Definition: oleidl.idl:929
const DWORD DROPEFFECT_LINK
Definition: oleidl.idl:932
const DWORD DROPEFFECT_COPY
Definition: oleidl.idl:930
const DWORD DROPEFFECT_MOVE
Definition: oleidl.idl:931
HRESULT GetDisplayNameOf([in] PCUITEMID_CHILD pidl, [in] SHGDNF uFlags, [out] STRRET *lpName)
HRESULT GetAttributesOf([in] UINT cidl, [in, size_is(cidl)] PCUITEMID_CHILD_ARRAY apidl, [in, out] SFGAOF *rgfInOut)
ULONG Release()
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
uint32_t entry
Definition: isohybrid.c:63
int WINAPI lstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:194
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
struct task_struct * current
Definition: linux.c:32
static PVOID ptr
Definition: dispmode.c:27
static char * dest
Definition: rtl.c:135
static LPOLESTR
Definition: stg_prop.c:27
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:63
static SHCONTF
Definition: ordinal.c:64
static VARIANTARG static DISPID
Definition: ordinal.c:52
static HWND child
Definition: cursoricon.c:298
static ATOM item
Definition: dde.c:856
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED _In_opt_ LPTRANSMIT_FILE_BUFFERS _In_ DWORD dwReserved
Definition: mswsock.h:95
unsigned int UINT
Definition: ndis.h:50
#define UNREACHABLE
const GUID IID_IDataObject
#define LOWORD(l)
Definition: pedump.c:82
#define WS_CHILD
Definition: pedump.c:617
#define WS_CLIPSIBLINGS
Definition: pedump.c:618
#define WS_CLIPCHILDREN
Definition: pedump.c:619
LPITEMIDLIST WINAPI ILClone(LPCITEMIDLIST pidl)
Definition: pidl.c:237
void WINAPI ILFree(LPITEMIDLIST pidl)
Definition: pidl.c:938
LPITEMIDLIST WINAPI ILFindLastID(LPCITEMIDLIST pidl)
Definition: pidl.c:198
LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
Definition: pidl.c:712
HRESULT WINAPI SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCITEMIDLIST *ppidlLast)
Definition: pidl.c:1361
PUIDLIST_RELATIVE WINAPI ILFindChild(PIDLIST_ABSOLUTE pidl1, PCIDLIST_ABSOLUTE pidl2)
Definition: pidl.c:654
#define TVN_DELETEITEM
Definition: commctrl.h:3742
#define TVITEM
Definition: commctrl.h:3365
#define TVN_SELCHANGED
Definition: commctrl.h:3735
#define TVN_BEGINDRAG
Definition: commctrl.h:3740
#define TVI_LAST
Definition: commctrl.h:3370
#define TreeView_DeleteAllItems(hwnd)
Definition: commctrl.h:3417
#define TVM_SORTCHILDRENCB
Definition: commctrl.h:3547
#define TVIF_TEXT
Definition: commctrl.h:3266
#define TreeView_SelectItem(hwnd, hitem)
Definition: commctrl.h:3481
#define TVHT_ONITEM
Definition: commctrl.h:3527
#define TreeView_Expand(hwnd, hitem, code)
Definition: commctrl.h:3420
#define TreeView_GetChild(hwnd, hitem)
Definition: commctrl.h:3466
#define TVIF_IMAGE
Definition: commctrl.h:3267
#define TVSIL_NORMAL
Definition: commctrl.h:3443
#define LPNMTREEVIEW
Definition: commctrl.h:3643
#define TreeView_GetParent(hwnd, hitem)
Definition: commctrl.h:3469
#define TVS_SHOWSELALWAYS
Definition: commctrl.h:3252
#define TreeView_GetSelection(hwnd)
Definition: commctrl.h:3473
#define TreeView_GetItem(hwnd, pitem)
Definition: commctrl.h:3490
#define TVS_HASLINES
Definition: commctrl.h:3248
#define TVE_EXPAND
Definition: commctrl.h:3423
#define TV_INSERTSTRUCT
Definition: commctrl.h:3377
#define WC_TREEVIEW
Definition: commctrl.h:3245
#define TV_ITEM
Definition: commctrl.h:3300
#define TVN_BEGINRDRAG
Definition: commctrl.h:3741
#define TVE_COLLAPSE
Definition: commctrl.h:3422
#define TreeView_GetNextSibling(hwnd, hitem)
Definition: commctrl.h:3467
#define TVIS_EXPANDED
Definition: commctrl.h:3284
#define NM_RCLICK
Definition: commctrl.h:133
#define TVN_ITEMEXPANDING
Definition: commctrl.h:3738
#define TVS_HASBUTTONS
Definition: commctrl.h:3247
#define TVN_BEGINLABELEDITW
Definition: commctrl.h:3710
#define TVIF_PARAM
Definition: commctrl.h:3268
#define LPNMTVDISPINFO
Definition: commctrl.h:3676
#define TVS_EDITLABELS
Definition: commctrl.h:3250
#define TreeView_SetImageList(hwnd, himl, iImage)
Definition: commctrl.h:3447
#define TVIF_CHILDREN
Definition: commctrl.h:3272
#define TreeView_HitTest(hwnd, lpht)
Definition: commctrl.h:3513
#define TreeView_InsertItem(hwnd, lpis)
Definition: commctrl.h:3412
#define TVIF_SELECTEDIMAGE
Definition: commctrl.h:3271
#define TVN_ENDLABELEDITW
Definition: commctrl.h:3712
#define TreeView_SetItem(hwnd, pitem)
Definition: commctrl.h:3497
#define TVIF_STATE
Definition: commctrl.h:3269
#define TreeView_DeleteItem(hwnd, hitem)
Definition: commctrl.h:3415
#define REFIID
Definition: guiddef.h:118
#define WM_CONTEXTMENU
Definition: richedit.h:64
#define WM_NOTIFY
Definition: richedit.h:61
const WCHAR * str
DWORD LCID
Definition: nls.h:13
#define SHIL_SMALL
Definition: shellapi.h:185
HRESULT WINAPI SHGetImageList(int iImageList, REFIID riid, void **ppv)
Definition: shellord.c:2452
HRESULT hr
Definition: shlfolder.c:183
#define SID_SShellBrowser
Definition: shlguid.h:128
#define SID_SWebBrowserApp
Definition: shlguid.h:111
#define SHCNRF_RecursiveInterrupt
Definition: shlobj.h:1922
#define SHCNE_RMDIR
Definition: shlobj.h:1879
#define SHCNE_MKDIR
Definition: shlobj.h:1878
#define SHCNE_UPDATEDIR
Definition: shlobj.h:1887
#define SHCNE_RENAMEFOLDER
Definition: shlobj.h:1892
#define SHCNE_DISKEVENTS
Definition: shlobj.h:1897
#define SHCNRF_ShellLevel
Definition: shlobj.h:1921
#define CSIDL_DESKTOP
Definition: shlobj.h:2158
#define FCIDM_SHVIEWFIRST
Definition: shlobj.h:573
#define SHCNRF_InterruptLevel
Definition: shlobj.h:1920
#define SHCNE_INTERRUPT
Definition: shlobj.h:1900
#define FCIDM_SHVIEWLAST
Definition: shlobj.h:607
#define StrRetToBuf
Definition: shlwapi.h:1769
#define PathIsRoot
Definition: shlwapi.h:955
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
#define _countof(array)
Definition: sndvol32.h:68
#define TRACE(s)
Definition: solgame.cpp:4
Definition: scsiwmi.h:51
LONG y
Definition: windef.h:330
LONG x
Definition: windef.h:329
PCIDLIST_ABSOLUTE pidl
Definition: shlobj.h:1871
int cChildren
Definition: treeview.c:154
Definition: fci.c:116
WCHAR wszTitle[256]
Definition: shobjidl.idl:2422
HWND hwnd
Definition: winuser.h:3114
UINT code
Definition: winuser.h:3159
LPARAM lParam
Definition: commctrl.h:3616
HTREEITEM hParent
Definition: commctrl.h:3614
PFNTVCOMPARE lpfnCompare
Definition: commctrl.h:3615
HTREEITEM hItem
Definition: treelist.h:37
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59
#define HIWORD(l)
Definition: typedefs.h:247
#define DeleteItem
Definition: userenv.h:210
#define DISPID_NAVIGATECOMPLETE2
Definition: webchild.h:54
#define DISPID_DOWNLOADCOMPLETE
Definition: webchild.h:39
#define ZeroMemory
Definition: winbase.h:1712
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
_In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon.h:531
_In_ void _In_ PCCERT_CONTEXT _In_opt_ LPFILETIME _In_ DWORD _In_ DWORD _Outptr_opt_ void ** ppvObject
Definition: wincrypt.h:6082
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
UINT_PTR WPARAM
Definition: windef.h:207
#define SubclassWindow(hwnd, lpfn)
Definition: windowsx.h:542
#define S_FALSE
Definition: winerror.h:2357
#define DRAGDROP_S_USEDEFAULTCURSORS
Definition: winerror.h:2648
#define DRAGDROP_S_DROP
Definition: winerror.h:2646
#define DRAGDROP_S_CANCEL
Definition: winerror.h:2647
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
#define E_POINTER
Definition: winerror.h:2365
#define MK_RBUTTON
Definition: winuser.h:2368
HMENU WINAPI CreatePopupMenu(void)
Definition: menu.c:838
BOOL WINAPI TranslateMessage(_In_ const MSG *)
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
DWORD WINAPI GetMessagePos(void)
Definition: message.c:1351
#define TPM_RIGHTBUTTON
Definition: winuser.h:2380
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
HWND WINAPI SetParent(_In_ HWND, _In_opt_ HWND)
#define VK_CONTROL
Definition: winuser.h:2203
#define CreateWindow
Definition: winuser.h:5754
#define WM_RBUTTONDOWN
Definition: winuser.h:1779
HWND WINAPI SetFocus(_In_opt_ HWND)
BOOL WINAPI IsChild(_In_ HWND, _In_ HWND)
HWND WINAPI SetActiveWindow(_In_ HWND)
#define TPM_LEFTALIGN
Definition: winuser.h:2377
#define SendMessage
Definition: winuser.h:5843
#define TPM_LEFTBUTTON
Definition: winuser.h:2379
#define MAKEINTRESOURCEA(i)
Definition: winuser.h:581
BOOL WINAPI DestroyMenu(_In_ HMENU)
#define MK_LBUTTON
Definition: winuser.h:2367
#define VK_SHIFT
Definition: winuser.h:2202
BOOL WINAPI TrackPopupMenu(_In_ HMENU, _In_ UINT, _In_ int, _In_ int, _Reserved_ int, _In_ HWND, _Reserved_ LPCRECT)
#define DispatchMessage
Definition: winuser.h:5765
#define TPM_RETURNCMD
Definition: winuser.h:2387
BOOL WINAPI DestroyWindow(_In_ HWND)
SHORT WINAPI GetKeyState(_In_ int)
#define WM_SETREDRAW
Definition: winuser.h:1616
BOOL WINAPI ScreenToClient(_In_ HWND, _Inout_ LPPOINT)
#define IID_PPV_ARG(Itype, ppType)
char TCHAR
Definition: xmlstorage.h:189
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned char BYTE
Definition: xxhash.c:193