shlwapi: Don't cast WCHAR string to BSTR.
[wine/testsucceed.git] / dlls / shell32 / shlview.c
blob7809344f4ae5234840f076f66add52e66577b0a1
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 fetched;
642 HRESULT hr;
643 HDPA hdpa;
645 TRACE("(%p)\n", This);
647 /* get the itemlist from the shfolder*/
648 hr = IShellFolder_EnumObjects(This->pSFParent, This->hWnd, SHCONTF_NONFOLDERS | SHCONTF_FOLDERS, &pEnumIDList);
649 if (hr != S_OK) return hr;
651 /* create a pointer array */
652 hdpa = DPA_Create(16);
653 if (!hdpa)
655 IEnumIDList_Release(pEnumIDList);
656 return E_OUTOFMEMORY;
659 /* copy the items into the array*/
660 while((S_OK == IEnumIDList_Next(pEnumIDList, 1, &pidl, &fetched)) && fetched)
662 if (DPA_InsertPtr(hdpa, DPA_GetPtrCount(hdpa), pidl) == -1)
664 SHFree(pidl);
668 /* sort the array */
669 DPA_Sort(hdpa, ShellView_CompareItems, (LPARAM)This->pSFParent);
671 SendMessageW(This->hWndList, WM_SETREDRAW, FALSE, 0);
672 DPA_DestroyCallback(hdpa, fill_list, This);
673 SendMessageW(This->hWndList, WM_SETREDRAW, TRUE, 0);
675 IEnumIDList_Release(pEnumIDList);
677 return S_OK;
680 /**********************************************************
681 * ShellView_OnCreate()
683 static LRESULT ShellView_OnCreate(IShellViewImpl *This)
685 IShellView2 *iface = (IShellView2*)This;
686 static const WCHAR accel_nameW[] = {'s','h','v','_','a','c','c','e','l',0};
687 IPersistFolder2 *ppf2;
688 IDropTarget* pdt;
689 HRESULT hr;
691 TRACE("(%p)\n", This);
693 if (ShellView_CreateList(This))
695 if (ShellView_InitList(This))
697 ShellView_FillList(This);
701 hr = IShellView2_QueryInterface(iface, &IID_IDropTarget, (LPVOID*)&pdt);
702 if (hr == S_OK)
704 RegisterDragDrop(This->hWnd, pdt);
705 IDropTarget_Release(pdt);
708 /* register for receiving notifications */
709 hr = IShellFolder_QueryInterface(This->pSFParent, &IID_IPersistFolder2, (LPVOID*)&ppf2);
710 if (hr == S_OK)
712 SHChangeNotifyEntry ntreg;
714 hr = IPersistFolder2_GetCurFolder(ppf2, (LPITEMIDLIST*)&ntreg.pidl);
715 if (hr == S_OK)
717 ntreg.fRecursive = TRUE;
718 This->hNotify = SHChangeNotifyRegister(This->hWnd, SHCNF_IDLIST, SHCNE_ALLEVENTS,
719 SHV_CHANGE_NOTIFY, 1, &ntreg);
720 SHFree((LPITEMIDLIST)ntreg.pidl);
722 IPersistFolder2_Release(ppf2);
725 This->hAccel = LoadAcceleratorsW(shell32_hInstance, accel_nameW);
727 return S_OK;
730 /**********************************************************
731 * #### Handling of the menus ####
734 /**********************************************************
735 * ShellView_BuildFileMenu()
737 static HMENU ShellView_BuildFileMenu(IShellViewImpl * This)
738 { WCHAR szText[MAX_PATH];
739 MENUITEMINFOW mii;
740 int nTools,i;
741 HMENU hSubMenu;
743 TRACE("(%p)\n",This);
745 hSubMenu = CreatePopupMenu();
746 if(hSubMenu)
747 { /*get the number of items in our global array*/
748 for(nTools = 0; Tools[nTools].idCommand != -1; nTools++){}
750 /*add the menu items*/
751 for(i = 0; i < nTools; i++)
753 LoadStringW(shell32_hInstance, Tools[i].idMenuString, szText, MAX_PATH);
755 ZeroMemory(&mii, sizeof(mii));
756 mii.cbSize = sizeof(mii);
757 mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
759 if(BTNS_SEP != Tools[i].bStyle) /* no separator*/
761 mii.fType = MFT_STRING;
762 mii.fState = MFS_ENABLED;
763 mii.dwTypeData = szText;
764 mii.wID = Tools[i].idCommand;
766 else
768 mii.fType = MFT_SEPARATOR;
770 /* tack This item onto the end of the menu */
771 InsertMenuItemW(hSubMenu, (UINT)-1, TRUE, &mii);
774 TRACE("-- return (menu=%p)\n",hSubMenu);
775 return hSubMenu;
777 /**********************************************************
778 * ShellView_MergeFileMenu()
780 static void ShellView_MergeFileMenu(IShellViewImpl *This, HMENU hSubMenu)
782 TRACE("(%p)->(submenu=%p) stub\n",This,hSubMenu);
784 if (hSubMenu)
786 static const WCHAR dummyW[] = {'d','u','m','m','y','4','5',0};
787 MENUITEMINFOW mii;
789 /* insert This item at the beginning of the menu */
791 mii.cbSize = sizeof(mii);
792 mii.fMask = MIIM_ID | MIIM_TYPE;
793 mii.wID = 0;
794 mii.fType = MFT_SEPARATOR;
795 InsertMenuItemW(hSubMenu, 0, TRUE, &mii);
797 mii.cbSize = sizeof(mii);
798 mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
799 mii.dwTypeData = (LPWSTR)dummyW;
800 mii.fState = MFS_ENABLED;
801 mii.wID = IDM_MYFILEITEM;
802 mii.fType = MFT_STRING;
803 InsertMenuItemW(hSubMenu, 0, TRUE, &mii);
806 TRACE("--\n");
809 /**********************************************************
810 * ShellView_MergeViewMenu()
813 static void ShellView_MergeViewMenu(IShellViewImpl *This, HMENU hSubMenu)
815 TRACE("(%p)->(submenu=%p)\n",This,hSubMenu);
817 /* add a separator at the correct position in the menu */
818 if (hSubMenu)
820 static const WCHAR menuW[] = {'M','E','N','U','_','0','0','1',0};
821 static const WCHAR viewW[] = {'V','i','e','w',0};
822 MENUITEMINFOW mii;
824 memset(&mii, 0, sizeof(mii));
825 mii.cbSize = sizeof(mii);
826 mii.fMask = MIIM_ID | MIIM_TYPE;
827 mii.wID = 0;
828 mii.fType = MFT_SEPARATOR;
829 InsertMenuItemW(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
831 mii.cbSize = sizeof(mii);
832 mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_DATA;
833 mii.fType = MFT_STRING;
834 mii.dwTypeData = (LPWSTR)viewW;
835 mii.hSubMenu = LoadMenuW(shell32_hInstance, menuW);
836 InsertMenuItemW(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
840 /**********************************************************
841 * ShellView_GetSelections()
843 * - fills the this->apidl list with the selected objects
845 * RETURNS
846 * number of selected items
848 static UINT ShellView_GetSelections(IShellViewImpl * This)
850 LVITEMW lvItem;
851 UINT i = 0;
853 SHFree(This->apidl);
855 This->cidl = SendMessageW(This->hWndList, LVM_GETSELECTEDCOUNT, 0, 0);
856 This->apidl = SHAlloc(This->cidl * sizeof(LPITEMIDLIST));
858 TRACE("selected=%i\n", This->cidl);
860 if(This->apidl)
862 TRACE("-- Items selected =%u\n", This->cidl);
864 lvItem.mask = LVIF_STATE | LVIF_PARAM;
865 lvItem.stateMask = LVIS_SELECTED;
866 lvItem.iItem = 0;
867 lvItem.iSubItem = 0;
869 while(ListView_GetItemW(This->hWndList, &lvItem) && (i < This->cidl))
871 if(lvItem.state & LVIS_SELECTED)
873 This->apidl[i] = (LPITEMIDLIST)lvItem.lParam;
874 i++;
875 TRACE("-- selected Item found\n");
877 lvItem.iItem++;
880 return This->cidl;
884 /**********************************************************
885 * ShellView_OpenSelectedItems()
887 static HRESULT ShellView_OpenSelectedItems(IShellViewImpl * This)
889 static UINT CF_IDLIST = 0;
890 HRESULT hr;
891 IDataObject* selection;
892 FORMATETC fetc;
893 STGMEDIUM stgm;
894 LPIDA pIDList;
895 LPCITEMIDLIST parent_pidl;
896 WCHAR parent_path[MAX_PATH];
897 LPCWSTR parent_dir = NULL;
898 SFGAOF attribs;
899 int i;
901 if (0 == ShellView_GetSelections(This))
903 return S_OK;
905 hr = IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl,
906 (LPCITEMIDLIST*)This->apidl, &IID_IDataObject,
907 0, (LPVOID *)&selection);
908 if (FAILED(hr))
909 return hr;
911 if (0 == CF_IDLIST)
913 CF_IDLIST = RegisterClipboardFormatW(CFSTR_SHELLIDLISTW);
915 fetc.cfFormat = CF_IDLIST;
916 fetc.ptd = NULL;
917 fetc.dwAspect = DVASPECT_CONTENT;
918 fetc.lindex = -1;
919 fetc.tymed = TYMED_HGLOBAL;
921 hr = IDataObject_QueryGetData(selection, &fetc);
922 if (FAILED(hr))
923 return hr;
925 hr = IDataObject_GetData(selection, &fetc, &stgm);
926 if (FAILED(hr))
927 return hr;
929 pIDList = GlobalLock(stgm.u.hGlobal);
931 parent_pidl = (LPCITEMIDLIST) ((LPBYTE)pIDList+pIDList->aoffset[0]);
932 hr = IShellFolder_GetAttributesOf(This->pSFParent, 1, &parent_pidl, &attribs);
933 if (SUCCEEDED(hr) && (attribs & SFGAO_FILESYSTEM) &&
934 SHGetPathFromIDListW(parent_pidl, parent_path))
936 parent_dir = parent_path;
939 for (i = pIDList->cidl; i > 0; --i)
941 LPCITEMIDLIST pidl;
943 pidl = (LPCITEMIDLIST)((LPBYTE)pIDList+pIDList->aoffset[i]);
945 attribs = SFGAO_FOLDER;
946 hr = IShellFolder_GetAttributesOf(This->pSFParent, 1, &pidl, &attribs);
948 if (SUCCEEDED(hr) && ! (attribs & SFGAO_FOLDER))
950 SHELLEXECUTEINFOW shexinfo;
952 shexinfo.cbSize = sizeof(SHELLEXECUTEINFOW);
953 shexinfo.fMask = SEE_MASK_INVOKEIDLIST; /* SEE_MASK_IDLIST is also possible. */
954 shexinfo.hwnd = NULL;
955 shexinfo.lpVerb = NULL;
956 shexinfo.lpFile = NULL;
957 shexinfo.lpParameters = NULL;
958 shexinfo.lpDirectory = parent_dir;
959 shexinfo.nShow = SW_NORMAL;
960 shexinfo.lpIDList = ILCombine(parent_pidl, pidl);
962 ShellExecuteExW(&shexinfo); /* Discard error/success info */
964 ILFree(shexinfo.lpIDList);
968 GlobalUnlock(stgm.u.hGlobal);
969 ReleaseStgMedium(&stgm);
971 IDataObject_Release(selection);
973 return S_OK;
976 /**********************************************************
977 * ShellView_DoContextMenu()
979 static void ShellView_DoContextMenu(IShellViewImpl * This, WORD x, WORD y, BOOL bDefault)
980 { UINT uCommand;
981 DWORD wFlags;
982 HMENU hMenu;
983 BOOL fExplore = FALSE;
984 HWND hwndTree = 0;
985 LPCONTEXTMENU pContextMenu = NULL;
986 IContextMenu2 *pCM = NULL;
987 CMINVOKECOMMANDINFO cmi;
989 TRACE("(%p)->(0x%08x 0x%08x 0x%08x) stub\n",This, x, y, bDefault);
991 /* look, what's selected and create a context menu object of it*/
992 if( ShellView_GetSelections(This) )
994 IShellFolder_GetUIObjectOf( This->pSFParent, This->hWndParent, This->cidl, (LPCITEMIDLIST*)This->apidl,
995 &IID_IContextMenu, NULL, (LPVOID *)&pContextMenu);
997 if(pContextMenu)
999 TRACE("-- pContextMenu\n");
1000 hMenu = CreatePopupMenu();
1002 if( hMenu )
1004 /* See if we are in Explore or Open mode. If the browser's tree is present, we are in Explore mode.*/
1005 if(SUCCEEDED(IShellBrowser_GetControlWindow(This->pShellBrowser,FCW_TREE, &hwndTree)) && hwndTree)
1007 TRACE("-- explore mode\n");
1008 fExplore = TRUE;
1011 /* build the flags depending on what we can do with the selected item */
1012 wFlags = CMF_NORMAL | (This->cidl != 1 ? 0 : CMF_CANRENAME) | (fExplore ? CMF_EXPLORE : 0);
1014 /* let the ContextMenu merge its items in */
1015 if (SUCCEEDED(IContextMenu_QueryContextMenu( pContextMenu, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, wFlags )))
1017 if (This->FolderSettings.fFlags & FWF_DESKTOP)
1018 SetMenuDefaultItem(hMenu, FCIDM_SHVIEW_OPEN, MF_BYCOMMAND);
1020 if( bDefault )
1022 TRACE("-- get menu default command\n");
1023 uCommand = GetMenuDefaultItem(hMenu, FALSE, GMDI_GOINTOPOPUPS);
1025 else
1027 TRACE("-- track popup\n");
1028 uCommand = TrackPopupMenu( hMenu,TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
1031 if(uCommand > 0)
1033 TRACE("-- uCommand=%u\n", uCommand);
1034 if (uCommand==FCIDM_SHVIEW_OPEN && IsInCommDlg(This))
1036 TRACE("-- dlg: OnDefaultCommand\n");
1037 if (OnDefaultCommand(This) != S_OK)
1039 ShellView_OpenSelectedItems(This);
1042 else
1044 TRACE("-- explore -- invoke command\n");
1045 ZeroMemory(&cmi, sizeof(cmi));
1046 cmi.cbSize = sizeof(cmi);
1047 cmi.hwnd = This->hWndParent; /* this window has to answer CWM_GETISHELLBROWSER */
1048 cmi.lpVerb = MAKEINTRESOURCEA(uCommand);
1049 IContextMenu_InvokeCommand(pContextMenu, &cmi);
1052 DestroyMenu(hMenu);
1055 if (pContextMenu)
1056 IContextMenu_Release(pContextMenu);
1059 else /* background context menu */
1061 hMenu = CreatePopupMenu();
1063 pCM = ISvBgCm_Constructor(This->pSFParent, FALSE);
1064 IContextMenu2_QueryContextMenu(pCM, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, 0);
1066 uCommand = TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
1067 DestroyMenu(hMenu);
1069 TRACE("-- (%p)->(uCommand=0x%08x )\n",This, uCommand);
1071 ZeroMemory(&cmi, sizeof(cmi));
1072 cmi.cbSize = sizeof(cmi);
1073 cmi.lpVerb = MAKEINTRESOURCEA(uCommand);
1074 cmi.hwnd = This->hWndParent;
1075 IContextMenu2_InvokeCommand(pCM, &cmi);
1077 IContextMenu2_Release(pCM);
1081 /**********************************************************
1082 * ##### message handling #####
1085 /**********************************************************
1086 * ShellView_OnSize()
1088 static LRESULT ShellView_OnSize(IShellViewImpl * This, WORD wWidth, WORD wHeight)
1090 TRACE("%p width=%u height=%u\n",This, wWidth,wHeight);
1092 /*resize the ListView to fit our window*/
1093 if(This->hWndList)
1095 MoveWindow(This->hWndList, 0, 0, wWidth, wHeight, TRUE);
1098 return S_OK;
1100 /**********************************************************
1101 * ShellView_OnDeactivate()
1103 * NOTES
1104 * internal
1106 static void ShellView_OnDeactivate(IShellViewImpl * This)
1108 TRACE("%p\n",This);
1110 if(This->uState != SVUIA_DEACTIVATE)
1112 if(This->hMenu)
1114 IShellBrowser_SetMenuSB(This->pShellBrowser,0, 0, 0);
1115 IShellBrowser_RemoveMenusSB(This->pShellBrowser,This->hMenu);
1116 DestroyMenu(This->hMenu);
1117 This->hMenu = 0;
1120 This->uState = SVUIA_DEACTIVATE;
1124 /**********************************************************
1125 * ShellView_OnActivate()
1127 static LRESULT ShellView_OnActivate(IShellViewImpl *This, UINT uState)
1129 OLEMENUGROUPWIDTHS omw = { {0, 0, 0, 0, 0, 0} };
1130 MENUITEMINFOW mii;
1132 TRACE("(%p) uState=%x\n",This,uState);
1134 /* don't do anything if the state isn't really changing */
1135 if (This->uState == uState) return S_OK;
1137 ShellView_OnDeactivate(This);
1139 /* only do This if we are active */
1140 if (uState != SVUIA_DEACTIVATE)
1142 /* merge the menus */
1143 This->hMenu = CreateMenu();
1145 if (This->hMenu)
1147 static const WCHAR dummyW[] = {'d','u','m','m','y',' ','3','1',0};
1149 IShellBrowser_InsertMenusSB(This->pShellBrowser, This->hMenu, &omw);
1150 TRACE("-- after fnInsertMenusSB\n");
1152 mii.cbSize = sizeof(mii);
1153 mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_STATE;
1154 mii.fType = MFT_STRING;
1155 mii.fState = MFS_ENABLED;
1156 mii.wID = 0;
1157 mii.hSubMenu = ShellView_BuildFileMenu(This);
1158 mii.hbmpChecked = NULL;
1159 mii.hbmpUnchecked = NULL;
1160 mii.dwItemData = 0;
1161 /* build the top level menu get the menu item's text */
1162 mii.dwTypeData = (LPWSTR)dummyW;
1163 mii.cch = 0;
1164 mii.hbmpItem = NULL;
1166 /* insert our menu into the menu bar */
1167 if (mii.hSubMenu)
1168 InsertMenuItemW(This->hMenu, FCIDM_MENU_HELP, FALSE, &mii);
1170 /* get the view menu so we can merge with it */
1171 memset(&mii, 0, sizeof(mii));
1172 mii.cbSize = sizeof(mii);
1173 mii.fMask = MIIM_SUBMENU;
1175 if (GetMenuItemInfoW(This->hMenu, FCIDM_MENU_VIEW, FALSE, &mii))
1176 ShellView_MergeViewMenu(This, mii.hSubMenu);
1178 /* add the items that should only be added if we have the focus */
1179 if (SVUIA_ACTIVATE_FOCUS == uState)
1181 /* get the file menu so we can merge with it */
1182 memset(&mii, 0, sizeof(mii));
1183 mii.cbSize = sizeof(mii);
1184 mii.fMask = MIIM_SUBMENU;
1186 if (GetMenuItemInfoW(This->hMenu, FCIDM_MENU_FILE, FALSE, &mii))
1187 ShellView_MergeFileMenu(This, mii.hSubMenu);
1190 TRACE("-- before fnSetMenuSB\n");
1191 IShellBrowser_SetMenuSB(This->pShellBrowser, This->hMenu, 0, This->hWnd);
1194 This->uState = uState;
1195 TRACE("--\n");
1196 return S_OK;
1199 /**********************************************************
1200 * ShellView_OnSetFocus()
1203 static LRESULT ShellView_OnSetFocus(IShellViewImpl * This)
1205 TRACE("%p\n",This);
1207 /* Tell the browser one of our windows has received the focus. This
1208 should always be done before merging menus (OnActivate merges the
1209 menus) if one of our windows has the focus.*/
1211 IShellBrowser_OnViewWindowActive(This->pShellBrowser,(IShellView*) This);
1212 ShellView_OnActivate(This, SVUIA_ACTIVATE_FOCUS);
1214 /* Set the focus to the listview */
1215 SetFocus(This->hWndList);
1217 /* Notify the ICommDlgBrowser interface */
1218 OnStateChange(This,CDBOSC_SETFOCUS);
1220 return 0;
1223 /**********************************************************
1224 * ShellView_OnKillFocus()
1226 static LRESULT ShellView_OnKillFocus(IShellViewImpl * This)
1228 TRACE("(%p) stub\n",This);
1230 ShellView_OnActivate(This, SVUIA_ACTIVATE_NOFOCUS);
1231 /* Notify the ICommDlgBrowser */
1232 OnStateChange(This,CDBOSC_KILLFOCUS);
1234 return 0;
1237 /**********************************************************
1238 * ShellView_OnCommand()
1240 * NOTES
1241 * the CmdID's are the ones from the context menu
1243 static LRESULT ShellView_OnCommand(IShellViewImpl * This,DWORD dwCmdID, DWORD dwCmd, HWND hwndCmd)
1245 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n",This, dwCmdID, dwCmd, hwndCmd);
1247 switch(dwCmdID)
1249 case FCIDM_SHVIEW_SMALLICON:
1250 This->FolderSettings.ViewMode = FVM_SMALLICON;
1251 SetStyle (This, LVS_SMALLICON, LVS_TYPEMASK);
1252 CheckToolbar(This);
1253 break;
1255 case FCIDM_SHVIEW_BIGICON:
1256 This->FolderSettings.ViewMode = FVM_ICON;
1257 SetStyle (This, LVS_ICON, LVS_TYPEMASK);
1258 CheckToolbar(This);
1259 break;
1261 case FCIDM_SHVIEW_LISTVIEW:
1262 This->FolderSettings.ViewMode = FVM_LIST;
1263 SetStyle (This, LVS_LIST, LVS_TYPEMASK);
1264 CheckToolbar(This);
1265 break;
1267 case FCIDM_SHVIEW_REPORTVIEW:
1268 This->FolderSettings.ViewMode = FVM_DETAILS;
1269 SetStyle (This, LVS_REPORT, LVS_TYPEMASK);
1270 CheckToolbar(This);
1271 break;
1273 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1274 case 0x30:
1275 case 0x31:
1276 case 0x32:
1277 case 0x33:
1278 This->ListViewSortInfo.nHeaderID = dwCmdID - 0x30;
1279 This->ListViewSortInfo.bIsAscending = TRUE;
1280 This->ListViewSortInfo.nLastHeaderID = This->ListViewSortInfo.nHeaderID;
1281 SendMessageW(This->hWndList, LVM_SORTITEMS, (WPARAM) &This->ListViewSortInfo, (LPARAM)ShellView_ListViewCompareItems);
1282 break;
1284 default:
1285 TRACE("-- COMMAND 0x%04x unhandled\n", dwCmdID);
1287 return 0;
1290 /**********************************************************
1291 * ShellView_OnNotify()
1294 static LRESULT ShellView_OnNotify(IShellViewImpl * This, UINT CtlID, LPNMHDR lpnmh)
1295 { LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)lpnmh;
1296 NMLVDISPINFOW *lpdi = (NMLVDISPINFOW *)lpnmh;
1297 LPITEMIDLIST pidl;
1299 TRACE("%p CtlID=%u lpnmh->code=%x\n",This,CtlID,lpnmh->code);
1301 switch(lpnmh->code)
1303 case NM_SETFOCUS:
1304 TRACE("-- NM_SETFOCUS %p\n",This);
1305 ShellView_OnSetFocus(This);
1306 break;
1308 case NM_KILLFOCUS:
1309 TRACE("-- NM_KILLFOCUS %p\n",This);
1310 ShellView_OnDeactivate(This);
1311 /* Notify the ICommDlgBrowser interface */
1312 OnStateChange(This,CDBOSC_KILLFOCUS);
1313 break;
1315 case NM_CUSTOMDRAW:
1316 TRACE("-- NM_CUSTOMDRAW %p\n",This);
1317 return CDRF_DODEFAULT;
1319 case NM_RELEASEDCAPTURE:
1320 TRACE("-- NM_RELEASEDCAPTURE %p\n",This);
1321 break;
1323 case NM_CLICK:
1324 TRACE("-- NM_CLICK %p\n",This);
1325 break;
1327 case NM_RCLICK:
1328 TRACE("-- NM_RCLICK %p\n",This);
1329 break;
1331 case NM_DBLCLK:
1332 TRACE("-- NM_DBLCLK %p\n",This);
1333 if (OnDefaultCommand(This) != S_OK) ShellView_OpenSelectedItems(This);
1334 break;
1336 case NM_RETURN:
1337 TRACE("-- NM_RETURN %p\n",This);
1338 if (OnDefaultCommand(This) != S_OK) ShellView_OpenSelectedItems(This);
1339 break;
1341 case HDN_ENDTRACKW:
1342 TRACE("-- HDN_ENDTRACKW %p\n",This);
1343 /*nColumn1 = ListView_GetColumnWidth(This->hWndList, 0);
1344 nColumn2 = ListView_GetColumnWidth(This->hWndList, 1);*/
1345 break;
1347 case LVN_DELETEITEM:
1348 TRACE("-- LVN_DELETEITEM %p\n",This);
1349 SHFree((LPITEMIDLIST)lpnmlv->lParam); /*delete the pidl because we made a copy of it*/
1350 break;
1352 case LVN_DELETEALLITEMS:
1353 TRACE("-- LVN_DELETEALLITEMS %p\n",This);
1354 return FALSE;
1356 case LVN_INSERTITEM:
1357 TRACE("-- LVN_INSERTITEM (STUB)%p\n",This);
1358 break;
1360 case LVN_ITEMACTIVATE:
1361 TRACE("-- LVN_ITEMACTIVATE %p\n",This);
1362 OnStateChange(This, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
1363 break;
1365 case LVN_COLUMNCLICK:
1366 This->ListViewSortInfo.nHeaderID = lpnmlv->iSubItem;
1367 if(This->ListViewSortInfo.nLastHeaderID == This->ListViewSortInfo.nHeaderID)
1369 This->ListViewSortInfo.bIsAscending = !This->ListViewSortInfo.bIsAscending;
1371 else
1373 This->ListViewSortInfo.bIsAscending = TRUE;
1375 This->ListViewSortInfo.nLastHeaderID = This->ListViewSortInfo.nHeaderID;
1377 SendMessageW(lpnmlv->hdr.hwndFrom, LVM_SORTITEMS, (WPARAM) &This->ListViewSortInfo, (LPARAM)ShellView_ListViewCompareItems);
1378 break;
1380 case LVN_GETDISPINFOA:
1381 case LVN_GETDISPINFOW:
1382 TRACE("-- LVN_GETDISPINFO %p\n",This);
1383 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1385 if(lpdi->item.mask & LVIF_TEXT) /* text requested */
1387 if (This->pSF2Parent)
1389 SHELLDETAILS sd;
1390 IShellFolder2_GetDetailsOf(This->pSF2Parent, pidl, lpdi->item.iSubItem, &sd);
1391 if (lpnmh->code == LVN_GETDISPINFOA)
1393 /* shouldn't happen */
1394 NMLVDISPINFOA *lpdiA = (NMLVDISPINFOA *)lpnmh;
1395 StrRetToStrNA( lpdiA->item.pszText, lpdiA->item.cchTextMax, &sd.str, NULL);
1396 TRACE("-- text=%s\n",lpdiA->item.pszText);
1398 else /* LVN_GETDISPINFOW */
1400 StrRetToStrNW( lpdi->item.pszText, lpdi->item.cchTextMax, &sd.str, NULL);
1401 TRACE("-- text=%s\n",debugstr_w(lpdi->item.pszText));
1404 else
1406 FIXME("no SF2\n");
1409 if(lpdi->item.mask & LVIF_IMAGE) /* image requested */
1411 lpdi->item.iImage = SHMapPIDLToSystemImageListIndex(This->pSFParent, pidl, 0);
1413 break;
1415 case LVN_ITEMCHANGED:
1416 TRACE("-- LVN_ITEMCHANGED %p\n",This);
1417 OnStateChange(This, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
1418 break;
1420 case LVN_BEGINDRAG:
1421 case LVN_BEGINRDRAG:
1422 TRACE("-- LVN_BEGINDRAG\n");
1424 if (ShellView_GetSelections(This))
1426 IDataObject * pda;
1427 DWORD dwAttributes = SFGAO_CANLINK;
1428 DWORD dwEffect = DROPEFFECT_COPY | DROPEFFECT_MOVE;
1430 if (SUCCEEDED(IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, (LPCITEMIDLIST*)This->apidl, &IID_IDataObject,0,(LPVOID *)&pda)))
1432 IDropSource * pds = (IDropSource*)&(This->lpvtblDropSource); /* own DropSource interface */
1434 if (SUCCEEDED(IShellFolder_GetAttributesOf(This->pSFParent, This->cidl, (LPCITEMIDLIST*)This->apidl, &dwAttributes)))
1436 if (dwAttributes & SFGAO_CANLINK)
1438 dwEffect |= DROPEFFECT_LINK;
1442 if (pds)
1444 DWORD dwEffect2;
1445 DoDragDrop(pda, pds, dwEffect, &dwEffect2);
1447 IDataObject_Release(pda);
1450 break;
1452 case LVN_BEGINLABELEDITW:
1454 DWORD dwAttr = SFGAO_CANRENAME;
1455 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1457 TRACE("-- LVN_BEGINLABELEDITW %p\n",This);
1459 IShellFolder_GetAttributesOf(This->pSFParent, 1, (LPCITEMIDLIST*)&pidl, &dwAttr);
1460 if (SFGAO_CANRENAME & dwAttr)
1462 return FALSE;
1464 return TRUE;
1467 case LVN_ENDLABELEDITW:
1469 TRACE("-- LVN_ENDLABELEDITA %p\n",This);
1470 if (lpdi->item.pszText)
1472 HRESULT hr;
1473 LVITEMW lvItem;
1475 lvItem.iItem = lpdi->item.iItem;
1476 lvItem.iSubItem = 0;
1477 lvItem.mask = LVIF_PARAM;
1478 SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem);
1480 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1481 hr = IShellFolder_SetNameOf(This->pSFParent, 0, pidl, lpdi->item.pszText, SHGDN_INFOLDER, &pidl);
1483 if(SUCCEEDED(hr) && pidl)
1485 lvItem.mask = LVIF_PARAM;
1486 lvItem.lParam = (LPARAM)pidl;
1487 SendMessageW(This->hWndList, LVM_SETITEMW, 0, (LPARAM) &lvItem);
1488 return TRUE;
1491 return FALSE;
1494 case LVN_KEYDOWN:
1496 /* MSG msg;
1497 msg.hwnd = This->hWnd;
1498 msg.message = WM_KEYDOWN;
1499 msg.wParam = plvKeyDown->wVKey;
1500 msg.lParam = 0;
1501 msg.time = 0;
1502 msg.pt = 0;*/
1504 LPNMLVKEYDOWN plvKeyDown = (LPNMLVKEYDOWN) lpnmh;
1506 /* initiate a rename of the selected file or directory */
1507 if(plvKeyDown->wVKey == VK_F2)
1509 /* see how many files are selected */
1510 int i = SendMessageW(This->hWndList, LVM_GETSELECTEDCOUNT, 0, 0);
1512 /* get selected item */
1513 if(i == 1)
1515 /* get selected item */
1516 i = SendMessageW(This->hWndList, LVM_GETNEXTITEM, -1, MAKELPARAM (LVNI_SELECTED, 0));
1518 SendMessageW(This->hWndList, LVM_ENSUREVISIBLE, i, 0);
1519 SendMessageW(This->hWndList, LVM_EDITLABELW, i, 0);
1522 #if 0
1523 TranslateAccelerator(This->hWnd, This->hAccel, &msg)
1524 #endif
1525 else if(plvKeyDown->wVKey == VK_DELETE)
1527 UINT i;
1528 int item_index;
1529 LVITEMA item;
1530 LPITEMIDLIST* pItems;
1531 ISFHelper *psfhlp;
1533 IShellFolder_QueryInterface(This->pSFParent, &IID_ISFHelper,
1534 (LPVOID*)&psfhlp);
1536 if (psfhlp == NULL)
1537 break;
1539 if(!(i = SendMessageW(This->hWndList, LVM_GETSELECTEDCOUNT, 0, 0)))
1540 break;
1542 /* allocate memory for the pidl array */
1543 pItems = HeapAlloc(GetProcessHeap(), 0,
1544 sizeof(LPITEMIDLIST) * i);
1546 /* retrieve all selected items */
1547 i = 0;
1548 item_index = -1;
1549 while(SendMessageW(This->hWndList, LVM_GETSELECTEDCOUNT, 0, 0) > i)
1551 /* get selected item */
1552 item_index = SendMessageW(This->hWndList, LVM_GETNEXTITEM, item_index,
1553 MAKELPARAM (LVNI_SELECTED, 0));
1554 item.iItem = item_index;
1555 item.mask = LVIF_PARAM;
1556 SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM) &item);
1558 /* get item pidl */
1559 pItems[i] = (LPITEMIDLIST)item.lParam;
1561 i++;
1564 /* perform the item deletion */
1565 ISFHelper_DeleteItems(psfhlp, i, (LPCITEMIDLIST*)pItems);
1567 /* free pidl array memory */
1568 HeapFree(GetProcessHeap(), 0, pItems);
1571 /* Initiate a refresh */
1572 else if(plvKeyDown->wVKey == VK_F5)
1574 IShellView_Refresh((IShellView*)This);
1577 else if(plvKeyDown->wVKey == VK_BACK)
1579 LPSHELLBROWSER lpSb;
1580 if((lpSb = (LPSHELLBROWSER)SendMessageW(This->hWndParent, CWM_GETISHELLBROWSER, 0, 0)))
1582 IShellBrowser_BrowseObject(lpSb, NULL, SBSP_PARENT);
1586 else
1587 FIXME("LVN_KEYDOWN key=0x%08x\n",plvKeyDown->wVKey);
1589 break;
1591 default:
1592 TRACE("-- %p WM_COMMAND %x unhandled\n", This, lpnmh->code);
1593 break;
1595 return 0;
1598 /**********************************************************
1599 * ShellView_OnChange()
1602 static LRESULT ShellView_OnChange(IShellViewImpl * This, const LPCITEMIDLIST * Pidls, LONG wEventId)
1605 TRACE("(%p)(%p,%p,0x%08x)\n", This, Pidls[0], Pidls[1], wEventId);
1606 switch(wEventId)
1608 case SHCNE_MKDIR:
1609 case SHCNE_CREATE:
1610 LV_AddItem(This, Pidls[0]);
1611 break;
1612 case SHCNE_RMDIR:
1613 case SHCNE_DELETE:
1614 LV_DeleteItem(This, Pidls[0]);
1615 break;
1616 case SHCNE_RENAMEFOLDER:
1617 case SHCNE_RENAMEITEM:
1618 LV_RenameItem(This, Pidls[0], Pidls[1]);
1619 break;
1620 case SHCNE_UPDATEITEM:
1621 break;
1623 return TRUE;
1625 /**********************************************************
1626 * ShellView_WndProc
1629 static LRESULT CALLBACK ShellView_WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
1631 IShellViewImpl * pThis = (IShellViewImpl*)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
1632 LPCREATESTRUCTW lpcs;
1634 TRACE("(hwnd=%p msg=%x wparm=%lx lparm=%lx)\n",hWnd, uMessage, wParam, lParam);
1636 switch (uMessage)
1638 case WM_NCCREATE:
1639 lpcs = (LPCREATESTRUCTW)lParam;
1640 pThis = lpcs->lpCreateParams;
1641 SetWindowLongPtrW(hWnd, GWLP_USERDATA, (ULONG_PTR)pThis);
1642 pThis->hWnd = hWnd; /*set the window handle*/
1643 break;
1645 case WM_SIZE: return ShellView_OnSize(pThis,LOWORD(lParam), HIWORD(lParam));
1646 case WM_SETFOCUS: return ShellView_OnSetFocus(pThis);
1647 case WM_KILLFOCUS: return ShellView_OnKillFocus(pThis);
1648 case WM_CREATE: return ShellView_OnCreate(pThis);
1649 case WM_ACTIVATE: return ShellView_OnActivate(pThis, SVUIA_ACTIVATE_FOCUS);
1650 case WM_NOTIFY: return ShellView_OnNotify(pThis,(UINT)wParam, (LPNMHDR)lParam);
1651 case WM_COMMAND: return ShellView_OnCommand(pThis,
1652 GET_WM_COMMAND_ID(wParam, lParam),
1653 GET_WM_COMMAND_CMD(wParam, lParam),
1654 GET_WM_COMMAND_HWND(wParam, lParam));
1655 case SHV_CHANGE_NOTIFY: return ShellView_OnChange(pThis, (const LPCITEMIDLIST*)wParam, (LONG)lParam);
1657 case WM_CONTEXTMENU: ShellView_DoContextMenu(pThis, LOWORD(lParam), HIWORD(lParam), FALSE);
1658 return 0;
1660 case WM_SHOWWINDOW: UpdateWindow(pThis->hWndList);
1661 break;
1663 case WM_GETDLGCODE: return SendMessageW(pThis->hWndList, uMessage, 0, 0);
1665 case WM_DESTROY:
1666 RevokeDragDrop(pThis->hWnd);
1667 SHChangeNotifyDeregister(pThis->hNotify);
1668 break;
1670 case WM_ERASEBKGND:
1671 if ((pThis->FolderSettings.fFlags & FWF_DESKTOP) ||
1672 (pThis->FolderSettings.fFlags & FWF_TRANSPARENT))
1673 return 1;
1674 break;
1677 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
1679 /**********************************************************
1682 * The INTERFACE of the IShellView object
1685 **********************************************************
1686 * IShellView_QueryInterface
1688 static HRESULT WINAPI IShellView_fnQueryInterface(IShellView2 * iface,REFIID riid, LPVOID *ppvObj)
1690 IShellViewImpl *This = (IShellViewImpl *)iface;
1692 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1694 *ppvObj = NULL;
1696 if(IsEqualIID(riid, &IID_IUnknown))
1698 *ppvObj = This;
1700 else if(IsEqualIID(riid, &IID_IShellView))
1702 *ppvObj = This;
1704 else if(IsEqualIID(riid, &IID_IShellView2))
1706 *ppvObj = This;
1708 else if(IsEqualIID(riid, &IID_IFolderView))
1710 *ppvObj = &This->lpvtblFolderView;
1712 else if(IsEqualIID(riid, &IID_IOleCommandTarget))
1714 *ppvObj = &This->lpvtblOleCommandTarget;
1716 else if(IsEqualIID(riid, &IID_IDropTarget))
1718 *ppvObj = &This->lpvtblDropTarget;
1720 else if(IsEqualIID(riid, &IID_IDropSource))
1722 *ppvObj = &This->lpvtblDropSource;
1724 else if(IsEqualIID(riid, &IID_IViewObject))
1726 *ppvObj = &This->lpvtblViewObject;
1729 if(*ppvObj)
1731 IUnknown_AddRef( (IUnknown*)*ppvObj );
1732 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1733 return S_OK;
1735 TRACE("-- Interface: E_NOINTERFACE\n");
1736 return E_NOINTERFACE;
1739 /**********************************************************
1740 * IShellView_AddRef
1742 static ULONG WINAPI IShellView_fnAddRef(IShellView2 * iface)
1744 IShellViewImpl *This = (IShellViewImpl *)iface;
1745 ULONG refCount = InterlockedIncrement(&This->ref);
1747 TRACE("(%p)->(count=%u)\n", This, refCount - 1);
1749 return refCount;
1751 /**********************************************************
1752 * IShellView_Release
1754 static ULONG WINAPI IShellView_fnRelease(IShellView2 * iface)
1756 IShellViewImpl *This = (IShellViewImpl *)iface;
1757 ULONG refCount = InterlockedDecrement(&This->ref);
1759 TRACE("(%p)->(count=%i)\n", This, refCount + 1);
1761 if (!refCount)
1763 TRACE(" destroying IShellView(%p)\n",This);
1765 DestroyWindow(This->hWndList);
1767 if(This->pSFParent)
1768 IShellFolder_Release(This->pSFParent);
1770 if(This->pSF2Parent)
1771 IShellFolder2_Release(This->pSF2Parent);
1773 SHFree(This->apidl);
1775 if(This->pAdvSink)
1776 IAdviseSink_Release(This->pAdvSink);
1778 HeapFree(GetProcessHeap(),0,This);
1780 return refCount;
1783 /**********************************************************
1784 * ShellView_GetWindow
1786 static HRESULT WINAPI IShellView_fnGetWindow(IShellView2 * iface,HWND * phWnd)
1788 IShellViewImpl *This = (IShellViewImpl *)iface;
1790 TRACE("(%p)\n",This);
1792 *phWnd = This->hWnd;
1794 return S_OK;
1797 static HRESULT WINAPI IShellView_fnContextSensitiveHelp(IShellView2 * iface,BOOL fEnterMode)
1799 IShellViewImpl *This = (IShellViewImpl *)iface;
1801 FIXME("(%p) stub\n",This);
1803 return E_NOTIMPL;
1806 /**********************************************************
1807 * IShellView_TranslateAccelerator
1809 * FIXME:
1810 * use the accel functions
1812 static HRESULT WINAPI IShellView_fnTranslateAccelerator(IShellView2 * iface,LPMSG lpmsg)
1814 #if 0
1815 IShellViewImpl *This = (IShellViewImpl *)iface;
1817 FIXME("(%p)->(%p: hwnd=%x msg=%x lp=%x wp=%x) stub\n",This,lpmsg, lpmsg->hwnd, lpmsg->message, lpmsg->lParam, lpmsg->wParam);
1818 #endif
1820 if ((lpmsg->message>=WM_KEYFIRST) && (lpmsg->message>=WM_KEYLAST))
1822 TRACE("-- key=0x04%lx\n",lpmsg->wParam) ;
1824 return S_FALSE; /* not handled */
1827 static HRESULT WINAPI IShellView_fnEnableModeless(IShellView2 * iface,BOOL fEnable)
1829 IShellViewImpl *This = (IShellViewImpl *)iface;
1831 FIXME("(%p) stub\n",This);
1833 return E_NOTIMPL;
1836 static HRESULT WINAPI IShellView_fnUIActivate(IShellView2 * iface,UINT uState)
1838 IShellViewImpl *This = (IShellViewImpl *)iface;
1841 CHAR szName[MAX_PATH];
1843 LRESULT lResult;
1844 int nPartArray[1] = {-1};
1846 TRACE("(%p)->(state=%x) stub\n",This, uState);
1848 /*don't do anything if the state isn't really changing*/
1849 if(This->uState == uState)
1851 return S_OK;
1854 /*OnActivate handles the menu merging and internal state*/
1855 ShellView_OnActivate(This, uState);
1857 /*only do This if we are active*/
1858 if(uState != SVUIA_DEACTIVATE)
1862 GetFolderPath is not a method of IShellFolder
1863 IShellFolder_GetFolderPath( This->pSFParent, szName, sizeof(szName) );
1865 /* set the number of parts */
1866 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETPARTS, 1,
1867 (LPARAM)nPartArray, &lResult);
1869 /* set the text for the parts */
1871 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETTEXTA,
1872 0, (LPARAM)szName, &lResult);
1876 return S_OK;
1879 static HRESULT WINAPI IShellView_fnRefresh(IShellView2 * iface)
1881 IShellViewImpl *This = (IShellViewImpl *)iface;
1883 TRACE("(%p)\n", This);
1885 SendMessageW(This->hWndList, LVM_DELETEALLITEMS, 0, 0);
1886 ShellView_FillList(This);
1888 return S_OK;
1891 static HRESULT WINAPI IShellView_fnCreateViewWindow(IShellView2 *iface, IShellView *lpPrevView,
1892 LPCFOLDERSETTINGS lpfs, IShellBrowser *psb, RECT *prcView, HWND *phWnd)
1894 HRESULT hr;
1895 SV2CVW2_PARAMS view_params;
1896 view_params.cbSize = sizeof(view_params);
1897 view_params.psvPrev = lpPrevView;
1898 view_params.pfs = lpfs;
1899 view_params.psbOwner = psb;
1900 view_params.prcView = prcView;
1901 view_params.pvid = NULL;
1902 view_params.hwndView = 0;
1904 TRACE("(%p) Forwarding to CreateViewWindow2\n", iface);
1906 hr = IShellView2_CreateViewWindow2(iface, &view_params);
1907 *phWnd = view_params.hwndView;
1909 return hr;
1912 static HRESULT WINAPI IShellView_fnDestroyViewWindow(IShellView2 * iface)
1914 IShellViewImpl *This = (IShellViewImpl *)iface;
1916 TRACE("(%p)\n",This);
1918 /*Make absolutely sure all our UI is cleaned up.*/
1919 IShellView_UIActivate((IShellView*)This, SVUIA_DEACTIVATE);
1921 if(This->hMenu)
1923 DestroyMenu(This->hMenu);
1926 DestroyWindow(This->hWnd);
1927 if(This->pShellBrowser) IShellBrowser_Release(This->pShellBrowser);
1928 if(This->pCommDlgBrowser) ICommDlgBrowser_Release(This->pCommDlgBrowser);
1931 return S_OK;
1934 static HRESULT WINAPI IShellView_fnGetCurrentInfo(IShellView2 * iface, LPFOLDERSETTINGS lpfs)
1936 IShellViewImpl *This = (IShellViewImpl *)iface;
1938 TRACE("(%p)->(%p) vmode=%x flags=%x\n",This, lpfs,
1939 This->FolderSettings.ViewMode, This->FolderSettings.fFlags);
1941 if (!lpfs) return E_INVALIDARG;
1943 *lpfs = This->FolderSettings;
1944 return NOERROR;
1947 static HRESULT WINAPI IShellView_fnAddPropertySheetPages(IShellView2 * iface, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam)
1949 IShellViewImpl *This = (IShellViewImpl *)iface;
1951 FIXME("(%p) stub\n",This);
1953 return E_NOTIMPL;
1956 static HRESULT WINAPI IShellView_fnSaveViewState(IShellView2 * iface)
1958 IShellViewImpl *This = (IShellViewImpl *)iface;
1960 FIXME("(%p) stub\n",This);
1962 return S_OK;
1965 static HRESULT WINAPI IShellView_fnSelectItem(
1966 IShellView2 * iface,
1967 LPCITEMIDLIST pidl,
1968 UINT flags)
1970 IShellViewImpl *This = (IShellViewImpl *)iface;
1971 IFolderView *view;
1972 HRESULT hr;
1973 int i;
1975 TRACE("(%p)->(pidl=%p, 0x%08x)\n",This, pidl, flags);
1977 i = LV_FindItemByPidl(This, pidl);
1978 if (i == -1) return S_OK;
1980 hr = IShellView2_QueryInterface(iface, &IID_IFolderView, (void**)&view);
1981 if (hr == S_OK)
1983 hr = IFolderView_SelectItem(view, i, flags);
1984 IFolderView_Release(view);
1987 return hr;
1990 static HRESULT WINAPI IShellView_fnGetItemObject(IShellView2 * iface, UINT uItem, REFIID riid, LPVOID *ppvOut)
1992 IShellViewImpl *This = (IShellViewImpl *)iface;
1994 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n",This, uItem, debugstr_guid(riid), ppvOut);
1996 *ppvOut = NULL;
1998 switch(uItem)
2000 case SVGIO_BACKGROUND:
2001 *ppvOut = ISvBgCm_Constructor(This->pSFParent, FALSE);
2002 break;
2004 case SVGIO_SELECTION:
2005 ShellView_GetSelections(This);
2006 IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, (LPCITEMIDLIST*)This->apidl, riid, 0, ppvOut);
2007 break;
2009 TRACE("-- (%p)->(interface=%p)\n",This, *ppvOut);
2011 if(!*ppvOut) return E_OUTOFMEMORY;
2013 return S_OK;
2016 static HRESULT WINAPI IShellView2_fnGetView(IShellView2* iface, SHELLVIEWID *view_guid, ULONG view_type)
2018 FIXME("(%p)->(view_guid %s, view_type %#x) stub!\n", iface, debugstr_guid(view_guid), view_type);
2019 return E_NOTIMPL;
2022 static HRESULT WINAPI IShellView2_fnCreateViewWindow2(IShellView2* iface, LPSV2CVW2_PARAMS view_params)
2024 IShellViewImpl *This = (IShellViewImpl *)iface;
2025 WNDCLASSW wc;
2026 HRESULT hr;
2027 HWND wnd;
2029 TRACE("(%p)->(view_params %p)\n", iface, view_params);
2031 if (view_params->cbSize != sizeof(*view_params))
2033 FIXME("Got unexpected cbSize %#x\n", view_params->cbSize);
2034 return E_FAIL;
2037 TRACE("-- psvPrev %p, pfs %p, psbOwner %p, prcView %p\n",
2038 view_params->psvPrev, view_params->pfs, view_params->psbOwner, view_params->prcView);
2039 TRACE("-- vmode %#x, flags %#x, left %d, top %d, right %d, bottom %d\n",
2040 view_params->pfs->ViewMode, view_params->pfs->fFlags, view_params->prcView->left,
2041 view_params->prcView->top, view_params->prcView->right, view_params->prcView->bottom);
2043 if (!view_params->psbOwner) return E_UNEXPECTED;
2045 /* Set up the member variables */
2046 This->pShellBrowser = view_params->psbOwner;
2047 This->FolderSettings = *view_params->pfs;
2049 if (view_params->pvid)
2051 if (IsEqualGUID(view_params->pvid, &VID_LargeIcons))
2052 This->FolderSettings.ViewMode = FVM_ICON;
2053 else if (IsEqualGUID(view_params->pvid, &VID_SmallIcons))
2054 This->FolderSettings.ViewMode = FVM_SMALLICON;
2055 else if (IsEqualGUID(view_params->pvid, &VID_List))
2056 This->FolderSettings.ViewMode = FVM_LIST;
2057 else if (IsEqualGUID(view_params->pvid, &VID_Details))
2058 This->FolderSettings.ViewMode = FVM_DETAILS;
2059 else if (IsEqualGUID(view_params->pvid, &VID_Thumbnails))
2060 This->FolderSettings.ViewMode = FVM_THUMBNAIL;
2061 else if (IsEqualGUID(view_params->pvid, &VID_Tile))
2062 This->FolderSettings.ViewMode = FVM_TILE;
2063 else if (IsEqualGUID(view_params->pvid, &VID_ThumbStrip))
2064 This->FolderSettings.ViewMode = FVM_THUMBSTRIP;
2065 else
2066 FIXME("Ignoring unrecognized VID %s\n", debugstr_guid(view_params->pvid));
2069 /* Get our parent window */
2070 IShellBrowser_AddRef(This->pShellBrowser);
2071 IShellBrowser_GetWindow(This->pShellBrowser, &This->hWndParent);
2073 /* Try to get the ICommDlgBrowserInterface, adds a reference !!! */
2074 This->pCommDlgBrowser = NULL;
2075 hr = IShellBrowser_QueryInterface(This->pShellBrowser, &IID_ICommDlgBrowser, (void **)&This->pCommDlgBrowser);
2076 if (hr == S_OK)
2077 TRACE("-- CommDlgBrowser %p\n", This->pCommDlgBrowser);
2079 /* If our window class has not been registered, then do so */
2080 if (!GetClassInfoW(shell32_hInstance, SV_CLASS_NAME, &wc))
2082 wc.style = CS_HREDRAW | CS_VREDRAW;
2083 wc.lpfnWndProc = ShellView_WndProc;
2084 wc.cbClsExtra = 0;
2085 wc.cbWndExtra = 0;
2086 wc.hInstance = shell32_hInstance;
2087 wc.hIcon = 0;
2088 wc.hCursor = LoadCursorW(0, (LPWSTR)IDC_ARROW);
2089 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
2090 wc.lpszMenuName = NULL;
2091 wc.lpszClassName = SV_CLASS_NAME;
2093 if (!RegisterClassW(&wc)) return E_FAIL;
2096 wnd = CreateWindowExW(0, SV_CLASS_NAME, NULL, WS_CHILD | WS_TABSTOP,
2097 view_params->prcView->left, view_params->prcView->top,
2098 view_params->prcView->right - view_params->prcView->left,
2099 view_params->prcView->bottom - view_params->prcView->top,
2100 This->hWndParent, 0, shell32_hInstance, This);
2102 CheckToolbar(This);
2104 if (!wnd)
2106 IShellBrowser_Release(This->pShellBrowser);
2107 return E_FAIL;
2110 SetWindowPos(wnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
2111 UpdateWindow(wnd);
2113 view_params->hwndView = wnd;
2115 return S_OK;
2118 static HRESULT WINAPI IShellView2_fnHandleRename(IShellView2* iface, LPCITEMIDLIST new_pidl)
2120 FIXME("(%p)->(new_pidl %p) stub!\n", iface, new_pidl);
2121 return E_NOTIMPL;
2124 static HRESULT WINAPI IShellView2_fnSelectAndPositionItem(
2125 IShellView2* iface,
2126 LPCITEMIDLIST item,
2127 UINT flags,
2128 POINT *point)
2130 IShellViewImpl *This = (IShellViewImpl *)iface;
2131 IFolderView *view;
2132 HRESULT hr;
2134 TRACE("(%p)->(item %p, flags %#x, point %p)\n", This, item, flags, point);
2136 hr = IShellView2_QueryInterface(iface, &IID_IFolderView, (void**)&view);
2137 if (hr == S_OK)
2139 hr = IFolderView_SelectAndPositionItems(view, 1, &item, point, flags);
2140 IFolderView_Release(view);
2143 return hr;
2146 static const IShellView2Vtbl svvt =
2148 IShellView_fnQueryInterface,
2149 IShellView_fnAddRef,
2150 IShellView_fnRelease,
2151 IShellView_fnGetWindow,
2152 IShellView_fnContextSensitiveHelp,
2153 IShellView_fnTranslateAccelerator,
2154 IShellView_fnEnableModeless,
2155 IShellView_fnUIActivate,
2156 IShellView_fnRefresh,
2157 IShellView_fnCreateViewWindow,
2158 IShellView_fnDestroyViewWindow,
2159 IShellView_fnGetCurrentInfo,
2160 IShellView_fnAddPropertySheetPages,
2161 IShellView_fnSaveViewState,
2162 IShellView_fnSelectItem,
2163 IShellView_fnGetItemObject,
2164 IShellView2_fnGetView,
2165 IShellView2_fnCreateViewWindow2,
2166 IShellView2_fnHandleRename,
2167 IShellView2_fnSelectAndPositionItem,
2171 /**********************************************************
2172 * ISVOleCmdTarget_QueryInterface (IUnknown)
2174 static HRESULT WINAPI ISVOleCmdTarget_QueryInterface(
2175 IOleCommandTarget * iface,
2176 REFIID iid,
2177 LPVOID* ppvObj)
2179 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2181 return IShellView2_QueryInterface((IShellView2*)This, iid, ppvObj);
2184 /**********************************************************
2185 * ISVOleCmdTarget_AddRef (IUnknown)
2187 static ULONG WINAPI ISVOleCmdTarget_AddRef(
2188 IOleCommandTarget * iface)
2190 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2192 return IShellView2_AddRef((IShellView2*)This);
2195 /**********************************************************
2196 * ISVOleCmdTarget_Release (IUnknown)
2198 static ULONG WINAPI ISVOleCmdTarget_Release(
2199 IOleCommandTarget * iface)
2201 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2203 return IShellView2_Release((IShellView2*)This);
2206 /**********************************************************
2207 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2209 static HRESULT WINAPI ISVOleCmdTarget_QueryStatus(
2210 IOleCommandTarget *iface,
2211 const GUID* pguidCmdGroup,
2212 ULONG cCmds,
2213 OLECMD * prgCmds,
2214 OLECMDTEXT* pCmdText)
2216 UINT i;
2217 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2219 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
2220 This, pguidCmdGroup, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText);
2222 if (!prgCmds)
2223 return E_POINTER;
2224 for (i = 0; i < cCmds; i++)
2226 FIXME("\tprgCmds[%d].cmdID = %d\n", i, prgCmds[i].cmdID);
2227 prgCmds[i].cmdf = 0;
2229 return OLECMDERR_E_UNKNOWNGROUP;
2232 /**********************************************************
2233 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2235 * nCmdID is the OLECMDID_* enumeration
2237 static HRESULT WINAPI ISVOleCmdTarget_Exec(
2238 IOleCommandTarget *iface,
2239 const GUID* pguidCmdGroup,
2240 DWORD nCmdID,
2241 DWORD nCmdexecopt,
2242 VARIANT* pvaIn,
2243 VARIANT* pvaOut)
2245 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2247 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2248 This, debugstr_guid(pguidCmdGroup), nCmdID, nCmdexecopt, pvaIn, pvaOut);
2250 if (IsEqualIID(pguidCmdGroup, &CGID_Explorer) &&
2251 (nCmdID == 0x29) &&
2252 (nCmdexecopt == 4) && pvaOut)
2253 return S_OK;
2254 if (IsEqualIID(pguidCmdGroup, &CGID_ShellDocView) &&
2255 (nCmdID == 9) &&
2256 (nCmdexecopt == 0))
2257 return 1;
2259 return OLECMDERR_E_UNKNOWNGROUP;
2262 static const IOleCommandTargetVtbl ctvt =
2264 ISVOleCmdTarget_QueryInterface,
2265 ISVOleCmdTarget_AddRef,
2266 ISVOleCmdTarget_Release,
2267 ISVOleCmdTarget_QueryStatus,
2268 ISVOleCmdTarget_Exec
2271 /**********************************************************
2272 * ISVDropTarget implementation
2275 static HRESULT WINAPI ISVDropTarget_QueryInterface(
2276 IDropTarget *iface,
2277 REFIID riid,
2278 LPVOID *ppvObj)
2280 IShellViewImpl *This = impl_from_IDropTarget(iface);
2282 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2284 return IShellView2_QueryInterface((IShellView2*)This, riid, ppvObj);
2287 static ULONG WINAPI ISVDropTarget_AddRef( IDropTarget *iface)
2289 IShellViewImpl *This = impl_from_IDropTarget(iface);
2291 TRACE("(%p)->(count=%u)\n",This,This->ref);
2293 return IShellView2_AddRef((IShellView2*)This);
2296 static ULONG WINAPI ISVDropTarget_Release( IDropTarget *iface)
2298 IShellViewImpl *This = impl_from_IDropTarget(iface);
2300 TRACE("(%p)->(count=%u)\n",This,This->ref);
2302 return IShellView2_Release((IShellView2*)This);
2305 /******************************************************************************
2306 * drag_notify_subitem [Internal]
2308 * Figure out the shellfolder object, which is currently under the mouse cursor
2309 * and notify it via the IDropTarget interface.
2312 #define SCROLLAREAWIDTH 20
2314 static HRESULT drag_notify_subitem(IShellViewImpl *This, DWORD grfKeyState, POINTL pt,
2315 DWORD *pdwEffect)
2317 LVHITTESTINFO htinfo;
2318 LVITEMW lvItem;
2319 LONG lResult;
2320 HRESULT hr;
2321 RECT clientRect;
2323 /* Map from global to client coordinates and query the index of the listview-item, which is
2324 * currently under the mouse cursor. */
2325 htinfo.pt.x = pt.x;
2326 htinfo.pt.y = pt.y;
2327 htinfo.flags = LVHT_ONITEM;
2328 ScreenToClient(This->hWndList, &htinfo.pt);
2329 lResult = SendMessageW(This->hWndList, LVM_HITTEST, 0, (LPARAM)&htinfo);
2331 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2332 GetClientRect(This->hWndList, &clientRect);
2333 if (htinfo.pt.x == This->ptLastMousePos.x && htinfo.pt.y == This->ptLastMousePos.y &&
2334 (htinfo.pt.x < SCROLLAREAWIDTH || htinfo.pt.x > clientRect.right - SCROLLAREAWIDTH ||
2335 htinfo.pt.y < SCROLLAREAWIDTH || htinfo.pt.y > clientRect.bottom - SCROLLAREAWIDTH ))
2337 This->cScrollDelay = (This->cScrollDelay + 1) % 5; /* DragOver is called every 50 ms */
2338 if (This->cScrollDelay == 0) { /* Mouse did hover another 250 ms over the scroll-area */
2339 if (htinfo.pt.x < SCROLLAREAWIDTH)
2340 SendMessageW(This->hWndList, WM_HSCROLL, SB_LINEUP, 0);
2341 if (htinfo.pt.x > clientRect.right - SCROLLAREAWIDTH)
2342 SendMessageW(This->hWndList, WM_HSCROLL, SB_LINEDOWN, 0);
2343 if (htinfo.pt.y < SCROLLAREAWIDTH)
2344 SendMessageW(This->hWndList, WM_VSCROLL, SB_LINEUP, 0);
2345 if (htinfo.pt.y > clientRect.bottom - SCROLLAREAWIDTH)
2346 SendMessageW(This->hWndList, WM_VSCROLL, SB_LINEDOWN, 0);
2348 } else {
2349 This->cScrollDelay = 0; /* Reset, if the cursor is not over the listview's scroll-area */
2351 This->ptLastMousePos = htinfo.pt;
2353 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2354 if (This->pCurDropTarget && lResult == This->iDragOverItem)
2355 return IDropTarget_DragOver(This->pCurDropTarget, grfKeyState, pt, pdwEffect);
2357 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2358 if (This->pCurDropTarget) {
2359 IDropTarget_DragLeave(This->pCurDropTarget);
2360 IDropTarget_Release(This->pCurDropTarget);
2361 This->pCurDropTarget = NULL;
2364 This->iDragOverItem = lResult;
2365 if (lResult == -1) {
2366 /* We are not above one of the listview's subitems. Bind to the parent folder's
2367 * DropTarget interface. */
2368 hr = IShellFolder_QueryInterface(This->pSFParent, &IID_IDropTarget,
2369 (LPVOID*)&This->pCurDropTarget);
2370 } else {
2371 /* Query the relative PIDL of the shellfolder object represented by the currently
2372 * dragged over listview-item ... */
2373 lvItem.mask = LVIF_PARAM;
2374 lvItem.iItem = lResult;
2375 lvItem.iSubItem = 0;
2376 SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem);
2378 /* ... and bind pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2379 hr = IShellFolder_GetUIObjectOf(This->pSFParent, This->hWndList, 1,
2380 (LPCITEMIDLIST*)&lvItem.lParam, &IID_IDropTarget, NULL, (LPVOID*)&This->pCurDropTarget);
2383 /* If anything failed, pCurDropTarget should be NULL now, which ought to be a save state. */
2384 if (FAILED(hr))
2385 return hr;
2387 /* Notify the item just entered via DragEnter. */
2388 return IDropTarget_DragEnter(This->pCurDropTarget, This->pCurDataObject, grfKeyState, pt, pdwEffect);
2391 static HRESULT WINAPI ISVDropTarget_DragEnter(IDropTarget *iface, IDataObject *pDataObject,
2392 DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
2394 IShellViewImpl *This = impl_from_IDropTarget(iface);
2396 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2397 This->pCurDataObject = pDataObject;
2398 IDataObject_AddRef(pDataObject);
2400 return drag_notify_subitem(This, grfKeyState, pt, pdwEffect);
2403 static HRESULT WINAPI ISVDropTarget_DragOver(IDropTarget *iface, DWORD grfKeyState, POINTL pt,
2404 DWORD *pdwEffect)
2406 IShellViewImpl *This = impl_from_IDropTarget(iface);
2407 return drag_notify_subitem(This, grfKeyState, pt, pdwEffect);
2410 static HRESULT WINAPI ISVDropTarget_DragLeave(IDropTarget *iface)
2412 IShellViewImpl *This = impl_from_IDropTarget(iface);
2414 if (This->pCurDropTarget)
2416 IDropTarget_DragLeave(This->pCurDropTarget);
2417 IDropTarget_Release(This->pCurDropTarget);
2418 This->pCurDropTarget = NULL;
2421 if (This->pCurDataObject)
2423 IDataObject_Release(This->pCurDataObject);
2424 This->pCurDataObject = NULL;
2427 This->iDragOverItem = 0;
2429 return S_OK;
2432 static HRESULT WINAPI ISVDropTarget_Drop(IDropTarget *iface, IDataObject* pDataObject,
2433 DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
2435 IShellViewImpl *This = impl_from_IDropTarget(iface);
2437 IDropTarget_Drop(This->pCurDropTarget, pDataObject, grfKeyState, pt, pdwEffect);
2439 IDropTarget_Release(This->pCurDropTarget);
2440 IDataObject_Release(This->pCurDataObject);
2441 This->pCurDataObject = NULL;
2442 This->pCurDropTarget = NULL;
2443 This->iDragOverItem = 0;
2445 return S_OK;
2448 static const IDropTargetVtbl dtvt =
2450 ISVDropTarget_QueryInterface,
2451 ISVDropTarget_AddRef,
2452 ISVDropTarget_Release,
2453 ISVDropTarget_DragEnter,
2454 ISVDropTarget_DragOver,
2455 ISVDropTarget_DragLeave,
2456 ISVDropTarget_Drop
2459 /**********************************************************
2460 * ISVDropSource implementation
2463 static HRESULT WINAPI ISVDropSource_QueryInterface(
2464 IDropSource *iface,
2465 REFIID riid,
2466 LPVOID *ppvObj)
2468 IShellViewImpl *This = impl_from_IDropSource(iface);
2470 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2472 return IShellView2_QueryInterface((IShellView2*)This, riid, ppvObj);
2475 static ULONG WINAPI ISVDropSource_AddRef( IDropSource *iface)
2477 IShellViewImpl *This = impl_from_IDropSource(iface);
2479 TRACE("(%p)->(count=%u)\n",This,This->ref);
2481 return IShellView2_AddRef((IShellView2*)This);
2484 static ULONG WINAPI ISVDropSource_Release( IDropSource *iface)
2486 IShellViewImpl *This = impl_from_IDropSource(iface);
2488 TRACE("(%p)->(count=%u)\n",This,This->ref);
2490 return IShellView2_Release((IShellView2*)This);
2493 static HRESULT WINAPI ISVDropSource_QueryContinueDrag(
2494 IDropSource *iface,
2495 BOOL fEscapePressed,
2496 DWORD grfKeyState)
2498 IShellViewImpl *This = impl_from_IDropSource(iface);
2499 TRACE("(%p)\n",This);
2501 if (fEscapePressed)
2502 return DRAGDROP_S_CANCEL;
2503 else if (!(grfKeyState & MK_LBUTTON) && !(grfKeyState & MK_RBUTTON))
2504 return DRAGDROP_S_DROP;
2505 else
2506 return NOERROR;
2509 static HRESULT WINAPI ISVDropSource_GiveFeedback(
2510 IDropSource *iface,
2511 DWORD dwEffect)
2513 IShellViewImpl *This = impl_from_IDropSource(iface);
2514 TRACE("(%p)\n",This);
2516 return DRAGDROP_S_USEDEFAULTCURSORS;
2519 static const IDropSourceVtbl dsvt =
2521 ISVDropSource_QueryInterface,
2522 ISVDropSource_AddRef,
2523 ISVDropSource_Release,
2524 ISVDropSource_QueryContinueDrag,
2525 ISVDropSource_GiveFeedback
2527 /**********************************************************
2528 * ISVViewObject implementation
2531 static HRESULT WINAPI ISVViewObject_QueryInterface(
2532 IViewObject *iface,
2533 REFIID riid,
2534 LPVOID *ppvObj)
2536 IShellViewImpl *This = impl_from_IViewObject(iface);
2538 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2540 return IShellView2_QueryInterface((IShellView2*)This, riid, ppvObj);
2543 static ULONG WINAPI ISVViewObject_AddRef( IViewObject *iface)
2545 IShellViewImpl *This = impl_from_IViewObject(iface);
2547 TRACE("(%p)->(count=%u)\n",This,This->ref);
2549 return IShellView2_AddRef((IShellView2*)This);
2552 static ULONG WINAPI ISVViewObject_Release( IViewObject *iface)
2554 IShellViewImpl *This = impl_from_IViewObject(iface);
2556 TRACE("(%p)->(count=%u)\n",This,This->ref);
2558 return IShellView2_Release((IShellView2*)This);
2561 static HRESULT WINAPI ISVViewObject_Draw(
2562 IViewObject *iface,
2563 DWORD dwDrawAspect,
2564 LONG lindex,
2565 void* pvAspect,
2566 DVTARGETDEVICE* ptd,
2567 HDC hdcTargetDev,
2568 HDC hdcDraw,
2569 LPCRECTL lprcBounds,
2570 LPCRECTL lprcWBounds,
2571 BOOL (CALLBACK *pfnContinue)(ULONG_PTR dwContinue),
2572 ULONG_PTR dwContinue)
2575 IShellViewImpl *This = impl_from_IViewObject(iface);
2577 FIXME("Stub: This=%p\n",This);
2579 return E_NOTIMPL;
2581 static HRESULT WINAPI ISVViewObject_GetColorSet(
2582 IViewObject *iface,
2583 DWORD dwDrawAspect,
2584 LONG lindex,
2585 void *pvAspect,
2586 DVTARGETDEVICE* ptd,
2587 HDC hicTargetDevice,
2588 LOGPALETTE** ppColorSet)
2591 IShellViewImpl *This = impl_from_IViewObject(iface);
2593 FIXME("Stub: This=%p\n",This);
2595 return E_NOTIMPL;
2597 static HRESULT WINAPI ISVViewObject_Freeze(
2598 IViewObject *iface,
2599 DWORD dwDrawAspect,
2600 LONG lindex,
2601 void* pvAspect,
2602 DWORD* pdwFreeze)
2605 IShellViewImpl *This = impl_from_IViewObject(iface);
2607 FIXME("Stub: This=%p\n",This);
2609 return E_NOTIMPL;
2611 static HRESULT WINAPI ISVViewObject_Unfreeze(
2612 IViewObject *iface,
2613 DWORD dwFreeze)
2616 IShellViewImpl *This = impl_from_IViewObject(iface);
2618 FIXME("Stub: This=%p\n",This);
2620 return E_NOTIMPL;
2622 static HRESULT WINAPI ISVViewObject_SetAdvise(
2623 IViewObject *iface,
2624 DWORD aspects,
2625 DWORD advf,
2626 IAdviseSink* pAdvSink)
2629 IShellViewImpl *This = impl_from_IViewObject(iface);
2631 FIXME("partial stub: %p %08x %08x %p\n",
2632 This, aspects, advf, pAdvSink);
2634 /* FIXME: we set the AdviseSink, but never use it to send any advice */
2635 This->pAdvSink = pAdvSink;
2636 This->dwAspects = aspects;
2637 This->dwAdvf = advf;
2639 return S_OK;
2642 static HRESULT WINAPI ISVViewObject_GetAdvise(
2643 IViewObject *iface,
2644 DWORD* pAspects,
2645 DWORD* pAdvf,
2646 IAdviseSink** ppAdvSink)
2649 IShellViewImpl *This = impl_from_IViewObject(iface);
2651 TRACE("This=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n",
2652 This, pAspects, pAdvf, ppAdvSink);
2654 if( ppAdvSink )
2656 IAdviseSink_AddRef( This->pAdvSink );
2657 *ppAdvSink = This->pAdvSink;
2659 if( pAspects )
2660 *pAspects = This->dwAspects;
2661 if( pAdvf )
2662 *pAdvf = This->dwAdvf;
2664 return S_OK;
2668 static const IViewObjectVtbl vovt =
2670 ISVViewObject_QueryInterface,
2671 ISVViewObject_AddRef,
2672 ISVViewObject_Release,
2673 ISVViewObject_Draw,
2674 ISVViewObject_GetColorSet,
2675 ISVViewObject_Freeze,
2676 ISVViewObject_Unfreeze,
2677 ISVViewObject_SetAdvise,
2678 ISVViewObject_GetAdvise
2681 /* IFolderView */
2682 static HRESULT WINAPI IFView_QueryInterface(
2683 IFolderView *iface,
2684 REFIID riid,
2685 LPVOID *ppvObj)
2687 IShellViewImpl *This = impl_from_IFolderView(iface);
2688 TRACE("(%p)->(IID:%s,%p)\n", This, debugstr_guid(riid), ppvObj);
2689 return IShellView2_QueryInterface((IShellView2*)This, riid, ppvObj);
2692 static ULONG WINAPI IFView_AddRef( IFolderView *iface)
2694 IShellViewImpl *This = impl_from_IFolderView(iface);
2695 TRACE("(%p)->(count=%u)\n", This, This->ref);
2696 return IShellView2_AddRef((IShellView2*)This);
2699 static ULONG WINAPI IFView_Release( IFolderView *iface)
2701 IShellViewImpl *This = impl_from_IFolderView(iface);
2702 TRACE("(%p)->(count=%u)\n", This, This->ref);
2703 return IShellView2_Release((IShellView2*)This);
2706 static HRESULT WINAPI IFView_GetCurrentViewMode(IFolderView *iface, UINT *mode)
2708 IShellViewImpl *This = impl_from_IFolderView(iface);
2709 FIXME("(%p)->(%p), stub\n", This, mode);
2710 return E_NOTIMPL;
2713 static HRESULT WINAPI IFView_SetCurrentViewMode(IFolderView *iface, UINT mode)
2715 IShellViewImpl *This = impl_from_IFolderView(iface);
2716 FIXME("(%p)->(%u), stub\n", This, mode);
2717 return E_NOTIMPL;
2720 static HRESULT WINAPI IFView_GetFolder(IFolderView *iface, REFIID riid, void **ppv)
2722 IShellViewImpl *This = impl_from_IFolderView(iface);
2724 TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv);
2726 if (!ppv) return E_POINTER;
2728 if (IsEqualIID(riid, &IID_IShellFolder))
2730 *ppv = This->pSFParent;
2731 return S_OK;
2734 return E_NOINTERFACE;
2737 static HRESULT WINAPI IFView_Item(IFolderView *iface, int index, PITEMID_CHILD *ppidl)
2739 IShellViewImpl *This = impl_from_IFolderView(iface);
2740 FIXME("(%p)->(%d %p), stub\n", This, index, ppidl);
2741 return E_NOTIMPL;
2744 static HRESULT WINAPI IFView_ItemCount(IFolderView *iface, UINT flags, int *items)
2746 IShellViewImpl *This = impl_from_IFolderView(iface);
2748 TRACE("(%p)->(%u %p)\n", This, flags, items);
2750 if (flags != SVGIO_ALLVIEW)
2751 FIXME("some flags unsupported, %x\n", flags & ~SVGIO_ALLVIEW);
2753 *items = SendMessageW(This->hWndList, LVM_GETITEMCOUNT, 0, 0);
2755 return S_OK;
2758 static HRESULT WINAPI IFView_Items(IFolderView *iface, UINT flags, REFIID riid, void **ppv)
2760 IShellViewImpl *This = impl_from_IFolderView(iface);
2761 FIXME("(%p)->(%u %s %p), stub\n", This, flags, debugstr_guid(riid), ppv);
2762 return E_NOTIMPL;
2765 static HRESULT WINAPI IFView_GetSelectionMarkedItem(IFolderView *iface, int *item)
2767 IShellViewImpl *This = impl_from_IFolderView(iface);
2769 TRACE("(%p)->(%p)\n", This, item);
2771 *item = SendMessageW(This->hWndList, LVM_GETSELECTIONMARK, 0, 0);
2773 return S_OK;
2776 static HRESULT WINAPI IFView_GetFocusedItem(IFolderView *iface, int *item)
2778 IShellViewImpl *This = impl_from_IFolderView(iface);
2780 TRACE("(%p)->(%p)\n", This, item);
2782 *item = SendMessageW(This->hWndList, LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
2784 return S_OK;
2787 static HRESULT WINAPI IFView_GetItemPosition(IFolderView *iface, PCUITEMID_CHILD pidl, POINT *ppt)
2789 IShellViewImpl *This = impl_from_IFolderView(iface);
2790 FIXME("(%p)->(%p %p), stub\n", This, pidl, ppt);
2791 return E_NOTIMPL;
2794 static HRESULT WINAPI IFView_GetSpacing(IFolderView *iface, POINT *pt)
2796 IShellViewImpl *This = impl_from_IFolderView(iface);
2798 TRACE("(%p)->(%p)\n", This, pt);
2800 if (!This->hWndList) return S_FALSE;
2802 if (pt)
2804 DWORD ret;
2805 ret = SendMessageW(This->hWndList, LVM_GETITEMSPACING, 0, 0);
2807 pt->x = LOWORD(ret);
2808 pt->y = HIWORD(ret);
2811 return S_OK;
2814 static HRESULT WINAPI IFView_GetDefaultSpacing(IFolderView *iface, POINT *pt)
2816 IShellViewImpl *This = impl_from_IFolderView(iface);
2817 FIXME("(%p)->(%p), stub\n", This, pt);
2818 return E_NOTIMPL;
2821 static HRESULT WINAPI IFView_GetAutoArrange(IFolderView *iface)
2823 IShellViewImpl *This = impl_from_IFolderView(iface);
2824 FIXME("(%p), stub\n", This);
2825 return E_NOTIMPL;
2828 static HRESULT WINAPI IFView_SelectItem(IFolderView *iface, int item, DWORD flags)
2830 IShellViewImpl *This = impl_from_IFolderView(iface);
2831 LVITEMW lvItem;
2833 TRACE("(%p)->(%d, %x)\n", This, item, flags);
2835 lvItem.state = 0;
2836 lvItem.stateMask = LVIS_SELECTED;
2838 if (flags & SVSI_ENSUREVISIBLE)
2839 SendMessageW(This->hWndList, LVM_ENSUREVISIBLE, item, 0);
2841 /* all items */
2842 if (flags & SVSI_DESELECTOTHERS)
2843 SendMessageW(This->hWndList, LVM_SETITEMSTATE, -1, (LPARAM)&lvItem);
2845 /* this item */
2846 if (flags & SVSI_SELECT)
2847 lvItem.state |= LVIS_SELECTED;
2849 if (flags & SVSI_FOCUSED)
2850 lvItem.stateMask |= LVIS_FOCUSED;
2852 SendMessageW(This->hWndList, LVM_SETITEMSTATE, item, (LPARAM)&lvItem);
2854 if (flags & SVSI_EDIT)
2855 SendMessageW(This->hWndList, LVM_EDITLABELW, item, 0);
2857 return S_OK;
2860 static HRESULT WINAPI IFView_SelectAndPositionItems(IFolderView *iface, UINT cidl,
2861 PCUITEMID_CHILD_ARRAY apidl, POINT *apt, DWORD flags)
2863 IShellViewImpl *This = impl_from_IFolderView(iface);
2864 FIXME("(%p)->(%u %p %p %x), stub\n", This, cidl, apidl, apt, flags);
2865 return E_NOTIMPL;
2868 static const IFolderViewVtbl fviewvt =
2870 IFView_QueryInterface,
2871 IFView_AddRef,
2872 IFView_Release,
2873 IFView_GetCurrentViewMode,
2874 IFView_SetCurrentViewMode,
2875 IFView_GetFolder,
2876 IFView_Item,
2877 IFView_ItemCount,
2878 IFView_Items,
2879 IFView_GetSelectionMarkedItem,
2880 IFView_GetFocusedItem,
2881 IFView_GetItemPosition,
2882 IFView_GetSpacing,
2883 IFView_GetDefaultSpacing,
2884 IFView_GetAutoArrange,
2885 IFView_SelectItem,
2886 IFView_SelectAndPositionItems