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 const IShellFolderViewVtbl *lpvtblShellFolderView;
90 IShellFolder* pSFParent;
91 IShellFolder2* pSF2Parent;
92 IShellBrowser* pShellBrowser;
93 ICommDlgBrowser* pCommDlgBrowser;
94 HWND hWnd; /* SHELLDLL_DefView */
95 HWND hWndList; /* ListView control */
97 FOLDERSETTINGS FolderSettings;
102 LISTVIEW_SORT_INFO ListViewSortInfo;
103 ULONG hNotify; /* change notification handle */
107 IAdviseSink *pAdvSink;
108 IDropTarget* pCurDropTarget; /* The sub-item, which is currently dragged over */
109 IDataObject* pCurDataObject; /* The dragged data-object */
110 LONG iDragOverItem; /* Dragged over item's index, iff pCurDropTarget != NULL */
111 UINT cScrollDelay; /* Send a WM_*SCROLL msg every 250 ms during drag-scroll */
112 POINT ptLastMousePos; /* Mouse position at last DragOver call */
115 static const IShellView2Vtbl svvt;
116 static const IOleCommandTargetVtbl ctvt;
117 static const IDropTargetVtbl dtvt;
118 static const IDropSourceVtbl dsvt;
119 static const IViewObjectVtbl vovt;
120 static const IFolderViewVtbl fviewvt;
121 static const IShellFolderViewVtbl shellfolderviewvt;
123 static inline IShellViewImpl *impl_from_IOleCommandTarget( IOleCommandTarget *iface )
125 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblOleCommandTarget));
128 static inline IShellViewImpl *impl_from_IDropTarget( IDropTarget *iface )
130 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblDropTarget));
133 static inline IShellViewImpl *impl_from_IDropSource( IDropSource *iface )
135 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblDropSource));
138 static inline IShellViewImpl *impl_from_IViewObject( IViewObject *iface )
140 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblViewObject));
143 static inline IShellViewImpl *impl_from_IFolderView( IFolderView *iface )
145 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblFolderView));
148 static inline IShellViewImpl *impl_from_IShellFolderView( IShellFolderView *iface )
150 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblShellFolderView));
153 /* ListView Header ID's */
154 #define LISTVIEW_COLUMN_NAME 0
155 #define LISTVIEW_COLUMN_SIZE 1
156 #define LISTVIEW_COLUMN_TYPE 2
157 #define LISTVIEW_COLUMN_TIME 3
158 #define LISTVIEW_COLUMN_ATTRIB 4
161 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
162 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
163 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
165 #define ID_LISTVIEW 1
167 #define SHV_CHANGE_NOTIFY WM_USER + 0x1111
170 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
171 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
172 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
175 Items merged into the toolbar and the filemenu
184 } MYTOOLINFO, *LPMYTOOLINFO;
186 static const MYTOOLINFO Tools[] =
188 { FCIDM_SHVIEW_BIGICON, 0, 0, IDS_VIEW_LARGE, TBSTATE_ENABLED, BTNS_BUTTON },
189 { FCIDM_SHVIEW_SMALLICON, 0, 0, IDS_VIEW_SMALL, TBSTATE_ENABLED, BTNS_BUTTON },
190 { FCIDM_SHVIEW_LISTVIEW, 0, 0, IDS_VIEW_LIST, TBSTATE_ENABLED, BTNS_BUTTON },
191 { FCIDM_SHVIEW_REPORTVIEW, 0, 0, IDS_VIEW_DETAILS, TBSTATE_ENABLED, BTNS_BUTTON },
195 typedef void (CALLBACK *PFNSHGETSETTINGSPROC)(LPSHELLFLAGSTATE lpsfs, DWORD dwMask);
197 /**********************************************************
198 * IShellView_Constructor
200 IShellView * IShellView_Constructor( IShellFolder * pFolder)
201 { IShellViewImpl * sv;
202 sv=HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IShellViewImpl));
205 sv->lpvtblOleCommandTarget=&ctvt;
206 sv->lpvtblDropTarget=&dtvt;
207 sv->lpvtblDropSource=&dsvt;
208 sv->lpvtblViewObject=&vovt;
209 sv->lpvtblFolderView=&fviewvt;
210 sv->lpvtblShellFolderView=&shellfolderviewvt;
212 sv->pSFParent = pFolder;
213 if(pFolder) IShellFolder_AddRef(pFolder);
214 IShellFolder_QueryInterface(sv->pSFParent, &IID_IShellFolder2, (LPVOID*)&sv->pSF2Parent);
216 sv->pCurDropTarget = NULL;
217 sv->pCurDataObject = NULL;
218 sv->iDragOverItem = 0;
219 sv->cScrollDelay = 0;
220 sv->ptLastMousePos.x = 0;
221 sv->ptLastMousePos.y = 0;
223 TRACE("(%p)->(%p)\n",sv, pFolder);
224 return (IShellView *) sv;
227 /**********************************************************
229 * ##### helperfunctions for communication with ICommDlgBrowser #####
231 static BOOL IsInCommDlg(IShellViewImpl * This)
232 { return(This->pCommDlgBrowser != NULL);
235 static HRESULT IncludeObject(IShellViewImpl * This, LPCITEMIDLIST pidl)
239 if ( IsInCommDlg(This) )
241 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl);
242 ret = ICommDlgBrowser_IncludeObject(This->pCommDlgBrowser, (IShellView*)This, pidl);
243 TRACE("--0x%08x\n", ret);
248 static HRESULT OnDefaultCommand(IShellViewImpl * This)
250 HRESULT ret = S_FALSE;
252 if (IsInCommDlg(This))
254 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
255 ret = ICommDlgBrowser_OnDefaultCommand(This->pCommDlgBrowser, (IShellView*)This);
256 TRACE("-- returns %08x\n", ret);
261 static HRESULT OnStateChange(IShellViewImpl * This, UINT uFlags)
263 HRESULT ret = S_FALSE;
265 if (IsInCommDlg(This))
267 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags);
268 ret = ICommDlgBrowser_OnStateChange(This->pCommDlgBrowser, (IShellView*)This, uFlags);
273 /**********************************************************
274 * set the toolbar of the filedialog buttons
276 * - activates the buttons from the shellbrowser according to
279 static void CheckToolbar(IShellViewImpl * This)
285 if (IsInCommDlg(This))
287 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
288 FCIDM_TB_SMALLICON, (This->FolderSettings.ViewMode==FVM_LIST)? TRUE : FALSE, &result);
289 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
290 FCIDM_TB_REPORTVIEW, (This->FolderSettings.ViewMode==FVM_DETAILS)? TRUE : FALSE, &result);
291 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
292 FCIDM_TB_SMALLICON, TRUE, &result);
293 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
294 FCIDM_TB_REPORTVIEW, TRUE, &result);
298 /**********************************************************
300 * ##### helperfunctions for initializing the view #####
302 /**********************************************************
303 * change the style of the listview control
305 static void SetStyle(IShellViewImpl * This, DWORD dwAdd, DWORD dwRemove)
309 TRACE("(%p)\n", This);
311 tmpstyle = GetWindowLongW(This->hWndList, GWL_STYLE);
312 SetWindowLongW(This->hWndList, GWL_STYLE, dwAdd | (tmpstyle & ~dwRemove));
315 static DWORD ViewModeToListStyle(UINT ViewMode)
319 TRACE("%d\n", 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", ViewMode);
338 /**********************************************************
339 * ShellView_CreateList()
341 * - creates the list view window
343 static BOOL ShellView_CreateList (IShellViewImpl * This)
344 { DWORD dwStyle, dwExStyle;
348 dwStyle = WS_TABSTOP | WS_VISIBLE | WS_CHILDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
349 LVS_SHAREIMAGELISTS | LVS_EDITLABELS | LVS_ALIGNLEFT | LVS_AUTOARRANGE;
350 dwExStyle = WS_EX_CLIENTEDGE;
352 dwStyle |= ViewModeToListStyle(This->FolderSettings.ViewMode);
354 if (This->FolderSettings.fFlags & FWF_AUTOARRANGE) dwStyle |= LVS_AUTOARRANGE;
355 if (This->FolderSettings.fFlags & FWF_DESKTOP)
356 This->FolderSettings.fFlags |= FWF_NOCLIENTEDGE | FWF_NOSCROLL;
357 if (This->FolderSettings.fFlags & FWF_SINGLESEL) dwStyle |= LVS_SINGLESEL;
358 if (This->FolderSettings.fFlags & FWF_NOCLIENTEDGE)
359 dwExStyle &= ~WS_EX_CLIENTEDGE;
361 This->hWndList=CreateWindowExW( dwExStyle,
374 This->ListViewSortInfo.bIsAscending = TRUE;
375 This->ListViewSortInfo.nHeaderID = -1;
376 This->ListViewSortInfo.nLastHeaderID = -1;
378 if (This->FolderSettings.fFlags & FWF_DESKTOP) {
380 * FIXME: look at the registry value
381 * HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ListviewShadow
382 * and activate drop shadows if necessary
385 SendMessageW(This->hWndList, LVM_SETTEXTBKCOLOR, 0, CLR_NONE);
387 SendMessageW(This->hWndList, LVM_SETTEXTBKCOLOR, 0, GetSysColor(COLOR_DESKTOP));
389 SendMessageW(This->hWndList, LVM_SETTEXTCOLOR, 0, RGB(255,255,255));
392 /* UpdateShellSettings(); */
396 /**********************************************************
397 * ShellView_InitList()
399 * - adds all needed columns to the shellview
401 static void ShellView_InitList(IShellViewImpl *This)
403 IShellDetails *details = NULL;
410 TRACE("(%p)\n", This);
412 SendMessageW(This->hWndList, LVM_DELETEALLITEMS, 0, 0);
413 SendMessageW(This->hWndList, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)ShellSmallIconList);
414 SendMessageW(This->hWndList, LVM_SETIMAGELIST, LVSIL_NORMAL, (LPARAM)ShellBigIconList);
416 lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT;
417 lvColumn.pszText = nameW;
419 if (!This->pSF2Parent)
421 hr = IShellFolder_QueryInterface(This->pSFParent, &IID_IShellDetails, (void**)&details);
424 WARN("IShellFolder2/IShellDetails not supported\n");
431 if (This->pSF2Parent)
432 hr = IShellFolder2_GetDetailsOf(This->pSF2Parent, NULL, i, &sd);
434 hr = IShellDetails_GetDetailsOf(details, NULL, i, &sd);
435 if (FAILED(hr)) break;
437 lvColumn.fmt = sd.fmt;
438 lvColumn.cx = sd.cxChar*8; /* chars->pixel */
439 StrRetToStrNW(nameW, sizeof(nameW)/sizeof(WCHAR), &sd.str, NULL);
440 SendMessageW(This->hWndList, LVM_INSERTCOLUMNW, i, (LPARAM) &lvColumn);
443 if (details) IShellDetails_Release(details);
446 /**********************************************************
447 * ShellView_CompareItems()
450 * internal, CALLBACK for DSA_Sort
452 static INT CALLBACK ShellView_CompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
455 TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1, lParam2, (LPVOID) lpData);
457 if(!lpData) return 0;
459 ret = (SHORT) SCODE_CODE(IShellFolder_CompareIDs((LPSHELLFOLDER)lpData, 0, (LPITEMIDLIST)lParam1, (LPITEMIDLIST)lParam2));
460 TRACE("ret=%i\n",ret);
464 /*************************************************************************
465 * ShellView_ListViewCompareItems
467 * Compare Function for the Listview (FileOpen Dialog)
470 * lParam1 [I] the first ItemIdList to compare with
471 * lParam2 [I] the second ItemIdList to compare with
472 * lpData [I] The column ID for the header Ctrl to process
475 * A negative value if the first item should precede the second,
476 * a positive value if the first item should follow the second,
477 * or zero if the two items are equivalent
480 * FIXME: function does what ShellView_CompareItems is supposed to do.
481 * unify it and figure out how to use the undocumented first parameter
482 * of IShellFolder_CompareIDs to do the job this function does and
483 * move this code to IShellFolder.
484 * make LISTVIEW_SORT_INFO obsolete
485 * the way this function works is only usable if we had only
486 * filesystemfolders (25/10/99 jsch)
488 static INT CALLBACK ShellView_ListViewCompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
492 char strName1[MAX_PATH], strName2[MAX_PATH];
493 BOOL bIsFolder1, bIsFolder2,bIsBothFolder;
494 LPITEMIDLIST pItemIdList1 = lParam1;
495 LPITEMIDLIST pItemIdList2 = lParam2;
496 LISTVIEW_SORT_INFO *pSortInfo = (LPLISTVIEW_SORT_INFO) lpData;
499 bIsFolder1 = _ILIsFolder(pItemIdList1);
500 bIsFolder2 = _ILIsFolder(pItemIdList2);
501 bIsBothFolder = bIsFolder1 && bIsFolder2;
503 /* When sorting between a File and a Folder, the Folder gets sorted first */
504 if( (bIsFolder1 || bIsFolder2) && !bIsBothFolder)
506 nDiff = bIsFolder1 ? -1 : 1;
510 /* Sort by Time: Folders or Files can be sorted */
512 if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TIME)
514 _ILGetFileDateTime(pItemIdList1, &fd1);
515 _ILGetFileDateTime(pItemIdList2, &fd2);
516 nDiff = CompareFileTime(&fd2, &fd1);
518 /* Sort by Attribute: Folder or Files can be sorted */
519 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_ATTRIB)
521 _ILGetFileAttributes(pItemIdList1, strName1, MAX_PATH);
522 _ILGetFileAttributes(pItemIdList2, strName2, MAX_PATH);
523 nDiff = lstrcmpiA(strName1, strName2);
525 /* Sort by FileName: Folder or Files can be sorted */
526 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_NAME || bIsBothFolder)
529 _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
530 _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
531 nDiff = lstrcmpiA(strName1, strName2);
533 /* Sort by File Size, Only valid for Files */
534 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_SIZE)
536 nDiff = (INT)(_ILGetFileSize(pItemIdList1, NULL, 0) - _ILGetFileSize(pItemIdList2, NULL, 0));
538 /* Sort by File Type, Only valid for Files */
539 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TYPE)
542 _ILGetFileType(pItemIdList1, strName1, MAX_PATH);
543 _ILGetFileType(pItemIdList2, strName2, MAX_PATH);
544 nDiff = lstrcmpiA(strName1, strName2);
547 /* If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
551 _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
552 _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
553 nDiff = lstrcmpiA(strName1, strName2);
556 if(!pSortInfo->bIsAscending)
565 /**********************************************************
566 * LV_FindItemByPidl()
568 static int LV_FindItemByPidl(
569 IShellViewImpl * This,
574 lvItem.mask = LVIF_PARAM;
575 for(lvItem.iItem = 0;
576 SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem);
579 LPITEMIDLIST currentpidl = (LPITEMIDLIST) lvItem.lParam;
580 HRESULT hr = IShellFolder_CompareIDs(This->pSFParent, 0, pidl, currentpidl);
581 if(SUCCEEDED(hr) && !HRESULT_CODE(hr))
589 /**********************************************************
592 static BOOLEAN LV_AddItem(IShellViewImpl * This, LPCITEMIDLIST pidl)
596 TRACE("(%p)(pidl=%p)\n", This, pidl);
598 lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; /*set the mask*/
599 lvItem.iItem = SendMessageW(This->hWndList, LVM_GETITEMCOUNT, 0, 0); /*add the item to the end of the list*/
601 lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidl)); /*set the item's data*/
602 lvItem.pszText = LPSTR_TEXTCALLBACKW; /*get text on a callback basis*/
603 lvItem.iImage = I_IMAGECALLBACK; /*get the image on a callback basis*/
604 return (-1==ListView_InsertItemW(This->hWndList, &lvItem))? FALSE: TRUE;
607 /**********************************************************
610 static BOOLEAN LV_RenameItem(IShellViewImpl * This, LPCITEMIDLIST pidlOld, LPCITEMIDLIST pidlNew )
615 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", This, pidlOld, pidlNew);
617 nItem = LV_FindItemByPidl(This, ILFindLastID(pidlOld));
620 lvItem.mask = LVIF_PARAM; /* only the pidl */
621 lvItem.iItem = nItem;
622 SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem);
624 SHFree((LPITEMIDLIST)lvItem.lParam);
625 lvItem.mask = LVIF_PARAM;
626 lvItem.iItem = nItem;
627 lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidlNew)); /* set the item's data */
628 SendMessageW(This->hWndList, LVM_SETITEMW, 0, (LPARAM) &lvItem);
629 SendMessageW(This->hWndList, LVM_UPDATE, nItem, 0);
630 return TRUE; /* FIXME: better handling */
634 /**********************************************************
635 * ShellView_FillList()
637 * - gets the objectlist from the shellfolder
639 * - fills the list into the view
642 static INT CALLBACK fill_list( LPVOID ptr, LPVOID arg )
644 LPITEMIDLIST pidl = ptr;
645 IShellViewImpl *This = arg;
646 /* in a commdlg This works as a filemask*/
647 if ( IncludeObject(This, pidl)==S_OK ) LV_AddItem(This, pidl);
652 static HRESULT ShellView_FillList(IShellViewImpl *This)
654 IShellFolderView *folderview = (IShellFolderView*)&This->lpvtblShellFolderView;
655 LPENUMIDLIST pEnumIDList;
661 TRACE("(%p)\n", This);
663 /* get the itemlist from the shfolder*/
664 hr = IShellFolder_EnumObjects(This->pSFParent, This->hWnd, SHCONTF_NONFOLDERS | SHCONTF_FOLDERS, &pEnumIDList);
665 if (hr != S_OK) return hr;
667 /* create a pointer array */
668 hdpa = DPA_Create(16);
671 IEnumIDList_Release(pEnumIDList);
672 return E_OUTOFMEMORY;
675 /* copy the items into the array*/
676 while((S_OK == IEnumIDList_Next(pEnumIDList, 1, &pidl, &fetched)) && fetched)
678 if (DPA_InsertPtr(hdpa, DPA_GetPtrCount(hdpa), pidl) == -1)
685 DPA_Sort(hdpa, ShellView_CompareItems, (LPARAM)This->pSFParent);
687 IShellFolderView_SetRedraw(folderview, FALSE);
688 DPA_DestroyCallback(hdpa, fill_list, This);
689 IShellFolderView_SetRedraw(folderview, TRUE);
691 IEnumIDList_Release(pEnumIDList);
696 /**********************************************************
697 * ShellView_OnCreate()
699 static LRESULT ShellView_OnCreate(IShellViewImpl *This)
701 IShellView2 *iface = (IShellView2*)This;
702 static const WCHAR accel_nameW[] = {'s','h','v','_','a','c','c','e','l',0};
703 IPersistFolder2 *ppf2;
707 TRACE("(%p)\n", This);
709 if (ShellView_CreateList(This))
711 ShellView_InitList(This);
712 ShellView_FillList(This);
715 hr = IShellView2_QueryInterface(iface, &IID_IDropTarget, (LPVOID*)&pdt);
718 RegisterDragDrop(This->hWnd, pdt);
719 IDropTarget_Release(pdt);
722 /* register for receiving notifications */
723 hr = IShellFolder_QueryInterface(This->pSFParent, &IID_IPersistFolder2, (LPVOID*)&ppf2);
726 SHChangeNotifyEntry ntreg;
728 hr = IPersistFolder2_GetCurFolder(ppf2, (LPITEMIDLIST*)&ntreg.pidl);
731 ntreg.fRecursive = TRUE;
732 This->hNotify = SHChangeNotifyRegister(This->hWnd, SHCNF_IDLIST, SHCNE_ALLEVENTS,
733 SHV_CHANGE_NOTIFY, 1, &ntreg);
734 SHFree((LPITEMIDLIST)ntreg.pidl);
736 IPersistFolder2_Release(ppf2);
739 This->hAccel = LoadAcceleratorsW(shell32_hInstance, accel_nameW);
744 /**********************************************************
745 * #### Handling of the menus ####
748 /**********************************************************
749 * ShellView_BuildFileMenu()
751 static HMENU ShellView_BuildFileMenu(IShellViewImpl * This)
752 { WCHAR szText[MAX_PATH];
757 TRACE("(%p)\n",This);
759 hSubMenu = CreatePopupMenu();
761 { /*get the number of items in our global array*/
762 for(nTools = 0; Tools[nTools].idCommand != -1; nTools++){}
764 /*add the menu items*/
765 for(i = 0; i < nTools; i++)
767 LoadStringW(shell32_hInstance, Tools[i].idMenuString, szText, MAX_PATH);
769 ZeroMemory(&mii, sizeof(mii));
770 mii.cbSize = sizeof(mii);
771 mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
773 if(BTNS_SEP != Tools[i].bStyle) /* no separator*/
775 mii.fType = MFT_STRING;
776 mii.fState = MFS_ENABLED;
777 mii.dwTypeData = szText;
778 mii.wID = Tools[i].idCommand;
782 mii.fType = MFT_SEPARATOR;
784 /* tack This item onto the end of the menu */
785 InsertMenuItemW(hSubMenu, (UINT)-1, TRUE, &mii);
788 TRACE("-- return (menu=%p)\n",hSubMenu);
791 /**********************************************************
792 * ShellView_MergeFileMenu()
794 static void ShellView_MergeFileMenu(IShellViewImpl *This, HMENU hSubMenu)
796 TRACE("(%p)->(submenu=%p) stub\n",This,hSubMenu);
800 static const WCHAR dummyW[] = {'d','u','m','m','y','4','5',0};
803 /* insert This item at the beginning of the menu */
805 mii.cbSize = sizeof(mii);
806 mii.fMask = MIIM_ID | MIIM_TYPE;
808 mii.fType = MFT_SEPARATOR;
809 InsertMenuItemW(hSubMenu, 0, TRUE, &mii);
811 mii.cbSize = sizeof(mii);
812 mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
813 mii.dwTypeData = (LPWSTR)dummyW;
814 mii.fState = MFS_ENABLED;
815 mii.wID = IDM_MYFILEITEM;
816 mii.fType = MFT_STRING;
817 InsertMenuItemW(hSubMenu, 0, TRUE, &mii);
823 /**********************************************************
824 * ShellView_MergeViewMenu()
827 static void ShellView_MergeViewMenu(IShellViewImpl *This, HMENU hSubMenu)
829 TRACE("(%p)->(submenu=%p)\n",This,hSubMenu);
831 /* add a separator at the correct position in the menu */
834 static const WCHAR menuW[] = {'M','E','N','U','_','0','0','1',0};
835 static const WCHAR viewW[] = {'V','i','e','w',0};
838 memset(&mii, 0, sizeof(mii));
839 mii.cbSize = sizeof(mii);
840 mii.fMask = MIIM_ID | MIIM_TYPE;
842 mii.fType = MFT_SEPARATOR;
843 InsertMenuItemW(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
845 mii.cbSize = sizeof(mii);
846 mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_DATA;
847 mii.fType = MFT_STRING;
848 mii.dwTypeData = (LPWSTR)viewW;
849 mii.hSubMenu = LoadMenuW(shell32_hInstance, menuW);
850 InsertMenuItemW(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
854 /**********************************************************
855 * ShellView_GetSelections()
857 * - fills the this->apidl list with the selected objects
860 * number of selected items
862 static UINT ShellView_GetSelections(IShellViewImpl * This)
869 This->cidl = SendMessageW(This->hWndList, LVM_GETSELECTEDCOUNT, 0, 0);
870 This->apidl = SHAlloc(This->cidl * sizeof(LPITEMIDLIST));
872 TRACE("selected=%i\n", This->cidl);
876 TRACE("-- Items selected =%u\n", This->cidl);
878 lvItem.mask = LVIF_STATE | LVIF_PARAM;
879 lvItem.stateMask = LVIS_SELECTED;
883 while(ListView_GetItemW(This->hWndList, &lvItem) && (i < This->cidl))
885 if(lvItem.state & LVIS_SELECTED)
887 This->apidl[i] = (LPITEMIDLIST)lvItem.lParam;
889 TRACE("-- selected Item found\n");
898 /**********************************************************
899 * ShellView_OpenSelectedItems()
901 static HRESULT ShellView_OpenSelectedItems(IShellViewImpl * This)
903 static UINT CF_IDLIST = 0;
905 IDataObject* selection;
909 LPCITEMIDLIST parent_pidl;
910 WCHAR parent_path[MAX_PATH];
911 LPCWSTR parent_dir = NULL;
915 if (0 == ShellView_GetSelections(This))
919 hr = IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl,
920 (LPCITEMIDLIST*)This->apidl, &IID_IDataObject,
921 0, (LPVOID *)&selection);
927 CF_IDLIST = RegisterClipboardFormatW(CFSTR_SHELLIDLISTW);
929 fetc.cfFormat = CF_IDLIST;
931 fetc.dwAspect = DVASPECT_CONTENT;
933 fetc.tymed = TYMED_HGLOBAL;
935 hr = IDataObject_QueryGetData(selection, &fetc);
939 hr = IDataObject_GetData(selection, &fetc, &stgm);
943 pIDList = GlobalLock(stgm.u.hGlobal);
945 parent_pidl = (LPCITEMIDLIST) ((LPBYTE)pIDList+pIDList->aoffset[0]);
946 hr = IShellFolder_GetAttributesOf(This->pSFParent, 1, &parent_pidl, &attribs);
947 if (SUCCEEDED(hr) && (attribs & SFGAO_FILESYSTEM) &&
948 SHGetPathFromIDListW(parent_pidl, parent_path))
950 parent_dir = parent_path;
953 for (i = pIDList->cidl; i > 0; --i)
957 pidl = (LPCITEMIDLIST)((LPBYTE)pIDList+pIDList->aoffset[i]);
959 attribs = SFGAO_FOLDER;
960 hr = IShellFolder_GetAttributesOf(This->pSFParent, 1, &pidl, &attribs);
962 if (SUCCEEDED(hr) && ! (attribs & SFGAO_FOLDER))
964 SHELLEXECUTEINFOW shexinfo;
966 shexinfo.cbSize = sizeof(SHELLEXECUTEINFOW);
967 shexinfo.fMask = SEE_MASK_INVOKEIDLIST; /* SEE_MASK_IDLIST is also possible. */
968 shexinfo.hwnd = NULL;
969 shexinfo.lpVerb = NULL;
970 shexinfo.lpFile = NULL;
971 shexinfo.lpParameters = NULL;
972 shexinfo.lpDirectory = parent_dir;
973 shexinfo.nShow = SW_NORMAL;
974 shexinfo.lpIDList = ILCombine(parent_pidl, pidl);
976 ShellExecuteExW(&shexinfo); /* Discard error/success info */
978 ILFree(shexinfo.lpIDList);
982 GlobalUnlock(stgm.u.hGlobal);
983 ReleaseStgMedium(&stgm);
985 IDataObject_Release(selection);
990 /**********************************************************
991 * ShellView_DoContextMenu()
993 static void ShellView_DoContextMenu(IShellViewImpl * This, WORD x, WORD y, BOOL bDefault)
997 BOOL fExplore = FALSE;
999 LPCONTEXTMENU pContextMenu = NULL;
1000 IContextMenu2 *pCM = NULL;
1001 CMINVOKECOMMANDINFO cmi;
1003 TRACE("(%p)->(0x%08x 0x%08x 0x%08x) stub\n",This, x, y, bDefault);
1005 /* look, what's selected and create a context menu object of it*/
1006 if( ShellView_GetSelections(This) )
1008 IShellFolder_GetUIObjectOf( This->pSFParent, This->hWndParent, This->cidl, (LPCITEMIDLIST*)This->apidl,
1009 &IID_IContextMenu, NULL, (LPVOID *)&pContextMenu);
1013 TRACE("-- pContextMenu\n");
1014 hMenu = CreatePopupMenu();
1018 /* See if we are in Explore or Open mode. If the browser's tree is present, we are in Explore mode.*/
1019 if(SUCCEEDED(IShellBrowser_GetControlWindow(This->pShellBrowser,FCW_TREE, &hwndTree)) && hwndTree)
1021 TRACE("-- explore mode\n");
1025 /* build the flags depending on what we can do with the selected item */
1026 wFlags = CMF_NORMAL | (This->cidl != 1 ? 0 : CMF_CANRENAME) | (fExplore ? CMF_EXPLORE : 0);
1028 /* let the ContextMenu merge its items in */
1029 if (SUCCEEDED(IContextMenu_QueryContextMenu( pContextMenu, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, wFlags )))
1031 if (This->FolderSettings.fFlags & FWF_DESKTOP)
1032 SetMenuDefaultItem(hMenu, FCIDM_SHVIEW_OPEN, MF_BYCOMMAND);
1036 TRACE("-- get menu default command\n");
1037 uCommand = GetMenuDefaultItem(hMenu, FALSE, GMDI_GOINTOPOPUPS);
1041 TRACE("-- track popup\n");
1042 uCommand = TrackPopupMenu( hMenu,TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
1047 TRACE("-- uCommand=%u\n", uCommand);
1048 if (uCommand==FCIDM_SHVIEW_OPEN && IsInCommDlg(This))
1050 TRACE("-- dlg: OnDefaultCommand\n");
1051 if (OnDefaultCommand(This) != S_OK)
1053 ShellView_OpenSelectedItems(This);
1058 TRACE("-- explore -- invoke command\n");
1059 ZeroMemory(&cmi, sizeof(cmi));
1060 cmi.cbSize = sizeof(cmi);
1061 cmi.hwnd = This->hWndParent; /* this window has to answer CWM_GETISHELLBROWSER */
1062 cmi.lpVerb = MAKEINTRESOURCEA(uCommand);
1063 IContextMenu_InvokeCommand(pContextMenu, &cmi);
1070 IContextMenu_Release(pContextMenu);
1073 else /* background context menu */
1075 hMenu = CreatePopupMenu();
1077 pCM = ISvBgCm_Constructor(This->pSFParent, FALSE);
1078 IContextMenu2_QueryContextMenu(pCM, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, 0);
1080 uCommand = TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
1083 TRACE("-- (%p)->(uCommand=0x%08x )\n",This, uCommand);
1085 ZeroMemory(&cmi, sizeof(cmi));
1086 cmi.cbSize = sizeof(cmi);
1087 cmi.lpVerb = MAKEINTRESOURCEA(uCommand);
1088 cmi.hwnd = This->hWndParent;
1089 IContextMenu2_InvokeCommand(pCM, &cmi);
1091 IContextMenu2_Release(pCM);
1095 /**********************************************************
1096 * ##### message handling #####
1099 /**********************************************************
1100 * ShellView_OnSize()
1102 static LRESULT ShellView_OnSize(IShellViewImpl * This, WORD wWidth, WORD wHeight)
1104 TRACE("%p width=%u height=%u\n",This, wWidth,wHeight);
1106 /*resize the ListView to fit our window*/
1109 MoveWindow(This->hWndList, 0, 0, wWidth, wHeight, TRUE);
1114 /**********************************************************
1115 * ShellView_OnDeactivate()
1120 static void ShellView_OnDeactivate(IShellViewImpl * This)
1124 if(This->uState != SVUIA_DEACTIVATE)
1128 IShellBrowser_SetMenuSB(This->pShellBrowser,0, 0, 0);
1129 IShellBrowser_RemoveMenusSB(This->pShellBrowser,This->hMenu);
1130 DestroyMenu(This->hMenu);
1134 This->uState = SVUIA_DEACTIVATE;
1138 /**********************************************************
1139 * ShellView_OnActivate()
1141 static LRESULT ShellView_OnActivate(IShellViewImpl *This, UINT uState)
1143 OLEMENUGROUPWIDTHS omw = { {0, 0, 0, 0, 0, 0} };
1146 TRACE("(%p) uState=%x\n",This,uState);
1148 /* don't do anything if the state isn't really changing */
1149 if (This->uState == uState) return S_OK;
1151 ShellView_OnDeactivate(This);
1153 /* only do This if we are active */
1154 if (uState != SVUIA_DEACTIVATE)
1156 /* merge the menus */
1157 This->hMenu = CreateMenu();
1161 static const WCHAR dummyW[] = {'d','u','m','m','y',' ','3','1',0};
1163 IShellBrowser_InsertMenusSB(This->pShellBrowser, This->hMenu, &omw);
1164 TRACE("-- after fnInsertMenusSB\n");
1166 mii.cbSize = sizeof(mii);
1167 mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_STATE;
1168 mii.fType = MFT_STRING;
1169 mii.fState = MFS_ENABLED;
1171 mii.hSubMenu = ShellView_BuildFileMenu(This);
1172 mii.hbmpChecked = NULL;
1173 mii.hbmpUnchecked = NULL;
1175 /* build the top level menu get the menu item's text */
1176 mii.dwTypeData = (LPWSTR)dummyW;
1178 mii.hbmpItem = NULL;
1180 /* insert our menu into the menu bar */
1182 InsertMenuItemW(This->hMenu, FCIDM_MENU_HELP, FALSE, &mii);
1184 /* get the view menu so we can merge with it */
1185 memset(&mii, 0, sizeof(mii));
1186 mii.cbSize = sizeof(mii);
1187 mii.fMask = MIIM_SUBMENU;
1189 if (GetMenuItemInfoW(This->hMenu, FCIDM_MENU_VIEW, FALSE, &mii))
1190 ShellView_MergeViewMenu(This, mii.hSubMenu);
1192 /* add the items that should only be added if we have the focus */
1193 if (SVUIA_ACTIVATE_FOCUS == uState)
1195 /* get the file menu so we can merge with it */
1196 memset(&mii, 0, sizeof(mii));
1197 mii.cbSize = sizeof(mii);
1198 mii.fMask = MIIM_SUBMENU;
1200 if (GetMenuItemInfoW(This->hMenu, FCIDM_MENU_FILE, FALSE, &mii))
1201 ShellView_MergeFileMenu(This, mii.hSubMenu);
1204 TRACE("-- before fnSetMenuSB\n");
1205 IShellBrowser_SetMenuSB(This->pShellBrowser, This->hMenu, 0, This->hWnd);
1208 This->uState = uState;
1213 /**********************************************************
1214 * ShellView_OnSetFocus()
1217 static LRESULT ShellView_OnSetFocus(IShellViewImpl * This)
1221 /* Tell the browser one of our windows has received the focus. This
1222 should always be done before merging menus (OnActivate merges the
1223 menus) if one of our windows has the focus.*/
1225 IShellBrowser_OnViewWindowActive(This->pShellBrowser,(IShellView*) This);
1226 ShellView_OnActivate(This, SVUIA_ACTIVATE_FOCUS);
1228 /* Set the focus to the listview */
1229 SetFocus(This->hWndList);
1231 /* Notify the ICommDlgBrowser interface */
1232 OnStateChange(This,CDBOSC_SETFOCUS);
1237 /**********************************************************
1238 * ShellView_OnKillFocus()
1240 static LRESULT ShellView_OnKillFocus(IShellViewImpl * This)
1242 TRACE("(%p) stub\n",This);
1244 ShellView_OnActivate(This, SVUIA_ACTIVATE_NOFOCUS);
1245 /* Notify the ICommDlgBrowser */
1246 OnStateChange(This,CDBOSC_KILLFOCUS);
1251 /**********************************************************
1252 * ShellView_OnCommand()
1255 * the CmdID's are the ones from the context menu
1257 static LRESULT ShellView_OnCommand(IShellViewImpl * This,DWORD dwCmdID, DWORD dwCmd, HWND hwndCmd)
1259 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n",This, dwCmdID, dwCmd, hwndCmd);
1263 case FCIDM_SHVIEW_SMALLICON:
1264 This->FolderSettings.ViewMode = FVM_SMALLICON;
1265 SetStyle (This, LVS_SMALLICON, LVS_TYPEMASK);
1269 case FCIDM_SHVIEW_BIGICON:
1270 This->FolderSettings.ViewMode = FVM_ICON;
1271 SetStyle (This, LVS_ICON, LVS_TYPEMASK);
1275 case FCIDM_SHVIEW_LISTVIEW:
1276 This->FolderSettings.ViewMode = FVM_LIST;
1277 SetStyle (This, LVS_LIST, LVS_TYPEMASK);
1281 case FCIDM_SHVIEW_REPORTVIEW:
1282 This->FolderSettings.ViewMode = FVM_DETAILS;
1283 SetStyle (This, LVS_REPORT, LVS_TYPEMASK);
1287 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1292 This->ListViewSortInfo.nHeaderID = dwCmdID - 0x30;
1293 This->ListViewSortInfo.bIsAscending = TRUE;
1294 This->ListViewSortInfo.nLastHeaderID = This->ListViewSortInfo.nHeaderID;
1295 SendMessageW(This->hWndList, LVM_SORTITEMS, (WPARAM) &This->ListViewSortInfo, (LPARAM)ShellView_ListViewCompareItems);
1299 TRACE("-- COMMAND 0x%04x unhandled\n", dwCmdID);
1304 /**********************************************************
1305 * ShellView_OnNotify()
1308 static LRESULT ShellView_OnNotify(IShellViewImpl * This, UINT CtlID, LPNMHDR lpnmh)
1309 { LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)lpnmh;
1310 NMLVDISPINFOW *lpdi = (NMLVDISPINFOW *)lpnmh;
1313 TRACE("%p CtlID=%u lpnmh->code=%x\n",This,CtlID,lpnmh->code);
1318 TRACE("-- NM_SETFOCUS %p\n",This);
1319 ShellView_OnSetFocus(This);
1323 TRACE("-- NM_KILLFOCUS %p\n",This);
1324 ShellView_OnDeactivate(This);
1325 /* Notify the ICommDlgBrowser interface */
1326 OnStateChange(This,CDBOSC_KILLFOCUS);
1330 TRACE("-- NM_CUSTOMDRAW %p\n",This);
1331 return CDRF_DODEFAULT;
1333 case NM_RELEASEDCAPTURE:
1334 TRACE("-- NM_RELEASEDCAPTURE %p\n",This);
1338 TRACE("-- NM_CLICK %p\n",This);
1342 TRACE("-- NM_RCLICK %p\n",This);
1346 TRACE("-- NM_DBLCLK %p\n",This);
1347 if (OnDefaultCommand(This) != S_OK) ShellView_OpenSelectedItems(This);
1351 TRACE("-- NM_RETURN %p\n",This);
1352 if (OnDefaultCommand(This) != S_OK) ShellView_OpenSelectedItems(This);
1356 TRACE("-- HDN_ENDTRACKW %p\n",This);
1357 /*nColumn1 = ListView_GetColumnWidth(This->hWndList, 0);
1358 nColumn2 = ListView_GetColumnWidth(This->hWndList, 1);*/
1361 case LVN_DELETEITEM:
1362 TRACE("-- LVN_DELETEITEM %p\n",This);
1363 SHFree((LPITEMIDLIST)lpnmlv->lParam); /*delete the pidl because we made a copy of it*/
1366 case LVN_DELETEALLITEMS:
1367 TRACE("-- LVN_DELETEALLITEMS %p\n",This);
1370 case LVN_INSERTITEM:
1371 TRACE("-- LVN_INSERTITEM (STUB)%p\n",This);
1374 case LVN_ITEMACTIVATE:
1375 TRACE("-- LVN_ITEMACTIVATE %p\n",This);
1376 OnStateChange(This, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
1379 case LVN_COLUMNCLICK:
1380 This->ListViewSortInfo.nHeaderID = lpnmlv->iSubItem;
1381 if(This->ListViewSortInfo.nLastHeaderID == This->ListViewSortInfo.nHeaderID)
1383 This->ListViewSortInfo.bIsAscending = !This->ListViewSortInfo.bIsAscending;
1387 This->ListViewSortInfo.bIsAscending = TRUE;
1389 This->ListViewSortInfo.nLastHeaderID = This->ListViewSortInfo.nHeaderID;
1391 SendMessageW(lpnmlv->hdr.hwndFrom, LVM_SORTITEMS, (WPARAM) &This->ListViewSortInfo, (LPARAM)ShellView_ListViewCompareItems);
1394 case LVN_GETDISPINFOA:
1395 case LVN_GETDISPINFOW:
1396 TRACE("-- LVN_GETDISPINFO %p\n",This);
1397 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1399 if(lpdi->item.mask & LVIF_TEXT) /* text requested */
1401 static WCHAR emptyW[] = { 0 };
1405 if (This->pSF2Parent)
1407 hr = IShellFolder2_GetDetailsOf(This->pSF2Parent, pidl, lpdi->item.iSubItem, &sd);
1411 IShellDetails *details;
1413 hr = IShellFolder_QueryInterface(This->pSFParent, &IID_IShellDetails, (void**)&details);
1416 hr = IShellDetails_GetDetailsOf(details, pidl, lpdi->item.iSubItem, &sd);
1417 IShellDetails_Release(details);
1420 WARN("IShellFolder2/IShellDetails not supported\n");
1425 /* set to empty on failure */
1426 sd.str.uType = STRRET_WSTR;
1427 sd.str.u.pOleStr = emptyW;
1430 if (lpnmh->code == LVN_GETDISPINFOW)
1432 StrRetToStrNW( lpdi->item.pszText, lpdi->item.cchTextMax, &sd.str, NULL);
1433 TRACE("-- text=%s\n", debugstr_w(lpdi->item.pszText));
1437 /* LVN_GETDISPINFOA - shouldn't happen */
1438 NMLVDISPINFOA *lpdiA = (NMLVDISPINFOA *)lpnmh;
1439 StrRetToStrNA( lpdiA->item.pszText, lpdiA->item.cchTextMax, &sd.str, NULL);
1440 TRACE("-- text=%s\n", lpdiA->item.pszText);
1444 if(lpdi->item.mask & LVIF_IMAGE) /* image requested */
1446 lpdi->item.iImage = SHMapPIDLToSystemImageListIndex(This->pSFParent, pidl, 0);
1450 case LVN_ITEMCHANGED:
1451 TRACE("-- LVN_ITEMCHANGED %p\n",This);
1452 OnStateChange(This, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
1456 case LVN_BEGINRDRAG:
1457 TRACE("-- LVN_BEGINDRAG\n");
1459 if (ShellView_GetSelections(This))
1462 DWORD dwAttributes = SFGAO_CANLINK;
1463 DWORD dwEffect = DROPEFFECT_COPY | DROPEFFECT_MOVE;
1465 if (SUCCEEDED(IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, (LPCITEMIDLIST*)This->apidl, &IID_IDataObject,0,(LPVOID *)&pda)))
1467 IDropSource * pds = (IDropSource*)&(This->lpvtblDropSource); /* own DropSource interface */
1469 if (SUCCEEDED(IShellFolder_GetAttributesOf(This->pSFParent, This->cidl, (LPCITEMIDLIST*)This->apidl, &dwAttributes)))
1471 if (dwAttributes & SFGAO_CANLINK)
1473 dwEffect |= DROPEFFECT_LINK;
1480 DoDragDrop(pda, pds, dwEffect, &dwEffect2);
1482 IDataObject_Release(pda);
1487 case LVN_BEGINLABELEDITW:
1489 DWORD dwAttr = SFGAO_CANRENAME;
1490 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1492 TRACE("-- LVN_BEGINLABELEDITW %p\n",This);
1494 IShellFolder_GetAttributesOf(This->pSFParent, 1, (LPCITEMIDLIST*)&pidl, &dwAttr);
1495 if (SFGAO_CANRENAME & dwAttr)
1502 case LVN_ENDLABELEDITW:
1504 TRACE("-- LVN_ENDLABELEDITA %p\n",This);
1505 if (lpdi->item.pszText)
1510 lvItem.iItem = lpdi->item.iItem;
1511 lvItem.iSubItem = 0;
1512 lvItem.mask = LVIF_PARAM;
1513 SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem);
1515 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1516 hr = IShellFolder_SetNameOf(This->pSFParent, 0, pidl, lpdi->item.pszText, SHGDN_INFOLDER, &pidl);
1518 if(SUCCEEDED(hr) && pidl)
1520 lvItem.mask = LVIF_PARAM;
1521 lvItem.lParam = (LPARAM)pidl;
1522 SendMessageW(This->hWndList, LVM_SETITEMW, 0, (LPARAM) &lvItem);
1531 LPNMLVKEYDOWN plvKeyDown = (LPNMLVKEYDOWN) lpnmh;
1533 /* initiate a rename of the selected file or directory */
1534 switch (plvKeyDown->wVKey)
1538 INT i = SendMessageW(This->hWndList, LVM_GETSELECTEDCOUNT, 0, 0);
1542 /* get selected item */
1543 i = SendMessageW(This->hWndList, LVM_GETNEXTITEM, -1, MAKELPARAM (LVNI_SELECTED, 0));
1545 SendMessageW(This->hWndList, LVM_ENSUREVISIBLE, i, 0);
1546 SendMessageW(This->hWndList, LVM_EDITLABELW, i, 0);
1555 LPITEMIDLIST* pItems;
1559 hr = IShellFolder_QueryInterface(This->pSFParent, &IID_ISFHelper, (void**)&psfhlp);
1560 if (hr != S_OK) return 0;
1562 if(!(count = SendMessageW(This->hWndList, LVM_GETSELECTEDCOUNT, 0, 0)))
1564 ISFHelper_Release(psfhlp);
1568 /* allocate memory for the pidl array */
1569 pItems = HeapAlloc(GetProcessHeap(), 0, sizeof(LPITEMIDLIST) * count);
1571 /* retrieve all selected items */
1577 /* get selected item */
1578 item_index = SendMessageW(This->hWndList, LVM_GETNEXTITEM, item_index,
1579 MAKELPARAM (LVNI_SELECTED, 0));
1580 item.iItem = item_index;
1581 item.mask = LVIF_PARAM;
1582 SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM)&item);
1585 pItems[i] = (LPITEMIDLIST)item.lParam;
1590 /* perform the item deletion */
1591 ISFHelper_DeleteItems(psfhlp, i, (LPCITEMIDLIST*)pItems);
1592 ISFHelper_Release(psfhlp);
1594 /* free pidl array memory */
1595 HeapFree(GetProcessHeap(), 0, pItems);
1600 /* Initiate a refresh */
1601 IShellView_Refresh((IShellView*)This);
1606 LPSHELLBROWSER lpSb;
1607 if((lpSb = (LPSHELLBROWSER)SendMessageW(This->hWndParent, CWM_GETISHELLBROWSER, 0, 0)))
1609 IShellBrowser_BrowseObject(lpSb, NULL, SBSP_PARENT);
1615 FIXME("LVN_KEYDOWN key=0x%08x\n", plvKeyDown->wVKey);
1621 TRACE("-- %p WM_COMMAND %x unhandled\n", This, lpnmh->code);
1627 /**********************************************************
1628 * ShellView_OnChange()
1631 static LRESULT ShellView_OnChange(IShellViewImpl * This, const LPCITEMIDLIST *pidls, LONG event)
1635 TRACE("(%p)->(%p, %p, 0x%08x)\n", This, pidls[0], pidls[1], event);
1641 LV_AddItem(This, pidls[0]);
1646 INT i = LV_FindItemByPidl(This, ILFindLastID(pidls[0]));
1647 ret = SendMessageW(This->hWndList, LVM_DELETEITEM, i, 0);
1650 case SHCNE_RENAMEFOLDER:
1651 case SHCNE_RENAMEITEM:
1652 LV_RenameItem(This, pidls[0], pidls[1]);
1654 case SHCNE_UPDATEITEM:
1659 /**********************************************************
1663 static LRESULT CALLBACK ShellView_WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
1665 IShellViewImpl * pThis = (IShellViewImpl*)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
1666 LPCREATESTRUCTW lpcs;
1668 TRACE("(hwnd=%p msg=%x wparm=%lx lparm=%lx)\n",hWnd, uMessage, wParam, lParam);
1673 lpcs = (LPCREATESTRUCTW)lParam;
1674 pThis = lpcs->lpCreateParams;
1675 SetWindowLongPtrW(hWnd, GWLP_USERDATA, (ULONG_PTR)pThis);
1676 pThis->hWnd = hWnd; /*set the window handle*/
1679 case WM_SIZE: return ShellView_OnSize(pThis,LOWORD(lParam), HIWORD(lParam));
1680 case WM_SETFOCUS: return ShellView_OnSetFocus(pThis);
1681 case WM_KILLFOCUS: return ShellView_OnKillFocus(pThis);
1682 case WM_CREATE: return ShellView_OnCreate(pThis);
1683 case WM_ACTIVATE: return ShellView_OnActivate(pThis, SVUIA_ACTIVATE_FOCUS);
1684 case WM_NOTIFY: return ShellView_OnNotify(pThis,(UINT)wParam, (LPNMHDR)lParam);
1685 case WM_COMMAND: return ShellView_OnCommand(pThis,
1686 GET_WM_COMMAND_ID(wParam, lParam),
1687 GET_WM_COMMAND_CMD(wParam, lParam),
1688 GET_WM_COMMAND_HWND(wParam, lParam));
1689 case SHV_CHANGE_NOTIFY: return ShellView_OnChange(pThis, (const LPCITEMIDLIST*)wParam, (LONG)lParam);
1691 case WM_CONTEXTMENU: ShellView_DoContextMenu(pThis, LOWORD(lParam), HIWORD(lParam), FALSE);
1694 case WM_SHOWWINDOW: UpdateWindow(pThis->hWndList);
1697 case WM_GETDLGCODE: return SendMessageW(pThis->hWndList, uMessage, 0, 0);
1700 RevokeDragDrop(pThis->hWnd);
1701 SHChangeNotifyDeregister(pThis->hNotify);
1705 if ((pThis->FolderSettings.fFlags & FWF_DESKTOP) ||
1706 (pThis->FolderSettings.fFlags & FWF_TRANSPARENT))
1711 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
1713 /**********************************************************
1716 * The INTERFACE of the IShellView object
1719 **********************************************************
1720 * IShellView_QueryInterface
1722 static HRESULT WINAPI IShellView_fnQueryInterface(IShellView2 * iface,REFIID riid, LPVOID *ppvObj)
1724 IShellViewImpl *This = (IShellViewImpl *)iface;
1726 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1730 if(IsEqualIID(riid, &IID_IUnknown))
1734 else if(IsEqualIID(riid, &IID_IShellView))
1738 else if(IsEqualIID(riid, &IID_IShellView2))
1742 else if(IsEqualIID(riid, &IID_IShellFolderView))
1744 *ppvObj = &This->lpvtblShellFolderView;
1746 else if(IsEqualIID(riid, &IID_IFolderView))
1748 *ppvObj = &This->lpvtblFolderView;
1750 else if(IsEqualIID(riid, &IID_IOleCommandTarget))
1752 *ppvObj = &This->lpvtblOleCommandTarget;
1754 else if(IsEqualIID(riid, &IID_IDropTarget))
1756 *ppvObj = &This->lpvtblDropTarget;
1758 else if(IsEqualIID(riid, &IID_IDropSource))
1760 *ppvObj = &This->lpvtblDropSource;
1762 else if(IsEqualIID(riid, &IID_IViewObject))
1764 *ppvObj = &This->lpvtblViewObject;
1769 IUnknown_AddRef( (IUnknown*)*ppvObj );
1770 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1773 TRACE("-- Interface: E_NOINTERFACE\n");
1774 return E_NOINTERFACE;
1777 /**********************************************************
1780 static ULONG WINAPI IShellView_fnAddRef(IShellView2 * iface)
1782 IShellViewImpl *This = (IShellViewImpl *)iface;
1783 ULONG refCount = InterlockedIncrement(&This->ref);
1785 TRACE("(%p)->(count=%u)\n", This, refCount - 1);
1789 /**********************************************************
1790 * IShellView_Release
1792 static ULONG WINAPI IShellView_fnRelease(IShellView2 * iface)
1794 IShellViewImpl *This = (IShellViewImpl *)iface;
1795 ULONG refCount = InterlockedDecrement(&This->ref);
1797 TRACE("(%p)->(count=%i)\n", This, refCount + 1);
1801 TRACE(" destroying IShellView(%p)\n",This);
1803 DestroyWindow(This->hWndList);
1806 IShellFolder_Release(This->pSFParent);
1808 if(This->pSF2Parent)
1809 IShellFolder2_Release(This->pSF2Parent);
1811 SHFree(This->apidl);
1814 IAdviseSink_Release(This->pAdvSink);
1816 HeapFree(GetProcessHeap(),0,This);
1821 /**********************************************************
1822 * ShellView_GetWindow
1824 static HRESULT WINAPI IShellView_fnGetWindow(IShellView2 * iface,HWND * phWnd)
1826 IShellViewImpl *This = (IShellViewImpl *)iface;
1828 TRACE("(%p)\n",This);
1830 *phWnd = This->hWnd;
1835 static HRESULT WINAPI IShellView_fnContextSensitiveHelp(IShellView2 *iface, BOOL mode)
1837 IShellViewImpl *This = (IShellViewImpl *)iface;
1838 TRACE("(%p)->(%d)\n", This, mode);
1842 /**********************************************************
1843 * IShellView_TranslateAccelerator
1846 * use the accel functions
1848 static HRESULT WINAPI IShellView_fnTranslateAccelerator(IShellView2 * iface,LPMSG lpmsg)
1851 IShellViewImpl *This = (IShellViewImpl *)iface;
1853 FIXME("(%p)->(%p: hwnd=%x msg=%x lp=%x wp=%x) stub\n",This,lpmsg, lpmsg->hwnd, lpmsg->message, lpmsg->lParam, lpmsg->wParam);
1856 if ((lpmsg->message>=WM_KEYFIRST) && (lpmsg->message>=WM_KEYLAST))
1858 TRACE("-- key=0x04%lx\n",lpmsg->wParam) ;
1860 return S_FALSE; /* not handled */
1863 static HRESULT WINAPI IShellView_fnEnableModeless(IShellView2 * iface,BOOL fEnable)
1865 IShellViewImpl *This = (IShellViewImpl *)iface;
1867 FIXME("(%p) stub\n",This);
1872 static HRESULT WINAPI IShellView_fnUIActivate(IShellView2 * iface,UINT uState)
1874 IShellViewImpl *This = (IShellViewImpl *)iface;
1877 CHAR szName[MAX_PATH];
1880 int nPartArray[1] = {-1};
1882 TRACE("(%p)->(state=%x) stub\n",This, uState);
1884 /*don't do anything if the state isn't really changing*/
1885 if(This->uState == uState)
1890 /*OnActivate handles the menu merging and internal state*/
1891 ShellView_OnActivate(This, uState);
1893 /*only do This if we are active*/
1894 if(uState != SVUIA_DEACTIVATE)
1898 GetFolderPath is not a method of IShellFolder
1899 IShellFolder_GetFolderPath( This->pSFParent, szName, sizeof(szName) );
1901 /* set the number of parts */
1902 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETPARTS, 1,
1903 (LPARAM)nPartArray, &lResult);
1905 /* set the text for the parts */
1907 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETTEXTA,
1908 0, (LPARAM)szName, &lResult);
1915 static HRESULT WINAPI IShellView_fnRefresh(IShellView2 * iface)
1917 IShellViewImpl *This = (IShellViewImpl *)iface;
1919 TRACE("(%p)\n", This);
1921 SendMessageW(This->hWndList, LVM_DELETEALLITEMS, 0, 0);
1922 ShellView_FillList(This);
1927 static HRESULT WINAPI IShellView_fnCreateViewWindow(IShellView2 *iface, IShellView *lpPrevView,
1928 LPCFOLDERSETTINGS lpfs, IShellBrowser *psb, RECT *prcView, HWND *phWnd)
1931 SV2CVW2_PARAMS view_params;
1932 view_params.cbSize = sizeof(view_params);
1933 view_params.psvPrev = lpPrevView;
1934 view_params.pfs = lpfs;
1935 view_params.psbOwner = psb;
1936 view_params.prcView = prcView;
1937 view_params.pvid = NULL;
1938 view_params.hwndView = 0;
1940 TRACE("(%p) Forwarding to CreateViewWindow2\n", iface);
1942 hr = IShellView2_CreateViewWindow2(iface, &view_params);
1943 *phWnd = view_params.hwndView;
1948 static HRESULT WINAPI IShellView_fnDestroyViewWindow(IShellView2 * iface)
1950 IShellViewImpl *This = (IShellViewImpl *)iface;
1952 TRACE("(%p)\n",This);
1954 /*Make absolutely sure all our UI is cleaned up.*/
1955 IShellView_UIActivate((IShellView*)This, SVUIA_DEACTIVATE);
1959 DestroyMenu(This->hMenu);
1962 DestroyWindow(This->hWnd);
1963 if(This->pShellBrowser) IShellBrowser_Release(This->pShellBrowser);
1964 if(This->pCommDlgBrowser) ICommDlgBrowser_Release(This->pCommDlgBrowser);
1970 static HRESULT WINAPI IShellView_fnGetCurrentInfo(IShellView2 * iface, LPFOLDERSETTINGS lpfs)
1972 IShellViewImpl *This = (IShellViewImpl *)iface;
1974 TRACE("(%p)->(%p) vmode=%x flags=%x\n",This, lpfs,
1975 This->FolderSettings.ViewMode, This->FolderSettings.fFlags);
1977 if (!lpfs) return E_INVALIDARG;
1979 *lpfs = This->FolderSettings;
1983 static HRESULT WINAPI IShellView_fnAddPropertySheetPages(IShellView2 * iface, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam)
1985 IShellViewImpl *This = (IShellViewImpl *)iface;
1987 FIXME("(%p) stub\n",This);
1992 static HRESULT WINAPI IShellView_fnSaveViewState(IShellView2 * iface)
1994 IShellViewImpl *This = (IShellViewImpl *)iface;
1996 FIXME("(%p) stub\n",This);
2001 static HRESULT WINAPI IShellView_fnSelectItem(
2002 IShellView2 * iface,
2006 IShellViewImpl *This = (IShellViewImpl *)iface;
2007 IFolderView *view = (IFolderView*)&This->lpvtblFolderView;
2010 TRACE("(%p)->(pidl=%p, 0x%08x)\n",This, pidl, flags);
2012 i = LV_FindItemByPidl(This, pidl);
2013 if (i == -1) return S_OK;
2015 return IFolderView_SelectItem(view, i, flags);
2018 static HRESULT WINAPI IShellView_fnGetItemObject(IShellView2 * iface, UINT uItem, REFIID riid, LPVOID *ppvOut)
2020 IShellViewImpl *This = (IShellViewImpl *)iface;
2021 HRESULT hr = E_NOINTERFACE;
2023 TRACE("(%p)->(0x%08x, %s, %p)\n",This, uItem, debugstr_guid(riid), ppvOut);
2029 case SVGIO_BACKGROUND:
2031 if (IsEqualIID(&IID_IContextMenu, riid))
2033 *ppvOut = ISvBgCm_Constructor(This->pSFParent, FALSE);
2037 FIXME("unsupported interface requested %s\n", debugstr_guid(riid));
2041 case SVGIO_SELECTION:
2042 ShellView_GetSelections(This);
2043 hr = IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, (LPCITEMIDLIST*)This->apidl, riid, 0, ppvOut);
2047 FIXME("unimplemented for uItem = 0x%08x\n", uItem);
2049 TRACE("-- (%p)->(interface=%p)\n",This, *ppvOut);
2054 static HRESULT WINAPI IShellView2_fnGetView(IShellView2* iface, SHELLVIEWID *view_guid, ULONG view_type)
2056 FIXME("(%p)->(view_guid %s, view_type %#x) stub!\n", iface, debugstr_guid(view_guid), view_type);
2060 static HRESULT WINAPI IShellView2_fnCreateViewWindow2(IShellView2* iface, LPSV2CVW2_PARAMS view_params)
2062 IShellViewImpl *This = (IShellViewImpl *)iface;
2067 TRACE("(%p)->(view_params %p)\n", iface, view_params);
2069 if (view_params->cbSize != sizeof(*view_params))
2071 FIXME("Got unexpected cbSize %#x\n", view_params->cbSize);
2075 TRACE("-- psvPrev %p, pfs %p, psbOwner %p, prcView %p\n",
2076 view_params->psvPrev, view_params->pfs, view_params->psbOwner, view_params->prcView);
2077 TRACE("-- vmode %#x, flags %#x, left %d, top %d, right %d, bottom %d\n",
2078 view_params->pfs->ViewMode, view_params->pfs->fFlags, view_params->prcView->left,
2079 view_params->prcView->top, view_params->prcView->right, view_params->prcView->bottom);
2081 if (!view_params->psbOwner) return E_UNEXPECTED;
2083 /* Set up the member variables */
2084 This->pShellBrowser = view_params->psbOwner;
2085 This->FolderSettings = *view_params->pfs;
2087 if (view_params->pvid)
2089 if (IsEqualGUID(view_params->pvid, &VID_LargeIcons))
2090 This->FolderSettings.ViewMode = FVM_ICON;
2091 else if (IsEqualGUID(view_params->pvid, &VID_SmallIcons))
2092 This->FolderSettings.ViewMode = FVM_SMALLICON;
2093 else if (IsEqualGUID(view_params->pvid, &VID_List))
2094 This->FolderSettings.ViewMode = FVM_LIST;
2095 else if (IsEqualGUID(view_params->pvid, &VID_Details))
2096 This->FolderSettings.ViewMode = FVM_DETAILS;
2097 else if (IsEqualGUID(view_params->pvid, &VID_Thumbnails))
2098 This->FolderSettings.ViewMode = FVM_THUMBNAIL;
2099 else if (IsEqualGUID(view_params->pvid, &VID_Tile))
2100 This->FolderSettings.ViewMode = FVM_TILE;
2101 else if (IsEqualGUID(view_params->pvid, &VID_ThumbStrip))
2102 This->FolderSettings.ViewMode = FVM_THUMBSTRIP;
2104 FIXME("Ignoring unrecognized VID %s\n", debugstr_guid(view_params->pvid));
2107 /* Get our parent window */
2108 IShellBrowser_AddRef(This->pShellBrowser);
2109 IShellBrowser_GetWindow(This->pShellBrowser, &This->hWndParent);
2111 /* Try to get the ICommDlgBrowserInterface, adds a reference !!! */
2112 This->pCommDlgBrowser = NULL;
2113 hr = IShellBrowser_QueryInterface(This->pShellBrowser, &IID_ICommDlgBrowser, (void **)&This->pCommDlgBrowser);
2115 TRACE("-- CommDlgBrowser %p\n", This->pCommDlgBrowser);
2117 /* If our window class has not been registered, then do so */
2118 if (!GetClassInfoW(shell32_hInstance, SV_CLASS_NAME, &wc))
2120 wc.style = CS_HREDRAW | CS_VREDRAW;
2121 wc.lpfnWndProc = ShellView_WndProc;
2124 wc.hInstance = shell32_hInstance;
2126 wc.hCursor = LoadCursorW(0, (LPWSTR)IDC_ARROW);
2127 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
2128 wc.lpszMenuName = NULL;
2129 wc.lpszClassName = SV_CLASS_NAME;
2131 if (!RegisterClassW(&wc)) return E_FAIL;
2134 wnd = CreateWindowExW(0, SV_CLASS_NAME, NULL, WS_CHILD | WS_TABSTOP,
2135 view_params->prcView->left, view_params->prcView->top,
2136 view_params->prcView->right - view_params->prcView->left,
2137 view_params->prcView->bottom - view_params->prcView->top,
2138 This->hWndParent, 0, shell32_hInstance, This);
2144 IShellBrowser_Release(This->pShellBrowser);
2148 SetWindowPos(wnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
2151 view_params->hwndView = wnd;
2156 static HRESULT WINAPI IShellView2_fnHandleRename(IShellView2* iface, LPCITEMIDLIST new_pidl)
2158 FIXME("(%p)->(new_pidl %p) stub!\n", iface, new_pidl);
2162 static HRESULT WINAPI IShellView2_fnSelectAndPositionItem(
2168 IShellViewImpl *This = (IShellViewImpl *)iface;
2172 TRACE("(%p)->(item %p, flags %#x, point %p)\n", This, item, flags, point);
2174 hr = IShellView2_QueryInterface(iface, &IID_IFolderView, (void**)&view);
2177 hr = IFolderView_SelectAndPositionItems(view, 1, &item, point, flags);
2178 IFolderView_Release(view);
2184 static const IShellView2Vtbl svvt =
2186 IShellView_fnQueryInterface,
2187 IShellView_fnAddRef,
2188 IShellView_fnRelease,
2189 IShellView_fnGetWindow,
2190 IShellView_fnContextSensitiveHelp,
2191 IShellView_fnTranslateAccelerator,
2192 IShellView_fnEnableModeless,
2193 IShellView_fnUIActivate,
2194 IShellView_fnRefresh,
2195 IShellView_fnCreateViewWindow,
2196 IShellView_fnDestroyViewWindow,
2197 IShellView_fnGetCurrentInfo,
2198 IShellView_fnAddPropertySheetPages,
2199 IShellView_fnSaveViewState,
2200 IShellView_fnSelectItem,
2201 IShellView_fnGetItemObject,
2202 IShellView2_fnGetView,
2203 IShellView2_fnCreateViewWindow2,
2204 IShellView2_fnHandleRename,
2205 IShellView2_fnSelectAndPositionItem,
2209 /**********************************************************
2210 * ISVOleCmdTarget_QueryInterface (IUnknown)
2212 static HRESULT WINAPI ISVOleCmdTarget_QueryInterface(
2213 IOleCommandTarget * iface,
2217 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2219 return IShellView2_QueryInterface((IShellView2*)This, iid, ppvObj);
2222 /**********************************************************
2223 * ISVOleCmdTarget_AddRef (IUnknown)
2225 static ULONG WINAPI ISVOleCmdTarget_AddRef(
2226 IOleCommandTarget * iface)
2228 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2230 return IShellView2_AddRef((IShellView2*)This);
2233 /**********************************************************
2234 * ISVOleCmdTarget_Release (IUnknown)
2236 static ULONG WINAPI ISVOleCmdTarget_Release(
2237 IOleCommandTarget * iface)
2239 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2241 return IShellView2_Release((IShellView2*)This);
2244 /**********************************************************
2245 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2247 static HRESULT WINAPI ISVOleCmdTarget_QueryStatus(
2248 IOleCommandTarget *iface,
2249 const GUID *pguidCmdGroup,
2252 OLECMDTEXT *pCmdText)
2254 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2257 FIXME("(%p)->(%s %d %p %p)\n",
2258 This, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText);
2261 return E_INVALIDARG;
2262 for (i = 0; i < cCmds; i++)
2264 FIXME("\tprgCmds[%d].cmdID = %d\n", i, prgCmds[i].cmdID);
2265 prgCmds[i].cmdf = 0;
2267 return OLECMDERR_E_UNKNOWNGROUP;
2270 /**********************************************************
2271 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2273 * nCmdID is the OLECMDID_* enumeration
2275 static HRESULT WINAPI ISVOleCmdTarget_Exec(
2276 IOleCommandTarget *iface,
2277 const GUID* pguidCmdGroup,
2283 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2285 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2286 This, debugstr_guid(pguidCmdGroup), nCmdID, nCmdexecopt, pvaIn, pvaOut);
2289 return OLECMDERR_E_UNKNOWNGROUP;
2290 if (IsEqualIID(pguidCmdGroup, &CGID_Explorer) &&
2292 (nCmdexecopt == 4) && pvaOut)
2294 if (IsEqualIID(pguidCmdGroup, &CGID_ShellDocView) &&
2299 return OLECMDERR_E_UNKNOWNGROUP;
2302 static const IOleCommandTargetVtbl ctvt =
2304 ISVOleCmdTarget_QueryInterface,
2305 ISVOleCmdTarget_AddRef,
2306 ISVOleCmdTarget_Release,
2307 ISVOleCmdTarget_QueryStatus,
2308 ISVOleCmdTarget_Exec
2311 /**********************************************************
2312 * ISVDropTarget implementation
2315 static HRESULT WINAPI ISVDropTarget_QueryInterface(
2320 IShellViewImpl *This = impl_from_IDropTarget(iface);
2322 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2324 return IShellView2_QueryInterface((IShellView2*)This, riid, ppvObj);
2327 static ULONG WINAPI ISVDropTarget_AddRef( IDropTarget *iface)
2329 IShellViewImpl *This = impl_from_IDropTarget(iface);
2331 TRACE("(%p)->(count=%u)\n",This,This->ref);
2333 return IShellView2_AddRef((IShellView2*)This);
2336 static ULONG WINAPI ISVDropTarget_Release( IDropTarget *iface)
2338 IShellViewImpl *This = impl_from_IDropTarget(iface);
2340 TRACE("(%p)->(count=%u)\n",This,This->ref);
2342 return IShellView2_Release((IShellView2*)This);
2345 /******************************************************************************
2346 * drag_notify_subitem [Internal]
2348 * Figure out the shellfolder object, which is currently under the mouse cursor
2349 * and notify it via the IDropTarget interface.
2352 #define SCROLLAREAWIDTH 20
2354 static HRESULT drag_notify_subitem(IShellViewImpl *This, DWORD grfKeyState, POINTL pt,
2357 LVHITTESTINFO htinfo;
2363 /* Map from global to client coordinates and query the index of the listview-item, which is
2364 * currently under the mouse cursor. */
2367 htinfo.flags = LVHT_ONITEM;
2368 ScreenToClient(This->hWndList, &htinfo.pt);
2369 lResult = SendMessageW(This->hWndList, LVM_HITTEST, 0, (LPARAM)&htinfo);
2371 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2372 GetClientRect(This->hWndList, &clientRect);
2373 if (htinfo.pt.x == This->ptLastMousePos.x && htinfo.pt.y == This->ptLastMousePos.y &&
2374 (htinfo.pt.x < SCROLLAREAWIDTH || htinfo.pt.x > clientRect.right - SCROLLAREAWIDTH ||
2375 htinfo.pt.y < SCROLLAREAWIDTH || htinfo.pt.y > clientRect.bottom - SCROLLAREAWIDTH ))
2377 This->cScrollDelay = (This->cScrollDelay + 1) % 5; /* DragOver is called every 50 ms */
2378 if (This->cScrollDelay == 0) { /* Mouse did hover another 250 ms over the scroll-area */
2379 if (htinfo.pt.x < SCROLLAREAWIDTH)
2380 SendMessageW(This->hWndList, WM_HSCROLL, SB_LINEUP, 0);
2381 if (htinfo.pt.x > clientRect.right - SCROLLAREAWIDTH)
2382 SendMessageW(This->hWndList, WM_HSCROLL, SB_LINEDOWN, 0);
2383 if (htinfo.pt.y < SCROLLAREAWIDTH)
2384 SendMessageW(This->hWndList, WM_VSCROLL, SB_LINEUP, 0);
2385 if (htinfo.pt.y > clientRect.bottom - SCROLLAREAWIDTH)
2386 SendMessageW(This->hWndList, WM_VSCROLL, SB_LINEDOWN, 0);
2389 This->cScrollDelay = 0; /* Reset, if the cursor is not over the listview's scroll-area */
2391 This->ptLastMousePos = htinfo.pt;
2393 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2394 if (This->pCurDropTarget && lResult == This->iDragOverItem)
2395 return IDropTarget_DragOver(This->pCurDropTarget, grfKeyState, pt, pdwEffect);
2397 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2398 if (This->pCurDropTarget) {
2399 IDropTarget_DragLeave(This->pCurDropTarget);
2400 IDropTarget_Release(This->pCurDropTarget);
2401 This->pCurDropTarget = NULL;
2404 This->iDragOverItem = lResult;
2405 if (lResult == -1) {
2406 /* We are not above one of the listview's subitems. Bind to the parent folder's
2407 * DropTarget interface. */
2408 hr = IShellFolder_QueryInterface(This->pSFParent, &IID_IDropTarget,
2409 (LPVOID*)&This->pCurDropTarget);
2411 /* Query the relative PIDL of the shellfolder object represented by the currently
2412 * dragged over listview-item ... */
2413 lvItem.mask = LVIF_PARAM;
2414 lvItem.iItem = lResult;
2415 lvItem.iSubItem = 0;
2416 SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem);
2418 /* ... and bind pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2419 hr = IShellFolder_GetUIObjectOf(This->pSFParent, This->hWndList, 1,
2420 (LPCITEMIDLIST*)&lvItem.lParam, &IID_IDropTarget, NULL, (LPVOID*)&This->pCurDropTarget);
2423 /* If anything failed, pCurDropTarget should be NULL now, which ought to be a save state. */
2427 /* Notify the item just entered via DragEnter. */
2428 return IDropTarget_DragEnter(This->pCurDropTarget, This->pCurDataObject, grfKeyState, pt, pdwEffect);
2431 static HRESULT WINAPI ISVDropTarget_DragEnter(IDropTarget *iface, IDataObject *pDataObject,
2432 DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
2434 IShellViewImpl *This = impl_from_IDropTarget(iface);
2436 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2437 This->pCurDataObject = pDataObject;
2438 IDataObject_AddRef(pDataObject);
2440 return drag_notify_subitem(This, grfKeyState, pt, pdwEffect);
2443 static HRESULT WINAPI ISVDropTarget_DragOver(IDropTarget *iface, DWORD grfKeyState, POINTL pt,
2446 IShellViewImpl *This = impl_from_IDropTarget(iface);
2447 return drag_notify_subitem(This, grfKeyState, pt, pdwEffect);
2450 static HRESULT WINAPI ISVDropTarget_DragLeave(IDropTarget *iface)
2452 IShellViewImpl *This = impl_from_IDropTarget(iface);
2454 if (This->pCurDropTarget)
2456 IDropTarget_DragLeave(This->pCurDropTarget);
2457 IDropTarget_Release(This->pCurDropTarget);
2458 This->pCurDropTarget = NULL;
2461 if (This->pCurDataObject)
2463 IDataObject_Release(This->pCurDataObject);
2464 This->pCurDataObject = NULL;
2467 This->iDragOverItem = 0;
2472 static HRESULT WINAPI ISVDropTarget_Drop(IDropTarget *iface, IDataObject* pDataObject,
2473 DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
2475 IShellViewImpl *This = impl_from_IDropTarget(iface);
2477 IDropTarget_Drop(This->pCurDropTarget, pDataObject, grfKeyState, pt, pdwEffect);
2479 IDropTarget_Release(This->pCurDropTarget);
2480 IDataObject_Release(This->pCurDataObject);
2481 This->pCurDataObject = NULL;
2482 This->pCurDropTarget = NULL;
2483 This->iDragOverItem = 0;
2488 static const IDropTargetVtbl dtvt =
2490 ISVDropTarget_QueryInterface,
2491 ISVDropTarget_AddRef,
2492 ISVDropTarget_Release,
2493 ISVDropTarget_DragEnter,
2494 ISVDropTarget_DragOver,
2495 ISVDropTarget_DragLeave,
2499 /**********************************************************
2500 * ISVDropSource implementation
2503 static HRESULT WINAPI ISVDropSource_QueryInterface(
2508 IShellViewImpl *This = impl_from_IDropSource(iface);
2510 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2512 return IShellView2_QueryInterface((IShellView2*)This, riid, ppvObj);
2515 static ULONG WINAPI ISVDropSource_AddRef( IDropSource *iface)
2517 IShellViewImpl *This = impl_from_IDropSource(iface);
2519 TRACE("(%p)->(count=%u)\n",This,This->ref);
2521 return IShellView2_AddRef((IShellView2*)This);
2524 static ULONG WINAPI ISVDropSource_Release( IDropSource *iface)
2526 IShellViewImpl *This = impl_from_IDropSource(iface);
2528 TRACE("(%p)->(count=%u)\n",This,This->ref);
2530 return IShellView2_Release((IShellView2*)This);
2533 static HRESULT WINAPI ISVDropSource_QueryContinueDrag(
2535 BOOL fEscapePressed,
2538 IShellViewImpl *This = impl_from_IDropSource(iface);
2539 TRACE("(%p)\n",This);
2542 return DRAGDROP_S_CANCEL;
2543 else if (!(grfKeyState & MK_LBUTTON) && !(grfKeyState & MK_RBUTTON))
2544 return DRAGDROP_S_DROP;
2549 static HRESULT WINAPI ISVDropSource_GiveFeedback(
2553 IShellViewImpl *This = impl_from_IDropSource(iface);
2554 TRACE("(%p)\n",This);
2556 return DRAGDROP_S_USEDEFAULTCURSORS;
2559 static const IDropSourceVtbl dsvt =
2561 ISVDropSource_QueryInterface,
2562 ISVDropSource_AddRef,
2563 ISVDropSource_Release,
2564 ISVDropSource_QueryContinueDrag,
2565 ISVDropSource_GiveFeedback
2567 /**********************************************************
2568 * ISVViewObject implementation
2571 static HRESULT WINAPI ISVViewObject_QueryInterface(
2576 IShellViewImpl *This = impl_from_IViewObject(iface);
2578 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2580 return IShellView2_QueryInterface((IShellView2*)This, riid, ppvObj);
2583 static ULONG WINAPI ISVViewObject_AddRef( IViewObject *iface)
2585 IShellViewImpl *This = impl_from_IViewObject(iface);
2587 TRACE("(%p)->(count=%u)\n",This,This->ref);
2589 return IShellView2_AddRef((IShellView2*)This);
2592 static ULONG WINAPI ISVViewObject_Release( IViewObject *iface)
2594 IShellViewImpl *This = impl_from_IViewObject(iface);
2596 TRACE("(%p)->(count=%u)\n",This,This->ref);
2598 return IShellView2_Release((IShellView2*)This);
2601 static HRESULT WINAPI ISVViewObject_Draw(
2606 DVTARGETDEVICE* ptd,
2609 LPCRECTL lprcBounds,
2610 LPCRECTL lprcWBounds,
2611 BOOL (CALLBACK *pfnContinue)(ULONG_PTR dwContinue),
2612 ULONG_PTR dwContinue)
2615 IShellViewImpl *This = impl_from_IViewObject(iface);
2617 FIXME("Stub: This=%p\n",This);
2621 static HRESULT WINAPI ISVViewObject_GetColorSet(
2626 DVTARGETDEVICE* ptd,
2627 HDC hicTargetDevice,
2628 LOGPALETTE** ppColorSet)
2631 IShellViewImpl *This = impl_from_IViewObject(iface);
2633 FIXME("Stub: This=%p\n",This);
2637 static HRESULT WINAPI ISVViewObject_Freeze(
2645 IShellViewImpl *This = impl_from_IViewObject(iface);
2647 FIXME("Stub: This=%p\n",This);
2651 static HRESULT WINAPI ISVViewObject_Unfreeze(
2656 IShellViewImpl *This = impl_from_IViewObject(iface);
2658 FIXME("Stub: This=%p\n",This);
2662 static HRESULT WINAPI ISVViewObject_SetAdvise(
2666 IAdviseSink* pAdvSink)
2669 IShellViewImpl *This = impl_from_IViewObject(iface);
2671 FIXME("partial stub: %p %08x %08x %p\n",
2672 This, aspects, advf, pAdvSink);
2674 /* FIXME: we set the AdviseSink, but never use it to send any advice */
2675 This->pAdvSink = pAdvSink;
2676 This->dwAspects = aspects;
2677 This->dwAdvf = advf;
2682 static HRESULT WINAPI ISVViewObject_GetAdvise(
2686 IAdviseSink** ppAdvSink)
2689 IShellViewImpl *This = impl_from_IViewObject(iface);
2691 TRACE("This=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n",
2692 This, pAspects, pAdvf, ppAdvSink);
2696 IAdviseSink_AddRef( This->pAdvSink );
2697 *ppAdvSink = This->pAdvSink;
2700 *pAspects = This->dwAspects;
2702 *pAdvf = This->dwAdvf;
2708 static const IViewObjectVtbl vovt =
2710 ISVViewObject_QueryInterface,
2711 ISVViewObject_AddRef,
2712 ISVViewObject_Release,
2714 ISVViewObject_GetColorSet,
2715 ISVViewObject_Freeze,
2716 ISVViewObject_Unfreeze,
2717 ISVViewObject_SetAdvise,
2718 ISVViewObject_GetAdvise
2722 static HRESULT WINAPI IFView_QueryInterface(
2727 IShellViewImpl *This = impl_from_IFolderView(iface);
2728 TRACE("(%p)->(IID:%s,%p)\n", This, debugstr_guid(riid), ppvObj);
2729 return IShellView2_QueryInterface((IShellView2*)This, riid, ppvObj);
2732 static ULONG WINAPI IFView_AddRef( IFolderView *iface)
2734 IShellViewImpl *This = impl_from_IFolderView(iface);
2735 TRACE("(%p)->(count=%u)\n", This, This->ref);
2736 return IShellView2_AddRef((IShellView2*)This);
2739 static ULONG WINAPI IFView_Release( IFolderView *iface)
2741 IShellViewImpl *This = impl_from_IFolderView(iface);
2742 TRACE("(%p)->(count=%u)\n", This, This->ref);
2743 return IShellView2_Release((IShellView2*)This);
2746 static HRESULT WINAPI IFView_GetCurrentViewMode(IFolderView *iface, UINT *mode)
2748 IShellViewImpl *This = impl_from_IFolderView(iface);
2749 TRACE("(%p)->(%p), stub\n", This, mode);
2752 return E_INVALIDARG;
2754 *mode = This->FolderSettings.ViewMode;
2758 static HRESULT WINAPI IFView_SetCurrentViewMode(IFolderView *iface, UINT mode)
2760 IShellViewImpl *This = impl_from_IFolderView(iface);
2762 TRACE("(%p)->(%u), stub\n", This, mode);
2764 if((mode < FVM_FIRST || mode > FVM_LAST) &&
2766 return E_INVALIDARG;
2768 /* Windows before Vista uses LVM_SETVIEW and possibly
2769 LVM_SETEXTENDEDLISTVIEWSTYLE to set the style of the listview,
2770 while later versions seem to accomplish this through other
2772 dwStyle = ViewModeToListStyle(mode);
2773 SetStyle(This, dwStyle, LVS_TYPEMASK);
2775 /* This will not necessarily be the actual mode set above.
2776 This mimics the behavior of Windows XP. */
2777 This->FolderSettings.ViewMode = mode;
2782 static HRESULT WINAPI IFView_GetFolder(IFolderView *iface, REFIID riid, void **ppv)
2784 IShellViewImpl *This = impl_from_IFolderView(iface);
2786 TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv);
2788 if (!ppv) return E_POINTER;
2790 if (IsEqualIID(riid, &IID_IShellFolder))
2792 *ppv = This->pSFParent;
2796 return E_NOINTERFACE;
2799 static HRESULT WINAPI IFView_Item(IFolderView *iface, int index, PITEMID_CHILD *ppidl)
2801 IShellViewImpl *This = impl_from_IFolderView(iface);
2804 TRACE("(%p)->(%d %p)\n", This, index, ppidl);
2806 item.mask = LVIF_PARAM;
2809 if (SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM)&item))
2811 *ppidl = ILClone((PITEMID_CHILD)item.lParam);
2817 return E_INVALIDARG;
2821 static HRESULT WINAPI IFView_ItemCount(IFolderView *iface, UINT flags, int *items)
2823 IShellViewImpl *This = impl_from_IFolderView(iface);
2825 TRACE("(%p)->(%u %p)\n", This, flags, items);
2827 if (flags != SVGIO_ALLVIEW)
2828 FIXME("some flags unsupported, %x\n", flags & ~SVGIO_ALLVIEW);
2830 *items = SendMessageW(This->hWndList, LVM_GETITEMCOUNT, 0, 0);
2835 static HRESULT WINAPI IFView_Items(IFolderView *iface, UINT flags, REFIID riid, void **ppv)
2837 IShellViewImpl *This = impl_from_IFolderView(iface);
2838 FIXME("(%p)->(%u %s %p), stub\n", This, flags, debugstr_guid(riid), ppv);
2842 static HRESULT WINAPI IFView_GetSelectionMarkedItem(IFolderView *iface, int *item)
2844 IShellViewImpl *This = impl_from_IFolderView(iface);
2846 TRACE("(%p)->(%p)\n", This, item);
2848 *item = SendMessageW(This->hWndList, LVM_GETSELECTIONMARK, 0, 0);
2853 static HRESULT WINAPI IFView_GetFocusedItem(IFolderView *iface, int *item)
2855 IShellViewImpl *This = impl_from_IFolderView(iface);
2857 TRACE("(%p)->(%p)\n", This, item);
2859 *item = SendMessageW(This->hWndList, LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
2864 static HRESULT WINAPI IFView_GetItemPosition(IFolderView *iface, PCUITEMID_CHILD pidl, POINT *ppt)
2866 IShellViewImpl *This = impl_from_IFolderView(iface);
2867 FIXME("(%p)->(%p %p), stub\n", This, pidl, ppt);
2871 static HRESULT WINAPI IFView_GetSpacing(IFolderView *iface, POINT *pt)
2873 IShellViewImpl *This = impl_from_IFolderView(iface);
2875 TRACE("(%p)->(%p)\n", This, pt);
2877 if (!This->hWndList) return S_FALSE;
2882 ret = SendMessageW(This->hWndList, LVM_GETITEMSPACING, 0, 0);
2884 pt->x = LOWORD(ret);
2885 pt->y = HIWORD(ret);
2891 static HRESULT WINAPI IFView_GetDefaultSpacing(IFolderView *iface, POINT *pt)
2893 IShellViewImpl *This = impl_from_IFolderView(iface);
2894 FIXME("(%p)->(%p), stub\n", This, pt);
2898 static HRESULT WINAPI IFView_GetAutoArrange(IFolderView *iface)
2900 IShellViewImpl *This = impl_from_IFolderView(iface);
2901 FIXME("(%p), stub\n", This);
2905 static HRESULT WINAPI IFView_SelectItem(IFolderView *iface, int item, DWORD flags)
2907 IShellViewImpl *This = impl_from_IFolderView(iface);
2910 TRACE("(%p)->(%d, %x)\n", This, item, flags);
2913 lvItem.stateMask = LVIS_SELECTED;
2915 if (flags & SVSI_ENSUREVISIBLE)
2916 SendMessageW(This->hWndList, LVM_ENSUREVISIBLE, item, 0);
2919 if (flags & SVSI_DESELECTOTHERS)
2920 SendMessageW(This->hWndList, LVM_SETITEMSTATE, -1, (LPARAM)&lvItem);
2923 if (flags & SVSI_SELECT)
2924 lvItem.state |= LVIS_SELECTED;
2926 if (flags & SVSI_FOCUSED)
2927 lvItem.stateMask |= LVIS_FOCUSED;
2929 SendMessageW(This->hWndList, LVM_SETITEMSTATE, item, (LPARAM)&lvItem);
2931 if (flags & SVSI_EDIT)
2932 SendMessageW(This->hWndList, LVM_EDITLABELW, item, 0);
2937 static HRESULT WINAPI IFView_SelectAndPositionItems(IFolderView *iface, UINT cidl,
2938 PCUITEMID_CHILD_ARRAY apidl, POINT *apt, DWORD flags)
2940 IShellViewImpl *This = impl_from_IFolderView(iface);
2941 FIXME("(%p)->(%u %p %p %x), stub\n", This, cidl, apidl, apt, flags);
2945 static const IFolderViewVtbl fviewvt =
2947 IFView_QueryInterface,
2950 IFView_GetCurrentViewMode,
2951 IFView_SetCurrentViewMode,
2956 IFView_GetSelectionMarkedItem,
2957 IFView_GetFocusedItem,
2958 IFView_GetItemPosition,
2960 IFView_GetDefaultSpacing,
2961 IFView_GetAutoArrange,
2963 IFView_SelectAndPositionItems
2966 /* IShellFolderView */
2967 static HRESULT WINAPI IShellFolderView_fnQueryInterface(
2968 IShellFolderView *iface,
2972 IShellViewImpl *This = impl_from_IShellFolderView(iface);
2973 TRACE("(%p)->(IID:%s,%p)\n", This, debugstr_guid(riid), ppvObj);
2974 return IShellView2_QueryInterface((IShellView2*)This, riid, ppvObj);
2977 static ULONG WINAPI IShellFolderView_fnAddRef(IShellFolderView *iface)
2979 IShellViewImpl *This = impl_from_IShellFolderView(iface);
2980 TRACE("(%p)->(count=%u)\n", This, This->ref);
2981 return IShellView2_AddRef((IShellView2*)This);
2984 static ULONG WINAPI IShellFolderView_fnRelease(IShellFolderView *iface)
2986 IShellViewImpl *This = impl_from_IShellFolderView(iface);
2987 TRACE("(%p)->(count=%u)\n", This, This->ref);
2988 return IShellView2_Release((IShellView2*)This);
2991 static HRESULT WINAPI IShellFolderView_fnRearrange(IShellFolderView *iface, LPARAM sort)
2993 IShellViewImpl *This = impl_from_IShellFolderView(iface);
2994 FIXME("(%p)->(%ld) stub\n", This, sort);
2998 static HRESULT WINAPI IShellFolderView_fnGetArrangeParam(IShellFolderView *iface, LPARAM *sort)
3000 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3001 FIXME("(%p)->(%p) stub\n", This, sort);
3005 static HRESULT WINAPI IShellFolderView_fnArrangeGrid(IShellFolderView *iface)
3007 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3008 FIXME("(%p) stub\n", This);
3012 static HRESULT WINAPI IShellFolderView_fnAutoArrange(IShellFolderView *iface)
3014 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3015 FIXME("(%p) stub\n", This);
3019 static HRESULT WINAPI IShellFolderView_fnGetAutoArrange(IShellFolderView *iface)
3021 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3022 IFolderView *view = (IFolderView*)&This->lpvtblFolderView;
3024 TRACE("(%p)\n", This);
3025 return IFolderView_GetAutoArrange(view);
3028 static HRESULT WINAPI IShellFolderView_fnAddObject(
3029 IShellFolderView *iface,
3033 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3034 FIXME("(%p)->(%p %p) stub\n", This, pidl, item);
3038 static HRESULT WINAPI IShellFolderView_fnGetObject(
3039 IShellFolderView *iface,
3040 PITEMID_CHILD *pidl,
3043 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3044 IFolderView *view = (IFolderView*)&This->lpvtblFolderView;
3046 TRACE("(%p)->(%p %d)\n", This, pidl, item);
3047 return IFolderView_Item(view, item, pidl);
3050 static HRESULT WINAPI IShellFolderView_fnRemoveObject(
3051 IShellFolderView *iface,
3055 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3057 TRACE("(%p)->(%p %p)\n", This, pidl, item);
3061 *item = LV_FindItemByPidl(This, ILFindLastID(pidl));
3062 SendMessageW(This->hWndList, LVM_DELETEITEM, *item, 0);
3067 SendMessageW(This->hWndList, LVM_DELETEALLITEMS, 0, 0);
3073 static HRESULT WINAPI IShellFolderView_fnGetObjectCount(
3074 IShellFolderView *iface,
3077 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3078 IFolderView *view = (IFolderView*)&This->lpvtblFolderView;
3080 TRACE("(%p)->(%p)\n", This, count);
3081 return IFolderView_ItemCount(view, SVGIO_ALLVIEW, (INT*)count);
3084 static HRESULT WINAPI IShellFolderView_fnSetObjectCount(
3085 IShellFolderView *iface,
3089 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3090 FIXME("(%p)->(%d %x) stub\n", This, count, flags);
3094 static HRESULT WINAPI IShellFolderView_fnUpdateObject(
3095 IShellFolderView *iface,
3096 PITEMID_CHILD pidl_old,
3097 PITEMID_CHILD pidl_new,
3100 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3101 FIXME("(%p)->(%p %p %p) stub\n", This, pidl_old, pidl_new, item);
3105 static HRESULT WINAPI IShellFolderView_fnRefreshObject(
3106 IShellFolderView *iface,
3110 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3111 FIXME("(%p)->(%p %p) stub\n", This, pidl, item);
3115 static HRESULT WINAPI IShellFolderView_fnSetRedraw(
3116 IShellFolderView *iface,
3119 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3120 TRACE("(%p)->(%d)\n", This, redraw);
3122 SendMessageW(This->hWndList, WM_SETREDRAW, redraw, 0);
3127 static HRESULT WINAPI IShellFolderView_fnGetSelectedCount(
3128 IShellFolderView *iface,
3131 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3132 FIXME("(%p)->(%p) stub\n", This, count);
3136 static HRESULT WINAPI IShellFolderView_fnGetSelectedObjects(
3137 IShellFolderView *iface,
3138 PCITEMID_CHILD **pidl,
3141 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3143 TRACE("(%p)->(%p %p)\n", This, pidl, items);
3145 *items = ShellView_GetSelections( This );
3149 *pidl = LocalAlloc(0, *items*sizeof(LPITEMIDLIST));
3150 if (!*pidl) return E_OUTOFMEMORY;
3152 /* it's documented that caller shouldn't free PIDLs, only array itself */
3153 memcpy((PITEMID_CHILD*)*pidl, This->apidl, *items*sizeof(LPITEMIDLIST));
3159 static HRESULT WINAPI IShellFolderView_fnIsDropOnSource(
3160 IShellFolderView *iface,
3161 IDropTarget *drop_target)
3163 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3164 FIXME("(%p)->(%p) stub\n", This, drop_target);
3168 static HRESULT WINAPI IShellFolderView_fnGetDragPoint(
3169 IShellFolderView *iface,
3172 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3173 FIXME("(%p)->(%p) stub\n", This, pt);
3177 static HRESULT WINAPI IShellFolderView_fnGetDropPoint(
3178 IShellFolderView *iface,
3181 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3182 FIXME("(%p)->(%p) stub\n", This, pt);
3186 static HRESULT WINAPI IShellFolderView_fnMoveIcons(
3187 IShellFolderView *iface,
3190 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3191 TRACE("(%p)->(%p)\n", This, obj);
3195 static HRESULT WINAPI IShellFolderView_fnSetItemPos(
3196 IShellFolderView *iface,
3197 PCUITEMID_CHILD pidl,
3200 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3201 FIXME("(%p)->(%p %p) stub\n", This, pidl, pt);
3205 static HRESULT WINAPI IShellFolderView_fnIsBkDropTarget(
3206 IShellFolderView *iface,
3207 IDropTarget *drop_target)
3209 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3210 FIXME("(%p)->(%p) stub\n", This, drop_target);
3214 static HRESULT WINAPI IShellFolderView_fnSetClipboard(
3215 IShellFolderView *iface,
3218 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3219 FIXME("(%p)->(%d) stub\n", This, move);
3223 static HRESULT WINAPI IShellFolderView_fnSetPoints(
3224 IShellFolderView *iface,
3227 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3228 FIXME("(%p)->(%p) stub\n", This, obj);
3232 static HRESULT WINAPI IShellFolderView_fnGetItemSpacing(
3233 IShellFolderView *iface,
3234 ITEMSPACING *spacing)
3236 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3237 FIXME("(%p)->(%p) stub\n", This, spacing);
3241 static HRESULT WINAPI IShellFolderView_fnSetCallback(
3242 IShellFolderView *iface,
3243 IShellFolderViewCB *new_cb,
3244 IShellFolderViewCB **old_cb)
3247 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3248 FIXME("(%p)->(%p %p) stub\n", This, new_cb, old_cb);
3252 static HRESULT WINAPI IShellFolderView_fnSelect(
3253 IShellFolderView *iface,
3256 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3257 FIXME("(%p)->(%d) stub\n", This, flags);
3261 static HRESULT WINAPI IShellFolderView_fnQuerySupport(
3262 IShellFolderView *iface,
3265 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3266 TRACE("(%p)->(%p)\n", This, support);
3270 static HRESULT WINAPI IShellFolderView_fnSetAutomationObject(
3271 IShellFolderView *iface,
3274 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3275 FIXME("(%p)->(%p) stub\n", This, disp);
3279 static const IShellFolderViewVtbl shellfolderviewvt =
3281 IShellFolderView_fnQueryInterface,
3282 IShellFolderView_fnAddRef,
3283 IShellFolderView_fnRelease,
3284 IShellFolderView_fnRearrange,
3285 IShellFolderView_fnGetArrangeParam,
3286 IShellFolderView_fnArrangeGrid,
3287 IShellFolderView_fnAutoArrange,
3288 IShellFolderView_fnGetAutoArrange,
3289 IShellFolderView_fnAddObject,
3290 IShellFolderView_fnGetObject,
3291 IShellFolderView_fnRemoveObject,
3292 IShellFolderView_fnGetObjectCount,
3293 IShellFolderView_fnSetObjectCount,
3294 IShellFolderView_fnUpdateObject,
3295 IShellFolderView_fnRefreshObject,
3296 IShellFolderView_fnSetRedraw,
3297 IShellFolderView_fnGetSelectedCount,
3298 IShellFolderView_fnGetSelectedObjects,
3299 IShellFolderView_fnIsDropOnSource,
3300 IShellFolderView_fnGetDragPoint,
3301 IShellFolderView_fnGetDropPoint,
3302 IShellFolderView_fnMoveIcons,
3303 IShellFolderView_fnSetItemPos,
3304 IShellFolderView_fnIsBkDropTarget,
3305 IShellFolderView_fnSetClipboard,
3306 IShellFolderView_fnSetPoints,
3307 IShellFolderView_fnGetItemSpacing,
3308 IShellFolderView_fnSetCallback,
3309 IShellFolderView_fnSelect,
3310 IShellFolderView_fnQuerySupport,
3311 IShellFolderView_fnSetAutomationObject