4 * Copyright 1998,1999 <juergen.schmied@debitel.net>
6 * This is the view visualizing the data provided by the shellfolder.
7 * No direct access to data from pidls should be done from here.
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 * FIXME: The order by part of the background context menu should be
24 * built according to the columns shown.
26 * FIXME: Load/Save the view state from/into the stream provided by
29 * FIXME: CheckToolbar: handle the "new folder" and "folder up" button
31 * FIXME: ShellView_FillList: consider sort orders
33 * FIXME: implement the drag and drop in the old (msg-based) way
35 * FIXME: when the ShellView_WndProc gets a WM_NCDESTROY should we do a
40 #include "wine/port.h"
47 #define NONAMELESSUNION
48 #define NONAMELESSSTRUCT
61 #include "undocshell.h"
63 #include "wine/debug.h"
67 #include "shell32_main.h"
68 #include "shellfolder.h"
70 WINE_DEFAULT_DEBUG_CHANNEL(shell);
72 static const WCHAR SV_CLASS_NAME[] = {'S','H','E','L','L','D','L','L','_','D','e','f','V','i','e','w',0};
78 }LISTVIEW_SORT_INFO, *LPLISTVIEW_SORT_INFO;
82 const IShellView2Vtbl* lpVtbl;
84 const IOleCommandTargetVtbl* lpvtblOleCommandTarget;
85 const IDropTargetVtbl* lpvtblDropTarget;
86 const IDropSourceVtbl* lpvtblDropSource;
87 const IViewObjectVtbl* lpvtblViewObject;
88 const IFolderViewVtbl* lpvtblFolderView;
89 IShellFolder* pSFParent;
90 IShellFolder2* pSF2Parent;
91 IShellBrowser* pShellBrowser;
92 ICommDlgBrowser* pCommDlgBrowser;
93 HWND hWnd; /* SHELLDLL_DefView */
94 HWND hWndList; /* ListView control */
96 FOLDERSETTINGS FolderSettings;
101 LISTVIEW_SORT_INFO ListViewSortInfo;
102 ULONG hNotify; /* change notification handle */
106 IAdviseSink *pAdvSink;
107 IDropTarget* pCurDropTarget; /* The sub-item, which is currently dragged over */
108 IDataObject* pCurDataObject; /* The dragged data-object */
109 LONG iDragOverItem; /* Dragged over item's index, iff pCurDropTarget != NULL */
110 UINT cScrollDelay; /* Send a WM_*SCROLL msg every 250 ms during drag-scroll */
111 POINT ptLastMousePos; /* Mouse position at last DragOver call */
114 static const IShellView2Vtbl svvt;
115 static const IOleCommandTargetVtbl ctvt;
116 static const IDropTargetVtbl dtvt;
117 static const IDropSourceVtbl dsvt;
118 static const IViewObjectVtbl vovt;
119 static const IFolderViewVtbl fviewvt;
121 static inline IShellViewImpl *impl_from_IOleCommandTarget( IOleCommandTarget *iface )
123 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblOleCommandTarget));
126 static inline IShellViewImpl *impl_from_IDropTarget( IDropTarget *iface )
128 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblDropTarget));
131 static inline IShellViewImpl *impl_from_IDropSource( IDropSource *iface )
133 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblDropSource));
136 static inline IShellViewImpl *impl_from_IViewObject( IViewObject *iface )
138 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblViewObject));
141 static inline IShellViewImpl *impl_from_IFolderView( IFolderView *iface )
143 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblFolderView));
146 /* ListView Header ID's */
147 #define LISTVIEW_COLUMN_NAME 0
148 #define LISTVIEW_COLUMN_SIZE 1
149 #define LISTVIEW_COLUMN_TYPE 2
150 #define LISTVIEW_COLUMN_TIME 3
151 #define LISTVIEW_COLUMN_ATTRIB 4
154 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
155 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
156 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
158 #define ID_LISTVIEW 1
160 #define SHV_CHANGE_NOTIFY WM_USER + 0x1111
163 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
164 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
165 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
168 Items merged into the toolbar and the filemenu
177 } MYTOOLINFO, *LPMYTOOLINFO;
179 static const MYTOOLINFO Tools[] =
181 { FCIDM_SHVIEW_BIGICON, 0, 0, IDS_VIEW_LARGE, TBSTATE_ENABLED, BTNS_BUTTON },
182 { FCIDM_SHVIEW_SMALLICON, 0, 0, IDS_VIEW_SMALL, TBSTATE_ENABLED, BTNS_BUTTON },
183 { FCIDM_SHVIEW_LISTVIEW, 0, 0, IDS_VIEW_LIST, TBSTATE_ENABLED, BTNS_BUTTON },
184 { FCIDM_SHVIEW_REPORTVIEW, 0, 0, IDS_VIEW_DETAILS, TBSTATE_ENABLED, BTNS_BUTTON },
188 typedef void (CALLBACK *PFNSHGETSETTINGSPROC)(LPSHELLFLAGSTATE lpsfs, DWORD dwMask);
190 /**********************************************************
191 * IShellView_Constructor
193 IShellView * IShellView_Constructor( IShellFolder * pFolder)
194 { IShellViewImpl * sv;
195 sv=HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IShellViewImpl));
198 sv->lpvtblOleCommandTarget=&ctvt;
199 sv->lpvtblDropTarget=&dtvt;
200 sv->lpvtblDropSource=&dsvt;
201 sv->lpvtblViewObject=&vovt;
202 sv->lpvtblFolderView=&fviewvt;
204 sv->pSFParent = pFolder;
205 if(pFolder) IShellFolder_AddRef(pFolder);
206 IShellFolder_QueryInterface(sv->pSFParent, &IID_IShellFolder2, (LPVOID*)&sv->pSF2Parent);
208 sv->pCurDropTarget = NULL;
209 sv->pCurDataObject = NULL;
210 sv->iDragOverItem = 0;
211 sv->cScrollDelay = 0;
212 sv->ptLastMousePos.x = 0;
213 sv->ptLastMousePos.y = 0;
215 TRACE("(%p)->(%p)\n",sv, pFolder);
216 return (IShellView *) sv;
219 /**********************************************************
221 * ##### helperfunctions for communication with ICommDlgBrowser #####
223 static BOOL IsInCommDlg(IShellViewImpl * This)
224 { return(This->pCommDlgBrowser != NULL);
227 static HRESULT IncludeObject(IShellViewImpl * This, LPCITEMIDLIST pidl)
231 if ( IsInCommDlg(This) )
233 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl);
234 ret = ICommDlgBrowser_IncludeObject(This->pCommDlgBrowser, (IShellView*)This, pidl);
235 TRACE("--0x%08x\n", ret);
240 static HRESULT OnDefaultCommand(IShellViewImpl * This)
242 HRESULT ret = S_FALSE;
244 if (IsInCommDlg(This))
246 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
247 ret = ICommDlgBrowser_OnDefaultCommand(This->pCommDlgBrowser, (IShellView*)This);
248 TRACE("-- returns %08x\n", ret);
253 static HRESULT OnStateChange(IShellViewImpl * This, UINT uFlags)
255 HRESULT ret = S_FALSE;
257 if (IsInCommDlg(This))
259 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags);
260 ret = ICommDlgBrowser_OnStateChange(This->pCommDlgBrowser, (IShellView*)This, uFlags);
265 /**********************************************************
266 * set the toolbar of the filedialog buttons
268 * - activates the buttons from the shellbrowser according to
271 static void CheckToolbar(IShellViewImpl * This)
277 if (IsInCommDlg(This))
279 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
280 FCIDM_TB_SMALLICON, (This->FolderSettings.ViewMode==FVM_LIST)? TRUE : FALSE, &result);
281 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
282 FCIDM_TB_REPORTVIEW, (This->FolderSettings.ViewMode==FVM_DETAILS)? TRUE : FALSE, &result);
283 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
284 FCIDM_TB_SMALLICON, TRUE, &result);
285 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
286 FCIDM_TB_REPORTVIEW, TRUE, &result);
290 /**********************************************************
292 * ##### helperfunctions for initializing the view #####
294 /**********************************************************
295 * change the style of the listview control
297 static void SetStyle(IShellViewImpl * This, DWORD dwAdd, DWORD dwRemove)
301 TRACE("(%p)\n", This);
303 tmpstyle = GetWindowLongW(This->hWndList, GWL_STYLE);
304 SetWindowLongW(This->hWndList, GWL_STYLE, dwAdd | (tmpstyle & ~dwRemove));
307 /**********************************************************
308 * ShellView_CreateList()
310 * - creates the list view window
312 static BOOL ShellView_CreateList (IShellViewImpl * This)
313 { DWORD dwStyle, dwExStyle;
317 dwStyle = WS_TABSTOP | WS_VISIBLE | WS_CHILDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
318 LVS_SHAREIMAGELISTS | LVS_EDITLABELS | LVS_ALIGNLEFT | LVS_AUTOARRANGE;
319 dwExStyle = WS_EX_CLIENTEDGE;
321 switch (This->FolderSettings.ViewMode)
323 case FVM_ICON: dwStyle |= LVS_ICON; break;
324 case FVM_DETAILS: dwStyle |= LVS_REPORT; break;
325 case FVM_SMALLICON: dwStyle |= LVS_SMALLICON; break;
326 case FVM_LIST: dwStyle |= LVS_LIST; break;
329 FIXME("ViewMode %d not implemented\n", This->FolderSettings.ViewMode);
335 if (This->FolderSettings.fFlags & FWF_AUTOARRANGE) dwStyle |= LVS_AUTOARRANGE;
336 if (This->FolderSettings.fFlags & FWF_DESKTOP)
337 This->FolderSettings.fFlags |= FWF_NOCLIENTEDGE | FWF_NOSCROLL;
338 if (This->FolderSettings.fFlags & FWF_SINGLESEL) dwStyle |= LVS_SINGLESEL;
339 if (This->FolderSettings.fFlags & FWF_NOCLIENTEDGE)
340 dwExStyle &= ~WS_EX_CLIENTEDGE;
342 This->hWndList=CreateWindowExW( dwExStyle,
355 This->ListViewSortInfo.bIsAscending = TRUE;
356 This->ListViewSortInfo.nHeaderID = -1;
357 This->ListViewSortInfo.nLastHeaderID = -1;
359 if (This->FolderSettings.fFlags & FWF_DESKTOP) {
361 * FIXME: look at the registry value
362 * HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ListviewShadow
363 * and activate drop shadows if necessary
366 SendMessageW(This->hWndList, LVM_SETTEXTBKCOLOR, 0, CLR_NONE);
368 SendMessageW(This->hWndList, LVM_SETTEXTBKCOLOR, 0, GetSysColor(COLOR_DESKTOP));
370 SendMessageW(This->hWndList, LVM_SETTEXTCOLOR, 0, RGB(255,255,255));
373 /* UpdateShellSettings(); */
377 /**********************************************************
378 * ShellView_InitList()
380 * - adds all needed columns to the shellview
382 static BOOL ShellView_InitList(IShellViewImpl * This)
391 SendMessageW(This->hWndList, LVM_DELETEALLITEMS, 0, 0);
393 lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT;
394 lvColumn.pszText = szTemp;
396 if (This->pSF2Parent)
400 if (FAILED(IShellFolder2_GetDetailsOf(This->pSF2Parent, NULL, i, &sd)))
402 lvColumn.fmt = sd.fmt;
403 lvColumn.cx = sd.cxChar*8; /* chars->pixel */
404 StrRetToStrNW( szTemp, 50, &sd.str, NULL);
405 SendMessageW(This->hWndList, LVM_INSERTCOLUMNW, i, (LPARAM) &lvColumn);
413 SendMessageW(This->hWndList, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)ShellSmallIconList);
414 SendMessageW(This->hWndList, LVM_SETIMAGELIST, LVSIL_NORMAL, (LPARAM)ShellBigIconList);
418 /**********************************************************
419 * ShellView_CompareItems()
422 * internal, CALLBACK for DSA_Sort
424 static INT CALLBACK ShellView_CompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
427 TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1, lParam2, (LPVOID) lpData);
429 if(!lpData) return 0;
431 ret = (SHORT) SCODE_CODE(IShellFolder_CompareIDs((LPSHELLFOLDER)lpData, 0, (LPITEMIDLIST)lParam1, (LPITEMIDLIST)lParam2));
432 TRACE("ret=%i\n",ret);
436 /*************************************************************************
437 * ShellView_ListViewCompareItems
439 * Compare Function for the Listview (FileOpen Dialog)
442 * lParam1 [I] the first ItemIdList to compare with
443 * lParam2 [I] the second ItemIdList to compare with
444 * lpData [I] The column ID for the header Ctrl to process
447 * A negative value if the first item should precede the second,
448 * a positive value if the first item should follow the second,
449 * or zero if the two items are equivalent
452 * FIXME: function does what ShellView_CompareItems is supposed to do.
453 * unify it and figure out how to use the undocumented first parameter
454 * of IShellFolder_CompareIDs to do the job this function does and
455 * move this code to IShellFolder.
456 * make LISTVIEW_SORT_INFO obsolete
457 * the way this function works is only usable if we had only
458 * filesystemfolders (25/10/99 jsch)
460 static INT CALLBACK ShellView_ListViewCompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
464 char strName1[MAX_PATH], strName2[MAX_PATH];
465 BOOL bIsFolder1, bIsFolder2,bIsBothFolder;
466 LPITEMIDLIST pItemIdList1 = lParam1;
467 LPITEMIDLIST pItemIdList2 = lParam2;
468 LISTVIEW_SORT_INFO *pSortInfo = (LPLISTVIEW_SORT_INFO) lpData;
471 bIsFolder1 = _ILIsFolder(pItemIdList1);
472 bIsFolder2 = _ILIsFolder(pItemIdList2);
473 bIsBothFolder = bIsFolder1 && bIsFolder2;
475 /* When sorting between a File and a Folder, the Folder gets sorted first */
476 if( (bIsFolder1 || bIsFolder2) && !bIsBothFolder)
478 nDiff = bIsFolder1 ? -1 : 1;
482 /* Sort by Time: Folders or Files can be sorted */
484 if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TIME)
486 _ILGetFileDateTime(pItemIdList1, &fd1);
487 _ILGetFileDateTime(pItemIdList2, &fd2);
488 nDiff = CompareFileTime(&fd2, &fd1);
490 /* Sort by Attribute: Folder or Files can be sorted */
491 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_ATTRIB)
493 _ILGetFileAttributes(pItemIdList1, strName1, MAX_PATH);
494 _ILGetFileAttributes(pItemIdList2, strName2, MAX_PATH);
495 nDiff = lstrcmpiA(strName1, strName2);
497 /* Sort by FileName: Folder or Files can be sorted */
498 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_NAME || bIsBothFolder)
501 _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
502 _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
503 nDiff = lstrcmpiA(strName1, strName2);
505 /* Sort by File Size, Only valid for Files */
506 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_SIZE)
508 nDiff = (INT)(_ILGetFileSize(pItemIdList1, NULL, 0) - _ILGetFileSize(pItemIdList2, NULL, 0));
510 /* Sort by File Type, Only valid for Files */
511 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TYPE)
514 _ILGetFileType(pItemIdList1, strName1, MAX_PATH);
515 _ILGetFileType(pItemIdList2, strName2, MAX_PATH);
516 nDiff = lstrcmpiA(strName1, strName2);
519 /* If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
523 _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
524 _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
525 nDiff = lstrcmpiA(strName1, strName2);
528 if(!pSortInfo->bIsAscending)
537 /**********************************************************
538 * LV_FindItemByPidl()
540 static int LV_FindItemByPidl(
541 IShellViewImpl * This,
546 lvItem.mask = LVIF_PARAM;
547 for(lvItem.iItem = 0;
548 SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem);
551 LPITEMIDLIST currentpidl = (LPITEMIDLIST) lvItem.lParam;
552 HRESULT hr = IShellFolder_CompareIDs(This->pSFParent, 0, pidl, currentpidl);
553 if(SUCCEEDED(hr) && !HRESULT_CODE(hr))
561 /**********************************************************
564 static BOOLEAN LV_AddItem(IShellViewImpl * This, LPCITEMIDLIST pidl)
568 TRACE("(%p)(pidl=%p)\n", This, pidl);
570 lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; /*set the mask*/
571 lvItem.iItem = SendMessageW(This->hWndList, LVM_GETITEMCOUNT, 0, 0); /*add the item to the end of the list*/
573 lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidl)); /*set the item's data*/
574 lvItem.pszText = LPSTR_TEXTCALLBACKW; /*get text on a callback basis*/
575 lvItem.iImage = I_IMAGECALLBACK; /*get the image on a callback basis*/
576 return (-1==ListView_InsertItemW(This->hWndList, &lvItem))? FALSE: TRUE;
579 /**********************************************************
582 static BOOLEAN LV_DeleteItem(IShellViewImpl * This, LPCITEMIDLIST pidl)
586 TRACE("(%p)(pidl=%p)\n", This, pidl);
588 nIndex = LV_FindItemByPidl(This, ILFindLastID(pidl));
589 return (-1==SendMessageW(This->hWndList, LVM_DELETEITEM, nIndex, 0))? FALSE: TRUE;
592 /**********************************************************
595 static BOOLEAN LV_RenameItem(IShellViewImpl * This, LPCITEMIDLIST pidlOld, LPCITEMIDLIST pidlNew )
600 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", This, pidlOld, pidlNew);
602 nItem = LV_FindItemByPidl(This, ILFindLastID(pidlOld));
605 lvItem.mask = LVIF_PARAM; /* only the pidl */
606 lvItem.iItem = nItem;
607 SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem);
609 SHFree((LPITEMIDLIST)lvItem.lParam);
610 lvItem.mask = LVIF_PARAM;
611 lvItem.iItem = nItem;
612 lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidlNew)); /* set the item's data */
613 SendMessageW(This->hWndList, LVM_SETITEMW, 0, (LPARAM) &lvItem);
614 SendMessageW(This->hWndList, LVM_UPDATE, nItem, 0);
615 return TRUE; /* FIXME: better handling */
619 /**********************************************************
620 * ShellView_FillList()
622 * - gets the objectlist from the shellfolder
624 * - fills the list into the view
627 static INT CALLBACK fill_list( LPVOID ptr, LPVOID arg )
629 LPITEMIDLIST pidl = ptr;
630 IShellViewImpl *This = arg;
631 /* in a commdlg This works as a filemask*/
632 if ( IncludeObject(This, pidl)==S_OK ) LV_AddItem(This, pidl);
637 static HRESULT ShellView_FillList(IShellViewImpl * This)
639 LPENUMIDLIST pEnumIDList;
647 /* get the itemlist from the shfolder*/
648 hRes = IShellFolder_EnumObjects(This->pSFParent,This->hWnd, SHCONTF_NONFOLDERS | SHCONTF_FOLDERS, &pEnumIDList);
656 /* create a pointer array */
657 hdpa = DPA_Create(16);
660 return(E_OUTOFMEMORY);
663 /* copy the items into the array*/
664 while((S_OK == IEnumIDList_Next(pEnumIDList,1, &pidl, &dwFetched)) && dwFetched)
666 if (DPA_InsertPtr(hdpa, 0x7fff, pidl) == -1)
673 DPA_Sort(hdpa, ShellView_CompareItems, (LPARAM)This->pSFParent);
675 /*turn the listview's redrawing off*/
676 SendMessageA(This->hWndList, WM_SETREDRAW, FALSE, 0);
678 DPA_DestroyCallback( hdpa, fill_list, This );
680 /*turn the listview's redrawing back on and force it to draw*/
681 SendMessageA(This->hWndList, WM_SETREDRAW, TRUE, 0);
683 IEnumIDList_Release(pEnumIDList); /* destroy the list*/
688 /**********************************************************
689 * ShellView_OnCreate()
691 static LRESULT ShellView_OnCreate(IShellViewImpl * This)
694 SHChangeNotifyEntry ntreg;
695 IPersistFolder2 * ppf2 = NULL;
699 if(ShellView_CreateList(This))
701 if(ShellView_InitList(This))
703 ShellView_FillList(This);
707 if (SUCCEEDED(IUnknown_QueryInterface((IUnknown*)&This->lpVtbl, &IID_IDropTarget, (LPVOID*)&pdt)))
709 RegisterDragDrop(This->hWnd, pdt);
710 IDropTarget_Release(pdt);
713 /* register for receiving notifications */
714 IShellFolder_QueryInterface(This->pSFParent, &IID_IPersistFolder2, (LPVOID*)&ppf2);
717 IPersistFolder2_GetCurFolder(ppf2, (LPITEMIDLIST*)&ntreg.pidl);
718 ntreg.fRecursive = TRUE;
719 This->hNotify = SHChangeNotifyRegister(This->hWnd, SHCNF_IDLIST, SHCNE_ALLEVENTS, SHV_CHANGE_NOTIFY, 1, &ntreg);
720 SHFree((LPITEMIDLIST)ntreg.pidl);
721 IPersistFolder2_Release(ppf2);
724 This->hAccel = LoadAcceleratorsA(shell32_hInstance, "shv_accel");
729 /**********************************************************
730 * #### Handling of the menus ####
733 /**********************************************************
734 * ShellView_BuildFileMenu()
736 static HMENU ShellView_BuildFileMenu(IShellViewImpl * This)
737 { WCHAR szText[MAX_PATH];
742 TRACE("(%p)\n",This);
744 hSubMenu = CreatePopupMenu();
746 { /*get the number of items in our global array*/
747 for(nTools = 0; Tools[nTools].idCommand != -1; nTools++){}
749 /*add the menu items*/
750 for(i = 0; i < nTools; i++)
752 LoadStringW(shell32_hInstance, Tools[i].idMenuString, szText, MAX_PATH);
754 ZeroMemory(&mii, sizeof(mii));
755 mii.cbSize = sizeof(mii);
756 mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
758 if(BTNS_SEP != Tools[i].bStyle) /* no separator*/
760 mii.fType = MFT_STRING;
761 mii.fState = MFS_ENABLED;
762 mii.dwTypeData = szText;
763 mii.wID = Tools[i].idCommand;
767 mii.fType = MFT_SEPARATOR;
769 /* tack This item onto the end of the menu */
770 InsertMenuItemW(hSubMenu, (UINT)-1, TRUE, &mii);
773 TRACE("-- return (menu=%p)\n",hSubMenu);
776 /**********************************************************
777 * ShellView_MergeFileMenu()
779 static void ShellView_MergeFileMenu(IShellViewImpl * This, HMENU hSubMenu)
780 { TRACE("(%p)->(submenu=%p) stub\n",This,hSubMenu);
783 { /*insert This item at the beginning of the menu */
786 mii.cbSize = sizeof(mii);
787 mii.fMask = MIIM_ID | MIIM_TYPE;
789 mii.fType = MFT_SEPARATOR;
790 InsertMenuItemA(hSubMenu, 0, TRUE, &mii);
792 mii.cbSize = sizeof(mii);
793 mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
794 mii.dwTypeData = (LPSTR)"dummy45";
795 mii.fState = MFS_ENABLED;
796 mii.wID = IDM_MYFILEITEM;
797 mii.fType = MFT_STRING;
798 InsertMenuItemA(hSubMenu, 0, TRUE, &mii);
803 /**********************************************************
804 * ShellView_MergeViewMenu()
807 static void ShellView_MergeViewMenu(IShellViewImpl * This, HMENU hSubMenu)
809 TRACE("(%p)->(submenu=%p)\n",This,hSubMenu);
812 { /*add a separator at the correct position in the menu*/
814 static char view[] = "View";
816 ZeroMemory(&mii, sizeof(mii));
817 mii.cbSize = sizeof(mii);
818 mii.fMask = MIIM_ID | MIIM_TYPE;
820 mii.fType = MFT_SEPARATOR;
821 InsertMenuItemA(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
823 mii.cbSize = sizeof(mii);
824 mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_DATA;
825 mii.fType = MFT_STRING;
826 mii.dwTypeData = view;
827 mii.hSubMenu = LoadMenuA(shell32_hInstance, "MENU_001");
828 InsertMenuItemA(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
832 /**********************************************************
833 * ShellView_GetSelections()
835 * - fills the this->apidl list with the selected objects
838 * number of selected items
840 static UINT ShellView_GetSelections(IShellViewImpl * This)
847 This->cidl = SendMessageW(This->hWndList, LVM_GETSELECTEDCOUNT, 0, 0);
848 This->apidl = SHAlloc(This->cidl * sizeof(LPITEMIDLIST));
850 TRACE("selected=%i\n", This->cidl);
854 TRACE("-- Items selected =%u\n", This->cidl);
856 lvItem.mask = LVIF_STATE | LVIF_PARAM;
857 lvItem.stateMask = LVIS_SELECTED;
861 while(ListView_GetItemW(This->hWndList, &lvItem) && (i < This->cidl))
863 if(lvItem.state & LVIS_SELECTED)
865 This->apidl[i] = (LPITEMIDLIST)lvItem.lParam;
867 TRACE("-- selected Item found\n");
876 /**********************************************************
877 * ShellView_OpenSelectedItems()
879 static HRESULT ShellView_OpenSelectedItems(IShellViewImpl * This)
881 static UINT CF_IDLIST = 0;
883 IDataObject* selection;
887 LPCITEMIDLIST parent_pidl;
888 WCHAR parent_path[MAX_PATH];
889 LPCWSTR parent_dir = NULL;
893 if (0 == ShellView_GetSelections(This))
897 hr = IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl,
898 (LPCITEMIDLIST*)This->apidl, &IID_IDataObject,
899 0, (LPVOID *)&selection);
905 CF_IDLIST = RegisterClipboardFormatW(CFSTR_SHELLIDLISTW);
907 fetc.cfFormat = CF_IDLIST;
909 fetc.dwAspect = DVASPECT_CONTENT;
911 fetc.tymed = TYMED_HGLOBAL;
913 hr = IDataObject_QueryGetData(selection, &fetc);
917 hr = IDataObject_GetData(selection, &fetc, &stgm);
921 pIDList = GlobalLock(stgm.u.hGlobal);
923 parent_pidl = (LPCITEMIDLIST) ((LPBYTE)pIDList+pIDList->aoffset[0]);
924 hr = IShellFolder_GetAttributesOf(This->pSFParent, 1, &parent_pidl, &attribs);
925 if (SUCCEEDED(hr) && (attribs & SFGAO_FILESYSTEM) &&
926 SHGetPathFromIDListW(parent_pidl, parent_path))
928 parent_dir = parent_path;
931 for (i = pIDList->cidl; i > 0; --i)
935 pidl = (LPCITEMIDLIST)((LPBYTE)pIDList+pIDList->aoffset[i]);
937 attribs = SFGAO_FOLDER;
938 hr = IShellFolder_GetAttributesOf(This->pSFParent, 1, &pidl, &attribs);
940 if (SUCCEEDED(hr) && ! (attribs & SFGAO_FOLDER))
942 SHELLEXECUTEINFOW shexinfo;
944 shexinfo.cbSize = sizeof(SHELLEXECUTEINFOW);
945 shexinfo.fMask = SEE_MASK_INVOKEIDLIST; /* SEE_MASK_IDLIST is also possible. */
946 shexinfo.hwnd = NULL;
947 shexinfo.lpVerb = NULL;
948 shexinfo.lpFile = NULL;
949 shexinfo.lpParameters = NULL;
950 shexinfo.lpDirectory = parent_dir;
951 shexinfo.nShow = SW_NORMAL;
952 shexinfo.lpIDList = ILCombine(parent_pidl, pidl);
954 ShellExecuteExW(&shexinfo); /* Discard error/success info */
956 ILFree(shexinfo.lpIDList);
960 GlobalUnlock(stgm.u.hGlobal);
961 ReleaseStgMedium(&stgm);
963 IDataObject_Release(selection);
968 /**********************************************************
969 * ShellView_DoContextMenu()
971 static void ShellView_DoContextMenu(IShellViewImpl * This, WORD x, WORD y, BOOL bDefault)
975 BOOL fExplore = FALSE;
977 LPCONTEXTMENU pContextMenu = NULL;
978 IContextMenu2 *pCM = NULL;
979 CMINVOKECOMMANDINFO cmi;
981 TRACE("(%p)->(0x%08x 0x%08x 0x%08x) stub\n",This, x, y, bDefault);
983 /* look, what's selected and create a context menu object of it*/
984 if( ShellView_GetSelections(This) )
986 IShellFolder_GetUIObjectOf( This->pSFParent, This->hWndParent, This->cidl, (LPCITEMIDLIST*)This->apidl,
987 &IID_IContextMenu, NULL, (LPVOID *)&pContextMenu);
991 TRACE("-- pContextMenu\n");
992 hMenu = CreatePopupMenu();
996 /* See if we are in Explore or Open mode. If the browser's tree is present, we are in Explore mode.*/
997 if(SUCCEEDED(IShellBrowser_GetControlWindow(This->pShellBrowser,FCW_TREE, &hwndTree)) && hwndTree)
999 TRACE("-- explore mode\n");
1003 /* build the flags depending on what we can do with the selected item */
1004 wFlags = CMF_NORMAL | (This->cidl != 1 ? 0 : CMF_CANRENAME) | (fExplore ? CMF_EXPLORE : 0);
1006 /* let the ContextMenu merge its items in */
1007 if (SUCCEEDED(IContextMenu_QueryContextMenu( pContextMenu, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, wFlags )))
1009 if (This->FolderSettings.fFlags & FWF_DESKTOP)
1010 SetMenuDefaultItem(hMenu, FCIDM_SHVIEW_OPEN, MF_BYCOMMAND);
1014 TRACE("-- get menu default command\n");
1015 uCommand = GetMenuDefaultItem(hMenu, FALSE, GMDI_GOINTOPOPUPS);
1019 TRACE("-- track popup\n");
1020 uCommand = TrackPopupMenu( hMenu,TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
1025 TRACE("-- uCommand=%u\n", uCommand);
1026 if (uCommand==FCIDM_SHVIEW_OPEN && IsInCommDlg(This))
1028 TRACE("-- dlg: OnDefaultCommand\n");
1029 if (OnDefaultCommand(This) != S_OK)
1031 ShellView_OpenSelectedItems(This);
1036 TRACE("-- explore -- invoke command\n");
1037 ZeroMemory(&cmi, sizeof(cmi));
1038 cmi.cbSize = sizeof(cmi);
1039 cmi.hwnd = This->hWndParent; /* this window has to answer CWM_GETISHELLBROWSER */
1040 cmi.lpVerb = MAKEINTRESOURCEA(uCommand);
1041 IContextMenu_InvokeCommand(pContextMenu, &cmi);
1048 IContextMenu_Release(pContextMenu);
1051 else /* background context menu */
1053 hMenu = CreatePopupMenu();
1055 pCM = ISvBgCm_Constructor(This->pSFParent, FALSE);
1056 IContextMenu2_QueryContextMenu(pCM, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, 0);
1058 uCommand = TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
1061 TRACE("-- (%p)->(uCommand=0x%08x )\n",This, uCommand);
1063 ZeroMemory(&cmi, sizeof(cmi));
1064 cmi.cbSize = sizeof(cmi);
1065 cmi.lpVerb = MAKEINTRESOURCEA(uCommand);
1066 cmi.hwnd = This->hWndParent;
1067 IContextMenu2_InvokeCommand(pCM, &cmi);
1069 IContextMenu2_Release(pCM);
1073 /**********************************************************
1074 * ##### message handling #####
1077 /**********************************************************
1078 * ShellView_OnSize()
1080 static LRESULT ShellView_OnSize(IShellViewImpl * This, WORD wWidth, WORD wHeight)
1082 TRACE("%p width=%u height=%u\n",This, wWidth,wHeight);
1084 /*resize the ListView to fit our window*/
1087 MoveWindow(This->hWndList, 0, 0, wWidth, wHeight, TRUE);
1092 /**********************************************************
1093 * ShellView_OnDeactivate()
1098 static void ShellView_OnDeactivate(IShellViewImpl * This)
1102 if(This->uState != SVUIA_DEACTIVATE)
1106 IShellBrowser_SetMenuSB(This->pShellBrowser,0, 0, 0);
1107 IShellBrowser_RemoveMenusSB(This->pShellBrowser,This->hMenu);
1108 DestroyMenu(This->hMenu);
1112 This->uState = SVUIA_DEACTIVATE;
1116 /**********************************************************
1117 * ShellView_OnActivate()
1119 static LRESULT ShellView_OnActivate(IShellViewImpl * This, UINT uState)
1120 { OLEMENUGROUPWIDTHS omw = { {0, 0, 0, 0, 0, 0} };
1122 CHAR szText[MAX_PATH];
1124 TRACE("%p uState=%x\n",This,uState);
1126 /*don't do anything if the state isn't really changing */
1127 if(This->uState == uState)
1132 ShellView_OnDeactivate(This);
1134 /*only do This if we are active */
1135 if(uState != SVUIA_DEACTIVATE)
1137 /*merge the menus */
1138 This->hMenu = CreateMenu();
1142 IShellBrowser_InsertMenusSB(This->pShellBrowser, This->hMenu, &omw);
1143 TRACE("-- after fnInsertMenusSB\n");
1145 /*build the top level menu get the menu item's text*/
1146 strcpy(szText,"dummy 31");
1148 ZeroMemory(&mii, sizeof(mii));
1149 mii.cbSize = sizeof(mii);
1150 mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_STATE;
1151 mii.fType = MFT_STRING;
1152 mii.fState = MFS_ENABLED;
1153 mii.dwTypeData = szText;
1154 mii.hSubMenu = ShellView_BuildFileMenu(This);
1156 /*insert our menu into the menu bar*/
1159 InsertMenuItemA(This->hMenu, FCIDM_MENU_HELP, FALSE, &mii);
1162 /*get the view menu so we can merge with it*/
1163 ZeroMemory(&mii, sizeof(mii));
1164 mii.cbSize = sizeof(mii);
1165 mii.fMask = MIIM_SUBMENU;
1167 if(GetMenuItemInfoA(This->hMenu, FCIDM_MENU_VIEW, FALSE, &mii))
1169 ShellView_MergeViewMenu(This, mii.hSubMenu);
1172 /*add the items that should only be added if we have the focus*/
1173 if(SVUIA_ACTIVATE_FOCUS == uState)
1175 /*get the file menu so we can merge with it */
1176 ZeroMemory(&mii, sizeof(mii));
1177 mii.cbSize = sizeof(mii);
1178 mii.fMask = MIIM_SUBMENU;
1180 if(GetMenuItemInfoA(This->hMenu, FCIDM_MENU_FILE, FALSE, &mii))
1182 ShellView_MergeFileMenu(This, mii.hSubMenu);
1185 TRACE("-- before fnSetMenuSB\n");
1186 IShellBrowser_SetMenuSB(This->pShellBrowser, This->hMenu, 0, This->hWnd);
1189 This->uState = uState;
1194 /**********************************************************
1195 * ShellView_OnSetFocus()
1198 static LRESULT ShellView_OnSetFocus(IShellViewImpl * This)
1202 /* Tell the browser one of our windows has received the focus. This
1203 should always be done before merging menus (OnActivate merges the
1204 menus) if one of our windows has the focus.*/
1206 IShellBrowser_OnViewWindowActive(This->pShellBrowser,(IShellView*) This);
1207 ShellView_OnActivate(This, SVUIA_ACTIVATE_FOCUS);
1209 /* Set the focus to the listview */
1210 SetFocus(This->hWndList);
1212 /* Notify the ICommDlgBrowser interface */
1213 OnStateChange(This,CDBOSC_SETFOCUS);
1218 /**********************************************************
1219 * ShellView_OnKillFocus()
1221 static LRESULT ShellView_OnKillFocus(IShellViewImpl * This)
1223 TRACE("(%p) stub\n",This);
1225 ShellView_OnActivate(This, SVUIA_ACTIVATE_NOFOCUS);
1226 /* Notify the ICommDlgBrowser */
1227 OnStateChange(This,CDBOSC_KILLFOCUS);
1232 /**********************************************************
1233 * ShellView_OnCommand()
1236 * the CmdID's are the ones from the context menu
1238 static LRESULT ShellView_OnCommand(IShellViewImpl * This,DWORD dwCmdID, DWORD dwCmd, HWND hwndCmd)
1240 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n",This, dwCmdID, dwCmd, hwndCmd);
1244 case FCIDM_SHVIEW_SMALLICON:
1245 This->FolderSettings.ViewMode = FVM_SMALLICON;
1246 SetStyle (This, LVS_SMALLICON, LVS_TYPEMASK);
1250 case FCIDM_SHVIEW_BIGICON:
1251 This->FolderSettings.ViewMode = FVM_ICON;
1252 SetStyle (This, LVS_ICON, LVS_TYPEMASK);
1256 case FCIDM_SHVIEW_LISTVIEW:
1257 This->FolderSettings.ViewMode = FVM_LIST;
1258 SetStyle (This, LVS_LIST, LVS_TYPEMASK);
1262 case FCIDM_SHVIEW_REPORTVIEW:
1263 This->FolderSettings.ViewMode = FVM_DETAILS;
1264 SetStyle (This, LVS_REPORT, LVS_TYPEMASK);
1268 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1273 This->ListViewSortInfo.nHeaderID = dwCmdID - 0x30;
1274 This->ListViewSortInfo.bIsAscending = TRUE;
1275 This->ListViewSortInfo.nLastHeaderID = This->ListViewSortInfo.nHeaderID;
1276 SendMessageA(This->hWndList, LVM_SORTITEMS, (WPARAM) &This->ListViewSortInfo, (LPARAM)ShellView_ListViewCompareItems);
1280 TRACE("-- COMMAND 0x%04x unhandled\n", dwCmdID);
1285 /**********************************************************
1286 * ShellView_OnNotify()
1289 static LRESULT ShellView_OnNotify(IShellViewImpl * This, UINT CtlID, LPNMHDR lpnmh)
1290 { LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)lpnmh;
1291 NMLVDISPINFOW *lpdi = (NMLVDISPINFOW *)lpnmh;
1294 TRACE("%p CtlID=%u lpnmh->code=%x\n",This,CtlID,lpnmh->code);
1299 TRACE("-- NM_SETFOCUS %p\n",This);
1300 ShellView_OnSetFocus(This);
1304 TRACE("-- NM_KILLFOCUS %p\n",This);
1305 ShellView_OnDeactivate(This);
1306 /* Notify the ICommDlgBrowser interface */
1307 OnStateChange(This,CDBOSC_KILLFOCUS);
1311 TRACE("-- NM_CUSTOMDRAW %p\n",This);
1312 return CDRF_DODEFAULT;
1314 case NM_RELEASEDCAPTURE:
1315 TRACE("-- NM_RELEASEDCAPTURE %p\n",This);
1319 TRACE("-- NM_CLICK %p\n",This);
1323 TRACE("-- NM_RCLICK %p\n",This);
1327 TRACE("-- NM_DBLCLK %p\n",This);
1328 if (OnDefaultCommand(This) != S_OK) ShellView_OpenSelectedItems(This);
1332 TRACE("-- NM_RETURN %p\n",This);
1333 if (OnDefaultCommand(This) != S_OK) ShellView_OpenSelectedItems(This);
1337 TRACE("-- HDN_ENDTRACKW %p\n",This);
1338 /*nColumn1 = ListView_GetColumnWidth(This->hWndList, 0);
1339 nColumn2 = ListView_GetColumnWidth(This->hWndList, 1);*/
1342 case LVN_DELETEITEM:
1343 TRACE("-- LVN_DELETEITEM %p\n",This);
1344 SHFree((LPITEMIDLIST)lpnmlv->lParam); /*delete the pidl because we made a copy of it*/
1347 case LVN_DELETEALLITEMS:
1348 TRACE("-- LVN_DELETEALLITEMS %p\n",This);
1351 case LVN_INSERTITEM:
1352 TRACE("-- LVN_INSERTITEM (STUB)%p\n",This);
1355 case LVN_ITEMACTIVATE:
1356 TRACE("-- LVN_ITEMACTIVATE %p\n",This);
1357 OnStateChange(This, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
1360 case LVN_COLUMNCLICK:
1361 This->ListViewSortInfo.nHeaderID = lpnmlv->iSubItem;
1362 if(This->ListViewSortInfo.nLastHeaderID == This->ListViewSortInfo.nHeaderID)
1364 This->ListViewSortInfo.bIsAscending = !This->ListViewSortInfo.bIsAscending;
1368 This->ListViewSortInfo.bIsAscending = TRUE;
1370 This->ListViewSortInfo.nLastHeaderID = This->ListViewSortInfo.nHeaderID;
1372 SendMessageW(lpnmlv->hdr.hwndFrom, LVM_SORTITEMS, (WPARAM) &This->ListViewSortInfo, (LPARAM)ShellView_ListViewCompareItems);
1375 case LVN_GETDISPINFOA:
1376 case LVN_GETDISPINFOW:
1377 TRACE("-- LVN_GETDISPINFO %p\n",This);
1378 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1380 if(lpdi->item.mask & LVIF_TEXT) /* text requested */
1382 if (This->pSF2Parent)
1385 IShellFolder2_GetDetailsOf(This->pSF2Parent, pidl, lpdi->item.iSubItem, &sd);
1386 if (lpnmh->code == LVN_GETDISPINFOA)
1388 /* shouldn't happen */
1389 NMLVDISPINFOA *lpdiA = (NMLVDISPINFOA *)lpnmh;
1390 StrRetToStrNA( lpdiA->item.pszText, lpdiA->item.cchTextMax, &sd.str, NULL);
1391 TRACE("-- text=%s\n",lpdiA->item.pszText);
1393 else /* LVN_GETDISPINFOW */
1395 StrRetToStrNW( lpdi->item.pszText, lpdi->item.cchTextMax, &sd.str, NULL);
1396 TRACE("-- text=%s\n",debugstr_w(lpdi->item.pszText));
1404 if(lpdi->item.mask & LVIF_IMAGE) /* image requested */
1406 lpdi->item.iImage = SHMapPIDLToSystemImageListIndex(This->pSFParent, pidl, 0);
1410 case LVN_ITEMCHANGED:
1411 TRACE("-- LVN_ITEMCHANGED %p\n",This);
1412 OnStateChange(This, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
1416 case LVN_BEGINRDRAG:
1417 TRACE("-- LVN_BEGINDRAG\n");
1419 if (ShellView_GetSelections(This))
1422 DWORD dwAttributes = SFGAO_CANLINK;
1423 DWORD dwEffect = DROPEFFECT_COPY | DROPEFFECT_MOVE;
1425 if (SUCCEEDED(IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, (LPCITEMIDLIST*)This->apidl, &IID_IDataObject,0,(LPVOID *)&pda)))
1427 IDropSource * pds = (IDropSource*)&(This->lpvtblDropSource); /* own DropSource interface */
1429 if (SUCCEEDED(IShellFolder_GetAttributesOf(This->pSFParent, This->cidl, (LPCITEMIDLIST*)This->apidl, &dwAttributes)))
1431 if (dwAttributes & SFGAO_CANLINK)
1433 dwEffect |= DROPEFFECT_LINK;
1440 DoDragDrop(pda, pds, dwEffect, &dwEffect2);
1442 IDataObject_Release(pda);
1447 case LVN_BEGINLABELEDITW:
1449 DWORD dwAttr = SFGAO_CANRENAME;
1450 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1452 TRACE("-- LVN_BEGINLABELEDITW %p\n",This);
1454 IShellFolder_GetAttributesOf(This->pSFParent, 1, (LPCITEMIDLIST*)&pidl, &dwAttr);
1455 if (SFGAO_CANRENAME & dwAttr)
1462 case LVN_ENDLABELEDITW:
1464 TRACE("-- LVN_ENDLABELEDITA %p\n",This);
1465 if (lpdi->item.pszText)
1470 lvItem.iItem = lpdi->item.iItem;
1471 lvItem.iSubItem = 0;
1472 lvItem.mask = LVIF_PARAM;
1473 SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem);
1475 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1476 hr = IShellFolder_SetNameOf(This->pSFParent, 0, pidl, lpdi->item.pszText, SHGDN_INFOLDER, &pidl);
1478 if(SUCCEEDED(hr) && pidl)
1480 lvItem.mask = LVIF_PARAM;
1481 lvItem.lParam = (LPARAM)pidl;
1482 SendMessageW(This->hWndList, LVM_SETITEMW, 0, (LPARAM) &lvItem);
1492 msg.hwnd = This->hWnd;
1493 msg.message = WM_KEYDOWN;
1494 msg.wParam = plvKeyDown->wVKey;
1499 LPNMLVKEYDOWN plvKeyDown = (LPNMLVKEYDOWN) lpnmh;
1501 /* initiate a rename of the selected file or directory */
1502 if(plvKeyDown->wVKey == VK_F2)
1504 /* see how many files are selected */
1505 int i = SendMessageW(This->hWndList, LVM_GETSELECTEDCOUNT, 0, 0);
1507 /* get selected item */
1510 /* get selected item */
1511 i = SendMessageW(This->hWndList, LVM_GETNEXTITEM, -1, MAKELPARAM (LVNI_SELECTED, 0));
1513 SendMessageW(This->hWndList, LVM_ENSUREVISIBLE, i, 0);
1514 SendMessageW(This->hWndList, LVM_EDITLABELW, i, 0);
1518 TranslateAccelerator(This->hWnd, This->hAccel, &msg)
1520 else if(plvKeyDown->wVKey == VK_DELETE)
1525 LPITEMIDLIST* pItems;
1528 IShellFolder_QueryInterface(This->pSFParent, &IID_ISFHelper,
1534 if(!(i = SendMessageW(This->hWndList, LVM_GETSELECTEDCOUNT, 0, 0)))
1537 /* allocate memory for the pidl array */
1538 pItems = HeapAlloc(GetProcessHeap(), 0,
1539 sizeof(LPITEMIDLIST) * i);
1541 /* retrieve all selected items */
1544 while(SendMessageW(This->hWndList, LVM_GETSELECTEDCOUNT, 0, 0) > i)
1546 /* get selected item */
1547 item_index = SendMessageW(This->hWndList, LVM_GETNEXTITEM, item_index,
1548 MAKELPARAM (LVNI_SELECTED, 0));
1549 item.iItem = item_index;
1550 item.mask = LVIF_PARAM;
1551 SendMessageA(This->hWndList, LVM_GETITEMA, 0, (LPARAM) &item);
1554 pItems[i] = (LPITEMIDLIST)item.lParam;
1559 /* perform the item deletion */
1560 ISFHelper_DeleteItems(psfhlp, i, (LPCITEMIDLIST*)pItems);
1562 /* free pidl array memory */
1563 HeapFree(GetProcessHeap(), 0, pItems);
1566 /* Initiate a refresh */
1567 else if(plvKeyDown->wVKey == VK_F5)
1569 IShellView_Refresh((IShellView*)This);
1572 else if(plvKeyDown->wVKey == VK_BACK)
1574 LPSHELLBROWSER lpSb;
1575 if((lpSb = (LPSHELLBROWSER)SendMessageW(This->hWndParent, CWM_GETISHELLBROWSER, 0, 0)))
1577 IShellBrowser_BrowseObject(lpSb, NULL, SBSP_PARENT);
1582 FIXME("LVN_KEYDOWN key=0x%08x\n",plvKeyDown->wVKey);
1587 TRACE("-- %p WM_COMMAND %x unhandled\n", This, lpnmh->code);
1593 /**********************************************************
1594 * ShellView_OnChange()
1597 static LRESULT ShellView_OnChange(IShellViewImpl * This, const LPCITEMIDLIST * Pidls, LONG wEventId)
1600 TRACE("(%p)(%p,%p,0x%08x)\n", This, Pidls[0], Pidls[1], wEventId);
1605 LV_AddItem(This, Pidls[0]);
1609 LV_DeleteItem(This, Pidls[0]);
1611 case SHCNE_RENAMEFOLDER:
1612 case SHCNE_RENAMEITEM:
1613 LV_RenameItem(This, Pidls[0], Pidls[1]);
1615 case SHCNE_UPDATEITEM:
1620 /**********************************************************
1624 static LRESULT CALLBACK ShellView_WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
1626 IShellViewImpl * pThis = (IShellViewImpl*)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
1627 LPCREATESTRUCTW lpcs;
1629 TRACE("(hwnd=%p msg=%x wparm=%lx lparm=%lx)\n",hWnd, uMessage, wParam, lParam);
1634 lpcs = (LPCREATESTRUCTW)lParam;
1635 pThis = lpcs->lpCreateParams;
1636 SetWindowLongPtrW(hWnd, GWLP_USERDATA, (ULONG_PTR)pThis);
1637 pThis->hWnd = hWnd; /*set the window handle*/
1640 case WM_SIZE: return ShellView_OnSize(pThis,LOWORD(lParam), HIWORD(lParam));
1641 case WM_SETFOCUS: return ShellView_OnSetFocus(pThis);
1642 case WM_KILLFOCUS: return ShellView_OnKillFocus(pThis);
1643 case WM_CREATE: return ShellView_OnCreate(pThis);
1644 case WM_ACTIVATE: return ShellView_OnActivate(pThis, SVUIA_ACTIVATE_FOCUS);
1645 case WM_NOTIFY: return ShellView_OnNotify(pThis,(UINT)wParam, (LPNMHDR)lParam);
1646 case WM_COMMAND: return ShellView_OnCommand(pThis,
1647 GET_WM_COMMAND_ID(wParam, lParam),
1648 GET_WM_COMMAND_CMD(wParam, lParam),
1649 GET_WM_COMMAND_HWND(wParam, lParam));
1650 case SHV_CHANGE_NOTIFY: return ShellView_OnChange(pThis, (const LPCITEMIDLIST*)wParam, (LONG)lParam);
1652 case WM_CONTEXTMENU: ShellView_DoContextMenu(pThis, LOWORD(lParam), HIWORD(lParam), FALSE);
1655 case WM_SHOWWINDOW: UpdateWindow(pThis->hWndList);
1658 case WM_GETDLGCODE: return SendMessageA(pThis->hWndList,uMessage,0,0);
1661 RevokeDragDrop(pThis->hWnd);
1662 SHChangeNotifyDeregister(pThis->hNotify);
1666 if ((pThis->FolderSettings.fFlags & FWF_DESKTOP) ||
1667 (pThis->FolderSettings.fFlags & FWF_TRANSPARENT))
1672 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
1674 /**********************************************************
1677 * The INTERFACE of the IShellView object
1680 **********************************************************
1681 * IShellView_QueryInterface
1683 static HRESULT WINAPI IShellView_fnQueryInterface(IShellView2 * iface,REFIID riid, LPVOID *ppvObj)
1685 IShellViewImpl *This = (IShellViewImpl *)iface;
1687 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1691 if(IsEqualIID(riid, &IID_IUnknown))
1695 else if(IsEqualIID(riid, &IID_IShellView))
1699 else if(IsEqualIID(riid, &IID_IShellView2))
1703 else if(IsEqualIID(riid, &IID_IFolderView))
1705 *ppvObj = &This->lpvtblFolderView;
1707 else if(IsEqualIID(riid, &IID_IOleCommandTarget))
1709 *ppvObj = &This->lpvtblOleCommandTarget;
1711 else if(IsEqualIID(riid, &IID_IDropTarget))
1713 *ppvObj = &This->lpvtblDropTarget;
1715 else if(IsEqualIID(riid, &IID_IDropSource))
1717 *ppvObj = &This->lpvtblDropSource;
1719 else if(IsEqualIID(riid, &IID_IViewObject))
1721 *ppvObj = &This->lpvtblViewObject;
1726 IUnknown_AddRef( (IUnknown*)*ppvObj );
1727 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1730 TRACE("-- Interface: E_NOINTERFACE\n");
1731 return E_NOINTERFACE;
1734 /**********************************************************
1737 static ULONG WINAPI IShellView_fnAddRef(IShellView2 * iface)
1739 IShellViewImpl *This = (IShellViewImpl *)iface;
1740 ULONG refCount = InterlockedIncrement(&This->ref);
1742 TRACE("(%p)->(count=%u)\n", This, refCount - 1);
1746 /**********************************************************
1747 * IShellView_Release
1749 static ULONG WINAPI IShellView_fnRelease(IShellView2 * iface)
1751 IShellViewImpl *This = (IShellViewImpl *)iface;
1752 ULONG refCount = InterlockedDecrement(&This->ref);
1754 TRACE("(%p)->(count=%i)\n", This, refCount + 1);
1758 TRACE(" destroying IShellView(%p)\n",This);
1760 DestroyWindow(This->hWndList);
1763 IShellFolder_Release(This->pSFParent);
1765 if(This->pSF2Parent)
1766 IShellFolder2_Release(This->pSF2Parent);
1768 SHFree(This->apidl);
1771 IAdviseSink_Release(This->pAdvSink);
1773 HeapFree(GetProcessHeap(),0,This);
1778 /**********************************************************
1779 * ShellView_GetWindow
1781 static HRESULT WINAPI IShellView_fnGetWindow(IShellView2 * iface,HWND * phWnd)
1783 IShellViewImpl *This = (IShellViewImpl *)iface;
1785 TRACE("(%p)\n",This);
1787 *phWnd = This->hWnd;
1792 static HRESULT WINAPI IShellView_fnContextSensitiveHelp(IShellView2 * iface,BOOL fEnterMode)
1794 IShellViewImpl *This = (IShellViewImpl *)iface;
1796 FIXME("(%p) stub\n",This);
1801 /**********************************************************
1802 * IShellView_TranslateAccelerator
1805 * use the accel functions
1807 static HRESULT WINAPI IShellView_fnTranslateAccelerator(IShellView2 * iface,LPMSG lpmsg)
1810 IShellViewImpl *This = (IShellViewImpl *)iface;
1812 FIXME("(%p)->(%p: hwnd=%x msg=%x lp=%x wp=%x) stub\n",This,lpmsg, lpmsg->hwnd, lpmsg->message, lpmsg->lParam, lpmsg->wParam);
1815 if ((lpmsg->message>=WM_KEYFIRST) && (lpmsg->message>=WM_KEYLAST))
1817 TRACE("-- key=0x04%lx\n",lpmsg->wParam) ;
1819 return S_FALSE; /* not handled */
1822 static HRESULT WINAPI IShellView_fnEnableModeless(IShellView2 * iface,BOOL fEnable)
1824 IShellViewImpl *This = (IShellViewImpl *)iface;
1826 FIXME("(%p) stub\n",This);
1831 static HRESULT WINAPI IShellView_fnUIActivate(IShellView2 * iface,UINT uState)
1833 IShellViewImpl *This = (IShellViewImpl *)iface;
1836 CHAR szName[MAX_PATH];
1839 int nPartArray[1] = {-1};
1841 TRACE("(%p)->(state=%x) stub\n",This, uState);
1843 /*don't do anything if the state isn't really changing*/
1844 if(This->uState == uState)
1849 /*OnActivate handles the menu merging and internal state*/
1850 ShellView_OnActivate(This, uState);
1852 /*only do This if we are active*/
1853 if(uState != SVUIA_DEACTIVATE)
1857 GetFolderPath is not a method of IShellFolder
1858 IShellFolder_GetFolderPath( This->pSFParent, szName, sizeof(szName) );
1860 /* set the number of parts */
1861 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETPARTS, 1,
1862 (LPARAM)nPartArray, &lResult);
1864 /* set the text for the parts */
1866 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETTEXTA,
1867 0, (LPARAM)szName, &lResult);
1874 static HRESULT WINAPI IShellView_fnRefresh(IShellView2 * iface)
1876 IShellViewImpl *This = (IShellViewImpl *)iface;
1878 TRACE("(%p)\n",This);
1880 SendMessageW(This->hWndList, LVM_DELETEALLITEMS, 0, 0);
1881 ShellView_FillList(This);
1886 static HRESULT WINAPI IShellView_fnCreateViewWindow(IShellView2 *iface, IShellView *lpPrevView,
1887 LPCFOLDERSETTINGS lpfs, IShellBrowser *psb, RECT *prcView, HWND *phWnd)
1890 SV2CVW2_PARAMS view_params;
1891 view_params.cbSize = sizeof(view_params);
1892 view_params.psvPrev = lpPrevView;
1893 view_params.pfs = lpfs;
1894 view_params.psbOwner = psb;
1895 view_params.prcView = prcView;
1896 view_params.pvid = NULL;
1897 view_params.hwndView = 0;
1899 TRACE("(%p) Forwarding to CreateViewWindow2\n", iface);
1901 hr = IShellView2_CreateViewWindow2(iface, &view_params);
1902 *phWnd = view_params.hwndView;
1907 static HRESULT WINAPI IShellView_fnDestroyViewWindow(IShellView2 * iface)
1909 IShellViewImpl *This = (IShellViewImpl *)iface;
1911 TRACE("(%p)\n",This);
1913 /*Make absolutely sure all our UI is cleaned up.*/
1914 IShellView_UIActivate((IShellView*)This, SVUIA_DEACTIVATE);
1918 DestroyMenu(This->hMenu);
1921 DestroyWindow(This->hWnd);
1922 if(This->pShellBrowser) IShellBrowser_Release(This->pShellBrowser);
1923 if(This->pCommDlgBrowser) ICommDlgBrowser_Release(This->pCommDlgBrowser);
1929 static HRESULT WINAPI IShellView_fnGetCurrentInfo(IShellView2 * iface, LPFOLDERSETTINGS lpfs)
1931 IShellViewImpl *This = (IShellViewImpl *)iface;
1933 TRACE("(%p)->(%p) vmode=%x flags=%x\n",This, lpfs,
1934 This->FolderSettings.ViewMode, This->FolderSettings.fFlags);
1936 if (!lpfs) return E_INVALIDARG;
1938 *lpfs = This->FolderSettings;
1942 static HRESULT WINAPI IShellView_fnAddPropertySheetPages(IShellView2 * iface, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam)
1944 IShellViewImpl *This = (IShellViewImpl *)iface;
1946 FIXME("(%p) stub\n",This);
1951 static HRESULT WINAPI IShellView_fnSaveViewState(IShellView2 * iface)
1953 IShellViewImpl *This = (IShellViewImpl *)iface;
1955 FIXME("(%p) stub\n",This);
1960 static HRESULT WINAPI IShellView_fnSelectItem(
1961 IShellView2 * iface,
1965 IShellViewImpl *This = (IShellViewImpl *)iface;
1970 TRACE("(%p)->(pidl=%p, 0x%08x)\n",This, pidl, flags);
1972 i = LV_FindItemByPidl(This, pidl);
1973 if (i == -1) return S_OK;
1975 hr = IShellView2_QueryInterface(iface, &IID_IFolderView, (void**)&view);
1978 hr = IFolderView_SelectItem(view, i, flags);
1979 IFolderView_Release(view);
1985 static HRESULT WINAPI IShellView_fnGetItemObject(IShellView2 * iface, UINT uItem, REFIID riid, LPVOID *ppvOut)
1987 IShellViewImpl *This = (IShellViewImpl *)iface;
1989 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n",This, uItem, debugstr_guid(riid), ppvOut);
1995 case SVGIO_BACKGROUND:
1996 *ppvOut = ISvBgCm_Constructor(This->pSFParent, FALSE);
1999 case SVGIO_SELECTION:
2000 ShellView_GetSelections(This);
2001 IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, (LPCITEMIDLIST*)This->apidl, riid, 0, ppvOut);
2004 TRACE("-- (%p)->(interface=%p)\n",This, *ppvOut);
2006 if(!*ppvOut) return E_OUTOFMEMORY;
2011 static HRESULT WINAPI IShellView2_fnGetView(IShellView2* iface, SHELLVIEWID *view_guid, ULONG view_type)
2013 FIXME("(%p)->(view_guid %s, view_type %#x) stub!\n", iface, debugstr_guid(view_guid), view_type);
2017 static HRESULT WINAPI IShellView2_fnCreateViewWindow2(IShellView2* iface, LPSV2CVW2_PARAMS view_params)
2019 IShellViewImpl *This = (IShellViewImpl *)iface;
2023 TRACE("(%p)->(view_params %p)\n", iface, view_params);
2025 if (view_params->cbSize != sizeof(*view_params))
2027 FIXME("Got unexpected cbSize %#x\n", view_params->cbSize);
2031 TRACE("-- psvPrev %p, pfs %p, psbOwner %p, prcView %p\n",
2032 view_params->psvPrev, view_params->pfs, view_params->psbOwner, view_params->prcView);
2033 TRACE("-- vmode %#x, flags %#x, left %d, top %d, right %d, bottom %d\n",
2034 view_params->pfs->ViewMode, view_params->pfs->fFlags, view_params->prcView->left,
2035 view_params->prcView->top, view_params->prcView->right, view_params->prcView->bottom);
2037 /* Set up the member variables */
2038 This->pShellBrowser = view_params->psbOwner;
2039 This->FolderSettings = *view_params->pfs;
2041 if (view_params->pvid)
2043 if (IsEqualGUID(view_params->pvid, &VID_LargeIcons))
2044 This->FolderSettings.ViewMode = FVM_ICON;
2045 else if (IsEqualGUID(view_params->pvid, &VID_SmallIcons))
2046 This->FolderSettings.ViewMode = FVM_SMALLICON;
2047 else if (IsEqualGUID(view_params->pvid, &VID_List))
2048 This->FolderSettings.ViewMode = FVM_LIST;
2049 else if (IsEqualGUID(view_params->pvid, &VID_Details))
2050 This->FolderSettings.ViewMode = FVM_DETAILS;
2051 else if (IsEqualGUID(view_params->pvid, &VID_Thumbnails))
2052 This->FolderSettings.ViewMode = FVM_THUMBNAIL;
2053 else if (IsEqualGUID(view_params->pvid, &VID_Tile))
2054 This->FolderSettings.ViewMode = FVM_TILE;
2055 else if (IsEqualGUID(view_params->pvid, &VID_ThumbStrip))
2056 This->FolderSettings.ViewMode = FVM_THUMBSTRIP;
2058 FIXME("Ignoring unrecognized VID %s\n", debugstr_guid(view_params->pvid));
2061 /* Get our parent window */
2062 IShellBrowser_AddRef(This->pShellBrowser);
2063 IShellBrowser_GetWindow(This->pShellBrowser, &(This->hWndParent));
2065 /* Try to get the ICommDlgBrowserInterface, adds a reference !!! */
2066 This->pCommDlgBrowser = NULL;
2067 if (SUCCEEDED(IShellBrowser_QueryInterface(This->pShellBrowser, &IID_ICommDlgBrowser, (void **)&This->pCommDlgBrowser)))
2069 TRACE("-- CommDlgBrowser %p\n", This->pCommDlgBrowser);
2072 /* If our window class has not been registered, then do so */
2073 if (!GetClassInfoW(shell32_hInstance, SV_CLASS_NAME, &wc))
2075 ZeroMemory(&wc, sizeof(wc));
2076 wc.style = CS_HREDRAW | CS_VREDRAW;
2077 wc.lpfnWndProc = ShellView_WndProc;
2080 wc.hInstance = shell32_hInstance;
2082 wc.hCursor = LoadCursorW(0, (LPWSTR)IDC_ARROW);
2083 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
2084 wc.lpszMenuName = NULL;
2085 wc.lpszClassName = SV_CLASS_NAME;
2087 if (!RegisterClassW(&wc)) return E_FAIL;
2090 wnd = CreateWindowExW(0, SV_CLASS_NAME, NULL, WS_CHILD | WS_TABSTOP,
2091 view_params->prcView->left, view_params->prcView->top,
2092 view_params->prcView->right - view_params->prcView->left,
2093 view_params->prcView->bottom - view_params->prcView->top,
2094 This->hWndParent, 0, shell32_hInstance, This);
2098 if (!wnd) return E_FAIL;
2100 SetWindowPos(wnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
2103 view_params->hwndView = wnd;
2108 static HRESULT WINAPI IShellView2_fnHandleRename(IShellView2* iface, LPCITEMIDLIST new_pidl)
2110 FIXME("(%p)->(new_pidl %p) stub!\n", iface, new_pidl);
2114 static HRESULT WINAPI IShellView2_fnSelectAndPositionItem(
2120 IShellViewImpl *This = (IShellViewImpl *)iface;
2124 TRACE("(%p)->(item %p, flags %#x, point %p)\n", This, item, flags, point);
2126 hr = IShellView2_QueryInterface(iface, &IID_IFolderView, (void**)&view);
2129 hr = IFolderView_SelectAndPositionItems(view, 1, &item, point, flags);
2130 IFolderView_Release(view);
2136 static const IShellView2Vtbl svvt =
2138 IShellView_fnQueryInterface,
2139 IShellView_fnAddRef,
2140 IShellView_fnRelease,
2141 IShellView_fnGetWindow,
2142 IShellView_fnContextSensitiveHelp,
2143 IShellView_fnTranslateAccelerator,
2144 IShellView_fnEnableModeless,
2145 IShellView_fnUIActivate,
2146 IShellView_fnRefresh,
2147 IShellView_fnCreateViewWindow,
2148 IShellView_fnDestroyViewWindow,
2149 IShellView_fnGetCurrentInfo,
2150 IShellView_fnAddPropertySheetPages,
2151 IShellView_fnSaveViewState,
2152 IShellView_fnSelectItem,
2153 IShellView_fnGetItemObject,
2154 IShellView2_fnGetView,
2155 IShellView2_fnCreateViewWindow2,
2156 IShellView2_fnHandleRename,
2157 IShellView2_fnSelectAndPositionItem,
2161 /**********************************************************
2162 * ISVOleCmdTarget_QueryInterface (IUnknown)
2164 static HRESULT WINAPI ISVOleCmdTarget_QueryInterface(
2165 IOleCommandTarget * iface,
2169 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2171 return IShellView2_QueryInterface((IShellView2*)This, iid, ppvObj);
2174 /**********************************************************
2175 * ISVOleCmdTarget_AddRef (IUnknown)
2177 static ULONG WINAPI ISVOleCmdTarget_AddRef(
2178 IOleCommandTarget * iface)
2180 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2182 return IShellView2_AddRef((IShellView2*)This);
2185 /**********************************************************
2186 * ISVOleCmdTarget_Release (IUnknown)
2188 static ULONG WINAPI ISVOleCmdTarget_Release(
2189 IOleCommandTarget * iface)
2191 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2193 return IShellView2_Release((IShellView2*)This);
2196 /**********************************************************
2197 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2199 static HRESULT WINAPI ISVOleCmdTarget_QueryStatus(
2200 IOleCommandTarget *iface,
2201 const GUID* pguidCmdGroup,
2204 OLECMDTEXT* pCmdText)
2207 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2209 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
2210 This, pguidCmdGroup, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText);
2214 for (i = 0; i < cCmds; i++)
2216 FIXME("\tprgCmds[%d].cmdID = %d\n", i, prgCmds[i].cmdID);
2217 prgCmds[i].cmdf = 0;
2219 return OLECMDERR_E_UNKNOWNGROUP;
2222 /**********************************************************
2223 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2225 * nCmdID is the OLECMDID_* enumeration
2227 static HRESULT WINAPI ISVOleCmdTarget_Exec(
2228 IOleCommandTarget *iface,
2229 const GUID* pguidCmdGroup,
2235 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2237 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2238 This, debugstr_guid(pguidCmdGroup), nCmdID, nCmdexecopt, pvaIn, pvaOut);
2240 if (IsEqualIID(pguidCmdGroup, &CGID_Explorer) &&
2242 (nCmdexecopt == 4) && pvaOut)
2244 if (IsEqualIID(pguidCmdGroup, &CGID_ShellDocView) &&
2249 return OLECMDERR_E_UNKNOWNGROUP;
2252 static const IOleCommandTargetVtbl ctvt =
2254 ISVOleCmdTarget_QueryInterface,
2255 ISVOleCmdTarget_AddRef,
2256 ISVOleCmdTarget_Release,
2257 ISVOleCmdTarget_QueryStatus,
2258 ISVOleCmdTarget_Exec
2261 /**********************************************************
2262 * ISVDropTarget implementation
2265 static HRESULT WINAPI ISVDropTarget_QueryInterface(
2270 IShellViewImpl *This = impl_from_IDropTarget(iface);
2272 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2274 return IShellView2_QueryInterface((IShellView2*)This, riid, ppvObj);
2277 static ULONG WINAPI ISVDropTarget_AddRef( IDropTarget *iface)
2279 IShellViewImpl *This = impl_from_IDropTarget(iface);
2281 TRACE("(%p)->(count=%u)\n",This,This->ref);
2283 return IShellView2_AddRef((IShellView2*)This);
2286 static ULONG WINAPI ISVDropTarget_Release( IDropTarget *iface)
2288 IShellViewImpl *This = impl_from_IDropTarget(iface);
2290 TRACE("(%p)->(count=%u)\n",This,This->ref);
2292 return IShellView2_Release((IShellView2*)This);
2295 /******************************************************************************
2296 * drag_notify_subitem [Internal]
2298 * Figure out the shellfolder object, which is currently under the mouse cursor
2299 * and notify it via the IDropTarget interface.
2302 #define SCROLLAREAWIDTH 20
2304 static HRESULT drag_notify_subitem(IShellViewImpl *This, DWORD grfKeyState, POINTL pt,
2307 LVHITTESTINFO htinfo;
2313 /* Map from global to client coordinates and query the index of the listview-item, which is
2314 * currently under the mouse cursor. */
2317 htinfo.flags = LVHT_ONITEM;
2318 ScreenToClient(This->hWndList, &htinfo.pt);
2319 lResult = SendMessageW(This->hWndList, LVM_HITTEST, 0, (LPARAM)&htinfo);
2321 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2322 GetClientRect(This->hWndList, &clientRect);
2323 if (htinfo.pt.x == This->ptLastMousePos.x && htinfo.pt.y == This->ptLastMousePos.y &&
2324 (htinfo.pt.x < SCROLLAREAWIDTH || htinfo.pt.x > clientRect.right - SCROLLAREAWIDTH ||
2325 htinfo.pt.y < SCROLLAREAWIDTH || htinfo.pt.y > clientRect.bottom - SCROLLAREAWIDTH ))
2327 This->cScrollDelay = (This->cScrollDelay + 1) % 5; /* DragOver is called every 50 ms */
2328 if (This->cScrollDelay == 0) { /* Mouse did hover another 250 ms over the scroll-area */
2329 if (htinfo.pt.x < SCROLLAREAWIDTH)
2330 SendMessageW(This->hWndList, WM_HSCROLL, SB_LINEUP, 0);
2331 if (htinfo.pt.x > clientRect.right - SCROLLAREAWIDTH)
2332 SendMessageW(This->hWndList, WM_HSCROLL, SB_LINEDOWN, 0);
2333 if (htinfo.pt.y < SCROLLAREAWIDTH)
2334 SendMessageW(This->hWndList, WM_VSCROLL, SB_LINEUP, 0);
2335 if (htinfo.pt.y > clientRect.bottom - SCROLLAREAWIDTH)
2336 SendMessageW(This->hWndList, WM_VSCROLL, SB_LINEDOWN, 0);
2339 This->cScrollDelay = 0; /* Reset, if the cursor is not over the listview's scroll-area */
2341 This->ptLastMousePos = htinfo.pt;
2343 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2344 if (This->pCurDropTarget && lResult == This->iDragOverItem)
2345 return IDropTarget_DragOver(This->pCurDropTarget, grfKeyState, pt, pdwEffect);
2347 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2348 if (This->pCurDropTarget) {
2349 IDropTarget_DragLeave(This->pCurDropTarget);
2350 IDropTarget_Release(This->pCurDropTarget);
2351 This->pCurDropTarget = NULL;
2354 This->iDragOverItem = lResult;
2355 if (lResult == -1) {
2356 /* We are not above one of the listview's subitems. Bind to the parent folder's
2357 * DropTarget interface. */
2358 hr = IShellFolder_QueryInterface(This->pSFParent, &IID_IDropTarget,
2359 (LPVOID*)&This->pCurDropTarget);
2361 /* Query the relative PIDL of the shellfolder object represented by the currently
2362 * dragged over listview-item ... */
2363 lvItem.mask = LVIF_PARAM;
2364 lvItem.iItem = lResult;
2365 lvItem.iSubItem = 0;
2366 SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem);
2368 /* ... and bind pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2369 hr = IShellFolder_GetUIObjectOf(This->pSFParent, This->hWndList, 1,
2370 (LPCITEMIDLIST*)&lvItem.lParam, &IID_IDropTarget, NULL, (LPVOID*)&This->pCurDropTarget);
2373 /* If anything failed, pCurDropTarget should be NULL now, which ought to be a save state. */
2377 /* Notify the item just entered via DragEnter. */
2378 return IDropTarget_DragEnter(This->pCurDropTarget, This->pCurDataObject, grfKeyState, pt, pdwEffect);
2381 static HRESULT WINAPI ISVDropTarget_DragEnter(IDropTarget *iface, IDataObject *pDataObject,
2382 DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
2384 IShellViewImpl *This = impl_from_IDropTarget(iface);
2386 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2387 This->pCurDataObject = pDataObject;
2388 IDataObject_AddRef(pDataObject);
2390 return drag_notify_subitem(This, grfKeyState, pt, pdwEffect);
2393 static HRESULT WINAPI ISVDropTarget_DragOver(IDropTarget *iface, DWORD grfKeyState, POINTL pt,
2396 IShellViewImpl *This = impl_from_IDropTarget(iface);
2397 return drag_notify_subitem(This, grfKeyState, pt, pdwEffect);
2400 static HRESULT WINAPI ISVDropTarget_DragLeave(IDropTarget *iface) {
2401 IShellViewImpl *This = impl_from_IDropTarget(iface);
2403 IDropTarget_DragLeave(This->pCurDropTarget);
2405 IDropTarget_Release(This->pCurDropTarget);
2406 IDataObject_Release(This->pCurDataObject);
2407 This->pCurDataObject = NULL;
2408 This->pCurDropTarget = NULL;
2409 This->iDragOverItem = 0;
2414 static HRESULT WINAPI ISVDropTarget_Drop(IDropTarget *iface, IDataObject* pDataObject,
2415 DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
2417 IShellViewImpl *This = impl_from_IDropTarget(iface);
2419 IDropTarget_Drop(This->pCurDropTarget, pDataObject, grfKeyState, pt, pdwEffect);
2421 IDropTarget_Release(This->pCurDropTarget);
2422 IDataObject_Release(This->pCurDataObject);
2423 This->pCurDataObject = NULL;
2424 This->pCurDropTarget = NULL;
2425 This->iDragOverItem = 0;
2430 static const IDropTargetVtbl dtvt =
2432 ISVDropTarget_QueryInterface,
2433 ISVDropTarget_AddRef,
2434 ISVDropTarget_Release,
2435 ISVDropTarget_DragEnter,
2436 ISVDropTarget_DragOver,
2437 ISVDropTarget_DragLeave,
2441 /**********************************************************
2442 * ISVDropSource implementation
2445 static HRESULT WINAPI ISVDropSource_QueryInterface(
2450 IShellViewImpl *This = impl_from_IDropSource(iface);
2452 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2454 return IShellView2_QueryInterface((IShellView2*)This, riid, ppvObj);
2457 static ULONG WINAPI ISVDropSource_AddRef( IDropSource *iface)
2459 IShellViewImpl *This = impl_from_IDropSource(iface);
2461 TRACE("(%p)->(count=%u)\n",This,This->ref);
2463 return IShellView2_AddRef((IShellView2*)This);
2466 static ULONG WINAPI ISVDropSource_Release( IDropSource *iface)
2468 IShellViewImpl *This = impl_from_IDropSource(iface);
2470 TRACE("(%p)->(count=%u)\n",This,This->ref);
2472 return IShellView2_Release((IShellView2*)This);
2475 static HRESULT WINAPI ISVDropSource_QueryContinueDrag(
2477 BOOL fEscapePressed,
2480 IShellViewImpl *This = impl_from_IDropSource(iface);
2481 TRACE("(%p)\n",This);
2484 return DRAGDROP_S_CANCEL;
2485 else if (!(grfKeyState & MK_LBUTTON) && !(grfKeyState & MK_RBUTTON))
2486 return DRAGDROP_S_DROP;
2491 static HRESULT WINAPI ISVDropSource_GiveFeedback(
2495 IShellViewImpl *This = impl_from_IDropSource(iface);
2496 TRACE("(%p)\n",This);
2498 return DRAGDROP_S_USEDEFAULTCURSORS;
2501 static const IDropSourceVtbl dsvt =
2503 ISVDropSource_QueryInterface,
2504 ISVDropSource_AddRef,
2505 ISVDropSource_Release,
2506 ISVDropSource_QueryContinueDrag,
2507 ISVDropSource_GiveFeedback
2509 /**********************************************************
2510 * ISVViewObject implementation
2513 static HRESULT WINAPI ISVViewObject_QueryInterface(
2518 IShellViewImpl *This = impl_from_IViewObject(iface);
2520 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2522 return IShellView2_QueryInterface((IShellView2*)This, riid, ppvObj);
2525 static ULONG WINAPI ISVViewObject_AddRef( IViewObject *iface)
2527 IShellViewImpl *This = impl_from_IViewObject(iface);
2529 TRACE("(%p)->(count=%u)\n",This,This->ref);
2531 return IShellView2_AddRef((IShellView2*)This);
2534 static ULONG WINAPI ISVViewObject_Release( IViewObject *iface)
2536 IShellViewImpl *This = impl_from_IViewObject(iface);
2538 TRACE("(%p)->(count=%u)\n",This,This->ref);
2540 return IShellView2_Release((IShellView2*)This);
2543 static HRESULT WINAPI ISVViewObject_Draw(
2548 DVTARGETDEVICE* ptd,
2551 LPCRECTL lprcBounds,
2552 LPCRECTL lprcWBounds,
2553 BOOL (CALLBACK *pfnContinue)(ULONG_PTR dwContinue),
2554 ULONG_PTR dwContinue)
2557 IShellViewImpl *This = impl_from_IViewObject(iface);
2559 FIXME("Stub: This=%p\n",This);
2563 static HRESULT WINAPI ISVViewObject_GetColorSet(
2568 DVTARGETDEVICE* ptd,
2569 HDC hicTargetDevice,
2570 LOGPALETTE** ppColorSet)
2573 IShellViewImpl *This = impl_from_IViewObject(iface);
2575 FIXME("Stub: This=%p\n",This);
2579 static HRESULT WINAPI ISVViewObject_Freeze(
2587 IShellViewImpl *This = impl_from_IViewObject(iface);
2589 FIXME("Stub: This=%p\n",This);
2593 static HRESULT WINAPI ISVViewObject_Unfreeze(
2598 IShellViewImpl *This = impl_from_IViewObject(iface);
2600 FIXME("Stub: This=%p\n",This);
2604 static HRESULT WINAPI ISVViewObject_SetAdvise(
2608 IAdviseSink* pAdvSink)
2611 IShellViewImpl *This = impl_from_IViewObject(iface);
2613 FIXME("partial stub: %p %08x %08x %p\n",
2614 This, aspects, advf, pAdvSink);
2616 /* FIXME: we set the AdviseSink, but never use it to send any advice */
2617 This->pAdvSink = pAdvSink;
2618 This->dwAspects = aspects;
2619 This->dwAdvf = advf;
2624 static HRESULT WINAPI ISVViewObject_GetAdvise(
2628 IAdviseSink** ppAdvSink)
2631 IShellViewImpl *This = impl_from_IViewObject(iface);
2633 TRACE("This=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n",
2634 This, pAspects, pAdvf, ppAdvSink);
2638 IAdviseSink_AddRef( This->pAdvSink );
2639 *ppAdvSink = This->pAdvSink;
2642 *pAspects = This->dwAspects;
2644 *pAdvf = This->dwAdvf;
2650 static const IViewObjectVtbl vovt =
2652 ISVViewObject_QueryInterface,
2653 ISVViewObject_AddRef,
2654 ISVViewObject_Release,
2656 ISVViewObject_GetColorSet,
2657 ISVViewObject_Freeze,
2658 ISVViewObject_Unfreeze,
2659 ISVViewObject_SetAdvise,
2660 ISVViewObject_GetAdvise
2664 static HRESULT WINAPI IFView_QueryInterface(
2669 IShellViewImpl *This = impl_from_IFolderView(iface);
2670 TRACE("(%p)->(IID:%s,%p)\n", This, debugstr_guid(riid), ppvObj);
2671 return IShellView2_QueryInterface((IShellView2*)This, riid, ppvObj);
2674 static ULONG WINAPI IFView_AddRef( IFolderView *iface)
2676 IShellViewImpl *This = impl_from_IFolderView(iface);
2677 TRACE("(%p)->(count=%u)\n", This, This->ref);
2678 return IShellView2_AddRef((IShellView2*)This);
2681 static ULONG WINAPI IFView_Release( IFolderView *iface)
2683 IShellViewImpl *This = impl_from_IFolderView(iface);
2684 TRACE("(%p)->(count=%u)\n", This, This->ref);
2685 return IShellView2_Release((IShellView2*)This);
2688 static HRESULT WINAPI IFView_GetCurrentViewMode(IFolderView *iface, UINT *mode)
2690 IShellViewImpl *This = impl_from_IFolderView(iface);
2691 FIXME("(%p)->(%p), stub\n", This, mode);
2695 static HRESULT WINAPI IFView_SetCurrentViewMode(IFolderView *iface, UINT mode)
2697 IShellViewImpl *This = impl_from_IFolderView(iface);
2698 FIXME("(%p)->(%u), stub\n", This, mode);
2702 static HRESULT WINAPI IFView_GetFolder(IFolderView *iface, REFIID riid, void **ppv)
2704 IShellViewImpl *This = impl_from_IFolderView(iface);
2705 FIXME("(%p)->(%s, %p), stub\n", This, debugstr_guid(riid), ppv);
2709 static HRESULT WINAPI IFView_Item(IFolderView *iface, int index, PITEMID_CHILD *ppidl)
2711 IShellViewImpl *This = impl_from_IFolderView(iface);
2712 FIXME("(%p)->(%d %p), stub\n", This, index, ppidl);
2716 static HRESULT WINAPI IFView_ItemCount(IFolderView *iface, UINT flags, int *items)
2718 IShellViewImpl *This = impl_from_IFolderView(iface);
2719 FIXME("(%p)->(%u %p), stub\n", This, flags, items);
2723 static HRESULT WINAPI IFView_Items(IFolderView *iface, UINT flags, REFIID riid, void **ppv)
2725 IShellViewImpl *This = impl_from_IFolderView(iface);
2726 FIXME("(%p)->(%u %s %p), stub\n", This, flags, debugstr_guid(riid), ppv);
2730 static HRESULT WINAPI IFView_GetSelectionMarkedItem(IFolderView *iface, int *item)
2732 IShellViewImpl *This = impl_from_IFolderView(iface);
2733 FIXME("(%p)->(%p), stub\n", This, item);
2737 static HRESULT WINAPI IFView_GetFocusedItem(IFolderView *iface, int *item)
2739 IShellViewImpl *This = impl_from_IFolderView(iface);
2740 FIXME("(%p)->(%p), stub\n", This, item);
2744 static HRESULT WINAPI IFView_GetItemPosition(IFolderView *iface, PCUITEMID_CHILD pidl, POINT *ppt)
2746 IShellViewImpl *This = impl_from_IFolderView(iface);
2747 FIXME("(%p)->(%p %p), stub\n", This, pidl, ppt);
2751 static HRESULT WINAPI IFView_GetSpacing(IFolderView *iface, POINT *pt)
2753 IShellViewImpl *This = impl_from_IFolderView(iface);
2754 FIXME("(%p)->(%p), stub\n", This, pt);
2758 static HRESULT WINAPI IFView_GetDefaultSpacing(IFolderView *iface, POINT *pt)
2760 IShellViewImpl *This = impl_from_IFolderView(iface);
2761 FIXME("(%p)->(%p), stub\n", This, pt);
2765 static HRESULT WINAPI IFView_GetAutoArrange(IFolderView *iface)
2767 IShellViewImpl *This = impl_from_IFolderView(iface);
2768 FIXME("(%p), stub\n", This);
2772 static HRESULT WINAPI IFView_SelectItem(IFolderView *iface, int item, DWORD flags)
2774 IShellViewImpl *This = impl_from_IFolderView(iface);
2777 TRACE("(%p)->(%d, %x)\n", This, item, flags);
2780 lvItem.stateMask = LVIS_SELECTED;
2782 if (flags & SVSI_ENSUREVISIBLE)
2783 SendMessageW(This->hWndList, LVM_ENSUREVISIBLE, item, 0);
2786 if (flags & SVSI_DESELECTOTHERS)
2787 SendMessageW(This->hWndList, LVM_SETITEMSTATE, -1, (LPARAM)&lvItem);
2790 if (flags & SVSI_SELECT)
2791 lvItem.state |= LVIS_SELECTED;
2793 if (flags & SVSI_FOCUSED)
2794 lvItem.stateMask |= LVIS_FOCUSED;
2796 SendMessageW(This->hWndList, LVM_SETITEMSTATE, item, (LPARAM)&lvItem);
2798 if (flags & SVSI_EDIT)
2799 SendMessageW(This->hWndList, LVM_EDITLABELW, item, 0);
2804 static HRESULT WINAPI IFView_SelectAndPositionItems(IFolderView *iface, UINT cidl,
2805 PCUITEMID_CHILD_ARRAY apidl, POINT *apt, DWORD flags)
2807 IShellViewImpl *This = impl_from_IFolderView(iface);
2808 FIXME("(%p)->(%u %p %p %x), stub\n", This, cidl, apidl, apt, flags);
2812 static const IFolderViewVtbl fviewvt =
2814 IFView_QueryInterface,
2817 IFView_GetCurrentViewMode,
2818 IFView_SetCurrentViewMode,
2823 IFView_GetSelectionMarkedItem,
2824 IFView_GetFocusedItem,
2825 IFView_GetItemPosition,
2827 IFView_GetDefaultSpacing,
2828 IFView_GetAutoArrange,
2830 IFView_SelectAndPositionItems