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