4 * Copyright 1998,1999 <juergen.schmied@debitel.net>
6 * This is the view visualizing the data provied 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 * FIXME: The order by part of the background context menu should be
24 * buily according to the columns shown.
26 * FIXME: Load/Save the view state from/into the stream provied 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);
75 }LISTVIEW_SORT_INFO, *LPLISTVIEW_SORT_INFO;
79 const IShellViewVtbl* lpVtbl;
81 const IOleCommandTargetVtbl* lpvtblOleCommandTarget;
82 const IDropTargetVtbl* lpvtblDropTarget;
83 const IDropSourceVtbl* lpvtblDropSource;
84 const IViewObjectVtbl* lpvtblViewObject;
85 IShellFolder* pSFParent;
86 IShellFolder2* pSF2Parent;
87 IShellBrowser* pShellBrowser;
88 ICommDlgBrowser* pCommDlgBrowser;
89 HWND hWnd; /* SHELLDLL_DefView */
90 HWND hWndList; /* ListView control */
92 FOLDERSETTINGS FolderSettings;
97 LISTVIEW_SORT_INFO ListViewSortInfo;
98 ULONG hNotify; /* change notification handle */
102 IAdviseSink *pAdvSink;
103 IDropTarget* pCurDropTarget; /* The sub-item, which is currently dragged over */
104 IDataObject* pCurDataObject; /* The dragged data-object */
105 LONG iDragOverItem; /* Dragged over item's index, iff pCurDropTarget != NULL */
108 static const IShellViewVtbl svvt;
109 static const IOleCommandTargetVtbl ctvt;
110 static const IDropTargetVtbl dtvt;
111 static const IDropSourceVtbl dsvt;
112 static const IViewObjectVtbl vovt;
115 static inline IShellViewImpl *impl_from_IOleCommandTarget( IOleCommandTarget *iface )
117 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblOleCommandTarget));
120 static inline IShellViewImpl *impl_from_IDropTarget( IDropTarget *iface )
122 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblDropTarget));
125 static inline IShellViewImpl *impl_from_IDropSource( IDropSource *iface )
127 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblDropSource));
130 static inline IShellViewImpl *impl_from_IViewObject( IViewObject *iface )
132 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblViewObject));
135 /* ListView Header ID's */
136 #define LISTVIEW_COLUMN_NAME 0
137 #define LISTVIEW_COLUMN_SIZE 1
138 #define LISTVIEW_COLUMN_TYPE 2
139 #define LISTVIEW_COLUMN_TIME 3
140 #define LISTVIEW_COLUMN_ATTRIB 4
143 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
144 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
145 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
147 #define ID_LISTVIEW 2000
149 #define SHV_CHANGE_NOTIFY WM_USER + 0x1111
152 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
153 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
154 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
157 Items merged into the toolbar and and the filemenu
166 } MYTOOLINFO, *LPMYTOOLINFO;
170 { FCIDM_SHVIEW_BIGICON, 0, 0, IDS_VIEW_LARGE, TBSTATE_ENABLED, BTNS_BUTTON },
171 { FCIDM_SHVIEW_SMALLICON, 0, 0, IDS_VIEW_SMALL, TBSTATE_ENABLED, BTNS_BUTTON },
172 { FCIDM_SHVIEW_LISTVIEW, 0, 0, IDS_VIEW_LIST, TBSTATE_ENABLED, BTNS_BUTTON },
173 { FCIDM_SHVIEW_REPORTVIEW, 0, 0, IDS_VIEW_DETAILS, TBSTATE_ENABLED, BTNS_BUTTON },
177 typedef void (CALLBACK *PFNSHGETSETTINGSPROC)(LPSHELLFLAGSTATE lpsfs, DWORD dwMask);
179 /**********************************************************
180 * IShellView_Constructor
182 IShellView * IShellView_Constructor( IShellFolder * pFolder)
183 { IShellViewImpl * sv;
184 sv=HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IShellViewImpl));
187 sv->lpvtblOleCommandTarget=&ctvt;
188 sv->lpvtblDropTarget=&dtvt;
189 sv->lpvtblDropSource=&dsvt;
190 sv->lpvtblViewObject=&vovt;
192 sv->pSFParent = pFolder;
193 if(pFolder) IShellFolder_AddRef(pFolder);
194 IShellFolder_QueryInterface(sv->pSFParent, &IID_IShellFolder2, (LPVOID*)&sv->pSF2Parent);
196 sv->pCurDropTarget = NULL;
197 sv->pCurDataObject = NULL;
198 sv->iDragOverItem = 0;
200 TRACE("(%p)->(%p)\n",sv, pFolder);
201 return (IShellView *) sv;
204 /**********************************************************
206 * ##### helperfunctions for communication with ICommDlgBrowser #####
208 static BOOL IsInCommDlg(IShellViewImpl * This)
209 { return(This->pCommDlgBrowser != NULL);
212 static HRESULT IncludeObject(IShellViewImpl * This, LPCITEMIDLIST pidl)
216 if ( IsInCommDlg(This) )
218 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl);
219 ret = ICommDlgBrowser_IncludeObject(This->pCommDlgBrowser, (IShellView*)This, pidl);
220 TRACE("--0x%08lx\n", ret);
225 static HRESULT OnDefaultCommand(IShellViewImpl * This)
227 HRESULT ret = S_FALSE;
229 if (IsInCommDlg(This))
231 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
232 ret = ICommDlgBrowser_OnDefaultCommand(This->pCommDlgBrowser, (IShellView*)This);
233 TRACE("-- returns %08lx\n", ret);
238 static HRESULT OnStateChange(IShellViewImpl * This, UINT uFlags)
240 HRESULT ret = S_FALSE;
242 if (IsInCommDlg(This))
244 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags);
245 ret = ICommDlgBrowser_OnStateChange(This->pCommDlgBrowser, (IShellView*)This, uFlags);
250 /**********************************************************
251 * set the toolbar of the filedialog buttons
253 * - activates the buttons from the shellbrowser according to
256 static void CheckToolbar(IShellViewImpl * This)
262 if (IsInCommDlg(This))
264 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
265 FCIDM_TB_SMALLICON, (This->FolderSettings.ViewMode==FVM_LIST)? TRUE : FALSE, &result);
266 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
267 FCIDM_TB_REPORTVIEW, (This->FolderSettings.ViewMode==FVM_DETAILS)? TRUE : FALSE, &result);
268 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
269 FCIDM_TB_SMALLICON, TRUE, &result);
270 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
271 FCIDM_TB_REPORTVIEW, TRUE, &result);
275 /**********************************************************
277 * ##### helperfunctions for initializing the view #####
279 /**********************************************************
280 * change the style of the listview control
282 static void SetStyle(IShellViewImpl * This, DWORD dwAdd, DWORD dwRemove)
286 TRACE("(%p)\n", This);
288 tmpstyle = GetWindowLongA(This->hWndList, GWL_STYLE);
289 SetWindowLongA(This->hWndList, GWL_STYLE, dwAdd | (tmpstyle & ~dwRemove));
292 /**********************************************************
293 * ShellView_CreateList()
295 * - creates the list view window
297 static BOOL ShellView_CreateList (IShellViewImpl * This)
298 { DWORD dwStyle, dwExStyle;
302 dwStyle = WS_TABSTOP | WS_VISIBLE | WS_CHILDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
303 LVS_SHAREIMAGELISTS | LVS_EDITLABELS | LVS_ALIGNLEFT | LVS_AUTOARRANGE;
304 dwExStyle = WS_EX_CLIENTEDGE;
306 switch (This->FolderSettings.ViewMode)
308 case FVM_ICON: dwStyle |= LVS_ICON; break;
309 case FVM_DETAILS: dwStyle |= LVS_REPORT; break;
310 case FVM_SMALLICON: dwStyle |= LVS_SMALLICON; break;
311 case FVM_LIST: dwStyle |= LVS_LIST; break;
312 default: dwStyle |= LVS_LIST; break;
315 if (This->FolderSettings.fFlags & FWF_AUTOARRANGE) dwStyle |= LVS_AUTOARRANGE;
316 if (This->FolderSettings.fFlags & FWF_DESKTOP)
317 This->FolderSettings.fFlags |= FWF_NOCLIENTEDGE | FWF_NOSCROLL;
318 if (This->FolderSettings.fFlags & FWF_SINGLESEL) dwStyle |= LVS_SINGLESEL;
319 if (This->FolderSettings.fFlags & FWF_NOCLIENTEDGE)
320 dwExStyle &= ~WS_EX_CLIENTEDGE;
322 This->hWndList=CreateWindowExA( dwExStyle,
335 This->ListViewSortInfo.bIsAscending = TRUE;
336 This->ListViewSortInfo.nHeaderID = -1;
337 This->ListViewSortInfo.nLastHeaderID = -1;
339 if (This->FolderSettings.fFlags & FWF_DESKTOP) {
340 if (0) /* FIXME: look into registry vale HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ListviewShadow and activate drop shadows */
341 ListView_SetTextBkColor(This->hWndList, CLR_NONE);
343 ListView_SetTextBkColor(This->hWndList, GetSysColor(COLOR_DESKTOP));
345 ListView_SetTextColor(This->hWndList, RGB(255,255,255));
348 /* UpdateShellSettings(); */
352 /**********************************************************
353 * ShellView_InitList()
355 * - adds all needed columns to the shellview
357 static BOOL ShellView_InitList(IShellViewImpl * This)
366 ListView_DeleteAllItems(This->hWndList);
368 lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT;
369 lvColumn.pszText = szTemp;
371 if (This->pSF2Parent)
375 if (!SUCCEEDED(IShellFolder2_GetDetailsOf(This->pSF2Parent, NULL, i, &sd)))
377 lvColumn.fmt = sd.fmt;
378 lvColumn.cx = sd.cxChar*8; /* chars->pixel */
379 StrRetToStrNA( szTemp, 50, &sd.str, NULL);
380 ListView_InsertColumnA(This->hWndList, i, &lvColumn);
388 ListView_SetImageList(This->hWndList, ShellSmallIconList, LVSIL_SMALL);
389 ListView_SetImageList(This->hWndList, ShellBigIconList, LVSIL_NORMAL);
393 /**********************************************************
394 * ShellView_CompareItems()
397 * internal, CALLBACK for DSA_Sort
399 static INT CALLBACK ShellView_CompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
402 TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1, lParam2, (LPVOID) lpData);
404 if(!lpData) return 0;
406 ret = (SHORT) SCODE_CODE(IShellFolder_CompareIDs((LPSHELLFOLDER)lpData, 0, (LPITEMIDLIST)lParam1, (LPITEMIDLIST)lParam2));
407 TRACE("ret=%i\n",ret);
411 /*************************************************************************
412 * ShellView_ListViewCompareItems
414 * Compare Function for the Listview (FileOpen Dialog)
417 * lParam1 [I] the first ItemIdList to compare with
418 * lParam2 [I] the second ItemIdList to compare with
419 * lpData [I] The column ID for the header Ctrl to process
422 * A negative value if the first item should precede the second,
423 * a positive value if the first item should follow the second,
424 * or zero if the two items are equivalent
427 * FIXME: function does what ShellView_CompareItems is supposed to do.
428 * unify it and figure out how to use the undocumented first parameter
429 * of IShellFolder_CompareIDs to do the job this function does and
430 * move this code to IShellFolder.
431 * make LISTVIEW_SORT_INFO obsolete
432 * the way this function works is only usable if we had only
433 * filesystemfolders (25/10/99 jsch)
435 static INT CALLBACK ShellView_ListViewCompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
439 char strName1[MAX_PATH], strName2[MAX_PATH];
440 BOOL bIsFolder1, bIsFolder2,bIsBothFolder;
441 LPITEMIDLIST pItemIdList1 = (LPITEMIDLIST) lParam1;
442 LPITEMIDLIST pItemIdList2 = (LPITEMIDLIST) lParam2;
443 LISTVIEW_SORT_INFO *pSortInfo = (LPLISTVIEW_SORT_INFO) lpData;
446 bIsFolder1 = _ILIsFolder(pItemIdList1);
447 bIsFolder2 = _ILIsFolder(pItemIdList2);
448 bIsBothFolder = bIsFolder1 && bIsFolder2;
450 /* When sorting between a File and a Folder, the Folder gets sorted first */
451 if( (bIsFolder1 || bIsFolder2) && !bIsBothFolder)
453 nDiff = bIsFolder1 ? -1 : 1;
457 /* Sort by Time: Folders or Files can be sorted */
459 if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TIME)
461 _ILGetFileDateTime(pItemIdList1, &fd1);
462 _ILGetFileDateTime(pItemIdList2, &fd2);
463 nDiff = CompareFileTime(&fd2, &fd1);
465 /* Sort by Attribute: Folder or Files can be sorted */
466 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_ATTRIB)
468 _ILGetFileAttributes(pItemIdList1, strName1, MAX_PATH);
469 _ILGetFileAttributes(pItemIdList2, strName2, MAX_PATH);
470 nDiff = lstrcmpiA(strName1, strName2);
472 /* Sort by FileName: Folder or Files can be sorted */
473 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_NAME || bIsBothFolder)
476 _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
477 _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
478 nDiff = lstrcmpiA(strName1, strName2);
480 /* Sort by File Size, Only valid for Files */
481 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_SIZE)
483 nDiff = (INT)(_ILGetFileSize(pItemIdList1, NULL, 0) - _ILGetFileSize(pItemIdList2, NULL, 0));
485 /* Sort by File Type, Only valid for Files */
486 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TYPE)
489 _ILGetFileType(pItemIdList1, strName1, MAX_PATH);
490 _ILGetFileType(pItemIdList2, strName2, MAX_PATH);
491 nDiff = lstrcmpiA(strName1, strName2);
494 /* If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
498 _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
499 _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
500 nDiff = lstrcmpiA(strName1, strName2);
503 if(!pSortInfo->bIsAscending)
512 /**********************************************************
513 * LV_FindItemByPidl()
515 static int LV_FindItemByPidl(
516 IShellViewImpl * This,
520 ZeroMemory(&lvItem, sizeof(LVITEMA));
521 lvItem.mask = LVIF_PARAM;
522 for(lvItem.iItem = 0; ListView_GetItemA(This->hWndList, &lvItem); lvItem.iItem++)
524 LPITEMIDLIST currentpidl = (LPITEMIDLIST) lvItem.lParam;
525 HRESULT hr = IShellFolder_CompareIDs(This->pSFParent, 0, pidl, currentpidl);
526 if(SUCCEEDED(hr) && !HRESULT_CODE(hr))
534 /**********************************************************
537 static BOOLEAN LV_AddItem(IShellViewImpl * This, LPCITEMIDLIST pidl)
541 TRACE("(%p)(pidl=%p)\n", This, pidl);
543 ZeroMemory(&lvItem, sizeof(lvItem)); /* create the listview item*/
544 lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; /*set the mask*/
545 lvItem.iItem = ListView_GetItemCount(This->hWndList); /*add the item to the end of the list*/
546 lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidl)); /*set the item's data*/
547 lvItem.pszText = LPSTR_TEXTCALLBACKA; /*get text on a callback basis*/
548 lvItem.iImage = I_IMAGECALLBACK; /*get the image on a callback basis*/
549 return (-1==ListView_InsertItemA(This->hWndList, &lvItem))? FALSE: TRUE;
552 /**********************************************************
555 static BOOLEAN LV_DeleteItem(IShellViewImpl * This, LPCITEMIDLIST pidl)
559 TRACE("(%p)(pidl=%p)\n", This, pidl);
561 nIndex = LV_FindItemByPidl(This, ILFindLastID(pidl));
562 return (-1==ListView_DeleteItem(This->hWndList, nIndex))? FALSE: TRUE;
565 /**********************************************************
568 static BOOLEAN LV_RenameItem(IShellViewImpl * This, LPCITEMIDLIST pidlOld, LPCITEMIDLIST pidlNew )
573 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", This, pidlOld, pidlNew);
575 nItem = LV_FindItemByPidl(This, ILFindLastID(pidlOld));
578 ZeroMemory(&lvItem, sizeof(lvItem)); /* create the listview item*/
579 lvItem.mask = LVIF_PARAM; /* only the pidl */
580 lvItem.iItem = nItem;
581 ListView_GetItemA(This->hWndList, &lvItem);
583 SHFree((LPITEMIDLIST)lvItem.lParam);
584 lvItem.mask = LVIF_PARAM;
585 lvItem.iItem = nItem;
586 lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidlNew)); /* set the item's data */
587 ListView_SetItemA(This->hWndList, &lvItem);
588 ListView_Update(This->hWndList, nItem);
589 return TRUE; /* FIXME: better handling */
593 /**********************************************************
594 * ShellView_FillList()
596 * - gets the objectlist from the shellfolder
598 * - fills the list into the view
601 static INT CALLBACK fill_list( LPVOID ptr, LPVOID arg )
603 LPITEMIDLIST pidl = ptr;
604 IShellViewImpl *This = arg;
605 /* in a commdlg This works as a filemask*/
606 if ( IncludeObject(This, pidl)==S_OK ) LV_AddItem(This, pidl);
611 static HRESULT ShellView_FillList(IShellViewImpl * This)
613 LPENUMIDLIST pEnumIDList;
621 /* get the itemlist from the shfolder*/
622 hRes = IShellFolder_EnumObjects(This->pSFParent,This->hWnd, SHCONTF_NONFOLDERS | SHCONTF_FOLDERS, &pEnumIDList);
630 /* create a pointer array */
631 hdpa = DPA_Create(16);
634 return(E_OUTOFMEMORY);
637 /* copy the items into the array*/
638 while((S_OK == IEnumIDList_Next(pEnumIDList,1, &pidl, &dwFetched)) && dwFetched)
640 if (DPA_InsertPtr(hdpa, 0x7fff, pidl) == -1)
647 DPA_Sort(hdpa, ShellView_CompareItems, (LPARAM)This->pSFParent);
649 /*turn the listview's redrawing off*/
650 SendMessageA(This->hWndList, WM_SETREDRAW, FALSE, 0);
652 DPA_DestroyCallback( hdpa, fill_list, This );
654 /*turn the listview's redrawing back on and force it to draw*/
655 SendMessageA(This->hWndList, WM_SETREDRAW, TRUE, 0);
657 IEnumIDList_Release(pEnumIDList); /* destroy the list*/
662 /**********************************************************
663 * ShellView_OnCreate()
665 static LRESULT ShellView_OnCreate(IShellViewImpl * This)
668 SHChangeNotifyEntry ntreg;
669 IPersistFolder2 * ppf2 = NULL;
673 if(ShellView_CreateList(This))
675 if(ShellView_InitList(This))
677 ShellView_FillList(This);
681 if (SUCCEEDED(IUnknown_QueryInterface((IUnknown*)&This->lpVtbl, &IID_IDropTarget, (LPVOID*)&pdt)))
683 RegisterDragDrop(This->hWnd, pdt);
684 IDropTarget_Release(pdt);
687 /* register for receiving notifications */
688 IShellFolder_QueryInterface(This->pSFParent, &IID_IPersistFolder2, (LPVOID*)&ppf2);
691 IPersistFolder2_GetCurFolder(ppf2, (LPITEMIDLIST*)&ntreg.pidl);
692 ntreg.fRecursive = TRUE;
693 This->hNotify = SHChangeNotifyRegister(This->hWnd, SHCNF_IDLIST, SHCNE_ALLEVENTS, SHV_CHANGE_NOTIFY, 1, &ntreg);
694 SHFree((LPITEMIDLIST)ntreg.pidl);
695 IPersistFolder2_Release(ppf2);
698 This->hAccel = LoadAcceleratorsA(shell32_hInstance, "shv_accel");
703 /**********************************************************
704 * #### Handling of the menus ####
707 /**********************************************************
708 * ShellView_BuildFileMenu()
710 static HMENU ShellView_BuildFileMenu(IShellViewImpl * This)
711 { CHAR szText[MAX_PATH];
716 TRACE("(%p)\n",This);
718 hSubMenu = CreatePopupMenu();
720 { /*get the number of items in our global array*/
721 for(nTools = 0; Tools[nTools].idCommand != -1; nTools++){}
723 /*add the menu items*/
724 for(i = 0; i < nTools; i++)
726 LoadStringA(shell32_hInstance, Tools[i].idMenuString, szText, MAX_PATH);
728 ZeroMemory(&mii, sizeof(mii));
729 mii.cbSize = sizeof(mii);
730 mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
732 if(BTNS_SEP != Tools[i].bStyle) /* no separator*/
734 mii.fType = MFT_STRING;
735 mii.fState = MFS_ENABLED;
736 mii.dwTypeData = szText;
737 mii.wID = Tools[i].idCommand;
741 mii.fType = MFT_SEPARATOR;
743 /* tack This item onto the end of the menu */
744 InsertMenuItemA(hSubMenu, (UINT)-1, TRUE, &mii);
747 TRACE("-- return (menu=%p)\n",hSubMenu);
750 /**********************************************************
751 * ShellView_MergeFileMenu()
753 static void ShellView_MergeFileMenu(IShellViewImpl * This, HMENU hSubMenu)
754 { TRACE("(%p)->(submenu=%p) stub\n",This,hSubMenu);
757 { /*insert This item at the beginning of the menu */
758 _InsertMenuItem(hSubMenu, 0, TRUE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
759 _InsertMenuItem(hSubMenu, 0, TRUE, IDM_MYFILEITEM, MFT_STRING, "dummy45", MFS_ENABLED);
765 /**********************************************************
766 * ShellView_MergeViewMenu()
769 static void ShellView_MergeViewMenu(IShellViewImpl * This, HMENU hSubMenu)
772 TRACE("(%p)->(submenu=%p)\n",This,hSubMenu);
775 { /*add a separator at the correct position in the menu*/
776 _InsertMenuItem(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
778 ZeroMemory(&mii, sizeof(mii));
779 mii.cbSize = sizeof(mii);
780 mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_DATA;
781 mii.fType = MFT_STRING;
782 mii.dwTypeData = "View";
783 mii.hSubMenu = LoadMenuA(shell32_hInstance, "MENU_001");
784 InsertMenuItemA(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
788 /**********************************************************
789 * ShellView_GetSelections()
791 * - fills the this->apidl list with the selected objects
794 * number of selected items
796 static UINT ShellView_GetSelections(IShellViewImpl * This)
806 This->cidl = ListView_GetSelectedCount(This->hWndList);
807 This->apidl = (LPITEMIDLIST*)SHAlloc(This->cidl * sizeof(LPITEMIDLIST));
809 TRACE("selected=%i\n", This->cidl);
813 TRACE("-- Items selected =%u\n", This->cidl);
815 ZeroMemory(&lvItem, sizeof(lvItem));
816 lvItem.mask = LVIF_STATE | LVIF_PARAM;
817 lvItem.stateMask = LVIS_SELECTED;
819 while(ListView_GetItemA(This->hWndList, &lvItem) && (i < This->cidl))
821 if(lvItem.state & LVIS_SELECTED)
823 This->apidl[i] = (LPITEMIDLIST)lvItem.lParam;
825 TRACE("-- selected Item found\n");
834 /**********************************************************
835 * ShellView_OpenSelectedItems()
837 static HRESULT ShellView_OpenSelectedItems(IShellViewImpl * This)
839 static UINT CF_IDLIST = 0;
841 IDataObject* selection;
845 LPCITEMIDLIST parent_pidl;
848 if (0 == ShellView_GetSelections(This))
852 hr = IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl,
853 (LPCITEMIDLIST*)This->apidl, &IID_IDataObject,
854 0, (LPVOID *)&selection);
860 CF_IDLIST = RegisterClipboardFormatA(CFSTR_SHELLIDLIST);
862 fetc.cfFormat = CF_IDLIST;
864 fetc.dwAspect = DVASPECT_CONTENT;
866 fetc.tymed = TYMED_HGLOBAL;
868 hr = IDataObject_QueryGetData(selection, &fetc);
872 hr = IDataObject_GetData(selection, &fetc, &stgm);
876 pIDList = GlobalLock(stgm.u.hGlobal);
878 parent_pidl = (LPCITEMIDLIST) ((LPBYTE)pIDList+pIDList->aoffset[0]);
879 for (i = pIDList->cidl; i > 0; --i)
884 pidl = (LPCITEMIDLIST)((LPBYTE)pIDList+pIDList->aoffset[i]);
886 attribs = SFGAO_FOLDER;
887 hr = IShellFolder_GetAttributesOf(This->pSFParent, 1, &pidl, &attribs);
889 if (SUCCEEDED(hr) && ! (attribs & SFGAO_FOLDER))
891 SHELLEXECUTEINFOA shexinfo;
893 shexinfo.cbSize = sizeof(SHELLEXECUTEINFOA);
894 shexinfo.fMask = SEE_MASK_INVOKEIDLIST; /* SEE_MASK_IDLIST is also possible. */
895 shexinfo.hwnd = NULL;
896 shexinfo.lpVerb = NULL;
897 shexinfo.lpFile = NULL;
898 shexinfo.lpParameters = NULL;
899 shexinfo.lpDirectory = NULL;
900 shexinfo.nShow = SW_NORMAL;
901 shexinfo.lpIDList = ILCombine(parent_pidl, pidl);
903 ShellExecuteExA(&shexinfo); /* Discard error/success info */
905 ILFree((LPITEMIDLIST)shexinfo.lpIDList);
909 GlobalUnlock(stgm.u.hGlobal);
910 ReleaseStgMedium(&stgm);
912 IDataObject_Release(selection);
917 /**********************************************************
918 * ShellView_DoContextMenu()
920 static void ShellView_DoContextMenu(IShellViewImpl * This, WORD x, WORD y, BOOL bDefault)
924 BOOL fExplore = FALSE;
926 LPCONTEXTMENU pContextMenu = NULL;
927 IContextMenu2 *pCM = NULL;
928 CMINVOKECOMMANDINFO cmi;
930 TRACE("(%p)->(0x%08x 0x%08x 0x%08x) stub\n",This, x, y, bDefault);
932 /* look, what's selected and create a context menu object of it*/
933 if( ShellView_GetSelections(This) )
935 IShellFolder_GetUIObjectOf( This->pSFParent, This->hWndParent, This->cidl, (LPCITEMIDLIST*)This->apidl,
936 (REFIID)&IID_IContextMenu, NULL, (LPVOID *)&pContextMenu);
940 TRACE("-- pContextMenu\n");
941 hMenu = CreatePopupMenu();
945 /* See if we are in Explore or Open mode. If the browser's tree is present, we are in Explore mode.*/
946 if(SUCCEEDED(IShellBrowser_GetControlWindow(This->pShellBrowser,FCW_TREE, &hwndTree)) && hwndTree)
948 TRACE("-- explore mode\n");
952 /* build the flags depending on what we can do with the selected item */
953 wFlags = CMF_NORMAL | (This->cidl != 1 ? 0 : CMF_CANRENAME) | (fExplore ? CMF_EXPLORE : 0);
955 /* let the ContextMenu merge its items in */
956 if (SUCCEEDED(IContextMenu_QueryContextMenu( pContextMenu, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, wFlags )))
958 if (This->FolderSettings.fFlags & FWF_DESKTOP)
959 SetMenuDefaultItem(hMenu, FCIDM_SHVIEW_OPEN, MF_BYCOMMAND);
963 TRACE("-- get menu default command\n");
964 uCommand = GetMenuDefaultItem(hMenu, FALSE, GMDI_GOINTOPOPUPS);
968 TRACE("-- track popup\n");
969 uCommand = TrackPopupMenu( hMenu,TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
974 TRACE("-- uCommand=%u\n", uCommand);
975 if (uCommand==FCIDM_SHVIEW_OPEN && IsInCommDlg(This))
977 TRACE("-- dlg: OnDefaultCommand\n");
978 if (OnDefaultCommand(This) != S_OK)
980 ShellView_OpenSelectedItems(This);
985 TRACE("-- explore -- invoke command\n");
986 ZeroMemory(&cmi, sizeof(cmi));
987 cmi.cbSize = sizeof(cmi);
988 cmi.hwnd = This->hWndParent; /* this window has to answer CWM_GETISHELLBROWSER */
989 cmi.lpVerb = (LPCSTR)MAKEINTRESOURCEA(uCommand);
990 IContextMenu_InvokeCommand(pContextMenu, &cmi);
997 IContextMenu_Release(pContextMenu);
1000 else /* background context menu */
1002 hMenu = CreatePopupMenu();
1004 pCM = ISvBgCm_Constructor(This->pSFParent, FALSE);
1005 IContextMenu2_QueryContextMenu(pCM, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, 0);
1007 uCommand = TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
1010 TRACE("-- (%p)->(uCommand=0x%08x )\n",This, uCommand);
1012 ZeroMemory(&cmi, sizeof(cmi));
1013 cmi.cbSize = sizeof(cmi);
1014 cmi.lpVerb = (LPCSTR)MAKEINTRESOURCEA(uCommand);
1015 cmi.hwnd = This->hWndParent;
1016 IContextMenu2_InvokeCommand(pCM, &cmi);
1018 IContextMenu2_Release(pCM);
1022 /**********************************************************
1023 * ##### message handling #####
1026 /**********************************************************
1027 * ShellView_OnSize()
1029 static LRESULT ShellView_OnSize(IShellViewImpl * This, WORD wWidth, WORD wHeight)
1031 TRACE("%p width=%u height=%u\n",This, wWidth,wHeight);
1033 /*resize the ListView to fit our window*/
1036 MoveWindow(This->hWndList, 0, 0, wWidth, wHeight, TRUE);
1041 /**********************************************************
1042 * ShellView_OnDeactivate()
1047 static void ShellView_OnDeactivate(IShellViewImpl * This)
1051 if(This->uState != SVUIA_DEACTIVATE)
1055 IShellBrowser_SetMenuSB(This->pShellBrowser,0, 0, 0);
1056 IShellBrowser_RemoveMenusSB(This->pShellBrowser,This->hMenu);
1057 DestroyMenu(This->hMenu);
1061 This->uState = SVUIA_DEACTIVATE;
1065 /**********************************************************
1066 * ShellView_OnActivate()
1068 static LRESULT ShellView_OnActivate(IShellViewImpl * This, UINT uState)
1069 { OLEMENUGROUPWIDTHS omw = { {0, 0, 0, 0, 0, 0} };
1071 CHAR szText[MAX_PATH];
1073 TRACE("%p uState=%x\n",This,uState);
1075 /*don't do anything if the state isn't really changing */
1076 if(This->uState == uState)
1081 ShellView_OnDeactivate(This);
1083 /*only do This if we are active */
1084 if(uState != SVUIA_DEACTIVATE)
1086 /*merge the menus */
1087 This->hMenu = CreateMenu();
1091 IShellBrowser_InsertMenusSB(This->pShellBrowser, This->hMenu, &omw);
1092 TRACE("-- after fnInsertMenusSB\n");
1094 /*build the top level menu get the menu item's text*/
1095 strcpy(szText,"dummy 31");
1097 ZeroMemory(&mii, sizeof(mii));
1098 mii.cbSize = sizeof(mii);
1099 mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_STATE;
1100 mii.fType = MFT_STRING;
1101 mii.fState = MFS_ENABLED;
1102 mii.dwTypeData = szText;
1103 mii.hSubMenu = ShellView_BuildFileMenu(This);
1105 /*insert our menu into the menu bar*/
1108 InsertMenuItemA(This->hMenu, FCIDM_MENU_HELP, FALSE, &mii);
1111 /*get the view menu so we can merge with it*/
1112 ZeroMemory(&mii, sizeof(mii));
1113 mii.cbSize = sizeof(mii);
1114 mii.fMask = MIIM_SUBMENU;
1116 if(GetMenuItemInfoA(This->hMenu, FCIDM_MENU_VIEW, FALSE, &mii))
1118 ShellView_MergeViewMenu(This, mii.hSubMenu);
1121 /*add the items that should only be added if we have the focus*/
1122 if(SVUIA_ACTIVATE_FOCUS == uState)
1124 /*get the file menu so we can merge with it */
1125 ZeroMemory(&mii, sizeof(mii));
1126 mii.cbSize = sizeof(mii);
1127 mii.fMask = MIIM_SUBMENU;
1129 if(GetMenuItemInfoA(This->hMenu, FCIDM_MENU_FILE, FALSE, &mii))
1131 ShellView_MergeFileMenu(This, mii.hSubMenu);
1134 TRACE("-- before fnSetMenuSB\n");
1135 IShellBrowser_SetMenuSB(This->pShellBrowser, This->hMenu, 0, This->hWnd);
1138 This->uState = uState;
1143 /**********************************************************
1144 * ShellView_OnSetFocus()
1147 static LRESULT ShellView_OnSetFocus(IShellViewImpl * This)
1151 /* Tell the browser one of our windows has received the focus. This
1152 should always be done before merging menus (OnActivate merges the
1153 menus) if one of our windows has the focus.*/
1155 IShellBrowser_OnViewWindowActive(This->pShellBrowser,(IShellView*) This);
1156 ShellView_OnActivate(This, SVUIA_ACTIVATE_FOCUS);
1158 /* Set the focus to the listview */
1159 SetFocus(This->hWndList);
1161 /* Notify the ICommDlgBrowser interface */
1162 OnStateChange(This,CDBOSC_SETFOCUS);
1167 /**********************************************************
1168 * ShellView_OnKillFocus()
1170 static LRESULT ShellView_OnKillFocus(IShellViewImpl * This)
1172 TRACE("(%p) stub\n",This);
1174 ShellView_OnActivate(This, SVUIA_ACTIVATE_NOFOCUS);
1175 /* Notify the ICommDlgBrowser */
1176 OnStateChange(This,CDBOSC_KILLFOCUS);
1181 /**********************************************************
1182 * ShellView_OnCommand()
1185 * the CmdID's are the ones from the context menu
1187 static LRESULT ShellView_OnCommand(IShellViewImpl * This,DWORD dwCmdID, DWORD dwCmd, HWND hwndCmd)
1189 TRACE("(%p)->(0x%08lx 0x%08lx %p) stub\n",This, dwCmdID, dwCmd, hwndCmd);
1193 case FCIDM_SHVIEW_SMALLICON:
1194 This->FolderSettings.ViewMode = FVM_SMALLICON;
1195 SetStyle (This, LVS_SMALLICON, LVS_TYPEMASK);
1199 case FCIDM_SHVIEW_BIGICON:
1200 This->FolderSettings.ViewMode = FVM_ICON;
1201 SetStyle (This, LVS_ICON, LVS_TYPEMASK);
1205 case FCIDM_SHVIEW_LISTVIEW:
1206 This->FolderSettings.ViewMode = FVM_LIST;
1207 SetStyle (This, LVS_LIST, LVS_TYPEMASK);
1211 case FCIDM_SHVIEW_REPORTVIEW:
1212 This->FolderSettings.ViewMode = FVM_DETAILS;
1213 SetStyle (This, LVS_REPORT, LVS_TYPEMASK);
1217 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1222 This->ListViewSortInfo.nHeaderID = (LPARAM) (dwCmdID - 0x30);
1223 This->ListViewSortInfo.bIsAscending = TRUE;
1224 This->ListViewSortInfo.nLastHeaderID = This->ListViewSortInfo.nHeaderID;
1225 ListView_SortItems(This->hWndList, ShellView_ListViewCompareItems, (LPARAM) (&(This->ListViewSortInfo)));
1229 TRACE("-- COMMAND 0x%04lx unhandled\n", dwCmdID);
1234 /**********************************************************
1235 * ShellView_OnNotify()
1238 static LRESULT ShellView_OnNotify(IShellViewImpl * This, UINT CtlID, LPNMHDR lpnmh)
1239 { LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)lpnmh;
1240 NMLVDISPINFOA *lpdi = (NMLVDISPINFOA *)lpnmh;
1243 TRACE("%p CtlID=%u lpnmh->code=%x\n",This,CtlID,lpnmh->code);
1248 TRACE("-- NM_SETFOCUS %p\n",This);
1249 ShellView_OnSetFocus(This);
1253 TRACE("-- NM_KILLFOCUS %p\n",This);
1254 ShellView_OnDeactivate(This);
1255 /* Notify the ICommDlgBrowser interface */
1256 OnStateChange(This,CDBOSC_KILLFOCUS);
1260 TRACE("-- NM_CUSTOMDRAW %p\n",This);
1261 return CDRF_DODEFAULT;
1263 case NM_RELEASEDCAPTURE:
1264 TRACE("-- NM_RELEASEDCAPTURE %p\n",This);
1268 TRACE("-- NM_CLICK %p\n",This);
1272 TRACE("-- NM_RCLICK %p\n",This);
1276 TRACE("-- NM_DBLCLK %p\n",This);
1277 if (OnDefaultCommand(This) != S_OK) ShellView_OpenSelectedItems(This);
1281 TRACE("-- NM_DBLCLK %p\n",This);
1282 if (OnDefaultCommand(This) != S_OK) ShellView_OpenSelectedItems(This);
1286 TRACE("-- HDN_ENDTRACKA %p\n",This);
1287 /*nColumn1 = ListView_GetColumnWidth(This->hWndList, 0);
1288 nColumn2 = ListView_GetColumnWidth(This->hWndList, 1);*/
1291 case LVN_DELETEITEM:
1292 TRACE("-- LVN_DELETEITEM %p\n",This);
1293 SHFree((LPITEMIDLIST)lpnmlv->lParam); /*delete the pidl because we made a copy of it*/
1296 case LVN_DELETEALLITEMS:
1297 TRACE("-- LVN_DELETEALLITEMS %p\n",This);
1300 case LVN_INSERTITEM:
1301 TRACE("-- LVN_INSERTITEM (STUB)%p\n",This);
1304 case LVN_ITEMACTIVATE:
1305 TRACE("-- LVN_ITEMACTIVATE %p\n",This);
1306 OnStateChange(This, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
1309 case LVN_COLUMNCLICK:
1310 This->ListViewSortInfo.nHeaderID = lpnmlv->iSubItem;
1311 if(This->ListViewSortInfo.nLastHeaderID == This->ListViewSortInfo.nHeaderID)
1313 This->ListViewSortInfo.bIsAscending = !This->ListViewSortInfo.bIsAscending;
1317 This->ListViewSortInfo.bIsAscending = TRUE;
1319 This->ListViewSortInfo.nLastHeaderID = This->ListViewSortInfo.nHeaderID;
1321 ListView_SortItems(lpnmlv->hdr.hwndFrom, ShellView_ListViewCompareItems, (LPARAM) (&(This->ListViewSortInfo)));
1324 case LVN_GETDISPINFOA:
1325 case LVN_GETDISPINFOW:
1326 TRACE("-- LVN_GETDISPINFO %p\n",This);
1327 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1329 if(lpdi->item.mask & LVIF_TEXT) /* text requested */
1331 if (This->pSF2Parent)
1334 IShellFolder2_GetDetailsOf(This->pSF2Parent, pidl, lpdi->item.iSubItem, &sd);
1335 if (lpnmh->code == LVN_GETDISPINFOA)
1337 StrRetToStrNA( lpdi->item.pszText, lpdi->item.cchTextMax, &sd.str, NULL);
1338 TRACE("-- text=%s\n",lpdi->item.pszText);
1340 else /* LVN_GETDISPINFOW */
1342 StrRetToStrNW( ((NMLVDISPINFOW *)lpdi)->item.pszText, lpdi->item.cchTextMax, &sd.str, NULL);
1343 TRACE("-- text=%s\n",debugstr_w((WCHAR*)(lpdi->item.pszText)));
1351 if(lpdi->item.mask & LVIF_IMAGE) /* image requested */
1353 lpdi->item.iImage = SHMapPIDLToSystemImageListIndex(This->pSFParent, pidl, 0);
1357 case LVN_ITEMCHANGED:
1358 TRACE("-- LVN_ITEMCHANGED %p\n",This);
1359 OnStateChange(This, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
1363 case LVN_BEGINRDRAG:
1364 TRACE("-- LVN_BEGINDRAG\n");
1366 if (ShellView_GetSelections(This))
1369 DWORD dwAttributes = SFGAO_CANLINK;
1370 DWORD dwEffect = DROPEFFECT_COPY | DROPEFFECT_MOVE;
1372 if (SUCCEEDED(IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, (LPCITEMIDLIST*)This->apidl, &IID_IDataObject,0,(LPVOID *)&pda)))
1374 IDropSource * pds = (IDropSource*)&(This->lpvtblDropSource); /* own DropSource interface */
1376 if (SUCCEEDED(IShellFolder_GetAttributesOf(This->pSFParent, This->cidl, (LPCITEMIDLIST*)This->apidl, &dwAttributes)))
1378 if (dwAttributes & SFGAO_CANLINK)
1380 dwEffect |= DROPEFFECT_LINK;
1387 DoDragDrop(pda, pds, dwEffect, &dwEffect);
1389 IDataObject_Release(pda);
1394 case LVN_BEGINLABELEDITA:
1396 DWORD dwAttr = SFGAO_CANRENAME;
1397 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1399 TRACE("-- LVN_BEGINLABELEDITA %p\n",This);
1401 IShellFolder_GetAttributesOf(This->pSFParent, 1, (LPCITEMIDLIST*)&pidl, &dwAttr);
1402 if (SFGAO_CANRENAME & dwAttr)
1409 case LVN_ENDLABELEDITA:
1411 TRACE("-- LVN_ENDLABELEDITA %p\n",This);
1412 if (lpdi->item.pszText)
1415 WCHAR wszNewName[MAX_PATH];
1418 ZeroMemory(&lvItem, sizeof(LVITEMA));
1419 lvItem.iItem = lpdi->item.iItem;
1420 lvItem.mask = LVIF_PARAM;
1421 ListView_GetItemA(This->hWndList, &lvItem);
1423 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1424 if (!MultiByteToWideChar( CP_ACP, 0, lpdi->item.pszText, -1, wszNewName, MAX_PATH ))
1425 wszNewName[MAX_PATH-1] = 0;
1426 hr = IShellFolder_SetNameOf(This->pSFParent, 0, pidl, wszNewName, SHGDN_INFOLDER, &pidl);
1428 if(SUCCEEDED(hr) && pidl)
1430 lvItem.mask = LVIF_PARAM;
1431 lvItem.lParam = (LPARAM)pidl;
1432 ListView_SetItemA(This->hWndList, &lvItem);
1442 msg.hwnd = This->hWnd;
1443 msg.message = WM_KEYDOWN;
1444 msg.wParam = plvKeyDown->wVKey;
1449 LPNMLVKEYDOWN plvKeyDown = (LPNMLVKEYDOWN) lpnmh;
1451 /* initiate a rename of the selected file or directory */
1452 if(plvKeyDown->wVKey == VK_F2)
1454 /* see how many files are selected */
1455 int i = ListView_GetSelectedCount(This->hWndList);
1457 /* get selected item */
1460 /* get selected item */
1461 i = ListView_GetNextItem(This->hWndList, -1,
1464 ListView_EnsureVisible(This->hWndList, i, 0);
1465 ListView_EditLabelA(This->hWndList, i);
1469 TranslateAccelerator(This->hWnd, This->hAccel, &msg)
1471 else if(plvKeyDown->wVKey == VK_DELETE)
1476 LPITEMIDLIST* pItems;
1479 IShellFolder_QueryInterface(This->pSFParent, &IID_ISFHelper,
1485 if(!(i = ListView_GetSelectedCount(This->hWndList)))
1488 /* allocate memory for the pidl array */
1489 pItems = HeapAlloc(GetProcessHeap(), 0,
1490 sizeof(LPITEMIDLIST) * i);
1492 /* retrieve all selected items */
1495 while(ListView_GetSelectedCount(This->hWndList) > i)
1497 /* get selected item */
1498 item_index = ListView_GetNextItem(This->hWndList,
1499 item_index, LVNI_SELECTED);
1500 item.iItem = item_index;
1501 item.mask |= LVIF_PARAM;
1502 ListView_GetItemA(This->hWndList, &item);
1505 pItems[i] = (LPITEMIDLIST)item.lParam;
1510 /* perform the item deletion */
1511 ISFHelper_DeleteItems(psfhlp, i, (LPCITEMIDLIST*)pItems);
1513 /* free pidl array memory */
1514 HeapFree(GetProcessHeap(), 0, pItems);
1517 /* Initiate a refresh */
1518 else if(plvKeyDown->wVKey == VK_F5)
1520 IShellView_Refresh((IShellView*)This);
1524 FIXME("LVN_KEYDOWN key=0x%08x\n",plvKeyDown->wVKey);
1529 TRACE("-- %p WM_COMMAND %x unhandled\n", This, lpnmh->code);
1535 /**********************************************************
1536 * ShellView_OnChange()
1539 static LRESULT ShellView_OnChange(IShellViewImpl * This, LPITEMIDLIST * Pidls, LONG wEventId)
1542 TRACE("(%p)(%p,%p,0x%08lx)\n", This, Pidls[0], Pidls[1], wEventId);
1547 LV_AddItem(This, Pidls[0]);
1551 LV_DeleteItem(This, Pidls[0]);
1553 case SHCNE_RENAMEFOLDER:
1554 case SHCNE_RENAMEITEM:
1555 LV_RenameItem(This, Pidls[0], Pidls[1]);
1557 case SHCNE_UPDATEITEM:
1562 /**********************************************************
1566 static LRESULT CALLBACK ShellView_WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
1568 IShellViewImpl * pThis = (IShellViewImpl*)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
1569 LPCREATESTRUCTA lpcs;
1571 TRACE("(hwnd=%p msg=%x wparm=%x lparm=%lx)\n",hWnd, uMessage, wParam, lParam);
1576 lpcs = (LPCREATESTRUCTA)lParam;
1577 pThis = (IShellViewImpl*)(lpcs->lpCreateParams);
1578 SetWindowLongPtrW(hWnd, GWLP_USERDATA, (ULONG_PTR)pThis);
1579 pThis->hWnd = hWnd; /*set the window handle*/
1582 case WM_SIZE: return ShellView_OnSize(pThis,LOWORD(lParam), HIWORD(lParam));
1583 case WM_SETFOCUS: return ShellView_OnSetFocus(pThis);
1584 case WM_KILLFOCUS: return ShellView_OnKillFocus(pThis);
1585 case WM_CREATE: return ShellView_OnCreate(pThis);
1586 case WM_ACTIVATE: return ShellView_OnActivate(pThis, SVUIA_ACTIVATE_FOCUS);
1587 case WM_NOTIFY: return ShellView_OnNotify(pThis,(UINT)wParam, (LPNMHDR)lParam);
1588 case WM_COMMAND: return ShellView_OnCommand(pThis,
1589 GET_WM_COMMAND_ID(wParam, lParam),
1590 GET_WM_COMMAND_CMD(wParam, lParam),
1591 GET_WM_COMMAND_HWND(wParam, lParam));
1592 case SHV_CHANGE_NOTIFY: return ShellView_OnChange(pThis, (LPITEMIDLIST*)wParam, (LONG)lParam);
1594 case WM_CONTEXTMENU: ShellView_DoContextMenu(pThis, LOWORD(lParam), HIWORD(lParam), FALSE);
1597 case WM_SHOWWINDOW: UpdateWindow(pThis->hWndList);
1600 case WM_GETDLGCODE: return SendMessageA(pThis->hWndList,uMessage,0,0);
1603 RevokeDragDrop(pThis->hWnd);
1604 SHChangeNotifyDeregister(pThis->hNotify);
1608 if ((pThis->FolderSettings.fFlags & FWF_DESKTOP) ||
1609 (pThis->FolderSettings.fFlags & FWF_TRANSPARENT))
1614 return DefWindowProcA (hWnd, uMessage, wParam, lParam);
1616 /**********************************************************
1619 * The INTERFACE of the IShellView object
1622 **********************************************************
1623 * IShellView_QueryInterface
1625 static HRESULT WINAPI IShellView_fnQueryInterface(IShellView * iface,REFIID riid, LPVOID *ppvObj)
1627 IShellViewImpl *This = (IShellViewImpl *)iface;
1629 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1633 if(IsEqualIID(riid, &IID_IUnknown))
1637 else if(IsEqualIID(riid, &IID_IShellView))
1639 *ppvObj = (IShellView*)This;
1641 else if(IsEqualIID(riid, &IID_IOleCommandTarget))
1643 *ppvObj = (IOleCommandTarget*)&(This->lpvtblOleCommandTarget);
1645 else if(IsEqualIID(riid, &IID_IDropTarget))
1647 *ppvObj = (IDropTarget*)&(This->lpvtblDropTarget);
1649 else if(IsEqualIID(riid, &IID_IDropSource))
1651 *ppvObj = (IDropSource*)&(This->lpvtblDropSource);
1653 else if(IsEqualIID(riid, &IID_IViewObject))
1655 *ppvObj = (IViewObject*)&(This->lpvtblViewObject);
1660 IUnknown_AddRef( (IUnknown*)*ppvObj );
1661 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1664 TRACE("-- Interface: E_NOINTERFACE\n");
1665 return E_NOINTERFACE;
1668 /**********************************************************
1671 static ULONG WINAPI IShellView_fnAddRef(IShellView * iface)
1673 IShellViewImpl *This = (IShellViewImpl *)iface;
1674 ULONG refCount = InterlockedIncrement(&This->ref);
1676 TRACE("(%p)->(count=%lu)\n", This, refCount - 1);
1680 /**********************************************************
1681 * IShellView_Release
1683 static ULONG WINAPI IShellView_fnRelease(IShellView * iface)
1685 IShellViewImpl *This = (IShellViewImpl *)iface;
1686 ULONG refCount = InterlockedDecrement(&This->ref);
1688 TRACE("(%p)->(count=%li)\n", This, refCount + 1);
1692 TRACE(" destroying IShellView(%p)\n",This);
1694 DestroyWindow(This->hWndList);
1697 IShellFolder_Release(This->pSFParent);
1699 if(This->pSF2Parent)
1700 IShellFolder2_Release(This->pSF2Parent);
1703 SHFree(This->apidl);
1706 IAdviseSink_Release(This->pAdvSink);
1708 HeapFree(GetProcessHeap(),0,This);
1713 /**********************************************************
1714 * ShellView_GetWindow
1716 static HRESULT WINAPI IShellView_fnGetWindow(IShellView * iface,HWND * phWnd)
1718 IShellViewImpl *This = (IShellViewImpl *)iface;
1720 TRACE("(%p)\n",This);
1722 *phWnd = This->hWnd;
1727 static HRESULT WINAPI IShellView_fnContextSensitiveHelp(IShellView * iface,BOOL fEnterMode)
1729 IShellViewImpl *This = (IShellViewImpl *)iface;
1731 FIXME("(%p) stub\n",This);
1736 /**********************************************************
1737 * IShellView_TranslateAccelerator
1740 * use the accel functions
1742 static HRESULT WINAPI IShellView_fnTranslateAccelerator(IShellView * iface,LPMSG lpmsg)
1745 IShellViewImpl *This = (IShellViewImpl *)iface;
1747 FIXME("(%p)->(%p: hwnd=%x msg=%x lp=%lx wp=%x) stub\n",This,lpmsg, lpmsg->hwnd, lpmsg->message, lpmsg->lParam, lpmsg->wParam);
1750 if ((lpmsg->message>=WM_KEYFIRST) && (lpmsg->message>=WM_KEYLAST))
1752 TRACE("-- key=0x04%x\n",lpmsg->wParam) ;
1754 return S_FALSE; /* not handled */
1757 static HRESULT WINAPI IShellView_fnEnableModeless(IShellView * iface,BOOL fEnable)
1759 IShellViewImpl *This = (IShellViewImpl *)iface;
1761 FIXME("(%p) stub\n",This);
1766 static HRESULT WINAPI IShellView_fnUIActivate(IShellView * iface,UINT uState)
1768 IShellViewImpl *This = (IShellViewImpl *)iface;
1771 CHAR szName[MAX_PATH];
1774 int nPartArray[1] = {-1};
1776 TRACE("(%p)->(state=%x) stub\n",This, uState);
1778 /*don't do anything if the state isn't really changing*/
1779 if(This->uState == uState)
1784 /*OnActivate handles the menu merging and internal state*/
1785 ShellView_OnActivate(This, uState);
1787 /*only do This if we are active*/
1788 if(uState != SVUIA_DEACTIVATE)
1792 GetFolderPath is not a method of IShellFolder
1793 IShellFolder_GetFolderPath( This->pSFParent, szName, sizeof(szName) );
1795 /* set the number of parts */
1796 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETPARTS, 1,
1797 (LPARAM)nPartArray, &lResult);
1799 /* set the text for the parts */
1801 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETTEXTA,
1802 0, (LPARAM)szName, &lResult);
1809 static HRESULT WINAPI IShellView_fnRefresh(IShellView * iface)
1811 IShellViewImpl *This = (IShellViewImpl *)iface;
1813 TRACE("(%p)\n",This);
1815 ListView_DeleteAllItems(This->hWndList);
1816 ShellView_FillList(This);
1821 static HRESULT WINAPI IShellView_fnCreateViewWindow(
1823 IShellView *lpPrevView,
1824 LPCFOLDERSETTINGS lpfs,
1825 IShellBrowser * psb,
1829 IShellViewImpl *This = (IShellViewImpl *)iface;
1835 TRACE("(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n",This, lpPrevView,lpfs, psb, prcView, phWnd);
1836 TRACE("-- vmode=%x flags=%x left=%li top=%li right=%li bottom=%li\n",lpfs->ViewMode, lpfs->fFlags ,prcView->left,prcView->top, prcView->right, prcView->bottom);
1838 /*set up the member variables*/
1839 This->pShellBrowser = psb;
1840 This->FolderSettings = *lpfs;
1842 /*get our parent window*/
1843 IShellBrowser_AddRef(This->pShellBrowser);
1844 IShellBrowser_GetWindow(This->pShellBrowser, &(This->hWndParent));
1846 /* try to get the ICommDlgBrowserInterface, adds a reference !!! */
1847 This->pCommDlgBrowser=NULL;
1848 if ( SUCCEEDED (IShellBrowser_QueryInterface( This->pShellBrowser,
1849 (REFIID)&IID_ICommDlgBrowser, (LPVOID*) &This->pCommDlgBrowser)))
1851 TRACE("-- CommDlgBrowser\n");
1854 /*if our window class has not been registered, then do so*/
1855 if(!GetClassInfoA(shell32_hInstance, SV_CLASS_NAME, &wc))
1857 ZeroMemory(&wc, sizeof(wc));
1858 wc.style = CS_HREDRAW | CS_VREDRAW;
1859 wc.lpfnWndProc = ShellView_WndProc;
1862 wc.hInstance = shell32_hInstance;
1864 wc.hCursor = LoadCursorA (0, (LPSTR)IDC_ARROW);
1865 wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
1866 wc.lpszMenuName = NULL;
1867 wc.lpszClassName = SV_CLASS_NAME;
1869 if(!RegisterClassA(&wc))
1873 *phWnd = CreateWindowExA(0,
1876 WS_CHILD | WS_VISIBLE | WS_TABSTOP,
1879 prcView->right - prcView->left,
1880 prcView->bottom - prcView->top,
1888 if(!*phWnd) return E_FAIL;
1893 static HRESULT WINAPI IShellView_fnDestroyViewWindow(IShellView * iface)
1895 IShellViewImpl *This = (IShellViewImpl *)iface;
1897 TRACE("(%p)\n",This);
1899 /*Make absolutely sure all our UI is cleaned up.*/
1900 IShellView_UIActivate((IShellView*)This, SVUIA_DEACTIVATE);
1904 DestroyMenu(This->hMenu);
1907 DestroyWindow(This->hWnd);
1908 if(This->pShellBrowser) IShellBrowser_Release(This->pShellBrowser);
1909 if(This->pCommDlgBrowser) ICommDlgBrowser_Release(This->pCommDlgBrowser);
1915 static HRESULT WINAPI IShellView_fnGetCurrentInfo(IShellView * iface, LPFOLDERSETTINGS lpfs)
1917 IShellViewImpl *This = (IShellViewImpl *)iface;
1919 TRACE("(%p)->(%p) vmode=%x flags=%x\n",This, lpfs,
1920 This->FolderSettings.ViewMode, This->FolderSettings.fFlags);
1922 if (!lpfs) return E_INVALIDARG;
1924 *lpfs = This->FolderSettings;
1928 static HRESULT WINAPI IShellView_fnAddPropertySheetPages(IShellView * iface, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam)
1930 IShellViewImpl *This = (IShellViewImpl *)iface;
1932 FIXME("(%p) stub\n",This);
1937 static HRESULT WINAPI IShellView_fnSaveViewState(IShellView * iface)
1939 IShellViewImpl *This = (IShellViewImpl *)iface;
1941 FIXME("(%p) stub\n",This);
1946 static HRESULT WINAPI IShellView_fnSelectItem(
1951 IShellViewImpl *This = (IShellViewImpl *)iface;
1954 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n",This, pidl, uFlags);
1956 i = LV_FindItemByPidl(This, pidl);
1962 if(uFlags & SVSI_ENSUREVISIBLE)
1963 ListView_EnsureVisible(This->hWndList, i, 0);
1965 ZeroMemory(&lvItem, sizeof(LVITEMA));
1966 lvItem.mask = LVIF_STATE;
1969 while(ListView_GetItemA(This->hWndList, &lvItem))
1971 if (lvItem.iItem == i)
1973 if (uFlags & SVSI_SELECT)
1974 lvItem.state |= LVIS_SELECTED;
1976 lvItem.state &= ~LVIS_SELECTED;
1978 if(uFlags & SVSI_FOCUSED)
1979 lvItem.state &= ~LVIS_FOCUSED;
1983 if (uFlags & SVSI_DESELECTOTHERS)
1984 lvItem.state &= ~LVIS_SELECTED;
1986 ListView_SetItemA(This->hWndList, &lvItem);
1991 if(uFlags & SVSI_EDIT)
1992 ListView_EditLabelA(This->hWndList, i);
1998 static HRESULT WINAPI IShellView_fnGetItemObject(IShellView * iface, UINT uItem, REFIID riid, LPVOID *ppvOut)
2000 IShellViewImpl *This = (IShellViewImpl *)iface;
2002 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n",This, uItem, debugstr_guid(riid), ppvOut);
2008 case SVGIO_BACKGROUND:
2009 *ppvOut = ISvBgCm_Constructor(This->pSFParent, FALSE);
2012 case SVGIO_SELECTION:
2013 ShellView_GetSelections(This);
2014 IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, (LPCITEMIDLIST*)This->apidl, riid, 0, ppvOut);
2017 TRACE("-- (%p)->(interface=%p)\n",This, *ppvOut);
2019 if(!*ppvOut) return E_OUTOFMEMORY;
2024 static const IShellViewVtbl svvt =
2026 IShellView_fnQueryInterface,
2027 IShellView_fnAddRef,
2028 IShellView_fnRelease,
2029 IShellView_fnGetWindow,
2030 IShellView_fnContextSensitiveHelp,
2031 IShellView_fnTranslateAccelerator,
2032 IShellView_fnEnableModeless,
2033 IShellView_fnUIActivate,
2034 IShellView_fnRefresh,
2035 IShellView_fnCreateViewWindow,
2036 IShellView_fnDestroyViewWindow,
2037 IShellView_fnGetCurrentInfo,
2038 IShellView_fnAddPropertySheetPages,
2039 IShellView_fnSaveViewState,
2040 IShellView_fnSelectItem,
2041 IShellView_fnGetItemObject
2045 /**********************************************************
2046 * ISVOleCmdTarget_QueryInterface (IUnknown)
2048 static HRESULT WINAPI ISVOleCmdTarget_QueryInterface(
2049 IOleCommandTarget * iface,
2053 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2055 return IShellFolder_QueryInterface((IShellFolder*)This, iid, ppvObj);
2058 /**********************************************************
2059 * ISVOleCmdTarget_AddRef (IUnknown)
2061 static ULONG WINAPI ISVOleCmdTarget_AddRef(
2062 IOleCommandTarget * iface)
2064 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2066 return IShellFolder_AddRef((IShellFolder*)This);
2069 /**********************************************************
2070 * ISVOleCmdTarget_Release (IUnknown)
2072 static ULONG WINAPI ISVOleCmdTarget_Release(
2073 IOleCommandTarget * iface)
2075 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2077 return IShellFolder_Release((IShellFolder*)This);
2080 /**********************************************************
2081 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2083 static HRESULT WINAPI ISVOleCmdTarget_QueryStatus(
2084 IOleCommandTarget *iface,
2085 const GUID* pguidCmdGroup,
2088 OLECMDTEXT* pCmdText)
2091 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2093 FIXME("(%p)->(%p(%s) 0x%08lx %p %p\n",
2094 This, pguidCmdGroup, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText);
2098 for (i = 0; i < cCmds; i++)
2100 FIXME("\tprgCmds[%d].cmdID = %ld\n", i, prgCmds[i].cmdID);
2101 prgCmds[i].cmdf = 0;
2103 return OLECMDERR_E_UNKNOWNGROUP;
2106 /**********************************************************
2107 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2109 * nCmdID is the OLECMDID_* enumeration
2111 static HRESULT WINAPI ISVOleCmdTarget_Exec(
2112 IOleCommandTarget *iface,
2113 const GUID* pguidCmdGroup,
2119 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2121 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08lx Opt:0x%08lx %p %p)\n",
2122 This, debugstr_guid(pguidCmdGroup), nCmdID, nCmdexecopt, pvaIn, pvaOut);
2124 if (IsEqualIID(pguidCmdGroup, &CGID_Explorer) &&
2126 (nCmdexecopt == 4) && pvaOut)
2128 if (IsEqualIID(pguidCmdGroup, &CGID_ShellDocView) &&
2133 return OLECMDERR_E_UNKNOWNGROUP;
2136 static const IOleCommandTargetVtbl ctvt =
2138 ISVOleCmdTarget_QueryInterface,
2139 ISVOleCmdTarget_AddRef,
2140 ISVOleCmdTarget_Release,
2141 ISVOleCmdTarget_QueryStatus,
2142 ISVOleCmdTarget_Exec
2145 /**********************************************************
2146 * ISVDropTarget implementation
2149 static HRESULT WINAPI ISVDropTarget_QueryInterface(
2154 IShellViewImpl *This = impl_from_IDropTarget(iface);
2156 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2158 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2161 static ULONG WINAPI ISVDropTarget_AddRef( IDropTarget *iface)
2163 IShellViewImpl *This = impl_from_IDropTarget(iface);
2165 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2167 return IShellFolder_AddRef((IShellFolder*)This);
2170 static ULONG WINAPI ISVDropTarget_Release( IDropTarget *iface)
2172 IShellViewImpl *This = impl_from_IDropTarget(iface);
2174 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2176 return IShellFolder_Release((IShellFolder*)This);
2179 /******************************************************************************
2180 * drag_notify_subitem [Internal]
2182 * Figure out the shellfolder object, which is currently under the mouse cursor
2183 * and notify it via the IDropTarget interface.
2185 static HRESULT drag_notify_subitem(IShellViewImpl *This, DWORD grfKeyState, POINTL pt,
2188 LVHITTESTINFO htinfo;
2193 /* Map from global to client coordinates and query the index of the listview-item, which is
2194 * currently under the mouse cursor. */
2197 htinfo.flags = LVHT_ONITEM;
2198 MapWindowPoints(NULL, This->hWndList, &htinfo.pt, 1);
2199 lResult = SendMessageW(This->hWndList, LVM_HITTEST, 0, (LPARAM)&htinfo);
2201 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2202 if (This->pCurDropTarget && lResult == This->iDragOverItem)
2203 return IDropTarget_DragOver(This->pCurDropTarget, grfKeyState, pt, pdwEffect);
2205 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2206 if (This->pCurDropTarget) {
2207 IDropTarget_DragLeave(This->pCurDropTarget);
2208 IDropTarget_Release(This->pCurDropTarget);
2209 This->pCurDropTarget = NULL;
2212 This->iDragOverItem = lResult;
2213 if (lResult == -1) {
2214 /* We are not above one of the listview's subitems. Bind to the parent folder's
2215 * DropTarget interface. */
2216 hr = IShellFolder_QueryInterface(This->pSFParent, &IID_IDropTarget,
2217 (LPVOID*)&This->pCurDropTarget);
2219 /* Query the relative PIDL of the shellfolder object represented by the currently
2220 * dragged over listview-item ... */
2221 ZeroMemory(&lvItem, sizeof(lvItem));
2222 lvItem.mask = LVIF_PARAM;
2223 lvItem.iItem = lResult;
2224 ListView_GetItemA(This->hWndList, &lvItem);
2226 /* ... and bind pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2227 hr = IShellFolder_GetUIObjectOf(This->pSFParent, This->hWndList, 1,
2228 (LPCITEMIDLIST*)&lvItem.lParam, &IID_IDropTarget, NULL, (LPVOID*)&This->pCurDropTarget);
2231 /* If anything failed, pCurDropTarget should be NULL now, which ought to be a save state. */
2235 /* Notify the item just entered via DragEnter. */
2236 return IDropTarget_DragEnter(This->pCurDropTarget, This->pCurDataObject, grfKeyState, pt, pdwEffect);
2239 static HRESULT WINAPI ISVDropTarget_DragEnter(IDropTarget *iface, IDataObject *pDataObject,
2240 DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
2242 IShellViewImpl *This = impl_from_IDropTarget(iface);
2244 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2245 This->pCurDataObject = pDataObject;
2246 IDataObject_AddRef(pDataObject);
2248 return drag_notify_subitem(This, grfKeyState, pt, pdwEffect);
2251 static HRESULT WINAPI ISVDropTarget_DragOver(IDropTarget *iface, DWORD grfKeyState, POINTL pt,
2254 IShellViewImpl *This = impl_from_IDropTarget(iface);
2255 return drag_notify_subitem(This, grfKeyState, pt, pdwEffect);
2258 static HRESULT WINAPI ISVDropTarget_DragLeave(IDropTarget *iface) {
2259 IShellViewImpl *This = impl_from_IDropTarget(iface);
2261 IDropTarget_DragLeave(This->pCurDropTarget);
2263 IDropTarget_Release(This->pCurDropTarget);
2264 IDataObject_Release(This->pCurDataObject);
2265 This->pCurDataObject = NULL;
2266 This->pCurDropTarget = NULL;
2267 This->iDragOverItem = 0;
2272 static HRESULT WINAPI ISVDropTarget_Drop(IDropTarget *iface, IDataObject* pDataObject,
2273 DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
2275 IShellViewImpl *This = impl_from_IDropTarget(iface);
2277 IDropTarget_Drop(This->pCurDropTarget, pDataObject, grfKeyState, pt, pdwEffect);
2279 IDropTarget_Release(This->pCurDropTarget);
2280 IDataObject_Release(This->pCurDataObject);
2281 This->pCurDataObject = NULL;
2282 This->pCurDropTarget = NULL;
2283 This->iDragOverItem = 0;
2288 static const IDropTargetVtbl dtvt =
2290 ISVDropTarget_QueryInterface,
2291 ISVDropTarget_AddRef,
2292 ISVDropTarget_Release,
2293 ISVDropTarget_DragEnter,
2294 ISVDropTarget_DragOver,
2295 ISVDropTarget_DragLeave,
2299 /**********************************************************
2300 * ISVDropSource implementation
2303 static HRESULT WINAPI ISVDropSource_QueryInterface(
2308 IShellViewImpl *This = impl_from_IDropSource(iface);
2310 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2312 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2315 static ULONG WINAPI ISVDropSource_AddRef( IDropSource *iface)
2317 IShellViewImpl *This = impl_from_IDropSource(iface);
2319 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2321 return IShellFolder_AddRef((IShellFolder*)This);
2324 static ULONG WINAPI ISVDropSource_Release( IDropSource *iface)
2326 IShellViewImpl *This = impl_from_IDropSource(iface);
2328 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2330 return IShellFolder_Release((IShellFolder*)This);
2332 static HRESULT WINAPI ISVDropSource_QueryContinueDrag(
2334 BOOL fEscapePressed,
2337 IShellViewImpl *This = impl_from_IDropSource(iface);
2338 TRACE("(%p)\n",This);
2341 return DRAGDROP_S_CANCEL;
2342 else if (!(grfKeyState & MK_LBUTTON) && !(grfKeyState & MK_RBUTTON))
2343 return DRAGDROP_S_DROP;
2348 static HRESULT WINAPI ISVDropSource_GiveFeedback(
2352 IShellViewImpl *This = impl_from_IDropSource(iface);
2353 TRACE("(%p)\n",This);
2355 return DRAGDROP_S_USEDEFAULTCURSORS;
2358 static const IDropSourceVtbl dsvt =
2360 ISVDropSource_QueryInterface,
2361 ISVDropSource_AddRef,
2362 ISVDropSource_Release,
2363 ISVDropSource_QueryContinueDrag,
2364 ISVDropSource_GiveFeedback
2366 /**********************************************************
2367 * ISVViewObject implementation
2370 static HRESULT WINAPI ISVViewObject_QueryInterface(
2375 IShellViewImpl *This = impl_from_IViewObject(iface);
2377 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2379 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2382 static ULONG WINAPI ISVViewObject_AddRef( IViewObject *iface)
2384 IShellViewImpl *This = impl_from_IViewObject(iface);
2386 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2388 return IShellFolder_AddRef((IShellFolder*)This);
2391 static ULONG WINAPI ISVViewObject_Release( IViewObject *iface)
2393 IShellViewImpl *This = impl_from_IViewObject(iface);
2395 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2397 return IShellFolder_Release((IShellFolder*)This);
2400 static HRESULT WINAPI ISVViewObject_Draw(
2405 DVTARGETDEVICE* ptd,
2408 LPCRECTL lprcBounds,
2409 LPCRECTL lprcWBounds,
2410 BOOL (CALLBACK *pfnContinue)(ULONG_PTR dwContinue),
2411 ULONG_PTR dwContinue)
2414 IShellViewImpl *This = impl_from_IViewObject(iface);
2416 FIXME("Stub: This=%p\n",This);
2420 static HRESULT WINAPI ISVViewObject_GetColorSet(
2425 DVTARGETDEVICE* ptd,
2426 HDC hicTargetDevice,
2427 LOGPALETTE** ppColorSet)
2430 IShellViewImpl *This = impl_from_IViewObject(iface);
2432 FIXME("Stub: This=%p\n",This);
2436 static HRESULT WINAPI ISVViewObject_Freeze(
2444 IShellViewImpl *This = impl_from_IViewObject(iface);
2446 FIXME("Stub: This=%p\n",This);
2450 static HRESULT WINAPI ISVViewObject_Unfreeze(
2455 IShellViewImpl *This = impl_from_IViewObject(iface);
2457 FIXME("Stub: This=%p\n",This);
2461 static HRESULT WINAPI ISVViewObject_SetAdvise(
2465 IAdviseSink* pAdvSink)
2468 IShellViewImpl *This = impl_from_IViewObject(iface);
2470 FIXME("partial stub: %p %08lx %08lx %p\n",
2471 This, aspects, advf, pAdvSink);
2473 /* FIXME: we set the AdviseSink, but never use it to send any advice */
2474 This->pAdvSink = pAdvSink;
2475 This->dwAspects = aspects;
2476 This->dwAdvf = advf;
2481 static HRESULT WINAPI ISVViewObject_GetAdvise(
2485 IAdviseSink** ppAdvSink)
2488 IShellViewImpl *This = impl_from_IViewObject(iface);
2490 TRACE("This=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n",
2491 This, pAspects, pAdvf, ppAdvSink);
2495 IAdviseSink_AddRef( This->pAdvSink );
2496 *ppAdvSink = This->pAdvSink;
2499 *pAspects = This->dwAspects;
2501 *pAdvf = This->dwAdvf;
2507 static const IViewObjectVtbl vovt =
2509 ISVViewObject_QueryInterface,
2510 ISVViewObject_AddRef,
2511 ISVViewObject_Release,
2513 ISVViewObject_GetColorSet,
2514 ISVViewObject_Freeze,
2515 ISVViewObject_Unfreeze,
2516 ISVViewObject_SetAdvise,
2517 ISVViewObject_GetAdvise