Release 1.1.37.
[wine/gsoc-2012-control.git] / dlls / shell32 / shlview.c
blobb14ba781b361e85c09963c85727b2370fca264e2
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 = SendMessageW(This->hWndList, LVM_GETITEMCOUNT, 0, 0); /*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==SendMessageW(This->hWndList, LVM_DELETEITEM, nIndex, 0))? 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 = SendMessageW(This->hWndList, LVM_GETSELECTEDCOUNT, 0, 0);
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 &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 = 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_RETURN %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 dwEffect2;
1432 DoDragDrop(pda, pds, dwEffect, &dwEffect2);
1434 IDataObject_Release(pda);
1437 break;
1439 case LVN_BEGINLABELEDITW:
1441 DWORD dwAttr = SFGAO_CANRENAME;
1442 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1444 TRACE("-- LVN_BEGINLABELEDITW %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 = SendMessageW(This->hWndList, LVM_GETSELECTEDCOUNT, 0, 0);
1499 /* get selected item */
1500 if(i == 1)
1502 /* get selected item */
1503 i = SendMessageW(This->hWndList, LVM_GETNEXTITEM, -1, MAKELPARAM (LVNI_SELECTED, 0));
1505 SendMessageW(This->hWndList, LVM_ENSUREVISIBLE, i, 0);
1506 SendMessageW(This->hWndList, LVM_EDITLABELW, i, 0);
1509 #if 0
1510 TranslateAccelerator(This->hWnd, This->hAccel, &msg)
1511 #endif
1512 else if(plvKeyDown->wVKey == VK_DELETE)
1514 UINT i;
1515 int item_index;
1516 LVITEMA item;
1517 LPITEMIDLIST* pItems;
1518 ISFHelper *psfhlp;
1520 IShellFolder_QueryInterface(This->pSFParent, &IID_ISFHelper,
1521 (LPVOID*)&psfhlp);
1523 if (psfhlp == NULL)
1524 break;
1526 if(!(i = SendMessageW(This->hWndList, LVM_GETSELECTEDCOUNT, 0, 0)))
1527 break;
1529 /* allocate memory for the pidl array */
1530 pItems = HeapAlloc(GetProcessHeap(), 0,
1531 sizeof(LPITEMIDLIST) * i);
1533 /* retrieve all selected items */
1534 i = 0;
1535 item_index = -1;
1536 while(SendMessageW(This->hWndList, LVM_GETSELECTEDCOUNT, 0, 0) > i)
1538 /* get selected item */
1539 item_index = SendMessageW(This->hWndList, LVM_GETNEXTITEM, item_index,
1540 MAKELPARAM (LVNI_SELECTED, 0));
1541 item.iItem = item_index;
1542 item.mask = LVIF_PARAM;
1543 SendMessageA(This->hWndList, LVM_GETITEMA, 0, (LPARAM) &item);
1545 /* get item pidl */
1546 pItems[i] = (LPITEMIDLIST)item.lParam;
1548 i++;
1551 /* perform the item deletion */
1552 ISFHelper_DeleteItems(psfhlp, i, (LPCITEMIDLIST*)pItems);
1554 /* free pidl array memory */
1555 HeapFree(GetProcessHeap(), 0, pItems);
1558 /* Initiate a refresh */
1559 else if(plvKeyDown->wVKey == VK_F5)
1561 IShellView_Refresh((IShellView*)This);
1564 else if(plvKeyDown->wVKey == VK_BACK)
1566 LPSHELLBROWSER lpSb;
1567 if((lpSb = (LPSHELLBROWSER)SendMessageW(This->hWndParent, CWM_GETISHELLBROWSER, 0, 0)))
1569 IShellBrowser_BrowseObject(lpSb, NULL, SBSP_PARENT);
1573 else
1574 FIXME("LVN_KEYDOWN key=0x%08x\n",plvKeyDown->wVKey);
1576 break;
1578 default:
1579 TRACE("-- %p WM_COMMAND %x unhandled\n", This, lpnmh->code);
1580 break;
1582 return 0;
1585 /**********************************************************
1586 * ShellView_OnChange()
1589 static LRESULT ShellView_OnChange(IShellViewImpl * This, const LPCITEMIDLIST * Pidls, LONG wEventId)
1592 TRACE("(%p)(%p,%p,0x%08x)\n", This, Pidls[0], Pidls[1], wEventId);
1593 switch(wEventId)
1595 case SHCNE_MKDIR:
1596 case SHCNE_CREATE:
1597 LV_AddItem(This, Pidls[0]);
1598 break;
1599 case SHCNE_RMDIR:
1600 case SHCNE_DELETE:
1601 LV_DeleteItem(This, Pidls[0]);
1602 break;
1603 case SHCNE_RENAMEFOLDER:
1604 case SHCNE_RENAMEITEM:
1605 LV_RenameItem(This, Pidls[0], Pidls[1]);
1606 break;
1607 case SHCNE_UPDATEITEM:
1608 break;
1610 return TRUE;
1612 /**********************************************************
1613 * ShellView_WndProc
1616 static LRESULT CALLBACK ShellView_WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
1618 IShellViewImpl * pThis = (IShellViewImpl*)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
1619 LPCREATESTRUCTW lpcs;
1621 TRACE("(hwnd=%p msg=%x wparm=%lx lparm=%lx)\n",hWnd, uMessage, wParam, lParam);
1623 switch (uMessage)
1625 case WM_NCCREATE:
1626 lpcs = (LPCREATESTRUCTW)lParam;
1627 pThis = lpcs->lpCreateParams;
1628 SetWindowLongPtrW(hWnd, GWLP_USERDATA, (ULONG_PTR)pThis);
1629 pThis->hWnd = hWnd; /*set the window handle*/
1630 break;
1632 case WM_SIZE: return ShellView_OnSize(pThis,LOWORD(lParam), HIWORD(lParam));
1633 case WM_SETFOCUS: return ShellView_OnSetFocus(pThis);
1634 case WM_KILLFOCUS: return ShellView_OnKillFocus(pThis);
1635 case WM_CREATE: return ShellView_OnCreate(pThis);
1636 case WM_ACTIVATE: return ShellView_OnActivate(pThis, SVUIA_ACTIVATE_FOCUS);
1637 case WM_NOTIFY: return ShellView_OnNotify(pThis,(UINT)wParam, (LPNMHDR)lParam);
1638 case WM_COMMAND: return ShellView_OnCommand(pThis,
1639 GET_WM_COMMAND_ID(wParam, lParam),
1640 GET_WM_COMMAND_CMD(wParam, lParam),
1641 GET_WM_COMMAND_HWND(wParam, lParam));
1642 case SHV_CHANGE_NOTIFY: return ShellView_OnChange(pThis, (const LPCITEMIDLIST*)wParam, (LONG)lParam);
1644 case WM_CONTEXTMENU: ShellView_DoContextMenu(pThis, LOWORD(lParam), HIWORD(lParam), FALSE);
1645 return 0;
1647 case WM_SHOWWINDOW: UpdateWindow(pThis->hWndList);
1648 break;
1650 case WM_GETDLGCODE: return SendMessageA(pThis->hWndList,uMessage,0,0);
1652 case WM_DESTROY:
1653 RevokeDragDrop(pThis->hWnd);
1654 SHChangeNotifyDeregister(pThis->hNotify);
1655 break;
1657 case WM_ERASEBKGND:
1658 if ((pThis->FolderSettings.fFlags & FWF_DESKTOP) ||
1659 (pThis->FolderSettings.fFlags & FWF_TRANSPARENT))
1660 return 1;
1661 break;
1664 return DefWindowProcW(hWnd, uMessage, wParam, lParam);
1666 /**********************************************************
1669 * The INTERFACE of the IShellView object
1672 **********************************************************
1673 * IShellView_QueryInterface
1675 static HRESULT WINAPI IShellView_fnQueryInterface(IShellView2 * iface,REFIID riid, LPVOID *ppvObj)
1677 IShellViewImpl *This = (IShellViewImpl *)iface;
1679 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1681 *ppvObj = NULL;
1683 if(IsEqualIID(riid, &IID_IUnknown))
1685 *ppvObj = This;
1687 else if(IsEqualIID(riid, &IID_IShellView))
1689 *ppvObj = This;
1691 else if(IsEqualIID(riid, &IID_IShellView2))
1693 *ppvObj = This;
1695 else if(IsEqualIID(riid, &IID_IOleCommandTarget))
1697 *ppvObj = &This->lpvtblOleCommandTarget;
1699 else if(IsEqualIID(riid, &IID_IDropTarget))
1701 *ppvObj = &This->lpvtblDropTarget;
1703 else if(IsEqualIID(riid, &IID_IDropSource))
1705 *ppvObj = &This->lpvtblDropSource;
1707 else if(IsEqualIID(riid, &IID_IViewObject))
1709 *ppvObj = &This->lpvtblViewObject;
1712 if(*ppvObj)
1714 IUnknown_AddRef( (IUnknown*)*ppvObj );
1715 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1716 return S_OK;
1718 TRACE("-- Interface: E_NOINTERFACE\n");
1719 return E_NOINTERFACE;
1722 /**********************************************************
1723 * IShellView_AddRef
1725 static ULONG WINAPI IShellView_fnAddRef(IShellView2 * iface)
1727 IShellViewImpl *This = (IShellViewImpl *)iface;
1728 ULONG refCount = InterlockedIncrement(&This->ref);
1730 TRACE("(%p)->(count=%u)\n", This, refCount - 1);
1732 return refCount;
1734 /**********************************************************
1735 * IShellView_Release
1737 static ULONG WINAPI IShellView_fnRelease(IShellView2 * iface)
1739 IShellViewImpl *This = (IShellViewImpl *)iface;
1740 ULONG refCount = InterlockedDecrement(&This->ref);
1742 TRACE("(%p)->(count=%i)\n", This, refCount + 1);
1744 if (!refCount)
1746 TRACE(" destroying IShellView(%p)\n",This);
1748 DestroyWindow(This->hWndList);
1750 if(This->pSFParent)
1751 IShellFolder_Release(This->pSFParent);
1753 if(This->pSF2Parent)
1754 IShellFolder2_Release(This->pSF2Parent);
1756 SHFree(This->apidl);
1758 if(This->pAdvSink)
1759 IAdviseSink_Release(This->pAdvSink);
1761 HeapFree(GetProcessHeap(),0,This);
1763 return refCount;
1766 /**********************************************************
1767 * ShellView_GetWindow
1769 static HRESULT WINAPI IShellView_fnGetWindow(IShellView2 * iface,HWND * phWnd)
1771 IShellViewImpl *This = (IShellViewImpl *)iface;
1773 TRACE("(%p)\n",This);
1775 *phWnd = This->hWnd;
1777 return S_OK;
1780 static HRESULT WINAPI IShellView_fnContextSensitiveHelp(IShellView2 * iface,BOOL fEnterMode)
1782 IShellViewImpl *This = (IShellViewImpl *)iface;
1784 FIXME("(%p) stub\n",This);
1786 return E_NOTIMPL;
1789 /**********************************************************
1790 * IShellView_TranslateAccelerator
1792 * FIXME:
1793 * use the accel functions
1795 static HRESULT WINAPI IShellView_fnTranslateAccelerator(IShellView2 * iface,LPMSG lpmsg)
1797 #if 0
1798 IShellViewImpl *This = (IShellViewImpl *)iface;
1800 FIXME("(%p)->(%p: hwnd=%x msg=%x lp=%x wp=%x) stub\n",This,lpmsg, lpmsg->hwnd, lpmsg->message, lpmsg->lParam, lpmsg->wParam);
1801 #endif
1803 if ((lpmsg->message>=WM_KEYFIRST) && (lpmsg->message>=WM_KEYLAST))
1805 TRACE("-- key=0x04%lx\n",lpmsg->wParam) ;
1807 return S_FALSE; /* not handled */
1810 static HRESULT WINAPI IShellView_fnEnableModeless(IShellView2 * iface,BOOL fEnable)
1812 IShellViewImpl *This = (IShellViewImpl *)iface;
1814 FIXME("(%p) stub\n",This);
1816 return E_NOTIMPL;
1819 static HRESULT WINAPI IShellView_fnUIActivate(IShellView2 * iface,UINT uState)
1821 IShellViewImpl *This = (IShellViewImpl *)iface;
1824 CHAR szName[MAX_PATH];
1826 LRESULT lResult;
1827 int nPartArray[1] = {-1};
1829 TRACE("(%p)->(state=%x) stub\n",This, uState);
1831 /*don't do anything if the state isn't really changing*/
1832 if(This->uState == uState)
1834 return S_OK;
1837 /*OnActivate handles the menu merging and internal state*/
1838 ShellView_OnActivate(This, uState);
1840 /*only do This if we are active*/
1841 if(uState != SVUIA_DEACTIVATE)
1845 GetFolderPath is not a method of IShellFolder
1846 IShellFolder_GetFolderPath( This->pSFParent, szName, sizeof(szName) );
1848 /* set the number of parts */
1849 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETPARTS, 1,
1850 (LPARAM)nPartArray, &lResult);
1852 /* set the text for the parts */
1854 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETTEXTA,
1855 0, (LPARAM)szName, &lResult);
1859 return S_OK;
1862 static HRESULT WINAPI IShellView_fnRefresh(IShellView2 * iface)
1864 IShellViewImpl *This = (IShellViewImpl *)iface;
1866 TRACE("(%p)\n",This);
1868 SendMessageW(This->hWndList, LVM_DELETEALLITEMS, 0, 0);
1869 ShellView_FillList(This);
1871 return S_OK;
1874 static HRESULT WINAPI IShellView_fnCreateViewWindow(IShellView2 *iface, IShellView *lpPrevView,
1875 LPCFOLDERSETTINGS lpfs, IShellBrowser *psb, RECT *prcView, HWND *phWnd)
1877 HRESULT hr;
1878 SV2CVW2_PARAMS view_params;
1879 view_params.cbSize = sizeof(view_params);
1880 view_params.psvPrev = lpPrevView;
1881 view_params.pfs = lpfs;
1882 view_params.psbOwner = psb;
1883 view_params.prcView = prcView;
1884 view_params.pvid = NULL;
1885 view_params.hwndView = 0;
1887 TRACE("(%p) Forwarding to CreateViewWindow2\n", iface);
1889 hr = IShellView2_CreateViewWindow2(iface, &view_params);
1890 *phWnd = view_params.hwndView;
1892 return hr;
1895 static HRESULT WINAPI IShellView_fnDestroyViewWindow(IShellView2 * iface)
1897 IShellViewImpl *This = (IShellViewImpl *)iface;
1899 TRACE("(%p)\n",This);
1901 /*Make absolutely sure all our UI is cleaned up.*/
1902 IShellView_UIActivate((IShellView*)This, SVUIA_DEACTIVATE);
1904 if(This->hMenu)
1906 DestroyMenu(This->hMenu);
1909 DestroyWindow(This->hWnd);
1910 if(This->pShellBrowser) IShellBrowser_Release(This->pShellBrowser);
1911 if(This->pCommDlgBrowser) ICommDlgBrowser_Release(This->pCommDlgBrowser);
1914 return S_OK;
1917 static HRESULT WINAPI IShellView_fnGetCurrentInfo(IShellView2 * iface, LPFOLDERSETTINGS lpfs)
1919 IShellViewImpl *This = (IShellViewImpl *)iface;
1921 TRACE("(%p)->(%p) vmode=%x flags=%x\n",This, lpfs,
1922 This->FolderSettings.ViewMode, This->FolderSettings.fFlags);
1924 if (!lpfs) return E_INVALIDARG;
1926 *lpfs = This->FolderSettings;
1927 return NOERROR;
1930 static HRESULT WINAPI IShellView_fnAddPropertySheetPages(IShellView2 * iface, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam)
1932 IShellViewImpl *This = (IShellViewImpl *)iface;
1934 FIXME("(%p) stub\n",This);
1936 return E_NOTIMPL;
1939 static HRESULT WINAPI IShellView_fnSaveViewState(IShellView2 * iface)
1941 IShellViewImpl *This = (IShellViewImpl *)iface;
1943 FIXME("(%p) stub\n",This);
1945 return S_OK;
1948 static HRESULT WINAPI IShellView_fnSelectItem(
1949 IShellView2 * iface,
1950 LPCITEMIDLIST pidl,
1951 UINT uFlags)
1953 IShellViewImpl *This = (IShellViewImpl *)iface;
1954 int i;
1956 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n",This, pidl, uFlags);
1958 i = LV_FindItemByPidl(This, pidl);
1960 if (i != -1)
1962 LVITEMW lvItem;
1964 if(uFlags & SVSI_ENSUREVISIBLE)
1965 SendMessageW(This->hWndList, LVM_ENSUREVISIBLE, i, 0);
1967 lvItem.mask = LVIF_STATE;
1968 lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
1969 lvItem.iItem = 0;
1970 lvItem.iSubItem = 0;
1972 while(SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem))
1974 if (lvItem.iItem == i)
1976 if (uFlags & SVSI_SELECT)
1977 lvItem.state |= LVIS_SELECTED;
1978 else
1979 lvItem.state &= ~LVIS_SELECTED;
1981 if(uFlags & SVSI_FOCUSED)
1982 lvItem.state &= ~LVIS_FOCUSED;
1984 else
1986 if (uFlags & SVSI_DESELECTOTHERS)
1987 lvItem.state &= ~LVIS_SELECTED;
1989 SendMessageW(This->hWndList, LVM_SETITEMW, 0, (LPARAM) &lvItem);
1990 lvItem.iItem++;
1994 if(uFlags & SVSI_EDIT)
1995 SendMessageW(This->hWndList, LVM_EDITLABELW, i, 0);
1998 return S_OK;
2001 static HRESULT WINAPI IShellView_fnGetItemObject(IShellView2 * iface, UINT uItem, REFIID riid, LPVOID *ppvOut)
2003 IShellViewImpl *This = (IShellViewImpl *)iface;
2005 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n",This, uItem, debugstr_guid(riid), ppvOut);
2007 *ppvOut = NULL;
2009 switch(uItem)
2011 case SVGIO_BACKGROUND:
2012 *ppvOut = ISvBgCm_Constructor(This->pSFParent, FALSE);
2013 break;
2015 case SVGIO_SELECTION:
2016 ShellView_GetSelections(This);
2017 IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, (LPCITEMIDLIST*)This->apidl, riid, 0, ppvOut);
2018 break;
2020 TRACE("-- (%p)->(interface=%p)\n",This, *ppvOut);
2022 if(!*ppvOut) return E_OUTOFMEMORY;
2024 return S_OK;
2027 static HRESULT WINAPI IShellView2_fnGetView(IShellView2* iface, SHELLVIEWID *view_guid, ULONG view_type)
2029 FIXME("(%p)->(view_guid %s, view_type %#x) stub!\n", iface, debugstr_guid(view_guid), view_type);
2030 return E_NOTIMPL;
2033 static HRESULT WINAPI IShellView2_fnCreateViewWindow2(IShellView2* iface, LPSV2CVW2_PARAMS view_params)
2035 IShellViewImpl *This = (IShellViewImpl *)iface;
2036 WNDCLASSW wc;
2037 HWND wnd;
2039 TRACE("(%p)->(view_params %p)\n", iface, view_params);
2041 if (view_params->cbSize != sizeof(*view_params))
2043 FIXME("Got unexpected cbSize %#x\n", view_params->cbSize);
2044 return E_FAIL;
2047 TRACE("-- psvPrev %p, pfs %p, psbOwner %p, prcView %p\n",
2048 view_params->psvPrev, view_params->pfs, view_params->psbOwner, view_params->prcView);
2049 TRACE("-- vmode %#x, flags %#x, left %d, top %d, right %d, bottom %d\n",
2050 view_params->pfs->ViewMode, view_params->pfs->fFlags, view_params->prcView->left,
2051 view_params->prcView->top, view_params->prcView->right, view_params->prcView->bottom);
2053 /* Set up the member variables */
2054 This->pShellBrowser = view_params->psbOwner;
2055 This->FolderSettings = *view_params->pfs;
2057 if (view_params->pvid)
2059 if (IsEqualGUID(view_params->pvid, &VID_LargeIcons))
2060 This->FolderSettings.ViewMode = FVM_ICON;
2061 else if (IsEqualGUID(view_params->pvid, &VID_SmallIcons))
2062 This->FolderSettings.ViewMode = FVM_SMALLICON;
2063 else if (IsEqualGUID(view_params->pvid, &VID_List))
2064 This->FolderSettings.ViewMode = FVM_LIST;
2065 else if (IsEqualGUID(view_params->pvid, &VID_Details))
2066 This->FolderSettings.ViewMode = FVM_DETAILS;
2067 else if (IsEqualGUID(view_params->pvid, &VID_Thumbnails))
2068 This->FolderSettings.ViewMode = FVM_THUMBNAIL;
2069 else if (IsEqualGUID(view_params->pvid, &VID_Tile))
2070 This->FolderSettings.ViewMode = FVM_TILE;
2071 else if (IsEqualGUID(view_params->pvid, &VID_ThumbStrip))
2072 This->FolderSettings.ViewMode = FVM_THUMBSTRIP;
2073 else
2074 FIXME("Ignoring unrecognized VID %s\n", debugstr_guid(view_params->pvid));
2077 /* Get our parent window */
2078 IShellBrowser_AddRef(This->pShellBrowser);
2079 IShellBrowser_GetWindow(This->pShellBrowser, &(This->hWndParent));
2081 /* Try to get the ICommDlgBrowserInterface, adds a reference !!! */
2082 This->pCommDlgBrowser = NULL;
2083 if (SUCCEEDED(IShellBrowser_QueryInterface(This->pShellBrowser, &IID_ICommDlgBrowser, (void **)&This->pCommDlgBrowser)))
2085 TRACE("-- CommDlgBrowser %p\n", This->pCommDlgBrowser);
2088 /* If our window class has not been registered, then do so */
2089 if (!GetClassInfoW(shell32_hInstance, SV_CLASS_NAME, &wc))
2091 ZeroMemory(&wc, sizeof(wc));
2092 wc.style = CS_HREDRAW | CS_VREDRAW;
2093 wc.lpfnWndProc = ShellView_WndProc;
2094 wc.cbClsExtra = 0;
2095 wc.cbWndExtra = 0;
2096 wc.hInstance = shell32_hInstance;
2097 wc.hIcon = 0;
2098 wc.hCursor = LoadCursorW(0, (LPWSTR)IDC_ARROW);
2099 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
2100 wc.lpszMenuName = NULL;
2101 wc.lpszClassName = SV_CLASS_NAME;
2103 if (!RegisterClassW(&wc)) return E_FAIL;
2106 wnd = CreateWindowExW(0, SV_CLASS_NAME, NULL, WS_CHILD | WS_TABSTOP,
2107 view_params->prcView->left, view_params->prcView->top,
2108 view_params->prcView->right - view_params->prcView->left,
2109 view_params->prcView->bottom - view_params->prcView->top,
2110 This->hWndParent, 0, shell32_hInstance, This);
2112 CheckToolbar(This);
2114 if (!wnd) return E_FAIL;
2116 SetWindowPos(wnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
2117 UpdateWindow(wnd);
2119 view_params->hwndView = wnd;
2121 return S_OK;
2124 static HRESULT WINAPI IShellView2_fnHandleRename(IShellView2* iface, LPCITEMIDLIST new_pidl)
2126 FIXME("(%p)->(new_pidl %p) stub!\n", iface, new_pidl);
2127 return E_NOTIMPL;
2130 static HRESULT WINAPI IShellView2_fnSelectAndPositionItem(IShellView2* iface, LPCITEMIDLIST item, UINT flags, POINT *point)
2132 FIXME("(%p)->(item %p, flags %#x, point %p) stub!\n", iface, item, flags, point);
2133 return E_NOTIMPL;
2136 static const IShellView2Vtbl svvt =
2138 IShellView_fnQueryInterface,
2139 IShellView_fnAddRef,
2140 IShellView_fnRelease,
2141 IShellView_fnGetWindow,
2142 IShellView_fnContextSensitiveHelp,
2143 IShellView_fnTranslateAccelerator,
2144 IShellView_fnEnableModeless,
2145 IShellView_fnUIActivate,
2146 IShellView_fnRefresh,
2147 IShellView_fnCreateViewWindow,
2148 IShellView_fnDestroyViewWindow,
2149 IShellView_fnGetCurrentInfo,
2150 IShellView_fnAddPropertySheetPages,
2151 IShellView_fnSaveViewState,
2152 IShellView_fnSelectItem,
2153 IShellView_fnGetItemObject,
2154 IShellView2_fnGetView,
2155 IShellView2_fnCreateViewWindow2,
2156 IShellView2_fnHandleRename,
2157 IShellView2_fnSelectAndPositionItem,
2161 /**********************************************************
2162 * ISVOleCmdTarget_QueryInterface (IUnknown)
2164 static HRESULT WINAPI ISVOleCmdTarget_QueryInterface(
2165 IOleCommandTarget * iface,
2166 REFIID iid,
2167 LPVOID* ppvObj)
2169 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2171 return IShellFolder_QueryInterface((IShellFolder*)This, iid, ppvObj);
2174 /**********************************************************
2175 * ISVOleCmdTarget_AddRef (IUnknown)
2177 static ULONG WINAPI ISVOleCmdTarget_AddRef(
2178 IOleCommandTarget * iface)
2180 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2182 return IShellFolder_AddRef((IShellFolder*)This);
2185 /**********************************************************
2186 * ISVOleCmdTarget_Release (IUnknown)
2188 static ULONG WINAPI ISVOleCmdTarget_Release(
2189 IOleCommandTarget * iface)
2191 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2193 return IShellFolder_Release((IShellFolder*)This);
2196 /**********************************************************
2197 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2199 static HRESULT WINAPI ISVOleCmdTarget_QueryStatus(
2200 IOleCommandTarget *iface,
2201 const GUID* pguidCmdGroup,
2202 ULONG cCmds,
2203 OLECMD * prgCmds,
2204 OLECMDTEXT* pCmdText)
2206 UINT i;
2207 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2209 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
2210 This, pguidCmdGroup, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText);
2212 if (!prgCmds)
2213 return E_POINTER;
2214 for (i = 0; i < cCmds; i++)
2216 FIXME("\tprgCmds[%d].cmdID = %d\n", i, prgCmds[i].cmdID);
2217 prgCmds[i].cmdf = 0;
2219 return OLECMDERR_E_UNKNOWNGROUP;
2222 /**********************************************************
2223 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2225 * nCmdID is the OLECMDID_* enumeration
2227 static HRESULT WINAPI ISVOleCmdTarget_Exec(
2228 IOleCommandTarget *iface,
2229 const GUID* pguidCmdGroup,
2230 DWORD nCmdID,
2231 DWORD nCmdexecopt,
2232 VARIANT* pvaIn,
2233 VARIANT* pvaOut)
2235 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2237 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2238 This, debugstr_guid(pguidCmdGroup), nCmdID, nCmdexecopt, pvaIn, pvaOut);
2240 if (IsEqualIID(pguidCmdGroup, &CGID_Explorer) &&
2241 (nCmdID == 0x29) &&
2242 (nCmdexecopt == 4) && pvaOut)
2243 return S_OK;
2244 if (IsEqualIID(pguidCmdGroup, &CGID_ShellDocView) &&
2245 (nCmdID == 9) &&
2246 (nCmdexecopt == 0))
2247 return 1;
2249 return OLECMDERR_E_UNKNOWNGROUP;
2252 static const IOleCommandTargetVtbl ctvt =
2254 ISVOleCmdTarget_QueryInterface,
2255 ISVOleCmdTarget_AddRef,
2256 ISVOleCmdTarget_Release,
2257 ISVOleCmdTarget_QueryStatus,
2258 ISVOleCmdTarget_Exec
2261 /**********************************************************
2262 * ISVDropTarget implementation
2265 static HRESULT WINAPI ISVDropTarget_QueryInterface(
2266 IDropTarget *iface,
2267 REFIID riid,
2268 LPVOID *ppvObj)
2270 IShellViewImpl *This = impl_from_IDropTarget(iface);
2272 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2274 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2277 static ULONG WINAPI ISVDropTarget_AddRef( IDropTarget *iface)
2279 IShellViewImpl *This = impl_from_IDropTarget(iface);
2281 TRACE("(%p)->(count=%u)\n",This,This->ref);
2283 return IShellFolder_AddRef((IShellFolder*)This);
2286 static ULONG WINAPI ISVDropTarget_Release( IDropTarget *iface)
2288 IShellViewImpl *This = impl_from_IDropTarget(iface);
2290 TRACE("(%p)->(count=%u)\n",This,This->ref);
2292 return IShellFolder_Release((IShellFolder*)This);
2295 /******************************************************************************
2296 * drag_notify_subitem [Internal]
2298 * Figure out the shellfolder object, which is currently under the mouse cursor
2299 * and notify it via the IDropTarget interface.
2302 #define SCROLLAREAWIDTH 20
2304 static HRESULT drag_notify_subitem(IShellViewImpl *This, DWORD grfKeyState, POINTL pt,
2305 DWORD *pdwEffect)
2307 LVHITTESTINFO htinfo;
2308 LVITEMW lvItem;
2309 LONG lResult;
2310 HRESULT hr;
2311 RECT clientRect;
2313 /* Map from global to client coordinates and query the index of the listview-item, which is
2314 * currently under the mouse cursor. */
2315 htinfo.pt.x = pt.x;
2316 htinfo.pt.y = pt.y;
2317 htinfo.flags = LVHT_ONITEM;
2318 ScreenToClient(This->hWndList, &htinfo.pt);
2319 lResult = SendMessageW(This->hWndList, LVM_HITTEST, 0, (LPARAM)&htinfo);
2321 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2322 GetClientRect(This->hWndList, &clientRect);
2323 if (htinfo.pt.x == This->ptLastMousePos.x && htinfo.pt.y == This->ptLastMousePos.y &&
2324 (htinfo.pt.x < SCROLLAREAWIDTH || htinfo.pt.x > clientRect.right - SCROLLAREAWIDTH ||
2325 htinfo.pt.y < SCROLLAREAWIDTH || htinfo.pt.y > clientRect.bottom - SCROLLAREAWIDTH ))
2327 This->cScrollDelay = (This->cScrollDelay + 1) % 5; /* DragOver is called every 50 ms */
2328 if (This->cScrollDelay == 0) { /* Mouse did hover another 250 ms over the scroll-area */
2329 if (htinfo.pt.x < SCROLLAREAWIDTH)
2330 SendMessageW(This->hWndList, WM_HSCROLL, SB_LINEUP, 0);
2331 if (htinfo.pt.x > clientRect.right - SCROLLAREAWIDTH)
2332 SendMessageW(This->hWndList, WM_HSCROLL, SB_LINEDOWN, 0);
2333 if (htinfo.pt.y < SCROLLAREAWIDTH)
2334 SendMessageW(This->hWndList, WM_VSCROLL, SB_LINEUP, 0);
2335 if (htinfo.pt.y > clientRect.bottom - SCROLLAREAWIDTH)
2336 SendMessageW(This->hWndList, WM_VSCROLL, SB_LINEDOWN, 0);
2338 } else {
2339 This->cScrollDelay = 0; /* Reset, if the cursor is not over the listview's scroll-area */
2341 This->ptLastMousePos = htinfo.pt;
2343 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2344 if (This->pCurDropTarget && lResult == This->iDragOverItem)
2345 return IDropTarget_DragOver(This->pCurDropTarget, grfKeyState, pt, pdwEffect);
2347 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2348 if (This->pCurDropTarget) {
2349 IDropTarget_DragLeave(This->pCurDropTarget);
2350 IDropTarget_Release(This->pCurDropTarget);
2351 This->pCurDropTarget = NULL;
2354 This->iDragOverItem = lResult;
2355 if (lResult == -1) {
2356 /* We are not above one of the listview's subitems. Bind to the parent folder's
2357 * DropTarget interface. */
2358 hr = IShellFolder_QueryInterface(This->pSFParent, &IID_IDropTarget,
2359 (LPVOID*)&This->pCurDropTarget);
2360 } else {
2361 /* Query the relative PIDL of the shellfolder object represented by the currently
2362 * dragged over listview-item ... */
2363 lvItem.mask = LVIF_PARAM;
2364 lvItem.iItem = lResult;
2365 lvItem.iSubItem = 0;
2366 SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem);
2368 /* ... and bind pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2369 hr = IShellFolder_GetUIObjectOf(This->pSFParent, This->hWndList, 1,
2370 (LPCITEMIDLIST*)&lvItem.lParam, &IID_IDropTarget, NULL, (LPVOID*)&This->pCurDropTarget);
2373 /* If anything failed, pCurDropTarget should be NULL now, which ought to be a save state. */
2374 if (FAILED(hr))
2375 return hr;
2377 /* Notify the item just entered via DragEnter. */
2378 return IDropTarget_DragEnter(This->pCurDropTarget, This->pCurDataObject, grfKeyState, pt, pdwEffect);
2381 static HRESULT WINAPI ISVDropTarget_DragEnter(IDropTarget *iface, IDataObject *pDataObject,
2382 DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
2384 IShellViewImpl *This = impl_from_IDropTarget(iface);
2386 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2387 This->pCurDataObject = pDataObject;
2388 IDataObject_AddRef(pDataObject);
2390 return drag_notify_subitem(This, grfKeyState, pt, pdwEffect);
2393 static HRESULT WINAPI ISVDropTarget_DragOver(IDropTarget *iface, DWORD grfKeyState, POINTL pt,
2394 DWORD *pdwEffect)
2396 IShellViewImpl *This = impl_from_IDropTarget(iface);
2397 return drag_notify_subitem(This, grfKeyState, pt, pdwEffect);
2400 static HRESULT WINAPI ISVDropTarget_DragLeave(IDropTarget *iface) {
2401 IShellViewImpl *This = impl_from_IDropTarget(iface);
2403 IDropTarget_DragLeave(This->pCurDropTarget);
2405 IDropTarget_Release(This->pCurDropTarget);
2406 IDataObject_Release(This->pCurDataObject);
2407 This->pCurDataObject = NULL;
2408 This->pCurDropTarget = NULL;
2409 This->iDragOverItem = 0;
2411 return S_OK;
2414 static HRESULT WINAPI ISVDropTarget_Drop(IDropTarget *iface, IDataObject* pDataObject,
2415 DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
2417 IShellViewImpl *This = impl_from_IDropTarget(iface);
2419 IDropTarget_Drop(This->pCurDropTarget, pDataObject, grfKeyState, pt, pdwEffect);
2421 IDropTarget_Release(This->pCurDropTarget);
2422 IDataObject_Release(This->pCurDataObject);
2423 This->pCurDataObject = NULL;
2424 This->pCurDropTarget = NULL;
2425 This->iDragOverItem = 0;
2427 return S_OK;
2430 static const IDropTargetVtbl dtvt =
2432 ISVDropTarget_QueryInterface,
2433 ISVDropTarget_AddRef,
2434 ISVDropTarget_Release,
2435 ISVDropTarget_DragEnter,
2436 ISVDropTarget_DragOver,
2437 ISVDropTarget_DragLeave,
2438 ISVDropTarget_Drop
2441 /**********************************************************
2442 * ISVDropSource implementation
2445 static HRESULT WINAPI ISVDropSource_QueryInterface(
2446 IDropSource *iface,
2447 REFIID riid,
2448 LPVOID *ppvObj)
2450 IShellViewImpl *This = impl_from_IDropSource(iface);
2452 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2454 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2457 static ULONG WINAPI ISVDropSource_AddRef( IDropSource *iface)
2459 IShellViewImpl *This = impl_from_IDropSource(iface);
2461 TRACE("(%p)->(count=%u)\n",This,This->ref);
2463 return IShellFolder_AddRef((IShellFolder*)This);
2466 static ULONG WINAPI ISVDropSource_Release( IDropSource *iface)
2468 IShellViewImpl *This = impl_from_IDropSource(iface);
2470 TRACE("(%p)->(count=%u)\n",This,This->ref);
2472 return IShellFolder_Release((IShellFolder*)This);
2474 static HRESULT WINAPI ISVDropSource_QueryContinueDrag(
2475 IDropSource *iface,
2476 BOOL fEscapePressed,
2477 DWORD grfKeyState)
2479 IShellViewImpl *This = impl_from_IDropSource(iface);
2480 TRACE("(%p)\n",This);
2482 if (fEscapePressed)
2483 return DRAGDROP_S_CANCEL;
2484 else if (!(grfKeyState & MK_LBUTTON) && !(grfKeyState & MK_RBUTTON))
2485 return DRAGDROP_S_DROP;
2486 else
2487 return NOERROR;
2490 static HRESULT WINAPI ISVDropSource_GiveFeedback(
2491 IDropSource *iface,
2492 DWORD dwEffect)
2494 IShellViewImpl *This = impl_from_IDropSource(iface);
2495 TRACE("(%p)\n",This);
2497 return DRAGDROP_S_USEDEFAULTCURSORS;
2500 static const IDropSourceVtbl dsvt =
2502 ISVDropSource_QueryInterface,
2503 ISVDropSource_AddRef,
2504 ISVDropSource_Release,
2505 ISVDropSource_QueryContinueDrag,
2506 ISVDropSource_GiveFeedback
2508 /**********************************************************
2509 * ISVViewObject implementation
2512 static HRESULT WINAPI ISVViewObject_QueryInterface(
2513 IViewObject *iface,
2514 REFIID riid,
2515 LPVOID *ppvObj)
2517 IShellViewImpl *This = impl_from_IViewObject(iface);
2519 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2521 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2524 static ULONG WINAPI ISVViewObject_AddRef( IViewObject *iface)
2526 IShellViewImpl *This = impl_from_IViewObject(iface);
2528 TRACE("(%p)->(count=%u)\n",This,This->ref);
2530 return IShellFolder_AddRef((IShellFolder*)This);
2533 static ULONG WINAPI ISVViewObject_Release( IViewObject *iface)
2535 IShellViewImpl *This = impl_from_IViewObject(iface);
2537 TRACE("(%p)->(count=%u)\n",This,This->ref);
2539 return IShellFolder_Release((IShellFolder*)This);
2542 static HRESULT WINAPI ISVViewObject_Draw(
2543 IViewObject *iface,
2544 DWORD dwDrawAspect,
2545 LONG lindex,
2546 void* pvAspect,
2547 DVTARGETDEVICE* ptd,
2548 HDC hdcTargetDev,
2549 HDC hdcDraw,
2550 LPCRECTL lprcBounds,
2551 LPCRECTL lprcWBounds,
2552 BOOL (CALLBACK *pfnContinue)(ULONG_PTR dwContinue),
2553 ULONG_PTR dwContinue)
2556 IShellViewImpl *This = impl_from_IViewObject(iface);
2558 FIXME("Stub: This=%p\n",This);
2560 return E_NOTIMPL;
2562 static HRESULT WINAPI ISVViewObject_GetColorSet(
2563 IViewObject *iface,
2564 DWORD dwDrawAspect,
2565 LONG lindex,
2566 void *pvAspect,
2567 DVTARGETDEVICE* ptd,
2568 HDC hicTargetDevice,
2569 LOGPALETTE** ppColorSet)
2572 IShellViewImpl *This = impl_from_IViewObject(iface);
2574 FIXME("Stub: This=%p\n",This);
2576 return E_NOTIMPL;
2578 static HRESULT WINAPI ISVViewObject_Freeze(
2579 IViewObject *iface,
2580 DWORD dwDrawAspect,
2581 LONG lindex,
2582 void* pvAspect,
2583 DWORD* pdwFreeze)
2586 IShellViewImpl *This = impl_from_IViewObject(iface);
2588 FIXME("Stub: This=%p\n",This);
2590 return E_NOTIMPL;
2592 static HRESULT WINAPI ISVViewObject_Unfreeze(
2593 IViewObject *iface,
2594 DWORD dwFreeze)
2597 IShellViewImpl *This = impl_from_IViewObject(iface);
2599 FIXME("Stub: This=%p\n",This);
2601 return E_NOTIMPL;
2603 static HRESULT WINAPI ISVViewObject_SetAdvise(
2604 IViewObject *iface,
2605 DWORD aspects,
2606 DWORD advf,
2607 IAdviseSink* pAdvSink)
2610 IShellViewImpl *This = impl_from_IViewObject(iface);
2612 FIXME("partial stub: %p %08x %08x %p\n",
2613 This, aspects, advf, pAdvSink);
2615 /* FIXME: we set the AdviseSink, but never use it to send any advice */
2616 This->pAdvSink = pAdvSink;
2617 This->dwAspects = aspects;
2618 This->dwAdvf = advf;
2620 return S_OK;
2623 static HRESULT WINAPI ISVViewObject_GetAdvise(
2624 IViewObject *iface,
2625 DWORD* pAspects,
2626 DWORD* pAdvf,
2627 IAdviseSink** ppAdvSink)
2630 IShellViewImpl *This = impl_from_IViewObject(iface);
2632 TRACE("This=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n",
2633 This, pAspects, pAdvf, ppAdvSink);
2635 if( ppAdvSink )
2637 IAdviseSink_AddRef( This->pAdvSink );
2638 *ppAdvSink = This->pAdvSink;
2640 if( pAspects )
2641 *pAspects = This->dwAspects;
2642 if( pAdvf )
2643 *pAdvf = This->dwAdvf;
2645 return S_OK;
2649 static const IViewObjectVtbl vovt =
2651 ISVViewObject_QueryInterface,
2652 ISVViewObject_AddRef,
2653 ISVViewObject_Release,
2654 ISVViewObject_Draw,
2655 ISVViewObject_GetColorSet,
2656 ISVViewObject_Freeze,
2657 ISVViewObject_Unfreeze,
2658 ISVViewObject_SetAdvise,
2659 ISVViewObject_GetAdvise