Use system metrics values in TOOLBAR_DrawPattern instead of hardcoded
[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           if(This->pSFParent)
1656             IShellFolder_Release(This->pSFParent);
1657
1658           if(This->pSF2Parent)
1659             IShellFolder2_Release(This->pSF2Parent);
1660
1661           if (This->apidl)
1662             SHFree(This->apidl);
1663
1664           HeapFree(GetProcessHeap(),0,This);
1665           return 0;
1666         }
1667         return This->ref;
1668 }
1669
1670 /**********************************************************
1671 *  ShellView_GetWindow
1672 */
1673 static HRESULT WINAPI IShellView_fnGetWindow(IShellView * iface,HWND * phWnd)
1674 {
1675         ICOM_THIS(IShellViewImpl, iface);
1676
1677         TRACE("(%p)\n",This);
1678
1679         *phWnd = This->hWnd;
1680
1681         return S_OK;
1682 }
1683
1684 static HRESULT WINAPI IShellView_fnContextSensitiveHelp(IShellView * iface,BOOL fEnterMode)
1685 {
1686         ICOM_THIS(IShellViewImpl, iface);
1687
1688         FIXME("(%p) stub\n",This);
1689
1690         return E_NOTIMPL;
1691 }
1692
1693 /**********************************************************
1694 * IShellView_TranslateAccelerator
1695 *
1696 * FIXME:
1697 *  use the accel functions
1698 */
1699 static HRESULT WINAPI IShellView_fnTranslateAccelerator(IShellView * iface,LPMSG lpmsg)
1700 {
1701 #if 0
1702         ICOM_THIS(IShellViewImpl, iface);
1703
1704         FIXME("(%p)->(%p: hwnd=%x msg=%x lp=%lx wp=%x) stub\n",This,lpmsg, lpmsg->hwnd, lpmsg->message, lpmsg->lParam, lpmsg->wParam);
1705 #endif
1706
1707         if ((lpmsg->message>=WM_KEYFIRST) && (lpmsg->message>=WM_KEYLAST))
1708         {
1709           TRACE("-- key=0x04%x\n",lpmsg->wParam) ;
1710         }
1711         return S_FALSE; /* not handled */
1712 }
1713
1714 static HRESULT WINAPI IShellView_fnEnableModeless(IShellView * iface,BOOL fEnable)
1715 {
1716         ICOM_THIS(IShellViewImpl, iface);
1717
1718         FIXME("(%p) stub\n",This);
1719
1720         return E_NOTIMPL;
1721 }
1722
1723 static HRESULT WINAPI IShellView_fnUIActivate(IShellView * iface,UINT uState)
1724 {
1725         ICOM_THIS(IShellViewImpl, iface);
1726
1727 /*
1728         CHAR    szName[MAX_PATH];
1729 */
1730         LRESULT lResult;
1731         int     nPartArray[1] = {-1};
1732
1733         TRACE("(%p)->(state=%x) stub\n",This, uState);
1734
1735         /*don't do anything if the state isn't really changing*/
1736         if(This->uState == uState)
1737         {
1738           return S_OK;
1739         }
1740
1741         /*OnActivate handles the menu merging and internal state*/
1742         ShellView_OnActivate(This, uState);
1743
1744         /*only do This if we are active*/
1745         if(uState != SVUIA_DEACTIVATE)
1746         {
1747
1748 /*
1749           GetFolderPath is not a method of IShellFolder
1750           IShellFolder_GetFolderPath( This->pSFParent, szName, sizeof(szName) );
1751 */
1752           /* set the number of parts */
1753           IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETPARTS, 1,
1754                                                         (LPARAM)nPartArray, &lResult);
1755
1756           /* set the text for the parts */
1757 /*
1758           IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETTEXTA,
1759                                                         0, (LPARAM)szName, &lResult);
1760 */
1761         }
1762
1763         return S_OK;
1764 }
1765
1766 static HRESULT WINAPI IShellView_fnRefresh(IShellView * iface)
1767 {
1768         ICOM_THIS(IShellViewImpl, iface);
1769
1770         TRACE("(%p)\n",This);
1771
1772         ListView_DeleteAllItems(This->hWndList);
1773         ShellView_FillList(This);
1774
1775         return S_OK;
1776 }
1777
1778 static HRESULT WINAPI IShellView_fnCreateViewWindow(
1779         IShellView * iface,
1780         IShellView *lpPrevView,
1781         LPCFOLDERSETTINGS lpfs,
1782         IShellBrowser * psb,
1783         RECT * prcView,
1784         HWND  *phWnd)
1785 {
1786         ICOM_THIS(IShellViewImpl, iface);
1787
1788         WNDCLASSA wc;
1789         *phWnd = 0;
1790
1791
1792         TRACE("(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n",This, lpPrevView,lpfs, psb, prcView, phWnd);
1793         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);
1794
1795         /*set up the member variables*/
1796         This->pShellBrowser = psb;
1797         This->FolderSettings = *lpfs;
1798
1799         /*get our parent window*/
1800         IShellBrowser_AddRef(This->pShellBrowser);
1801         IShellBrowser_GetWindow(This->pShellBrowser, &(This->hWndParent));
1802
1803         /* try to get the ICommDlgBrowserInterface, adds a reference !!! */
1804         This->pCommDlgBrowser=NULL;
1805         if ( SUCCEEDED (IShellBrowser_QueryInterface( This->pShellBrowser,
1806                         (REFIID)&IID_ICommDlgBrowser, (LPVOID*) &This->pCommDlgBrowser)))
1807         {
1808           TRACE("-- CommDlgBrowser\n");
1809         }
1810
1811         /*if our window class has not been registered, then do so*/
1812         if(!GetClassInfoA(shell32_hInstance, SV_CLASS_NAME, &wc))
1813         {
1814           ZeroMemory(&wc, sizeof(wc));
1815           wc.style              = CS_HREDRAW | CS_VREDRAW;
1816           wc.lpfnWndProc        = (WNDPROC) ShellView_WndProc;
1817           wc.cbClsExtra         = 0;
1818           wc.cbWndExtra         = 0;
1819           wc.hInstance          = shell32_hInstance;
1820           wc.hIcon              = 0;
1821           wc.hCursor            = LoadCursorA (0, (LPSTR)IDC_ARROW);
1822           wc.hbrBackground      = (HBRUSH) (COLOR_WINDOW + 1);
1823           wc.lpszMenuName       = NULL;
1824           wc.lpszClassName      = SV_CLASS_NAME;
1825
1826           if(!RegisterClassA(&wc))
1827             return E_FAIL;
1828         }
1829
1830         *phWnd = CreateWindowExA(0,
1831                                 SV_CLASS_NAME,
1832                                 NULL,
1833                                 WS_CHILD | WS_VISIBLE | WS_TABSTOP,
1834                                 prcView->left,
1835                                 prcView->top,
1836                                 prcView->right - prcView->left,
1837                                 prcView->bottom - prcView->top,
1838                                 This->hWndParent,
1839                                 0,
1840                                 shell32_hInstance,
1841                                 (LPVOID)This);
1842
1843         CheckToolbar(This);
1844
1845         if(!*phWnd) return E_FAIL;
1846
1847         return S_OK;
1848 }
1849
1850 static HRESULT WINAPI IShellView_fnDestroyViewWindow(IShellView * iface)
1851 {
1852         ICOM_THIS(IShellViewImpl, iface);
1853
1854         TRACE("(%p)\n",This);
1855
1856         /*Make absolutely sure all our UI is cleaned up.*/
1857         IShellView_UIActivate((IShellView*)This, SVUIA_DEACTIVATE);
1858
1859         if(This->hMenu)
1860         {
1861           DestroyMenu(This->hMenu);
1862         }
1863
1864         DestroyWindow(This->hWnd);
1865         if(This->pShellBrowser) IShellBrowser_Release(This->pShellBrowser);
1866         if(This->pCommDlgBrowser) ICommDlgBrowser_Release(This->pCommDlgBrowser);
1867
1868
1869         return S_OK;
1870 }
1871
1872 static HRESULT WINAPI IShellView_fnGetCurrentInfo(IShellView * iface, LPFOLDERSETTINGS lpfs)
1873 {
1874         ICOM_THIS(IShellViewImpl, iface);
1875
1876         TRACE("(%p)->(%p) vmode=%x flags=%x\n",This, lpfs,
1877                 This->FolderSettings.ViewMode, This->FolderSettings.fFlags);
1878
1879         if (!lpfs) return E_INVALIDARG;
1880
1881         *lpfs = This->FolderSettings;
1882         return NOERROR;
1883 }
1884
1885 static HRESULT WINAPI IShellView_fnAddPropertySheetPages(IShellView * iface, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam)
1886 {
1887         ICOM_THIS(IShellViewImpl, iface);
1888
1889         FIXME("(%p) stub\n",This);
1890
1891         return E_NOTIMPL;
1892 }
1893
1894 static HRESULT WINAPI IShellView_fnSaveViewState(IShellView * iface)
1895 {
1896         ICOM_THIS(IShellViewImpl, iface);
1897
1898         FIXME("(%p) stub\n",This);
1899
1900         return S_OK;
1901 }
1902
1903 static HRESULT WINAPI IShellView_fnSelectItem(
1904         IShellView * iface,
1905         LPCITEMIDLIST pidl,
1906         UINT uFlags)
1907 {
1908         ICOM_THIS(IShellViewImpl, iface);
1909         int i;
1910
1911         TRACE("(%p)->(pidl=%p, 0x%08x) stub\n",This, pidl, uFlags);
1912
1913         i = LV_FindItemByPidl(This, pidl);
1914
1915         if (i != -1)
1916         {
1917           LVITEMA lvItem;
1918
1919           if(uFlags & SVSI_ENSUREVISIBLE)
1920             ListView_EnsureVisible(This->hWndList, i, 0);
1921
1922           ZeroMemory(&lvItem, sizeof(LVITEMA));
1923           lvItem.mask = LVIF_STATE;
1924           lvItem.iItem = 0;
1925
1926           while(ListView_GetItemA(This->hWndList, &lvItem))
1927           {
1928             if (lvItem.iItem == i)
1929             {
1930               if (uFlags & SVSI_SELECT)
1931                 lvItem.state |= LVIS_SELECTED;
1932               else
1933                 lvItem.state &= ~LVIS_SELECTED;
1934
1935               if(uFlags & SVSI_FOCUSED)
1936                 lvItem.state &= ~LVIS_FOCUSED;
1937             }
1938             else
1939             {
1940               if (uFlags & SVSI_DESELECTOTHERS)
1941                 lvItem.state &= ~LVIS_SELECTED;
1942             }
1943             ListView_SetItemA(This->hWndList, &lvItem);
1944             lvItem.iItem++;
1945           }
1946
1947
1948           if(uFlags & SVSI_EDIT)
1949             ListView_EditLabelA(This->hWndList, i);
1950
1951         }
1952         return S_OK;
1953 }
1954
1955 static HRESULT WINAPI IShellView_fnGetItemObject(IShellView * iface, UINT uItem, REFIID riid, LPVOID *ppvOut)
1956 {
1957         ICOM_THIS(IShellViewImpl, iface);
1958
1959         TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n",This, uItem, debugstr_guid(riid), ppvOut);
1960
1961         *ppvOut = NULL;
1962
1963         switch(uItem)
1964         {
1965           case SVGIO_BACKGROUND:
1966             *ppvOut = ISvBgCm_Constructor(This->pSFParent);
1967             break;
1968
1969           case SVGIO_SELECTION:
1970             ShellView_GetSelections(This);
1971             IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, (LPCITEMIDLIST*)This->apidl, riid, 0, ppvOut);
1972             break;
1973         }
1974         TRACE("-- (%p)->(interface=%p)\n",This, *ppvOut);
1975
1976         if(!*ppvOut) return E_OUTOFMEMORY;
1977
1978         return S_OK;
1979 }
1980
1981 static struct ICOM_VTABLE(IShellView) svvt =
1982 {
1983         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1984         IShellView_fnQueryInterface,
1985         IShellView_fnAddRef,
1986         IShellView_fnRelease,
1987         IShellView_fnGetWindow,
1988         IShellView_fnContextSensitiveHelp,
1989         IShellView_fnTranslateAccelerator,
1990         IShellView_fnEnableModeless,
1991         IShellView_fnUIActivate,
1992         IShellView_fnRefresh,
1993         IShellView_fnCreateViewWindow,
1994         IShellView_fnDestroyViewWindow,
1995         IShellView_fnGetCurrentInfo,
1996         IShellView_fnAddPropertySheetPages,
1997         IShellView_fnSaveViewState,
1998         IShellView_fnSelectItem,
1999         IShellView_fnGetItemObject
2000 };
2001
2002
2003 /**********************************************************
2004  * ISVOleCmdTarget_QueryInterface (IUnknown)
2005  */
2006 static HRESULT WINAPI ISVOleCmdTarget_QueryInterface(
2007         IOleCommandTarget *     iface,
2008         REFIID                  iid,
2009         LPVOID*                 ppvObj)
2010 {
2011         _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
2012
2013         return IShellFolder_QueryInterface((IShellFolder*)This, iid, ppvObj);
2014 }
2015
2016 /**********************************************************
2017  * ISVOleCmdTarget_AddRef (IUnknown)
2018  */
2019 static ULONG WINAPI ISVOleCmdTarget_AddRef(
2020         IOleCommandTarget *     iface)
2021 {
2022         _ICOM_THIS_From_IOleCommandTarget(IShellFolder, iface);
2023
2024         return IShellFolder_AddRef((IShellFolder*)This);
2025 }
2026
2027 /**********************************************************
2028  * ISVOleCmdTarget_Release (IUnknown)
2029  */
2030 static ULONG WINAPI ISVOleCmdTarget_Release(
2031         IOleCommandTarget *     iface)
2032 {
2033         _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
2034
2035         return IShellFolder_Release((IShellFolder*)This);
2036 }
2037
2038 /**********************************************************
2039  * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2040  */
2041 static HRESULT WINAPI ISVOleCmdTarget_QueryStatus(
2042         IOleCommandTarget *iface,
2043         const GUID* pguidCmdGroup,
2044         ULONG cCmds,
2045         OLECMD * prgCmds,
2046         OLECMDTEXT* pCmdText)
2047 {
2048     UINT i;
2049     _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
2050
2051     FIXME("(%p)->(%p(%s) 0x%08lx %p %p\n",
2052               This, pguidCmdGroup, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText);
2053
2054     if (!prgCmds)
2055         return E_POINTER;
2056     for (i = 0; i < cCmds; i++)
2057     {
2058         FIXME("\tprgCmds[%d].cmdID = %ld\n", i, prgCmds[i].cmdID);
2059         prgCmds[i].cmdf = 0;
2060     }
2061     return OLECMDERR_E_UNKNOWNGROUP;
2062 }
2063
2064 /**********************************************************
2065  * ISVOleCmdTarget_Exec (IOleCommandTarget)
2066  *
2067  * nCmdID is the OLECMDID_* enumeration
2068  */
2069 static HRESULT WINAPI ISVOleCmdTarget_Exec(
2070         IOleCommandTarget *iface,
2071         const GUID* pguidCmdGroup,
2072         DWORD nCmdID,
2073         DWORD nCmdexecopt,
2074         VARIANT* pvaIn,
2075         VARIANT* pvaOut)
2076 {
2077         _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
2078
2079         FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08lx Opt:0x%08lx %p %p)\n",
2080               This, debugstr_guid(pguidCmdGroup), nCmdID, nCmdexecopt, pvaIn, pvaOut);
2081
2082         if (IsEqualIID(pguidCmdGroup, &CGID_Explorer) &&
2083            (nCmdID == 0x29) &&
2084            (nCmdexecopt == 4) && pvaOut)
2085            return S_OK;
2086         if (IsEqualIID(pguidCmdGroup, &CGID_ShellDocView) &&
2087            (nCmdID == 9) &&
2088            (nCmdexecopt == 0))
2089            return 1;
2090
2091         return OLECMDERR_E_UNKNOWNGROUP;
2092 }
2093
2094 static ICOM_VTABLE(IOleCommandTarget) ctvt =
2095 {
2096         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2097         ISVOleCmdTarget_QueryInterface,
2098         ISVOleCmdTarget_AddRef,
2099         ISVOleCmdTarget_Release,
2100         ISVOleCmdTarget_QueryStatus,
2101         ISVOleCmdTarget_Exec
2102 };
2103
2104 /**********************************************************
2105  * ISVDropTarget implementation
2106  */
2107
2108 static HRESULT WINAPI ISVDropTarget_QueryInterface(
2109         IDropTarget *iface,
2110         REFIID riid,
2111         LPVOID *ppvObj)
2112 {
2113         _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2114
2115         TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2116
2117         return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2118 }
2119
2120 static ULONG WINAPI ISVDropTarget_AddRef( IDropTarget *iface)
2121 {
2122         _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2123
2124         TRACE("(%p)->(count=%lu)\n",This,This->ref);
2125
2126         return IShellFolder_AddRef((IShellFolder*)This);
2127 }
2128
2129 static ULONG WINAPI ISVDropTarget_Release( IDropTarget *iface)
2130 {
2131         _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2132
2133         TRACE("(%p)->(count=%lu)\n",This,This->ref);
2134
2135         return IShellFolder_Release((IShellFolder*)This);
2136 }
2137
2138 static HRESULT WINAPI ISVDropTarget_DragEnter(
2139         IDropTarget     *iface,
2140         IDataObject     *pDataObject,
2141         DWORD           grfKeyState,
2142         POINTL          pt,
2143         DWORD           *pdwEffect)
2144 {
2145
2146         _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2147
2148         FIXME("Stub: This=%p, DataObject=%p\n",This,pDataObject);
2149
2150         return E_NOTIMPL;
2151 }
2152
2153 static HRESULT WINAPI ISVDropTarget_DragOver(
2154         IDropTarget     *iface,
2155         DWORD           grfKeyState,
2156         POINTL          pt,
2157         DWORD           *pdwEffect)
2158 {
2159         _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2160
2161         FIXME("Stub: This=%p\n",This);
2162
2163         return E_NOTIMPL;
2164 }
2165
2166 static HRESULT WINAPI ISVDropTarget_DragLeave(
2167         IDropTarget     *iface)
2168 {
2169         _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2170
2171         FIXME("Stub: This=%p\n",This);
2172
2173         return E_NOTIMPL;
2174 }
2175
2176 static HRESULT WINAPI ISVDropTarget_Drop(
2177         IDropTarget     *iface,
2178         IDataObject*    pDataObject,
2179         DWORD           grfKeyState,
2180         POINTL          pt,
2181         DWORD           *pdwEffect)
2182 {
2183         _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2184
2185         FIXME("Stub: This=%p\n",This);
2186
2187         return E_NOTIMPL;
2188 }
2189
2190 static struct ICOM_VTABLE(IDropTarget) dtvt =
2191 {
2192         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2193         ISVDropTarget_QueryInterface,
2194         ISVDropTarget_AddRef,
2195         ISVDropTarget_Release,
2196         ISVDropTarget_DragEnter,
2197         ISVDropTarget_DragOver,
2198         ISVDropTarget_DragLeave,
2199         ISVDropTarget_Drop
2200 };
2201
2202 /**********************************************************
2203  * ISVDropSource implementation
2204  */
2205
2206 static HRESULT WINAPI ISVDropSource_QueryInterface(
2207         IDropSource *iface,
2208         REFIID riid,
2209         LPVOID *ppvObj)
2210 {
2211         _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2212
2213         TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2214
2215         return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2216 }
2217
2218 static ULONG WINAPI ISVDropSource_AddRef( IDropSource *iface)
2219 {
2220         _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2221
2222         TRACE("(%p)->(count=%lu)\n",This,This->ref);
2223
2224         return IShellFolder_AddRef((IShellFolder*)This);
2225 }
2226
2227 static ULONG WINAPI ISVDropSource_Release( IDropSource *iface)
2228 {
2229         _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2230
2231         TRACE("(%p)->(count=%lu)\n",This,This->ref);
2232
2233         return IShellFolder_Release((IShellFolder*)This);
2234 }
2235 static HRESULT WINAPI ISVDropSource_QueryContinueDrag(
2236         IDropSource *iface,
2237         BOOL fEscapePressed,
2238         DWORD grfKeyState)
2239 {
2240         _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2241         TRACE("(%p)\n",This);
2242
2243         if (fEscapePressed)
2244           return DRAGDROP_S_CANCEL;
2245         else if (!(grfKeyState & MK_LBUTTON) && !(grfKeyState & MK_RBUTTON))
2246           return DRAGDROP_S_DROP;
2247         else
2248           return NOERROR;
2249 }
2250
2251 static HRESULT WINAPI ISVDropSource_GiveFeedback(
2252         IDropSource *iface,
2253         DWORD dwEffect)
2254 {
2255         _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2256         TRACE("(%p)\n",This);
2257
2258         return DRAGDROP_S_USEDEFAULTCURSORS;
2259 }
2260
2261 static struct ICOM_VTABLE(IDropSource) dsvt =
2262 {
2263         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2264         ISVDropSource_QueryInterface,
2265         ISVDropSource_AddRef,
2266         ISVDropSource_Release,
2267         ISVDropSource_QueryContinueDrag,
2268         ISVDropSource_GiveFeedback
2269 };
2270 /**********************************************************
2271  * ISVViewObject implementation
2272  */
2273
2274 static HRESULT WINAPI ISVViewObject_QueryInterface(
2275         IViewObject *iface,
2276         REFIID riid,
2277         LPVOID *ppvObj)
2278 {
2279         _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2280
2281         TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2282
2283         return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2284 }
2285
2286 static ULONG WINAPI ISVViewObject_AddRef( IViewObject *iface)
2287 {
2288         _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2289
2290         TRACE("(%p)->(count=%lu)\n",This,This->ref);
2291
2292         return IShellFolder_AddRef((IShellFolder*)This);
2293 }
2294
2295 static ULONG WINAPI ISVViewObject_Release( IViewObject *iface)
2296 {
2297         _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2298
2299         TRACE("(%p)->(count=%lu)\n",This,This->ref);
2300
2301         return IShellFolder_Release((IShellFolder*)This);
2302 }
2303
2304 static HRESULT WINAPI ISVViewObject_Draw(
2305         IViewObject     *iface,
2306         DWORD dwDrawAspect,
2307         LONG lindex,
2308         void* pvAspect,
2309         DVTARGETDEVICE* ptd,
2310         HDC hdcTargetDev,
2311         HDC hdcDraw,
2312         LPCRECTL lprcBounds,
2313         LPCRECTL lprcWBounds,
2314         BOOL (CALLBACK *pfnContinue)(ULONG_PTR dwContinue),
2315         DWORD dwContinue)
2316 {
2317
2318         _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2319
2320         FIXME("Stub: This=%p\n",This);
2321
2322         return E_NOTIMPL;
2323 }
2324 static HRESULT WINAPI ISVViewObject_GetColorSet(
2325         IViewObject     *iface,
2326         DWORD dwDrawAspect,
2327         LONG lindex,
2328         void *pvAspect,
2329         DVTARGETDEVICE* ptd,
2330         HDC hicTargetDevice,
2331         LOGPALETTE** ppColorSet)
2332 {
2333
2334         _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2335
2336         FIXME("Stub: This=%p\n",This);
2337
2338         return E_NOTIMPL;
2339 }
2340 static HRESULT WINAPI ISVViewObject_Freeze(
2341         IViewObject     *iface,
2342         DWORD dwDrawAspect,
2343         LONG lindex,
2344         void* pvAspect,
2345         DWORD* pdwFreeze)
2346 {
2347
2348         _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2349
2350         FIXME("Stub: This=%p\n",This);
2351
2352         return E_NOTIMPL;
2353 }
2354 static HRESULT WINAPI ISVViewObject_Unfreeze(
2355         IViewObject     *iface,
2356         DWORD dwFreeze)
2357 {
2358
2359         _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2360
2361         FIXME("Stub: This=%p\n",This);
2362
2363         return E_NOTIMPL;
2364 }
2365 static HRESULT WINAPI ISVViewObject_SetAdvise(
2366         IViewObject     *iface,
2367         DWORD aspects,
2368         DWORD advf,
2369         IAdviseSink* pAdvSink)
2370 {
2371
2372         _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2373
2374         FIXME("Stub: This=%p\n",This);
2375
2376         return E_NOTIMPL;
2377 }
2378 static HRESULT WINAPI ISVViewObject_GetAdvise(
2379         IViewObject     *iface,
2380         DWORD* pAspects,
2381         DWORD* pAdvf,
2382         IAdviseSink** ppAdvSink)
2383 {
2384
2385         _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2386
2387         FIXME("Stub: This=%p\n",This);
2388
2389         return E_NOTIMPL;
2390 }
2391
2392
2393 static struct ICOM_VTABLE(IViewObject) vovt =
2394 {
2395         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2396         ISVViewObject_QueryInterface,
2397         ISVViewObject_AddRef,
2398         ISVViewObject_Release,
2399         ISVViewObject_Draw,
2400         ISVViewObject_GetColorSet,
2401         ISVViewObject_Freeze,
2402         ISVViewObject_Unfreeze,
2403         ISVViewObject_SetAdvise,
2404         ISVViewObject_GetAdvise
2405 };