push d49b3885cdb0e58b792f6bf912143b7a9a4ea546
[wine/hacks.git] / dlls / shell32 / shlview.c
blobc5783dcda898f6bb65caf7efdb9730db54b4ab4f
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 "undocshell.h"
61 #include "shresdef.h"
62 #include "wine/debug.h"
64 #include "docobj.h"
65 #include "pidl.h"
66 #include "shell32_main.h"
67 #include "shellfolder.h"
69 WINE_DEFAULT_DEBUG_CHANNEL(shell);
71 static const WCHAR SV_CLASS_NAME[] = {'S','H','E','L','L','D','L','L','_','D','e','f','V','i','e','w',0};
73 typedef struct
74 { BOOL bIsAscending;
75 INT nHeaderID;
76 INT nLastHeaderID;
77 }LISTVIEW_SORT_INFO, *LPLISTVIEW_SORT_INFO;
79 typedef struct
81 const IShellView2Vtbl* lpVtbl;
82 LONG ref;
83 const IOleCommandTargetVtbl* lpvtblOleCommandTarget;
84 const IDropTargetVtbl* lpvtblDropTarget;
85 const IDropSourceVtbl* lpvtblDropSource;
86 const IViewObjectVtbl* lpvtblViewObject;
87 IShellFolder* pSFParent;
88 IShellFolder2* pSF2Parent;
89 IShellBrowser* pShellBrowser;
90 ICommDlgBrowser* pCommDlgBrowser;
91 HWND hWnd; /* SHELLDLL_DefView */
92 HWND hWndList; /* ListView control */
93 HWND hWndParent;
94 FOLDERSETTINGS FolderSettings;
95 HMENU hMenu;
96 UINT uState;
97 UINT cidl;
98 LPITEMIDLIST *apidl;
99 LISTVIEW_SORT_INFO ListViewSortInfo;
100 ULONG hNotify; /* change notification handle */
101 HANDLE hAccel;
102 DWORD dwAspects;
103 DWORD dwAdvf;
104 IAdviseSink *pAdvSink;
105 IDropTarget* pCurDropTarget; /* The sub-item, which is currently dragged over */
106 IDataObject* pCurDataObject; /* The dragged data-object */
107 LONG iDragOverItem; /* Dragged over item's index, iff pCurDropTarget != NULL */
108 UINT cScrollDelay; /* Send a WM_*SCROLL msg every 250 ms during drag-scroll */
109 POINT ptLastMousePos; /* Mouse position at last DragOver call */
110 } IShellViewImpl;
112 static const IShellView2Vtbl svvt;
113 static const IOleCommandTargetVtbl ctvt;
114 static const IDropTargetVtbl dtvt;
115 static const IDropSourceVtbl dsvt;
116 static const IViewObjectVtbl vovt;
119 static inline IShellViewImpl *impl_from_IOleCommandTarget( IOleCommandTarget *iface )
121 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblOleCommandTarget));
124 static inline IShellViewImpl *impl_from_IDropTarget( IDropTarget *iface )
126 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblDropTarget));
129 static inline IShellViewImpl *impl_from_IDropSource( IDropSource *iface )
131 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblDropSource));
134 static inline IShellViewImpl *impl_from_IViewObject( IViewObject *iface )
136 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblViewObject));
139 /* ListView Header ID's */
140 #define LISTVIEW_COLUMN_NAME 0
141 #define LISTVIEW_COLUMN_SIZE 1
142 #define LISTVIEW_COLUMN_TYPE 2
143 #define LISTVIEW_COLUMN_TIME 3
144 #define LISTVIEW_COLUMN_ATTRIB 4
146 /*menu items */
147 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
148 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
149 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
151 #define ID_LISTVIEW 1
153 #define SHV_CHANGE_NOTIFY WM_USER + 0x1111
155 /*windowsx.h */
156 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
157 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
158 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
161 Items merged into the toolbar and the filemenu
163 typedef struct
164 { int idCommand;
165 int iImage;
166 int idButtonString;
167 int idMenuString;
168 BYTE bState;
169 BYTE bStyle;
170 } MYTOOLINFO, *LPMYTOOLINFO;
172 static const MYTOOLINFO Tools[] =
174 { FCIDM_SHVIEW_BIGICON, 0, 0, IDS_VIEW_LARGE, TBSTATE_ENABLED, BTNS_BUTTON },
175 { FCIDM_SHVIEW_SMALLICON, 0, 0, IDS_VIEW_SMALL, TBSTATE_ENABLED, BTNS_BUTTON },
176 { FCIDM_SHVIEW_LISTVIEW, 0, 0, IDS_VIEW_LIST, TBSTATE_ENABLED, BTNS_BUTTON },
177 { FCIDM_SHVIEW_REPORTVIEW, 0, 0, IDS_VIEW_DETAILS, TBSTATE_ENABLED, BTNS_BUTTON },
178 { -1, 0, 0, 0, 0, 0}
181 typedef void (CALLBACK *PFNSHGETSETTINGSPROC)(LPSHELLFLAGSTATE lpsfs, DWORD dwMask);
183 /**********************************************************
184 * IShellView_Constructor
186 IShellView * IShellView_Constructor( IShellFolder * pFolder)
187 { IShellViewImpl * sv;
188 sv=HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IShellViewImpl));
189 sv->ref=1;
190 sv->lpVtbl=&svvt;
191 sv->lpvtblOleCommandTarget=&ctvt;
192 sv->lpvtblDropTarget=&dtvt;
193 sv->lpvtblDropSource=&dsvt;
194 sv->lpvtblViewObject=&vovt;
196 sv->pSFParent = pFolder;
197 if(pFolder) IShellFolder_AddRef(pFolder);
198 IShellFolder_QueryInterface(sv->pSFParent, &IID_IShellFolder2, (LPVOID*)&sv->pSF2Parent);
200 sv->pCurDropTarget = NULL;
201 sv->pCurDataObject = NULL;
202 sv->iDragOverItem = 0;
203 sv->cScrollDelay = 0;
204 sv->ptLastMousePos.x = 0;
205 sv->ptLastMousePos.y = 0;
207 TRACE("(%p)->(%p)\n",sv, pFolder);
208 return (IShellView *) sv;
211 /**********************************************************
213 * ##### helperfunctions for communication with ICommDlgBrowser #####
215 static BOOL IsInCommDlg(IShellViewImpl * This)
216 { return(This->pCommDlgBrowser != NULL);
219 static HRESULT IncludeObject(IShellViewImpl * This, LPCITEMIDLIST pidl)
221 HRESULT ret = S_OK;
223 if ( IsInCommDlg(This) )
225 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl);
226 ret = ICommDlgBrowser_IncludeObject(This->pCommDlgBrowser, (IShellView*)This, pidl);
227 TRACE("--0x%08x\n", ret);
229 return ret;
232 static HRESULT OnDefaultCommand(IShellViewImpl * This)
234 HRESULT ret = S_FALSE;
236 if (IsInCommDlg(This))
238 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
239 ret = ICommDlgBrowser_OnDefaultCommand(This->pCommDlgBrowser, (IShellView*)This);
240 TRACE("-- returns %08x\n", ret);
242 return ret;
245 static HRESULT OnStateChange(IShellViewImpl * This, UINT uFlags)
247 HRESULT ret = S_FALSE;
249 if (IsInCommDlg(This))
251 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags);
252 ret = ICommDlgBrowser_OnStateChange(This->pCommDlgBrowser, (IShellView*)This, uFlags);
253 TRACE("--\n");
255 return ret;
257 /**********************************************************
258 * set the toolbar of the filedialog buttons
260 * - activates the buttons from the shellbrowser according to
261 * the view state
263 static void CheckToolbar(IShellViewImpl * This)
265 LRESULT result;
267 TRACE("\n");
269 if (IsInCommDlg(This))
271 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
272 FCIDM_TB_SMALLICON, (This->FolderSettings.ViewMode==FVM_LIST)? TRUE : FALSE, &result);
273 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
274 FCIDM_TB_REPORTVIEW, (This->FolderSettings.ViewMode==FVM_DETAILS)? TRUE : FALSE, &result);
275 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
276 FCIDM_TB_SMALLICON, TRUE, &result);
277 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
278 FCIDM_TB_REPORTVIEW, TRUE, &result);
282 /**********************************************************
284 * ##### helperfunctions for initializing the view #####
286 /**********************************************************
287 * change the style of the listview control
289 static void SetStyle(IShellViewImpl * This, DWORD dwAdd, DWORD dwRemove)
291 DWORD tmpstyle;
293 TRACE("(%p)\n", This);
295 tmpstyle = GetWindowLongW(This->hWndList, GWL_STYLE);
296 SetWindowLongW(This->hWndList, GWL_STYLE, dwAdd | (tmpstyle & ~dwRemove));
299 /**********************************************************
300 * ShellView_CreateList()
302 * - creates the list view window
304 static BOOL ShellView_CreateList (IShellViewImpl * This)
305 { DWORD dwStyle, dwExStyle;
307 TRACE("%p\n",This);
309 dwStyle = WS_TABSTOP | WS_VISIBLE | WS_CHILDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
310 LVS_SHAREIMAGELISTS | LVS_EDITLABELS | LVS_ALIGNLEFT | LVS_AUTOARRANGE;
311 dwExStyle = WS_EX_CLIENTEDGE;
313 switch (This->FolderSettings.ViewMode)
315 case FVM_ICON: dwStyle |= LVS_ICON; break;
316 case FVM_DETAILS: dwStyle |= LVS_REPORT; break;
317 case FVM_SMALLICON: dwStyle |= LVS_SMALLICON; break;
318 case FVM_LIST: dwStyle |= LVS_LIST; break;
319 default:
321 FIXME("ViewMode %d not implemented\n", This->FolderSettings.ViewMode);
322 dwStyle |= LVS_LIST;
323 break;
327 if (This->FolderSettings.fFlags & FWF_AUTOARRANGE) dwStyle |= LVS_AUTOARRANGE;
328 if (This->FolderSettings.fFlags & FWF_DESKTOP)
329 This->FolderSettings.fFlags |= FWF_NOCLIENTEDGE | FWF_NOSCROLL;
330 if (This->FolderSettings.fFlags & FWF_SINGLESEL) dwStyle |= LVS_SINGLESEL;
331 if (This->FolderSettings.fFlags & FWF_NOCLIENTEDGE)
332 dwExStyle &= ~WS_EX_CLIENTEDGE;
334 This->hWndList=CreateWindowExW( dwExStyle,
335 WC_LISTVIEWW,
336 NULL,
337 dwStyle,
338 0,0,0,0,
339 This->hWnd,
340 (HMENU)ID_LISTVIEW,
341 shell32_hInstance,
342 NULL);
344 if(!This->hWndList)
345 return FALSE;
347 This->ListViewSortInfo.bIsAscending = TRUE;
348 This->ListViewSortInfo.nHeaderID = -1;
349 This->ListViewSortInfo.nLastHeaderID = -1;
351 if (This->FolderSettings.fFlags & FWF_DESKTOP) {
353 * FIXME: look at the registry value
354 * HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ListviewShadow
355 * and activate drop shadows if necessary
357 if (0)
358 SendMessageW(This->hWndList, LVM_SETTEXTBKCOLOR, 0, CLR_NONE);
359 else
360 SendMessageW(This->hWndList, LVM_SETTEXTBKCOLOR, 0, GetSysColor(COLOR_DESKTOP));
362 SendMessageW(This->hWndList, LVM_SETTEXTCOLOR, 0, RGB(255,255,255));
365 /* UpdateShellSettings(); */
366 return TRUE;
369 /**********************************************************
370 * ShellView_InitList()
372 * - adds all needed columns to the shellview
374 static BOOL ShellView_InitList(IShellViewImpl * This)
376 LVCOLUMNW lvColumn;
377 SHELLDETAILS sd;
378 int i;
379 WCHAR szTemp[50];
381 TRACE("%p\n",This);
383 SendMessageW(This->hWndList, LVM_DELETEALLITEMS, 0, 0);
385 lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT;
386 lvColumn.pszText = szTemp;
388 if (This->pSF2Parent)
390 for (i=0; 1; i++)
392 if (FAILED(IShellFolder2_GetDetailsOf(This->pSF2Parent, NULL, i, &sd)))
393 break;
394 lvColumn.fmt = sd.fmt;
395 lvColumn.cx = sd.cxChar*8; /* chars->pixel */
396 StrRetToStrNW( szTemp, 50, &sd.str, NULL);
397 SendMessageW(This->hWndList, LVM_INSERTCOLUMNW, i, (LPARAM) &lvColumn);
400 else
402 FIXME("no SF2\n");
405 SendMessageW(This->hWndList, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)ShellSmallIconList);
406 SendMessageW(This->hWndList, LVM_SETIMAGELIST, LVSIL_NORMAL, (LPARAM)ShellBigIconList);
408 return TRUE;
410 /**********************************************************
411 * ShellView_CompareItems()
413 * NOTES
414 * internal, CALLBACK for DSA_Sort
416 static INT CALLBACK ShellView_CompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
418 int ret;
419 TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1, lParam2, (LPVOID) lpData);
421 if(!lpData) return 0;
423 ret = (SHORT) SCODE_CODE(IShellFolder_CompareIDs((LPSHELLFOLDER)lpData, 0, (LPITEMIDLIST)lParam1, (LPITEMIDLIST)lParam2));
424 TRACE("ret=%i\n",ret);
425 return ret;
428 /*************************************************************************
429 * ShellView_ListViewCompareItems
431 * Compare Function for the Listview (FileOpen Dialog)
433 * PARAMS
434 * lParam1 [I] the first ItemIdList to compare with
435 * lParam2 [I] the second ItemIdList to compare with
436 * lpData [I] The column ID for the header Ctrl to process
438 * RETURNS
439 * A negative value if the first item should precede the second,
440 * a positive value if the first item should follow the second,
441 * or zero if the two items are equivalent
443 * NOTES
444 * FIXME: function does what ShellView_CompareItems is supposed to do.
445 * unify it and figure out how to use the undocumented first parameter
446 * of IShellFolder_CompareIDs to do the job this function does and
447 * move this code to IShellFolder.
448 * make LISTVIEW_SORT_INFO obsolete
449 * the way this function works is only usable if we had only
450 * filesystemfolders (25/10/99 jsch)
452 static INT CALLBACK ShellView_ListViewCompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
454 INT nDiff=0;
455 FILETIME fd1, fd2;
456 char strName1[MAX_PATH], strName2[MAX_PATH];
457 BOOL bIsFolder1, bIsFolder2,bIsBothFolder;
458 LPITEMIDLIST pItemIdList1 = lParam1;
459 LPITEMIDLIST pItemIdList2 = lParam2;
460 LISTVIEW_SORT_INFO *pSortInfo = (LPLISTVIEW_SORT_INFO) lpData;
463 bIsFolder1 = _ILIsFolder(pItemIdList1);
464 bIsFolder2 = _ILIsFolder(pItemIdList2);
465 bIsBothFolder = bIsFolder1 && bIsFolder2;
467 /* When sorting between a File and a Folder, the Folder gets sorted first */
468 if( (bIsFolder1 || bIsFolder2) && !bIsBothFolder)
470 nDiff = bIsFolder1 ? -1 : 1;
472 else
474 /* Sort by Time: Folders or Files can be sorted */
476 if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TIME)
478 _ILGetFileDateTime(pItemIdList1, &fd1);
479 _ILGetFileDateTime(pItemIdList2, &fd2);
480 nDiff = CompareFileTime(&fd2, &fd1);
482 /* Sort by Attribute: Folder or Files can be sorted */
483 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_ATTRIB)
485 _ILGetFileAttributes(pItemIdList1, strName1, MAX_PATH);
486 _ILGetFileAttributes(pItemIdList2, strName2, MAX_PATH);
487 nDiff = lstrcmpiA(strName1, strName2);
489 /* Sort by FileName: Folder or Files can be sorted */
490 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_NAME || bIsBothFolder)
492 /* Sort by Text */
493 _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
494 _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
495 nDiff = lstrcmpiA(strName1, strName2);
497 /* Sort by File Size, Only valid for Files */
498 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_SIZE)
500 nDiff = (INT)(_ILGetFileSize(pItemIdList1, NULL, 0) - _ILGetFileSize(pItemIdList2, NULL, 0));
502 /* Sort by File Type, Only valid for Files */
503 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TYPE)
505 /* Sort by Type */
506 _ILGetFileType(pItemIdList1, strName1, MAX_PATH);
507 _ILGetFileType(pItemIdList2, strName2, MAX_PATH);
508 nDiff = lstrcmpiA(strName1, strName2);
511 /* If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
513 if(nDiff == 0)
515 _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
516 _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
517 nDiff = lstrcmpiA(strName1, strName2);
520 if(!pSortInfo->bIsAscending)
522 nDiff = -nDiff;
525 return nDiff;
529 /**********************************************************
530 * LV_FindItemByPidl()
532 static int LV_FindItemByPidl(
533 IShellViewImpl * This,
534 LPCITEMIDLIST pidl)
536 LVITEMW lvItem;
537 lvItem.iSubItem = 0;
538 lvItem.mask = LVIF_PARAM;
539 for(lvItem.iItem = 0;
540 SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem);
541 lvItem.iItem++)
543 LPITEMIDLIST currentpidl = (LPITEMIDLIST) lvItem.lParam;
544 HRESULT hr = IShellFolder_CompareIDs(This->pSFParent, 0, pidl, currentpidl);
545 if(SUCCEEDED(hr) && !HRESULT_CODE(hr))
547 return lvItem.iItem;
550 return -1;
553 /**********************************************************
554 * LV_AddItem()
556 static BOOLEAN LV_AddItem(IShellViewImpl * This, LPCITEMIDLIST pidl)
558 LVITEMW lvItem;
560 TRACE("(%p)(pidl=%p)\n", This, pidl);
562 lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; /*set the mask*/
563 lvItem.iItem = ListView_GetItemCount(This->hWndList); /*add the item to the end of the list*/
564 lvItem.iSubItem = 0;
565 lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidl)); /*set the item's data*/
566 lvItem.pszText = LPSTR_TEXTCALLBACKW; /*get text on a callback basis*/
567 lvItem.iImage = I_IMAGECALLBACK; /*get the image on a callback basis*/
568 return (-1==ListView_InsertItemW(This->hWndList, &lvItem))? FALSE: TRUE;
571 /**********************************************************
572 * LV_DeleteItem()
574 static BOOLEAN LV_DeleteItem(IShellViewImpl * This, LPCITEMIDLIST pidl)
576 int nIndex;
578 TRACE("(%p)(pidl=%p)\n", This, pidl);
580 nIndex = LV_FindItemByPidl(This, ILFindLastID(pidl));
581 return (-1==ListView_DeleteItem(This->hWndList, nIndex))? FALSE: TRUE;
584 /**********************************************************
585 * LV_RenameItem()
587 static BOOLEAN LV_RenameItem(IShellViewImpl * This, LPCITEMIDLIST pidlOld, LPCITEMIDLIST pidlNew )
589 int nItem;
590 LVITEMW lvItem;
592 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", This, pidlOld, pidlNew);
594 nItem = LV_FindItemByPidl(This, ILFindLastID(pidlOld));
595 if ( -1 != nItem )
597 lvItem.mask = LVIF_PARAM; /* only the pidl */
598 lvItem.iItem = nItem;
599 SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem);
601 SHFree((LPITEMIDLIST)lvItem.lParam);
602 lvItem.mask = LVIF_PARAM;
603 lvItem.iItem = nItem;
604 lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidlNew)); /* set the item's data */
605 SendMessageW(This->hWndList, LVM_SETITEMW, 0, (LPARAM) &lvItem);
606 SendMessageW(This->hWndList, LVM_UPDATE, nItem, 0);
607 return TRUE; /* FIXME: better handling */
609 return FALSE;
611 /**********************************************************
612 * ShellView_FillList()
614 * - gets the objectlist from the shellfolder
615 * - sorts the list
616 * - fills the list into the view
619 static INT CALLBACK fill_list( LPVOID ptr, LPVOID arg )
621 LPITEMIDLIST pidl = ptr;
622 IShellViewImpl *This = arg;
623 /* in a commdlg This works as a filemask*/
624 if ( IncludeObject(This, pidl)==S_OK ) LV_AddItem(This, pidl);
625 SHFree(pidl);
626 return TRUE;
629 static HRESULT ShellView_FillList(IShellViewImpl * This)
631 LPENUMIDLIST pEnumIDList;
632 LPITEMIDLIST pidl;
633 DWORD dwFetched;
634 HRESULT hRes;
635 HDPA hdpa;
637 TRACE("%p\n",This);
639 /* get the itemlist from the shfolder*/
640 hRes = IShellFolder_EnumObjects(This->pSFParent,This->hWnd, SHCONTF_NONFOLDERS | SHCONTF_FOLDERS, &pEnumIDList);
641 if (hRes != S_OK)
643 if (hRes==S_FALSE)
644 return(NOERROR);
645 return(hRes);
648 /* create a pointer array */
649 hdpa = DPA_Create(16);
650 if (!hdpa)
652 return(E_OUTOFMEMORY);
655 /* copy the items into the array*/
656 while((S_OK == IEnumIDList_Next(pEnumIDList,1, &pidl, &dwFetched)) && dwFetched)
658 if (DPA_InsertPtr(hdpa, 0x7fff, pidl) == -1)
660 SHFree(pidl);
664 /* sort the array */
665 DPA_Sort(hdpa, ShellView_CompareItems, (LPARAM)This->pSFParent);
667 /*turn the listview's redrawing off*/
668 SendMessageA(This->hWndList, WM_SETREDRAW, FALSE, 0);
670 DPA_DestroyCallback( hdpa, fill_list, This );
672 /*turn the listview's redrawing back on and force it to draw*/
673 SendMessageA(This->hWndList, WM_SETREDRAW, TRUE, 0);
675 IEnumIDList_Release(pEnumIDList); /* destroy the list*/
677 return S_OK;
680 /**********************************************************
681 * ShellView_OnCreate()
683 static LRESULT ShellView_OnCreate(IShellViewImpl * This)
685 IDropTarget* pdt;
686 SHChangeNotifyEntry ntreg;
687 IPersistFolder2 * ppf2 = NULL;
689 TRACE("%p\n",This);
691 if(ShellView_CreateList(This))
693 if(ShellView_InitList(This))
695 ShellView_FillList(This);
699 if (SUCCEEDED(IUnknown_QueryInterface((IUnknown*)&This->lpVtbl, &IID_IDropTarget, (LPVOID*)&pdt)))
701 RegisterDragDrop(This->hWnd, pdt);
702 IDropTarget_Release(pdt);
705 /* register for receiving notifications */
706 IShellFolder_QueryInterface(This->pSFParent, &IID_IPersistFolder2, (LPVOID*)&ppf2);
707 if (ppf2)
709 IPersistFolder2_GetCurFolder(ppf2, (LPITEMIDLIST*)&ntreg.pidl);
710 ntreg.fRecursive = TRUE;
711 This->hNotify = SHChangeNotifyRegister(This->hWnd, SHCNF_IDLIST, SHCNE_ALLEVENTS, SHV_CHANGE_NOTIFY, 1, &ntreg);
712 SHFree((LPITEMIDLIST)ntreg.pidl);
713 IPersistFolder2_Release(ppf2);
716 This->hAccel = LoadAcceleratorsA(shell32_hInstance, "shv_accel");
718 return S_OK;
721 /**********************************************************
722 * #### Handling of the menus ####
725 /**********************************************************
726 * ShellView_BuildFileMenu()
728 static HMENU ShellView_BuildFileMenu(IShellViewImpl * This)
729 { WCHAR szText[MAX_PATH];
730 MENUITEMINFOW mii;
731 int nTools,i;
732 HMENU hSubMenu;
734 TRACE("(%p)\n",This);
736 hSubMenu = CreatePopupMenu();
737 if(hSubMenu)
738 { /*get the number of items in our global array*/
739 for(nTools = 0; Tools[nTools].idCommand != -1; nTools++){}
741 /*add the menu items*/
742 for(i = 0; i < nTools; i++)
744 LoadStringW(shell32_hInstance, Tools[i].idMenuString, szText, MAX_PATH);
746 ZeroMemory(&mii, sizeof(mii));
747 mii.cbSize = sizeof(mii);
748 mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
750 if(BTNS_SEP != Tools[i].bStyle) /* no separator*/
752 mii.fType = MFT_STRING;
753 mii.fState = MFS_ENABLED;
754 mii.dwTypeData = szText;
755 mii.wID = Tools[i].idCommand;
757 else
759 mii.fType = MFT_SEPARATOR;
761 /* tack This item onto the end of the menu */
762 InsertMenuItemW(hSubMenu, (UINT)-1, TRUE, &mii);
765 TRACE("-- return (menu=%p)\n",hSubMenu);
766 return hSubMenu;
768 /**********************************************************
769 * ShellView_MergeFileMenu()
771 static void ShellView_MergeFileMenu(IShellViewImpl * This, HMENU hSubMenu)
772 { TRACE("(%p)->(submenu=%p) stub\n",This,hSubMenu);
774 if(hSubMenu)
775 { /*insert This item at the beginning of the menu */
776 MENUITEMINFOA mii;
778 mii.cbSize = sizeof(mii);
779 mii.fMask = MIIM_ID | MIIM_TYPE;
780 mii.wID = 0;
781 mii.fType = MFT_SEPARATOR;
782 InsertMenuItemA(hSubMenu, 0, TRUE, &mii);
784 mii.cbSize = sizeof(mii);
785 mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
786 mii.dwTypeData = (LPSTR)"dummy45";
787 mii.fState = MFS_ENABLED;
788 mii.wID = IDM_MYFILEITEM;
789 mii.fType = MFT_STRING;
790 InsertMenuItemA(hSubMenu, 0, TRUE, &mii);
792 TRACE("--\n");
795 /**********************************************************
796 * ShellView_MergeViewMenu()
799 static void ShellView_MergeViewMenu(IShellViewImpl * This, HMENU hSubMenu)
801 TRACE("(%p)->(submenu=%p)\n",This,hSubMenu);
803 if(hSubMenu)
804 { /*add a separator at the correct position in the menu*/
805 MENUITEMINFOA mii;
806 static char view[] = "View";
808 ZeroMemory(&mii, sizeof(mii));
809 mii.cbSize = sizeof(mii);
810 mii.fMask = MIIM_ID | MIIM_TYPE;
811 mii.wID = 0;
812 mii.fType = MFT_SEPARATOR;
813 InsertMenuItemA(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
815 mii.cbSize = sizeof(mii);
816 mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_DATA;
817 mii.fType = MFT_STRING;
818 mii.dwTypeData = view;
819 mii.hSubMenu = LoadMenuA(shell32_hInstance, "MENU_001");
820 InsertMenuItemA(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
824 /**********************************************************
825 * ShellView_GetSelections()
827 * - fills the this->apidl list with the selected objects
829 * RETURNS
830 * number of selected items
832 static UINT ShellView_GetSelections(IShellViewImpl * This)
834 LVITEMW lvItem;
835 UINT i = 0;
837 SHFree(This->apidl);
839 This->cidl = ListView_GetSelectedCount(This->hWndList);
840 This->apidl = SHAlloc(This->cidl * sizeof(LPITEMIDLIST));
842 TRACE("selected=%i\n", This->cidl);
844 if(This->apidl)
846 TRACE("-- Items selected =%u\n", This->cidl);
848 lvItem.mask = LVIF_STATE | LVIF_PARAM;
849 lvItem.stateMask = LVIS_SELECTED;
850 lvItem.iItem = 0;
851 lvItem.iSubItem = 0;
853 while(ListView_GetItemW(This->hWndList, &lvItem) && (i < This->cidl))
855 if(lvItem.state & LVIS_SELECTED)
857 This->apidl[i] = (LPITEMIDLIST)lvItem.lParam;
858 i++;
859 TRACE("-- selected Item found\n");
861 lvItem.iItem++;
864 return This->cidl;
868 /**********************************************************
869 * ShellView_OpenSelectedItems()
871 static HRESULT ShellView_OpenSelectedItems(IShellViewImpl * This)
873 static UINT CF_IDLIST = 0;
874 HRESULT hr;
875 IDataObject* selection;
876 FORMATETC fetc;
877 STGMEDIUM stgm;
878 LPIDA pIDList;
879 LPCITEMIDLIST parent_pidl;
880 WCHAR parent_path[MAX_PATH];
881 LPCWSTR parent_dir = NULL;
882 SFGAOF attribs;
883 int i;
885 if (0 == ShellView_GetSelections(This))
887 return S_OK;
889 hr = IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl,
890 (LPCITEMIDLIST*)This->apidl, &IID_IDataObject,
891 0, (LPVOID *)&selection);
892 if (FAILED(hr))
893 return hr;
895 if (0 == CF_IDLIST)
897 CF_IDLIST = RegisterClipboardFormatW(CFSTR_SHELLIDLISTW);
899 fetc.cfFormat = CF_IDLIST;
900 fetc.ptd = NULL;
901 fetc.dwAspect = DVASPECT_CONTENT;
902 fetc.lindex = -1;
903 fetc.tymed = TYMED_HGLOBAL;
905 hr = IDataObject_QueryGetData(selection, &fetc);
906 if (FAILED(hr))
907 return hr;
909 hr = IDataObject_GetData(selection, &fetc, &stgm);
910 if (FAILED(hr))
911 return hr;
913 pIDList = GlobalLock(stgm.u.hGlobal);
915 parent_pidl = (LPCITEMIDLIST) ((LPBYTE)pIDList+pIDList->aoffset[0]);
916 hr = IShellFolder_GetAttributesOf(This->pSFParent, 1, &parent_pidl, &attribs);
917 if (SUCCEEDED(hr) && (attribs & SFGAO_FILESYSTEM) &&
918 SHGetPathFromIDListW(parent_pidl, parent_path))
920 parent_dir = parent_path;
923 for (i = pIDList->cidl; i > 0; --i)
925 LPCITEMIDLIST pidl;
927 pidl = (LPCITEMIDLIST)((LPBYTE)pIDList+pIDList->aoffset[i]);
929 attribs = SFGAO_FOLDER;
930 hr = IShellFolder_GetAttributesOf(This->pSFParent, 1, &pidl, &attribs);
932 if (SUCCEEDED(hr) && ! (attribs & SFGAO_FOLDER))
934 SHELLEXECUTEINFOW shexinfo;
936 shexinfo.cbSize = sizeof(SHELLEXECUTEINFOW);
937 shexinfo.fMask = SEE_MASK_INVOKEIDLIST; /* SEE_MASK_IDLIST is also possible. */
938 shexinfo.hwnd = NULL;
939 shexinfo.lpVerb = NULL;
940 shexinfo.lpFile = NULL;
941 shexinfo.lpParameters = NULL;
942 shexinfo.lpDirectory = parent_dir;
943 shexinfo.nShow = SW_NORMAL;
944 shexinfo.lpIDList = ILCombine(parent_pidl, pidl);
946 ShellExecuteExW(&shexinfo); /* Discard error/success info */
948 ILFree(shexinfo.lpIDList);
952 GlobalUnlock(stgm.u.hGlobal);
953 ReleaseStgMedium(&stgm);
955 IDataObject_Release(selection);
957 return S_OK;
960 /**********************************************************
961 * ShellView_DoContextMenu()
963 static void ShellView_DoContextMenu(IShellViewImpl * This, WORD x, WORD y, BOOL bDefault)
964 { UINT uCommand;
965 DWORD wFlags;
966 HMENU hMenu;
967 BOOL fExplore = FALSE;
968 HWND hwndTree = 0;
969 LPCONTEXTMENU pContextMenu = NULL;
970 IContextMenu2 *pCM = NULL;
971 CMINVOKECOMMANDINFO cmi;
973 TRACE("(%p)->(0x%08x 0x%08x 0x%08x) stub\n",This, x, y, bDefault);
975 /* look, what's selected and create a context menu object of it*/
976 if( ShellView_GetSelections(This) )
978 IShellFolder_GetUIObjectOf( This->pSFParent, This->hWndParent, This->cidl, (LPCITEMIDLIST*)This->apidl,
979 (REFIID)&IID_IContextMenu, NULL, (LPVOID *)&pContextMenu);
981 if(pContextMenu)
983 TRACE("-- pContextMenu\n");
984 hMenu = CreatePopupMenu();
986 if( hMenu )
988 /* See if we are in Explore or Open mode. If the browser's tree is present, we are in Explore mode.*/
989 if(SUCCEEDED(IShellBrowser_GetControlWindow(This->pShellBrowser,FCW_TREE, &hwndTree)) && hwndTree)
991 TRACE("-- explore mode\n");
992 fExplore = TRUE;
995 /* build the flags depending on what we can do with the selected item */
996 wFlags = CMF_NORMAL | (This->cidl != 1 ? 0 : CMF_CANRENAME) | (fExplore ? CMF_EXPLORE : 0);
998 /* let the ContextMenu merge its items in */
999 if (SUCCEEDED(IContextMenu_QueryContextMenu( pContextMenu, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, wFlags )))
1001 if (This->FolderSettings.fFlags & FWF_DESKTOP)
1002 SetMenuDefaultItem(hMenu, FCIDM_SHVIEW_OPEN, MF_BYCOMMAND);
1004 if( bDefault )
1006 TRACE("-- get menu default command\n");
1007 uCommand = GetMenuDefaultItem(hMenu, FALSE, GMDI_GOINTOPOPUPS);
1009 else
1011 TRACE("-- track popup\n");
1012 uCommand = TrackPopupMenu( hMenu,TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
1015 if(uCommand > 0)
1017 TRACE("-- uCommand=%u\n", uCommand);
1018 if (uCommand==FCIDM_SHVIEW_OPEN && IsInCommDlg(This))
1020 TRACE("-- dlg: OnDefaultCommand\n");
1021 if (OnDefaultCommand(This) != S_OK)
1023 ShellView_OpenSelectedItems(This);
1026 else
1028 TRACE("-- explore -- invoke command\n");
1029 ZeroMemory(&cmi, sizeof(cmi));
1030 cmi.cbSize = sizeof(cmi);
1031 cmi.hwnd = This->hWndParent; /* this window has to answer CWM_GETISHELLBROWSER */
1032 cmi.lpVerb = MAKEINTRESOURCEA(uCommand);
1033 IContextMenu_InvokeCommand(pContextMenu, &cmi);
1036 DestroyMenu(hMenu);
1039 if (pContextMenu)
1040 IContextMenu_Release(pContextMenu);
1043 else /* background context menu */
1045 hMenu = CreatePopupMenu();
1047 pCM = ISvBgCm_Constructor(This->pSFParent, FALSE);
1048 IContextMenu2_QueryContextMenu(pCM, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, 0);
1050 uCommand = TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
1051 DestroyMenu(hMenu);
1053 TRACE("-- (%p)->(uCommand=0x%08x )\n",This, uCommand);
1055 ZeroMemory(&cmi, sizeof(cmi));
1056 cmi.cbSize = sizeof(cmi);
1057 cmi.lpVerb = MAKEINTRESOURCEA(uCommand);
1058 cmi.hwnd = This->hWndParent;
1059 IContextMenu2_InvokeCommand(pCM, &cmi);
1061 IContextMenu2_Release(pCM);
1065 /**********************************************************
1066 * ##### message handling #####
1069 /**********************************************************
1070 * ShellView_OnSize()
1072 static LRESULT ShellView_OnSize(IShellViewImpl * This, WORD wWidth, WORD wHeight)
1074 TRACE("%p width=%u height=%u\n",This, wWidth,wHeight);
1076 /*resize the ListView to fit our window*/
1077 if(This->hWndList)
1079 MoveWindow(This->hWndList, 0, 0, wWidth, wHeight, TRUE);
1082 return S_OK;
1084 /**********************************************************
1085 * ShellView_OnDeactivate()
1087 * NOTES
1088 * internal
1090 static void ShellView_OnDeactivate(IShellViewImpl * This)
1092 TRACE("%p\n",This);
1094 if(This->uState != SVUIA_DEACTIVATE)
1096 if(This->hMenu)
1098 IShellBrowser_SetMenuSB(This->pShellBrowser,0, 0, 0);
1099 IShellBrowser_RemoveMenusSB(This->pShellBrowser,This->hMenu);
1100 DestroyMenu(This->hMenu);
1101 This->hMenu = 0;
1104 This->uState = SVUIA_DEACTIVATE;
1108 /**********************************************************
1109 * ShellView_OnActivate()
1111 static LRESULT ShellView_OnActivate(IShellViewImpl * This, UINT uState)
1112 { OLEMENUGROUPWIDTHS omw = { {0, 0, 0, 0, 0, 0} };
1113 MENUITEMINFOA mii;
1114 CHAR szText[MAX_PATH];
1116 TRACE("%p uState=%x\n",This,uState);
1118 /*don't do anything if the state isn't really changing */
1119 if(This->uState == uState)
1121 return S_OK;
1124 ShellView_OnDeactivate(This);
1126 /*only do This if we are active */
1127 if(uState != SVUIA_DEACTIVATE)
1129 /*merge the menus */
1130 This->hMenu = CreateMenu();
1132 if(This->hMenu)
1134 IShellBrowser_InsertMenusSB(This->pShellBrowser, This->hMenu, &omw);
1135 TRACE("-- after fnInsertMenusSB\n");
1137 /*build the top level menu get the menu item's text*/
1138 strcpy(szText,"dummy 31");
1140 ZeroMemory(&mii, sizeof(mii));
1141 mii.cbSize = sizeof(mii);
1142 mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_STATE;
1143 mii.fType = MFT_STRING;
1144 mii.fState = MFS_ENABLED;
1145 mii.dwTypeData = szText;
1146 mii.hSubMenu = ShellView_BuildFileMenu(This);
1148 /*insert our menu into the menu bar*/
1149 if(mii.hSubMenu)
1151 InsertMenuItemA(This->hMenu, FCIDM_MENU_HELP, FALSE, &mii);
1154 /*get the view menu so we can merge with it*/
1155 ZeroMemory(&mii, sizeof(mii));
1156 mii.cbSize = sizeof(mii);
1157 mii.fMask = MIIM_SUBMENU;
1159 if(GetMenuItemInfoA(This->hMenu, FCIDM_MENU_VIEW, FALSE, &mii))
1161 ShellView_MergeViewMenu(This, mii.hSubMenu);
1164 /*add the items that should only be added if we have the focus*/
1165 if(SVUIA_ACTIVATE_FOCUS == uState)
1167 /*get the file menu so we can merge with it */
1168 ZeroMemory(&mii, sizeof(mii));
1169 mii.cbSize = sizeof(mii);
1170 mii.fMask = MIIM_SUBMENU;
1172 if(GetMenuItemInfoA(This->hMenu, FCIDM_MENU_FILE, FALSE, &mii))
1174 ShellView_MergeFileMenu(This, mii.hSubMenu);
1177 TRACE("-- before fnSetMenuSB\n");
1178 IShellBrowser_SetMenuSB(This->pShellBrowser, This->hMenu, 0, This->hWnd);
1181 This->uState = uState;
1182 TRACE("--\n");
1183 return S_OK;
1186 /**********************************************************
1187 * ShellView_OnSetFocus()
1190 static LRESULT ShellView_OnSetFocus(IShellViewImpl * This)
1192 TRACE("%p\n",This);
1194 /* Tell the browser one of our windows has received the focus. This
1195 should always be done before merging menus (OnActivate merges the
1196 menus) if one of our windows has the focus.*/
1198 IShellBrowser_OnViewWindowActive(This->pShellBrowser,(IShellView*) This);
1199 ShellView_OnActivate(This, SVUIA_ACTIVATE_FOCUS);
1201 /* Set the focus to the listview */
1202 SetFocus(This->hWndList);
1204 /* Notify the ICommDlgBrowser interface */
1205 OnStateChange(This,CDBOSC_SETFOCUS);
1207 return 0;
1210 /**********************************************************
1211 * ShellView_OnKillFocus()
1213 static LRESULT ShellView_OnKillFocus(IShellViewImpl * This)
1215 TRACE("(%p) stub\n",This);
1217 ShellView_OnActivate(This, SVUIA_ACTIVATE_NOFOCUS);
1218 /* Notify the ICommDlgBrowser */
1219 OnStateChange(This,CDBOSC_KILLFOCUS);
1221 return 0;
1224 /**********************************************************
1225 * ShellView_OnCommand()
1227 * NOTES
1228 * the CmdID's are the ones from the context menu
1230 static LRESULT ShellView_OnCommand(IShellViewImpl * This,DWORD dwCmdID, DWORD dwCmd, HWND hwndCmd)
1232 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n",This, dwCmdID, dwCmd, hwndCmd);
1234 switch(dwCmdID)
1236 case FCIDM_SHVIEW_SMALLICON:
1237 This->FolderSettings.ViewMode = FVM_SMALLICON;
1238 SetStyle (This, LVS_SMALLICON, LVS_TYPEMASK);
1239 CheckToolbar(This);
1240 break;
1242 case FCIDM_SHVIEW_BIGICON:
1243 This->FolderSettings.ViewMode = FVM_ICON;
1244 SetStyle (This, LVS_ICON, LVS_TYPEMASK);
1245 CheckToolbar(This);
1246 break;
1248 case FCIDM_SHVIEW_LISTVIEW:
1249 This->FolderSettings.ViewMode = FVM_LIST;
1250 SetStyle (This, LVS_LIST, LVS_TYPEMASK);
1251 CheckToolbar(This);
1252 break;
1254 case FCIDM_SHVIEW_REPORTVIEW:
1255 This->FolderSettings.ViewMode = FVM_DETAILS;
1256 SetStyle (This, LVS_REPORT, LVS_TYPEMASK);
1257 CheckToolbar(This);
1258 break;
1260 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1261 case 0x30:
1262 case 0x31:
1263 case 0x32:
1264 case 0x33:
1265 This->ListViewSortInfo.nHeaderID = (LPARAM) (dwCmdID - 0x30);
1266 This->ListViewSortInfo.bIsAscending = TRUE;
1267 This->ListViewSortInfo.nLastHeaderID = This->ListViewSortInfo.nHeaderID;
1268 SendMessageA(This->hWndList, LVM_SORTITEMS, (WPARAM) &This->ListViewSortInfo, (LPARAM)ShellView_ListViewCompareItems);
1269 break;
1271 default:
1272 TRACE("-- COMMAND 0x%04x unhandled\n", dwCmdID);
1274 return 0;
1277 /**********************************************************
1278 * ShellView_OnNotify()
1281 static LRESULT ShellView_OnNotify(IShellViewImpl * This, UINT CtlID, LPNMHDR lpnmh)
1282 { LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)lpnmh;
1283 NMLVDISPINFOW *lpdi = (NMLVDISPINFOW *)lpnmh;
1284 LPITEMIDLIST pidl;
1286 TRACE("%p CtlID=%u lpnmh->code=%x\n",This,CtlID,lpnmh->code);
1288 switch(lpnmh->code)
1290 case NM_SETFOCUS:
1291 TRACE("-- NM_SETFOCUS %p\n",This);
1292 ShellView_OnSetFocus(This);
1293 break;
1295 case NM_KILLFOCUS:
1296 TRACE("-- NM_KILLFOCUS %p\n",This);
1297 ShellView_OnDeactivate(This);
1298 /* Notify the ICommDlgBrowser interface */
1299 OnStateChange(This,CDBOSC_KILLFOCUS);
1300 break;
1302 case NM_CUSTOMDRAW:
1303 TRACE("-- NM_CUSTOMDRAW %p\n",This);
1304 return CDRF_DODEFAULT;
1306 case NM_RELEASEDCAPTURE:
1307 TRACE("-- NM_RELEASEDCAPTURE %p\n",This);
1308 break;
1310 case NM_CLICK:
1311 TRACE("-- NM_CLICK %p\n",This);
1312 break;
1314 case NM_RCLICK:
1315 TRACE("-- NM_RCLICK %p\n",This);
1316 break;
1318 case NM_DBLCLK:
1319 TRACE("-- NM_DBLCLK %p\n",This);
1320 if (OnDefaultCommand(This) != S_OK) ShellView_OpenSelectedItems(This);
1321 break;
1323 case NM_RETURN:
1324 TRACE("-- NM_DBLCLK %p\n",This);
1325 if (OnDefaultCommand(This) != S_OK) ShellView_OpenSelectedItems(This);
1326 break;
1328 case HDN_ENDTRACKW:
1329 TRACE("-- HDN_ENDTRACKW %p\n",This);
1330 /*nColumn1 = ListView_GetColumnWidth(This->hWndList, 0);
1331 nColumn2 = ListView_GetColumnWidth(This->hWndList, 1);*/
1332 break;
1334 case LVN_DELETEITEM:
1335 TRACE("-- LVN_DELETEITEM %p\n",This);
1336 SHFree((LPITEMIDLIST)lpnmlv->lParam); /*delete the pidl because we made a copy of it*/
1337 break;
1339 case LVN_DELETEALLITEMS:
1340 TRACE("-- LVN_DELETEALLITEMS %p\n",This);
1341 return FALSE;
1343 case LVN_INSERTITEM:
1344 TRACE("-- LVN_INSERTITEM (STUB)%p\n",This);
1345 break;
1347 case LVN_ITEMACTIVATE:
1348 TRACE("-- LVN_ITEMACTIVATE %p\n",This);
1349 OnStateChange(This, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
1350 break;
1352 case LVN_COLUMNCLICK:
1353 This->ListViewSortInfo.nHeaderID = lpnmlv->iSubItem;
1354 if(This->ListViewSortInfo.nLastHeaderID == This->ListViewSortInfo.nHeaderID)
1356 This->ListViewSortInfo.bIsAscending = !This->ListViewSortInfo.bIsAscending;
1358 else
1360 This->ListViewSortInfo.bIsAscending = TRUE;
1362 This->ListViewSortInfo.nLastHeaderID = This->ListViewSortInfo.nHeaderID;
1364 SendMessageW(lpnmlv->hdr.hwndFrom, LVM_SORTITEMS, (WPARAM) &This->ListViewSortInfo, (LPARAM)ShellView_ListViewCompareItems);
1365 break;
1367 case LVN_GETDISPINFOA:
1368 case LVN_GETDISPINFOW:
1369 TRACE("-- LVN_GETDISPINFO %p\n",This);
1370 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1372 if(lpdi->item.mask & LVIF_TEXT) /* text requested */
1374 if (This->pSF2Parent)
1376 SHELLDETAILS sd;
1377 IShellFolder2_GetDetailsOf(This->pSF2Parent, pidl, lpdi->item.iSubItem, &sd);
1378 if (lpnmh->code == LVN_GETDISPINFOA)
1380 /* shouldn't happen */
1381 NMLVDISPINFOA *lpdiA = (NMLVDISPINFOA *)lpnmh;
1382 StrRetToStrNA( lpdiA->item.pszText, lpdiA->item.cchTextMax, &sd.str, NULL);
1383 TRACE("-- text=%s\n",lpdiA->item.pszText);
1385 else /* LVN_GETDISPINFOW */
1387 StrRetToStrNW( lpdi->item.pszText, lpdi->item.cchTextMax, &sd.str, NULL);
1388 TRACE("-- text=%s\n",debugstr_w(lpdi->item.pszText));
1391 else
1393 FIXME("no SF2\n");
1396 if(lpdi->item.mask & LVIF_IMAGE) /* image requested */
1398 lpdi->item.iImage = SHMapPIDLToSystemImageListIndex(This->pSFParent, pidl, 0);
1400 break;
1402 case LVN_ITEMCHANGED:
1403 TRACE("-- LVN_ITEMCHANGED %p\n",This);
1404 OnStateChange(This, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
1405 break;
1407 case LVN_BEGINDRAG:
1408 case LVN_BEGINRDRAG:
1409 TRACE("-- LVN_BEGINDRAG\n");
1411 if (ShellView_GetSelections(This))
1413 IDataObject * pda;
1414 DWORD dwAttributes = SFGAO_CANLINK;
1415 DWORD dwEffect = DROPEFFECT_COPY | DROPEFFECT_MOVE;
1417 if (SUCCEEDED(IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, (LPCITEMIDLIST*)This->apidl, &IID_IDataObject,0,(LPVOID *)&pda)))
1419 IDropSource * pds = (IDropSource*)&(This->lpvtblDropSource); /* own DropSource interface */
1421 if (SUCCEEDED(IShellFolder_GetAttributesOf(This->pSFParent, This->cidl, (LPCITEMIDLIST*)This->apidl, &dwAttributes)))
1423 if (dwAttributes & SFGAO_CANLINK)
1425 dwEffect |= DROPEFFECT_LINK;
1429 if (pds)
1431 DWORD dwEffect;
1432 DoDragDrop(pda, pds, dwEffect, &dwEffect);
1434 IDataObject_Release(pda);
1437 break;
1439 case LVN_BEGINLABELEDITW:
1441 DWORD dwAttr = SFGAO_CANRENAME;
1442 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1444 TRACE("-- LVN_BEGINLABELEDITA %p\n",This);
1446 IShellFolder_GetAttributesOf(This->pSFParent, 1, (LPCITEMIDLIST*)&pidl, &dwAttr);
1447 if (SFGAO_CANRENAME & dwAttr)
1449 return FALSE;
1451 return TRUE;
1454 case LVN_ENDLABELEDITW:
1456 TRACE("-- LVN_ENDLABELEDITA %p\n",This);
1457 if (lpdi->item.pszText)
1459 HRESULT hr;
1460 LVITEMW lvItem;
1462 lvItem.iItem = lpdi->item.iItem;
1463 lvItem.iSubItem = 0;
1464 lvItem.mask = LVIF_PARAM;
1465 SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem);
1467 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1468 hr = IShellFolder_SetNameOf(This->pSFParent, 0, pidl, lpdi->item.pszText, SHGDN_INFOLDER, &pidl);
1470 if(SUCCEEDED(hr) && pidl)
1472 lvItem.mask = LVIF_PARAM;
1473 lvItem.lParam = (LPARAM)pidl;
1474 SendMessageW(This->hWndList, LVM_SETITEMW, 0, (LPARAM) &lvItem);
1475 return TRUE;
1478 return FALSE;
1481 case LVN_KEYDOWN:
1483 /* MSG msg;
1484 msg.hwnd = This->hWnd;
1485 msg.message = WM_KEYDOWN;
1486 msg.wParam = plvKeyDown->wVKey;
1487 msg.lParam = 0;
1488 msg.time = 0;
1489 msg.pt = 0;*/
1491 LPNMLVKEYDOWN plvKeyDown = (LPNMLVKEYDOWN) lpnmh;
1493 /* initiate a rename of the selected file or directory */
1494 if(plvKeyDown->wVKey == VK_F2)
1496 /* see how many files are selected */
1497 int i = ListView_GetSelectedCount(This->hWndList);
1499 /* get selected item */
1500 if(i == 1)
1502 /* get selected item */
1503 i = ListView_GetNextItem(This->hWndList, -1,
1504 LVNI_SELECTED);
1506 SendMessageW(This->hWndList, LVM_ENSUREVISIBLE, i, 0);
1507 SendMessageW(This->hWndList, LVM_EDITLABELW, i, 0);
1510 #if 0
1511 TranslateAccelerator(This->hWnd, This->hAccel, &msg)
1512 #endif
1513 else if(plvKeyDown->wVKey == VK_DELETE)
1515 UINT i;
1516 int item_index;
1517 LVITEMA item;
1518 LPITEMIDLIST* pItems;
1519 ISFHelper *psfhlp;
1521 IShellFolder_QueryInterface(This->pSFParent, &IID_ISFHelper,
1522 (LPVOID*)&psfhlp);
1524 if (psfhlp == NULL)
1525 break;
1527 if(!(i = ListView_GetSelectedCount(This->hWndList)))
1528 break;
1530 /* allocate memory for the pidl array */
1531 pItems = HeapAlloc(GetProcessHeap(), 0,
1532 sizeof(LPITEMIDLIST) * i);
1534 /* retrieve all selected items */
1535 i = 0;
1536 item_index = -1;
1537 while(ListView_GetSelectedCount(This->hWndList) > i)
1539 /* get selected item */
1540 item_index = ListView_GetNextItem(This->hWndList,
1541 item_index, LVNI_SELECTED);
1542 item.iItem = item_index;
1543 item.mask = LVIF_PARAM;
1544 SendMessageA(This->hWndList, LVM_GETITEMA, 0, (LPARAM) &item);
1546 /* get item pidl */
1547 pItems[i] = (LPITEMIDLIST)item.lParam;
1549 i++;
1552 /* perform the item deletion */
1553 ISFHelper_DeleteItems(psfhlp, i, (LPCITEMIDLIST*)pItems);
1555 /* free pidl array memory */
1556 HeapFree(GetProcessHeap(), 0, pItems);
1559 /* Initiate a refresh */
1560 else if(plvKeyDown->wVKey == VK_F5)
1562 IShellView_Refresh((IShellView*)This);
1565 else if(plvKeyDown->wVKey == VK_BACK)
1567 LPSHELLBROWSER lpSb;
1568 if((lpSb = (LPSHELLBROWSER)SendMessageW(This->hWndParent, CWM_GETISHELLBROWSER, 0, 0)))
1570 IShellBrowser_BrowseObject(lpSb, NULL, SBSP_PARENT);
1574 else
1575 FIXME("LVN_KEYDOWN key=0x%08x\n",plvKeyDown->wVKey);
1577 break;
1579 default:
1580 TRACE("-- %p WM_COMMAND %x unhandled\n", This, lpnmh->code);
1581 break;
1583 return 0;
1586 /**********************************************************
1587 * ShellView_OnChange()
1590 static LRESULT ShellView_OnChange(IShellViewImpl * This, const LPCITEMIDLIST * Pidls, LONG wEventId)
1593 TRACE("(%p)(%p,%p,0x%08x)\n", This, Pidls[0], Pidls[1], wEventId);
1594 switch(wEventId)
1596 case SHCNE_MKDIR:
1597 case SHCNE_CREATE:
1598 LV_AddItem(This, Pidls[0]);
1599 break;
1600 case SHCNE_RMDIR:
1601 case SHCNE_DELETE:
1602 LV_DeleteItem(This, Pidls[0]);
1603 break;
1604 case SHCNE_RENAMEFOLDER:
1605 case SHCNE_RENAMEITEM:
1606 LV_RenameItem(This, Pidls[0], Pidls[1]);
1607 break;
1608 case SHCNE_UPDATEITEM:
1609 break;
1611 return TRUE;
1613 /**********************************************************
1614 * ShellView_WndProc
1617 static LRESULT CALLBACK ShellView_WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
1619 IShellViewImpl * pThis = (IShellViewImpl*)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
1620 LPCREATESTRUCTW lpcs;
1622 TRACE("(hwnd=%p msg=%x wparm=%lx lparm=%lx)\n",hWnd, uMessage, wParam, lParam);
1624 switch (uMessage)
1626 case WM_NCCREATE:
1627 lpcs = (LPCREATESTRUCTW)lParam;
1628 pThis = lpcs->lpCreateParams;
1629 SetWindowLongPtrW(hWnd, GWLP_USERDATA, (ULONG_PTR)pThis);
1630 pThis->hWnd = hWnd; /*set the window handle*/
1631 break;
1633 case WM_SIZE: return ShellView_OnSize(pThis,LOWORD(lParam), HIWORD(lParam));
1634 case WM_SETFOCUS: return ShellView_OnSetFocus(pThis);
1635 case WM_KILLFOCUS: return ShellView_OnKillFocus(pThis);
1636 case WM_CREATE: return ShellView_OnCreate(pThis);
1637 case WM_ACTIVATE: return ShellView_OnActivate(pThis, SVUIA_ACTIVATE_FOCUS);
1638 case WM_NOTIFY: return ShellView_OnNotify(pThis,(UINT)wParam, (LPNMHDR)lParam);
1639 case WM_COMMAND: return ShellView_OnCommand(pThis,
1640 GET_WM_COMMAND_ID(wParam, lParam),
1641 GET_WM_COMMAND_CMD(wParam, lParam),
1642 GET_WM_COMMAND_HWND(wParam, lParam));
1643 case SHV_CHANGE_NOTIFY: return ShellView_OnChange(pThis, (const LPCITEMIDLIST*)wParam, (LONG)lParam);
1645 case WM_CONTEXTMENU: ShellView_DoContextMenu(pThis, LOWORD(lParam), HIWORD(lParam), FALSE);
1646 return 0;
1648 case WM_SHOWWINDOW: UpdateWindow(pThis->hWndList);
1649 break;
1651 case WM_GETDLGCODE: return SendMessageA(pThis->hWndList,uMessage,0,0);
1653 case WM_DESTROY:
1654 RevokeDragDrop(pThis->hWnd);
1655 SHChangeNotifyDeregister(pThis->hNotify);
1656 break;
1658 case WM_ERASEBKGND:
1659 if ((pThis->FolderSettings.fFlags & FWF_DESKTOP) ||
1660 (pThis->FolderSettings.fFlags & FWF_TRANSPARENT))
1661 return 1;
1662 break;
1665 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
1667 /**********************************************************
1670 * The INTERFACE of the IShellView object
1673 **********************************************************
1674 * IShellView_QueryInterface
1676 static HRESULT WINAPI IShellView_fnQueryInterface(IShellView2 * iface,REFIID riid, LPVOID *ppvObj)
1678 IShellViewImpl *This = (IShellViewImpl *)iface;
1680 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1682 *ppvObj = NULL;
1684 if(IsEqualIID(riid, &IID_IUnknown))
1686 *ppvObj = This;
1688 else if(IsEqualIID(riid, &IID_IShellView))
1690 *ppvObj = This;
1692 else if(IsEqualIID(riid, &IID_IShellView2))
1694 *ppvObj = This;
1696 else if(IsEqualIID(riid, &IID_IOleCommandTarget))
1698 *ppvObj = &This->lpvtblOleCommandTarget;
1700 else if(IsEqualIID(riid, &IID_IDropTarget))
1702 *ppvObj = &This->lpvtblDropTarget;
1704 else if(IsEqualIID(riid, &IID_IDropSource))
1706 *ppvObj = &This->lpvtblDropSource;
1708 else if(IsEqualIID(riid, &IID_IViewObject))
1710 *ppvObj = &This->lpvtblViewObject;
1713 if(*ppvObj)
1715 IUnknown_AddRef( (IUnknown*)*ppvObj );
1716 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1717 return S_OK;
1719 TRACE("-- Interface: E_NOINTERFACE\n");
1720 return E_NOINTERFACE;
1723 /**********************************************************
1724 * IShellView_AddRef
1726 static ULONG WINAPI IShellView_fnAddRef(IShellView2 * iface)
1728 IShellViewImpl *This = (IShellViewImpl *)iface;
1729 ULONG refCount = InterlockedIncrement(&This->ref);
1731 TRACE("(%p)->(count=%u)\n", This, refCount - 1);
1733 return refCount;
1735 /**********************************************************
1736 * IShellView_Release
1738 static ULONG WINAPI IShellView_fnRelease(IShellView2 * iface)
1740 IShellViewImpl *This = (IShellViewImpl *)iface;
1741 ULONG refCount = InterlockedDecrement(&This->ref);
1743 TRACE("(%p)->(count=%i)\n", This, refCount + 1);
1745 if (!refCount)
1747 TRACE(" destroying IShellView(%p)\n",This);
1749 DestroyWindow(This->hWndList);
1751 if(This->pSFParent)
1752 IShellFolder_Release(This->pSFParent);
1754 if(This->pSF2Parent)
1755 IShellFolder2_Release(This->pSF2Parent);
1757 SHFree(This->apidl);
1759 if(This->pAdvSink)
1760 IAdviseSink_Release(This->pAdvSink);
1762 HeapFree(GetProcessHeap(),0,This);
1764 return refCount;
1767 /**********************************************************
1768 * ShellView_GetWindow
1770 static HRESULT WINAPI IShellView_fnGetWindow(IShellView2 * iface,HWND * phWnd)
1772 IShellViewImpl *This = (IShellViewImpl *)iface;
1774 TRACE("(%p)\n",This);
1776 *phWnd = This->hWnd;
1778 return S_OK;
1781 static HRESULT WINAPI IShellView_fnContextSensitiveHelp(IShellView2 * iface,BOOL fEnterMode)
1783 IShellViewImpl *This = (IShellViewImpl *)iface;
1785 FIXME("(%p) stub\n",This);
1787 return E_NOTIMPL;
1790 /**********************************************************
1791 * IShellView_TranslateAccelerator
1793 * FIXME:
1794 * use the accel functions
1796 static HRESULT WINAPI IShellView_fnTranslateAccelerator(IShellView2 * iface,LPMSG lpmsg)
1798 #if 0
1799 IShellViewImpl *This = (IShellViewImpl *)iface;
1801 FIXME("(%p)->(%p: hwnd=%x msg=%x lp=%x wp=%x) stub\n",This,lpmsg, lpmsg->hwnd, lpmsg->message, lpmsg->lParam, lpmsg->wParam);
1802 #endif
1804 if ((lpmsg->message>=WM_KEYFIRST) && (lpmsg->message>=WM_KEYLAST))
1806 TRACE("-- key=0x04%lx\n",lpmsg->wParam) ;
1808 return S_FALSE; /* not handled */
1811 static HRESULT WINAPI IShellView_fnEnableModeless(IShellView2 * iface,BOOL fEnable)
1813 IShellViewImpl *This = (IShellViewImpl *)iface;
1815 FIXME("(%p) stub\n",This);
1817 return E_NOTIMPL;
1820 static HRESULT WINAPI IShellView_fnUIActivate(IShellView2 * iface,UINT uState)
1822 IShellViewImpl *This = (IShellViewImpl *)iface;
1825 CHAR szName[MAX_PATH];
1827 LRESULT lResult;
1828 int nPartArray[1] = {-1};
1830 TRACE("(%p)->(state=%x) stub\n",This, uState);
1832 /*don't do anything if the state isn't really changing*/
1833 if(This->uState == uState)
1835 return S_OK;
1838 /*OnActivate handles the menu merging and internal state*/
1839 ShellView_OnActivate(This, uState);
1841 /*only do This if we are active*/
1842 if(uState != SVUIA_DEACTIVATE)
1846 GetFolderPath is not a method of IShellFolder
1847 IShellFolder_GetFolderPath( This->pSFParent, szName, sizeof(szName) );
1849 /* set the number of parts */
1850 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETPARTS, 1,
1851 (LPARAM)nPartArray, &lResult);
1853 /* set the text for the parts */
1855 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETTEXTA,
1856 0, (LPARAM)szName, &lResult);
1860 return S_OK;
1863 static HRESULT WINAPI IShellView_fnRefresh(IShellView2 * iface)
1865 IShellViewImpl *This = (IShellViewImpl *)iface;
1867 TRACE("(%p)\n",This);
1869 SendMessageW(This->hWndList, LVM_DELETEALLITEMS, 0, 0);
1870 ShellView_FillList(This);
1872 return S_OK;
1875 static HRESULT WINAPI IShellView_fnCreateViewWindow(IShellView2 *iface, IShellView *lpPrevView,
1876 LPCFOLDERSETTINGS lpfs, IShellBrowser *psb, RECT *prcView, HWND *phWnd)
1878 HRESULT hr;
1879 SV2CVW2_PARAMS view_params;
1880 view_params.cbSize = sizeof(view_params);
1881 view_params.psvPrev = lpPrevView;
1882 view_params.pfs = lpfs;
1883 view_params.psbOwner = psb;
1884 view_params.prcView = prcView;
1885 view_params.pvid = NULL;
1886 view_params.hwndView = 0;
1888 TRACE("(%p) Forwarding to CreateViewWindow2\n", iface);
1890 hr = IShellView2_CreateViewWindow2(iface, &view_params);
1891 *phWnd = view_params.hwndView;
1893 return hr;
1896 static HRESULT WINAPI IShellView_fnDestroyViewWindow(IShellView2 * iface)
1898 IShellViewImpl *This = (IShellViewImpl *)iface;
1900 TRACE("(%p)\n",This);
1902 /*Make absolutely sure all our UI is cleaned up.*/
1903 IShellView_UIActivate((IShellView*)This, SVUIA_DEACTIVATE);
1905 if(This->hMenu)
1907 DestroyMenu(This->hMenu);
1910 DestroyWindow(This->hWnd);
1911 if(This->pShellBrowser) IShellBrowser_Release(This->pShellBrowser);
1912 if(This->pCommDlgBrowser) ICommDlgBrowser_Release(This->pCommDlgBrowser);
1915 return S_OK;
1918 static HRESULT WINAPI IShellView_fnGetCurrentInfo(IShellView2 * iface, LPFOLDERSETTINGS lpfs)
1920 IShellViewImpl *This = (IShellViewImpl *)iface;
1922 TRACE("(%p)->(%p) vmode=%x flags=%x\n",This, lpfs,
1923 This->FolderSettings.ViewMode, This->FolderSettings.fFlags);
1925 if (!lpfs) return E_INVALIDARG;
1927 *lpfs = This->FolderSettings;
1928 return NOERROR;
1931 static HRESULT WINAPI IShellView_fnAddPropertySheetPages(IShellView2 * iface, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam)
1933 IShellViewImpl *This = (IShellViewImpl *)iface;
1935 FIXME("(%p) stub\n",This);
1937 return E_NOTIMPL;
1940 static HRESULT WINAPI IShellView_fnSaveViewState(IShellView2 * iface)
1942 IShellViewImpl *This = (IShellViewImpl *)iface;
1944 FIXME("(%p) stub\n",This);
1946 return S_OK;
1949 static HRESULT WINAPI IShellView_fnSelectItem(
1950 IShellView2 * iface,
1951 LPCITEMIDLIST pidl,
1952 UINT uFlags)
1954 IShellViewImpl *This = (IShellViewImpl *)iface;
1955 int i;
1957 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n",This, pidl, uFlags);
1959 i = LV_FindItemByPidl(This, pidl);
1961 if (i != -1)
1963 LVITEMW lvItem;
1965 if(uFlags & SVSI_ENSUREVISIBLE)
1966 SendMessageW(This->hWndList, LVM_ENSUREVISIBLE, i, 0);
1968 lvItem.mask = LVIF_STATE;
1969 lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
1970 lvItem.iItem = 0;
1971 lvItem.iSubItem = 0;
1973 while(SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem))
1975 if (lvItem.iItem == i)
1977 if (uFlags & SVSI_SELECT)
1978 lvItem.state |= LVIS_SELECTED;
1979 else
1980 lvItem.state &= ~LVIS_SELECTED;
1982 if(uFlags & SVSI_FOCUSED)
1983 lvItem.state &= ~LVIS_FOCUSED;
1985 else
1987 if (uFlags & SVSI_DESELECTOTHERS)
1988 lvItem.state &= ~LVIS_SELECTED;
1990 SendMessageW(This->hWndList, LVM_SETITEMW, 0, (LPARAM) &lvItem);
1991 lvItem.iItem++;
1995 if(uFlags & SVSI_EDIT)
1996 SendMessageW(This->hWndList, LVM_EDITLABELW, i, 0);
1999 return S_OK;
2002 static HRESULT WINAPI IShellView_fnGetItemObject(IShellView2 * iface, UINT uItem, REFIID riid, LPVOID *ppvOut)
2004 IShellViewImpl *This = (IShellViewImpl *)iface;
2006 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n",This, uItem, debugstr_guid(riid), ppvOut);
2008 *ppvOut = NULL;
2010 switch(uItem)
2012 case SVGIO_BACKGROUND:
2013 *ppvOut = ISvBgCm_Constructor(This->pSFParent, FALSE);
2014 break;
2016 case SVGIO_SELECTION:
2017 ShellView_GetSelections(This);
2018 IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, (LPCITEMIDLIST*)This->apidl, riid, 0, ppvOut);
2019 break;
2021 TRACE("-- (%p)->(interface=%p)\n",This, *ppvOut);
2023 if(!*ppvOut) return E_OUTOFMEMORY;
2025 return S_OK;
2028 static HRESULT WINAPI IShellView2_fnGetView(IShellView2* iface, SHELLVIEWID *view_guid, ULONG view_type)
2030 FIXME("(%p)->(view_guid %s, view_type %#x) stub!\n", iface, debugstr_guid(view_guid), view_type);
2031 return E_NOTIMPL;
2034 static HRESULT WINAPI IShellView2_fnCreateViewWindow2(IShellView2* iface, LPSV2CVW2_PARAMS view_params)
2036 IShellViewImpl *This = (IShellViewImpl *)iface;
2037 WNDCLASSW wc;
2038 HWND wnd;
2040 TRACE("(%p)->(view_params %p)\n", iface, view_params);
2042 if (view_params->cbSize != sizeof(*view_params))
2044 FIXME("Got unexpected cbSize %#x\n", view_params->cbSize);
2045 return E_FAIL;
2048 TRACE("-- psvPrev %p, pfs %p, psbOwner %p, prcView %p\n",
2049 view_params->psvPrev, view_params->pfs, view_params->psbOwner, view_params->prcView);
2050 TRACE("-- vmode %#x, flags %#x, left %d, top %d, right %d, bottom %d\n",
2051 view_params->pfs->ViewMode, view_params->pfs->fFlags, view_params->prcView->left,
2052 view_params->prcView->top, view_params->prcView->right, view_params->prcView->bottom);
2054 /* Set up the member variables */
2055 This->pShellBrowser = view_params->psbOwner;
2056 This->FolderSettings = *view_params->pfs;
2058 if (view_params->pvid)
2060 if (IsEqualGUID(view_params->pvid, &VID_LargeIcons))
2061 This->FolderSettings.ViewMode = FVM_ICON;
2062 else if (IsEqualGUID(view_params->pvid, &VID_SmallIcons))
2063 This->FolderSettings.ViewMode = FVM_SMALLICON;
2064 else if (IsEqualGUID(view_params->pvid, &VID_List))
2065 This->FolderSettings.ViewMode = FVM_LIST;
2066 else if (IsEqualGUID(view_params->pvid, &VID_Details))
2067 This->FolderSettings.ViewMode = FVM_DETAILS;
2068 else if (IsEqualGUID(view_params->pvid, &VID_Thumbnails))
2069 This->FolderSettings.ViewMode = FVM_THUMBNAIL;
2070 else if (IsEqualGUID(view_params->pvid, &VID_Tile))
2071 This->FolderSettings.ViewMode = FVM_TILE;
2072 else if (IsEqualGUID(view_params->pvid, &VID_ThumbStrip))
2073 This->FolderSettings.ViewMode = FVM_THUMBSTRIP;
2074 else
2075 FIXME("Ignoring unrecognized VID %s\n", debugstr_guid(view_params->pvid));
2078 /* Get our parent window */
2079 IShellBrowser_AddRef(This->pShellBrowser);
2080 IShellBrowser_GetWindow(This->pShellBrowser, &(This->hWndParent));
2082 /* Try to get the ICommDlgBrowserInterface, adds a reference !!! */
2083 This->pCommDlgBrowser = NULL;
2084 if (SUCCEEDED(IShellBrowser_QueryInterface(This->pShellBrowser, &IID_ICommDlgBrowser, (void **)&This->pCommDlgBrowser)))
2086 TRACE("-- CommDlgBrowser %p\n", This->pCommDlgBrowser);
2089 /* If our window class has not been registered, then do so */
2090 if (!GetClassInfoW(shell32_hInstance, SV_CLASS_NAME, &wc))
2092 ZeroMemory(&wc, sizeof(wc));
2093 wc.style = CS_HREDRAW | CS_VREDRAW;
2094 wc.lpfnWndProc = ShellView_WndProc;
2095 wc.cbClsExtra = 0;
2096 wc.cbWndExtra = 0;
2097 wc.hInstance = shell32_hInstance;
2098 wc.hIcon = 0;
2099 wc.hCursor = LoadCursorW(0, (LPWSTR)IDC_ARROW);
2100 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
2101 wc.lpszMenuName = NULL;
2102 wc.lpszClassName = SV_CLASS_NAME;
2104 if (!RegisterClassW(&wc)) return E_FAIL;
2107 wnd = CreateWindowExW(0, SV_CLASS_NAME, NULL, WS_CHILD | WS_TABSTOP,
2108 view_params->prcView->left, view_params->prcView->top,
2109 view_params->prcView->right - view_params->prcView->left,
2110 view_params->prcView->bottom - view_params->prcView->top,
2111 This->hWndParent, 0, shell32_hInstance, This);
2113 CheckToolbar(This);
2115 if (!wnd) return E_FAIL;
2117 SetWindowPos(wnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
2118 UpdateWindow(wnd);
2120 view_params->hwndView = wnd;
2122 return S_OK;
2125 static HRESULT WINAPI IShellView2_fnHandleRename(IShellView2* iface, LPCITEMIDLIST new_pidl)
2127 FIXME("(%p)->(new_pidl %p) stub!\n", iface, new_pidl);
2128 return E_NOTIMPL;
2131 static HRESULT WINAPI IShellView2_fnSelectAndPositionItem(IShellView2* iface, LPCITEMIDLIST item, UINT flags, POINT *point)
2133 FIXME("(%p)->(item %p, flags %#x, point %p) stub!\n", iface, item, flags, point);
2134 return E_NOTIMPL;
2137 static const IShellView2Vtbl svvt =
2139 IShellView_fnQueryInterface,
2140 IShellView_fnAddRef,
2141 IShellView_fnRelease,
2142 IShellView_fnGetWindow,
2143 IShellView_fnContextSensitiveHelp,
2144 IShellView_fnTranslateAccelerator,
2145 IShellView_fnEnableModeless,
2146 IShellView_fnUIActivate,
2147 IShellView_fnRefresh,
2148 IShellView_fnCreateViewWindow,
2149 IShellView_fnDestroyViewWindow,
2150 IShellView_fnGetCurrentInfo,
2151 IShellView_fnAddPropertySheetPages,
2152 IShellView_fnSaveViewState,
2153 IShellView_fnSelectItem,
2154 IShellView_fnGetItemObject,
2155 IShellView2_fnGetView,
2156 IShellView2_fnCreateViewWindow2,
2157 IShellView2_fnHandleRename,
2158 IShellView2_fnSelectAndPositionItem,
2162 /**********************************************************
2163 * ISVOleCmdTarget_QueryInterface (IUnknown)
2165 static HRESULT WINAPI ISVOleCmdTarget_QueryInterface(
2166 IOleCommandTarget * iface,
2167 REFIID iid,
2168 LPVOID* ppvObj)
2170 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2172 return IShellFolder_QueryInterface((IShellFolder*)This, iid, ppvObj);
2175 /**********************************************************
2176 * ISVOleCmdTarget_AddRef (IUnknown)
2178 static ULONG WINAPI ISVOleCmdTarget_AddRef(
2179 IOleCommandTarget * iface)
2181 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2183 return IShellFolder_AddRef((IShellFolder*)This);
2186 /**********************************************************
2187 * ISVOleCmdTarget_Release (IUnknown)
2189 static ULONG WINAPI ISVOleCmdTarget_Release(
2190 IOleCommandTarget * iface)
2192 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2194 return IShellFolder_Release((IShellFolder*)This);
2197 /**********************************************************
2198 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2200 static HRESULT WINAPI ISVOleCmdTarget_QueryStatus(
2201 IOleCommandTarget *iface,
2202 const GUID* pguidCmdGroup,
2203 ULONG cCmds,
2204 OLECMD * prgCmds,
2205 OLECMDTEXT* pCmdText)
2207 UINT i;
2208 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2210 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
2211 This, pguidCmdGroup, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText);
2213 if (!prgCmds)
2214 return E_POINTER;
2215 for (i = 0; i < cCmds; i++)
2217 FIXME("\tprgCmds[%d].cmdID = %d\n", i, prgCmds[i].cmdID);
2218 prgCmds[i].cmdf = 0;
2220 return OLECMDERR_E_UNKNOWNGROUP;
2223 /**********************************************************
2224 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2226 * nCmdID is the OLECMDID_* enumeration
2228 static HRESULT WINAPI ISVOleCmdTarget_Exec(
2229 IOleCommandTarget *iface,
2230 const GUID* pguidCmdGroup,
2231 DWORD nCmdID,
2232 DWORD nCmdexecopt,
2233 VARIANT* pvaIn,
2234 VARIANT* pvaOut)
2236 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2238 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2239 This, debugstr_guid(pguidCmdGroup), nCmdID, nCmdexecopt, pvaIn, pvaOut);
2241 if (IsEqualIID(pguidCmdGroup, &CGID_Explorer) &&
2242 (nCmdID == 0x29) &&
2243 (nCmdexecopt == 4) && pvaOut)
2244 return S_OK;
2245 if (IsEqualIID(pguidCmdGroup, &CGID_ShellDocView) &&
2246 (nCmdID == 9) &&
2247 (nCmdexecopt == 0))
2248 return 1;
2250 return OLECMDERR_E_UNKNOWNGROUP;
2253 static const IOleCommandTargetVtbl ctvt =
2255 ISVOleCmdTarget_QueryInterface,
2256 ISVOleCmdTarget_AddRef,
2257 ISVOleCmdTarget_Release,
2258 ISVOleCmdTarget_QueryStatus,
2259 ISVOleCmdTarget_Exec
2262 /**********************************************************
2263 * ISVDropTarget implementation
2266 static HRESULT WINAPI ISVDropTarget_QueryInterface(
2267 IDropTarget *iface,
2268 REFIID riid,
2269 LPVOID *ppvObj)
2271 IShellViewImpl *This = impl_from_IDropTarget(iface);
2273 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2275 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2278 static ULONG WINAPI ISVDropTarget_AddRef( IDropTarget *iface)
2280 IShellViewImpl *This = impl_from_IDropTarget(iface);
2282 TRACE("(%p)->(count=%u)\n",This,This->ref);
2284 return IShellFolder_AddRef((IShellFolder*)This);
2287 static ULONG WINAPI ISVDropTarget_Release( IDropTarget *iface)
2289 IShellViewImpl *This = impl_from_IDropTarget(iface);
2291 TRACE("(%p)->(count=%u)\n",This,This->ref);
2293 return IShellFolder_Release((IShellFolder*)This);
2296 /******************************************************************************
2297 * drag_notify_subitem [Internal]
2299 * Figure out the shellfolder object, which is currently under the mouse cursor
2300 * and notify it via the IDropTarget interface.
2303 #define SCROLLAREAWIDTH 20
2305 static HRESULT drag_notify_subitem(IShellViewImpl *This, DWORD grfKeyState, POINTL pt,
2306 DWORD *pdwEffect)
2308 LVHITTESTINFO htinfo;
2309 LVITEMW lvItem;
2310 LONG lResult;
2311 HRESULT hr;
2312 RECT clientRect;
2314 /* Map from global to client coordinates and query the index of the listview-item, which is
2315 * currently under the mouse cursor. */
2316 htinfo.pt.x = pt.x;
2317 htinfo.pt.y = pt.y;
2318 htinfo.flags = LVHT_ONITEM;
2319 ScreenToClient(This->hWndList, &htinfo.pt);
2320 lResult = SendMessageW(This->hWndList, LVM_HITTEST, 0, (LPARAM)&htinfo);
2322 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2323 GetClientRect(This->hWndList, &clientRect);
2324 if (htinfo.pt.x == This->ptLastMousePos.x && htinfo.pt.y == This->ptLastMousePos.y &&
2325 (htinfo.pt.x < SCROLLAREAWIDTH || htinfo.pt.x > clientRect.right - SCROLLAREAWIDTH ||
2326 htinfo.pt.y < SCROLLAREAWIDTH || htinfo.pt.y > clientRect.bottom - SCROLLAREAWIDTH ))
2328 This->cScrollDelay = (This->cScrollDelay + 1) % 5; /* DragOver is called every 50 ms */
2329 if (This->cScrollDelay == 0) { /* Mouse did hover another 250 ms over the scroll-area */
2330 if (htinfo.pt.x < SCROLLAREAWIDTH)
2331 SendMessageW(This->hWndList, WM_HSCROLL, SB_LINEUP, 0);
2332 if (htinfo.pt.x > clientRect.right - SCROLLAREAWIDTH)
2333 SendMessageW(This->hWndList, WM_HSCROLL, SB_LINEDOWN, 0);
2334 if (htinfo.pt.y < SCROLLAREAWIDTH)
2335 SendMessageW(This->hWndList, WM_VSCROLL, SB_LINEUP, 0);
2336 if (htinfo.pt.y > clientRect.bottom - SCROLLAREAWIDTH)
2337 SendMessageW(This->hWndList, WM_VSCROLL, SB_LINEDOWN, 0);
2339 } else {
2340 This->cScrollDelay = 0; /* Reset, if the cursor is not over the listview's scroll-area */
2342 This->ptLastMousePos = htinfo.pt;
2344 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2345 if (This->pCurDropTarget && lResult == This->iDragOverItem)
2346 return IDropTarget_DragOver(This->pCurDropTarget, grfKeyState, pt, pdwEffect);
2348 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2349 if (This->pCurDropTarget) {
2350 IDropTarget_DragLeave(This->pCurDropTarget);
2351 IDropTarget_Release(This->pCurDropTarget);
2352 This->pCurDropTarget = NULL;
2355 This->iDragOverItem = lResult;
2356 if (lResult == -1) {
2357 /* We are not above one of the listview's subitems. Bind to the parent folder's
2358 * DropTarget interface. */
2359 hr = IShellFolder_QueryInterface(This->pSFParent, &IID_IDropTarget,
2360 (LPVOID*)&This->pCurDropTarget);
2361 } else {
2362 /* Query the relative PIDL of the shellfolder object represented by the currently
2363 * dragged over listview-item ... */
2364 lvItem.mask = LVIF_PARAM;
2365 lvItem.iItem = lResult;
2366 lvItem.iSubItem = 0;
2367 SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem);
2369 /* ... and bind pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2370 hr = IShellFolder_GetUIObjectOf(This->pSFParent, This->hWndList, 1,
2371 (LPCITEMIDLIST*)&lvItem.lParam, &IID_IDropTarget, NULL, (LPVOID*)&This->pCurDropTarget);
2374 /* If anything failed, pCurDropTarget should be NULL now, which ought to be a save state. */
2375 if (FAILED(hr))
2376 return hr;
2378 /* Notify the item just entered via DragEnter. */
2379 return IDropTarget_DragEnter(This->pCurDropTarget, This->pCurDataObject, grfKeyState, pt, pdwEffect);
2382 static HRESULT WINAPI ISVDropTarget_DragEnter(IDropTarget *iface, IDataObject *pDataObject,
2383 DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
2385 IShellViewImpl *This = impl_from_IDropTarget(iface);
2387 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2388 This->pCurDataObject = pDataObject;
2389 IDataObject_AddRef(pDataObject);
2391 return drag_notify_subitem(This, grfKeyState, pt, pdwEffect);
2394 static HRESULT WINAPI ISVDropTarget_DragOver(IDropTarget *iface, DWORD grfKeyState, POINTL pt,
2395 DWORD *pdwEffect)
2397 IShellViewImpl *This = impl_from_IDropTarget(iface);
2398 return drag_notify_subitem(This, grfKeyState, pt, pdwEffect);
2401 static HRESULT WINAPI ISVDropTarget_DragLeave(IDropTarget *iface) {
2402 IShellViewImpl *This = impl_from_IDropTarget(iface);
2404 IDropTarget_DragLeave(This->pCurDropTarget);
2406 IDropTarget_Release(This->pCurDropTarget);
2407 IDataObject_Release(This->pCurDataObject);
2408 This->pCurDataObject = NULL;
2409 This->pCurDropTarget = NULL;
2410 This->iDragOverItem = 0;
2412 return S_OK;
2415 static HRESULT WINAPI ISVDropTarget_Drop(IDropTarget *iface, IDataObject* pDataObject,
2416 DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
2418 IShellViewImpl *This = impl_from_IDropTarget(iface);
2420 IDropTarget_Drop(This->pCurDropTarget, pDataObject, grfKeyState, pt, pdwEffect);
2422 IDropTarget_Release(This->pCurDropTarget);
2423 IDataObject_Release(This->pCurDataObject);
2424 This->pCurDataObject = NULL;
2425 This->pCurDropTarget = NULL;
2426 This->iDragOverItem = 0;
2428 return S_OK;
2431 static const IDropTargetVtbl dtvt =
2433 ISVDropTarget_QueryInterface,
2434 ISVDropTarget_AddRef,
2435 ISVDropTarget_Release,
2436 ISVDropTarget_DragEnter,
2437 ISVDropTarget_DragOver,
2438 ISVDropTarget_DragLeave,
2439 ISVDropTarget_Drop
2442 /**********************************************************
2443 * ISVDropSource implementation
2446 static HRESULT WINAPI ISVDropSource_QueryInterface(
2447 IDropSource *iface,
2448 REFIID riid,
2449 LPVOID *ppvObj)
2451 IShellViewImpl *This = impl_from_IDropSource(iface);
2453 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2455 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2458 static ULONG WINAPI ISVDropSource_AddRef( IDropSource *iface)
2460 IShellViewImpl *This = impl_from_IDropSource(iface);
2462 TRACE("(%p)->(count=%u)\n",This,This->ref);
2464 return IShellFolder_AddRef((IShellFolder*)This);
2467 static ULONG WINAPI ISVDropSource_Release( IDropSource *iface)
2469 IShellViewImpl *This = impl_from_IDropSource(iface);
2471 TRACE("(%p)->(count=%u)\n",This,This->ref);
2473 return IShellFolder_Release((IShellFolder*)This);
2475 static HRESULT WINAPI ISVDropSource_QueryContinueDrag(
2476 IDropSource *iface,
2477 BOOL fEscapePressed,
2478 DWORD grfKeyState)
2480 IShellViewImpl *This = impl_from_IDropSource(iface);
2481 TRACE("(%p)\n",This);
2483 if (fEscapePressed)
2484 return DRAGDROP_S_CANCEL;
2485 else if (!(grfKeyState & MK_LBUTTON) && !(grfKeyState & MK_RBUTTON))
2486 return DRAGDROP_S_DROP;
2487 else
2488 return NOERROR;
2491 static HRESULT WINAPI ISVDropSource_GiveFeedback(
2492 IDropSource *iface,
2493 DWORD dwEffect)
2495 IShellViewImpl *This = impl_from_IDropSource(iface);
2496 TRACE("(%p)\n",This);
2498 return DRAGDROP_S_USEDEFAULTCURSORS;
2501 static const IDropSourceVtbl dsvt =
2503 ISVDropSource_QueryInterface,
2504 ISVDropSource_AddRef,
2505 ISVDropSource_Release,
2506 ISVDropSource_QueryContinueDrag,
2507 ISVDropSource_GiveFeedback
2509 /**********************************************************
2510 * ISVViewObject implementation
2513 static HRESULT WINAPI ISVViewObject_QueryInterface(
2514 IViewObject *iface,
2515 REFIID riid,
2516 LPVOID *ppvObj)
2518 IShellViewImpl *This = impl_from_IViewObject(iface);
2520 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2522 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2525 static ULONG WINAPI ISVViewObject_AddRef( IViewObject *iface)
2527 IShellViewImpl *This = impl_from_IViewObject(iface);
2529 TRACE("(%p)->(count=%u)\n",This,This->ref);
2531 return IShellFolder_AddRef((IShellFolder*)This);
2534 static ULONG WINAPI ISVViewObject_Release( IViewObject *iface)
2536 IShellViewImpl *This = impl_from_IViewObject(iface);
2538 TRACE("(%p)->(count=%u)\n",This,This->ref);
2540 return IShellFolder_Release((IShellFolder*)This);
2543 static HRESULT WINAPI ISVViewObject_Draw(
2544 IViewObject *iface,
2545 DWORD dwDrawAspect,
2546 LONG lindex,
2547 void* pvAspect,
2548 DVTARGETDEVICE* ptd,
2549 HDC hdcTargetDev,
2550 HDC hdcDraw,
2551 LPCRECTL lprcBounds,
2552 LPCRECTL lprcWBounds,
2553 BOOL (CALLBACK *pfnContinue)(ULONG_PTR dwContinue),
2554 ULONG_PTR dwContinue)
2557 IShellViewImpl *This = impl_from_IViewObject(iface);
2559 FIXME("Stub: This=%p\n",This);
2561 return E_NOTIMPL;
2563 static HRESULT WINAPI ISVViewObject_GetColorSet(
2564 IViewObject *iface,
2565 DWORD dwDrawAspect,
2566 LONG lindex,
2567 void *pvAspect,
2568 DVTARGETDEVICE* ptd,
2569 HDC hicTargetDevice,
2570 LOGPALETTE** ppColorSet)
2573 IShellViewImpl *This = impl_from_IViewObject(iface);
2575 FIXME("Stub: This=%p\n",This);
2577 return E_NOTIMPL;
2579 static HRESULT WINAPI ISVViewObject_Freeze(
2580 IViewObject *iface,
2581 DWORD dwDrawAspect,
2582 LONG lindex,
2583 void* pvAspect,
2584 DWORD* pdwFreeze)
2587 IShellViewImpl *This = impl_from_IViewObject(iface);
2589 FIXME("Stub: This=%p\n",This);
2591 return E_NOTIMPL;
2593 static HRESULT WINAPI ISVViewObject_Unfreeze(
2594 IViewObject *iface,
2595 DWORD dwFreeze)
2598 IShellViewImpl *This = impl_from_IViewObject(iface);
2600 FIXME("Stub: This=%p\n",This);
2602 return E_NOTIMPL;
2604 static HRESULT WINAPI ISVViewObject_SetAdvise(
2605 IViewObject *iface,
2606 DWORD aspects,
2607 DWORD advf,
2608 IAdviseSink* pAdvSink)
2611 IShellViewImpl *This = impl_from_IViewObject(iface);
2613 FIXME("partial stub: %p %08x %08x %p\n",
2614 This, aspects, advf, pAdvSink);
2616 /* FIXME: we set the AdviseSink, but never use it to send any advice */
2617 This->pAdvSink = pAdvSink;
2618 This->dwAspects = aspects;
2619 This->dwAdvf = advf;
2621 return S_OK;
2624 static HRESULT WINAPI ISVViewObject_GetAdvise(
2625 IViewObject *iface,
2626 DWORD* pAspects,
2627 DWORD* pAdvf,
2628 IAdviseSink** ppAdvSink)
2631 IShellViewImpl *This = impl_from_IViewObject(iface);
2633 TRACE("This=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n",
2634 This, pAspects, pAdvf, ppAdvSink);
2636 if( ppAdvSink )
2638 IAdviseSink_AddRef( This->pAdvSink );
2639 *ppAdvSink = This->pAdvSink;
2641 if( pAspects )
2642 *pAspects = This->dwAspects;
2643 if( pAdvf )
2644 *pAdvf = This->dwAdvf;
2646 return S_OK;
2650 static const IViewObjectVtbl vovt =
2652 ISVViewObject_QueryInterface,
2653 ISVViewObject_AddRef,
2654 ISVViewObject_Release,
2655 ISVViewObject_Draw,
2656 ISVViewObject_GetColorSet,
2657 ISVViewObject_Freeze,
2658 ISVViewObject_Unfreeze,
2659 ISVViewObject_SetAdvise,
2660 ISVViewObject_GetAdvise