ReactOS  0.4.15-dev-5126-g3bb451b
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  /* Release cached IContextMenu */
1314  if (m_pCM)
1315  {
1317  m_pCM.Release();
1318  }
1319 
1320  /* Cleanup the items added previously */
1321  for (int i = GetMenuItemCount(hFileMenu) - 1; i >= 0; i--)
1322  {
1323  UINT id = GetMenuItemID(hFileMenu, i);
1325  DeleteMenu(hFileMenu, i, MF_BYPOSITION);
1326  }
1327 
1329 
1330  /* Store the context menu in m_pCM and keep it in order to invoke the selected command later on */
1333  if (FAILED_UNEXPECTEDLY(hr))
1334  return hr;
1335 
1337 
1338  hr = m_pCM->QueryContextMenu(hmenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, 0);
1339  if (FAILED_UNEXPECTEDLY(hr))
1340  return hr;
1341 
1342  // TODO: filter or something
1343 
1344  Shell_MergeMenus(hFileMenu, hmenu, 0, 0, 0xFFFF, MM_ADDSEPARATOR | MM_SUBMENUSHAVEIDS);
1345 
1347 
1348  return S_OK;
1349 }
1350 
1352 {
1354  if (!hEditMenu)
1355  return E_FAIL;
1356 
1357  HMENU hmenuContents = ::LoadMenuW(shell32_hInstance, L"MENU_003");
1358  if (!hmenuContents)
1359  return E_FAIL;
1360 
1361  Shell_MergeMenus(hEditMenu, hmenuContents, 0, 0, 0xFFFF, 0);
1362 
1363  ::DestroyMenu(hmenuContents);
1364 
1365  return S_OK;
1366 }
1367 
1369 {
1371  if (!hViewMenu)
1372  return E_FAIL;
1373 
1375  if (!m_hMenuViewModes)
1376  return E_FAIL;
1377 
1380 
1381  return S_OK;
1382 }
1383 
1385 {
1386  /* We only need to fill this once */
1387  if (GetMenuItemID(hmenuArrange, 0) == FCIDM_SHVIEW_AUTOARRANGE)
1388  {
1389  Shell_MergeMenus(hmenuArrange, m_hMenuArrangeModes, 0, 0, 0xFFFF,0);
1390  }
1391 
1392  /* Also check the menu item according to which we sort */
1393  CheckMenuRadioItem(hmenuArrange,
1394  0x30,
1395  0x100,
1396  m_sortInfo.nHeaderID + 0x30,
1397  MF_BYCOMMAND);
1398 
1400  {
1403  }
1404  else
1405  {
1408 
1409  if (GetAutoArrange() == S_OK)
1411  else
1413 
1414  if (_GetSnapToGrid() == S_OK)
1416  else
1418  }
1419 
1420 
1421  return S_OK;
1422 }
1423 
1425 {
1427  {
1428  UINT iItemFirst = FCIDM_SHVIEW_BIGICON;
1429  UINT iItemLast = iItemFirst + FVM_LAST - FVM_FIRST;
1430  UINT iItem = iItemFirst + m_FolderSettings.ViewMode - FVM_FIRST;
1431  CheckMenuRadioItem(hmenuView, iItemFirst, iItemLast, iItem, MF_BYCOMMAND);
1432  }
1433 
1434  return S_OK;
1435 }
1436 
1437 /**********************************************************
1438 * ShellView_GetSelections()
1439 *
1440 * - fills the m_apidl list with the selected objects
1441 *
1442 * RETURNS
1443 * number of selected items
1444 */
1446 {
1447  SHFree(m_apidl);
1448 
1450  m_apidl = static_cast<PCUITEMID_CHILD*>(SHAlloc(m_cidl * sizeof(PCUITEMID_CHILD)));
1451  if (!m_apidl)
1452  {
1453  m_cidl = 0;
1454  return 0;
1455  }
1456 
1457  TRACE("-- Items selected =%u\n", m_cidl);
1458 
1459  UINT i = 0;
1460  int lvIndex = -1;
1461  while ((lvIndex = m_ListView.GetNextItem(lvIndex, LVNI_SELECTED)) > -1)
1462  {
1463  m_apidl[i] = _PidlByItem(lvIndex);
1464  i++;
1465  if (i == m_cidl)
1466  break;
1467  TRACE("-- selected Item found\n");
1468  }
1469 
1470  return m_cidl;
1471 }
1472 
1474 {
1475  CMINVOKECOMMANDINFO cmi;
1476 
1477  ZeroMemory(&cmi, sizeof(cmi));
1478  cmi.cbSize = sizeof(cmi);
1479  cmi.lpVerb = MAKEINTRESOURCEA(uCommand);
1480  cmi.hwnd = m_hWnd;
1481 
1482  if (GetKeyState(VK_SHIFT) & 0x8000)
1483  cmi.fMask |= CMIC_MASK_SHIFT_DOWN;
1484 
1485  if (GetKeyState(VK_CONTROL) & 0x8000)
1486  cmi.fMask |= CMIC_MASK_CONTROL_DOWN;
1487 
1488  HRESULT hr = m_pCM->InvokeCommand(&cmi);
1489  if (FAILED_UNEXPECTEDLY(hr))
1490  return hr;
1491 
1492  return S_OK;
1493 }
1494 
1495 /**********************************************************
1496  * ShellView_OpenSelectedItems()
1497  */
1499 {
1500  HMENU hMenu;
1501  UINT uCommand;
1502  HRESULT hResult;
1503 
1505  if (m_cidl == 0)
1506  return S_OK;
1507 
1508  hResult = OnDefaultCommand();
1509  if (hResult == S_OK)
1510  return hResult;
1511 
1512  hMenu = CreatePopupMenu();
1513  if (!hMenu)
1514  return E_FAIL;
1515 
1517  if (FAILED_UNEXPECTEDLY(hResult))
1518  goto cleanup;
1519 
1520  hResult = m_pCM->QueryContextMenu(hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, CMF_DEFAULTONLY);
1521  if (FAILED_UNEXPECTEDLY(hResult))
1522  goto cleanup;
1523 
1524  uCommand = GetMenuDefaultItem(hMenu, FALSE, 0);
1525  if (uCommand == (UINT)-1)
1526  {
1527  hResult = E_FAIL;
1528  goto cleanup;
1529  }
1530 
1531  InvokeContextMenuCommand(uCommand);
1532 
1533 cleanup:
1534 
1535  if (hMenu)
1536  DestroyMenu(hMenu);
1537 
1538  if (m_pCM)
1539  {
1541  m_pCM.Release();
1542  }
1543 
1544  return hResult;
1545 }
1546 
1547 /**********************************************************
1548  * ShellView_DoContextMenu()
1549  */
1551 {
1552  int x, y;
1553  UINT uCommand;
1554  HRESULT hResult;
1555 
1556  TRACE("(%p)\n", this);
1557 
1559  if (!m_hContextMenu)
1560  return E_FAIL;
1561 
1562  if (lParam != ~0) // unless app key (menu key) was pressed
1563  {
1564  x = GET_X_LPARAM(lParam);
1565  y = GET_Y_LPARAM(lParam);
1566 
1567  LV_HITTESTINFO hittest = { { x, y } };
1568  ScreenToClient(&hittest.pt);
1569  m_ListView.HitTest(&hittest);
1570 
1571  // Right-Clicked item is selected? If selected, no selection change.
1572  // If not selected, then reset the selection and select the item.
1573  if ((hittest.flags & LVHT_ONITEM) &&
1575  {
1576  SelectItem(hittest.iItem, SVSI_SELECT | SVSI_DESELECTOTHERS | SVSI_ENSUREVISIBLE);
1577  }
1578  }
1579 
1581 
1583  if (FAILED_UNEXPECTEDLY(hResult))
1584  goto cleanup;
1585 
1586  /* Use 1 as the first id as we want 0 the mean that the user canceled the menu */
1587  hResult = m_pCM->QueryContextMenu(m_hContextMenu, 0, CONTEXT_MENU_BASE_ID, FCIDM_SHVIEWLAST, CMF_NORMAL);
1588  if (FAILED_UNEXPECTEDLY(hResult))
1589  goto cleanup;
1590 
1591  /* There is no position requested, so try to find one */
1592  if (lParam == ~0)
1593  {
1594  HWND hFocus = ::GetFocus();
1595  int lvIndex = -1;
1596  POINT pt;
1597 
1598  if (hFocus == m_ListView.m_hWnd || m_ListView.IsChild(hFocus))
1599  {
1600  /* Is there an item focused and selected? */
1602  /* If not, find the first selected item */
1603  if (lvIndex < 0)
1604  lvIndex = m_ListView.GetNextItem(-1, LVIS_SELECTED);
1605  }
1606 
1607  /* We got something */
1608  if (lvIndex > -1)
1609  {
1610  /* Let's find the center of the icon */
1611  RECT rc = { LVIR_ICON };
1612  m_ListView.SendMessage(LVM_GETITEMRECT, lvIndex, (LPARAM)&rc);
1613  pt.x = (rc.right + rc.left) / 2;
1614  pt.y = (rc.bottom + rc.top) / 2;
1615  }
1616  else
1617  {
1618  /* We have to drop it somewhere.. */
1619  pt.x = pt.y = 0;
1620  }
1621 
1622  m_ListView.ClientToScreen(&pt);
1623  x = pt.x;
1624  y = pt.y;
1625  }
1626 
1627  uCommand = TrackPopupMenu(m_hContextMenu,
1629  x, y, 0, m_hWnd, NULL);
1630  if (uCommand == 0)
1631  goto cleanup;
1632 
1633  if (uCommand == FCIDM_SHVIEW_OPEN && OnDefaultCommand() == S_OK)
1634  goto cleanup;
1635 
1637 
1638 cleanup:
1639  if (m_pCM)
1640  {
1642  m_pCM.Release();
1643  }
1644 
1645  if (m_hContextMenu)
1646  {
1648  m_hContextMenu = NULL;
1649  }
1650 
1651  return 0;
1652 }
1653 
1655 {
1656  HRESULT hResult;
1657  HMENU hMenu = NULL;
1658 
1659  hResult = GetItemObject( bUseSelection ? SVGIO_SELECTION : SVGIO_BACKGROUND, IID_PPV_ARG(IContextMenu, &m_pCM));
1660  if (FAILED_UNEXPECTEDLY( hResult))
1661  goto cleanup;
1662  if ((uCommand != FCIDM_SHVIEW_DELETE) && (uCommand != FCIDM_SHVIEW_RENAME))
1663  {
1664  hMenu = CreatePopupMenu();
1665  if (!hMenu)
1666  return 0;
1667 
1668  hResult = m_pCM->QueryContextMenu(hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, CMF_NORMAL);
1669  if (FAILED_UNEXPECTEDLY(hResult))
1670  goto cleanup;
1671  }
1672 
1673  if (bUseSelection)
1674  {
1675  // FIXME: we should cache this....
1676  SFGAOF rfg = SFGAO_BROWSABLE | SFGAO_CANCOPY | SFGAO_CANLINK | SFGAO_CANMOVE | SFGAO_CANDELETE | SFGAO_CANRENAME | SFGAO_HASPROPSHEET | SFGAO_FILESYSTEM | SFGAO_FOLDER;
1677  hResult = m_pSFParent->GetAttributesOf(m_cidl, m_apidl, &rfg);
1678  if (FAILED_UNEXPECTEDLY(hResult))
1679  return 0;
1680 
1681  if (!(rfg & SFGAO_CANMOVE) && uCommand == FCIDM_SHVIEW_CUT)
1682  return 0;
1683  if (!(rfg & SFGAO_CANCOPY) && uCommand == FCIDM_SHVIEW_COPY)
1684  return 0;
1685  if (!(rfg & SFGAO_CANDELETE) && uCommand == FCIDM_SHVIEW_DELETE)
1686  return 0;
1687  if (!(rfg & SFGAO_CANRENAME) && uCommand == FCIDM_SHVIEW_RENAME)
1688  return 0;
1689  if (!(rfg & SFGAO_HASPROPSHEET) && uCommand == FCIDM_SHVIEW_PROPERTIES)
1690  return 0;
1691  }
1692 
1693  InvokeContextMenuCommand(uCommand);
1694 
1695 cleanup:
1696  if (m_pCM)
1697  {
1699  m_pCM.Release();
1700  }
1701 
1702  if (hMenu)
1703  DestroyMenu(hMenu);
1704 
1705  return 0;
1706 }
1707 
1708 /**********************************************************
1709  * ##### message handling #####
1710  */
1711 
1712 /**********************************************************
1713 * ShellView_OnSize()
1714 */
1716 {
1717  WORD wWidth, wHeight;
1718 
1719  wWidth = LOWORD(lParam);
1720  wHeight = HIWORD(lParam);
1721 
1722  TRACE("%p width=%u height=%u\n", this, wWidth, wHeight);
1723 
1724  /* Resize the ListView to fit our window */
1725  if (m_ListView)
1726  {
1727  ::MoveWindow(m_ListView, 0, 0, wWidth, wHeight, TRUE);
1728  }
1729 
1730  _DoFolderViewCB(SFVM_SIZE, 0, 0);
1731 
1732  _HandleStatusBarResize(wWidth);
1733  UpdateStatusbar();
1734 
1735  return 0;
1736 }
1737 
1738 /**********************************************************
1739 * ShellView_OnDeactivate()
1740 *
1741 * NOTES
1742 * internal
1743 */
1745 {
1746  TRACE("%p\n", this);
1747 
1748  if (m_uState != SVUIA_DEACTIVATE)
1749  {
1750  // TODO: cleanup menu after deactivation
1751 
1753  }
1754 }
1755 
1757 {
1758  TRACE("%p uState=%x\n", this, uState);
1759 
1760  /*don't do anything if the state isn't really changing */
1761  if (m_uState == uState)
1762  {
1763  return;
1764  }
1765 
1766  if (uState == SVUIA_DEACTIVATE)
1767  {
1768  OnDeactivate();
1769  }
1770  else
1771  {
1773  {
1774  FillEditMenu();
1775  FillViewMenu();
1776  m_pShellBrowser->SetMenuSB(m_hMenu, 0, m_hWnd);
1778  }
1779 
1780  if (SVUIA_ACTIVATE_FOCUS == uState)
1781  {
1782  m_ListView.SetFocus();
1783  }
1784  }
1785 
1786  m_uState = uState;
1787  TRACE("--\n");
1788 }
1789 
1790 /**********************************************************
1791 * ShellView_OnActivate()
1792 */
1794 {
1796  return 0;
1797 }
1798 
1799 /**********************************************************
1800 * ShellView_OnSetFocus()
1801 *
1802 */
1804 {
1805  TRACE("%p\n", this);
1806 
1807  /* Tell the browser one of our windows has received the focus. This
1808  should always be done before merging menus (OnActivate merges the
1809  menus) if one of our windows has the focus.*/
1810 
1811  m_pShellBrowser->OnViewWindowActive(this);
1813 
1814  /* Set the focus to the listview */
1815  m_ListView.SetFocus();
1816 
1817  /* Notify the ICommDlgBrowser interface */
1818  OnStateChange(CDBOSC_SETFOCUS);
1819 
1820  return 0;
1821 }
1822 
1823 /**********************************************************
1824 * ShellView_OnKillFocus()
1825 */
1827 {
1828  TRACE("(%p) stub\n", this);
1829 
1831  /* Notify the ICommDlgBrowser */
1832  OnStateChange(CDBOSC_KILLFOCUS);
1833 
1834  return 0;
1835 }
1836 
1837 /**********************************************************
1838 * ShellView_OnCommand()
1839 *
1840 * NOTES
1841 * the CmdID's are the ones from the context menu
1842 */
1844 {
1845  DWORD dwCmdID;
1846  DWORD dwCmd;
1847  HWND hwndCmd;
1848  int nCount;
1849 
1850  dwCmdID = GET_WM_COMMAND_ID(wParam, lParam);
1851  dwCmd = GET_WM_COMMAND_CMD(wParam, lParam);
1852  hwndCmd = GET_WM_COMMAND_HWND(wParam, lParam);
1853 
1854  TRACE("(%p)->(0x%08x 0x%08x %p) stub\n", this, dwCmdID, dwCmd, hwndCmd);
1855 
1856  switch (dwCmdID)
1857  {
1860  m_ListView.ModifyStyle(LVS_TYPEMASK, LVS_SMALLICON);
1861  CheckToolbar();
1862  break;
1863 
1864  case FCIDM_SHVIEW_BIGICON:
1866  m_ListView.ModifyStyle(LVS_TYPEMASK, LVS_ICON);
1867  CheckToolbar();
1868  break;
1869 
1870  case FCIDM_SHVIEW_LISTVIEW:
1872  m_ListView.ModifyStyle(LVS_TYPEMASK, LVS_LIST);
1873  CheckToolbar();
1874  break;
1875 
1878  m_ListView.ModifyStyle(LVS_TYPEMASK, LVS_REPORT);
1879  CheckToolbar();
1880  break;
1881 
1882  /* the menu-ID's for sorting are 0x30... see shrec.rc */
1883  case 0x30:
1884  case 0x31:
1885  case 0x32:
1886  case 0x33:
1887  m_sortInfo.nHeaderID = dwCmdID - 0x30;
1889  _Sort();
1890  break;
1891 
1894  break;
1896  if (_GetSnapToGrid() == S_OK)
1898  else
1899  ArrangeGrid();
1900  break;
1902  if (GetAutoArrange() == S_OK)
1903  m_ListView.ModifyStyle(LVS_AUTOARRANGE, 0);
1904  else
1905  AutoArrange();
1906  break;
1909  break;
1910 
1912  nCount = m_ListView.GetItemCount();
1913  for (int i=0; i < nCount; i++)
1915  break;
1916 
1917  case FCIDM_SHVIEW_REFRESH:
1918  Refresh();
1919  break;
1920 
1921  case FCIDM_SHVIEW_DELETE:
1922  case FCIDM_SHVIEW_CUT:
1923  case FCIDM_SHVIEW_COPY:
1924  case FCIDM_SHVIEW_RENAME:
1926  case FCIDM_SHVIEW_COPYTO:
1927  case FCIDM_SHVIEW_MOVETO:
1929  return 0;
1930 
1931  return OnExplorerCommand(dwCmdID, TRUE);
1932 
1933  case FCIDM_SHVIEW_INSERT:
1934  case FCIDM_SHVIEW_UNDO:
1937  return OnExplorerCommand(dwCmdID, FALSE);
1938  default:
1939  /* WM_COMMAND messages from the file menu are routed to the CDefView so as to let m_pCM handle the command */
1940  if (m_pCM && dwCmd == 0)
1941  {
1942  InvokeContextMenuCommand(dwCmdID);
1943  }
1944  }
1945 
1946  return 0;
1947 }
1948 
1949 static BOOL
1951 {
1952  HKEY hKey;
1953  LONG error;
1954  DWORD dwValue = FALSE, cbValue;
1955 
1957  L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer",
1958  0, KEY_READ, &hKey);
1959  if (error)
1960  return dwValue;
1961 
1962  cbValue = sizeof(dwValue);
1963  RegQueryValueExW(hKey, L"SelectExtOnRename", NULL, NULL, (LPBYTE)&dwValue, &cbValue);
1964 
1965  RegCloseKey(hKey);
1966  return !!dwValue;
1967 }
1968 
1969 /**********************************************************
1970 * ShellView_OnNotify()
1971 */
1972 
1974 {
1975  UINT CtlID;
1976  LPNMHDR lpnmh;
1977  LPNMLISTVIEW lpnmlv;
1978  NMLVDISPINFOW *lpdi;
1979  PCUITEMID_CHILD pidl;
1980  BOOL unused;
1981 
1982  CtlID = wParam;
1983  lpnmh = (LPNMHDR)lParam;
1984  lpnmlv = (LPNMLISTVIEW)lpnmh;
1985  lpdi = (NMLVDISPINFOW *)lpnmh;
1986 
1987  TRACE("%p CtlID=%u lpnmh->code=%x\n", this, CtlID, lpnmh->code);
1988 
1989  switch (lpnmh->code)
1990  {
1991  case NM_SETFOCUS:
1992  TRACE("-- NM_SETFOCUS %p\n", this);
1993  OnSetFocus(0, 0, 0, unused);
1994  break;
1995 
1996  case NM_KILLFOCUS:
1997  TRACE("-- NM_KILLFOCUS %p\n", this);
1998  OnDeactivate();
1999  /* Notify the ICommDlgBrowser interface */
2000  OnStateChange(CDBOSC_KILLFOCUS);
2001  break;
2002 
2003  case NM_CUSTOMDRAW:
2004  TRACE("-- NM_CUSTOMDRAW %p\n", this);
2005  return CDRF_DODEFAULT;
2006 
2007  case NM_RELEASEDCAPTURE:
2008  TRACE("-- NM_RELEASEDCAPTURE %p\n", this);
2009  break;
2010 
2011  case NM_CLICK:
2012  TRACE("-- NM_CLICK %p\n", this);
2013  break;
2014 
2015  case NM_RCLICK:
2016  TRACE("-- NM_RCLICK %p\n", this);
2017  break;
2018 
2019  case NM_DBLCLK:
2020  TRACE("-- NM_DBLCLK %p\n", this);
2022  break;
2023 
2024  case NM_RETURN:
2025  TRACE("-- NM_RETURN %p\n", this);
2027  break;
2028 
2029  case HDN_ENDTRACKW:
2030  TRACE("-- HDN_ENDTRACKW %p\n", this);
2031  /*nColumn1 = m_ListView.GetColumnWidth(0);
2032  nColumn2 = m_ListView.GetColumnWidth(1);*/
2033  break;
2034 
2035  case LVN_DELETEITEM:
2036  TRACE("-- LVN_DELETEITEM %p\n", this);
2037 
2038  /*delete the pidl because we made a copy of it*/
2039  SHFree(reinterpret_cast<LPVOID>(lpnmlv->lParam));
2040 
2041  break;
2042 
2043  case LVN_DELETEALLITEMS:
2044  TRACE("-- LVN_DELETEALLITEMS %p\n", this);
2045  return FALSE;
2046 
2047  case LVN_INSERTITEM:
2048  TRACE("-- LVN_INSERTITEM (STUB)%p\n", this);
2049  break;
2050 
2051  case LVN_ITEMACTIVATE:
2052  TRACE("-- LVN_ITEMACTIVATE %p\n", this);
2053  OnStateChange(CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
2054  break;
2055 
2056  case LVN_COLUMNCLICK:
2057  m_sortInfo.nHeaderID = lpnmlv->iSubItem;
2060  else
2062  _Sort();
2063  break;
2064 
2065  case LVN_GETDISPINFOA:
2066  case LVN_GETDISPINFOW:
2067  TRACE("-- LVN_GETDISPINFO %p\n", this);
2068  pidl = _PidlByItem(lpdi->item);
2069 
2070  if (lpdi->item.mask & LVIF_TEXT) /* text requested */
2071  {
2072  if (m_pSF2Parent)
2073  {
2074  SHELLDETAILS sd;
2075  if (FAILED_UNEXPECTEDLY(m_pSF2Parent->GetDetailsOf(pidl, lpdi->item.iSubItem, &sd)))
2076  break;
2077 
2078  if (lpnmh->code == LVN_GETDISPINFOA)
2079  {
2080  /* shouldn't happen */
2081  NMLVDISPINFOA *lpdiA = (NMLVDISPINFOA *)lpnmh;
2082  StrRetToStrNA( lpdiA->item.pszText, lpdiA->item.cchTextMax, &sd.str, NULL);
2083  TRACE("-- text=%s\n", lpdiA->item.pszText);
2084  }
2085  else /* LVN_GETDISPINFOW */
2086  {
2087  StrRetToStrNW( lpdi->item.pszText, lpdi->item.cchTextMax, &sd.str, NULL);
2088  TRACE("-- text=%s\n", debugstr_w(lpdi->item.pszText));
2089  }
2090  }
2091  else
2092  {
2093  FIXME("no m_pSF2Parent\n");
2094  }
2095  }
2096  if(lpdi->item.mask & LVIF_IMAGE) /* image requested */
2097  {
2099  }
2100  if(lpdi->item.mask & LVIF_STATE)
2101  {
2102  ULONG attributes = SFGAO_HIDDEN;
2103  if (SUCCEEDED(m_pSFParent->GetAttributesOf(1, &pidl, &attributes)))
2104  {
2105  if (attributes & SFGAO_HIDDEN)
2106  {
2107  lpdi->item.state |= LVIS_CUT;
2108  }
2109  }
2110  }
2111  lpdi->item.mask |= LVIF_DI_SETITEM;
2112  break;
2113 
2114  case LVN_ITEMCHANGED:
2115  TRACE("-- LVN_ITEMCHANGED %p\n", this);
2116  OnStateChange(CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
2117  UpdateStatusbar();
2118  _DoFolderViewCB(SFVM_SELECTIONCHANGED, NULL/* FIXME */, NULL/* FIXME */);
2119  break;
2120 
2121  case LVN_BEGINDRAG:
2122  case LVN_BEGINRDRAG:
2123  TRACE("-- LVN_BEGINDRAG\n");
2124 
2125  if (GetSelections())
2126  {
2128  DWORD dwAttributes = SFGAO_CANCOPY | SFGAO_CANLINK;
2129  DWORD dwEffect = DROPEFFECT_MOVE;
2130 
2131  if (SUCCEEDED(m_pSFParent->GetUIObjectOf(m_hWnd, m_cidl, m_apidl, IID_NULL_PPV_ARG(IDataObject, &pda))))
2132  {
2134 
2135  if (SUCCEEDED(m_pSFParent->GetAttributesOf(m_cidl, m_apidl, &dwAttributes)))
2136  {
2137  dwEffect |= dwAttributes & (SFGAO_CANCOPY | SFGAO_CANLINK);
2138  }
2139 
2141  if (SUCCEEDED(pda->QueryInterface(IID_PPV_ARG(IAsyncOperation, &piaso))))
2142  {
2143  piaso->SetAsyncMode(TRUE);
2144  }
2145 
2146  DWORD dwEffect2;
2147 
2148  m_pSourceDataObject = pda;
2149  m_ptFirstMousePos = params->ptAction;
2152 
2153  HIMAGELIST big_icons, small_icons;
2154  Shell_GetImageLists(&big_icons, &small_icons);
2155  PCUITEMID_CHILD pidl = _PidlByItem(params->iItem);
2156  int iIcon = SHMapPIDLToSystemImageListIndex(m_pSFParent, pidl, 0);
2157  POINT ptItem;
2158  m_ListView.GetItemPosition(params->iItem, &ptItem);
2159 
2160  ImageList_BeginDrag(big_icons, iIcon, params->ptAction.x - ptItem.x, params->ptAction.y - ptItem.y);
2161 
2162  DoDragDrop(pda, this, dwEffect, &dwEffect2);
2163 
2165  }
2166  }
2167  break;
2168 
2169  case LVN_BEGINLABELEDITW:
2170  {
2171  DWORD dwAttr = SFGAO_CANRENAME;
2172  pidl = _PidlByItem(lpdi->item);
2173 
2174  TRACE("-- LVN_BEGINLABELEDITW %p\n", this);
2175 
2176  m_pSFParent->GetAttributesOf(1, &pidl, &dwAttr);
2177  if (SFGAO_CANRENAME & dwAttr)
2178  {
2179  HWND hEdit = reinterpret_cast<HWND>(m_ListView.SendMessage(LVM_GETEDITCONTROL));
2181 
2182  /* smartass-renaming: See CORE-15242 */
2183  if (!(dwAttr & SFGAO_FOLDER) && (dwAttr & SFGAO_FILESYSTEM) &&
2184  (lpdi->item.mask & LVIF_TEXT) && !SelectExtOnRename())
2185  {
2186  WCHAR szFullPath[MAX_PATH];
2187  PIDLIST_ABSOLUTE pidlFull = ILCombine(m_pidlParent, pidl);
2188  SHGetPathFromIDListW(pidlFull, szFullPath);
2189 
2190  if (!SHELL_FS_HideExtension(szFullPath))
2191  {
2192  LPWSTR pszText = lpdi->item.pszText;
2193  LPWSTR pchDotExt = PathFindExtensionW(pszText);
2194  ::PostMessageW(hEdit, EM_SETSEL, 0, pchDotExt - pszText);
2196  }
2197 
2198  ILFree(pidlFull);
2199  }
2200 
2201  m_isEditing = TRUE;
2202  return FALSE;
2203  }
2204 
2205  return TRUE;
2206  }
2207 
2208  case LVN_ENDLABELEDITW:
2209  {
2210  TRACE("-- LVN_ENDLABELEDITW %p\n", this);
2211 
2212  m_isEditing = FALSE;
2213 
2214  if (lpdi->item.pszText)
2215  {
2216  HRESULT hr;
2217  LVITEMW lvItem;
2218 
2219  pidl = _PidlByItem(lpdi->item);
2220  PITEMID_CHILD pidlNew = NULL;
2221  hr = m_pSFParent->SetNameOf(0, pidl, lpdi->item.pszText, SHGDN_INFOLDER, &pidlNew);
2222 
2223  if (SUCCEEDED(hr) && pidlNew)
2224  {
2225  lvItem.mask = LVIF_PARAM|LVIF_IMAGE;
2226  lvItem.iItem = lpdi->item.iItem;
2227  lvItem.iSubItem = 0;
2228  lvItem.lParam = reinterpret_cast<LPARAM>(pidlNew);
2229  lvItem.iImage = SHMapPIDLToSystemImageListIndex(m_pSFParent, pidlNew, 0);
2230  m_ListView.SetItem(&lvItem);
2231  m_ListView.Update(lpdi->item.iItem);
2232  return TRUE;
2233  }
2234  }
2235 
2236  return FALSE;
2237  }
2238 
2239  default:
2240  TRACE("-- %p WM_COMMAND %x unhandled\n", this, lpnmh->code);
2241  break;
2242  }
2243 
2244  return 0;
2245 }
2246 
2247 /*
2248  * This is just a quick hack to make the desktop work correctly.
2249  * ITranslateShellChangeNotify's IsChildID is undocumented, but most likely the way that
2250  * a folder should know if it should update upon a change notification.
2251  * It is exported by merged folders at a minimum.
2252  */
2254 {
2255  if (!pidl1 || !pidl2)
2256  return FALSE;
2257  if (ILIsParent(pidl1, pidl2, TRUE))
2258  return TRUE;
2259 
2260  if (_ILIsDesktop(pidl1))
2261  {
2262  PIDLIST_ABSOLUTE deskpidl;
2264  if (ILIsParent(deskpidl, pidl2, TRUE))
2265  {
2266  ILFree(deskpidl);
2267  return TRUE;
2268  }
2269  ILFree(deskpidl);
2271  if (ILIsParent(deskpidl, pidl2, TRUE))
2272  {
2273  ILFree(deskpidl);
2274  return TRUE;
2275  }
2276  ILFree(deskpidl);
2277  }
2278 
2279  WCHAR szPath1[MAX_PATH], szPath2[MAX_PATH];
2280  LPITEMIDLIST pidl2Clone = ILClone(pidl2);
2281  ILRemoveLastID(pidl2Clone);
2282  if (SHGetPathFromIDListW(pidl1, szPath1) &&
2283  SHGetPathFromIDListW(pidl2Clone, szPath2))
2284  {
2285  if (lstrcmpiW(szPath1, szPath2) == 0)
2286  {
2287  ILFree(pidl2Clone);
2288  return TRUE;
2289  }
2290  }
2291  ILFree(pidl2Clone);
2292 
2293  return FALSE;
2294 }
2295 
2296 /**********************************************************
2297 * ShellView_OnChange()
2298 */
2300 {
2301  HANDLE hChange = (HANDLE)wParam;
2302  DWORD dwProcID = (DWORD)lParam;
2303  PIDLIST_ABSOLUTE *Pidls;
2304  LONG lEvent;
2305  HANDLE hLock = SHChangeNotification_Lock(hChange, dwProcID, &Pidls, &lEvent);
2306  if (hLock == NULL)
2307  {
2308  ERR("hLock == NULL\n");
2309  return FALSE;
2310  }
2311 
2312  BOOL bParent0 = ILIsParentOrSpecialParent(m_pidlParent, Pidls[0]);
2313  BOOL bParent1 = ILIsParentOrSpecialParent(m_pidlParent, Pidls[1]);
2314 
2315  TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls[0], Pidls[1], lParam);
2316 
2317  lEvent &= ~SHCNE_INTERRUPT;
2318  switch (lEvent)
2319  {
2320  case SHCNE_MKDIR:
2321  case SHCNE_CREATE:
2322  if (bParent0)
2323  {
2324  if (LV_FindItemByPidl(ILFindLastID(Pidls[0])) == -1)
2325  {
2326  LV_AddItem(ILFindLastID(Pidls[0]));
2327  }
2328  else
2329  {
2330  LV_ProdItem(ILFindLastID(Pidls[0]));
2331  }
2332  }
2333  break;
2334 
2335  case SHCNE_RMDIR:
2336  case SHCNE_DELETE:
2337  if (bParent0)
2338  LV_DeleteItem(ILFindLastID(Pidls[0]));
2339  break;
2340 
2341  case SHCNE_RENAMEFOLDER:
2342  case SHCNE_RENAMEITEM:
2343  if (bParent0 && bParent1)
2344  LV_RenameItem(ILFindLastID(Pidls[0]), ILFindLastID(Pidls[1]));
2345  else if (bParent0)
2346  LV_DeleteItem(ILFindLastID(Pidls[0]));
2347  else if (bParent1)
2348  LV_AddItem(ILFindLastID(Pidls[1]));
2349  break;
2350 
2351  case SHCNE_UPDATEITEM:
2352  if (bParent0)
2353  LV_RenameItem(ILFindLastID(Pidls[0]), ILFindLastID(Pidls[0]));
2354  break;
2355 
2356  case SHCNE_UPDATEDIR:
2357  Refresh();
2358  break;
2359  }
2360 
2362  return TRUE;
2363 }
2364 
2367 
2368 /**********************************************************
2369 * CDefView::OnCustomItem
2370 */
2372 {
2373  if (!m_pCM.p)
2374  {
2375  /* no menu */
2376  ERR("no menu!!!\n");
2377  return FALSE;
2378  }
2379 
2380  /* The lParam of WM_DRAWITEM WM_MEASUREITEM contain a menu id and this also needs to
2381  be changed to a menu identifier offset */
2382  UINT CmdID;
2383  HRESULT hres = SHGetMenuIdFromMenuMsg(uMsg, lParam, &CmdID);
2384  if (SUCCEEDED(hres))
2386 
2387  /* Forward the message to the IContextMenu2 */
2388  LRESULT result;
2390 
2391  return (SUCCEEDED(hres));
2392 }
2393 
2395 {
2396  /* Wallpaper setting affects drop shadows effect */
2397  if (wParam == SPI_SETDESKWALLPAPER || wParam == 0)
2398  UpdateListColors();
2399 
2400  return S_OK;
2401 }
2402 
2403 /**********************************************************
2404 * CDefView::OnInitMenuPopup
2405 */
2407 {
2408  HMENU hmenu = (HMENU) wParam;
2409  int nPos = LOWORD(lParam);
2410  UINT menuItemId;
2411 
2412  OnCustomItem(uMsg, wParam, lParam, bHandled);
2413 
2415 
2416  if (GetSelections() == 0)
2417  {
2424  }
2425  else
2426  {
2427  // FIXME: Check copyable
2434  }
2435 
2436  /* Lets try to find out what the hell wParam is */
2437  if (hmenu == GetSubMenu(m_hMenu, nPos))
2438  menuItemId = ReallyGetMenuItemID(m_hMenu, nPos);
2439  else if (hViewMenu && hmenu == GetSubMenu(hViewMenu, nPos))
2440  menuItemId = ReallyGetMenuItemID(hViewMenu, nPos);
2441  else if (m_hContextMenu && hmenu == GetSubMenu(m_hContextMenu, nPos))
2442  menuItemId = ReallyGetMenuItemID(m_hContextMenu, nPos);
2443  else
2444  return FALSE;
2445 
2446  switch (menuItemId)
2447  {
2448  case FCIDM_MENU_FILE:
2449  FillFileMenu();
2450  break;
2451  case FCIDM_MENU_VIEW:
2452  case FCIDM_SHVIEW_VIEW:
2454  break;
2455  case FCIDM_SHVIEW_ARRANGE:
2457  break;
2458  }
2459 
2460  return FALSE;
2461 }
2462 
2463 /**********************************************************
2464 *
2465 *
2466 * The INTERFACE of the IShellView object
2467 *
2468 *
2469 **********************************************************
2470 */
2471 
2472 /**********************************************************
2473 * ShellView_GetWindow
2474 */
2476 {
2477  TRACE("(%p)\n", this);
2478 
2479  *phWnd = m_hWnd;
2480 
2481  return S_OK;
2482 }
2483 
2485 {
2486  FIXME("(%p) stub\n", this);
2487 
2488  return E_NOTIMPL;
2489 }
2490 
2491 /**********************************************************
2492 * IShellView_TranslateAccelerator
2493 *
2494 * FIXME:
2495 * use the accel functions
2496 */
2498 {
2499  if (m_isEditing)
2500  return S_FALSE;
2501 
2502  if (lpmsg->message >= WM_KEYFIRST && lpmsg->message <= WM_KEYLAST)
2503  {
2504  if (::TranslateAcceleratorW(m_hWnd, m_hAccel, lpmsg) != 0)
2505  return S_OK;
2506 
2507  TRACE("-- key=0x%04lx\n", lpmsg->wParam) ;
2508  }
2509 
2510  return m_pShellBrowser->TranslateAcceleratorSB(lpmsg, 0);
2511 }
2512 
2514 {
2515  FIXME("(%p) stub\n", this);
2516 
2517  return E_NOTIMPL;
2518 }
2519 
2521 {
2522  TRACE("(%p)->(state=%x) stub\n", this, uState);
2523 
2524  /* don't do anything if the state isn't really changing */
2525  if (m_uState == uState)
2526  {
2527  return S_OK;
2528  }
2529 
2530  /* OnActivate handles the menu merging and internal state */
2531  DoActivate(uState);
2532 
2533  /* only do This if we are active */
2534  if (uState != SVUIA_DEACTIVATE)
2535  {
2537 
2538  /* Set the text for the status bar */
2539  UpdateStatusbar();
2540  }
2541 
2542  return S_OK;
2543 }
2544 
2546 {
2547  TRACE("(%p)\n", this);
2548 
2550 
2552  FillList();
2553 
2554  return S_OK;
2555 }
2556 
2558 {
2559  return CreateViewWindow3(psb, lpPrevView, SV3CVW3_DEFAULT,
2560  (FOLDERFLAGS)lpfs->fFlags, (FOLDERFLAGS)lpfs->fFlags, (FOLDERVIEWMODE)lpfs->ViewMode, NULL, prcView, phWnd);
2561 }
2562 
2564 {
2565  TRACE("(%p)\n", this);
2566 
2567  /* Make absolutely sure all our UI is cleaned up */
2569 
2570  if (m_hAccel)
2571  {
2572  // "Accelerator tables loaded from resources are freed automatically when the application terminates." -- MSDN
2573  m_hAccel = NULL;
2574  }
2575 
2576  if (m_hMenuArrangeModes)
2577  {
2580  }
2581 
2582  if (m_hMenuViewModes)
2583  {
2586  }
2587 
2588  if (m_hMenu)
2589  {
2591  m_hMenu = NULL;
2592  }
2593 
2594  if (m_ListView)
2595  {
2596  m_ListView.DestroyWindow();
2597  }
2598 
2599  if (m_hWnd)
2600  {
2602  DestroyWindow();
2603  }
2604 
2607 
2608  return S_OK;
2609 }
2610 
2612 {
2613  TRACE("(%p)->(%p) vmode=%x flags=%x\n", this, lpfs,
2615 
2616  if (!lpfs)
2617  return E_INVALIDARG;
2618 
2619  *lpfs = m_FolderSettings;
2620  return S_OK;
2621 }
2622 
2624 {
2625  FIXME("(%p) stub\n", this);
2626 
2627  return E_NOTIMPL;
2628 }
2629 
2631 {
2632  FIXME("(%p) stub\n", this);
2633 
2634  return S_OK;
2635 }
2636 
2638 {
2639  int i;
2640 
2641  TRACE("(%p)->(pidl=%p, 0x%08x) stub\n", this, pidl, uFlags);
2642 
2643  i = LV_FindItemByPidl(pidl);
2644  if (i == -1)
2645  return S_OK;
2646 
2647  LVITEMW lvItem = {0};
2648  lvItem.mask = LVIF_STATE;
2650 
2651  while (m_ListView.GetItem(&lvItem))
2652  {
2653  if (lvItem.iItem == i)
2654  {
2655  if (uFlags & SVSI_SELECT)
2656  lvItem.state |= LVIS_SELECTED;
2657  else
2658  lvItem.state &= ~LVIS_SELECTED;
2659 
2660  if (uFlags & SVSI_FOCUSED)
2661  lvItem.state |= LVIS_FOCUSED;
2662  else
2663  lvItem.state &= ~LVIS_FOCUSED;
2664  }
2665  else
2666  {
2667  if (uFlags & SVSI_DESELECTOTHERS)
2668  {
2669  lvItem.state &= ~LVIS_SELECTED;
2670  }
2671  lvItem.state &= ~LVIS_FOCUSED;
2672  }
2673 
2674  m_ListView.SetItem(&lvItem);
2675  lvItem.iItem++;
2676  }
2677 
2678  if (uFlags & SVSI_ENSUREVISIBLE)
2680 
2681  if((uFlags & SVSI_EDIT) == SVSI_EDIT)
2683 
2684  return S_OK;
2685 }
2686 
2688 {
2690 
2691  TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n", this, uItem, debugstr_guid(&riid), ppvOut);
2692 
2693  if (!ppvOut)
2694  return E_INVALIDARG;
2695 
2696  *ppvOut = NULL;
2697 
2698  switch (uItem)
2699  {
2700  case SVGIO_BACKGROUND:
2701  if (IsEqualIID(riid, IID_IContextMenu))
2702  {
2704  if (FAILED_UNEXPECTEDLY(hr))
2705  return hr;
2706 
2707  IUnknown_SetSite(*((IUnknown**)ppvOut), (IShellView *)this);
2708  }
2709  else if (IsEqualIID(riid, IID_IDispatch))
2710  {
2712  {
2714  if (FAILED_UNEXPECTEDLY(hr))
2715  return hr;
2716  }
2717  hr = m_pShellFolderViewDual->QueryInterface(riid, ppvOut);
2718  }
2719  break;
2720 
2721  case SVGIO_SELECTION:
2722  GetSelections();
2723  hr = m_pSFParent->GetUIObjectOf(m_hWnd, m_cidl, m_apidl, riid, 0, ppvOut);
2724  if (FAILED_UNEXPECTEDLY(hr))
2725  return hr;
2726 
2727  if (IsEqualIID(riid, IID_IContextMenu))
2728  IUnknown_SetSite(*((IUnknown**)ppvOut), (IShellView *)this);
2729 
2730  break;
2731  }
2732 
2733  TRACE("-- (%p)->(interface=%p)\n", this, *ppvOut);
2734 
2735  return hr;
2736 }
2737 
2739 {
2740  TRACE("(%p)->(%p), stub\n", this, pViewMode);
2741 
2742  if (!pViewMode)
2743  return E_INVALIDARG;
2744 
2745  *pViewMode = m_FolderSettings.ViewMode;
2746  return S_OK;
2747 }
2748 
2750 {
2751  DWORD dwStyle;
2752  TRACE("(%p)->(%u), stub\n", this, ViewMode);
2753 
2754  /* It's not redundant to check FVM_AUTO because it's a (UINT)-1 */
2755  if (((INT)ViewMode < FVM_FIRST || (INT)ViewMode > FVM_LAST) && ((INT)ViewMode != FVM_AUTO))
2756  return E_INVALIDARG;
2757 
2758  /* Windows before Vista uses LVM_SETVIEW and possibly
2759  LVM_SETEXTENDEDLISTVIEWSTYLE to set the style of the listview,
2760  while later versions seem to accomplish this through other
2761  means. */
2762  switch (ViewMode)
2763  {
2764  case FVM_ICON:
2765  dwStyle = LVS_ICON;
2766  break;
2767  case FVM_DETAILS:
2768  dwStyle = LVS_REPORT;
2769  break;
2770  case FVM_SMALLICON:
2771  dwStyle = LVS_SMALLICON;
2772  break;
2773  case FVM_LIST:
2774  dwStyle = LVS_LIST;
2775  break;
2776  default:
2777  {
2778  FIXME("ViewMode %d not implemented\n", ViewMode);
2779  dwStyle = LVS_LIST;
2780  break;
2781  }
2782  }
2783 
2784  m_ListView.ModifyStyle(LVS_TYPEMASK, dwStyle);
2785 
2786  /* This will not necessarily be the actual mode set above.
2787  This mimics the behavior of Windows XP. */
2788  m_FolderSettings.ViewMode = ViewMode;
2789 
2790  return S_OK;
2791 }
2792 
2794 {
2795  if (m_pSFParent == NULL)
2796  return E_FAIL;
2797 
2798  return m_pSFParent->QueryInterface(riid, ppv);
2799 }
2800 
2802 {
2803  PCUITEMID_CHILD pidl = _PidlByItem(iItemIndex);
2804  if (pidl)
2805  {
2806  *ppidl = ILClone(pidl);
2807  return S_OK;
2808  }
2809 
2810  *ppidl = 0;
2811  return E_INVALIDARG;
2812 }
2813 
2815 {
2816  TRACE("(%p)->(%u %p)\n", this, uFlags, pcItems);
2817 
2818  if (uFlags != SVGIO_ALLVIEW)
2819  FIXME("some flags unsupported, %x\n", uFlags & ~SVGIO_ALLVIEW);
2820 
2822 
2823  return S_OK;
2824 }
2825 
2827 {
2828  return E_NOTIMPL;
2829 }
2830 
2832 {
2833  TRACE("(%p)->(%p)\n", this, piItem);
2834 
2835  *piItem = m_ListView.GetSelectionMark();
2836 
2837  return S_OK;
2838 }
2839 
2841 {
2842  TRACE("(%p)->(%p)\n", this, piItem);
2843 
2844  *piItem = m_ListView.GetNextItem(-1, LVNI_FOCUSED);
2845 
2846  return S_OK;
2847 }
2848 
2850 {
2851  int lvIndex = LV_FindItemByPidl(pidl);
2852  if (lvIndex == -1 || ppt == NULL)
2853  return E_INVALIDARG;
2854 
2855  m_ListView.GetItemPosition(lvIndex, ppt);
2856  return S_OK;
2857 }
2858 
2860 {
2861  TRACE("(%p)->(%p)\n", this, ppt);
2862 
2863  if (!m_ListView)
2864  return S_FALSE;
2865 
2866  if (ppt)
2867  {
2868  SIZE spacing;
2869  m_ListView.GetItemSpacing(spacing);
2870 
2871  ppt->x = spacing.cx;
2872  ppt->y = spacing.cy;
2873  }
2874 
2875  return S_OK;
2876 }
2877 
2879 {
2880  return E_NOTIMPL;
2881 }
2882 
2884 {
2885  return ((m_ListView.GetStyle() & LVS_AUTOARRANGE) ? S_OK : S_FALSE);
2886 }
2887 
2889 {
2890  DWORD dwExStyle = (DWORD)m_ListView.SendMessage(LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0);
2891  return ((dwExStyle & LVS_EX_SNAPTOGRID) ? S_OK : S_FALSE);
2892 }
2893 
2895 {
2896  LVITEMW lvItem;
2897 
2898  TRACE("(%p)->(%d, %x)\n", this, iItem, dwFlags);
2899 
2900  lvItem.state = 0;
2901  lvItem.stateMask = LVIS_SELECTED;
2902 
2903  if (dwFlags & SVSI_ENSUREVISIBLE)
2904  m_ListView.EnsureVisible(iItem, 0);
2905 
2906  /* all items */
2907  if (dwFlags & SVSI_DESELECTOTHERS)
2909 
2910  /* this item */
2911  if (dwFlags & SVSI_SELECT)
2912  lvItem.state |= LVIS_SELECTED;
2913 
2914  if (dwFlags & SVSI_FOCUSED)
2915  lvItem.stateMask |= LVIS_FOCUSED;
2916 
2917  m_ListView.SetItemState(iItem, lvItem.state, lvItem.stateMask);
2918 
2919  if ((dwFlags & SVSI_EDIT) == SVSI_EDIT)
2920  m_ListView.EditLabel(iItem);
2921 
2922  return S_OK;
2923 }
2924 
2926 {
2927  /* Reset the selection */
2929 
2930  int lvIndex;
2931  for (UINT i = 0 ; i < m_cidl; i++)
2932  {
2933  lvIndex = LV_FindItemByPidl(apidl[i]);
2934  if (lvIndex != -1)
2935  {
2936  SelectItem(lvIndex, dwFlags);
2937  m_ListView.SetItemPosition(lvIndex, &apt[i]);
2938  }
2939  }
2940 
2941  return S_OK;
2942 }
2943 
2944 /**********************************************************
2945  * IShellView2 implementation
2946  */
2947 
2949 {
2950  FIXME("(%p)->(%p, %lu) stub\n", this, view_guid, view_type);
2951  return E_NOTIMPL;
2952 }
2953 
2955 {
2956  return CreateViewWindow3(view_params->psbOwner, view_params->psvPrev,
2957  SV3CVW3_DEFAULT, (FOLDERFLAGS)view_params->pfs->fFlags, (FOLDERFLAGS)view_params->pfs->fFlags,
2958  (FOLDERVIEWMODE)view_params->pfs->ViewMode, view_params->pvid, view_params->prcView, &view_params->hwndView);
2959 }
2960 
2962 {
2963  OLEMENUGROUPWIDTHS omw = { { 0, 0, 0, 0, 0, 0 } };
2964 
2965  *hwnd = NULL;
2966 
2967  TRACE("(%p)->(shlview=%p shlbrs=%p rec=%p hwnd=%p vmode=%x flags=%x)\n", this, psvPrevious, psb, prcView, hwnd, mode, flags);
2968  if (prcView != NULL)
2969  TRACE("-- left=%i top=%i right=%i bottom=%i\n", prcView->left, prcView->top, prcView->right, prcView->bottom);
2970 
2971  /* Validate the Shell Browser */
2972  if (psb == NULL || m_hWnd)
2973  return E_UNEXPECTED;
2974 
2975  if (view_flags != SV3CVW3_DEFAULT)
2976  FIXME("unsupported view flags 0x%08x\n", view_flags);
2977 
2978  /* Set up the member variables */
2979  m_pShellBrowser = psb;
2982 
2983  if (view_id)
2984  {
2985  if (IsEqualIID(*view_id, VID_LargeIcons))
2987  else if (IsEqualIID(*view_id, VID_SmallIcons))
2989  else if (IsEqualIID(*view_id, VID_List))
2991  else if (IsEqualIID(*view_id, VID_Details))
2993  else if (IsEqualIID(*view_id, VID_Thumbnails))
2995  else if (IsEqualIID(*view_id, VID_Tile))
2997  else if (IsEqualIID(*view_id, VID_ThumbStrip))
2999  else
3000  FIXME("Ignoring unrecognized VID %s\n", debugstr_guid(view_id));
3001  }
3002 
3003  /* Get our parent window */
3004  m_pShellBrowser->GetWindow(&m_hWndParent);
3005 
3006  /* Try to get the ICommDlgBrowserInterface, adds a reference !!! */
3009  {
3010  TRACE("-- CommDlgBrowser\n");
3011  }
3012 
3014  if (m_hWnd == NULL)
3015  return E_FAIL;
3016 
3017  *hwnd = m_hWnd;
3018 
3019  CheckToolbar();
3020 
3021  if (!*hwnd)
3022  return E_FAIL;
3023 
3025 
3027  UpdateWindow();
3028 
3029  if (!m_hMenu)
3030  {
3031  m_hMenu = CreateMenu();
3032  m_pShellBrowser->InsertMenusSB(m_hMenu, &omw);
3033  TRACE("-- after fnInsertMenusSB\n");
3034  }
3035 
3036  _MergeToolbar();
3037 
3038  return S_OK;
3039 }
3040 
3042 {
3043  FIXME("(%p)->(%p) stub\n", this, new_pidl);
3044  return E_NOTIMPL;
3045 }
3046 
3048 {
3049  FIXME("(%p)->(%p, %u, %p) stub\n", this, item, flags, point);
3050  return E_NOTIMPL;
3051 }
3052 
3053 /**********************************************************
3054  * IShellFolderView implementation
3055  */
3057 {
3058  FIXME("(%p)->(%ld) stub\n", this, sort);
3059  return E_NOTIMPL;
3060 }
3061 
3063 {
3064  FIXME("(%p)->(%p) stub\n", this, sort);
3065  return E_NOTIMPL;
3066 }
3067 
3069 {
3071  return S_OK;
3072 }
3073 
3075 {
3076  m_ListView.ModifyStyle(0, LVS_AUTOARRANGE);
3078  return S_OK;
3079 }
3080 
3082 {
3083  TRACE("(%p)->(%p %p)\n", this, pidl, item);
3084  *item = LV_AddItem(pidl);
3085  return (int)*item >= 0 ? S_OK : E_OUTOFMEMORY;
3086 }
3087 
3089 {
3090  TRACE("(%p)->(%p %d)\n", this, pidl, item);
3091  return Item(item, pidl);
3092 }
3093 
3095 {
3096 
3097  TRACE("(%p)->(%p %p)\n", this, pidl, item);
3098 
3099  if (pidl)
3100  {
3103  }
3104  else
3105  {
3106  *item = 0;
3108  }
3109 
3110  return S_OK;
3111 }
3112 
3114 {
3115  TRACE("(%p)->(%p)\n", this, count);
3117  return S_OK;
3118 }
3119 
3121 {
3122  FIXME("(%p)->(%d %x) stub\n", this, count, flags);
3123  return E_NOTIMPL;
3124 }
3125 
3127 {
3128  FIXME("(%p)->(%p %p %p) stub\n", this, pidl_old, pidl_new, item);
3129  return E_NOTIMPL;
3130 }
3131 
3133 {
3134  FIXME("(%p)->(%p %p) stub\n", this, pidl, item);
3135  return E_NOTIMPL;
3136 }
3137 
3139 {
3140  TRACE("(%p)->(%d)\n", this, redraw);
3142  return S_OK;
3143 }
3144 
3146 {
3147  FIXME("(%p)->(%p) stub\n", this, count);
3148  return E_NOTIMPL;
3149 }
3150 
3152 {
3153  TRACE("(%p)->(%p %p)\n", this, pidl, items);
3154 
3155  *items = GetSelections();
3156 
3157  if (*items)
3158  {
3159  *pidl = static_cast<PCUITEMID_CHILD *>(LocalAlloc(0, *items * sizeof(PCUITEMID_CHILD)));
3160  if (!*pidl)
3161  {
3162  return E_OUTOFMEMORY;
3163  }
3164 
3165  /* it's documented that caller shouldn't PIDLs, only array itself */
3166  memcpy(*pidl, m_apidl, *items * sizeof(PCUITEMID_CHILD));
3167  }
3168 
3169  return S_OK;
3170 }
3171 
3173 {
3174  if ((m_iDragOverItem == -1 || m_pCurDropTarget == NULL) &&
3176  {
3177  return S_OK;
3178  }
3179 
3180  return S_FALSE;
3181 }
3182 
3184 {
3185  if (!pt)
3186  return E_INVALIDARG;
3187 
3188  *pt = m_ptFirstMousePos;
3189  return S_OK;
3190 }
3191 
3193 {
3194  FIXME("(%p)->(%p) stub\n", this, pt);
3195  return E_NOTIMPL;
3196 }
3197 
3199 {
3200  TRACE("(%p)->(%p)\n", this, obj);
3201  return E_NOTIMPL;
3202 }
3203 
3205 {
3206  FIXME("(%p)->(%p %p) stub\n", this, pidl, pt);
3207  return E_NOTIMPL;
3208 }
3209 
3211 {
3212  FIXME("(%p)->(%p) stub\n", this, drop_target);
3213  return E_NOTIMPL;
3214 }
3215 
3217 {
3218  FIXME("(%p)->(%d) stub\n", this, move);
3219  return E_NOTIMPL;
3220 }
3221 
3223 {
3224  FIXME("(%p)->(%p) stub\n", this, obj);
3225  return E_NOTIMPL;
3226 }
3227 
3229 {
3230  FIXME("(%p)->(%p) stub\n", this, spacing);
3231  return E_NOTIMPL;
3232 }
3233 
3234 HRESULT STDMETHODCALLTYPE CDefView::SetCallback(IShellFolderViewCB *new_cb, IShellFolderViewCB **old_cb)
3235 {
3236  if (old_cb)
3237  *old_cb = m_pShellFolderViewCB.Detach();
3238 
3239  m_pShellFolderViewCB = new_cb;
3240  return S_OK;
3241 }
3242 
3244 {
3245  FIXME("(%p)->(%d) stub\n", this, flags);
3246  return E_NOTIMPL;
3247 }
3248 
3250 {
3251  TRACE("(%p)->(%p)\n", this, support);
3252  return S_OK;
3253 }
3254 
3256 {
3257  FIXME("(%p)->(%p) stub\n", this, disp);
3258  return E_NOTIMPL;
3259 }
3260 
3261 /**********************************************************
3262  * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
3263  */
3264 HRESULT WINAPI CDefView::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD *prgCmds, OLECMDTEXT *pCmdText)
3265 {
3266  FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
3267  this, pguidCmdGroup, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText);
3268 
3269  if (!prgCmds)
3270  return E_INVALIDARG;
3271 
3272  for (UINT i = 0; i < cCmds; i++)
3273  {
3274  FIXME("\tprgCmds[%d].cmdID = %d\n", i, prgCmds[i].cmdID);
3275  prgCmds[i].cmdf = 0;
3276  }
3277 
3278  return OLECMDERR_E_UNKNOWNGROUP;
3279 }
3280 
3281 /**********************************************************
3282  * ISVOleCmdTarget_Exec (IOleCommandTarget)
3283  *
3284  * nCmdID is the OLECMDID_* enumeration
3285  */
3286 HRESULT WINAPI CDefView::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
3287 {
3288  FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
3289  this, debugstr_guid(pguidCmdGroup), nCmdID, nCmdexecopt, pvaIn, pvaOut);
3290 
3291  if (!pguidCmdGroup)
3292  return OLECMDERR_E_UNKNOWNGROUP;
3293 
3294  if (IsEqualCLSID(*pguidCmdGroup, m_Category))
3295  {
3296  if (nCmdID == FCIDM_SHVIEW_AUTOARRANGE)
3297  {
3298  if (V_VT(pvaIn) != VT_INT_PTR)
3299  return OLECMDERR_E_NOTSUPPORTED;
3300 
3301  TPMPARAMS params;
3302  params.cbSize = sizeof(params);
3303  params.rcExclude = *(RECT*) V_INTREF(pvaIn);
3304 
3305  if (m_hMenuViewModes)
3306  {
3307  /* Duplicate all but the last two items of the view modes menu */
3308  HMENU hmenuViewPopup = CreatePopupMenu();
3309  Shell_MergeMenus(hmenuViewPopup, m_hMenuViewModes, 0, 0, 0xFFFF, 0);
3310  DeleteMenu(hmenuViewPopup, GetMenuItemCount(hmenuViewPopup) - 1, MF_BYPOSITION);
3311  DeleteMenu(hmenuViewPopup, GetMenuItemCount(hmenuViewPopup) - 1, MF_BYPOSITION);
3312  CheckViewMode(hmenuViewPopup);
3313  TrackPopupMenuEx(hmenuViewPopup, TPM_LEFTALIGN | TPM_TOPALIGN, params.rcExclude.left, params.rcExclude.bottom, m_hWndParent, &params);
3314  ::DestroyMenu(hmenuViewPopup);
3315  }
3316 
3317  // pvaOut is VT_I4 with value 0x403 (cmd id of the new mode maybe?)
3318  V_VT(pvaOut) = VT_I4;
3319  V_I4(pvaOut) = 0x403;
3320  }
3321  }
3322 
3323  if (IsEqualIID(*pguidCmdGroup, CGID_Explorer) &&
3324  (nCmdID == 0x29) &&
3325  (nCmdexecopt == 4) && pvaOut)
3326  return S_OK;
3327 
3328  if (IsEqualIID(*pguidCmdGroup, CGID_ShellDocView) &&
3329  (nCmdID == 9) &&
3330  (nCmdexecopt == 0))
3331  return 1;
3332 
3333  return OLECMDERR_E_UNKNOWNGROUP;
3334 }
3335 
3336 /**********************************************************
3337  * ISVDropTarget implementation
3338  */
3339 
3340 /******************************************************************************
3341  * drag_notify_subitem [Internal]
3342  *
3343  * Figure out the shellfolder object, which is currently under the mouse cursor
3344  * and notify it via the IDropTarget interface.
3345  */
3346 
3347 #define SCROLLAREAWIDTH 20
3348 
3350 {
3351  LONG lResult;
3352  HRESULT hr;
3353  RECT clientRect;
3354 
3355  /* The key state on drop doesn't have MK_LBUTTON or MK_RBUTTON because it
3356  reflects the key state after the user released the button, so we need
3357  to remember the last key state when the button was pressed */
3358  m_grfKeyState = grfKeyState;
3359 
3360  /* Map from global to client coordinates and query the index of the listview-item, which is
3361  * currently under the mouse cursor. */
3362  LVHITTESTINFO htinfo = {{pt.x, pt.y}, LVHT_ONITEM};
3363  ScreenToClient(&htinfo.pt);
3364  lResult = m_ListView.HitTest(&htinfo);
3365 
3366  /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
3367  ::GetClientRect(m_ListView, &clientRect);
3368  if (htinfo.pt.x == m_ptLastMousePos.x && htinfo.pt.y == m_ptLastMousePos.y &&
3369  (htinfo.pt.x < SCROLLAREAWIDTH || htinfo.pt.x > clientRect.right - SCROLLAREAWIDTH ||
3370  htinfo.pt.y < SCROLLAREAWIDTH || htinfo.pt.y > clientRect.bottom - SCROLLAREAWIDTH ))
3371  {
3372  m_cScrollDelay = (m_cScrollDelay + 1) % 5; /* DragOver is called every 50 ms */
3373  if (m_cScrollDelay == 0)
3374  {
3375  /* Mouse did hover another 250 ms over the scroll-area */
3376  if (htinfo.pt.x < SCROLLAREAWIDTH)
3377  m_ListView.SendMessageW(WM_HSCROLL, SB_LINEUP, 0);
3378 
3379  if (htinfo.pt.x > clientRect.right - SCROLLAREAWIDTH)
3380  m_ListView.SendMessageW(WM_HSCROLL, SB_LINEDOWN, 0);
3381 
3382  if (htinfo.pt.y < SCROLLAREAWIDTH)
3383  m_ListView.SendMessageW(WM_VSCROLL, SB_LINEUP, 0);
3384 
3385  if (htinfo.pt.y > clientRect.bottom - SCROLLAREAWIDTH)
3386  m_ListView.SendMessageW(WM_VSCROLL, SB_LINEDOWN, 0);
3387  }
3388  }
3389  else
3390  {
3391  m_cScrollDelay = 0; /* Reset, if the cursor is not over the listview's scroll-area */
3392  }
3393 
3394  m_ptLastMousePos = htinfo.pt;
3396 
3397  /* We need to check if we drag the selection over itself */
3398  if (lResult != -1 && m_pSourceDataObject.p != NULL)
3399  {
3400  PCUITEMID_CHILD pidl = _PidlByItem(lResult);
3401 
3402  for (UINT i = 0; i < m_cidl; i++)
3403  {
3404  if (pidl == m_apidl[i])
3405  {
3406  /* The item that is being draged is hovering itself. */
3407  lResult = -1;
3408  break;
3409  }
3410  }
3411  }
3412 
3413  /* If we are still over the previous sub-item, notify it via DragOver and return. */
3414  if (m_pCurDropTarget && lResult == m_iDragOverItem)
3415  return m_pCurDropTarget->DragOver(grfKeyState, pt, pdwEffect);
3416 
3417  /* We've left the previous sub-item, notify it via DragLeave and Release it. */
3418  if (m_pCurDropTarget)
3419  {
3421  if (pidl)
3422  SelectItem(pidl, 0);
3423 
3424  m_pCurDropTarget->DragLeave();
3426  }
3427 
3428  m_iDragOverItem = lResult;
3429 
3430  if (lResult == -1)
3431  {
3432  /* We are not above one of the listview's subitems. Bind to the parent folder's
3433  * DropTarget interface. */
3434  hr = m_pSFParent->CreateViewObject(NULL, IID_PPV_ARG(IDropTarget,&m_pCurDropTarget));
3435  }
3436  else
3437  {
3438  /* Query the relative PIDL of the shellfolder object represented by the currently
3439  * dragged over listview-item ... */
3440  PCUITEMID_CHILD pidl = _PidlByItem(lResult);
3441 
3442  /* ... and bind m_pCurDropTarget to the IDropTarget interface of an UIObject of this object */
3443  hr = m_pSFParent->GetUIObjectOf(m_ListView, 1, &pidl, IID_NULL_PPV_ARG(IDropTarget, &m_pCurDropTarget));
3444  }
3445 
3447 
3448  /* If anything failed, m_pCurDropTarget should be NULL now, which ought to be a save state. */
3449  if (FAILED(hr))
3450  {
3451  *pdwEffect = DROPEFFECT_NONE;
3452  return hr;
3453  }
3454 
3455  if (m_iDragOverItem != -1)
3456  {
3457  SelectItem(m_iDragOverItem, SVSI_SELECT);
3458  }
3459 
3460  /* Notify the item just entered via DragEnter. */
3461  return m_pCurDropTarget->DragEnter(m_pCurDataObject, grfKeyState, pt, pdwEffect);
3462 }
3463 
3464 HRESULT WINAPI CDefView::DragEnter(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
3465 {
3466  if (*pdwEffect == DROPEFFECT_NONE)
3467  return S_OK;
3468 
3469  /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
3470  m_pCurDataObject = pDataObject;
3471 
3472  HRESULT hr = drag_notify_subitem(grfKeyState, pt, pdwEffect);
3473  if (SUCCEEDED(hr))
3474  {
3475  POINT ptClient = {pt.x, pt.y};
3476  ScreenToClient(&ptClient);
3477  ImageList_DragEnter(m_hWnd, ptClient.x, ptClient.y);
3478  }
3479 
3480  return hr;
3481 }
3482 
3484 {
3485  POINT ptClient = {pt.x, pt.y};
3486  ScreenToClient(&ptClient);
3487  ImageList_DragMove(ptClient.x, ptClient.y);
3488  return drag_notify_subitem(grfKeyState, pt, pdwEffect);
3489 }
3490 
3492 {
3494 
3495  if (m_pCurDropTarget)
3496  {
3497  m_pCurDropTarget->DragLeave();
3499  }
3500 
3501  if (m_pCurDataObject != NULL)
3502  {
3504  }
3505 
3506  m_iDragOverItem = 0;
3507 
3508  return S_OK;
3509 }
3510 
3512 {
3513  RECT rcBound;
3514  INT i, nCount = m_ListView.GetItemCount();
3515  DWORD dwSpacing;
3516  INT dx, dy;
3517  BOOL bSmall = ((m_ListView.GetStyle() & LVS_TYPEMASK) != LVS_ICON);
3518 
3519  /* FIXME: LVM_GETORIGIN is broken. See CORE-17266 */
3520  pt.x += m_ListView.GetScrollPos(SB_HORZ);
3521  pt.y += m_ListView.GetScrollPos(SB_VERT);
3522 
3523  if (m_ListView.GetStyle() & LVS_ALIGNLEFT)
3524  {
3525  // vertically
3526  for (i = 0; i < nCount; ++i)
3527  {
3528  dwSpacing = ListView_GetItemSpacing(m_ListView, bSmall);
3529  dx = LOWORD(dwSpacing);
3530  dy = HIWORD(dwSpacing);
3532  rcBound.right = rcBound.left + dx;
3533  rcBound.bottom = rcBound.top + dy;
3534  if (pt.x < rcBound.right && pt.y < (rcBound.top + rcBound.bottom) / 2)
3535  {
3536  return i;
3537  }
3538  }
3539  for (i = nCount - 1; i >= 0; --i)
3540  {
3542  if (rcBound.left < pt.x && rcBound.top < pt.y)
3543  {
3544  return i + 1;
3545  }
3546  }
3547  }
3548  else
3549  {
3550  // horizontally
3551  for (i = 0; i < nCount; ++i)
3552  {
3553  dwSpacing = ListView_GetItemSpacing(m_ListView, bSmall);
3554  dx = LOWORD(dwSpacing);
3555  dy = HIWORD(dwSpacing);
3557  rcBound.right = rcBound.left + dx;
3558  rcBound.bottom = rcBound.top + dy;
3559  if (pt.y < rcBound.bottom && pt.x < rcBound.left)
3560  {
3561  return i;
3562  }
3563  if (pt.y < rcBound.bottom && pt.x < rcBound.right)
3564  {
3565  return i + 1;
3566  }
3567  }
3568  for (i = nCount - 1; i >= 0; --i)
3569  {
3571  if (rcBound.left < pt.x && rcBound.top < pt.y)
3572  {
3573  return i + 1;
3574  }
3575  }
3576  }
3577 
3578  return nCount;
3579 }
3580 
3582 {
3583  LRESULT lResult;
3584 
3586  {
3587  int nPartArray[] = {-1};
3588  m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETPARTS, _countof(nPartArray), (LPARAM)nPartArray, &lResult);
3589  return;
3590  }
3591 
3592  int nFileSizePartLength = 125;
3593  const int nLocationPartLength = 150;
3594  const int nRightPartsLength = nFileSizePartLength + nLocationPartLength;
3595  int nObjectsPartLength = nWidth - nRightPartsLength;
3596 
3597  /* If the window is small enough just divide each part into thirds
3598  * This is the behavior of Windows Server 2003. */
3599  if (nObjectsPartLength <= nLocationPartLength)
3600  nObjectsPartLength = nFileSizePartLength = nWidth / 3;
3601 
3602  int nPartArray[] = {nObjectsPartLength, nObjectsPartLength + nFileSizePartLength, -1};
3603 
3604  m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETPARTS, _countof(nPartArray), (LPARAM)nPartArray, &lResult);
3605 }
3606 
3608 {
3609  /* Get the handle for the status bar */
3610  HWND fStatusBar;
3611  m_pShellBrowser->GetControlWindow(FCW_STATUS, &fStatusBar);
3612 
3613  /* Get the size of our status bar */
3614  RECT statusBarSize;
3615  ::GetWindowRect(fStatusBar, &statusBarSize);
3616 
3617  /* Resize the status bar */
3618  _HandleStatusBarResize(statusBarSize.right - statusBarSize.left);
3619 }
3620 
3622 
3623 static INT CALLBACK
3624 SelectionMoveCompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
3625 {
3626  CLParamIndexMap *pmap = (CLParamIndexMap *)lParamSort;
3627  INT i1 = pmap->Lookup(lParam1), i2 = pmap->Lookup(lParam2);
3628  if (i1 < i2)
3629  return -1;
3630  if (i1 > i2)
3631  return 1;
3632  return 0;
3633 }
3634 
3636 {
3637  // get insertable index from position
3638  INT iPosition = _FindInsertableIndexFromPoint(pt);
3639 
3640  // create identity mapping of indexes
3642  INT nCount = m_ListView.GetItemCount();
3643  for (INT i = 0; i < nCount; ++i)
3644  {
3645  array.Add(i);
3646  }
3647 
3648  // re-ordering mapping
3649  INT iItem = -1;
3650  while ((iItem = m_ListView.GetNextItem(iItem, LVNI_SELECTED)) >= 0)
3651  {
3652  INT iFrom = iItem, iTo = iPosition;
3653  if (iFrom < iTo)
3654  --iTo;
3655  if (iFrom >= nCount)
3656  iFrom = nCount - 1;
3657  if (iTo >= nCount)
3658  iTo = nCount - 1;
3659 
3660  // shift indexes by swapping (like a bucket relay)
3661  if (iFrom < iTo)
3662  {
3663  for (INT i = iFrom; i < iTo; ++i)
3664  {
3665  // swap array[i] and array[i + 1]
3666  INT tmp = array[i];
3667  array[i] = array[i + 1];
3668  array[i + 1] = tmp;
3669  }
3670  }
3671  else
3672  {
3673  for (INT i = iFrom; i > iTo; --i)
3674  {
3675  // swap array[i] and array[i - 1]
3676  INT tmp = array[i];
3677  array[i] = array[i - 1];
3678  array[i - 1] = tmp;
3679  }
3680  }
3681  }
3682 
3683  // create mapping (ListView's lParam to index) from array
3685  for (INT i = 0; i < nCount; ++i)
3686  {
3688  map.Add(lParam, i);
3689  }
3690 
3691  // finally sort
3693 }
3694 
3695 HRESULT WINAPI CDefView::Drop(IDataObject* pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
3696 {
3699 
3700  if ((IsDropOnSource(NULL) == S_OK) &&
3701  (*pdwEffect & DROPEFFECT_MOVE) &&
3703  {
3704  if (m_pCurDropTarget)
3705  {
3706  m_pCurDropTarget->DragLeave();
3708  }
3709 
3710  POINT ptDrop = { pt.x, pt.y };
3711  ::ScreenToClient(m_ListView, &ptDrop);
3712  ::ClientToListView(m_ListView, &ptDrop);
3713  m_ptLastMousePos = ptDrop;
3714 
3716  if (m_ListView.GetStyle() & LVS_AUTOARRANGE)
3717  {
3719  }
3720  else
3721  {
3722  POINT ptItem;
3723  INT iItem = -1;
3724  while ((iItem = m_ListView.GetNextItem(iItem, LVNI_SELECTED)) >= 0)
3725  {
3726  if (m_ListView.GetItemPosition(iItem, &ptItem))
3727  {
3728  ptItem.x += m_ptLastMousePos.x - m_ptFirstMousePos.x;
3729  ptItem.y += m_ptLastMousePos.y - m_ptFirstMousePos.y;
3730  m_ListView.SetItemPosition(iItem, &ptItem);
3731  }
3732  }
3733  }
3735  }
3736  else if (m_pCurDropTarget)
3737  {
3738  m_pCurDropTarget->Drop(pDataObject, grfKeyState, pt, pdwEffect);
3740  }
3741 
3743  m_iDragOverItem = 0;
3744  return S_OK;
3745 }
3746 
3747 /**********************************************************
3748  * ISVDropSource implementation
3749  */
3750 
3752 {
3753  TRACE("(%p)\n", this);
3754 
3755  if (fEscapePressed)
3756  return DRAGDROP_S_CANCEL;
3757  else if (!(grfKeyState & MK_LBUTTON) && !(grfKeyState & MK_RBUTTON))
3758  return DRAGDROP_S_DROP;
3759  else
3760  return S_OK;
3761 }
3762 
3764 {
3765  TRACE("(%p)\n", this);
3766 
3768 }
3769 
3770 /**********************************************************
3771  * ISVViewObject implementation
3772  */
3773 
3774 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)
3775 {
3776  FIXME("Stub: this=%p\n", this);
3777 
3778  return E_NOTIMPL;
3779 }
3780 
3781 HRESULT WINAPI CDefView::GetColorSet(DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd, HDC hicTargetDevice, LOGPALETTE **ppColorSet)
3782 {
3783  FIXME("Stub: this=%p\n", this);
3784 
3785  return E_NOTIMPL;
3786 }
3787 
3788 HRESULT WINAPI CDefView::Freeze(DWORD dwDrawAspect, LONG lindex, void *pvAspect, DWORD *pdwFreeze)
3789 {
3790  FIXME("Stub: this=%p\n", this);
3791 
3792  return E_NOTIMPL;
3793 }
3794 
3796 {
3797  FIXME("Stub: this=%p\n", this);
3798 
3799  return E_NOTIMPL;
3800 }
3801 
3803 {
3804  FIXME("partial stub: %p 0x%08x 0x%08x %p\n", this, aspects, advf, pAdvSink);
3805 
3806  /* FIXME: we set the AdviseSink, but never use it to send any advice */
3807  m_pAdvSink = pAdvSink;
3808  m_dwAspects = aspects;
3809  m_dwAdvf = advf;
3810 
3811  return S_OK;
3812 }
3813 
3814 HRESULT WINAPI CDefView::GetAdvise(DWORD *pAspects, DWORD *pAdvf, IAdviseSink **ppAdvSink)
3815 {
3816  TRACE("this=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n", this, pAspects, pAdvf, ppAdvSink);
3817 
3818  if (ppAdvSink)
3819  {
3820  *ppAdvSink = m_pAdvSink;
3821  m_pAdvSink.p->AddRef();
3822  }
3823 
3824  if (pAspects)
3825  *pAspects = m_dwAspects;
3826 
3827  if (pAdvf)
3828  *pAdvf = m_dwAdvf;
3829 
3830  return S_OK;
3831 }
3832 
3834 {
3835  if (IsEqualIID(guidService, SID_IShellBrowser))
3836  return m_pShellBrowser->QueryInterface(riid, ppvObject);
3837  else if(IsEqualIID(guidService, SID_IFolderView))
3838  return QueryInterface(riid, ppvObject);
3839 
3840  return E_NOINTERFACE;
3841 }
3842 
3844 {
3846  HRESULT hr = S_OK;
3847 
3848  hr = IUnknown_QueryService(m_pShellBrowser, IID_IExplorerToolbar, IID_PPV_ARG(IExplorerToolbar, &ptb));
3849  if (FAILED(hr))
3850  return hr;
3851 
3852  m_Category = CGID_DefViewFrame;
3853 
3854  hr = ptb->SetCommandTarget(static_cast<IOleCommandTarget*>(this), &m_Category, 0);
3855  if (FAILED(hr))
3856  return hr;
3857 
3858  if (hr == S_FALSE)
3859  return S_OK;
3860 
3861 #if 0
3862  hr = ptb->AddButtons(&m_Category, buttonsCount, buttons);
3863  if (FAILED(hr))
3864  return hr;
3865 #endif
3866 
3867  return S_OK;
3868 }
3869 
3871 {
3872  HRESULT hr = E_NOTIMPL;
3873 
3875  {
3876  hr = m_pShellFolderViewCB->MessageSFVCB(uMsg, wParam, lParam);
3877  }
3878 
3879  return hr;
3880 }
3881 
3883 {
3884  return ShellObjectCreatorInit<CDefView>(pFolder, riid, ppvOut);
3885 }
3886 
3888  LPCSFV psvcbi, /* [in] shelltemplate struct */
3889  IShellView **ppsv) /* [out] IShellView pointer */
3890 {
3891  CComPtr<IShellView> psv;
3892  HRESULT hRes;
3893 
3894  TRACE("sf=%p pidl=%p cb=%p mode=0x%08x parm=%p\n",
3895  psvcbi->pshf, psvcbi->pidl, psvcbi->pfnCallback,
3896  psvcbi->fvm, psvcbi->psvOuter);
3897 
3898  *ppsv = NULL;
3899  hRes = CDefView_CreateInstance(psvcbi->pshf, IID_PPV_ARG(IShellView, &psv));
3900  if (FAILED_UNEXPECTEDLY(hRes))
3901  return hRes;
3902 
3903  *ppsv = psv.Detach();
3904  return hRes;
3905 }
3906 
3908  IShellView **ppsv)
3909 {
3910  CComPtr<IShellView> psv;
3911  HRESULT hRes;
3912 
3913  if (!ppsv)
3914  return E_INVALIDARG;
3915 
3916  *ppsv = NULL;
3917 
3918  if (!pcsfv || pcsfv->cbSize != sizeof(*pcsfv))
3919  return E_INVALIDARG;
3920 
3921  TRACE("sf=%p outer=%p callback=%p\n",
3922  pcsfv->pshf, pcsfv->psvOuter, pcsfv->psfvcb);
3923 
3924  hRes = CDefView_CreateInstance(pcsfv->pshf, IID_PPV_ARG(IShellView, &psv));
3925  if (FAILED(hRes))
3926  return hRes;
3927 
3928  if (pcsfv->psfvcb)
3929  {
3931  if (SUCCEEDED(psv->QueryInterface(IID_PPV_ARG(IShellFolderView, &sfv))))
3932  {
3933  sfv->SetCallback(pcsfv->psfvcb, NULL);
3934  }
3935  }
3936 
3937  *ppsv = psv.Detach();
3938  return hRes;
3939 }
#define SHCNE_MKDIR
Definition: shlobj.h:1732
HRESULT FillViewMenu()
Definition: CDefView.cpp:1368
#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:3882
HRESULT FillEditMenu()
Definition: CDefView.cpp:1351
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:3204
int LV_FindItemByPidl(PCUITEMID_CHILD pidl)
Definition: CDefView.cpp:853
HRESULT FillArrangeAsMenu(HMENU hmenuArrange)
Definition: CDefView.cpp:1384
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:3802
#define WM_SYSCOLORCHANGE
Definition: winuser.h:1616
virtual HRESULT STDMETHODCALLTYPE DestroyViewWindow()
Definition: CDefView.cpp:2563
void WINAPI DPA_DestroyCallback(HDPA hdpa, PFNDPAENUMCALLBACK enumProc, LPVOID lParam)
Definition: dpa.c:1003
BOOL GetScrollPos(int nBar)
Definition: atlwin.h:706
#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:3483
const GUID IID_IViewObject
BOOL MoveWindow(int x, int y, int nWidth, int nHeight, BOOL bRepaint=TRUE)
Definition: atlwin.h:1020
virtual HRESULT STDMETHODCALLTYPE GetAutoArrange()
Definition: CDefView.cpp:2883
virtual HRESULT STDMETHODCALLTYPE Refresh()
Definition: CDefView.cpp:2545
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:2888
#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:3243
virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
Definition: CDefView.cpp:3833
long y
Definition: polytest.cpp:48
#define FCIDM_SHVIEW_SNAPTOGRID
Definition: shresdef.h:811
#define WM_GETDLGCODE
Definition: winuser.h:1679
#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:1498
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:2357
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:2954
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:3198
#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:1793
#define pt(x, y)
Definition: drawing.c:79
#define TPM_LEFTALIGN
Definition: winuser.h:2367
#define GET_WM_COMMAND_ID(wp, lp)
Definition: CDefView.cpp:377
virtual HRESULT STDMETHODCALLTYPE GetSelectedCount(UINT *count)
Definition: CDefView.cpp:3145
#define WM_INITMENUPOPUP
Definition: winuser.h:1736
BOOL _ILIsNetHood(LPCITEMIDLIST pidl)
Definition: pidl.c:1909
REFIID riid
Definition: precomp.h:44
#define SPI_SETDESKWALLPAPER
Definition: winuser.h:1359
static BOOL ILIsParentOrSpecialParent(PCIDLIST_ABSOLUTE pidl1, PCIDLIST_ABSOLUTE pidl2)
Definition: CDefView.cpp:2253
#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:1728
#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:2377
_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:2948
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:1282
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:2878
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:1618
virtual HRESULT STDMETHODCALLTYPE SetCurrentViewMode(UINT ViewMode)
Definition: CDefView.cpp:2749
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:3106
LRESULT OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: CDefView.cpp:1826
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:2801
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:3056
LONG left
Definition: windef.h:306
void _HandleStatusBarResize(int width)
Definition: CDefView.cpp:3581
virtual HRESULT STDMETHODCALLTYPE GetSpacing(POINT *ppt)
Definition: CDefView.cpp:2859
virtual HRESULT STDMETHODCALLTYPE GetItemObject(UINT uItem, REFIID riid, void **ppv)
Definition: CDefView.cpp:2687
UINT uFlags
Definition: