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