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