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