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