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