ReactOS  0.4.15-dev-4603-gb922b6d
CDefView.cpp
Go to the documentation of this file.
1 /*
2  * ShellView
3  *
4  * Copyright 1998,1999 <juergen.schmied@debitel.net>
5  * Copyright 2022 Russell Johnson <russell.johnson@superdark.net>
6  *
7  * This is the view visualizing the data provided by the shellfolder.
8  * No direct access to data from pidls should be done from here.
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23  *
24  * FIXME: CheckToolbar: handle the "new folder" and "folder up" button
25  */
26 
27 /*
28 TODO:
29 - Load/Save the view state from/into the stream provided by the ShellBrowser.
30 - When editing starts on item, set edit text to for editing value.
31 - Fix shell view to handle view mode popup exec.
32 - The background context menu should have a pidl just like foreground menus. This
33  causes crashes when dynamic handlers try to use the NULL pidl.
34 - Reorder of columns doesn't work - might be bug in comctl32
35 */
36 
37 #include "precomp.h"
38 
39 #include <atlwin.h>
40 #include <ui/rosctrls.h>
41 
43 
44 typedef struct
45 {
50 
51 #define SHV_CHANGE_NOTIFY WM_USER + 0x1111
52 
53 /* For the context menu of the def view, the id of the items are based on 1 because we need
54  to call TrackPopupMenu and let it use the 0 value as an indication that the menu was canceled */
55 #define CONTEXT_MENU_BASE_ID 1
56 
57 /* Convert client coordinates to listview coordinates */
58 static void
60 {
61  POINT Origin;
62 
63  /* FIXME: LVM_GETORIGIN is broken. See CORE-17266 */
64  if (!ListView_GetOrigin(hwndLV, &Origin))
65  return;
66 
67  ppt->x += Origin.x;
68  ppt->y += Origin.y;
69 }
70 
71 class CDefView :
72  public CWindowImpl<CDefView, CWindow, CControlWinTraits>,
73  public CComObjectRootEx<CComMultiThreadModelNoCS>,
74  public IShellView2,
75  public IFolderView,
76  public IShellFolderView,
77  public IOleCommandTarget,
78  public IDropTarget,
79  public IDropSource,
80  public IViewObject,
81  public IServiceProvider
82 {
83  private:
93  HMENU m_hMenu; /* Handle to the menu bar of the browser */
94  HMENU m_hMenuArrangeModes; /* Handle to the popup menu with the arrange modes */
95  HMENU m_hMenuViewModes; /* Handle to the popup menu with the view modes */
96  HMENU m_hContextMenu; /* Handle to the open context menu */
103  ULONG m_hNotify; /* Change notification handle */
104  HACCEL m_hAccel;
108  // for drag and drop
110  CComPtr<IDropTarget> m_pCurDropTarget; /* The sub-item, which is currently dragged over */
111  CComPtr<IDataObject> m_pCurDataObject; /* The dragged data-object */
112  LONG m_iDragOverItem; /* Dragged over item's index, iff m_pCurDropTarget != NULL */
113  UINT m_cScrollDelay; /* Send a WM_*SCROLL msg every 250 ms during drag-scroll */
114  POINT m_ptLastMousePos; /* Mouse position at last DragOver call */
115  POINT m_ptFirstMousePos; /* Mouse position when the drag operation started */
117  //
119 
122 
126 
128 
129  private:
131  BOOL _Sort();
136  void _HandleStatusBarResize(int width);
137  void _ForceStatusBarResize();
138 
139  public:
140  CDefView();
141  ~CDefView();
142  HRESULT WINAPI Initialize(IShellFolder *shellFolder);
146  void UpdateStatusbar();
147  void CheckToolbar();
148  BOOL CreateList();
149  void UpdateListColors();
150  BOOL InitList();
151  static INT CALLBACK ListViewCompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lpData);
152 
156  int LV_AddItem(PCUITEMID_CHILD pidl);
161  HRESULT FillList();
165  HRESULT FillArrangeAsMenu(HMENU hmenuArrange);
166  HRESULT CheckViewMode(HMENU hmenuView);
169  void OnDeactivate();
170  void DoActivate(UINT uState);
171  HRESULT drag_notify_subitem(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
173  LRESULT OnExplorerCommand(UINT uCommand, BOOL bUseSelection);
174 
175  // *** IOleWindow methods ***
176  virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND *lphwnd);
178 
179  // *** IShellView methods ***
181  virtual HRESULT STDMETHODCALLTYPE EnableModeless(BOOL fEnable);
182  virtual HRESULT STDMETHODCALLTYPE UIActivate(UINT uState);
184  virtual HRESULT STDMETHODCALLTYPE CreateViewWindow(IShellView *psvPrevious, LPCFOLDERSETTINGS pfs, IShellBrowser *psb, RECT *prcView, HWND *phWnd);
190  virtual HRESULT STDMETHODCALLTYPE GetItemObject(UINT uItem, REFIID riid, void **ppv);
191 
192  // *** IShellView2 methods ***
197 
198  // *** IShellView3 methods ***
199  virtual HRESULT STDMETHODCALLTYPE CreateViewWindow3(IShellBrowser *psb, IShellView *psvPrevious, SV3CVW3_FLAGS view_flags, FOLDERFLAGS mask, FOLDERFLAGS flags, FOLDERVIEWMODE mode, const SHELLVIEWID *view_id, RECT *prcView, HWND *hwnd);
200 
201  // *** IFolderView methods ***
202  virtual HRESULT STDMETHODCALLTYPE GetCurrentViewMode(UINT *pViewMode);
205  virtual HRESULT STDMETHODCALLTYPE Item(int iItemIndex, PITEMID_CHILD *ppidl);
208  virtual HRESULT STDMETHODCALLTYPE GetSelectionMarkedItem(int *piItem);
209  virtual HRESULT STDMETHODCALLTYPE GetFocusedItem(int *piItem);
214  virtual HRESULT STDMETHODCALLTYPE SelectItem(int iItem, DWORD dwFlags);
216 
217  // *** IShellFolderView methods ***
232  virtual HRESULT STDMETHODCALLTYPE IsDropOnSource(IDropTarget *drop_target);
237  virtual HRESULT STDMETHODCALLTYPE IsBkDropTarget(IDropTarget *drop_target);
241  virtual HRESULT STDMETHODCALLTYPE SetCallback(IShellFolderViewCB *new_cb, IShellFolderViewCB **old_cb);
243  virtual HRESULT STDMETHODCALLTYPE QuerySupport(UINT *support);
245 
246  // *** IOleCommandTarget methods ***
247  virtual HRESULT STDMETHODCALLTYPE QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[ ], OLECMDTEXT *pCmdText);
248  virtual HRESULT STDMETHODCALLTYPE Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut);
249 
250  // *** IDropTarget methods ***
251  virtual HRESULT STDMETHODCALLTYPE DragEnter(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
252  virtual HRESULT STDMETHODCALLTYPE DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
254  virtual HRESULT STDMETHODCALLTYPE Drop(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
255 
256  // *** IDropSource methods ***
257  virtual HRESULT STDMETHODCALLTYPE QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState);
258  virtual HRESULT STDMETHODCALLTYPE GiveFeedback(DWORD dwEffect);
259 
260  // *** IViewObject methods ***
261  virtual HRESULT STDMETHODCALLTYPE Draw(DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd,
262  HDC hdcTargetDev, HDC hdcDraw, LPCRECTL lprcBounds, LPCRECTL lprcWBounds,
263  BOOL ( STDMETHODCALLTYPE *pfnContinue )(ULONG_PTR dwContinue), ULONG_PTR dwContinue);
264  virtual HRESULT STDMETHODCALLTYPE GetColorSet(DWORD dwDrawAspect, LONG lindex, void *pvAspect,
265  DVTARGETDEVICE *ptd, HDC hicTargetDev, LOGPALETTE **ppColorSet);
266  virtual HRESULT STDMETHODCALLTYPE Freeze(DWORD dwDrawAspect, LONG lindex, void *pvAspect, DWORD *pdwFreeze);
267  virtual HRESULT STDMETHODCALLTYPE Unfreeze(DWORD dwFreeze);
268  virtual HRESULT STDMETHODCALLTYPE SetAdvise(DWORD aspects, DWORD advf, IAdviseSink *pAdvSink);
269  virtual HRESULT STDMETHODCALLTYPE GetAdvise(DWORD *pAspects, DWORD *pAdvf, IAdviseSink **ppAdvSink);
270 
271  // *** IServiceProvider methods ***
272  virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID guidService, REFIID riid, void **ppvObject);
273 
274  // Message handlers
275  LRESULT OnShowWindow(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
276  LRESULT OnGetDlgCode(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
277  LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
282  LRESULT OnNCCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
283  LRESULT OnNCDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
284  LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
286  LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
287  LRESULT OnActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
288  LRESULT OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
289  LRESULT OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
290  LRESULT OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
291  LRESULT OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
293  LRESULT OnCustomItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
296 
298  {
299  static ATL::CWndClassInfo wc =
300  {
302  0, 0, NULL, NULL,
303  LoadCursor(NULL, IDC_ARROW), NULL, NULL, L"SHELLDLL_DefView", NULL
304  },
305  NULL, NULL, IDC_ARROW, TRUE, 0, _T("")
306  };
307  return wc;
308  }
309 
311  {
312  return WindowProc;
313  }
314 
316  {
317  CDefView *pThis;
318  LRESULT result;
319 
320  // Must hold a reference during message handling
321  pThis = reinterpret_cast<CDefView *>(hWnd);
322  pThis->AddRef();
324  pThis->Release();
325  return result;
326  }
327 
351  END_MSG_MAP()
352 
354  // Windows returns E_NOINTERFACE for IOleWindow
355  // COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
356  COM_INTERFACE_ENTRY_IID(IID_IShellView, IShellView)
357  COM_INTERFACE_ENTRY_IID(IID_CDefView, IShellView)
358  COM_INTERFACE_ENTRY_IID(IID_IShellView2, IShellView2)
359  COM_INTERFACE_ENTRY_IID(IID_IFolderView, IFolderView)
360  COM_INTERFACE_ENTRY_IID(IID_IShellFolderView, IShellFolderView)
361  COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget, IOleCommandTarget)
362  COM_INTERFACE_ENTRY_IID(IID_IDropTarget, IDropTarget)
363  COM_INTERFACE_ENTRY_IID(IID_IDropSource, IDropSource)
365  COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider)
366  END_COM_MAP()
367 };
368 
369 /*menu items */
370 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
371 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
372 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
373 
374 #define ID_LISTVIEW 1
375 
376 /*windowsx.h */
377 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
378 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
379 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
380 
382 
384  m_ListView(),
386  m_hMenu(NULL),
391  m_uState(0),
392  m_cidl(0),
393  m_apidl(NULL),
395  m_hNotify(0),
396  m_hAccel(NULL),
397  m_dwAspects(0),
398  m_dwAdvf(0),
399  m_iDragOverItem(0),
400  m_cScrollDelay(0),
404 {
406  ZeroMemory(&m_sortInfo, sizeof(m_sortInfo));
408  ZeroMemory(&m_Category, sizeof(m_Category));
412 
414 }
415 
417 {
418  TRACE(" destroying IShellView(%p)\n", this);
419 
421 
423  {
426  }
427 
428  if (m_hWnd)
429  {
431  }
432 
433  SHFree(m_apidl);
434 }
435 
437 {
438  m_pSFParent = shellFolder;
440 
441  return S_OK;
442 }
443 
444 /**********************************************************
445  *
446  * ##### helperfunctions for communication with ICommDlgBrowser #####
447  */
449 {
450  HRESULT ret = S_OK;
451 
452  if (m_pCommDlgBrowser.p != NULL)
453  {
454  TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl);
455  ret = m_pCommDlgBrowser->IncludeObject(this, pidl);
456  TRACE("-- returns 0x%08x\n", ret);
457  }
458 
459  return ret;
460 }
461 
463 {
464  HRESULT ret = S_FALSE;
465 
466  if (m_pCommDlgBrowser.p != NULL)
467  {
468  TRACE("ICommDlgBrowser::OnDefaultCommand\n");
469  ret = m_pCommDlgBrowser->OnDefaultCommand(this);
470  TRACE("-- returns 0x%08x\n", ret);
471  }
472 
473  return ret;
474 }
475 
477 {
478  HRESULT ret = S_FALSE;
479 
480  if (m_pCommDlgBrowser.p != NULL)
481  {
482  TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags);
483  ret = m_pCommDlgBrowser->OnStateChange(this, uFlags);
484  TRACE("--\n");
485  }
486 
487  return ret;
488 }
489 /**********************************************************
490  * set the toolbar of the filedialog buttons
491  *
492  * - activates the buttons from the shellbrowser according to
493  * the view state
494  */
496 {
497  LRESULT result;
498 
499  TRACE("\n");
500 
501  if (m_pCommDlgBrowser != NULL)
502  {
503  m_pShellBrowser->SendControlMsg(FCW_TOOLBAR, TB_CHECKBUTTON,
505  m_pShellBrowser->SendControlMsg(FCW_TOOLBAR, TB_CHECKBUTTON,
507  m_pShellBrowser->SendControlMsg(FCW_TOOLBAR, TB_ENABLEBUTTON,
509  m_pShellBrowser->SendControlMsg(FCW_TOOLBAR, TB_ENABLEBUTTON,
511  }
512 }
513 
515 {
516  WCHAR szFormat[MAX_PATH] = {0};
517  WCHAR szPartText[MAX_PATH] = {0};
518  UINT cSelectedItems;
519 
520  cSelectedItems = m_ListView.GetSelectedCount();
521  if (cSelectedItems)
522  {
524  StringCchPrintfW(szPartText, _countof(szPartText), szFormat, cSelectedItems);
525  }
526  else
527  {
528  LoadStringW(shell32_hInstance, IDS_OBJECTS, szFormat, _countof(szFormat));
529  StringCchPrintfW(szPartText, _countof(szPartText), szFormat, m_ListView.GetItemCount());
530  }
531 
532  LRESULT lResult;
533  m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXT, 0, (LPARAM)szPartText, &lResult);
534 
535  /* Don't bother with the extra processing if we only have one StatusBar part. */
537  {
538  DWORD uTotalFileSize = 0;
539  WORD uFileFlags = LVNI_ALL;
540  LPARAM pIcon = NULL;
541  INT nItem = -1;
542  bool bIsOnlyFoldersSelected = true;
543 
544  /* If we have something selected then only count selected file sizes. */
545  if (cSelectedItems)
546  {
547  uFileFlags = LVNI_SELECTED;
548  }
549 
550  while ((nItem = m_ListView.GetNextItem(nItem, uFileFlags)) >= 0)
551  {
552  PCUITEMID_CHILD pidl = _PidlByItem(nItem);
553 
554  uTotalFileSize += _ILGetFileSize(pidl, NULL, 0);
555 
556  if (!_ILIsFolder(pidl))
557  {
558  bIsOnlyFoldersSelected = false;
559  }
560  }
561 
562  /* Don't show the file size text if there is 0 bytes in the folder
563  * OR we only have folders selected. */
564  if ((cSelectedItems && !bIsOnlyFoldersSelected) || uTotalFileSize)
565  {
566  StrFormatByteSizeW(uTotalFileSize, szPartText, _countof(szPartText));
567  }
568  else
569  {
570  *szPartText = 0;
571  }
572 
573  m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXT, 1, (LPARAM)szPartText, &lResult);
574 
575  /* If we are in a Recycle Bin folder then show no text for the location part. */
577  {
578  LoadStringW(shell32_hInstance, IDS_MYCOMPUTER, szPartText, _countof(szPartText));
579  pIcon = (LPARAM)m_hMyComputerIcon;
580  }
581 
582  m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETICON, 2, pIcon, &lResult);
583  m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXT, 2, (LPARAM)szPartText, &lResult);
584  }
585 }
586 
587 /**********************************************************
588  *
589  * ##### helperfunctions for initializing the view #####
590  */
591 
592 /**********************************************************
593 * ShellView_CreateList()
594 *
595 * - creates the list view window
596 */
598 {
599  HRESULT hr;
600  DWORD dwStyle, dwExStyle;
601  UINT ViewMode;
602 
603  TRACE("%p\n", this);
604 
607  dwExStyle = WS_EX_CLIENTEDGE;
608 
610  dwStyle |= LVS_ALIGNLEFT;
611  else
612  dwStyle |= LVS_ALIGNTOP | LVS_SHOWSELALWAYS;
613 
614  ViewMode = m_FolderSettings.ViewMode;
615  hr = _DoFolderViewCB(SFVM_DEFVIEWMODE, 0, (LPARAM)&ViewMode);
616  if (SUCCEEDED(hr))
617  {
618  if (ViewMode >= FVM_FIRST && ViewMode <= FVM_LAST)
619  m_FolderSettings.ViewMode = ViewMode;
620  else
621  ERR("Ignoring invalid ViewMode from SFVM_DEFVIEWMODE: %u (was: %u)\n", ViewMode, m_FolderSettings.ViewMode);
622  }
623 
624  switch (m_FolderSettings.ViewMode)
625  {
626  case FVM_ICON:
627  dwStyle |= LVS_ICON;
628  break;
629 
630  case FVM_DETAILS:
631  dwStyle |= LVS_REPORT;
632  break;
633 
634  case FVM_SMALLICON:
635  dwStyle |= LVS_SMALLICON;
636  break;
637 
638  case FVM_LIST:
639  dwStyle |= LVS_LIST;
640  break;
641 
642  default:
643  dwStyle |= LVS_LIST;
644  break;
645  }
646 
648  dwStyle |= LVS_AUTOARRANGE;
649 
651  dwExStyle |= LVS_EX_SNAPTOGRID;
652 
655 
657  dwStyle |= LVS_SINGLESEL;
658 
660  dwExStyle &= ~WS_EX_CLIENTEDGE;
661 
662  RECT rcListView = {0,0,0,0};
663  m_ListView.Create(m_hWnd, rcListView, L"FolderView", dwStyle, dwExStyle, ID_LISTVIEW);
664 
665  if (!m_ListView)
666  return FALSE;
667 
669  m_sortInfo.nHeaderID = -1;
671 
672  /* UpdateShellSettings(); */
673  return TRUE;
674 }
675 
677 {
679  {
680  /* Check if drop shadows option is enabled */
681  BOOL bDropShadow = FALSE;
682  DWORD cbDropShadow = sizeof(bDropShadow);
683 
684  /*
685  * The desktop ListView always take the default desktop colours, by
686  * remaining transparent and letting user32/win32k paint itself the
687  * desktop background color, if any.
688  */
690 
691  SHGetValueW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
692  L"ListviewShadow", NULL, &bDropShadow, &cbDropShadow);
693  if (bDropShadow)
694  {
695  /* Set the icon background transparent */
697  m_ListView.SetTextColor(RGB(255, 255, 255));
698  m_ListView.SetExtendedListViewStyle(LVS_EX_TRANSPARENTSHADOWTEXT, LVS_EX_TRANSPARENTSHADOWTEXT);
699  }
700  else
701  {
702  /* Set the icon background as the same colour as the desktop */
703  COLORREF crDesktop = GetSysColor(COLOR_DESKTOP);
704  m_ListView.SetTextBkColor(crDesktop);
705  if (GetRValue(crDesktop) + GetGValue(crDesktop) + GetBValue(crDesktop) > 128 * 3)
706  m_ListView.SetTextColor(RGB(0, 0, 0));
707  else
708  m_ListView.SetTextColor(RGB(255, 255, 255));
709  m_ListView.SetExtendedListViewStyle(0, LVS_EX_TRANSPARENTSHADOWTEXT);
710  }
711  }
712  else
713  {
714  // text background color
715  COLORREF clrTextBack = m_viewinfo_data.clrTextBack;
716  m_ListView.SetTextBkColor(clrTextBack);
717 
718  // text color
719  COLORREF clrText;
721  clrText = m_viewinfo_data.clrText;
722  else
723  clrText = GetSysColor(COLOR_WINDOWTEXT);
724 
725  m_ListView.SetTextColor(clrText);
726 
727  // Background is painted by the parent via WM_PRINTCLIENT.
728  m_ListView.SetExtendedListViewStyle(LVS_EX_TRANSPARENTBKGND, LVS_EX_TRANSPARENTBKGND);
729  }
730 }
731 
732 /**********************************************************
733 * ShellView_InitList()
734 *
735 * - adds all needed columns to the shellview
736 */
738 {
740  WCHAR szTemp[50];
741  HIMAGELIST big_icons, small_icons;
742 
743  TRACE("%p\n", this);
744 
746 
748 
749  if (m_pSF2Parent)
750  {
751  for (int i = 0; 1; i++)
752  {
753  if (FAILED(m_pSF2Parent->GetDetailsOf(NULL, i, &sd)))
754  break;
755  StrRetToStrNW( szTemp, 50, &sd.str, NULL);
756  m_ListView.InsertColumn(i, szTemp, sd.fmt, sd.cxChar * 8);
757 
758  InsertMenuW(m_hMenuArrangeModes, -1, MF_STRING, 0x30 + i, szTemp);
759  }
760 
762  }
763  else
764  {
765  FIXME("no m_pSF2Parent\n");
766  }
767 
768  Shell_GetImageLists(&big_icons, &small_icons);
770  m_ListView.SetImageList(small_icons, LVSIL_SMALL);
771 
772  return TRUE;
773 }
774 
775 /*************************************************************************
776  * ShellView_ListViewCompareItems
777  *
778  * Compare Function for the Listview (FileOpen Dialog)
779  *
780  * PARAMS
781  * lParam1 [I] the first ItemIdList to compare with
782  * lParam2 [I] the second ItemIdList to compare with
783  * lpData [I] The column ID for the header Ctrl to process
784  *
785  * RETURNS
786  * A negative value if the first item should precede the second,
787  * a positive value if the first item should follow the second,
788  * or zero if the two items are equivalent
789  */
791 {
792  PCUIDLIST_RELATIVE pidl1 = reinterpret_cast<PCUIDLIST_RELATIVE>(lParam1);
793  PCUIDLIST_RELATIVE pidl2 = reinterpret_cast<PCUIDLIST_RELATIVE>(lParam2);
794  CDefView *pThis = reinterpret_cast<CDefView*>(lpData);
795 
796  HRESULT hres = pThis->m_pSFParent->CompareIDs(pThis->m_sortInfo.nHeaderID, pidl1, pidl2);
798  return 0;
799 
800  SHORT nDiff = HRESULT_CODE(hres);
801  if (!pThis->m_sortInfo.bIsAscending)
802  nDiff = -nDiff;
803  return nDiff;
804 }
805 
807 {
808  HWND hHeader;
809  HDITEM hColumn;
810 
811  if (m_ListView.GetWindowLongPtr(GWL_STYLE) & LVS_NOSORTHEADER)
812  return TRUE;
813 
814  hHeader = (HWND)m_ListView.SendMessage(LVM_GETHEADER, 0, 0);
815  ZeroMemory(&hColumn, sizeof(hColumn));
816 
817  /* If the sorting column changed, remove the sorting style from the old column */
818  if ( (m_sortInfo.nLastHeaderID != -1) &&
820  {
821  hColumn.mask = HDI_FORMAT;
822  Header_GetItem(hHeader, m_sortInfo.nLastHeaderID, &hColumn);
823  hColumn.fmt &= ~(HDF_SORTUP | HDF_SORTDOWN);
824  Header_SetItem(hHeader, m_sortInfo.nLastHeaderID, &hColumn);
825  }
826 
827  /* Set the sorting style to the new column */
828  hColumn.mask = HDI_FORMAT;
829  Header_GetItem(hHeader, m_sortInfo.nHeaderID, &hColumn);
830 
831  hColumn.fmt &= (m_sortInfo.bIsAscending ? ~HDF_SORTDOWN : ~HDF_SORTUP );
832  hColumn.fmt |= (m_sortInfo.bIsAscending ? HDF_SORTUP : HDF_SORTDOWN);
833  Header_SetItem(hHeader, m_sortInfo.nHeaderID, &hColumn);
834 
835  /* Sort the list, using the current values of nHeaderID and bIsAscending */
838 }
839 
841 {
842  return reinterpret_cast<PCUITEMID_CHILD>(m_ListView.GetItemData(i));
843 }
844 
846 {
847  return reinterpret_cast<PCUITEMID_CHILD>(lvItem.lParam);
848 }
849 
850 /**********************************************************
851 * LV_FindItemByPidl()
852 */
854 {
855  int cItems = m_ListView.GetItemCount();
856 
857  for (int i = 0; i<cItems; i++)
858  {
859  PCUITEMID_CHILD currentpidl = _PidlByItem(i);
860  if (ILIsEqual(pidl, currentpidl))
861  return i;
862  }
863  return -1;
864 }
865 
866 /**********************************************************
867 * LV_AddItem()
868 */
870 {
871  LVITEMW lvItem;
872 
873  TRACE("(%p)(pidl=%p)\n", this, pidl);
874 
876  return -1;
877 
878  lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; /*set the mask*/
879  lvItem.iItem = m_ListView.GetItemCount(); /*add the item to the end of the list*/
880  lvItem.iSubItem = 0;
881  lvItem.lParam = reinterpret_cast<LPARAM>(ILClone(pidl)); /*set the item's data*/
882  lvItem.pszText = LPSTR_TEXTCALLBACKW; /*get text on a callback basis*/
883  lvItem.iImage = I_IMAGECALLBACK; /*get the image on a callback basis*/
884  lvItem.stateMask = LVIS_CUT;
885 
886  return m_ListView.InsertItem(&lvItem);
887 }
888 
889 /**********************************************************
890 * LV_DeleteItem()
891 */
893 {
894  int nIndex;
895 
896  TRACE("(%p)(pidl=%p)\n", this, pidl);
897 
898  nIndex = LV_FindItemByPidl(pidl);
899 
900  return m_ListView.DeleteItem(nIndex);
901 }
902 
903 /**********************************************************
904 * LV_RenameItem()
905 */
907 {
908  int nItem;
909  LVITEMW lvItem;
910 
911  TRACE("(%p)(pidlold=%p pidlnew=%p)\n", this, pidlOld, pidlNew);
912 
913  nItem = LV_FindItemByPidl(pidlOld);
914 
915  if ( -1 != nItem )
916  {
917  lvItem.mask = LVIF_PARAM; /* only the pidl */
918  lvItem.iItem = nItem;
919  lvItem.iSubItem = 0;
920  m_ListView.GetItem(&lvItem);
921 
922  LPVOID oldPidl = reinterpret_cast<LPVOID>(lvItem.lParam); /* Store the old pidl until the new item is replaced */
923 
924  lvItem.mask = LVIF_PARAM | LVIF_IMAGE | LVIF_TEXT;
925  lvItem.iItem = nItem;
926  lvItem.iSubItem = 0;
927  lvItem.lParam = reinterpret_cast<LPARAM>(ILClone(pidlNew)); /* set the item's data */
928  lvItem.pszText = LPSTR_TEXTCALLBACKW;
929  lvItem.iImage = SHMapPIDLToSystemImageListIndex(m_pSFParent, pidlNew, 0);
930  m_ListView.SetItem(&lvItem);
931  m_ListView.Update(nItem);
932 
933  SHFree(oldPidl); /* Now that the new item is in place, we can safely release the old pidl */
934 
935  return TRUE; /* FIXME: better handling */
936  }
937 
938  return FALSE;
939 }
940 
941 /**********************************************************
942 * LV_ProdItem()
943 */
945 {
946  int nItem;
947  LVITEMW lvItem;
948 
949  TRACE("(%p)(pidl=%p)\n", this, pidl);
950 
951  nItem = LV_FindItemByPidl(pidl);
952 
953  if (-1 != nItem)
954  {
955  lvItem.mask = LVIF_IMAGE;
956  lvItem.iItem = nItem;
957  lvItem.iSubItem = 0;
959  m_ListView.SetItem(&lvItem);
960  m_ListView.Update(nItem);
961  return TRUE;
962  }
963 
964  return FALSE;
965 }
966 
967 /**********************************************************
968 * ShellView_FillList()
969 *
970 * - gets the objectlist from the shellfolder
971 * - sorts the list
972 * - fills the list into the view
973 */
975 {
976  PITEMID_CHILD pidl = static_cast<PITEMID_CHILD>(ptr);
977  CDefView *pThis = static_cast<CDefView *>(arg);
978 
979  /* in a commdlg This works as a filemask*/
980  if (pThis->IncludeObject(pidl) == S_OK)
981  pThis->LV_AddItem(pidl);
982 
983  SHFree(pidl);
984  return TRUE;
985 }
986 
988 {
989  CComPtr<IEnumIDList> pEnumIDList;
990  PITEMID_CHILD pidl;
991  DWORD dwFetched;
992  HRESULT hRes;
993  HDPA hdpa;
994  DWORD dFlags = SHCONTF_NONFOLDERS | SHCONTF_FOLDERS;
995  DWORD dwValue, cbValue;
996 
997  TRACE("%p\n", this);
998 
999  /* determine if there is a setting to show all the hidden files/folders */
1000  dwValue = 1;
1001  cbValue = sizeof(dwValue);
1003  L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
1004  L"Hidden", NULL, &dwValue, &cbValue);
1005  if (dwValue == 1)
1006  {
1007  dFlags |= SHCONTF_INCLUDEHIDDEN;
1008  m_ListView.SendMessageW(LVM_SETCALLBACKMASK, LVIS_CUT, 0);
1009  }
1010 
1011  dwValue = 0;
1012  cbValue = sizeof(dwValue);
1014  L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
1015  L"ShowSuperHidden", NULL, &dwValue, &cbValue);
1016  if (dwValue)
1017  {
1018  dFlags |= SHCONTF_INCLUDESUPERHIDDEN;
1019  m_ListView.SendMessageW(LVM_SETCALLBACKMASK, LVIS_CUT, 0);
1020  }
1021 
1022  /* get the itemlist from the shfolder */
1023  hRes = m_pSFParent->EnumObjects(m_hWnd, dFlags, &pEnumIDList);
1024  if (hRes != S_OK)
1025  {
1026  if (hRes == S_FALSE)
1027  return(NOERROR);
1028  return(hRes);
1029  }
1030 
1031  /* create a pointer array */
1032  hdpa = DPA_Create(16);
1033  if (!hdpa)
1034  {
1035  return(E_OUTOFMEMORY);
1036  }
1037 
1038  /* copy the items into the array*/
1039  while((S_OK == pEnumIDList->Next(1, &pidl, &dwFetched)) && dwFetched)
1040  {
1041  if (DPA_InsertPtr(hdpa, 0x7fff, pidl) == -1)
1042  {
1043  SHFree(pidl);
1044  }
1045  }
1046 
1047  /*turn the listview's redrawing off*/
1049 
1050  DPA_DestroyCallback( hdpa, fill_list, this);
1051 
1052  /* sort the array */
1053  if (m_pSF2Parent)
1054  {
1055  m_pSF2Parent->GetDefaultColumn(NULL, (ULONG*)&m_sortInfo.nHeaderID, NULL);
1056  }
1057  else
1058  {
1059  FIXME("no m_pSF2Parent\n");
1060  }
1062  _Sort();
1063 
1065  {
1068  }
1069 
1070  // load custom background image and custom text color
1073 
1074  /*turn the listview's redrawing back on and force it to draw*/
1076 
1077  UpdateListColors();
1078 
1080  {
1081  // redraw now
1082  m_ListView.InvalidateRect(NULL, TRUE);
1083  }
1084 
1086 
1087  return S_OK;
1088 }
1089 
1091 {
1092  if (m_ListView.IsWindow())
1093  m_ListView.UpdateWindow();
1094  bHandled = FALSE;
1095  return 0;
1096 }
1097 
1099 {
1100  return m_ListView.SendMessageW(uMsg, 0, 0);
1101 }
1102 
1104 {
1105  if (!m_Destroyed)
1106  {
1107  m_Destroyed = TRUE;
1108  if (m_hMenu)
1109  {
1111  m_hMenu = NULL;
1112  }
1115  m_hNotify = NULL;
1117  m_pidlParent = NULL;
1118  }
1119  bHandled = FALSE;
1120  return 0;
1121 }
1122 
1124 {
1125  /* redirect to parent */
1128 
1129  bHandled = FALSE;
1130  return 0;
1131 }
1132 
1133 static VOID
1135 {
1136  INT x0 = prc->left, y0 = prc->top, x1 = prc->right, y1 = prc->bottom;
1137  x0 += dx;
1138  y0 += dy;
1139 
1140  HDC hMemDC = CreateCompatibleDC(hDC);
1141  HGDIOBJ hbmOld = SelectObject(hMemDC, hbm);
1142 
1143  for (INT y = y0; y < y1; y += nHeight)
1144  {
1145  for (INT x = x0; x < x1; x += nWidth)
1146  {
1147  BitBlt(hDC, x, y, nWidth, nHeight, hMemDC, 0, 0, SRCCOPY);
1148  }
1149  }
1150 
1151  SelectObject(hMemDC, hbmOld);
1152  DeleteDC(hMemDC);
1153 }
1154 
1156 {
1157  HDC hDC = (HDC)wParam;
1158 
1159  RECT rc;
1161 
1163  {
1164  BITMAP bm;
1165  if (::GetObject(m_viewinfo_data.hbmBack, sizeof(BITMAP), &bm))
1166  {
1167  INT dx = -(::GetScrollPos(m_ListView, SB_HORZ) % bm.bmWidth);
1168  INT dy = -(::GetScrollPos(m_ListView, SB_VERT) % bm.bmHeight);
1169  DrawTileBitmap(hDC, &rc, m_viewinfo_data.hbmBack, bm.bmWidth, bm.bmHeight, dx, dy);
1170  }
1171  }
1172  else
1173  {
1175  }
1176 
1177  bHandled = TRUE;
1178 
1179  return TRUE;
1180 }
1181 
1183 {
1184  /* Update desktop labels color */
1185  UpdateListColors();
1186 
1187  /* Forward WM_SYSCOLORCHANGE to common controls */
1188  return m_ListView.SendMessageW(uMsg, 0, 0);
1189 }
1190 
1192 {
1193  return reinterpret_cast<LRESULT>(m_pShellBrowser.p);
1194 }
1195 
1197 {
1198  this->AddRef();
1199  bHandled = FALSE;
1200  return 0;
1201 }
1202 
1204 {
1205  this->Release();
1206  bHandled = FALSE;
1207  return 0;
1208 }
1209 
1210 /**********************************************************
1211 * ShellView_OnCreate()
1212 */
1214 {
1217 
1218  TRACE("%p\n", this);
1219 
1221  {
1222  if (FAILED(RegisterDragDrop(m_hWnd, pdt)))
1223  ERR("Registering Drag Drop Failed\n");
1224  }
1225 
1226  /* register for receiving notifications */
1227  m_pSFParent->QueryInterface(IID_PPV_ARG(IPersistFolder2, &ppf2));
1228  if (ppf2)
1229  {
1230  ppf2->GetCurFolder(&m_pidlParent);
1231  }
1232 
1233  if (CreateList())
1234  {
1235  if (InitList())
1236  {
1237  FillList();
1238  }
1239  }
1240 
1242  {
1243  HWND hwndSB;
1244  m_pShellBrowser->GetWindow(&hwndSB);
1245  SetShellWindowEx(hwndSB, m_ListView);
1246  }
1247 
1248  SHChangeNotifyEntry ntreg[1];
1249  ntreg[0].fRecursive = FALSE;
1250  ntreg[0].pidl = m_pidlParent;
1255  1, ntreg);
1256 
1257  /* _DoFolderViewCB(SFVM_GETNOTIFY, ?? ??) */
1258 
1260 
1261  BOOL bPreviousParentSpecial = m_isParentFolderSpecial;
1262 
1263  /* A folder is special if it is the Desktop folder,
1264  * a network folder, or a Control Panel folder. */
1267 
1268  /* Only force StatusBar part refresh if the state
1269  * changed from the previous folder. */
1270  if (bPreviousParentSpecial != m_isParentFolderSpecial)
1271  {
1272  /* This handles changing StatusBar parts. */
1274  }
1275 
1276  UpdateStatusbar();
1277 
1278  return S_OK;
1279 }
1280 
1281 /**********************************************************
1282  * #### Handling of the menus ####
1283  */
1284 
1285 extern "C" DWORD WINAPI SHMenuIndexFromID(HMENU hMenu, UINT uID);
1286 
1288 {
1289  MENUITEMINFOW mii = {sizeof(mii), MIIM_SUBMENU};
1290  if (::GetMenuItemInfoW(hmenu, id, FALSE, &mii))
1291  return mii.hSubMenu;
1292 
1293  return NULL;
1294 }
1295 
1296 /* ReallyGetMenuItemID returns the id of an item even if it opens a submenu,
1297  GetMenuItemID returns -1 if the specified item opens a submenu */
1299 {
1300  MENUITEMINFOW mii = {sizeof(mii), MIIM_ID};
1301  if (::GetMenuItemInfoW(hmenu, i, TRUE, &mii))
1302  return mii.wID;
1303 
1304  return UINT_MAX;
1305 }
1306 
1308 {
1310  if (!hFileMenu)
1311  return E_FAIL;
1312 
1313  /* Cleanup the items added previously */
1314  for (int i = GetMenuItemCount(hFileMenu) - 1; i >= 0; i--)
1315  {
1316  UINT id = GetMenuItemID(hFileMenu, i);
1318  DeleteMenu(hFileMenu, i, MF_BYPOSITION);
1319  }
1320 
1322 
1323  /* Store the context menu in m_pCM and keep it in order to invoke the selected command later on */
1326  if (FAILED_UNEXPECTEDLY(hr))
1327  return hr;
1328 
1330 
1331  hr = m_pCM->QueryContextMenu(hmenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, 0);
1332  if (FAILED_UNEXPECTEDLY(hr))
1333  return hr;
1334 
1335  // TODO: filter or something
1336 
1337  Shell_MergeMenus(hFileMenu, hmenu, 0, 0, 0xFFFF, MM_ADDSEPARATOR | MM_SUBMENUSHAVEIDS);
1338 
1340 
1341  return S_OK;
1342 }
1343 
1345 {
1347  if (!hEditMenu)
1348  return E_FAIL;
1349 
1350  HMENU hmenuContents = ::LoadMenuW(shell32_hInstance, L"MENU_003");
1351  if (!hmenuContents)
1352  return E_FAIL;
1353 
1354  Shell_MergeMenus(hEditMenu, hmenuContents, 0, 0, 0xFFFF, 0);
1355 
1356  ::DestroyMenu(hmenuContents);
1357 
1358  return S_OK;
1359 }
1360 
1362 {
1364  if (!hViewMenu)
1365  return E_FAIL;
1366 
1368  if (!m_hMenuViewModes)
1369  return E_FAIL;
1370 
1373 
1374  return S_OK;
1375 }
1376 
1378 {
1379  /* We only need to fill this once */
1380  if (GetMenuItemID(hmenuArrange, 0) == FCIDM_SHVIEW_AUTOARRANGE)
1381  {
1382  Shell_MergeMenus(hmenuArrange, m_hMenuArrangeModes, 0, 0, 0xFFFF,0);
1383  }
1384 
1385  /* Also check the menu item according to which we sort */
1386  CheckMenuRadioItem(hmenuArrange,
1387  0x30,
1388  0x100,
1389  m_sortInfo.nHeaderID + 0x30,
1390  MF_BYCOMMAND);
1391 
1393  {
1396  }
1397  else
1398  {
1401 
1402  if (GetAutoArrange() == S_OK)
1404  else
1406 
1407  if (_GetSnapToGrid() == S_OK)
1409  else
1411  }
1412 
1413 
1414  return S_OK;
1415 }
1416 
1418 {
1420  {
1421  UINT iItemFirst = FCIDM_SHVIEW_BIGICON;
1422  UINT iItemLast = iItemFirst + FVM_LAST - FVM_FIRST;
1423  UINT iItem = iItemFirst + m_FolderSettings.ViewMode - FVM_FIRST;
1424  CheckMenuRadioItem(hmenuView, iItemFirst, iItemLast, iItem, MF_BYCOMMAND);
1425  }
1426 
1427  return S_OK;
1428 }
1429 
1430 /**********************************************************
1431 * ShellView_GetSelections()
1432 *
1433 * - fills the m_apidl list with the selected objects
1434 *
1435 * RETURNS
1436 * number of selected items
1437 */
1439 {
1440  SHFree(m_apidl);
1441 
1443  m_apidl = static_cast<PCUITEMID_CHILD*>(SHAlloc(m_cidl * sizeof(PCUITEMID_CHILD)));
1444  if (!m_apidl)
1445  {
1446  m_cidl = 0;
1447  return 0;
1448  }
1449 
1450  TRACE("-- Items selected =%u\n", m_cidl);
1451 
1452  UINT i = 0;
1453  int lvIndex = -1;
1454  while ((lvIndex = m_ListView.GetNextItem(lvIndex, LVNI_SELECTED)) > -1)
1455  {
1456  m_apidl[i] = _PidlByItem(lvIndex);
1457  i++;
1458  if (i == m_cidl)
1459  break;
1460  TRACE("-- selected Item found\n");
1461  }
1462 
1463  return m_cidl;
1464 }
1465 
1467 {
1468  CMINVOKECOMMANDINFO cmi;
1469 
1470  ZeroMemory(&cmi, sizeof(cmi));
1471  cmi.cbSize = sizeof(cmi);
1472  cmi.lpVerb = MAKEINTRESOURCEA(uCommand);
1473  cmi.hwnd = m_hWnd;
1474 
1475  if (GetKeyState(VK_SHIFT) & 0x8000)
1476  cmi.fMask |= CMIC_MASK_SHIFT_DOWN;
1477 
1478  if (GetKeyState(VK_CONTROL) & 0x8000)
1479  cmi.fMask |= CMIC_MASK_CONTROL_DOWN;
1480 
1481  HRESULT hr = m_pCM->InvokeCommand(&cmi);
1482  if (FAILED_UNEXPECTEDLY(hr))
1483  return hr;
1484 
1485  return S_OK;
1486 }
1487 
1488 /**********************************************************
1489  * ShellView_OpenSelectedItems()
1490  */
1492 {
1493  HMENU hMenu;
1494  UINT uCommand;
1495  HRESULT hResult;
1496 
1498  if (m_cidl == 0)
1499  return S_OK;
1500 
1501  hResult = OnDefaultCommand();
1502  if (hResult == S_OK)
1503  return hResult;
1504 
1505  hMenu = CreatePopupMenu();
1506  if (!hMenu)
1507  return E_FAIL;
1508 
1510  if (FAILED_UNEXPECTEDLY(hResult))
1511  goto cleanup;
1512 
1513  hResult = m_pCM->QueryContextMenu(hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, CMF_DEFAULTONLY);
1514  if (FAILED_UNEXPECTEDLY(hResult))
1515  goto cleanup;
1516 
1517  uCommand = GetMenuDefaultItem(hMenu, FALSE, 0);
1518  if (uCommand == (UINT)-1)
1519  {
1520  hResult = E_FAIL;
1521  goto cleanup;
1522  }
1523 
1524  InvokeContextMenuCommand(uCommand);
1525 
1526 cleanup:
1527 
1528  if (hMenu)
1529  DestroyMenu(hMenu);
1530 
1531  if (m_pCM)
1532  {
1534  m_pCM.Release();
1535  }
1536 
1537  return hResult;
1538 }
1539 
1540 /**********************************************************
1541  * ShellView_DoContextMenu()
1542  */
1544 {
1545  int x, y;
1546  UINT uCommand;
1547  HRESULT hResult;
1548 
1549  TRACE("(%p)\n", this);
1550 
1552  if (!m_hContextMenu)
1553  return E_FAIL;
1554 
1555  if (lParam != ~0) // unless app key (menu key) was pressed
1556  {
1557  x = GET_X_LPARAM(lParam);
1558  y = GET_Y_LPARAM(lParam);
1559 
1560  LV_HITTESTINFO hittest = { { x, y } };
1561  ScreenToClient(&hittest.pt);
1562  m_ListView.HitTest(&hittest);
1563 
1564  // Right-Clicked item is selected? If selected, no selection change.
1565  // If not selected, then reset the selection and select the item.
1566  if ((hittest.flags & LVHT_ONITEM) &&
1568  {
1569  SelectItem(hittest.iItem, SVSI_SELECT | SVSI_DESELECTOTHERS | SVSI_ENSUREVISIBLE);
1570  }
1571  }
1572 
1574 
1576  if (FAILED_UNEXPECTEDLY(hResult))
1577  goto cleanup;
1578 
1579  /* Use 1 as the first id as we want 0 the mean that the user canceled the menu */
1580  hResult = m_pCM->QueryContextMenu(m_hContextMenu, 0, CONTEXT_MENU_BASE_ID, FCIDM_SHVIEWLAST, CMF_NORMAL);
1581  if (FAILED_UNEXPECTEDLY(hResult))
1582  goto cleanup;
1583 
1584  /* There is no position requested, so try to find one */
1585  if (lParam == ~0)
1586  {
1587  HWND hFocus = ::GetFocus();
1588  int lvIndex = -1;
1589  POINT pt;
1590 
1591  if (hFocus == m_ListView.m_hWnd || m_ListView.IsChild(hFocus))
1592  {
1593  /* Is there an item focused and selected? */
1595  /* If not, find the first selected item */
1596  if (lvIndex < 0)
1597  lvIndex = m_ListView.GetNextItem(-1, LVIS_SELECTED);
1598  }
1599 
1600  /* We got something */
1601  if (lvIndex > -1)
1602  {
1603  /* Let's find the center of the icon */
1604  RECT rc = { LVIR_ICON };
1605  m_ListView.SendMessage(LVM_GETITEMRECT, lvIndex, (LPARAM)&rc);
1606  pt.x = (rc.right + rc.left) / 2;
1607  pt.y = (rc.bottom + rc.top) / 2;
1608  }
1609  else
1610  {
1611  /* We have to drop it somewhere.. */
1612  pt.x = pt.y = 0;
1613  }
1614 
1615  m_ListView.ClientToScreen(&pt);
1616  x = pt.x;
1617  y = pt.y;
1618  }
1619 
1620  uCommand = TrackPopupMenu(m_hContextMenu,
1622  x, y, 0, m_hWnd, NULL);
1623  if (uCommand == 0)
1624  goto cleanup;
1625 
1626  if (uCommand == FCIDM_SHVIEW_OPEN && OnDefaultCommand() == S_OK)
1627  goto cleanup;
1628 
1630 
1631 cleanup:
1632  if (m_pCM)
1633  {
1635  m_pCM.Release();
1636  }
1637 
1638  if (m_hContextMenu)
1639  {
1641  m_hContextMenu = NULL;
1642  }
1643 
1644  return 0;
1645 }
1646 
1648 {
1649  HRESULT hResult;
1650  HMENU hMenu = NULL;
1651 
1652  hResult = GetItemObject( bUseSelection ? SVGIO_SELECTION : SVGIO_BACKGROUND, IID_PPV_ARG(IContextMenu, &m_pCM));
1653  if (FAILED_UNEXPECTEDLY( hResult))
1654  goto cleanup;
1655  if ((uCommand != FCIDM_SHVIEW_DELETE) && (uCommand != FCIDM_SHVIEW_RENAME))
1656  {
1657  hMenu = CreatePopupMenu();
1658  if (!hMenu)
1659  return 0;
1660 
1661  hResult = m_pCM->QueryContextMenu(hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, CMF_NORMAL);
1662  if (FAILED_UNEXPECTEDLY(hResult))
1663  goto cleanup;
1664  }
1665 
1666  if (bUseSelection)
1667  {
1668  // FIXME: we should cache this....
1669  SFGAOF rfg = SFGAO_BROWSABLE | SFGAO_CANCOPY | SFGAO_CANLINK | SFGAO_CANMOVE | SFGAO_CANDELETE | SFGAO_CANRENAME | SFGAO_HASPROPSHEET | SFGAO_FILESYSTEM | SFGAO_FOLDER;
1670  hResult = m_pSFParent->GetAttributesOf(m_cidl, m_apidl, &rfg);
1671  if (FAILED_UNEXPECTEDLY(hResult))
1672  return 0;
1673 
1674  if (!(rfg & SFGAO_CANMOVE) && uCommand == FCIDM_SHVIEW_CUT)
1675  return 0;
1676  if (!(rfg & SFGAO_CANCOPY) && uCommand == FCIDM_SHVIEW_COPY)
1677  return 0;
1678  if (!(rfg & SFGAO_CANDELETE) && uCommand == FCIDM_SHVIEW_DELETE)
1679  return 0;
1680  if (!(rfg & SFGAO_CANRENAME) && uCommand == FCIDM_SHVIEW_RENAME)
1681  return 0;
1682  if (!(rfg & SFGAO_HASPROPSHEET) && uCommand == FCIDM_SHVIEW_PROPERTIES)
1683  return 0;
1684  }
1685 
1686  InvokeContextMenuCommand(uCommand);
1687 
1688 cleanup:
1689  if (m_pCM)
1690  {
1692  m_pCM.Release();
1693  }
1694 
1695  if (hMenu)
1696  DestroyMenu(hMenu);
1697 
1698  return 0;
1699 }
1700 
1701 /**********************************************************
1702  * ##### message handling #####
1703  */
1704 
1705 /**********************************************************
1706 * ShellView_OnSize()
1707 */
1709 {
1710  WORD wWidth, wHeight;
1711 
1712  wWidth = LOWORD(lParam);
1713  wHeight = HIWORD(lParam);
1714 
1715  TRACE("%p width=%u height=%u\n", this, wWidth, wHeight);
1716 
1717  /* Resize the ListView to fit our window */
1718  if (m_ListView)
1719  {
1720  ::MoveWindow(m_ListView, 0, 0, wWidth, wHeight, TRUE);
1721  }
1722 
1723  _DoFolderViewCB(SFVM_SIZE, 0, 0);
1724 
1725  _HandleStatusBarResize(wWidth);
1726  UpdateStatusbar();
1727 
1728  return 0;
1729 }
1730 
1731 /**********************************************************
1732 * ShellView_OnDeactivate()
1733 *
1734 * NOTES
1735 * internal
1736 */
1738 {
1739  TRACE("%p\n", this);
1740 
1741  if (m_uState != SVUIA_DEACTIVATE)
1742  {
1743  // TODO: cleanup menu after deactivation
1744 
1746  }
1747 }
1748 
1750 {
1751  TRACE("%p uState=%x\n", this, uState);
1752 
1753  /*don't do anything if the state isn't really changing */
1754  if (m_uState == uState)
1755  {
1756  return;
1757  }
1758 
1759  if (uState == SVUIA_DEACTIVATE)
1760  {
1761  OnDeactivate();
1762  }
1763  else
1764  {
1766  {
1767  FillEditMenu();
1768  FillViewMenu();
1769  m_pShellBrowser->SetMenuSB(m_hMenu, 0, m_hWnd);
1771  }
1772 
1773  if (SVUIA_ACTIVATE_FOCUS == uState)
1774  {
1775  m_ListView.SetFocus();
1776  }
1777  }
1778 
1779  m_uState = uState;
1780  TRACE("--\n");
1781 }
1782 
1783 /**********************************************************
1784 * ShellView_OnActivate()
1785 */
1787 {
1789  return 0;
1790 }
1791 
1792 /**********************************************************
1793 * ShellView_OnSetFocus()
1794 *
1795 */
1797 {
1798  TRACE("%p\n", this);
1799 
1800  /* Tell the browser one of our windows has received the focus. This
1801  should always be done before merging menus (OnActivate merges the
1802  menus) if one of our windows has the focus.*/
1803 
1804  m_pShellBrowser->OnViewWindowActive(this);
1806 
1807  /* Set the focus to the listview */
1808  m_ListView.SetFocus();
1809 
1810  /* Notify the ICommDlgBrowser interface */
1811  OnStateChange(CDBOSC_SETFOCUS);
1812 
1813  return 0;
1814 }
1815 
1816 /**********************************************************
1817 * ShellView_OnKillFocus()
1818 */
1820 {
1821  TRACE("(%p) stub\n", this);
1822 
1824  /* Notify the ICommDlgBrowser */
1825  OnStateChange(CDBOSC_KILLFOCUS);
1826 
1827  return 0;
1828 }
1829 
1830 /**********************************************************
1831 * ShellView_OnCommand()
1832 *
1833 * NOTES
1834 * the CmdID's are the ones from the context menu
1835 */
1837 {
1838  DWORD dwCmdID;
1839  DWORD dwCmd;
1840  HWND hwndCmd;
1841  int nCount;
1842 
1843  dwCmdID = GET_WM_COMMAND_ID(wParam, lParam);
1844  dwCmd = GET_WM_COMMAND_CMD(wParam, lParam);
1845  hwndCmd = GET_WM_COMMAND_HWND(wParam, lParam);
1846 
1847  TRACE("(%p)->(0x%08x 0x%08x %p) stub\n", this, dwCmdID, dwCmd, hwndCmd);
1848 
1849  switch (dwCmdID)
1850  {
1853  m_ListView.ModifyStyle(LVS_TYPEMASK, LVS_SMALLICON);
1854  CheckToolbar();
1855  break;
1856 
1857  case FCIDM_SHVIEW_BIGICON:
1859  m_ListView.ModifyStyle(LVS_TYPEMASK, LVS_ICON);
1860  CheckToolbar();
1861  break;
1862 
1863  case FCIDM_SHVIEW_LISTVIEW:
1865  m_ListView.ModifyStyle(LVS_TYPEMASK, LVS_LIST);
1866  CheckToolbar();
1867  break;
1868 
1871  m_ListView.ModifyStyle(LVS_TYPEMASK, LVS_REPORT);
1872  CheckToolbar();
1873  break;
1874 
1875  /* the menu-ID's for sorting are 0x30... see shrec.rc */
1876  case 0x30:
1877  case 0x31:
1878  case 0x32:
1879  case 0x33:
1880  m_sortInfo.nHeaderID = dwCmdID - 0x30;
1882  _Sort();
1883  break;
1884 
1887  break;
1889  if (_GetSnapToGrid() == S_OK)
1891  else
1892  ArrangeGrid();
1893  break;
1895  if (GetAutoArrange() == S_OK)
1896  m_ListView.ModifyStyle(LVS_AUTOARRANGE, 0);
1897  else
1898  AutoArrange();
1899  break;
1902  break;
1903 
1905  nCount = m_ListView.GetItemCount();
1906  for (int i=0; i < nCount; i++)
1908  break;
1909 
1910  case FCIDM_SHVIEW_REFRESH:
1911  Refresh();
1912  break;
1913 
1914  case FCIDM_SHVIEW_DELETE:
1915  case FCIDM_SHVIEW_CUT:
1916  case FCIDM_SHVIEW_COPY:
1917  case FCIDM_SHVIEW_RENAME:
1919  case FCIDM_SHVIEW_COPYTO:
1920  case FCIDM_SHVIEW_MOVETO:
1922  return 0;
1923 
1924  return OnExplorerCommand(dwCmdID, TRUE);
1925 
1926  case FCIDM_SHVIEW_INSERT:
1927  case FCIDM_SHVIEW_UNDO:
1930  return OnExplorerCommand(dwCmdID, FALSE);
1931  default:
1932  /* WM_COMMAND messages from the file menu are routed to the CDefView so as to let m_pCM handle the command */
1933  if (m_pCM && dwCmd == 0)
1934  {
1935  InvokeContextMenuCommand(dwCmdID);
1936  }
1937  }
1938 
1939  return 0;
1940 }
1941 
1942 static BOOL
1944 {
1945  HKEY hKey;
1946  LONG error;
1947  DWORD dwValue = FALSE, cbValue;
1948 
1950  L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer",
1951  0, KEY_READ, &hKey);
1952  if (error)
1953  return dwValue;
1954 
1955  cbValue = sizeof(dwValue);
1956  RegQueryValueExW(hKey, L"SelectExtOnRename", NULL, NULL, (LPBYTE)&dwValue, &cbValue);
1957 
1958  RegCloseKey(hKey);
1959  return !!dwValue;
1960 }
1961 
1962 /**********************************************************
1963 * ShellView_OnNotify()
1964 */
1965 
1967 {
1968  UINT CtlID;
1969  LPNMHDR lpnmh;
1970  LPNMLISTVIEW lpnmlv;
1971  NMLVDISPINFOW *lpdi;
1972  PCUITEMID_CHILD pidl;
1973  BOOL unused;
1974 
1975  CtlID = wParam;
1976  lpnmh = (LPNMHDR)lParam;
1977  lpnmlv = (LPNMLISTVIEW)lpnmh;
1978  lpdi = (NMLVDISPINFOW *)lpnmh;
1979 
1980  TRACE("%p CtlID=%u lpnmh->code=%x\n", this, CtlID, lpnmh->code);
1981 
1982  switch (lpnmh->code)
1983  {
1984  case NM_SETFOCUS:
1985  TRACE("-- NM_SETFOCUS %p\n", this);
1986  OnSetFocus(0, 0, 0, unused);
1987  break;
1988 
1989  case NM_KILLFOCUS:
1990  TRACE("-- NM_KILLFOCUS %p\n", this);
1991  OnDeactivate();
1992  /* Notify the ICommDlgBrowser interface */
1993  OnStateChange(CDBOSC_KILLFOCUS);
1994  break;
1995 
1996  case NM_CUSTOMDRAW:
1997  TRACE("-- NM_CUSTOMDRAW %p\n", this);
1998  return CDRF_DODEFAULT;
1999 
2000  case NM_RELEASEDCAPTURE:
2001  TRACE("-- NM_RELEASEDCAPTURE %p\n", this);
2002  break;
2003 
2004  case NM_CLICK:
2005  TRACE("-- NM_CLICK %p\n", this);
2006  break;
2007 
2008  case NM_RCLICK:
2009  TRACE("-- NM_RCLICK %p\n", this);
2010  break;
2011 
2012  case NM_DBLCLK:
2013  TRACE("-- NM_DBLCLK %p\n", this);
2015  break;
2016 
2017  case NM_RETURN:
2018  TRACE("-- NM_RETURN %p\n", this);
2020  break;
2021 
2022  case HDN_ENDTRACKW:
2023  TRACE("-- HDN_ENDTRACKW %p\n", this);
2024  /*nColumn1 = m_ListView.GetColumnWidth(0);
2025  nColumn2 = m_ListView.GetColumnWidth(1);*/
2026  break;
2027 
2028  case LVN_DELETEITEM:
2029  TRACE("-- LVN_DELETEITEM %p\n", this);
2030 
2031  /*delete the pidl because we made a copy of it*/
2032  SHFree(reinterpret_cast<LPVOID>(lpnmlv->lParam));
2033 
2034  break;
2035 
2036  case LVN_DELETEALLITEMS:
2037  TRACE("-- LVN_DELETEALLITEMS %p\n", this);
2038  return FALSE;
2039 
2040  case LVN_INSERTITEM:
2041  TRACE("-- LVN_INSERTITEM (STUB)%p\n", this);
2042  break;
2043 
2044  case LVN_ITEMACTIVATE:
2045  TRACE("-- LVN_ITEMACTIVATE %p\n", this);
2046  OnStateChange(CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
2047  break;
2048 
2049  case LVN_COLUMNCLICK:
2050  m_sortInfo.nHeaderID = lpnmlv->iSubItem;
2053  else
2055  _Sort();
2056  break;
2057 
2058  case LVN_GETDISPINFOA:
2059  case LVN_GETDISPINFOW:
2060  TRACE("-- LVN_GETDISPINFO %p\n", this);
2061  pidl = _PidlByItem(lpdi->item);
2062 
2063  if (lpdi->item.mask & LVIF_TEXT) /* text requested */
2064  {
2065  if (m_pSF2Parent)
2066  {
2067  SHELLDETAILS sd;
2068  if (FAILED_UNEXPECTEDLY(m_pSF2Parent->GetDetailsOf(pidl, lpdi->item.iSubItem, &sd)))
2069  break;
2070 
2071  if (lpnmh->code == LVN_GETDISPINFOA)
2072  {
2073  /* shouldn't happen */
2074  NMLVDISPINFOA *lpdiA = (NMLVDISPINFOA *)lpnmh;
2075  StrRetToStrNA( lpdiA->item.pszText, lpdiA->item.cchTextMax, &sd.str, NULL);
2076  TRACE("-- text=%s\n", lpdiA->item.pszText);
2077  }
2078  else /* LVN_GETDISPINFOW */
2079  {
2080  StrRetToStrNW( lpdi->item.pszText, lpdi->item.cchTextMax, &sd.str, NULL);
2081  TRACE("-- text=%s\n", debugstr_w(lpdi->item.pszText));
2082  }
2083  }
2084  else
2085  {
2086  FIXME("no m_pSF2Parent\n");
2087  }
2088  }
2089  if(lpdi->item.mask & LVIF_IMAGE) /* image requested */
2090  {
2092  }
2093  if(lpdi->item.mask & LVIF_STATE)
2094  {
2095  ULONG attributes = SFGAO_HIDDEN;
2096  if (SUCCEEDED(m_pSFParent->GetAttributesOf(1, &pidl, &attributes)))
2097  {
2098  if (attributes & SFGAO_HIDDEN)
2099  {
2100  lpdi->item.state |= LVIS_CUT;
2101  }
2102  }
2103  }
2104  lpdi->item.mask |= LVIF_DI_SETITEM;
2105  break;
2106 
2107  case LVN_ITEMCHANGED:
2108  TRACE("-- LVN_ITEMCHANGED %p\n", this);
2109  OnStateChange(CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
2110  UpdateStatusbar();
2111  _DoFolderViewCB(SFVM_SELECTIONCHANGED, NULL/* FIXME */, NULL/* FIXME */);
2112  break;
2113 
2114  case LVN_BEGINDRAG:
2115  case LVN_BEGINRDRAG:
2116  TRACE("-- LVN_BEGINDRAG\n");
2117 
2118  if (GetSelections())
2119  {
2121  DWORD dwAttributes = SFGAO_CANCOPY | SFGAO_CANLINK;
2122  DWORD dwEffect = DROPEFFECT_MOVE;
2123 
2124  if (SUCCEEDED(m_pSFParent->GetUIObjectOf(m_hWnd, m_cidl, m_apidl, IID_NULL_PPV_ARG(IDataObject, &pda))))
2125  {
2127 
2128  if (SUCCEEDED(m_pSFParent->GetAttributesOf(m_cidl, m_apidl, &dwAttributes)))
2129  {
2130  dwEffect |= dwAttributes & (SFGAO_CANCOPY | SFGAO_CANLINK);
2131  }
2132 
2134  if (SUCCEEDED(pda->QueryInterface(IID_PPV_ARG(IAsyncOperation, &piaso))))
2135  {
2136  piaso->SetAsyncMode(TRUE);
2137  }
2138 
2139  DWORD dwEffect2;
2140 
2141  m_pSourceDataObject = pda;
2142  m_ptFirstMousePos = params->ptAction;
2145 
2146  HIMAGELIST big_icons, small_icons;
2147  Shell_GetImageLists(&big_icons, &small_icons);
2148  PCUITEMID_CHILD pidl = _PidlByItem(params->iItem);
2149  int iIcon = SHMapPIDLToSystemImageListIndex(m_pSFParent, pidl, 0);
2150  POINT ptItem;
2151  m_ListView.GetItemPosition(params->iItem, &ptItem);
2152 
2153  ImageList_BeginDrag(big_icons, iIcon, params->ptAction.x - ptItem.x, params->ptAction.y - ptItem.y);
2154 
2155  DoDragDrop(pda, this, dwEffect, &dwEffect2);
2156 
2158  }
2159  }
2160  break;
2161 
2162  case LVN_BEGINLABELEDITW:
2163  {
2164  DWORD dwAttr = SFGAO_CANRENAME;
2165  pidl = _PidlByItem(lpdi->item);
2166 
2167  TRACE("-- LVN_BEGINLABELEDITW %p\n", this);
2168 
2169  m_pSFParent->GetAttributesOf(1, &pidl, &dwAttr);
2170  if (SFGAO_CANRENAME & dwAttr)
2171  {
2172  HWND hEdit = reinterpret_cast<HWND>(m_ListView.SendMessage(LVM_GETEDITCONTROL));
2174 
2175  /* smartass-renaming: See CORE-15242 */
2176  if (!(dwAttr & SFGAO_FOLDER) && (dwAttr & SFGAO_FILESYSTEM) &&
2177  (lpdi->item.mask & LVIF_TEXT) && !SelectExtOnRename())
2178  {
2179  WCHAR szFullPath[MAX_PATH];
2180  PIDLIST_ABSOLUTE pidlFull = ILCombine(m_pidlParent, pidl);
2181  SHGetPathFromIDListW(pidlFull, szFullPath);
2182 
2183  if (!SHELL_FS_HideExtension(szFullPath))
2184  {
2185  LPWSTR pszText = lpdi->item.pszText;
2186  LPWSTR pchDotExt = PathFindExtensionW(pszText);
2187  ::PostMessageW(hEdit, EM_SETSEL, 0, pchDotExt - pszText);
2189  }
2190 
2191  ILFree(pidlFull);
2192  }
2193 
2194  m_isEditing = TRUE;
2195  return FALSE;
2196  }
2197 
2198  return TRUE;
2199  }
2200 
2201  case LVN_ENDLABELEDITW:
2202  {
2203  TRACE("-- LVN_ENDLABELEDITW %p\n", this);
2204 
2205  m_isEditing = FALSE;
2206 
2207  if (lpdi->item.pszText)
2208  {
2209  HRESULT hr;
2210  LVITEMW lvItem;
2211 
2212  pidl = _PidlByItem(lpdi->item);
2213  PITEMID_CHILD pidlNew = NULL;
2214  hr = m_pSFParent->SetNameOf(0, pidl, lpdi->item.pszText, SHGDN_INFOLDER, &pidlNew);
2215 
2216  if (SUCCEEDED(hr) && pidlNew)
2217  {
2218  lvItem.mask = LVIF_PARAM|LVIF_IMAGE;
2219  lvItem.iItem = lpdi->item.iItem;
2220  lvItem.iSubItem = 0;
2221  lvItem.lParam = reinterpret_cast<LPARAM>(pidlNew);
2222  lvItem.iImage = SHMapPIDLToSystemImageListIndex(m_pSFParent, pidlNew, 0);
2223  m_ListView.SetItem(&lvItem);
2224  m_ListView.Update(lpdi->item.iItem);
2225  return TRUE;
2226  }
2227  }
2228 
2229  return FALSE;
2230  }
2231 
2232  default:
2233  TRACE("-- %p WM_COMMAND %x unhandled\n", this, lpnmh->code);
2234  break;
2235  }
2236 
2237  return 0;
2238 }
2239 
2240 /*
2241  * This is just a quick hack to make the desktop work correctly.
2242  * ITranslateShellChangeNotify's IsChildID is undocumented, but most likely the way that
2243  * a folder should know if it should update upon a change notification.
2244  * It is exported by merged folders at a minimum.
2245  */
2247 {
2248  if (!pidl1 || !pidl2)
2249  return FALSE;
2250  if (ILIsParent(pidl1, pidl2, TRUE))
2251  return TRUE;
2252 
2253  if (_ILIsDesktop(pidl1))
2254  {
2255  PIDLIST_ABSOLUTE deskpidl;
2257  if (ILIsParent(deskpidl, pidl2, TRUE))
2258  {
2259  ILFree(deskpidl);
2260  return TRUE;
2261  }
2262  ILFree(deskpidl);
2264  if (ILIsParent(deskpidl, pidl2, TRUE))
2265  {
2266  ILFree(deskpidl);
2267  return TRUE;
2268  }
2269  ILFree(deskpidl);
2270  }
2271 
2272  WCHAR szPath1[MAX_PATH], szPath2[MAX_PATH];
2273  LPITEMIDLIST pidl2Clone = ILClone(pidl2);
2274  ILRemoveLastID(pidl2Clone);
2275  if (SHGetPathFromIDListW(pidl1, szPath1) &&
2276  SHGetPathFromIDListW(pidl2Clone, szPath2))
2277  {
2278  if (lstrcmpiW(szPath1, szPath2) == 0)
2279  {
2280  ILFree(pidl2Clone);
2281  return TRUE;
2282  }
2283  }
2284  ILFree(pidl2Clone);
2285 
2286  return FALSE;
2287 }
2288 
2289 /**********************************************************
2290 * ShellView_OnChange()
2291 */
2293 {
2294  HANDLE hChange = (HANDLE)wParam;
2295  DWORD dwProcID = (DWORD)lParam;
2296  PIDLIST_ABSOLUTE *Pidls;
2297  LONG lEvent;
2298  HANDLE hLock = SHChangeNotification_Lock(hChange, dwProcID, &Pidls, &lEvent);
2299  if (hLock == NULL)
2300  {
2301  ERR("hLock == NULL\n");
2302  return FALSE;
2303  }
2304 
2305  BOOL bParent0 = ILIsParentOrSpecialParent(m_pidlParent, Pidls[0]);
2306  BOOL bParent1 = ILIsParentOrSpecialParent(m_pidlParent, Pidls[1]);
2307 
2308  TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls[0], Pidls[1], lParam);
2309 
2310  lEvent &= ~SHCNE_INTERRUPT;
2311  switch (lEvent)
2312  {
2313  case SHCNE_MKDIR:
2314  case SHCNE_CREATE:
2315  if (bParent0)
2316  {
2317  if (LV_FindItemByPidl(ILFindLastID(Pidls[0])) == -1)
2318  {
2319  LV_AddItem(ILFindLastID(Pidls[0]));
2320  }
2321  else
2322  {
2323  LV_ProdItem(ILFindLastID(Pidls[0]));
2324  }
2325  }
2326  break;
2327 
2328  case SHCNE_RMDIR:
2329  case SHCNE_DELETE:
2330  if (bParent0)
2331  LV_DeleteItem(ILFindLastID(Pidls[0]));
2332  break;
2333 
2334  case SHCNE_RENAMEFOLDER:
2335  case SHCNE_RENAMEITEM:
2336  if (bParent0 && bParent1)
2337  LV_RenameItem(ILFindLastID(Pidls[0]), ILFindLastID(Pidls[1]));
2338  else if (bParent0)
2339  LV_DeleteItem(ILFindLastID(Pidls[0]));
2340  else if (bParent1)
2341  LV_AddItem(ILFindLastID(Pidls[1]));
2342  break;
2343 
2344  case SHCNE_UPDATEITEM:
2345  if (bParent0)
2346  LV_RenameItem(ILFindLastID(Pidls[0]), ILFindLastID(Pidls[0]));
2347  break;
2348 
2349  case SHCNE_UPDATEDIR:
2350  Refresh();
2351  break;
2352  }
2353 
2355  return TRUE;
2356 }
2357 
2360 
2361 /**********************************************************
2362 * CDefView::OnCustomItem
2363 */
2365 {
2366  if (!m_pCM.p)
2367  {
2368  /* no menu */
2369  ERR("no menu!!!\n");
2370  return FALSE;
2371  }
2372 
2373  /* The lParam of WM_DRAWITEM WM_MEASUREITEM contain a menu id and this also needs to
2374  be changed to a menu identifier offset */
2375  UINT CmdID;
2376  HRESULT hres = SHGetMenuIdFromMenuMsg(uMsg, lParam, &CmdID);
2377  if (SUCCEEDED(hres))
2379 
2380  /* Forward the message to the IContextMenu2 */
2381  LRESULT result;
2383 
2384  return (SUCCEEDED(hres));
2385 }
2386 
2388 {
2389  /* Wallpaper setting affects drop shadows effect */
2390  if (wParam == SPI_SETDESKWALLPAPER || wParam == 0)
2391  UpdateListColors();
2392 
2393  return S_OK;
2394 }
2395 
2396 /**********************************************************
2397 * CDefView::OnInitMenuPopup
2398 */
2400 {
2401  HMENU hmenu = (HMENU) wParam;
2402  int nPos = LOWORD(lParam);
2403  UINT menuItemId;
2404 
2405  OnCustomItem(uMsg, wParam, lParam, bHandled);
2406 
2408 
2409  if (GetSelections() == 0)
2410  {
2417  }
2418  else
2419  {
2420  // FIXME: Check copyable
2427  }
2428 
2429  /* Lets try to find out what the hell wParam is */
2430  if (hmenu == GetSubMenu(m_hMenu, nPos))
2431  menuItemId = ReallyGetMenuItemID(m_hMenu, nPos);
2432  else if (hViewMenu && hmenu == GetSubMenu(hViewMenu, nPos))
2433  menuItemId = ReallyGetMenuItemID(hViewMenu, nPos);
2434  else if (m_hContextMenu && hmenu == GetSubMenu(m_hContextMenu, nPos))
2435  menuItemId = ReallyGetMenuItemID(m_hContextMenu, nPos);
2436  else
2437  return FALSE;
2438 
2439  switch (menuItemId)
2440  {
2441  case FCIDM_MENU_FILE:
2442  FillFileMenu();
2443  break;
2444  case FCIDM_MENU_VIEW:
2445  case FCIDM_SHVIEW_VIEW:
2447  break;
2448  case FCIDM_SHVIEW_ARRANGE:
2450  break;
2451  }
2452 
2453  return FALSE;
2454 }
2455 
2456 /**********************************************************
2457 *
2458 *
2459 * The INTERFACE of the IShellView object
2460 *
2461 *
2462 **********************************************************
2463 */
2464 
2465 /**********************************************************
2466 * ShellView_GetWindow
2467 */
2469 {
2470  TRACE("(%p)\n", this);
2471 
2472  *phWnd = m_hWnd;
2473 
2474  return S_OK;
2475 }
2476 
2478 {
2479  FIXME("(%p) stub\n", this);
2480 
2481  return E_NOTIMPL;
2482 }
2483 
2484 /**********************************************************
2485 * IShellView_TranslateAccelerator
2486 *
2487 * FIXME:
2488 * use the accel functions
2489 */
2491 {
2492  if (m_isEditing)
2493  return S_FALSE;
2494 
2495  if (lpmsg->message >= WM_KEYFIRST && lpmsg->message <= WM_KEYLAST)
2496  {
2497  if (::TranslateAcceleratorW(m_hWnd, m_hAccel, lpmsg) != 0)
2498  return S_OK;
2499 
2500  TRACE("-- key=0x%04lx\n", lpmsg->wParam) ;
2501  }
2502 
2503  return m_pShellBrowser->TranslateAcceleratorSB(lpmsg, 0);
2504 }
2505 
2507 {
2508  FIXME("(%p) stub\n", this);
2509 
2510  return E_NOTIMPL;
2511 }
2512 
2514 {
2515  TRACE("(%p)->(state=%x) stub\n", this, uState);
2516 
2517  /* don't do anything if the state isn't really changing */
2518  if (m_uState == uState)
2519  {
2520  return S_OK;
2521  }
2522 
2523  /* OnActivate handles the menu merging and internal state */
2524  DoActivate(uState);
2525 
2526  /* only do This if we are active */
2527  if (uState != SVUIA_DEACTIVATE)
2528  {
2530 
2531  /* Set the text for the status bar */
2532  UpdateStatusbar();
2533  }
2534 
2535  return S_OK;
2536 }
2537 
2539 {
2540  TRACE("(%p)\n", this);
2541 
2543 
2545  FillList();
2546 
2547  return S_OK;
2548 }
2549 
2551 {
2552  return CreateViewWindow3(psb, lpPrevView, SV3CVW3_DEFAULT,
2553  (FOLDERFLAGS)lpfs->fFlags, (FOLDERFLAGS)lpfs->fFlags, (FOLDERVIEWMODE)lpfs->ViewMode, NULL, prcView, phWnd);
2554 }
2555 
2557 {
2558  TRACE("(%p)\n", this);
2559 
2560  /* Make absolutely sure all our UI is cleaned up */
2562 
2563  if (m_hAccel)
2564  {
2565  // "Accelerator tables loaded from resources are freed automatically when the application terminates." -- MSDN
2566  m_hAccel = NULL;
2567  }
2568 
2569  if (m_hMenuArrangeModes)
2570  {
2573  }
2574 
2575  if (m_hMenuViewModes)
2576  {
2579  }
2580 
2581  if (m_hMenu)
2582  {
2584  m_hMenu = NULL;
2585  }
2586 
2587  if (m_ListView)
2588  {
2589  m_ListView.DestroyWindow();
2590  }
2591 
2592  if (m_hWnd)
2593  {
2595  DestroyWindow();
2596  }
2597 
2600 
2601  return S_OK;
2602 }
2603 
2605 {
2606  TRACE("(%p)->(%p) vmode=%x flags=%x\n", this, lpfs,
2608 
2609  if (!lpfs)
2610  return E_INVALIDARG;
2611 
2612  *lpfs = m_FolderSettings;
2613  return S_OK;
2614 }
2615 
2617 {
2618  FIXME("(%p) stub\n", this);
2619 
2620  return E_NOTIMPL;
2621 }
2622 
2624 {
2625  FIXME("(%p) stub\n", this);
2626 
2627  return S_OK;
2628 }
2629 
2631 {
2632  int i;
2633 
2634  TRACE("(%p)->(pidl=%p, 0x%08x) stub\n", this, pidl, uFlags);
2635 
2636  i = LV_FindItemByPidl(pidl);
2637  if (i == -1)
2638  return S_OK;
2639 
2640  LVITEMW lvItem = {0};
2641  lvItem.mask = LVIF_STATE;
2643 
2644  while (m_ListView.GetItem(&lvItem))
2645  {
2646  if (lvItem.iItem == i)
2647  {
2648  if (uFlags & SVSI_SELECT)
2649  lvItem.state |= LVIS_SELECTED;
2650  else
2651  lvItem.state &= ~LVIS_SELECTED;
2652 
2653  if (uFlags & SVSI_FOCUSED)
2654  lvItem.state |= LVIS_FOCUSED;
2655  else
2656  lvItem.state &= ~LVIS_FOCUSED;
2657  }
2658  else
2659  {
2660  if (uFlags & SVSI_DESELECTOTHERS)
2661  {
2662  lvItem.state &= ~LVIS_SELECTED;
2663  }
2664  lvItem.state &= ~LVIS_FOCUSED;
2665  }
2666 
2667  m_ListView.SetItem(&lvItem);
2668  lvItem.iItem++;
2669  }
2670 
2671  if (uFlags & SVSI_ENSUREVISIBLE)
2673 
2674  if((uFlags & SVSI_EDIT) == SVSI_EDIT)
2676 
2677  return S_OK;
2678 }
2679 
2681 {
2683 
2684  TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n", this, uItem, debugstr_guid(&riid), ppvOut);
2685 
2686  if (!ppvOut)
2687  return E_INVALIDARG;
2688 
2689  *ppvOut = NULL;
2690 
2691  switch (uItem)
2692  {
2693  case SVGIO_BACKGROUND:
2694  if (IsEqualIID(riid, IID_IContextMenu))
2695  {
2697  if (FAILED_UNEXPECTEDLY(hr))
2698  return hr;
2699 
2700  IUnknown_SetSite(*((IUnknown**)ppvOut), (IShellView *)this);
2701  }
2702  else if (IsEqualIID(riid, IID_IDispatch))
2703  {
2705  {
2707  if (FAILED_UNEXPECTEDLY(hr))
2708  return hr;
2709  }
2710  hr = m_pShellFolderViewDual->QueryInterface(riid, ppvOut);
2711  }
2712  break;
2713 
2714  case SVGIO_SELECTION:
2715  GetSelections();
2716  hr = m_pSFParent->GetUIObjectOf(m_hWnd, m_cidl, m_apidl, riid, 0, ppvOut);
2717  if (FAILED_UNEXPECTEDLY(hr))
2718  return hr;
2719 
2720  if (IsEqualIID(riid, IID_IContextMenu))
2721  IUnknown_SetSite(*((IUnknown**)ppvOut), (IShellView *)this);
2722 
2723  break;
2724  }
2725 
2726  TRACE("-- (%p)->(interface=%p)\n", this, *ppvOut);
2727 
2728  return hr;
2729 }
2730 
2732 {
2733  TRACE("(%p)->(%p), stub\n", this, pViewMode);
2734 
2735  if (!pViewMode)
2736  return E_INVALIDARG;
2737 
2738  *pViewMode = m_FolderSettings.ViewMode;
2739  return S_OK;
2740 }
2741 
2743 {
2744  DWORD dwStyle;
2745  TRACE("(%p)->(%u), stub\n", this, ViewMode);
2746 
2747  /* It's not redundant to check FVM_AUTO because it's a (UINT)-1 */
2748  if (((INT)ViewMode < FVM_FIRST || (INT)ViewMode > FVM_LAST) && ((INT)ViewMode != FVM_AUTO))
2749  return E_INVALIDARG;
2750 
2751  /* Windows before Vista uses LVM_SETVIEW and possibly
2752  LVM_SETEXTENDEDLISTVIEWSTYLE to set the style of the listview,
2753  while later versions seem to accomplish this through other
2754  means. */
2755  switch (ViewMode)
2756  {
2757  case FVM_ICON:
2758  dwStyle = LVS_ICON;
2759  break;
2760  case FVM_DETAILS:
2761  dwStyle = LVS_REPORT;
2762  break;
2763  case FVM_SMALLICON:
2764  dwStyle = LVS_SMALLICON;
2765  break;
2766  case FVM_LIST:
2767  dwStyle = LVS_LIST;
2768  break;
2769  default:
2770  {
2771  FIXME("ViewMode %d not implemented\n", ViewMode);
2772  dwStyle = LVS_LIST;
2773  break;
2774  }
2775  }
2776 
2777  m_ListView.ModifyStyle(LVS_TYPEMASK, dwStyle);
2778 
2779  /* This will not necessarily be the actual mode set above.
2780  This mimics the behavior of Windows XP. */
2781  m_FolderSettings.ViewMode = ViewMode;
2782 
2783  return S_OK;
2784 }
2785 
2787 {
2788  if (m_pSFParent == NULL)
2789  return E_FAIL;
2790 
2791  return m_pSFParent->QueryInterface(riid, ppv);
2792 }
2793 
2795 {
2796  PCUITEMID_CHILD pidl = _PidlByItem(iItemIndex);
2797  if (pidl)
2798  {
2799  *ppidl = ILClone(pidl);
2800  return S_OK;
2801  }
2802 
2803  *ppidl = 0;
2804  return E_INVALIDARG;
2805 }
2806 
2808 {
2809  TRACE("(%p)->(%u %p)\n", this, uFlags, pcItems);
2810 
2811  if (uFlags != SVGIO_ALLVIEW)
2812  FIXME("some flags unsupported, %x\n", uFlags & ~SVGIO_ALLVIEW);
2813 
2815 
2816  return S_OK;
2817 }
2818 
2820 {
2821  return E_NOTIMPL;
2822 }
2823 
2825 {
2826  TRACE("(%p)->(%p)\n", this, piItem);
2827 
2828  *piItem = m_ListView.GetSelectionMark();
2829 
2830  return S_OK;
2831 }
2832 
2834 {
2835  TRACE("(%p)->(%p)\n", this, piItem);
2836 
2837  *piItem = m_ListView.GetNextItem(-1, LVNI_FOCUSED);
2838 
2839  return S_OK;
2840 }
2841 
2843 {
2844  int lvIndex = LV_FindItemByPidl(pidl);
2845  if (lvIndex == -1 || ppt == NULL)
2846  return E_INVALIDARG;
2847 
2848  m_ListView.GetItemPosition(lvIndex, ppt);
2849  return S_OK;
2850 }
2851 
2853 {
2854  TRACE("(%p)->(%p)\n", this, ppt);
2855 
2856  if (!m_ListView)
2857  return S_FALSE;
2858 
2859  if (ppt)
2860  {
2861  SIZE spacing;
2862  m_ListView.GetItemSpacing(spacing);
2863 
2864  ppt->x = spacing.cx;
2865  ppt->y = spacing.cy;
2866  }
2867 
2868  return S_OK;
2869 }
2870 
2872 {
2873  return E_NOTIMPL;
2874 }
2875 
2877 {
2878  return ((m_ListView.GetStyle() & LVS_AUTOARRANGE) ? S_OK : S_FALSE);
2879 }
2880 
2882 {
2883  DWORD dwExStyle = (DWORD)m_ListView.SendMessage(LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0);
2884  return ((dwExStyle & LVS_EX_SNAPTOGRID) ? S_OK : S_FALSE);
2885 }
2886 
2888 {
2889  LVITEMW lvItem;
2890 
2891  TRACE("(%p)->(%d, %x)\n", this, iItem, dwFlags);
2892 
2893  lvItem.state = 0;
2894  lvItem.stateMask = LVIS_SELECTED;
2895 
2896  if (dwFlags & SVSI_ENSUREVISIBLE)
2897  m_ListView.EnsureVisible(iItem, 0);
2898 
2899  /* all items */
2900  if (dwFlags & SVSI_DESELECTOTHERS)
2902 
2903  /* this item */
2904  if (dwFlags & SVSI_SELECT)
2905  lvItem.state |= LVIS_SELECTED;
2906 
2907  if (dwFlags & SVSI_FOCUSED)
2908  lvItem.stateMask |= LVIS_FOCUSED;
2909 
2910  m_ListView.SetItemState(iItem, lvItem.state, lvItem.stateMask);
2911 
2912  if ((dwFlags & SVSI_EDIT) == SVSI_EDIT)
2913  m_ListView.EditLabel(iItem);
2914 
2915  return S_OK;
2916 }
2917 
2919 {
2920  /* Reset the selection */
2922 
2923  int lvIndex;
2924  for (UINT i = 0 ; i < m_cidl; i++)
2925  {
2926  lvIndex = LV_FindItemByPidl(apidl[i]);
2927  if (lvIndex != -1)
2928  {
2929  SelectItem(lvIndex, dwFlags);
2930  m_ListView.SetItemPosition(lvIndex, &apt[i]);
2931  }
2932  }
2933 
2934  return S_OK;
2935 }
2936 
2937 /**********************************************************
2938  * IShellView2 implementation
2939  */
2940 
2942 {
2943  FIXME("(%p)->(%p, %lu) stub\n", this, view_guid, view_type);
2944  return E_NOTIMPL;
2945 }
2946 
2948 {
2949  return CreateViewWindow3(view_params->psbOwner, view_params->psvPrev,
2950  SV3CVW3_DEFAULT, (FOLDERFLAGS)view_params->pfs->fFlags, (FOLDERFLAGS)view_params->pfs->fFlags,
2951  (FOLDERVIEWMODE)view_params->pfs->ViewMode, view_params->pvid, view_params->prcView, &view_params->hwndView);
2952 }
2953 
2955 {
2956  OLEMENUGROUPWIDTHS omw = { { 0, 0, 0, 0, 0, 0 } };
2957 
2958  *hwnd = NULL;
2959 
2960  TRACE("(%p)->(shlview=%p shlbrs=%p rec=%p hwnd=%p vmode=%x flags=%x)\n", this, psvPrevious, psb, prcView, hwnd, mode, flags);
2961  if (prcView != NULL)
2962  TRACE("-- left=%i top=%i right=%i bottom=%i\n", prcView->left, prcView->top, prcView->right, prcView->bottom);
2963 
2964  /* Validate the Shell Browser */
2965  if (psb == NULL || m_hWnd)
2966  return E_UNEXPECTED;
2967 
2968  if (view_flags != SV3CVW3_DEFAULT)
2969  FIXME("unsupported view flags 0x%08x\n", view_flags);
2970 
2971  /* Set up the member variables */
2972  m_pShellBrowser = psb;
2975 
2976  if (view_id)
2977  {
2978  if (IsEqualIID(*view_id, VID_LargeIcons))
2980  else if (IsEqualIID(*view_id, VID_SmallIcons))
2982  else if (IsEqualIID(*view_id, VID_List))
2984  else if (IsEqualIID(*view_id, VID_Details))
2986  else if (IsEqualIID(*view_id, VID_Thumbnails))
2988  else if (IsEqualIID(*view_id, VID_Tile))
2990  else if (IsEqualIID(*view_id, VID_ThumbStrip))
2992  else
2993  FIXME("Ignoring unrecognized VID %s\n", debugstr_guid(view_id));
2994  }
2995 
2996  /* Get our parent window */
2997  m_pShellBrowser->GetWindow(&m_hWndParent);
2998 
2999  /* Try to get the ICommDlgBrowserInterface, adds a reference !!! */
3002  {
3003  TRACE("-- CommDlgBrowser\n");
3004  }
3005 
3007  if (m_hWnd == NULL)
3008  return E_FAIL;
3009 
3010  *hwnd = m_hWnd;
3011 
3012  CheckToolbar();
3013 
3014  if (!*hwnd)
3015  return E_FAIL;
3016 
3018 
3020  UpdateWindow();
3021 
3022  if (!m_hMenu)
3023  {
3024  m_hMenu = CreateMenu();
3025  m_pShellBrowser->InsertMenusSB(m_hMenu, &omw);
3026  TRACE("-- after fnInsertMenusSB\n");
3027  }
3028 
3029  _MergeToolbar();
3030 
3031  return S_OK;
3032 }
3033 
3035 {
3036  FIXME("(%p)->(%p) stub\n", this, new_pidl);
3037  return E_NOTIMPL;
3038 }
3039 
3041 {
3042  FIXME("(%p)->(%p, %u, %p) stub\n", this, item, flags, point);
3043  return E_NOTIMPL;
3044 }
3045 
3046 /**********************************************************
3047  * IShellFolderView implementation
3048  */
3050 {
3051  FIXME("(%p)->(%ld) stub\n", this, sort);
3052  return E_NOTIMPL;
3053 }
3054 
3056 {
3057  FIXME("(%p)->(%p) stub\n", this, sort);
3058  return E_NOTIMPL;
3059 }
3060 
3062 {
3064  return S_OK;
3065 }
3066 
3068 {
3069  m_ListView.ModifyStyle(0, LVS_AUTOARRANGE);
3071  return S_OK;
3072 }
3073 
3075 {
3076  TRACE("(%p)->(%p %p)\n", this, pidl, item);
3077  *item = LV_AddItem(pidl);
3078  return (int)*item >= 0 ? S_OK : E_OUTOFMEMORY;
3079 }
3080 
3082 {
3083  TRACE("(%p)->(%p %d)\n", this, pidl, item);
3084  return Item(item, pidl);
3085 }
3086 
3088 {
3089 
3090  TRACE("(%p)->(%p %p)\n", this, pidl, item);
3091 
3092  if (pidl)
3093  {
3096  }
3097  else
3098  {
3099  *item = 0;
3101  }
3102 
3103  return S_OK;
3104 }
3105 
3107 {
3108  TRACE("(%p)->(%p)\n", this, count);
3110  return S_OK;
3111 }
3112 
3114 {
3115  FIXME("(%p)->(%d %x) stub\n", this, count, flags);
3116  return E_NOTIMPL;
3117 }
3118 
3120 {
3121  FIXME("(%p)->(%p %p %p) stub\n", this, pidl_old, pidl_new, item);
3122  return E_NOTIMPL;
3123 }
3124 
3126 {
3127  FIXME("(%p)->(%p %p) stub\n", this, pidl, item);
3128  return E_NOTIMPL;
3129 }
3130 
3132 {
3133  TRACE("(%p)->(%d)\n", this, redraw);
3135  return S_OK;
3136 }
3137 
3139 {
3140  FIXME("(%p)->(%p) stub\n", this, count);
3141  return E_NOTIMPL;
3142 }
3143 
3145 {
3146  TRACE("(%p)->(%p %p)\n", this, pidl, items);
3147 
3148  *items = GetSelections();
3149 
3150  if (*items)
3151  {
3152  *pidl = static_cast<PCUITEMID_CHILD *>(LocalAlloc(0, *items * sizeof(PCUITEMID_CHILD)));
3153  if (!*pidl)
3154  {
3155  return E_OUTOFMEMORY;
3156  }
3157 
3158  /* it's documented that caller shouldn't PIDLs, only array itself */
3159  memcpy(*pidl, m_apidl, *items * sizeof(PCUITEMID_CHILD));
3160  }
3161 
3162  return S_OK;
3163 }
3164 
3166 {
3167  if ((m_iDragOverItem == -1 || m_pCurDropTarget == NULL) &&
3169  {
3170  return S_OK;
3171  }
3172 
3173  return S_FALSE;
3174 }
3175 
3177 {
3178  if (!pt)
3179  return E_INVALIDARG;
3180 
3181  *pt = m_ptFirstMousePos;
3182  return S_OK;
3183 }
3184 
3186 {
3187  FIXME("(%p)->(%p) stub\n", this, pt);
3188  return E_NOTIMPL;
3189 }
3190 
3192 {
3193  TRACE("(%p)->(%p)\n", this, obj);
3194  return E_NOTIMPL;
3195 }
3196 
3198 {
3199  FIXME("(%p)->(%p %p) stub\n", this, pidl, pt);
3200  return E_NOTIMPL;
3201 }
3202 
3204 {
3205  FIXME("(%p)->(%p) stub\n", this, drop_target);
3206  return E_NOTIMPL;
3207 }
3208 
3210 {
3211  FIXME("(%p)->(%d) stub\n", this, move);
3212  return E_NOTIMPL;
3213 }
3214 
3216 {
3217  FIXME("(%p)->(%p) stub\n", this, obj);
3218  return E_NOTIMPL;
3219 }
3220 
3222 {
3223  FIXME("(%p)->(%p) stub\n", this, spacing);
3224  return E_NOTIMPL;
3225 }
3226 
3227 HRESULT STDMETHODCALLTYPE CDefView::SetCallback(IShellFolderViewCB *new_cb, IShellFolderViewCB **old_cb)
3228 {
3229  if (old_cb)
3230  *old_cb = m_pShellFolderViewCB.Detach();
3231 
3232  m_pShellFolderViewCB = new_cb;
3233  return S_OK;
3234 }
3235 
3237 {
3238  FIXME("(%p)->(%d) stub\n", this, flags);
3239  return E_NOTIMPL;
3240 }
3241 
3243 {
3244  TRACE("(%p)->(%p)\n", this, support);
3245  return S_OK;
3246 }
3247 
3249 {
3250  FIXME("(%p)->(%p) stub\n", this, disp);
3251  return E_NOTIMPL;
3252 }
3253 
3254 /**********************************************************
3255  * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
3256  */
3257 HRESULT WINAPI CDefView::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD *prgCmds, OLECMDTEXT *pCmdText)
3258 {
3259  FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
3260  this, pguidCmdGroup, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText);
3261 
3262  if (!prgCmds)
3263  return E_INVALIDARG;
3264 
3265  for (UINT i = 0; i < cCmds; i++)
3266  {
3267  FIXME("\tprgCmds[%d].cmdID = %d\n", i, prgCmds[i].cmdID);
3268  prgCmds[i].cmdf = 0;
3269  }
3270 
3271  return OLECMDERR_E_UNKNOWNGROUP;
3272 }
3273 
3274 /**********************************************************
3275  * ISVOleCmdTarget_Exec (IOleCommandTarget)
3276  *
3277  * nCmdID is the OLECMDID_* enumeration
3278  */
3279 HRESULT WINAPI CDefView::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
3280 {
3281  FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
3282  this, debugstr_guid(pguidCmdGroup), nCmdID, nCmdexecopt, pvaIn, pvaOut);
3283 
3284  if (!pguidCmdGroup)
3285  return OLECMDERR_E_UNKNOWNGROUP;
3286 
3287  if (IsEqualCLSID(*pguidCmdGroup, m_Category))
3288  {
3289  if (nCmdID == FCIDM_SHVIEW_AUTOARRANGE)
3290  {
3291  if (V_VT(pvaIn) != VT_INT_PTR)
3292  return OLECMDERR_E_NOTSUPPORTED;
3293 
3294  TPMPARAMS params;
3295  params.cbSize = sizeof(params);
3296  params.rcExclude = *(RECT*) V_INTREF(pvaIn);
3297 
3298  if (m_hMenuViewModes)
3299  {
3300  /* Duplicate all but the last two items of the view modes menu */
3301  HMENU hmenuViewPopup = CreatePopupMenu();
3302  Shell_MergeMenus(hmenuViewPopup, m_hMenuViewModes, 0, 0, 0xFFFF, 0);
3303  DeleteMenu(hmenuViewPopup, GetMenuItemCount(hmenuViewPopup) - 1, MF_BYPOSITION);
3304  DeleteMenu(hmenuViewPopup, GetMenuItemCount(hmenuViewPopup) - 1, MF_BYPOSITION);
3305  CheckViewMode(hmenuViewPopup);
3306  TrackPopupMenuEx(hmenuViewPopup, TPM_LEFTALIGN | TPM_TOPALIGN, params.rcExclude.left, params.rcExclude.bottom, m_hWndParent, &params);
3307  ::DestroyMenu(hmenuViewPopup);
3308  }
3309 
3310  // pvaOut is VT_I4 with value 0x403 (cmd id of the new mode maybe?)
3311  V_VT(pvaOut) = VT_I4;
3312  V_I4(pvaOut) = 0x403;
3313  }
3314  }
3315 
3316  if (IsEqualIID(*pguidCmdGroup, CGID_Explorer) &&
3317  (nCmdID == 0x29) &&
3318  (nCmdexecopt == 4) && pvaOut)
3319  return S_OK;
3320 
3321  if (IsEqualIID(*pguidCmdGroup, CGID_ShellDocView) &&
3322  (nCmdID == 9) &&
3323  (nCmdexecopt == 0))
3324  return 1;
3325 
3326  return OLECMDERR_E_UNKNOWNGROUP;
3327 }
3328 
3329 /**********************************************************
3330  * ISVDropTarget implementation
3331  */
3332 
3333 /******************************************************************************
3334  * drag_notify_subitem [Internal]
3335  *
3336  * Figure out the shellfolder object, which is currently under the mouse cursor
3337  * and notify it via the IDropTarget interface.
3338  */
3339 
3340 #define SCROLLAREAWIDTH 20
3341 
3343 {
3344  LONG lResult;
3345  HRESULT hr;
3346  RECT clientRect;
3347 
3348  /* The key state on drop doesn't have MK_LBUTTON or MK_RBUTTON because it
3349  reflects the key state after the user released the button, so we need
3350  to remember the last key state when the button was pressed */
3351  m_grfKeyState = grfKeyState;
3352 
3353  /* Map from global to client coordinates and query the index of the listview-item, which is
3354  * currently under the mouse cursor. */
3355  LVHITTESTINFO htinfo = {{pt.x, pt.y}, LVHT_ONITEM};
3356  ScreenToClient(&htinfo.pt);
3357  lResult = m_ListView.HitTest(&htinfo);
3358 
3359  /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
3360  ::GetClientRect(m_ListView, &clientRect);
3361  if (htinfo.pt.x == m_ptLastMousePos.x && htinfo.pt.y == m_ptLastMousePos.y &&
3362  (htinfo.pt.x < SCROLLAREAWIDTH || htinfo.pt.x > clientRect.right - SCROLLAREAWIDTH ||
3363  htinfo.pt.y < SCROLLAREAWIDTH || htinfo.pt.y > clientRect.bottom - SCROLLAREAWIDTH ))
3364  {
3365  m_cScrollDelay = (m_cScrollDelay + 1) % 5; /* DragOver is called every 50 ms */
3366  if (m_cScrollDelay == 0)
3367  {
3368  /* Mouse did hover another 250 ms over the scroll-area */
3369  if (htinfo.pt.x < SCROLLAREAWIDTH)
3370  m_ListView.SendMessageW(WM_HSCROLL, SB_LINEUP, 0);
3371 
3372  if (htinfo.pt.x > clientRect.right - SCROLLAREAWIDTH)
3373  m_ListView.SendMessageW(WM_HSCROLL, SB_LINEDOWN, 0);
3374 
3375  if (htinfo.pt.y < SCROLLAREAWIDTH)
3376  m_ListView.SendMessageW(WM_VSCROLL, SB_LINEUP, 0);
3377 
3378  if (htinfo.pt.y > clientRect.bottom - SCROLLAREAWIDTH)
3379  m_ListView.SendMessageW(WM_VSCROLL, SB_LINEDOWN, 0);
3380  }
3381  }
3382  else
3383  {
3384  m_cScrollDelay = 0; /* Reset, if the cursor is not over the listview's scroll-area */
3385  }
3386 
3387  m_ptLastMousePos = htinfo.pt;
3389 
3390  /* We need to check if we drag the selection over itself */
3391  if (lResult != -1 && m_pSourceDataObject.p != NULL)
3392  {
3393  PCUITEMID_CHILD pidl = _PidlByItem(lResult);
3394 
3395  for (UINT i = 0; i < m_cidl; i++)
3396  {
3397  if (pidl == m_apidl[i])
3398  {
3399  /* The item that is being draged is hovering itself. */
3400  lResult = -1;
3401  break;
3402  }
3403  }
3404  }
3405 
3406  /* If we are still over the previous sub-item, notify it via DragOver and return. */
3407  if (m_pCurDropTarget && lResult == m_iDragOverItem)
3408  return m_pCurDropTarget->DragOver(grfKeyState, pt, pdwEffect);
3409 
3410  /* We've left the previous sub-item, notify it via DragLeave and Release it. */
3411  if (m_pCurDropTarget)
3412  {
3414  if (pidl)
3415  SelectItem(pidl, 0);
3416 
3417  m_pCurDropTarget->DragLeave();
3419  }
3420 
3421  m_iDragOverItem = lResult;
3422 
3423  if (lResult == -1)
3424  {
3425  /* We are not above one of the listview's subitems. Bind to the parent folder's
3426  * DropTarget interface. */
3427  hr = m_pSFParent->CreateViewObject(NULL, IID_PPV_ARG(IDropTarget,&m_pCurDropTarget));
3428  }
3429  else
3430  {
3431  /* Query the relative PIDL of the shellfolder object represented by the currently
3432  * dragged over listview-item ... */
3433  PCUITEMID_CHILD pidl = _PidlByItem(lResult);
3434 
3435  /* ... and bind m_pCurDropTarget to the IDropTarget interface of an UIObject of this object */
3436  hr = m_pSFParent->GetUIObjectOf(m_ListView, 1, &pidl, IID_NULL_PPV_ARG(IDropTarget, &m_pCurDropTarget));
3437  }
3438 
3440 
3441  /* If anything failed, m_pCurDropTarget should be NULL now, which ought to be a save state. */
3442  if (FAILED(hr))
3443  {
3444  *pdwEffect = DROPEFFECT_NONE;
3445  return hr;
3446  }
3447 
3448  if (m_iDragOverItem != -1)
3449  {
3450  SelectItem(m_iDragOverItem, SVSI_SELECT);
3451  }
3452 
3453  /* Notify the item just entered via DragEnter. */
3454  return m_pCurDropTarget->DragEnter(m_pCurDataObject, grfKeyState, pt, pdwEffect);
3455 }
3456 
3457 HRESULT WINAPI CDefView::DragEnter(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
3458 {
3459  if (*pdwEffect == DROPEFFECT_NONE)
3460  return S_OK;
3461 
3462  /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
3463  m_pCurDataObject = pDataObject;
3464 
3465  HRESULT hr = drag_notify_subitem(grfKeyState, pt, pdwEffect);
3466  if (SUCCEEDED(hr))
3467  {
3468  POINT ptClient = {pt.x, pt.y};
3469  ScreenToClient(&ptClient);
3470  ImageList_DragEnter(m_hWnd, ptClient.x, ptClient.y);
3471  }
3472 
3473  return hr;
3474 }
3475 
3477 {
3478  POINT ptClient = {pt.x, pt.y};
3479  ScreenToClient(&ptClient);
3480  ImageList_DragMove(ptClient.x, ptClient.y);
3481  return drag_notify_subitem(grfKeyState, pt, pdwEffect);
3482 }
3483 
3485 {
3487 
3488  if (m_pCurDropTarget)
3489  {
3490  m_pCurDropTarget->DragLeave();
3492  }
3493 
3494  if (m_pCurDataObject != NULL)
3495  {
3497  }
3498 
3499  m_iDragOverItem = 0;
3500 
3501  return S_OK;
3502 }
3503 
3505 {
3506  RECT rcBound;
3507  INT i, nCount = m_ListView.GetItemCount();
3508  DWORD dwSpacing;
3509  INT dx, dy;
3510  BOOL bSmall = ((m_ListView.GetStyle() & LVS_TYPEMASK) != LVS_ICON);
3511 
3512  /* FIXME: LVM_GETORIGIN is broken. See CORE-17266 */
3513  pt.x += m_ListView.GetScrollPos(SB_HORZ);
3514  pt.y += m_ListView.GetScrollPos(SB_VERT);
3515 
3516  if (m_ListView.GetStyle() & LVS_ALIGNLEFT)
3517  {
3518  // vertically
3519  for (i = 0; i < nCount; ++i)
3520  {
3521  dwSpacing = ListView_GetItemSpacing(m_ListView, bSmall);
3522  dx = LOWORD(dwSpacing);
3523  dy = HIWORD(dwSpacing);
3525  rcBound.right = rcBound.left + dx;
3526  rcBound.bottom = rcBound.top + dy;
3527  if (pt.x < rcBound.right && pt.y < (rcBound.top + rcBound.bottom) / 2)
3528  {
3529  return i;
3530  }
3531  }
3532  for (i = nCount - 1; i >= 0; --i)
3533  {
3535  if (rcBound.left < pt.x && rcBound.top < pt.y)
3536  {
3537  return i + 1;
3538  }
3539  }
3540  }
3541  else
3542  {
3543  // horizontally
3544  for (i = 0; i < nCount; ++i)
3545  {
3546  dwSpacing = ListView_GetItemSpacing(m_ListView, bSmall);
3547  dx = LOWORD(dwSpacing);
3548  dy = HIWORD(dwSpacing);
3550  rcBound.right = rcBound.left + dx;
3551  rcBound.bottom = rcBound.top + dy;
3552  if (pt.y < rcBound.bottom && pt.x < rcBound.left)
3553  {
3554  return i;
3555  }
3556  if (pt.y < rcBound.bottom && pt.x < rcBound.right)
3557  {
3558  return i + 1;
3559  }
3560  }
3561  for (i = nCount - 1; i >= 0; --i)
3562  {
3564  if (rcBound.left < pt.x && rcBound.top < pt.y)
3565  {
3566  return i + 1;
3567  }
3568  }
3569  }
3570 
3571  return nCount;
3572 }
3573 
3575 {
3576  LRESULT lResult;
3577 
3579  {
3580  int nPartArray[] = {-1};
3581  m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETPARTS, _countof(nPartArray), (LPARAM)nPartArray, &lResult);
3582  return;
3583  }
3584 
3585  int nFileSizePartLength = 125;
3586  const int nLocationPartLength = 150;
3587  const int nRightPartsLength = nFileSizePartLength + nLocationPartLength;
3588  int nObjectsPartLength = nWidth - nRightPartsLength;
3589 
3590  /* If the window is small enough just divide each part into thirds
3591  * This is the behavior of Windows Server 2003. */
3592  if (nObjectsPartLength <= nLocationPartLength)
3593  nObjectsPartLength = nFileSizePartLength = nWidth / 3;
3594 
3595  int nPartArray[] = {nObjectsPartLength, nObjectsPartLength + nFileSizePartLength, -1};
3596 
3597  m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETPARTS, _countof(nPartArray), (LPARAM)nPartArray, &lResult);
3598 }
3599 
3601 {
3602  /* Get the handle for the status bar */
3603  HWND fStatusBar;
3604  m_pShellBrowser->GetControlWindow(FCW_STATUS, &fStatusBar);
3605 
3606  /* Get the size of our status bar */
3607  RECT statusBarSize;
3608  ::GetWindowRect(fStatusBar, &statusBarSize);
3609 
3610  /* Resize the status bar */
3611  _HandleStatusBarResize(statusBarSize.right - statusBarSize.left);
3612 }
3613 
3615 
3616 static INT CALLBACK
3617 SelectionMoveCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
3618 {
3619  CLParamIndexMap *pmap = (CLParamIndexMap *)lParamSort;
3620  INT i1 = pmap->Lookup(lParam1), i2 = pmap->Lookup(lParam2);
3621  if (i1 < i2)
3622  return -1;
3623  if (i1 > i2)
3624  return 1;
3625  return 0;
3626 }
3627 
3629 {
3630  // get insertable index from position
3631  INT iPosition = _FindInsertableIndexFromPoint(pt);
3632 
3633  // create identity mapping of indexes
3635  INT nCount = m_ListView.GetItemCount();
3636  for (INT i = 0; i < nCount; ++i)
3637  {
3638  array.Add(i);
3639  }
3640 
3641  // re-ordering mapping
3642  INT iItem = -1;
3643  while ((iItem = m_ListView.GetNextItem(iItem, LVNI_SELECTED)) >= 0)
3644  {
3645  INT iFrom = iItem, iTo = iPosition;
3646  if (iFrom < iTo)
3647  --iTo;
3648  if (iFrom >= nCount)
3649  iFrom = nCount - 1;
3650  if (iTo >= nCount)
3651  iTo = nCount - 1;
3652 
3653  // shift indexes by swapping (like a bucket relay)
3654  if (iFrom < iTo)
3655  {
3656  for (INT i = iFrom; i < iTo; ++i)
3657  {
3658  // swap array[i] and array[i + 1]
3659  INT tmp = array[i];
3660  array[i] = array[i + 1];
3661  array[i + 1] = tmp;
3662  }
3663  }
3664  else
3665  {
3666  for (INT i = iFrom; i > iTo; --i)
3667  {
3668  // swap array[i] and array[i - 1]
3669  INT tmp = array[i];
3670  array[i] = array[i - 1];
3671  array[i - 1] = tmp;
3672  }
3673  }
3674  }
3675 
3676  // create mapping (ListView's lParam to index) from array
3678  for (INT i = 0; i < nCount; ++i)
3679  {
3681  map.Add(lParam, i);
3682  }
3683 
3684  // finally sort
3686 }
3687 
3688 HRESULT WINAPI CDefView::Drop(IDataObject* pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
3689 {
3692 
3693  if ((IsDropOnSource(NULL) == S_OK) &&
3694  (*pdwEffect & DROPEFFECT_MOVE) &&
3696  {
3697  if (m_pCurDropTarget)
3698  {
3699  m_pCurDropTarget->DragLeave();
3701  }
3702 
3703  POINT ptDrop = { pt.x, pt.y };
3704  ::ScreenToClient(m_ListView, &ptDrop);
3705  ::ClientToListView(m_ListView, &ptDrop);
3706  m_ptLastMousePos = ptDrop;
3707 
3709  if (m_ListView.GetStyle() & LVS_AUTOARRANGE)
3710  {
3712  }
3713  else
3714  {
3715  POINT ptItem;
3716  INT iItem = -1;
3717  while ((iItem = m_ListView.GetNextItem(iItem, LVNI_SELECTED)) >= 0)
3718  {
3719  if (m_ListView.GetItemPosition(iItem, &ptItem))
3720  {
3721  ptItem.x += m_ptLastMousePos.x - m_ptFirstMousePos.x;
3722  ptItem.y += m_ptLastMousePos.y - m_ptFirstMousePos.y;
3723  m_ListView.SetItemPosition(iItem, &ptItem);
3724  }
3725  }
3726  }
3728  }
3729  else if (m_pCurDropTarget)
3730  {
3731  m_pCurDropTarget->Drop(pDataObject, grfKeyState, pt, pdwEffect);
3733  }
3734 
3736  m_iDragOverItem = 0;
3737  return S_OK;
3738 }
3739 
3740 /**********************************************************
3741  * ISVDropSource implementation
3742  */
3743 
3745 {
3746  TRACE("(%p)\n", this);
3747 
3748  if (fEscapePressed)
3749  return DRAGDROP_S_CANCEL;
3750  else if (!(grfKeyState & MK_LBUTTON) && !(grfKeyState & MK_RBUTTON))
3751  return DRAGDROP_S_DROP;
3752  else
3753  return S_OK;
3754 }
3755 
3757 {
3758  TRACE("(%p)\n", this);
3759 
3761 }
3762 
3763 /**********************************************************
3764  * ISVViewObject implementation
3765  */
3766 
3767 HRESULT WINAPI CDefView::Draw(DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd, HDC hdcTargetDev, HDC hdcDraw, LPCRECTL lprcBounds, LPCRECTL lprcWBounds, BOOL (CALLBACK *pfnContinue)(ULONG_PTR dwContinue), ULONG_PTR dwContinue)
3768 {
3769  FIXME("Stub: this=%p\n", this);
3770 
3771  return E_NOTIMPL;
3772 }
3773 
3774 HRESULT WINAPI CDefView::GetColorSet(DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd, HDC hicTargetDevice, LOGPALETTE **ppColorSet)
3775 {
3776  FIXME("Stub: this=%p\n", this);
3777 
3778  return E_NOTIMPL;
3779 }
3780 
3781 HRESULT WINAPI CDefView::Freeze(DWORD dwDrawAspect, LONG lindex, void *pvAspect, DWORD *pdwFreeze)
3782 {
3783  FIXME("Stub: this=%p\n", this);
3784 
3785  return E_NOTIMPL;
3786 }
3787 
3789 {
3790  FIXME("Stub: this=%p\n", this);
3791 
3792  return E_NOTIMPL;
3793 }
3794 
3796 {
3797  FIXME("partial stub: %p 0x%08x 0x%08x %p\n", this, aspects, advf, pAdvSink);
3798 
3799  /* FIXME: we set the AdviseSink, but never use it to send any advice */
3800  m_pAdvSink = pAdvSink;
3801  m_dwAspects = aspects;
3802  m_dwAdvf = advf;
3803 
3804  return S_OK;
3805 }
3806 
3807 HRESULT WINAPI CDefView::GetAdvise(DWORD *pAspects, DWORD *pAdvf, IAdviseSink **ppAdvSink)
3808 {
3809  TRACE("this=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n", this, pAspects, pAdvf, ppAdvSink);
3810 
3811  if (ppAdvSink)
3812  {
3813  *ppAdvSink = m_pAdvSink;
3814  m_pAdvSink.p->AddRef();
3815  }
3816 
3817  if (pAspects)
3818  *pAspects = m_dwAspects;
3819 
3820  if (pAdvf)
3821  *pAdvf = m_dwAdvf;
3822 
3823  return S_OK;
3824 }
3825 
3827 {
3828  if (IsEqualIID(guidService, SID_IShellBrowser))
3829  return m_pShellBrowser->QueryInterface(riid, ppvObject);
3830  else if(IsEqualIID(guidService, SID_IFolderView))
3831  return QueryInterface(riid, ppvObject);
3832 
3833  return E_NOINTERFACE;
3834 }
3835 
3837 {
3839  HRESULT hr = S_OK;
3840 
3841  hr = IUnknown_QueryService(m_pShellBrowser, IID_IExplorerToolbar, IID_PPV_ARG(IExplorerToolbar, &ptb));
3842  if (FAILED(hr))
3843  return hr;
3844 
3845  m_Category = CGID_DefViewFrame;
3846 
3847  hr = ptb->SetCommandTarget(static_cast<IOleCommandTarget*>(this), &m_Category, 0);
3848  if (FAILED(hr))
3849  return hr;
3850 
3851  if (hr == S_FALSE)
3852  return S_OK;
3853 
3854 #if 0
3855  hr = ptb->AddButtons(&m_Category, buttonsCount, buttons);
3856  if (FAILED(hr))
3857  return hr;
3858 #endif
3859 
3860  return S_OK;
3861 }
3862 
3864 {
3865  HRESULT hr = E_NOTIMPL;
3866 
3868  {
3869  hr = m_pShellFolderViewCB->MessageSFVCB(uMsg, wParam, lParam);
3870  }
3871 
3872  return hr;
3873 }
3874 
3876 {
3877  return ShellObjectCreatorInit<CDefView>(pFolder, riid, ppvOut);
3878 }
3879 
3881  LPCSFV psvcbi, /* [in] shelltemplate struct */
3882  IShellView **ppsv) /* [out] IShellView pointer */
3883 {
3884  CComPtr<IShellView> psv;
3885  HRESULT hRes;
3886 
3887  TRACE("sf=%p pidl=%p cb=%p mode=0x%08x parm=%p\n",
3888  psvcbi->pshf, psvcbi->pidl, psvcbi->pfnCallback,
3889  psvcbi->fvm, psvcbi->psvOuter);
3890 
3891  *ppsv = NULL;
3892  hRes = CDefView_CreateInstance(psvcbi->pshf, IID_PPV_ARG(IShellView, &psv));
3893  if (FAILED_UNEXPECTEDLY(hRes))
3894  return hRes;
3895 
3896  *ppsv = psv.Detach();
3897  return hRes;
3898 }
3899 
3901  IShellView **ppsv)
3902 {
3903  CComPtr<IShellView> psv;
3904  HRESULT hRes;
3905 
3906  if (!ppsv)
3907  return E_INVALIDARG;
3908 
3909  *ppsv = NULL;
3910 
3911  if (!pcsfv || pcsfv->cbSize != sizeof(*pcsfv))
3912  return E_INVALIDARG;
3913 
3914  TRACE("sf=%p outer=%p callback=%p\n",
3915  pcsfv->pshf, pcsfv->psvOuter, pcsfv->psfvcb);
3916 
3917  hRes = CDefView_CreateInstance(pcsfv->pshf, IID_PPV_ARG(IShellView, &psv));
3918  if (FAILED(hRes))
3919  return hRes;
3920 
3921  if (pcsfv->psfvcb)
3922  {
3924  if (SUCCEEDED(psv->QueryInterface(IID_PPV_ARG(IShellFolderView, &sfv))))
3925  {
3926  sfv->SetCallback(pcsfv->psfvcb, NULL);
3927  }
3928  }
3929 
3930  *ppsv = psv.Detach();
3931  return hRes;
3932 }
#define SHCNE_MKDIR
Definition: shlobj.h:1732
HRESULT FillViewMenu()
Definition: CDefView.cpp:1361
#define WS_CLIPSIBLINGS
Definition: pedump.c:618
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG y1
Definition: winddi.h:3706
HMENU m_hMenuArrangeModes
Definition: CDefView.cpp:94
HRESULT CDefView_CreateInstance(IShellFolder *pFolder, REFIID riid, LPVOID *ppvOut)
Definition: CDefView.cpp:3875
HRESULT FillEditMenu()
Definition: CDefView.cpp:1344
POINT m_ptFirstMousePos
Definition: CDefView.cpp:115
#define FCIDM_SHVIEW_UNDO
Definition: shresdef.h:798
virtual HRESULT STDMETHODCALLTYPE SetItemPos(PCUITEMID_CHILD pidl, POINT *pt)
Definition: CDefView.cpp:3197
int LV_FindItemByPidl(PCUITEMID_CHILD pidl)
Definition: CDefView.cpp:853
HRESULT FillArrangeAsMenu(HMENU hmenuArrange)
Definition: CDefView.cpp:1377
DWORD_PTR GetItemData(int i)
Definition: rosctrls.h:204
LPWSTR WINAPI StrFormatByteSizeW(LONGLONG llBytes, LPWSTR lpszDest, UINT cchMax)
Definition: string.c:2380
#define NM_KILLFOCUS
Definition: commctrl.h:136
HMENU WINAPI CreateMenu(void)
Definition: menu.c:837
GLint GLint GLsizei width
Definition: gl.h:1546
virtual HRESULT STDMETHODCALLTYPE SetAdvise(DWORD aspects, DWORD advf, IAdviseSink *pAdvSink)
Definition: CDefView.cpp:3795
#define WM_SYSCOLORCHANGE
Definition: winuser.h:1613
virtual HRESULT STDMETHODCALLTYPE DestroyViewWindow()
Definition: CDefView.cpp:2556
void WINAPI DPA_DestroyCallback(HDPA hdpa, PFNDPAENUMCALLBACK enumProc, LPVOID lParam)
Definition: dpa.c:1003
BOOL GetScrollPos(int nBar)
Definition: atlwin.h:678
#define LVN_BEGINRDRAG
Definition: commctrl.h:3141
static HICON
Definition: imagelist.c:84
int iImage
Definition: commctrl.h:2367
#define FCIDM_SHVIEW_INVERTSELECTION
Definition: shresdef.h:803
int LV_AddItem(PCUITEMID_CHILD pidl)
Definition: CDefView.cpp:869
#define FCIDM_SHVIEW_LISTVIEW
Definition: shresdef.h:807
BOOL m_Destroyed
Definition: CDefView.cpp:124
#define REFIID
Definition: guiddef.h:118
WINE_DEFAULT_DEBUG_CHANNEL(shell)
HACCEL m_hAccel
Definition: CDefView.cpp:104
#define SHCNE_RMDIR
Definition: shlobj.h:1733
#define FCIDM_TB_REPORTVIEW
Definition: shresdef.h:827
UINT m_cScrollDelay
Definition: CDefView.cpp:113
virtual HRESULT STDMETHODCALLTYPE DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
Definition: CDefView.cpp:3476
const GUID IID_IViewObject
BOOL MoveWindow(int x, int y, int nWidth, int nHeight, BOOL bRepaint=TRUE)
Definition: atlwin.h:992
virtual HRESULT STDMETHODCALLTYPE GetAutoArrange()
Definition: CDefView.cpp:2876
virtual HRESULT STDMETHODCALLTYPE Refresh()
Definition: CDefView.cpp:2538
void WINAPI ILFree(LPITEMIDLIST pidl)
Definition: pidl.c:925
#define E_NOINTERFACE
Definition: winerror.h:2364
HDPA WINAPI DPA_Create(INT nGrow)
Definition: dpa.c:950
Definition: compat.h:2157
#define LVN_BEGINDRAG
Definition: commctrl.h:3140
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
HRESULT _GetSnapToGrid()
Definition: CDefView.cpp:2881
#define MF_BYCOMMAND
Definition: winuser.h:202
HRESULT WINAPI CDefViewDual_Constructor(REFIID riid, LPVOID *ppvOut)
HRESULT WINAPI SHLimitInputEdit(HWND hWnd, IShellFolder *psf)
Definition: shellord.c:2780
#define LVSIL_SMALL
Definition: commctrl.h:2299
virtual HRESULT STDMETHODCALLTYPE Select(UINT flags)
Definition: CDefView.cpp:3236
virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
Definition: CDefView.cpp:3826
long y
Definition: polytest.cpp:48
#define FCIDM_SHVIEW_SNAPTOGRID
Definition: shresdef.h:811
#define WM_GETDLGCODE
Definition: winuser.h:1676
#define LVM_GETEDITCONTROL
Definition: commctrl.h:2542
UINT WINAPI Shell_MergeMenus(HMENU hmDst, HMENU hmSrc, UINT uInsert, UINT uIDAdjust, UINT uIDAdjustMax, ULONG uFlags)
Definition: shlmenu.c:856
#define WM_CONTEXTMENU
Definition: richedit.h:64
HRESULT OpenSelectedItems()
Definition: CDefView.cpp:1491
LRESULT OnPrintClient(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: CDefView.cpp:1155
#define FCIDM_SHVIEW_AUTOARRANGE
Definition: shresdef.h:810
#define IDS_OBJECTS_SELECTED
Definition: shresdef.h:272
HRESULT hr
Definition: shlfolder.c:183
#define error(str)
Definition: mkdosfs.c:1605
GLint x0
Definition: linetemp.h:95
static HMENU hmenu
Definition: win.c:66
IShellFolderViewCB * psfvcb
Definition: shlobj.h:1285
GLuint64EXT * result
Definition: glext.h:11304
Definition: scsiwmi.h:51
#define RGB(r, g, b)
Definition: precomp.h:62
#define NOERROR
Definition: winerror.h:2354
HRESULT WINAPI Initialize(IShellFolder *shellFolder)
Definition: CDefView.cpp:436
BOOL WINAPI InsertMenuW(_In_ HMENU, _In_ UINT, _In_ UINT, _In_ UINT_PTR, _In_opt_ LPCWSTR)
#define MK_LBUTTON
Definition: winuser.h:2347
long x
Definition: polytest.cpp:48
EXTERN_C BOOL WINAPI SHChangeNotification_Unlock(HANDLE hLock)
BOOL m_isEditing
Definition: CDefView.cpp:120
#define LVIR_ICON
Definition: commctrl.h:2473
#define CSIDL_COMMON_DESKTOPDIRECTORY
Definition: shlobj.h:2036
#define LVS_SHOWSELALWAYS
Definition: commctrl.h:2267
virtual HRESULT STDMETHODCALLTYPE CreateViewWindow2(LPSV2CVW2_PARAMS view_params)
Definition: CDefView.cpp:2947
int GetSelectionMark()
Definition: rosctrls.h:156
#define SB_VERT
Definition: winuser.h:553
FOLDERSETTINGS m_FolderSettings
Definition: CDefView.cpp:92
LPFNVIEWCALLBACK pfnCallback
Definition: shlobj.h:1208
#define FCIDM_MENU_VIEW_SEP_OPTIONS
Definition: shlobj.h:560
#define KEY_READ
Definition: nt_native.h:1023
virtual HRESULT STDMETHODCALLTYPE MoveIcons(IDataObject *obj)
Definition: CDefView.cpp:3191
#define TRUE
Definition: types.h:120
struct LISTVIEW_SORT_INFO * LPLISTVIEW_SORT_INFO
LRESULT OnActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: CDefView.cpp:1786
#define pt(x, y)
Definition: drawing.c:79
#define TPM_LEFTALIGN
Definition: winuser.h:2357
#define GET_WM_COMMAND_ID(wp, lp)
Definition: CDefView.cpp:377
virtual HRESULT STDMETHODCALLTYPE GetSelectedCount(UINT *count)
Definition: CDefView.cpp:3138
#define WM_INITMENUPOPUP
Definition: winuser.h:1733
BOOL _ILIsNetHood(LPCITEMIDLIST pidl)
Definition: pidl.c:1909
REFIID riid
Definition: precomp.h:44
#define SPI_SETDESKWALLPAPER
Definition: winuser.h:1356
static BOOL ILIsParentOrSpecialParent(PCIDLIST_ABSOLUTE pidl1, PCIDLIST_ABSOLUTE pidl2)
Definition: CDefView.cpp:2246
#define LVS_REPORT
Definition: commctrl.h:2262
virtual WNDPROC GetWindowProc()
Definition: CDefView.cpp:310
HWND Create(HWND hWndParent, _U_RECT rect=NULL, LPCTSTR szWindowName=NULL, DWORD dwStyle=0, DWORD dwExStyle=0, _U_MENUorID MenuOrID=0U, LPVOID lpCreateParam=NULL)
Definition: atlwin.h:1700
#define LVN_GETDISPINFOA
Definition: commctrl.h:3153
BOOL WINAPI CheckMenuRadioItem(_In_ HMENU, _In_ UINT, _In_ UINT, _In_ UINT, _In_ UINT)
#define TPM_RETURNCMD
Definition: winuser.h:2367
_STLP_MOVE_TO_STD_NAMESPACE void sort(_RandomAccessIter __first, _RandomAccessIter __last)
Definition: _algo.c:993
#define HKEY_CURRENT_USER
Definition: winreg.h:11
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint dy
Definition: linetemp.h:97
virtual HRESULT STDMETHODCALLTYPE GetView(SHELLVIEWID *view_guid, ULONG view_type)
Definition: CDefView.cpp:2941
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1827
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
PCUITEMID_CHILD _PidlByItem(int i)
Definition: CDefView.cpp:840
#define SB_HORZ
Definition: winuser.h:552
#define U(x)
Definition: wordpad.c:45
Definition: shlobj.h:1201
LRESULT OnShowWindow(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: CDefView.cpp:1090
#define LVN_ITEMCHANGED
Definition: commctrl.h:3131
LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
Definition: pidl.c:699
#define NM_RELEASEDCAPTURE
Definition: commctrl.h:141
BOOL WINAPI TrackPopupMenuEx(_In_ HMENU, _In_ UINT, _In_ int, _In_ int, _In_ HWND, _In_opt_ LPTPMPARAMS)
BOOL WINAPI ImageList_DragMove(INT x, INT y)
Definition: imagelist.c:1070
void SetRedraw(BOOL redraw)
Definition: rosctrls.h:27
#define FCIDM_SHVIEW_OPEN
Definition: shresdef.h:822
#define SHCNE_RENAMEFOLDER
Definition: shlobj.h:1746
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
BOOL WINAPI SHGetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath)
Definition: pidl.c:1294
IShellBrowser * psbOwner
Definition: shobjidl.idl:791
static HDC
Definition: imagelist.c:92
CComPtr< ICommDlgBrowser > m_pCommDlgBrowser
Definition: CDefView.cpp:88
#define CALLBACK
Definition: compat.h:35
#define SHCNE_INTERRUPT
Definition: shlobj.h:1754
#define MF_STRING
Definition: winuser.h:138
#define CLR_INVALID
Definition: wingdi.h:883
#define FCIDM_SHVIEW_COPYTO
Definition: shresdef.h:800
HWND hWnd
Definition: settings.c:17
BOOL _ILIsControlPanel(LPCITEMIDLIST pidl)
Definition: pidl.c:1920
REFIID LPVOID * ppv
Definition: atlbase.h:39
HRESULT FillList()
Definition: CDefView.cpp:987
BOOL SetWindowPos(HWND hWndInsertAfter, int x, int y, int cx, int cy, UINT nFlags)
Definition: atlwin.h:1254
LONG top
Definition: windef.h:307
static INT CALLBACK ListViewCompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lpData)
Definition: CDefView.cpp:790
#define ListView_GetItemRect(hwnd, i, prc, code)
Definition: commctrl.h:2478
#define SFVM_ADDINGOBJECT
#define LVN_GETDISPINFOW
Definition: commctrl.h:3154
HANDLE HWND
Definition: compat.h:19
IShellView * psvOuter
Definition: shlobj.h:1284
#define GET_X_LPARAM(lp)
Definition: windowsx.h:274
virtual HRESULT STDMETHODCALLTYPE GetDefaultSpacing(POINT *ppt)
Definition: CDefView.cpp:2871
int GetNextItem(int i, WORD flags)
Definition: rosctrls.h:161
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1539
#define WM_SHOWWINDOW
Definition: winuser.h:1615
virtual HRESULT STDMETHODCALLTYPE SetCurrentViewMode(UINT ViewMode)
Definition: CDefView.cpp:2742
const ITEMID_CHILD UNALIGNED * PCUITEMID_CHILD
Definition: shtypes.idl:70
#define GetRValue(quad)
Definition: precomp.h:64
#define ZeroMemory
Definition: winbase.h:1667
BOOL WINAPI DeleteObject(_In_ HGDIOBJ)
#define LVIS_CUT
Definition: commctrl.h:2320
#define HWND_TOP
Definition: winuser.h:1197
CComPtr< IShellFolderViewDual > m_pShellFolderViewDual
Definition: CDefView.cpp:89
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
#define MAKEINTRESOURCEA(i)
Definition: winuser.h:581
#define HDF_SORTUP
Definition: commctrl.h:724
#define FCIDM_SHVIEWFIRST
Definition: shlobj.h:507
WPARAM wParam
Definition: winuser.h:3096
LRESULT OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: CDefView.cpp:1819
BOOL(CALLBACK * LPFNADDPROPSHEETPAGE)(HPROPSHEETPAGE, LPARAM)
Definition: prsht.h:327
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
#define COLOR_DESKTOP
Definition: winuser.h:908
HRESULT WINAPI RegisterDragDrop(HWND hwnd, LPDROPTARGET pDropTarget)
Definition: ole2.c:557
#define LVHT_ONITEM
Definition: commctrl.h:2497
virtual HRESULT STDMETHODCALLTYPE Item(int iItemIndex, PITEMID_CHILD *ppidl)
Definition: CDefView.cpp:2794
static int int const SCRIPT_CONTROL const SCRIPT_STATE SCRIPT_ITEM ULONG int * pcItems
Definition: usp10.c:62
BOOL EnsureVisible(int i, BOOL fPartialOK)
Definition: rosctrls.h:146
#define LVNI_SELECTED
Definition: commctrl.h:2424
BOOL WINAPI ILIsEqual(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
Definition: pidl.c:535
UINT_PTR WPARAM
Definition: windef.h:207
BOOL WINAPI ILRemoveLastID(LPITEMIDLIST pidl)
Definition: pidl.c:212
view_type
HRESULT FillFileMenu()
Definition: CDefView.cpp:1307
#define WS_CHILD
Definition: pedump.c:617
HMENU m_hMenu
Definition: CDefView.cpp:93
virtual HRESULT STDMETHODCALLTYPE Rearrange(LPARAM sort)
Definition: CDefView.cpp:3049
LONG left
Definition: windef.h:306
void _HandleStatusBarResize(int width)
Definition: CDefView.cpp:3574
virtual HRESULT STDMETHODCALLTYPE GetSpacing(POINT *ppt)
Definition: CDefView.cpp:2852
virtual HRESULT STDMETHODCALLTYPE GetItemObject(UINT uItem, REFIID riid, void **ppv)
Definition: CDefView.cpp:2680
UINT uFlags
Definition: api.c:59
#define LVM_SETCALLBACKMASK
Definition: commctrl.h:2419
int GetItemCount()
Definition: rosctrls.h:121
#define WS_CLIPCHILDREN
Definition: