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