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