Handle context menu->refresh, and F5 to initiate a refresh of the file
[wine.git] / dlls / shell32 / shlview.c
bloba024933797f421ad0ced6d300a17322f588e489c
1 /*
2 * ShellView
4 * Copyright 1998,1999 <juergen.schmied@debitel.net>
6 * This is the view visualizing the data provied 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 * FIXME: The order by part of the background context menu should be
24 * buily according to the columns shown.
26 * FIXME: Load/Save the view state from/into the stream provied 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 typedef struct
72 { BOOL bIsAscending;
73 INT nHeaderID;
74 INT nLastHeaderID;
75 }LISTVIEW_SORT_INFO, *LPLISTVIEW_SORT_INFO;
77 typedef struct
79 const IShellViewVtbl* lpVtbl;
80 LONG ref;
81 const IOleCommandTargetVtbl* lpvtblOleCommandTarget;
82 const IDropTargetVtbl* lpvtblDropTarget;
83 const IDropSourceVtbl* lpvtblDropSource;
84 const IViewObjectVtbl* lpvtblViewObject;
85 IShellFolder* pSFParent;
86 IShellFolder2* pSF2Parent;
87 IShellBrowser* pShellBrowser;
88 ICommDlgBrowser* pCommDlgBrowser;
89 HWND hWnd; /* SHELLDLL_DefView */
90 HWND hWndList; /* ListView control */
91 HWND hWndParent;
92 FOLDERSETTINGS FolderSettings;
93 HMENU hMenu;
94 UINT uState;
95 UINT cidl;
96 LPITEMIDLIST *apidl;
97 LISTVIEW_SORT_INFO ListViewSortInfo;
98 ULONG hNotify; /* change notification handle */
99 HANDLE hAccel;
100 DWORD dwAspects;
101 DWORD dwAdvf;
102 IAdviseSink *pAdvSink;
103 } IShellViewImpl;
105 static const IShellViewVtbl svvt;
106 static const IOleCommandTargetVtbl ctvt;
107 static const IDropTargetVtbl dtvt;
108 static const IDropSourceVtbl dsvt;
109 static const IViewObjectVtbl vovt;
112 static inline IShellViewImpl *impl_from_IOleCommandTarget( IOleCommandTarget *iface )
114 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblOleCommandTarget));
117 static inline IShellViewImpl *impl_from_IDropTarget( IDropTarget *iface )
119 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblDropTarget));
122 static inline IShellViewImpl *impl_from_IDropSource( IDropSource *iface )
124 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblDropSource));
127 static inline IShellViewImpl *impl_from_IViewObject( IViewObject *iface )
129 return (IShellViewImpl *)((char*)iface - FIELD_OFFSET(IShellViewImpl, lpvtblViewObject));
132 /* ListView Header ID's */
133 #define LISTVIEW_COLUMN_NAME 0
134 #define LISTVIEW_COLUMN_SIZE 1
135 #define LISTVIEW_COLUMN_TYPE 2
136 #define LISTVIEW_COLUMN_TIME 3
137 #define LISTVIEW_COLUMN_ATTRIB 4
139 /*menu items */
140 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
141 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
142 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
144 #define ID_LISTVIEW 2000
146 #define SHV_CHANGE_NOTIFY WM_USER + 0x1111
148 /*windowsx.h */
149 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
150 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
151 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
154 Items merged into the toolbar and and the filemenu
156 typedef struct
157 { int idCommand;
158 int iImage;
159 int idButtonString;
160 int idMenuString;
161 BYTE bState;
162 BYTE bStyle;
163 } MYTOOLINFO, *LPMYTOOLINFO;
165 MYTOOLINFO Tools[] =
167 { FCIDM_SHVIEW_BIGICON, 0, 0, IDS_VIEW_LARGE, TBSTATE_ENABLED, BTNS_BUTTON },
168 { FCIDM_SHVIEW_SMALLICON, 0, 0, IDS_VIEW_SMALL, TBSTATE_ENABLED, BTNS_BUTTON },
169 { FCIDM_SHVIEW_LISTVIEW, 0, 0, IDS_VIEW_LIST, TBSTATE_ENABLED, BTNS_BUTTON },
170 { FCIDM_SHVIEW_REPORTVIEW, 0, 0, IDS_VIEW_DETAILS, TBSTATE_ENABLED, BTNS_BUTTON },
171 { -1, 0, 0, 0, 0, 0}
174 typedef void (CALLBACK *PFNSHGETSETTINGSPROC)(LPSHELLFLAGSTATE lpsfs, DWORD dwMask);
176 /**********************************************************
177 * IShellView_Constructor
179 IShellView * IShellView_Constructor( IShellFolder * pFolder)
180 { IShellViewImpl * sv;
181 sv=HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IShellViewImpl));
182 sv->ref=1;
183 sv->lpVtbl=&svvt;
184 sv->lpvtblOleCommandTarget=&ctvt;
185 sv->lpvtblDropTarget=&dtvt;
186 sv->lpvtblDropSource=&dsvt;
187 sv->lpvtblViewObject=&vovt;
189 sv->pSFParent = pFolder;
190 if(pFolder) IShellFolder_AddRef(pFolder);
191 IShellFolder_QueryInterface(sv->pSFParent, &IID_IShellFolder2, (LPVOID*)&sv->pSF2Parent);
193 TRACE("(%p)->(%p)\n",sv, pFolder);
194 return (IShellView *) sv;
197 /**********************************************************
199 * ##### helperfunctions for communication with ICommDlgBrowser #####
201 static BOOL IsInCommDlg(IShellViewImpl * This)
202 { return(This->pCommDlgBrowser != NULL);
205 static HRESULT IncludeObject(IShellViewImpl * This, LPCITEMIDLIST pidl)
207 HRESULT ret = S_OK;
209 if ( IsInCommDlg(This) )
211 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl);
212 ret = ICommDlgBrowser_IncludeObject(This->pCommDlgBrowser, (IShellView*)This, pidl);
213 TRACE("--0x%08lx\n", ret);
215 return ret;
218 static HRESULT OnDefaultCommand(IShellViewImpl * This)
220 HRESULT ret = S_FALSE;
222 if (IsInCommDlg(This))
224 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
225 ret = ICommDlgBrowser_OnDefaultCommand(This->pCommDlgBrowser, (IShellView*)This);
226 TRACE("-- returns %08lx\n", ret);
228 return ret;
231 static HRESULT OnStateChange(IShellViewImpl * This, UINT uFlags)
233 HRESULT ret = S_FALSE;
235 if (IsInCommDlg(This))
237 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags);
238 ret = ICommDlgBrowser_OnStateChange(This->pCommDlgBrowser, (IShellView*)This, uFlags);
239 TRACE("--\n");
241 return ret;
243 /**********************************************************
244 * set the toolbar of the filedialog buttons
246 * - activates the buttons from the shellbrowser according to
247 * the view state
249 static void CheckToolbar(IShellViewImpl * This)
251 LRESULT result;
253 TRACE("\n");
255 if (IsInCommDlg(This))
257 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
258 FCIDM_TB_SMALLICON, (This->FolderSettings.ViewMode==FVM_LIST)? TRUE : FALSE, &result);
259 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
260 FCIDM_TB_REPORTVIEW, (This->FolderSettings.ViewMode==FVM_DETAILS)? TRUE : FALSE, &result);
261 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
262 FCIDM_TB_SMALLICON, TRUE, &result);
263 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
264 FCIDM_TB_REPORTVIEW, TRUE, &result);
268 /**********************************************************
270 * ##### helperfunctions for initializing the view #####
272 /**********************************************************
273 * change the style of the listview control
275 static void SetStyle(IShellViewImpl * This, DWORD dwAdd, DWORD dwRemove)
277 DWORD tmpstyle;
279 TRACE("(%p)\n", This);
281 tmpstyle = GetWindowLongA(This->hWndList, GWL_STYLE);
282 SetWindowLongA(This->hWndList, GWL_STYLE, dwAdd | (tmpstyle & ~dwRemove));
285 /**********************************************************
286 * ShellView_CreateList()
288 * - creates the list view window
290 static BOOL ShellView_CreateList (IShellViewImpl * This)
291 { DWORD dwStyle, dwExStyle;
293 TRACE("%p\n",This);
295 dwStyle = WS_TABSTOP | WS_VISIBLE | WS_CHILDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
296 LVS_SHAREIMAGELISTS | LVS_EDITLABELS | LVS_ALIGNLEFT | LVS_AUTOARRANGE;
297 dwExStyle = WS_EX_CLIENTEDGE;
299 switch (This->FolderSettings.ViewMode)
301 case FVM_ICON: dwStyle |= LVS_ICON; break;
302 case FVM_DETAILS: dwStyle |= LVS_REPORT; break;
303 case FVM_SMALLICON: dwStyle |= LVS_SMALLICON; break;
304 case FVM_LIST: dwStyle |= LVS_LIST; break;
305 default: dwStyle |= LVS_LIST; break;
308 if (This->FolderSettings.fFlags & FWF_AUTOARRANGE) dwStyle |= LVS_AUTOARRANGE;
309 if (This->FolderSettings.fFlags & FWF_DESKTOP)
310 This->FolderSettings.fFlags |= FWF_NOCLIENTEDGE | FWF_NOSCROLL;
311 if (This->FolderSettings.fFlags & FWF_SINGLESEL) dwStyle |= LVS_SINGLESEL;
312 if (This->FolderSettings.fFlags & FWF_NOCLIENTEDGE)
313 dwExStyle &= ~WS_EX_CLIENTEDGE;
315 This->hWndList=CreateWindowExA( dwExStyle,
316 WC_LISTVIEWA,
317 NULL,
318 dwStyle,
319 0,0,0,0,
320 This->hWnd,
321 (HMENU)ID_LISTVIEW,
322 shell32_hInstance,
323 NULL);
325 if(!This->hWndList)
326 return FALSE;
328 This->ListViewSortInfo.bIsAscending = TRUE;
329 This->ListViewSortInfo.nHeaderID = -1;
330 This->ListViewSortInfo.nLastHeaderID = -1;
332 if (This->FolderSettings.fFlags & FWF_DESKTOP) {
333 if (0) /* FIXME: look into registry vale HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ListviewShadow and activate drop shadows */
334 ListView_SetTextBkColor(This->hWndList, CLR_NONE);
335 else
336 ListView_SetTextBkColor(This->hWndList, GetSysColor(COLOR_DESKTOP));
338 ListView_SetTextColor(This->hWndList, RGB(255,255,255));
341 /* UpdateShellSettings(); */
342 return TRUE;
345 /**********************************************************
346 * ShellView_InitList()
348 * - adds all needed columns to the shellview
350 static BOOL ShellView_InitList(IShellViewImpl * This)
352 LVCOLUMNA lvColumn;
353 SHELLDETAILS sd;
354 int i;
355 char szTemp[50];
357 TRACE("%p\n",This);
359 ListView_DeleteAllItems(This->hWndList);
361 lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT;
362 lvColumn.pszText = szTemp;
364 if (This->pSF2Parent)
366 for (i=0; 1; i++)
368 if (!SUCCEEDED(IShellFolder2_GetDetailsOf(This->pSF2Parent, NULL, i, &sd)))
369 break;
370 lvColumn.fmt = sd.fmt;
371 lvColumn.cx = sd.cxChar*8; /* chars->pixel */
372 StrRetToStrNA( szTemp, 50, &sd.str, NULL);
373 ListView_InsertColumnA(This->hWndList, i, &lvColumn);
376 else
378 FIXME("no SF2\n");
381 ListView_SetImageList(This->hWndList, ShellSmallIconList, LVSIL_SMALL);
382 ListView_SetImageList(This->hWndList, ShellBigIconList, LVSIL_NORMAL);
384 return TRUE;
386 /**********************************************************
387 * ShellView_CompareItems()
389 * NOTES
390 * internal, CALLBACK for DSA_Sort
392 static INT CALLBACK ShellView_CompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
394 int ret;
395 TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1, lParam2, (LPVOID) lpData);
397 if(!lpData) return 0;
399 ret = (SHORT) SCODE_CODE(IShellFolder_CompareIDs((LPSHELLFOLDER)lpData, 0, (LPITEMIDLIST)lParam1, (LPITEMIDLIST)lParam2));
400 TRACE("ret=%i\n",ret);
401 return ret;
404 /*************************************************************************
405 * ShellView_ListViewCompareItems
407 * Compare Function for the Listview (FileOpen Dialog)
409 * PARAMS
410 * lParam1 [I] the first ItemIdList to compare with
411 * lParam2 [I] the second ItemIdList to compare with
412 * lpData [I] The column ID for the header Ctrl to process
414 * RETURNS
415 * A negative value if the first item should precede the second,
416 * a positive value if the first item should follow the second,
417 * or zero if the two items are equivalent
419 * NOTES
420 * FIXME: function does what ShellView_CompareItems is supposed to do.
421 * unify it and figure out how to use the undocumented first parameter
422 * of IShellFolder_CompareIDs to do the job this function does and
423 * move this code to IShellFolder.
424 * make LISTVIEW_SORT_INFO obsolete
425 * the way this function works is only usable if we had only
426 * filesystemfolders (25/10/99 jsch)
428 static INT CALLBACK ShellView_ListViewCompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
430 INT nDiff=0;
431 FILETIME fd1, fd2;
432 char strName1[MAX_PATH], strName2[MAX_PATH];
433 BOOL bIsFolder1, bIsFolder2,bIsBothFolder;
434 LPITEMIDLIST pItemIdList1 = (LPITEMIDLIST) lParam1;
435 LPITEMIDLIST pItemIdList2 = (LPITEMIDLIST) lParam2;
436 LISTVIEW_SORT_INFO *pSortInfo = (LPLISTVIEW_SORT_INFO) lpData;
439 bIsFolder1 = _ILIsFolder(pItemIdList1);
440 bIsFolder2 = _ILIsFolder(pItemIdList2);
441 bIsBothFolder = bIsFolder1 && bIsFolder2;
443 /* When sorting between a File and a Folder, the Folder gets sorted first */
444 if( (bIsFolder1 || bIsFolder2) && !bIsBothFolder)
446 nDiff = bIsFolder1 ? -1 : 1;
448 else
450 /* Sort by Time: Folders or Files can be sorted */
452 if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TIME)
454 _ILGetFileDateTime(pItemIdList1, &fd1);
455 _ILGetFileDateTime(pItemIdList2, &fd2);
456 nDiff = CompareFileTime(&fd2, &fd1);
458 /* Sort by Attribute: Folder or Files can be sorted */
459 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_ATTRIB)
461 _ILGetFileAttributes(pItemIdList1, strName1, MAX_PATH);
462 _ILGetFileAttributes(pItemIdList2, strName2, MAX_PATH);
463 nDiff = lstrcmpiA(strName1, strName2);
465 /* Sort by FileName: Folder or Files can be sorted */
466 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_NAME || bIsBothFolder)
468 /* Sort by Text */
469 _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
470 _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
471 nDiff = lstrcmpiA(strName1, strName2);
473 /* Sort by File Size, Only valid for Files */
474 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_SIZE)
476 nDiff = (INT)(_ILGetFileSize(pItemIdList1, NULL, 0) - _ILGetFileSize(pItemIdList2, NULL, 0));
478 /* Sort by File Type, Only valid for Files */
479 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TYPE)
481 /* Sort by Type */
482 _ILGetFileType(pItemIdList1, strName1, MAX_PATH);
483 _ILGetFileType(pItemIdList2, strName2, MAX_PATH);
484 nDiff = lstrcmpiA(strName1, strName2);
487 /* If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
489 if(nDiff == 0)
491 _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
492 _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
493 nDiff = lstrcmpiA(strName1, strName2);
496 if(!pSortInfo->bIsAscending)
498 nDiff = -nDiff;
501 return nDiff;
505 /**********************************************************
506 * LV_FindItemByPidl()
508 static int LV_FindItemByPidl(
509 IShellViewImpl * This,
510 LPCITEMIDLIST pidl)
512 LVITEMA lvItem;
513 ZeroMemory(&lvItem, sizeof(LVITEMA));
514 lvItem.mask = LVIF_PARAM;
515 for(lvItem.iItem = 0; ListView_GetItemA(This->hWndList, &lvItem); lvItem.iItem++)
517 LPITEMIDLIST currentpidl = (LPITEMIDLIST) lvItem.lParam;
518 HRESULT hr = IShellFolder_CompareIDs(This->pSFParent, 0, pidl, currentpidl);
519 if(SUCCEEDED(hr) && !HRESULT_CODE(hr))
521 return lvItem.iItem;
524 return -1;
527 /**********************************************************
528 * LV_AddItem()
530 static BOOLEAN LV_AddItem(IShellViewImpl * This, LPCITEMIDLIST pidl)
532 LVITEMA lvItem;
534 TRACE("(%p)(pidl=%p)\n", This, pidl);
536 ZeroMemory(&lvItem, sizeof(lvItem)); /* create the listview item*/
537 lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; /*set the mask*/
538 lvItem.iItem = ListView_GetItemCount(This->hWndList); /*add the item to the end of the list*/
539 lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidl)); /*set the item's data*/
540 lvItem.pszText = LPSTR_TEXTCALLBACKA; /*get text on a callback basis*/
541 lvItem.iImage = I_IMAGECALLBACK; /*get the image on a callback basis*/
542 return (-1==ListView_InsertItemA(This->hWndList, &lvItem))? FALSE: TRUE;
545 /**********************************************************
546 * LV_DeleteItem()
548 static BOOLEAN LV_DeleteItem(IShellViewImpl * This, LPCITEMIDLIST pidl)
550 int nIndex;
552 TRACE("(%p)(pidl=%p)\n", This, pidl);
554 nIndex = LV_FindItemByPidl(This, ILFindLastID(pidl));
555 return (-1==ListView_DeleteItem(This->hWndList, nIndex))? FALSE: TRUE;
558 /**********************************************************
559 * LV_RenameItem()
561 static BOOLEAN LV_RenameItem(IShellViewImpl * This, LPCITEMIDLIST pidlOld, LPCITEMIDLIST pidlNew )
563 int nItem;
564 LVITEMA lvItem;
566 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", This, pidlOld, pidlNew);
568 nItem = LV_FindItemByPidl(This, ILFindLastID(pidlOld));
569 if ( -1 != nItem )
571 ZeroMemory(&lvItem, sizeof(lvItem)); /* create the listview item*/
572 lvItem.mask = LVIF_PARAM; /* only the pidl */
573 lvItem.iItem = nItem;
574 ListView_GetItemA(This->hWndList, &lvItem);
576 SHFree((LPITEMIDLIST)lvItem.lParam);
577 lvItem.mask = LVIF_PARAM;
578 lvItem.iItem = nItem;
579 lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidlNew)); /* set the item's data */
580 ListView_SetItemA(This->hWndList, &lvItem);
581 ListView_Update(This->hWndList, nItem);
582 return TRUE; /* FIXME: better handling */
584 return FALSE;
586 /**********************************************************
587 * ShellView_FillList()
589 * - gets the objectlist from the shellfolder
590 * - sorts the list
591 * - fills the list into the view
594 static INT CALLBACK fill_list( LPVOID ptr, LPVOID arg )
596 LPITEMIDLIST pidl = ptr;
597 IShellViewImpl *This = arg;
598 /* in a commdlg This works as a filemask*/
599 if ( IncludeObject(This, pidl)==S_OK ) LV_AddItem(This, pidl);
600 SHFree(pidl);
601 return TRUE;
604 static HRESULT ShellView_FillList(IShellViewImpl * This)
606 LPENUMIDLIST pEnumIDList;
607 LPITEMIDLIST pidl;
608 DWORD dwFetched;
609 HRESULT hRes;
610 HDPA hdpa;
612 TRACE("%p\n",This);
614 /* get the itemlist from the shfolder*/
615 hRes = IShellFolder_EnumObjects(This->pSFParent,This->hWnd, SHCONTF_NONFOLDERS | SHCONTF_FOLDERS, &pEnumIDList);
616 if (hRes != S_OK)
618 if (hRes==S_FALSE)
619 return(NOERROR);
620 return(hRes);
623 /* create a pointer array */
624 hdpa = DPA_Create(16);
625 if (!hdpa)
627 return(E_OUTOFMEMORY);
630 /* copy the items into the array*/
631 while((S_OK == IEnumIDList_Next(pEnumIDList,1, &pidl, &dwFetched)) && dwFetched)
633 if (DPA_InsertPtr(hdpa, 0x7fff, pidl) == -1)
635 SHFree(pidl);
639 /* sort the array */
640 DPA_Sort(hdpa, ShellView_CompareItems, (LPARAM)This->pSFParent);
642 /*turn the listview's redrawing off*/
643 SendMessageA(This->hWndList, WM_SETREDRAW, FALSE, 0);
645 DPA_DestroyCallback( hdpa, fill_list, This );
647 /*turn the listview's redrawing back on and force it to draw*/
648 SendMessageA(This->hWndList, WM_SETREDRAW, TRUE, 0);
650 IEnumIDList_Release(pEnumIDList); /* destroy the list*/
652 return S_OK;
655 /**********************************************************
656 * ShellView_OnCreate()
658 static LRESULT ShellView_OnCreate(IShellViewImpl * This)
660 IDropTarget* pdt;
661 SHChangeNotifyEntry ntreg;
662 IPersistFolder2 * ppf2 = NULL;
664 TRACE("%p\n",This);
666 if(ShellView_CreateList(This))
668 if(ShellView_InitList(This))
670 ShellView_FillList(This);
674 if (SUCCEEDED(IShellFolder_CreateViewObject(This->pSFParent, This->hWnd, &IID_IDropTarget, (LPVOID*)&pdt)))
676 RegisterDragDrop(This->hWnd, pdt);
677 IDropTarget_Release(pdt);
680 /* register for receiving notifications */
681 IShellFolder_QueryInterface(This->pSFParent, &IID_IPersistFolder2, (LPVOID*)&ppf2);
682 if (ppf2)
684 IPersistFolder2_GetCurFolder(ppf2, (LPITEMIDLIST*)&ntreg.pidl);
685 ntreg.fRecursive = TRUE;
686 This->hNotify = SHChangeNotifyRegister(This->hWnd, SHCNF_IDLIST, SHCNE_ALLEVENTS, SHV_CHANGE_NOTIFY, 1, &ntreg);
687 SHFree((LPITEMIDLIST)ntreg.pidl);
688 IPersistFolder2_Release(ppf2);
691 This->hAccel = LoadAcceleratorsA(shell32_hInstance, "shv_accel");
693 return S_OK;
696 /**********************************************************
697 * #### Handling of the menus ####
700 /**********************************************************
701 * ShellView_BuildFileMenu()
703 static HMENU ShellView_BuildFileMenu(IShellViewImpl * This)
704 { CHAR szText[MAX_PATH];
705 MENUITEMINFOA mii;
706 int nTools,i;
707 HMENU hSubMenu;
709 TRACE("(%p)\n",This);
711 hSubMenu = CreatePopupMenu();
712 if(hSubMenu)
713 { /*get the number of items in our global array*/
714 for(nTools = 0; Tools[nTools].idCommand != -1; nTools++){}
716 /*add the menu items*/
717 for(i = 0; i < nTools; i++)
719 LoadStringA(shell32_hInstance, Tools[i].idMenuString, szText, MAX_PATH);
721 ZeroMemory(&mii, sizeof(mii));
722 mii.cbSize = sizeof(mii);
723 mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
725 if(BTNS_SEP != Tools[i].bStyle) /* no separator*/
727 mii.fType = MFT_STRING;
728 mii.fState = MFS_ENABLED;
729 mii.dwTypeData = szText;
730 mii.wID = Tools[i].idCommand;
732 else
734 mii.fType = MFT_SEPARATOR;
736 /* tack This item onto the end of the menu */
737 InsertMenuItemA(hSubMenu, (UINT)-1, TRUE, &mii);
740 TRACE("-- return (menu=%p)\n",hSubMenu);
741 return hSubMenu;
743 /**********************************************************
744 * ShellView_MergeFileMenu()
746 static void ShellView_MergeFileMenu(IShellViewImpl * This, HMENU hSubMenu)
747 { TRACE("(%p)->(submenu=%p) stub\n",This,hSubMenu);
749 if(hSubMenu)
750 { /*insert This item at the beginning of the menu */
751 _InsertMenuItem(hSubMenu, 0, TRUE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
752 _InsertMenuItem(hSubMenu, 0, TRUE, IDM_MYFILEITEM, MFT_STRING, "dummy45", MFS_ENABLED);
755 TRACE("--\n");
758 /**********************************************************
759 * ShellView_MergeViewMenu()
762 static void ShellView_MergeViewMenu(IShellViewImpl * This, HMENU hSubMenu)
763 { MENUITEMINFOA mii;
765 TRACE("(%p)->(submenu=%p)\n",This,hSubMenu);
767 if(hSubMenu)
768 { /*add a separator at the correct position in the menu*/
769 _InsertMenuItem(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
771 ZeroMemory(&mii, sizeof(mii));
772 mii.cbSize = sizeof(mii);
773 mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_DATA;
774 mii.fType = MFT_STRING;
775 mii.dwTypeData = "View";
776 mii.hSubMenu = LoadMenuA(shell32_hInstance, "MENU_001");
777 InsertMenuItemA(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
781 /**********************************************************
782 * ShellView_GetSelections()
784 * - fills the this->apidl list with the selected objects
786 * RETURNS
787 * number of selected items
789 static UINT ShellView_GetSelections(IShellViewImpl * This)
791 LVITEMA lvItem;
792 UINT i = 0;
794 if (This->apidl)
796 SHFree(This->apidl);
799 This->cidl = ListView_GetSelectedCount(This->hWndList);
800 This->apidl = (LPITEMIDLIST*)SHAlloc(This->cidl * sizeof(LPITEMIDLIST));
802 TRACE("selected=%i\n", This->cidl);
804 if(This->apidl)
806 TRACE("-- Items selected =%u\n", This->cidl);
808 ZeroMemory(&lvItem, sizeof(lvItem));
809 lvItem.mask = LVIF_STATE | LVIF_PARAM;
810 lvItem.stateMask = LVIS_SELECTED;
812 while(ListView_GetItemA(This->hWndList, &lvItem) && (i < This->cidl))
814 if(lvItem.state & LVIS_SELECTED)
816 This->apidl[i] = (LPITEMIDLIST)lvItem.lParam;
817 i++;
818 TRACE("-- selected Item found\n");
820 lvItem.iItem++;
823 return This->cidl;
827 /**********************************************************
828 * ShellView_OpenSelectedItems()
830 static HRESULT ShellView_OpenSelectedItems(IShellViewImpl * This)
832 static UINT CF_IDLIST = 0;
833 HRESULT hr;
834 IDataObject* selection;
835 FORMATETC fetc;
836 STGMEDIUM stgm;
837 LPIDA pIDList;
838 LPCITEMIDLIST parent_pidl;
839 int i;
841 if (0 == ShellView_GetSelections(This))
843 return S_OK;
845 hr = IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl,
846 (LPCITEMIDLIST*)This->apidl, &IID_IDataObject,
847 0, (LPVOID *)&selection);
848 if (FAILED(hr))
849 return hr;
851 if (0 == CF_IDLIST)
853 CF_IDLIST = RegisterClipboardFormatA(CFSTR_SHELLIDLIST);
855 fetc.cfFormat = CF_IDLIST;
856 fetc.ptd = NULL;
857 fetc.dwAspect = DVASPECT_CONTENT;
858 fetc.lindex = -1;
859 fetc.tymed = TYMED_HGLOBAL;
861 hr = IDataObject_QueryGetData(selection, &fetc);
862 if (FAILED(hr))
863 return hr;
865 hr = IDataObject_GetData(selection, &fetc, &stgm);
866 if (FAILED(hr))
867 return hr;
869 pIDList = GlobalLock(stgm.u.hGlobal);
871 parent_pidl = (LPCITEMIDLIST) ((LPBYTE)pIDList+pIDList->aoffset[0]);
872 for (i = pIDList->cidl; i > 0; --i)
874 LPCITEMIDLIST pidl;
875 SFGAOF attribs;
877 pidl = (LPCITEMIDLIST)((LPBYTE)pIDList+pIDList->aoffset[i]);
879 attribs = SFGAO_FOLDER;
880 hr = IShellFolder_GetAttributesOf(This->pSFParent, 1, &pidl, &attribs);
882 if (SUCCEEDED(hr) && ! (attribs & SFGAO_FOLDER))
884 SHELLEXECUTEINFOA shexinfo;
886 shexinfo.cbSize = sizeof(SHELLEXECUTEINFOA);
887 shexinfo.fMask = SEE_MASK_INVOKEIDLIST; /* SEE_MASK_IDLIST is also possible. */
888 shexinfo.hwnd = NULL;
889 shexinfo.lpVerb = NULL;
890 shexinfo.lpFile = NULL;
891 shexinfo.lpParameters = NULL;
892 shexinfo.lpDirectory = NULL;
893 shexinfo.nShow = SW_NORMAL;
894 shexinfo.lpIDList = ILCombine(parent_pidl, pidl);
896 ShellExecuteExA(&shexinfo); /* Discard error/success info */
898 ILFree((LPITEMIDLIST)shexinfo.lpIDList);
902 GlobalUnlock(stgm.u.hGlobal);
903 ReleaseStgMedium(&stgm);
905 IDataObject_Release(selection);
907 return S_OK;
910 /**********************************************************
911 * ShellView_DoContextMenu()
913 static void ShellView_DoContextMenu(IShellViewImpl * This, WORD x, WORD y, BOOL bDefault)
914 { UINT uCommand;
915 DWORD wFlags;
916 HMENU hMenu;
917 BOOL fExplore = FALSE;
918 HWND hwndTree = 0;
919 LPCONTEXTMENU pContextMenu = NULL;
920 IContextMenu2 *pCM = NULL;
921 CMINVOKECOMMANDINFO cmi;
923 TRACE("(%p)->(0x%08x 0x%08x 0x%08x) stub\n",This, x, y, bDefault);
925 /* look, what's selected and create a context menu object of it*/
926 if( ShellView_GetSelections(This) )
928 IShellFolder_GetUIObjectOf( This->pSFParent, This->hWndParent, This->cidl, (LPCITEMIDLIST*)This->apidl,
929 (REFIID)&IID_IContextMenu, NULL, (LPVOID *)&pContextMenu);
931 if(pContextMenu)
933 TRACE("-- pContextMenu\n");
934 hMenu = CreatePopupMenu();
936 if( hMenu )
938 /* See if we are in Explore or Open mode. If the browser's tree is present, we are in Explore mode.*/
939 if(SUCCEEDED(IShellBrowser_GetControlWindow(This->pShellBrowser,FCW_TREE, &hwndTree)) && hwndTree)
941 TRACE("-- explore mode\n");
942 fExplore = TRUE;
945 /* build the flags depending on what we can do with the selected item */
946 wFlags = CMF_NORMAL | (This->cidl != 1 ? 0 : CMF_CANRENAME) | (fExplore ? CMF_EXPLORE : 0);
948 /* let the ContextMenu merge its items in */
949 if (SUCCEEDED(IContextMenu_QueryContextMenu( pContextMenu, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, wFlags )))
951 if (This->FolderSettings.fFlags & FWF_DESKTOP)
952 SetMenuDefaultItem(hMenu, FCIDM_SHVIEW_OPEN, MF_BYCOMMAND);
954 if( bDefault )
956 TRACE("-- get menu default command\n");
957 uCommand = GetMenuDefaultItem(hMenu, FALSE, GMDI_GOINTOPOPUPS);
959 else
961 TRACE("-- track popup\n");
962 uCommand = TrackPopupMenu( hMenu,TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
965 if(uCommand > 0)
967 TRACE("-- uCommand=%u\n", uCommand);
968 if (uCommand==FCIDM_SHVIEW_OPEN && IsInCommDlg(This))
970 TRACE("-- dlg: OnDefaultCommand\n");
971 if (OnDefaultCommand(This) != S_OK)
973 ShellView_OpenSelectedItems(This);
976 else
978 TRACE("-- explore -- invoke command\n");
979 ZeroMemory(&cmi, sizeof(cmi));
980 cmi.cbSize = sizeof(cmi);
981 cmi.hwnd = This->hWndParent; /* this window has to answer CWM_GETISHELLBROWSER */
982 cmi.lpVerb = (LPCSTR)MAKEINTRESOURCEA(uCommand);
983 IContextMenu_InvokeCommand(pContextMenu, &cmi);
986 DestroyMenu(hMenu);
989 if (pContextMenu)
990 IContextMenu_Release(pContextMenu);
993 else /* background context menu */
995 hMenu = CreatePopupMenu();
997 pCM = ISvBgCm_Constructor(This->pSFParent, FALSE);
998 IContextMenu2_QueryContextMenu(pCM, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, 0);
1000 uCommand = TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
1001 DestroyMenu(hMenu);
1003 TRACE("-- (%p)->(uCommand=0x%08x )\n",This, uCommand);
1005 ZeroMemory(&cmi, sizeof(cmi));
1006 cmi.cbSize = sizeof(cmi);
1007 cmi.lpVerb = (LPCSTR)MAKEINTRESOURCEA(uCommand);
1008 cmi.hwnd = This->hWndParent;
1009 IContextMenu2_InvokeCommand(pCM, &cmi);
1011 IContextMenu2_Release(pCM);
1015 /**********************************************************
1016 * ##### message handling #####
1019 /**********************************************************
1020 * ShellView_OnSize()
1022 static LRESULT ShellView_OnSize(IShellViewImpl * This, WORD wWidth, WORD wHeight)
1024 TRACE("%p width=%u height=%u\n",This, wWidth,wHeight);
1026 /*resize the ListView to fit our window*/
1027 if(This->hWndList)
1029 MoveWindow(This->hWndList, 0, 0, wWidth, wHeight, TRUE);
1032 return S_OK;
1034 /**********************************************************
1035 * ShellView_OnDeactivate()
1037 * NOTES
1038 * internal
1040 static void ShellView_OnDeactivate(IShellViewImpl * This)
1042 TRACE("%p\n",This);
1044 if(This->uState != SVUIA_DEACTIVATE)
1046 if(This->hMenu)
1048 IShellBrowser_SetMenuSB(This->pShellBrowser,0, 0, 0);
1049 IShellBrowser_RemoveMenusSB(This->pShellBrowser,This->hMenu);
1050 DestroyMenu(This->hMenu);
1051 This->hMenu = 0;
1054 This->uState = SVUIA_DEACTIVATE;
1058 /**********************************************************
1059 * ShellView_OnActivate()
1061 static LRESULT ShellView_OnActivate(IShellViewImpl * This, UINT uState)
1062 { OLEMENUGROUPWIDTHS omw = { {0, 0, 0, 0, 0, 0} };
1063 MENUITEMINFOA mii;
1064 CHAR szText[MAX_PATH];
1066 TRACE("%p uState=%x\n",This,uState);
1068 /*don't do anything if the state isn't really changing */
1069 if(This->uState == uState)
1071 return S_OK;
1074 ShellView_OnDeactivate(This);
1076 /*only do This if we are active */
1077 if(uState != SVUIA_DEACTIVATE)
1079 /*merge the menus */
1080 This->hMenu = CreateMenu();
1082 if(This->hMenu)
1084 IShellBrowser_InsertMenusSB(This->pShellBrowser, This->hMenu, &omw);
1085 TRACE("-- after fnInsertMenusSB\n");
1087 /*build the top level menu get the menu item's text*/
1088 strcpy(szText,"dummy 31");
1090 ZeroMemory(&mii, sizeof(mii));
1091 mii.cbSize = sizeof(mii);
1092 mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_STATE;
1093 mii.fType = MFT_STRING;
1094 mii.fState = MFS_ENABLED;
1095 mii.dwTypeData = szText;
1096 mii.hSubMenu = ShellView_BuildFileMenu(This);
1098 /*insert our menu into the menu bar*/
1099 if(mii.hSubMenu)
1101 InsertMenuItemA(This->hMenu, FCIDM_MENU_HELP, FALSE, &mii);
1104 /*get the view menu so we can merge with it*/
1105 ZeroMemory(&mii, sizeof(mii));
1106 mii.cbSize = sizeof(mii);
1107 mii.fMask = MIIM_SUBMENU;
1109 if(GetMenuItemInfoA(This->hMenu, FCIDM_MENU_VIEW, FALSE, &mii))
1111 ShellView_MergeViewMenu(This, mii.hSubMenu);
1114 /*add the items that should only be added if we have the focus*/
1115 if(SVUIA_ACTIVATE_FOCUS == uState)
1117 /*get the file menu so we can merge with it */
1118 ZeroMemory(&mii, sizeof(mii));
1119 mii.cbSize = sizeof(mii);
1120 mii.fMask = MIIM_SUBMENU;
1122 if(GetMenuItemInfoA(This->hMenu, FCIDM_MENU_FILE, FALSE, &mii))
1124 ShellView_MergeFileMenu(This, mii.hSubMenu);
1127 TRACE("-- before fnSetMenuSB\n");
1128 IShellBrowser_SetMenuSB(This->pShellBrowser, This->hMenu, 0, This->hWnd);
1131 This->uState = uState;
1132 TRACE("--\n");
1133 return S_OK;
1136 /**********************************************************
1137 * ShellView_OnSetFocus()
1140 static LRESULT ShellView_OnSetFocus(IShellViewImpl * This)
1142 TRACE("%p\n",This);
1144 /* Tell the browser one of our windows has received the focus. This
1145 should always be done before merging menus (OnActivate merges the
1146 menus) if one of our windows has the focus.*/
1148 IShellBrowser_OnViewWindowActive(This->pShellBrowser,(IShellView*) This);
1149 ShellView_OnActivate(This, SVUIA_ACTIVATE_FOCUS);
1151 /* Set the focus to the listview */
1152 SetFocus(This->hWndList);
1154 /* Notify the ICommDlgBrowser interface */
1155 OnStateChange(This,CDBOSC_SETFOCUS);
1157 return 0;
1160 /**********************************************************
1161 * ShellView_OnKillFocus()
1163 static LRESULT ShellView_OnKillFocus(IShellViewImpl * This)
1165 TRACE("(%p) stub\n",This);
1167 ShellView_OnActivate(This, SVUIA_ACTIVATE_NOFOCUS);
1168 /* Notify the ICommDlgBrowser */
1169 OnStateChange(This,CDBOSC_KILLFOCUS);
1171 return 0;
1174 /**********************************************************
1175 * ShellView_OnCommand()
1177 * NOTES
1178 * the CmdID's are the ones from the context menu
1180 static LRESULT ShellView_OnCommand(IShellViewImpl * This,DWORD dwCmdID, DWORD dwCmd, HWND hwndCmd)
1182 TRACE("(%p)->(0x%08lx 0x%08lx %p) stub\n",This, dwCmdID, dwCmd, hwndCmd);
1184 switch(dwCmdID)
1186 case FCIDM_SHVIEW_SMALLICON:
1187 This->FolderSettings.ViewMode = FVM_SMALLICON;
1188 SetStyle (This, LVS_SMALLICON, LVS_TYPEMASK);
1189 CheckToolbar(This);
1190 break;
1192 case FCIDM_SHVIEW_BIGICON:
1193 This->FolderSettings.ViewMode = FVM_ICON;
1194 SetStyle (This, LVS_ICON, LVS_TYPEMASK);
1195 CheckToolbar(This);
1196 break;
1198 case FCIDM_SHVIEW_LISTVIEW:
1199 This->FolderSettings.ViewMode = FVM_LIST;
1200 SetStyle (This, LVS_LIST, LVS_TYPEMASK);
1201 CheckToolbar(This);
1202 break;
1204 case FCIDM_SHVIEW_REPORTVIEW:
1205 This->FolderSettings.ViewMode = FVM_DETAILS;
1206 SetStyle (This, LVS_REPORT, LVS_TYPEMASK);
1207 CheckToolbar(This);
1208 break;
1210 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1211 case 0x30:
1212 case 0x31:
1213 case 0x32:
1214 case 0x33:
1215 This->ListViewSortInfo.nHeaderID = (LPARAM) (dwCmdID - 0x30);
1216 This->ListViewSortInfo.bIsAscending = TRUE;
1217 This->ListViewSortInfo.nLastHeaderID = This->ListViewSortInfo.nHeaderID;
1218 ListView_SortItems(This->hWndList, ShellView_ListViewCompareItems, (LPARAM) (&(This->ListViewSortInfo)));
1219 break;
1221 default:
1222 TRACE("-- COMMAND 0x%04lx unhandled\n", dwCmdID);
1224 return 0;
1227 /**********************************************************
1228 * ShellView_OnNotify()
1231 static LRESULT ShellView_OnNotify(IShellViewImpl * This, UINT CtlID, LPNMHDR lpnmh)
1232 { LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)lpnmh;
1233 NMLVDISPINFOA *lpdi = (NMLVDISPINFOA *)lpnmh;
1234 LPITEMIDLIST pidl;
1236 TRACE("%p CtlID=%u lpnmh->code=%x\n",This,CtlID,lpnmh->code);
1238 switch(lpnmh->code)
1240 case NM_SETFOCUS:
1241 TRACE("-- NM_SETFOCUS %p\n",This);
1242 ShellView_OnSetFocus(This);
1243 break;
1245 case NM_KILLFOCUS:
1246 TRACE("-- NM_KILLFOCUS %p\n",This);
1247 ShellView_OnDeactivate(This);
1248 /* Notify the ICommDlgBrowser interface */
1249 OnStateChange(This,CDBOSC_KILLFOCUS);
1250 break;
1252 case NM_CUSTOMDRAW:
1253 TRACE("-- NM_CUSTOMDRAW %p\n",This);
1254 return CDRF_DODEFAULT;
1256 case NM_RELEASEDCAPTURE:
1257 TRACE("-- NM_RELEASEDCAPTURE %p\n",This);
1258 break;
1260 case NM_CLICK:
1261 TRACE("-- NM_CLICK %p\n",This);
1262 break;
1264 case NM_RCLICK:
1265 TRACE("-- NM_RCLICK %p\n",This);
1266 break;
1268 case NM_DBLCLK:
1269 TRACE("-- NM_DBLCLK %p\n",This);
1270 if (OnDefaultCommand(This) != S_OK) ShellView_OpenSelectedItems(This);
1271 break;
1273 case NM_RETURN:
1274 TRACE("-- NM_DBLCLK %p\n",This);
1275 if (OnDefaultCommand(This) != S_OK) ShellView_OpenSelectedItems(This);
1276 break;
1278 case HDN_ENDTRACKA:
1279 TRACE("-- HDN_ENDTRACKA %p\n",This);
1280 /*nColumn1 = ListView_GetColumnWidth(This->hWndList, 0);
1281 nColumn2 = ListView_GetColumnWidth(This->hWndList, 1);*/
1282 break;
1284 case LVN_DELETEITEM:
1285 TRACE("-- LVN_DELETEITEM %p\n",This);
1286 SHFree((LPITEMIDLIST)lpnmlv->lParam); /*delete the pidl because we made a copy of it*/
1287 break;
1289 case LVN_DELETEALLITEMS:
1290 TRACE("-- LVN_DELETEALLITEMS %p\n",This);
1291 return FALSE;
1293 case LVN_INSERTITEM:
1294 TRACE("-- LVN_INSERTITEM (STUB)%p\n",This);
1295 break;
1297 case LVN_ITEMACTIVATE:
1298 TRACE("-- LVN_ITEMACTIVATE %p\n",This);
1299 OnStateChange(This, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
1300 break;
1302 case LVN_COLUMNCLICK:
1303 This->ListViewSortInfo.nHeaderID = lpnmlv->iSubItem;
1304 if(This->ListViewSortInfo.nLastHeaderID == This->ListViewSortInfo.nHeaderID)
1306 This->ListViewSortInfo.bIsAscending = !This->ListViewSortInfo.bIsAscending;
1308 else
1310 This->ListViewSortInfo.bIsAscending = TRUE;
1312 This->ListViewSortInfo.nLastHeaderID = This->ListViewSortInfo.nHeaderID;
1314 ListView_SortItems(lpnmlv->hdr.hwndFrom, ShellView_ListViewCompareItems, (LPARAM) (&(This->ListViewSortInfo)));
1315 break;
1317 case LVN_GETDISPINFOA:
1318 case LVN_GETDISPINFOW:
1319 TRACE("-- LVN_GETDISPINFO %p\n",This);
1320 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1322 if(lpdi->item.mask & LVIF_TEXT) /* text requested */
1324 if (This->pSF2Parent)
1326 SHELLDETAILS sd;
1327 IShellFolder2_GetDetailsOf(This->pSF2Parent, pidl, lpdi->item.iSubItem, &sd);
1328 if (lpnmh->code == LVN_GETDISPINFOA)
1330 StrRetToStrNA( lpdi->item.pszText, lpdi->item.cchTextMax, &sd.str, NULL);
1331 TRACE("-- text=%s\n",lpdi->item.pszText);
1333 else /* LVN_GETDISPINFOW */
1335 StrRetToStrNW( ((NMLVDISPINFOW *)lpdi)->item.pszText, lpdi->item.cchTextMax, &sd.str, NULL);
1336 TRACE("-- text=%s\n",debugstr_w((WCHAR*)(lpdi->item.pszText)));
1339 else
1341 FIXME("no SF2\n");
1344 if(lpdi->item.mask & LVIF_IMAGE) /* image requested */
1346 lpdi->item.iImage = SHMapPIDLToSystemImageListIndex(This->pSFParent, pidl, 0);
1348 break;
1350 case LVN_ITEMCHANGED:
1351 TRACE("-- LVN_ITEMCHANGED %p\n",This);
1352 OnStateChange(This, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
1353 break;
1355 case LVN_BEGINDRAG:
1356 case LVN_BEGINRDRAG:
1357 TRACE("-- LVN_BEGINDRAG\n");
1359 if (ShellView_GetSelections(This))
1361 IDataObject * pda;
1362 DWORD dwAttributes = SFGAO_CANLINK;
1363 DWORD dwEffect = DROPEFFECT_COPY | DROPEFFECT_MOVE;
1365 if (SUCCEEDED(IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, (LPCITEMIDLIST*)This->apidl, &IID_IDataObject,0,(LPVOID *)&pda)))
1367 IDropSource * pds = (IDropSource*)&(This->lpvtblDropSource); /* own DropSource interface */
1369 if (SUCCEEDED(IShellFolder_GetAttributesOf(This->pSFParent, This->cidl, (LPCITEMIDLIST*)This->apidl, &dwAttributes)))
1371 if (dwAttributes & SFGAO_CANLINK)
1373 dwEffect |= DROPEFFECT_LINK;
1377 if (pds)
1379 DWORD dwEffect;
1380 DoDragDrop(pda, pds, dwEffect, &dwEffect);
1382 IDataObject_Release(pda);
1385 break;
1387 case LVN_BEGINLABELEDITA:
1389 DWORD dwAttr = SFGAO_CANRENAME;
1390 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1392 TRACE("-- LVN_BEGINLABELEDITA %p\n",This);
1394 IShellFolder_GetAttributesOf(This->pSFParent, 1, (LPCITEMIDLIST*)&pidl, &dwAttr);
1395 if (SFGAO_CANRENAME & dwAttr)
1397 return FALSE;
1399 return TRUE;
1402 case LVN_ENDLABELEDITA:
1404 TRACE("-- LVN_ENDLABELEDITA %p\n",This);
1405 if (lpdi->item.pszText)
1407 HRESULT hr;
1408 WCHAR wszNewName[MAX_PATH];
1409 LVITEMA lvItem;
1411 ZeroMemory(&lvItem, sizeof(LVITEMA));
1412 lvItem.iItem = lpdi->item.iItem;
1413 lvItem.mask = LVIF_PARAM;
1414 ListView_GetItemA(This->hWndList, &lvItem);
1416 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1417 if (!MultiByteToWideChar( CP_ACP, 0, lpdi->item.pszText, -1, wszNewName, MAX_PATH ))
1418 wszNewName[MAX_PATH-1] = 0;
1419 hr = IShellFolder_SetNameOf(This->pSFParent, 0, pidl, wszNewName, SHGDN_INFOLDER, &pidl);
1421 if(SUCCEEDED(hr) && pidl)
1423 lvItem.mask = LVIF_PARAM;
1424 lvItem.lParam = (LPARAM)pidl;
1425 ListView_SetItemA(This->hWndList, &lvItem);
1426 return TRUE;
1429 return FALSE;
1432 case LVN_KEYDOWN:
1434 /* MSG msg;
1435 msg.hwnd = This->hWnd;
1436 msg.message = WM_KEYDOWN;
1437 msg.wParam = plvKeyDown->wVKey;
1438 msg.lParam = 0;
1439 msg.time = 0;
1440 msg.pt = 0;*/
1442 LPNMLVKEYDOWN plvKeyDown = (LPNMLVKEYDOWN) lpnmh;
1444 /* initiate a rename of the selected file or directory */
1445 if(plvKeyDown->wVKey == VK_F2)
1447 /* see how many files are selected */
1448 int i = ListView_GetSelectedCount(This->hWndList);
1450 /* get selected item */
1451 if(i == 1)
1453 /* get selected item */
1454 i = ListView_GetNextItem(This->hWndList, -1,
1455 LVNI_SELECTED);
1457 ListView_EnsureVisible(This->hWndList, i, 0);
1458 ListView_EditLabelA(This->hWndList, i);
1461 #if 0
1462 TranslateAccelerator(This->hWnd, This->hAccel, &msg)
1463 #endif
1464 else if(plvKeyDown->wVKey == VK_DELETE)
1466 UINT i;
1467 int item_index;
1468 LVITEMA item;
1469 LPITEMIDLIST* pItems;
1470 ISFHelper *psfhlp;
1472 IShellFolder_QueryInterface(This->pSFParent, &IID_ISFHelper,
1473 (LPVOID*)&psfhlp);
1475 if (psfhlp == NULL)
1476 break;
1478 if(!(i = ListView_GetSelectedCount(This->hWndList)))
1479 break;
1481 /* allocate memory for the pidl array */
1482 pItems = HeapAlloc(GetProcessHeap(), 0,
1483 sizeof(LPITEMIDLIST) * i);
1485 /* retrieve all selected items */
1486 i = 0;
1487 item_index = -1;
1488 while(ListView_GetSelectedCount(This->hWndList) > i)
1490 /* get selected item */
1491 item_index = ListView_GetNextItem(This->hWndList,
1492 item_index, LVNI_SELECTED);
1493 item.iItem = item_index;
1494 item.mask |= LVIF_PARAM;
1495 ListView_GetItemA(This->hWndList, &item);
1497 /* get item pidl */
1498 pItems[i] = (LPITEMIDLIST)item.lParam;
1500 i++;
1503 /* perform the item deletion */
1504 ISFHelper_DeleteItems(psfhlp, i, (LPCITEMIDLIST*)pItems);
1506 /* free pidl array memory */
1507 HeapFree(GetProcessHeap(), 0, pItems);
1510 /* Initiate a refresh */
1511 else if(plvKeyDown->wVKey == VK_F5)
1513 IShellView_Refresh((IShellView*)This);
1516 else
1517 FIXME("LVN_KEYDOWN key=0x%08x\n",plvKeyDown->wVKey);
1519 break;
1521 default:
1522 TRACE("-- %p WM_COMMAND %x unhandled\n", This, lpnmh->code);
1523 break;
1525 return 0;
1528 /**********************************************************
1529 * ShellView_OnChange()
1532 static LRESULT ShellView_OnChange(IShellViewImpl * This, LPITEMIDLIST * Pidls, LONG wEventId)
1535 TRACE("(%p)(%p,%p,0x%08lx)\n", This, Pidls[0], Pidls[1], wEventId);
1536 switch(wEventId)
1538 case SHCNE_MKDIR:
1539 case SHCNE_CREATE:
1540 LV_AddItem(This, Pidls[0]);
1541 break;
1542 case SHCNE_RMDIR:
1543 case SHCNE_DELETE:
1544 LV_DeleteItem(This, Pidls[0]);
1545 break;
1546 case SHCNE_RENAMEFOLDER:
1547 case SHCNE_RENAMEITEM:
1548 LV_RenameItem(This, Pidls[0], Pidls[1]);
1549 break;
1550 case SHCNE_UPDATEITEM:
1551 break;
1553 return TRUE;
1555 /**********************************************************
1556 * ShellView_WndProc
1559 static LRESULT CALLBACK ShellView_WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
1561 IShellViewImpl * pThis = (IShellViewImpl*)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
1562 LPCREATESTRUCTA lpcs;
1564 TRACE("(hwnd=%p msg=%x wparm=%x lparm=%lx)\n",hWnd, uMessage, wParam, lParam);
1566 switch (uMessage)
1568 case WM_NCCREATE:
1569 lpcs = (LPCREATESTRUCTA)lParam;
1570 pThis = (IShellViewImpl*)(lpcs->lpCreateParams);
1571 SetWindowLongPtrW(hWnd, GWLP_USERDATA, (ULONG_PTR)pThis);
1572 pThis->hWnd = hWnd; /*set the window handle*/
1573 break;
1575 case WM_SIZE: return ShellView_OnSize(pThis,LOWORD(lParam), HIWORD(lParam));
1576 case WM_SETFOCUS: return ShellView_OnSetFocus(pThis);
1577 case WM_KILLFOCUS: return ShellView_OnKillFocus(pThis);
1578 case WM_CREATE: return ShellView_OnCreate(pThis);
1579 case WM_ACTIVATE: return ShellView_OnActivate(pThis, SVUIA_ACTIVATE_FOCUS);
1580 case WM_NOTIFY: return ShellView_OnNotify(pThis,(UINT)wParam, (LPNMHDR)lParam);
1581 case WM_COMMAND: return ShellView_OnCommand(pThis,
1582 GET_WM_COMMAND_ID(wParam, lParam),
1583 GET_WM_COMMAND_CMD(wParam, lParam),
1584 GET_WM_COMMAND_HWND(wParam, lParam));
1585 case SHV_CHANGE_NOTIFY: return ShellView_OnChange(pThis, (LPITEMIDLIST*)wParam, (LONG)lParam);
1587 case WM_CONTEXTMENU: ShellView_DoContextMenu(pThis, LOWORD(lParam), HIWORD(lParam), FALSE);
1588 return 0;
1590 case WM_SHOWWINDOW: UpdateWindow(pThis->hWndList);
1591 break;
1593 case WM_GETDLGCODE: return SendMessageA(pThis->hWndList,uMessage,0,0);
1595 case WM_DESTROY:
1596 RevokeDragDrop(pThis->hWnd);
1597 SHChangeNotifyDeregister(pThis->hNotify);
1598 break;
1600 case WM_ERASEBKGND:
1601 if ((pThis->FolderSettings.fFlags & FWF_DESKTOP) ||
1602 (pThis->FolderSettings.fFlags & FWF_TRANSPARENT))
1603 return 1;
1604 break;
1607 return DefWindowProcA (hWnd, uMessage, wParam, lParam);
1609 /**********************************************************
1612 * The INTERFACE of the IShellView object
1615 **********************************************************
1616 * IShellView_QueryInterface
1618 static HRESULT WINAPI IShellView_fnQueryInterface(IShellView * iface,REFIID riid, LPVOID *ppvObj)
1620 IShellViewImpl *This = (IShellViewImpl *)iface;
1622 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1624 *ppvObj = NULL;
1626 if(IsEqualIID(riid, &IID_IUnknown))
1628 *ppvObj = This;
1630 else if(IsEqualIID(riid, &IID_IShellView))
1632 *ppvObj = (IShellView*)This;
1634 else if(IsEqualIID(riid, &IID_IOleCommandTarget))
1636 *ppvObj = (IOleCommandTarget*)&(This->lpvtblOleCommandTarget);
1638 else if(IsEqualIID(riid, &IID_IDropTarget))
1640 *ppvObj = (IDropTarget*)&(This->lpvtblDropTarget);
1642 else if(IsEqualIID(riid, &IID_IDropSource))
1644 *ppvObj = (IDropSource*)&(This->lpvtblDropSource);
1646 else if(IsEqualIID(riid, &IID_IViewObject))
1648 *ppvObj = (IViewObject*)&(This->lpvtblViewObject);
1651 if(*ppvObj)
1653 IUnknown_AddRef( (IUnknown*)*ppvObj );
1654 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1655 return S_OK;
1657 TRACE("-- Interface: E_NOINTERFACE\n");
1658 return E_NOINTERFACE;
1661 /**********************************************************
1662 * IShellView_AddRef
1664 static ULONG WINAPI IShellView_fnAddRef(IShellView * iface)
1666 IShellViewImpl *This = (IShellViewImpl *)iface;
1667 ULONG refCount = InterlockedIncrement(&This->ref);
1669 TRACE("(%p)->(count=%lu)\n", This, refCount - 1);
1671 return refCount;
1673 /**********************************************************
1674 * IShellView_Release
1676 static ULONG WINAPI IShellView_fnRelease(IShellView * iface)
1678 IShellViewImpl *This = (IShellViewImpl *)iface;
1679 ULONG refCount = InterlockedDecrement(&This->ref);
1681 TRACE("(%p)->(count=%li)\n", This, refCount + 1);
1683 if (!refCount)
1685 TRACE(" destroying IShellView(%p)\n",This);
1687 DestroyWindow(This->hWndList);
1689 if(This->pSFParent)
1690 IShellFolder_Release(This->pSFParent);
1692 if(This->pSF2Parent)
1693 IShellFolder2_Release(This->pSF2Parent);
1695 if(This->apidl)
1696 SHFree(This->apidl);
1698 if(This->pAdvSink)
1699 IAdviseSink_Release(This->pAdvSink);
1701 HeapFree(GetProcessHeap(),0,This);
1703 return refCount;
1706 /**********************************************************
1707 * ShellView_GetWindow
1709 static HRESULT WINAPI IShellView_fnGetWindow(IShellView * iface,HWND * phWnd)
1711 IShellViewImpl *This = (IShellViewImpl *)iface;
1713 TRACE("(%p)\n",This);
1715 *phWnd = This->hWnd;
1717 return S_OK;
1720 static HRESULT WINAPI IShellView_fnContextSensitiveHelp(IShellView * iface,BOOL fEnterMode)
1722 IShellViewImpl *This = (IShellViewImpl *)iface;
1724 FIXME("(%p) stub\n",This);
1726 return E_NOTIMPL;
1729 /**********************************************************
1730 * IShellView_TranslateAccelerator
1732 * FIXME:
1733 * use the accel functions
1735 static HRESULT WINAPI IShellView_fnTranslateAccelerator(IShellView * iface,LPMSG lpmsg)
1737 #if 0
1738 IShellViewImpl *This = (IShellViewImpl *)iface;
1740 FIXME("(%p)->(%p: hwnd=%x msg=%x lp=%lx wp=%x) stub\n",This,lpmsg, lpmsg->hwnd, lpmsg->message, lpmsg->lParam, lpmsg->wParam);
1741 #endif
1743 if ((lpmsg->message>=WM_KEYFIRST) && (lpmsg->message>=WM_KEYLAST))
1745 TRACE("-- key=0x04%x\n",lpmsg->wParam) ;
1747 return S_FALSE; /* not handled */
1750 static HRESULT WINAPI IShellView_fnEnableModeless(IShellView * iface,BOOL fEnable)
1752 IShellViewImpl *This = (IShellViewImpl *)iface;
1754 FIXME("(%p) stub\n",This);
1756 return E_NOTIMPL;
1759 static HRESULT WINAPI IShellView_fnUIActivate(IShellView * iface,UINT uState)
1761 IShellViewImpl *This = (IShellViewImpl *)iface;
1764 CHAR szName[MAX_PATH];
1766 LRESULT lResult;
1767 int nPartArray[1] = {-1};
1769 TRACE("(%p)->(state=%x) stub\n",This, uState);
1771 /*don't do anything if the state isn't really changing*/
1772 if(This->uState == uState)
1774 return S_OK;
1777 /*OnActivate handles the menu merging and internal state*/
1778 ShellView_OnActivate(This, uState);
1780 /*only do This if we are active*/
1781 if(uState != SVUIA_DEACTIVATE)
1785 GetFolderPath is not a method of IShellFolder
1786 IShellFolder_GetFolderPath( This->pSFParent, szName, sizeof(szName) );
1788 /* set the number of parts */
1789 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETPARTS, 1,
1790 (LPARAM)nPartArray, &lResult);
1792 /* set the text for the parts */
1794 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETTEXTA,
1795 0, (LPARAM)szName, &lResult);
1799 return S_OK;
1802 static HRESULT WINAPI IShellView_fnRefresh(IShellView * iface)
1804 IShellViewImpl *This = (IShellViewImpl *)iface;
1806 TRACE("(%p)\n",This);
1808 ListView_DeleteAllItems(This->hWndList);
1809 ShellView_FillList(This);
1811 return S_OK;
1814 static HRESULT WINAPI IShellView_fnCreateViewWindow(
1815 IShellView * iface,
1816 IShellView *lpPrevView,
1817 LPCFOLDERSETTINGS lpfs,
1818 IShellBrowser * psb,
1819 RECT * prcView,
1820 HWND *phWnd)
1822 IShellViewImpl *This = (IShellViewImpl *)iface;
1824 WNDCLASSA wc;
1825 *phWnd = 0;
1828 TRACE("(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n",This, lpPrevView,lpfs, psb, prcView, phWnd);
1829 TRACE("-- vmode=%x flags=%x left=%li top=%li right=%li bottom=%li\n",lpfs->ViewMode, lpfs->fFlags ,prcView->left,prcView->top, prcView->right, prcView->bottom);
1831 /*set up the member variables*/
1832 This->pShellBrowser = psb;
1833 This->FolderSettings = *lpfs;
1835 /*get our parent window*/
1836 IShellBrowser_AddRef(This->pShellBrowser);
1837 IShellBrowser_GetWindow(This->pShellBrowser, &(This->hWndParent));
1839 /* try to get the ICommDlgBrowserInterface, adds a reference !!! */
1840 This->pCommDlgBrowser=NULL;
1841 if ( SUCCEEDED (IShellBrowser_QueryInterface( This->pShellBrowser,
1842 (REFIID)&IID_ICommDlgBrowser, (LPVOID*) &This->pCommDlgBrowser)))
1844 TRACE("-- CommDlgBrowser\n");
1847 /*if our window class has not been registered, then do so*/
1848 if(!GetClassInfoA(shell32_hInstance, SV_CLASS_NAME, &wc))
1850 ZeroMemory(&wc, sizeof(wc));
1851 wc.style = CS_HREDRAW | CS_VREDRAW;
1852 wc.lpfnWndProc = ShellView_WndProc;
1853 wc.cbClsExtra = 0;
1854 wc.cbWndExtra = 0;
1855 wc.hInstance = shell32_hInstance;
1856 wc.hIcon = 0;
1857 wc.hCursor = LoadCursorA (0, (LPSTR)IDC_ARROW);
1858 wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
1859 wc.lpszMenuName = NULL;
1860 wc.lpszClassName = SV_CLASS_NAME;
1862 if(!RegisterClassA(&wc))
1863 return E_FAIL;
1866 *phWnd = CreateWindowExA(0,
1867 SV_CLASS_NAME,
1868 NULL,
1869 WS_CHILD | WS_VISIBLE | WS_TABSTOP,
1870 prcView->left,
1871 prcView->top,
1872 prcView->right - prcView->left,
1873 prcView->bottom - prcView->top,
1874 This->hWndParent,
1876 shell32_hInstance,
1877 (LPVOID)This);
1879 CheckToolbar(This);
1881 if(!*phWnd) return E_FAIL;
1883 return S_OK;
1886 static HRESULT WINAPI IShellView_fnDestroyViewWindow(IShellView * iface)
1888 IShellViewImpl *This = (IShellViewImpl *)iface;
1890 TRACE("(%p)\n",This);
1892 /*Make absolutely sure all our UI is cleaned up.*/
1893 IShellView_UIActivate((IShellView*)This, SVUIA_DEACTIVATE);
1895 if(This->hMenu)
1897 DestroyMenu(This->hMenu);
1900 DestroyWindow(This->hWnd);
1901 if(This->pShellBrowser) IShellBrowser_Release(This->pShellBrowser);
1902 if(This->pCommDlgBrowser) ICommDlgBrowser_Release(This->pCommDlgBrowser);
1905 return S_OK;
1908 static HRESULT WINAPI IShellView_fnGetCurrentInfo(IShellView * iface, LPFOLDERSETTINGS lpfs)
1910 IShellViewImpl *This = (IShellViewImpl *)iface;
1912 TRACE("(%p)->(%p) vmode=%x flags=%x\n",This, lpfs,
1913 This->FolderSettings.ViewMode, This->FolderSettings.fFlags);
1915 if (!lpfs) return E_INVALIDARG;
1917 *lpfs = This->FolderSettings;
1918 return NOERROR;
1921 static HRESULT WINAPI IShellView_fnAddPropertySheetPages(IShellView * iface, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam)
1923 IShellViewImpl *This = (IShellViewImpl *)iface;
1925 FIXME("(%p) stub\n",This);
1927 return E_NOTIMPL;
1930 static HRESULT WINAPI IShellView_fnSaveViewState(IShellView * iface)
1932 IShellViewImpl *This = (IShellViewImpl *)iface;
1934 FIXME("(%p) stub\n",This);
1936 return S_OK;
1939 static HRESULT WINAPI IShellView_fnSelectItem(
1940 IShellView * iface,
1941 LPCITEMIDLIST pidl,
1942 UINT uFlags)
1944 IShellViewImpl *This = (IShellViewImpl *)iface;
1945 int i;
1947 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n",This, pidl, uFlags);
1949 i = LV_FindItemByPidl(This, pidl);
1951 if (i != -1)
1953 LVITEMA lvItem;
1955 if(uFlags & SVSI_ENSUREVISIBLE)
1956 ListView_EnsureVisible(This->hWndList, i, 0);
1958 ZeroMemory(&lvItem, sizeof(LVITEMA));
1959 lvItem.mask = LVIF_STATE;
1960 lvItem.iItem = 0;
1962 while(ListView_GetItemA(This->hWndList, &lvItem))
1964 if (lvItem.iItem == i)
1966 if (uFlags & SVSI_SELECT)
1967 lvItem.state |= LVIS_SELECTED;
1968 else
1969 lvItem.state &= ~LVIS_SELECTED;
1971 if(uFlags & SVSI_FOCUSED)
1972 lvItem.state &= ~LVIS_FOCUSED;
1974 else
1976 if (uFlags & SVSI_DESELECTOTHERS)
1977 lvItem.state &= ~LVIS_SELECTED;
1979 ListView_SetItemA(This->hWndList, &lvItem);
1980 lvItem.iItem++;
1984 if(uFlags & SVSI_EDIT)
1985 ListView_EditLabelA(This->hWndList, i);
1988 return S_OK;
1991 static HRESULT WINAPI IShellView_fnGetItemObject(IShellView * iface, UINT uItem, REFIID riid, LPVOID *ppvOut)
1993 IShellViewImpl *This = (IShellViewImpl *)iface;
1995 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n",This, uItem, debugstr_guid(riid), ppvOut);
1997 *ppvOut = NULL;
1999 switch(uItem)
2001 case SVGIO_BACKGROUND:
2002 *ppvOut = ISvBgCm_Constructor(This->pSFParent, FALSE);
2003 break;
2005 case SVGIO_SELECTION:
2006 ShellView_GetSelections(This);
2007 IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, (LPCITEMIDLIST*)This->apidl, riid, 0, ppvOut);
2008 break;
2010 TRACE("-- (%p)->(interface=%p)\n",This, *ppvOut);
2012 if(!*ppvOut) return E_OUTOFMEMORY;
2014 return S_OK;
2017 static const IShellViewVtbl svvt =
2019 IShellView_fnQueryInterface,
2020 IShellView_fnAddRef,
2021 IShellView_fnRelease,
2022 IShellView_fnGetWindow,
2023 IShellView_fnContextSensitiveHelp,
2024 IShellView_fnTranslateAccelerator,
2025 IShellView_fnEnableModeless,
2026 IShellView_fnUIActivate,
2027 IShellView_fnRefresh,
2028 IShellView_fnCreateViewWindow,
2029 IShellView_fnDestroyViewWindow,
2030 IShellView_fnGetCurrentInfo,
2031 IShellView_fnAddPropertySheetPages,
2032 IShellView_fnSaveViewState,
2033 IShellView_fnSelectItem,
2034 IShellView_fnGetItemObject
2038 /**********************************************************
2039 * ISVOleCmdTarget_QueryInterface (IUnknown)
2041 static HRESULT WINAPI ISVOleCmdTarget_QueryInterface(
2042 IOleCommandTarget * iface,
2043 REFIID iid,
2044 LPVOID* ppvObj)
2046 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2048 return IShellFolder_QueryInterface((IShellFolder*)This, iid, ppvObj);
2051 /**********************************************************
2052 * ISVOleCmdTarget_AddRef (IUnknown)
2054 static ULONG WINAPI ISVOleCmdTarget_AddRef(
2055 IOleCommandTarget * iface)
2057 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2059 return IShellFolder_AddRef((IShellFolder*)This);
2062 /**********************************************************
2063 * ISVOleCmdTarget_Release (IUnknown)
2065 static ULONG WINAPI ISVOleCmdTarget_Release(
2066 IOleCommandTarget * iface)
2068 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2070 return IShellFolder_Release((IShellFolder*)This);
2073 /**********************************************************
2074 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2076 static HRESULT WINAPI ISVOleCmdTarget_QueryStatus(
2077 IOleCommandTarget *iface,
2078 const GUID* pguidCmdGroup,
2079 ULONG cCmds,
2080 OLECMD * prgCmds,
2081 OLECMDTEXT* pCmdText)
2083 UINT i;
2084 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2086 FIXME("(%p)->(%p(%s) 0x%08lx %p %p\n",
2087 This, pguidCmdGroup, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText);
2089 if (!prgCmds)
2090 return E_POINTER;
2091 for (i = 0; i < cCmds; i++)
2093 FIXME("\tprgCmds[%d].cmdID = %ld\n", i, prgCmds[i].cmdID);
2094 prgCmds[i].cmdf = 0;
2096 return OLECMDERR_E_UNKNOWNGROUP;
2099 /**********************************************************
2100 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2102 * nCmdID is the OLECMDID_* enumeration
2104 static HRESULT WINAPI ISVOleCmdTarget_Exec(
2105 IOleCommandTarget *iface,
2106 const GUID* pguidCmdGroup,
2107 DWORD nCmdID,
2108 DWORD nCmdexecopt,
2109 VARIANT* pvaIn,
2110 VARIANT* pvaOut)
2112 IShellViewImpl *This = impl_from_IOleCommandTarget(iface);
2114 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08lx Opt:0x%08lx %p %p)\n",
2115 This, debugstr_guid(pguidCmdGroup), nCmdID, nCmdexecopt, pvaIn, pvaOut);
2117 if (IsEqualIID(pguidCmdGroup, &CGID_Explorer) &&
2118 (nCmdID == 0x29) &&
2119 (nCmdexecopt == 4) && pvaOut)
2120 return S_OK;
2121 if (IsEqualIID(pguidCmdGroup, &CGID_ShellDocView) &&
2122 (nCmdID == 9) &&
2123 (nCmdexecopt == 0))
2124 return 1;
2126 return OLECMDERR_E_UNKNOWNGROUP;
2129 static const IOleCommandTargetVtbl ctvt =
2131 ISVOleCmdTarget_QueryInterface,
2132 ISVOleCmdTarget_AddRef,
2133 ISVOleCmdTarget_Release,
2134 ISVOleCmdTarget_QueryStatus,
2135 ISVOleCmdTarget_Exec
2138 /**********************************************************
2139 * ISVDropTarget implementation
2142 static HRESULT WINAPI ISVDropTarget_QueryInterface(
2143 IDropTarget *iface,
2144 REFIID riid,
2145 LPVOID *ppvObj)
2147 IShellViewImpl *This = impl_from_IDropTarget(iface);
2149 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2151 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2154 static ULONG WINAPI ISVDropTarget_AddRef( IDropTarget *iface)
2156 IShellViewImpl *This = impl_from_IDropTarget(iface);
2158 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2160 return IShellFolder_AddRef((IShellFolder*)This);
2163 static ULONG WINAPI ISVDropTarget_Release( IDropTarget *iface)
2165 IShellViewImpl *This = impl_from_IDropTarget(iface);
2167 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2169 return IShellFolder_Release((IShellFolder*)This);
2172 static HRESULT WINAPI ISVDropTarget_DragEnter(
2173 IDropTarget *iface,
2174 IDataObject *pDataObject,
2175 DWORD grfKeyState,
2176 POINTL pt,
2177 DWORD *pdwEffect)
2180 IShellViewImpl *This = impl_from_IDropTarget(iface);
2182 FIXME("Stub: This=%p, DataObject=%p\n",This,pDataObject);
2184 return E_NOTIMPL;
2187 static HRESULT WINAPI ISVDropTarget_DragOver(
2188 IDropTarget *iface,
2189 DWORD grfKeyState,
2190 POINTL pt,
2191 DWORD *pdwEffect)
2193 IShellViewImpl *This = impl_from_IDropTarget(iface);
2195 FIXME("Stub: This=%p\n",This);
2197 return E_NOTIMPL;
2200 static HRESULT WINAPI ISVDropTarget_DragLeave(
2201 IDropTarget *iface)
2203 IShellViewImpl *This = impl_from_IDropTarget(iface);
2205 FIXME("Stub: This=%p\n",This);
2207 return E_NOTIMPL;
2210 static HRESULT WINAPI ISVDropTarget_Drop(
2211 IDropTarget *iface,
2212 IDataObject* pDataObject,
2213 DWORD grfKeyState,
2214 POINTL pt,
2215 DWORD *pdwEffect)
2217 IShellViewImpl *This = impl_from_IDropTarget(iface);
2219 FIXME("Stub: This=%p\n",This);
2221 return E_NOTIMPL;
2224 static const IDropTargetVtbl dtvt =
2226 ISVDropTarget_QueryInterface,
2227 ISVDropTarget_AddRef,
2228 ISVDropTarget_Release,
2229 ISVDropTarget_DragEnter,
2230 ISVDropTarget_DragOver,
2231 ISVDropTarget_DragLeave,
2232 ISVDropTarget_Drop
2235 /**********************************************************
2236 * ISVDropSource implementation
2239 static HRESULT WINAPI ISVDropSource_QueryInterface(
2240 IDropSource *iface,
2241 REFIID riid,
2242 LPVOID *ppvObj)
2244 IShellViewImpl *This = impl_from_IDropSource(iface);
2246 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2248 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2251 static ULONG WINAPI ISVDropSource_AddRef( IDropSource *iface)
2253 IShellViewImpl *This = impl_from_IDropSource(iface);
2255 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2257 return IShellFolder_AddRef((IShellFolder*)This);
2260 static ULONG WINAPI ISVDropSource_Release( IDropSource *iface)
2262 IShellViewImpl *This = impl_from_IDropSource(iface);
2264 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2266 return IShellFolder_Release((IShellFolder*)This);
2268 static HRESULT WINAPI ISVDropSource_QueryContinueDrag(
2269 IDropSource *iface,
2270 BOOL fEscapePressed,
2271 DWORD grfKeyState)
2273 IShellViewImpl *This = impl_from_IDropSource(iface);
2274 TRACE("(%p)\n",This);
2276 if (fEscapePressed)
2277 return DRAGDROP_S_CANCEL;
2278 else if (!(grfKeyState & MK_LBUTTON) && !(grfKeyState & MK_RBUTTON))
2279 return DRAGDROP_S_DROP;
2280 else
2281 return NOERROR;
2284 static HRESULT WINAPI ISVDropSource_GiveFeedback(
2285 IDropSource *iface,
2286 DWORD dwEffect)
2288 IShellViewImpl *This = impl_from_IDropSource(iface);
2289 TRACE("(%p)\n",This);
2291 return DRAGDROP_S_USEDEFAULTCURSORS;
2294 static const IDropSourceVtbl dsvt =
2296 ISVDropSource_QueryInterface,
2297 ISVDropSource_AddRef,
2298 ISVDropSource_Release,
2299 ISVDropSource_QueryContinueDrag,
2300 ISVDropSource_GiveFeedback
2302 /**********************************************************
2303 * ISVViewObject implementation
2306 static HRESULT WINAPI ISVViewObject_QueryInterface(
2307 IViewObject *iface,
2308 REFIID riid,
2309 LPVOID *ppvObj)
2311 IShellViewImpl *This = impl_from_IViewObject(iface);
2313 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2315 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2318 static ULONG WINAPI ISVViewObject_AddRef( IViewObject *iface)
2320 IShellViewImpl *This = impl_from_IViewObject(iface);
2322 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2324 return IShellFolder_AddRef((IShellFolder*)This);
2327 static ULONG WINAPI ISVViewObject_Release( IViewObject *iface)
2329 IShellViewImpl *This = impl_from_IViewObject(iface);
2331 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2333 return IShellFolder_Release((IShellFolder*)This);
2336 static HRESULT WINAPI ISVViewObject_Draw(
2337 IViewObject *iface,
2338 DWORD dwDrawAspect,
2339 LONG lindex,
2340 void* pvAspect,
2341 DVTARGETDEVICE* ptd,
2342 HDC hdcTargetDev,
2343 HDC hdcDraw,
2344 LPCRECTL lprcBounds,
2345 LPCRECTL lprcWBounds,
2346 BOOL (CALLBACK *pfnContinue)(ULONG_PTR dwContinue),
2347 ULONG_PTR dwContinue)
2350 IShellViewImpl *This = impl_from_IViewObject(iface);
2352 FIXME("Stub: This=%p\n",This);
2354 return E_NOTIMPL;
2356 static HRESULT WINAPI ISVViewObject_GetColorSet(
2357 IViewObject *iface,
2358 DWORD dwDrawAspect,
2359 LONG lindex,
2360 void *pvAspect,
2361 DVTARGETDEVICE* ptd,
2362 HDC hicTargetDevice,
2363 LOGPALETTE** ppColorSet)
2366 IShellViewImpl *This = impl_from_IViewObject(iface);
2368 FIXME("Stub: This=%p\n",This);
2370 return E_NOTIMPL;
2372 static HRESULT WINAPI ISVViewObject_Freeze(
2373 IViewObject *iface,
2374 DWORD dwDrawAspect,
2375 LONG lindex,
2376 void* pvAspect,
2377 DWORD* pdwFreeze)
2380 IShellViewImpl *This = impl_from_IViewObject(iface);
2382 FIXME("Stub: This=%p\n",This);
2384 return E_NOTIMPL;
2386 static HRESULT WINAPI ISVViewObject_Unfreeze(
2387 IViewObject *iface,
2388 DWORD dwFreeze)
2391 IShellViewImpl *This = impl_from_IViewObject(iface);
2393 FIXME("Stub: This=%p\n",This);
2395 return E_NOTIMPL;
2397 static HRESULT WINAPI ISVViewObject_SetAdvise(
2398 IViewObject *iface,
2399 DWORD aspects,
2400 DWORD advf,
2401 IAdviseSink* pAdvSink)
2404 IShellViewImpl *This = impl_from_IViewObject(iface);
2406 FIXME("partial stub: %p %08lx %08lx %p\n",
2407 This, aspects, advf, pAdvSink);
2409 /* FIXME: we set the AdviseSink, but never use it to send any advice */
2410 This->pAdvSink = pAdvSink;
2411 This->dwAspects = aspects;
2412 This->dwAdvf = advf;
2414 return S_OK;
2417 static HRESULT WINAPI ISVViewObject_GetAdvise(
2418 IViewObject *iface,
2419 DWORD* pAspects,
2420 DWORD* pAdvf,
2421 IAdviseSink** ppAdvSink)
2424 IShellViewImpl *This = impl_from_IViewObject(iface);
2426 TRACE("This=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n",
2427 This, pAspects, pAdvf, ppAdvSink);
2429 if( ppAdvSink )
2431 IAdviseSink_AddRef( This->pAdvSink );
2432 *ppAdvSink = This->pAdvSink;
2434 if( pAspects )
2435 *pAspects = This->dwAspects;
2436 if( pAdvf )
2437 *pAdvf = This->dwAdvf;
2439 return S_OK;
2443 static const IViewObjectVtbl vovt =
2445 ISVViewObject_QueryInterface,
2446 ISVViewObject_AddRef,
2447 ISVViewObject_Release,
2448 ISVViewObject_Draw,
2449 ISVViewObject_GetColorSet,
2450 ISVViewObject_Freeze,
2451 ISVViewObject_Unfreeze,
2452 ISVViewObject_SetAdvise,
2453 ISVViewObject_GetAdvise