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