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