push 6e61d6ca5bcaf95ac09a664b4ba4f88238c927be
[wine/hacks.git] / dlls / shell32 / shlview.c
blob80c4c3a67576f940bf48041e50402fa428fe1135
1 /*
2 * ShellView
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
27 * the ShellBrowser
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
36 * Release() ???
39 #include "config.h"
40 #include "wine/port.h"
42 #include <stdarg.h>
43 #include <stdlib.h>
44 #include <string.h>
46 #define COBJMACROS
47 #define NONAMELESSUNION
48 #define NONAMELESSSTRUCT
50 #include "windef.h"
51 #include "winerror.h"
52 #include "winbase.h"
53 #include "winnls.h"
54 #include "objbase.h"
55 #include "servprov.h"
56 #include "shlguid.h"
57 #include "wingdi.h"
58 #include "winuser.h"
59 #include "shlobj.h"
60 #include "shobjidl.h"
61 #include "undocshell.h"
62 #include "shresdef.h"
63 #include "wine/debug.h"
65 #include "docobj.h"
66 #include "pidl.h"
67 #include "shell32_main.h"
68 #include "shellfolder.h"
70 WINE_DEFAULT_DEBUG_CHANNEL(shell);
72 static const WCHAR SV_CLASS_NAME[] = {'S','H','E','L','L','D','L','L','_','D','e','f','V','i','e','w',0};
74 typedef struct
75 { BOOL bIsAscending;
76 INT nHeaderID;
77 INT nLastHeaderID;
78 }LISTVIEW_SORT_INFO, *LPLISTVIEW_SORT_INFO;
80 typedef struct
82 const IShellView2Vtbl* lpVtbl;
83 LONG ref;
84 const IOleCommandTargetVtbl* lpvtblOleCommandTarget;
85 const IDropTargetVtbl* lpvtblDropTarget;
86 const IDropSourceVtbl* lpvtblDropSource;
87 const IViewObjectVtbl* lpvtblViewObject;
88 const IFolderViewVtbl* lpvtblFolderView;
89 IShellFolder* pSFParent;
90 IShellFolder2* pSF2Parent;
91 IShellBrowser* pShellBrowser;
92 ICommDlgBrowser* pCommDlgBrowser;
93 HWND hWnd; /* SHELLDLL_DefView */
94 HWND hWndList; /* ListView control */
95 HWND hWndParent;
96 FOLDERSETTINGS FolderSettings;
97 HMENU hMenu;
98 UINT uState;
99 UINT cidl;
100 LPITEMIDLIST *apidl;
101 LISTVIEW_SORT_INFO ListViewSortInfo;
102 ULONG hNotify; /* change notification handle */
103 HANDLE hAccel;
104 DWORD dwAspects;
105 DWORD dwAdvf;
106 IAdviseSink *pAdvSink;
107 IDropTarget* pCurDropTarget; /* The sub-item, which is currently dragged over */
108 IDataObject* pCurDataObject; /* The dragged data-object */
109 LONG iDragOverItem; /* Dragged over item's index, iff pCurDropTarget != NULL */
110 UINT cScrollDelay; /* Send a WM_*SCROLL msg every 250 ms during drag-scroll */
111 POINT ptLastMousePos; /* Mouse position at last DragOver call */
112 } IShellViewImpl;
114 static const IShellView2Vtbl svvt;
115 static const IOleCommandTargetVtbl ctvt;
116 static const IDropTargetVtbl dtvt;
117 static const IDropSourceVtbl dsvt;
118 static const IViewObjectVtbl vovt;
119 static const IFolderViewVtbl fviewvt;
121 static inline IShellViewImpl *impl_from_IOleCommandTarget( IOleCommandTarget *iface )
123 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblOleCommandTarget));
126 static inline IShellViewImpl *impl_from_IDropTarget( IDropTarget *iface )
128 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblDropTarget));
131 static inline IShellViewImpl *impl_from_IDropSource( IDropSource *iface )
133 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblDropSource));
136 static inline IShellViewImpl *impl_from_IViewObject( IViewObject *iface )
138 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblViewObject));
141 static inline IShellViewImpl *impl_from_IFolderView( IFolderView *iface )
143 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblFolderView));
146 /* ListView Header ID's */
147 #define LISTVIEW_COLUMN_NAME 0
148 #define LISTVIEW_COLUMN_SIZE 1
149 #define LISTVIEW_COLUMN_TYPE 2
150 #define LISTVIEW_COLUMN_TIME 3
151 #define LISTVIEW_COLUMN_ATTRIB 4
153 /*menu items */
154 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
155 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
156 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
158 #define ID_LISTVIEW 1
160 #define SHV_CHANGE_NOTIFY WM_USER + 0x1111
162 /*windowsx.h */
163 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
164 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
165 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
168 Items merged into the toolbar and the filemenu
170 typedef struct
171 { int idCommand;
172 int iImage;
173 int idButtonString;
174 int idMenuString;
175 BYTE bState;
176 BYTE bStyle;
177 } MYTOOLINFO, *LPMYTOOLINFO;
179 static const MYTOOLINFO Tools[] =
181 { FCIDM_SHVIEW_BIGICON, 0, 0, IDS_VIEW_LARGE, TBSTATE_ENABLED, BTNS_BUTTON },
182 { FCIDM_SHVIEW_SMALLICON, 0, 0, IDS_VIEW_SMALL, TBSTATE_ENABLED, BTNS_BUTTON },
183 { FCIDM_SHVIEW_LISTVIEW, 0, 0, IDS_VIEW_LIST, TBSTATE_ENABLED, BTNS_BUTTON },
184 { FCIDM_SHVIEW_REPORTVIEW, 0, 0, IDS_VIEW_DETAILS, TBSTATE_ENABLED, BTNS_BUTTON },
185 { -1, 0, 0, 0, 0, 0}
188 typedef void (CALLBACK *PFNSHGETSETTINGSPROC)(LPSHELLFLAGSTATE lpsfs, DWORD dwMask);
190 /**********************************************************
191 * IShellView_Constructor
193 IShellView * IShellView_Constructor( IShellFolder * pFolder)
194 { IShellViewImpl * sv;
195 sv=HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IShellViewImpl));
196 sv->ref=1;
197 sv->lpVtbl=&svvt;
198 sv->lpvtblOleCommandTarget=&ctvt;
199 sv->lpvtblDropTarget=&dtvt;
200 sv->lpvtblDropSource=&dsvt;
201 sv->lpvtblViewObject=&vovt;
202 sv->lpvtblFolderView=&fviewvt;
204 sv->pSFParent = pFolder;
205 if(pFolder) IShellFolder_AddRef(pFolder);
206 IShellFolder_QueryInterface(sv->pSFParent, &IID_IShellFolder2, (LPVOID*)&sv->pSF2Parent);
208 sv->pCurDropTarget = NULL;
209 sv->pCurDataObject = NULL;
210 sv->iDragOverItem = 0;
211 sv->cScrollDelay = 0;
212 sv->ptLastMousePos.x = 0;
213 sv->ptLastMousePos.y = 0;
215 TRACE("(%p)->(%p)\n",sv, pFolder);
216 return (IShellView *) sv;
219 /**********************************************************
221 * ##### helperfunctions for communication with ICommDlgBrowser #####
223 static BOOL IsInCommDlg(IShellViewImpl * This)
224 { return(This->pCommDlgBrowser != NULL);
227 static HRESULT IncludeObject(IShellViewImpl * This, LPCITEMIDLIST pidl)
229 HRESULT ret = S_OK;
231 if ( IsInCommDlg(This) )
233 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl);
234 ret = ICommDlgBrowser_IncludeObject(This->pCommDlgBrowser, (IShellView*)This, pidl);
235 TRACE("--0x%08x\n", ret);
237 return ret;
240 static HRESULT OnDefaultCommand(IShellViewImpl * This)
242 HRESULT ret = S_FALSE;
244 if (IsInCommDlg(This))
246 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
247 ret = ICommDlgBrowser_OnDefaultCommand(This->pCommDlgBrowser, (IShellView*)This);
248 TRACE("-- returns %08x\n", ret);
250 return ret;
253 static HRESULT OnStateChange(IShellViewImpl * This, UINT uFlags)
255 HRESULT ret = S_FALSE;
257 if (IsInCommDlg(This))
259 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags);
260 ret = ICommDlgBrowser_OnStateChange(This->pCommDlgBrowser, (IShellView*)This, uFlags);
261 TRACE("--\n");
263 return ret;
265 /**********************************************************
266 * set the toolbar of the filedialog buttons
268 * - activates the buttons from the shellbrowser according to
269 * the view state
271 static void CheckToolbar(IShellViewImpl * This)
273 LRESULT result;
275 TRACE("\n");
277 if (IsInCommDlg(This))
279 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
280 FCIDM_TB_SMALLICON, (This->FolderSettings.ViewMode==FVM_LIST)? TRUE : FALSE, &result);
281 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
282 FCIDM_TB_REPORTVIEW, (This->FolderSettings.ViewMode==FVM_DETAILS)? TRUE : FALSE, &result);
283 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
284 FCIDM_TB_SMALLICON, TRUE, &result);
285 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
286 FCIDM_TB_REPORTVIEW, TRUE, &result);
290 /**********************************************************
292 * ##### helperfunctions for initializing the view #####
294 /**********************************************************
295 * change the style of the listview control
297 static void SetStyle(IShellViewImpl * This, DWORD dwAdd, DWORD dwRemove)
299 DWORD tmpstyle;
301 TRACE("(%p)\n", This);
303 tmpstyle = GetWindowLongW(This->hWndList, GWL_STYLE);
304 SetWindowLongW(This->hWndList, GWL_STYLE, dwAdd | (tmpstyle & ~dwRemove));
307 /**********************************************************
308 * ShellView_CreateList()
310 * - creates the list view window
312 static BOOL ShellView_CreateList (IShellViewImpl * This)
313 { DWORD dwStyle, dwExStyle;
315 TRACE("%p\n",This);
317 dwStyle = WS_TABSTOP | WS_VISIBLE | WS_CHILDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
318 LVS_SHAREIMAGELISTS | LVS_EDITLABELS | LVS_ALIGNLEFT | LVS_AUTOARRANGE;
319 dwExStyle = WS_EX_CLIENTEDGE;
321 switch (This->FolderSettings.ViewMode)
323 case FVM_ICON: dwStyle |= LVS_ICON; break;
324 case FVM_DETAILS: dwStyle |= LVS_REPORT; break;
325 case FVM_SMALLICON: dwStyle |= LVS_SMALLICON; break;
326 case FVM_LIST: dwStyle |= LVS_LIST; break;
327 default:
329 FIXME("ViewMode %d not implemented\n", This->FolderSettings.ViewMode);
330 dwStyle |= LVS_LIST;
331 break;
335 if (This->FolderSettings.fFlags & FWF_AUTOARRANGE) dwStyle |= LVS_AUTOARRANGE;
336 if (This->FolderSettings.fFlags & FWF_DESKTOP)
337 This->FolderSettings.fFlags |= FWF_NOCLIENTEDGE | FWF_NOSCROLL;
338 if (This->FolderSettings.fFlags & FWF_SINGLESEL) dwStyle |= LVS_SINGLESEL;
339 if (This->FolderSettings.fFlags & FWF_NOCLIENTEDGE)
340 dwExStyle &= ~WS_EX_CLIENTEDGE;
342 This->hWndList=CreateWindowExW( dwExStyle,
343 WC_LISTVIEWW,
344 NULL,
345 dwStyle,
346 0,0,0,0,
347 This->hWnd,
348 (HMENU)ID_LISTVIEW,
349 shell32_hInstance,
350 NULL);
352 if(!This->hWndList)
353 return FALSE;
355 This->ListViewSortInfo.bIsAscending = TRUE;
356 This->ListViewSortInfo.nHeaderID = -1;
357 This->ListViewSortInfo.nLastHeaderID = -1;
359 if (This->FolderSettings.fFlags & FWF_DESKTOP) {
361 * FIXME: look at the registry value
362 * HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ListviewShadow
363 * and activate drop shadows if necessary
365 if (0)
366 SendMessageW(This->hWndList, LVM_SETTEXTBKCOLOR, 0, CLR_NONE);
367 else
368 SendMessageW(This->hWndList, LVM_SETTEXTBKCOLOR, 0, GetSysColor(COLOR_DESKTOP));
370 SendMessageW(This->hWndList, LVM_SETTEXTCOLOR, 0, RGB(255,255,255));
373 /* UpdateShellSettings(); */
374 return TRUE;
377 /**********************************************************
378 * ShellView_InitList()
380 * - adds all needed columns to the shellview
382 static BOOL ShellView_InitList(IShellViewImpl * This)
384 LVCOLUMNW lvColumn;
385 SHELLDETAILS sd;
386 int i;
387 WCHAR szTemp[50];
389 TRACE("%p\n",This);
391 SendMessageW(This->hWndList, LVM_DELETEALLITEMS, 0, 0);
393 lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT;
394 lvColumn.pszText = szTemp;
396 if (This->pSF2Parent)
398 for (i=0; 1; i++)
400 if (FAILED(IShellFolder2_GetDetailsOf(This->pSF2Parent, NULL, i, &sd)))
401 break;
402 lvColumn.fmt = sd.fmt;
403 lvColumn.cx = sd.cxChar*8; /* chars->pixel */
404 StrRetToStrNW( szTemp, 50, &sd.str, NULL);
405 SendMessageW(This->hWndList, LVM_INSERTCOLUMNW, i, (LPARAM) &lvColumn);
408 else
410 FIXME("no SF2\n");
413 SendMessageW(This->hWndList, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)ShellSmallIconList);
414 SendMessageW(This->hWndList, LVM_SETIMAGELIST, LVSIL_NORMAL, (LPARAM)ShellBigIconList);
416 return TRUE;
418 /**********************************************************
419 * ShellView_CompareItems()
421 * NOTES
422 * internal, CALLBACK for DSA_Sort
424 static INT CALLBACK ShellView_CompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
426 int ret;
427 TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1, lParam2, (LPVOID) lpData);
429 if(!lpData) return 0;
431 ret = (SHORT) SCODE_CODE(IShellFolder_CompareIDs((LPSHELLFOLDER)lpData, 0, (LPITEMIDLIST)lParam1, (LPITEMIDLIST)lParam2));
432 TRACE("ret=%i\n",ret);
433 return ret;
436 /*************************************************************************
437 * ShellView_ListViewCompareItems
439 * Compare Function for the Listview (FileOpen Dialog)
441 * PARAMS
442 * lParam1 [I] the first ItemIdList to compare with
443 * lParam2 [I] the second ItemIdList to compare with
444 * lpData [I] The column ID for the header Ctrl to process
446 * RETURNS
447 * A negative value if the first item should precede the second,
448 * a positive value if the first item should follow the second,
449 * or zero if the two items are equivalent
451 * NOTES
452 * FIXME: function does what ShellView_CompareItems is supposed to do.
453 * unify it and figure out how to use the undocumented first parameter
454 * of IShellFolder_CompareIDs to do the job this function does and
455 * move this code to IShellFolder.
456 * make LISTVIEW_SORT_INFO obsolete
457 * the way this function works is only usable if we had only
458 * filesystemfolders (25/10/99 jsch)
460 static INT CALLBACK ShellView_ListViewCompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
462 INT nDiff=0;
463 FILETIME fd1, fd2;
464 char strName1[MAX_PATH], strName2[MAX_PATH];
465 BOOL bIsFolder1, bIsFolder2,bIsBothFolder;
466 LPITEMIDLIST pItemIdList1 = lParam1;
467 LPITEMIDLIST pItemIdList2 = lParam2;
468 LISTVIEW_SORT_INFO *pSortInfo = (LPLISTVIEW_SORT_INFO) lpData;
471 bIsFolder1 = _ILIsFolder(pItemIdList1);
472 bIsFolder2 = _ILIsFolder(pItemIdList2);
473 bIsBothFolder = bIsFolder1 && bIsFolder2;
475 /* When sorting between a File and a Folder, the Folder gets sorted first */
476 if( (bIsFolder1 || bIsFolder2) && !bIsBothFolder)
478 nDiff = bIsFolder1 ? -1 : 1;
480 else
482 /* Sort by Time: Folders or Files can be sorted */
484 if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TIME)
486 _ILGetFileDateTime(pItemIdList1, &fd1);
487 _ILGetFileDateTime(pItemIdList2, &fd2);
488 nDiff = CompareFileTime(&fd2, &fd1);
490 /* Sort by Attribute: Folder or Files can be sorted */
491 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_ATTRIB)
493 _ILGetFileAttributes(pItemIdList1, strName1, MAX_PATH);
494 _ILGetFileAttributes(pItemIdList2, strName2, MAX_PATH);
495 nDiff = lstrcmpiA(strName1, strName2);
497 /* Sort by FileName: Folder or Files can be sorted */
498 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_NAME || bIsBothFolder)
500 /* Sort by Text */
501 _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
502 _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
503 nDiff = lstrcmpiA(strName1, strName2);
505 /* Sort by File Size, Only valid for Files */
506 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_SIZE)
508 nDiff = (INT)(_ILGetFileSize(pItemIdList1, NULL, 0) - _ILGetFileSize(pItemIdList2, NULL, 0));
510 /* Sort by File Type, Only valid for Files */
511 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TYPE)
513 /* Sort by Type */
514 _ILGetFileType(pItemIdList1, strName1, MAX_PATH);
515 _ILGetFileType(pItemIdList2, strName2, MAX_PATH);
516 nDiff = lstrcmpiA(strName1, strName2);
519 /* If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
521 if(nDiff == 0)
523 _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
524 _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
525 nDiff = lstrcmpiA(strName1, strName2);
528 if(!pSortInfo->bIsAscending)
530 nDiff = -nDiff;
533 return nDiff;
537 /**********************************************************
538 * LV_FindItemByPidl()
540 static int LV_FindItemByPidl(
541 IShellViewImpl * This,
542 LPCITEMIDLIST pidl)
544 LVITEMW lvItem;
545 lvItem.iSubItem = 0;
546 lvItem.mask = LVIF_PARAM;
547 for(lvItem.iItem = 0;
548 SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem);
549 lvItem.iItem++)
551 LPITEMIDLIST currentpidl = (LPITEMIDLIST) lvItem.lParam;
552 HRESULT hr = IShellFolder_CompareIDs(This->pSFParent, 0, pidl, currentpidl);
553 if(SUCCEEDED(hr) && !HRESULT_CODE(hr))
555 return lvItem.iItem;
558 return -1;
561 /**********************************************************
562 * LV_AddItem()
564 static BOOLEAN LV_AddItem(IShellViewImpl * This, LPCITEMIDLIST pidl)
566 LVITEMW lvItem;
568 TRACE("(%p)(pidl=%p)\n", This, pidl);
570 lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; /*set the mask*/
571 lvItem.iItem = SendMessageW(This->hWndList, LVM_GETITEMCOUNT, 0, 0); /*add the item to the end of the list*/
572 lvItem.iSubItem = 0;
573 lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidl)); /*set the item's data*/
574 lvItem.pszText = LPSTR_TEXTCALLBACKW; /*get text on a callback basis*/
575 lvItem.iImage = I_IMAGECALLBACK; /*get the image on a callback basis*/
576 return (-1==ListView_InsertItemW(This->hWndList, &lvItem))? FALSE: TRUE;
579 /**********************************************************
580 * LV_DeleteItem()
582 static BOOLEAN LV_DeleteItem(IShellViewImpl * This, LPCITEMIDLIST pidl)
584 int nIndex;
586 TRACE("(%p)(pidl=%p)\n", This, pidl);
588 nIndex = LV_FindItemByPidl(This, ILFindLastID(pidl));
589 return (-1==SendMessageW(This->hWndList, LVM_DELETEITEM, nIndex, 0))? FALSE: TRUE;
592 /**********************************************************
593 * LV_RenameItem()
595 static BOOLEAN LV_RenameItem(IShellViewImpl * This, LPCITEMIDLIST pidlOld, LPCITEMIDLIST pidlNew )
597 int nItem;
598 LVITEMW lvItem;
600 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", This, pidlOld, pidlNew);
602 nItem = LV_FindItemByPidl(This, ILFindLastID(pidlOld));
603 if ( -1 != nItem )
605 lvItem.mask = LVIF_PARAM; /* only the pidl */
606 lvItem.iItem = nItem;
607 SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem);
609 SHFree((LPITEMIDLIST)lvItem.lParam);
610 lvItem.mask = LVIF_PARAM;
611 lvItem.iItem = nItem;
612 lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidlNew)); /* set the item's data */
613 SendMessageW(This->hWndList, LVM_SETITEMW, 0, (LPARAM) &lvItem);
614 SendMessageW(This->hWndList, LVM_UPDATE, nItem, 0);
615 return TRUE; /* FIXME: better handling */
617 return FALSE;
619 /**********************************************************
620 * ShellView_FillList()
622 * - gets the objectlist from the shellfolder
623 * - sorts the list
624 * - fills the list into the view
627 static INT CALLBACK fill_list( LPVOID ptr, LPVOID arg )
629 LPITEMIDLIST pidl = ptr;
630 IShellViewImpl *This = arg;
631 /* in a commdlg This works as a filemask*/
632 if ( IncludeObject(This, pidl)==S_OK ) LV_AddItem(This, pidl);
633 SHFree(pidl);
634 return TRUE;
637 static HRESULT ShellView_FillList(IShellViewImpl * This)
639 LPENUMIDLIST pEnumIDList;
640 LPITEMIDLIST pidl;
641 DWORD dwFetched;
642 HRESULT hRes;
643 HDPA hdpa;
645 TRACE("%p\n",This);
647 /* get the itemlist from the shfolder*/
648 hRes = IShellFolder_EnumObjects(This->pSFParent,This->hWnd, SHCONTF_NONFOLDERS | SHCONTF_FOLDERS, &pEnumIDList);
649 if (hRes != S_OK)
651 if (hRes==S_FALSE)
652 return(NOERROR);
653 return(hRes);
656 /* create a pointer array */
657 hdpa = DPA_Create(16);
658 if (!hdpa)
660 return(E_OUTOFMEMORY);
663 /* copy the items into the array*/
664 while((S_OK == IEnumIDList_Next(pEnumIDList,1, &pidl, &dwFetched)) && dwFetched)
666 if (DPA_InsertPtr(hdpa, 0x7fff, pidl) == -1)
668 SHFree(pidl);
672 /* sort the array */
673 DPA_Sort(hdpa, ShellView_CompareItems, (LPARAM)This->pSFParent);
675 /*turn the listview's redrawing off*/
676 SendMessageA(This->hWndList, WM_SETREDRAW, FALSE, 0);
678 DPA_DestroyCallback( hdpa, fill_list, This );
680 /*turn the listview's redrawing back on and force it to draw*/
681 SendMessageA(This->hWndList, WM_SETREDRAW, TRUE, 0);
683 IEnumIDList_Release(pEnumIDList); /* destroy the list*/
685 return S_OK;
688 /**********************************************************
689 * ShellView_OnCreate()
691 static LRESULT ShellView_OnCreate(IShellViewImpl * This)
693 IDropTarget* pdt;
694 SHChangeNotifyEntry ntreg;
695 IPersistFolder2 * ppf2 = NULL;
697 TRACE("%p\n",This);
699 if(ShellView_CreateList(This))
701 if(ShellView_InitList(This))
703 ShellView_FillList(This);
707 if (SUCCEEDED(IUnknown_QueryInterface((IUnknown*)&This->lpVtbl, &IID_IDropTarget, (LPVOID*)&pdt)))
709 RegisterDragDrop(This->hWnd, pdt);
710 IDropTarget_Release(pdt);
713 /* register for receiving notifications */
714 IShellFolder_QueryInterface(This->pSFParent, &IID_IPersistFolder2, (LPVOID*)&ppf2);
715 if (ppf2)
717 IPersistFolder2_GetCurFolder(ppf2, (LPITEMIDLIST*)&ntreg.pidl);
718 ntreg.fRecursive = TRUE;
719 This->hNotify = SHChangeNotifyRegister(This->hWnd, SHCNF_IDLIST, SHCNE_ALLEVENTS, SHV_CHANGE_NOTIFY, 1, &ntreg);
720 SHFree((LPITEMIDLIST)ntreg.pidl);
721 IPersistFolder2_Release(ppf2);
724 This->hAccel = LoadAcceleratorsA(shell32_hInstance, "shv_accel");
726 return S_OK;
729 /**********************************************************
730 * #### Handling of the menus ####
733 /**********************************************************
734 * ShellView_BuildFileMenu()
736 static HMENU ShellView_BuildFileMenu(IShellViewImpl * This)
737 { WCHAR szText[MAX_PATH];
738 MENUITEMINFOW mii;
739 int nTools,i;
740 HMENU hSubMenu;
742 TRACE("(%p)\n",This);
744 hSubMenu = CreatePopupMenu();
745 if(hSubMenu)
746 { /*get the number of items in our global array*/
747 for(nTools = 0; Tools[nTools].idCommand != -1; nTools++){}
749 /*add the menu items*/
750 for(i = 0; i < nTools; i++)
752 LoadStringW(shell32_hInstance, Tools[i].idMenuString, szText, MAX_PATH);
754 ZeroMemory(&mii, sizeof(mii));
755 mii.cbSize = sizeof(mii);
756 mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
758 if(BTNS_SEP != Tools[i].bStyle) /* no separator*/
760 mii.fType = MFT_STRING;
761 mii.fState = MFS_ENABLED;
762 mii.dwTypeData = szText;
763 mii.wID = Tools[i].idCommand;
765 else
767 mii.fType = MFT_SEPARATOR;
769 /* tack This item onto the end of the menu */
770 InsertMenuItemW(hSubMenu, (UINT)-1, TRUE, &mii);
773 TRACE("-- return (menu=%p)\n",hSubMenu);
774 return hSubMenu;
776 /**********************************************************
777 * ShellView_MergeFileMenu()
779 static void ShellView_MergeFileMenu(IShellViewImpl * This, HMENU hSubMenu)
780 { TRACE("(%p)->(submenu=%p) stub\n",This,hSubMenu);
782 if(hSubMenu)
783 { /*insert This item at the beginning of the menu */
784 MENUITEMINFOA mii;
786 mii.cbSize = sizeof(mii);
787 mii.fMask = MIIM_ID | MIIM_TYPE;
788 mii.wID = 0;
789 mii.fType = MFT_SEPARATOR;
790 InsertMenuItemA(hSubMenu, 0, TRUE, &mii);
792 mii.cbSize = sizeof(mii);
793 mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
794 mii.dwTypeData = (LPSTR)"dummy45";
795 mii.fState = MFS_ENABLED;
796 mii.wID = IDM_MYFILEITEM;
797 mii.fType = MFT_STRING;
798 InsertMenuItemA(hSubMenu, 0, TRUE, &mii);
800 TRACE("--\n");
803 /**********************************************************
804 * ShellView_MergeViewMenu()
807 static void ShellView_MergeViewMenu(IShellViewImpl * This, HMENU hSubMenu)
809 TRACE("(%p)->(submenu=%p)\n",This,hSubMenu);
811 if(hSubMenu)
812 { /*add a separator at the correct position in the menu*/
813 MENUITEMINFOA mii;
814 static char view[] = "View";
816 ZeroMemory(&mii, sizeof(mii));
817 mii.cbSize = sizeof(mii);
818 mii.fMask = MIIM_ID | MIIM_TYPE;
819 mii.wID = 0;
820 mii.fType = MFT_SEPARATOR;
821 InsertMenuItemA(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
823 mii.cbSize = sizeof(mii);
824 mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_DATA;
825 mii.fType = MFT_STRING;
826 mii.dwTypeData = view;
827 mii.hSubMenu = LoadMenuA(shell32_hInstance, "MENU_001");
828 InsertMenuItemA(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
832 /**********************************************************
833 * ShellView_GetSelections()
835 * - fills the this->apidl list with the selected objects
837 * RETURNS
838 * number of selected items
840 static UINT ShellView_GetSelections(IShellViewImpl * This)
842 LVITEMW lvItem;
843 UINT i = 0;
845 SHFree(This->apidl);
847 This->cidl = SendMessageW(This->hWndList, LVM_GETSELECTEDCOUNT, 0, 0);
848 This->apidl = SHAlloc(This->cidl * sizeof(LPITEMIDLIST));
850 TRACE("selected=%i\n", This->cidl);
852 if(This->apidl)
854 TRACE("-- Items selected =%u\n", This->cidl);
856 lvItem.mask = LVIF_STATE | LVIF_PARAM;
857 lvItem.stateMask = LVIS_SELECTED;
858 lvItem.iItem = 0;
859 lvItem.iSubItem = 0;
861 while(ListView_GetItemW(This->hWndList, &lvItem) && (i < This->cidl))
863 if(lvItem.state & LVIS_SELECTED)
865 This->apidl[i] = (LPITEMIDLIST)lvItem.lParam;
866 i++;
867 TRACE("-- selected Item found\n");
869 lvItem.iItem++;
872 return This->cidl;
876 /**********************************************************
877 * ShellView_OpenSelectedItems()
879 static HRESULT ShellView_OpenSelectedItems(IShellViewImpl * This)
881 static UINT CF_IDLIST = 0;
882 HRESULT hr;
883 IDataObject* selection;
884 FORMATETC fetc;
885 STGMEDIUM stgm;
886 LPIDA pIDList;
887 LPCITEMIDLIST parent_pidl;
888 WCHAR parent_path[MAX_PATH];
889 LPCWSTR parent_dir = NULL;
890 SFGAOF attribs;
891 int i;
893 if (0 == ShellView_GetSelections(This))
895 return S_OK;
897 hr = IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl,
898 (LPCITEMIDLIST*)This->apidl, &IID_IDataObject,
899 0, (LPVOID *)&selection);
900 if (FAILED(hr))
901 return hr;
903 if (0 == CF_IDLIST)
905 CF_IDLIST = RegisterClipboardFormatW(CFSTR_SHELLIDLISTW);
907 fetc.cfFormat = CF_IDLIST;
908 fetc.ptd = NULL;
909 fetc.dwAspect = DVASPECT_CONTENT;
910 fetc.lindex = -1;
911 fetc.tymed = TYMED_HGLOBAL;
913 hr = IDataObject_QueryGetData(selection, &fetc);
914 if (FAILED(hr))
915 return hr;
917 hr = IDataObject_GetData(selection, &fetc, &stgm);
918 if (FAILED(hr))
919 return hr;
921 pIDList = GlobalLock(stgm.u.hGlobal);
923 parent_pidl = (LPCITEMIDLIST) ((LPBYTE)pIDList+pIDList->aoffset[0]);
924 hr = IShellFolder_GetAttributesOf(This->pSFParent, 1, &parent_pidl, &attribs);
925 if (SUCCEEDED(hr) && (attribs & SFGAO_FILESYSTEM) &&
926 SHGetPathFromIDListW(parent_pidl, parent_path))
928 parent_dir = parent_path;
931 for (i = pIDList->cidl; i > 0; --i)
933 LPCITEMIDLIST pidl;
935 pidl = (LPCITEMIDLIST)((LPBYTE)pIDList+pIDList->aoffset[i]);
937 attribs = SFGAO_FOLDER;
938 hr = IShellFolder_GetAttributesOf(This->pSFParent, 1, &pidl, &attribs);
940 if (SUCCEEDED(hr) && ! (attribs & SFGAO_FOLDER))
942 SHELLEXECUTEINFOW shexinfo;
944 shexinfo.cbSize = sizeof(SHELLEXECUTEINFOW);
945 shexinfo.fMask = SEE_MASK_INVOKEIDLIST; /* SEE_MASK_IDLIST is also possible. */
946 shexinfo.hwnd = NULL;
947 shexinfo.lpVerb = NULL;
948 shexinfo.lpFile = NULL;
949 shexinfo.lpParameters = NULL;
950 shexinfo.lpDirectory = parent_dir;
951 shexinfo.nShow = SW_NORMAL;
952 shexinfo.lpIDList = ILCombine(parent_pidl, pidl);
954 ShellExecuteExW(&shexinfo); /* Discard error/success info */
956 ILFree(shexinfo.lpIDList);
960 GlobalUnlock(stgm.u.hGlobal);
961 ReleaseStgMedium(&stgm);
963 IDataObject_Release(selection);
965 return S_OK;
968 /**********************************************************
969 * ShellView_DoContextMenu()
971 static void ShellView_DoContextMenu(IShellViewImpl * This, WORD x, WORD y, BOOL bDefault)
972 { UINT uCommand;
973 DWORD wFlags;
974 HMENU hMenu;
975 BOOL fExplore = FALSE;
976 HWND hwndTree = 0;
977 LPCONTEXTMENU pContextMenu = NULL;
978 IContextMenu2 *pCM = NULL;
979 CMINVOKECOMMANDINFO cmi;
981 TRACE("(%p)->(0x%08x 0x%08x 0x%08x) stub\n",This, x, y, bDefault);
983 /* look, what's selected and create a context menu object of it*/
984 if( ShellView_GetSelections(This) )
986 IShellFolder_GetUIObjectOf( This->pSFParent, This->hWndParent, This->cidl, (LPCITEMIDLIST*)This->apidl,
987 &IID_IContextMenu, NULL, (LPVOID *)&pContextMenu);
989 if(pContextMenu)
991 TRACE("-- pContextMenu\n");
992 hMenu = CreatePopupMenu();
994 if( hMenu )
996 /* See if we are in Explore or Open mode. If the browser's tree is present, we are in Explore mode.*/
997 if(SUCCEEDED(IShellBrowser_GetControlWindow(This->pShellBrowser,FCW_TREE, &hwndTree)) && hwndTree)
999 TRACE("-- explore mode\n");
1000 fExplore = TRUE;
1003 /* build the flags depending on what we can do with the selected item */
1004 wFlags = CMF_NORMAL | (This->cidl != 1 ? 0 : CMF_CANRENAME) | (fExplore ? CMF_EXPLORE : 0);
1006 /* let the ContextMenu merge its items in */
1007 if (SUCCEEDED(IContextMenu_QueryContextMenu( pContextMenu, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, wFlags )))
1009 if (This->FolderSettings.fFlags & FWF_DESKTOP)
1010 SetMenuDefaultItem(hMenu, FCIDM_SHVIEW_OPEN, MF_BYCOMMAND);
1012 if( bDefault )
1014 TRACE("-- get menu default command\n");
1015 uCommand = GetMenuDefaultItem(hMenu, FALSE, GMDI_GOINTOPOPUPS);
1017 else
1019 TRACE("-- track popup\n");
1020 uCommand = TrackPopupMenu( hMenu,TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
1023 if(uCommand > 0)
1025 TRACE("-- uCommand=%u\n", uCommand);
1026 if (uCommand==FCIDM_SHVIEW_OPEN && IsInCommDlg(This))
1028 TRACE("-- dlg: OnDefaultCommand\n");
1029 if (OnDefaultCommand(This) != S_OK)
1031 ShellView_OpenSelectedItems(This);
1034 else
1036 TRACE("-- explore -- invoke command\n");
1037 ZeroMemory(&cmi, sizeof(cmi));
1038 cmi.cbSize = sizeof(cmi);
1039 cmi.hwnd = This->hWndParent; /* this window has to answer CWM_GETISHELLBROWSER */
1040 cmi.lpVerb = MAKEINTRESOURCEA(uCommand);
1041 IContextMenu_InvokeCommand(pContextMenu, &cmi);
1044 DestroyMenu(hMenu);
1047 if (pContextMenu)
1048 IContextMenu_Release(pContextMenu);
1051 else /* background context menu */
1053 hMenu = CreatePopupMenu();
1055 pCM = ISvBgCm_Constructor(This->pSFParent, FALSE);
1056 IContextMenu2_QueryContextMenu(pCM, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, 0);
1058 uCommand = TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
1059 DestroyMenu(hMenu);
1061 TRACE("-- (%p)->(uCommand=0x%08x )\n",This, uCommand);
1063 ZeroMemory(&cmi, sizeof(cmi));
1064 cmi.cbSize = sizeof(cmi);
1065 cmi.lpVerb = MAKEINTRESOURCEA(uCommand);
1066 cmi.hwnd = This->hWndParent;
1067 IContextMenu2_InvokeCommand(pCM, &cmi);
1069 IContextMenu2_Release(pCM);
1073 /**********************************************************
1074 * ##### message handling #####
1077 /**********************************************************
1078 * ShellView_OnSize()
1080 static LRESULT ShellView_OnSize(IShellViewImpl * This, WORD wWidth, WORD wHeight)
1082 TRACE("%p width=%u height=%u\n",This, wWidth,wHeight);
1084 /*resize the ListView to fit our window*/
1085 if(This->hWndList)
1087 MoveWindow(This->hWndList, 0, 0, wWidth, wHeight, TRUE);
1090 return S_OK;
1092 /**********************************************************
1093 * ShellView_OnDeactivate()
1095 * NOTES
1096 * internal
1098 static void ShellView_OnDeactivate(IShellViewImpl * This)
1100 TRACE("%p\n",This);
1102 if(This->uState != SVUIA_DEACTIVATE)
1104 if(This->hMenu)
1106 IShellBrowser_SetMenuSB(This->pShellBrowser,0, 0, 0);
1107 IShellBrowser_RemoveMenusSB(This->pShellBrowser,This->hMenu);
1108 DestroyMenu(This->hMenu);
1109 This->hMenu = 0;
1112 This->uState = SVUIA_DEACTIVATE;
1116 /**********************************************************
1117 * ShellView_OnActivate()
1119 static LRESULT ShellView_OnActivate(IShellViewImpl * This, UINT uState)
1120 { OLEMENUGROUPWIDTHS omw = { {0, 0, 0, 0, 0, 0} };
1121 MENUITEMINFOA mii;
1122 CHAR szText[MAX_PATH];
1124 TRACE("%p uState=%x\n",This,uState);
1126 /*don't do anything if the state isn't really changing */
1127 if(This->uState == uState)
1129 return S_OK;
1132 ShellView_OnDeactivate(This);
1134 /*only do This if we are active */
1135 if(uState != SVUIA_DEACTIVATE)
1137 /*merge the menus */
1138 This->hMenu = CreateMenu();
1140 if(This->hMenu)
1142 IShellBrowser_InsertMenusSB(This->pShellBrowser, This->hMenu, &omw);
1143 TRACE("-- after fnInsertMenusSB\n");
1145 /*build the top level menu get the menu item's text*/
1146 strcpy(szText,"dummy 31");
1148 ZeroMemory(&mii, sizeof(mii));
1149 mii.cbSize = sizeof(mii);
1150 mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_STATE;
1151 mii.fType = MFT_STRING;
1152 mii.fState = MFS_ENABLED;
1153 mii.dwTypeData = szText;
1154 mii.hSubMenu = ShellView_BuildFileMenu(This);
1156 /*insert our menu into the menu bar*/
1157 if(mii.hSubMenu)
1159 InsertMenuItemA(This->hMenu, FCIDM_MENU_HELP, FALSE, &mii);
1162 /*get the view menu so we can merge with it*/
1163 ZeroMemory(&mii, sizeof(mii));
1164 mii.cbSize = sizeof(mii);
1165 mii.fMask = MIIM_SUBMENU;
1167 if(GetMenuItemInfoA(This->hMenu, FCIDM_MENU_VIEW, FALSE, &mii))
1169 ShellView_MergeViewMenu(This, mii.hSubMenu);
1172 /*add the items that should only be added if we have the focus*/
1173 if(SVUIA_ACTIVATE_FOCUS == uState)
1175 /*get the file menu so we can merge with it */
1176 ZeroMemory(&mii, sizeof(mii));
1177 mii.cbSize = sizeof(mii);
1178 mii.fMask = MIIM_SUBMENU;
1180 if(GetMenuItemInfoA(This->hMenu, FCIDM_MENU_FILE, FALSE, &mii))
1182 ShellView_MergeFileMenu(This, mii.hSubMenu);
1185 TRACE("-- before fnSetMenuSB\n");
1186 IShellBrowser_SetMenuSB(This->pShellBrowser, This->hMenu, 0, This->hWnd);
1189 This->uState = uState;
1190 TRACE("--\n");
1191 return S_OK;
1194 /**********************************************************
1195 * ShellView_OnSetFocus()
1198 static LRESULT ShellView_OnSetFocus(IShellViewImpl * This)
1200 TRACE("%p\n",This);
1202 /* Tell the browser one of our windows has received the focus. This
1203 should always be done before merging menus (OnActivate merges the
1204 menus) if one of our windows has the focus.*/
1206 IShellBrowser_OnViewWindowActive(This->pShellBrowser,(IShellView*) This);
1207 ShellView_OnActivate(This, SVUIA_ACTIVATE_FOCUS);
1209 /* Set the focus to the listview */
1210 SetFocus(This->hWndList);
1212 /* Notify the ICommDlgBrowser interface */
1213 OnStateChange(This,CDBOSC_SETFOCUS);
1215 return 0;
1218 /**********************************************************
1219 * ShellView_OnKillFocus()
1221 static LRESULT ShellView_OnKillFocus(IShellViewImpl * This)
1223 TRACE("(%p) stub\n",This);
1225 ShellView_OnActivate(This, SVUIA_ACTIVATE_NOFOCUS);
1226 /* Notify the ICommDlgBrowser */
1227 OnStateChange(This,CDBOSC_KILLFOCUS);
1229 return 0;
1232 /**********************************************************
1233 * ShellView_OnCommand()
1235 * NOTES
1236 * the CmdID's are the ones from the context menu
1238 static LRESULT ShellView_OnCommand(IShellViewImpl * This,DWORD dwCmdID, DWORD dwCmd, HWND hwndCmd)
1240 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n",This, dwCmdID, dwCmd, hwndCmd);
1242 switch(dwCmdID)
1244 case FCIDM_SHVIEW_SMALLICON:
1245 This->FolderSettings.ViewMode = FVM_SMALLICON;
1246 SetStyle (This, LVS_SMALLICON, LVS_TYPEMASK);
1247 CheckToolbar(This);
1248 break;
1250 case FCIDM_SHVIEW_BIGICON:
1251 This->FolderSettings.ViewMode = FVM_ICON;
1252 SetStyle (This, LVS_ICON, LVS_TYPEMASK);
1253 CheckToolbar(This);
1254 break;
1256 case FCIDM_SHVIEW_LISTVIEW:
1257 This->FolderSettings.ViewMode = FVM_LIST;
1258 SetStyle (This, LVS_LIST, LVS_TYPEMASK);
1259 CheckToolbar(This);
1260 break;
1262 case FCIDM_SHVIEW_REPORTVIEW:
1263 This->FolderSettings.ViewMode = FVM_DETAILS;
1264 SetStyle (This, LVS_REPORT, LVS_TYPEMASK);
1265 CheckToolbar(This);
1266 break;
1268 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1269 case 0x30:
1270 case 0x31:
1271 case 0x32:
1272 case 0x33:
1273 This->ListViewSortInfo.nHeaderID = dwCmdID - 0x30;
1274 This->ListViewSortInfo.bIsAscending = TRUE;
1275 This->ListViewSortInfo.nLastHeaderID = This->ListViewSortInfo.nHeaderID;
1276 SendMessageA(This->hWndList, LVM_SORTITEMS, (WPARAM) &This->ListViewSortInfo, (LPARAM)ShellView_ListViewCompareItems);
1277 break;
1279 default:
1280 TRACE("-- COMMAND 0x%04x unhandled\n", dwCmdID);
1282 return 0;
1285 /**********************************************************
1286 * ShellView_OnNotify()
1289 static LRESULT ShellView_OnNotify(IShellViewImpl * This, UINT CtlID, LPNMHDR lpnmh)
1290 { LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)lpnmh;
1291 NMLVDISPINFOW *lpdi = (NMLVDISPINFOW *)lpnmh;
1292 LPITEMIDLIST pidl;
1294 TRACE("%p CtlID=%u lpnmh->code=%x\n",This,CtlID,lpnmh->code);
1296 switch(lpnmh->code)
1298 case NM_SETFOCUS:
1299 TRACE("-- NM_SETFOCUS %p\n",This);
1300 ShellView_OnSetFocus(This);
1301 break;
1303 case NM_KILLFOCUS:
1304 TRACE("-- NM_KILLFOCUS %p\n",This);
1305 ShellView_OnDeactivate(This);
1306 /* Notify the ICommDlgBrowser interface */
1307 OnStateChange(This,CDBOSC_KILLFOCUS);
1308 break;
1310 case NM_CUSTOMDRAW:
1311 TRACE("-- NM_CUSTOMDRAW %p\n",This);
1312 return CDRF_DODEFAULT;
1314 case NM_RELEASEDCAPTURE:
1315 TRACE("-- NM_RELEASEDCAPTURE %p\n",This);
1316 break;
1318 case NM_CLICK:
1319 TRACE("-- NM_CLICK %p\n",This);
1320 break;
1322 case NM_RCLICK:
1323 TRACE("-- NM_RCLICK %p\n",This);
1324 break;
1326 case NM_DBLCLK:
1327 TRACE("-- NM_DBLCLK %p\n",This);
1328 if (OnDefaultCommand(This) != S_OK) ShellView_OpenSelectedItems(This);
1329 break;
1331 case NM_RETURN:
1332 TRACE("-- NM_RETURN %p\n",This);
1333 if (OnDefaultCommand(This) != S_OK) ShellView_OpenSelectedItems(This);
1334 break;
1336 case HDN_ENDTRACKW:
1337 TRACE("-- HDN_ENDTRACKW %p\n",This);
1338 /*nColumn1 = ListView_GetColumnWidth(This->hWndList, 0);
1339 nColumn2 = ListView_GetColumnWidth(This->hWndList, 1);*/
1340 break;
1342 case LVN_DELETEITEM:
1343 TRACE("-- LVN_DELETEITEM %p\n",This);
1344 SHFree((LPITEMIDLIST)lpnmlv->lParam); /*delete the pidl because we made a copy of it*/
1345 break;
1347 case LVN_DELETEALLITEMS:
1348 TRACE("-- LVN_DELETEALLITEMS %p\n",This);
1349 return FALSE;
1351 case LVN_INSERTITEM:
1352 TRACE("-- LVN_INSERTITEM (STUB)%p\n",This);
1353 break;
1355 case LVN_ITEMACTIVATE:
1356 TRACE("-- LVN_ITEMACTIVATE %p\n",This);
1357 OnStateChange(This, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
1358 break;
1360 case LVN_COLUMNCLICK:
1361 This->ListViewSortInfo.nHeaderID = lpnmlv->iSubItem;
1362 if(This->ListViewSortInfo.nLastHeaderID == This->ListViewSortInfo.nHeaderID)
1364 This->ListViewSortInfo.bIsAscending = !This->ListViewSortInfo.bIsAscending;
1366 else
1368 This->ListViewSortInfo.bIsAscending = TRUE;
1370 This->ListViewSortInfo.nLastHeaderID = This->ListViewSortInfo.nHeaderID;
1372 SendMessageW(lpnmlv->hdr.hwndFrom, LVM_SORTITEMS, (WPARAM) &This->ListViewSortInfo, (LPARAM)ShellView_ListViewCompareItems);
1373 break;
1375 case LVN_GETDISPINFOA:
1376 case LVN_GETDISPINFOW:
1377 TRACE("-- LVN_GETDISPINFO %p\n",This);
1378 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1380 if(lpdi->item.mask & LVIF_TEXT) /* text requested */
1382 if (This->pSF2Parent)
1384 SHELLDETAILS sd;
1385 IShellFolder2_GetDetailsOf(This->pSF2Parent, pidl, lpdi->item.iSubItem, &sd);
1386 if (lpnmh->code == LVN_GETDISPINFOA)
1388 /* shouldn't happen */
1389 NMLVDISPINFOA *lpdiA = (NMLVDISPINFOA *)lpnmh;
1390 StrRetToStrNA( lpdiA->item.pszText, lpdiA->item.cchTextMax, &sd.str, NULL);
1391 TRACE("-- text=%s\n",lpdiA->item.pszText);
1393 else /* LVN_GETDISPINFOW */
1395 StrRetToStrNW( lpdi->item.pszText, lpdi->item.cchTextMax, &sd.str, NULL);
1396 TRACE("-- text=%s\n",debugstr_w(lpdi->item.pszText));
1399 else
1401 FIXME("no SF2\n");
1404 if(lpdi->item.mask & LVIF_IMAGE) /* image requested */
1406 lpdi->item.iImage = SHMapPIDLToSystemImageListIndex(This->pSFParent, pidl, 0);
1408 break;
1410 case LVN_ITEMCHANGED:
1411 TRACE("-- LVN_ITEMCHANGED %p\n",This);
1412 OnStateChange(This, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
1413 break;
1415 case LVN_BEGINDRAG:
1416 case LVN_BEGINRDRAG:
1417 TRACE("-- LVN_BEGINDRAG\n");
1419 if (ShellView_GetSelections(This))
1421 IDataObject * pda;
1422 DWORD dwAttributes = SFGAO_CANLINK;
1423 DWORD dwEffect = DROPEFFECT_COPY | DROPEFFECT_MOVE;
1425 if (SUCCEEDED(IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, (LPCITEMIDLIST*)This->apidl, &IID_IDataObject,0,(LPVOID *)&pda)))
1427 IDropSource * pds = (IDropSource*)&(This->lpvtblDropSource); /* own DropSource interface */
1429 if (SUCCEEDED(IShellFolder_GetAttributesOf(This->pSFParent, This->cidl, (LPCITEMIDLIST*)This->apidl, &dwAttributes)))
1431 if (dwAttributes & SFGAO_CANLINK)
1433 dwEffect |= DROPEFFECT_LINK;
1437 if (pds)
1439 DWORD dwEffect2;
1440 DoDragDrop(pda, pds, dwEffect, &dwEffect2);
1442 IDataObject_Release(pda);
1445 break;
1447 case LVN_BEGINLABELEDITW:
1449 DWORD dwAttr = SFGAO_CANRENAME;
1450 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1452 TRACE("-- LVN_BEGINLABELEDITW %p\n",This);
1454 IShellFolder_GetAttributesOf(This->pSFParent, 1, (LPCITEMIDLIST*)&pidl, &dwAttr);
1455 if (SFGAO_CANRENAME & dwAttr)
1457 return FALSE;
1459 return TRUE;
1462 case LVN_ENDLABELEDITW:
1464 TRACE("-- LVN_ENDLABELEDITA %p\n",This);
1465 if (lpdi->item.pszText)
1467 HRESULT hr;
1468 LVITEMW lvItem;
1470 lvItem.iItem = lpdi->item.iItem;
1471 lvItem.iSubItem = 0;
1472 lvItem.mask = LVIF_PARAM;
1473 SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem);
1475 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1476 hr = IShellFolder_SetNameOf(This->pSFParent, 0, pidl, lpdi->item.pszText, SHGDN_INFOLDER, &pidl);
1478 if(SUCCEEDED(hr) && pidl)
1480 lvItem.mask = LVIF_PARAM;
1481 lvItem.lParam = (LPARAM)pidl;
1482 SendMessageW(This->hWndList, LVM_SETITEMW, 0, (LPARAM) &lvItem);
1483 return TRUE;
1486 return FALSE;
1489 case LVN_KEYDOWN:
1491 /* MSG msg;
1492 msg.hwnd = This->hWnd;
1493 msg.message = WM_KEYDOWN;
1494 msg.wParam = plvKeyDown->wVKey;
1495 msg.lParam = 0;
1496 msg.time = 0;
1497 msg.pt = 0;*/
1499 LPNMLVKEYDOWN plvKeyDown = (LPNMLVKEYDOWN) lpnmh;
1501 /* initiate a rename of the selected file or directory */
1502 if(plvKeyDown->wVKey == VK_F2)
1504 /* see how many files are selected */
1505 int i = SendMessageW(This->hWndList, LVM_GETSELECTEDCOUNT, 0, 0);
1507 /* get selected item */
1508 if(i == 1)
1510 /* get selected item */
1511 i = SendMessageW(This->hWndList, LVM_GETNEXTITEM, -1, MAKELPARAM (LVNI_SELECTED, 0));
1513 SendMessageW(This->hWndList, LVM_ENSUREVISIBLE, i, 0);
1514 SendMessageW(This->hWndList, LVM_EDITLABELW, i, 0);
1517 #if 0
1518 TranslateAccelerator(This->hWnd, This->hAccel, &msg)
1519 #endif
1520 else if(plvKeyDown->wVKey == VK_DELETE)
1522 UINT i;
1523 int item_index;
1524 LVITEMA item;
1525 LPITEMIDLIST* pItems;
1526 ISFHelper *psfhlp;
1528 IShellFolder_QueryInterface(This->pSFParent, &IID_ISFHelper,
1529 (LPVOID*)&psfhlp);
1531 if (psfhlp == NULL)
1532 break;
1534 if(!(i = SendMessageW(This->hWndList, LVM_GETSELECTEDCOUNT, 0, 0)))
1535 break;
1537 /* allocate memory for the pidl array */
1538 pItems = HeapAlloc(GetProcessHeap(), 0,
1539 sizeof(LPITEMIDLIST) * i);
1541 /* retrieve all selected items */
1542 i = 0;
1543 item_index = -1;
1544 while(SendMessageW(This->hWndList, LVM_GETSELECTEDCOUNT, 0, 0) > i)
1546 /* get selected item */
1547 item_index = SendMessageW(This->hWndList, LVM_GETNEXTITEM, item_index,
1548 MAKELPARAM (LVNI_SELECTED, 0));
1549 item.iItem = item_index;
1550 item.mask = LVIF_PARAM;
1551 SendMessageA(This->hWndList, LVM_GETITEMA, 0, (LPARAM) &item);
1553 /* get item pidl */
1554 pItems[i] = (LPITEMIDLIST)item.lParam;
1556 i++;
1559 /* perform the item deletion */
1560 ISFHelper_DeleteItems(psfhlp, i, (LPCITEMIDLIST*)pItems);
1562 /* free pidl array memory */
1563 HeapFree(GetProcessHeap(), 0, pItems);
1566 /* Initiate a refresh */
1567 else if(plvKeyDown->wVKey == VK_F5)
1569 IShellView_Refresh((IShellView*)This);
1572 else if(plvKeyDown->wVKey == VK_BACK)
1574 LPSHELLBROWSER lpSb;
1575 if((lpSb = (LPSHELLBROWSER)SendMessageW(This->hWndParent, CWM_GETISHELLBROWSER, 0, 0)))
1577 IShellBrowser_BrowseObject(lpSb, NULL, SBSP_PARENT);
1581 else
1582 FIXME("LVN_KEYDOWN key=0x%08x\n",plvKeyDown->wVKey);
1584 break;
1586 default:
1587 TRACE("-- %p WM_COMMAND %x unhandled\n", This, lpnmh->code);
1588 break;
1590 return 0;
1593 /**********************************************************
1594 * ShellView_OnChange()
1597 static LRESULT ShellView_OnChange(IShellViewImpl * This, const LPCITEMIDLIST * Pidls, LONG wEventId)
1600 TRACE("(%p)(%p,%p,0x%08x)\n", This, Pidls[0], Pidls[1], wEventId);
1601 switch(wEventId)
1603 case SHCNE_MKDIR:
1604 case SHCNE_CREATE:
1605 LV_AddItem(This, Pidls[0]);
1606 break;
1607 case SHCNE_RMDIR:
1608 case SHCNE_DELETE:
1609 LV_DeleteItem(This, Pidls[0]);
1610 break;
1611 case SHCNE_RENAMEFOLDER:
1612 case SHCNE_RENAMEITEM:
1613 LV_RenameItem(This, Pidls[0], Pidls[1]);
1614 break;
1615 case SHCNE_UPDATEITEM:
1616 break;
1618 return TRUE;
1620 /**********************************************************
1621 * ShellView_WndProc
1624 static LRESULT CALLBACK ShellView_WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
1626 IShellViewImpl * pThis = (IShellViewImpl*)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
1627 LPCREATESTRUCTW lpcs;
1629 TRACE("(hwnd=%p msg=%x wparm=%lx lparm=%lx)\n",hWnd, uMessage, wParam, lParam);
1631 switch (uMessage)
1633 case WM_NCCREATE:
1634 lpcs = (LPCREATESTRUCTW)lParam;
1635 pThis = lpcs->lpCreateParams;
1636 SetWindowLongPtrW(hWnd, GWLP_USERDATA, (ULONG_PTR)pThis);
1637 pThis->hWnd = hWnd; /*set the window handle*/
1638 break;
1640 case WM_SIZE: return ShellView_OnSize(pThis,LOWORD(lParam), HIWORD(lParam));
1641 case WM_SETFOCUS: return ShellView_OnSetFocus(pThis);
1642 case WM_KILLFOCUS: return ShellView_OnKillFocus(pThis);
1643 case WM_CREATE: return ShellView_OnCreate(pThis);
1644 case WM_ACTIVATE: return ShellView_OnActivate(pThis, SVUIA_ACTIVATE_FOCUS);
1645 case WM_NOTIFY: return ShellView_OnNotify(pThis,(UINT)wParam, (LPNMHDR)lParam);
1646 case WM_COMMAND: return ShellView_OnCommand(pThis,
1647 GET_WM_COMMAND_ID(wParam, lParam),
1648 GET_WM_COMMAND_CMD(wParam, lParam),
1649 GET_WM_COMMAND_HWND(wParam, lParam));
1650 case SHV_CHANGE_NOTIFY: return ShellView_OnChange(pThis, (const LPCITEMIDLIST*)wParam, (LONG)lParam);
1652 case WM_CONTEXTMENU: ShellView_DoContextMenu(pThis, LOWORD(lParam), HIWORD(lParam), FALSE);
1653 return 0;
1655 case WM_SHOWWINDOW: UpdateWindow(pThis->hWndList);
1656 break;
1658 case WM_GETDLGCODE: return SendMessageA(pThis->hWndList,uMessage,0,0);
1660 case WM_DESTROY:
1661 RevokeDragDrop(pThis->hWnd);
1662 SHChangeNotifyDeregister(pThis->hNotify);
1663 break;
1665 case WM_ERASEBKGND:
1666 if ((pThis->FolderSettings.fFlags & FWF_DESKTOP) ||
1667 (pThis->FolderSettings.fFlags & FWF_TRANSPARENT))
1668 return 1;
1669 break;
1672 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
1674 /**********************************************************
1677 * The INTERFACE of the IShellView object
1680 **********************************************************
1681 * IShellView_QueryInterface
1683 static HRESULT WINAPI IShellView_fnQueryInterface(IShellView2 * iface,REFIID riid, LPVOID *ppvObj)
1685 IShellViewImpl *This = (IShellViewImpl *)iface;
1687 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1689 *ppvObj = NULL;
1691 if(IsEqualIID(riid, &IID_IUnknown))
1693 *ppvObj = This;
1695 else if(IsEqualIID(riid, &IID_IShellView))
1697 *ppvObj = This;
1699 else if(IsEqualIID(riid, &IID_IShellView2))
1701 *ppvObj = This;
1703 else if(IsEqualIID(riid, &IID_IFolderView))
1705 *ppvObj = &This->lpvtblFolderView;
1707 else if(IsEqualIID(riid, &IID_IOleCommandTarget))
1709 *ppvObj = &This->lpvtblOleCommandTarget;
1711 else if(IsEqualIID(riid, &IID_IDropTarget))
1713 *ppvObj = &This->lpvtblDropTarget;
1715 else if(IsEqualIID(riid, &IID_IDropSource))
1717 *ppvObj = &This->lpvtblDropSource;
1719 else if(IsEqualIID(riid, &IID_IViewObject))
1721 *ppvObj = &This->lpvtblViewObject;
1724 if(*ppvObj)
1726 IUnknown_AddRef( (IUnknown*)*ppvObj );
1727 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1728 return S_OK;
1730 TRACE("-- Interface: E_NOINTERFACE\n");
1731 return E_NOINTERFACE;
1734 /**********************************************************
1735 * IShellView_AddRef
1737 static ULONG WINAPI IShellView_fnAddRef(IShellView2 * iface)
1739 IShellViewImpl *This = (IShellViewImpl *)iface;
1740 ULONG refCount = InterlockedIncrement(&This->ref);
1742 TRACE("(%p)->(count=%u)\n", This, refCount - 1);
1744 return refCount;
1746 /**********************************************************
1747 * IShellView_Release
1749 static ULONG WINAPI IShellView_fnRelease(IShellView2 * iface)
1751 IShellViewImpl *This = (IShellViewImpl *)iface;
1752 ULONG refCount = InterlockedDecrement(&This->ref);
1754 TRACE("(%p)->(count=%i)\n", This, refCount + 1);
1756 if (!refCount)
1758 TRACE(" destroying IShellView(%p)\n",This);
1760 DestroyWindow(This->hWndList);
1762 if(This->pSFParent)
1763 IShellFolder_Release(This->pSFParent);
1765 if(This->pSF2Parent)
1766 IShellFolder2_Release(This->pSF2Parent);
1768 SHFree(This->apidl);
1770 if(This->pAdvSink)
1771 IAdviseSink_Release(This->pAdvSink);
1773 HeapFree(GetProcessHeap(),0,This);
1775 return refCount;
1778 /**********************************************************
1779 * ShellView_GetWindow
1781 static HRESULT WINAPI IShellView_fnGetWindow(IShellView2 * iface,HWND * phWnd)
1783 IShellViewImpl *This = (IShellViewImpl *)iface;
1785 TRACE("(%p)\n",This);
1787 *phWnd = This->hWnd;
1789 return S_OK;
1792 static HRESULT WINAPI IShellView_fnContextSensitiveHelp(IShellView2 * iface,BOOL fEnterMode)
1794 IShellViewImpl *This = (IShellViewImpl *)iface;
1796 FIXME("(%p) stub\n",This);
1798 return E_NOTIMPL;
1801 /**********************************************************
1802 * IShellView_TranslateAccelerator
1804 * FIXME:
1805 * use the accel functions
1807 static HRESULT WINAPI IShellView_fnTranslateAccelerator(IShellView2 * iface,LPMSG lpmsg)
1809 #if 0
1810 IShellViewImpl *This = (IShellViewImpl *)iface;
1812 FIXME("(%p)->(%p: hwnd=%x msg=%x lp=%x wp=%x) stub\n",This,lpmsg, lpmsg->hwnd, lpmsg->message, lpmsg->lParam, lpmsg->wParam);
1813 #endif
1815 if ((lpmsg->message>=WM_KEYFIRST) && (lpmsg->message>=WM_KEYLAST))
1817 TRACE("-- key=0x04%lx\n",lpmsg->wParam) ;
1819 return S_FALSE; /* not handled */
1822 static HRESULT WINAPI IShellView_fnEnableModeless(IShellView2 * iface,BOOL fEnable)
1824 IShellViewImpl *This = (IShellViewImpl *)iface;
1826 FIXME("(%p) stub\n",This);
1828 return E_NOTIMPL;
1831 static HRESULT WINAPI IShellView_fnUIActivate(IShellView2 * iface,UINT uState)
1833 IShellViewImpl *This = (IShellViewImpl *)iface;
1836 CHAR szName[MAX_PATH];
1838 LRESULT lResult;
1839 int nPartArray[1] = {-1};
1841 TRACE("(%p)->(state=%x) stub\n",This, uState);
1843 /*don't do anything if the state isn't really changing*/
1844 if(This->uState == uState)
1846 return S_OK;
1849 /*OnActivate handles the menu merging and internal state*/
1850 ShellView_OnActivate(This, uState);
1852 /*only do This if we are active*/
1853 if(uState != SVUIA_DEACTIVATE)
1857 GetFolderPath is not a method of IShellFolder
1858 IShellFolder_GetFolderPath( This->pSFParent, szName, sizeof(szName) );
1860 /* set the number of parts */
1861 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETPARTS, 1,
1862 (LPARAM)nPartArray, &lResult);
1864 /* set the text for the parts */
1866 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETTEXTA,
1867 0, (LPARAM)szName, &lResult);
1871 return S_OK;
1874 static HRESULT WINAPI IShellView_fnRefresh(IShellView2 * iface)
1876 IShellViewImpl *This = (IShellViewImpl *)iface;
1878 TRACE("(%p)\n",This);
1880 SendMessageW(This->hWndList, LVM_DELETEALLITEMS, 0, 0);
1881 ShellView_FillList(This);
1883 return S_OK;
1886 static HRESULT WINAPI IShellView_fnCreateViewWindow(IShellView2 *iface, IShellView *lpPrevView,
1887 LPCFOLDERSETTINGS lpfs, IShellBrowser *psb, RECT *prcView, HWND *phWnd)
1889 HRESULT hr;
1890 SV2CVW2_PARAMS view_params;
1891 view_params.cbSize = sizeof(view_params);
1892 view_params.psvPrev = lpPrevView;
1893 view_params.pfs = lpfs;
1894 view_params.psbOwner = psb;
1895 view_params.prcView = prcView;
1896 view_params.pvid = NULL;
1897 view_params.hwndView = 0;
1899 TRACE("(%p) Forwarding to CreateViewWindow2\n", iface);
1901 hr = IShellView2_CreateViewWindow2(iface, &view_params);
1902 *phWnd = view_params.hwndView;
1904 return hr;
1907 static HRESULT WINAPI IShellView_fnDestroyViewWindow(IShellView2 * iface)
1909 IShellViewImpl *This = (IShellViewImpl *)iface;
1911 TRACE("(%p)\n",This);
1913 /*Make absolutely sure all our UI is cleaned up.*/
1914 IShellView_UIActivate((IShellView*)This, SVUIA_DEACTIVATE);
1916 if(This->hMenu)
1918 DestroyMenu(This->hMenu);
1921 DestroyWindow(This->hWnd);
1922 if(This->pShellBrowser) IShellBrowser_Release(This->pShellBrowser);
1923 if(This->pCommDlgBrowser) ICommDlgBrowser_Release(This->pCommDlgBrowser);
1926 return S_OK;
1929 static HRESULT WINAPI IShellView_fnGetCurrentInfo(IShellView2 * iface, LPFOLDERSETTINGS lpfs)
1931 IShellViewImpl *This = (IShellViewImpl *)iface;
1933 TRACE("(%p)->(%p) vmode=%x flags=%x\n",This, lpfs,
1934 This->FolderSettings.ViewMode, This->FolderSettings.fFlags);
1936 if (!lpfs) return E_INVALIDARG;
1938 *lpfs = This->FolderSettings;
1939 return NOERROR;
1942 static HRESULT WINAPI IShellView_fnAddPropertySheetPages(IShellView2 * iface, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam)
1944 IShellViewImpl *This = (IShellViewImpl *)iface;
1946 FIXME("(%p) stub\n",This);
1948 return E_NOTIMPL;
1951 static HRESULT WINAPI IShellView_fnSaveViewState(IShellView2 * iface)
1953 IShellViewImpl *This = (IShellViewImpl *)iface;
1955 FIXME("(%p) stub\n",This);
1957 return S_OK;
1960 static HRESULT WINAPI IShellView_fnSelectItem(
1961 IShellView2 * iface,
1962 LPCITEMIDLIST pidl,
1963 UINT flags)
1965 IShellViewImpl *This = (IShellViewImpl *)iface;
1966 IFolderView *view;
1967 HRESULT hr;
1968 int i;
1970 TRACE("(%p)->(pidl=%p, 0x%08x)\n",This, pidl, flags);
1972 i = LV_FindItemByPidl(This, pidl);
1973 if (i == -1) return S_OK;
1975 hr = IShellView2_QueryInterface(iface, &IID_IFolderView, (void**)&view);
1976 if (hr == S_OK)
1978 hr = IFolderView_SelectItem(view, i, flags);
1979 IFolderView_Release(view);
1982 return hr;
1985 static HRESULT WINAPI IShellView_fnGetItemObject(IShellView2 * iface, UINT uItem, REFIID riid, LPVOID *ppvOut)
1987 IShellViewImpl *This = (IShellViewImpl *)iface;
1989 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n",This, uItem, debugstr_guid(riid), ppvOut);
1991 *ppvOut = NULL;
1993 switch(uItem)
1995 case SVGIO_BACKGROUND:
1996 *ppvOut = ISvBgCm_Constructor(This->pSFParent, FALSE);
1997 break;
1999 case SVGIO_SELECTION:
2000 ShellView_GetSelections(This);
2001 IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, (LPCITEMIDLIST*)This->apidl, riid, 0, ppvOut);
2002 break;
2004 TRACE("-- (%p)->(interface=%p)\n",This, *ppvOut);
2006 if(!*ppvOut) return E_OUTOFMEMORY;
2008 return S_OK;
2011 static HRESULT WINAPI IShellView2_fnGetView(IShellView2* iface, SHELLVIEWID *view_guid, ULONG view_type)
2013 FIXME("(%p)->(view_guid %s, view_type %#x) stub!\n", iface, debugstr_guid(view_guid), view_type);
2014 return E_NOTIMPL;
2017 static HRESULT WINAPI IShellView2_fnCreateViewWindow2(IShellView2* iface, LPSV2CVW2_PARAMS view_params)
2019 IShellViewImpl *This = (IShellViewImpl *)iface;
2020 WNDCLASSW wc;
2021 HWND wnd;
2023 TRACE("(%p)->(view_params %p)\n", iface, view_params);
2025 if (view_params->cbSize != sizeof(*view_params))
2027 FIXME("Got unexpected cbSize %#x\n", view_params->cbSize);
2028 return E_FAIL;
2031 TRACE("-- psvPrev %p, pfs %p, psbOwner %p, prcView %p\n",
2032 view_params->psvPrev, view_params->pfs, view_params->psbOwner, view_params->prcView);
2033 TRACE("-- vmode %#x, flags %#x, left %d, top %d, right %d, bottom %d\n",
2034 view_params->pfs->ViewMode, view_params->pfs->fFlags, view_params->prcView->left,
2035 view_params->prcView->top, view_params->prcView->right, view_params->prcView->bottom);
2037 /* Set up the member variables */
2038 This->pShellBrowser = view_params->psbOwner;
2039 This->FolderSettings = *view_params->pfs;
2041 if (view_params->pvid)
2043 if (IsEqualGUID(view_params->pvid, &VID_LargeIcons))
2044 This->FolderSettings.ViewMode = FVM_ICON;
2045 else if (IsEqualGUID(view_params->pvid, &VID_SmallIcons))
2046 This->FolderSettings.ViewMode = FVM_SMALLICON;
2047 else if (IsEqualGUID(view_params->pvid, &VID_List))
2048 This->FolderSettings.ViewMode = FVM_LIST;
2049 else if (IsEqualGUID(view_params->pvid, &VID_Details))
2050 This->FolderSettings.ViewMode = FVM_DETAILS;
2051 else if (IsEqualGUID(view_params->pvid, &VID_Thumbnails))
2052 This->FolderSettings.ViewMode = FVM_THUMBNAIL;
2053 else if (IsEqualGUID(view_params->pvid, &VID_Tile))
2054 This->FolderSettings.ViewMode = FVM_TILE;
2055 else if (IsEqualGUID(view_params->pvid, &VID_ThumbStrip))
2056 This->FolderSettings.ViewMode = FVM_THUMBSTRIP;
2057 else
2058 FIXME("Ignoring unrecognized VID %s\n", debugstr_guid(view_params->pvid));
2061 /* Get our parent window */
2062 IShellBrowser_AddRef(This->pShellBrowser);
2063 IShellBrowser_GetWindow(This->pShellBrowser, &(This->hWndParent));
2065 /* Try to get the ICommDlgBrowserInterface, adds a reference !!! */
2066 This->pCommDlgBrowser = NULL;
2067 if (SUCCEEDED(IShellBrowser_QueryInterface(This->pShellBrowser, &IID_ICommDlgBrowser, (void **)&This->pCommDlgBrowser)))
2069 TRACE("-- CommDlgBrowser %p\n", This->pCommDlgBrowser);
2072 /* If our window class has not been registered, then do so */
2073 if (!GetClassInfoW(shell32_hInstance, SV_CLASS_NAME, &wc))
2075 ZeroMemory(&wc, sizeof(wc));
2076 wc.style = CS_HREDRAW | CS_VREDRAW;
2077 wc.lpfnWndProc = ShellView_WndProc;
2078 wc.cbClsExtra = 0;
2079 wc.cbWndExtra = 0;
2080 wc.hInstance = shell32_hInstance;
2081 wc.hIcon = 0;
2082 wc.hCursor = LoadCursorW(0, (LPWSTR)IDC_ARROW);
2083 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
2084 wc.lpszMenuName = NULL;
2085 wc.lpszClassName = SV_CLASS_NAME;
2087 if (!RegisterClassW(&wc)) return E_FAIL;
2090 wnd = CreateWindowExW(0, SV_CLASS_NAME, NULL, WS_CHILD | WS_TABSTOP,
2091 view_params->prcView->left, view_params->prcView->top,
2092 view_params->prcView->right - view_params->prcView->left,
2093 view_params->prcView->bottom - view_params->prcView->top,
2094 This->hWndParent, 0, shell32_hInstance, This);
2096 CheckToolbar(This);
2098 if (!wnd) return E_FAIL;
2100 SetWindowPos(wnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
2101 UpdateWindow(wnd);
2103 view_params->hwndView = wnd;
2105 return S_OK;
2108 static HRESULT WINAPI IShellView2_fnHandleRename(IShellView2* iface, LPCITEMIDLIST new_pidl)
2110 FIXME("(%p)->(new_pidl %p) stub!\n", iface, new_pidl);
2111 return E_NOTIMPL;
2114 static HRESULT WINAPI IShellView2_fnSelectAndPositionItem(
2115 IShellView2* iface,
2116 LPCITEMIDLIST item,
2117 UINT flags,
2118 POINT *point)
2120 IShellViewImpl *This = (IShellViewImpl *)iface;
2121 IFolderView *view;
2122 HRESULT hr;
2124 TRACE("(%p)->(item %p, flags %#x, point %p)\n", This, item, flags, point);
2126 hr = IShellView2_QueryInterface(iface, &IID_IFolderView, (void**)&view);
2127 if (hr == S_OK)
2129 hr = IFolderView_SelectAndPositionItems(view, 1, &item, point, flags);
2130 IFolderView_Release(view);
2133 return hr;
2136 static const IShellView2Vtbl svvt =
2138 IShellView_fnQueryInterface,
2139 IShellView_fnAddRef,
2140 IShellView_fnRelease,
2141 IShellView_fnGetWindow,
2142 IShellView_fnContextSensitiveHelp,
2143 IShellView_fnTranslateAccelerator,
2144 IShellView_fnEnableModeless,
2145 IShellView_fnUIActivate,
2146 IShellView_fnRefresh,
2147 IShellView_fnCreateViewWindow,
2148 IShellView_fnDestroyViewWindow,
2149 IShellView_fnGetCurrentInfo,
2150 IShellView_fnAddPropertySheetPages,
2151 IShellView_fnSaveViewState,
2152 IShellView_fnSelectItem,
2153 IShellView_fnGetItemObject,
2154 IShellView2_fnGetView,
2155 IShellView2_fnCreateViewWindow2,
2156 IShellView2_fnHandleRename,
2157 IShellView2_fnSelectAndPositionItem,
2161 /**********************************************************
2162 * ISVOleCmdTarget_QueryInterface (IUnknown)
2164 static HRESULT WINAPI ISVOleCmdTarget_QueryInterface(
2165 IOleCommandTarget * iface,
2166 REFIID iid,
2167 LPVOID* ppvObj)
2169 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2171 return IShellView2_QueryInterface((IShellView2*)This, iid, ppvObj);
2174 /**********************************************************
2175 * ISVOleCmdTarget_AddRef (IUnknown)
2177 static ULONG WINAPI ISVOleCmdTarget_AddRef(
2178 IOleCommandTarget * iface)
2180 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2182 return IShellView2_AddRef((IShellView2*)This);
2185 /**********************************************************
2186 * ISVOleCmdTarget_Release (IUnknown)
2188 static ULONG WINAPI ISVOleCmdTarget_Release(
2189 IOleCommandTarget * iface)
2191 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2193 return IShellView2_Release((IShellView2*)This);
2196 /**********************************************************
2197 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2199 static HRESULT WINAPI ISVOleCmdTarget_QueryStatus(
2200 IOleCommandTarget *iface,
2201 const GUID* pguidCmdGroup,
2202 ULONG cCmds,
2203 OLECMD * prgCmds,
2204 OLECMDTEXT* pCmdText)
2206 UINT i;
2207 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2209 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
2210 This, pguidCmdGroup, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText);
2212 if (!prgCmds)
2213 return E_POINTER;
2214 for (i = 0; i < cCmds; i++)
2216 FIXME("\tprgCmds[%d].cmdID = %d\n", i, prgCmds[i].cmdID);
2217 prgCmds[i].cmdf = 0;
2219 return OLECMDERR_E_UNKNOWNGROUP;
2222 /**********************************************************
2223 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2225 * nCmdID is the OLECMDID_* enumeration
2227 static HRESULT WINAPI ISVOleCmdTarget_Exec(
2228 IOleCommandTarget *iface,
2229 const GUID* pguidCmdGroup,
2230 DWORD nCmdID,
2231 DWORD nCmdexecopt,
2232 VARIANT* pvaIn,
2233 VARIANT* pvaOut)
2235 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2237 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2238 This, debugstr_guid(pguidCmdGroup), nCmdID, nCmdexecopt, pvaIn, pvaOut);
2240 if (IsEqualIID(pguidCmdGroup, &CGID_Explorer) &&
2241 (nCmdID == 0x29) &&
2242 (nCmdexecopt == 4) && pvaOut)
2243 return S_OK;
2244 if (IsEqualIID(pguidCmdGroup, &CGID_ShellDocView) &&
2245 (nCmdID == 9) &&
2246 (nCmdexecopt == 0))
2247 return 1;
2249 return OLECMDERR_E_UNKNOWNGROUP;
2252 static const IOleCommandTargetVtbl ctvt =
2254 ISVOleCmdTarget_QueryInterface,
2255 ISVOleCmdTarget_AddRef,
2256 ISVOleCmdTarget_Release,
2257 ISVOleCmdTarget_QueryStatus,
2258 ISVOleCmdTarget_Exec
2261 /**********************************************************
2262 * ISVDropTarget implementation
2265 static HRESULT WINAPI ISVDropTarget_QueryInterface(
2266 IDropTarget *iface,
2267 REFIID riid,
2268 LPVOID *ppvObj)
2270 IShellViewImpl *This = impl_from_IDropTarget(iface);
2272 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2274 return IShellView2_QueryInterface((IShellView2*)This, riid, ppvObj);
2277 static ULONG WINAPI ISVDropTarget_AddRef( IDropTarget *iface)
2279 IShellViewImpl *This = impl_from_IDropTarget(iface);
2281 TRACE("(%p)->(count=%u)\n",This,This->ref);
2283 return IShellView2_AddRef((IShellView2*)This);
2286 static ULONG WINAPI ISVDropTarget_Release( IDropTarget *iface)
2288 IShellViewImpl *This = impl_from_IDropTarget(iface);
2290 TRACE("(%p)->(count=%u)\n",This,This->ref);
2292 return IShellView2_Release((IShellView2*)This);
2295 /******************************************************************************
2296 * drag_notify_subitem [Internal]
2298 * Figure out the shellfolder object, which is currently under the mouse cursor
2299 * and notify it via the IDropTarget interface.
2302 #define SCROLLAREAWIDTH 20
2304 static HRESULT drag_notify_subitem(IShellViewImpl *This, DWORD grfKeyState, POINTL pt,
2305 DWORD *pdwEffect)
2307 LVHITTESTINFO htinfo;
2308 LVITEMW lvItem;
2309 LONG lResult;
2310 HRESULT hr;
2311 RECT clientRect;
2313 /* Map from global to client coordinates and query the index of the listview-item, which is
2314 * currently under the mouse cursor. */
2315 htinfo.pt.x = pt.x;
2316 htinfo.pt.y = pt.y;
2317 htinfo.flags = LVHT_ONITEM;
2318 ScreenToClient(This->hWndList, &htinfo.pt);
2319 lResult = SendMessageW(This->hWndList, LVM_HITTEST, 0, (LPARAM)&htinfo);
2321 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2322 GetClientRect(This->hWndList, &clientRect);
2323 if (htinfo.pt.x == This->ptLastMousePos.x && htinfo.pt.y == This->ptLastMousePos.y &&
2324 (htinfo.pt.x < SCROLLAREAWIDTH || htinfo.pt.x > clientRect.right - SCROLLAREAWIDTH ||
2325 htinfo.pt.y < SCROLLAREAWIDTH || htinfo.pt.y > clientRect.bottom - SCROLLAREAWIDTH ))
2327 This->cScrollDelay = (This->cScrollDelay + 1) % 5; /* DragOver is called every 50 ms */
2328 if (This->cScrollDelay == 0) { /* Mouse did hover another 250 ms over the scroll-area */
2329 if (htinfo.pt.x < SCROLLAREAWIDTH)
2330 SendMessageW(This->hWndList, WM_HSCROLL, SB_LINEUP, 0);
2331 if (htinfo.pt.x > clientRect.right - SCROLLAREAWIDTH)
2332 SendMessageW(This->hWndList, WM_HSCROLL, SB_LINEDOWN, 0);
2333 if (htinfo.pt.y < SCROLLAREAWIDTH)
2334 SendMessageW(This->hWndList, WM_VSCROLL, SB_LINEUP, 0);
2335 if (htinfo.pt.y > clientRect.bottom - SCROLLAREAWIDTH)
2336 SendMessageW(This->hWndList, WM_VSCROLL, SB_LINEDOWN, 0);
2338 } else {
2339 This->cScrollDelay = 0; /* Reset, if the cursor is not over the listview's scroll-area */
2341 This->ptLastMousePos = htinfo.pt;
2343 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2344 if (This->pCurDropTarget && lResult == This->iDragOverItem)
2345 return IDropTarget_DragOver(This->pCurDropTarget, grfKeyState, pt, pdwEffect);
2347 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2348 if (This->pCurDropTarget) {
2349 IDropTarget_DragLeave(This->pCurDropTarget);
2350 IDropTarget_Release(This->pCurDropTarget);
2351 This->pCurDropTarget = NULL;
2354 This->iDragOverItem = lResult;
2355 if (lResult == -1) {
2356 /* We are not above one of the listview's subitems. Bind to the parent folder's
2357 * DropTarget interface. */
2358 hr = IShellFolder_QueryInterface(This->pSFParent, &IID_IDropTarget,
2359 (LPVOID*)&This->pCurDropTarget);
2360 } else {
2361 /* Query the relative PIDL of the shellfolder object represented by the currently
2362 * dragged over listview-item ... */
2363 lvItem.mask = LVIF_PARAM;
2364 lvItem.iItem = lResult;
2365 lvItem.iSubItem = 0;
2366 SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem);
2368 /* ... and bind pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2369 hr = IShellFolder_GetUIObjectOf(This->pSFParent, This->hWndList, 1,
2370 (LPCITEMIDLIST*)&lvItem.lParam, &IID_IDropTarget, NULL, (LPVOID*)&This->pCurDropTarget);
2373 /* If anything failed, pCurDropTarget should be NULL now, which ought to be a save state. */
2374 if (FAILED(hr))
2375 return hr;
2377 /* Notify the item just entered via DragEnter. */
2378 return IDropTarget_DragEnter(This->pCurDropTarget, This->pCurDataObject, grfKeyState, pt, pdwEffect);
2381 static HRESULT WINAPI ISVDropTarget_DragEnter(IDropTarget *iface, IDataObject *pDataObject,
2382 DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
2384 IShellViewImpl *This = impl_from_IDropTarget(iface);
2386 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2387 This->pCurDataObject = pDataObject;
2388 IDataObject_AddRef(pDataObject);
2390 return drag_notify_subitem(This, grfKeyState, pt, pdwEffect);
2393 static HRESULT WINAPI ISVDropTarget_DragOver(IDropTarget *iface, DWORD grfKeyState, POINTL pt,
2394 DWORD *pdwEffect)
2396 IShellViewImpl *This = impl_from_IDropTarget(iface);
2397 return drag_notify_subitem(This, grfKeyState, pt, pdwEffect);
2400 static HRESULT WINAPI ISVDropTarget_DragLeave(IDropTarget *iface) {
2401 IShellViewImpl *This = impl_from_IDropTarget(iface);
2403 IDropTarget_DragLeave(This->pCurDropTarget);
2405 IDropTarget_Release(This->pCurDropTarget);
2406 IDataObject_Release(This->pCurDataObject);
2407 This->pCurDataObject = NULL;
2408 This->pCurDropTarget = NULL;
2409 This->iDragOverItem = 0;
2411 return S_OK;
2414 static HRESULT WINAPI ISVDropTarget_Drop(IDropTarget *iface, IDataObject* pDataObject,
2415 DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
2417 IShellViewImpl *This = impl_from_IDropTarget(iface);
2419 IDropTarget_Drop(This->pCurDropTarget, pDataObject, grfKeyState, pt, pdwEffect);
2421 IDropTarget_Release(This->pCurDropTarget);
2422 IDataObject_Release(This->pCurDataObject);
2423 This->pCurDataObject = NULL;
2424 This->pCurDropTarget = NULL;
2425 This->iDragOverItem = 0;
2427 return S_OK;
2430 static const IDropTargetVtbl dtvt =
2432 ISVDropTarget_QueryInterface,
2433 ISVDropTarget_AddRef,
2434 ISVDropTarget_Release,
2435 ISVDropTarget_DragEnter,
2436 ISVDropTarget_DragOver,
2437 ISVDropTarget_DragLeave,
2438 ISVDropTarget_Drop
2441 /**********************************************************
2442 * ISVDropSource implementation
2445 static HRESULT WINAPI ISVDropSource_QueryInterface(
2446 IDropSource *iface,
2447 REFIID riid,
2448 LPVOID *ppvObj)
2450 IShellViewImpl *This = impl_from_IDropSource(iface);
2452 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2454 return IShellView2_QueryInterface((IShellView2*)This, riid, ppvObj);
2457 static ULONG WINAPI ISVDropSource_AddRef( IDropSource *iface)
2459 IShellViewImpl *This = impl_from_IDropSource(iface);
2461 TRACE("(%p)->(count=%u)\n",This,This->ref);
2463 return IShellView2_AddRef((IShellView2*)This);
2466 static ULONG WINAPI ISVDropSource_Release( IDropSource *iface)
2468 IShellViewImpl *This = impl_from_IDropSource(iface);
2470 TRACE("(%p)->(count=%u)\n",This,This->ref);
2472 return IShellView2_Release((IShellView2*)This);
2475 static HRESULT WINAPI ISVDropSource_QueryContinueDrag(
2476 IDropSource *iface,
2477 BOOL fEscapePressed,
2478 DWORD grfKeyState)
2480 IShellViewImpl *This = impl_from_IDropSource(iface);
2481 TRACE("(%p)\n",This);
2483 if (fEscapePressed)
2484 return DRAGDROP_S_CANCEL;
2485 else if (!(grfKeyState & MK_LBUTTON) && !(grfKeyState & MK_RBUTTON))
2486 return DRAGDROP_S_DROP;
2487 else
2488 return NOERROR;
2491 static HRESULT WINAPI ISVDropSource_GiveFeedback(
2492 IDropSource *iface,
2493 DWORD dwEffect)
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(
2514 IViewObject *iface,
2515 REFIID riid,
2516 LPVOID *ppvObj)
2518 IShellViewImpl *This = impl_from_IViewObject(iface);
2520 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2522 return IShellView2_QueryInterface((IShellView2*)This, riid, ppvObj);
2525 static ULONG WINAPI ISVViewObject_AddRef( IViewObject *iface)
2527 IShellViewImpl *This = impl_from_IViewObject(iface);
2529 TRACE("(%p)->(count=%u)\n",This,This->ref);
2531 return IShellView2_AddRef((IShellView2*)This);
2534 static ULONG WINAPI ISVViewObject_Release( IViewObject *iface)
2536 IShellViewImpl *This = impl_from_IViewObject(iface);
2538 TRACE("(%p)->(count=%u)\n",This,This->ref);
2540 return IShellView2_Release((IShellView2*)This);
2543 static HRESULT WINAPI ISVViewObject_Draw(
2544 IViewObject *iface,
2545 DWORD dwDrawAspect,
2546 LONG lindex,
2547 void* pvAspect,
2548 DVTARGETDEVICE* ptd,
2549 HDC hdcTargetDev,
2550 HDC hdcDraw,
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);
2561 return E_NOTIMPL;
2563 static HRESULT WINAPI ISVViewObject_GetColorSet(
2564 IViewObject *iface,
2565 DWORD dwDrawAspect,
2566 LONG lindex,
2567 void *pvAspect,
2568 DVTARGETDEVICE* ptd,
2569 HDC hicTargetDevice,
2570 LOGPALETTE** ppColorSet)
2573 IShellViewImpl *This = impl_from_IViewObject(iface);
2575 FIXME("Stub: This=%p\n",This);
2577 return E_NOTIMPL;
2579 static HRESULT WINAPI ISVViewObject_Freeze(
2580 IViewObject *iface,
2581 DWORD dwDrawAspect,
2582 LONG lindex,
2583 void* pvAspect,
2584 DWORD* pdwFreeze)
2587 IShellViewImpl *This = impl_from_IViewObject(iface);
2589 FIXME("Stub: This=%p\n",This);
2591 return E_NOTIMPL;
2593 static HRESULT WINAPI ISVViewObject_Unfreeze(
2594 IViewObject *iface,
2595 DWORD dwFreeze)
2598 IShellViewImpl *This = impl_from_IViewObject(iface);
2600 FIXME("Stub: This=%p\n",This);
2602 return E_NOTIMPL;
2604 static HRESULT WINAPI ISVViewObject_SetAdvise(
2605 IViewObject *iface,
2606 DWORD aspects,
2607 DWORD advf,
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;
2621 return S_OK;
2624 static HRESULT WINAPI ISVViewObject_GetAdvise(
2625 IViewObject *iface,
2626 DWORD* pAspects,
2627 DWORD* pAdvf,
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);
2636 if( ppAdvSink )
2638 IAdviseSink_AddRef( This->pAdvSink );
2639 *ppAdvSink = This->pAdvSink;
2641 if( pAspects )
2642 *pAspects = This->dwAspects;
2643 if( pAdvf )
2644 *pAdvf = This->dwAdvf;
2646 return S_OK;
2650 static const IViewObjectVtbl vovt =
2652 ISVViewObject_QueryInterface,
2653 ISVViewObject_AddRef,
2654 ISVViewObject_Release,
2655 ISVViewObject_Draw,
2656 ISVViewObject_GetColorSet,
2657 ISVViewObject_Freeze,
2658 ISVViewObject_Unfreeze,
2659 ISVViewObject_SetAdvise,
2660 ISVViewObject_GetAdvise
2663 /* IFolderView */
2664 static HRESULT WINAPI IFView_QueryInterface(
2665 IFolderView *iface,
2666 REFIID riid,
2667 LPVOID *ppvObj)
2669 IShellViewImpl *This = impl_from_IFolderView(iface);
2670 TRACE("(%p)->(IID:%s,%p)\n", This, debugstr_guid(riid), ppvObj);
2671 return IShellView2_QueryInterface((IShellView2*)This, riid, ppvObj);
2674 static ULONG WINAPI IFView_AddRef( IFolderView *iface)
2676 IShellViewImpl *This = impl_from_IFolderView(iface);
2677 TRACE("(%p)->(count=%u)\n", This, This->ref);
2678 return IShellView2_AddRef((IShellView2*)This);
2681 static ULONG WINAPI IFView_Release( IFolderView *iface)
2683 IShellViewImpl *This = impl_from_IFolderView(iface);
2684 TRACE("(%p)->(count=%u)\n", This, This->ref);
2685 return IShellView2_Release((IShellView2*)This);
2688 static HRESULT WINAPI IFView_GetCurrentViewMode(IFolderView *iface, UINT *mode)
2690 IShellViewImpl *This = impl_from_IFolderView(iface);
2691 FIXME("(%p)->(%p), stub\n", This, mode);
2692 return E_NOTIMPL;
2695 static HRESULT WINAPI IFView_SetCurrentViewMode(IFolderView *iface, UINT mode)
2697 IShellViewImpl *This = impl_from_IFolderView(iface);
2698 FIXME("(%p)->(%u), stub\n", This, mode);
2699 return E_NOTIMPL;
2702 static HRESULT WINAPI IFView_GetFolder(IFolderView *iface, REFIID riid, void **ppv)
2704 IShellViewImpl *This = impl_from_IFolderView(iface);
2705 FIXME("(%p)->(%s, %p), stub\n", This, debugstr_guid(riid), ppv);
2706 return E_NOTIMPL;
2709 static HRESULT WINAPI IFView_Item(IFolderView *iface, int index, PITEMID_CHILD *ppidl)
2711 IShellViewImpl *This = impl_from_IFolderView(iface);
2712 FIXME("(%p)->(%d %p), stub\n", This, index, ppidl);
2713 return E_NOTIMPL;
2716 static HRESULT WINAPI IFView_ItemCount(IFolderView *iface, UINT flags, int *items)
2718 IShellViewImpl *This = impl_from_IFolderView(iface);
2719 FIXME("(%p)->(%u %p), stub\n", This, flags, items);
2720 return E_NOTIMPL;
2723 static HRESULT WINAPI IFView_Items(IFolderView *iface, UINT flags, REFIID riid, void **ppv)
2725 IShellViewImpl *This = impl_from_IFolderView(iface);
2726 FIXME("(%p)->(%u %s %p), stub\n", This, flags, debugstr_guid(riid), ppv);
2727 return E_NOTIMPL;
2730 static HRESULT WINAPI IFView_GetSelectionMarkedItem(IFolderView *iface, int *item)
2732 IShellViewImpl *This = impl_from_IFolderView(iface);
2733 FIXME("(%p)->(%p), stub\n", This, item);
2734 return E_NOTIMPL;
2737 static HRESULT WINAPI IFView_GetFocusedItem(IFolderView *iface, int *item)
2739 IShellViewImpl *This = impl_from_IFolderView(iface);
2740 FIXME("(%p)->(%p), stub\n", This, item);
2741 return E_NOTIMPL;
2744 static HRESULT WINAPI IFView_GetItemPosition(IFolderView *iface, PCUITEMID_CHILD pidl, POINT *ppt)
2746 IShellViewImpl *This = impl_from_IFolderView(iface);
2747 FIXME("(%p)->(%p %p), stub\n", This, pidl, ppt);
2748 return E_NOTIMPL;
2751 static HRESULT WINAPI IFView_GetSpacing(IFolderView *iface, POINT *pt)
2753 IShellViewImpl *This = impl_from_IFolderView(iface);
2754 FIXME("(%p)->(%p), stub\n", This, pt);
2755 return E_NOTIMPL;
2758 static HRESULT WINAPI IFView_GetDefaultSpacing(IFolderView *iface, POINT *pt)
2760 IShellViewImpl *This = impl_from_IFolderView(iface);
2761 FIXME("(%p)->(%p), stub\n", This, pt);
2762 return E_NOTIMPL;
2765 static HRESULT WINAPI IFView_GetAutoArrange(IFolderView *iface)
2767 IShellViewImpl *This = impl_from_IFolderView(iface);
2768 FIXME("(%p), stub\n", This);
2769 return E_NOTIMPL;
2772 static HRESULT WINAPI IFView_SelectItem(IFolderView *iface, int item, DWORD flags)
2774 IShellViewImpl *This = impl_from_IFolderView(iface);
2775 LVITEMW lvItem;
2777 TRACE("(%p)->(%d, %x)\n", This, item, flags);
2779 lvItem.state = 0;
2780 lvItem.stateMask = LVIS_SELECTED;
2782 if (flags & SVSI_ENSUREVISIBLE)
2783 SendMessageW(This->hWndList, LVM_ENSUREVISIBLE, item, 0);
2785 /* all items */
2786 if (flags & SVSI_DESELECTOTHERS)
2787 SendMessageW(This->hWndList, LVM_SETITEMSTATE, -1, (LPARAM)&lvItem);
2789 /* this item */
2790 if (flags & SVSI_SELECT)
2791 lvItem.state |= LVIS_SELECTED;
2793 if (flags & SVSI_FOCUSED)
2794 lvItem.stateMask |= LVIS_FOCUSED;
2796 SendMessageW(This->hWndList, LVM_SETITEMSTATE, item, (LPARAM)&lvItem);
2798 if (flags & SVSI_EDIT)
2799 SendMessageW(This->hWndList, LVM_EDITLABELW, item, 0);
2801 return S_OK;
2804 static HRESULT WINAPI IFView_SelectAndPositionItems(IFolderView *iface, UINT cidl,
2805 PCUITEMID_CHILD_ARRAY apidl, POINT *apt, DWORD flags)
2807 IShellViewImpl *This = impl_from_IFolderView(iface);
2808 FIXME("(%p)->(%u %p %p %x), stub\n", This, cidl, apidl, apt, flags);
2809 return E_NOTIMPL;
2812 static const IFolderViewVtbl fviewvt =
2814 IFView_QueryInterface,
2815 IFView_AddRef,
2816 IFView_Release,
2817 IFView_GetCurrentViewMode,
2818 IFView_SetCurrentViewMode,
2819 IFView_GetFolder,
2820 IFView_Item,
2821 IFView_ItemCount,
2822 IFView_Items,
2823 IFView_GetSelectionMarkedItem,
2824 IFView_GetFocusedItem,
2825 IFView_GetItemPosition,
2826 IFView_GetSpacing,
2827 IFView_GetDefaultSpacing,
2828 IFView_GetAutoArrange,
2829 IFView_SelectItem,
2830 IFView_SelectAndPositionItems