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