No longer directly accessing debuggee memory.
[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 //            TranslateAccelerator(This->hWnd, This->hAccel, &msg)
1288               FIXME("LVN_KEYDOWN key=0x%08x\n",plvKeyDown->wVKey);
1289             }
1290             break;
1291           default:
1292             TRACE("-- %p WM_COMMAND %s unhandled\n", This, SPY_GetMsgName(lpnmh->code));
1293             break;;
1294         }
1295         return 0;
1296 }
1297
1298 /**********************************************************
1299 * ShellView_OnChange()
1300 */
1301
1302 static LRESULT ShellView_OnChange(IShellViewImpl * This, LPITEMIDLIST * Pidls, LONG wEventId)
1303 {
1304
1305         TRACE("(%p)(%p,%p,0x%08lx)\n", This, Pidls[0], Pidls[1], wEventId);
1306         switch(wEventId)
1307         {               
1308           case SHCNE_MKDIR:
1309           case SHCNE_CREATE:
1310             LV_AddItem(This, Pidls[0]);
1311             break;
1312           case SHCNE_RMDIR:
1313           case SHCNE_DELETE:
1314             LV_DeleteItem(This, Pidls[0]);
1315             break;
1316           case SHCNE_RENAMEFOLDER:
1317           case SHCNE_RENAMEITEM:
1318             LV_RenameItem(This, Pidls[0], Pidls[1]);
1319             break;
1320           case SHCNE_UPDATEITEM:
1321             break;
1322         }
1323         return TRUE;
1324 }
1325 /**********************************************************
1326 *  ShellView_WndProc
1327 */
1328
1329 static LRESULT CALLBACK ShellView_WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
1330 {
1331         IShellViewImpl * pThis = (IShellViewImpl*)GetWindowLongA(hWnd, GWL_USERDATA);
1332         LPCREATESTRUCTA lpcs;
1333
1334         TRACE("(hwnd=%x msg=%x wparm=%x lparm=%lx)\n",hWnd, uMessage, wParam, lParam);
1335
1336         switch (uMessage)
1337         {
1338           case WM_NCCREATE:
1339             lpcs = (LPCREATESTRUCTA)lParam;
1340             pThis = (IShellViewImpl*)(lpcs->lpCreateParams);
1341             SetWindowLongA(hWnd, GWL_USERDATA, (LONG)pThis);
1342             pThis->hWnd = hWnd;        /*set the window handle*/
1343             break;
1344
1345           case WM_SIZE:         return ShellView_OnSize(pThis,LOWORD(lParam), HIWORD(lParam));
1346           case WM_SETFOCUS:     return ShellView_OnSetFocus(pThis);
1347           case WM_KILLFOCUS:    return ShellView_OnKillFocus(pThis);
1348           case WM_CREATE:       return ShellView_OnCreate(pThis);
1349           case WM_ACTIVATE:     return ShellView_OnActivate(pThis, SVUIA_ACTIVATE_FOCUS);
1350           case WM_NOTIFY:       return ShellView_OnNotify(pThis,(UINT)wParam, (LPNMHDR)lParam);
1351           case WM_COMMAND:      return ShellView_OnCommand(pThis, 
1352                                         GET_WM_COMMAND_ID(wParam, lParam), 
1353                                         GET_WM_COMMAND_CMD(wParam, lParam), 
1354                                         GET_WM_COMMAND_HWND(wParam, lParam));
1355           case SHV_CHANGE_NOTIFY: return ShellView_OnChange(pThis, (LPITEMIDLIST*)wParam, (LONG)lParam);
1356
1357           case WM_CONTEXTMENU:  ShellView_DoContextMenu(pThis, LOWORD(lParam), HIWORD(lParam), FALSE);
1358                                 return 0;
1359
1360           case WM_SHOWWINDOW:   UpdateWindow(pThis->hWndList);
1361                                 break;
1362
1363           case WM_GETDLGCODE:   return SendMessageA(pThis->hWndList,uMessage,0,0);
1364
1365           case WM_DESTROY:      if(GetShellOle())
1366                                 {
1367                                   pRevokeDragDrop(pThis->hWnd);
1368                                 }
1369                                 SHChangeNotifyDeregister(pThis->hNotify);
1370                                 break;
1371         }
1372
1373         return DefWindowProcA (hWnd, uMessage, wParam, lParam);
1374 }
1375 /**********************************************************
1376 *
1377 *
1378 *  The INTERFACE of the IShellView object
1379 *
1380 *
1381 **********************************************************
1382 *  IShellView_QueryInterface
1383 */
1384 static HRESULT WINAPI IShellView_fnQueryInterface(IShellView * iface,REFIID riid, LPVOID *ppvObj)
1385 {
1386         ICOM_THIS(IShellViewImpl, iface);
1387
1388         TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1389
1390         *ppvObj = NULL;
1391
1392         if(IsEqualIID(riid, &IID_IUnknown))
1393         {
1394           *ppvObj = This; 
1395         }
1396         else if(IsEqualIID(riid, &IID_IShellView))
1397         {
1398           *ppvObj = (IShellView*)This;
1399         }
1400         else if(IsEqualIID(riid, &IID_IOleCommandTarget))
1401         {
1402           *ppvObj = (IOleCommandTarget*)&(This->lpvtblOleCommandTarget);
1403         }
1404         else if(IsEqualIID(riid, &IID_IDropTarget))
1405         {
1406           *ppvObj = (IDropTarget*)&(This->lpvtblDropTarget);
1407         }
1408         else if(IsEqualIID(riid, &IID_IDropSource))
1409         {
1410           *ppvObj = (IDropSource*)&(This->lpvtblDropSource);
1411         }
1412         else if(IsEqualIID(riid, &IID_IViewObject))
1413         {
1414           *ppvObj = (IViewObject*)&(This->lpvtblViewObject);
1415         }
1416
1417         if(*ppvObj)
1418         {
1419           IUnknown_AddRef( (IUnknown*)*ppvObj );
1420           TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1421           return S_OK;
1422         }
1423         TRACE("-- Interface: E_NOINTERFACE\n");
1424         return E_NOINTERFACE;
1425 }
1426
1427 /**********************************************************
1428 *  IShellView_AddRef
1429 */
1430 static ULONG WINAPI IShellView_fnAddRef(IShellView * iface)
1431 {
1432         ICOM_THIS(IShellViewImpl, iface);
1433
1434         TRACE("(%p)->(count=%lu)\n",This,This->ref);
1435
1436         shell32_ObjCount++;
1437         return ++(This->ref);
1438 }
1439 /**********************************************************
1440 *  IShellView_Release
1441 */
1442 static ULONG WINAPI IShellView_fnRelease(IShellView * iface)
1443 {
1444         ICOM_THIS(IShellViewImpl, iface);
1445
1446         TRACE("(%p)->()\n",This);
1447
1448         shell32_ObjCount--;
1449
1450         if (!--(This->ref)) 
1451         {
1452           TRACE(" destroying IShellView(%p)\n",This);
1453
1454           if(This->pSFParent)
1455             IShellFolder_Release(This->pSFParent);
1456
1457           if(This->pSF2Parent)
1458             IShellFolder2_Release(This->pSF2Parent);
1459
1460           if (This->apidl)
1461             SHFree(This->apidl);
1462
1463           if (This->pCommDlgBrowser)
1464             ICommDlgBrowser_Release(This->pCommDlgBrowser);
1465
1466           HeapFree(GetProcessHeap(),0,This);
1467           return 0;
1468         }
1469         return This->ref;
1470 }
1471
1472 /**********************************************************
1473 *  ShellView_GetWindow
1474 */
1475 static HRESULT WINAPI IShellView_fnGetWindow(IShellView * iface,HWND * phWnd)
1476 {
1477         ICOM_THIS(IShellViewImpl, iface);
1478
1479         TRACE("(%p)\n",This);
1480
1481         *phWnd = This->hWnd;
1482
1483         return S_OK;
1484 }
1485
1486 static HRESULT WINAPI IShellView_fnContextSensitiveHelp(IShellView * iface,BOOL fEnterMode)
1487 {
1488         ICOM_THIS(IShellViewImpl, iface);
1489
1490         FIXME("(%p) stub\n",This);
1491
1492         return E_NOTIMPL;
1493 }
1494
1495 /**********************************************************
1496 * IShellView_TranslateAccelerator
1497 *
1498 * FIXME:
1499 *  use the accel functions
1500 */
1501 static HRESULT WINAPI IShellView_fnTranslateAccelerator(IShellView * iface,LPMSG lpmsg)
1502 {
1503 #if 0
1504         ICOM_THIS(IShellViewImpl, iface);
1505
1506         FIXME("(%p)->(%p: hwnd=%x msg=%x lp=%lx wp=%x) stub\n",This,lpmsg, lpmsg->hwnd, lpmsg->message, lpmsg->lParam, lpmsg->wParam);
1507 #endif
1508         
1509         if ((lpmsg->message>=WM_KEYFIRST) && (lpmsg->message>=WM_KEYLAST))
1510         {
1511           TRACE("-- key=0x04%x",lpmsg->wParam) ;
1512         }
1513         return S_FALSE; /* not handled */
1514 }
1515
1516 static HRESULT WINAPI IShellView_fnEnableModeless(IShellView * iface,BOOL fEnable)
1517 {
1518         ICOM_THIS(IShellViewImpl, iface);
1519
1520         FIXME("(%p) stub\n",This);
1521
1522         return E_NOTIMPL;
1523 }
1524
1525 static HRESULT WINAPI IShellView_fnUIActivate(IShellView * iface,UINT uState)
1526 {
1527         ICOM_THIS(IShellViewImpl, iface);
1528
1529 /*
1530         CHAR    szName[MAX_PATH];
1531 */
1532         LRESULT lResult;
1533         int     nPartArray[1] = {-1};
1534
1535         TRACE("(%p)->(state=%x) stub\n",This, uState);
1536
1537         /*don't do anything if the state isn't really changing*/
1538         if(This->uState == uState)
1539         {
1540           return S_OK;
1541         }
1542
1543         /*OnActivate handles the menu merging and internal state*/
1544         ShellView_OnActivate(This, uState);
1545
1546         /*only do This if we are active*/
1547         if(uState != SVUIA_DEACTIVATE)
1548         {
1549
1550 /*
1551           GetFolderPath is not a method of IShellFolder
1552           IShellFolder_GetFolderPath( This->pSFParent, szName, sizeof(szName) );
1553 */
1554           /* set the number of parts */
1555           IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETPARTS, 1,
1556                                                         (LPARAM)nPartArray, &lResult);
1557
1558           /* set the text for the parts */
1559 /*
1560           IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETTEXTA,
1561                                                         0, (LPARAM)szName, &lResult);
1562 */                                                      
1563         }
1564
1565         return S_OK;
1566 }
1567
1568 static HRESULT WINAPI IShellView_fnRefresh(IShellView * iface)
1569 {
1570         ICOM_THIS(IShellViewImpl, iface);
1571
1572         TRACE("(%p)\n",This);
1573
1574         ListView_DeleteAllItems(This->hWndList);
1575         ShellView_FillList(This);
1576
1577         return S_OK;
1578 }
1579
1580 static HRESULT WINAPI IShellView_fnCreateViewWindow(
1581         IShellView * iface,
1582         IShellView *lpPrevView,
1583         LPCFOLDERSETTINGS lpfs,
1584         IShellBrowser * psb,
1585         RECT * prcView,
1586         HWND  *phWnd)
1587 {
1588         ICOM_THIS(IShellViewImpl, iface);
1589
1590         WNDCLASSA wc;
1591         *phWnd = 0;
1592
1593         
1594         TRACE("(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n",This, lpPrevView,lpfs, psb, prcView, phWnd);
1595         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);
1596
1597         /*set up the member variables*/
1598         This->pShellBrowser = psb;
1599         This->FolderSettings = *lpfs;
1600
1601         /*get our parent window*/
1602         IShellBrowser_AddRef(This->pShellBrowser);
1603         IShellBrowser_GetWindow(This->pShellBrowser, &(This->hWndParent));
1604
1605         /* try to get the ICommDlgBrowserInterface, adds a reference !!! */
1606         This->pCommDlgBrowser=NULL;
1607         if ( SUCCEEDED (IShellBrowser_QueryInterface( This->pShellBrowser, 
1608                         (REFIID)&IID_ICommDlgBrowser, (LPVOID*) &This->pCommDlgBrowser)))
1609         {
1610           TRACE("-- CommDlgBrowser\n");
1611         }
1612
1613         /*if our window class has not been registered, then do so*/
1614         if(!GetClassInfoA(shell32_hInstance, SV_CLASS_NAME, &wc))
1615         {
1616           ZeroMemory(&wc, sizeof(wc));
1617           wc.style              = CS_HREDRAW | CS_VREDRAW;
1618           wc.lpfnWndProc        = (WNDPROC) ShellView_WndProc;
1619           wc.cbClsExtra         = 0;
1620           wc.cbWndExtra         = 0;
1621           wc.hInstance          = shell32_hInstance;
1622           wc.hIcon              = 0;
1623           wc.hCursor            = LoadCursorA (0, IDC_ARROWA);
1624           wc.hbrBackground      = (HBRUSH) (COLOR_WINDOW + 1);
1625           wc.lpszMenuName       = NULL;
1626           wc.lpszClassName      = SV_CLASS_NAME;
1627
1628           if(!RegisterClassA(&wc))
1629             return E_FAIL;
1630         }
1631
1632         *phWnd = CreateWindowExA(0,
1633                                 SV_CLASS_NAME,
1634                                 NULL,
1635                                 WS_CHILD | WS_VISIBLE | WS_TABSTOP,
1636                                 prcView->left,
1637                                 prcView->top,
1638                                 prcView->right - prcView->left,
1639                                 prcView->bottom - prcView->top,
1640                                 This->hWndParent,
1641                                 0,
1642                                 shell32_hInstance,
1643                                 (LPVOID)This);
1644
1645         CheckToolbar(This);
1646         
1647         if(!*phWnd) return E_FAIL;
1648
1649         return S_OK;
1650 }
1651
1652 static HRESULT WINAPI IShellView_fnDestroyViewWindow(IShellView * iface)
1653 {
1654         ICOM_THIS(IShellViewImpl, iface);
1655
1656         TRACE("(%p)\n",This);
1657
1658         /*Make absolutely sure all our UI is cleaned up.*/
1659         IShellView_UIActivate((IShellView*)This, SVUIA_DEACTIVATE);
1660
1661         if(This->hMenu)
1662         {
1663           DestroyMenu(This->hMenu);
1664         }
1665
1666         DestroyWindow(This->hWnd);
1667         IShellBrowser_Release(This->pShellBrowser);
1668
1669         return S_OK;
1670 }
1671
1672 static HRESULT WINAPI IShellView_fnGetCurrentInfo(IShellView * iface, LPFOLDERSETTINGS lpfs)
1673 {
1674         ICOM_THIS(IShellViewImpl, iface);
1675
1676         TRACE("(%p)->(%p) vmode=%x flags=%x\n",This, lpfs, 
1677                 This->FolderSettings.ViewMode, This->FolderSettings.fFlags);
1678
1679         if (!lpfs) return E_INVALIDARG;
1680
1681         *lpfs = This->FolderSettings;
1682         return NOERROR;
1683 }
1684
1685 static HRESULT WINAPI IShellView_fnAddPropertySheetPages(IShellView * iface, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam)
1686 {
1687         ICOM_THIS(IShellViewImpl, iface);
1688
1689         FIXME("(%p) stub\n",This);
1690
1691         return E_NOTIMPL;
1692 }
1693
1694 static HRESULT WINAPI IShellView_fnSaveViewState(IShellView * iface)
1695 {
1696         ICOM_THIS(IShellViewImpl, iface);
1697
1698         FIXME("(%p) stub\n",This);
1699
1700         return S_OK;
1701 }
1702
1703 static HRESULT WINAPI IShellView_fnSelectItem(
1704         IShellView * iface,
1705         LPCITEMIDLIST pidl,
1706         UINT uFlags)
1707 {
1708         ICOM_THIS(IShellViewImpl, iface);
1709         int i;
1710         
1711         TRACE("(%p)->(pidl=%p, 0x%08x) stub\n",This, pidl, uFlags);
1712         
1713         i = LV_FindItemByPidl(This, pidl);
1714
1715         if (i != -1)
1716         {
1717           LVITEMA lvItem;
1718           
1719           if(uFlags & SVSI_ENSUREVISIBLE)
1720             ListView_EnsureVisible(This->hWndList, i, 0);
1721
1722           ZeroMemory(&lvItem, sizeof(LVITEMA));
1723           lvItem.mask = LVIF_STATE;
1724           lvItem.iItem = 0;
1725
1726           while(ListView_GetItemA(This->hWndList, &lvItem))
1727           {
1728             if (lvItem.iItem == i)
1729             {
1730               if (uFlags & SVSI_SELECT)
1731                 lvItem.state |= LVIS_SELECTED;
1732               else
1733                 lvItem.state &= ~LVIS_SELECTED;
1734
1735               if(uFlags & SVSI_FOCUSED)
1736                 lvItem.state &= ~LVIS_FOCUSED;
1737             }
1738             else
1739             {
1740               if (uFlags & SVSI_DESELECTOTHERS)
1741                 lvItem.state &= ~LVIS_SELECTED;
1742             }
1743             ListView_SetItemA(This->hWndList, &lvItem);
1744             lvItem.iItem++;
1745           }
1746
1747
1748           if(uFlags & SVSI_EDIT)
1749             ListView_EditLabelA(This->hWndList, i);
1750
1751         }
1752         return S_OK;
1753 }
1754
1755 static HRESULT WINAPI IShellView_fnGetItemObject(IShellView * iface, UINT uItem, REFIID riid, LPVOID *ppvOut)
1756 {
1757         ICOM_THIS(IShellViewImpl, iface);
1758
1759         TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n",This, uItem, debugstr_guid(riid), ppvOut);
1760
1761         *ppvOut = NULL;
1762
1763         switch(uItem)
1764         {
1765           case SVGIO_BACKGROUND:
1766             *ppvOut = ISvBgCm_Constructor(This->pSFParent);
1767             break;
1768
1769           case SVGIO_SELECTION:
1770             ShellView_GetSelections(This);
1771             IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, This->apidl, riid, 0, ppvOut);
1772             break;
1773         }
1774         TRACE("-- (%p)->(interface=%p)\n",This, *ppvOut);
1775
1776         if(!*ppvOut) return E_OUTOFMEMORY;
1777
1778         return S_OK;
1779 }
1780
1781 static HRESULT WINAPI IShellView_fnEditItem(
1782         IShellView * iface,
1783         LPITEMIDLIST pidl)
1784 {
1785         ICOM_THIS(IShellViewImpl, iface);
1786         int i;
1787         
1788         TRACE("(%p)->(pidl=%p)\n",This, pidl);
1789         
1790         i = LV_FindItemByPidl(This, pidl);
1791         if (i != -1)
1792         {
1793           SetFocus(This->hWndList);
1794           ListView_EditLabelA(This->hWndList, i);
1795         }
1796         return S_OK;
1797 }
1798
1799 static struct ICOM_VTABLE(IShellView) svvt = 
1800 {       
1801         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1802         IShellView_fnQueryInterface,
1803         IShellView_fnAddRef,
1804         IShellView_fnRelease,
1805         IShellView_fnGetWindow,
1806         IShellView_fnContextSensitiveHelp,
1807         IShellView_fnTranslateAccelerator,
1808         IShellView_fnEnableModeless,
1809         IShellView_fnUIActivate,
1810         IShellView_fnRefresh,
1811         IShellView_fnCreateViewWindow,
1812         IShellView_fnDestroyViewWindow,
1813         IShellView_fnGetCurrentInfo,
1814         IShellView_fnAddPropertySheetPages,
1815         IShellView_fnSaveViewState,
1816         IShellView_fnSelectItem,
1817         IShellView_fnGetItemObject,
1818         IShellView_fnEditItem
1819 };
1820
1821
1822 /**********************************************************
1823  * ISVOleCmdTarget_QueryInterface (IUnknown)
1824  */
1825 static HRESULT WINAPI ISVOleCmdTarget_QueryInterface(
1826         IOleCommandTarget *     iface,
1827         REFIID                  iid,
1828         LPVOID*                 ppvObj)
1829 {
1830         _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
1831
1832         return IShellFolder_QueryInterface((IShellFolder*)This, iid, ppvObj);
1833 }
1834
1835 /**********************************************************
1836  * ISVOleCmdTarget_AddRef (IUnknown)
1837  */
1838 static ULONG WINAPI ISVOleCmdTarget_AddRef(
1839         IOleCommandTarget *     iface)
1840 {
1841         _ICOM_THIS_From_IOleCommandTarget(IShellFolder, iface);
1842
1843         return IShellFolder_AddRef((IShellFolder*)This);
1844 }
1845
1846 /**********************************************************
1847  * ISVOleCmdTarget_Release (IUnknown)
1848  */
1849 static ULONG WINAPI ISVOleCmdTarget_Release(
1850         IOleCommandTarget *     iface)
1851 {
1852         _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
1853
1854         return IShellFolder_Release((IShellFolder*)This);
1855 }
1856
1857 /**********************************************************
1858  * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
1859  */
1860 static HRESULT WINAPI ISVOleCmdTarget_QueryStatus(
1861         IOleCommandTarget *iface,
1862         const GUID* pguidCmdGroup,
1863         ULONG cCmds, 
1864         OLECMD * prgCmds,
1865         OLECMDTEXT* pCmdText)
1866 {
1867         _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
1868
1869         FIXME("(%p)->(%p(%s) 0x%08lx %p %p\n",
1870               This, pguidCmdGroup, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText);
1871         return E_NOTIMPL;
1872 }
1873
1874 /**********************************************************
1875  * ISVOleCmdTarget_Exec (IOleCommandTarget)
1876  *
1877  * nCmdID is the OLECMDID_* enumeration
1878  */
1879 static HRESULT WINAPI ISVOleCmdTarget_Exec(
1880         IOleCommandTarget *iface,
1881         const GUID* pguidCmdGroup,
1882         DWORD nCmdID,
1883         DWORD nCmdexecopt,
1884         VARIANT* pvaIn,
1885         VARIANT* pvaOut)
1886 {
1887         _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
1888
1889         FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08lx Opt:0x%08lx %p %p)\n",
1890               This, debugstr_guid(pguidCmdGroup), nCmdID, nCmdexecopt, pvaIn, pvaOut);
1891         return E_NOTIMPL;
1892 }
1893
1894 static ICOM_VTABLE(IOleCommandTarget) ctvt = 
1895 {
1896         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1897         ISVOleCmdTarget_QueryInterface,
1898         ISVOleCmdTarget_AddRef,
1899         ISVOleCmdTarget_Release,
1900         ISVOleCmdTarget_QueryStatus,
1901         ISVOleCmdTarget_Exec
1902 };
1903
1904 /**********************************************************
1905  * ISVDropTarget implementation
1906  */
1907
1908 static HRESULT WINAPI ISVDropTarget_QueryInterface(
1909         IDropTarget *iface,
1910         REFIID riid,
1911         LPVOID *ppvObj)
1912 {
1913         _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
1914
1915         TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1916
1917         return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
1918 }
1919
1920 static ULONG WINAPI ISVDropTarget_AddRef( IDropTarget *iface)
1921 {
1922         _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
1923
1924         TRACE("(%p)->(count=%lu)\n",This,This->ref);
1925
1926         return IShellFolder_AddRef((IShellFolder*)This);
1927 }
1928
1929 static ULONG WINAPI ISVDropTarget_Release( IDropTarget *iface)
1930 {
1931         _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
1932
1933         TRACE("(%p)->(count=%lu)\n",This,This->ref);
1934
1935         return IShellFolder_Release((IShellFolder*)This);
1936 }
1937
1938 static HRESULT WINAPI ISVDropTarget_DragEnter(
1939         IDropTarget     *iface,
1940         IDataObject     *pDataObject,
1941         DWORD           grfKeyState,
1942         POINTL          pt,
1943         DWORD           *pdwEffect)
1944 {       
1945
1946         _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
1947
1948         FIXME("Stub: This=%p, DataObject=%p\n",This,pDataObject);
1949
1950         return E_NOTIMPL;
1951 }
1952
1953 static HRESULT WINAPI ISVDropTarget_DragOver(
1954         IDropTarget     *iface,
1955         DWORD           grfKeyState,
1956         POINTL          pt,
1957         DWORD           *pdwEffect)
1958 {
1959         _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
1960
1961         FIXME("Stub: This=%p\n",This);
1962
1963         return E_NOTIMPL;
1964 }
1965
1966 static HRESULT WINAPI ISVDropTarget_DragLeave(
1967         IDropTarget     *iface)
1968 {
1969         _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
1970
1971         FIXME("Stub: This=%p\n",This);
1972
1973         return E_NOTIMPL;
1974 }
1975
1976 static HRESULT WINAPI ISVDropTarget_Drop(
1977         IDropTarget     *iface,
1978         IDataObject*    pDataObject,
1979         DWORD           grfKeyState,
1980         POINTL          pt,
1981         DWORD           *pdwEffect)
1982 {
1983         _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
1984
1985         FIXME("Stub: This=%p\n",This);
1986
1987         return E_NOTIMPL;
1988 }
1989
1990 static struct ICOM_VTABLE(IDropTarget) dtvt = 
1991 {
1992         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1993         ISVDropTarget_QueryInterface,
1994         ISVDropTarget_AddRef,
1995         ISVDropTarget_Release,
1996         ISVDropTarget_DragEnter,
1997         ISVDropTarget_DragOver,
1998         ISVDropTarget_DragLeave,
1999         ISVDropTarget_Drop
2000 };
2001
2002 /**********************************************************
2003  * ISVDropSource implementation
2004  */
2005
2006 static HRESULT WINAPI ISVDropSource_QueryInterface(
2007         IDropSource *iface,
2008         REFIID riid,
2009         LPVOID *ppvObj)
2010 {
2011         _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2012
2013         TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2014
2015         return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2016 }
2017
2018 static ULONG WINAPI ISVDropSource_AddRef( IDropSource *iface)
2019 {
2020         _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2021
2022         TRACE("(%p)->(count=%lu)\n",This,This->ref);
2023
2024         return IShellFolder_AddRef((IShellFolder*)This);
2025 }
2026
2027 static ULONG WINAPI ISVDropSource_Release( IDropSource *iface)
2028 {
2029         _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2030
2031         TRACE("(%p)->(count=%lu)\n",This,This->ref);
2032
2033         return IShellFolder_Release((IShellFolder*)This);
2034 }
2035 static HRESULT WINAPI ISVDropSource_QueryContinueDrag(
2036         IDropSource *iface,
2037         BOOL fEscapePressed,
2038         DWORD grfKeyState)
2039 {
2040         _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2041         TRACE("(%p)\n",This);
2042
2043         if (fEscapePressed)
2044           return DRAGDROP_S_CANCEL;
2045         else if (!(grfKeyState & MK_LBUTTON) && !(grfKeyState & MK_RBUTTON))
2046           return DRAGDROP_S_DROP;
2047         else
2048           return NOERROR;
2049 }
2050
2051 static HRESULT WINAPI ISVDropSource_GiveFeedback(
2052         IDropSource *iface,
2053         DWORD dwEffect)
2054 {
2055         _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2056         TRACE("(%p)\n",This);
2057
2058         return DRAGDROP_S_USEDEFAULTCURSORS;
2059 }
2060
2061 static struct ICOM_VTABLE(IDropSource) dsvt =
2062 {
2063         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2064         ISVDropSource_QueryInterface,
2065         ISVDropSource_AddRef,
2066         ISVDropSource_Release,
2067         ISVDropSource_QueryContinueDrag,
2068         ISVDropSource_GiveFeedback
2069 };
2070 /**********************************************************
2071  * ISVViewObject implementation
2072  */
2073
2074 static HRESULT WINAPI ISVViewObject_QueryInterface(
2075         IViewObject *iface,
2076         REFIID riid,
2077         LPVOID *ppvObj)
2078 {
2079         _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2080
2081         TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2082
2083         return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2084 }
2085
2086 static ULONG WINAPI ISVViewObject_AddRef( IViewObject *iface)
2087 {
2088         _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2089
2090         TRACE("(%p)->(count=%lu)\n",This,This->ref);
2091
2092         return IShellFolder_AddRef((IShellFolder*)This);
2093 }
2094
2095 static ULONG WINAPI ISVViewObject_Release( IViewObject *iface)
2096 {
2097         _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2098
2099         TRACE("(%p)->(count=%lu)\n",This,This->ref);
2100
2101         return IShellFolder_Release((IShellFolder*)This);
2102 }
2103
2104 static HRESULT WINAPI ISVViewObject_Draw(
2105         IViewObject     *iface,
2106         DWORD dwDrawAspect,
2107         LONG lindex,
2108         void* pvAspect,
2109         DVTARGETDEVICE* ptd,
2110         HDC hdcTargetDev,
2111         HDC hdcDraw,
2112         LPCRECTL lprcBounds,
2113         LPCRECTL lprcWBounds, 
2114         IVO_ContCallback pfnContinue,
2115         DWORD dwContinue)
2116 {       
2117
2118         _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2119
2120         FIXME("Stub: This=%p\n",This);
2121
2122         return E_NOTIMPL;
2123 }
2124 static HRESULT WINAPI ISVViewObject_GetColorSet(
2125         IViewObject     *iface,
2126         DWORD dwDrawAspect,
2127         LONG lindex,
2128         void *pvAspect,
2129         DVTARGETDEVICE* ptd,
2130         HDC hicTargetDevice,
2131         LOGPALETTE** ppColorSet)
2132 {       
2133
2134         _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2135
2136         FIXME("Stub: This=%p\n",This);
2137
2138         return E_NOTIMPL;
2139 }
2140 static HRESULT WINAPI ISVViewObject_Freeze(
2141         IViewObject     *iface,
2142         DWORD dwDrawAspect,
2143         LONG lindex,
2144         void* pvAspect,
2145         DWORD* pdwFreeze)
2146 {       
2147
2148         _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2149
2150         FIXME("Stub: This=%p\n",This);
2151
2152         return E_NOTIMPL;
2153 }
2154 static HRESULT WINAPI ISVViewObject_Unfreeze(
2155         IViewObject     *iface,
2156         DWORD dwFreeze)
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_SetAdvise(
2166         IViewObject     *iface,
2167         DWORD aspects,
2168         DWORD advf,
2169         IAdviseSink* pAdvSink)
2170 {       
2171
2172         _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2173
2174         FIXME("Stub: This=%p\n",This);
2175
2176         return E_NOTIMPL;
2177 }
2178 static HRESULT WINAPI ISVViewObject_GetAdvise(
2179         IViewObject     *iface,
2180         DWORD* pAspects,
2181         DWORD* pAdvf,
2182         IAdviseSink** ppAdvSink)
2183 {       
2184
2185         _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2186
2187         FIXME("Stub: This=%p\n",This);
2188
2189         return E_NOTIMPL;
2190 }
2191
2192
2193 static struct ICOM_VTABLE(IViewObject) vovt = 
2194 {
2195         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2196         ISVViewObject_QueryInterface,
2197         ISVViewObject_AddRef,
2198         ISVViewObject_Release,
2199         ISVViewObject_Draw,
2200         ISVViewObject_GetColorSet,
2201         ISVViewObject_Freeze,
2202         ISVViewObject_Unfreeze,
2203         ISVViewObject_SetAdvise,
2204         ISVViewObject_GetAdvise
2205 };
2206