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