_findclose() exists on MinGW, so prefix it.
[wine/gsoc_dplay.git] / dlls / shell32 / shlview.c
blob0634a4ffc8f4dbcb2317fb4b5824b98d37986c93
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 IShellViewVtbl* lpVtbl;
80 DWORD ref;
81 IOleCommandTargetVtbl* lpvtblOleCommandTarget;
82 IDropTargetVtbl* lpvtblDropTarget;
83 IDropSourceVtbl* lpvtblDropSource;
84 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 struct IShellViewVtbl svvt;
107 static struct IOleCommandTargetVtbl ctvt;
108 #define _IOleCommandTarget_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblOleCommandTarget)))
109 #define _ICOM_THIS_From_IOleCommandTarget(class, name) class* This = (class*)(((char*)name)-_IOleCommandTarget_Offset);
111 static struct IDropTargetVtbl dtvt;
112 #define _IDropTarget_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblDropTarget)))
113 #define _ICOM_THIS_From_IDropTarget(class, name) class* This = (class*)(((char*)name)-_IDropTarget_Offset);
115 static struct IDropSourceVtbl dsvt;
116 #define _IDropSource_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblDropSource)))
117 #define _ICOM_THIS_From_IDropSource(class, name) class* This = (class*)(((char*)name)-_IDropSource_Offset);
119 static struct IViewObjectVtbl vovt;
120 #define _IViewObject_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblViewObject)))
121 #define _ICOM_THIS_From_IViewObject(class, name) class* This = (class*)(((char*)name)-_IViewObject_Offset);
123 /* ListView Header ID's */
124 #define LISTVIEW_COLUMN_NAME 0
125 #define LISTVIEW_COLUMN_SIZE 1
126 #define LISTVIEW_COLUMN_TYPE 2
127 #define LISTVIEW_COLUMN_TIME 3
128 #define LISTVIEW_COLUMN_ATTRIB 4
130 /*menu items */
131 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
132 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
133 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
135 #define ID_LISTVIEW 2000
137 #define SHV_CHANGE_NOTIFY WM_USER + 0x1111
139 /*windowsx.h */
140 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
141 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
142 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
144 extern void WINAPI _InsertMenuItem (HMENU hmenu, UINT indexMenu, BOOL fByPosition,
145 UINT wID, UINT fType, LPSTR dwTypeData, UINT fState);
148 Items merged into the toolbar and and the filemenu
150 typedef struct
151 { int idCommand;
152 int iImage;
153 int idButtonString;
154 int idMenuString;
155 BYTE bState;
156 BYTE bStyle;
157 } MYTOOLINFO, *LPMYTOOLINFO;
159 MYTOOLINFO Tools[] =
161 { FCIDM_SHVIEW_BIGICON, 0, 0, IDS_VIEW_LARGE, TBSTATE_ENABLED, BTNS_BUTTON },
162 { FCIDM_SHVIEW_SMALLICON, 0, 0, IDS_VIEW_SMALL, TBSTATE_ENABLED, BTNS_BUTTON },
163 { FCIDM_SHVIEW_LISTVIEW, 0, 0, IDS_VIEW_LIST, TBSTATE_ENABLED, BTNS_BUTTON },
164 { FCIDM_SHVIEW_REPORTVIEW, 0, 0, IDS_VIEW_DETAILS, TBSTATE_ENABLED, BTNS_BUTTON },
165 { -1, 0, 0, 0, 0, 0}
168 typedef void (CALLBACK *PFNSHGETSETTINGSPROC)(LPSHELLFLAGSTATE lpsfs, DWORD dwMask);
170 /**********************************************************
171 * IShellView_Constructor
173 IShellView * IShellView_Constructor( IShellFolder * pFolder)
174 { IShellViewImpl * sv;
175 sv=HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IShellViewImpl));
176 sv->ref=1;
177 sv->lpVtbl=&svvt;
178 sv->lpvtblOleCommandTarget=&ctvt;
179 sv->lpvtblDropTarget=&dtvt;
180 sv->lpvtblDropSource=&dsvt;
181 sv->lpvtblViewObject=&vovt;
183 sv->pSFParent = pFolder;
184 if(pFolder) IShellFolder_AddRef(pFolder);
185 IShellFolder_QueryInterface(sv->pSFParent, &IID_IShellFolder2, (LPVOID*)&sv->pSF2Parent);
187 TRACE("(%p)->(%p)\n",sv, pFolder);
188 return (IShellView *) sv;
191 /**********************************************************
193 * ##### helperfunctions for communication with ICommDlgBrowser #####
195 static BOOL IsInCommDlg(IShellViewImpl * This)
196 { return(This->pCommDlgBrowser != NULL);
199 static HRESULT IncludeObject(IShellViewImpl * This, LPCITEMIDLIST pidl)
201 HRESULT ret = S_OK;
203 if ( IsInCommDlg(This) )
205 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl);
206 ret = ICommDlgBrowser_IncludeObject(This->pCommDlgBrowser, (IShellView*)This, pidl);
207 TRACE("--0x%08lx\n", ret);
209 return ret;
212 static HRESULT OnDefaultCommand(IShellViewImpl * This)
214 HRESULT ret = S_FALSE;
216 if (IsInCommDlg(This))
218 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
219 ret = ICommDlgBrowser_OnDefaultCommand(This->pCommDlgBrowser, (IShellView*)This);
220 TRACE("-- returns %08lx\n", ret);
222 return ret;
225 static HRESULT OnStateChange(IShellViewImpl * This, UINT uFlags)
227 HRESULT ret = S_FALSE;
229 if (IsInCommDlg(This))
231 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags);
232 ret = ICommDlgBrowser_OnStateChange(This->pCommDlgBrowser, (IShellView*)This, uFlags);
233 TRACE("--\n");
235 return ret;
237 /**********************************************************
238 * set the toolbar of the filedialog buttons
240 * - activates the buttons from the shellbrowser according to
241 * the view state
243 static void CheckToolbar(IShellViewImpl * This)
245 LRESULT result;
247 TRACE("\n");
249 if (IsInCommDlg(This))
251 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
252 FCIDM_TB_SMALLICON, (This->FolderSettings.ViewMode==FVM_LIST)? TRUE : FALSE, &result);
253 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
254 FCIDM_TB_REPORTVIEW, (This->FolderSettings.ViewMode==FVM_DETAILS)? TRUE : FALSE, &result);
255 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
256 FCIDM_TB_SMALLICON, TRUE, &result);
257 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
258 FCIDM_TB_REPORTVIEW, TRUE, &result);
262 /**********************************************************
264 * ##### helperfunctions for initializing the view #####
266 /**********************************************************
267 * change the style of the listview control
269 static void SetStyle(IShellViewImpl * This, DWORD dwAdd, DWORD dwRemove)
271 DWORD tmpstyle;
273 TRACE("(%p)\n", This);
275 tmpstyle = GetWindowLongA(This->hWndList, GWL_STYLE);
276 SetWindowLongA(This->hWndList, GWL_STYLE, dwAdd | (tmpstyle & ~dwRemove));
279 /**********************************************************
280 * ShellView_CreateList()
282 * - creates the list view window
284 static BOOL ShellView_CreateList (IShellViewImpl * This)
285 { DWORD dwStyle, dwExStyle;
287 TRACE("%p\n",This);
289 dwStyle = WS_TABSTOP | WS_VISIBLE | WS_CHILDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
290 LVS_SHAREIMAGELISTS | LVS_EDITLABELS | LVS_ALIGNLEFT | LVS_AUTOARRANGE;
291 dwExStyle = WS_EX_CLIENTEDGE;
293 switch (This->FolderSettings.ViewMode)
295 case FVM_ICON: dwStyle |= LVS_ICON; break;
296 case FVM_DETAILS: dwStyle |= LVS_REPORT; break;
297 case FVM_SMALLICON: dwStyle |= LVS_SMALLICON; break;
298 case FVM_LIST: dwStyle |= LVS_LIST; break;
299 default: dwStyle |= LVS_LIST; break;
302 if (This->FolderSettings.fFlags & FWF_AUTOARRANGE) dwStyle |= LVS_AUTOARRANGE;
303 if (This->FolderSettings.fFlags & FWF_DESKTOP)
304 This->FolderSettings.fFlags |= FWF_NOCLIENTEDGE | FWF_NOSCROLL;
305 if (This->FolderSettings.fFlags & FWF_SINGLESEL) dwStyle |= LVS_SINGLESEL;
306 if (This->FolderSettings.fFlags & FWF_NOCLIENTEDGE)
307 dwExStyle &= ~WS_EX_CLIENTEDGE;
309 This->hWndList=CreateWindowExA( dwExStyle,
310 WC_LISTVIEWA,
311 NULL,
312 dwStyle,
313 0,0,0,0,
314 This->hWnd,
315 (HMENU)ID_LISTVIEW,
316 shell32_hInstance,
317 NULL);
319 if(!This->hWndList)
320 return FALSE;
322 This->ListViewSortInfo.bIsAscending = TRUE;
323 This->ListViewSortInfo.nHeaderID = -1;
324 This->ListViewSortInfo.nLastHeaderID = -1;
326 if (This->FolderSettings.fFlags & FWF_DESKTOP) {
327 if (0) /* FIXME: look into registry vale HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ListviewShadow and activate drop shadows */
328 ListView_SetTextBkColor(This->hWndList, CLR_NONE);
329 else
330 ListView_SetTextBkColor(This->hWndList, GetSysColor(COLOR_DESKTOP));
332 ListView_SetTextColor(This->hWndList, RGB(255,255,255));
335 /* UpdateShellSettings(); */
336 return TRUE;
339 /**********************************************************
340 * ShellView_InitList()
342 * - adds all needed columns to the shellview
344 static BOOL ShellView_InitList(IShellViewImpl * This)
346 LVCOLUMNA lvColumn;
347 SHELLDETAILS sd;
348 int i;
349 char szTemp[50];
351 TRACE("%p\n",This);
353 ListView_DeleteAllItems(This->hWndList);
355 lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT;
356 lvColumn.pszText = szTemp;
358 if (This->pSF2Parent)
360 for (i=0; 1; i++)
362 if (!SUCCEEDED(IShellFolder2_GetDetailsOf(This->pSF2Parent, NULL, i, &sd)))
363 break;
364 lvColumn.fmt = sd.fmt;
365 lvColumn.cx = sd.cxChar*8; /* chars->pixel */
366 StrRetToStrNA( szTemp, 50, &sd.str, NULL);
367 ListView_InsertColumnA(This->hWndList, i, &lvColumn);
370 else
372 FIXME("no SF2\n");
375 ListView_SetImageList(This->hWndList, ShellSmallIconList, LVSIL_SMALL);
376 ListView_SetImageList(This->hWndList, ShellBigIconList, LVSIL_NORMAL);
378 return TRUE;
380 /**********************************************************
381 * ShellView_CompareItems()
383 * NOTES
384 * internal, CALLBACK for DSA_Sort
386 static INT CALLBACK ShellView_CompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
388 int ret;
389 TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1, lParam2, (LPVOID) lpData);
391 if(!lpData) return 0;
393 ret = (SHORT) SCODE_CODE(IShellFolder_CompareIDs((LPSHELLFOLDER)lpData, 0, (LPITEMIDLIST)lParam1, (LPITEMIDLIST)lParam2));
394 TRACE("ret=%i\n",ret);
395 return ret;
398 /*************************************************************************
399 * ShellView_ListViewCompareItems
401 * Compare Function for the Listview (FileOpen Dialog)
403 * PARAMS
404 * lParam1 [I] the first ItemIdList to compare with
405 * lParam2 [I] the second ItemIdList to compare with
406 * lpData [I] The column ID for the header Ctrl to process
408 * RETURNS
409 * A negative value if the first item should precede the second,
410 * a positive value if the first item should follow the second,
411 * or zero if the two items are equivalent
413 * NOTES
414 * FIXME: function does what ShellView_CompareItems is supposed to do.
415 * unify it and figure out how to use the undocumented first parameter
416 * of IShellFolder_CompareIDs to do the job this function does and
417 * move this code to IShellFolder.
418 * make LISTVIEW_SORT_INFO obsolete
419 * the way this function works is only usable if we had only
420 * filesystemfolders (25/10/99 jsch)
422 static INT CALLBACK ShellView_ListViewCompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
424 INT nDiff=0;
425 FILETIME fd1, fd2;
426 char strName1[MAX_PATH], strName2[MAX_PATH];
427 BOOL bIsFolder1, bIsFolder2,bIsBothFolder;
428 LPITEMIDLIST pItemIdList1 = (LPITEMIDLIST) lParam1;
429 LPITEMIDLIST pItemIdList2 = (LPITEMIDLIST) lParam2;
430 LISTVIEW_SORT_INFO *pSortInfo = (LPLISTVIEW_SORT_INFO) lpData;
433 bIsFolder1 = _ILIsFolder(pItemIdList1);
434 bIsFolder2 = _ILIsFolder(pItemIdList2);
435 bIsBothFolder = bIsFolder1 && bIsFolder2;
437 /* When sorting between a File and a Folder, the Folder gets sorted first */
438 if( (bIsFolder1 || bIsFolder2) && !bIsBothFolder)
440 nDiff = bIsFolder1 ? -1 : 1;
442 else
444 /* Sort by Time: Folders or Files can be sorted */
446 if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TIME)
448 _ILGetFileDateTime(pItemIdList1, &fd1);
449 _ILGetFileDateTime(pItemIdList2, &fd2);
450 nDiff = CompareFileTime(&fd2, &fd1);
452 /* Sort by Attribute: Folder or Files can be sorted */
453 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_ATTRIB)
455 _ILGetFileAttributes(pItemIdList1, strName1, MAX_PATH);
456 _ILGetFileAttributes(pItemIdList2, strName2, MAX_PATH);
457 nDiff = lstrcmpiA(strName1, strName2);
459 /* Sort by FileName: Folder or Files can be sorted */
460 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_NAME || bIsBothFolder)
462 /* Sort by Text */
463 _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
464 _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
465 nDiff = lstrcmpiA(strName1, strName2);
467 /* Sort by File Size, Only valid for Files */
468 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_SIZE)
470 nDiff = (INT)(_ILGetFileSize(pItemIdList1, NULL, 0) - _ILGetFileSize(pItemIdList2, NULL, 0));
472 /* Sort by File Type, Only valid for Files */
473 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TYPE)
475 /* Sort by Type */
476 _ILGetFileType(pItemIdList1, strName1, MAX_PATH);
477 _ILGetFileType(pItemIdList2, strName2, MAX_PATH);
478 nDiff = lstrcmpiA(strName1, strName2);
481 /* If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
483 if(nDiff == 0)
485 _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
486 _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
487 nDiff = lstrcmpiA(strName1, strName2);
490 if(!pSortInfo->bIsAscending)
492 nDiff = -nDiff;
495 return nDiff;
499 /**********************************************************
500 * LV_FindItemByPidl()
502 static int LV_FindItemByPidl(
503 IShellViewImpl * This,
504 LPCITEMIDLIST pidl)
506 LVITEMA lvItem;
507 ZeroMemory(&lvItem, sizeof(LVITEMA));
508 lvItem.mask = LVIF_PARAM;
509 for(lvItem.iItem = 0; ListView_GetItemA(This->hWndList, &lvItem); lvItem.iItem++)
511 LPITEMIDLIST currentpidl = (LPITEMIDLIST) lvItem.lParam;
512 HRESULT hr = IShellFolder_CompareIDs(This->pSFParent, 0, pidl, currentpidl);
513 if(SUCCEEDED(hr) && !HRESULT_CODE(hr))
515 return lvItem.iItem;
518 return -1;
521 /**********************************************************
522 * LV_AddItem()
524 static BOOLEAN LV_AddItem(IShellViewImpl * This, LPCITEMIDLIST pidl)
526 LVITEMA lvItem;
528 TRACE("(%p)(pidl=%p)\n", This, pidl);
530 ZeroMemory(&lvItem, sizeof(lvItem)); /* create the listview item*/
531 lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; /*set the mask*/
532 lvItem.iItem = ListView_GetItemCount(This->hWndList); /*add the item to the end of the list*/
533 lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidl)); /*set the item's data*/
534 lvItem.pszText = LPSTR_TEXTCALLBACKA; /*get text on a callback basis*/
535 lvItem.iImage = I_IMAGECALLBACK; /*get the image on a callback basis*/
536 return (-1==ListView_InsertItemA(This->hWndList, &lvItem))? FALSE: TRUE;
539 /**********************************************************
540 * LV_DeleteItem()
542 static BOOLEAN LV_DeleteItem(IShellViewImpl * This, LPCITEMIDLIST pidl)
544 int nIndex;
546 TRACE("(%p)(pidl=%p)\n", This, pidl);
548 nIndex = LV_FindItemByPidl(This, ILFindLastID(pidl));
549 return (-1==ListView_DeleteItem(This->hWndList, nIndex))? FALSE: TRUE;
552 /**********************************************************
553 * LV_RenameItem()
555 static BOOLEAN LV_RenameItem(IShellViewImpl * This, LPCITEMIDLIST pidlOld, LPCITEMIDLIST pidlNew )
557 int nItem;
558 LVITEMA lvItem;
560 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", This, pidlOld, pidlNew);
562 nItem = LV_FindItemByPidl(This, ILFindLastID(pidlOld));
563 if ( -1 != nItem )
565 ZeroMemory(&lvItem, sizeof(lvItem)); /* create the listview item*/
566 lvItem.mask = LVIF_PARAM; /* only the pidl */
567 lvItem.iItem = nItem;
568 ListView_GetItemA(This->hWndList, &lvItem);
570 SHFree((LPITEMIDLIST)lvItem.lParam);
571 lvItem.mask = LVIF_PARAM;
572 lvItem.iItem = nItem;
573 lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidlNew)); /* set the item's data */
574 ListView_SetItemA(This->hWndList, &lvItem);
575 ListView_Update(This->hWndList, nItem);
576 return TRUE; /* FIXME: better handling */
578 return FALSE;
580 /**********************************************************
581 * ShellView_FillList()
583 * - gets the objectlist from the shellfolder
584 * - sorts the list
585 * - fills the list into the view
588 static INT CALLBACK fill_list( LPVOID ptr, LPVOID arg )
590 LPITEMIDLIST pidl = ptr;
591 IShellViewImpl *This = arg;
592 /* in a commdlg This works as a filemask*/
593 if ( IncludeObject(This, pidl)==S_OK ) LV_AddItem(This, pidl);
594 SHFree(pidl);
595 return TRUE;
598 static HRESULT ShellView_FillList(IShellViewImpl * This)
600 LPENUMIDLIST pEnumIDList;
601 LPITEMIDLIST pidl;
602 DWORD dwFetched;
603 HRESULT hRes;
604 HDPA hdpa;
606 TRACE("%p\n",This);
608 /* get the itemlist from the shfolder*/
609 hRes = IShellFolder_EnumObjects(This->pSFParent,This->hWnd, SHCONTF_NONFOLDERS | SHCONTF_FOLDERS, &pEnumIDList);
610 if (hRes != S_OK)
612 if (hRes==S_FALSE)
613 return(NOERROR);
614 return(hRes);
617 /* create a pointer array */
618 hdpa = DPA_Create(16);
619 if (!hdpa)
621 return(E_OUTOFMEMORY);
624 /* copy the items into the array*/
625 while((S_OK == IEnumIDList_Next(pEnumIDList,1, &pidl, &dwFetched)) && dwFetched)
627 if (DPA_InsertPtr(hdpa, 0x7fff, pidl) == -1)
629 SHFree(pidl);
633 /* sort the array */
634 DPA_Sort(hdpa, ShellView_CompareItems, (LPARAM)This->pSFParent);
636 /*turn the listview's redrawing off*/
637 SendMessageA(This->hWndList, WM_SETREDRAW, FALSE, 0);
639 DPA_DestroyCallback( hdpa, fill_list, This );
641 /*turn the listview's redrawing back on and force it to draw*/
642 SendMessageA(This->hWndList, WM_SETREDRAW, TRUE, 0);
644 IEnumIDList_Release(pEnumIDList); /* destroy the list*/
646 return S_OK;
649 /**********************************************************
650 * ShellView_OnCreate()
652 static LRESULT ShellView_OnCreate(IShellViewImpl * This)
654 IDropTarget* pdt;
655 SHChangeNotifyEntry ntreg;
656 IPersistFolder2 * ppf2 = NULL;
658 TRACE("%p\n",This);
660 if(ShellView_CreateList(This))
662 if(ShellView_InitList(This))
664 ShellView_FillList(This);
668 if (SUCCEEDED(IShellFolder_CreateViewObject(This->pSFParent, This->hWnd, &IID_IDropTarget, (LPVOID*)&pdt)))
670 RegisterDragDrop(This->hWnd, pdt);
671 IDropTarget_Release(pdt);
674 /* register for receiving notifications */
675 IShellFolder_QueryInterface(This->pSFParent, &IID_IPersistFolder2, (LPVOID*)&ppf2);
676 if (ppf2)
678 IPersistFolder2_GetCurFolder(ppf2, (LPITEMIDLIST*)&ntreg.pidl);
679 ntreg.fRecursive = TRUE;
680 This->hNotify = SHChangeNotifyRegister(This->hWnd, SHCNF_IDLIST, SHCNE_ALLEVENTS, SHV_CHANGE_NOTIFY, 1, &ntreg);
681 SHFree((LPITEMIDLIST)ntreg.pidl);
682 IPersistFolder2_Release(ppf2);
685 This->hAccel = LoadAcceleratorsA(shell32_hInstance, "shv_accel");
687 return S_OK;
690 /**********************************************************
691 * #### Handling of the menus ####
694 /**********************************************************
695 * ShellView_BuildFileMenu()
697 static HMENU ShellView_BuildFileMenu(IShellViewImpl * This)
698 { CHAR szText[MAX_PATH];
699 MENUITEMINFOA mii;
700 int nTools,i;
701 HMENU hSubMenu;
703 TRACE("(%p)\n",This);
705 hSubMenu = CreatePopupMenu();
706 if(hSubMenu)
707 { /*get the number of items in our global array*/
708 for(nTools = 0; Tools[nTools].idCommand != -1; nTools++){}
710 /*add the menu items*/
711 for(i = 0; i < nTools; i++)
713 LoadStringA(shell32_hInstance, Tools[i].idMenuString, szText, MAX_PATH);
715 ZeroMemory(&mii, sizeof(mii));
716 mii.cbSize = sizeof(mii);
717 mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
719 if(BTNS_SEP != Tools[i].bStyle) /* no separator*/
721 mii.fType = MFT_STRING;
722 mii.fState = MFS_ENABLED;
723 mii.dwTypeData = szText;
724 mii.wID = Tools[i].idCommand;
726 else
728 mii.fType = MFT_SEPARATOR;
730 /* tack This item onto the end of the menu */
731 InsertMenuItemA(hSubMenu, (UINT)-1, TRUE, &mii);
734 TRACE("-- return (menu=%p)\n",hSubMenu);
735 return hSubMenu;
737 /**********************************************************
738 * ShellView_MergeFileMenu()
740 static void ShellView_MergeFileMenu(IShellViewImpl * This, HMENU hSubMenu)
741 { TRACE("(%p)->(submenu=%p) stub\n",This,hSubMenu);
743 if(hSubMenu)
744 { /*insert This item at the beginning of the menu */
745 _InsertMenuItem(hSubMenu, 0, TRUE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
746 _InsertMenuItem(hSubMenu, 0, TRUE, IDM_MYFILEITEM, MFT_STRING, "dummy45", MFS_ENABLED);
749 TRACE("--\n");
752 /**********************************************************
753 * ShellView_MergeViewMenu()
756 static void ShellView_MergeViewMenu(IShellViewImpl * This, HMENU hSubMenu)
757 { MENUITEMINFOA mii;
759 TRACE("(%p)->(submenu=%p)\n",This,hSubMenu);
761 if(hSubMenu)
762 { /*add a separator at the correct position in the menu*/
763 _InsertMenuItem(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
765 ZeroMemory(&mii, sizeof(mii));
766 mii.cbSize = sizeof(mii);
767 mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_DATA;
768 mii.fType = MFT_STRING;
769 mii.dwTypeData = "View";
770 mii.hSubMenu = LoadMenuA(shell32_hInstance, "MENU_001");
771 InsertMenuItemA(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
775 /**********************************************************
776 * ShellView_GetSelections()
778 * - fills the this->apidl list with the selected objects
780 * RETURNS
781 * number of selected items
783 static UINT ShellView_GetSelections(IShellViewImpl * This)
785 LVITEMA lvItem;
786 UINT i = 0;
788 if (This->apidl)
790 SHFree(This->apidl);
793 This->cidl = ListView_GetSelectedCount(This->hWndList);
794 This->apidl = (LPITEMIDLIST*)SHAlloc(This->cidl * sizeof(LPITEMIDLIST));
796 TRACE("selected=%i\n", This->cidl);
798 if(This->apidl)
800 TRACE("-- Items selected =%u\n", This->cidl);
802 ZeroMemory(&lvItem, sizeof(lvItem));
803 lvItem.mask = LVIF_STATE | LVIF_PARAM;
804 lvItem.stateMask = LVIS_SELECTED;
806 while(ListView_GetItemA(This->hWndList, &lvItem) && (i < This->cidl))
808 if(lvItem.state & LVIS_SELECTED)
810 This->apidl[i] = (LPITEMIDLIST)lvItem.lParam;
811 i++;
812 TRACE("-- selected Item found\n");
814 lvItem.iItem++;
817 return This->cidl;
821 /**********************************************************
822 * ShellView_OpenSelectedItems()
824 static HRESULT ShellView_OpenSelectedItems(IShellViewImpl * This)
826 static UINT CF_IDLIST = 0;
827 HRESULT hr;
828 IDataObject* selection;
829 FORMATETC fetc;
830 STGMEDIUM stgm;
831 LPIDA pIDList;
832 LPCITEMIDLIST parent_pidl;
833 int i;
835 if (0 == ShellView_GetSelections(This))
837 return S_OK;
839 hr = IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl,
840 (LPCITEMIDLIST*)This->apidl, &IID_IDataObject,
841 0, (LPVOID *)&selection);
842 if (FAILED(hr))
843 return hr;
845 if (0 == CF_IDLIST)
847 CF_IDLIST = RegisterClipboardFormatA(CFSTR_SHELLIDLIST);
849 fetc.cfFormat = CF_IDLIST;
850 fetc.ptd = NULL;
851 fetc.dwAspect = DVASPECT_CONTENT;
852 fetc.lindex = -1;
853 fetc.tymed = TYMED_HGLOBAL;
855 hr = IDataObject_QueryGetData(selection, &fetc);
856 if (FAILED(hr))
857 return hr;
859 hr = IDataObject_GetData(selection, &fetc, &stgm);
860 if (FAILED(hr))
861 return hr;
863 pIDList = GlobalLock(stgm.u.hGlobal);
865 parent_pidl = (LPCITEMIDLIST) ((LPBYTE)pIDList+pIDList->aoffset[0]);
866 for (i = pIDList->cidl; i > 0; --i)
868 LPCITEMIDLIST pidl;
869 SFGAOF attribs;
871 pidl = (LPCITEMIDLIST)((LPBYTE)pIDList+pIDList->aoffset[i]);
873 attribs = SFGAO_FOLDER;
874 hr = IShellFolder_GetAttributesOf(This->pSFParent, 1, &pidl, &attribs);
876 if (SUCCEEDED(hr) && ! (attribs & SFGAO_FOLDER))
878 SHELLEXECUTEINFOA shexinfo;
880 shexinfo.cbSize = sizeof(SHELLEXECUTEINFOA);
881 shexinfo.fMask = SEE_MASK_INVOKEIDLIST; /* SEE_MASK_IDLIST is also possible. */
882 shexinfo.hwnd = NULL;
883 shexinfo.lpVerb = NULL;
884 shexinfo.lpFile = NULL;
885 shexinfo.lpParameters = NULL;
886 shexinfo.lpDirectory = NULL;
887 shexinfo.nShow = SW_NORMAL;
888 shexinfo.lpIDList = ILCombine(parent_pidl, pidl);
890 ShellExecuteExA(&shexinfo); /* Discard error/success info */
892 ILFree((LPITEMIDLIST)shexinfo.lpIDList);
896 GlobalUnlock(stgm.u.hGlobal);
897 ReleaseStgMedium(&stgm);
899 IDataObject_Release(selection);
901 return S_OK;
904 /**********************************************************
905 * ShellView_DoContextMenu()
907 static void ShellView_DoContextMenu(IShellViewImpl * This, WORD x, WORD y, BOOL bDefault)
908 { UINT uCommand;
909 DWORD wFlags;
910 HMENU hMenu;
911 BOOL fExplore = FALSE;
912 HWND hwndTree = 0;
913 LPCONTEXTMENU pContextMenu = NULL;
914 IContextMenu2 *pCM = NULL;
915 CMINVOKECOMMANDINFO cmi;
917 TRACE("(%p)->(0x%08x 0x%08x 0x%08x) stub\n",This, x, y, bDefault);
919 /* look, what's selected and create a context menu object of it*/
920 if( ShellView_GetSelections(This) )
922 IShellFolder_GetUIObjectOf( This->pSFParent, This->hWndParent, This->cidl, (LPCITEMIDLIST*)This->apidl,
923 (REFIID)&IID_IContextMenu, NULL, (LPVOID *)&pContextMenu);
925 if(pContextMenu)
927 TRACE("-- pContextMenu\n");
928 hMenu = CreatePopupMenu();
930 if( hMenu )
932 /* See if we are in Explore or Open mode. If the browser's tree is present, we are in Explore mode.*/
933 if(SUCCEEDED(IShellBrowser_GetControlWindow(This->pShellBrowser,FCW_TREE, &hwndTree)) && hwndTree)
935 TRACE("-- explore mode\n");
936 fExplore = TRUE;
939 /* build the flags depending on what we can do with the selected item */
940 wFlags = CMF_NORMAL | (This->cidl != 1 ? 0 : CMF_CANRENAME) | (fExplore ? CMF_EXPLORE : 0);
942 /* let the ContextMenu merge its items in */
943 if (SUCCEEDED(IContextMenu_QueryContextMenu( pContextMenu, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, wFlags )))
945 if (This->FolderSettings.fFlags & FWF_DESKTOP)
946 SetMenuDefaultItem(hMenu, FCIDM_SHVIEW_OPEN, MF_BYCOMMAND);
948 if( bDefault )
950 TRACE("-- get menu default command\n");
951 uCommand = GetMenuDefaultItem(hMenu, FALSE, GMDI_GOINTOPOPUPS);
953 else
955 TRACE("-- track popup\n");
956 uCommand = TrackPopupMenu( hMenu,TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
959 if(uCommand > 0)
961 TRACE("-- uCommand=%u\n", uCommand);
962 if (uCommand==FCIDM_SHVIEW_OPEN && IsInCommDlg(This))
964 TRACE("-- dlg: OnDefaultCommand\n");
965 if (OnDefaultCommand(This) != S_OK)
967 ShellView_OpenSelectedItems(This);
970 else
972 TRACE("-- explore -- invoke command\n");
973 ZeroMemory(&cmi, sizeof(cmi));
974 cmi.cbSize = sizeof(cmi);
975 cmi.hwnd = This->hWndParent; /* this window has to answer CWM_GETISHELLBROWSER */
976 cmi.lpVerb = (LPCSTR)MAKEINTRESOURCEA(uCommand);
977 IContextMenu_InvokeCommand(pContextMenu, &cmi);
980 DestroyMenu(hMenu);
983 if (pContextMenu)
984 IContextMenu_Release(pContextMenu);
987 else /* background context menu */
989 hMenu = CreatePopupMenu();
991 pCM = ISvBgCm_Constructor(This->pSFParent, FALSE);
992 IContextMenu2_QueryContextMenu(pCM, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, 0);
994 uCommand = TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
995 DestroyMenu(hMenu);
997 TRACE("-- (%p)->(uCommand=0x%08x )\n",This, uCommand);
999 ZeroMemory(&cmi, sizeof(cmi));
1000 cmi.cbSize = sizeof(cmi);
1001 cmi.lpVerb = (LPCSTR)MAKEINTRESOURCEA(uCommand);
1002 cmi.hwnd = This->hWndParent;
1003 IContextMenu2_InvokeCommand(pCM, &cmi);
1005 IContextMenu2_Release(pCM);
1009 /**********************************************************
1010 * ##### message handling #####
1013 /**********************************************************
1014 * ShellView_OnSize()
1016 static LRESULT ShellView_OnSize(IShellViewImpl * This, WORD wWidth, WORD wHeight)
1018 TRACE("%p width=%u height=%u\n",This, wWidth,wHeight);
1020 /*resize the ListView to fit our window*/
1021 if(This->hWndList)
1023 MoveWindow(This->hWndList, 0, 0, wWidth, wHeight, TRUE);
1026 return S_OK;
1028 /**********************************************************
1029 * ShellView_OnDeactivate()
1031 * NOTES
1032 * internal
1034 static void ShellView_OnDeactivate(IShellViewImpl * This)
1036 TRACE("%p\n",This);
1038 if(This->uState != SVUIA_DEACTIVATE)
1040 if(This->hMenu)
1042 IShellBrowser_SetMenuSB(This->pShellBrowser,0, 0, 0);
1043 IShellBrowser_RemoveMenusSB(This->pShellBrowser,This->hMenu);
1044 DestroyMenu(This->hMenu);
1045 This->hMenu = 0;
1048 This->uState = SVUIA_DEACTIVATE;
1052 /**********************************************************
1053 * ShellView_OnActivate()
1055 static LRESULT ShellView_OnActivate(IShellViewImpl * This, UINT uState)
1056 { OLEMENUGROUPWIDTHS omw = { {0, 0, 0, 0, 0, 0} };
1057 MENUITEMINFOA mii;
1058 CHAR szText[MAX_PATH];
1060 TRACE("%p uState=%x\n",This,uState);
1062 /*don't do anything if the state isn't really changing */
1063 if(This->uState == uState)
1065 return S_OK;
1068 ShellView_OnDeactivate(This);
1070 /*only do This if we are active */
1071 if(uState != SVUIA_DEACTIVATE)
1073 /*merge the menus */
1074 This->hMenu = CreateMenu();
1076 if(This->hMenu)
1078 IShellBrowser_InsertMenusSB(This->pShellBrowser, This->hMenu, &omw);
1079 TRACE("-- after fnInsertMenusSB\n");
1081 /*build the top level menu get the menu item's text*/
1082 strcpy(szText,"dummy 31");
1084 ZeroMemory(&mii, sizeof(mii));
1085 mii.cbSize = sizeof(mii);
1086 mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_STATE;
1087 mii.fType = MFT_STRING;
1088 mii.fState = MFS_ENABLED;
1089 mii.dwTypeData = szText;
1090 mii.hSubMenu = ShellView_BuildFileMenu(This);
1092 /*insert our menu into the menu bar*/
1093 if(mii.hSubMenu)
1095 InsertMenuItemA(This->hMenu, FCIDM_MENU_HELP, FALSE, &mii);
1098 /*get the view menu so we can merge with it*/
1099 ZeroMemory(&mii, sizeof(mii));
1100 mii.cbSize = sizeof(mii);
1101 mii.fMask = MIIM_SUBMENU;
1103 if(GetMenuItemInfoA(This->hMenu, FCIDM_MENU_VIEW, FALSE, &mii))
1105 ShellView_MergeViewMenu(This, mii.hSubMenu);
1108 /*add the items that should only be added if we have the focus*/
1109 if(SVUIA_ACTIVATE_FOCUS == uState)
1111 /*get the file menu so we can merge with it */
1112 ZeroMemory(&mii, sizeof(mii));
1113 mii.cbSize = sizeof(mii);
1114 mii.fMask = MIIM_SUBMENU;
1116 if(GetMenuItemInfoA(This->hMenu, FCIDM_MENU_FILE, FALSE, &mii))
1118 ShellView_MergeFileMenu(This, mii.hSubMenu);
1121 TRACE("-- before fnSetMenuSB\n");
1122 IShellBrowser_SetMenuSB(This->pShellBrowser, This->hMenu, 0, This->hWnd);
1125 This->uState = uState;
1126 TRACE("--\n");
1127 return S_OK;
1130 /**********************************************************
1131 * ShellView_OnSetFocus()
1134 static LRESULT ShellView_OnSetFocus(IShellViewImpl * This)
1136 TRACE("%p\n",This);
1138 /* Tell the browser one of our windows has received the focus. This
1139 should always be done before merging menus (OnActivate merges the
1140 menus) if one of our windows has the focus.*/
1142 IShellBrowser_OnViewWindowActive(This->pShellBrowser,(IShellView*) This);
1143 ShellView_OnActivate(This, SVUIA_ACTIVATE_FOCUS);
1145 /* Set the focus to the listview */
1146 SetFocus(This->hWndList);
1148 /* Notify the ICommDlgBrowser interface */
1149 OnStateChange(This,CDBOSC_SETFOCUS);
1151 return 0;
1154 /**********************************************************
1155 * ShellView_OnKillFocus()
1157 static LRESULT ShellView_OnKillFocus(IShellViewImpl * This)
1159 TRACE("(%p) stub\n",This);
1161 ShellView_OnActivate(This, SVUIA_ACTIVATE_NOFOCUS);
1162 /* Notify the ICommDlgBrowser */
1163 OnStateChange(This,CDBOSC_KILLFOCUS);
1165 return 0;
1168 /**********************************************************
1169 * ShellView_OnCommand()
1171 * NOTES
1172 * the CmdID's are the ones from the context menu
1174 static LRESULT ShellView_OnCommand(IShellViewImpl * This,DWORD dwCmdID, DWORD dwCmd, HWND hwndCmd)
1176 TRACE("(%p)->(0x%08lx 0x%08lx %p) stub\n",This, dwCmdID, dwCmd, hwndCmd);
1178 switch(dwCmdID)
1180 case FCIDM_SHVIEW_SMALLICON:
1181 This->FolderSettings.ViewMode = FVM_SMALLICON;
1182 SetStyle (This, LVS_SMALLICON, LVS_TYPEMASK);
1183 CheckToolbar(This);
1184 break;
1186 case FCIDM_SHVIEW_BIGICON:
1187 This->FolderSettings.ViewMode = FVM_ICON;
1188 SetStyle (This, LVS_ICON, LVS_TYPEMASK);
1189 CheckToolbar(This);
1190 break;
1192 case FCIDM_SHVIEW_LISTVIEW:
1193 This->FolderSettings.ViewMode = FVM_LIST;
1194 SetStyle (This, LVS_LIST, LVS_TYPEMASK);
1195 CheckToolbar(This);
1196 break;
1198 case FCIDM_SHVIEW_REPORTVIEW:
1199 This->FolderSettings.ViewMode = FVM_DETAILS;
1200 SetStyle (This, LVS_REPORT, LVS_TYPEMASK);
1201 CheckToolbar(This);
1202 break;
1204 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1205 case 0x30:
1206 case 0x31:
1207 case 0x32:
1208 case 0x33:
1209 This->ListViewSortInfo.nHeaderID = (LPARAM) (dwCmdID - 0x30);
1210 This->ListViewSortInfo.bIsAscending = TRUE;
1211 This->ListViewSortInfo.nLastHeaderID = This->ListViewSortInfo.nHeaderID;
1212 ListView_SortItems(This->hWndList, ShellView_ListViewCompareItems, (LPARAM) (&(This->ListViewSortInfo)));
1213 break;
1215 default:
1216 TRACE("-- COMMAND 0x%04lx unhandled\n", dwCmdID);
1218 return 0;
1221 /**********************************************************
1222 * ShellView_OnNotify()
1225 static LRESULT ShellView_OnNotify(IShellViewImpl * This, UINT CtlID, LPNMHDR lpnmh)
1226 { LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)lpnmh;
1227 NMLVDISPINFOA *lpdi = (NMLVDISPINFOA *)lpnmh;
1228 LPITEMIDLIST pidl;
1230 TRACE("%p CtlID=%u lpnmh->code=%x\n",This,CtlID,lpnmh->code);
1232 switch(lpnmh->code)
1234 case NM_SETFOCUS:
1235 TRACE("-- NM_SETFOCUS %p\n",This);
1236 ShellView_OnSetFocus(This);
1237 break;
1239 case NM_KILLFOCUS:
1240 TRACE("-- NM_KILLFOCUS %p\n",This);
1241 ShellView_OnDeactivate(This);
1242 /* Notify the ICommDlgBrowser interface */
1243 OnStateChange(This,CDBOSC_KILLFOCUS);
1244 break;
1246 case NM_CUSTOMDRAW:
1247 TRACE("-- NM_CUSTOMDRAW %p\n",This);
1248 return CDRF_DODEFAULT;
1250 case NM_RELEASEDCAPTURE:
1251 TRACE("-- NM_RELEASEDCAPTURE %p\n",This);
1252 break;
1254 case NM_CLICK:
1255 TRACE("-- NM_CLICK %p\n",This);
1256 break;
1258 case NM_RCLICK:
1259 TRACE("-- NM_RCLICK %p\n",This);
1260 break;
1262 case HDN_ENDTRACKA:
1263 TRACE("-- HDN_ENDTRACKA %p\n",This);
1264 /*nColumn1 = ListView_GetColumnWidth(This->hWndList, 0);
1265 nColumn2 = ListView_GetColumnWidth(This->hWndList, 1);*/
1266 break;
1268 case LVN_DELETEITEM:
1269 TRACE("-- LVN_DELETEITEM %p\n",This);
1270 SHFree((LPITEMIDLIST)lpnmlv->lParam); /*delete the pidl because we made a copy of it*/
1271 break;
1273 case LVN_DELETEALLITEMS:
1274 TRACE("-- LVN_DELETEALLITEMS %p\n",This);
1275 return FALSE;
1277 case LVN_INSERTITEM:
1278 TRACE("-- LVN_INSERTITEM (STUB)%p\n",This);
1279 break;
1281 case LVN_ITEMACTIVATE:
1282 TRACE("-- LVN_ITEMACTIVATE %p\n",This);
1283 OnStateChange(This, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
1284 ShellView_DoContextMenu(This, 0, 0, TRUE);
1285 break;
1287 case LVN_COLUMNCLICK:
1288 This->ListViewSortInfo.nHeaderID = lpnmlv->iSubItem;
1289 if(This->ListViewSortInfo.nLastHeaderID == This->ListViewSortInfo.nHeaderID)
1291 This->ListViewSortInfo.bIsAscending = !This->ListViewSortInfo.bIsAscending;
1293 else
1295 This->ListViewSortInfo.bIsAscending = TRUE;
1297 This->ListViewSortInfo.nLastHeaderID = This->ListViewSortInfo.nHeaderID;
1299 ListView_SortItems(lpnmlv->hdr.hwndFrom, ShellView_ListViewCompareItems, (LPARAM) (&(This->ListViewSortInfo)));
1300 break;
1302 case LVN_GETDISPINFOA:
1303 case LVN_GETDISPINFOW:
1304 TRACE("-- LVN_GETDISPINFO %p\n",This);
1305 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1307 if(lpdi->item.mask & LVIF_TEXT) /* text requested */
1309 if (This->pSF2Parent)
1311 SHELLDETAILS sd;
1312 IShellFolder2_GetDetailsOf(This->pSF2Parent, pidl, lpdi->item.iSubItem, &sd);
1313 if (lpnmh->code == LVN_GETDISPINFOA)
1315 StrRetToStrNA( lpdi->item.pszText, lpdi->item.cchTextMax, &sd.str, NULL);
1316 TRACE("-- text=%s\n",lpdi->item.pszText);
1318 else /* LVN_GETDISPINFOW */
1320 StrRetToStrNW( ((NMLVDISPINFOW *)lpdi)->item.pszText, lpdi->item.cchTextMax, &sd.str, NULL);
1321 TRACE("-- text=%s\n",debugstr_w((WCHAR*)(lpdi->item.pszText)));
1324 else
1326 FIXME("no SF2\n");
1329 if(lpdi->item.mask & LVIF_IMAGE) /* image requested */
1331 lpdi->item.iImage = SHMapPIDLToSystemImageListIndex(This->pSFParent, pidl, 0);
1333 break;
1335 case LVN_ITEMCHANGED:
1336 TRACE("-- LVN_ITEMCHANGED %p\n",This);
1337 OnStateChange(This, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
1338 break;
1340 case LVN_BEGINDRAG:
1341 case LVN_BEGINRDRAG:
1342 TRACE("-- LVN_BEGINDRAG\n");
1344 if (ShellView_GetSelections(This))
1346 IDataObject * pda;
1347 DWORD dwAttributes = SFGAO_CANLINK;
1348 DWORD dwEffect = DROPEFFECT_COPY | DROPEFFECT_MOVE;
1350 if (SUCCEEDED(IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, (LPCITEMIDLIST*)This->apidl, &IID_IDataObject,0,(LPVOID *)&pda)))
1352 IDropSource * pds = (IDropSource*)&(This->lpvtblDropSource); /* own DropSource interface */
1354 if (SUCCEEDED(IShellFolder_GetAttributesOf(This->pSFParent, This->cidl, (LPCITEMIDLIST*)This->apidl, &dwAttributes)))
1356 if (dwAttributes & SFGAO_CANLINK)
1358 dwEffect |= DROPEFFECT_LINK;
1362 if (pds)
1364 DWORD dwEffect;
1365 DoDragDrop(pda, pds, dwEffect, &dwEffect);
1367 IDataObject_Release(pda);
1370 break;
1372 case LVN_BEGINLABELEDITA:
1374 DWORD dwAttr = SFGAO_CANRENAME;
1375 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1377 TRACE("-- LVN_BEGINLABELEDITA %p\n",This);
1379 IShellFolder_GetAttributesOf(This->pSFParent, 1, (LPCITEMIDLIST*)&pidl, &dwAttr);
1380 if (SFGAO_CANRENAME & dwAttr)
1382 return FALSE;
1384 return TRUE;
1387 case LVN_ENDLABELEDITA:
1389 TRACE("-- LVN_ENDLABELEDITA %p\n",This);
1390 if (lpdi->item.pszText)
1392 HRESULT hr;
1393 WCHAR wszNewName[MAX_PATH];
1394 LVITEMA lvItem;
1396 ZeroMemory(&lvItem, sizeof(LVITEMA));
1397 lvItem.iItem = lpdi->item.iItem;
1398 lvItem.mask = LVIF_PARAM;
1399 ListView_GetItemA(This->hWndList, &lvItem);
1401 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1402 if (!MultiByteToWideChar( CP_ACP, 0, lpdi->item.pszText, -1, wszNewName, MAX_PATH ))
1403 wszNewName[MAX_PATH-1] = 0;
1404 hr = IShellFolder_SetNameOf(This->pSFParent, 0, pidl, wszNewName, SHGDN_INFOLDER, &pidl);
1406 if(SUCCEEDED(hr) && pidl)
1408 lvItem.mask = LVIF_PARAM;
1409 lvItem.lParam = (LPARAM)pidl;
1410 ListView_SetItemA(This->hWndList, &lvItem);
1411 return TRUE;
1414 return FALSE;
1417 case LVN_KEYDOWN:
1419 /* MSG msg;
1420 msg.hwnd = This->hWnd;
1421 msg.message = WM_KEYDOWN;
1422 msg.wParam = plvKeyDown->wVKey;
1423 msg.lParam = 0;
1424 msg.time = 0;
1425 msg.pt = 0;*/
1427 LPNMLVKEYDOWN plvKeyDown = (LPNMLVKEYDOWN) lpnmh;
1429 /* initiate a rename of the selected file or directory */
1430 if(plvKeyDown->wVKey == VK_F2)
1432 /* see how many files are selected */
1433 int i = ListView_GetSelectedCount(This->hWndList);
1435 /* get selected item */
1436 if(i == 1)
1438 /* get selected item */
1439 i = ListView_GetNextItem(This->hWndList, -1,
1440 LVNI_SELECTED);
1442 ListView_EnsureVisible(This->hWndList, i, 0);
1443 ListView_EditLabelA(This->hWndList, i);
1446 #if 0
1447 TranslateAccelerator(This->hWnd, This->hAccel, &msg)
1448 #endif
1449 else if(plvKeyDown->wVKey == VK_DELETE)
1451 UINT i;
1452 int item_index;
1453 LVITEMA item;
1454 LPITEMIDLIST* pItems;
1455 ISFHelper *psfhlp;
1457 IShellFolder_QueryInterface(This->pSFParent, &IID_ISFHelper,
1458 (LPVOID*)&psfhlp);
1460 if (psfhlp == NULL)
1461 break;
1463 if(!(i = ListView_GetSelectedCount(This->hWndList)))
1464 break;
1466 /* allocate memory for the pidl array */
1467 pItems = HeapAlloc(GetProcessHeap(), 0,
1468 sizeof(LPITEMIDLIST) * i);
1470 /* retrieve all selected items */
1471 i = 0;
1472 item_index = -1;
1473 while(ListView_GetSelectedCount(This->hWndList) > i)
1475 /* get selected item */
1476 item_index = ListView_GetNextItem(This->hWndList,
1477 item_index, LVNI_SELECTED);
1478 item.iItem = item_index;
1479 item.mask |= LVIF_PARAM;
1480 ListView_GetItemA(This->hWndList, &item);
1482 /* get item pidl */
1483 pItems[i] = (LPITEMIDLIST)item.lParam;
1485 i++;
1488 /* perform the item deletion */
1489 ISFHelper_DeleteItems(psfhlp, i, (LPCITEMIDLIST*)pItems);
1491 /* free pidl array memory */
1492 HeapFree(GetProcessHeap(), 0, pItems);
1494 else
1495 FIXME("LVN_KEYDOWN key=0x%08x\n",plvKeyDown->wVKey);
1497 break;
1499 default:
1500 TRACE("-- %p WM_COMMAND %x unhandled\n", This, lpnmh->code);
1501 break;
1503 return 0;
1506 /**********************************************************
1507 * ShellView_OnChange()
1510 static LRESULT ShellView_OnChange(IShellViewImpl * This, LPITEMIDLIST * Pidls, LONG wEventId)
1513 TRACE("(%p)(%p,%p,0x%08lx)\n", This, Pidls[0], Pidls[1], wEventId);
1514 switch(wEventId)
1516 case SHCNE_MKDIR:
1517 case SHCNE_CREATE:
1518 LV_AddItem(This, Pidls[0]);
1519 break;
1520 case SHCNE_RMDIR:
1521 case SHCNE_DELETE:
1522 LV_DeleteItem(This, Pidls[0]);
1523 break;
1524 case SHCNE_RENAMEFOLDER:
1525 case SHCNE_RENAMEITEM:
1526 LV_RenameItem(This, Pidls[0], Pidls[1]);
1527 break;
1528 case SHCNE_UPDATEITEM:
1529 break;
1531 return TRUE;
1533 /**********************************************************
1534 * ShellView_WndProc
1537 static LRESULT CALLBACK ShellView_WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
1539 IShellViewImpl * pThis = (IShellViewImpl*)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
1540 LPCREATESTRUCTA lpcs;
1542 TRACE("(hwnd=%p msg=%x wparm=%x lparm=%lx)\n",hWnd, uMessage, wParam, lParam);
1544 switch (uMessage)
1546 case WM_NCCREATE:
1547 lpcs = (LPCREATESTRUCTA)lParam;
1548 pThis = (IShellViewImpl*)(lpcs->lpCreateParams);
1549 SetWindowLongPtrW(hWnd, GWLP_USERDATA, (ULONG_PTR)pThis);
1550 pThis->hWnd = hWnd; /*set the window handle*/
1551 break;
1553 case WM_SIZE: return ShellView_OnSize(pThis,LOWORD(lParam), HIWORD(lParam));
1554 case WM_SETFOCUS: return ShellView_OnSetFocus(pThis);
1555 case WM_KILLFOCUS: return ShellView_OnKillFocus(pThis);
1556 case WM_CREATE: return ShellView_OnCreate(pThis);
1557 case WM_ACTIVATE: return ShellView_OnActivate(pThis, SVUIA_ACTIVATE_FOCUS);
1558 case WM_NOTIFY: return ShellView_OnNotify(pThis,(UINT)wParam, (LPNMHDR)lParam);
1559 case WM_COMMAND: return ShellView_OnCommand(pThis,
1560 GET_WM_COMMAND_ID(wParam, lParam),
1561 GET_WM_COMMAND_CMD(wParam, lParam),
1562 GET_WM_COMMAND_HWND(wParam, lParam));
1563 case SHV_CHANGE_NOTIFY: return ShellView_OnChange(pThis, (LPITEMIDLIST*)wParam, (LONG)lParam);
1565 case WM_CONTEXTMENU: ShellView_DoContextMenu(pThis, LOWORD(lParam), HIWORD(lParam), FALSE);
1566 return 0;
1568 case WM_SHOWWINDOW: UpdateWindow(pThis->hWndList);
1569 break;
1571 case WM_GETDLGCODE: return SendMessageA(pThis->hWndList,uMessage,0,0);
1573 case WM_DESTROY:
1574 RevokeDragDrop(pThis->hWnd);
1575 SHChangeNotifyDeregister(pThis->hNotify);
1576 break;
1578 case WM_ERASEBKGND:
1579 if ((pThis->FolderSettings.fFlags & FWF_DESKTOP) ||
1580 (pThis->FolderSettings.fFlags & FWF_TRANSPARENT))
1581 return 1;
1582 break;
1585 return DefWindowProcA (hWnd, uMessage, wParam, lParam);
1587 /**********************************************************
1590 * The INTERFACE of the IShellView object
1593 **********************************************************
1594 * IShellView_QueryInterface
1596 static HRESULT WINAPI IShellView_fnQueryInterface(IShellView * iface,REFIID riid, LPVOID *ppvObj)
1598 IShellViewImpl *This = (IShellViewImpl *)iface;
1600 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1602 *ppvObj = NULL;
1604 if(IsEqualIID(riid, &IID_IUnknown))
1606 *ppvObj = This;
1608 else if(IsEqualIID(riid, &IID_IShellView))
1610 *ppvObj = (IShellView*)This;
1612 else if(IsEqualIID(riid, &IID_IOleCommandTarget))
1614 *ppvObj = (IOleCommandTarget*)&(This->lpvtblOleCommandTarget);
1616 else if(IsEqualIID(riid, &IID_IDropTarget))
1618 *ppvObj = (IDropTarget*)&(This->lpvtblDropTarget);
1620 else if(IsEqualIID(riid, &IID_IDropSource))
1622 *ppvObj = (IDropSource*)&(This->lpvtblDropSource);
1624 else if(IsEqualIID(riid, &IID_IViewObject))
1626 *ppvObj = (IViewObject*)&(This->lpvtblViewObject);
1629 if(*ppvObj)
1631 IUnknown_AddRef( (IUnknown*)*ppvObj );
1632 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1633 return S_OK;
1635 TRACE("-- Interface: E_NOINTERFACE\n");
1636 return E_NOINTERFACE;
1639 /**********************************************************
1640 * IShellView_AddRef
1642 static ULONG WINAPI IShellView_fnAddRef(IShellView * iface)
1644 IShellViewImpl *This = (IShellViewImpl *)iface;
1645 ULONG refCount = InterlockedIncrement(&This->ref);
1647 TRACE("(%p)->(count=%lu)\n", This, refCount - 1);
1649 return refCount;
1651 /**********************************************************
1652 * IShellView_Release
1654 static ULONG WINAPI IShellView_fnRelease(IShellView * iface)
1656 IShellViewImpl *This = (IShellViewImpl *)iface;
1657 ULONG refCount = InterlockedDecrement(&This->ref);
1659 TRACE("(%p)->(count=%li)\n", This, refCount + 1);
1661 if (!refCount)
1663 TRACE(" destroying IShellView(%p)\n",This);
1665 DestroyWindow(This->hWndList);
1667 if(This->pSFParent)
1668 IShellFolder_Release(This->pSFParent);
1670 if(This->pSF2Parent)
1671 IShellFolder2_Release(This->pSF2Parent);
1673 if(This->apidl)
1674 SHFree(This->apidl);
1676 if(This->pAdvSink)
1677 IAdviseSink_Release(This->pAdvSink);
1679 HeapFree(GetProcessHeap(),0,This);
1681 return refCount;
1684 /**********************************************************
1685 * ShellView_GetWindow
1687 static HRESULT WINAPI IShellView_fnGetWindow(IShellView * iface,HWND * phWnd)
1689 IShellViewImpl *This = (IShellViewImpl *)iface;
1691 TRACE("(%p)\n",This);
1693 *phWnd = This->hWnd;
1695 return S_OK;
1698 static HRESULT WINAPI IShellView_fnContextSensitiveHelp(IShellView * iface,BOOL fEnterMode)
1700 IShellViewImpl *This = (IShellViewImpl *)iface;
1702 FIXME("(%p) stub\n",This);
1704 return E_NOTIMPL;
1707 /**********************************************************
1708 * IShellView_TranslateAccelerator
1710 * FIXME:
1711 * use the accel functions
1713 static HRESULT WINAPI IShellView_fnTranslateAccelerator(IShellView * iface,LPMSG lpmsg)
1715 #if 0
1716 IShellViewImpl *This = (IShellViewImpl *)iface;
1718 FIXME("(%p)->(%p: hwnd=%x msg=%x lp=%lx wp=%x) stub\n",This,lpmsg, lpmsg->hwnd, lpmsg->message, lpmsg->lParam, lpmsg->wParam);
1719 #endif
1721 if ((lpmsg->message>=WM_KEYFIRST) && (lpmsg->message>=WM_KEYLAST))
1723 TRACE("-- key=0x04%x\n",lpmsg->wParam) ;
1725 return S_FALSE; /* not handled */
1728 static HRESULT WINAPI IShellView_fnEnableModeless(IShellView * iface,BOOL fEnable)
1730 IShellViewImpl *This = (IShellViewImpl *)iface;
1732 FIXME("(%p) stub\n",This);
1734 return E_NOTIMPL;
1737 static HRESULT WINAPI IShellView_fnUIActivate(IShellView * iface,UINT uState)
1739 IShellViewImpl *This = (IShellViewImpl *)iface;
1742 CHAR szName[MAX_PATH];
1744 LRESULT lResult;
1745 int nPartArray[1] = {-1};
1747 TRACE("(%p)->(state=%x) stub\n",This, uState);
1749 /*don't do anything if the state isn't really changing*/
1750 if(This->uState == uState)
1752 return S_OK;
1755 /*OnActivate handles the menu merging and internal state*/
1756 ShellView_OnActivate(This, uState);
1758 /*only do This if we are active*/
1759 if(uState != SVUIA_DEACTIVATE)
1763 GetFolderPath is not a method of IShellFolder
1764 IShellFolder_GetFolderPath( This->pSFParent, szName, sizeof(szName) );
1766 /* set the number of parts */
1767 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETPARTS, 1,
1768 (LPARAM)nPartArray, &lResult);
1770 /* set the text for the parts */
1772 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETTEXTA,
1773 0, (LPARAM)szName, &lResult);
1777 return S_OK;
1780 static HRESULT WINAPI IShellView_fnRefresh(IShellView * iface)
1782 IShellViewImpl *This = (IShellViewImpl *)iface;
1784 TRACE("(%p)\n",This);
1786 ListView_DeleteAllItems(This->hWndList);
1787 ShellView_FillList(This);
1789 return S_OK;
1792 static HRESULT WINAPI IShellView_fnCreateViewWindow(
1793 IShellView * iface,
1794 IShellView *lpPrevView,
1795 LPCFOLDERSETTINGS lpfs,
1796 IShellBrowser * psb,
1797 RECT * prcView,
1798 HWND *phWnd)
1800 IShellViewImpl *This = (IShellViewImpl *)iface;
1802 WNDCLASSA wc;
1803 *phWnd = 0;
1806 TRACE("(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n",This, lpPrevView,lpfs, psb, prcView, phWnd);
1807 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);
1809 /*set up the member variables*/
1810 This->pShellBrowser = psb;
1811 This->FolderSettings = *lpfs;
1813 /*get our parent window*/
1814 IShellBrowser_AddRef(This->pShellBrowser);
1815 IShellBrowser_GetWindow(This->pShellBrowser, &(This->hWndParent));
1817 /* try to get the ICommDlgBrowserInterface, adds a reference !!! */
1818 This->pCommDlgBrowser=NULL;
1819 if ( SUCCEEDED (IShellBrowser_QueryInterface( This->pShellBrowser,
1820 (REFIID)&IID_ICommDlgBrowser, (LPVOID*) &This->pCommDlgBrowser)))
1822 TRACE("-- CommDlgBrowser\n");
1825 /*if our window class has not been registered, then do so*/
1826 if(!GetClassInfoA(shell32_hInstance, SV_CLASS_NAME, &wc))
1828 ZeroMemory(&wc, sizeof(wc));
1829 wc.style = CS_HREDRAW | CS_VREDRAW;
1830 wc.lpfnWndProc = ShellView_WndProc;
1831 wc.cbClsExtra = 0;
1832 wc.cbWndExtra = 0;
1833 wc.hInstance = shell32_hInstance;
1834 wc.hIcon = 0;
1835 wc.hCursor = LoadCursorA (0, (LPSTR)IDC_ARROW);
1836 wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
1837 wc.lpszMenuName = NULL;
1838 wc.lpszClassName = SV_CLASS_NAME;
1840 if(!RegisterClassA(&wc))
1841 return E_FAIL;
1844 *phWnd = CreateWindowExA(0,
1845 SV_CLASS_NAME,
1846 NULL,
1847 WS_CHILD | WS_VISIBLE | WS_TABSTOP,
1848 prcView->left,
1849 prcView->top,
1850 prcView->right - prcView->left,
1851 prcView->bottom - prcView->top,
1852 This->hWndParent,
1854 shell32_hInstance,
1855 (LPVOID)This);
1857 CheckToolbar(This);
1859 if(!*phWnd) return E_FAIL;
1861 return S_OK;
1864 static HRESULT WINAPI IShellView_fnDestroyViewWindow(IShellView * iface)
1866 IShellViewImpl *This = (IShellViewImpl *)iface;
1868 TRACE("(%p)\n",This);
1870 /*Make absolutely sure all our UI is cleaned up.*/
1871 IShellView_UIActivate((IShellView*)This, SVUIA_DEACTIVATE);
1873 if(This->hMenu)
1875 DestroyMenu(This->hMenu);
1878 DestroyWindow(This->hWnd);
1879 if(This->pShellBrowser) IShellBrowser_Release(This->pShellBrowser);
1880 if(This->pCommDlgBrowser) ICommDlgBrowser_Release(This->pCommDlgBrowser);
1883 return S_OK;
1886 static HRESULT WINAPI IShellView_fnGetCurrentInfo(IShellView * iface, LPFOLDERSETTINGS lpfs)
1888 IShellViewImpl *This = (IShellViewImpl *)iface;
1890 TRACE("(%p)->(%p) vmode=%x flags=%x\n",This, lpfs,
1891 This->FolderSettings.ViewMode, This->FolderSettings.fFlags);
1893 if (!lpfs) return E_INVALIDARG;
1895 *lpfs = This->FolderSettings;
1896 return NOERROR;
1899 static HRESULT WINAPI IShellView_fnAddPropertySheetPages(IShellView * iface, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam)
1901 IShellViewImpl *This = (IShellViewImpl *)iface;
1903 FIXME("(%p) stub\n",This);
1905 return E_NOTIMPL;
1908 static HRESULT WINAPI IShellView_fnSaveViewState(IShellView * iface)
1910 IShellViewImpl *This = (IShellViewImpl *)iface;
1912 FIXME("(%p) stub\n",This);
1914 return S_OK;
1917 static HRESULT WINAPI IShellView_fnSelectItem(
1918 IShellView * iface,
1919 LPCITEMIDLIST pidl,
1920 UINT uFlags)
1922 IShellViewImpl *This = (IShellViewImpl *)iface;
1923 int i;
1925 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n",This, pidl, uFlags);
1927 i = LV_FindItemByPidl(This, pidl);
1929 if (i != -1)
1931 LVITEMA lvItem;
1933 if(uFlags & SVSI_ENSUREVISIBLE)
1934 ListView_EnsureVisible(This->hWndList, i, 0);
1936 ZeroMemory(&lvItem, sizeof(LVITEMA));
1937 lvItem.mask = LVIF_STATE;
1938 lvItem.iItem = 0;
1940 while(ListView_GetItemA(This->hWndList, &lvItem))
1942 if (lvItem.iItem == i)
1944 if (uFlags & SVSI_SELECT)
1945 lvItem.state |= LVIS_SELECTED;
1946 else
1947 lvItem.state &= ~LVIS_SELECTED;
1949 if(uFlags & SVSI_FOCUSED)
1950 lvItem.state &= ~LVIS_FOCUSED;
1952 else
1954 if (uFlags & SVSI_DESELECTOTHERS)
1955 lvItem.state &= ~LVIS_SELECTED;
1957 ListView_SetItemA(This->hWndList, &lvItem);
1958 lvItem.iItem++;
1962 if(uFlags & SVSI_EDIT)
1963 ListView_EditLabelA(This->hWndList, i);
1966 return S_OK;
1969 static HRESULT WINAPI IShellView_fnGetItemObject(IShellView * iface, UINT uItem, REFIID riid, LPVOID *ppvOut)
1971 IShellViewImpl *This = (IShellViewImpl *)iface;
1973 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n",This, uItem, debugstr_guid(riid), ppvOut);
1975 *ppvOut = NULL;
1977 switch(uItem)
1979 case SVGIO_BACKGROUND:
1980 *ppvOut = ISvBgCm_Constructor(This->pSFParent, FALSE);
1981 break;
1983 case SVGIO_SELECTION:
1984 ShellView_GetSelections(This);
1985 IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, (LPCITEMIDLIST*)This->apidl, riid, 0, ppvOut);
1986 break;
1988 TRACE("-- (%p)->(interface=%p)\n",This, *ppvOut);
1990 if(!*ppvOut) return E_OUTOFMEMORY;
1992 return S_OK;
1995 static struct IShellViewVtbl svvt =
1997 IShellView_fnQueryInterface,
1998 IShellView_fnAddRef,
1999 IShellView_fnRelease,
2000 IShellView_fnGetWindow,
2001 IShellView_fnContextSensitiveHelp,
2002 IShellView_fnTranslateAccelerator,
2003 IShellView_fnEnableModeless,
2004 IShellView_fnUIActivate,
2005 IShellView_fnRefresh,
2006 IShellView_fnCreateViewWindow,
2007 IShellView_fnDestroyViewWindow,
2008 IShellView_fnGetCurrentInfo,
2009 IShellView_fnAddPropertySheetPages,
2010 IShellView_fnSaveViewState,
2011 IShellView_fnSelectItem,
2012 IShellView_fnGetItemObject
2016 /**********************************************************
2017 * ISVOleCmdTarget_QueryInterface (IUnknown)
2019 static HRESULT WINAPI ISVOleCmdTarget_QueryInterface(
2020 IOleCommandTarget * iface,
2021 REFIID iid,
2022 LPVOID* ppvObj)
2024 _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
2026 return IShellFolder_QueryInterface((IShellFolder*)This, iid, ppvObj);
2029 /**********************************************************
2030 * ISVOleCmdTarget_AddRef (IUnknown)
2032 static ULONG WINAPI ISVOleCmdTarget_AddRef(
2033 IOleCommandTarget * iface)
2035 _ICOM_THIS_From_IOleCommandTarget(IShellFolder, iface);
2037 return IShellFolder_AddRef((IShellFolder*)This);
2040 /**********************************************************
2041 * ISVOleCmdTarget_Release (IUnknown)
2043 static ULONG WINAPI ISVOleCmdTarget_Release(
2044 IOleCommandTarget * iface)
2046 _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
2048 return IShellFolder_Release((IShellFolder*)This);
2051 /**********************************************************
2052 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2054 static HRESULT WINAPI ISVOleCmdTarget_QueryStatus(
2055 IOleCommandTarget *iface,
2056 const GUID* pguidCmdGroup,
2057 ULONG cCmds,
2058 OLECMD * prgCmds,
2059 OLECMDTEXT* pCmdText)
2061 UINT i;
2062 _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
2064 FIXME("(%p)->(%p(%s) 0x%08lx %p %p\n",
2065 This, pguidCmdGroup, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText);
2067 if (!prgCmds)
2068 return E_POINTER;
2069 for (i = 0; i < cCmds; i++)
2071 FIXME("\tprgCmds[%d].cmdID = %ld\n", i, prgCmds[i].cmdID);
2072 prgCmds[i].cmdf = 0;
2074 return OLECMDERR_E_UNKNOWNGROUP;
2077 /**********************************************************
2078 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2080 * nCmdID is the OLECMDID_* enumeration
2082 static HRESULT WINAPI ISVOleCmdTarget_Exec(
2083 IOleCommandTarget *iface,
2084 const GUID* pguidCmdGroup,
2085 DWORD nCmdID,
2086 DWORD nCmdexecopt,
2087 VARIANT* pvaIn,
2088 VARIANT* pvaOut)
2090 _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
2092 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08lx Opt:0x%08lx %p %p)\n",
2093 This, debugstr_guid(pguidCmdGroup), nCmdID, nCmdexecopt, pvaIn, pvaOut);
2095 if (IsEqualIID(pguidCmdGroup, &CGID_Explorer) &&
2096 (nCmdID == 0x29) &&
2097 (nCmdexecopt == 4) && pvaOut)
2098 return S_OK;
2099 if (IsEqualIID(pguidCmdGroup, &CGID_ShellDocView) &&
2100 (nCmdID == 9) &&
2101 (nCmdexecopt == 0))
2102 return 1;
2104 return OLECMDERR_E_UNKNOWNGROUP;
2107 static IOleCommandTargetVtbl ctvt =
2109 ISVOleCmdTarget_QueryInterface,
2110 ISVOleCmdTarget_AddRef,
2111 ISVOleCmdTarget_Release,
2112 ISVOleCmdTarget_QueryStatus,
2113 ISVOleCmdTarget_Exec
2116 /**********************************************************
2117 * ISVDropTarget implementation
2120 static HRESULT WINAPI ISVDropTarget_QueryInterface(
2121 IDropTarget *iface,
2122 REFIID riid,
2123 LPVOID *ppvObj)
2125 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2127 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2129 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2132 static ULONG WINAPI ISVDropTarget_AddRef( IDropTarget *iface)
2134 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2136 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2138 return IShellFolder_AddRef((IShellFolder*)This);
2141 static ULONG WINAPI ISVDropTarget_Release( IDropTarget *iface)
2143 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2145 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2147 return IShellFolder_Release((IShellFolder*)This);
2150 static HRESULT WINAPI ISVDropTarget_DragEnter(
2151 IDropTarget *iface,
2152 IDataObject *pDataObject,
2153 DWORD grfKeyState,
2154 POINTL pt,
2155 DWORD *pdwEffect)
2158 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2160 FIXME("Stub: This=%p, DataObject=%p\n",This,pDataObject);
2162 return E_NOTIMPL;
2165 static HRESULT WINAPI ISVDropTarget_DragOver(
2166 IDropTarget *iface,
2167 DWORD grfKeyState,
2168 POINTL pt,
2169 DWORD *pdwEffect)
2171 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2173 FIXME("Stub: This=%p\n",This);
2175 return E_NOTIMPL;
2178 static HRESULT WINAPI ISVDropTarget_DragLeave(
2179 IDropTarget *iface)
2181 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2183 FIXME("Stub: This=%p\n",This);
2185 return E_NOTIMPL;
2188 static HRESULT WINAPI ISVDropTarget_Drop(
2189 IDropTarget *iface,
2190 IDataObject* pDataObject,
2191 DWORD grfKeyState,
2192 POINTL pt,
2193 DWORD *pdwEffect)
2195 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2197 FIXME("Stub: This=%p\n",This);
2199 return E_NOTIMPL;
2202 static struct IDropTargetVtbl dtvt =
2204 ISVDropTarget_QueryInterface,
2205 ISVDropTarget_AddRef,
2206 ISVDropTarget_Release,
2207 ISVDropTarget_DragEnter,
2208 ISVDropTarget_DragOver,
2209 ISVDropTarget_DragLeave,
2210 ISVDropTarget_Drop
2213 /**********************************************************
2214 * ISVDropSource implementation
2217 static HRESULT WINAPI ISVDropSource_QueryInterface(
2218 IDropSource *iface,
2219 REFIID riid,
2220 LPVOID *ppvObj)
2222 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2224 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2226 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2229 static ULONG WINAPI ISVDropSource_AddRef( IDropSource *iface)
2231 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2233 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2235 return IShellFolder_AddRef((IShellFolder*)This);
2238 static ULONG WINAPI ISVDropSource_Release( IDropSource *iface)
2240 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2242 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2244 return IShellFolder_Release((IShellFolder*)This);
2246 static HRESULT WINAPI ISVDropSource_QueryContinueDrag(
2247 IDropSource *iface,
2248 BOOL fEscapePressed,
2249 DWORD grfKeyState)
2251 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2252 TRACE("(%p)\n",This);
2254 if (fEscapePressed)
2255 return DRAGDROP_S_CANCEL;
2256 else if (!(grfKeyState & MK_LBUTTON) && !(grfKeyState & MK_RBUTTON))
2257 return DRAGDROP_S_DROP;
2258 else
2259 return NOERROR;
2262 static HRESULT WINAPI ISVDropSource_GiveFeedback(
2263 IDropSource *iface,
2264 DWORD dwEffect)
2266 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2267 TRACE("(%p)\n",This);
2269 return DRAGDROP_S_USEDEFAULTCURSORS;
2272 static struct IDropSourceVtbl dsvt =
2274 ISVDropSource_QueryInterface,
2275 ISVDropSource_AddRef,
2276 ISVDropSource_Release,
2277 ISVDropSource_QueryContinueDrag,
2278 ISVDropSource_GiveFeedback
2280 /**********************************************************
2281 * ISVViewObject implementation
2284 static HRESULT WINAPI ISVViewObject_QueryInterface(
2285 IViewObject *iface,
2286 REFIID riid,
2287 LPVOID *ppvObj)
2289 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2291 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2293 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2296 static ULONG WINAPI ISVViewObject_AddRef( IViewObject *iface)
2298 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2300 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2302 return IShellFolder_AddRef((IShellFolder*)This);
2305 static ULONG WINAPI ISVViewObject_Release( IViewObject *iface)
2307 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2309 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2311 return IShellFolder_Release((IShellFolder*)This);
2314 static HRESULT WINAPI ISVViewObject_Draw(
2315 IViewObject *iface,
2316 DWORD dwDrawAspect,
2317 LONG lindex,
2318 void* pvAspect,
2319 DVTARGETDEVICE* ptd,
2320 HDC hdcTargetDev,
2321 HDC hdcDraw,
2322 LPCRECTL lprcBounds,
2323 LPCRECTL lprcWBounds,
2324 BOOL (CALLBACK *pfnContinue)(ULONG_PTR dwContinue),
2325 ULONG_PTR dwContinue)
2328 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2330 FIXME("Stub: This=%p\n",This);
2332 return E_NOTIMPL;
2334 static HRESULT WINAPI ISVViewObject_GetColorSet(
2335 IViewObject *iface,
2336 DWORD dwDrawAspect,
2337 LONG lindex,
2338 void *pvAspect,
2339 DVTARGETDEVICE* ptd,
2340 HDC hicTargetDevice,
2341 LOGPALETTE** ppColorSet)
2344 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2346 FIXME("Stub: This=%p\n",This);
2348 return E_NOTIMPL;
2350 static HRESULT WINAPI ISVViewObject_Freeze(
2351 IViewObject *iface,
2352 DWORD dwDrawAspect,
2353 LONG lindex,
2354 void* pvAspect,
2355 DWORD* pdwFreeze)
2358 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2360 FIXME("Stub: This=%p\n",This);
2362 return E_NOTIMPL;
2364 static HRESULT WINAPI ISVViewObject_Unfreeze(
2365 IViewObject *iface,
2366 DWORD dwFreeze)
2369 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2371 FIXME("Stub: This=%p\n",This);
2373 return E_NOTIMPL;
2375 static HRESULT WINAPI ISVViewObject_SetAdvise(
2376 IViewObject *iface,
2377 DWORD aspects,
2378 DWORD advf,
2379 IAdviseSink* pAdvSink)
2382 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2384 FIXME("partial stub: %p %08lx %08lx %p\n",
2385 This, aspects, advf, pAdvSink);
2387 /* FIXME: we set the AdviseSink, but never use it to send any advice */
2388 This->pAdvSink = pAdvSink;
2389 This->dwAspects = aspects;
2390 This->dwAdvf = advf;
2392 return S_OK;
2395 static HRESULT WINAPI ISVViewObject_GetAdvise(
2396 IViewObject *iface,
2397 DWORD* pAspects,
2398 DWORD* pAdvf,
2399 IAdviseSink** ppAdvSink)
2402 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2404 TRACE("This=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n",
2405 This, pAspects, pAdvf, ppAdvSink);
2407 if( ppAdvSink )
2409 IAdviseSink_AddRef( This->pAdvSink );
2410 *ppAdvSink = This->pAdvSink;
2412 if( pAspects )
2413 *pAspects = This->dwAspects;
2414 if( pAdvf )
2415 *pAdvf = This->dwAdvf;
2417 return S_OK;
2421 static struct IViewObjectVtbl vovt =
2423 ISVViewObject_QueryInterface,
2424 ISVViewObject_AddRef,
2425 ISVViewObject_Release,
2426 ISVViewObject_Draw,
2427 ISVViewObject_GetColorSet,
2428 ISVViewObject_Freeze,
2429 ISVViewObject_Unfreeze,
2430 ISVViewObject_SetAdvise,
2431 ISVViewObject_GetAdvise