[BROWSEUI]
[reactos.git] / reactos / dll / win32 / browseui / explorerband.cpp
1 /*
2 * ReactOS Explorer
3 *
4 * Copyright 2016 Sylvain Deverre <deverre dot sylv at gmail dot com>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #include "precomp.h"
22 #include <commoncontrols.h>
23 #include <undocshell.h>
24
25 #if 1
26 #undef UNIMPLEMENTED
27
28 #define UNIMPLEMENTED DbgPrint("%s is UNIMPLEMENTED!\n", __FUNCTION__)
29 #endif
30
31 extern "C"
32 HRESULT WINAPI CExplorerBand_Constructor(REFIID riid, LPVOID *ppv)
33 {
34 return ShellObjectCreator<CExplorerBand>(riid, ppv);
35 }
36
37 CExplorerBand::CExplorerBand() :
38 pSite(NULL), fVisible(FALSE), dwBandID(0)
39 {
40 }
41
42 CExplorerBand::~CExplorerBand()
43 {
44 }
45
46 void CExplorerBand::InitializeExplorerBand()
47 {
48 // Init the treeview here
49 HRESULT hr;
50 LPITEMIDLIST pidl;
51 CComPtr<IWebBrowser2> browserService;
52 SHChangeNotifyEntry shcne;
53
54 hr = SHGetDesktopFolder(&pDesktop);
55 if (FAILED_UNEXPECTEDLY(hr))
56 return;
57
58 hr = SHGetFolderLocation(m_hWnd, CSIDL_DESKTOP, NULL, 0, &pidl);
59 if (FAILED_UNEXPECTEDLY(hr))
60 return;
61
62 IImageList * piml;
63 hr = SHGetImageList(SHIL_SMALL, IID_PPV_ARG(IImageList, &piml));
64 if (FAILED_UNEXPECTEDLY(hr))
65 return;
66
67 TreeView_SetImageList(m_hWnd, (HIMAGELIST)piml, TVSIL_NORMAL);
68
69 // Insert the root node
70 HTREEITEM hItem = InsertItem(0, pDesktop, pidl, pidl, FALSE);
71 if (!hItem)
72 {
73 ERR("Failed to create root item\n");
74 return;
75 }
76
77 NodeInfo* pNodeInfo = GetNodeInfo(hItem);
78
79 // Insert child nodes
80 InsertSubitems(hItem, pNodeInfo);
81 TreeView_Expand(m_hWnd, hItem, TVE_EXPAND);
82
83 // Navigate to current folder position
84 //NavigateToCurrentFolder();
85
86 // Register shell notification
87 shcne.pidl = pidl;
88 shcne.fRecursive = TRUE;
89 shellRegID = SHChangeNotifyRegister(
90 m_hWnd,
91 SHCNRF_ShellLevel | SHCNRF_InterruptLevel | SHCNRF_RecursiveInterrupt,
92 SHCNE_DISKEVENTS | SHCNE_RENAMEFOLDER | SHCNE_RMDIR | SHCNE_MKDIR,
93 WM_USER_SHELLEVENT,
94 1,
95 &shcne);
96 if (!shellRegID)
97 {
98 ERR("Something went wrong, error %08x\n", GetLastError());
99 }
100 // Register browser connection endpoint
101 hr = IUnknown_QueryService(pSite, SID_SWebBrowserApp, IID_PPV_ARG(IWebBrowser2, &browserService));
102 if (FAILED_UNEXPECTEDLY(hr))
103 return;
104
105 hr = AtlAdvise(browserService, dynamic_cast<IDispatch*>(this), DIID_DWebBrowserEvents, &adviseCookie);
106 if (FAILED_UNEXPECTEDLY(hr))
107 return;
108
109 ILFree(pidl);
110 }
111
112 void CExplorerBand::DestroyExplorerBand()
113 {
114 HRESULT hr;
115 CComPtr <IWebBrowser2> browserService;
116
117 TRACE("Cleaning up explorer band ...\n");
118
119 hr = IUnknown_QueryService(pSite, SID_SWebBrowserApp, IID_PPV_ARG(IWebBrowser2, &browserService));
120 if (FAILED_UNEXPECTEDLY(hr))
121 return;
122
123 hr = AtlUnadvise(browserService, DIID_DWebBrowserEvents, adviseCookie);
124 /* Remove all items of the treeview */
125 RevokeDragDrop(m_hWnd);
126 TreeView_DeleteAllItems(m_hWnd);
127 pDesktop = NULL;
128 hRoot = NULL;
129 TRACE("Cleanup done !\n");
130 }
131
132 CExplorerBand::NodeInfo* CExplorerBand::GetNodeInfo(HTREEITEM hItem)
133 {
134 TVITEM tvItem;
135
136 tvItem.mask = TVIF_PARAM;
137 tvItem.hItem = hItem;
138
139 if (!TreeView_GetItem(m_hWnd, &tvItem))
140 return 0;
141
142 return reinterpret_cast<NodeInfo*>(tvItem.lParam);
143 }
144
145 HRESULT CExplorerBand::UpdateBrowser(LPITEMIDLIST pidlGoto)
146 {
147 CComPtr<IShellBrowser> pBrowserService;
148 HRESULT hr;
149
150 hr = IUnknown_QueryService(pSite, SID_STopLevelBrowser, IID_PPV_ARG(IShellBrowser, &pBrowserService));
151 if (FAILED_UNEXPECTEDLY(hr))
152 return hr;
153
154 hr = pBrowserService->BrowseObject(pidlGoto, SBSP_SAMEBROWSER | SBSP_ABSOLUTE);
155 if (FAILED_UNEXPECTEDLY(hr))
156 return hr;
157
158 return hr;
159 }
160
161 // *** notifications handling ***
162 BOOL CExplorerBand::OnTreeItemExpanding(LPNMTREEVIEW pnmtv)
163 {
164 NodeInfo *pNodeInfo;
165
166 if (pnmtv->action == TVE_COLLAPSE) {
167 if (pnmtv->itemNew.hItem == hRoot)
168 {
169 // Prenvent root from collapsing
170 pnmtv->itemNew.mask |= TVIF_STATE;
171 pnmtv->itemNew.stateMask |= TVIS_EXPANDED;
172 pnmtv->itemNew.state &= ~TVIS_EXPANDED;
173 pnmtv->action = TVE_EXPAND;
174 return TRUE;
175 }
176 }
177 if (pnmtv->action == TVE_EXPAND) {
178 // Grab our directory PIDL
179 pNodeInfo = GetNodeInfo(pnmtv->itemNew.hItem);
180 // We have it, let's try
181 if (pNodeInfo && !pNodeInfo->expanded)
182 if (!InsertSubitems(pnmtv->itemNew.hItem, pNodeInfo)) {
183 // remove subitem "+" since we failed to add subitems
184 TV_ITEM tvItem;
185
186 tvItem.mask = TVIF_CHILDREN;
187 tvItem.hItem = pnmtv->itemNew.hItem;
188 tvItem.cChildren = 0;
189
190 TreeView_SetItem(m_hWnd, &tvItem);
191 }
192 }
193 return FALSE;
194 }
195
196 void CExplorerBand::OnSelectionChanged(LPNMTREEVIEW pnmtv)
197 {
198 NodeInfo* pNodeInfo = GetNodeInfo(pnmtv->itemNew.hItem);
199
200 UpdateBrowser(pNodeInfo->absolutePidl);
201 SetFocus();
202 // Expand the node
203 //TreeView_Expand(m_hWnd, pnmtv->itemNew.hItem, TVE_EXPAND);
204 }
205
206 // *** Helper functions ***
207 HTREEITEM CExplorerBand::InsertItem(HTREEITEM hParent, IShellFolder *psfParent, LPITEMIDLIST pElt, LPITEMIDLIST pEltRelative, BOOL bSort)
208 {
209 TV_INSERTSTRUCT tvInsert;
210 HTREEITEM htiCreated;
211
212 /* Get the attributes of the node */
213 SFGAOF attrs = SFGAO_STREAM | SFGAO_HASSUBFOLDER;
214 HRESULT hr = psfParent->GetAttributesOf(1, &pEltRelative, &attrs);
215 if (FAILED_UNEXPECTEDLY(hr))
216 return NULL;
217
218 /* Ignore streams */
219 if ((attrs & SFGAO_STREAM))
220 {
221 TRACE("Ignoring stream\n");
222 return NULL;
223 }
224
225 /* Get the name of the node */
226 WCHAR wszDisplayName[MAX_PATH];
227 if (!ILGetDisplayNameEx(psfParent, pEltRelative, wszDisplayName, ILGDN_INFOLDER))
228 {
229 ERR("Failed to get node name\n");
230 return NULL;
231 }
232
233 /* Get the icon of the node */
234 INT iIcon = SHMapPIDLToSystemImageListIndex(psfParent, pEltRelative, NULL);
235
236 NodeInfo* pChildInfo = new NodeInfo;
237 if (!pChildInfo)
238 {
239 ERR("Failed to allocate NodeInfo\n");
240 return FALSE;
241 }
242
243 // Store our node info
244 pChildInfo->absolutePidl = ILClone(pElt);
245 pChildInfo->relativePidl = ILClone(pEltRelative);
246 pChildInfo->expanded = FALSE;
247
248 // Set up our treeview template
249 tvInsert.hParent = hParent;
250 tvInsert.hInsertAfter = TVI_LAST;
251 tvInsert.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN;
252 tvInsert.item.cchTextMax = MAX_PATH;
253 tvInsert.item.pszText = wszDisplayName;
254 tvInsert.item.iImage = tvInsert.item.iSelectedImage = iIcon;
255 tvInsert.item.cChildren = (attrs & SFGAO_HASSUBFOLDER) ? 1 : 0;
256 tvInsert.item.lParam = (LPARAM)pChildInfo;
257
258 htiCreated = TreeView_InsertItem(m_hWnd, &tvInsert);
259
260 return htiCreated;
261 }
262
263 BOOL CExplorerBand::InsertSubitems(HTREEITEM hItem, NodeInfo *pNodeInfo)
264 {
265 CComPtr<IEnumIDList> pEnumIDList;
266 LPITEMIDLIST pidlSub;
267 LPITEMIDLIST entry;
268 SHCONTF EnumFlags;
269 HRESULT hr;
270 ULONG fetched;
271 ULONG uItemCount;
272 CComPtr<IShellFolder> pFolder;
273
274 entry = pNodeInfo->absolutePidl;
275 fetched = 1;
276 uItemCount = 0;
277 EnumFlags = SHCONTF_FOLDERS;
278
279 hr = SHGetFolderLocation(m_hWnd, CSIDL_DESKTOP, NULL, 0, &pidlSub);
280 if (!SUCCEEDED(hr))
281 {
282 ERR("Can't get desktop PIDL !\n");
283 return FALSE;
284 }
285
286 if (!pDesktop->CompareIDs(NULL, pidlSub, entry))
287 {
288 // We are the desktop, so use pDesktop as pFolder
289 pFolder = pDesktop;
290 }
291 else
292 {
293 // Get an IShellFolder of our pidl
294 hr = pDesktop->BindToObject(entry, NULL, IID_PPV_ARG(IShellFolder, &pFolder));
295 if (!SUCCEEDED(hr))
296 {
297 ILFree(pidlSub);
298 ERR("Can't bind folder to desktop !\n");
299 return FALSE;
300 }
301 }
302 ILFree(pidlSub);
303
304 // TODO: handle hidden folders according to settings !
305 EnumFlags |= SHCONTF_INCLUDEHIDDEN;
306
307 // Enum through objects
308 hr = pFolder->EnumObjects(NULL,EnumFlags,&pEnumIDList);
309
310 // avoid broken IShellFolder implementations that return null pointer with success
311 if (!SUCCEEDED(hr) || !pEnumIDList)
312 {
313 ERR("Can't enum the folder !\n");
314 return FALSE;
315 }
316
317 /* Don't redraw while we add stuff into the tree */
318 SendMessage(WM_SETREDRAW, FALSE, 0);
319 while(SUCCEEDED(pEnumIDList->Next(1, &pidlSub, &fetched)) && pidlSub && fetched)
320 {
321 LPITEMIDLIST pidlSubComplete;
322 pidlSubComplete = ILCombine(entry, pidlSub);
323
324 if (InsertItem(hItem, pFolder, pidlSubComplete, pidlSub, FALSE))
325 uItemCount++;
326 ILFree(pidlSubComplete);
327 ILFree(pidlSub);
328 }
329 pNodeInfo->expanded = TRUE;
330
331 /* Now we can redraw */
332 SendMessage(WM_SETREDRAW, TRUE, 0);
333
334 return (uItemCount > 0) ? TRUE : FALSE;
335 }
336
337 // *** IOleWindow methods ***
338 HRESULT STDMETHODCALLTYPE CExplorerBand::GetWindow(HWND *lphwnd)
339 {
340 if (!lphwnd)
341 return E_INVALIDARG;
342 *lphwnd = m_hWnd;
343 return S_OK;
344 }
345
346 HRESULT STDMETHODCALLTYPE CExplorerBand::ContextSensitiveHelp(BOOL fEnterMode)
347 {
348 UNIMPLEMENTED;
349 return E_NOTIMPL;
350 }
351
352
353 // *** IDockingWindow methods ***
354 HRESULT STDMETHODCALLTYPE CExplorerBand::CloseDW(DWORD dwReserved)
355 {
356 // We do nothing, we don't have anything to save yet
357 TRACE("CloseDW called\n");
358 return S_OK;
359 }
360
361 HRESULT STDMETHODCALLTYPE CExplorerBand::ResizeBorderDW(const RECT *prcBorder, IUnknown *punkToolbarSite, BOOL fReserved)
362 {
363 /* Must return E_NOTIMPL according to MSDN */
364 return E_NOTIMPL;
365 }
366
367 HRESULT STDMETHODCALLTYPE CExplorerBand::ShowDW(BOOL fShow)
368 {
369 fVisible = fShow;
370 ShowWindow(fShow);
371 return S_OK;
372 }
373
374
375 // *** IDeskBand methods ***
376 HRESULT STDMETHODCALLTYPE CExplorerBand::GetBandInfo(DWORD dwBandID, DWORD dwViewMode, DESKBANDINFO *pdbi)
377 {
378 if (!pdbi)
379 {
380 return E_INVALIDARG;
381 }
382 this->dwBandID = dwBandID;
383
384 if (pdbi->dwMask & DBIM_MINSIZE)
385 {
386 pdbi->ptMinSize.x = 200;
387 pdbi->ptMinSize.y = 30;
388 }
389
390 if (pdbi->dwMask & DBIM_MAXSIZE)
391 {
392 pdbi->ptMaxSize.y = -1;
393 }
394
395 if (pdbi->dwMask & DBIM_INTEGRAL)
396 {
397 pdbi->ptIntegral.y = 1;
398 }
399
400 if (pdbi->dwMask & DBIM_ACTUAL)
401 {
402 pdbi->ptActual.x = 200;
403 pdbi->ptActual.y = 30;
404 }
405
406 if (pdbi->dwMask & DBIM_TITLE)
407 {
408 lstrcpyW(pdbi->wszTitle, L"Explorer");
409 }
410
411 if (pdbi->dwMask & DBIM_MODEFLAGS)
412 {
413 pdbi->dwModeFlags = DBIMF_NORMAL | DBIMF_VARIABLEHEIGHT;
414 }
415
416 if (pdbi->dwMask & DBIM_BKCOLOR)
417 {
418 pdbi->dwMask &= ~DBIM_BKCOLOR;
419 }
420 return S_OK;
421 }
422
423
424 // *** IObjectWithSite methods ***
425 HRESULT STDMETHODCALLTYPE CExplorerBand::SetSite(IUnknown *pUnkSite)
426 {
427 HRESULT hr;
428 HWND parentWnd;
429
430 if (pUnkSite == pSite)
431 return S_OK;
432
433 TRACE("SetSite called \n");
434 if (!pUnkSite)
435 {
436 DestroyExplorerBand();
437 DestroyWindow();
438 m_hWnd = NULL;
439 }
440
441 if (pUnkSite != pSite)
442 {
443 pSite = NULL;
444 }
445
446 if(!pUnkSite)
447 return S_OK;
448
449 hr = IUnknown_GetWindow(pUnkSite, &parentWnd);
450 if (!SUCCEEDED(hr))
451 {
452 ERR("Could not get parent's window ! Status: %08lx\n", hr);
453 return E_INVALIDARG;
454 }
455
456 pSite = pUnkSite;
457
458 if (m_hWnd)
459 {
460 // Change its parent
461 SetParent(parentWnd);
462 }
463 else
464 {
465 HWND wnd = CreateWindow(WC_TREEVIEW, NULL,
466 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
467 0, 0, 0, 0, parentWnd, NULL, _AtlBaseModule.GetModuleInstance(), NULL);
468
469 // Subclass the window
470 SubclassWindow(wnd);
471
472 // Initialize our treeview now
473 InitializeExplorerBand();
474 RegisterDragDrop(m_hWnd, dynamic_cast<IDropTarget*>(this));
475 }
476 return S_OK;
477 }
478
479 HRESULT STDMETHODCALLTYPE CExplorerBand::GetSite(REFIID riid, void **ppvSite)
480 {
481 if (!ppvSite)
482 return E_POINTER;
483 *ppvSite = pSite;
484 return S_OK;
485 }
486
487
488 // *** IOleCommandTarget methods ***
489 HRESULT STDMETHODCALLTYPE CExplorerBand::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText)
490 {
491 UNIMPLEMENTED;
492 return E_NOTIMPL;
493 }
494
495 HRESULT STDMETHODCALLTYPE CExplorerBand::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
496 {
497 UNIMPLEMENTED;
498 return E_NOTIMPL;
499 }
500
501
502 // *** IServiceProvider methods ***
503 HRESULT STDMETHODCALLTYPE CExplorerBand::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
504 {
505 UNIMPLEMENTED;
506 return E_NOTIMPL;
507 }
508
509
510 // *** IInputObject methods ***
511 HRESULT STDMETHODCALLTYPE CExplorerBand::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
512 {
513 if (fActivate)
514 {
515 //SetFocus();
516 SetActiveWindow();
517 }
518 // TODO: handle message
519 if(lpMsg)
520 {
521 TranslateMessage(lpMsg);
522 DispatchMessage(lpMsg);
523 }
524 return S_OK;
525 }
526
527 HRESULT STDMETHODCALLTYPE CExplorerBand::HasFocusIO()
528 {
529 return bFocused ? S_OK : S_FALSE;
530 }
531
532 HRESULT STDMETHODCALLTYPE CExplorerBand::TranslateAcceleratorIO(LPMSG lpMsg)
533 {
534 TranslateMessage(lpMsg);
535 DispatchMessage(lpMsg);
536 return S_OK;
537 }
538
539
540 // *** IPersist methods ***
541 HRESULT STDMETHODCALLTYPE CExplorerBand::GetClassID(CLSID *pClassID)
542 {
543 if (!pClassID)
544 return E_POINTER;
545 memcpy(pClassID, &CLSID_ExplorerBand, sizeof(CLSID));
546 return S_OK;
547 }
548
549
550 // *** IPersistStream methods ***
551 HRESULT STDMETHODCALLTYPE CExplorerBand::IsDirty()
552 {
553 UNIMPLEMENTED;
554 return E_NOTIMPL;
555 }
556
557 HRESULT STDMETHODCALLTYPE CExplorerBand::Load(IStream *pStm)
558 {
559 UNIMPLEMENTED;
560 return E_NOTIMPL;
561 }
562
563 HRESULT STDMETHODCALLTYPE CExplorerBand::Save(IStream *pStm, BOOL fClearDirty)
564 {
565 UNIMPLEMENTED;
566 return E_NOTIMPL;
567 }
568
569 HRESULT STDMETHODCALLTYPE CExplorerBand::GetSizeMax(ULARGE_INTEGER *pcbSize)
570 {
571 UNIMPLEMENTED;
572 return E_NOTIMPL;
573 }
574
575
576 // *** IWinEventHandler methods ***
577 HRESULT STDMETHODCALLTYPE CExplorerBand::OnWinEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
578 {
579 if (uMsg == WM_NOTIFY)
580 {
581 NMHDR *pNotifyHeader = (NMHDR*)lParam;
582 switch (pNotifyHeader->code)
583 {
584 case TVN_ITEMEXPANDING:
585 *theResult = OnTreeItemExpanding((LPNMTREEVIEW)lParam);
586 break;
587 case TVN_SELCHANGED:
588 OnSelectionChanged((LPNMTREEVIEW)lParam);
589 break;
590 default:
591 break;
592 }
593 }
594 return S_OK;
595 }
596
597 HRESULT STDMETHODCALLTYPE CExplorerBand::IsWindowOwner(HWND hWnd)
598 {
599 return (hWnd == m_hWnd) ? S_OK : S_FALSE;
600 }
601
602 // *** IBandNavigate methods ***
603 HRESULT STDMETHODCALLTYPE CExplorerBand::Select(long paramC)
604 {
605 UNIMPLEMENTED;
606 return E_NOTIMPL;
607 }
608
609 // *** INamespaceProxy ***
610 HRESULT STDMETHODCALLTYPE CExplorerBand::GetNavigateTarget(long paramC, long param10, long param14)
611 {
612 UNIMPLEMENTED;
613 return E_NOTIMPL;
614 }
615
616 HRESULT STDMETHODCALLTYPE CExplorerBand::Invoke(long paramC)
617 {
618 UNIMPLEMENTED;
619 return E_NOTIMPL;
620 }
621
622 HRESULT STDMETHODCALLTYPE CExplorerBand::OnSelectionChanged(long paramC)
623 {
624 UNIMPLEMENTED;
625 return E_NOTIMPL;
626 }
627
628 HRESULT STDMETHODCALLTYPE CExplorerBand::RefreshFlags(long paramC, long param10, long param14)
629 {
630 UNIMPLEMENTED;
631 return E_NOTIMPL;
632 }
633
634 HRESULT STDMETHODCALLTYPE CExplorerBand::CacheItem(long paramC)
635 {
636 UNIMPLEMENTED;
637 return E_NOTIMPL;
638 }
639
640 // *** IDispatch methods ***
641 HRESULT STDMETHODCALLTYPE CExplorerBand::GetTypeInfoCount(UINT *pctinfo)
642 {
643 UNIMPLEMENTED;
644 return E_NOTIMPL;
645 }
646
647 HRESULT STDMETHODCALLTYPE CExplorerBand::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
648 {
649 UNIMPLEMENTED;
650 return E_NOTIMPL;
651 }
652
653 HRESULT STDMETHODCALLTYPE CExplorerBand::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
654 {
655 UNIMPLEMENTED;
656 return E_NOTIMPL;
657 }
658
659 HRESULT STDMETHODCALLTYPE CExplorerBand::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
660 {
661 UNIMPLEMENTED;
662 return E_NOTIMPL;
663 }
664
665 // *** IDropTarget methods ***
666 HRESULT STDMETHODCALLTYPE CExplorerBand::DragEnter(IDataObject *pObj, DWORD glfKeyState, POINTL pt, DWORD *pdwEffect)
667 {
668 UNIMPLEMENTED;
669 return E_NOTIMPL;
670 }
671
672 HRESULT STDMETHODCALLTYPE CExplorerBand::DragOver(DWORD glfKeyState, POINTL pt, DWORD *pdwEffect)
673 {
674 UNIMPLEMENTED;
675 return E_NOTIMPL;
676 }
677
678 HRESULT STDMETHODCALLTYPE CExplorerBand::DragLeave()
679 {
680 UNIMPLEMENTED;
681 return E_NOTIMPL;
682 }
683
684 HRESULT STDMETHODCALLTYPE CExplorerBand::Drop(IDataObject *pObj, DWORD glfKeyState, POINTL pt, DWORD *pdwEffect)
685 {
686 UNIMPLEMENTED;
687 return E_NOTIMPL;
688 }
689
690 // *** IDropSource methods ***
691 HRESULT STDMETHODCALLTYPE CExplorerBand::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState)
692 {
693 UNIMPLEMENTED;
694 return E_NOTIMPL;
695 }
696
697 HRESULT STDMETHODCALLTYPE CExplorerBand::GiveFeedback(DWORD dwEffect)
698 {
699 UNIMPLEMENTED;
700 return E_NOTIMPL;
701 }