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