-Wpointer-sign fixes.
[wine/multimedia.git] / dlls / shell32 / shlview.c
blob6ca119802faa18bd2a154506f113c66fcf487217
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 #define _IOleCommandTarget_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblOleCommandTarget)))
108 #define _ICOM_THIS_From_IOleCommandTarget(class, name) class* This = (class*)(((char*)name)-_IOleCommandTarget_Offset);
110 static const IDropTargetVtbl dtvt;
111 #define _IDropTarget_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblDropTarget)))
112 #define _ICOM_THIS_From_IDropTarget(class, name) class* This = (class*)(((char*)name)-_IDropTarget_Offset);
114 static const IDropSourceVtbl dsvt;
115 #define _IDropSource_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblDropSource)))
116 #define _ICOM_THIS_From_IDropSource(class, name) class* This = (class*)(((char*)name)-_IDropSource_Offset);
118 static const IViewObjectVtbl vovt;
119 #define _IViewObject_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblViewObject)))
120 #define _ICOM_THIS_From_IViewObject(class, name) class* This = (class*)(((char*)name)-_IViewObject_Offset);
122 /* ListView Header ID's */
123 #define LISTVIEW_COLUMN_NAME 0
124 #define LISTVIEW_COLUMN_SIZE 1
125 #define LISTVIEW_COLUMN_TYPE 2
126 #define LISTVIEW_COLUMN_TIME 3
127 #define LISTVIEW_COLUMN_ATTRIB 4
129 /*menu items */
130 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
131 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
132 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
134 #define ID_LISTVIEW 2000
136 #define SHV_CHANGE_NOTIFY WM_USER + 0x1111
138 /*windowsx.h */
139 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
140 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
141 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
144 Items merged into the toolbar and and the filemenu
146 typedef struct
147 { int idCommand;
148 int iImage;
149 int idButtonString;
150 int idMenuString;
151 BYTE bState;
152 BYTE bStyle;
153 } MYTOOLINFO, *LPMYTOOLINFO;
155 MYTOOLINFO Tools[] =
157 { FCIDM_SHVIEW_BIGICON, 0, 0, IDS_VIEW_LARGE, TBSTATE_ENABLED, BTNS_BUTTON },
158 { FCIDM_SHVIEW_SMALLICON, 0, 0, IDS_VIEW_SMALL, TBSTATE_ENABLED, BTNS_BUTTON },
159 { FCIDM_SHVIEW_LISTVIEW, 0, 0, IDS_VIEW_LIST, TBSTATE_ENABLED, BTNS_BUTTON },
160 { FCIDM_SHVIEW_REPORTVIEW, 0, 0, IDS_VIEW_DETAILS, TBSTATE_ENABLED, BTNS_BUTTON },
161 { -1, 0, 0, 0, 0, 0}
164 typedef void (CALLBACK *PFNSHGETSETTINGSPROC)(LPSHELLFLAGSTATE lpsfs, DWORD dwMask);
166 /**********************************************************
167 * IShellView_Constructor
169 IShellView * IShellView_Constructor( IShellFolder * pFolder)
170 { IShellViewImpl * sv;
171 sv=HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IShellViewImpl));
172 sv->ref=1;
173 sv->lpVtbl=&svvt;
174 sv->lpvtblOleCommandTarget=&ctvt;
175 sv->lpvtblDropTarget=&dtvt;
176 sv->lpvtblDropSource=&dsvt;
177 sv->lpvtblViewObject=&vovt;
179 sv->pSFParent = pFolder;
180 if(pFolder) IShellFolder_AddRef(pFolder);
181 IShellFolder_QueryInterface(sv->pSFParent, &IID_IShellFolder2, (LPVOID*)&sv->pSF2Parent);
183 TRACE("(%p)->(%p)\n",sv, pFolder);
184 return (IShellView *) sv;
187 /**********************************************************
189 * ##### helperfunctions for communication with ICommDlgBrowser #####
191 static BOOL IsInCommDlg(IShellViewImpl * This)
192 { return(This->pCommDlgBrowser != NULL);
195 static HRESULT IncludeObject(IShellViewImpl * This, LPCITEMIDLIST pidl)
197 HRESULT ret = S_OK;
199 if ( IsInCommDlg(This) )
201 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl);
202 ret = ICommDlgBrowser_IncludeObject(This->pCommDlgBrowser, (IShellView*)This, pidl);
203 TRACE("--0x%08lx\n", ret);
205 return ret;
208 static HRESULT OnDefaultCommand(IShellViewImpl * This)
210 HRESULT ret = S_FALSE;
212 if (IsInCommDlg(This))
214 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
215 ret = ICommDlgBrowser_OnDefaultCommand(This->pCommDlgBrowser, (IShellView*)This);
216 TRACE("-- returns %08lx\n", ret);
218 return ret;
221 static HRESULT OnStateChange(IShellViewImpl * This, UINT uFlags)
223 HRESULT ret = S_FALSE;
225 if (IsInCommDlg(This))
227 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags);
228 ret = ICommDlgBrowser_OnStateChange(This->pCommDlgBrowser, (IShellView*)This, uFlags);
229 TRACE("--\n");
231 return ret;
233 /**********************************************************
234 * set the toolbar of the filedialog buttons
236 * - activates the buttons from the shellbrowser according to
237 * the view state
239 static void CheckToolbar(IShellViewImpl * This)
241 LRESULT result;
243 TRACE("\n");
245 if (IsInCommDlg(This))
247 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
248 FCIDM_TB_SMALLICON, (This->FolderSettings.ViewMode==FVM_LIST)? TRUE : FALSE, &result);
249 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
250 FCIDM_TB_REPORTVIEW, (This->FolderSettings.ViewMode==FVM_DETAILS)? TRUE : FALSE, &result);
251 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
252 FCIDM_TB_SMALLICON, TRUE, &result);
253 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
254 FCIDM_TB_REPORTVIEW, TRUE, &result);
258 /**********************************************************
260 * ##### helperfunctions for initializing the view #####
262 /**********************************************************
263 * change the style of the listview control
265 static void SetStyle(IShellViewImpl * This, DWORD dwAdd, DWORD dwRemove)
267 DWORD tmpstyle;
269 TRACE("(%p)\n", This);
271 tmpstyle = GetWindowLongA(This->hWndList, GWL_STYLE);
272 SetWindowLongA(This->hWndList, GWL_STYLE, dwAdd | (tmpstyle & ~dwRemove));
275 /**********************************************************
276 * ShellView_CreateList()
278 * - creates the list view window
280 static BOOL ShellView_CreateList (IShellViewImpl * This)
281 { DWORD dwStyle, dwExStyle;
283 TRACE("%p\n",This);
285 dwStyle = WS_TABSTOP | WS_VISIBLE | WS_CHILDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
286 LVS_SHAREIMAGELISTS | LVS_EDITLABELS | LVS_ALIGNLEFT | LVS_AUTOARRANGE;
287 dwExStyle = WS_EX_CLIENTEDGE;
289 switch (This->FolderSettings.ViewMode)
291 case FVM_ICON: dwStyle |= LVS_ICON; break;
292 case FVM_DETAILS: dwStyle |= LVS_REPORT; break;
293 case FVM_SMALLICON: dwStyle |= LVS_SMALLICON; break;
294 case FVM_LIST: dwStyle |= LVS_LIST; break;
295 default: dwStyle |= LVS_LIST; break;
298 if (This->FolderSettings.fFlags & FWF_AUTOARRANGE) dwStyle |= LVS_AUTOARRANGE;
299 if (This->FolderSettings.fFlags & FWF_DESKTOP)
300 This->FolderSettings.fFlags |= FWF_NOCLIENTEDGE | FWF_NOSCROLL;
301 if (This->FolderSettings.fFlags & FWF_SINGLESEL) dwStyle |= LVS_SINGLESEL;
302 if (This->FolderSettings.fFlags & FWF_NOCLIENTEDGE)
303 dwExStyle &= ~WS_EX_CLIENTEDGE;
305 This->hWndList=CreateWindowExA( dwExStyle,
306 WC_LISTVIEWA,
307 NULL,
308 dwStyle,
309 0,0,0,0,
310 This->hWnd,
311 (HMENU)ID_LISTVIEW,
312 shell32_hInstance,
313 NULL);
315 if(!This->hWndList)
316 return FALSE;
318 This->ListViewSortInfo.bIsAscending = TRUE;
319 This->ListViewSortInfo.nHeaderID = -1;
320 This->ListViewSortInfo.nLastHeaderID = -1;
322 if (This->FolderSettings.fFlags & FWF_DESKTOP) {
323 if (0) /* FIXME: look into registry vale HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ListviewShadow and activate drop shadows */
324 ListView_SetTextBkColor(This->hWndList, CLR_NONE);
325 else
326 ListView_SetTextBkColor(This->hWndList, GetSysColor(COLOR_DESKTOP));
328 ListView_SetTextColor(This->hWndList, RGB(255,255,255));
331 /* UpdateShellSettings(); */
332 return TRUE;
335 /**********************************************************
336 * ShellView_InitList()
338 * - adds all needed columns to the shellview
340 static BOOL ShellView_InitList(IShellViewImpl * This)
342 LVCOLUMNA lvColumn;
343 SHELLDETAILS sd;
344 int i;
345 char szTemp[50];
347 TRACE("%p\n",This);
349 ListView_DeleteAllItems(This->hWndList);
351 lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT;
352 lvColumn.pszText = szTemp;
354 if (This->pSF2Parent)
356 for (i=0; 1; i++)
358 if (!SUCCEEDED(IShellFolder2_GetDetailsOf(This->pSF2Parent, NULL, i, &sd)))
359 break;
360 lvColumn.fmt = sd.fmt;
361 lvColumn.cx = sd.cxChar*8; /* chars->pixel */
362 StrRetToStrNA( szTemp, 50, &sd.str, NULL);
363 ListView_InsertColumnA(This->hWndList, i, &lvColumn);
366 else
368 FIXME("no SF2\n");
371 ListView_SetImageList(This->hWndList, ShellSmallIconList, LVSIL_SMALL);
372 ListView_SetImageList(This->hWndList, ShellBigIconList, LVSIL_NORMAL);
374 return TRUE;
376 /**********************************************************
377 * ShellView_CompareItems()
379 * NOTES
380 * internal, CALLBACK for DSA_Sort
382 static INT CALLBACK ShellView_CompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
384 int ret;
385 TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1, lParam2, (LPVOID) lpData);
387 if(!lpData) return 0;
389 ret = (SHORT) SCODE_CODE(IShellFolder_CompareIDs((LPSHELLFOLDER)lpData, 0, (LPITEMIDLIST)lParam1, (LPITEMIDLIST)lParam2));
390 TRACE("ret=%i\n",ret);
391 return ret;
394 /*************************************************************************
395 * ShellView_ListViewCompareItems
397 * Compare Function for the Listview (FileOpen Dialog)
399 * PARAMS
400 * lParam1 [I] the first ItemIdList to compare with
401 * lParam2 [I] the second ItemIdList to compare with
402 * lpData [I] The column ID for the header Ctrl to process
404 * RETURNS
405 * A negative value if the first item should precede the second,
406 * a positive value if the first item should follow the second,
407 * or zero if the two items are equivalent
409 * NOTES
410 * FIXME: function does what ShellView_CompareItems is supposed to do.
411 * unify it and figure out how to use the undocumented first parameter
412 * of IShellFolder_CompareIDs to do the job this function does and
413 * move this code to IShellFolder.
414 * make LISTVIEW_SORT_INFO obsolete
415 * the way this function works is only usable if we had only
416 * filesystemfolders (25/10/99 jsch)
418 static INT CALLBACK ShellView_ListViewCompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
420 INT nDiff=0;
421 FILETIME fd1, fd2;
422 char strName1[MAX_PATH], strName2[MAX_PATH];
423 BOOL bIsFolder1, bIsFolder2,bIsBothFolder;
424 LPITEMIDLIST pItemIdList1 = (LPITEMIDLIST) lParam1;
425 LPITEMIDLIST pItemIdList2 = (LPITEMIDLIST) lParam2;
426 LISTVIEW_SORT_INFO *pSortInfo = (LPLISTVIEW_SORT_INFO) lpData;
429 bIsFolder1 = _ILIsFolder(pItemIdList1);
430 bIsFolder2 = _ILIsFolder(pItemIdList2);
431 bIsBothFolder = bIsFolder1 && bIsFolder2;
433 /* When sorting between a File and a Folder, the Folder gets sorted first */
434 if( (bIsFolder1 || bIsFolder2) && !bIsBothFolder)
436 nDiff = bIsFolder1 ? -1 : 1;
438 else
440 /* Sort by Time: Folders or Files can be sorted */
442 if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TIME)
444 _ILGetFileDateTime(pItemIdList1, &fd1);
445 _ILGetFileDateTime(pItemIdList2, &fd2);
446 nDiff = CompareFileTime(&fd2, &fd1);
448 /* Sort by Attribute: Folder or Files can be sorted */
449 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_ATTRIB)
451 _ILGetFileAttributes(pItemIdList1, strName1, MAX_PATH);
452 _ILGetFileAttributes(pItemIdList2, strName2, MAX_PATH);
453 nDiff = lstrcmpiA(strName1, strName2);
455 /* Sort by FileName: Folder or Files can be sorted */
456 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_NAME || bIsBothFolder)
458 /* Sort by Text */
459 _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
460 _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
461 nDiff = lstrcmpiA(strName1, strName2);
463 /* Sort by File Size, Only valid for Files */
464 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_SIZE)
466 nDiff = (INT)(_ILGetFileSize(pItemIdList1, NULL, 0) - _ILGetFileSize(pItemIdList2, NULL, 0));
468 /* Sort by File Type, Only valid for Files */
469 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TYPE)
471 /* Sort by Type */
472 _ILGetFileType(pItemIdList1, strName1, MAX_PATH);
473 _ILGetFileType(pItemIdList2, strName2, MAX_PATH);
474 nDiff = lstrcmpiA(strName1, strName2);
477 /* If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
479 if(nDiff == 0)
481 _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
482 _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
483 nDiff = lstrcmpiA(strName1, strName2);
486 if(!pSortInfo->bIsAscending)
488 nDiff = -nDiff;
491 return nDiff;
495 /**********************************************************
496 * LV_FindItemByPidl()
498 static int LV_FindItemByPidl(
499 IShellViewImpl * This,
500 LPCITEMIDLIST pidl)
502 LVITEMA lvItem;
503 ZeroMemory(&lvItem, sizeof(LVITEMA));
504 lvItem.mask = LVIF_PARAM;
505 for(lvItem.iItem = 0; ListView_GetItemA(This->hWndList, &lvItem); lvItem.iItem++)
507 LPITEMIDLIST currentpidl = (LPITEMIDLIST) lvItem.lParam;
508 HRESULT hr = IShellFolder_CompareIDs(This->pSFParent, 0, pidl, currentpidl);
509 if(SUCCEEDED(hr) && !HRESULT_CODE(hr))
511 return lvItem.iItem;
514 return -1;
517 /**********************************************************
518 * LV_AddItem()
520 static BOOLEAN LV_AddItem(IShellViewImpl * This, LPCITEMIDLIST pidl)
522 LVITEMA lvItem;
524 TRACE("(%p)(pidl=%p)\n", This, pidl);
526 ZeroMemory(&lvItem, sizeof(lvItem)); /* create the listview item*/
527 lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; /*set the mask*/
528 lvItem.iItem = ListView_GetItemCount(This->hWndList); /*add the item to the end of the list*/
529 lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidl)); /*set the item's data*/
530 lvItem.pszText = LPSTR_TEXTCALLBACKA; /*get text on a callback basis*/
531 lvItem.iImage = I_IMAGECALLBACK; /*get the image on a callback basis*/
532 return (-1==ListView_InsertItemA(This->hWndList, &lvItem))? FALSE: TRUE;
535 /**********************************************************
536 * LV_DeleteItem()
538 static BOOLEAN LV_DeleteItem(IShellViewImpl * This, LPCITEMIDLIST pidl)
540 int nIndex;
542 TRACE("(%p)(pidl=%p)\n", This, pidl);
544 nIndex = LV_FindItemByPidl(This, ILFindLastID(pidl));
545 return (-1==ListView_DeleteItem(This->hWndList, nIndex))? FALSE: TRUE;
548 /**********************************************************
549 * LV_RenameItem()
551 static BOOLEAN LV_RenameItem(IShellViewImpl * This, LPCITEMIDLIST pidlOld, LPCITEMIDLIST pidlNew )
553 int nItem;
554 LVITEMA lvItem;
556 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", This, pidlOld, pidlNew);
558 nItem = LV_FindItemByPidl(This, ILFindLastID(pidlOld));
559 if ( -1 != nItem )
561 ZeroMemory(&lvItem, sizeof(lvItem)); /* create the listview item*/
562 lvItem.mask = LVIF_PARAM; /* only the pidl */
563 lvItem.iItem = nItem;
564 ListView_GetItemA(This->hWndList, &lvItem);
566 SHFree((LPITEMIDLIST)lvItem.lParam);
567 lvItem.mask = LVIF_PARAM;
568 lvItem.iItem = nItem;
569 lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidlNew)); /* set the item's data */
570 ListView_SetItemA(This->hWndList, &lvItem);
571 ListView_Update(This->hWndList, nItem);
572 return TRUE; /* FIXME: better handling */
574 return FALSE;
576 /**********************************************************
577 * ShellView_FillList()
579 * - gets the objectlist from the shellfolder
580 * - sorts the list
581 * - fills the list into the view
584 static INT CALLBACK fill_list( LPVOID ptr, LPVOID arg )
586 LPITEMIDLIST pidl = ptr;
587 IShellViewImpl *This = arg;
588 /* in a commdlg This works as a filemask*/
589 if ( IncludeObject(This, pidl)==S_OK ) LV_AddItem(This, pidl);
590 SHFree(pidl);
591 return TRUE;
594 static HRESULT ShellView_FillList(IShellViewImpl * This)
596 LPENUMIDLIST pEnumIDList;
597 LPITEMIDLIST pidl;
598 DWORD dwFetched;
599 HRESULT hRes;
600 HDPA hdpa;
602 TRACE("%p\n",This);
604 /* get the itemlist from the shfolder*/
605 hRes = IShellFolder_EnumObjects(This->pSFParent,This->hWnd, SHCONTF_NONFOLDERS | SHCONTF_FOLDERS, &pEnumIDList);
606 if (hRes != S_OK)
608 if (hRes==S_FALSE)
609 return(NOERROR);
610 return(hRes);
613 /* create a pointer array */
614 hdpa = DPA_Create(16);
615 if (!hdpa)
617 return(E_OUTOFMEMORY);
620 /* copy the items into the array*/
621 while((S_OK == IEnumIDList_Next(pEnumIDList,1, &pidl, &dwFetched)) && dwFetched)
623 if (DPA_InsertPtr(hdpa, 0x7fff, pidl) == -1)
625 SHFree(pidl);
629 /* sort the array */
630 DPA_Sort(hdpa, ShellView_CompareItems, (LPARAM)This->pSFParent);
632 /*turn the listview's redrawing off*/
633 SendMessageA(This->hWndList, WM_SETREDRAW, FALSE, 0);
635 DPA_DestroyCallback( hdpa, fill_list, This );
637 /*turn the listview's redrawing back on and force it to draw*/
638 SendMessageA(This->hWndList, WM_SETREDRAW, TRUE, 0);
640 IEnumIDList_Release(pEnumIDList); /* destroy the list*/
642 return S_OK;
645 /**********************************************************
646 * ShellView_OnCreate()
648 static LRESULT ShellView_OnCreate(IShellViewImpl * This)
650 IDropTarget* pdt;
651 SHChangeNotifyEntry ntreg;
652 IPersistFolder2 * ppf2 = NULL;
654 TRACE("%p\n",This);
656 if(ShellView_CreateList(This))
658 if(ShellView_InitList(This))
660 ShellView_FillList(This);
664 if (SUCCEEDED(IShellFolder_CreateViewObject(This->pSFParent, This->hWnd, &IID_IDropTarget, (LPVOID*)&pdt)))
666 RegisterDragDrop(This->hWnd, pdt);
667 IDropTarget_Release(pdt);
670 /* register for receiving notifications */
671 IShellFolder_QueryInterface(This->pSFParent, &IID_IPersistFolder2, (LPVOID*)&ppf2);
672 if (ppf2)
674 IPersistFolder2_GetCurFolder(ppf2, (LPITEMIDLIST*)&ntreg.pidl);
675 ntreg.fRecursive = TRUE;
676 This->hNotify = SHChangeNotifyRegister(This->hWnd, SHCNF_IDLIST, SHCNE_ALLEVENTS, SHV_CHANGE_NOTIFY, 1, &ntreg);
677 SHFree((LPITEMIDLIST)ntreg.pidl);
678 IPersistFolder2_Release(ppf2);
681 This->hAccel = LoadAcceleratorsA(shell32_hInstance, "shv_accel");
683 return S_OK;
686 /**********************************************************
687 * #### Handling of the menus ####
690 /**********************************************************
691 * ShellView_BuildFileMenu()
693 static HMENU ShellView_BuildFileMenu(IShellViewImpl * This)
694 { CHAR szText[MAX_PATH];
695 MENUITEMINFOA mii;
696 int nTools,i;
697 HMENU hSubMenu;
699 TRACE("(%p)\n",This);
701 hSubMenu = CreatePopupMenu();
702 if(hSubMenu)
703 { /*get the number of items in our global array*/
704 for(nTools = 0; Tools[nTools].idCommand != -1; nTools++){}
706 /*add the menu items*/
707 for(i = 0; i < nTools; i++)
709 LoadStringA(shell32_hInstance, Tools[i].idMenuString, szText, MAX_PATH);
711 ZeroMemory(&mii, sizeof(mii));
712 mii.cbSize = sizeof(mii);
713 mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
715 if(BTNS_SEP != Tools[i].bStyle) /* no separator*/
717 mii.fType = MFT_STRING;
718 mii.fState = MFS_ENABLED;
719 mii.dwTypeData = szText;
720 mii.wID = Tools[i].idCommand;
722 else
724 mii.fType = MFT_SEPARATOR;
726 /* tack This item onto the end of the menu */
727 InsertMenuItemA(hSubMenu, (UINT)-1, TRUE, &mii);
730 TRACE("-- return (menu=%p)\n",hSubMenu);
731 return hSubMenu;
733 /**********************************************************
734 * ShellView_MergeFileMenu()
736 static void ShellView_MergeFileMenu(IShellViewImpl * This, HMENU hSubMenu)
737 { TRACE("(%p)->(submenu=%p) stub\n",This,hSubMenu);
739 if(hSubMenu)
740 { /*insert This item at the beginning of the menu */
741 _InsertMenuItem(hSubMenu, 0, TRUE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
742 _InsertMenuItem(hSubMenu, 0, TRUE, IDM_MYFILEITEM, MFT_STRING, "dummy45", MFS_ENABLED);
745 TRACE("--\n");
748 /**********************************************************
749 * ShellView_MergeViewMenu()
752 static void ShellView_MergeViewMenu(IShellViewImpl * This, HMENU hSubMenu)
753 { MENUITEMINFOA mii;
755 TRACE("(%p)->(submenu=%p)\n",This,hSubMenu);
757 if(hSubMenu)
758 { /*add a separator at the correct position in the menu*/
759 _InsertMenuItem(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
761 ZeroMemory(&mii, sizeof(mii));
762 mii.cbSize = sizeof(mii);
763 mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_DATA;
764 mii.fType = MFT_STRING;
765 mii.dwTypeData = "View";
766 mii.hSubMenu = LoadMenuA(shell32_hInstance, "MENU_001");
767 InsertMenuItemA(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
771 /**********************************************************
772 * ShellView_GetSelections()
774 * - fills the this->apidl list with the selected objects
776 * RETURNS
777 * number of selected items
779 static UINT ShellView_GetSelections(IShellViewImpl * This)
781 LVITEMA lvItem;
782 UINT i = 0;
784 if (This->apidl)
786 SHFree(This->apidl);
789 This->cidl = ListView_GetSelectedCount(This->hWndList);
790 This->apidl = (LPITEMIDLIST*)SHAlloc(This->cidl * sizeof(LPITEMIDLIST));
792 TRACE("selected=%i\n", This->cidl);
794 if(This->apidl)
796 TRACE("-- Items selected =%u\n", This->cidl);
798 ZeroMemory(&lvItem, sizeof(lvItem));
799 lvItem.mask = LVIF_STATE | LVIF_PARAM;
800 lvItem.stateMask = LVIS_SELECTED;
802 while(ListView_GetItemA(This->hWndList, &lvItem) && (i < This->cidl))
804 if(lvItem.state & LVIS_SELECTED)
806 This->apidl[i] = (LPITEMIDLIST)lvItem.lParam;
807 i++;
808 TRACE("-- selected Item found\n");
810 lvItem.iItem++;
813 return This->cidl;
817 /**********************************************************
818 * ShellView_OpenSelectedItems()
820 static HRESULT ShellView_OpenSelectedItems(IShellViewImpl * This)
822 static UINT CF_IDLIST = 0;
823 HRESULT hr;
824 IDataObject* selection;
825 FORMATETC fetc;
826 STGMEDIUM stgm;
827 LPIDA pIDList;
828 LPCITEMIDLIST parent_pidl;
829 int i;
831 if (0 == ShellView_GetSelections(This))
833 return S_OK;
835 hr = IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl,
836 (LPCITEMIDLIST*)This->apidl, &IID_IDataObject,
837 0, (LPVOID *)&selection);
838 if (FAILED(hr))
839 return hr;
841 if (0 == CF_IDLIST)
843 CF_IDLIST = RegisterClipboardFormatA(CFSTR_SHELLIDLIST);
845 fetc.cfFormat = CF_IDLIST;
846 fetc.ptd = NULL;
847 fetc.dwAspect = DVASPECT_CONTENT;
848 fetc.lindex = -1;
849 fetc.tymed = TYMED_HGLOBAL;
851 hr = IDataObject_QueryGetData(selection, &fetc);
852 if (FAILED(hr))
853 return hr;
855 hr = IDataObject_GetData(selection, &fetc, &stgm);
856 if (FAILED(hr))
857 return hr;
859 pIDList = GlobalLock(stgm.u.hGlobal);
861 parent_pidl = (LPCITEMIDLIST) ((LPBYTE)pIDList+pIDList->aoffset[0]);
862 for (i = pIDList->cidl; i > 0; --i)
864 LPCITEMIDLIST pidl;
865 SFGAOF attribs;
867 pidl = (LPCITEMIDLIST)((LPBYTE)pIDList+pIDList->aoffset[i]);
869 attribs = SFGAO_FOLDER;
870 hr = IShellFolder_GetAttributesOf(This->pSFParent, 1, &pidl, &attribs);
872 if (SUCCEEDED(hr) && ! (attribs & SFGAO_FOLDER))
874 SHELLEXECUTEINFOA shexinfo;
876 shexinfo.cbSize = sizeof(SHELLEXECUTEINFOA);
877 shexinfo.fMask = SEE_MASK_INVOKEIDLIST; /* SEE_MASK_IDLIST is also possible. */
878 shexinfo.hwnd = NULL;
879 shexinfo.lpVerb = NULL;
880 shexinfo.lpFile = NULL;
881 shexinfo.lpParameters = NULL;
882 shexinfo.lpDirectory = NULL;
883 shexinfo.nShow = SW_NORMAL;
884 shexinfo.lpIDList = ILCombine(parent_pidl, pidl);
886 ShellExecuteExA(&shexinfo); /* Discard error/success info */
888 ILFree((LPITEMIDLIST)shexinfo.lpIDList);
892 GlobalUnlock(stgm.u.hGlobal);
893 ReleaseStgMedium(&stgm);
895 IDataObject_Release(selection);
897 return S_OK;
900 /**********************************************************
901 * ShellView_DoContextMenu()
903 static void ShellView_DoContextMenu(IShellViewImpl * This, WORD x, WORD y, BOOL bDefault)
904 { UINT uCommand;
905 DWORD wFlags;
906 HMENU hMenu;
907 BOOL fExplore = FALSE;
908 HWND hwndTree = 0;
909 LPCONTEXTMENU pContextMenu = NULL;
910 IContextMenu2 *pCM = NULL;
911 CMINVOKECOMMANDINFO cmi;
913 TRACE("(%p)->(0x%08x 0x%08x 0x%08x) stub\n",This, x, y, bDefault);
915 /* look, what's selected and create a context menu object of it*/
916 if( ShellView_GetSelections(This) )
918 IShellFolder_GetUIObjectOf( This->pSFParent, This->hWndParent, This->cidl, (LPCITEMIDLIST*)This->apidl,
919 (REFIID)&IID_IContextMenu, NULL, (LPVOID *)&pContextMenu);
921 if(pContextMenu)
923 TRACE("-- pContextMenu\n");
924 hMenu = CreatePopupMenu();
926 if( hMenu )
928 /* See if we are in Explore or Open mode. If the browser's tree is present, we are in Explore mode.*/
929 if(SUCCEEDED(IShellBrowser_GetControlWindow(This->pShellBrowser,FCW_TREE, &hwndTree)) && hwndTree)
931 TRACE("-- explore mode\n");
932 fExplore = TRUE;
935 /* build the flags depending on what we can do with the selected item */
936 wFlags = CMF_NORMAL | (This->cidl != 1 ? 0 : CMF_CANRENAME) | (fExplore ? CMF_EXPLORE : 0);
938 /* let the ContextMenu merge its items in */
939 if (SUCCEEDED(IContextMenu_QueryContextMenu( pContextMenu, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, wFlags )))
941 if (This->FolderSettings.fFlags & FWF_DESKTOP)
942 SetMenuDefaultItem(hMenu, FCIDM_SHVIEW_OPEN, MF_BYCOMMAND);
944 if( bDefault )
946 TRACE("-- get menu default command\n");
947 uCommand = GetMenuDefaultItem(hMenu, FALSE, GMDI_GOINTOPOPUPS);
949 else
951 TRACE("-- track popup\n");
952 uCommand = TrackPopupMenu( hMenu,TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
955 if(uCommand > 0)
957 TRACE("-- uCommand=%u\n", uCommand);
958 if (uCommand==FCIDM_SHVIEW_OPEN && IsInCommDlg(This))
960 TRACE("-- dlg: OnDefaultCommand\n");
961 if (OnDefaultCommand(This) != S_OK)
963 ShellView_OpenSelectedItems(This);
966 else
968 TRACE("-- explore -- invoke command\n");
969 ZeroMemory(&cmi, sizeof(cmi));
970 cmi.cbSize = sizeof(cmi);
971 cmi.hwnd = This->hWndParent; /* this window has to answer CWM_GETISHELLBROWSER */
972 cmi.lpVerb = (LPCSTR)MAKEINTRESOURCEA(uCommand);
973 IContextMenu_InvokeCommand(pContextMenu, &cmi);
976 DestroyMenu(hMenu);
979 if (pContextMenu)
980 IContextMenu_Release(pContextMenu);
983 else /* background context menu */
985 hMenu = CreatePopupMenu();
987 pCM = ISvBgCm_Constructor(This->pSFParent, FALSE);
988 IContextMenu2_QueryContextMenu(pCM, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, 0);
990 uCommand = TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
991 DestroyMenu(hMenu);
993 TRACE("-- (%p)->(uCommand=0x%08x )\n",This, uCommand);
995 ZeroMemory(&cmi, sizeof(cmi));
996 cmi.cbSize = sizeof(cmi);
997 cmi.lpVerb = (LPCSTR)MAKEINTRESOURCEA(uCommand);
998 cmi.hwnd = This->hWndParent;
999 IContextMenu2_InvokeCommand(pCM, &cmi);
1001 IContextMenu2_Release(pCM);
1005 /**********************************************************
1006 * ##### message handling #####
1009 /**********************************************************
1010 * ShellView_OnSize()
1012 static LRESULT ShellView_OnSize(IShellViewImpl * This, WORD wWidth, WORD wHeight)
1014 TRACE("%p width=%u height=%u\n",This, wWidth,wHeight);
1016 /*resize the ListView to fit our window*/
1017 if(This->hWndList)
1019 MoveWindow(This->hWndList, 0, 0, wWidth, wHeight, TRUE);
1022 return S_OK;
1024 /**********************************************************
1025 * ShellView_OnDeactivate()
1027 * NOTES
1028 * internal
1030 static void ShellView_OnDeactivate(IShellViewImpl * This)
1032 TRACE("%p\n",This);
1034 if(This->uState != SVUIA_DEACTIVATE)
1036 if(This->hMenu)
1038 IShellBrowser_SetMenuSB(This->pShellBrowser,0, 0, 0);
1039 IShellBrowser_RemoveMenusSB(This->pShellBrowser,This->hMenu);
1040 DestroyMenu(This->hMenu);
1041 This->hMenu = 0;
1044 This->uState = SVUIA_DEACTIVATE;
1048 /**********************************************************
1049 * ShellView_OnActivate()
1051 static LRESULT ShellView_OnActivate(IShellViewImpl * This, UINT uState)
1052 { OLEMENUGROUPWIDTHS omw = { {0, 0, 0, 0, 0, 0} };
1053 MENUITEMINFOA mii;
1054 CHAR szText[MAX_PATH];
1056 TRACE("%p uState=%x\n",This,uState);
1058 /*don't do anything if the state isn't really changing */
1059 if(This->uState == uState)
1061 return S_OK;
1064 ShellView_OnDeactivate(This);
1066 /*only do This if we are active */
1067 if(uState != SVUIA_DEACTIVATE)
1069 /*merge the menus */
1070 This->hMenu = CreateMenu();
1072 if(This->hMenu)
1074 IShellBrowser_InsertMenusSB(This->pShellBrowser, This->hMenu, &omw);
1075 TRACE("-- after fnInsertMenusSB\n");
1077 /*build the top level menu get the menu item's text*/
1078 strcpy(szText,"dummy 31");
1080 ZeroMemory(&mii, sizeof(mii));
1081 mii.cbSize = sizeof(mii);
1082 mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_STATE;
1083 mii.fType = MFT_STRING;
1084 mii.fState = MFS_ENABLED;
1085 mii.dwTypeData = szText;
1086 mii.hSubMenu = ShellView_BuildFileMenu(This);
1088 /*insert our menu into the menu bar*/
1089 if(mii.hSubMenu)
1091 InsertMenuItemA(This->hMenu, FCIDM_MENU_HELP, FALSE, &mii);
1094 /*get the view menu so we can merge with it*/
1095 ZeroMemory(&mii, sizeof(mii));
1096 mii.cbSize = sizeof(mii);
1097 mii.fMask = MIIM_SUBMENU;
1099 if(GetMenuItemInfoA(This->hMenu, FCIDM_MENU_VIEW, FALSE, &mii))
1101 ShellView_MergeViewMenu(This, mii.hSubMenu);
1104 /*add the items that should only be added if we have the focus*/
1105 if(SVUIA_ACTIVATE_FOCUS == uState)
1107 /*get the file menu so we can merge with it */
1108 ZeroMemory(&mii, sizeof(mii));
1109 mii.cbSize = sizeof(mii);
1110 mii.fMask = MIIM_SUBMENU;
1112 if(GetMenuItemInfoA(This->hMenu, FCIDM_MENU_FILE, FALSE, &mii))
1114 ShellView_MergeFileMenu(This, mii.hSubMenu);
1117 TRACE("-- before fnSetMenuSB\n");
1118 IShellBrowser_SetMenuSB(This->pShellBrowser, This->hMenu, 0, This->hWnd);
1121 This->uState = uState;
1122 TRACE("--\n");
1123 return S_OK;
1126 /**********************************************************
1127 * ShellView_OnSetFocus()
1130 static LRESULT ShellView_OnSetFocus(IShellViewImpl * This)
1132 TRACE("%p\n",This);
1134 /* Tell the browser one of our windows has received the focus. This
1135 should always be done before merging menus (OnActivate merges the
1136 menus) if one of our windows has the focus.*/
1138 IShellBrowser_OnViewWindowActive(This->pShellBrowser,(IShellView*) This);
1139 ShellView_OnActivate(This, SVUIA_ACTIVATE_FOCUS);
1141 /* Set the focus to the listview */
1142 SetFocus(This->hWndList);
1144 /* Notify the ICommDlgBrowser interface */
1145 OnStateChange(This,CDBOSC_SETFOCUS);
1147 return 0;
1150 /**********************************************************
1151 * ShellView_OnKillFocus()
1153 static LRESULT ShellView_OnKillFocus(IShellViewImpl * This)
1155 TRACE("(%p) stub\n",This);
1157 ShellView_OnActivate(This, SVUIA_ACTIVATE_NOFOCUS);
1158 /* Notify the ICommDlgBrowser */
1159 OnStateChange(This,CDBOSC_KILLFOCUS);
1161 return 0;
1164 /**********************************************************
1165 * ShellView_OnCommand()
1167 * NOTES
1168 * the CmdID's are the ones from the context menu
1170 static LRESULT ShellView_OnCommand(IShellViewImpl * This,DWORD dwCmdID, DWORD dwCmd, HWND hwndCmd)
1172 TRACE("(%p)->(0x%08lx 0x%08lx %p) stub\n",This, dwCmdID, dwCmd, hwndCmd);
1174 switch(dwCmdID)
1176 case FCIDM_SHVIEW_SMALLICON:
1177 This->FolderSettings.ViewMode = FVM_SMALLICON;
1178 SetStyle (This, LVS_SMALLICON, LVS_TYPEMASK);
1179 CheckToolbar(This);
1180 break;
1182 case FCIDM_SHVIEW_BIGICON:
1183 This->FolderSettings.ViewMode = FVM_ICON;
1184 SetStyle (This, LVS_ICON, LVS_TYPEMASK);
1185 CheckToolbar(This);
1186 break;
1188 case FCIDM_SHVIEW_LISTVIEW:
1189 This->FolderSettings.ViewMode = FVM_LIST;
1190 SetStyle (This, LVS_LIST, LVS_TYPEMASK);
1191 CheckToolbar(This);
1192 break;
1194 case FCIDM_SHVIEW_REPORTVIEW:
1195 This->FolderSettings.ViewMode = FVM_DETAILS;
1196 SetStyle (This, LVS_REPORT, LVS_TYPEMASK);
1197 CheckToolbar(This);
1198 break;
1200 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1201 case 0x30:
1202 case 0x31:
1203 case 0x32:
1204 case 0x33:
1205 This->ListViewSortInfo.nHeaderID = (LPARAM) (dwCmdID - 0x30);
1206 This->ListViewSortInfo.bIsAscending = TRUE;
1207 This->ListViewSortInfo.nLastHeaderID = This->ListViewSortInfo.nHeaderID;
1208 ListView_SortItems(This->hWndList, ShellView_ListViewCompareItems, (LPARAM) (&(This->ListViewSortInfo)));
1209 break;
1211 default:
1212 TRACE("-- COMMAND 0x%04lx unhandled\n", dwCmdID);
1214 return 0;
1217 /**********************************************************
1218 * ShellView_OnNotify()
1221 static LRESULT ShellView_OnNotify(IShellViewImpl * This, UINT CtlID, LPNMHDR lpnmh)
1222 { LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)lpnmh;
1223 NMLVDISPINFOA *lpdi = (NMLVDISPINFOA *)lpnmh;
1224 LPITEMIDLIST pidl;
1226 TRACE("%p CtlID=%u lpnmh->code=%x\n",This,CtlID,lpnmh->code);
1228 switch(lpnmh->code)
1230 case NM_SETFOCUS:
1231 TRACE("-- NM_SETFOCUS %p\n",This);
1232 ShellView_OnSetFocus(This);
1233 break;
1235 case NM_KILLFOCUS:
1236 TRACE("-- NM_KILLFOCUS %p\n",This);
1237 ShellView_OnDeactivate(This);
1238 /* Notify the ICommDlgBrowser interface */
1239 OnStateChange(This,CDBOSC_KILLFOCUS);
1240 break;
1242 case NM_CUSTOMDRAW:
1243 TRACE("-- NM_CUSTOMDRAW %p\n",This);
1244 return CDRF_DODEFAULT;
1246 case NM_RELEASEDCAPTURE:
1247 TRACE("-- NM_RELEASEDCAPTURE %p\n",This);
1248 break;
1250 case NM_CLICK:
1251 TRACE("-- NM_CLICK %p\n",This);
1252 break;
1254 case NM_RCLICK:
1255 TRACE("-- NM_RCLICK %p\n",This);
1256 break;
1258 case HDN_ENDTRACKA:
1259 TRACE("-- HDN_ENDTRACKA %p\n",This);
1260 /*nColumn1 = ListView_GetColumnWidth(This->hWndList, 0);
1261 nColumn2 = ListView_GetColumnWidth(This->hWndList, 1);*/
1262 break;
1264 case LVN_DELETEITEM:
1265 TRACE("-- LVN_DELETEITEM %p\n",This);
1266 SHFree((LPITEMIDLIST)lpnmlv->lParam); /*delete the pidl because we made a copy of it*/
1267 break;
1269 case LVN_DELETEALLITEMS:
1270 TRACE("-- LVN_DELETEALLITEMS %p\n",This);
1271 return FALSE;
1273 case LVN_INSERTITEM:
1274 TRACE("-- LVN_INSERTITEM (STUB)%p\n",This);
1275 break;
1277 case LVN_ITEMACTIVATE:
1278 TRACE("-- LVN_ITEMACTIVATE %p\n",This);
1279 OnStateChange(This, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
1280 ShellView_DoContextMenu(This, 0, 0, TRUE);
1281 break;
1283 case LVN_COLUMNCLICK:
1284 This->ListViewSortInfo.nHeaderID = lpnmlv->iSubItem;
1285 if(This->ListViewSortInfo.nLastHeaderID == This->ListViewSortInfo.nHeaderID)
1287 This->ListViewSortInfo.bIsAscending = !This->ListViewSortInfo.bIsAscending;
1289 else
1291 This->ListViewSortInfo.bIsAscending = TRUE;
1293 This->ListViewSortInfo.nLastHeaderID = This->ListViewSortInfo.nHeaderID;
1295 ListView_SortItems(lpnmlv->hdr.hwndFrom, ShellView_ListViewCompareItems, (LPARAM) (&(This->ListViewSortInfo)));
1296 break;
1298 case LVN_GETDISPINFOA:
1299 case LVN_GETDISPINFOW:
1300 TRACE("-- LVN_GETDISPINFO %p\n",This);
1301 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1303 if(lpdi->item.mask & LVIF_TEXT) /* text requested */
1305 if (This->pSF2Parent)
1307 SHELLDETAILS sd;
1308 IShellFolder2_GetDetailsOf(This->pSF2Parent, pidl, lpdi->item.iSubItem, &sd);
1309 if (lpnmh->code == LVN_GETDISPINFOA)
1311 StrRetToStrNA( lpdi->item.pszText, lpdi->item.cchTextMax, &sd.str, NULL);
1312 TRACE("-- text=%s\n",lpdi->item.pszText);
1314 else /* LVN_GETDISPINFOW */
1316 StrRetToStrNW( ((NMLVDISPINFOW *)lpdi)->item.pszText, lpdi->item.cchTextMax, &sd.str, NULL);
1317 TRACE("-- text=%s\n",debugstr_w((WCHAR*)(lpdi->item.pszText)));
1320 else
1322 FIXME("no SF2\n");
1325 if(lpdi->item.mask & LVIF_IMAGE) /* image requested */
1327 lpdi->item.iImage = SHMapPIDLToSystemImageListIndex(This->pSFParent, pidl, 0);
1329 break;
1331 case LVN_ITEMCHANGED:
1332 TRACE("-- LVN_ITEMCHANGED %p\n",This);
1333 OnStateChange(This, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
1334 break;
1336 case LVN_BEGINDRAG:
1337 case LVN_BEGINRDRAG:
1338 TRACE("-- LVN_BEGINDRAG\n");
1340 if (ShellView_GetSelections(This))
1342 IDataObject * pda;
1343 DWORD dwAttributes = SFGAO_CANLINK;
1344 DWORD dwEffect = DROPEFFECT_COPY | DROPEFFECT_MOVE;
1346 if (SUCCEEDED(IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, (LPCITEMIDLIST*)This->apidl, &IID_IDataObject,0,(LPVOID *)&pda)))
1348 IDropSource * pds = (IDropSource*)&(This->lpvtblDropSource); /* own DropSource interface */
1350 if (SUCCEEDED(IShellFolder_GetAttributesOf(This->pSFParent, This->cidl, (LPCITEMIDLIST*)This->apidl, &dwAttributes)))
1352 if (dwAttributes & SFGAO_CANLINK)
1354 dwEffect |= DROPEFFECT_LINK;
1358 if (pds)
1360 DWORD dwEffect;
1361 DoDragDrop(pda, pds, dwEffect, &dwEffect);
1363 IDataObject_Release(pda);
1366 break;
1368 case LVN_BEGINLABELEDITA:
1370 DWORD dwAttr = SFGAO_CANRENAME;
1371 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1373 TRACE("-- LVN_BEGINLABELEDITA %p\n",This);
1375 IShellFolder_GetAttributesOf(This->pSFParent, 1, (LPCITEMIDLIST*)&pidl, &dwAttr);
1376 if (SFGAO_CANRENAME & dwAttr)
1378 return FALSE;
1380 return TRUE;
1383 case LVN_ENDLABELEDITA:
1385 TRACE("-- LVN_ENDLABELEDITA %p\n",This);
1386 if (lpdi->item.pszText)
1388 HRESULT hr;
1389 WCHAR wszNewName[MAX_PATH];
1390 LVITEMA lvItem;
1392 ZeroMemory(&lvItem, sizeof(LVITEMA));
1393 lvItem.iItem = lpdi->item.iItem;
1394 lvItem.mask = LVIF_PARAM;
1395 ListView_GetItemA(This->hWndList, &lvItem);
1397 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1398 if (!MultiByteToWideChar( CP_ACP, 0, lpdi->item.pszText, -1, wszNewName, MAX_PATH ))
1399 wszNewName[MAX_PATH-1] = 0;
1400 hr = IShellFolder_SetNameOf(This->pSFParent, 0, pidl, wszNewName, SHGDN_INFOLDER, &pidl);
1402 if(SUCCEEDED(hr) && pidl)
1404 lvItem.mask = LVIF_PARAM;
1405 lvItem.lParam = (LPARAM)pidl;
1406 ListView_SetItemA(This->hWndList, &lvItem);
1407 return TRUE;
1410 return FALSE;
1413 case LVN_KEYDOWN:
1415 /* MSG msg;
1416 msg.hwnd = This->hWnd;
1417 msg.message = WM_KEYDOWN;
1418 msg.wParam = plvKeyDown->wVKey;
1419 msg.lParam = 0;
1420 msg.time = 0;
1421 msg.pt = 0;*/
1423 LPNMLVKEYDOWN plvKeyDown = (LPNMLVKEYDOWN) lpnmh;
1425 /* initiate a rename of the selected file or directory */
1426 if(plvKeyDown->wVKey == VK_F2)
1428 /* see how many files are selected */
1429 int i = ListView_GetSelectedCount(This->hWndList);
1431 /* get selected item */
1432 if(i == 1)
1434 /* get selected item */
1435 i = ListView_GetNextItem(This->hWndList, -1,
1436 LVNI_SELECTED);
1438 ListView_EnsureVisible(This->hWndList, i, 0);
1439 ListView_EditLabelA(This->hWndList, i);
1442 #if 0
1443 TranslateAccelerator(This->hWnd, This->hAccel, &msg)
1444 #endif
1445 else if(plvKeyDown->wVKey == VK_DELETE)
1447 UINT i;
1448 int item_index;
1449 LVITEMA item;
1450 LPITEMIDLIST* pItems;
1451 ISFHelper *psfhlp;
1453 IShellFolder_QueryInterface(This->pSFParent, &IID_ISFHelper,
1454 (LPVOID*)&psfhlp);
1456 if (psfhlp == NULL)
1457 break;
1459 if(!(i = ListView_GetSelectedCount(This->hWndList)))
1460 break;
1462 /* allocate memory for the pidl array */
1463 pItems = HeapAlloc(GetProcessHeap(), 0,
1464 sizeof(LPITEMIDLIST) * i);
1466 /* retrieve all selected items */
1467 i = 0;
1468 item_index = -1;
1469 while(ListView_GetSelectedCount(This->hWndList) > i)
1471 /* get selected item */
1472 item_index = ListView_GetNextItem(This->hWndList,
1473 item_index, LVNI_SELECTED);
1474 item.iItem = item_index;
1475 item.mask |= LVIF_PARAM;
1476 ListView_GetItemA(This->hWndList, &item);
1478 /* get item pidl */
1479 pItems[i] = (LPITEMIDLIST)item.lParam;
1481 i++;
1484 /* perform the item deletion */
1485 ISFHelper_DeleteItems(psfhlp, i, (LPCITEMIDLIST*)pItems);
1487 /* free pidl array memory */
1488 HeapFree(GetProcessHeap(), 0, pItems);
1490 else
1491 FIXME("LVN_KEYDOWN key=0x%08x\n",plvKeyDown->wVKey);
1493 break;
1495 default:
1496 TRACE("-- %p WM_COMMAND %x unhandled\n", This, lpnmh->code);
1497 break;
1499 return 0;
1502 /**********************************************************
1503 * ShellView_OnChange()
1506 static LRESULT ShellView_OnChange(IShellViewImpl * This, LPITEMIDLIST * Pidls, LONG wEventId)
1509 TRACE("(%p)(%p,%p,0x%08lx)\n", This, Pidls[0], Pidls[1], wEventId);
1510 switch(wEventId)
1512 case SHCNE_MKDIR:
1513 case SHCNE_CREATE:
1514 LV_AddItem(This, Pidls[0]);
1515 break;
1516 case SHCNE_RMDIR:
1517 case SHCNE_DELETE:
1518 LV_DeleteItem(This, Pidls[0]);
1519 break;
1520 case SHCNE_RENAMEFOLDER:
1521 case SHCNE_RENAMEITEM:
1522 LV_RenameItem(This, Pidls[0], Pidls[1]);
1523 break;
1524 case SHCNE_UPDATEITEM:
1525 break;
1527 return TRUE;
1529 /**********************************************************
1530 * ShellView_WndProc
1533 static LRESULT CALLBACK ShellView_WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
1535 IShellViewImpl * pThis = (IShellViewImpl*)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
1536 LPCREATESTRUCTA lpcs;
1538 TRACE("(hwnd=%p msg=%x wparm=%x lparm=%lx)\n",hWnd, uMessage, wParam, lParam);
1540 switch (uMessage)
1542 case WM_NCCREATE:
1543 lpcs = (LPCREATESTRUCTA)lParam;
1544 pThis = (IShellViewImpl*)(lpcs->lpCreateParams);
1545 SetWindowLongPtrW(hWnd, GWLP_USERDATA, (ULONG_PTR)pThis);
1546 pThis->hWnd = hWnd; /*set the window handle*/
1547 break;
1549 case WM_SIZE: return ShellView_OnSize(pThis,LOWORD(lParam), HIWORD(lParam));
1550 case WM_SETFOCUS: return ShellView_OnSetFocus(pThis);
1551 case WM_KILLFOCUS: return ShellView_OnKillFocus(pThis);
1552 case WM_CREATE: return ShellView_OnCreate(pThis);
1553 case WM_ACTIVATE: return ShellView_OnActivate(pThis, SVUIA_ACTIVATE_FOCUS);
1554 case WM_NOTIFY: return ShellView_OnNotify(pThis,(UINT)wParam, (LPNMHDR)lParam);
1555 case WM_COMMAND: return ShellView_OnCommand(pThis,
1556 GET_WM_COMMAND_ID(wParam, lParam),
1557 GET_WM_COMMAND_CMD(wParam, lParam),
1558 GET_WM_COMMAND_HWND(wParam, lParam));
1559 case SHV_CHANGE_NOTIFY: return ShellView_OnChange(pThis, (LPITEMIDLIST*)wParam, (LONG)lParam);
1561 case WM_CONTEXTMENU: ShellView_DoContextMenu(pThis, LOWORD(lParam), HIWORD(lParam), FALSE);
1562 return 0;
1564 case WM_SHOWWINDOW: UpdateWindow(pThis->hWndList);
1565 break;
1567 case WM_GETDLGCODE: return SendMessageA(pThis->hWndList,uMessage,0,0);
1569 case WM_DESTROY:
1570 RevokeDragDrop(pThis->hWnd);
1571 SHChangeNotifyDeregister(pThis->hNotify);
1572 break;
1574 case WM_ERASEBKGND:
1575 if ((pThis->FolderSettings.fFlags & FWF_DESKTOP) ||
1576 (pThis->FolderSettings.fFlags & FWF_TRANSPARENT))
1577 return 1;
1578 break;
1581 return DefWindowProcA (hWnd, uMessage, wParam, lParam);
1583 /**********************************************************
1586 * The INTERFACE of the IShellView object
1589 **********************************************************
1590 * IShellView_QueryInterface
1592 static HRESULT WINAPI IShellView_fnQueryInterface(IShellView * iface,REFIID riid, LPVOID *ppvObj)
1594 IShellViewImpl *This = (IShellViewImpl *)iface;
1596 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1598 *ppvObj = NULL;
1600 if(IsEqualIID(riid, &IID_IUnknown))
1602 *ppvObj = This;
1604 else if(IsEqualIID(riid, &IID_IShellView))
1606 *ppvObj = (IShellView*)This;
1608 else if(IsEqualIID(riid, &IID_IOleCommandTarget))
1610 *ppvObj = (IOleCommandTarget*)&(This->lpvtblOleCommandTarget);
1612 else if(IsEqualIID(riid, &IID_IDropTarget))
1614 *ppvObj = (IDropTarget*)&(This->lpvtblDropTarget);
1616 else if(IsEqualIID(riid, &IID_IDropSource))
1618 *ppvObj = (IDropSource*)&(This->lpvtblDropSource);
1620 else if(IsEqualIID(riid, &IID_IViewObject))
1622 *ppvObj = (IViewObject*)&(This->lpvtblViewObject);
1625 if(*ppvObj)
1627 IUnknown_AddRef( (IUnknown*)*ppvObj );
1628 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1629 return S_OK;
1631 TRACE("-- Interface: E_NOINTERFACE\n");
1632 return E_NOINTERFACE;
1635 /**********************************************************
1636 * IShellView_AddRef
1638 static ULONG WINAPI IShellView_fnAddRef(IShellView * iface)
1640 IShellViewImpl *This = (IShellViewImpl *)iface;
1641 ULONG refCount = InterlockedIncrement(&This->ref);
1643 TRACE("(%p)->(count=%lu)\n", This, refCount - 1);
1645 return refCount;
1647 /**********************************************************
1648 * IShellView_Release
1650 static ULONG WINAPI IShellView_fnRelease(IShellView * iface)
1652 IShellViewImpl *This = (IShellViewImpl *)iface;
1653 ULONG refCount = InterlockedDecrement(&This->ref);
1655 TRACE("(%p)->(count=%li)\n", This, refCount + 1);
1657 if (!refCount)
1659 TRACE(" destroying IShellView(%p)\n",This);
1661 DestroyWindow(This->hWndList);
1663 if(This->pSFParent)
1664 IShellFolder_Release(This->pSFParent);
1666 if(This->pSF2Parent)
1667 IShellFolder2_Release(This->pSF2Parent);
1669 if(This->apidl)
1670 SHFree(This->apidl);
1672 if(This->pAdvSink)
1673 IAdviseSink_Release(This->pAdvSink);
1675 HeapFree(GetProcessHeap(),0,This);
1677 return refCount;
1680 /**********************************************************
1681 * ShellView_GetWindow
1683 static HRESULT WINAPI IShellView_fnGetWindow(IShellView * iface,HWND * phWnd)
1685 IShellViewImpl *This = (IShellViewImpl *)iface;
1687 TRACE("(%p)\n",This);
1689 *phWnd = This->hWnd;
1691 return S_OK;
1694 static HRESULT WINAPI IShellView_fnContextSensitiveHelp(IShellView * iface,BOOL fEnterMode)
1696 IShellViewImpl *This = (IShellViewImpl *)iface;
1698 FIXME("(%p) stub\n",This);
1700 return E_NOTIMPL;
1703 /**********************************************************
1704 * IShellView_TranslateAccelerator
1706 * FIXME:
1707 * use the accel functions
1709 static HRESULT WINAPI IShellView_fnTranslateAccelerator(IShellView * iface,LPMSG lpmsg)
1711 #if 0
1712 IShellViewImpl *This = (IShellViewImpl *)iface;
1714 FIXME("(%p)->(%p: hwnd=%x msg=%x lp=%lx wp=%x) stub\n",This,lpmsg, lpmsg->hwnd, lpmsg->message, lpmsg->lParam, lpmsg->wParam);
1715 #endif
1717 if ((lpmsg->message>=WM_KEYFIRST) && (lpmsg->message>=WM_KEYLAST))
1719 TRACE("-- key=0x04%x\n",lpmsg->wParam) ;
1721 return S_FALSE; /* not handled */
1724 static HRESULT WINAPI IShellView_fnEnableModeless(IShellView * iface,BOOL fEnable)
1726 IShellViewImpl *This = (IShellViewImpl *)iface;
1728 FIXME("(%p) stub\n",This);
1730 return E_NOTIMPL;
1733 static HRESULT WINAPI IShellView_fnUIActivate(IShellView * iface,UINT uState)
1735 IShellViewImpl *This = (IShellViewImpl *)iface;
1738 CHAR szName[MAX_PATH];
1740 LRESULT lResult;
1741 int nPartArray[1] = {-1};
1743 TRACE("(%p)->(state=%x) stub\n",This, uState);
1745 /*don't do anything if the state isn't really changing*/
1746 if(This->uState == uState)
1748 return S_OK;
1751 /*OnActivate handles the menu merging and internal state*/
1752 ShellView_OnActivate(This, uState);
1754 /*only do This if we are active*/
1755 if(uState != SVUIA_DEACTIVATE)
1759 GetFolderPath is not a method of IShellFolder
1760 IShellFolder_GetFolderPath( This->pSFParent, szName, sizeof(szName) );
1762 /* set the number of parts */
1763 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETPARTS, 1,
1764 (LPARAM)nPartArray, &lResult);
1766 /* set the text for the parts */
1768 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETTEXTA,
1769 0, (LPARAM)szName, &lResult);
1773 return S_OK;
1776 static HRESULT WINAPI IShellView_fnRefresh(IShellView * iface)
1778 IShellViewImpl *This = (IShellViewImpl *)iface;
1780 TRACE("(%p)\n",This);
1782 ListView_DeleteAllItems(This->hWndList);
1783 ShellView_FillList(This);
1785 return S_OK;
1788 static HRESULT WINAPI IShellView_fnCreateViewWindow(
1789 IShellView * iface,
1790 IShellView *lpPrevView,
1791 LPCFOLDERSETTINGS lpfs,
1792 IShellBrowser * psb,
1793 RECT * prcView,
1794 HWND *phWnd)
1796 IShellViewImpl *This = (IShellViewImpl *)iface;
1798 WNDCLASSA wc;
1799 *phWnd = 0;
1802 TRACE("(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n",This, lpPrevView,lpfs, psb, prcView, phWnd);
1803 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);
1805 /*set up the member variables*/
1806 This->pShellBrowser = psb;
1807 This->FolderSettings = *lpfs;
1809 /*get our parent window*/
1810 IShellBrowser_AddRef(This->pShellBrowser);
1811 IShellBrowser_GetWindow(This->pShellBrowser, &(This->hWndParent));
1813 /* try to get the ICommDlgBrowserInterface, adds a reference !!! */
1814 This->pCommDlgBrowser=NULL;
1815 if ( SUCCEEDED (IShellBrowser_QueryInterface( This->pShellBrowser,
1816 (REFIID)&IID_ICommDlgBrowser, (LPVOID*) &This->pCommDlgBrowser)))
1818 TRACE("-- CommDlgBrowser\n");
1821 /*if our window class has not been registered, then do so*/
1822 if(!GetClassInfoA(shell32_hInstance, SV_CLASS_NAME, &wc))
1824 ZeroMemory(&wc, sizeof(wc));
1825 wc.style = CS_HREDRAW | CS_VREDRAW;
1826 wc.lpfnWndProc = ShellView_WndProc;
1827 wc.cbClsExtra = 0;
1828 wc.cbWndExtra = 0;
1829 wc.hInstance = shell32_hInstance;
1830 wc.hIcon = 0;
1831 wc.hCursor = LoadCursorA (0, (LPSTR)IDC_ARROW);
1832 wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
1833 wc.lpszMenuName = NULL;
1834 wc.lpszClassName = SV_CLASS_NAME;
1836 if(!RegisterClassA(&wc))
1837 return E_FAIL;
1840 *phWnd = CreateWindowExA(0,
1841 SV_CLASS_NAME,
1842 NULL,
1843 WS_CHILD | WS_VISIBLE | WS_TABSTOP,
1844 prcView->left,
1845 prcView->top,
1846 prcView->right - prcView->left,
1847 prcView->bottom - prcView->top,
1848 This->hWndParent,
1850 shell32_hInstance,
1851 (LPVOID)This);
1853 CheckToolbar(This);
1855 if(!*phWnd) return E_FAIL;
1857 return S_OK;
1860 static HRESULT WINAPI IShellView_fnDestroyViewWindow(IShellView * iface)
1862 IShellViewImpl *This = (IShellViewImpl *)iface;
1864 TRACE("(%p)\n",This);
1866 /*Make absolutely sure all our UI is cleaned up.*/
1867 IShellView_UIActivate((IShellView*)This, SVUIA_DEACTIVATE);
1869 if(This->hMenu)
1871 DestroyMenu(This->hMenu);
1874 DestroyWindow(This->hWnd);
1875 if(This->pShellBrowser) IShellBrowser_Release(This->pShellBrowser);
1876 if(This->pCommDlgBrowser) ICommDlgBrowser_Release(This->pCommDlgBrowser);
1879 return S_OK;
1882 static HRESULT WINAPI IShellView_fnGetCurrentInfo(IShellView * iface, LPFOLDERSETTINGS lpfs)
1884 IShellViewImpl *This = (IShellViewImpl *)iface;
1886 TRACE("(%p)->(%p) vmode=%x flags=%x\n",This, lpfs,
1887 This->FolderSettings.ViewMode, This->FolderSettings.fFlags);
1889 if (!lpfs) return E_INVALIDARG;
1891 *lpfs = This->FolderSettings;
1892 return NOERROR;
1895 static HRESULT WINAPI IShellView_fnAddPropertySheetPages(IShellView * iface, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam)
1897 IShellViewImpl *This = (IShellViewImpl *)iface;
1899 FIXME("(%p) stub\n",This);
1901 return E_NOTIMPL;
1904 static HRESULT WINAPI IShellView_fnSaveViewState(IShellView * iface)
1906 IShellViewImpl *This = (IShellViewImpl *)iface;
1908 FIXME("(%p) stub\n",This);
1910 return S_OK;
1913 static HRESULT WINAPI IShellView_fnSelectItem(
1914 IShellView * iface,
1915 LPCITEMIDLIST pidl,
1916 UINT uFlags)
1918 IShellViewImpl *This = (IShellViewImpl *)iface;
1919 int i;
1921 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n",This, pidl, uFlags);
1923 i = LV_FindItemByPidl(This, pidl);
1925 if (i != -1)
1927 LVITEMA lvItem;
1929 if(uFlags & SVSI_ENSUREVISIBLE)
1930 ListView_EnsureVisible(This->hWndList, i, 0);
1932 ZeroMemory(&lvItem, sizeof(LVITEMA));
1933 lvItem.mask = LVIF_STATE;
1934 lvItem.iItem = 0;
1936 while(ListView_GetItemA(This->hWndList, &lvItem))
1938 if (lvItem.iItem == i)
1940 if (uFlags & SVSI_SELECT)
1941 lvItem.state |= LVIS_SELECTED;
1942 else
1943 lvItem.state &= ~LVIS_SELECTED;
1945 if(uFlags & SVSI_FOCUSED)
1946 lvItem.state &= ~LVIS_FOCUSED;
1948 else
1950 if (uFlags & SVSI_DESELECTOTHERS)
1951 lvItem.state &= ~LVIS_SELECTED;
1953 ListView_SetItemA(This->hWndList, &lvItem);
1954 lvItem.iItem++;
1958 if(uFlags & SVSI_EDIT)
1959 ListView_EditLabelA(This->hWndList, i);
1962 return S_OK;
1965 static HRESULT WINAPI IShellView_fnGetItemObject(IShellView * iface, UINT uItem, REFIID riid, LPVOID *ppvOut)
1967 IShellViewImpl *This = (IShellViewImpl *)iface;
1969 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n",This, uItem, debugstr_guid(riid), ppvOut);
1971 *ppvOut = NULL;
1973 switch(uItem)
1975 case SVGIO_BACKGROUND:
1976 *ppvOut = ISvBgCm_Constructor(This->pSFParent, FALSE);
1977 break;
1979 case SVGIO_SELECTION:
1980 ShellView_GetSelections(This);
1981 IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, (LPCITEMIDLIST*)This->apidl, riid, 0, ppvOut);
1982 break;
1984 TRACE("-- (%p)->(interface=%p)\n",This, *ppvOut);
1986 if(!*ppvOut) return E_OUTOFMEMORY;
1988 return S_OK;
1991 static const IShellViewVtbl svvt =
1993 IShellView_fnQueryInterface,
1994 IShellView_fnAddRef,
1995 IShellView_fnRelease,
1996 IShellView_fnGetWindow,
1997 IShellView_fnContextSensitiveHelp,
1998 IShellView_fnTranslateAccelerator,
1999 IShellView_fnEnableModeless,
2000 IShellView_fnUIActivate,
2001 IShellView_fnRefresh,
2002 IShellView_fnCreateViewWindow,
2003 IShellView_fnDestroyViewWindow,
2004 IShellView_fnGetCurrentInfo,
2005 IShellView_fnAddPropertySheetPages,
2006 IShellView_fnSaveViewState,
2007 IShellView_fnSelectItem,
2008 IShellView_fnGetItemObject
2012 /**********************************************************
2013 * ISVOleCmdTarget_QueryInterface (IUnknown)
2015 static HRESULT WINAPI ISVOleCmdTarget_QueryInterface(
2016 IOleCommandTarget * iface,
2017 REFIID iid,
2018 LPVOID* ppvObj)
2020 _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
2022 return IShellFolder_QueryInterface((IShellFolder*)This, iid, ppvObj);
2025 /**********************************************************
2026 * ISVOleCmdTarget_AddRef (IUnknown)
2028 static ULONG WINAPI ISVOleCmdTarget_AddRef(
2029 IOleCommandTarget * iface)
2031 _ICOM_THIS_From_IOleCommandTarget(IShellFolder, iface);
2033 return IShellFolder_AddRef((IShellFolder*)This);
2036 /**********************************************************
2037 * ISVOleCmdTarget_Release (IUnknown)
2039 static ULONG WINAPI ISVOleCmdTarget_Release(
2040 IOleCommandTarget * iface)
2042 _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
2044 return IShellFolder_Release((IShellFolder*)This);
2047 /**********************************************************
2048 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2050 static HRESULT WINAPI ISVOleCmdTarget_QueryStatus(
2051 IOleCommandTarget *iface,
2052 const GUID* pguidCmdGroup,
2053 ULONG cCmds,
2054 OLECMD * prgCmds,
2055 OLECMDTEXT* pCmdText)
2057 UINT i;
2058 _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
2060 FIXME("(%p)->(%p(%s) 0x%08lx %p %p\n",
2061 This, pguidCmdGroup, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText);
2063 if (!prgCmds)
2064 return E_POINTER;
2065 for (i = 0; i < cCmds; i++)
2067 FIXME("\tprgCmds[%d].cmdID = %ld\n", i, prgCmds[i].cmdID);
2068 prgCmds[i].cmdf = 0;
2070 return OLECMDERR_E_UNKNOWNGROUP;
2073 /**********************************************************
2074 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2076 * nCmdID is the OLECMDID_* enumeration
2078 static HRESULT WINAPI ISVOleCmdTarget_Exec(
2079 IOleCommandTarget *iface,
2080 const GUID* pguidCmdGroup,
2081 DWORD nCmdID,
2082 DWORD nCmdexecopt,
2083 VARIANT* pvaIn,
2084 VARIANT* pvaOut)
2086 _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
2088 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08lx Opt:0x%08lx %p %p)\n",
2089 This, debugstr_guid(pguidCmdGroup), nCmdID, nCmdexecopt, pvaIn, pvaOut);
2091 if (IsEqualIID(pguidCmdGroup, &CGID_Explorer) &&
2092 (nCmdID == 0x29) &&
2093 (nCmdexecopt == 4) && pvaOut)
2094 return S_OK;
2095 if (IsEqualIID(pguidCmdGroup, &CGID_ShellDocView) &&
2096 (nCmdID == 9) &&
2097 (nCmdexecopt == 0))
2098 return 1;
2100 return OLECMDERR_E_UNKNOWNGROUP;
2103 static const IOleCommandTargetVtbl ctvt =
2105 ISVOleCmdTarget_QueryInterface,
2106 ISVOleCmdTarget_AddRef,
2107 ISVOleCmdTarget_Release,
2108 ISVOleCmdTarget_QueryStatus,
2109 ISVOleCmdTarget_Exec
2112 /**********************************************************
2113 * ISVDropTarget implementation
2116 static HRESULT WINAPI ISVDropTarget_QueryInterface(
2117 IDropTarget *iface,
2118 REFIID riid,
2119 LPVOID *ppvObj)
2121 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2123 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2125 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2128 static ULONG WINAPI ISVDropTarget_AddRef( IDropTarget *iface)
2130 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2132 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2134 return IShellFolder_AddRef((IShellFolder*)This);
2137 static ULONG WINAPI ISVDropTarget_Release( IDropTarget *iface)
2139 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2141 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2143 return IShellFolder_Release((IShellFolder*)This);
2146 static HRESULT WINAPI ISVDropTarget_DragEnter(
2147 IDropTarget *iface,
2148 IDataObject *pDataObject,
2149 DWORD grfKeyState,
2150 POINTL pt,
2151 DWORD *pdwEffect)
2154 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2156 FIXME("Stub: This=%p, DataObject=%p\n",This,pDataObject);
2158 return E_NOTIMPL;
2161 static HRESULT WINAPI ISVDropTarget_DragOver(
2162 IDropTarget *iface,
2163 DWORD grfKeyState,
2164 POINTL pt,
2165 DWORD *pdwEffect)
2167 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2169 FIXME("Stub: This=%p\n",This);
2171 return E_NOTIMPL;
2174 static HRESULT WINAPI ISVDropTarget_DragLeave(
2175 IDropTarget *iface)
2177 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2179 FIXME("Stub: This=%p\n",This);
2181 return E_NOTIMPL;
2184 static HRESULT WINAPI ISVDropTarget_Drop(
2185 IDropTarget *iface,
2186 IDataObject* pDataObject,
2187 DWORD grfKeyState,
2188 POINTL pt,
2189 DWORD *pdwEffect)
2191 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2193 FIXME("Stub: This=%p\n",This);
2195 return E_NOTIMPL;
2198 static const IDropTargetVtbl dtvt =
2200 ISVDropTarget_QueryInterface,
2201 ISVDropTarget_AddRef,
2202 ISVDropTarget_Release,
2203 ISVDropTarget_DragEnter,
2204 ISVDropTarget_DragOver,
2205 ISVDropTarget_DragLeave,
2206 ISVDropTarget_Drop
2209 /**********************************************************
2210 * ISVDropSource implementation
2213 static HRESULT WINAPI ISVDropSource_QueryInterface(
2214 IDropSource *iface,
2215 REFIID riid,
2216 LPVOID *ppvObj)
2218 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2220 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2222 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2225 static ULONG WINAPI ISVDropSource_AddRef( IDropSource *iface)
2227 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2229 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2231 return IShellFolder_AddRef((IShellFolder*)This);
2234 static ULONG WINAPI ISVDropSource_Release( IDropSource *iface)
2236 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2238 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2240 return IShellFolder_Release((IShellFolder*)This);
2242 static HRESULT WINAPI ISVDropSource_QueryContinueDrag(
2243 IDropSource *iface,
2244 BOOL fEscapePressed,
2245 DWORD grfKeyState)
2247 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2248 TRACE("(%p)\n",This);
2250 if (fEscapePressed)
2251 return DRAGDROP_S_CANCEL;
2252 else if (!(grfKeyState & MK_LBUTTON) && !(grfKeyState & MK_RBUTTON))
2253 return DRAGDROP_S_DROP;
2254 else
2255 return NOERROR;
2258 static HRESULT WINAPI ISVDropSource_GiveFeedback(
2259 IDropSource *iface,
2260 DWORD dwEffect)
2262 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2263 TRACE("(%p)\n",This);
2265 return DRAGDROP_S_USEDEFAULTCURSORS;
2268 static const IDropSourceVtbl dsvt =
2270 ISVDropSource_QueryInterface,
2271 ISVDropSource_AddRef,
2272 ISVDropSource_Release,
2273 ISVDropSource_QueryContinueDrag,
2274 ISVDropSource_GiveFeedback
2276 /**********************************************************
2277 * ISVViewObject implementation
2280 static HRESULT WINAPI ISVViewObject_QueryInterface(
2281 IViewObject *iface,
2282 REFIID riid,
2283 LPVOID *ppvObj)
2285 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2287 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2289 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2292 static ULONG WINAPI ISVViewObject_AddRef( IViewObject *iface)
2294 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2296 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2298 return IShellFolder_AddRef((IShellFolder*)This);
2301 static ULONG WINAPI ISVViewObject_Release( IViewObject *iface)
2303 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2305 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2307 return IShellFolder_Release((IShellFolder*)This);
2310 static HRESULT WINAPI ISVViewObject_Draw(
2311 IViewObject *iface,
2312 DWORD dwDrawAspect,
2313 LONG lindex,
2314 void* pvAspect,
2315 DVTARGETDEVICE* ptd,
2316 HDC hdcTargetDev,
2317 HDC hdcDraw,
2318 LPCRECTL lprcBounds,
2319 LPCRECTL lprcWBounds,
2320 BOOL (CALLBACK *pfnContinue)(ULONG_PTR dwContinue),
2321 ULONG_PTR dwContinue)
2324 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2326 FIXME("Stub: This=%p\n",This);
2328 return E_NOTIMPL;
2330 static HRESULT WINAPI ISVViewObject_GetColorSet(
2331 IViewObject *iface,
2332 DWORD dwDrawAspect,
2333 LONG lindex,
2334 void *pvAspect,
2335 DVTARGETDEVICE* ptd,
2336 HDC hicTargetDevice,
2337 LOGPALETTE** ppColorSet)
2340 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2342 FIXME("Stub: This=%p\n",This);
2344 return E_NOTIMPL;
2346 static HRESULT WINAPI ISVViewObject_Freeze(
2347 IViewObject *iface,
2348 DWORD dwDrawAspect,
2349 LONG lindex,
2350 void* pvAspect,
2351 DWORD* pdwFreeze)
2354 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2356 FIXME("Stub: This=%p\n",This);
2358 return E_NOTIMPL;
2360 static HRESULT WINAPI ISVViewObject_Unfreeze(
2361 IViewObject *iface,
2362 DWORD dwFreeze)
2365 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2367 FIXME("Stub: This=%p\n",This);
2369 return E_NOTIMPL;
2371 static HRESULT WINAPI ISVViewObject_SetAdvise(
2372 IViewObject *iface,
2373 DWORD aspects,
2374 DWORD advf,
2375 IAdviseSink* pAdvSink)
2378 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2380 FIXME("partial stub: %p %08lx %08lx %p\n",
2381 This, aspects, advf, pAdvSink);
2383 /* FIXME: we set the AdviseSink, but never use it to send any advice */
2384 This->pAdvSink = pAdvSink;
2385 This->dwAspects = aspects;
2386 This->dwAdvf = advf;
2388 return S_OK;
2391 static HRESULT WINAPI ISVViewObject_GetAdvise(
2392 IViewObject *iface,
2393 DWORD* pAspects,
2394 DWORD* pAdvf,
2395 IAdviseSink** ppAdvSink)
2398 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2400 TRACE("This=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n",
2401 This, pAspects, pAdvf, ppAdvSink);
2403 if( ppAdvSink )
2405 IAdviseSink_AddRef( This->pAdvSink );
2406 *ppAdvSink = This->pAdvSink;
2408 if( pAspects )
2409 *pAspects = This->dwAspects;
2410 if( pAdvf )
2411 *pAdvf = This->dwAdvf;
2413 return S_OK;
2417 static const IViewObjectVtbl vovt =
2419 ISVViewObject_QueryInterface,
2420 ISVViewObject_AddRef,
2421 ISVViewObject_Release,
2422 ISVViewObject_Draw,
2423 ISVViewObject_GetColorSet,
2424 ISVViewObject_Freeze,
2425 ISVViewObject_Unfreeze,
2426 ISVViewObject_SetAdvise,
2427 ISVViewObject_GetAdvise