New XP debugging APIs: implemented DebugActiveProcessStop,
[wine] / dlls / shell32 / shlview.c
1 /*
2  *      ShellView
3  *
4  *      Copyright 1998,1999     <juergen.schmied@debitel.net>
5  *
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. 
8  * 
9  * FIXME: The order by part of the background context menu should be
10  * buily according to the columns shown.
11  *
12  * FIXME: Load/Save the view state from/into the stream provied by
13  * the ShellBrowser
14  *
15  * FIXME: CheckToolbar: handle the "new folder" and "folder up" button
16  *
17  * FIXME: ShellView_FillList: consider sort orders
18  *
19  * FIXME: implement the drag and drop in the old (msg-based) way
20  *
21  * FIXME: when the ShellView_WndProc gets a WM_NCDESTROY should we do a
22  * Release() ??? 
23  */
24
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include "windef.h"
29 #include "winerror.h"
30 #include "winnls.h"
31 #include "servprov.h"
32 #include "shlguid.h"
33 #include "shlobj.h"
34 #include "undocshell.h"
35 #include "shresdef.h"
36 #include "debugtools.h"
37
38 #include "docobj.h"
39 #include "pidl.h"
40 #include "shell32_main.h"
41 #include "shellfolder.h"
42
43 DEFAULT_DEBUG_CHANNEL(shell);
44
45 typedef struct
46 {   BOOL    bIsAscending;
47     INT     nHeaderID;
48     INT     nLastHeaderID;
49 }LISTVIEW_SORT_INFO, *LPLISTVIEW_SORT_INFO;
50
51 typedef struct 
52 {       ICOM_VFIELD(IShellView);
53         DWORD           ref;
54         ICOM_VTABLE(IOleCommandTarget)* lpvtblOleCommandTarget;
55         ICOM_VTABLE(IDropTarget)*       lpvtblDropTarget;
56         ICOM_VTABLE(IDropSource)*       lpvtblDropSource;
57         ICOM_VTABLE(IViewObject)*       lpvtblViewObject;
58         IShellFolder*   pSFParent;
59         IShellFolder2*  pSF2Parent;
60         IShellBrowser*  pShellBrowser;
61         ICommDlgBrowser*        pCommDlgBrowser;
62         HWND            hWnd;           /* SHELLDLL_DefView */
63         HWND            hWndList;       /* ListView control */
64         HWND            hWndParent;
65         FOLDERSETTINGS  FolderSettings;
66         HMENU           hMenu;
67         UINT            uState;
68         UINT            cidl;
69         LPITEMIDLIST    *apidl;
70         LISTVIEW_SORT_INFO ListViewSortInfo;
71         HANDLE          hNotify;        /* change notification handle */
72         HANDLE          hAccel;
73 } IShellViewImpl;
74
75 static struct ICOM_VTABLE(IShellView) svvt;
76
77 static struct ICOM_VTABLE(IOleCommandTarget) ctvt;
78 #define _IOleCommandTarget_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblOleCommandTarget))) 
79 #define _ICOM_THIS_From_IOleCommandTarget(class, name) class* This = (class*)(((char*)name)-_IOleCommandTarget_Offset); 
80
81 static struct ICOM_VTABLE(IDropTarget) dtvt;
82 #define _IDropTarget_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblDropTarget))) 
83 #define _ICOM_THIS_From_IDropTarget(class, name) class* This = (class*)(((char*)name)-_IDropTarget_Offset); 
84
85 static struct ICOM_VTABLE(IDropSource) dsvt;
86 #define _IDropSource_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblDropSource))) 
87 #define _ICOM_THIS_From_IDropSource(class, name) class* This = (class*)(((char*)name)-_IDropSource_Offset); 
88
89 static struct ICOM_VTABLE(IViewObject) vovt;
90 #define _IViewObject_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblViewObject))) 
91 #define _ICOM_THIS_From_IViewObject(class, name) class* This = (class*)(((char*)name)-_IViewObject_Offset); 
92
93 /* ListView Header ID's */
94 #define LISTVIEW_COLUMN_NAME 0
95 #define LISTVIEW_COLUMN_SIZE 1
96 #define LISTVIEW_COLUMN_TYPE 2
97 #define LISTVIEW_COLUMN_TIME 3
98 #define LISTVIEW_COLUMN_ATTRIB 4
99
100 /*menu items */
101 #define IDM_VIEW_FILES  (FCIDM_SHVIEWFIRST + 0x500)
102 #define IDM_VIEW_IDW    (FCIDM_SHVIEWFIRST + 0x501)
103 #define IDM_MYFILEITEM  (FCIDM_SHVIEWFIRST + 0x502)
104
105 #define ID_LISTVIEW     2000
106
107 #define SHV_CHANGE_NOTIFY WM_USER + 0x1111
108
109 /*windowsx.h */
110 #define GET_WM_COMMAND_ID(wp, lp)               LOWORD(wp)
111 #define GET_WM_COMMAND_HWND(wp, lp)             (HWND)(lp)
112 #define GET_WM_COMMAND_CMD(wp, lp)              HIWORD(wp)
113
114 extern void WINAPI _InsertMenuItem (HMENU hmenu, UINT indexMenu, BOOL fByPosition, 
115                         UINT wID, UINT fType, LPSTR dwTypeData, UINT fState);
116
117 /*
118   Items merged into the toolbar and and the filemenu
119 */
120 typedef struct
121 {  int   idCommand;
122    int   iImage;
123    int   idButtonString;
124    int   idMenuString;
125    BYTE  bState;
126    BYTE  bStyle;
127 } MYTOOLINFO, *LPMYTOOLINFO;
128
129 MYTOOLINFO Tools[] = 
130 {
131 { FCIDM_SHVIEW_BIGICON,    0, 0, IDS_VIEW_LARGE,   TBSTATE_ENABLED, TBSTYLE_BUTTON },
132 { FCIDM_SHVIEW_SMALLICON,  0, 0, IDS_VIEW_SMALL,   TBSTATE_ENABLED, TBSTYLE_BUTTON },
133 { FCIDM_SHVIEW_LISTVIEW,   0, 0, IDS_VIEW_LIST,    TBSTATE_ENABLED, TBSTYLE_BUTTON },
134 { FCIDM_SHVIEW_REPORTVIEW, 0, 0, IDS_VIEW_DETAILS, TBSTATE_ENABLED, TBSTYLE_BUTTON },
135 { -1, 0, 0, 0, 0, 0}
136 };
137
138 typedef void (CALLBACK *PFNSHGETSETTINGSPROC)(LPSHELLFLAGSTATE lpsfs, DWORD dwMask);
139
140 /**********************************************************
141  *      IShellView_Constructor
142  */
143 IShellView * IShellView_Constructor( IShellFolder * pFolder)
144 {       IShellViewImpl * sv;
145         sv=(IShellViewImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IShellViewImpl));
146         sv->ref=1;
147         ICOM_VTBL(sv)=&svvt;
148         sv->lpvtblOleCommandTarget=&ctvt;
149         sv->lpvtblDropTarget=&dtvt;
150         sv->lpvtblDropSource=&dsvt;
151         sv->lpvtblViewObject=&vovt;
152
153         sv->pSFParent = pFolder;
154         if(pFolder) IShellFolder_AddRef(pFolder);
155         IShellFolder_QueryInterface(sv->pSFParent, &IID_IShellFolder2, (LPVOID*)&sv->pSF2Parent);
156         
157         TRACE("(%p)->(%p)\n",sv, pFolder);
158         shell32_ObjCount++;
159         return (IShellView *) sv;
160 }
161
162 /**********************************************************
163  *
164  * ##### helperfunctions for communication with ICommDlgBrowser #####
165  */
166 static BOOL IsInCommDlg(IShellViewImpl * This)
167 {       return(This->pCommDlgBrowser != NULL);
168 }
169
170 static HRESULT IncludeObject(IShellViewImpl * This, LPCITEMIDLIST pidl)
171 {
172         HRESULT ret = S_OK;
173         
174         if ( IsInCommDlg(This) )
175         {
176           TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl);
177           ret = ICommDlgBrowser_IncludeObject(This->pCommDlgBrowser, (IShellView*)This, pidl);
178           TRACE("--0x%08lx\n", ret);
179         }
180         return ret;
181 }
182
183 static HRESULT OnDefaultCommand(IShellViewImpl * This)
184 {
185         HRESULT ret = S_FALSE;
186         
187         if (IsInCommDlg(This))
188         {
189           TRACE("ICommDlgBrowser::OnDefaultCommand\n");
190           ret = ICommDlgBrowser_OnDefaultCommand(This->pCommDlgBrowser, (IShellView*)This);
191           TRACE("--\n");
192         }
193         return ret;
194 }
195
196 static HRESULT OnStateChange(IShellViewImpl * This, UINT uFlags)
197 {
198         HRESULT ret = S_FALSE;
199
200         if (IsInCommDlg(This))
201         {
202           TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags);
203           ret = ICommDlgBrowser_OnStateChange(This->pCommDlgBrowser, (IShellView*)This, uFlags);
204           TRACE("--\n");
205         }
206         return ret;
207 }
208 /**********************************************************
209  *      set the toolbar of the filedialog buttons
210  *
211  * - activates the buttons from the shellbrowser according to 
212  *   the view state
213  */
214 static void CheckToolbar(IShellViewImpl * This)
215 {
216         LRESULT result;
217
218         TRACE("\n");
219         
220         if (IsInCommDlg(This))
221         {
222           IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
223                 FCIDM_TB_SMALLICON, (This->FolderSettings.ViewMode==FVM_LIST)? TRUE : FALSE, &result);
224           IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
225                 FCIDM_TB_REPORTVIEW, (This->FolderSettings.ViewMode==FVM_DETAILS)? TRUE : FALSE, &result);
226           IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
227                 FCIDM_TB_SMALLICON, TRUE, &result);
228           IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
229                 FCIDM_TB_REPORTVIEW, TRUE, &result);
230         }
231 }
232
233 /**********************************************************
234  *
235  * ##### helperfunctions for initializing the view #####
236  */
237 /**********************************************************
238  *      change the style of the listview control
239  */
240 static void SetStyle(IShellViewImpl * This, DWORD dwAdd, DWORD dwRemove)
241 {
242         DWORD tmpstyle;
243
244         TRACE("(%p)\n", This);
245
246         tmpstyle = GetWindowLongA(This->hWndList, GWL_STYLE);
247         SetWindowLongA(This->hWndList, GWL_STYLE, dwAdd | (tmpstyle & ~dwRemove));
248 }
249
250 /**********************************************************
251 * ShellView_CreateList()
252 *
253 * - creates the list view window
254 */
255 static BOOL ShellView_CreateList (IShellViewImpl * This)
256 {       DWORD dwStyle;
257
258         TRACE("%p\n",This);
259
260         dwStyle = WS_TABSTOP | WS_VISIBLE | WS_CHILDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
261                   LVS_SHAREIMAGELISTS | LVS_EDITLABELS | LVS_ALIGNLEFT | LVS_AUTOARRANGE;
262
263         switch (This->FolderSettings.ViewMode)
264         {
265           case FVM_ICON:        dwStyle |= LVS_ICON;            break;
266           case FVM_DETAILS:     dwStyle |= LVS_REPORT;          break;
267           case FVM_SMALLICON:   dwStyle |= LVS_SMALLICON;       break;
268           case FVM_LIST:        dwStyle |= LVS_LIST;            break;
269           default:              dwStyle |= LVS_LIST;            break;
270         }
271
272         if (This->FolderSettings.fFlags & FWF_AUTOARRANGE)      dwStyle |= LVS_AUTOARRANGE;
273         /*if (This->FolderSettings.fFlags && FWF_DESKTOP); used from explorer*/
274         if (This->FolderSettings.fFlags & FWF_SINGLESEL)        dwStyle |= LVS_SINGLESEL;
275
276         This->hWndList=CreateWindowExA( WS_EX_CLIENTEDGE,
277                                         WC_LISTVIEWA,
278                                         NULL,
279                                         dwStyle,
280                                         0,0,0,0,
281                                         This->hWnd,
282                                         (HMENU)ID_LISTVIEW,
283                                         shell32_hInstance,
284                                         NULL);
285
286         if(!This->hWndList)
287           return FALSE;
288
289         This->ListViewSortInfo.bIsAscending = TRUE;
290         This->ListViewSortInfo.nHeaderID = -1;
291         This->ListViewSortInfo.nLastHeaderID = -1;
292
293         /*  UpdateShellSettings(); */
294         return TRUE;
295 }
296
297 /**********************************************************
298 * ShellView_InitList()
299 *
300 * - adds all needed columns to the shellview
301 */
302 static BOOL ShellView_InitList(IShellViewImpl * This)
303 {
304         LVCOLUMNA       lvColumn;
305         SHELLDETAILS    sd;
306         int     i;
307         char    szTemp[50];
308
309         TRACE("%p\n",This);
310
311         ListView_DeleteAllItems(This->hWndList);
312
313         lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT;
314         lvColumn.pszText = szTemp;
315
316         if (This->pSF2Parent)
317         {
318           for (i=0; 1; i++)
319           {
320             if (!SUCCEEDED(IShellFolder2_GetDetailsOf(This->pSF2Parent, NULL, i, &sd)))
321               break;
322             lvColumn.fmt = sd.fmt;
323             lvColumn.cx = sd.cxChar*8; /* chars->pixel */
324             StrRetToStrNA( szTemp, 50, &sd.str, NULL);
325             ListView_InsertColumnA(This->hWndList, i, &lvColumn);
326           }
327         }
328         else
329         {
330           FIXME("no SF2\n");
331         }
332
333         ListView_SetImageList(This->hWndList, ShellSmallIconList, LVSIL_SMALL);
334         ListView_SetImageList(This->hWndList, ShellBigIconList, LVSIL_NORMAL);
335
336         return TRUE;
337 }
338 /**********************************************************
339 * ShellView_CompareItems() 
340 *
341 * NOTES
342 *  internal, CALLBACK for DSA_Sort
343 */   
344 static INT CALLBACK ShellView_CompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
345 {
346         int ret;
347         TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1, lParam2, (LPVOID) lpData);
348
349         if(!lpData) return 0;
350
351         ret =  (SHORT) SCODE_CODE(IShellFolder_CompareIDs((LPSHELLFOLDER)lpData, 0, (LPITEMIDLIST)lParam1, (LPITEMIDLIST)lParam2));  
352         TRACE("ret=%i\n",ret);
353         return ret;
354 }
355
356 /*************************************************************************
357  * ShellView_ListViewCompareItems
358  *
359  * Compare Function for the Listview (FileOpen Dialog)
360  *
361  * PARAMS
362  *     lParam1       [I] the first ItemIdList to compare with
363  *     lParam2       [I] the second ItemIdList to compare with
364  *     lpData        [I] The column ID for the header Ctrl to process
365  *
366  * RETURNS
367  *     A negative value if the first item should precede the second, 
368  *     a positive value if the first item should follow the second, 
369  *     or zero if the two items are equivalent
370  *
371  * NOTES
372  *      FIXME: function does what ShellView_CompareItems is supposed to do.
373  *      unify it and figure out how to use the undocumented first parameter
374  *      of IShellFolder_CompareIDs to do the job this function does and
375  *      move this code to IShellFolder. 
376  *      make LISTVIEW_SORT_INFO obsolete
377  *      the way this function works is only usable if we had only 
378  *      filesystemfolders  (25/10/99 jsch)
379  */
380 static INT CALLBACK ShellView_ListViewCompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
381 {
382     INT nDiff=0;
383     FILETIME fd1, fd2;
384     char strName1[MAX_PATH], strName2[MAX_PATH];
385     BOOL bIsFolder1, bIsFolder2,bIsBothFolder;
386     LPITEMIDLIST pItemIdList1 = (LPITEMIDLIST) lParam1;
387     LPITEMIDLIST pItemIdList2 = (LPITEMIDLIST) lParam2;
388     LISTVIEW_SORT_INFO *pSortInfo = (LPLISTVIEW_SORT_INFO) lpData;
389
390
391     bIsFolder1 = _ILIsFolder(pItemIdList1);
392     bIsFolder2 = _ILIsFolder(pItemIdList2);
393     bIsBothFolder = bIsFolder1 && bIsFolder2;
394
395     /* When sorting between a File and a Folder, the Folder gets sorted first */
396     if( (bIsFolder1 || bIsFolder2) && !bIsBothFolder)
397     {
398         nDiff = bIsFolder1 ? -1 : 1;
399     }
400     else
401     {   
402         /* Sort by Time: Folders or Files can be sorted */
403  
404         if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TIME)
405         {
406             _ILGetFileDateTime(pItemIdList1, &fd1);
407             _ILGetFileDateTime(pItemIdList2, &fd2);
408             nDiff = CompareFileTime(&fd2, &fd1);
409         }
410         /* Sort by Attribute: Folder or Files can be sorted */
411         else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_ATTRIB)
412         {
413             _ILGetFileAttributes(pItemIdList1, strName1, MAX_PATH);
414             _ILGetFileAttributes(pItemIdList2, strName2, MAX_PATH);
415             nDiff = strcasecmp(strName1, strName2);
416         }
417         /* Sort by FileName: Folder or Files can be sorted */
418         else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_NAME || bIsBothFolder)
419         {
420             /* Sort by Text */
421             _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
422             _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
423             nDiff = strcasecmp(strName1, strName2);
424         }
425         /* Sort by File Size, Only valid for Files */
426         else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_SIZE)
427         {
428             nDiff = (INT)(_ILGetFileSize(pItemIdList1, NULL, 0) - _ILGetFileSize(pItemIdList2, NULL, 0));
429         }
430         /* Sort by File Type, Only valid for Files */
431         else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TYPE)
432         {
433             /* Sort by Type */
434             _ILGetFileType(pItemIdList1, strName1, MAX_PATH);
435             _ILGetFileType(pItemIdList2, strName2, MAX_PATH);
436             nDiff = strcasecmp(strName1, strName2);
437         }
438     }
439     /*  If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
440         
441     if(nDiff == 0)
442     {
443         _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
444         _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
445         nDiff = strcasecmp(strName1, strName2);
446     }
447
448     if(!pSortInfo->bIsAscending)
449     {
450         nDiff = -nDiff;
451     }
452
453     return nDiff;
454
455 }
456
457 /**********************************************************
458 *  LV_FindItemByPidl()
459 */   
460 static int LV_FindItemByPidl(
461         IShellViewImpl * This,
462         LPCITEMIDLIST pidl)
463 {
464         LVITEMA lvItem;
465         ZeroMemory(&lvItem, sizeof(LVITEMA));
466         lvItem.mask = LVIF_PARAM;
467         for(lvItem.iItem = 0; ListView_GetItemA(This->hWndList, &lvItem); lvItem.iItem++)
468         {
469           LPITEMIDLIST currentpidl = (LPITEMIDLIST) lvItem.lParam;
470           HRESULT hr = IShellFolder_CompareIDs(This->pSFParent, 0, pidl, currentpidl);
471           if(SUCCEEDED(hr) && !HRESULT_CODE(hr))
472           {
473             return lvItem.iItem;
474           }
475         }
476         return -1;
477 }
478
479 /**********************************************************
480 * LV_AddItem()
481 */
482 static BOOLEAN LV_AddItem(IShellViewImpl * This, LPCITEMIDLIST pidl)
483 {
484         LVITEMA lvItem;
485
486         TRACE("(%p)(pidl=%p)\n", This, pidl);
487
488         ZeroMemory(&lvItem, sizeof(lvItem));    /* create the listview item*/
489         lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;      /*set the mask*/
490         lvItem.iItem = ListView_GetItemCount(This->hWndList);   /*add the item to the end of the list*/
491         lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidl));                           /*set the item's data*/
492         lvItem.pszText = LPSTR_TEXTCALLBACKA;                   /*get text on a callback basis*/
493         lvItem.iImage = I_IMAGECALLBACK;                        /*get the image on a callback basis*/
494         return (-1==ListView_InsertItemA(This->hWndList, &lvItem))? FALSE: TRUE;
495 }
496
497 /**********************************************************
498 * LV_DeleteItem()
499 */
500 static BOOLEAN LV_DeleteItem(IShellViewImpl * This, LPCITEMIDLIST pidl)
501 {
502         int nIndex;
503
504         TRACE("(%p)(pidl=%p)\n", This, pidl);
505
506         nIndex = LV_FindItemByPidl(This, ILFindLastID(pidl));
507         return (-1==ListView_DeleteItem(This->hWndList, nIndex))? FALSE: TRUE;
508 }
509
510 /**********************************************************
511 * LV_RenameItem()
512 */
513 static BOOLEAN LV_RenameItem(IShellViewImpl * This, LPCITEMIDLIST pidlOld, LPCITEMIDLIST pidlNew )
514 {
515         int nItem;
516         LVITEMA lvItem;
517
518         TRACE("(%p)(pidlold=%p pidlnew=%p)\n", This, pidlOld, pidlNew);
519
520         nItem = LV_FindItemByPidl(This, ILFindLastID(pidlOld));
521         if ( -1 != nItem )
522         {
523           ZeroMemory(&lvItem, sizeof(lvItem));  /* create the listview item*/
524           lvItem.mask = LVIF_PARAM;             /* only the pidl */
525           lvItem.iItem = nItem;
526           ListView_GetItemA(This->hWndList, &lvItem);
527
528           SHFree((LPITEMIDLIST)lvItem.lParam);
529           lvItem.mask = LVIF_PARAM;
530           lvItem.iItem = nItem;
531           lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidlNew));      /* set the item's data */
532           ListView_SetItemA(This->hWndList, &lvItem);
533           ListView_Update(This->hWndList, nItem);
534           return TRUE;                                  /* FIXME: better handling */
535         }
536         return FALSE;
537 }
538 /**********************************************************
539 * ShellView_FillList()
540 *
541 * - gets the objectlist from the shellfolder
542 * - sorts the list
543 * - fills the list into the view
544 */   
545
546 static HRESULT ShellView_FillList(IShellViewImpl * This)
547 {
548         LPENUMIDLIST    pEnumIDList;
549         LPITEMIDLIST    pidl;
550         DWORD           dwFetched;
551         UINT            i;
552         HRESULT         hRes;
553         HDPA            hdpa;
554
555         TRACE("%p\n",This);
556
557         /* get the itemlist from the shfolder*/  
558         hRes = IShellFolder_EnumObjects(This->pSFParent,This->hWnd, SHCONTF_NONFOLDERS | SHCONTF_FOLDERS, &pEnumIDList);
559         if (hRes != S_OK)
560         {
561           if (hRes==S_FALSE)
562             return(NOERROR);
563           return(hRes);
564         }
565
566         /* create a pointer array */    
567         hdpa = pDPA_Create(16);
568         if (!hdpa)
569         {
570           return(E_OUTOFMEMORY);
571         }
572
573         /* copy the items into the array*/
574         while((S_OK == IEnumIDList_Next(pEnumIDList,1, &pidl, &dwFetched)) && dwFetched)
575         {
576           if (pDPA_InsertPtr(hdpa, 0x7fff, pidl) == -1)
577           {
578             SHFree(pidl);
579           } 
580         }
581
582         /* sort the array */
583         pDPA_Sort(hdpa, ShellView_CompareItems, (LPARAM)This->pSFParent);
584
585         /*turn the listview's redrawing off*/
586         SendMessageA(This->hWndList, WM_SETREDRAW, FALSE, 0); 
587
588         for (i=0; i < DPA_GetPtrCount(hdpa); ++i)       /* DPA_GetPtrCount is a macro*/
589         {
590           pidl = (LPITEMIDLIST)pDPA_GetPtr(hdpa, i);
591
592           /* in a commdlg This works as a filemask*/
593           if ( IncludeObject(This, pidl)==S_OK )
594             LV_AddItem(This, pidl);
595           SHFree(pidl);
596         }
597
598         /*turn the listview's redrawing back on and force it to draw*/
599         SendMessageA(This->hWndList, WM_SETREDRAW, TRUE, 0);
600
601         IEnumIDList_Release(pEnumIDList); /* destroy the list*/
602         pDPA_Destroy(hdpa);
603         
604         return S_OK;
605 }
606
607 /**********************************************************
608 *  ShellView_OnCreate()
609 */   
610 static LRESULT ShellView_OnCreate(IShellViewImpl * This)
611 {
612         IDropTarget* pdt;
613         NOTIFYREGISTER ntreg;
614         IPersistFolder2 * ppf2 = NULL;
615         
616         TRACE("%p\n",This);
617
618         if(ShellView_CreateList(This))
619         {
620           if(ShellView_InitList(This))
621           {
622             ShellView_FillList(This);
623           }
624         }
625         
626         if(GetShellOle())
627         {
628           if (SUCCEEDED(IShellFolder_CreateViewObject(This->pSFParent, This->hWnd, &IID_IDropTarget, (LPVOID*)&pdt)))
629           {
630             pRegisterDragDrop(This->hWnd, pdt);
631             IDropTarget_Release(pdt);
632           }
633         }
634
635         /* register for receiving notifications */
636         IShellFolder_QueryInterface(This->pSFParent, &IID_IPersistFolder2, (LPVOID*)&ppf2);
637         if (ppf2)
638         {
639           IPersistFolder2_GetCurFolder(ppf2, &ntreg.pidlPath);
640           ntreg.bWatchSubtree = FALSE;
641           This->hNotify = SHChangeNotifyRegister(This->hWnd, SHCNF_IDLIST, SHCNE_ALLEVENTS, SHV_CHANGE_NOTIFY, 1, &ntreg);
642           SHFree(ntreg.pidlPath);
643           IPersistFolder2_Release(ppf2);
644         }
645
646         This->hAccel = LoadAcceleratorsA(shell32_hInstance, "shv_accel");
647         
648         return S_OK;
649 }
650
651 /**********************************************************
652  *      #### Handling of the menus ####
653  */
654
655 /**********************************************************
656 * ShellView_BuildFileMenu()
657 */
658 static HMENU ShellView_BuildFileMenu(IShellViewImpl * This)
659 {       CHAR    szText[MAX_PATH];
660         MENUITEMINFOA   mii;
661         int     nTools,i;
662         HMENU   hSubMenu;
663
664         TRACE("(%p)\n",This);
665
666         hSubMenu = CreatePopupMenu();
667         if(hSubMenu)
668         { /*get the number of items in our global array*/
669           for(nTools = 0; Tools[nTools].idCommand != -1; nTools++){}
670
671           /*add the menu items*/
672           for(i = 0; i < nTools; i++)
673           { 
674             LoadStringA(shell32_hInstance, Tools[i].idMenuString, szText, MAX_PATH);
675
676             ZeroMemory(&mii, sizeof(mii));
677             mii.cbSize = sizeof(mii);
678             mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
679
680             if(TBSTYLE_SEP != Tools[i].bStyle) /* no seperator*/
681             {
682               mii.fType = MFT_STRING;
683               mii.fState = MFS_ENABLED;
684               mii.dwTypeData = szText;
685               mii.wID = Tools[i].idCommand;
686             }
687             else
688             {
689               mii.fType = MFT_SEPARATOR;
690             }
691             /* tack This item onto the end of the menu */
692             InsertMenuItemA(hSubMenu, (UINT)-1, TRUE, &mii);
693           }
694         }
695         TRACE("-- return (menu=0x%x)\n",hSubMenu);
696         return hSubMenu;
697 }
698 /**********************************************************
699 * ShellView_MergeFileMenu()
700 */
701 static void ShellView_MergeFileMenu(IShellViewImpl * This, HMENU hSubMenu)
702 {       TRACE("(%p)->(submenu=0x%08x) stub\n",This,hSubMenu);
703
704         if(hSubMenu)
705         { /*insert This item at the beginning of the menu */
706           _InsertMenuItem(hSubMenu, 0, TRUE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
707           _InsertMenuItem(hSubMenu, 0, TRUE, IDM_MYFILEITEM, MFT_STRING, "dummy45", MFS_ENABLED);
708
709         }
710         TRACE("--\n");  
711 }
712
713 /**********************************************************
714 * ShellView_MergeViewMenu()
715 */
716
717 static void ShellView_MergeViewMenu(IShellViewImpl * This, HMENU hSubMenu)
718 {       MENUITEMINFOA   mii;
719
720         TRACE("(%p)->(submenu=0x%08x)\n",This,hSubMenu);
721
722         if(hSubMenu)
723         { /*add a separator at the correct position in the menu*/
724           _InsertMenuItem(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
725
726           ZeroMemory(&mii, sizeof(mii));
727           mii.cbSize = sizeof(mii);
728           mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_DATA;;
729           mii.fType = MFT_STRING;
730           mii.dwTypeData = "View";
731           mii.hSubMenu = LoadMenuA(shell32_hInstance, "MENU_001");
732           InsertMenuItemA(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
733         }
734 }
735
736 /**********************************************************
737 *   ShellView_GetSelections()
738 *
739 * - fills the this->apidl list with the selected objects
740 *
741 * RETURNS
742 *  number of selected items
743 */   
744 static UINT ShellView_GetSelections(IShellViewImpl * This)
745 {
746         LVITEMA lvItem;
747         UINT    i = 0;
748
749         if (This->apidl)
750         {
751           SHFree(This->apidl);
752         }
753
754         This->cidl = ListView_GetSelectedCount(This->hWndList);
755         This->apidl = (LPITEMIDLIST*)SHAlloc(This->cidl * sizeof(LPITEMIDLIST));
756
757         TRACE("selected=%i\n", This->cidl);
758         
759         if(This->apidl)
760         {
761           TRACE("-- Items selected =%u\n", This->cidl);
762
763           ZeroMemory(&lvItem, sizeof(lvItem));
764           lvItem.mask = LVIF_STATE | LVIF_PARAM;
765           lvItem.stateMask = LVIS_SELECTED;
766
767           while(ListView_GetItemA(This->hWndList, &lvItem) && (i < This->cidl))
768           {
769             if(lvItem.state & LVIS_SELECTED)
770             {
771               This->apidl[i] = (LPITEMIDLIST)lvItem.lParam;
772               i++;
773               TRACE("-- selected Item found\n");
774             }
775             lvItem.iItem++;
776           }
777         }
778         return This->cidl;
779
780 }
781 /**********************************************************
782  *      ShellView_DoContextMenu()
783  */
784 static void ShellView_DoContextMenu(IShellViewImpl * This, WORD x, WORD y, BOOL bDefault)
785 {       UINT    uCommand;
786         DWORD   wFlags;
787         HMENU   hMenu;
788         BOOL    fExplore = FALSE;
789         HWND    hwndTree = 0;
790         LPCONTEXTMENU   pContextMenu = NULL;
791         IContextMenu *  pCM = NULL;
792         CMINVOKECOMMANDINFO     cmi;
793         
794         TRACE("(%p)->(0x%08x 0x%08x 0x%08x) stub\n",This, x, y, bDefault);
795
796         /* look, what's selected and create a context menu object of it*/
797         if( ShellView_GetSelections(This) )
798         {
799           IShellFolder_GetUIObjectOf( This->pSFParent, This->hWndParent, This->cidl, This->apidl, 
800                                         (REFIID)&IID_IContextMenu, NULL, (LPVOID *)&pContextMenu);
801
802           if(pContextMenu)
803           {
804             TRACE("-- pContextMenu\n");
805             hMenu = CreatePopupMenu();
806
807             if( hMenu )
808             {
809               /* See if we are in Explore or Open mode. If the browser's tree is present, we are in Explore mode.*/
810               if(SUCCEEDED(IShellBrowser_GetControlWindow(This->pShellBrowser,FCW_TREE, &hwndTree)) && hwndTree)
811               {
812                 TRACE("-- explore mode\n");
813                 fExplore = TRUE;
814               }
815
816               /* build the flags depending on what we can do with the selected item */
817               wFlags = CMF_NORMAL | (This->cidl != 1 ? 0 : CMF_CANRENAME) | (fExplore ? CMF_EXPLORE : 0);
818
819               /* let the ContextMenu merge its items in */
820               if (SUCCEEDED(IContextMenu_QueryContextMenu( pContextMenu, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, wFlags )))
821               {
822                 if( bDefault )
823                 {
824                   TRACE("-- get menu default command\n");
825                   uCommand = GetMenuDefaultItem(hMenu, FALSE, GMDI_GOINTOPOPUPS);
826                 }
827                 else
828                 {
829                   TRACE("-- track popup\n");
830                   uCommand = TrackPopupMenu( hMenu,TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
831                 }               
832
833                 if(uCommand > 0)
834                 {
835                   TRACE("-- uCommand=%u\n", uCommand);
836                   if (IsInCommDlg(This) && ((uCommand==FCIDM_SHVIEW_EXPLORE) || (uCommand==FCIDM_SHVIEW_OPEN)))
837                   {
838                     TRACE("-- dlg: OnDefaultCommand\n");
839                     OnDefaultCommand(This);
840                   }
841                   else
842                   {
843                     TRACE("-- explore -- invoke command\n");
844                     ZeroMemory(&cmi, sizeof(cmi));
845                     cmi.cbSize = sizeof(cmi);
846                     cmi.hwnd = This->hWndParent; /* this window has to answer CWM_GETISHELLBROWSER */
847                     cmi.lpVerb = (LPCSTR)MAKEINTRESOURCEA(uCommand);
848                     IContextMenu_InvokeCommand(pContextMenu, &cmi);
849                   }
850                 }
851                 DestroyMenu(hMenu);
852               }
853             }
854             if (pContextMenu)
855               IContextMenu_Release(pContextMenu);
856           }
857         }
858         else    /* background context menu */
859         { 
860           hMenu = CreatePopupMenu();
861
862           pCM = ISvBgCm_Constructor(This->pSFParent);
863           IContextMenu_QueryContextMenu(pCM, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, 0);
864
865           uCommand = TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
866           DestroyMenu(hMenu);
867
868           TRACE("-- (%p)->(uCommand=0x%08x )\n",This, uCommand);
869
870           ZeroMemory(&cmi, sizeof(cmi));
871           cmi.cbSize = sizeof(cmi);
872           cmi.lpVerb = (LPCSTR)MAKEINTRESOURCEA(uCommand);
873           cmi.hwnd = This->hWndParent;
874           IContextMenu_InvokeCommand(pCM, &cmi);
875
876           IContextMenu_Release(pCM);
877         }
878 }
879
880 /**********************************************************
881  *      ##### message handling #####
882  */
883
884 /**********************************************************
885 *  ShellView_OnSize()
886 */
887 static LRESULT ShellView_OnSize(IShellViewImpl * This, WORD wWidth, WORD wHeight)
888 {
889         TRACE("%p width=%u height=%u\n",This, wWidth,wHeight);
890
891         /*resize the ListView to fit our window*/
892         if(This->hWndList)
893         {
894           MoveWindow(This->hWndList, 0, 0, wWidth, wHeight, TRUE);
895         }
896
897         return S_OK;
898 }
899 /**********************************************************
900 * ShellView_OnDeactivate()
901 *
902 * NOTES
903 *  internal
904 */   
905 static void ShellView_OnDeactivate(IShellViewImpl * This)
906 {
907         TRACE("%p\n",This);
908
909         if(This->uState != SVUIA_DEACTIVATE)
910         {
911           if(This->hMenu)
912           {
913             IShellBrowser_SetMenuSB(This->pShellBrowser,0, 0, 0);
914             IShellBrowser_RemoveMenusSB(This->pShellBrowser,This->hMenu);
915             DestroyMenu(This->hMenu);
916             This->hMenu = 0;
917           }
918
919           This->uState = SVUIA_DEACTIVATE;
920         }
921 }
922
923 /**********************************************************
924 * ShellView_OnActivate()
925 */   
926 static LRESULT ShellView_OnActivate(IShellViewImpl * This, UINT uState)
927 {       OLEMENUGROUPWIDTHS   omw = { {0, 0, 0, 0, 0, 0} };
928         MENUITEMINFOA         mii;
929         CHAR                szText[MAX_PATH];
930
931         TRACE("%p uState=%x\n",This,uState);    
932
933         /*don't do anything if the state isn't really changing */
934         if(This->uState == uState)
935         {
936           return S_OK;
937         }
938
939         ShellView_OnDeactivate(This);
940
941         /*only do This if we are active */
942         if(uState != SVUIA_DEACTIVATE)
943         {
944           /*merge the menus */
945           This->hMenu = CreateMenu();
946
947           if(This->hMenu)
948           {
949             IShellBrowser_InsertMenusSB(This->pShellBrowser, This->hMenu, &omw);
950             TRACE("-- after fnInsertMenusSB\n");    
951
952             /*build the top level menu get the menu item's text*/
953             strcpy(szText,"dummy 31");
954
955             ZeroMemory(&mii, sizeof(mii));
956             mii.cbSize = sizeof(mii);
957             mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_STATE;
958             mii.fType = MFT_STRING;
959             mii.fState = MFS_ENABLED;
960             mii.dwTypeData = szText;
961             mii.hSubMenu = ShellView_BuildFileMenu(This);
962
963             /*insert our menu into the menu bar*/
964             if(mii.hSubMenu)
965             {
966               InsertMenuItemA(This->hMenu, FCIDM_MENU_HELP, FALSE, &mii);
967             }
968
969             /*get the view menu so we can merge with it*/
970             ZeroMemory(&mii, sizeof(mii));
971             mii.cbSize = sizeof(mii);
972             mii.fMask = MIIM_SUBMENU;
973
974             if(GetMenuItemInfoA(This->hMenu, FCIDM_MENU_VIEW, FALSE, &mii))
975             {
976               ShellView_MergeViewMenu(This, mii.hSubMenu);
977             }
978
979             /*add the items that should only be added if we have the focus*/
980             if(SVUIA_ACTIVATE_FOCUS == uState)
981             {
982               /*get the file menu so we can merge with it */
983               ZeroMemory(&mii, sizeof(mii));
984               mii.cbSize = sizeof(mii);
985               mii.fMask = MIIM_SUBMENU;
986
987               if(GetMenuItemInfoA(This->hMenu, FCIDM_MENU_FILE, FALSE, &mii))
988               {
989                 ShellView_MergeFileMenu(This, mii.hSubMenu);
990               }
991             }
992             TRACE("-- before fnSetMenuSB\n");      
993             IShellBrowser_SetMenuSB(This->pShellBrowser, This->hMenu, 0, This->hWnd);
994           }
995         }
996         This->uState = uState;
997         TRACE("--\n");    
998         return S_OK;
999 }
1000
1001 /**********************************************************
1002 *  ShellView_OnSetFocus()
1003 *
1004 */
1005 static LRESULT ShellView_OnSetFocus(IShellViewImpl * This)
1006 {
1007         TRACE("%p\n",This);
1008
1009         /* Tell the browser one of our windows has received the focus. This
1010         should always be done before merging menus (OnActivate merges the 
1011         menus) if one of our windows has the focus.*/
1012
1013         IShellBrowser_OnViewWindowActive(This->pShellBrowser,(IShellView*) This);
1014         ShellView_OnActivate(This, SVUIA_ACTIVATE_FOCUS);
1015
1016         /* Set the focus to the listview */
1017         SetFocus(This->hWndList);
1018
1019         /* Notify the ICommDlgBrowser interface */
1020         OnStateChange(This,CDBOSC_SETFOCUS);
1021
1022         return 0;
1023 }
1024
1025 /**********************************************************
1026 * ShellView_OnKillFocus()
1027 */   
1028 static LRESULT ShellView_OnKillFocus(IShellViewImpl * This)
1029 {
1030         TRACE("(%p) stub\n",This);
1031
1032         ShellView_OnActivate(This, SVUIA_ACTIVATE_NOFOCUS);
1033         /* Notify the ICommDlgBrowser */
1034         OnStateChange(This,CDBOSC_KILLFOCUS);
1035
1036         return 0;
1037 }
1038
1039 /**********************************************************
1040 * ShellView_OnCommand()
1041 *
1042 * NOTES
1043 *       the CmdID's are the ones from the context menu
1044 */   
1045 static LRESULT ShellView_OnCommand(IShellViewImpl * This,DWORD dwCmdID, DWORD dwCmd, HWND hwndCmd)
1046 {
1047         TRACE("(%p)->(0x%08lx 0x%08lx 0x%08x) stub\n",This, dwCmdID, dwCmd, hwndCmd);
1048
1049         switch(dwCmdID)
1050         {
1051           case FCIDM_SHVIEW_SMALLICON:
1052             This->FolderSettings.ViewMode = FVM_SMALLICON;
1053             SetStyle (This, LVS_SMALLICON, LVS_TYPEMASK);
1054             CheckToolbar(This);
1055             break;
1056
1057           case FCIDM_SHVIEW_BIGICON:
1058             This->FolderSettings.ViewMode = FVM_ICON;
1059             SetStyle (This, LVS_ICON, LVS_TYPEMASK);
1060             CheckToolbar(This);
1061             break;
1062
1063           case FCIDM_SHVIEW_LISTVIEW:
1064             This->FolderSettings.ViewMode = FVM_LIST;
1065             SetStyle (This, LVS_LIST, LVS_TYPEMASK);
1066             CheckToolbar(This);
1067             break;
1068
1069           case FCIDM_SHVIEW_REPORTVIEW:
1070             This->FolderSettings.ViewMode = FVM_DETAILS;
1071             SetStyle (This, LVS_REPORT, LVS_TYPEMASK);
1072             CheckToolbar(This);
1073             break;
1074
1075           /* the menu-ID's for sorting are 0x30... see shrec.rc */
1076           case 0x30:
1077           case 0x31:
1078           case 0x32:
1079           case 0x33:
1080             This->ListViewSortInfo.nHeaderID = (LPARAM) (dwCmdID - 0x30);
1081             This->ListViewSortInfo.bIsAscending = TRUE;
1082             This->ListViewSortInfo.nLastHeaderID = This->ListViewSortInfo.nHeaderID;
1083             ListView_SortItems(This->hWndList, ShellView_ListViewCompareItems, (LPARAM) (&(This->ListViewSortInfo)));
1084             break;
1085             
1086           default:
1087             TRACE("-- COMMAND 0x%04lx unhandled\n", dwCmdID);
1088         }
1089         return 0;
1090 }
1091
1092 /**********************************************************
1093 * ShellView_OnNotify()
1094 */
1095    
1096 static LRESULT ShellView_OnNotify(IShellViewImpl * This, UINT CtlID, LPNMHDR lpnmh)
1097 {       LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)lpnmh;
1098         NMLVDISPINFOA *lpdi = (NMLVDISPINFOA *)lpnmh;
1099         LPITEMIDLIST pidl;
1100
1101         TRACE("%p CtlID=%u lpnmh->code=%x\n",This,CtlID,lpnmh->code);
1102
1103         switch(lpnmh->code)
1104         {
1105           case NM_SETFOCUS:
1106             TRACE("-- NM_SETFOCUS %p\n",This);
1107             ShellView_OnSetFocus(This);
1108             break;
1109
1110           case NM_KILLFOCUS:
1111             TRACE("-- NM_KILLFOCUS %p\n",This);
1112             ShellView_OnDeactivate(This);
1113             /* Notify the ICommDlgBrowser interface */
1114             OnStateChange(This,CDBOSC_KILLFOCUS);
1115             break;
1116
1117           case HDN_ENDTRACKA:
1118             TRACE("-- HDN_ENDTRACKA %p\n",This);
1119             /*nColumn1 = ListView_GetColumnWidth(This->hWndList, 0);
1120             nColumn2 = ListView_GetColumnWidth(This->hWndList, 1);*/
1121             break;
1122
1123           case LVN_DELETEITEM:
1124             TRACE("-- LVN_DELETEITEM %p\n",This);
1125             SHFree((LPITEMIDLIST)lpnmlv->lParam);     /*delete the pidl because we made a copy of it*/
1126             break;
1127
1128           case LVN_ITEMACTIVATE:
1129             TRACE("-- LVN_ITEMACTIVATE %p\n",This);
1130             OnStateChange(This, CDBOSC_SELCHANGE);  /* the browser will get the IDataObject now */
1131             ShellView_DoContextMenu(This, 0, 0, TRUE);
1132             break;
1133
1134           case LVN_COLUMNCLICK:
1135             This->ListViewSortInfo.nHeaderID = lpnmlv->iSubItem;
1136             if(This->ListViewSortInfo.nLastHeaderID == This->ListViewSortInfo.nHeaderID)
1137             {
1138               This->ListViewSortInfo.bIsAscending = !This->ListViewSortInfo.bIsAscending;
1139             }
1140             else
1141             {
1142               This->ListViewSortInfo.bIsAscending = TRUE;
1143             }
1144             This->ListViewSortInfo.nLastHeaderID = This->ListViewSortInfo.nHeaderID;
1145
1146             ListView_SortItems(lpnmlv->hdr.hwndFrom, ShellView_ListViewCompareItems, (LPARAM) (&(This->ListViewSortInfo)));
1147             break;
1148         
1149           case LVN_GETDISPINFOA:
1150           case LVN_GETDISPINFOW:
1151             TRACE("-- LVN_GETDISPINFO %p\n",This);
1152             pidl = (LPITEMIDLIST)lpdi->item.lParam;
1153
1154             if(lpdi->item.mask & LVIF_TEXT)     /* text requested */
1155             {
1156               if (This->pSF2Parent)
1157               {
1158                 SHELLDETAILS sd;
1159                 IShellFolder2_GetDetailsOf(This->pSF2Parent, pidl, lpdi->item.iSubItem, &sd);
1160                 if (lpnmh->code == LVN_GETDISPINFOA)
1161                 {
1162                     StrRetToStrNA( lpdi->item.pszText, lpdi->item.cchTextMax, &sd.str, NULL);
1163                     TRACE("-- text=%s\n",lpdi->item.pszText);
1164                 }
1165                 else /* LVN_GETDISPINFOW */
1166                 {
1167                     StrRetToStrNW( lpdi->item.pszText, lpdi->item.cchTextMax, &sd.str, NULL);
1168                     TRACE("-- text=%s\n",debugstr_w((WCHAR*)(lpdi->item.pszText)));
1169                 }
1170               }
1171               else
1172               {
1173                 FIXME("no SF2\n");
1174               }
1175             }
1176             if(lpdi->item.mask & LVIF_IMAGE)    /* image requested */
1177             {
1178               lpdi->item.iImage = SHMapPIDLToSystemImageListIndex(This->pSFParent, pidl, 0);
1179             }
1180             break;
1181
1182           case LVN_ITEMCHANGED:
1183             TRACE("-- LVN_ITEMCHANGED %p\n",This);
1184             OnStateChange(This, CDBOSC_SELCHANGE);  /* the browser will get the IDataObject now */
1185             break;
1186
1187           case LVN_BEGINDRAG:
1188           case LVN_BEGINRDRAG:
1189             TRACE("-- LVN_BEGINDRAG\n");
1190
1191             if (ShellView_GetSelections(This))
1192             {  
1193               IDataObject * pda;
1194               DWORD dwAttributes = SFGAO_CANLINK;
1195               DWORD dwEffect = DROPEFFECT_COPY | DROPEFFECT_MOVE;
1196               
1197               if(GetShellOle())
1198               {
1199                 if (SUCCEEDED(IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, This->apidl, &IID_IDataObject,0,(LPVOID *)&pda)))
1200                 {
1201                   IDropSource * pds = (IDropSource*)&(This->lpvtblDropSource);  /* own DropSource interface */
1202
1203                   if (SUCCEEDED(IShellFolder_GetAttributesOf(This->pSFParent, This->cidl, This->apidl, &dwAttributes)))
1204                   {
1205                     if (dwAttributes & SFGAO_CANLINK)
1206                     {
1207                       dwEffect |= DROPEFFECT_LINK;
1208                     }
1209                   }
1210                 
1211                   if (pds)
1212                   {
1213                     DWORD dwEffect;
1214                     pDoDragDrop(pda, pds, dwEffect, &dwEffect);
1215                   }
1216                   IDataObject_Release(pda);
1217                 }
1218               }
1219             }
1220             break;
1221
1222           case LVN_BEGINLABELEDITA:
1223             {
1224               DWORD dwAttr = SFGAO_CANRENAME;
1225               pidl = (LPITEMIDLIST)lpdi->item.lParam;
1226
1227               TRACE("-- LVN_BEGINLABELEDITA %p\n",This);
1228
1229               IShellFolder_GetAttributesOf(This->pSFParent, 1, &pidl, &dwAttr);
1230               if (SFGAO_CANRENAME & dwAttr)
1231               {
1232                 return FALSE;
1233               }
1234               return TRUE;
1235             }
1236             break;
1237
1238           case LVN_ENDLABELEDITA:
1239             {
1240               TRACE("-- LVN_ENDLABELEDITA %p\n",This);
1241               if (lpdi->item.pszText)
1242               {
1243                 HRESULT hr;
1244                 WCHAR wszNewName[MAX_PATH];
1245                 LVITEMA lvItem;
1246
1247                 ZeroMemory(&lvItem, sizeof(LVITEMA));
1248                 lvItem.iItem = lpdi->item.iItem;
1249                 lvItem.mask = LVIF_PARAM;
1250                 ListView_GetItemA(This->hWndList, &lvItem);
1251                 
1252                 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1253                 if (!MultiByteToWideChar( CP_ACP, 0, lpdi->item.pszText, -1, wszNewName, MAX_PATH ))
1254                     wszNewName[MAX_PATH-1] = 0;
1255                 hr = IShellFolder_SetNameOf(This->pSFParent, 0, pidl, wszNewName, SHGDN_INFOLDER, &pidl);
1256                 
1257                 if(SUCCEEDED(hr) && pidl)
1258                 {
1259                   lvItem.mask = LVIF_PARAM;
1260                   lvItem.lParam = (LPARAM)pidl;
1261                   ListView_SetItemA(This->hWndList, &lvItem);
1262                   return TRUE;
1263                 }
1264               }
1265               return FALSE;
1266             }
1267             break;
1268           
1269           case LVN_KEYDOWN:
1270             {
1271             /*  MSG msg;
1272               msg.hwnd = This->hWnd;
1273               msg.message = WM_KEYDOWN;
1274               msg.wParam = plvKeyDown->wVKey;
1275               msg.lParam = 0;
1276               msg.time = 0;
1277               msg.pt = 0;*/
1278               
1279               LPNMLVKEYDOWN plvKeyDown = (LPNMLVKEYDOWN) lpnmh;
1280
1281               /* initiate a rename of the selected file or directory */
1282               if(plvKeyDown->wVKey == VK_F2)
1283               {
1284                 /* see how many files are selected */
1285                 int i = ListView_GetSelectedCount(This->hWndList);
1286
1287                 /* get selected item */
1288                 if(i == 1)
1289                 {
1290                   /* get selected item */
1291                   i = ListView_GetNextItem(This->hWndList, -1,
1292                         LVNI_SELECTED);
1293  
1294                   ListView_EnsureVisible(This->hWndList, i, 0);
1295                   ListView_EditLabelA(This->hWndList, i);
1296                 }
1297               }
1298 #if 0
1299               TranslateAccelerator(This->hWnd, This->hAccel, &msg)
1300 #endif
1301               else if(plvKeyDown->wVKey == VK_DELETE)
1302               {
1303                 int i, item_index;
1304                 LVITEMA item;
1305                 LPITEMIDLIST* pItems;
1306                 ISFHelper *psfhlp;
1307
1308                 IShellFolder_QueryInterface(This->pSFParent, &IID_ISFHelper,
1309                         (LPVOID*)&psfhlp);
1310
1311                 if(!(i = ListView_GetSelectedCount(This->hWndList)))
1312                   break;
1313         
1314                 /* allocate memory for the pidl array */
1315                 pItems = HeapAlloc(GetProcessHeap(), 0, 
1316                         sizeof(LPITEMIDLIST) * i);
1317  
1318                 /* retrieve all selected items */
1319                 i = 0;
1320                 item_index = -1;
1321                 while(ListView_GetSelectedCount(This->hWndList) > i)
1322                 {
1323                   /* get selected item */
1324                   item_index = ListView_GetNextItem(This->hWndList, 
1325                         item_index, LVNI_SELECTED);
1326                   item.iItem = item_index;
1327                   ListView_GetItemA(This->hWndList, &item);
1328
1329                   /* get item pidl */
1330                   pItems[i] = (LPITEMIDLIST)item.lParam;
1331                   
1332                   i++;
1333                 }
1334
1335                 /* perform the item deletion */
1336                 ISFHelper_DeleteItems(psfhlp, i, pItems);
1337
1338                 /* free pidl array memory */
1339                 HeapFree(GetProcessHeap(), 0, pItems);
1340               }
1341               else
1342                 FIXME("LVN_KEYDOWN key=0x%08x\n",plvKeyDown->wVKey);
1343             }
1344             break;
1345
1346           default:
1347             TRACE("-- %p WM_COMMAND %x unhandled\n", This, lpnmh->code);
1348             break;;
1349         }
1350         return 0;
1351 }
1352
1353 /**********************************************************
1354 * ShellView_OnChange()
1355 */
1356
1357 static LRESULT ShellView_OnChange(IShellViewImpl * This, LPITEMIDLIST * Pidls, LONG wEventId)
1358 {
1359
1360         TRACE("(%p)(%p,%p,0x%08lx)\n", This, Pidls[0], Pidls[1], wEventId);
1361         switch(wEventId)
1362         {               
1363           case SHCNE_MKDIR:
1364           case SHCNE_CREATE:
1365             LV_AddItem(This, Pidls[0]);
1366             break;
1367           case SHCNE_RMDIR:
1368           case SHCNE_DELETE:
1369             LV_DeleteItem(This, Pidls[0]);
1370             break;
1371           case SHCNE_RENAMEFOLDER:
1372           case SHCNE_RENAMEITEM:
1373             LV_RenameItem(This, Pidls[0], Pidls[1]);
1374             break;
1375           case SHCNE_UPDATEITEM:
1376             break;
1377         }
1378         return TRUE;
1379 }
1380 /**********************************************************
1381 *  ShellView_WndProc
1382 */
1383
1384 static LRESULT CALLBACK ShellView_WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
1385 {
1386         IShellViewImpl * pThis = (IShellViewImpl*)GetWindowLongA(hWnd, GWL_USERDATA);
1387         LPCREATESTRUCTA lpcs;
1388
1389         TRACE("(hwnd=%x msg=%x wparm=%x lparm=%lx)\n",hWnd, uMessage, wParam, lParam);
1390
1391         switch (uMessage)
1392         {
1393           case WM_NCCREATE:
1394             lpcs = (LPCREATESTRUCTA)lParam;
1395             pThis = (IShellViewImpl*)(lpcs->lpCreateParams);
1396             SetWindowLongA(hWnd, GWL_USERDATA, (LONG)pThis);
1397             pThis->hWnd = hWnd;        /*set the window handle*/
1398             break;
1399
1400           case WM_SIZE:         return ShellView_OnSize(pThis,LOWORD(lParam), HIWORD(lParam));
1401           case WM_SETFOCUS:     return ShellView_OnSetFocus(pThis);
1402           case WM_KILLFOCUS:    return ShellView_OnKillFocus(pThis);
1403           case WM_CREATE:       return ShellView_OnCreate(pThis);
1404           case WM_ACTIVATE:     return ShellView_OnActivate(pThis, SVUIA_ACTIVATE_FOCUS);
1405           case WM_NOTIFY:       return ShellView_OnNotify(pThis,(UINT)wParam, (LPNMHDR)lParam);
1406           case WM_COMMAND:      return ShellView_OnCommand(pThis, 
1407                                         GET_WM_COMMAND_ID(wParam, lParam), 
1408                                         GET_WM_COMMAND_CMD(wParam, lParam), 
1409                                         GET_WM_COMMAND_HWND(wParam, lParam));
1410           case SHV_CHANGE_NOTIFY: return ShellView_OnChange(pThis, (LPITEMIDLIST*)wParam, (LONG)lParam);
1411
1412           case WM_CONTEXTMENU:  ShellView_DoContextMenu(pThis, LOWORD(lParam), HIWORD(lParam), FALSE);
1413                                 return 0;
1414
1415           case WM_SHOWWINDOW:   UpdateWindow(pThis->hWndList);
1416                                 break;
1417
1418           case WM_GETDLGCODE:   return SendMessageA(pThis->hWndList,uMessage,0,0);
1419
1420           case WM_DESTROY:      if(GetShellOle())
1421                                 {
1422                                   pRevokeDragDrop(pThis->hWnd);
1423                                 }
1424                                 SHChangeNotifyDeregister(pThis->hNotify);
1425                                 break;
1426         }
1427
1428         return DefWindowProcA (hWnd, uMessage, wParam, lParam);
1429 }
1430 /**********************************************************
1431 *
1432 *
1433 *  The INTERFACE of the IShellView object
1434 *
1435 *
1436 **********************************************************
1437 *  IShellView_QueryInterface
1438 */
1439 static HRESULT WINAPI IShellView_fnQueryInterface(IShellView * iface,REFIID riid, LPVOID *ppvObj)
1440 {
1441         ICOM_THIS(IShellViewImpl, iface);
1442
1443         TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1444
1445         *ppvObj = NULL;
1446
1447         if(IsEqualIID(riid, &IID_IUnknown))
1448         {
1449           *ppvObj = This; 
1450         }
1451         else if(IsEqualIID(riid, &IID_IShellView))
1452         {
1453           *ppvObj = (IShellView*)This;
1454         }
1455         else if(IsEqualIID(riid, &IID_IOleCommandTarget))
1456         {
1457           *ppvObj = (IOleCommandTarget*)&(This->lpvtblOleCommandTarget);
1458         }
1459         else if(IsEqualIID(riid, &IID_IDropTarget))
1460         {
1461           *ppvObj = (IDropTarget*)&(This->lpvtblDropTarget);
1462         }
1463         else if(IsEqualIID(riid, &IID_IDropSource))
1464         {
1465           *ppvObj = (IDropSource*)&(This->lpvtblDropSource);
1466         }
1467         else if(IsEqualIID(riid, &IID_IViewObject))
1468         {
1469           *ppvObj = (IViewObject*)&(This->lpvtblViewObject);
1470         }
1471
1472         if(*ppvObj)
1473         {
1474           IUnknown_AddRef( (IUnknown*)*ppvObj );
1475           TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1476           return S_OK;
1477         }
1478         TRACE("-- Interface: E_NOINTERFACE\n");
1479         return E_NOINTERFACE;
1480 }
1481
1482 /**********************************************************
1483 *  IShellView_AddRef
1484 */
1485 static ULONG WINAPI IShellView_fnAddRef(IShellView * iface)
1486 {
1487         ICOM_THIS(IShellViewImpl, iface);
1488
1489         TRACE("(%p)->(count=%lu)\n",This,This->ref);
1490
1491         shell32_ObjCount++;
1492         return ++(This->ref);
1493 }
1494 /**********************************************************
1495 *  IShellView_Release
1496 */
1497 static ULONG WINAPI IShellView_fnRelease(IShellView * iface)
1498 {
1499         ICOM_THIS(IShellViewImpl, iface);
1500
1501         TRACE("(%p)->()\n",This);
1502
1503         shell32_ObjCount--;
1504
1505         if (!--(This->ref)) 
1506         {
1507           TRACE(" destroying IShellView(%p)\n",This);
1508
1509           if(This->pSFParent)
1510             IShellFolder_Release(This->pSFParent);
1511
1512           if(This->pSF2Parent)
1513             IShellFolder2_Release(This->pSF2Parent);
1514
1515           if (This->apidl)
1516             SHFree(This->apidl);
1517
1518           if (This->pCommDlgBrowser)
1519             ICommDlgBrowser_Release(This->pCommDlgBrowser);
1520
1521           HeapFree(GetProcessHeap(),0,This);
1522           return 0;
1523         }
1524         return This->ref;
1525 }
1526
1527 /**********************************************************
1528 *  ShellView_GetWindow
1529 */
1530 static HRESULT WINAPI IShellView_fnGetWindow(IShellView * iface,HWND * phWnd)
1531 {
1532         ICOM_THIS(IShellViewImpl, iface);
1533
1534         TRACE("(%p)\n",This);
1535
1536         *phWnd = This->hWnd;
1537
1538         return S_OK;
1539 }
1540
1541 static HRESULT WINAPI IShellView_fnContextSensitiveHelp(IShellView * iface,BOOL fEnterMode)
1542 {
1543         ICOM_THIS(IShellViewImpl, iface);
1544
1545         FIXME("(%p) stub\n",This);
1546
1547         return E_NOTIMPL;
1548 }
1549
1550 /**********************************************************
1551 * IShellView_TranslateAccelerator
1552 *
1553 * FIXME:
1554 *  use the accel functions
1555 */
1556 static HRESULT WINAPI IShellView_fnTranslateAccelerator(IShellView * iface,LPMSG lpmsg)
1557 {
1558 #if 0
1559         ICOM_THIS(IShellViewImpl, iface);
1560
1561         FIXME("(%p)->(%p: hwnd=%x msg=%x lp=%lx wp=%x) stub\n",This,lpmsg, lpmsg->hwnd, lpmsg->message, lpmsg->lParam, lpmsg->wParam);
1562 #endif
1563         
1564         if ((lpmsg->message>=WM_KEYFIRST) && (lpmsg->message>=WM_KEYLAST))
1565         {
1566           TRACE("-- key=0x04%x\n",lpmsg->wParam) ;
1567         }
1568         return S_FALSE; /* not handled */
1569 }
1570
1571 static HRESULT WINAPI IShellView_fnEnableModeless(IShellView * iface,BOOL fEnable)
1572 {
1573         ICOM_THIS(IShellViewImpl, iface);
1574
1575         FIXME("(%p) stub\n",This);
1576
1577         return E_NOTIMPL;
1578 }
1579
1580 static HRESULT WINAPI IShellView_fnUIActivate(IShellView * iface,UINT uState)
1581 {
1582         ICOM_THIS(IShellViewImpl, iface);
1583
1584 /*
1585         CHAR    szName[MAX_PATH];
1586 */
1587         LRESULT lResult;
1588         int     nPartArray[1] = {-1};
1589
1590         TRACE("(%p)->(state=%x) stub\n",This, uState);
1591
1592         /*don't do anything if the state isn't really changing*/
1593         if(This->uState == uState)
1594         {
1595           return S_OK;
1596         }
1597
1598         /*OnActivate handles the menu merging and internal state*/
1599         ShellView_OnActivate(This, uState);
1600
1601         /*only do This if we are active*/
1602         if(uState != SVUIA_DEACTIVATE)
1603         {
1604
1605 /*
1606           GetFolderPath is not a method of IShellFolder
1607           IShellFolder_GetFolderPath( This->pSFParent, szName, sizeof(szName) );
1608 */
1609           /* set the number of parts */
1610           IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETPARTS, 1,
1611                                                         (LPARAM)nPartArray, &lResult);
1612
1613           /* set the text for the parts */
1614 /*
1615           IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETTEXTA,
1616                                                         0, (LPARAM)szName, &lResult);
1617 */                                                      
1618         }
1619
1620         return S_OK;
1621 }
1622
1623 static HRESULT WINAPI IShellView_fnRefresh(IShellView * iface)
1624 {
1625         ICOM_THIS(IShellViewImpl, iface);
1626
1627         TRACE("(%p)\n",This);
1628
1629         ListView_DeleteAllItems(This->hWndList);
1630         ShellView_FillList(This);
1631
1632         return S_OK;
1633 }
1634
1635 static HRESULT WINAPI IShellView_fnCreateViewWindow(
1636         IShellView * iface,
1637         IShellView *lpPrevView,
1638         LPCFOLDERSETTINGS lpfs,
1639         IShellBrowser * psb,
1640         RECT * prcView,
1641         HWND  *phWnd)
1642 {
1643         ICOM_THIS(IShellViewImpl, iface);
1644
1645         WNDCLASSA wc;
1646         *phWnd = 0;
1647
1648         
1649         TRACE("(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n",This, lpPrevView,lpfs, psb, prcView, phWnd);
1650         TRACE("-- vmode=%x flags=%x left=%i top=%i right=%i bottom=%i\n",lpfs->ViewMode, lpfs->fFlags ,prcView->left,prcView->top, prcView->right, prcView->bottom);
1651
1652         /*set up the member variables*/
1653         This->pShellBrowser = psb;
1654         This->FolderSettings = *lpfs;
1655
1656         /*get our parent window*/
1657         IShellBrowser_AddRef(This->pShellBrowser);
1658         IShellBrowser_GetWindow(This->pShellBrowser, &(This->hWndParent));
1659
1660         /* try to get the ICommDlgBrowserInterface, adds a reference !!! */
1661         This->pCommDlgBrowser=NULL;
1662         if ( SUCCEEDED (IShellBrowser_QueryInterface( This->pShellBrowser, 
1663                         (REFIID)&IID_ICommDlgBrowser, (LPVOID*) &This->pCommDlgBrowser)))
1664         {
1665           TRACE("-- CommDlgBrowser\n");
1666         }
1667
1668         /*if our window class has not been registered, then do so*/
1669         if(!GetClassInfoA(shell32_hInstance, SV_CLASS_NAME, &wc))
1670         {
1671           ZeroMemory(&wc, sizeof(wc));
1672           wc.style              = CS_HREDRAW | CS_VREDRAW;
1673           wc.lpfnWndProc        = (WNDPROC) ShellView_WndProc;
1674           wc.cbClsExtra         = 0;
1675           wc.cbWndExtra         = 0;
1676           wc.hInstance          = shell32_hInstance;
1677           wc.hIcon              = 0;
1678           wc.hCursor            = LoadCursorA (0, IDC_ARROWA);
1679           wc.hbrBackground      = (HBRUSH) (COLOR_WINDOW + 1);
1680           wc.lpszMenuName       = NULL;
1681           wc.lpszClassName      = SV_CLASS_NAME;
1682
1683           if(!RegisterClassA(&wc))
1684             return E_FAIL;
1685         }
1686
1687         *phWnd = CreateWindowExA(0,
1688                                 SV_CLASS_NAME,
1689                                 NULL,
1690                                 WS_CHILD | WS_VISIBLE | WS_TABSTOP,
1691                                 prcView->left,
1692                                 prcView->top,
1693                                 prcView->right - prcView->left,
1694                                 prcView->bottom - prcView->top,
1695                                 This->hWndParent,
1696                                 0,
1697                                 shell32_hInstance,
1698                                 (LPVOID)This);
1699
1700         CheckToolbar(This);
1701         
1702         if(!*phWnd) return E_FAIL;
1703
1704         return S_OK;
1705 }
1706
1707 static HRESULT WINAPI IShellView_fnDestroyViewWindow(IShellView * iface)
1708 {
1709         ICOM_THIS(IShellViewImpl, iface);
1710
1711         TRACE("(%p)\n",This);
1712
1713         /*Make absolutely sure all our UI is cleaned up.*/
1714         IShellView_UIActivate((IShellView*)This, SVUIA_DEACTIVATE);
1715
1716         if(This->hMenu)
1717         {
1718           DestroyMenu(This->hMenu);
1719         }
1720
1721         DestroyWindow(This->hWnd);
1722         IShellBrowser_Release(This->pShellBrowser);
1723
1724         return S_OK;
1725 }
1726
1727 static HRESULT WINAPI IShellView_fnGetCurrentInfo(IShellView * iface, LPFOLDERSETTINGS lpfs)
1728 {
1729         ICOM_THIS(IShellViewImpl, iface);
1730
1731         TRACE("(%p)->(%p) vmode=%x flags=%x\n",This, lpfs, 
1732                 This->FolderSettings.ViewMode, This->FolderSettings.fFlags);
1733
1734         if (!lpfs) return E_INVALIDARG;
1735
1736         *lpfs = This->FolderSettings;
1737         return NOERROR;
1738 }
1739
1740 static HRESULT WINAPI IShellView_fnAddPropertySheetPages(IShellView * iface, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam)
1741 {
1742         ICOM_THIS(IShellViewImpl, iface);
1743
1744         FIXME("(%p) stub\n",This);
1745
1746         return E_NOTIMPL;
1747 }
1748
1749 static HRESULT WINAPI IShellView_fnSaveViewState(IShellView * iface)
1750 {
1751         ICOM_THIS(IShellViewImpl, iface);
1752
1753         FIXME("(%p) stub\n",This);
1754
1755         return S_OK;
1756 }
1757
1758 static HRESULT WINAPI IShellView_fnSelectItem(
1759         IShellView * iface,
1760         LPCITEMIDLIST pidl,
1761         UINT uFlags)
1762 {
1763         ICOM_THIS(IShellViewImpl, iface);
1764         int i;
1765         
1766         TRACE("(%p)->(pidl=%p, 0x%08x) stub\n",This, pidl, uFlags);
1767         
1768         i = LV_FindItemByPidl(This, pidl);
1769
1770         if (i != -1)
1771         {
1772           LVITEMA lvItem;
1773           
1774           if(uFlags & SVSI_ENSUREVISIBLE)
1775             ListView_EnsureVisible(This->hWndList, i, 0);
1776
1777           ZeroMemory(&lvItem, sizeof(LVITEMA));
1778           lvItem.mask = LVIF_STATE;
1779           lvItem.iItem = 0;
1780
1781           while(ListView_GetItemA(This->hWndList, &lvItem))
1782           {
1783             if (lvItem.iItem == i)
1784             {
1785               if (uFlags & SVSI_SELECT)
1786                 lvItem.state |= LVIS_SELECTED;
1787               else
1788                 lvItem.state &= ~LVIS_SELECTED;
1789
1790               if(uFlags & SVSI_FOCUSED)
1791                 lvItem.state &= ~LVIS_FOCUSED;
1792             }
1793             else
1794             {
1795               if (uFlags & SVSI_DESELECTOTHERS)
1796                 lvItem.state &= ~LVIS_SELECTED;
1797             }
1798             ListView_SetItemA(This->hWndList, &lvItem);
1799             lvItem.iItem++;
1800           }
1801
1802
1803           if(uFlags & SVSI_EDIT)
1804             ListView_EditLabelA(This->hWndList, i);
1805
1806         }
1807         return S_OK;
1808 }
1809
1810 static HRESULT WINAPI IShellView_fnGetItemObject(IShellView * iface, UINT uItem, REFIID riid, LPVOID *ppvOut)
1811 {
1812         ICOM_THIS(IShellViewImpl, iface);
1813
1814         TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n",This, uItem, debugstr_guid(riid), ppvOut);
1815
1816         *ppvOut = NULL;
1817
1818         switch(uItem)
1819         {
1820           case SVGIO_BACKGROUND:
1821             *ppvOut = ISvBgCm_Constructor(This->pSFParent);
1822             break;
1823
1824           case SVGIO_SELECTION:
1825             ShellView_GetSelections(This);
1826             IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, This->apidl, riid, 0, ppvOut);
1827             break;
1828         }
1829         TRACE("-- (%p)->(interface=%p)\n",This, *ppvOut);
1830
1831         if(!*ppvOut) return E_OUTOFMEMORY;
1832
1833         return S_OK;
1834 }
1835
1836 static HRESULT WINAPI IShellView_fnEditItem(
1837         IShellView * iface,
1838         LPITEMIDLIST pidl)
1839 {
1840         ICOM_THIS(IShellViewImpl, iface);
1841         int i;
1842         
1843         TRACE("(%p)->(pidl=%p)\n",This, pidl);
1844         
1845         i = LV_FindItemByPidl(This, pidl);
1846         if (i != -1)
1847         {
1848           SetFocus(This->hWndList);
1849           ListView_EditLabelA(This->hWndList, i);
1850         }
1851         return S_OK;
1852 }
1853
1854 static struct ICOM_VTABLE(IShellView) svvt = 
1855 {       
1856         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1857         IShellView_fnQueryInterface,
1858         IShellView_fnAddRef,
1859         IShellView_fnRelease,
1860         IShellView_fnGetWindow,
1861         IShellView_fnContextSensitiveHelp,
1862         IShellView_fnTranslateAccelerator,
1863         IShellView_fnEnableModeless,
1864         IShellView_fnUIActivate,
1865         IShellView_fnRefresh,
1866         IShellView_fnCreateViewWindow,
1867         IShellView_fnDestroyViewWindow,
1868         IShellView_fnGetCurrentInfo,
1869         IShellView_fnAddPropertySheetPages,
1870         IShellView_fnSaveViewState,
1871         IShellView_fnSelectItem,
1872         IShellView_fnGetItemObject,
1873         IShellView_fnEditItem
1874 };
1875
1876
1877 /**********************************************************
1878  * ISVOleCmdTarget_QueryInterface (IUnknown)
1879  */
1880 static HRESULT WINAPI ISVOleCmdTarget_QueryInterface(
1881         IOleCommandTarget *     iface,
1882         REFIID                  iid,
1883         LPVOID*                 ppvObj)
1884 {
1885         _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
1886
1887         return IShellFolder_QueryInterface((IShellFolder*)This, iid, ppvObj);
1888 }
1889
1890 /**********************************************************
1891  * ISVOleCmdTarget_AddRef (IUnknown)
1892  */
1893 static ULONG WINAPI ISVOleCmdTarget_AddRef(
1894         IOleCommandTarget *     iface)
1895 {
1896         _ICOM_THIS_From_IOleCommandTarget(IShellFolder, iface);
1897
1898         return IShellFolder_AddRef((IShellFolder*)This);
1899 }
1900
1901 /**********************************************************
1902  * ISVOleCmdTarget_Release (IUnknown)
1903  */
1904 static ULONG WINAPI ISVOleCmdTarget_Release(
1905         IOleCommandTarget *     iface)
1906 {
1907         _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
1908
1909         return IShellFolder_Release((IShellFolder*)This);
1910 }
1911
1912 /**********************************************************
1913  * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
1914  */
1915 static HRESULT WINAPI ISVOleCmdTarget_QueryStatus(
1916         IOleCommandTarget *iface,
1917         const GUID* pguidCmdGroup,
1918         ULONG cCmds, 
1919         OLECMD * prgCmds,
1920         OLECMDTEXT* pCmdText)
1921 {
1922         _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
1923
1924         FIXME("(%p)->(%p(%s) 0x%08lx %p %p\n",
1925               This, pguidCmdGroup, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText);
1926         return E_NOTIMPL;
1927 }
1928
1929 /**********************************************************
1930  * ISVOleCmdTarget_Exec (IOleCommandTarget)
1931  *
1932  * nCmdID is the OLECMDID_* enumeration
1933  */
1934 static HRESULT WINAPI ISVOleCmdTarget_Exec(
1935         IOleCommandTarget *iface,
1936         const GUID* pguidCmdGroup,
1937         DWORD nCmdID,
1938         DWORD nCmdexecopt,
1939         VARIANT* pvaIn,
1940         VARIANT* pvaOut)
1941 {
1942         _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
1943
1944         FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08lx Opt:0x%08lx %p %p)\n",
1945               This, debugstr_guid(pguidCmdGroup), nCmdID, nCmdexecopt, pvaIn, pvaOut);
1946         return E_NOTIMPL;
1947 }
1948
1949 static ICOM_VTABLE(IOleCommandTarget) ctvt = 
1950 {
1951         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1952         ISVOleCmdTarget_QueryInterface,
1953         ISVOleCmdTarget_AddRef,
1954         ISVOleCmdTarget_Release,
1955         ISVOleCmdTarget_QueryStatus,
1956         ISVOleCmdTarget_Exec
1957 };
1958
1959 /**********************************************************
1960  * ISVDropTarget implementation
1961  */
1962
1963 static HRESULT WINAPI ISVDropTarget_QueryInterface(
1964         IDropTarget *iface,
1965         REFIID riid,
1966         LPVOID *ppvObj)
1967 {
1968         _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
1969
1970         TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1971
1972         return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
1973 }
1974
1975 static ULONG WINAPI ISVDropTarget_AddRef( IDropTarget *iface)
1976 {
1977         _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
1978
1979         TRACE("(%p)->(count=%lu)\n",This,This->ref);
1980
1981         return IShellFolder_AddRef((IShellFolder*)This);
1982 }
1983
1984 static ULONG WINAPI ISVDropTarget_Release( IDropTarget *iface)
1985 {
1986         _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
1987
1988         TRACE("(%p)->(count=%lu)\n",This,This->ref);
1989
1990         return IShellFolder_Release((IShellFolder*)This);
1991 }
1992
1993 static HRESULT WINAPI ISVDropTarget_DragEnter(
1994         IDropTarget     *iface,
1995         IDataObject     *pDataObject,
1996         DWORD           grfKeyState,
1997         POINTL          pt,
1998         DWORD           *pdwEffect)
1999 {       
2000
2001         _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2002
2003         FIXME("Stub: This=%p, DataObject=%p\n",This,pDataObject);
2004
2005         return E_NOTIMPL;
2006 }
2007
2008 static HRESULT WINAPI ISVDropTarget_DragOver(
2009         IDropTarget     *iface,
2010         DWORD           grfKeyState,
2011         POINTL          pt,
2012         DWORD           *pdwEffect)
2013 {
2014         _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2015
2016         FIXME("Stub: This=%p\n",This);
2017
2018         return E_NOTIMPL;
2019 }
2020
2021 static HRESULT WINAPI ISVDropTarget_DragLeave(
2022         IDropTarget     *iface)
2023 {
2024         _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2025
2026         FIXME("Stub: This=%p\n",This);
2027
2028         return E_NOTIMPL;
2029 }
2030
2031 static HRESULT WINAPI ISVDropTarget_Drop(
2032         IDropTarget     *iface,
2033         IDataObject*    pDataObject,
2034         DWORD           grfKeyState,
2035         POINTL          pt,
2036         DWORD           *pdwEffect)
2037 {
2038         _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2039
2040         FIXME("Stub: This=%p\n",This);
2041
2042         return E_NOTIMPL;
2043 }
2044
2045 static struct ICOM_VTABLE(IDropTarget) dtvt = 
2046 {
2047         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2048         ISVDropTarget_QueryInterface,
2049         ISVDropTarget_AddRef,
2050         ISVDropTarget_Release,
2051         ISVDropTarget_DragEnter,
2052         ISVDropTarget_DragOver,
2053         ISVDropTarget_DragLeave,
2054         ISVDropTarget_Drop
2055 };
2056
2057 /**********************************************************
2058  * ISVDropSource implementation
2059  */
2060
2061 static HRESULT WINAPI ISVDropSource_QueryInterface(
2062         IDropSource *iface,
2063         REFIID riid,
2064         LPVOID *ppvObj)
2065 {
2066         _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2067
2068         TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2069
2070         return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2071 }
2072
2073 static ULONG WINAPI ISVDropSource_AddRef( IDropSource *iface)
2074 {
2075         _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2076
2077         TRACE("(%p)->(count=%lu)\n",This,This->ref);
2078
2079         return IShellFolder_AddRef((IShellFolder*)This);
2080 }
2081
2082 static ULONG WINAPI ISVDropSource_Release( IDropSource *iface)
2083 {
2084         _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2085
2086         TRACE("(%p)->(count=%lu)\n",This,This->ref);
2087
2088         return IShellFolder_Release((IShellFolder*)This);
2089 }
2090 static HRESULT WINAPI ISVDropSource_QueryContinueDrag(
2091         IDropSource *iface,
2092         BOOL fEscapePressed,
2093         DWORD grfKeyState)
2094 {
2095         _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2096         TRACE("(%p)\n",This);
2097
2098         if (fEscapePressed)
2099           return DRAGDROP_S_CANCEL;
2100         else if (!(grfKeyState & MK_LBUTTON) && !(grfKeyState & MK_RBUTTON))
2101           return DRAGDROP_S_DROP;
2102         else
2103           return NOERROR;
2104 }
2105
2106 static HRESULT WINAPI ISVDropSource_GiveFeedback(
2107         IDropSource *iface,
2108         DWORD dwEffect)
2109 {
2110         _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2111         TRACE("(%p)\n",This);
2112
2113         return DRAGDROP_S_USEDEFAULTCURSORS;
2114 }
2115
2116 static struct ICOM_VTABLE(IDropSource) dsvt =
2117 {
2118         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2119         ISVDropSource_QueryInterface,
2120         ISVDropSource_AddRef,
2121         ISVDropSource_Release,
2122         ISVDropSource_QueryContinueDrag,
2123         ISVDropSource_GiveFeedback
2124 };
2125 /**********************************************************
2126  * ISVViewObject implementation
2127  */
2128
2129 static HRESULT WINAPI ISVViewObject_QueryInterface(
2130         IViewObject *iface,
2131         REFIID riid,
2132         LPVOID *ppvObj)
2133 {
2134         _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2135
2136         TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2137
2138         return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2139 }
2140
2141 static ULONG WINAPI ISVViewObject_AddRef( IViewObject *iface)
2142 {
2143         _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2144
2145         TRACE("(%p)->(count=%lu)\n",This,This->ref);
2146
2147         return IShellFolder_AddRef((IShellFolder*)This);
2148 }
2149
2150 static ULONG WINAPI ISVViewObject_Release( IViewObject *iface)
2151 {
2152         _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2153
2154         TRACE("(%p)->(count=%lu)\n",This,This->ref);
2155
2156         return IShellFolder_Release((IShellFolder*)This);
2157 }
2158
2159 static HRESULT WINAPI ISVViewObject_Draw(
2160         IViewObject     *iface,
2161         DWORD dwDrawAspect,
2162         LONG lindex,
2163         void* pvAspect,
2164         DVTARGETDEVICE* ptd,
2165         HDC hdcTargetDev,
2166         HDC hdcDraw,
2167         LPCRECTL lprcBounds,
2168         LPCRECTL lprcWBounds, 
2169         IVO_ContCallback pfnContinue,
2170         DWORD dwContinue)
2171 {       
2172
2173         _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2174
2175         FIXME("Stub: This=%p\n",This);
2176
2177         return E_NOTIMPL;
2178 }
2179 static HRESULT WINAPI ISVViewObject_GetColorSet(
2180         IViewObject     *iface,
2181         DWORD dwDrawAspect,
2182         LONG lindex,
2183         void *pvAspect,
2184         DVTARGETDEVICE* ptd,
2185         HDC hicTargetDevice,
2186         LOGPALETTE** ppColorSet)
2187 {       
2188
2189         _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2190
2191         FIXME("Stub: This=%p\n",This);
2192
2193         return E_NOTIMPL;
2194 }
2195 static HRESULT WINAPI ISVViewObject_Freeze(
2196         IViewObject     *iface,
2197         DWORD dwDrawAspect,
2198         LONG lindex,
2199         void* pvAspect,
2200         DWORD* pdwFreeze)
2201 {       
2202
2203         _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2204
2205         FIXME("Stub: This=%p\n",This);
2206
2207         return E_NOTIMPL;
2208 }
2209 static HRESULT WINAPI ISVViewObject_Unfreeze(
2210         IViewObject     *iface,
2211         DWORD dwFreeze)
2212 {       
2213
2214         _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2215
2216         FIXME("Stub: This=%p\n",This);
2217
2218         return E_NOTIMPL;
2219 }
2220 static HRESULT WINAPI ISVViewObject_SetAdvise(
2221         IViewObject     *iface,
2222         DWORD aspects,
2223         DWORD advf,
2224         IAdviseSink* pAdvSink)
2225 {       
2226
2227         _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2228
2229         FIXME("Stub: This=%p\n",This);
2230
2231         return E_NOTIMPL;
2232 }
2233 static HRESULT WINAPI ISVViewObject_GetAdvise(
2234         IViewObject     *iface,
2235         DWORD* pAspects,
2236         DWORD* pAdvf,
2237         IAdviseSink** ppAdvSink)
2238 {       
2239
2240         _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2241
2242         FIXME("Stub: This=%p\n",This);
2243
2244         return E_NOTIMPL;
2245 }
2246
2247
2248 static struct ICOM_VTABLE(IViewObject) vovt = 
2249 {
2250         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2251         ISVViewObject_QueryInterface,
2252         ISVViewObject_AddRef,
2253         ISVViewObject_Release,
2254         ISVViewObject_Draw,
2255         ISVViewObject_GetColorSet,
2256         ISVViewObject_Freeze,
2257         ISVViewObject_Unfreeze,
2258         ISVViewObject_SetAdvise,
2259         ISVViewObject_GetAdvise
2260 };
2261