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
60 #include "undocshell.h"
62 #include "wine/debug.h"
66 #include "shell32_main.h"
67 #include "shellfolder.h"
69 WINE_DEFAULT_DEBUG_CHANNEL(shell);
71 static const WCHAR SV_CLASS_NAME[] = {'S','H','E','L','L','D','L','L','_','D','e','f','V','i','e','w',0};
77 }LISTVIEW_SORT_INFO, *LPLISTVIEW_SORT_INFO;
81 const IShellView2Vtbl* lpVtbl;
83 const IOleCommandTargetVtbl* lpvtblOleCommandTarget;
84 const IDropTargetVtbl* lpvtblDropTarget;
85 const IDropSourceVtbl* lpvtblDropSource;
86 const IViewObjectVtbl* lpvtblViewObject;
87 IShellFolder* pSFParent;
88 IShellFolder2* pSF2Parent;
89 IShellBrowser* pShellBrowser;
90 ICommDlgBrowser* pCommDlgBrowser;
91 HWND hWnd; /* SHELLDLL_DefView */
92 HWND hWndList; /* ListView control */
94 FOLDERSETTINGS FolderSettings;
99 LISTVIEW_SORT_INFO ListViewSortInfo;
100 ULONG hNotify; /* change notification handle */
104 IAdviseSink *pAdvSink;
105 IDropTarget* pCurDropTarget; /* The sub-item, which is currently dragged over */
106 IDataObject* pCurDataObject; /* The dragged data-object */
107 LONG iDragOverItem; /* Dragged over item's index, iff pCurDropTarget != NULL */
108 UINT cScrollDelay; /* Send a WM_*SCROLL msg every 250 ms during drag-scroll */
109 POINT ptLastMousePos; /* Mouse position at last DragOver call */
112 static const IShellView2Vtbl svvt;
113 static const IOleCommandTargetVtbl ctvt;
114 static const IDropTargetVtbl dtvt;
115 static const IDropSourceVtbl dsvt;
116 static const IViewObjectVtbl vovt;
119 static inline IShellViewImpl *impl_from_IOleCommandTarget( IOleCommandTarget *iface )
121 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblOleCommandTarget));
124 static inline IShellViewImpl *impl_from_IDropTarget( IDropTarget *iface )
126 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblDropTarget));
129 static inline IShellViewImpl *impl_from_IDropSource( IDropSource *iface )
131 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblDropSource));
134 static inline IShellViewImpl *impl_from_IViewObject( IViewObject *iface )
136 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblViewObject));
139 /* ListView Header ID's */
140 #define LISTVIEW_COLUMN_NAME 0
141 #define LISTVIEW_COLUMN_SIZE 1
142 #define LISTVIEW_COLUMN_TYPE 2
143 #define LISTVIEW_COLUMN_TIME 3
144 #define LISTVIEW_COLUMN_ATTRIB 4
147 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
148 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
149 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
151 #define ID_LISTVIEW 1
153 #define SHV_CHANGE_NOTIFY WM_USER + 0x1111
156 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
157 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
158 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
161 Items merged into the toolbar and the filemenu
170 } MYTOOLINFO, *LPMYTOOLINFO;
172 static const MYTOOLINFO Tools[] =
174 { FCIDM_SHVIEW_BIGICON, 0, 0, IDS_VIEW_LARGE, TBSTATE_ENABLED, BTNS_BUTTON },
175 { FCIDM_SHVIEW_SMALLICON, 0, 0, IDS_VIEW_SMALL, TBSTATE_ENABLED, BTNS_BUTTON },
176 { FCIDM_SHVIEW_LISTVIEW, 0, 0, IDS_VIEW_LIST, TBSTATE_ENABLED, BTNS_BUTTON },
177 { FCIDM_SHVIEW_REPORTVIEW, 0, 0, IDS_VIEW_DETAILS, TBSTATE_ENABLED, BTNS_BUTTON },
181 typedef void (CALLBACK *PFNSHGETSETTINGSPROC)(LPSHELLFLAGSTATE lpsfs, DWORD dwMask);
183 /**********************************************************
184 * IShellView_Constructor
186 IShellView * IShellView_Constructor( IShellFolder * pFolder)
187 { IShellViewImpl * sv;
188 sv=HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IShellViewImpl));
191 sv->lpvtblOleCommandTarget=&ctvt;
192 sv->lpvtblDropTarget=&dtvt;
193 sv->lpvtblDropSource=&dsvt;
194 sv->lpvtblViewObject=&vovt;
196 sv->pSFParent = pFolder;
197 if(pFolder) IShellFolder_AddRef(pFolder);
198 IShellFolder_QueryInterface(sv->pSFParent, &IID_IShellFolder2, (LPVOID*)&sv->pSF2Parent);
200 sv->pCurDropTarget = NULL;
201 sv->pCurDataObject = NULL;
202 sv->iDragOverItem = 0;
203 sv->cScrollDelay = 0;
204 sv->ptLastMousePos.x = 0;
205 sv->ptLastMousePos.y = 0;
207 TRACE("(%p)->(%p)\n",sv, pFolder);
208 return (IShellView *) sv;
211 /**********************************************************
213 * ##### helperfunctions for communication with ICommDlgBrowser #####
215 static BOOL IsInCommDlg(IShellViewImpl * This)
216 { return(This->pCommDlgBrowser != NULL);
219 static HRESULT IncludeObject(IShellViewImpl * This, LPCITEMIDLIST pidl)
223 if ( IsInCommDlg(This) )
225 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl);
226 ret = ICommDlgBrowser_IncludeObject(This->pCommDlgBrowser, (IShellView*)This, pidl);
227 TRACE("--0x%08x\n", ret);
232 static HRESULT OnDefaultCommand(IShellViewImpl * This)
234 HRESULT ret = S_FALSE;
236 if (IsInCommDlg(This))
238 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
239 ret = ICommDlgBrowser_OnDefaultCommand(This->pCommDlgBrowser, (IShellView*)This);
240 TRACE("-- returns %08x\n", ret);
245 static HRESULT OnStateChange(IShellViewImpl * This, UINT uFlags)
247 HRESULT ret = S_FALSE;
249 if (IsInCommDlg(This))
251 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags);
252 ret = ICommDlgBrowser_OnStateChange(This->pCommDlgBrowser, (IShellView*)This, uFlags);
257 /**********************************************************
258 * set the toolbar of the filedialog buttons
260 * - activates the buttons from the shellbrowser according to
263 static void CheckToolbar(IShellViewImpl * This)
269 if (IsInCommDlg(This))
271 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
272 FCIDM_TB_SMALLICON, (This->FolderSettings.ViewMode==FVM_LIST)? TRUE : FALSE, &result);
273 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
274 FCIDM_TB_REPORTVIEW, (This->FolderSettings.ViewMode==FVM_DETAILS)? TRUE : FALSE, &result);
275 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
276 FCIDM_TB_SMALLICON, TRUE, &result);
277 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
278 FCIDM_TB_REPORTVIEW, TRUE, &result);
282 /**********************************************************
284 * ##### helperfunctions for initializing the view #####
286 /**********************************************************
287 * change the style of the listview control
289 static void SetStyle(IShellViewImpl * This, DWORD dwAdd, DWORD dwRemove)
293 TRACE("(%p)\n", This);
295 tmpstyle = GetWindowLongW(This->hWndList, GWL_STYLE);
296 SetWindowLongW(This->hWndList, GWL_STYLE, dwAdd | (tmpstyle & ~dwRemove));
299 /**********************************************************
300 * ShellView_CreateList()
302 * - creates the list view window
304 static BOOL ShellView_CreateList (IShellViewImpl * This)
305 { DWORD dwStyle, dwExStyle;
309 dwStyle = WS_TABSTOP | WS_VISIBLE | WS_CHILDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
310 LVS_SHAREIMAGELISTS | LVS_EDITLABELS | LVS_ALIGNLEFT | LVS_AUTOARRANGE;
311 dwExStyle = WS_EX_CLIENTEDGE;
313 switch (This->FolderSettings.ViewMode)
315 case FVM_ICON: dwStyle |= LVS_ICON; break;
316 case FVM_DETAILS: dwStyle |= LVS_REPORT; break;
317 case FVM_SMALLICON: dwStyle |= LVS_SMALLICON; break;
318 case FVM_LIST: dwStyle |= LVS_LIST; break;
321 FIXME("ViewMode %d not implemented\n", This->FolderSettings.ViewMode);
327 if (This->FolderSettings.fFlags & FWF_AUTOARRANGE) dwStyle |= LVS_AUTOARRANGE;
328 if (This->FolderSettings.fFlags & FWF_DESKTOP)
329 This->FolderSettings.fFlags |= FWF_NOCLIENTEDGE | FWF_NOSCROLL;
330 if (This->FolderSettings.fFlags & FWF_SINGLESEL) dwStyle |= LVS_SINGLESEL;
331 if (This->FolderSettings.fFlags & FWF_NOCLIENTEDGE)
332 dwExStyle &= ~WS_EX_CLIENTEDGE;
334 This->hWndList=CreateWindowExW( dwExStyle,
347 This->ListViewSortInfo.bIsAscending = TRUE;
348 This->ListViewSortInfo.nHeaderID = -1;
349 This->ListViewSortInfo.nLastHeaderID = -1;
351 if (This->FolderSettings.fFlags & FWF_DESKTOP) {
353 * FIXME: look at the registry value
354 * HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ListviewShadow
355 * and activate drop shadows if necessary
358 SendMessageW(This->hWndList, LVM_SETTEXTBKCOLOR, 0, CLR_NONE);
360 SendMessageW(This->hWndList, LVM_SETTEXTBKCOLOR, 0, GetSysColor(COLOR_DESKTOP));
362 SendMessageW(This->hWndList, LVM_SETTEXTCOLOR, 0, RGB(255,255,255));
365 /* UpdateShellSettings(); */
369 /**********************************************************
370 * ShellView_InitList()
372 * - adds all needed columns to the shellview
374 static BOOL ShellView_InitList(IShellViewImpl * This)
383 SendMessageW(This->hWndList, LVM_DELETEALLITEMS, 0, 0);
385 lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT;
386 lvColumn.pszText = szTemp;
388 if (This->pSF2Parent)
392 if (FAILED(IShellFolder2_GetDetailsOf(This->pSF2Parent, NULL, i, &sd)))
394 lvColumn.fmt = sd.fmt;
395 lvColumn.cx = sd.cxChar*8; /* chars->pixel */
396 StrRetToStrNW( szTemp, 50, &sd.str, NULL);
397 SendMessageW(This->hWndList, LVM_INSERTCOLUMNW, i, (LPARAM) &lvColumn);
405 SendMessageW(This->hWndList, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)ShellSmallIconList);
406 SendMessageW(This->hWndList, LVM_SETIMAGELIST, LVSIL_NORMAL, (LPARAM)ShellBigIconList);
410 /**********************************************************
411 * ShellView_CompareItems()
414 * internal, CALLBACK for DSA_Sort
416 static INT CALLBACK ShellView_CompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
419 TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1, lParam2, (LPVOID) lpData);
421 if(!lpData) return 0;
423 ret = (SHORT) SCODE_CODE(IShellFolder_CompareIDs((LPSHELLFOLDER)lpData, 0, (LPITEMIDLIST)lParam1, (LPITEMIDLIST)lParam2));
424 TRACE("ret=%i\n",ret);
428 /*************************************************************************
429 * ShellView_ListViewCompareItems
431 * Compare Function for the Listview (FileOpen Dialog)
434 * lParam1 [I] the first ItemIdList to compare with
435 * lParam2 [I] the second ItemIdList to compare with
436 * lpData [I] The column ID for the header Ctrl to process
439 * A negative value if the first item should precede the second,
440 * a positive value if the first item should follow the second,
441 * or zero if the two items are equivalent
444 * FIXME: function does what ShellView_CompareItems is supposed to do.
445 * unify it and figure out how to use the undocumented first parameter
446 * of IShellFolder_CompareIDs to do the job this function does and
447 * move this code to IShellFolder.
448 * make LISTVIEW_SORT_INFO obsolete
449 * the way this function works is only usable if we had only
450 * filesystemfolders (25/10/99 jsch)
452 static INT CALLBACK ShellView_ListViewCompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
456 char strName1[MAX_PATH], strName2[MAX_PATH];
457 BOOL bIsFolder1, bIsFolder2,bIsBothFolder;
458 LPITEMIDLIST pItemIdList1 = lParam1;
459 LPITEMIDLIST pItemIdList2 = lParam2;
460 LISTVIEW_SORT_INFO *pSortInfo = (LPLISTVIEW_SORT_INFO) lpData;
463 bIsFolder1 = _ILIsFolder(pItemIdList1);
464 bIsFolder2 = _ILIsFolder(pItemIdList2);
465 bIsBothFolder = bIsFolder1 && bIsFolder2;
467 /* When sorting between a File and a Folder, the Folder gets sorted first */
468 if( (bIsFolder1 || bIsFolder2) && !bIsBothFolder)
470 nDiff = bIsFolder1 ? -1 : 1;
474 /* Sort by Time: Folders or Files can be sorted */
476 if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TIME)
478 _ILGetFileDateTime(pItemIdList1, &fd1);
479 _ILGetFileDateTime(pItemIdList2, &fd2);
480 nDiff = CompareFileTime(&fd2, &fd1);
482 /* Sort by Attribute: Folder or Files can be sorted */
483 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_ATTRIB)
485 _ILGetFileAttributes(pItemIdList1, strName1, MAX_PATH);
486 _ILGetFileAttributes(pItemIdList2, strName2, MAX_PATH);
487 nDiff = lstrcmpiA(strName1, strName2);
489 /* Sort by FileName: Folder or Files can be sorted */
490 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_NAME || bIsBothFolder)
493 _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
494 _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
495 nDiff = lstrcmpiA(strName1, strName2);
497 /* Sort by File Size, Only valid for Files */
498 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_SIZE)
500 nDiff = (INT)(_ILGetFileSize(pItemIdList1, NULL, 0) - _ILGetFileSize(pItemIdList2, NULL, 0));
502 /* Sort by File Type, Only valid for Files */
503 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TYPE)
506 _ILGetFileType(pItemIdList1, strName1, MAX_PATH);
507 _ILGetFileType(pItemIdList2, strName2, MAX_PATH);
508 nDiff = lstrcmpiA(strName1, strName2);
511 /* If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
515 _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
516 _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
517 nDiff = lstrcmpiA(strName1, strName2);
520 if(!pSortInfo->bIsAscending)
529 /**********************************************************
530 * LV_FindItemByPidl()
532 static int LV_FindItemByPidl(
533 IShellViewImpl * This,
538 lvItem.mask = LVIF_PARAM;
539 for(lvItem.iItem = 0;
540 SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem);
543 LPITEMIDLIST currentpidl = (LPITEMIDLIST) lvItem.lParam;
544 HRESULT hr = IShellFolder_CompareIDs(This->pSFParent, 0, pidl, currentpidl);
545 if(SUCCEEDED(hr) && !HRESULT_CODE(hr))
553 /**********************************************************
556 static BOOLEAN LV_AddItem(IShellViewImpl * This, LPCITEMIDLIST pidl)
560 TRACE("(%p)(pidl=%p)\n", This, pidl);
562 lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; /*set the mask*/
563 lvItem.iItem = ListView_GetItemCount(This->hWndList); /*add the item to the end of the list*/
565 lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidl)); /*set the item's data*/
566 lvItem.pszText = LPSTR_TEXTCALLBACKW; /*get text on a callback basis*/
567 lvItem.iImage = I_IMAGECALLBACK; /*get the image on a callback basis*/
568 return (-1==ListView_InsertItemW(This->hWndList, &lvItem))? FALSE: TRUE;
571 /**********************************************************
574 static BOOLEAN LV_DeleteItem(IShellViewImpl * This, LPCITEMIDLIST pidl)
578 TRACE("(%p)(pidl=%p)\n", This, pidl);
580 nIndex = LV_FindItemByPidl(This, ILFindLastID(pidl));
581 return (-1==ListView_DeleteItem(This->hWndList, nIndex))? FALSE: TRUE;
584 /**********************************************************
587 static BOOLEAN LV_RenameItem(IShellViewImpl * This, LPCITEMIDLIST pidlOld, LPCITEMIDLIST pidlNew )
592 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", This, pidlOld, pidlNew);
594 nItem = LV_FindItemByPidl(This, ILFindLastID(pidlOld));
597 lvItem.mask = LVIF_PARAM; /* only the pidl */
598 lvItem.iItem = nItem;
599 SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem);
601 SHFree((LPITEMIDLIST)lvItem.lParam);
602 lvItem.mask = LVIF_PARAM;
603 lvItem.iItem = nItem;
604 lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidlNew)); /* set the item's data */
605 SendMessageW(This->hWndList, LVM_SETITEMW, 0, (LPARAM) &lvItem);
606 SendMessageW(This->hWndList, LVM_UPDATE, nItem, 0);
607 return TRUE; /* FIXME: better handling */
611 /**********************************************************
612 * ShellView_FillList()
614 * - gets the objectlist from the shellfolder
616 * - fills the list into the view
619 static INT CALLBACK fill_list( LPVOID ptr, LPVOID arg )
621 LPITEMIDLIST pidl = ptr;
622 IShellViewImpl *This = arg;
623 /* in a commdlg This works as a filemask*/
624 if ( IncludeObject(This, pidl)==S_OK ) LV_AddItem(This, pidl);
629 static HRESULT ShellView_FillList(IShellViewImpl * This)
631 LPENUMIDLIST pEnumIDList;
639 /* get the itemlist from the shfolder*/
640 hRes = IShellFolder_EnumObjects(This->pSFParent,This->hWnd, SHCONTF_NONFOLDERS | SHCONTF_FOLDERS, &pEnumIDList);
648 /* create a pointer array */
649 hdpa = DPA_Create(16);
652 return(E_OUTOFMEMORY);
655 /* copy the items into the array*/
656 while((S_OK == IEnumIDList_Next(pEnumIDList,1, &pidl, &dwFetched)) && dwFetched)
658 if (DPA_InsertPtr(hdpa, 0x7fff, pidl) == -1)
665 DPA_Sort(hdpa, ShellView_CompareItems, (LPARAM)This->pSFParent);
667 /*turn the listview's redrawing off*/
668 SendMessageA(This->hWndList, WM_SETREDRAW, FALSE, 0);
670 DPA_DestroyCallback( hdpa, fill_list, This );
672 /*turn the listview's redrawing back on and force it to draw*/
673 SendMessageA(This->hWndList, WM_SETREDRAW, TRUE, 0);
675 IEnumIDList_Release(pEnumIDList); /* destroy the list*/
680 /**********************************************************
681 * ShellView_OnCreate()
683 static LRESULT ShellView_OnCreate(IShellViewImpl * This)
686 SHChangeNotifyEntry ntreg;
687 IPersistFolder2 * ppf2 = NULL;
691 if(ShellView_CreateList(This))
693 if(ShellView_InitList(This))
695 ShellView_FillList(This);
699 if (SUCCEEDED(IUnknown_QueryInterface((IUnknown*)&This->lpVtbl, &IID_IDropTarget, (LPVOID*)&pdt)))
701 RegisterDragDrop(This->hWnd, pdt);
702 IDropTarget_Release(pdt);
705 /* register for receiving notifications */
706 IShellFolder_QueryInterface(This->pSFParent, &IID_IPersistFolder2, (LPVOID*)&ppf2);
709 IPersistFolder2_GetCurFolder(ppf2, (LPITEMIDLIST*)&ntreg.pidl);
710 ntreg.fRecursive = TRUE;
711 This->hNotify = SHChangeNotifyRegister(This->hWnd, SHCNF_IDLIST, SHCNE_ALLEVENTS, SHV_CHANGE_NOTIFY, 1, &ntreg);
712 SHFree((LPITEMIDLIST)ntreg.pidl);
713 IPersistFolder2_Release(ppf2);
716 This->hAccel = LoadAcceleratorsA(shell32_hInstance, "shv_accel");
721 /**********************************************************
722 * #### Handling of the menus ####
725 /**********************************************************
726 * ShellView_BuildFileMenu()
728 static HMENU ShellView_BuildFileMenu(IShellViewImpl * This)
729 { WCHAR szText[MAX_PATH];
734 TRACE("(%p)\n",This);
736 hSubMenu = CreatePopupMenu();
738 { /*get the number of items in our global array*/
739 for(nTools = 0; Tools[nTools].idCommand != -1; nTools++){}
741 /*add the menu items*/
742 for(i = 0; i < nTools; i++)
744 LoadStringW(shell32_hInstance, Tools[i].idMenuString, szText, MAX_PATH);
746 ZeroMemory(&mii, sizeof(mii));
747 mii.cbSize = sizeof(mii);
748 mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
750 if(BTNS_SEP != Tools[i].bStyle) /* no separator*/
752 mii.fType = MFT_STRING;
753 mii.fState = MFS_ENABLED;
754 mii.dwTypeData = szText;
755 mii.wID = Tools[i].idCommand;
759 mii.fType = MFT_SEPARATOR;
761 /* tack This item onto the end of the menu */
762 InsertMenuItemW(hSubMenu, (UINT)-1, TRUE, &mii);
765 TRACE("-- return (menu=%p)\n",hSubMenu);
768 /**********************************************************
769 * ShellView_MergeFileMenu()
771 static void ShellView_MergeFileMenu(IShellViewImpl * This, HMENU hSubMenu)
772 { TRACE("(%p)->(submenu=%p) stub\n",This,hSubMenu);
775 { /*insert This item at the beginning of the menu */
778 mii.cbSize = sizeof(mii);
779 mii.fMask = MIIM_ID | MIIM_TYPE;
781 mii.fType = MFT_SEPARATOR;
782 InsertMenuItemA(hSubMenu, 0, TRUE, &mii);
784 mii.cbSize = sizeof(mii);
785 mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
786 mii.dwTypeData = (LPSTR)"dummy45";
787 mii.fState = MFS_ENABLED;
788 mii.wID = IDM_MYFILEITEM;
789 mii.fType = MFT_STRING;
790 InsertMenuItemA(hSubMenu, 0, TRUE, &mii);
795 /**********************************************************
796 * ShellView_MergeViewMenu()
799 static void ShellView_MergeViewMenu(IShellViewImpl * This, HMENU hSubMenu)
801 TRACE("(%p)->(submenu=%p)\n",This,hSubMenu);
804 { /*add a separator at the correct position in the menu*/
806 static char view[] = "View";
808 ZeroMemory(&mii, sizeof(mii));
809 mii.cbSize = sizeof(mii);
810 mii.fMask = MIIM_ID | MIIM_TYPE;
812 mii.fType = MFT_SEPARATOR;
813 InsertMenuItemA(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
815 mii.cbSize = sizeof(mii);
816 mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_DATA;
817 mii.fType = MFT_STRING;
818 mii.dwTypeData = view;
819 mii.hSubMenu = LoadMenuA(shell32_hInstance, "MENU_001");
820 InsertMenuItemA(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
824 /**********************************************************
825 * ShellView_GetSelections()
827 * - fills the this->apidl list with the selected objects
830 * number of selected items
832 static UINT ShellView_GetSelections(IShellViewImpl * This)
839 This->cidl = ListView_GetSelectedCount(This->hWndList);
840 This->apidl = SHAlloc(This->cidl * sizeof(LPITEMIDLIST));
842 TRACE("selected=%i\n", This->cidl);
846 TRACE("-- Items selected =%u\n", This->cidl);
848 lvItem.mask = LVIF_STATE | LVIF_PARAM;
849 lvItem.stateMask = LVIS_SELECTED;
853 while(ListView_GetItemW(This->hWndList, &lvItem) && (i < This->cidl))
855 if(lvItem.state & LVIS_SELECTED)
857 This->apidl[i] = (LPITEMIDLIST)lvItem.lParam;
859 TRACE("-- selected Item found\n");
868 /**********************************************************
869 * ShellView_OpenSelectedItems()
871 static HRESULT ShellView_OpenSelectedItems(IShellViewImpl * This)
873 static UINT CF_IDLIST = 0;
875 IDataObject* selection;
879 LPCITEMIDLIST parent_pidl;
880 WCHAR parent_path[MAX_PATH];
881 LPCWSTR parent_dir = NULL;
885 if (0 == ShellView_GetSelections(This))
889 hr = IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl,
890 (LPCITEMIDLIST*)This->apidl, &IID_IDataObject,
891 0, (LPVOID *)&selection);
897 CF_IDLIST = RegisterClipboardFormatW(CFSTR_SHELLIDLISTW);
899 fetc.cfFormat = CF_IDLIST;
901 fetc.dwAspect = DVASPECT_CONTENT;
903 fetc.tymed = TYMED_HGLOBAL;
905 hr = IDataObject_QueryGetData(selection, &fetc);
909 hr = IDataObject_GetData(selection, &fetc, &stgm);
913 pIDList = GlobalLock(stgm.u.hGlobal);
915 parent_pidl = (LPCITEMIDLIST) ((LPBYTE)pIDList+pIDList->aoffset[0]);
916 hr = IShellFolder_GetAttributesOf(This->pSFParent, 1, &parent_pidl, &attribs);
917 if (SUCCEEDED(hr) && (attribs & SFGAO_FILESYSTEM) &&
918 SHGetPathFromIDListW(parent_pidl, parent_path))
920 parent_dir = parent_path;
923 for (i = pIDList->cidl; i > 0; --i)
927 pidl = (LPCITEMIDLIST)((LPBYTE)pIDList+pIDList->aoffset[i]);
929 attribs = SFGAO_FOLDER;
930 hr = IShellFolder_GetAttributesOf(This->pSFParent, 1, &pidl, &attribs);
932 if (SUCCEEDED(hr) && ! (attribs & SFGAO_FOLDER))
934 SHELLEXECUTEINFOW shexinfo;
936 shexinfo.cbSize = sizeof(SHELLEXECUTEINFOW);
937 shexinfo.fMask = SEE_MASK_INVOKEIDLIST; /* SEE_MASK_IDLIST is also possible. */
938 shexinfo.hwnd = NULL;
939 shexinfo.lpVerb = NULL;
940 shexinfo.lpFile = NULL;
941 shexinfo.lpParameters = NULL;
942 shexinfo.lpDirectory = parent_dir;
943 shexinfo.nShow = SW_NORMAL;
944 shexinfo.lpIDList = ILCombine(parent_pidl, pidl);
946 ShellExecuteExW(&shexinfo); /* Discard error/success info */
948 ILFree(shexinfo.lpIDList);
952 GlobalUnlock(stgm.u.hGlobal);
953 ReleaseStgMedium(&stgm);
955 IDataObject_Release(selection);
960 /**********************************************************
961 * ShellView_DoContextMenu()
963 static void ShellView_DoContextMenu(IShellViewImpl * This, WORD x, WORD y, BOOL bDefault)
967 BOOL fExplore = FALSE;
969 LPCONTEXTMENU pContextMenu = NULL;
970 IContextMenu2 *pCM = NULL;
971 CMINVOKECOMMANDINFO cmi;
973 TRACE("(%p)->(0x%08x 0x%08x 0x%08x) stub\n",This, x, y, bDefault);
975 /* look, what's selected and create a context menu object of it*/
976 if( ShellView_GetSelections(This) )
978 IShellFolder_GetUIObjectOf( This->pSFParent, This->hWndParent, This->cidl, (LPCITEMIDLIST*)This->apidl,
979 (REFIID)&IID_IContextMenu, NULL, (LPVOID *)&pContextMenu);
983 TRACE("-- pContextMenu\n");
984 hMenu = CreatePopupMenu();
988 /* See if we are in Explore or Open mode. If the browser's tree is present, we are in Explore mode.*/
989 if(SUCCEEDED(IShellBrowser_GetControlWindow(This->pShellBrowser,FCW_TREE, &hwndTree)) && hwndTree)
991 TRACE("-- explore mode\n");
995 /* build the flags depending on what we can do with the selected item */
996 wFlags = CMF_NORMAL | (This->cidl != 1 ? 0 : CMF_CANRENAME) | (fExplore ? CMF_EXPLORE : 0);
998 /* let the ContextMenu merge its items in */
999 if (SUCCEEDED(IContextMenu_QueryContextMenu( pContextMenu, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, wFlags )))
1001 if (This->FolderSettings.fFlags & FWF_DESKTOP)
1002 SetMenuDefaultItem(hMenu, FCIDM_SHVIEW_OPEN, MF_BYCOMMAND);
1006 TRACE("-- get menu default command\n");
1007 uCommand = GetMenuDefaultItem(hMenu, FALSE, GMDI_GOINTOPOPUPS);
1011 TRACE("-- track popup\n");
1012 uCommand = TrackPopupMenu( hMenu,TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
1017 TRACE("-- uCommand=%u\n", uCommand);
1018 if (uCommand==FCIDM_SHVIEW_OPEN && IsInCommDlg(This))
1020 TRACE("-- dlg: OnDefaultCommand\n");
1021 if (OnDefaultCommand(This) != S_OK)
1023 ShellView_OpenSelectedItems(This);
1028 TRACE("-- explore -- invoke command\n");
1029 ZeroMemory(&cmi, sizeof(cmi));
1030 cmi.cbSize = sizeof(cmi);
1031 cmi.hwnd = This->hWndParent; /* this window has to answer CWM_GETISHELLBROWSER */
1032 cmi.lpVerb = MAKEINTRESOURCEA(uCommand);
1033 IContextMenu_InvokeCommand(pContextMenu, &cmi);
1040 IContextMenu_Release(pContextMenu);
1043 else /* background context menu */
1045 hMenu = CreatePopupMenu();
1047 pCM = ISvBgCm_Constructor(This->pSFParent, FALSE);
1048 IContextMenu2_QueryContextMenu(pCM, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, 0);
1050 uCommand = TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
1053 TRACE("-- (%p)->(uCommand=0x%08x )\n",This, uCommand);
1055 ZeroMemory(&cmi, sizeof(cmi));
1056 cmi.cbSize = sizeof(cmi);
1057 cmi.lpVerb = MAKEINTRESOURCEA(uCommand);
1058 cmi.hwnd = This->hWndParent;
1059 IContextMenu2_InvokeCommand(pCM, &cmi);
1061 IContextMenu2_Release(pCM);
1065 /**********************************************************
1066 * ##### message handling #####
1069 /**********************************************************
1070 * ShellView_OnSize()
1072 static LRESULT ShellView_OnSize(IShellViewImpl * This, WORD wWidth, WORD wHeight)
1074 TRACE("%p width=%u height=%u\n",This, wWidth,wHeight);
1076 /*resize the ListView to fit our window*/
1079 MoveWindow(This->hWndList, 0, 0, wWidth, wHeight, TRUE);
1084 /**********************************************************
1085 * ShellView_OnDeactivate()
1090 static void ShellView_OnDeactivate(IShellViewImpl * This)
1094 if(This->uState != SVUIA_DEACTIVATE)
1098 IShellBrowser_SetMenuSB(This->pShellBrowser,0, 0, 0);
1099 IShellBrowser_RemoveMenusSB(This->pShellBrowser,This->hMenu);
1100 DestroyMenu(This->hMenu);
1104 This->uState = SVUIA_DEACTIVATE;
1108 /**********************************************************
1109 * ShellView_OnActivate()
1111 static LRESULT ShellView_OnActivate(IShellViewImpl * This, UINT uState)
1112 { OLEMENUGROUPWIDTHS omw = { {0, 0, 0, 0, 0, 0} };
1114 CHAR szText[MAX_PATH];
1116 TRACE("%p uState=%x\n",This,uState);
1118 /*don't do anything if the state isn't really changing */
1119 if(This->uState == uState)
1124 ShellView_OnDeactivate(This);
1126 /*only do This if we are active */
1127 if(uState != SVUIA_DEACTIVATE)
1129 /*merge the menus */
1130 This->hMenu = CreateMenu();
1134 IShellBrowser_InsertMenusSB(This->pShellBrowser, This->hMenu, &omw);
1135 TRACE("-- after fnInsertMenusSB\n");
1137 /*build the top level menu get the menu item's text*/
1138 strcpy(szText,"dummy 31");
1140 ZeroMemory(&mii, sizeof(mii));
1141 mii.cbSize = sizeof(mii);
1142 mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_STATE;
1143 mii.fType = MFT_STRING;
1144 mii.fState = MFS_ENABLED;
1145 mii.dwTypeData = szText;
1146 mii.hSubMenu = ShellView_BuildFileMenu(This);
1148 /*insert our menu into the menu bar*/
1151 InsertMenuItemA(This->hMenu, FCIDM_MENU_HELP, FALSE, &mii);
1154 /*get the view menu so we can merge with it*/
1155 ZeroMemory(&mii, sizeof(mii));
1156 mii.cbSize = sizeof(mii);
1157 mii.fMask = MIIM_SUBMENU;
1159 if(GetMenuItemInfoA(This->hMenu, FCIDM_MENU_VIEW, FALSE, &mii))
1161 ShellView_MergeViewMenu(This, mii.hSubMenu);
1164 /*add the items that should only be added if we have the focus*/
1165 if(SVUIA_ACTIVATE_FOCUS == uState)
1167 /*get the file menu so we can merge with it */
1168 ZeroMemory(&mii, sizeof(mii));
1169 mii.cbSize = sizeof(mii);
1170 mii.fMask = MIIM_SUBMENU;
1172 if(GetMenuItemInfoA(This->hMenu, FCIDM_MENU_FILE, FALSE, &mii))
1174 ShellView_MergeFileMenu(This, mii.hSubMenu);
1177 TRACE("-- before fnSetMenuSB\n");
1178 IShellBrowser_SetMenuSB(This->pShellBrowser, This->hMenu, 0, This->hWnd);
1181 This->uState = uState;
1186 /**********************************************************
1187 * ShellView_OnSetFocus()
1190 static LRESULT ShellView_OnSetFocus(IShellViewImpl * This)
1194 /* Tell the browser one of our windows has received the focus. This
1195 should always be done before merging menus (OnActivate merges the
1196 menus) if one of our windows has the focus.*/
1198 IShellBrowser_OnViewWindowActive(This->pShellBrowser,(IShellView*) This);
1199 ShellView_OnActivate(This, SVUIA_ACTIVATE_FOCUS);
1201 /* Set the focus to the listview */
1202 SetFocus(This->hWndList);
1204 /* Notify the ICommDlgBrowser interface */
1205 OnStateChange(This,CDBOSC_SETFOCUS);
1210 /**********************************************************
1211 * ShellView_OnKillFocus()
1213 static LRESULT ShellView_OnKillFocus(IShellViewImpl * This)
1215 TRACE("(%p) stub\n",This);
1217 ShellView_OnActivate(This, SVUIA_ACTIVATE_NOFOCUS);
1218 /* Notify the ICommDlgBrowser */
1219 OnStateChange(This,CDBOSC_KILLFOCUS);
1224 /**********************************************************
1225 * ShellView_OnCommand()
1228 * the CmdID's are the ones from the context menu
1230 static LRESULT ShellView_OnCommand(IShellViewImpl * This,DWORD dwCmdID, DWORD dwCmd, HWND hwndCmd)
1232 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n",This, dwCmdID, dwCmd, hwndCmd);
1236 case FCIDM_SHVIEW_SMALLICON:
1237 This->FolderSettings.ViewMode = FVM_SMALLICON;
1238 SetStyle (This, LVS_SMALLICON, LVS_TYPEMASK);
1242 case FCIDM_SHVIEW_BIGICON:
1243 This->FolderSettings.ViewMode = FVM_ICON;
1244 SetStyle (This, LVS_ICON, LVS_TYPEMASK);
1248 case FCIDM_SHVIEW_LISTVIEW:
1249 This->FolderSettings.ViewMode = FVM_LIST;
1250 SetStyle (This, LVS_LIST, LVS_TYPEMASK);
1254 case FCIDM_SHVIEW_REPORTVIEW:
1255 This->FolderSettings.ViewMode = FVM_DETAILS;
1256 SetStyle (This, LVS_REPORT, LVS_TYPEMASK);
1260 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1265 This->ListViewSortInfo.nHeaderID = (LPARAM) (dwCmdID - 0x30);
1266 This->ListViewSortInfo.bIsAscending = TRUE;
1267 This->ListViewSortInfo.nLastHeaderID = This->ListViewSortInfo.nHeaderID;
1268 SendMessageA(This->hWndList, LVM_SORTITEMS, (WPARAM) &This->ListViewSortInfo, (LPARAM)ShellView_ListViewCompareItems);
1272 TRACE("-- COMMAND 0x%04x unhandled\n", dwCmdID);
1277 /**********************************************************
1278 * ShellView_OnNotify()
1281 static LRESULT ShellView_OnNotify(IShellViewImpl * This, UINT CtlID, LPNMHDR lpnmh)
1282 { LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)lpnmh;
1283 NMLVDISPINFOW *lpdi = (NMLVDISPINFOW *)lpnmh;
1286 TRACE("%p CtlID=%u lpnmh->code=%x\n",This,CtlID,lpnmh->code);
1291 TRACE("-- NM_SETFOCUS %p\n",This);
1292 ShellView_OnSetFocus(This);
1296 TRACE("-- NM_KILLFOCUS %p\n",This);
1297 ShellView_OnDeactivate(This);
1298 /* Notify the ICommDlgBrowser interface */
1299 OnStateChange(This,CDBOSC_KILLFOCUS);
1303 TRACE("-- NM_CUSTOMDRAW %p\n",This);
1304 return CDRF_DODEFAULT;
1306 case NM_RELEASEDCAPTURE:
1307 TRACE("-- NM_RELEASEDCAPTURE %p\n",This);
1311 TRACE("-- NM_CLICK %p\n",This);
1315 TRACE("-- NM_RCLICK %p\n",This);
1319 TRACE("-- NM_DBLCLK %p\n",This);
1320 if (OnDefaultCommand(This) != S_OK) ShellView_OpenSelectedItems(This);
1324 TRACE("-- NM_DBLCLK %p\n",This);
1325 if (OnDefaultCommand(This) != S_OK) ShellView_OpenSelectedItems(This);
1329 TRACE("-- HDN_ENDTRACKW %p\n",This);
1330 /*nColumn1 = ListView_GetColumnWidth(This->hWndList, 0);
1331 nColumn2 = ListView_GetColumnWidth(This->hWndList, 1);*/
1334 case LVN_DELETEITEM:
1335 TRACE("-- LVN_DELETEITEM %p\n",This);
1336 SHFree((LPITEMIDLIST)lpnmlv->lParam); /*delete the pidl because we made a copy of it*/
1339 case LVN_DELETEALLITEMS:
1340 TRACE("-- LVN_DELETEALLITEMS %p\n",This);
1343 case LVN_INSERTITEM:
1344 TRACE("-- LVN_INSERTITEM (STUB)%p\n",This);
1347 case LVN_ITEMACTIVATE:
1348 TRACE("-- LVN_ITEMACTIVATE %p\n",This);
1349 OnStateChange(This, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
1352 case LVN_COLUMNCLICK:
1353 This->ListViewSortInfo.nHeaderID = lpnmlv->iSubItem;
1354 if(This->ListViewSortInfo.nLastHeaderID == This->ListViewSortInfo.nHeaderID)
1356 This->ListViewSortInfo.bIsAscending = !This->ListViewSortInfo.bIsAscending;
1360 This->ListViewSortInfo.bIsAscending = TRUE;
1362 This->ListViewSortInfo.nLastHeaderID = This->ListViewSortInfo.nHeaderID;
1364 SendMessageW(lpnmlv->hdr.hwndFrom, LVM_SORTITEMS, (WPARAM) &This->ListViewSortInfo, (LPARAM)ShellView_ListViewCompareItems);
1367 case LVN_GETDISPINFOA:
1368 case LVN_GETDISPINFOW:
1369 TRACE("-- LVN_GETDISPINFO %p\n",This);
1370 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1372 if(lpdi->item.mask & LVIF_TEXT) /* text requested */
1374 if (This->pSF2Parent)
1377 IShellFolder2_GetDetailsOf(This->pSF2Parent, pidl, lpdi->item.iSubItem, &sd);
1378 if (lpnmh->code == LVN_GETDISPINFOA)
1380 /* shouldn't happen */
1381 NMLVDISPINFOA *lpdiA = (NMLVDISPINFOA *)lpnmh;
1382 StrRetToStrNA( lpdiA->item.pszText, lpdiA->item.cchTextMax, &sd.str, NULL);
1383 TRACE("-- text=%s\n",lpdiA->item.pszText);
1385 else /* LVN_GETDISPINFOW */
1387 StrRetToStrNW( lpdi->item.pszText, lpdi->item.cchTextMax, &sd.str, NULL);
1388 TRACE("-- text=%s\n",debugstr_w(lpdi->item.pszText));
1396 if(lpdi->item.mask & LVIF_IMAGE) /* image requested */
1398 lpdi->item.iImage = SHMapPIDLToSystemImageListIndex(This->pSFParent, pidl, 0);
1402 case LVN_ITEMCHANGED:
1403 TRACE("-- LVN_ITEMCHANGED %p\n",This);
1404 OnStateChange(This, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
1408 case LVN_BEGINRDRAG:
1409 TRACE("-- LVN_BEGINDRAG\n");
1411 if (ShellView_GetSelections(This))
1414 DWORD dwAttributes = SFGAO_CANLINK;
1415 DWORD dwEffect = DROPEFFECT_COPY | DROPEFFECT_MOVE;
1417 if (SUCCEEDED(IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, (LPCITEMIDLIST*)This->apidl, &IID_IDataObject,0,(LPVOID *)&pda)))
1419 IDropSource * pds = (IDropSource*)&(This->lpvtblDropSource); /* own DropSource interface */
1421 if (SUCCEEDED(IShellFolder_GetAttributesOf(This->pSFParent, This->cidl, (LPCITEMIDLIST*)This->apidl, &dwAttributes)))
1423 if (dwAttributes & SFGAO_CANLINK)
1425 dwEffect |= DROPEFFECT_LINK;
1432 DoDragDrop(pda, pds, dwEffect, &dwEffect);
1434 IDataObject_Release(pda);
1439 case LVN_BEGINLABELEDITW:
1441 DWORD dwAttr = SFGAO_CANRENAME;
1442 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1444 TRACE("-- LVN_BEGINLABELEDITA %p\n",This);
1446 IShellFolder_GetAttributesOf(This->pSFParent, 1, (LPCITEMIDLIST*)&pidl, &dwAttr);
1447 if (SFGAO_CANRENAME & dwAttr)
1454 case LVN_ENDLABELEDITW:
1456 TRACE("-- LVN_ENDLABELEDITA %p\n",This);
1457 if (lpdi->item.pszText)
1462 lvItem.iItem = lpdi->item.iItem;
1463 lvItem.iSubItem = 0;
1464 lvItem.mask = LVIF_PARAM;
1465 SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem);
1467 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1468 hr = IShellFolder_SetNameOf(This->pSFParent, 0, pidl, lpdi->item.pszText, SHGDN_INFOLDER, &pidl);
1470 if(SUCCEEDED(hr) && pidl)
1472 lvItem.mask = LVIF_PARAM;
1473 lvItem.lParam = (LPARAM)pidl;
1474 SendMessageW(This->hWndList, LVM_SETITEMW, 0, (LPARAM) &lvItem);
1484 msg.hwnd = This->hWnd;
1485 msg.message = WM_KEYDOWN;
1486 msg.wParam = plvKeyDown->wVKey;
1491 LPNMLVKEYDOWN plvKeyDown = (LPNMLVKEYDOWN) lpnmh;
1493 /* initiate a rename of the selected file or directory */
1494 if(plvKeyDown->wVKey == VK_F2)
1496 /* see how many files are selected */
1497 int i = ListView_GetSelectedCount(This->hWndList);
1499 /* get selected item */
1502 /* get selected item */
1503 i = ListView_GetNextItem(This->hWndList, -1,
1506 SendMessageW(This->hWndList, LVM_ENSUREVISIBLE, i, 0);
1507 SendMessageW(This->hWndList, LVM_EDITLABELW, i, 0);
1511 TranslateAccelerator(This->hWnd, This->hAccel, &msg)
1513 else if(plvKeyDown->wVKey == VK_DELETE)
1518 LPITEMIDLIST* pItems;
1521 IShellFolder_QueryInterface(This->pSFParent, &IID_ISFHelper,
1527 if(!(i = ListView_GetSelectedCount(This->hWndList)))
1530 /* allocate memory for the pidl array */
1531 pItems = HeapAlloc(GetProcessHeap(), 0,
1532 sizeof(LPITEMIDLIST) * i);
1534 /* retrieve all selected items */
1537 while(ListView_GetSelectedCount(This->hWndList) > i)
1539 /* get selected item */
1540 item_index = ListView_GetNextItem(This->hWndList,
1541 item_index, LVNI_SELECTED);
1542 item.iItem = item_index;
1543 item.mask = LVIF_PARAM;
1544 SendMessageA(This->hWndList, LVM_GETITEMA, 0, (LPARAM) &item);
1547 pItems[i] = (LPITEMIDLIST)item.lParam;
1552 /* perform the item deletion */
1553 ISFHelper_DeleteItems(psfhlp, i, (LPCITEMIDLIST*)pItems);
1555 /* free pidl array memory */
1556 HeapFree(GetProcessHeap(), 0, pItems);
1559 /* Initiate a refresh */
1560 else if(plvKeyDown->wVKey == VK_F5)
1562 IShellView_Refresh((IShellView*)This);
1565 else if(plvKeyDown->wVKey == VK_BACK)
1567 LPSHELLBROWSER lpSb;
1568 if((lpSb = (LPSHELLBROWSER)SendMessageW(This->hWndParent, CWM_GETISHELLBROWSER, 0, 0)))
1570 IShellBrowser_BrowseObject(lpSb, NULL, SBSP_PARENT);
1575 FIXME("LVN_KEYDOWN key=0x%08x\n",plvKeyDown->wVKey);
1580 TRACE("-- %p WM_COMMAND %x unhandled\n", This, lpnmh->code);
1586 /**********************************************************
1587 * ShellView_OnChange()
1590 static LRESULT ShellView_OnChange(IShellViewImpl * This, const LPCITEMIDLIST * Pidls, LONG wEventId)
1593 TRACE("(%p)(%p,%p,0x%08x)\n", This, Pidls[0], Pidls[1], wEventId);
1598 LV_AddItem(This, Pidls[0]);
1602 LV_DeleteItem(This, Pidls[0]);
1604 case SHCNE_RENAMEFOLDER:
1605 case SHCNE_RENAMEITEM:
1606 LV_RenameItem(This, Pidls[0], Pidls[1]);
1608 case SHCNE_UPDATEITEM:
1613 /**********************************************************
1617 static LRESULT CALLBACK ShellView_WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
1619 IShellViewImpl * pThis = (IShellViewImpl*)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
1620 LPCREATESTRUCTW lpcs;
1622 TRACE("(hwnd=%p msg=%x wparm=%lx lparm=%lx)\n",hWnd, uMessage, wParam, lParam);
1627 lpcs = (LPCREATESTRUCTW)lParam;
1628 pThis = lpcs->lpCreateParams;
1629 SetWindowLongPtrW(hWnd, GWLP_USERDATA, (ULONG_PTR)pThis);
1630 pThis->hWnd = hWnd; /*set the window handle*/
1633 case WM_SIZE: return ShellView_OnSize(pThis,LOWORD(lParam), HIWORD(lParam));
1634 case WM_SETFOCUS: return ShellView_OnSetFocus(pThis);
1635 case WM_KILLFOCUS: return ShellView_OnKillFocus(pThis);
1636 case WM_CREATE: return ShellView_OnCreate(pThis);
1637 case WM_ACTIVATE: return ShellView_OnActivate(pThis, SVUIA_ACTIVATE_FOCUS);
1638 case WM_NOTIFY: return ShellView_OnNotify(pThis,(UINT)wParam, (LPNMHDR)lParam);
1639 case WM_COMMAND: return ShellView_OnCommand(pThis,
1640 GET_WM_COMMAND_ID(wParam, lParam),
1641 GET_WM_COMMAND_CMD(wParam, lParam),
1642 GET_WM_COMMAND_HWND(wParam, lParam));
1643 case SHV_CHANGE_NOTIFY: return ShellView_OnChange(pThis, (const LPCITEMIDLIST*)wParam, (LONG)lParam);
1645 case WM_CONTEXTMENU: ShellView_DoContextMenu(pThis, LOWORD(lParam), HIWORD(lParam), FALSE);
1648 case WM_SHOWWINDOW: UpdateWindow(pThis->hWndList);
1651 case WM_GETDLGCODE: return SendMessageA(pThis->hWndList,uMessage,0,0);
1654 RevokeDragDrop(pThis->hWnd);
1655 SHChangeNotifyDeregister(pThis->hNotify);
1659 if ((pThis->FolderSettings.fFlags & FWF_DESKTOP) ||
1660 (pThis->FolderSettings.fFlags & FWF_TRANSPARENT))
1665 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
1667 /**********************************************************
1670 * The INTERFACE of the IShellView object
1673 **********************************************************
1674 * IShellView_QueryInterface
1676 static HRESULT WINAPI IShellView_fnQueryInterface(IShellView2 * iface,REFIID riid, LPVOID *ppvObj)
1678 IShellViewImpl *This = (IShellViewImpl *)iface;
1680 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1684 if(IsEqualIID(riid, &IID_IUnknown))
1688 else if(IsEqualIID(riid, &IID_IShellView))
1692 else if(IsEqualIID(riid, &IID_IShellView2))
1696 else if(IsEqualIID(riid, &IID_IOleCommandTarget))
1698 *ppvObj = &This->lpvtblOleCommandTarget;
1700 else if(IsEqualIID(riid, &IID_IDropTarget))
1702 *ppvObj = &This->lpvtblDropTarget;
1704 else if(IsEqualIID(riid, &IID_IDropSource))
1706 *ppvObj = &This->lpvtblDropSource;
1708 else if(IsEqualIID(riid, &IID_IViewObject))
1710 *ppvObj = &This->lpvtblViewObject;
1715 IUnknown_AddRef( (IUnknown*)*ppvObj );
1716 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1719 TRACE("-- Interface: E_NOINTERFACE\n");
1720 return E_NOINTERFACE;
1723 /**********************************************************
1726 static ULONG WINAPI IShellView_fnAddRef(IShellView2 * iface)
1728 IShellViewImpl *This = (IShellViewImpl *)iface;
1729 ULONG refCount = InterlockedIncrement(&This->ref);
1731 TRACE("(%p)->(count=%u)\n", This, refCount - 1);
1735 /**********************************************************
1736 * IShellView_Release
1738 static ULONG WINAPI IShellView_fnRelease(IShellView2 * iface)
1740 IShellViewImpl *This = (IShellViewImpl *)iface;
1741 ULONG refCount = InterlockedDecrement(&This->ref);
1743 TRACE("(%p)->(count=%i)\n", This, refCount + 1);
1747 TRACE(" destroying IShellView(%p)\n",This);
1749 DestroyWindow(This->hWndList);
1752 IShellFolder_Release(This->pSFParent);
1754 if(This->pSF2Parent)
1755 IShellFolder2_Release(This->pSF2Parent);
1757 SHFree(This->apidl);
1760 IAdviseSink_Release(This->pAdvSink);
1762 HeapFree(GetProcessHeap(),0,This);
1767 /**********************************************************
1768 * ShellView_GetWindow
1770 static HRESULT WINAPI IShellView_fnGetWindow(IShellView2 * iface,HWND * phWnd)
1772 IShellViewImpl *This = (IShellViewImpl *)iface;
1774 TRACE("(%p)\n",This);
1776 *phWnd = This->hWnd;
1781 static HRESULT WINAPI IShellView_fnContextSensitiveHelp(IShellView2 * iface,BOOL fEnterMode)
1783 IShellViewImpl *This = (IShellViewImpl *)iface;
1785 FIXME("(%p) stub\n",This);
1790 /**********************************************************
1791 * IShellView_TranslateAccelerator
1794 * use the accel functions
1796 static HRESULT WINAPI IShellView_fnTranslateAccelerator(IShellView2 * iface,LPMSG lpmsg)
1799 IShellViewImpl *This = (IShellViewImpl *)iface;
1801 FIXME("(%p)->(%p: hwnd=%x msg=%x lp=%x wp=%x) stub\n",This,lpmsg, lpmsg->hwnd, lpmsg->message, lpmsg->lParam, lpmsg->wParam);
1804 if ((lpmsg->message>=WM_KEYFIRST) && (lpmsg->message>=WM_KEYLAST))
1806 TRACE("-- key=0x04%lx\n",lpmsg->wParam) ;
1808 return S_FALSE; /* not handled */
1811 static HRESULT WINAPI IShellView_fnEnableModeless(IShellView2 * iface,BOOL fEnable)
1813 IShellViewImpl *This = (IShellViewImpl *)iface;
1815 FIXME("(%p) stub\n",This);
1820 static HRESULT WINAPI IShellView_fnUIActivate(IShellView2 * iface,UINT uState)
1822 IShellViewImpl *This = (IShellViewImpl *)iface;
1825 CHAR szName[MAX_PATH];
1828 int nPartArray[1] = {-1};
1830 TRACE("(%p)->(state=%x) stub\n",This, uState);
1832 /*don't do anything if the state isn't really changing*/
1833 if(This->uState == uState)
1838 /*OnActivate handles the menu merging and internal state*/
1839 ShellView_OnActivate(This, uState);
1841 /*only do This if we are active*/
1842 if(uState != SVUIA_DEACTIVATE)
1846 GetFolderPath is not a method of IShellFolder
1847 IShellFolder_GetFolderPath( This->pSFParent, szName, sizeof(szName) );
1849 /* set the number of parts */
1850 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETPARTS, 1,
1851 (LPARAM)nPartArray, &lResult);
1853 /* set the text for the parts */
1855 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETTEXTA,
1856 0, (LPARAM)szName, &lResult);
1863 static HRESULT WINAPI IShellView_fnRefresh(IShellView2 * iface)
1865 IShellViewImpl *This = (IShellViewImpl *)iface;
1867 TRACE("(%p)\n",This);
1869 SendMessageW(This->hWndList, LVM_DELETEALLITEMS, 0, 0);
1870 ShellView_FillList(This);
1875 static HRESULT WINAPI IShellView_fnCreateViewWindow(IShellView2 *iface, IShellView *lpPrevView,
1876 LPCFOLDERSETTINGS lpfs, IShellBrowser *psb, RECT *prcView, HWND *phWnd)
1879 SV2CVW2_PARAMS view_params;
1880 view_params.cbSize = sizeof(view_params);
1881 view_params.psvPrev = lpPrevView;
1882 view_params.pfs = lpfs;
1883 view_params.psbOwner = psb;
1884 view_params.prcView = prcView;
1885 view_params.pvid = NULL;
1886 view_params.hwndView = 0;
1888 TRACE("(%p) Forwarding to CreateViewWindow2\n", iface);
1890 hr = IShellView2_CreateViewWindow2(iface, &view_params);
1891 *phWnd = view_params.hwndView;
1896 static HRESULT WINAPI IShellView_fnDestroyViewWindow(IShellView2 * iface)
1898 IShellViewImpl *This = (IShellViewImpl *)iface;
1900 TRACE("(%p)\n",This);
1902 /*Make absolutely sure all our UI is cleaned up.*/
1903 IShellView_UIActivate((IShellView*)This, SVUIA_DEACTIVATE);
1907 DestroyMenu(This->hMenu);
1910 DestroyWindow(This->hWnd);
1911 if(This->pShellBrowser) IShellBrowser_Release(This->pShellBrowser);
1912 if(This->pCommDlgBrowser) ICommDlgBrowser_Release(This->pCommDlgBrowser);
1918 static HRESULT WINAPI IShellView_fnGetCurrentInfo(IShellView2 * iface, LPFOLDERSETTINGS lpfs)
1920 IShellViewImpl *This = (IShellViewImpl *)iface;
1922 TRACE("(%p)->(%p) vmode=%x flags=%x\n",This, lpfs,
1923 This->FolderSettings.ViewMode, This->FolderSettings.fFlags);
1925 if (!lpfs) return E_INVALIDARG;
1927 *lpfs = This->FolderSettings;
1931 static HRESULT WINAPI IShellView_fnAddPropertySheetPages(IShellView2 * iface, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam)
1933 IShellViewImpl *This = (IShellViewImpl *)iface;
1935 FIXME("(%p) stub\n",This);
1940 static HRESULT WINAPI IShellView_fnSaveViewState(IShellView2 * iface)
1942 IShellViewImpl *This = (IShellViewImpl *)iface;
1944 FIXME("(%p) stub\n",This);
1949 static HRESULT WINAPI IShellView_fnSelectItem(
1950 IShellView2 * iface,
1954 IShellViewImpl *This = (IShellViewImpl *)iface;
1957 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n",This, pidl, uFlags);
1959 i = LV_FindItemByPidl(This, pidl);
1965 if(uFlags & SVSI_ENSUREVISIBLE)
1966 SendMessageW(This->hWndList, LVM_ENSUREVISIBLE, i, 0);
1968 lvItem.mask = LVIF_STATE;
1969 lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
1971 lvItem.iSubItem = 0;
1973 while(SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem))
1975 if (lvItem.iItem == i)
1977 if (uFlags & SVSI_SELECT)
1978 lvItem.state |= LVIS_SELECTED;
1980 lvItem.state &= ~LVIS_SELECTED;
1982 if(uFlags & SVSI_FOCUSED)
1983 lvItem.state &= ~LVIS_FOCUSED;
1987 if (uFlags & SVSI_DESELECTOTHERS)
1988 lvItem.state &= ~LVIS_SELECTED;
1990 SendMessageW(This->hWndList, LVM_SETITEMW, 0, (LPARAM) &lvItem);
1995 if(uFlags & SVSI_EDIT)
1996 SendMessageW(This->hWndList, LVM_EDITLABELW, i, 0);
2002 static HRESULT WINAPI IShellView_fnGetItemObject(IShellView2 * iface, UINT uItem, REFIID riid, LPVOID *ppvOut)
2004 IShellViewImpl *This = (IShellViewImpl *)iface;
2006 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n",This, uItem, debugstr_guid(riid), ppvOut);
2012 case SVGIO_BACKGROUND:
2013 *ppvOut = ISvBgCm_Constructor(This->pSFParent, FALSE);
2016 case SVGIO_SELECTION:
2017 ShellView_GetSelections(This);
2018 IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, (LPCITEMIDLIST*)This->apidl, riid, 0, ppvOut);
2021 TRACE("-- (%p)->(interface=%p)\n",This, *ppvOut);
2023 if(!*ppvOut) return E_OUTOFMEMORY;
2028 static HRESULT WINAPI IShellView2_fnGetView(IShellView2* iface, SHELLVIEWID *view_guid, ULONG view_type)
2030 FIXME("(%p)->(view_guid %s, view_type %#x) stub!\n", iface, debugstr_guid(view_guid), view_type);
2034 static HRESULT WINAPI IShellView2_fnCreateViewWindow2(IShellView2* iface, LPSV2CVW2_PARAMS view_params)
2036 IShellViewImpl *This = (IShellViewImpl *)iface;
2040 TRACE("(%p)->(view_params %p)\n", iface, view_params);
2042 if (view_params->cbSize != sizeof(*view_params))
2044 FIXME("Got unexpected cbSize %#x\n", view_params->cbSize);
2048 TRACE("-- psvPrev %p, pfs %p, psbOwner %p, prcView %p\n",
2049 view_params->psvPrev, view_params->pfs, view_params->psbOwner, view_params->prcView);
2050 TRACE("-- vmode %#x, flags %#x, left %d, top %d, right %d, bottom %d\n",
2051 view_params->pfs->ViewMode, view_params->pfs->fFlags, view_params->prcView->left,
2052 view_params->prcView->top, view_params->prcView->right, view_params->prcView->bottom);
2054 /* Set up the member variables */
2055 This->pShellBrowser = view_params->psbOwner;
2056 This->FolderSettings = *view_params->pfs;
2058 if (view_params->pvid)
2060 if (IsEqualGUID(view_params->pvid, &VID_LargeIcons))
2061 This->FolderSettings.ViewMode = FVM_ICON;
2062 else if (IsEqualGUID(view_params->pvid, &VID_SmallIcons))
2063 This->FolderSettings.ViewMode = FVM_SMALLICON;
2064 else if (IsEqualGUID(view_params->pvid, &VID_List))
2065 This->FolderSettings.ViewMode = FVM_LIST;
2066 else if (IsEqualGUID(view_params->pvid, &VID_Details))
2067 This->FolderSettings.ViewMode = FVM_DETAILS;
2068 else if (IsEqualGUID(view_params->pvid, &VID_Thumbnails))
2069 This->FolderSettings.ViewMode = FVM_THUMBNAIL;
2070 else if (IsEqualGUID(view_params->pvid, &VID_Tile))
2071 This->FolderSettings.ViewMode = FVM_TILE;
2072 else if (IsEqualGUID(view_params->pvid, &VID_ThumbStrip))
2073 This->FolderSettings.ViewMode = FVM_THUMBSTRIP;
2075 FIXME("Ignoring unrecognized VID %s\n", debugstr_guid(view_params->pvid));
2078 /* Get our parent window */
2079 IShellBrowser_AddRef(This->pShellBrowser);
2080 IShellBrowser_GetWindow(This->pShellBrowser, &(This->hWndParent));
2082 /* Try to get the ICommDlgBrowserInterface, adds a reference !!! */
2083 This->pCommDlgBrowser = NULL;
2084 if (SUCCEEDED(IShellBrowser_QueryInterface(This->pShellBrowser, &IID_ICommDlgBrowser, (void **)&This->pCommDlgBrowser)))
2086 TRACE("-- CommDlgBrowser %p\n", This->pCommDlgBrowser);
2089 /* If our window class has not been registered, then do so */
2090 if (!GetClassInfoW(shell32_hInstance, SV_CLASS_NAME, &wc))
2092 ZeroMemory(&wc, sizeof(wc));
2093 wc.style = CS_HREDRAW | CS_VREDRAW;
2094 wc.lpfnWndProc = ShellView_WndProc;
2097 wc.hInstance = shell32_hInstance;
2099 wc.hCursor = LoadCursorW(0, (LPWSTR)IDC_ARROW);
2100 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
2101 wc.lpszMenuName = NULL;
2102 wc.lpszClassName = SV_CLASS_NAME;
2104 if (!RegisterClassW(&wc)) return E_FAIL;
2107 wnd = CreateWindowExW(0, SV_CLASS_NAME, NULL, WS_CHILD | WS_TABSTOP,
2108 view_params->prcView->left, view_params->prcView->top,
2109 view_params->prcView->right - view_params->prcView->left,
2110 view_params->prcView->bottom - view_params->prcView->top,
2111 This->hWndParent, 0, shell32_hInstance, This);
2115 if (!wnd) return E_FAIL;
2117 SetWindowPos(wnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
2120 view_params->hwndView = wnd;
2125 static HRESULT WINAPI IShellView2_fnHandleRename(IShellView2* iface, LPCITEMIDLIST new_pidl)
2127 FIXME("(%p)->(new_pidl %p) stub!\n", iface, new_pidl);
2131 static HRESULT WINAPI IShellView2_fnSelectAndPositionItem(IShellView2* iface, LPCITEMIDLIST item, UINT flags, POINT *point)
2133 FIXME("(%p)->(item %p, flags %#x, point %p) stub!\n", iface, item, flags, point);
2137 static const IShellView2Vtbl svvt =
2139 IShellView_fnQueryInterface,
2140 IShellView_fnAddRef,
2141 IShellView_fnRelease,
2142 IShellView_fnGetWindow,
2143 IShellView_fnContextSensitiveHelp,
2144 IShellView_fnTranslateAccelerator,
2145 IShellView_fnEnableModeless,
2146 IShellView_fnUIActivate,
2147 IShellView_fnRefresh,
2148 IShellView_fnCreateViewWindow,
2149 IShellView_fnDestroyViewWindow,
2150 IShellView_fnGetCurrentInfo,
2151 IShellView_fnAddPropertySheetPages,
2152 IShellView_fnSaveViewState,
2153 IShellView_fnSelectItem,
2154 IShellView_fnGetItemObject,
2155 IShellView2_fnGetView,
2156 IShellView2_fnCreateViewWindow2,
2157 IShellView2_fnHandleRename,
2158 IShellView2_fnSelectAndPositionItem,
2162 /**********************************************************
2163 * ISVOleCmdTarget_QueryInterface (IUnknown)
2165 static HRESULT WINAPI ISVOleCmdTarget_QueryInterface(
2166 IOleCommandTarget * iface,
2170 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2172 return IShellFolder_QueryInterface((IShellFolder*)This, iid, ppvObj);
2175 /**********************************************************
2176 * ISVOleCmdTarget_AddRef (IUnknown)
2178 static ULONG WINAPI ISVOleCmdTarget_AddRef(
2179 IOleCommandTarget * iface)
2181 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2183 return IShellFolder_AddRef((IShellFolder*)This);
2186 /**********************************************************
2187 * ISVOleCmdTarget_Release (IUnknown)
2189 static ULONG WINAPI ISVOleCmdTarget_Release(
2190 IOleCommandTarget * iface)
2192 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2194 return IShellFolder_Release((IShellFolder*)This);
2197 /**********************************************************
2198 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2200 static HRESULT WINAPI ISVOleCmdTarget_QueryStatus(
2201 IOleCommandTarget *iface,
2202 const GUID* pguidCmdGroup,
2205 OLECMDTEXT* pCmdText)
2208 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2210 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
2211 This, pguidCmdGroup, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText);
2215 for (i = 0; i < cCmds; i++)
2217 FIXME("\tprgCmds[%d].cmdID = %d\n", i, prgCmds[i].cmdID);
2218 prgCmds[i].cmdf = 0;
2220 return OLECMDERR_E_UNKNOWNGROUP;
2223 /**********************************************************
2224 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2226 * nCmdID is the OLECMDID_* enumeration
2228 static HRESULT WINAPI ISVOleCmdTarget_Exec(
2229 IOleCommandTarget *iface,
2230 const GUID* pguidCmdGroup,
2236 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2238 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2239 This, debugstr_guid(pguidCmdGroup), nCmdID, nCmdexecopt, pvaIn, pvaOut);
2241 if (IsEqualIID(pguidCmdGroup, &CGID_Explorer) &&
2243 (nCmdexecopt == 4) && pvaOut)
2245 if (IsEqualIID(pguidCmdGroup, &CGID_ShellDocView) &&
2250 return OLECMDERR_E_UNKNOWNGROUP;
2253 static const IOleCommandTargetVtbl ctvt =
2255 ISVOleCmdTarget_QueryInterface,
2256 ISVOleCmdTarget_AddRef,
2257 ISVOleCmdTarget_Release,
2258 ISVOleCmdTarget_QueryStatus,
2259 ISVOleCmdTarget_Exec
2262 /**********************************************************
2263 * ISVDropTarget implementation
2266 static HRESULT WINAPI ISVDropTarget_QueryInterface(
2271 IShellViewImpl *This = impl_from_IDropTarget(iface);
2273 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2275 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2278 static ULONG WINAPI ISVDropTarget_AddRef( IDropTarget *iface)
2280 IShellViewImpl *This = impl_from_IDropTarget(iface);
2282 TRACE("(%p)->(count=%u)\n",This,This->ref);
2284 return IShellFolder_AddRef((IShellFolder*)This);
2287 static ULONG WINAPI ISVDropTarget_Release( IDropTarget *iface)
2289 IShellViewImpl *This = impl_from_IDropTarget(iface);
2291 TRACE("(%p)->(count=%u)\n",This,This->ref);
2293 return IShellFolder_Release((IShellFolder*)This);
2296 /******************************************************************************
2297 * drag_notify_subitem [Internal]
2299 * Figure out the shellfolder object, which is currently under the mouse cursor
2300 * and notify it via the IDropTarget interface.
2303 #define SCROLLAREAWIDTH 20
2305 static HRESULT drag_notify_subitem(IShellViewImpl *This, DWORD grfKeyState, POINTL pt,
2308 LVHITTESTINFO htinfo;
2314 /* Map from global to client coordinates and query the index of the listview-item, which is
2315 * currently under the mouse cursor. */
2318 htinfo.flags = LVHT_ONITEM;
2319 ScreenToClient(This->hWndList, &htinfo.pt);
2320 lResult = SendMessageW(This->hWndList, LVM_HITTEST, 0, (LPARAM)&htinfo);
2322 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2323 GetClientRect(This->hWndList, &clientRect);
2324 if (htinfo.pt.x == This->ptLastMousePos.x && htinfo.pt.y == This->ptLastMousePos.y &&
2325 (htinfo.pt.x < SCROLLAREAWIDTH || htinfo.pt.x > clientRect.right - SCROLLAREAWIDTH ||
2326 htinfo.pt.y < SCROLLAREAWIDTH || htinfo.pt.y > clientRect.bottom - SCROLLAREAWIDTH ))
2328 This->cScrollDelay = (This->cScrollDelay + 1) % 5; /* DragOver is called every 50 ms */
2329 if (This->cScrollDelay == 0) { /* Mouse did hover another 250 ms over the scroll-area */
2330 if (htinfo.pt.x < SCROLLAREAWIDTH)
2331 SendMessageW(This->hWndList, WM_HSCROLL, SB_LINEUP, 0);
2332 if (htinfo.pt.x > clientRect.right - SCROLLAREAWIDTH)
2333 SendMessageW(This->hWndList, WM_HSCROLL, SB_LINEDOWN, 0);
2334 if (htinfo.pt.y < SCROLLAREAWIDTH)
2335 SendMessageW(This->hWndList, WM_VSCROLL, SB_LINEUP, 0);
2336 if (htinfo.pt.y > clientRect.bottom - SCROLLAREAWIDTH)
2337 SendMessageW(This->hWndList, WM_VSCROLL, SB_LINEDOWN, 0);
2340 This->cScrollDelay = 0; /* Reset, if the cursor is not over the listview's scroll-area */
2342 This->ptLastMousePos = htinfo.pt;
2344 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2345 if (This->pCurDropTarget && lResult == This->iDragOverItem)
2346 return IDropTarget_DragOver(This->pCurDropTarget, grfKeyState, pt, pdwEffect);
2348 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2349 if (This->pCurDropTarget) {
2350 IDropTarget_DragLeave(This->pCurDropTarget);
2351 IDropTarget_Release(This->pCurDropTarget);
2352 This->pCurDropTarget = NULL;
2355 This->iDragOverItem = lResult;
2356 if (lResult == -1) {
2357 /* We are not above one of the listview's subitems. Bind to the parent folder's
2358 * DropTarget interface. */
2359 hr = IShellFolder_QueryInterface(This->pSFParent, &IID_IDropTarget,
2360 (LPVOID*)&This->pCurDropTarget);
2362 /* Query the relative PIDL of the shellfolder object represented by the currently
2363 * dragged over listview-item ... */
2364 lvItem.mask = LVIF_PARAM;
2365 lvItem.iItem = lResult;
2366 lvItem.iSubItem = 0;
2367 SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem);
2369 /* ... and bind pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2370 hr = IShellFolder_GetUIObjectOf(This->pSFParent, This->hWndList, 1,
2371 (LPCITEMIDLIST*)&lvItem.lParam, &IID_IDropTarget, NULL, (LPVOID*)&This->pCurDropTarget);
2374 /* If anything failed, pCurDropTarget should be NULL now, which ought to be a save state. */
2378 /* Notify the item just entered via DragEnter. */
2379 return IDropTarget_DragEnter(This->pCurDropTarget, This->pCurDataObject, grfKeyState, pt, pdwEffect);
2382 static HRESULT WINAPI ISVDropTarget_DragEnter(IDropTarget *iface, IDataObject *pDataObject,
2383 DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
2385 IShellViewImpl *This = impl_from_IDropTarget(iface);
2387 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2388 This->pCurDataObject = pDataObject;
2389 IDataObject_AddRef(pDataObject);
2391 return drag_notify_subitem(This, grfKeyState, pt, pdwEffect);
2394 static HRESULT WINAPI ISVDropTarget_DragOver(IDropTarget *iface, DWORD grfKeyState, POINTL pt,
2397 IShellViewImpl *This = impl_from_IDropTarget(iface);
2398 return drag_notify_subitem(This, grfKeyState, pt, pdwEffect);
2401 static HRESULT WINAPI ISVDropTarget_DragLeave(IDropTarget *iface) {
2402 IShellViewImpl *This = impl_from_IDropTarget(iface);
2404 IDropTarget_DragLeave(This->pCurDropTarget);
2406 IDropTarget_Release(This->pCurDropTarget);
2407 IDataObject_Release(This->pCurDataObject);
2408 This->pCurDataObject = NULL;
2409 This->pCurDropTarget = NULL;
2410 This->iDragOverItem = 0;
2415 static HRESULT WINAPI ISVDropTarget_Drop(IDropTarget *iface, IDataObject* pDataObject,
2416 DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
2418 IShellViewImpl *This = impl_from_IDropTarget(iface);
2420 IDropTarget_Drop(This->pCurDropTarget, pDataObject, grfKeyState, pt, pdwEffect);
2422 IDropTarget_Release(This->pCurDropTarget);
2423 IDataObject_Release(This->pCurDataObject);
2424 This->pCurDataObject = NULL;
2425 This->pCurDropTarget = NULL;
2426 This->iDragOverItem = 0;
2431 static const IDropTargetVtbl dtvt =
2433 ISVDropTarget_QueryInterface,
2434 ISVDropTarget_AddRef,
2435 ISVDropTarget_Release,
2436 ISVDropTarget_DragEnter,
2437 ISVDropTarget_DragOver,
2438 ISVDropTarget_DragLeave,
2442 /**********************************************************
2443 * ISVDropSource implementation
2446 static HRESULT WINAPI ISVDropSource_QueryInterface(
2451 IShellViewImpl *This = impl_from_IDropSource(iface);
2453 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2455 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2458 static ULONG WINAPI ISVDropSource_AddRef( IDropSource *iface)
2460 IShellViewImpl *This = impl_from_IDropSource(iface);
2462 TRACE("(%p)->(count=%u)\n",This,This->ref);
2464 return IShellFolder_AddRef((IShellFolder*)This);
2467 static ULONG WINAPI ISVDropSource_Release( IDropSource *iface)
2469 IShellViewImpl *This = impl_from_IDropSource(iface);
2471 TRACE("(%p)->(count=%u)\n",This,This->ref);
2473 return IShellFolder_Release((IShellFolder*)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 IShellFolder_QueryInterface((IShellFolder*)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 IShellFolder_AddRef((IShellFolder*)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 IShellFolder_Release((IShellFolder*)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