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