shell32: Replaced folder_open.ico with a Tango compliant icon.
[wine.git] / dlls / shell32 / shlview.c
blob653e5f36a9c54f6efbd6490ee40ff3550acf3e92
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 const IShellFolderViewVtbl *lpvtblShellFolderView;
90 IShellFolder* pSFParent;
91 IShellFolder2* pSF2Parent;
92 IShellBrowser* pShellBrowser;
93 ICommDlgBrowser* pCommDlgBrowser;
94 HWND hWnd; /* SHELLDLL_DefView */
95 HWND hWndList; /* ListView control */
96 HWND hWndParent;
97 FOLDERSETTINGS FolderSettings;
98 HMENU hMenu;
99 UINT uState;
100 UINT cidl;
101 LPITEMIDLIST *apidl;
102 LISTVIEW_SORT_INFO ListViewSortInfo;
103 ULONG hNotify; /* change notification handle */
104 HANDLE hAccel;
105 DWORD dwAspects;
106 DWORD dwAdvf;
107 IAdviseSink *pAdvSink;
108 IDropTarget* pCurDropTarget; /* The sub-item, which is currently dragged over */
109 IDataObject* pCurDataObject; /* The dragged data-object */
110 LONG iDragOverItem; /* Dragged over item's index, iff pCurDropTarget != NULL */
111 UINT cScrollDelay; /* Send a WM_*SCROLL msg every 250 ms during drag-scroll */
112 POINT ptLastMousePos; /* Mouse position at last DragOver call */
113 } IShellViewImpl;
115 static const IShellView2Vtbl svvt;
116 static const IOleCommandTargetVtbl ctvt;
117 static const IDropTargetVtbl dtvt;
118 static const IDropSourceVtbl dsvt;
119 static const IViewObjectVtbl vovt;
120 static const IFolderViewVtbl fviewvt;
121 static const IShellFolderViewVtbl shellfolderviewvt;
123 static inline IShellViewImpl *impl_from_IOleCommandTarget( IOleCommandTarget *iface )
125 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblOleCommandTarget));
128 static inline IShellViewImpl *impl_from_IDropTarget( IDropTarget *iface )
130 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblDropTarget));
133 static inline IShellViewImpl *impl_from_IDropSource( IDropSource *iface )
135 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblDropSource));
138 static inline IShellViewImpl *impl_from_IViewObject( IViewObject *iface )
140 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblViewObject));
143 static inline IShellViewImpl *impl_from_IFolderView( IFolderView *iface )
145 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblFolderView));
148 static inline IShellViewImpl *impl_from_IShellFolderView( IShellFolderView *iface )
150 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblShellFolderView));
153 /* ListView Header ID's */
154 #define LISTVIEW_COLUMN_NAME 0
155 #define LISTVIEW_COLUMN_SIZE 1
156 #define LISTVIEW_COLUMN_TYPE 2
157 #define LISTVIEW_COLUMN_TIME 3
158 #define LISTVIEW_COLUMN_ATTRIB 4
160 /*menu items */
161 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
162 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
163 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
165 #define ID_LISTVIEW 1
167 #define SHV_CHANGE_NOTIFY WM_USER + 0x1111
169 /*windowsx.h */
170 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
171 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
172 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
175 Items merged into the toolbar and the filemenu
177 typedef struct
178 { int idCommand;
179 int iImage;
180 int idButtonString;
181 int idMenuString;
182 BYTE bState;
183 BYTE bStyle;
184 } MYTOOLINFO, *LPMYTOOLINFO;
186 static const MYTOOLINFO Tools[] =
188 { FCIDM_SHVIEW_BIGICON, 0, 0, IDS_VIEW_LARGE, TBSTATE_ENABLED, BTNS_BUTTON },
189 { FCIDM_SHVIEW_SMALLICON, 0, 0, IDS_VIEW_SMALL, TBSTATE_ENABLED, BTNS_BUTTON },
190 { FCIDM_SHVIEW_LISTVIEW, 0, 0, IDS_VIEW_LIST, TBSTATE_ENABLED, BTNS_BUTTON },
191 { FCIDM_SHVIEW_REPORTVIEW, 0, 0, IDS_VIEW_DETAILS, TBSTATE_ENABLED, BTNS_BUTTON },
192 { -1, 0, 0, 0, 0, 0}
195 typedef void (CALLBACK *PFNSHGETSETTINGSPROC)(LPSHELLFLAGSTATE lpsfs, DWORD dwMask);
197 /**********************************************************
198 * IShellView_Constructor
200 IShellView * IShellView_Constructor( IShellFolder * pFolder)
201 { IShellViewImpl * sv;
202 sv=HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IShellViewImpl));
203 sv->ref=1;
204 sv->lpVtbl=&svvt;
205 sv->lpvtblOleCommandTarget=&ctvt;
206 sv->lpvtblDropTarget=&dtvt;
207 sv->lpvtblDropSource=&dsvt;
208 sv->lpvtblViewObject=&vovt;
209 sv->lpvtblFolderView=&fviewvt;
210 sv->lpvtblShellFolderView=&shellfolderviewvt;
212 sv->pSFParent = pFolder;
213 if(pFolder) IShellFolder_AddRef(pFolder);
214 IShellFolder_QueryInterface(sv->pSFParent, &IID_IShellFolder2, (LPVOID*)&sv->pSF2Parent);
216 sv->pCurDropTarget = NULL;
217 sv->pCurDataObject = NULL;
218 sv->iDragOverItem = 0;
219 sv->cScrollDelay = 0;
220 sv->ptLastMousePos.x = 0;
221 sv->ptLastMousePos.y = 0;
223 TRACE("(%p)->(%p)\n",sv, pFolder);
224 return (IShellView *) sv;
227 /**********************************************************
229 * ##### helperfunctions for communication with ICommDlgBrowser #####
231 static BOOL IsInCommDlg(IShellViewImpl * This)
232 { return(This->pCommDlgBrowser != NULL);
235 static HRESULT IncludeObject(IShellViewImpl * This, LPCITEMIDLIST pidl)
237 HRESULT ret = S_OK;
239 if ( IsInCommDlg(This) )
241 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl);
242 ret = ICommDlgBrowser_IncludeObject(This->pCommDlgBrowser, (IShellView*)This, pidl);
243 TRACE("--0x%08x\n", ret);
245 return ret;
248 static HRESULT OnDefaultCommand(IShellViewImpl * This)
250 HRESULT ret = S_FALSE;
252 if (IsInCommDlg(This))
254 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
255 ret = ICommDlgBrowser_OnDefaultCommand(This->pCommDlgBrowser, (IShellView*)This);
256 TRACE("-- returns %08x\n", ret);
258 return ret;
261 static HRESULT OnStateChange(IShellViewImpl * This, UINT uFlags)
263 HRESULT ret = S_FALSE;
265 if (IsInCommDlg(This))
267 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags);
268 ret = ICommDlgBrowser_OnStateChange(This->pCommDlgBrowser, (IShellView*)This, uFlags);
269 TRACE("--\n");
271 return ret;
273 /**********************************************************
274 * set the toolbar of the filedialog buttons
276 * - activates the buttons from the shellbrowser according to
277 * the view state
279 static void CheckToolbar(IShellViewImpl * This)
281 LRESULT result;
283 TRACE("\n");
285 if (IsInCommDlg(This))
287 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
288 FCIDM_TB_SMALLICON, (This->FolderSettings.ViewMode==FVM_LIST)? TRUE : FALSE, &result);
289 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
290 FCIDM_TB_REPORTVIEW, (This->FolderSettings.ViewMode==FVM_DETAILS)? TRUE : FALSE, &result);
291 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
292 FCIDM_TB_SMALLICON, TRUE, &result);
293 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
294 FCIDM_TB_REPORTVIEW, TRUE, &result);
298 /**********************************************************
300 * ##### helperfunctions for initializing the view #####
302 /**********************************************************
303 * change the style of the listview control
305 static void SetStyle(IShellViewImpl * This, DWORD dwAdd, DWORD dwRemove)
307 DWORD tmpstyle;
309 TRACE("(%p)\n", This);
311 tmpstyle = GetWindowLongW(This->hWndList, GWL_STYLE);
312 SetWindowLongW(This->hWndList, GWL_STYLE, dwAdd | (tmpstyle & ~dwRemove));
315 /**********************************************************
316 * ShellView_CreateList()
318 * - creates the list view window
320 static BOOL ShellView_CreateList (IShellViewImpl * This)
321 { DWORD dwStyle, dwExStyle;
323 TRACE("%p\n",This);
325 dwStyle = WS_TABSTOP | WS_VISIBLE | WS_CHILDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
326 LVS_SHAREIMAGELISTS | LVS_EDITLABELS | LVS_ALIGNLEFT | LVS_AUTOARRANGE;
327 dwExStyle = WS_EX_CLIENTEDGE;
329 switch (This->FolderSettings.ViewMode)
331 case FVM_ICON: dwStyle |= LVS_ICON; break;
332 case FVM_DETAILS: dwStyle |= LVS_REPORT; break;
333 case FVM_SMALLICON: dwStyle |= LVS_SMALLICON; break;
334 case FVM_LIST: dwStyle |= LVS_LIST; break;
335 default:
337 FIXME("ViewMode %d not implemented\n", This->FolderSettings.ViewMode);
338 dwStyle |= LVS_LIST;
339 break;
343 if (This->FolderSettings.fFlags & FWF_AUTOARRANGE) dwStyle |= LVS_AUTOARRANGE;
344 if (This->FolderSettings.fFlags & FWF_DESKTOP)
345 This->FolderSettings.fFlags |= FWF_NOCLIENTEDGE | FWF_NOSCROLL;
346 if (This->FolderSettings.fFlags & FWF_SINGLESEL) dwStyle |= LVS_SINGLESEL;
347 if (This->FolderSettings.fFlags & FWF_NOCLIENTEDGE)
348 dwExStyle &= ~WS_EX_CLIENTEDGE;
350 This->hWndList=CreateWindowExW( dwExStyle,
351 WC_LISTVIEWW,
352 NULL,
353 dwStyle,
354 0,0,0,0,
355 This->hWnd,
356 (HMENU)ID_LISTVIEW,
357 shell32_hInstance,
358 NULL);
360 if(!This->hWndList)
361 return FALSE;
363 This->ListViewSortInfo.bIsAscending = TRUE;
364 This->ListViewSortInfo.nHeaderID = -1;
365 This->ListViewSortInfo.nLastHeaderID = -1;
367 if (This->FolderSettings.fFlags & FWF_DESKTOP) {
369 * FIXME: look at the registry value
370 * HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ListviewShadow
371 * and activate drop shadows if necessary
373 if (0)
374 SendMessageW(This->hWndList, LVM_SETTEXTBKCOLOR, 0, CLR_NONE);
375 else
376 SendMessageW(This->hWndList, LVM_SETTEXTBKCOLOR, 0, GetSysColor(COLOR_DESKTOP));
378 SendMessageW(This->hWndList, LVM_SETTEXTCOLOR, 0, RGB(255,255,255));
381 /* UpdateShellSettings(); */
382 return TRUE;
385 /**********************************************************
386 * ShellView_InitList()
388 * - adds all needed columns to the shellview
390 static BOOL ShellView_InitList(IShellViewImpl * This)
392 LVCOLUMNW lvColumn;
393 SHELLDETAILS sd;
394 int i;
395 WCHAR szTemp[50];
397 TRACE("%p\n",This);
399 SendMessageW(This->hWndList, LVM_DELETEALLITEMS, 0, 0);
401 lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT;
402 lvColumn.pszText = szTemp;
404 if (This->pSF2Parent)
406 for (i=0; 1; i++)
408 if (FAILED(IShellFolder2_GetDetailsOf(This->pSF2Parent, NULL, i, &sd)))
409 break;
410 lvColumn.fmt = sd.fmt;
411 lvColumn.cx = sd.cxChar*8; /* chars->pixel */
412 StrRetToStrNW( szTemp, 50, &sd.str, NULL);
413 SendMessageW(This->hWndList, LVM_INSERTCOLUMNW, i, (LPARAM) &lvColumn);
416 else
418 FIXME("no SF2\n");
421 SendMessageW(This->hWndList, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)ShellSmallIconList);
422 SendMessageW(This->hWndList, LVM_SETIMAGELIST, LVSIL_NORMAL, (LPARAM)ShellBigIconList);
424 return TRUE;
426 /**********************************************************
427 * ShellView_CompareItems()
429 * NOTES
430 * internal, CALLBACK for DSA_Sort
432 static INT CALLBACK ShellView_CompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
434 int ret;
435 TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1, lParam2, (LPVOID) lpData);
437 if(!lpData) return 0;
439 ret = (SHORT) SCODE_CODE(IShellFolder_CompareIDs((LPSHELLFOLDER)lpData, 0, (LPITEMIDLIST)lParam1, (LPITEMIDLIST)lParam2));
440 TRACE("ret=%i\n",ret);
441 return ret;
444 /*************************************************************************
445 * ShellView_ListViewCompareItems
447 * Compare Function for the Listview (FileOpen Dialog)
449 * PARAMS
450 * lParam1 [I] the first ItemIdList to compare with
451 * lParam2 [I] the second ItemIdList to compare with
452 * lpData [I] The column ID for the header Ctrl to process
454 * RETURNS
455 * A negative value if the first item should precede the second,
456 * a positive value if the first item should follow the second,
457 * or zero if the two items are equivalent
459 * NOTES
460 * FIXME: function does what ShellView_CompareItems is supposed to do.
461 * unify it and figure out how to use the undocumented first parameter
462 * of IShellFolder_CompareIDs to do the job this function does and
463 * move this code to IShellFolder.
464 * make LISTVIEW_SORT_INFO obsolete
465 * the way this function works is only usable if we had only
466 * filesystemfolders (25/10/99 jsch)
468 static INT CALLBACK ShellView_ListViewCompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
470 INT nDiff=0;
471 FILETIME fd1, fd2;
472 char strName1[MAX_PATH], strName2[MAX_PATH];
473 BOOL bIsFolder1, bIsFolder2,bIsBothFolder;
474 LPITEMIDLIST pItemIdList1 = lParam1;
475 LPITEMIDLIST pItemIdList2 = lParam2;
476 LISTVIEW_SORT_INFO *pSortInfo = (LPLISTVIEW_SORT_INFO) lpData;
479 bIsFolder1 = _ILIsFolder(pItemIdList1);
480 bIsFolder2 = _ILIsFolder(pItemIdList2);
481 bIsBothFolder = bIsFolder1 && bIsFolder2;
483 /* When sorting between a File and a Folder, the Folder gets sorted first */
484 if( (bIsFolder1 || bIsFolder2) && !bIsBothFolder)
486 nDiff = bIsFolder1 ? -1 : 1;
488 else
490 /* Sort by Time: Folders or Files can be sorted */
492 if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TIME)
494 _ILGetFileDateTime(pItemIdList1, &fd1);
495 _ILGetFileDateTime(pItemIdList2, &fd2);
496 nDiff = CompareFileTime(&fd2, &fd1);
498 /* Sort by Attribute: Folder or Files can be sorted */
499 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_ATTRIB)
501 _ILGetFileAttributes(pItemIdList1, strName1, MAX_PATH);
502 _ILGetFileAttributes(pItemIdList2, strName2, MAX_PATH);
503 nDiff = lstrcmpiA(strName1, strName2);
505 /* Sort by FileName: Folder or Files can be sorted */
506 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_NAME || bIsBothFolder)
508 /* Sort by Text */
509 _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
510 _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
511 nDiff = lstrcmpiA(strName1, strName2);
513 /* Sort by File Size, Only valid for Files */
514 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_SIZE)
516 nDiff = (INT)(_ILGetFileSize(pItemIdList1, NULL, 0) - _ILGetFileSize(pItemIdList2, NULL, 0));
518 /* Sort by File Type, Only valid for Files */
519 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TYPE)
521 /* Sort by Type */
522 _ILGetFileType(pItemIdList1, strName1, MAX_PATH);
523 _ILGetFileType(pItemIdList2, strName2, MAX_PATH);
524 nDiff = lstrcmpiA(strName1, strName2);
527 /* If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
529 if(nDiff == 0)
531 _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
532 _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
533 nDiff = lstrcmpiA(strName1, strName2);
536 if(!pSortInfo->bIsAscending)
538 nDiff = -nDiff;
541 return nDiff;
545 /**********************************************************
546 * LV_FindItemByPidl()
548 static int LV_FindItemByPidl(
549 IShellViewImpl * This,
550 LPCITEMIDLIST pidl)
552 LVITEMW lvItem;
553 lvItem.iSubItem = 0;
554 lvItem.mask = LVIF_PARAM;
555 for(lvItem.iItem = 0;
556 SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem);
557 lvItem.iItem++)
559 LPITEMIDLIST currentpidl = (LPITEMIDLIST) lvItem.lParam;
560 HRESULT hr = IShellFolder_CompareIDs(This->pSFParent, 0, pidl, currentpidl);
561 if(SUCCEEDED(hr) && !HRESULT_CODE(hr))
563 return lvItem.iItem;
566 return -1;
569 /**********************************************************
570 * LV_AddItem()
572 static BOOLEAN LV_AddItem(IShellViewImpl * This, LPCITEMIDLIST pidl)
574 LVITEMW lvItem;
576 TRACE("(%p)(pidl=%p)\n", This, pidl);
578 lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; /*set the mask*/
579 lvItem.iItem = SendMessageW(This->hWndList, LVM_GETITEMCOUNT, 0, 0); /*add the item to the end of the list*/
580 lvItem.iSubItem = 0;
581 lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidl)); /*set the item's data*/
582 lvItem.pszText = LPSTR_TEXTCALLBACKW; /*get text on a callback basis*/
583 lvItem.iImage = I_IMAGECALLBACK; /*get the image on a callback basis*/
584 return (-1==ListView_InsertItemW(This->hWndList, &lvItem))? FALSE: TRUE;
587 /**********************************************************
588 * LV_RenameItem()
590 static BOOLEAN LV_RenameItem(IShellViewImpl * This, LPCITEMIDLIST pidlOld, LPCITEMIDLIST pidlNew )
592 int nItem;
593 LVITEMW lvItem;
595 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", This, pidlOld, pidlNew);
597 nItem = LV_FindItemByPidl(This, ILFindLastID(pidlOld));
598 if ( -1 != nItem )
600 lvItem.mask = LVIF_PARAM; /* only the pidl */
601 lvItem.iItem = nItem;
602 SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem);
604 SHFree((LPITEMIDLIST)lvItem.lParam);
605 lvItem.mask = LVIF_PARAM;
606 lvItem.iItem = nItem;
607 lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidlNew)); /* set the item's data */
608 SendMessageW(This->hWndList, LVM_SETITEMW, 0, (LPARAM) &lvItem);
609 SendMessageW(This->hWndList, LVM_UPDATE, nItem, 0);
610 return TRUE; /* FIXME: better handling */
612 return FALSE;
614 /**********************************************************
615 * ShellView_FillList()
617 * - gets the objectlist from the shellfolder
618 * - sorts the list
619 * - fills the list into the view
622 static INT CALLBACK fill_list( LPVOID ptr, LPVOID arg )
624 LPITEMIDLIST pidl = ptr;
625 IShellViewImpl *This = arg;
626 /* in a commdlg This works as a filemask*/
627 if ( IncludeObject(This, pidl)==S_OK ) LV_AddItem(This, pidl);
628 SHFree(pidl);
629 return TRUE;
632 static HRESULT ShellView_FillList(IShellViewImpl *This)
634 IShellFolderView *folderview = (IShellFolderView*)&This->lpvtblShellFolderView;
635 LPENUMIDLIST pEnumIDList;
636 LPITEMIDLIST pidl;
637 DWORD fetched;
638 HRESULT hr;
639 HDPA hdpa;
641 TRACE("(%p)\n", This);
643 /* get the itemlist from the shfolder*/
644 hr = IShellFolder_EnumObjects(This->pSFParent, This->hWnd, SHCONTF_NONFOLDERS | SHCONTF_FOLDERS, &pEnumIDList);
645 if (hr != S_OK) return hr;
647 /* create a pointer array */
648 hdpa = DPA_Create(16);
649 if (!hdpa)
651 IEnumIDList_Release(pEnumIDList);
652 return E_OUTOFMEMORY;
655 /* copy the items into the array*/
656 while((S_OK == IEnumIDList_Next(pEnumIDList, 1, &pidl, &fetched)) && fetched)
658 if (DPA_InsertPtr(hdpa, DPA_GetPtrCount(hdpa), pidl) == -1)
660 SHFree(pidl);
664 /* sort the array */
665 DPA_Sort(hdpa, ShellView_CompareItems, (LPARAM)This->pSFParent);
667 IShellFolderView_SetRedraw(folderview, FALSE);
668 DPA_DestroyCallback(hdpa, fill_list, This);
669 IShellFolderView_SetRedraw(folderview, TRUE);
671 IEnumIDList_Release(pEnumIDList);
673 return S_OK;
676 /**********************************************************
677 * ShellView_OnCreate()
679 static LRESULT ShellView_OnCreate(IShellViewImpl *This)
681 IShellView2 *iface = (IShellView2*)This;
682 static const WCHAR accel_nameW[] = {'s','h','v','_','a','c','c','e','l',0};
683 IPersistFolder2 *ppf2;
684 IDropTarget* pdt;
685 HRESULT hr;
687 TRACE("(%p)\n", This);
689 if (ShellView_CreateList(This))
691 if (ShellView_InitList(This))
693 ShellView_FillList(This);
697 hr = IShellView2_QueryInterface(iface, &IID_IDropTarget, (LPVOID*)&pdt);
698 if (hr == S_OK)
700 RegisterDragDrop(This->hWnd, pdt);
701 IDropTarget_Release(pdt);
704 /* register for receiving notifications */
705 hr = IShellFolder_QueryInterface(This->pSFParent, &IID_IPersistFolder2, (LPVOID*)&ppf2);
706 if (hr == S_OK)
708 SHChangeNotifyEntry ntreg;
710 hr = IPersistFolder2_GetCurFolder(ppf2, (LPITEMIDLIST*)&ntreg.pidl);
711 if (hr == S_OK)
713 ntreg.fRecursive = TRUE;
714 This->hNotify = SHChangeNotifyRegister(This->hWnd, SHCNF_IDLIST, SHCNE_ALLEVENTS,
715 SHV_CHANGE_NOTIFY, 1, &ntreg);
716 SHFree((LPITEMIDLIST)ntreg.pidl);
718 IPersistFolder2_Release(ppf2);
721 This->hAccel = LoadAcceleratorsW(shell32_hInstance, accel_nameW);
723 return S_OK;
726 /**********************************************************
727 * #### Handling of the menus ####
730 /**********************************************************
731 * ShellView_BuildFileMenu()
733 static HMENU ShellView_BuildFileMenu(IShellViewImpl * This)
734 { WCHAR szText[MAX_PATH];
735 MENUITEMINFOW mii;
736 int nTools,i;
737 HMENU hSubMenu;
739 TRACE("(%p)\n",This);
741 hSubMenu = CreatePopupMenu();
742 if(hSubMenu)
743 { /*get the number of items in our global array*/
744 for(nTools = 0; Tools[nTools].idCommand != -1; nTools++){}
746 /*add the menu items*/
747 for(i = 0; i < nTools; i++)
749 LoadStringW(shell32_hInstance, Tools[i].idMenuString, szText, MAX_PATH);
751 ZeroMemory(&mii, sizeof(mii));
752 mii.cbSize = sizeof(mii);
753 mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
755 if(BTNS_SEP != Tools[i].bStyle) /* no separator*/
757 mii.fType = MFT_STRING;
758 mii.fState = MFS_ENABLED;
759 mii.dwTypeData = szText;
760 mii.wID = Tools[i].idCommand;
762 else
764 mii.fType = MFT_SEPARATOR;
766 /* tack This item onto the end of the menu */
767 InsertMenuItemW(hSubMenu, (UINT)-1, TRUE, &mii);
770 TRACE("-- return (menu=%p)\n",hSubMenu);
771 return hSubMenu;
773 /**********************************************************
774 * ShellView_MergeFileMenu()
776 static void ShellView_MergeFileMenu(IShellViewImpl *This, HMENU hSubMenu)
778 TRACE("(%p)->(submenu=%p) stub\n",This,hSubMenu);
780 if (hSubMenu)
782 static const WCHAR dummyW[] = {'d','u','m','m','y','4','5',0};
783 MENUITEMINFOW mii;
785 /* insert This item at the beginning of the menu */
787 mii.cbSize = sizeof(mii);
788 mii.fMask = MIIM_ID | MIIM_TYPE;
789 mii.wID = 0;
790 mii.fType = MFT_SEPARATOR;
791 InsertMenuItemW(hSubMenu, 0, TRUE, &mii);
793 mii.cbSize = sizeof(mii);
794 mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
795 mii.dwTypeData = (LPWSTR)dummyW;
796 mii.fState = MFS_ENABLED;
797 mii.wID = IDM_MYFILEITEM;
798 mii.fType = MFT_STRING;
799 InsertMenuItemW(hSubMenu, 0, TRUE, &mii);
802 TRACE("--\n");
805 /**********************************************************
806 * ShellView_MergeViewMenu()
809 static void ShellView_MergeViewMenu(IShellViewImpl *This, HMENU hSubMenu)
811 TRACE("(%p)->(submenu=%p)\n",This,hSubMenu);
813 /* add a separator at the correct position in the menu */
814 if (hSubMenu)
816 static const WCHAR menuW[] = {'M','E','N','U','_','0','0','1',0};
817 static const WCHAR viewW[] = {'V','i','e','w',0};
818 MENUITEMINFOW mii;
820 memset(&mii, 0, sizeof(mii));
821 mii.cbSize = sizeof(mii);
822 mii.fMask = MIIM_ID | MIIM_TYPE;
823 mii.wID = 0;
824 mii.fType = MFT_SEPARATOR;
825 InsertMenuItemW(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
827 mii.cbSize = sizeof(mii);
828 mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_DATA;
829 mii.fType = MFT_STRING;
830 mii.dwTypeData = (LPWSTR)viewW;
831 mii.hSubMenu = LoadMenuW(shell32_hInstance, menuW);
832 InsertMenuItemW(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
836 /**********************************************************
837 * ShellView_GetSelections()
839 * - fills the this->apidl list with the selected objects
841 * RETURNS
842 * number of selected items
844 static UINT ShellView_GetSelections(IShellViewImpl * This)
846 LVITEMW lvItem;
847 UINT i = 0;
849 SHFree(This->apidl);
851 This->cidl = SendMessageW(This->hWndList, LVM_GETSELECTEDCOUNT, 0, 0);
852 This->apidl = SHAlloc(This->cidl * sizeof(LPITEMIDLIST));
854 TRACE("selected=%i\n", This->cidl);
856 if(This->apidl)
858 TRACE("-- Items selected =%u\n", This->cidl);
860 lvItem.mask = LVIF_STATE | LVIF_PARAM;
861 lvItem.stateMask = LVIS_SELECTED;
862 lvItem.iItem = 0;
863 lvItem.iSubItem = 0;
865 while(ListView_GetItemW(This->hWndList, &lvItem) && (i < This->cidl))
867 if(lvItem.state & LVIS_SELECTED)
869 This->apidl[i] = (LPITEMIDLIST)lvItem.lParam;
870 i++;
871 TRACE("-- selected Item found\n");
873 lvItem.iItem++;
876 return This->cidl;
880 /**********************************************************
881 * ShellView_OpenSelectedItems()
883 static HRESULT ShellView_OpenSelectedItems(IShellViewImpl * This)
885 static UINT CF_IDLIST = 0;
886 HRESULT hr;
887 IDataObject* selection;
888 FORMATETC fetc;
889 STGMEDIUM stgm;
890 LPIDA pIDList;
891 LPCITEMIDLIST parent_pidl;
892 WCHAR parent_path[MAX_PATH];
893 LPCWSTR parent_dir = NULL;
894 SFGAOF attribs;
895 int i;
897 if (0 == ShellView_GetSelections(This))
899 return S_OK;
901 hr = IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl,
902 (LPCITEMIDLIST*)This->apidl, &IID_IDataObject,
903 0, (LPVOID *)&selection);
904 if (FAILED(hr))
905 return hr;
907 if (0 == CF_IDLIST)
909 CF_IDLIST = RegisterClipboardFormatW(CFSTR_SHELLIDLISTW);
911 fetc.cfFormat = CF_IDLIST;
912 fetc.ptd = NULL;
913 fetc.dwAspect = DVASPECT_CONTENT;
914 fetc.lindex = -1;
915 fetc.tymed = TYMED_HGLOBAL;
917 hr = IDataObject_QueryGetData(selection, &fetc);
918 if (FAILED(hr))
919 return hr;
921 hr = IDataObject_GetData(selection, &fetc, &stgm);
922 if (FAILED(hr))
923 return hr;
925 pIDList = GlobalLock(stgm.u.hGlobal);
927 parent_pidl = (LPCITEMIDLIST) ((LPBYTE)pIDList+pIDList->aoffset[0]);
928 hr = IShellFolder_GetAttributesOf(This->pSFParent, 1, &parent_pidl, &attribs);
929 if (SUCCEEDED(hr) && (attribs & SFGAO_FILESYSTEM) &&
930 SHGetPathFromIDListW(parent_pidl, parent_path))
932 parent_dir = parent_path;
935 for (i = pIDList->cidl; i > 0; --i)
937 LPCITEMIDLIST pidl;
939 pidl = (LPCITEMIDLIST)((LPBYTE)pIDList+pIDList->aoffset[i]);
941 attribs = SFGAO_FOLDER;
942 hr = IShellFolder_GetAttributesOf(This->pSFParent, 1, &pidl, &attribs);
944 if (SUCCEEDED(hr) && ! (attribs & SFGAO_FOLDER))
946 SHELLEXECUTEINFOW shexinfo;
948 shexinfo.cbSize = sizeof(SHELLEXECUTEINFOW);
949 shexinfo.fMask = SEE_MASK_INVOKEIDLIST; /* SEE_MASK_IDLIST is also possible. */
950 shexinfo.hwnd = NULL;
951 shexinfo.lpVerb = NULL;
952 shexinfo.lpFile = NULL;
953 shexinfo.lpParameters = NULL;
954 shexinfo.lpDirectory = parent_dir;
955 shexinfo.nShow = SW_NORMAL;
956 shexinfo.lpIDList = ILCombine(parent_pidl, pidl);
958 ShellExecuteExW(&shexinfo); /* Discard error/success info */
960 ILFree(shexinfo.lpIDList);
964 GlobalUnlock(stgm.u.hGlobal);
965 ReleaseStgMedium(&stgm);
967 IDataObject_Release(selection);
969 return S_OK;
972 /**********************************************************
973 * ShellView_DoContextMenu()
975 static void ShellView_DoContextMenu(IShellViewImpl * This, WORD x, WORD y, BOOL bDefault)
976 { UINT uCommand;
977 DWORD wFlags;
978 HMENU hMenu;
979 BOOL fExplore = FALSE;
980 HWND hwndTree = 0;
981 LPCONTEXTMENU pContextMenu = NULL;
982 IContextMenu2 *pCM = NULL;
983 CMINVOKECOMMANDINFO cmi;
985 TRACE("(%p)->(0x%08x 0x%08x 0x%08x) stub\n",This, x, y, bDefault);
987 /* look, what's selected and create a context menu object of it*/
988 if( ShellView_GetSelections(This) )
990 IShellFolder_GetUIObjectOf( This->pSFParent, This->hWndParent, This->cidl, (LPCITEMIDLIST*)This->apidl,
991 &IID_IContextMenu, NULL, (LPVOID *)&pContextMenu);
993 if(pContextMenu)
995 TRACE("-- pContextMenu\n");
996 hMenu = CreatePopupMenu();
998 if( hMenu )
1000 /* See if we are in Explore or Open mode. If the browser's tree is present, we are in Explore mode.*/
1001 if(SUCCEEDED(IShellBrowser_GetControlWindow(This->pShellBrowser,FCW_TREE, &hwndTree)) && hwndTree)
1003 TRACE("-- explore mode\n");
1004 fExplore = TRUE;
1007 /* build the flags depending on what we can do with the selected item */
1008 wFlags = CMF_NORMAL | (This->cidl != 1 ? 0 : CMF_CANRENAME) | (fExplore ? CMF_EXPLORE : 0);
1010 /* let the ContextMenu merge its items in */
1011 if (SUCCEEDED(IContextMenu_QueryContextMenu( pContextMenu, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, wFlags )))
1013 if (This->FolderSettings.fFlags & FWF_DESKTOP)
1014 SetMenuDefaultItem(hMenu, FCIDM_SHVIEW_OPEN, MF_BYCOMMAND);
1016 if( bDefault )
1018 TRACE("-- get menu default command\n");
1019 uCommand = GetMenuDefaultItem(hMenu, FALSE, GMDI_GOINTOPOPUPS);
1021 else
1023 TRACE("-- track popup\n");
1024 uCommand = TrackPopupMenu( hMenu,TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
1027 if(uCommand > 0)
1029 TRACE("-- uCommand=%u\n", uCommand);
1030 if (uCommand==FCIDM_SHVIEW_OPEN && IsInCommDlg(This))
1032 TRACE("-- dlg: OnDefaultCommand\n");
1033 if (OnDefaultCommand(This) != S_OK)
1035 ShellView_OpenSelectedItems(This);
1038 else
1040 TRACE("-- explore -- invoke command\n");
1041 ZeroMemory(&cmi, sizeof(cmi));
1042 cmi.cbSize = sizeof(cmi);
1043 cmi.hwnd = This->hWndParent; /* this window has to answer CWM_GETISHELLBROWSER */
1044 cmi.lpVerb = MAKEINTRESOURCEA(uCommand);
1045 IContextMenu_InvokeCommand(pContextMenu, &cmi);
1048 DestroyMenu(hMenu);
1051 if (pContextMenu)
1052 IContextMenu_Release(pContextMenu);
1055 else /* background context menu */
1057 hMenu = CreatePopupMenu();
1059 pCM = ISvBgCm_Constructor(This->pSFParent, FALSE);
1060 IContextMenu2_QueryContextMenu(pCM, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, 0);
1062 uCommand = TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
1063 DestroyMenu(hMenu);
1065 TRACE("-- (%p)->(uCommand=0x%08x )\n",This, uCommand);
1067 ZeroMemory(&cmi, sizeof(cmi));
1068 cmi.cbSize = sizeof(cmi);
1069 cmi.lpVerb = MAKEINTRESOURCEA(uCommand);
1070 cmi.hwnd = This->hWndParent;
1071 IContextMenu2_InvokeCommand(pCM, &cmi);
1073 IContextMenu2_Release(pCM);
1077 /**********************************************************
1078 * ##### message handling #####
1081 /**********************************************************
1082 * ShellView_OnSize()
1084 static LRESULT ShellView_OnSize(IShellViewImpl * This, WORD wWidth, WORD wHeight)
1086 TRACE("%p width=%u height=%u\n",This, wWidth,wHeight);
1088 /*resize the ListView to fit our window*/
1089 if(This->hWndList)
1091 MoveWindow(This->hWndList, 0, 0, wWidth, wHeight, TRUE);
1094 return S_OK;
1096 /**********************************************************
1097 * ShellView_OnDeactivate()
1099 * NOTES
1100 * internal
1102 static void ShellView_OnDeactivate(IShellViewImpl * This)
1104 TRACE("%p\n",This);
1106 if(This->uState != SVUIA_DEACTIVATE)
1108 if(This->hMenu)
1110 IShellBrowser_SetMenuSB(This->pShellBrowser,0, 0, 0);
1111 IShellBrowser_RemoveMenusSB(This->pShellBrowser,This->hMenu);
1112 DestroyMenu(This->hMenu);
1113 This->hMenu = 0;
1116 This->uState = SVUIA_DEACTIVATE;
1120 /**********************************************************
1121 * ShellView_OnActivate()
1123 static LRESULT ShellView_OnActivate(IShellViewImpl *This, UINT uState)
1125 OLEMENUGROUPWIDTHS omw = { {0, 0, 0, 0, 0, 0} };
1126 MENUITEMINFOW mii;
1128 TRACE("(%p) uState=%x\n",This,uState);
1130 /* don't do anything if the state isn't really changing */
1131 if (This->uState == uState) return S_OK;
1133 ShellView_OnDeactivate(This);
1135 /* only do This if we are active */
1136 if (uState != SVUIA_DEACTIVATE)
1138 /* merge the menus */
1139 This->hMenu = CreateMenu();
1141 if (This->hMenu)
1143 static const WCHAR dummyW[] = {'d','u','m','m','y',' ','3','1',0};
1145 IShellBrowser_InsertMenusSB(This->pShellBrowser, This->hMenu, &omw);
1146 TRACE("-- after fnInsertMenusSB\n");
1148 mii.cbSize = sizeof(mii);
1149 mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_STATE;
1150 mii.fType = MFT_STRING;
1151 mii.fState = MFS_ENABLED;
1152 mii.wID = 0;
1153 mii.hSubMenu = ShellView_BuildFileMenu(This);
1154 mii.hbmpChecked = NULL;
1155 mii.hbmpUnchecked = NULL;
1156 mii.dwItemData = 0;
1157 /* build the top level menu get the menu item's text */
1158 mii.dwTypeData = (LPWSTR)dummyW;
1159 mii.cch = 0;
1160 mii.hbmpItem = NULL;
1162 /* insert our menu into the menu bar */
1163 if (mii.hSubMenu)
1164 InsertMenuItemW(This->hMenu, FCIDM_MENU_HELP, FALSE, &mii);
1166 /* get the view menu so we can merge with it */
1167 memset(&mii, 0, sizeof(mii));
1168 mii.cbSize = sizeof(mii);
1169 mii.fMask = MIIM_SUBMENU;
1171 if (GetMenuItemInfoW(This->hMenu, FCIDM_MENU_VIEW, FALSE, &mii))
1172 ShellView_MergeViewMenu(This, mii.hSubMenu);
1174 /* add the items that should only be added if we have the focus */
1175 if (SVUIA_ACTIVATE_FOCUS == uState)
1177 /* get the file menu so we can merge with it */
1178 memset(&mii, 0, sizeof(mii));
1179 mii.cbSize = sizeof(mii);
1180 mii.fMask = MIIM_SUBMENU;
1182 if (GetMenuItemInfoW(This->hMenu, FCIDM_MENU_FILE, FALSE, &mii))
1183 ShellView_MergeFileMenu(This, mii.hSubMenu);
1186 TRACE("-- before fnSetMenuSB\n");
1187 IShellBrowser_SetMenuSB(This->pShellBrowser, This->hMenu, 0, This->hWnd);
1190 This->uState = uState;
1191 TRACE("--\n");
1192 return S_OK;
1195 /**********************************************************
1196 * ShellView_OnSetFocus()
1199 static LRESULT ShellView_OnSetFocus(IShellViewImpl * This)
1201 TRACE("%p\n",This);
1203 /* Tell the browser one of our windows has received the focus. This
1204 should always be done before merging menus (OnActivate merges the
1205 menus) if one of our windows has the focus.*/
1207 IShellBrowser_OnViewWindowActive(This->pShellBrowser,(IShellView*) This);
1208 ShellView_OnActivate(This, SVUIA_ACTIVATE_FOCUS);
1210 /* Set the focus to the listview */
1211 SetFocus(This->hWndList);
1213 /* Notify the ICommDlgBrowser interface */
1214 OnStateChange(This,CDBOSC_SETFOCUS);
1216 return 0;
1219 /**********************************************************
1220 * ShellView_OnKillFocus()
1222 static LRESULT ShellView_OnKillFocus(IShellViewImpl * This)
1224 TRACE("(%p) stub\n",This);
1226 ShellView_OnActivate(This, SVUIA_ACTIVATE_NOFOCUS);
1227 /* Notify the ICommDlgBrowser */
1228 OnStateChange(This,CDBOSC_KILLFOCUS);
1230 return 0;
1233 /**********************************************************
1234 * ShellView_OnCommand()
1236 * NOTES
1237 * the CmdID's are the ones from the context menu
1239 static LRESULT ShellView_OnCommand(IShellViewImpl * This,DWORD dwCmdID, DWORD dwCmd, HWND hwndCmd)
1241 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n",This, dwCmdID, dwCmd, hwndCmd);
1243 switch(dwCmdID)
1245 case FCIDM_SHVIEW_SMALLICON:
1246 This->FolderSettings.ViewMode = FVM_SMALLICON;
1247 SetStyle (This, LVS_SMALLICON, LVS_TYPEMASK);
1248 CheckToolbar(This);
1249 break;
1251 case FCIDM_SHVIEW_BIGICON:
1252 This->FolderSettings.ViewMode = FVM_ICON;
1253 SetStyle (This, LVS_ICON, LVS_TYPEMASK);
1254 CheckToolbar(This);
1255 break;
1257 case FCIDM_SHVIEW_LISTVIEW:
1258 This->FolderSettings.ViewMode = FVM_LIST;
1259 SetStyle (This, LVS_LIST, LVS_TYPEMASK);
1260 CheckToolbar(This);
1261 break;
1263 case FCIDM_SHVIEW_REPORTVIEW:
1264 This->FolderSettings.ViewMode = FVM_DETAILS;
1265 SetStyle (This, LVS_REPORT, LVS_TYPEMASK);
1266 CheckToolbar(This);
1267 break;
1269 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1270 case 0x30:
1271 case 0x31:
1272 case 0x32:
1273 case 0x33:
1274 This->ListViewSortInfo.nHeaderID = dwCmdID - 0x30;
1275 This->ListViewSortInfo.bIsAscending = TRUE;
1276 This->ListViewSortInfo.nLastHeaderID = This->ListViewSortInfo.nHeaderID;
1277 SendMessageW(This->hWndList, LVM_SORTITEMS, (WPARAM) &This->ListViewSortInfo, (LPARAM)ShellView_ListViewCompareItems);
1278 break;
1280 default:
1281 TRACE("-- COMMAND 0x%04x unhandled\n", dwCmdID);
1283 return 0;
1286 /**********************************************************
1287 * ShellView_OnNotify()
1290 static LRESULT ShellView_OnNotify(IShellViewImpl * This, UINT CtlID, LPNMHDR lpnmh)
1291 { LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)lpnmh;
1292 NMLVDISPINFOW *lpdi = (NMLVDISPINFOW *)lpnmh;
1293 LPITEMIDLIST pidl;
1295 TRACE("%p CtlID=%u lpnmh->code=%x\n",This,CtlID,lpnmh->code);
1297 switch(lpnmh->code)
1299 case NM_SETFOCUS:
1300 TRACE("-- NM_SETFOCUS %p\n",This);
1301 ShellView_OnSetFocus(This);
1302 break;
1304 case NM_KILLFOCUS:
1305 TRACE("-- NM_KILLFOCUS %p\n",This);
1306 ShellView_OnDeactivate(This);
1307 /* Notify the ICommDlgBrowser interface */
1308 OnStateChange(This,CDBOSC_KILLFOCUS);
1309 break;
1311 case NM_CUSTOMDRAW:
1312 TRACE("-- NM_CUSTOMDRAW %p\n",This);
1313 return CDRF_DODEFAULT;
1315 case NM_RELEASEDCAPTURE:
1316 TRACE("-- NM_RELEASEDCAPTURE %p\n",This);
1317 break;
1319 case NM_CLICK:
1320 TRACE("-- NM_CLICK %p\n",This);
1321 break;
1323 case NM_RCLICK:
1324 TRACE("-- NM_RCLICK %p\n",This);
1325 break;
1327 case NM_DBLCLK:
1328 TRACE("-- NM_DBLCLK %p\n",This);
1329 if (OnDefaultCommand(This) != S_OK) ShellView_OpenSelectedItems(This);
1330 break;
1332 case NM_RETURN:
1333 TRACE("-- NM_RETURN %p\n",This);
1334 if (OnDefaultCommand(This) != S_OK) ShellView_OpenSelectedItems(This);
1335 break;
1337 case HDN_ENDTRACKW:
1338 TRACE("-- HDN_ENDTRACKW %p\n",This);
1339 /*nColumn1 = ListView_GetColumnWidth(This->hWndList, 0);
1340 nColumn2 = ListView_GetColumnWidth(This->hWndList, 1);*/
1341 break;
1343 case LVN_DELETEITEM:
1344 TRACE("-- LVN_DELETEITEM %p\n",This);
1345 SHFree((LPITEMIDLIST)lpnmlv->lParam); /*delete the pidl because we made a copy of it*/
1346 break;
1348 case LVN_DELETEALLITEMS:
1349 TRACE("-- LVN_DELETEALLITEMS %p\n",This);
1350 return FALSE;
1352 case LVN_INSERTITEM:
1353 TRACE("-- LVN_INSERTITEM (STUB)%p\n",This);
1354 break;
1356 case LVN_ITEMACTIVATE:
1357 TRACE("-- LVN_ITEMACTIVATE %p\n",This);
1358 OnStateChange(This, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
1359 break;
1361 case LVN_COLUMNCLICK:
1362 This->ListViewSortInfo.nHeaderID = lpnmlv->iSubItem;
1363 if(This->ListViewSortInfo.nLastHeaderID == This->ListViewSortInfo.nHeaderID)
1365 This->ListViewSortInfo.bIsAscending = !This->ListViewSortInfo.bIsAscending;
1367 else
1369 This->ListViewSortInfo.bIsAscending = TRUE;
1371 This->ListViewSortInfo.nLastHeaderID = This->ListViewSortInfo.nHeaderID;
1373 SendMessageW(lpnmlv->hdr.hwndFrom, LVM_SORTITEMS, (WPARAM) &This->ListViewSortInfo, (LPARAM)ShellView_ListViewCompareItems);
1374 break;
1376 case LVN_GETDISPINFOA:
1377 case LVN_GETDISPINFOW:
1378 TRACE("-- LVN_GETDISPINFO %p\n",This);
1379 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1381 if(lpdi->item.mask & LVIF_TEXT) /* text requested */
1383 if (This->pSF2Parent)
1385 SHELLDETAILS sd;
1386 IShellFolder2_GetDetailsOf(This->pSF2Parent, pidl, lpdi->item.iSubItem, &sd);
1387 if (lpnmh->code == LVN_GETDISPINFOA)
1389 /* shouldn't happen */
1390 NMLVDISPINFOA *lpdiA = (NMLVDISPINFOA *)lpnmh;
1391 StrRetToStrNA( lpdiA->item.pszText, lpdiA->item.cchTextMax, &sd.str, NULL);
1392 TRACE("-- text=%s\n",lpdiA->item.pszText);
1394 else /* LVN_GETDISPINFOW */
1396 StrRetToStrNW( lpdi->item.pszText, lpdi->item.cchTextMax, &sd.str, NULL);
1397 TRACE("-- text=%s\n",debugstr_w(lpdi->item.pszText));
1400 else
1402 FIXME("no SF2\n");
1405 if(lpdi->item.mask & LVIF_IMAGE) /* image requested */
1407 lpdi->item.iImage = SHMapPIDLToSystemImageListIndex(This->pSFParent, pidl, 0);
1409 break;
1411 case LVN_ITEMCHANGED:
1412 TRACE("-- LVN_ITEMCHANGED %p\n",This);
1413 OnStateChange(This, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
1414 break;
1416 case LVN_BEGINDRAG:
1417 case LVN_BEGINRDRAG:
1418 TRACE("-- LVN_BEGINDRAG\n");
1420 if (ShellView_GetSelections(This))
1422 IDataObject * pda;
1423 DWORD dwAttributes = SFGAO_CANLINK;
1424 DWORD dwEffect = DROPEFFECT_COPY | DROPEFFECT_MOVE;
1426 if (SUCCEEDED(IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, (LPCITEMIDLIST*)This->apidl, &IID_IDataObject,0,(LPVOID *)&pda)))
1428 IDropSource * pds = (IDropSource*)&(This->lpvtblDropSource); /* own DropSource interface */
1430 if (SUCCEEDED(IShellFolder_GetAttributesOf(This->pSFParent, This->cidl, (LPCITEMIDLIST*)This->apidl, &dwAttributes)))
1432 if (dwAttributes & SFGAO_CANLINK)
1434 dwEffect |= DROPEFFECT_LINK;
1438 if (pds)
1440 DWORD dwEffect2;
1441 DoDragDrop(pda, pds, dwEffect, &dwEffect2);
1443 IDataObject_Release(pda);
1446 break;
1448 case LVN_BEGINLABELEDITW:
1450 DWORD dwAttr = SFGAO_CANRENAME;
1451 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1453 TRACE("-- LVN_BEGINLABELEDITW %p\n",This);
1455 IShellFolder_GetAttributesOf(This->pSFParent, 1, (LPCITEMIDLIST*)&pidl, &dwAttr);
1456 if (SFGAO_CANRENAME & dwAttr)
1458 return FALSE;
1460 return TRUE;
1463 case LVN_ENDLABELEDITW:
1465 TRACE("-- LVN_ENDLABELEDITA %p\n",This);
1466 if (lpdi->item.pszText)
1468 HRESULT hr;
1469 LVITEMW lvItem;
1471 lvItem.iItem = lpdi->item.iItem;
1472 lvItem.iSubItem = 0;
1473 lvItem.mask = LVIF_PARAM;
1474 SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem);
1476 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1477 hr = IShellFolder_SetNameOf(This->pSFParent, 0, pidl, lpdi->item.pszText, SHGDN_INFOLDER, &pidl);
1479 if(SUCCEEDED(hr) && pidl)
1481 lvItem.mask = LVIF_PARAM;
1482 lvItem.lParam = (LPARAM)pidl;
1483 SendMessageW(This->hWndList, LVM_SETITEMW, 0, (LPARAM) &lvItem);
1484 return TRUE;
1487 return FALSE;
1490 case LVN_KEYDOWN:
1492 /* MSG msg;
1493 msg.hwnd = This->hWnd;
1494 msg.message = WM_KEYDOWN;
1495 msg.wParam = plvKeyDown->wVKey;
1496 msg.lParam = 0;
1497 msg.time = 0;
1498 msg.pt = 0;*/
1500 LPNMLVKEYDOWN plvKeyDown = (LPNMLVKEYDOWN) lpnmh;
1502 /* initiate a rename of the selected file or directory */
1503 if(plvKeyDown->wVKey == VK_F2)
1505 /* see how many files are selected */
1506 int i = SendMessageW(This->hWndList, LVM_GETSELECTEDCOUNT, 0, 0);
1508 /* get selected item */
1509 if(i == 1)
1511 /* get selected item */
1512 i = SendMessageW(This->hWndList, LVM_GETNEXTITEM, -1, MAKELPARAM (LVNI_SELECTED, 0));
1514 SendMessageW(This->hWndList, LVM_ENSUREVISIBLE, i, 0);
1515 SendMessageW(This->hWndList, LVM_EDITLABELW, i, 0);
1518 #if 0
1519 TranslateAccelerator(This->hWnd, This->hAccel, &msg)
1520 #endif
1521 else if(plvKeyDown->wVKey == VK_DELETE)
1523 UINT i;
1524 int item_index;
1525 LVITEMA item;
1526 LPITEMIDLIST* pItems;
1527 ISFHelper *psfhlp;
1529 IShellFolder_QueryInterface(This->pSFParent, &IID_ISFHelper,
1530 (LPVOID*)&psfhlp);
1532 if (psfhlp == NULL)
1533 break;
1535 if(!(i = SendMessageW(This->hWndList, LVM_GETSELECTEDCOUNT, 0, 0)))
1536 break;
1538 /* allocate memory for the pidl array */
1539 pItems = HeapAlloc(GetProcessHeap(), 0,
1540 sizeof(LPITEMIDLIST) * i);
1542 /* retrieve all selected items */
1543 i = 0;
1544 item_index = -1;
1545 while(SendMessageW(This->hWndList, LVM_GETSELECTEDCOUNT, 0, 0) > i)
1547 /* get selected item */
1548 item_index = SendMessageW(This->hWndList, LVM_GETNEXTITEM, item_index,
1549 MAKELPARAM (LVNI_SELECTED, 0));
1550 item.iItem = item_index;
1551 item.mask = LVIF_PARAM;
1552 SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM) &item);
1554 /* get item pidl */
1555 pItems[i] = (LPITEMIDLIST)item.lParam;
1557 i++;
1560 /* perform the item deletion */
1561 ISFHelper_DeleteItems(psfhlp, i, (LPCITEMIDLIST*)pItems);
1563 /* free pidl array memory */
1564 HeapFree(GetProcessHeap(), 0, pItems);
1567 /* Initiate a refresh */
1568 else if(plvKeyDown->wVKey == VK_F5)
1570 IShellView_Refresh((IShellView*)This);
1573 else if(plvKeyDown->wVKey == VK_BACK)
1575 LPSHELLBROWSER lpSb;
1576 if((lpSb = (LPSHELLBROWSER)SendMessageW(This->hWndParent, CWM_GETISHELLBROWSER, 0, 0)))
1578 IShellBrowser_BrowseObject(lpSb, NULL, SBSP_PARENT);
1582 else
1583 FIXME("LVN_KEYDOWN key=0x%08x\n",plvKeyDown->wVKey);
1585 break;
1587 default:
1588 TRACE("-- %p WM_COMMAND %x unhandled\n", This, lpnmh->code);
1589 break;
1591 return 0;
1594 /**********************************************************
1595 * ShellView_OnChange()
1598 static LRESULT ShellView_OnChange(IShellViewImpl * This, const LPCITEMIDLIST *pidls, LONG event)
1600 BOOL ret = TRUE;
1602 TRACE("(%p)->(%p, %p, 0x%08x)\n", This, pidls[0], pidls[1], event);
1604 switch (event)
1606 case SHCNE_MKDIR:
1607 case SHCNE_CREATE:
1608 LV_AddItem(This, pidls[0]);
1609 break;
1610 case SHCNE_RMDIR:
1611 case SHCNE_DELETE:
1613 INT i = LV_FindItemByPidl(This, ILFindLastID(pidls[0]));
1614 ret = SendMessageW(This->hWndList, LVM_DELETEITEM, i, 0);
1615 break;
1617 case SHCNE_RENAMEFOLDER:
1618 case SHCNE_RENAMEITEM:
1619 LV_RenameItem(This, pidls[0], pidls[1]);
1620 break;
1621 case SHCNE_UPDATEITEM:
1622 break;
1624 return ret;
1626 /**********************************************************
1627 * ShellView_WndProc
1630 static LRESULT CALLBACK ShellView_WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
1632 IShellViewImpl * pThis = (IShellViewImpl*)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
1633 LPCREATESTRUCTW lpcs;
1635 TRACE("(hwnd=%p msg=%x wparm=%lx lparm=%lx)\n",hWnd, uMessage, wParam, lParam);
1637 switch (uMessage)
1639 case WM_NCCREATE:
1640 lpcs = (LPCREATESTRUCTW)lParam;
1641 pThis = lpcs->lpCreateParams;
1642 SetWindowLongPtrW(hWnd, GWLP_USERDATA, (ULONG_PTR)pThis);
1643 pThis->hWnd = hWnd; /*set the window handle*/
1644 break;
1646 case WM_SIZE: return ShellView_OnSize(pThis,LOWORD(lParam), HIWORD(lParam));
1647 case WM_SETFOCUS: return ShellView_OnSetFocus(pThis);
1648 case WM_KILLFOCUS: return ShellView_OnKillFocus(pThis);
1649 case WM_CREATE: return ShellView_OnCreate(pThis);
1650 case WM_ACTIVATE: return ShellView_OnActivate(pThis, SVUIA_ACTIVATE_FOCUS);
1651 case WM_NOTIFY: return ShellView_OnNotify(pThis,(UINT)wParam, (LPNMHDR)lParam);
1652 case WM_COMMAND: return ShellView_OnCommand(pThis,
1653 GET_WM_COMMAND_ID(wParam, lParam),
1654 GET_WM_COMMAND_CMD(wParam, lParam),
1655 GET_WM_COMMAND_HWND(wParam, lParam));
1656 case SHV_CHANGE_NOTIFY: return ShellView_OnChange(pThis, (const LPCITEMIDLIST*)wParam, (LONG)lParam);
1658 case WM_CONTEXTMENU: ShellView_DoContextMenu(pThis, LOWORD(lParam), HIWORD(lParam), FALSE);
1659 return 0;
1661 case WM_SHOWWINDOW: UpdateWindow(pThis->hWndList);
1662 break;
1664 case WM_GETDLGCODE: return SendMessageW(pThis->hWndList, uMessage, 0, 0);
1666 case WM_DESTROY:
1667 RevokeDragDrop(pThis->hWnd);
1668 SHChangeNotifyDeregister(pThis->hNotify);
1669 break;
1671 case WM_ERASEBKGND:
1672 if ((pThis->FolderSettings.fFlags & FWF_DESKTOP) ||
1673 (pThis->FolderSettings.fFlags & FWF_TRANSPARENT))
1674 return 1;
1675 break;
1678 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
1680 /**********************************************************
1683 * The INTERFACE of the IShellView object
1686 **********************************************************
1687 * IShellView_QueryInterface
1689 static HRESULT WINAPI IShellView_fnQueryInterface(IShellView2 * iface,REFIID riid, LPVOID *ppvObj)
1691 IShellViewImpl *This = (IShellViewImpl *)iface;
1693 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1695 *ppvObj = NULL;
1697 if(IsEqualIID(riid, &IID_IUnknown))
1699 *ppvObj = This;
1701 else if(IsEqualIID(riid, &IID_IShellView))
1703 *ppvObj = This;
1705 else if(IsEqualIID(riid, &IID_IShellView2))
1707 *ppvObj = This;
1709 else if(IsEqualIID(riid, &IID_IShellFolderView))
1711 *ppvObj = &This->lpvtblShellFolderView;
1713 else if(IsEqualIID(riid, &IID_IFolderView))
1715 *ppvObj = &This->lpvtblFolderView;
1717 else if(IsEqualIID(riid, &IID_IOleCommandTarget))
1719 *ppvObj = &This->lpvtblOleCommandTarget;
1721 else if(IsEqualIID(riid, &IID_IDropTarget))
1723 *ppvObj = &This->lpvtblDropTarget;
1725 else if(IsEqualIID(riid, &IID_IDropSource))
1727 *ppvObj = &This->lpvtblDropSource;
1729 else if(IsEqualIID(riid, &IID_IViewObject))
1731 *ppvObj = &This->lpvtblViewObject;
1734 if(*ppvObj)
1736 IUnknown_AddRef( (IUnknown*)*ppvObj );
1737 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1738 return S_OK;
1740 TRACE("-- Interface: E_NOINTERFACE\n");
1741 return E_NOINTERFACE;
1744 /**********************************************************
1745 * IShellView_AddRef
1747 static ULONG WINAPI IShellView_fnAddRef(IShellView2 * iface)
1749 IShellViewImpl *This = (IShellViewImpl *)iface;
1750 ULONG refCount = InterlockedIncrement(&This->ref);
1752 TRACE("(%p)->(count=%u)\n", This, refCount - 1);
1754 return refCount;
1756 /**********************************************************
1757 * IShellView_Release
1759 static ULONG WINAPI IShellView_fnRelease(IShellView2 * iface)
1761 IShellViewImpl *This = (IShellViewImpl *)iface;
1762 ULONG refCount = InterlockedDecrement(&This->ref);
1764 TRACE("(%p)->(count=%i)\n", This, refCount + 1);
1766 if (!refCount)
1768 TRACE(" destroying IShellView(%p)\n",This);
1770 DestroyWindow(This->hWndList);
1772 if(This->pSFParent)
1773 IShellFolder_Release(This->pSFParent);
1775 if(This->pSF2Parent)
1776 IShellFolder2_Release(This->pSF2Parent);
1778 SHFree(This->apidl);
1780 if(This->pAdvSink)
1781 IAdviseSink_Release(This->pAdvSink);
1783 HeapFree(GetProcessHeap(),0,This);
1785 return refCount;
1788 /**********************************************************
1789 * ShellView_GetWindow
1791 static HRESULT WINAPI IShellView_fnGetWindow(IShellView2 * iface,HWND * phWnd)
1793 IShellViewImpl *This = (IShellViewImpl *)iface;
1795 TRACE("(%p)\n",This);
1797 *phWnd = This->hWnd;
1799 return S_OK;
1802 static HRESULT WINAPI IShellView_fnContextSensitiveHelp(IShellView2 *iface, BOOL mode)
1804 IShellViewImpl *This = (IShellViewImpl *)iface;
1805 TRACE("(%p)->(%d)\n", This, mode);
1806 return E_NOTIMPL;
1809 /**********************************************************
1810 * IShellView_TranslateAccelerator
1812 * FIXME:
1813 * use the accel functions
1815 static HRESULT WINAPI IShellView_fnTranslateAccelerator(IShellView2 * iface,LPMSG lpmsg)
1817 #if 0
1818 IShellViewImpl *This = (IShellViewImpl *)iface;
1820 FIXME("(%p)->(%p: hwnd=%x msg=%x lp=%x wp=%x) stub\n",This,lpmsg, lpmsg->hwnd, lpmsg->message, lpmsg->lParam, lpmsg->wParam);
1821 #endif
1823 if ((lpmsg->message>=WM_KEYFIRST) && (lpmsg->message>=WM_KEYLAST))
1825 TRACE("-- key=0x04%lx\n",lpmsg->wParam) ;
1827 return S_FALSE; /* not handled */
1830 static HRESULT WINAPI IShellView_fnEnableModeless(IShellView2 * iface,BOOL fEnable)
1832 IShellViewImpl *This = (IShellViewImpl *)iface;
1834 FIXME("(%p) stub\n",This);
1836 return E_NOTIMPL;
1839 static HRESULT WINAPI IShellView_fnUIActivate(IShellView2 * iface,UINT uState)
1841 IShellViewImpl *This = (IShellViewImpl *)iface;
1844 CHAR szName[MAX_PATH];
1846 LRESULT lResult;
1847 int nPartArray[1] = {-1};
1849 TRACE("(%p)->(state=%x) stub\n",This, uState);
1851 /*don't do anything if the state isn't really changing*/
1852 if(This->uState == uState)
1854 return S_OK;
1857 /*OnActivate handles the menu merging and internal state*/
1858 ShellView_OnActivate(This, uState);
1860 /*only do This if we are active*/
1861 if(uState != SVUIA_DEACTIVATE)
1865 GetFolderPath is not a method of IShellFolder
1866 IShellFolder_GetFolderPath( This->pSFParent, szName, sizeof(szName) );
1868 /* set the number of parts */
1869 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETPARTS, 1,
1870 (LPARAM)nPartArray, &lResult);
1872 /* set the text for the parts */
1874 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETTEXTA,
1875 0, (LPARAM)szName, &lResult);
1879 return S_OK;
1882 static HRESULT WINAPI IShellView_fnRefresh(IShellView2 * iface)
1884 IShellViewImpl *This = (IShellViewImpl *)iface;
1886 TRACE("(%p)\n", This);
1888 SendMessageW(This->hWndList, LVM_DELETEALLITEMS, 0, 0);
1889 ShellView_FillList(This);
1891 return S_OK;
1894 static HRESULT WINAPI IShellView_fnCreateViewWindow(IShellView2 *iface, IShellView *lpPrevView,
1895 LPCFOLDERSETTINGS lpfs, IShellBrowser *psb, RECT *prcView, HWND *phWnd)
1897 HRESULT hr;
1898 SV2CVW2_PARAMS view_params;
1899 view_params.cbSize = sizeof(view_params);
1900 view_params.psvPrev = lpPrevView;
1901 view_params.pfs = lpfs;
1902 view_params.psbOwner = psb;
1903 view_params.prcView = prcView;
1904 view_params.pvid = NULL;
1905 view_params.hwndView = 0;
1907 TRACE("(%p) Forwarding to CreateViewWindow2\n", iface);
1909 hr = IShellView2_CreateViewWindow2(iface, &view_params);
1910 *phWnd = view_params.hwndView;
1912 return hr;
1915 static HRESULT WINAPI IShellView_fnDestroyViewWindow(IShellView2 * iface)
1917 IShellViewImpl *This = (IShellViewImpl *)iface;
1919 TRACE("(%p)\n",This);
1921 /*Make absolutely sure all our UI is cleaned up.*/
1922 IShellView_UIActivate((IShellView*)This, SVUIA_DEACTIVATE);
1924 if(This->hMenu)
1926 DestroyMenu(This->hMenu);
1929 DestroyWindow(This->hWnd);
1930 if(This->pShellBrowser) IShellBrowser_Release(This->pShellBrowser);
1931 if(This->pCommDlgBrowser) ICommDlgBrowser_Release(This->pCommDlgBrowser);
1934 return S_OK;
1937 static HRESULT WINAPI IShellView_fnGetCurrentInfo(IShellView2 * iface, LPFOLDERSETTINGS lpfs)
1939 IShellViewImpl *This = (IShellViewImpl *)iface;
1941 TRACE("(%p)->(%p) vmode=%x flags=%x\n",This, lpfs,
1942 This->FolderSettings.ViewMode, This->FolderSettings.fFlags);
1944 if (!lpfs) return E_INVALIDARG;
1946 *lpfs = This->FolderSettings;
1947 return NOERROR;
1950 static HRESULT WINAPI IShellView_fnAddPropertySheetPages(IShellView2 * iface, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam)
1952 IShellViewImpl *This = (IShellViewImpl *)iface;
1954 FIXME("(%p) stub\n",This);
1956 return E_NOTIMPL;
1959 static HRESULT WINAPI IShellView_fnSaveViewState(IShellView2 * iface)
1961 IShellViewImpl *This = (IShellViewImpl *)iface;
1963 FIXME("(%p) stub\n",This);
1965 return S_OK;
1968 static HRESULT WINAPI IShellView_fnSelectItem(
1969 IShellView2 * iface,
1970 LPCITEMIDLIST pidl,
1971 UINT flags)
1973 IShellViewImpl *This = (IShellViewImpl *)iface;
1974 IFolderView *view = (IFolderView*)&This->lpvtblFolderView;
1975 int i;
1977 TRACE("(%p)->(pidl=%p, 0x%08x)\n",This, pidl, flags);
1979 i = LV_FindItemByPidl(This, pidl);
1980 if (i == -1) return S_OK;
1982 return IFolderView_SelectItem(view, i, flags);
1985 static HRESULT WINAPI IShellView_fnGetItemObject(IShellView2 * iface, UINT uItem, REFIID riid, LPVOID *ppvOut)
1987 IShellViewImpl *This = (IShellViewImpl *)iface;
1988 HRESULT hr = E_NOINTERFACE;
1990 TRACE("(%p)->(0x%08x, %s, %p)\n",This, uItem, debugstr_guid(riid), ppvOut);
1992 *ppvOut = NULL;
1994 switch(uItem)
1996 case SVGIO_BACKGROUND:
1998 if (IsEqualIID(&IID_IContextMenu, riid))
2000 *ppvOut = ISvBgCm_Constructor(This->pSFParent, FALSE);
2001 hr = S_OK;
2003 else
2004 FIXME("unsupported interface requested %s\n", debugstr_guid(riid));
2006 break;
2008 case SVGIO_SELECTION:
2009 ShellView_GetSelections(This);
2010 hr = IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, (LPCITEMIDLIST*)This->apidl, riid, 0, ppvOut);
2011 break;
2013 default:
2014 FIXME("unimplemented for uItem = 0x%08x\n", uItem);
2016 TRACE("-- (%p)->(interface=%p)\n",This, *ppvOut);
2018 return hr;
2021 static HRESULT WINAPI IShellView2_fnGetView(IShellView2* iface, SHELLVIEWID *view_guid, ULONG view_type)
2023 FIXME("(%p)->(view_guid %s, view_type %#x) stub!\n", iface, debugstr_guid(view_guid), view_type);
2024 return E_NOTIMPL;
2027 static HRESULT WINAPI IShellView2_fnCreateViewWindow2(IShellView2* iface, LPSV2CVW2_PARAMS view_params)
2029 IShellViewImpl *This = (IShellViewImpl *)iface;
2030 WNDCLASSW wc;
2031 HRESULT hr;
2032 HWND wnd;
2034 TRACE("(%p)->(view_params %p)\n", iface, view_params);
2036 if (view_params->cbSize != sizeof(*view_params))
2038 FIXME("Got unexpected cbSize %#x\n", view_params->cbSize);
2039 return E_FAIL;
2042 TRACE("-- psvPrev %p, pfs %p, psbOwner %p, prcView %p\n",
2043 view_params->psvPrev, view_params->pfs, view_params->psbOwner, view_params->prcView);
2044 TRACE("-- vmode %#x, flags %#x, left %d, top %d, right %d, bottom %d\n",
2045 view_params->pfs->ViewMode, view_params->pfs->fFlags, view_params->prcView->left,
2046 view_params->prcView->top, view_params->prcView->right, view_params->prcView->bottom);
2048 if (!view_params->psbOwner) return E_UNEXPECTED;
2050 /* Set up the member variables */
2051 This->pShellBrowser = view_params->psbOwner;
2052 This->FolderSettings = *view_params->pfs;
2054 if (view_params->pvid)
2056 if (IsEqualGUID(view_params->pvid, &VID_LargeIcons))
2057 This->FolderSettings.ViewMode = FVM_ICON;
2058 else if (IsEqualGUID(view_params->pvid, &VID_SmallIcons))
2059 This->FolderSettings.ViewMode = FVM_SMALLICON;
2060 else if (IsEqualGUID(view_params->pvid, &VID_List))
2061 This->FolderSettings.ViewMode = FVM_LIST;
2062 else if (IsEqualGUID(view_params->pvid, &VID_Details))
2063 This->FolderSettings.ViewMode = FVM_DETAILS;
2064 else if (IsEqualGUID(view_params->pvid, &VID_Thumbnails))
2065 This->FolderSettings.ViewMode = FVM_THUMBNAIL;
2066 else if (IsEqualGUID(view_params->pvid, &VID_Tile))
2067 This->FolderSettings.ViewMode = FVM_TILE;
2068 else if (IsEqualGUID(view_params->pvid, &VID_ThumbStrip))
2069 This->FolderSettings.ViewMode = FVM_THUMBSTRIP;
2070 else
2071 FIXME("Ignoring unrecognized VID %s\n", debugstr_guid(view_params->pvid));
2074 /* Get our parent window */
2075 IShellBrowser_AddRef(This->pShellBrowser);
2076 IShellBrowser_GetWindow(This->pShellBrowser, &This->hWndParent);
2078 /* Try to get the ICommDlgBrowserInterface, adds a reference !!! */
2079 This->pCommDlgBrowser = NULL;
2080 hr = IShellBrowser_QueryInterface(This->pShellBrowser, &IID_ICommDlgBrowser, (void **)&This->pCommDlgBrowser);
2081 if (hr == S_OK)
2082 TRACE("-- CommDlgBrowser %p\n", This->pCommDlgBrowser);
2084 /* If our window class has not been registered, then do so */
2085 if (!GetClassInfoW(shell32_hInstance, SV_CLASS_NAME, &wc))
2087 wc.style = CS_HREDRAW | CS_VREDRAW;
2088 wc.lpfnWndProc = ShellView_WndProc;
2089 wc.cbClsExtra = 0;
2090 wc.cbWndExtra = 0;
2091 wc.hInstance = shell32_hInstance;
2092 wc.hIcon = 0;
2093 wc.hCursor = LoadCursorW(0, (LPWSTR)IDC_ARROW);
2094 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
2095 wc.lpszMenuName = NULL;
2096 wc.lpszClassName = SV_CLASS_NAME;
2098 if (!RegisterClassW(&wc)) return E_FAIL;
2101 wnd = CreateWindowExW(0, SV_CLASS_NAME, NULL, WS_CHILD | WS_TABSTOP,
2102 view_params->prcView->left, view_params->prcView->top,
2103 view_params->prcView->right - view_params->prcView->left,
2104 view_params->prcView->bottom - view_params->prcView->top,
2105 This->hWndParent, 0, shell32_hInstance, This);
2107 CheckToolbar(This);
2109 if (!wnd)
2111 IShellBrowser_Release(This->pShellBrowser);
2112 return E_FAIL;
2115 SetWindowPos(wnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
2116 UpdateWindow(wnd);
2118 view_params->hwndView = wnd;
2120 return S_OK;
2123 static HRESULT WINAPI IShellView2_fnHandleRename(IShellView2* iface, LPCITEMIDLIST new_pidl)
2125 FIXME("(%p)->(new_pidl %p) stub!\n", iface, new_pidl);
2126 return E_NOTIMPL;
2129 static HRESULT WINAPI IShellView2_fnSelectAndPositionItem(
2130 IShellView2* iface,
2131 LPCITEMIDLIST item,
2132 UINT flags,
2133 POINT *point)
2135 IShellViewImpl *This = (IShellViewImpl *)iface;
2136 IFolderView *view;
2137 HRESULT hr;
2139 TRACE("(%p)->(item %p, flags %#x, point %p)\n", This, item, flags, point);
2141 hr = IShellView2_QueryInterface(iface, &IID_IFolderView, (void**)&view);
2142 if (hr == S_OK)
2144 hr = IFolderView_SelectAndPositionItems(view, 1, &item, point, flags);
2145 IFolderView_Release(view);
2148 return hr;
2151 static const IShellView2Vtbl svvt =
2153 IShellView_fnQueryInterface,
2154 IShellView_fnAddRef,
2155 IShellView_fnRelease,
2156 IShellView_fnGetWindow,
2157 IShellView_fnContextSensitiveHelp,
2158 IShellView_fnTranslateAccelerator,
2159 IShellView_fnEnableModeless,
2160 IShellView_fnUIActivate,
2161 IShellView_fnRefresh,
2162 IShellView_fnCreateViewWindow,
2163 IShellView_fnDestroyViewWindow,
2164 IShellView_fnGetCurrentInfo,
2165 IShellView_fnAddPropertySheetPages,
2166 IShellView_fnSaveViewState,
2167 IShellView_fnSelectItem,
2168 IShellView_fnGetItemObject,
2169 IShellView2_fnGetView,
2170 IShellView2_fnCreateViewWindow2,
2171 IShellView2_fnHandleRename,
2172 IShellView2_fnSelectAndPositionItem,
2176 /**********************************************************
2177 * ISVOleCmdTarget_QueryInterface (IUnknown)
2179 static HRESULT WINAPI ISVOleCmdTarget_QueryInterface(
2180 IOleCommandTarget * iface,
2181 REFIID iid,
2182 LPVOID* ppvObj)
2184 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2186 return IShellView2_QueryInterface((IShellView2*)This, iid, ppvObj);
2189 /**********************************************************
2190 * ISVOleCmdTarget_AddRef (IUnknown)
2192 static ULONG WINAPI ISVOleCmdTarget_AddRef(
2193 IOleCommandTarget * iface)
2195 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2197 return IShellView2_AddRef((IShellView2*)This);
2200 /**********************************************************
2201 * ISVOleCmdTarget_Release (IUnknown)
2203 static ULONG WINAPI ISVOleCmdTarget_Release(
2204 IOleCommandTarget * iface)
2206 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2208 return IShellView2_Release((IShellView2*)This);
2211 /**********************************************************
2212 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2214 static HRESULT WINAPI ISVOleCmdTarget_QueryStatus(
2215 IOleCommandTarget *iface,
2216 const GUID *pguidCmdGroup,
2217 ULONG cCmds,
2218 OLECMD *prgCmds,
2219 OLECMDTEXT *pCmdText)
2221 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2222 UINT i;
2224 FIXME("(%p)->(%s %d %p %p)\n",
2225 This, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText);
2227 if (!prgCmds)
2228 return E_POINTER;
2229 for (i = 0; i < cCmds; i++)
2231 FIXME("\tprgCmds[%d].cmdID = %d\n", i, prgCmds[i].cmdID);
2232 prgCmds[i].cmdf = 0;
2234 return OLECMDERR_E_UNKNOWNGROUP;
2237 /**********************************************************
2238 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2240 * nCmdID is the OLECMDID_* enumeration
2242 static HRESULT WINAPI ISVOleCmdTarget_Exec(
2243 IOleCommandTarget *iface,
2244 const GUID* pguidCmdGroup,
2245 DWORD nCmdID,
2246 DWORD nCmdexecopt,
2247 VARIANT* pvaIn,
2248 VARIANT* pvaOut)
2250 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2252 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2253 This, debugstr_guid(pguidCmdGroup), nCmdID, nCmdexecopt, pvaIn, pvaOut);
2255 if (IsEqualIID(pguidCmdGroup, &CGID_Explorer) &&
2256 (nCmdID == 0x29) &&
2257 (nCmdexecopt == 4) && pvaOut)
2258 return S_OK;
2259 if (IsEqualIID(pguidCmdGroup, &CGID_ShellDocView) &&
2260 (nCmdID == 9) &&
2261 (nCmdexecopt == 0))
2262 return 1;
2264 return OLECMDERR_E_UNKNOWNGROUP;
2267 static const IOleCommandTargetVtbl ctvt =
2269 ISVOleCmdTarget_QueryInterface,
2270 ISVOleCmdTarget_AddRef,
2271 ISVOleCmdTarget_Release,
2272 ISVOleCmdTarget_QueryStatus,
2273 ISVOleCmdTarget_Exec
2276 /**********************************************************
2277 * ISVDropTarget implementation
2280 static HRESULT WINAPI ISVDropTarget_QueryInterface(
2281 IDropTarget *iface,
2282 REFIID riid,
2283 LPVOID *ppvObj)
2285 IShellViewImpl *This = impl_from_IDropTarget(iface);
2287 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2289 return IShellView2_QueryInterface((IShellView2*)This, riid, ppvObj);
2292 static ULONG WINAPI ISVDropTarget_AddRef( IDropTarget *iface)
2294 IShellViewImpl *This = impl_from_IDropTarget(iface);
2296 TRACE("(%p)->(count=%u)\n",This,This->ref);
2298 return IShellView2_AddRef((IShellView2*)This);
2301 static ULONG WINAPI ISVDropTarget_Release( IDropTarget *iface)
2303 IShellViewImpl *This = impl_from_IDropTarget(iface);
2305 TRACE("(%p)->(count=%u)\n",This,This->ref);
2307 return IShellView2_Release((IShellView2*)This);
2310 /******************************************************************************
2311 * drag_notify_subitem [Internal]
2313 * Figure out the shellfolder object, which is currently under the mouse cursor
2314 * and notify it via the IDropTarget interface.
2317 #define SCROLLAREAWIDTH 20
2319 static HRESULT drag_notify_subitem(IShellViewImpl *This, DWORD grfKeyState, POINTL pt,
2320 DWORD *pdwEffect)
2322 LVHITTESTINFO htinfo;
2323 LVITEMW lvItem;
2324 LONG lResult;
2325 HRESULT hr;
2326 RECT clientRect;
2328 /* Map from global to client coordinates and query the index of the listview-item, which is
2329 * currently under the mouse cursor. */
2330 htinfo.pt.x = pt.x;
2331 htinfo.pt.y = pt.y;
2332 htinfo.flags = LVHT_ONITEM;
2333 ScreenToClient(This->hWndList, &htinfo.pt);
2334 lResult = SendMessageW(This->hWndList, LVM_HITTEST, 0, (LPARAM)&htinfo);
2336 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2337 GetClientRect(This->hWndList, &clientRect);
2338 if (htinfo.pt.x == This->ptLastMousePos.x && htinfo.pt.y == This->ptLastMousePos.y &&
2339 (htinfo.pt.x < SCROLLAREAWIDTH || htinfo.pt.x > clientRect.right - SCROLLAREAWIDTH ||
2340 htinfo.pt.y < SCROLLAREAWIDTH || htinfo.pt.y > clientRect.bottom - SCROLLAREAWIDTH ))
2342 This->cScrollDelay = (This->cScrollDelay + 1) % 5; /* DragOver is called every 50 ms */
2343 if (This->cScrollDelay == 0) { /* Mouse did hover another 250 ms over the scroll-area */
2344 if (htinfo.pt.x < SCROLLAREAWIDTH)
2345 SendMessageW(This->hWndList, WM_HSCROLL, SB_LINEUP, 0);
2346 if (htinfo.pt.x > clientRect.right - SCROLLAREAWIDTH)
2347 SendMessageW(This->hWndList, WM_HSCROLL, SB_LINEDOWN, 0);
2348 if (htinfo.pt.y < SCROLLAREAWIDTH)
2349 SendMessageW(This->hWndList, WM_VSCROLL, SB_LINEUP, 0);
2350 if (htinfo.pt.y > clientRect.bottom - SCROLLAREAWIDTH)
2351 SendMessageW(This->hWndList, WM_VSCROLL, SB_LINEDOWN, 0);
2353 } else {
2354 This->cScrollDelay = 0; /* Reset, if the cursor is not over the listview's scroll-area */
2356 This->ptLastMousePos = htinfo.pt;
2358 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2359 if (This->pCurDropTarget && lResult == This->iDragOverItem)
2360 return IDropTarget_DragOver(This->pCurDropTarget, grfKeyState, pt, pdwEffect);
2362 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2363 if (This->pCurDropTarget) {
2364 IDropTarget_DragLeave(This->pCurDropTarget);
2365 IDropTarget_Release(This->pCurDropTarget);
2366 This->pCurDropTarget = NULL;
2369 This->iDragOverItem = lResult;
2370 if (lResult == -1) {
2371 /* We are not above one of the listview's subitems. Bind to the parent folder's
2372 * DropTarget interface. */
2373 hr = IShellFolder_QueryInterface(This->pSFParent, &IID_IDropTarget,
2374 (LPVOID*)&This->pCurDropTarget);
2375 } else {
2376 /* Query the relative PIDL of the shellfolder object represented by the currently
2377 * dragged over listview-item ... */
2378 lvItem.mask = LVIF_PARAM;
2379 lvItem.iItem = lResult;
2380 lvItem.iSubItem = 0;
2381 SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem);
2383 /* ... and bind pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2384 hr = IShellFolder_GetUIObjectOf(This->pSFParent, This->hWndList, 1,
2385 (LPCITEMIDLIST*)&lvItem.lParam, &IID_IDropTarget, NULL, (LPVOID*)&This->pCurDropTarget);
2388 /* If anything failed, pCurDropTarget should be NULL now, which ought to be a save state. */
2389 if (FAILED(hr))
2390 return hr;
2392 /* Notify the item just entered via DragEnter. */
2393 return IDropTarget_DragEnter(This->pCurDropTarget, This->pCurDataObject, grfKeyState, pt, pdwEffect);
2396 static HRESULT WINAPI ISVDropTarget_DragEnter(IDropTarget *iface, IDataObject *pDataObject,
2397 DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
2399 IShellViewImpl *This = impl_from_IDropTarget(iface);
2401 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2402 This->pCurDataObject = pDataObject;
2403 IDataObject_AddRef(pDataObject);
2405 return drag_notify_subitem(This, grfKeyState, pt, pdwEffect);
2408 static HRESULT WINAPI ISVDropTarget_DragOver(IDropTarget *iface, DWORD grfKeyState, POINTL pt,
2409 DWORD *pdwEffect)
2411 IShellViewImpl *This = impl_from_IDropTarget(iface);
2412 return drag_notify_subitem(This, grfKeyState, pt, pdwEffect);
2415 static HRESULT WINAPI ISVDropTarget_DragLeave(IDropTarget *iface)
2417 IShellViewImpl *This = impl_from_IDropTarget(iface);
2419 if (This->pCurDropTarget)
2421 IDropTarget_DragLeave(This->pCurDropTarget);
2422 IDropTarget_Release(This->pCurDropTarget);
2423 This->pCurDropTarget = NULL;
2426 if (This->pCurDataObject)
2428 IDataObject_Release(This->pCurDataObject);
2429 This->pCurDataObject = NULL;
2432 This->iDragOverItem = 0;
2434 return S_OK;
2437 static HRESULT WINAPI ISVDropTarget_Drop(IDropTarget *iface, IDataObject* pDataObject,
2438 DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
2440 IShellViewImpl *This = impl_from_IDropTarget(iface);
2442 IDropTarget_Drop(This->pCurDropTarget, pDataObject, grfKeyState, pt, pdwEffect);
2444 IDropTarget_Release(This->pCurDropTarget);
2445 IDataObject_Release(This->pCurDataObject);
2446 This->pCurDataObject = NULL;
2447 This->pCurDropTarget = NULL;
2448 This->iDragOverItem = 0;
2450 return S_OK;
2453 static const IDropTargetVtbl dtvt =
2455 ISVDropTarget_QueryInterface,
2456 ISVDropTarget_AddRef,
2457 ISVDropTarget_Release,
2458 ISVDropTarget_DragEnter,
2459 ISVDropTarget_DragOver,
2460 ISVDropTarget_DragLeave,
2461 ISVDropTarget_Drop
2464 /**********************************************************
2465 * ISVDropSource implementation
2468 static HRESULT WINAPI ISVDropSource_QueryInterface(
2469 IDropSource *iface,
2470 REFIID riid,
2471 LPVOID *ppvObj)
2473 IShellViewImpl *This = impl_from_IDropSource(iface);
2475 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2477 return IShellView2_QueryInterface((IShellView2*)This, riid, ppvObj);
2480 static ULONG WINAPI ISVDropSource_AddRef( IDropSource *iface)
2482 IShellViewImpl *This = impl_from_IDropSource(iface);
2484 TRACE("(%p)->(count=%u)\n",This,This->ref);
2486 return IShellView2_AddRef((IShellView2*)This);
2489 static ULONG WINAPI ISVDropSource_Release( IDropSource *iface)
2491 IShellViewImpl *This = impl_from_IDropSource(iface);
2493 TRACE("(%p)->(count=%u)\n",This,This->ref);
2495 return IShellView2_Release((IShellView2*)This);
2498 static HRESULT WINAPI ISVDropSource_QueryContinueDrag(
2499 IDropSource *iface,
2500 BOOL fEscapePressed,
2501 DWORD grfKeyState)
2503 IShellViewImpl *This = impl_from_IDropSource(iface);
2504 TRACE("(%p)\n",This);
2506 if (fEscapePressed)
2507 return DRAGDROP_S_CANCEL;
2508 else if (!(grfKeyState & MK_LBUTTON) && !(grfKeyState & MK_RBUTTON))
2509 return DRAGDROP_S_DROP;
2510 else
2511 return NOERROR;
2514 static HRESULT WINAPI ISVDropSource_GiveFeedback(
2515 IDropSource *iface,
2516 DWORD dwEffect)
2518 IShellViewImpl *This = impl_from_IDropSource(iface);
2519 TRACE("(%p)\n",This);
2521 return DRAGDROP_S_USEDEFAULTCURSORS;
2524 static const IDropSourceVtbl dsvt =
2526 ISVDropSource_QueryInterface,
2527 ISVDropSource_AddRef,
2528 ISVDropSource_Release,
2529 ISVDropSource_QueryContinueDrag,
2530 ISVDropSource_GiveFeedback
2532 /**********************************************************
2533 * ISVViewObject implementation
2536 static HRESULT WINAPI ISVViewObject_QueryInterface(
2537 IViewObject *iface,
2538 REFIID riid,
2539 LPVOID *ppvObj)
2541 IShellViewImpl *This = impl_from_IViewObject(iface);
2543 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2545 return IShellView2_QueryInterface((IShellView2*)This, riid, ppvObj);
2548 static ULONG WINAPI ISVViewObject_AddRef( IViewObject *iface)
2550 IShellViewImpl *This = impl_from_IViewObject(iface);
2552 TRACE("(%p)->(count=%u)\n",This,This->ref);
2554 return IShellView2_AddRef((IShellView2*)This);
2557 static ULONG WINAPI ISVViewObject_Release( IViewObject *iface)
2559 IShellViewImpl *This = impl_from_IViewObject(iface);
2561 TRACE("(%p)->(count=%u)\n",This,This->ref);
2563 return IShellView2_Release((IShellView2*)This);
2566 static HRESULT WINAPI ISVViewObject_Draw(
2567 IViewObject *iface,
2568 DWORD dwDrawAspect,
2569 LONG lindex,
2570 void* pvAspect,
2571 DVTARGETDEVICE* ptd,
2572 HDC hdcTargetDev,
2573 HDC hdcDraw,
2574 LPCRECTL lprcBounds,
2575 LPCRECTL lprcWBounds,
2576 BOOL (CALLBACK *pfnContinue)(ULONG_PTR dwContinue),
2577 ULONG_PTR dwContinue)
2580 IShellViewImpl *This = impl_from_IViewObject(iface);
2582 FIXME("Stub: This=%p\n",This);
2584 return E_NOTIMPL;
2586 static HRESULT WINAPI ISVViewObject_GetColorSet(
2587 IViewObject *iface,
2588 DWORD dwDrawAspect,
2589 LONG lindex,
2590 void *pvAspect,
2591 DVTARGETDEVICE* ptd,
2592 HDC hicTargetDevice,
2593 LOGPALETTE** ppColorSet)
2596 IShellViewImpl *This = impl_from_IViewObject(iface);
2598 FIXME("Stub: This=%p\n",This);
2600 return E_NOTIMPL;
2602 static HRESULT WINAPI ISVViewObject_Freeze(
2603 IViewObject *iface,
2604 DWORD dwDrawAspect,
2605 LONG lindex,
2606 void* pvAspect,
2607 DWORD* pdwFreeze)
2610 IShellViewImpl *This = impl_from_IViewObject(iface);
2612 FIXME("Stub: This=%p\n",This);
2614 return E_NOTIMPL;
2616 static HRESULT WINAPI ISVViewObject_Unfreeze(
2617 IViewObject *iface,
2618 DWORD dwFreeze)
2621 IShellViewImpl *This = impl_from_IViewObject(iface);
2623 FIXME("Stub: This=%p\n",This);
2625 return E_NOTIMPL;
2627 static HRESULT WINAPI ISVViewObject_SetAdvise(
2628 IViewObject *iface,
2629 DWORD aspects,
2630 DWORD advf,
2631 IAdviseSink* pAdvSink)
2634 IShellViewImpl *This = impl_from_IViewObject(iface);
2636 FIXME("partial stub: %p %08x %08x %p\n",
2637 This, aspects, advf, pAdvSink);
2639 /* FIXME: we set the AdviseSink, but never use it to send any advice */
2640 This->pAdvSink = pAdvSink;
2641 This->dwAspects = aspects;
2642 This->dwAdvf = advf;
2644 return S_OK;
2647 static HRESULT WINAPI ISVViewObject_GetAdvise(
2648 IViewObject *iface,
2649 DWORD* pAspects,
2650 DWORD* pAdvf,
2651 IAdviseSink** ppAdvSink)
2654 IShellViewImpl *This = impl_from_IViewObject(iface);
2656 TRACE("This=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n",
2657 This, pAspects, pAdvf, ppAdvSink);
2659 if( ppAdvSink )
2661 IAdviseSink_AddRef( This->pAdvSink );
2662 *ppAdvSink = This->pAdvSink;
2664 if( pAspects )
2665 *pAspects = This->dwAspects;
2666 if( pAdvf )
2667 *pAdvf = This->dwAdvf;
2669 return S_OK;
2673 static const IViewObjectVtbl vovt =
2675 ISVViewObject_QueryInterface,
2676 ISVViewObject_AddRef,
2677 ISVViewObject_Release,
2678 ISVViewObject_Draw,
2679 ISVViewObject_GetColorSet,
2680 ISVViewObject_Freeze,
2681 ISVViewObject_Unfreeze,
2682 ISVViewObject_SetAdvise,
2683 ISVViewObject_GetAdvise
2686 /* IFolderView */
2687 static HRESULT WINAPI IFView_QueryInterface(
2688 IFolderView *iface,
2689 REFIID riid,
2690 LPVOID *ppvObj)
2692 IShellViewImpl *This = impl_from_IFolderView(iface);
2693 TRACE("(%p)->(IID:%s,%p)\n", This, debugstr_guid(riid), ppvObj);
2694 return IShellView2_QueryInterface((IShellView2*)This, riid, ppvObj);
2697 static ULONG WINAPI IFView_AddRef( IFolderView *iface)
2699 IShellViewImpl *This = impl_from_IFolderView(iface);
2700 TRACE("(%p)->(count=%u)\n", This, This->ref);
2701 return IShellView2_AddRef((IShellView2*)This);
2704 static ULONG WINAPI IFView_Release( IFolderView *iface)
2706 IShellViewImpl *This = impl_from_IFolderView(iface);
2707 TRACE("(%p)->(count=%u)\n", This, This->ref);
2708 return IShellView2_Release((IShellView2*)This);
2711 static HRESULT WINAPI IFView_GetCurrentViewMode(IFolderView *iface, UINT *mode)
2713 IShellViewImpl *This = impl_from_IFolderView(iface);
2714 FIXME("(%p)->(%p), stub\n", This, mode);
2715 return E_NOTIMPL;
2718 static HRESULT WINAPI IFView_SetCurrentViewMode(IFolderView *iface, UINT mode)
2720 IShellViewImpl *This = impl_from_IFolderView(iface);
2721 FIXME("(%p)->(%u), stub\n", This, mode);
2722 return E_NOTIMPL;
2725 static HRESULT WINAPI IFView_GetFolder(IFolderView *iface, REFIID riid, void **ppv)
2727 IShellViewImpl *This = impl_from_IFolderView(iface);
2729 TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv);
2731 if (!ppv) return E_POINTER;
2733 if (IsEqualIID(riid, &IID_IShellFolder))
2735 *ppv = This->pSFParent;
2736 return S_OK;
2739 return E_NOINTERFACE;
2742 static HRESULT WINAPI IFView_Item(IFolderView *iface, int index, PITEMID_CHILD *ppidl)
2744 IShellViewImpl *This = impl_from_IFolderView(iface);
2745 LVITEMW item;
2747 TRACE("(%p)->(%d %p)\n", This, index, ppidl);
2749 item.mask = LVIF_PARAM;
2750 item.iItem = index;
2752 if (SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM)&item))
2754 *ppidl = ILClone((PITEMID_CHILD)item.lParam);
2755 return S_OK;
2757 else
2759 *ppidl = 0;
2760 return E_INVALIDARG;
2764 static HRESULT WINAPI IFView_ItemCount(IFolderView *iface, UINT flags, int *items)
2766 IShellViewImpl *This = impl_from_IFolderView(iface);
2768 TRACE("(%p)->(%u %p)\n", This, flags, items);
2770 if (flags != SVGIO_ALLVIEW)
2771 FIXME("some flags unsupported, %x\n", flags & ~SVGIO_ALLVIEW);
2773 *items = SendMessageW(This->hWndList, LVM_GETITEMCOUNT, 0, 0);
2775 return S_OK;
2778 static HRESULT WINAPI IFView_Items(IFolderView *iface, UINT flags, REFIID riid, void **ppv)
2780 IShellViewImpl *This = impl_from_IFolderView(iface);
2781 FIXME("(%p)->(%u %s %p), stub\n", This, flags, debugstr_guid(riid), ppv);
2782 return E_NOTIMPL;
2785 static HRESULT WINAPI IFView_GetSelectionMarkedItem(IFolderView *iface, int *item)
2787 IShellViewImpl *This = impl_from_IFolderView(iface);
2789 TRACE("(%p)->(%p)\n", This, item);
2791 *item = SendMessageW(This->hWndList, LVM_GETSELECTIONMARK, 0, 0);
2793 return S_OK;
2796 static HRESULT WINAPI IFView_GetFocusedItem(IFolderView *iface, int *item)
2798 IShellViewImpl *This = impl_from_IFolderView(iface);
2800 TRACE("(%p)->(%p)\n", This, item);
2802 *item = SendMessageW(This->hWndList, LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
2804 return S_OK;
2807 static HRESULT WINAPI IFView_GetItemPosition(IFolderView *iface, PCUITEMID_CHILD pidl, POINT *ppt)
2809 IShellViewImpl *This = impl_from_IFolderView(iface);
2810 FIXME("(%p)->(%p %p), stub\n", This, pidl, ppt);
2811 return E_NOTIMPL;
2814 static HRESULT WINAPI IFView_GetSpacing(IFolderView *iface, POINT *pt)
2816 IShellViewImpl *This = impl_from_IFolderView(iface);
2818 TRACE("(%p)->(%p)\n", This, pt);
2820 if (!This->hWndList) return S_FALSE;
2822 if (pt)
2824 DWORD ret;
2825 ret = SendMessageW(This->hWndList, LVM_GETITEMSPACING, 0, 0);
2827 pt->x = LOWORD(ret);
2828 pt->y = HIWORD(ret);
2831 return S_OK;
2834 static HRESULT WINAPI IFView_GetDefaultSpacing(IFolderView *iface, POINT *pt)
2836 IShellViewImpl *This = impl_from_IFolderView(iface);
2837 FIXME("(%p)->(%p), stub\n", This, pt);
2838 return E_NOTIMPL;
2841 static HRESULT WINAPI IFView_GetAutoArrange(IFolderView *iface)
2843 IShellViewImpl *This = impl_from_IFolderView(iface);
2844 FIXME("(%p), stub\n", This);
2845 return E_NOTIMPL;
2848 static HRESULT WINAPI IFView_SelectItem(IFolderView *iface, int item, DWORD flags)
2850 IShellViewImpl *This = impl_from_IFolderView(iface);
2851 LVITEMW lvItem;
2853 TRACE("(%p)->(%d, %x)\n", This, item, flags);
2855 lvItem.state = 0;
2856 lvItem.stateMask = LVIS_SELECTED;
2858 if (flags & SVSI_ENSUREVISIBLE)
2859 SendMessageW(This->hWndList, LVM_ENSUREVISIBLE, item, 0);
2861 /* all items */
2862 if (flags & SVSI_DESELECTOTHERS)
2863 SendMessageW(This->hWndList, LVM_SETITEMSTATE, -1, (LPARAM)&lvItem);
2865 /* this item */
2866 if (flags & SVSI_SELECT)
2867 lvItem.state |= LVIS_SELECTED;
2869 if (flags & SVSI_FOCUSED)
2870 lvItem.stateMask |= LVIS_FOCUSED;
2872 SendMessageW(This->hWndList, LVM_SETITEMSTATE, item, (LPARAM)&lvItem);
2874 if (flags & SVSI_EDIT)
2875 SendMessageW(This->hWndList, LVM_EDITLABELW, item, 0);
2877 return S_OK;
2880 static HRESULT WINAPI IFView_SelectAndPositionItems(IFolderView *iface, UINT cidl,
2881 PCUITEMID_CHILD_ARRAY apidl, POINT *apt, DWORD flags)
2883 IShellViewImpl *This = impl_from_IFolderView(iface);
2884 FIXME("(%p)->(%u %p %p %x), stub\n", This, cidl, apidl, apt, flags);
2885 return E_NOTIMPL;
2888 static const IFolderViewVtbl fviewvt =
2890 IFView_QueryInterface,
2891 IFView_AddRef,
2892 IFView_Release,
2893 IFView_GetCurrentViewMode,
2894 IFView_SetCurrentViewMode,
2895 IFView_GetFolder,
2896 IFView_Item,
2897 IFView_ItemCount,
2898 IFView_Items,
2899 IFView_GetSelectionMarkedItem,
2900 IFView_GetFocusedItem,
2901 IFView_GetItemPosition,
2902 IFView_GetSpacing,
2903 IFView_GetDefaultSpacing,
2904 IFView_GetAutoArrange,
2905 IFView_SelectItem,
2906 IFView_SelectAndPositionItems
2909 /* IShellFolderView */
2910 static HRESULT WINAPI IShellFolderView_fnQueryInterface(
2911 IShellFolderView *iface,
2912 REFIID riid,
2913 LPVOID *ppvObj)
2915 IShellViewImpl *This = impl_from_IShellFolderView(iface);
2916 TRACE("(%p)->(IID:%s,%p)\n", This, debugstr_guid(riid), ppvObj);
2917 return IShellView2_QueryInterface((IShellView2*)This, riid, ppvObj);
2920 static ULONG WINAPI IShellFolderView_fnAddRef(IShellFolderView *iface)
2922 IShellViewImpl *This = impl_from_IShellFolderView(iface);
2923 TRACE("(%p)->(count=%u)\n", This, This->ref);
2924 return IShellView2_AddRef((IShellView2*)This);
2927 static ULONG WINAPI IShellFolderView_fnRelease(IShellFolderView *iface)
2929 IShellViewImpl *This = impl_from_IShellFolderView(iface);
2930 TRACE("(%p)->(count=%u)\n", This, This->ref);
2931 return IShellView2_Release((IShellView2*)This);
2934 static HRESULT WINAPI IShellFolderView_fnRearrange(IShellFolderView *iface, LPARAM sort)
2936 IShellViewImpl *This = impl_from_IShellFolderView(iface);
2937 FIXME("(%p)->(%ld) stub\n", This, sort);
2938 return E_NOTIMPL;
2941 static HRESULT WINAPI IShellFolderView_fnGetArrangeParam(IShellFolderView *iface, LPARAM *sort)
2943 IShellViewImpl *This = impl_from_IShellFolderView(iface);
2944 FIXME("(%p)->(%p) stub\n", This, sort);
2945 return E_NOTIMPL;
2948 static HRESULT WINAPI IShellFolderView_fnArrangeGrid(IShellFolderView *iface)
2950 IShellViewImpl *This = impl_from_IShellFolderView(iface);
2951 FIXME("(%p) stub\n", This);
2952 return E_NOTIMPL;
2955 static HRESULT WINAPI IShellFolderView_fnAutoArrange(IShellFolderView *iface)
2957 IShellViewImpl *This = impl_from_IShellFolderView(iface);
2958 FIXME("(%p) stub\n", This);
2959 return E_NOTIMPL;
2962 static HRESULT WINAPI IShellFolderView_fnGetAutoArrange(IShellFolderView *iface)
2964 IShellViewImpl *This = impl_from_IShellFolderView(iface);
2965 IFolderView *view = (IFolderView*)&This->lpvtblFolderView;
2967 TRACE("(%p)\n", This);
2968 return IFolderView_GetAutoArrange(view);
2971 static HRESULT WINAPI IShellFolderView_fnAddObject(
2972 IShellFolderView *iface,
2973 PITEMID_CHILD pidl,
2974 UINT *item)
2976 IShellViewImpl *This = impl_from_IShellFolderView(iface);
2977 FIXME("(%p)->(%p %p) stub\n", This, pidl, item);
2978 return E_NOTIMPL;
2981 static HRESULT WINAPI IShellFolderView_fnGetObject(
2982 IShellFolderView *iface,
2983 PITEMID_CHILD *pidl,
2984 UINT item)
2986 IShellViewImpl *This = impl_from_IShellFolderView(iface);
2987 IFolderView *view = (IFolderView*)&This->lpvtblFolderView;
2989 TRACE("(%p)->(%p %d)\n", This, pidl, item);
2990 return IFolderView_Item(view, item, pidl);
2993 static HRESULT WINAPI IShellFolderView_fnRemoveObject(
2994 IShellFolderView *iface,
2995 PITEMID_CHILD pidl,
2996 UINT *item)
2998 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3000 TRACE("(%p)->(%p %p)\n", This, pidl, item);
3002 if (pidl)
3004 *item = LV_FindItemByPidl(This, ILFindLastID(pidl));
3005 SendMessageW(This->hWndList, LVM_DELETEITEM, *item, 0);
3007 else
3009 *item = 0;
3010 SendMessageW(This->hWndList, LVM_DELETEALLITEMS, 0, 0);
3013 return S_OK;
3016 static HRESULT WINAPI IShellFolderView_fnGetObjectCount(
3017 IShellFolderView *iface,
3018 UINT *count)
3020 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3021 IFolderView *view = (IFolderView*)&This->lpvtblFolderView;
3023 TRACE("(%p)->(%p)\n", This, count);
3024 return IFolderView_ItemCount(view, SVGIO_ALLVIEW, (INT*)count);
3027 static HRESULT WINAPI IShellFolderView_fnSetObjectCount(
3028 IShellFolderView *iface,
3029 UINT count,
3030 UINT flags)
3032 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3033 FIXME("(%p)->(%d %x) stub\n", This, count, flags);
3034 return E_NOTIMPL;
3037 static HRESULT WINAPI IShellFolderView_fnUpdateObject(
3038 IShellFolderView *iface,
3039 PITEMID_CHILD pidl_old,
3040 PITEMID_CHILD pidl_new,
3041 UINT *item)
3043 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3044 FIXME("(%p)->(%p %p %p) stub\n", This, pidl_old, pidl_new, item);
3045 return E_NOTIMPL;
3048 static HRESULT WINAPI IShellFolderView_fnRefreshObject(
3049 IShellFolderView *iface,
3050 PITEMID_CHILD pidl,
3051 UINT *item)
3053 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3054 FIXME("(%p)->(%p %p) stub\n", This, pidl, item);
3055 return E_NOTIMPL;
3058 static HRESULT WINAPI IShellFolderView_fnSetRedraw(
3059 IShellFolderView *iface,
3060 BOOL redraw)
3062 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3063 TRACE("(%p)->(%d)\n", This, redraw);
3065 SendMessageW(This->hWndList, WM_SETREDRAW, redraw, 0);
3067 return S_OK;
3070 static HRESULT WINAPI IShellFolderView_fnGetSelectedCount(
3071 IShellFolderView *iface,
3072 UINT *count)
3074 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3075 FIXME("(%p)->(%p) stub\n", This, count);
3076 return E_NOTIMPL;
3079 static HRESULT WINAPI IShellFolderView_fnGetSelectedObjects(
3080 IShellFolderView *iface,
3081 PCITEMID_CHILD **pidl,
3082 UINT *items)
3084 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3086 TRACE("(%p)->(%p %p)\n", This, pidl, items);
3088 *items = ShellView_GetSelections( This );
3090 if (*items)
3092 *pidl = LocalAlloc(0, *items*sizeof(LPITEMIDLIST));
3093 if (!*pidl) return E_OUTOFMEMORY;
3095 /* it's documented that caller shouldn't free PIDLs, only array itself */
3096 memcpy((PITEMID_CHILD*)*pidl, This->apidl, *items*sizeof(LPITEMIDLIST));
3099 return S_OK;
3102 static HRESULT WINAPI IShellFolderView_fnIsDropOnSource(
3103 IShellFolderView *iface,
3104 IDropTarget *drop_target)
3106 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3107 FIXME("(%p)->(%p) stub\n", This, drop_target);
3108 return E_NOTIMPL;
3111 static HRESULT WINAPI IShellFolderView_fnGetDragPoint(
3112 IShellFolderView *iface,
3113 POINT *pt)
3115 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3116 FIXME("(%p)->(%p) stub\n", This, pt);
3117 return E_NOTIMPL;
3120 static HRESULT WINAPI IShellFolderView_fnGetDropPoint(
3121 IShellFolderView *iface,
3122 POINT *pt)
3124 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3125 FIXME("(%p)->(%p) stub\n", This, pt);
3126 return E_NOTIMPL;
3129 static HRESULT WINAPI IShellFolderView_fnMoveIcons(
3130 IShellFolderView *iface,
3131 IDataObject *obj)
3133 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3134 TRACE("(%p)->(%p)\n", This, obj);
3135 return E_NOTIMPL;
3138 static HRESULT WINAPI IShellFolderView_fnSetItemPos(
3139 IShellFolderView *iface,
3140 PCUITEMID_CHILD pidl,
3141 POINT *pt)
3143 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3144 FIXME("(%p)->(%p %p) stub\n", This, pidl, pt);
3145 return E_NOTIMPL;
3148 static HRESULT WINAPI IShellFolderView_fnIsBkDropTarget(
3149 IShellFolderView *iface,
3150 IDropTarget *drop_target)
3152 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3153 FIXME("(%p)->(%p) stub\n", This, drop_target);
3154 return E_NOTIMPL;
3157 static HRESULT WINAPI IShellFolderView_fnSetClipboard(
3158 IShellFolderView *iface,
3159 BOOL move)
3161 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3162 FIXME("(%p)->(%d) stub\n", This, move);
3163 return E_NOTIMPL;
3166 static HRESULT WINAPI IShellFolderView_fnSetPoints(
3167 IShellFolderView *iface,
3168 IDataObject *obj)
3170 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3171 FIXME("(%p)->(%p) stub\n", This, obj);
3172 return E_NOTIMPL;
3175 static HRESULT WINAPI IShellFolderView_fnGetItemSpacing(
3176 IShellFolderView *iface,
3177 ITEMSPACING *spacing)
3179 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3180 FIXME("(%p)->(%p) stub\n", This, spacing);
3181 return E_NOTIMPL;
3184 static HRESULT WINAPI IShellFolderView_fnSetCallback(
3185 IShellFolderView *iface,
3186 IShellFolderViewCB *new_cb,
3187 IShellFolderViewCB **old_cb)
3190 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3191 FIXME("(%p)->(%p %p) stub\n", This, new_cb, old_cb);
3192 return E_NOTIMPL;
3195 static HRESULT WINAPI IShellFolderView_fnSelect(
3196 IShellFolderView *iface,
3197 UINT flags)
3199 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3200 FIXME("(%p)->(%d) stub\n", This, flags);
3201 return E_NOTIMPL;
3204 static HRESULT WINAPI IShellFolderView_fnQuerySupport(
3205 IShellFolderView *iface,
3206 UINT *support)
3208 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3209 TRACE("(%p)->(%p)\n", This, support);
3210 return S_OK;
3213 static HRESULT WINAPI IShellFolderView_fnSetAutomationObject(
3214 IShellFolderView *iface,
3215 IDispatch *disp)
3217 IShellViewImpl *This = impl_from_IShellFolderView(iface);
3218 FIXME("(%p)->(%p) stub\n", This, disp);
3219 return E_NOTIMPL;
3222 static const IShellFolderViewVtbl shellfolderviewvt =
3224 IShellFolderView_fnQueryInterface,
3225 IShellFolderView_fnAddRef,
3226 IShellFolderView_fnRelease,
3227 IShellFolderView_fnRearrange,
3228 IShellFolderView_fnGetArrangeParam,
3229 IShellFolderView_fnArrangeGrid,
3230 IShellFolderView_fnAutoArrange,
3231 IShellFolderView_fnGetAutoArrange,
3232 IShellFolderView_fnAddObject,
3233 IShellFolderView_fnGetObject,
3234 IShellFolderView_fnRemoveObject,
3235 IShellFolderView_fnGetObjectCount,
3236 IShellFolderView_fnSetObjectCount,
3237 IShellFolderView_fnUpdateObject,
3238 IShellFolderView_fnRefreshObject,
3239 IShellFolderView_fnSetRedraw,
3240 IShellFolderView_fnGetSelectedCount,
3241 IShellFolderView_fnGetSelectedObjects,
3242 IShellFolderView_fnIsDropOnSource,
3243 IShellFolderView_fnGetDragPoint,
3244 IShellFolderView_fnGetDropPoint,
3245 IShellFolderView_fnMoveIcons,
3246 IShellFolderView_fnSetItemPos,
3247 IShellFolderView_fnIsBkDropTarget,
3248 IShellFolderView_fnSetClipboard,
3249 IShellFolderView_fnSetPoints,
3250 IShellFolderView_fnGetItemSpacing,
3251 IShellFolderView_fnSetCallback,
3252 IShellFolderView_fnSelect,
3253 IShellFolderView_fnQuerySupport,
3254 IShellFolderView_fnSetAutomationObject