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