Build most dlls as separate shared libraries.
[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             _ILGetFileAttributes(pItemIdList1, strName1, MAX_PATH);
421             _ILGetFileAttributes(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         TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1205
1206         *ppvObj = NULL;
1207
1208         if(IsEqualIID(riid, &IID_IUnknown))
1209         {
1210           *ppvObj = This; 
1211         }
1212         else if(IsEqualIID(riid, &IID_IShellView))
1213         {
1214           *ppvObj = (IShellView*)This;
1215         }
1216         else if(IsEqualIID(riid, &IID_IOleCommandTarget))
1217         {
1218           *ppvObj = (IOleCommandTarget*)&(This->lpvtblOleCommandTarget);
1219         }
1220         else if(IsEqualIID(riid, &IID_IDropTarget))
1221         {
1222           *ppvObj = (IDropTarget*)&(This->lpvtblDropTarget);
1223         }
1224         else if(IsEqualIID(riid, &IID_IDropSource))
1225         {
1226           *ppvObj = (IDropSource*)&(This->lpvtblDropSource);
1227         }
1228         else if(IsEqualIID(riid, &IID_IViewObject))
1229         {
1230           *ppvObj = (IViewObject*)&(This->lpvtblViewObject);
1231         }
1232
1233         if(*ppvObj)
1234         {
1235           IUnknown_AddRef( (IUnknown*)*ppvObj );
1236           TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1237           return S_OK;
1238         }
1239         TRACE("-- Interface: E_NOINTERFACE\n");
1240         return E_NOINTERFACE;
1241 }
1242
1243 /**********************************************************
1244 *  IShellView_AddRef
1245 */
1246 static ULONG WINAPI IShellView_fnAddRef(IShellView * iface)
1247 {
1248         ICOM_THIS(IShellViewImpl, iface);
1249
1250         TRACE("(%p)->(count=%lu)\n",This,This->ref);
1251
1252         shell32_ObjCount++;
1253         return ++(This->ref);
1254 }
1255 /**********************************************************
1256 *  IShellView_Release
1257 */
1258 static ULONG WINAPI IShellView_fnRelease(IShellView * iface)
1259 {
1260         ICOM_THIS(IShellViewImpl, iface);
1261
1262         TRACE("(%p)->()\n",This);
1263
1264         shell32_ObjCount--;
1265
1266         if (!--(This->ref)) 
1267         {
1268           TRACE(" destroying IShellView(%p)\n",This);
1269
1270           if(This->pSFParent)
1271             IShellFolder_Release(This->pSFParent);
1272
1273           if(This->pSF2Parent)
1274             IShellFolder2_Release(This->pSF2Parent);
1275
1276           if (This->apidl)
1277             SHFree(This->apidl);
1278
1279           if (This->pCommDlgBrowser)
1280             ICommDlgBrowser_Release(This->pCommDlgBrowser);
1281
1282           HeapFree(GetProcessHeap(),0,This);
1283           return 0;
1284         }
1285         return This->ref;
1286 }
1287
1288 /**********************************************************
1289 *  ShellView_GetWindow
1290 */
1291 static HRESULT WINAPI IShellView_fnGetWindow(IShellView * iface,HWND * phWnd)
1292 {
1293         ICOM_THIS(IShellViewImpl, iface);
1294
1295         TRACE("(%p)\n",This);
1296
1297         *phWnd = This->hWnd;
1298
1299         return S_OK;
1300 }
1301
1302 static HRESULT WINAPI IShellView_fnContextSensitiveHelp(IShellView * iface,BOOL fEnterMode)
1303 {
1304         ICOM_THIS(IShellViewImpl, iface);
1305
1306         FIXME("(%p) stub\n",This);
1307
1308         return E_NOTIMPL;
1309 }
1310
1311 /**********************************************************
1312 * IShellView_TranslateAccelerator
1313 *
1314 * FIXME:
1315 *  use the accel functions
1316 */
1317 static HRESULT WINAPI IShellView_fnTranslateAccelerator(IShellView * iface,LPMSG lpmsg)
1318 {
1319 #if 0
1320         ICOM_THIS(IShellViewImpl, iface);
1321
1322         FIXME("(%p)->(%p: hwnd=%x msg=%x lp=%lx wp=%x) stub\n",This,lpmsg, lpmsg->hwnd, lpmsg->message, lpmsg->lParam, lpmsg->wParam);
1323 #endif
1324         
1325         if ((lpmsg->message>=WM_KEYFIRST) && (lpmsg->message>=WM_KEYLAST))
1326         {
1327           TRACE("-- key=0x04%x",lpmsg->wParam) ;
1328         }
1329         return S_FALSE; /* not handled */
1330 }
1331
1332 static HRESULT WINAPI IShellView_fnEnableModeless(IShellView * iface,BOOL fEnable)
1333 {
1334         ICOM_THIS(IShellViewImpl, iface);
1335
1336         FIXME("(%p) stub\n",This);
1337
1338         return E_NOTIMPL;
1339 }
1340
1341 static HRESULT WINAPI IShellView_fnUIActivate(IShellView * iface,UINT uState)
1342 {
1343         ICOM_THIS(IShellViewImpl, iface);
1344
1345 /*
1346         CHAR    szName[MAX_PATH];
1347 */
1348         LRESULT lResult;
1349         int     nPartArray[1] = {-1};
1350
1351         TRACE("(%p)->(state=%x) stub\n",This, uState);
1352
1353         /*don't do anything if the state isn't really changing*/
1354         if(This->uState == uState)
1355         {
1356           return S_OK;
1357         }
1358
1359         /*OnActivate handles the menu merging and internal state*/
1360         ShellView_OnActivate(This, uState);
1361
1362         /*only do This if we are active*/
1363         if(uState != SVUIA_DEACTIVATE)
1364         {
1365
1366 /*
1367           GetFolderPath is not a method of IShellFolder
1368           IShellFolder_GetFolderPath( This->pSFParent, szName, sizeof(szName) );
1369 */
1370           /* set the number of parts */
1371           IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETPARTS, 1,
1372                                                         (LPARAM)nPartArray, &lResult);
1373
1374           /* set the text for the parts */
1375 /*
1376           IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETTEXTA,
1377                                                         0, (LPARAM)szName, &lResult);
1378 */                                                      
1379         }
1380
1381         return S_OK;
1382 }
1383
1384 static HRESULT WINAPI IShellView_fnRefresh(IShellView * iface)
1385 {
1386         ICOM_THIS(IShellViewImpl, iface);
1387
1388         TRACE("(%p)\n",This);
1389
1390         ListView_DeleteAllItems(This->hWndList);
1391         ShellView_FillList(This);
1392
1393         return S_OK;
1394 }
1395
1396 static HRESULT WINAPI IShellView_fnCreateViewWindow(
1397         IShellView * iface,
1398         IShellView *lpPrevView,
1399         LPCFOLDERSETTINGS lpfs,
1400         IShellBrowser * psb,
1401         RECT * prcView,
1402         HWND  *phWnd)
1403 {
1404         ICOM_THIS(IShellViewImpl, iface);
1405
1406         WNDCLASSA wc;
1407         *phWnd = 0;
1408
1409         
1410         TRACE("(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n",This, lpPrevView,lpfs, psb, prcView, phWnd);
1411         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);
1412
1413         /*set up the member variables*/
1414         This->pShellBrowser = psb;
1415         This->FolderSettings = *lpfs;
1416
1417         /*get our parent window*/
1418         IShellBrowser_AddRef(This->pShellBrowser);
1419         IShellBrowser_GetWindow(This->pShellBrowser, &(This->hWndParent));
1420
1421         /* try to get the ICommDlgBrowserInterface, adds a reference !!! */
1422         This->pCommDlgBrowser=NULL;
1423         if ( SUCCEEDED (IShellBrowser_QueryInterface( This->pShellBrowser, 
1424                         (REFIID)&IID_ICommDlgBrowser, (LPVOID*) &This->pCommDlgBrowser)))
1425         {
1426           TRACE("-- CommDlgBrowser\n");
1427         }
1428
1429         /*if our window class has not been registered, then do so*/
1430         if(!GetClassInfoA(shell32_hInstance, SV_CLASS_NAME, &wc))
1431         {
1432           ZeroMemory(&wc, sizeof(wc));
1433           wc.style              = CS_HREDRAW | CS_VREDRAW;
1434           wc.lpfnWndProc        = (WNDPROC) ShellView_WndProc;
1435           wc.cbClsExtra         = 0;
1436           wc.cbWndExtra         = 0;
1437           wc.hInstance          = shell32_hInstance;
1438           wc.hIcon              = 0;
1439           wc.hCursor            = LoadCursorA (0, IDC_ARROWA);
1440           wc.hbrBackground      = (HBRUSH) (COLOR_WINDOW + 1);
1441           wc.lpszMenuName       = NULL;
1442           wc.lpszClassName      = SV_CLASS_NAME;
1443
1444           if(!RegisterClassA(&wc))
1445             return E_FAIL;
1446         }
1447
1448         *phWnd = CreateWindowExA(0,
1449                                 SV_CLASS_NAME,
1450                                 NULL,
1451                                 WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_TABSTOP,
1452                                 prcView->left,
1453                                 prcView->top,
1454                                 prcView->right - prcView->left,
1455                                 prcView->bottom - prcView->top,
1456                                 This->hWndParent,
1457                                 0,
1458                                 shell32_hInstance,
1459                                 (LPVOID)This);
1460
1461         CheckToolbar(This);
1462         
1463         if(!*phWnd)
1464           return E_FAIL;
1465
1466         return S_OK;
1467 }
1468
1469 static HRESULT WINAPI IShellView_fnDestroyViewWindow(IShellView * iface)
1470 {
1471         ICOM_THIS(IShellViewImpl, iface);
1472
1473         TRACE("(%p)\n",This);
1474
1475         /*Make absolutely sure all our UI is cleaned up.*/
1476         IShellView_UIActivate((IShellView*)This, SVUIA_DEACTIVATE);
1477
1478         if(This->hMenu)
1479         {
1480           DestroyMenu(This->hMenu);
1481         }
1482
1483         DestroyWindow(This->hWnd);
1484         IShellBrowser_Release(This->pShellBrowser);
1485
1486         return S_OK;
1487 }
1488
1489 static HRESULT WINAPI IShellView_fnGetCurrentInfo(IShellView * iface, LPFOLDERSETTINGS lpfs)
1490 {
1491         ICOM_THIS(IShellViewImpl, iface);
1492
1493         TRACE("(%p)->(%p) vmode=%x flags=%x\n",This, lpfs, 
1494                 This->FolderSettings.ViewMode, This->FolderSettings.fFlags);
1495
1496         if (!lpfs) return E_INVALIDARG;
1497
1498         *lpfs = This->FolderSettings;
1499         return NOERROR;
1500 }
1501
1502 static HRESULT WINAPI IShellView_fnAddPropertySheetPages(IShellView * iface, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam)
1503 {
1504         ICOM_THIS(IShellViewImpl, iface);
1505
1506         FIXME("(%p) stub\n",This);
1507
1508         return E_NOTIMPL;
1509 }
1510
1511 static HRESULT WINAPI IShellView_fnSaveViewState(IShellView * iface)
1512 {
1513         ICOM_THIS(IShellViewImpl, iface);
1514
1515         FIXME("(%p) stub\n",This);
1516
1517         return S_OK;
1518 }
1519
1520 static HRESULT WINAPI IShellView_fnSelectItem(IShellView * iface, LPCITEMIDLIST pidlItem, UINT uFlags)
1521 {       ICOM_THIS(IShellViewImpl, iface);
1522         
1523         FIXME("(%p)->(pidl=%p, 0x%08x) stub\n",This, pidlItem, uFlags);
1524
1525         return E_NOTIMPL;
1526 }
1527
1528 static HRESULT WINAPI IShellView_fnGetItemObject(IShellView * iface, UINT uItem, REFIID riid, LPVOID *ppvOut)
1529 {
1530         ICOM_THIS(IShellViewImpl, iface);
1531
1532         TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n",This, uItem, debugstr_guid(riid), ppvOut);
1533
1534         *ppvOut = NULL;
1535
1536         switch(uItem)
1537         {
1538           case SVGIO_BACKGROUND:
1539             *ppvOut = ISvBgCm_Constructor();
1540             break;
1541
1542           case SVGIO_SELECTION:
1543             ShellView_GetSelections(This);
1544             IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, This->apidl, riid, 0, ppvOut);
1545             break;
1546         }
1547         TRACE("-- (%p)->(interface=%p)\n",This, *ppvOut);
1548
1549         if(!*ppvOut) return E_OUTOFMEMORY;
1550
1551         return S_OK;
1552 }
1553
1554 static struct ICOM_VTABLE(IShellView) svvt = 
1555 {       
1556         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1557         IShellView_fnQueryInterface,
1558         IShellView_fnAddRef,
1559         IShellView_fnRelease,
1560         IShellView_fnGetWindow,
1561         IShellView_fnContextSensitiveHelp,
1562         IShellView_fnTranslateAccelerator,
1563         IShellView_fnEnableModeless,
1564         IShellView_fnUIActivate,
1565         IShellView_fnRefresh,
1566         IShellView_fnCreateViewWindow,
1567         IShellView_fnDestroyViewWindow,
1568         IShellView_fnGetCurrentInfo,
1569         IShellView_fnAddPropertySheetPages,
1570         IShellView_fnSaveViewState,
1571         IShellView_fnSelectItem,
1572         IShellView_fnGetItemObject
1573 };
1574
1575
1576 /**********************************************************
1577  * ISVOleCmdTarget_QueryInterface (IUnknown)
1578  */
1579 static HRESULT WINAPI ISVOleCmdTarget_QueryInterface(
1580         IOleCommandTarget *     iface,
1581         REFIID                  iid,
1582         LPVOID*                 ppvObj)
1583 {
1584         _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
1585
1586         return IShellFolder_QueryInterface((IShellFolder*)This, iid, ppvObj);
1587 }
1588
1589 /**********************************************************
1590  * ISVOleCmdTarget_AddRef (IUnknown)
1591  */
1592 static ULONG WINAPI ISVOleCmdTarget_AddRef(
1593         IOleCommandTarget *     iface)
1594 {
1595         _ICOM_THIS_From_IOleCommandTarget(IShellFolder, iface);
1596
1597         return IShellFolder_AddRef((IShellFolder*)This);
1598 }
1599
1600 /**********************************************************
1601  * ISVOleCmdTarget_Release (IUnknown)
1602  */
1603 static ULONG WINAPI ISVOleCmdTarget_Release(
1604         IOleCommandTarget *     iface)
1605 {
1606         _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
1607
1608         return IShellFolder_Release((IShellFolder*)This);
1609 }
1610
1611 /**********************************************************
1612  * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
1613  */
1614 static HRESULT WINAPI ISVOleCmdTarget_QueryStatus(
1615         IOleCommandTarget *iface,
1616         const GUID* pguidCmdGroup,
1617         ULONG cCmds, 
1618         OLECMD * prgCmds,
1619         OLECMDTEXT* pCmdText)
1620 {
1621         _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
1622
1623         FIXME("(%p)->(%p(%s) 0x%08lx %p %p\n",
1624               This, pguidCmdGroup, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText);
1625         return E_NOTIMPL;
1626 }
1627
1628 /**********************************************************
1629  * ISVOleCmdTarget_Exec (IOleCommandTarget)
1630  *
1631  * nCmdID is the OLECMDID_* enumeration
1632  */
1633 static HRESULT WINAPI ISVOleCmdTarget_Exec(
1634         IOleCommandTarget *iface,
1635         const GUID* pguidCmdGroup,
1636         DWORD nCmdID,
1637         DWORD nCmdexecopt,
1638         VARIANT* pvaIn,
1639         VARIANT* pvaOut)
1640 {
1641         _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
1642
1643         FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08lx Opt:0x%08lx %p %p)\n",
1644               This, debugstr_guid(pguidCmdGroup), nCmdID, nCmdexecopt, pvaIn, pvaOut);
1645         return E_NOTIMPL;
1646 }
1647
1648 static ICOM_VTABLE(IOleCommandTarget) ctvt = 
1649 {
1650         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1651         ISVOleCmdTarget_QueryInterface,
1652         ISVOleCmdTarget_AddRef,
1653         ISVOleCmdTarget_Release,
1654         ISVOleCmdTarget_QueryStatus,
1655         ISVOleCmdTarget_Exec
1656 };
1657
1658 /**********************************************************
1659  * ISVDropTarget implementation
1660  */
1661
1662 static HRESULT WINAPI ISVDropTarget_QueryInterface(
1663         IDropTarget *iface,
1664         REFIID riid,
1665         LPVOID *ppvObj)
1666 {
1667         _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
1668
1669         TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1670
1671         return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
1672 }
1673
1674 static ULONG WINAPI ISVDropTarget_AddRef( IDropTarget *iface)
1675 {
1676         _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
1677
1678         TRACE("(%p)->(count=%lu)\n",This,This->ref);
1679
1680         return IShellFolder_AddRef((IShellFolder*)This);
1681 }
1682
1683 static ULONG WINAPI ISVDropTarget_Release( IDropTarget *iface)
1684 {
1685         _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
1686
1687         TRACE("(%p)->(count=%lu)\n",This,This->ref);
1688
1689         return IShellFolder_Release((IShellFolder*)This);
1690 }
1691
1692 static HRESULT WINAPI ISVDropTarget_DragEnter(
1693         IDropTarget     *iface,
1694         IDataObject     *pDataObject,
1695         DWORD           grfKeyState,
1696         POINTL          pt,
1697         DWORD           *pdwEffect)
1698 {       
1699
1700         _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
1701
1702         FIXME("Stub: This=%p, DataObject=%p\n",This,pDataObject);
1703
1704         return E_NOTIMPL;
1705 }
1706
1707 static HRESULT WINAPI ISVDropTarget_DragOver(
1708         IDropTarget     *iface,
1709         DWORD           grfKeyState,
1710         POINTL          pt,
1711         DWORD           *pdwEffect)
1712 {
1713         _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
1714
1715         FIXME("Stub: This=%p\n",This);
1716
1717         return E_NOTIMPL;
1718 }
1719
1720 static HRESULT WINAPI ISVDropTarget_DragLeave(
1721         IDropTarget     *iface)
1722 {
1723         _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
1724
1725         FIXME("Stub: This=%p\n",This);
1726
1727         return E_NOTIMPL;
1728 }
1729
1730 static HRESULT WINAPI ISVDropTarget_Drop(
1731         IDropTarget     *iface,
1732         IDataObject*    pDataObject,
1733         DWORD           grfKeyState,
1734         POINTL          pt,
1735         DWORD           *pdwEffect)
1736 {
1737         _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
1738
1739         FIXME("Stub: This=%p\n",This);
1740
1741         return E_NOTIMPL;
1742 }
1743
1744 static struct ICOM_VTABLE(IDropTarget) dtvt = 
1745 {
1746         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1747         ISVDropTarget_QueryInterface,
1748         ISVDropTarget_AddRef,
1749         ISVDropTarget_Release,
1750         ISVDropTarget_DragEnter,
1751         ISVDropTarget_DragOver,
1752         ISVDropTarget_DragLeave,
1753         ISVDropTarget_Drop
1754 };
1755
1756 /**********************************************************
1757  * ISVDropSource implementation
1758  */
1759
1760 static HRESULT WINAPI ISVDropSource_QueryInterface(
1761         IDropSource *iface,
1762         REFIID riid,
1763         LPVOID *ppvObj)
1764 {
1765         _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
1766
1767         TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1768
1769         return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
1770 }
1771
1772 static ULONG WINAPI ISVDropSource_AddRef( IDropSource *iface)
1773 {
1774         _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
1775
1776         TRACE("(%p)->(count=%lu)\n",This,This->ref);
1777
1778         return IShellFolder_AddRef((IShellFolder*)This);
1779 }
1780
1781 static ULONG WINAPI ISVDropSource_Release( IDropSource *iface)
1782 {
1783         _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
1784
1785         TRACE("(%p)->(count=%lu)\n",This,This->ref);
1786
1787         return IShellFolder_Release((IShellFolder*)This);
1788 }
1789 static HRESULT WINAPI ISVDropSource_QueryContinueDrag(
1790         IDropSource *iface,
1791         BOOL fEscapePressed,
1792         DWORD grfKeyState)
1793 {
1794         _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
1795         TRACE("(%p)\n",This);
1796
1797         if (fEscapePressed)
1798           return DRAGDROP_S_CANCEL;
1799         else if (!(grfKeyState & MK_LBUTTON) && !(grfKeyState & MK_RBUTTON))
1800           return DRAGDROP_S_DROP;
1801         else
1802           return NOERROR;
1803 }
1804
1805 static HRESULT WINAPI ISVDropSource_GiveFeedback(
1806         IDropSource *iface,
1807         DWORD dwEffect)
1808 {
1809         _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
1810         TRACE("(%p)\n",This);
1811
1812         return DRAGDROP_S_USEDEFAULTCURSORS;
1813 }
1814
1815 static struct ICOM_VTABLE(IDropSource) dsvt =
1816 {
1817         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1818         ISVDropSource_QueryInterface,
1819         ISVDropSource_AddRef,
1820         ISVDropSource_Release,
1821         ISVDropSource_QueryContinueDrag,
1822         ISVDropSource_GiveFeedback
1823 };
1824 /**********************************************************
1825  * ISVViewObject implementation
1826  */
1827
1828 static HRESULT WINAPI ISVViewObject_QueryInterface(
1829         IViewObject *iface,
1830         REFIID riid,
1831         LPVOID *ppvObj)
1832 {
1833         _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
1834
1835         TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1836
1837         return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
1838 }
1839
1840 static ULONG WINAPI ISVViewObject_AddRef( IViewObject *iface)
1841 {
1842         _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
1843
1844         TRACE("(%p)->(count=%lu)\n",This,This->ref);
1845
1846         return IShellFolder_AddRef((IShellFolder*)This);
1847 }
1848
1849 static ULONG WINAPI ISVViewObject_Release( IViewObject *iface)
1850 {
1851         _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
1852
1853         TRACE("(%p)->(count=%lu)\n",This,This->ref);
1854
1855         return IShellFolder_Release((IShellFolder*)This);
1856 }
1857
1858 static HRESULT WINAPI ISVViewObject_Draw(
1859         IViewObject     *iface,
1860         DWORD dwDrawAspect,
1861         LONG lindex,
1862         void* pvAspect,
1863         DVTARGETDEVICE* ptd,
1864         HDC hdcTargetDev,
1865         HDC hdcDraw,
1866         LPCRECTL lprcBounds,
1867         LPCRECTL lprcWBounds, 
1868         IVO_ContCallback pfnContinue,
1869         DWORD dwContinue)
1870 {       
1871
1872         _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
1873
1874         FIXME("Stub: This=%p\n",This);
1875
1876         return E_NOTIMPL;
1877 }
1878 static HRESULT WINAPI ISVViewObject_GetColorSet(
1879         IViewObject     *iface,
1880         DWORD dwDrawAspect,
1881         LONG lindex,
1882         void *pvAspect,
1883         DVTARGETDEVICE* ptd,
1884         HDC hicTargetDevice,
1885         LOGPALETTE** ppColorSet)
1886 {       
1887
1888         _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
1889
1890         FIXME("Stub: This=%p\n",This);
1891
1892         return E_NOTIMPL;
1893 }
1894 static HRESULT WINAPI ISVViewObject_Freeze(
1895         IViewObject     *iface,
1896         DWORD dwDrawAspect,
1897         LONG lindex,
1898         void* pvAspect,
1899         DWORD* pdwFreeze)
1900 {       
1901
1902         _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
1903
1904         FIXME("Stub: This=%p\n",This);
1905
1906         return E_NOTIMPL;
1907 }
1908 static HRESULT WINAPI ISVViewObject_Unfreeze(
1909         IViewObject     *iface,
1910         DWORD dwFreeze)
1911 {       
1912
1913         _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
1914
1915         FIXME("Stub: This=%p\n",This);
1916
1917         return E_NOTIMPL;
1918 }
1919 static HRESULT WINAPI ISVViewObject_SetAdvise(
1920         IViewObject     *iface,
1921         DWORD aspects,
1922         DWORD advf,
1923         IAdviseSink* pAdvSink)
1924 {       
1925
1926         _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
1927
1928         FIXME("Stub: This=%p\n",This);
1929
1930         return E_NOTIMPL;
1931 }
1932 static HRESULT WINAPI ISVViewObject_GetAdvise(
1933         IViewObject     *iface,
1934         DWORD* pAspects,
1935         DWORD* pAdvf,
1936         IAdviseSink** ppAdvSink)
1937 {       
1938
1939         _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
1940
1941         FIXME("Stub: This=%p\n",This);
1942
1943         return E_NOTIMPL;
1944 }
1945
1946
1947 static struct ICOM_VTABLE(IViewObject) vovt = 
1948 {
1949         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1950         ISVViewObject_QueryInterface,
1951         ISVViewObject_AddRef,
1952         ISVViewObject_Release,
1953         ISVViewObject_Draw,
1954         ISVViewObject_GetColorSet,
1955         ISVViewObject_Freeze,
1956         ISVViewObject_Unfreeze,
1957         ISVViewObject_SetAdvise,
1958         ISVViewObject_GetAdvise
1959 };
1960