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