ReactOS 0.4.15-dev-5672-gf73ac17
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_pidlCurrent(NULL)
153{
154}
155
157{
158 if (m_pidlCurrent)
159 {
161 }
162}
163
165{
166 // Init the treeview here
167 HRESULT hr;
168 LPITEMIDLIST pidl;
169 CComPtr<IWebBrowser2> browserService;
171
174 return;
175
176 hr = SHGetFolderLocation(m_hWnd, CSIDL_DESKTOP, NULL, 0, &pidl);
178 return;
179
180 IImageList * piml;
183 return;
184
186
187 // Insert the root node
188 m_hRoot = InsertItem(0, m_pDesktop, pidl, pidl, FALSE);
189 if (!m_hRoot)
190 {
191 ERR("Failed to create root item\n");
192 return;
193 }
194
195 NodeInfo* pNodeInfo = GetNodeInfo(m_hRoot);
196
197 // Insert child nodes
198 InsertSubitems(m_hRoot, pNodeInfo);
200
201 // Navigate to current folder position
203
204 // Register shell notification
205 shcne.pidl = pidl;
206 shcne.fRecursive = TRUE;
208 m_hWnd,
212 1,
213 &shcne);
214 if (!m_shellRegID)
215 {
216 ERR("Something went wrong, error %08x\n", GetLastError());
217 }
218 // Register browser connection endpoint
219 hr = IUnknown_QueryService(m_pSite, SID_SWebBrowserApp, IID_PPV_ARG(IWebBrowser2, &browserService));
221 return;
222
223 hr = AtlAdvise(browserService, dynamic_cast<IDispatch*>(this), DIID_DWebBrowserEvents, &m_adviseCookie);
225 return;
226
227 ILFree(pidl);
228}
229
231{
232 HRESULT hr;
233 CComPtr <IWebBrowser2> browserService;
234
235 TRACE("Cleaning up explorer band ...\n");
236
237 hr = IUnknown_QueryService(m_pSite, SID_SWebBrowserApp, IID_PPV_ARG(IWebBrowser2, &browserService));
239 return;
240
241 hr = AtlUnadvise(browserService, DIID_DWebBrowserEvents, m_adviseCookie);
242 /* Remove all items of the treeview */
243 RevokeDragDrop(m_hWnd);
246 m_hRoot = NULL;
247 TRACE("Cleanup done !\n");
248}
249
251{
252 TVITEM tvItem;
253
254 tvItem.mask = TVIF_PARAM;
255 tvItem.hItem = hItem;
256
257 if (!TreeView_GetItem(m_hWnd, &tvItem))
258 return 0;
259
260 return reinterpret_cast<NodeInfo*>(tvItem.lParam);
261}
262
264{
265 CComPtr<IOleWindow> pBrowserOleWnd;
266 CMINVOKECOMMANDINFO cmi;
267 HWND browserWnd;
268 HRESULT hr;
269
272 return hr;
273
274 hr = pBrowserOleWnd->GetWindow(&browserWnd);
276 return hr;
277
278 ZeroMemory(&cmi, sizeof(cmi));
279 cmi.cbSize = sizeof(cmi);
280 cmi.lpVerb = MAKEINTRESOURCEA(nCmd);
281 cmi.hwnd = browserWnd;
282 if (GetKeyState(VK_SHIFT) & 0x8000)
283 cmi.fMask |= CMIC_MASK_SHIFT_DOWN;
284 if (GetKeyState(VK_CONTROL) & 0x8000)
285 cmi.fMask |= CMIC_MASK_CONTROL_DOWN;
286
287 return menu->InvokeCommand(&cmi);
288}
289
291{
292 CComPtr<IShellBrowser> pBrowserService;
293 HRESULT hr;
294
295 hr = IUnknown_QueryService(m_pSite, SID_STopLevelBrowser, IID_PPV_ARG(IShellBrowser, &pBrowserService));
297 return hr;
298
299 hr = pBrowserService->BrowseObject(pidlGoto, SBSP_SAMEBROWSER | SBSP_ABSOLUTE);
301 return hr;
302
303 if (m_pidlCurrent)
304 {
306 m_pidlCurrent = ILClone(pidlGoto);
307 }
308 return hr;
309}
310
311// *** notifications handling ***
313{
314 NodeInfo *pNodeInfo;
315
316 if (pnmtv->action == TVE_COLLAPSE) {
317 if (pnmtv->itemNew.hItem == m_hRoot)
318 {
319 // Prenvent root from collapsing
320 pnmtv->itemNew.mask |= TVIF_STATE;
321 pnmtv->itemNew.stateMask |= TVIS_EXPANDED;
322 pnmtv->itemNew.state &= ~TVIS_EXPANDED;
323 pnmtv->action = TVE_EXPAND;
324 return TRUE;
325 }
326 }
327 if (pnmtv->action == TVE_EXPAND) {
328 // Grab our directory PIDL
329 pNodeInfo = GetNodeInfo(pnmtv->itemNew.hItem);
330 // We have it, let's try
331 if (pNodeInfo && !pNodeInfo->expanded)
332 if (!InsertSubitems(pnmtv->itemNew.hItem, pNodeInfo)) {
333 // remove subitem "+" since we failed to add subitems
334 TV_ITEM tvItem;
335
336 tvItem.mask = TVIF_CHILDREN;
337 tvItem.hItem = pnmtv->itemNew.hItem;
338 tvItem.cChildren = 0;
339
340 TreeView_SetItem(m_hWnd, &tvItem);
341 }
342 }
343 return FALSE;
344}
345
347{
348 /* Destroy memory associated to our node */
349 NodeInfo* ptr = GetNodeInfo(pnmtv->itemNew.hItem);
350 if (ptr)
351 {
352 ILFree(ptr->relativePidl);
353 ILFree(ptr->absolutePidl);
354 delete ptr;
355 }
356 return TRUE;
357}
358
360{
361 NodeInfo* pNodeInfo = GetNodeInfo(pnmtv->itemNew.hItem);
362
363 /* Prevents navigation if selection is initiated inside the band */
364 if (m_bNavigating)
365 return;
366
367 UpdateBrowser(pNodeInfo->absolutePidl);
368
369 SetFocus();
370 // Expand the node
371 //TreeView_Expand(m_hWnd, pnmtv->itemNew.hItem, TVE_EXPAND);
372}
373
375{
376 CComPtr<IShellFolder> pSrcFolder;
378 LPCITEMIDLIST pLast;
379 HRESULT hr;
380 DWORD dwEffect;
381 DWORD dwEffect2;
382
383 dwEffect = DROPEFFECT_COPY | DROPEFFECT_MOVE;
384 if (!pnmtv->itemNew.lParam)
385 return;
386 NodeInfo* pNodeInfo = GetNodeInfo(pnmtv->itemNew.hItem);
387 hr = SHBindToParent(pNodeInfo->absolutePidl, IID_PPV_ARG(IShellFolder, &pSrcFolder), &pLast);
388 if (!SUCCEEDED(hr))
389 return;
390 hr = pSrcFolder->GetUIObjectOf(m_hWnd, 1, &pLast, IID_IDataObject, 0, reinterpret_cast<void**>(&pObj));
391 if (!SUCCEEDED(hr))
392 return;
393 DoDragDrop(pObj, this, dwEffect, &dwEffect2);
394 return;
395}
396
397
398// *** ATL event handlers ***
400{
402 NodeInfo *info;
403 HMENU treeMenu;
404 WORD x;
405 WORD y;
406 CComPtr<IShellFolder> pFolder;
407 CComPtr<IContextMenu> contextMenu;
408 HRESULT hr;
409 UINT uCommand;
410 LPITEMIDLIST pidlChild;
411
412 treeMenu = NULL;
413 item = TreeView_GetSelection(m_hWnd);
414 bHandled = TRUE;
415 if (!item)
416 {
417 goto Cleanup;
418 }
419
420 x = LOWORD(lParam);
421 y = HIWORD(lParam);
422 if (x == -1 && y == -1)
423 {
424 // TODO: grab position of tree item and position it correctly
425 }
426
428 if (!info)
429 {
430 ERR("No node data, something has gone wrong !\n");
431 goto Cleanup;
432 }
433 hr = SHBindToParent(info->absolutePidl, IID_PPV_ARG(IShellFolder, &pFolder),
434 (LPCITEMIDLIST*)&pidlChild);
435 if (!SUCCEEDED(hr))
436 {
437 ERR("Can't bind to folder!\n");
438 goto Cleanup;
439 }
440 hr = pFolder->GetUIObjectOf(m_hWnd, 1, (LPCITEMIDLIST*)&pidlChild, IID_IContextMenu,
441 NULL, reinterpret_cast<void**>(&contextMenu));
442 if (!SUCCEEDED(hr))
443 {
444 ERR("Can't get IContextMenu interface\n");
445 goto Cleanup;
446 }
447
448 IUnknown_SetSite(contextMenu, (IDeskBand *)this);
449
450 treeMenu = CreatePopupMenu();
451 hr = contextMenu->QueryContextMenu(treeMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST,
452 CMF_EXPLORE);
453 if (!SUCCEEDED(hr))
454 {
455 WARN("Can't get context menu for item\n");
456 DestroyMenu(treeMenu);
457 goto Cleanup;
458 }
460 x, y, 0, m_hWnd, NULL);
461
462 ExecuteCommand(contextMenu, uCommand);
463
464Cleanup:
465 if (contextMenu)
466 IUnknown_SetSite(contextMenu, NULL);
467 if (treeMenu)
468 DestroyMenu(treeMenu);
472 return TRUE;
473}
474
476{
477 bHandled = FALSE;
478 if (uMsg == WM_RBUTTONDOWN)
479 {
481 info.pt.x = LOWORD(lParam);
482 info.pt.y = HIWORD(lParam);
483 info.flags = TVHT_ONITEM;
484 info.hItem = NULL;
485
486 // Save the current location
488
489 // Move to the item selected by the treeview (don't change right pane)
490 TreeView_HitTest(m_hWnd, &info);
492 TreeView_SelectItem(m_hWnd, info.hItem);
494 }
495 return FALSE; /* let the wndproc process the message */
496}
497
499{
501 LPITEMIDLIST clean;
502 HTREEITEM pItem;
503
505 /* TODO: handle shell notifications */
506 switch(lParam & ~SHCNE_INTERRUPT)
507 {
508 case SHCNE_MKDIR:
509 if (!SUCCEEDED(_ReparsePIDL(dest[0], &clean)))
510 {
511 ERR("Can't reparse PIDL to a valid one\n");
512 return FALSE;
513 }
514 NavigateToPIDL(clean, &pItem, FALSE, TRUE, FALSE);
515 ILFree(clean);
516 break;
517 case SHCNE_RMDIR:
518 DeleteItem(dest[0]);
519 break;
521 if (!SUCCEEDED(_ReparsePIDL(dest[1], &clean)))
522 {
523 ERR("Can't reparse PIDL to a valid one\n");
524 return FALSE;
525 }
526 if (NavigateToPIDL(dest[0], &pItem, FALSE, FALSE, FALSE))
527 RenameItem(pItem, clean);
528 ILFree(clean);
529 break;
530 case SHCNE_UPDATEDIR:
531 // We don't take care of this message
532 TRACE("Directory updated\n");
533 break;
534 default:
535 TRACE("Unhandled message\n");
536 }
537 return TRUE;
538}
539
541{
543 IUnknown_OnFocusChangeIS(m_pSite, reinterpret_cast<IUnknown*>(this), TRUE);
544 bHandled = FALSE;
545 return TRUE;
546}
547
549{
550 IUnknown_OnFocusChangeIS(m_pSite, reinterpret_cast<IUnknown*>(this), FALSE);
551 bHandled = FALSE;
552 return TRUE;
553}
554
555// *** Helper functions ***
557{
558 TV_INSERTSTRUCT tvInsert;
559 HTREEITEM htiCreated;
560
561 /* Get the attributes of the node */
562 SFGAOF attrs = SFGAO_STREAM | SFGAO_HASSUBFOLDER;
563 HRESULT hr = psfParent->GetAttributesOf(1, &pEltRelative, &attrs);
565 return NULL;
566
567 /* Ignore streams */
568 if ((attrs & SFGAO_STREAM))
569 {
570 TRACE("Ignoring stream\n");
571 return NULL;
572 }
573
574 /* Get the name of the node */
575 WCHAR wszDisplayName[MAX_PATH];
576 STRRET strret;
577 hr = psfParent->GetDisplayNameOf(pEltRelative, SHGDN_INFOLDER, &strret);
579 return NULL;
580
581 hr = StrRetToBufW(&strret, pEltRelative, wszDisplayName, MAX_PATH);
583 return NULL;
584
585 /* Get the icon of the node */
586 INT iIcon = SHMapPIDLToSystemImageListIndex(psfParent, pEltRelative, NULL);
587
588 NodeInfo* pChildInfo = new NodeInfo;
589 if (!pChildInfo)
590 {
591 ERR("Failed to allocate NodeInfo\n");
592 return FALSE;
593 }
594
595 // Store our node info
596 pChildInfo->absolutePidl = ILClone(pElt);
597 pChildInfo->relativePidl = ILClone(pEltRelative);
598 pChildInfo->expanded = FALSE;
599
600 // Set up our treeview template
601 tvInsert.hParent = hParent;
602 tvInsert.hInsertAfter = TVI_LAST;
604 tvInsert.item.cchTextMax = MAX_PATH;
605 tvInsert.item.pszText = wszDisplayName;
606 tvInsert.item.iImage = tvInsert.item.iSelectedImage = iIcon;
607 tvInsert.item.cChildren = (attrs & SFGAO_HASSUBFOLDER) ? 1 : 0;
608 tvInsert.item.lParam = (LPARAM)pChildInfo;
609
610 htiCreated = TreeView_InsertItem(m_hWnd, &tvInsert);
611
612 if (bSort)
613 {
614 TVSORTCB sortCallback;
615 sortCallback.hParent = hParent;
616 sortCallback.lpfnCompare = CompareTreeItems;
617 sortCallback.lParam = (LPARAM)this;
618 SendMessage(TVM_SORTCHILDRENCB, 0, (LPARAM)&sortCallback);
619 }
620
621 return htiCreated;
622}
623
624/* This is the slow version of the above method */
626{
627 CComPtr<IShellFolder> psfFolder;
628 HRESULT hr = SHBindToParent(pElt, IID_PPV_ARG(IShellFolder, &psfFolder), NULL);
630 return NULL;
631
632 return InsertItem(hParent, psfFolder, pElt, pEltRelative, bSort);
633}
634
636{
637 CComPtr<IEnumIDList> pEnumIDList;
638 LPITEMIDLIST pidlSub;
640 SHCONTF EnumFlags;
641 HRESULT hr;
642 ULONG fetched;
643 ULONG uItemCount;
644 CComPtr<IShellFolder> pFolder;
645 TVSORTCB sortCallback;
646
647 entry = pNodeInfo->absolutePidl;
648 fetched = 1;
649 uItemCount = 0;
650 EnumFlags = SHCONTF_FOLDERS;
651
652 hr = SHGetFolderLocation(m_hWnd, CSIDL_DESKTOP, NULL, 0, &pidlSub);
653 if (!SUCCEEDED(hr))
654 {
655 ERR("Can't get desktop PIDL !\n");
656 return FALSE;
657 }
658
659 if (!m_pDesktop->CompareIDs(NULL, pidlSub, entry))
660 {
661 // We are the desktop, so use pDesktop as pFolder
662 pFolder = m_pDesktop;
663 }
664 else
665 {
666 // Get an IShellFolder of our pidl
667 hr = m_pDesktop->BindToObject(entry, NULL, IID_PPV_ARG(IShellFolder, &pFolder));
668 if (!SUCCEEDED(hr))
669 {
670 ILFree(pidlSub);
671 ERR("Can't bind folder to desktop !\n");
672 return FALSE;
673 }
674 }
675 ILFree(pidlSub);
676
677 // TODO: handle hidden folders according to settings !
678 EnumFlags |= SHCONTF_INCLUDEHIDDEN;
679
680 // Enum through objects
681 hr = pFolder->EnumObjects(NULL,EnumFlags,&pEnumIDList);
682
683 // avoid broken IShellFolder implementations that return null pointer with success
684 if (!SUCCEEDED(hr) || !pEnumIDList)
685 {
686 ERR("Can't enum the folder !\n");
687 return FALSE;
688 }
689
690 /* Don't redraw while we add stuff into the tree */
692 while(SUCCEEDED(pEnumIDList->Next(1, &pidlSub, &fetched)) && pidlSub && fetched)
693 {
694 LPITEMIDLIST pidlSubComplete;
695 pidlSubComplete = ILCombine(entry, pidlSub);
696
697 if (InsertItem(hItem, pFolder, pidlSubComplete, pidlSub, FALSE))
698 uItemCount++;
699 ILFree(pidlSubComplete);
700 ILFree(pidlSub);
701 }
702 pNodeInfo->expanded = TRUE;
703 /* Let's do sorting */
704 sortCallback.hParent = hItem;
705 sortCallback.lpfnCompare = CompareTreeItems;
706 sortCallback.lParam = (LPARAM)this;
707 SendMessage(TVM_SORTCHILDRENCB, 0, (LPARAM)&sortCallback);
708
709 /* Now we can redraw */
711
712 return (uItemCount > 0) ? TRUE : FALSE;
713}
714
724 BOOL bSelect)
725{
727 HTREEITEM tmp;
729 NodeInfo *nodeData;
730 LPITEMIDLIST relativeChild;
731 TVITEM tvItem;
732
733 if (!item)
734 return FALSE;
735
737 parent = NULL;
738 while (TRUE)
739 {
740 nodeData = GetNodeInfo(current);
741 if (!nodeData)
742 {
743 ERR("Something has gone wrong, no data associated to node !\n");
744 *item = NULL;
745 return FALSE;
746 }
747 // If we found our node, give it back
748 if (!m_pDesktop->CompareIDs(0, nodeData->absolutePidl, dest))
749 {
750 if (bSelect)
752 *item = current;
753 return TRUE;
754 }
755
756 // Check if we are a parent of the requested item
757 relativeChild = ILFindChild(nodeData->absolutePidl, dest);
758 if (relativeChild != 0)
759 {
760 // Notify treeview we have children
761 tvItem.mask = TVIF_CHILDREN;
762 tvItem.hItem = current;
763 tvItem.cChildren = 1;
764 TreeView_SetItem(m_hWnd, &tvItem);
765
766 // If we can expand and the node isn't expanded yet, do it
767 if (bExpand)
768 {
769 if (!nodeData->expanded)
770 InsertSubitems(current, nodeData);
772 }
773
774 // Try to get a child
775 tmp = TreeView_GetChild(m_hWnd, current);
776 if (tmp)
777 {
778 // We have a child, let's continue with it
779 parent = current;
780 current = tmp;
781 continue;
782 }
783
784 if (bInsert && nodeData->expanded)
785 {
786 // Happens when we have to create a subchild inside a child
787 current = InsertItem(current, dest, relativeChild, TRUE);
788 }
789 // We end up here, without any children, so we found nothing
790 // Tell the parent node it has children
791 ZeroMemory(&tvItem, sizeof(tvItem));
792 *item = NULL;
793 return FALSE;
794 }
795
796 // Find sibling
797 tmp = TreeView_GetNextSibling(m_hWnd, current);
798 if (tmp)
799 {
800 current = tmp;
801 continue;
802 }
803 if (bInsert)
804 {
806 *item = current;
807 return TRUE;
808 }
809 *item = NULL;
810 return FALSE;
811 }
813}
814
816{
817 LPITEMIDLIST explorerPidl;
818 CComPtr<IBrowserService> pBrowserService;
819 HRESULT hr;
821 BOOL result;
822 explorerPidl = NULL;
823
824 hr = IUnknown_QueryService(m_pSite, SID_STopLevelBrowser, IID_PPV_ARG(IBrowserService, &pBrowserService));
825 if (!SUCCEEDED(hr))
826 {
827 ERR("Can't get IBrowserService !\n");
828 return FALSE;
829 }
830
831 hr = pBrowserService->GetPidl(&explorerPidl);
832 if (!SUCCEEDED(hr) || !explorerPidl)
833 {
834 ERR("Unable to get browser PIDL !\n");
835 return FALSE;
836 }
838 /* find PIDL into our explorer */
839 result = NavigateToPIDL(explorerPidl, &dummy, TRUE, FALSE, TRUE);
841 return result;
842}
843
845{
846 HTREEITEM toDelete;
847 TVITEM tvItem;
848 HTREEITEM parentNode;
849
850 if (!NavigateToPIDL(idl, &toDelete, FALSE, FALSE, FALSE))
851 return FALSE;
852
853 // TODO: check that the treeview item is really deleted
854
855 parentNode = TreeView_GetParent(m_hWnd, toDelete);
856 // Navigate to parent when deleting child item
857 if (!m_pDesktop->CompareIDs(0, idl, m_pidlCurrent))
858 {
859 TreeView_SelectItem(m_hWnd, parentNode);
860 }
861
862 // Remove the child item
863 TreeView_DeleteItem(m_hWnd, toDelete);
864 // Probe parent to see if it has children
865 if (!TreeView_GetChild(m_hWnd, parentNode))
866 {
867 // Decrement parent's child count
868 ZeroMemory(&tvItem, sizeof(tvItem));
869 tvItem.mask = TVIF_CHILDREN;
870 tvItem.hItem = parentNode;
871 tvItem.cChildren = 0;
872 TreeView_SetItem(m_hWnd, &tvItem);
873 }
874 return TRUE;
875}
876
878{
879 WCHAR wszDisplayName[MAX_PATH];
880 TVITEM itemInfo;
881 LPCITEMIDLIST relPidl;
882 NodeInfo *treeInfo;
883 TVSORTCB sortCallback;
885
886 ZeroMemory(&itemInfo, sizeof(itemInfo));
887 itemInfo.mask = TVIF_PARAM;
888 itemInfo.hItem = toRename;
889
890 // Change PIDL associated to the item
891 relPidl = ILFindLastID(newPidl);
892 TreeView_GetItem(m_hWnd, &itemInfo);
893 if (!itemInfo.lParam)
894 {
895 ERR("Unable to fetch lParam\n");
896 return FALSE;
897 }
899 treeInfo = (NodeInfo*)itemInfo.lParam;
900 ILFree(treeInfo->absolutePidl);
901 ILFree(treeInfo->relativePidl);
902 treeInfo->absolutePidl = ILClone(newPidl);
903 treeInfo->relativePidl = ILClone(relPidl);
904
905 // Change the display name
906 GetDisplayName(newPidl, wszDisplayName, MAX_PATH, SHGDN_INFOLDER);
907 ZeroMemory(&itemInfo, sizeof(itemInfo));
908 itemInfo.hItem = toRename;
909 itemInfo.mask = TVIF_TEXT;
910 itemInfo.pszText = wszDisplayName;
911 TreeView_SetItem(m_hWnd, &itemInfo);
912
913 if((child = TreeView_GetChild(m_hWnd, toRename)) != NULL)
914 {
915 RefreshTreePidl(child, newPidl);
916 }
917
918 // Sorting
919 sortCallback.hParent = TreeView_GetParent(m_hWnd, toRename);
920 sortCallback.lpfnCompare = CompareTreeItems;
921 sortCallback.lParam = (LPARAM)this;
922 SendMessage(TVM_SORTCHILDRENCB, 0, (LPARAM)&sortCallback);
924 return TRUE;
925}
926
928{
929 HTREEITEM tmp;
930 NodeInfo *pInfo;
931
932 // Update our node data
933 pInfo = GetNodeInfo(tree);
934 if (!pInfo)
935 {
936 WARN("No tree info !\n");
937 return FALSE;
938 }
939 ILFree(pInfo->absolutePidl);
940 pInfo->absolutePidl = ILCombine(pidlParent, pInfo->relativePidl);
941 if (!pInfo->absolutePidl)
942 {
943 WARN("PIDL allocation failed\n");
944 return FALSE;
945 }
946 // Recursively update children
947 if ((tmp = TreeView_GetChild(m_hWnd, tree)) != NULL)
948 {
949 RefreshTreePidl(tmp, pInfo->absolutePidl);
950 }
951
952 tmp = TreeView_GetNextSibling(m_hWnd, tree);
953 while(tmp != NULL)
954 {
955 pInfo = GetNodeInfo(tmp);
956 if(!pInfo)
957 {
958 WARN("No tree info !\n");
959 continue;
960 }
961 ILFree(pInfo->absolutePidl);
962 pInfo->absolutePidl = ILCombine(pidlParent, pInfo->relativePidl);
963 tmp = TreeView_GetNextSibling(m_hWnd, tmp);
964 }
965 return TRUE;
966}
967
968// *** Tree item sorting callback ***
970{
971 /*
972 * We first sort drive letters (Path root), then PIDLs and then regular folder
973 * display name.
974 * This is not how Windows sorts item, but it gives decent results.
975 */
976 NodeInfo *info1;
977 NodeInfo *info2;
978 CExplorerBand *pThis;
979 WCHAR wszFolder1[MAX_PATH];
980 WCHAR wszFolder2[MAX_PATH];
981
982 info1 = (NodeInfo*)p1;
983 info2 = (NodeInfo*)p2;
984 pThis = (CExplorerBand*)p3;
985
986 GetDisplayName(info1->absolutePidl, wszFolder1, MAX_PATH, SHGDN_FORPARSING);
987 GetDisplayName(info2->absolutePidl, wszFolder2, MAX_PATH, SHGDN_FORPARSING);
988 if (PathIsRoot(wszFolder1) && PathIsRoot(wszFolder2))
989 {
990 return lstrcmpiW(wszFolder1,wszFolder2);
991 }
992 if (PathIsRoot(wszFolder1) && !PathIsRoot(wszFolder2))
993 {
994 return -1;
995 }
996 if (!PathIsRoot(wszFolder1) && PathIsRoot(wszFolder2))
997 {
998 return 1;
999 }
1000 // Now, we compare non-root folders, grab display name
1001 GetDisplayName(info1->absolutePidl, wszFolder1, MAX_PATH, SHGDN_INFOLDER);
1002 GetDisplayName(info2->absolutePidl, wszFolder2, MAX_PATH, SHGDN_INFOLDER);
1003
1005 {
1006 return -1;
1007 }
1009 {
1010 return 1;
1011 }
1013 {
1014 HRESULT hr;
1015 hr = pThis->m_pDesktop->CompareIDs(0, info1->absolutePidl, info2->absolutePidl);
1016 if (!hr) return 0;
1017 return (hr > 0) ? -1 : 1;
1018 }
1019 return StrCmpLogicalW(wszFolder1, wszFolder2);
1020}
1021
1022// *** IOleWindow methods ***
1024{
1025 if (!lphwnd)
1026 return E_INVALIDARG;
1027 *lphwnd = m_hWnd;
1028 return S_OK;
1029}
1030
1032{
1034 return E_NOTIMPL;
1035}
1036
1037
1038// *** IDockingWindow methods ***
1040{
1041 // We do nothing, we don't have anything to save yet
1042 TRACE("CloseDW called\n");
1043 return S_OK;
1044}
1045
1046HRESULT STDMETHODCALLTYPE CExplorerBand::ResizeBorderDW(const RECT *prcBorder, IUnknown *punkToolbarSite, BOOL fReserved)
1047{
1048 /* Must return E_NOTIMPL according to MSDN */
1049 return E_NOTIMPL;
1050}
1051
1053{
1054 m_fVisible = fShow;
1055 ShowWindow(fShow);
1056 return S_OK;
1057}
1058
1059
1060// *** IDeskBand methods ***
1062{
1063 if (!pdbi)
1064 {
1065 return E_INVALIDARG;
1066 }
1067 this->m_dwBandID = dwBandID;
1068
1069 if (pdbi->dwMask & DBIM_MINSIZE)
1070 {
1071 pdbi->ptMinSize.x = 200;
1072 pdbi->ptMinSize.y = 30;
1073 }
1074
1075 if (pdbi->dwMask & DBIM_MAXSIZE)
1076 {
1077 pdbi->ptMaxSize.y = -1;
1078 }
1079
1080 if (pdbi->dwMask & DBIM_INTEGRAL)
1081 {
1082 pdbi->ptIntegral.y = 1;
1083 }
1084
1085 if (pdbi->dwMask & DBIM_ACTUAL)
1086 {
1087 pdbi->ptActual.x = 200;
1088 pdbi->ptActual.y = 30;
1089 }
1090
1091 if (pdbi->dwMask & DBIM_TITLE)
1092 {
1093 if (!LoadStringW(_AtlBaseModule.GetResourceInstance(), IDS_FOLDERSLABEL, pdbi->wszTitle, _countof(pdbi->wszTitle)))
1095 }
1096
1097 if (pdbi->dwMask & DBIM_MODEFLAGS)
1098 {
1099 pdbi->dwModeFlags = DBIMF_NORMAL | DBIMF_VARIABLEHEIGHT;
1100 }
1101
1102 if (pdbi->dwMask & DBIM_BKCOLOR)
1103 {
1104 pdbi->dwMask &= ~DBIM_BKCOLOR;
1105 }
1106 return S_OK;
1107}
1108
1109
1110// *** IObjectWithSite methods ***
1112{
1113 HRESULT hr;
1114 HWND parentWnd;
1115
1116 if (pUnkSite == m_pSite)
1117 return S_OK;
1118
1119 TRACE("SetSite called \n");
1120 if (!pUnkSite)
1121 {
1123 DestroyWindow();
1124 m_hWnd = NULL;
1125 }
1126
1127 if (pUnkSite != m_pSite)
1128 {
1129 m_pSite = NULL;
1130 }
1131
1132 if(!pUnkSite)
1133 return S_OK;
1134
1135 hr = IUnknown_GetWindow(pUnkSite, &parentWnd);
1136 if (!SUCCEEDED(hr))
1137 {
1138 ERR("Could not get parent's window ! Status: %08lx\n", hr);
1139 return E_INVALIDARG;
1140 }
1141
1142 m_pSite = pUnkSite;
1143
1144 if (m_hWnd)
1145 {
1146 // Change its parent
1147 SetParent(parentWnd);
1148 }
1149 else
1150 {
1152 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
1153 0, 0, 0, 0, parentWnd, NULL, _AtlBaseModule.GetModuleInstance(), NULL);
1154
1155 // Subclass the window
1156 SubclassWindow(wnd);
1157
1158 // Initialize our treeview now
1160 RegisterDragDrop(m_hWnd, dynamic_cast<IDropTarget*>(this));
1161 }
1162 return S_OK;
1163}
1164
1166{
1167 if (!ppvSite)
1168 return E_POINTER;
1169 *ppvSite = m_pSite;
1170 return S_OK;
1171}
1172
1173
1174// *** IOleCommandTarget methods ***
1175HRESULT STDMETHODCALLTYPE CExplorerBand::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText)
1176{
1178 return E_NOTIMPL;
1179}
1180
1181HRESULT STDMETHODCALLTYPE CExplorerBand::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
1182{
1184 return E_NOTIMPL;
1185}
1186
1187
1188// *** IServiceProvider methods ***
1190{
1191 /* FIXME: we probably want to handle more services here */
1193}
1194
1195
1196// *** IInputObject methods ***
1198{
1199 if (fActivate)
1200 {
1201 //SetFocus();
1203 }
1204 // TODO: handle message
1205 if(lpMsg)
1206 {
1207 TranslateMessage(lpMsg);
1208 DispatchMessage(lpMsg);
1209 }
1210 return S_OK;
1211}
1212
1214{
1215 return m_bFocused ? S_OK : S_FALSE;
1216}
1217
1219{
1220 if (lpMsg->hwnd == m_hWnd)
1221 {
1222 TranslateMessage(lpMsg);
1223 DispatchMessage(lpMsg);
1224 return S_OK;
1225 }
1226
1227 return S_FALSE;
1228}
1229
1230// *** IPersist methods ***
1232{
1233 if (!pClassID)
1234 return E_POINTER;
1235 memcpy(pClassID, &CLSID_ExplorerBand, sizeof(CLSID));
1236 return S_OK;
1237}
1238
1239
1240// *** IPersistStream methods ***
1242{
1244 return E_NOTIMPL;
1245}
1246
1248{
1250 return E_NOTIMPL;
1251}
1252
1254{
1256 return E_NOTIMPL;
1257}
1258
1260{
1261 // TODO: calculate max size
1263 return E_NOTIMPL;
1264}
1265
1266
1267// *** IWinEventHandler methods ***
1269{
1270 BOOL bHandled;
1272
1273 if (uMsg == WM_NOTIFY)
1274 {
1275 NMHDR *pNotifyHeader = (NMHDR*)lParam;
1276 switch (pNotifyHeader->code)
1277 {
1278 case TVN_ITEMEXPANDING:
1280 if (theResult)
1281 *theResult = result;
1282 break;
1283 case TVN_SELCHANGED:
1285 break;
1286 case TVN_DELETEITEM:
1288 break;
1289 case NM_RCLICK:
1290 OnContextMenu(WM_CONTEXTMENU, (WPARAM)m_hWnd, GetMessagePos(), bHandled);
1291 if (theResult)
1292 *theResult = 1;
1293 break;
1294 case TVN_BEGINDRAG:
1295 case TVN_BEGINRDRAG:
1298 {
1299 // TODO: put this in a function ? (mostly copypasta from CDefView)
1300 DWORD dwAttr = SFGAO_CANRENAME;
1303 LPCITEMIDLIST pChild;
1304 HRESULT hr;
1305
1306 if (theResult)
1307 *theResult = 1;
1308 NodeInfo *info = GetNodeInfo(dispInfo->item.hItem);
1309 if (!info)
1310 return E_FAIL;
1311 hr = SHBindToParent(info->absolutePidl, IID_PPV_ARG(IShellFolder, &pParent), &pChild);
1312 if (!SUCCEEDED(hr) || !pParent.p)
1313 return E_FAIL;
1314
1315 hr = pParent->GetAttributesOf(1, &pChild, &dwAttr);
1316 if (SUCCEEDED(hr) && (dwAttr & SFGAO_CANRENAME) && theResult)
1317 *theResult = 0;
1318 return S_OK;
1319 }
1320 case TVN_ENDLABELEDITW:
1321 {
1323 NodeInfo *info = GetNodeInfo(dispInfo->item.hItem);
1324 HRESULT hr;
1325
1326 if (theResult)
1327 *theResult = 0;
1328 if (dispInfo->item.pszText)
1329 {
1330 LPITEMIDLIST pidlNew;
1332 LPCITEMIDLIST pidlChild;
1333
1334 hr = SHBindToParent(info->absolutePidl, IID_PPV_ARG(IShellFolder, &pParent), &pidlChild);
1335 if (!SUCCEEDED(hr) || !pParent.p)
1336 return E_FAIL;
1337
1338 hr = pParent->SetNameOf(0, pidlChild, dispInfo->item.pszText, SHGDN_INFOLDER, &pidlNew);
1339 if(SUCCEEDED(hr) && pidlNew)
1340 {
1341 CComPtr<IPersistFolder2> pPersist;
1342 LPITEMIDLIST pidlParent, pidlNewAbs;
1343
1345 if(!SUCCEEDED(hr))
1346 return E_FAIL;
1347
1348 hr = pPersist->GetCurFolder(&pidlParent);
1349 if(!SUCCEEDED(hr))
1350 return E_FAIL;
1351 pidlNewAbs = ILCombine(pidlParent, pidlNew);
1352
1353 // Navigate to our new location
1354 UpdateBrowser(pidlNewAbs);
1355
1356 ILFree(pidlParent);
1357 ILFree(pidlNewAbs);
1358 ILFree(pidlNew);
1359 if (theResult)
1360 *theResult = 1;
1361 }
1362 return S_OK;
1363 }
1364 }
1365 default:
1366 break;
1367 }
1368 }
1369 return S_OK;
1370}
1371
1373{
1374 return (hWnd == m_hWnd) ? S_OK : S_FALSE;
1375}
1376
1377// *** IBandNavigate methods ***
1379{
1381 return E_NOTIMPL;
1382}
1383
1384// *** INamespaceProxy ***
1385HRESULT STDMETHODCALLTYPE CExplorerBand::GetNavigateTarget(long paramC, long param10, long param14)
1386{
1388 return E_NOTIMPL;
1389}
1390
1392{
1394 return E_NOTIMPL;
1395}
1396
1398{
1400 return E_NOTIMPL;
1401}
1402
1403HRESULT STDMETHODCALLTYPE CExplorerBand::RefreshFlags(long paramC, long param10, long param14)
1404{
1406 return E_NOTIMPL;
1407}
1408
1410{
1412 return E_NOTIMPL;
1413}
1414
1415// *** IDispatch methods ***
1417{
1419 return E_NOTIMPL;
1420}
1421
1423{
1425 return E_NOTIMPL;
1426}
1427
1429{
1431 return E_NOTIMPL;
1432}
1433
1434HRESULT STDMETHODCALLTYPE CExplorerBand::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1435{
1436 switch (dispIdMember)
1437 {
1440 TRACE("DISPID_NAVIGATECOMPLETE2 received\n");
1442 return S_OK;
1443 }
1444 TRACE("Unknown dispid requested: %08x\n", dispIdMember);
1445 return E_INVALIDARG;
1446}
1447
1448// *** IDropTarget methods ***
1450{
1451 ERR("Entering drag\n");
1452 m_pCurObject = pObj;
1454 return DragOver(glfKeyState, pt, pdwEffect);
1455}
1456
1458{
1460 CComPtr<IShellFolder> pShellFldr;
1461 NodeInfo *nodeInfo;
1462 //LPCITEMIDLIST pChild;
1463 HRESULT hr;
1464
1465 info.pt.x = pt.x;
1466 info.pt.y = pt.y;
1467 info.flags = TVHT_ONITEM;
1468 info.hItem = NULL;
1469 ScreenToClient(&info.pt);
1470
1471 // Move to the item selected by the treeview (don't change right pane)
1472 TreeView_HitTest(m_hWnd, &info);
1473
1474 if (info.hItem)
1475 {
1477 TreeView_SelectItem(m_hWnd, info.hItem);
1479 // Delegate to shell folder
1480 if (m_pDropTarget && info.hItem != m_childTargetNode)
1481 {
1483 }
1484 if (info.hItem != m_childTargetNode)
1485 {
1486 nodeInfo = GetNodeInfo(info.hItem);
1487 if (!nodeInfo)
1488 return E_FAIL;
1489#if 0
1490 hr = SHBindToParent(nodeInfo->absolutePidl, IID_PPV_ARG(IShellFolder, &pShellFldr), &pChild);
1491 if (!SUCCEEDED(hr))
1492 return E_FAIL;
1493 hr = pShellFldr->GetUIObjectOf(m_hWnd, 1, &pChild, IID_IDropTarget, NULL, reinterpret_cast<void**>(&pDropTarget));
1494 if (!SUCCEEDED(hr))
1495 return E_FAIL;
1496#endif
1497 if(_ILIsDesktop(nodeInfo->absolutePidl))
1498 pShellFldr = m_pDesktop;
1499 else
1500 {
1501 hr = m_pDesktop->BindToObject(nodeInfo->absolutePidl, 0, IID_PPV_ARG(IShellFolder, &pShellFldr));
1502 if (!SUCCEEDED(hr))
1503 {
1504 /* Don't allow dnd since we couldn't get our folder object */
1505 ERR("Can't bind to folder object\n");
1506 *pdwEffect = DROPEFFECT_NONE;
1507 return E_FAIL;
1508 }
1509 }
1510 hr = pShellFldr->CreateViewObject(m_hWnd, IID_PPV_ARG(IDropTarget, &m_pDropTarget));
1511 if (!SUCCEEDED(hr))
1512 {
1513 /* Don't allow dnd since we couldn't get our drop target */
1514 ERR("Can't get drop target for folder object\n");
1515 *pdwEffect = DROPEFFECT_NONE;
1516 return E_FAIL;
1517 }
1518 hr = m_pDropTarget->DragEnter(m_pCurObject, glfKeyState, pt, pdwEffect);
1519 m_childTargetNode = info.hItem;
1520 }
1521 if (m_pDropTarget)
1522 {
1523 hr = m_pDropTarget->DragOver(glfKeyState, pt, pdwEffect);
1524 }
1525 }
1526 else
1527 {
1530 *pdwEffect = DROPEFFECT_NONE;
1531 }
1532 return S_OK;
1533}
1534
1536{
1541 if (m_pCurObject)
1542 {
1544 }
1545 return S_OK;
1546}
1547
1549{
1550 if (!m_pDropTarget)
1551 return E_FAIL;
1552 m_pDropTarget->Drop(pObj, glfKeyState, pt, pdwEffect);
1553 DragLeave();
1554 return S_OK;
1555}
1556
1557// *** IDropSource methods ***
1559{
1560 if (fEscapePressed)
1561 return DRAGDROP_S_CANCEL;
1562 if ((grfKeyState & MK_LBUTTON) || (grfKeyState & MK_RBUTTON))
1563 return S_OK;
1564 return DRAGDROP_S_DROP;
1565}
1566
1568{
1570}
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:64
BOOL OnTreeItemExpanding(LPNMTREEVIEW pnmtv)
virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
HTREEITEM m_oldSelected
Definition: explorerband.h:65
void DestroyExplorerBand()
virtual HRESULT STDMETHODCALLTYPE DragOver(DWORD glfKeyState, POINTL pt, DWORD *pdwEffect)
virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT *pctinfo)
virtual HRESULT STDMETHODCALLTYPE TranslateAcceleratorIO(LPMSG lpMsg)
void OnSelectionChanged(LPNMTREEVIEW pnmtv)
virtual HRESULT STDMETHODCALLTYPE QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText)
virtual HRESULT STDMETHODCALLTYPE Drop(IDataObject *pObj, DWORD glfKeyState, POINTL pt, DWORD *pdwEffect)
virtual HRESULT STDMETHODCALLTYPE GetClassID(CLSID *pClassID)
HRESULT ExecuteCommand(CComPtr< IContextMenu > &menu, UINT nCmd)
virtual HRESULT STDMETHODCALLTYPE RefreshFlags(long paramC, long param10, long param14)
LRESULT OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
virtual HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
virtual HRESULT STDMETHODCALLTYPE Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
virtual HRESULT STDMETHODCALLTYPE QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState)
virtual HRESULT STDMETHODCALLTYPE Save(IStream *pStm, BOOL fClearDirty)
virtual HRESULT STDMETHODCALLTYPE GetNavigateTarget(long paramC, long param10, long param14)
BOOL m_bNavigating
Definition: explorerband.h:60
virtual HRESULT STDMETHODCALLTYPE UIActivateIO(BOOL fActivate, LPMSG lpMsg)
virtual HRESULT STDMETHODCALLTYPE DragLeave()
virtual HRESULT STDMETHODCALLTYPE Select(long paramC)
void InitializeExplorerBand()
virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
HTREEITEM m_childTargetNode
Definition: explorerband.h:74
DWORD m_dwBandID
Definition: explorerband.h:62
virtual HRESULT STDMETHODCALLTYPE IsWindowOwner(HWND hWnd)
virtual HRESULT STDMETHODCALLTYPE Load(IStream *pStm)
static int CALLBACK CompareTreeItems(LPARAM p1, LPARAM p2, LPARAM p3)
virtual HRESULT STDMETHODCALLTYPE CacheItem(long paramC)
virtual HRESULT STDMETHODCALLTYPE GetBandInfo(DWORD dwBandID, DWORD dwViewMode, DESKBANDINFO *pdbi)
BOOL DeleteItem(LPITEMIDLIST toDelete)
HRESULT UpdateBrowser(LPITEMIDLIST pidlGoto)
virtual HRESULT STDMETHODCALLTYPE ShowDW(BOOL fShow)
BOOL NavigateToCurrentFolder()
LPITEMIDLIST m_pidlCurrent
Definition: explorerband.h:66
virtual HRESULT STDMETHODCALLTYPE OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
virtual HRESULT STDMETHODCALLTYPE HasFocusIO()
virtual HRESULT STDMETHODCALLTYPE SetSite(IUnknown *pUnkSite)
CComPtr< IDataObject > m_pCurObject
Definition: explorerband.h:75
void OnTreeItemDragging(LPNMTREEVIEW pnmtv, BOOL isRightClick)
CComPtr< IUnknown > m_pSite
Definition: explorerband.h:55
DWORD m_adviseCookie
Definition: explorerband.h:69
BOOL RefreshTreePidl(HTREEITEM tree, LPITEMIDLIST pidlParent)
LRESULT OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
NodeInfo * GetNodeInfo(HTREEITEM hItem)
virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND *lphwnd)
virtual HRESULT STDMETHODCALLTYPE GetSizeMax(ULARGE_INTEGER *pcbSize)
BOOL NavigateToPIDL(LPITEMIDLIST dest, HTREEITEM *item, BOOL bExpand, BOOL bInsert, BOOL bSelect)
virtual HRESULT STDMETHODCALLTYPE GiveFeedback(DWORD dwEffect)
LRESULT OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
LRESULT ContextMenuHack(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
virtual HRESULT STDMETHODCALLTYPE GetSite(REFIID riid, void **ppvSite)
CComPtr< IShellFolder > m_pDesktop
Definition: explorerband.h:56
BOOL OnTreeItemDeleted(LPNMTREEVIEW pnmtv)
CComPtr< IDropTarget > m_pDropTarget
Definition: explorerband.h:73
ULONG m_shellRegID
Definition: explorerband.h:70
virtual HRESULT STDMETHODCALLTYPE CloseDW(DWORD dwReserved)
virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode)
virtual HRESULT STDMETHODCALLTYPE DragEnter(IDataObject *pObj, DWORD glfKeyState, POINTL pt, DWORD *pdwEffect)
LRESULT OnShellEvent(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
BOOL InsertSubitems(HTREEITEM hItem, NodeInfo *pNodeInfo)
virtual HRESULT STDMETHODCALLTYPE Invoke(long paramC)
virtual HRESULT STDMETHODCALLTYPE IsDirty()
virtual HRESULT STDMETHODCALLTYPE ResizeBorderDW(const RECT *prcBorder, IUnknown *punkToolbarSite, BOOL fReserved)
virtual ~CExplorerBand()
BOOL RenameItem(HTREEITEM toRename, LPITEMIDLIST newPidl)
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
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:3093
HRESULT WINAPI IUnknown_QueryService(IUnknown *, REFGUID, REFIID, LPVOID *)
Definition: ordinal.c:1494
HRESULT WINAPI IUnknown_GetWindow(IUnknown *lpUnknown, HWND *lphWnd)
Definition: ordinal.c:1329
HRESULT WINAPI IUnknown_OnFocusChangeIS(LPUNKNOWN lpUnknown, LPUNKNOWN pFocusObject, BOOL bFocus)
Definition: ordinal.c:4652
HRESULT WINAPI IUnknown_SetSite(IUnknown *obj, IUnknown *site)
Definition: ordinal.c:1404
INT WINAPI StrCmpLogicalW(LPCWSTR lpszStr, LPCWSTR lpszComp)
Definition: string.c:2296
HRESULT WINAPI StrRetToBufW(LPSTRRET src, const ITEMIDLIST *pidl, LPWSTR dest, UINT len)
Definition: string.c:1522
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:783
REFIID riid
Definition: atlbase.h:39
const DWORD DROPEFFECT_NONE
Definition: oleidl.idl:929
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:60
static SHCONTF
Definition: ordinal.c:61
static VARIANTARG static DISPID
Definition: ordinal.c:49
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:228
void WINAPI ILFree(LPITEMIDLIST pidl)
Definition: pidl.c:925
LPITEMIDLIST WINAPI ILFindLastID(LPCITEMIDLIST pidl)
Definition: pidl.c:189
LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
Definition: pidl.c:699
HRESULT WINAPI SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCITEMIDLIST *ppidlLast)
Definition: pidl.c:1337
PUIDLIST_RELATIVE WINAPI ILFindChild(PIDLIST_ABSOLUTE pidl1, PCIDLIST_ABSOLUTE pidl2)
Definition: pidl.c:641
#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:182
HRESULT WINAPI SHGetImageList(int iImageList, REFIID riid, void **ppv)
Definition: shellord.c:2406
#define FAILED_UNEXPECTEDLY(hr)
Definition: shellutils.h:82
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:1789
#define SHCNE_RMDIR
Definition: shlobj.h:1746
#define SHCNE_MKDIR
Definition: shlobj.h:1745
#define SHCNE_UPDATEDIR
Definition: shlobj.h:1754
#define SHCNE_RENAMEFOLDER
Definition: shlobj.h:1759
#define SHCNE_DISKEVENTS
Definition: shlobj.h:1764
#define SHCNRF_ShellLevel
Definition: shlobj.h:1788
#define CSIDL_DESKTOP
Definition: shlobj.h:2025
#define FCIDM_SHVIEWFIRST
Definition: shlobj.h:507
#define SHCNRF_InterruptLevel
Definition: shlobj.h:1787
#define SHCNE_INTERRUPT
Definition: shlobj.h:1767
#define FCIDM_SHVIEWLAST
Definition: shlobj.h:541
#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:1738
int cChildren
Definition: treeview.c:154
Definition: fci.c:116
WCHAR wszTitle[256]
Definition: shobjidl.idl:2380
HWND hwnd
Definition: winuser.h:3104
UINT code
Definition: winuser.h:3149
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:1670
DWORD WINAPI GetLastError(void)
Definition: except.c:1040
_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:2358
HMENU WINAPI CreatePopupMenu(void)
Definition: menu.c:846
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:2370
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:2193
#define CreateWindow
Definition: winuser.h:5744
#define WM_RBUTTONDOWN
Definition: winuser.h:1769
HWND WINAPI SetFocus(_In_opt_ HWND)
HWND WINAPI SetActiveWindow(_In_ HWND)
#define TPM_LEFTALIGN
Definition: winuser.h:2367
#define SendMessage
Definition: winuser.h:5833
#define TPM_LEFTBUTTON
Definition: winuser.h:2369
#define MAKEINTRESOURCEA(i)
Definition: winuser.h:581
BOOL WINAPI DestroyMenu(_In_ HMENU)
#define MK_LBUTTON
Definition: winuser.h:2357
#define VK_SHIFT
Definition: winuser.h:2192
BOOL WINAPI TrackPopupMenu(_In_ HMENU, _In_ UINT, _In_ int, _In_ int, _Reserved_ int, _In_ HWND, _Reserved_ LPCRECT)
#define DispatchMessage
Definition: winuser.h:5755
#define TPM_RETURNCMD
Definition: winuser.h:2377
BOOL WINAPI DestroyWindow(_In_ HWND)
SHORT WINAPI GetKeyState(_In_ int)
#define WM_SETREDRAW
Definition: winuser.h:1606
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