4 * Copyright 1998,1999 <juergen.schmied@debitel.net>
6 * This is the view visualizing the data provided by the shellfolder.
7 * No direct access to data from pidls should be done from here.
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.
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.
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 * FIXME: The order by part of the background context menu should be
24 * built according to the columns shown.
26 * FIXME: Load/Save the view state from/into the stream provided by
29 * FIXME: CheckToolbar: handle the "new folder" and "folder up" button
31 * FIXME: ShellView_FillList: consider sort orders
33 * FIXME: implement the drag and drop in the old (msg-based) way
35 * FIXME: when the ShellView_WndProc gets a WM_NCDESTROY should we do a
40 #include "wine/port.h"
47 #define NONAMELESSUNION
48 #define NONAMELESSSTRUCT
61 #include "undocshell.h"
63 #include "wine/debug.h"
67 #include "shell32_main.h"
68 #include "shellfolder.h"
70 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
72 static const WCHAR SV_CLASS_NAME
[] = {'S','H','E','L','L','D','L','L','_','D','e','f','V','i','e','w',0};
78 }LISTVIEW_SORT_INFO
, *LPLISTVIEW_SORT_INFO
;
82 IShellView2 IShellView2_iface
;
83 IOleCommandTarget IOleCommandTarget_iface
;
84 IDropTarget IDropTarget_iface
;
85 IDropSource IDropSource_iface
;
86 IViewObject IViewObject_iface
;
87 IFolderView IFolderView_iface
;
88 IShellFolderView IShellFolderView_iface
;
90 IShellFolder
* pSFParent
;
91 IShellFolder2
* pSF2Parent
;
92 IShellBrowser
* pShellBrowser
;
93 ICommDlgBrowser
* pCommDlgBrowser
;
94 HWND hWnd
; /* SHELLDLL_DefView */
95 HWND hWndList
; /* ListView control */
97 FOLDERSETTINGS FolderSettings
;
102 LISTVIEW_SORT_INFO ListViewSortInfo
;
103 ULONG hNotify
; /* change notification handle */
107 IAdviseSink
*pAdvSink
;
108 IDropTarget
* pCurDropTarget
; /* The sub-item, which is currently dragged over */
109 IDataObject
* pCurDataObject
; /* The dragged data-object */
110 LONG iDragOverItem
; /* Dragged over item's index, iff pCurDropTarget != NULL */
111 UINT cScrollDelay
; /* Send a WM_*SCROLL msg every 250 ms during drag-scroll */
112 POINT ptLastMousePos
; /* Mouse position at last DragOver call */
115 static const IShellView2Vtbl svvt
;
116 static const IOleCommandTargetVtbl ctvt
;
117 static const IDropTargetVtbl dtvt
;
118 static const IDropSourceVtbl dsvt
;
119 static const IViewObjectVtbl vovt
;
120 static const IFolderViewVtbl fviewvt
;
121 static const IShellFolderViewVtbl shellfolderviewvt
;
123 static inline IShellViewImpl
*impl_from_IShellView2(IShellView2
*iface
)
125 return CONTAINING_RECORD(iface
, IShellViewImpl
, IShellView2_iface
);
128 static inline IShellViewImpl
*impl_from_IOleCommandTarget(IOleCommandTarget
*iface
)
130 return CONTAINING_RECORD(iface
, IShellViewImpl
, IOleCommandTarget_iface
);
133 static inline IShellViewImpl
*impl_from_IDropTarget(IDropTarget
*iface
)
135 return CONTAINING_RECORD(iface
, IShellViewImpl
, IDropTarget_iface
);
138 static inline IShellViewImpl
*impl_from_IDropSource(IDropSource
*iface
)
140 return CONTAINING_RECORD(iface
, IShellViewImpl
, IDropSource_iface
);
143 static inline IShellViewImpl
*impl_from_IViewObject(IViewObject
*iface
)
145 return CONTAINING_RECORD(iface
, IShellViewImpl
, IViewObject_iface
);
148 static inline IShellViewImpl
*impl_from_IFolderView(IFolderView
*iface
)
150 return CONTAINING_RECORD(iface
, IShellViewImpl
, IFolderView_iface
);
153 static inline IShellViewImpl
*impl_from_IShellFolderView(IShellFolderView
*iface
)
155 return CONTAINING_RECORD(iface
, IShellViewImpl
, IShellFolderView_iface
);
158 /* ListView Header ID's */
159 #define LISTVIEW_COLUMN_NAME 0
160 #define LISTVIEW_COLUMN_SIZE 1
161 #define LISTVIEW_COLUMN_TYPE 2
162 #define LISTVIEW_COLUMN_TIME 3
163 #define LISTVIEW_COLUMN_ATTRIB 4
166 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
167 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
168 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
170 #define ID_LISTVIEW 1
172 #define SHV_CHANGE_NOTIFY WM_USER + 0x1111
175 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
176 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
177 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
180 Items merged into the toolbar and the filemenu
189 } MYTOOLINFO
, *LPMYTOOLINFO
;
191 static const MYTOOLINFO Tools
[] =
193 { FCIDM_SHVIEW_BIGICON
, 0, 0, IDS_VIEW_LARGE
, TBSTATE_ENABLED
, BTNS_BUTTON
},
194 { FCIDM_SHVIEW_SMALLICON
, 0, 0, IDS_VIEW_SMALL
, TBSTATE_ENABLED
, BTNS_BUTTON
},
195 { FCIDM_SHVIEW_LISTVIEW
, 0, 0, IDS_VIEW_LIST
, TBSTATE_ENABLED
, BTNS_BUTTON
},
196 { FCIDM_SHVIEW_REPORTVIEW
, 0, 0, IDS_VIEW_DETAILS
, TBSTATE_ENABLED
, BTNS_BUTTON
},
200 typedef void (CALLBACK
*PFNSHGETSETTINGSPROC
)(LPSHELLFLAGSTATE lpsfs
, DWORD dwMask
);
202 /**********************************************************
203 * IShellView_Constructor
205 IShellView
* IShellView_Constructor( IShellFolder
* pFolder
)
206 { IShellViewImpl
* sv
;
207 sv
=HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IShellViewImpl
));
209 sv
->IShellView2_iface
.lpVtbl
= &svvt
;
210 sv
->IOleCommandTarget_iface
.lpVtbl
= &ctvt
;
211 sv
->IDropTarget_iface
.lpVtbl
= &dtvt
;
212 sv
->IDropSource_iface
.lpVtbl
= &dsvt
;
213 sv
->IViewObject_iface
.lpVtbl
= &vovt
;
214 sv
->IFolderView_iface
.lpVtbl
= &fviewvt
;
215 sv
->IShellFolderView_iface
.lpVtbl
= &shellfolderviewvt
;
217 sv
->pSFParent
= pFolder
;
218 if(pFolder
) IShellFolder_AddRef(pFolder
);
219 IShellFolder_QueryInterface(sv
->pSFParent
, &IID_IShellFolder2
, (LPVOID
*)&sv
->pSF2Parent
);
221 sv
->pCurDropTarget
= NULL
;
222 sv
->pCurDataObject
= NULL
;
223 sv
->iDragOverItem
= 0;
224 sv
->cScrollDelay
= 0;
225 sv
->ptLastMousePos
.x
= 0;
226 sv
->ptLastMousePos
.y
= 0;
228 TRACE("(%p)->(%p)\n",sv
, pFolder
);
229 return (IShellView
*) sv
;
232 /**********************************************************
234 * ##### helperfunctions for communication with ICommDlgBrowser #####
236 static BOOL
IsInCommDlg(IShellViewImpl
* This
)
237 { return(This
->pCommDlgBrowser
!= NULL
);
240 static HRESULT
IncludeObject(IShellViewImpl
* This
, LPCITEMIDLIST pidl
)
244 if ( IsInCommDlg(This
) )
246 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl
);
247 ret
= ICommDlgBrowser_IncludeObject(This
->pCommDlgBrowser
, (IShellView
*)This
, pidl
);
248 TRACE("--0x%08x\n", ret
);
253 static HRESULT
OnDefaultCommand(IShellViewImpl
* This
)
255 HRESULT ret
= S_FALSE
;
257 if (IsInCommDlg(This
))
259 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
260 ret
= ICommDlgBrowser_OnDefaultCommand(This
->pCommDlgBrowser
, (IShellView
*)This
);
261 TRACE("-- returns %08x\n", ret
);
266 static HRESULT
OnStateChange(IShellViewImpl
* This
, UINT uFlags
)
268 HRESULT ret
= S_FALSE
;
270 if (IsInCommDlg(This
))
272 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags
);
273 ret
= ICommDlgBrowser_OnStateChange(This
->pCommDlgBrowser
, (IShellView
*)This
, uFlags
);
278 /**********************************************************
279 * set the toolbar of the filedialog buttons
281 * - activates the buttons from the shellbrowser according to
284 static void CheckToolbar(IShellViewImpl
* This
)
290 if (IsInCommDlg(This
))
292 IShellBrowser_SendControlMsg(This
->pShellBrowser
, FCW_TOOLBAR
, TB_CHECKBUTTON
,
293 FCIDM_TB_SMALLICON
, (This
->FolderSettings
.ViewMode
==FVM_LIST
)? TRUE
: FALSE
, &result
);
294 IShellBrowser_SendControlMsg(This
->pShellBrowser
, FCW_TOOLBAR
, TB_CHECKBUTTON
,
295 FCIDM_TB_REPORTVIEW
, (This
->FolderSettings
.ViewMode
==FVM_DETAILS
)? TRUE
: FALSE
, &result
);
296 IShellBrowser_SendControlMsg(This
->pShellBrowser
, FCW_TOOLBAR
, TB_ENABLEBUTTON
,
297 FCIDM_TB_SMALLICON
, TRUE
, &result
);
298 IShellBrowser_SendControlMsg(This
->pShellBrowser
, FCW_TOOLBAR
, TB_ENABLEBUTTON
,
299 FCIDM_TB_REPORTVIEW
, TRUE
, &result
);
303 /**********************************************************
305 * ##### helperfunctions for initializing the view #####
307 /**********************************************************
308 * change the style of the listview control
310 static void SetStyle(IShellViewImpl
* This
, DWORD dwAdd
, DWORD dwRemove
)
314 TRACE("(%p)\n", This
);
316 tmpstyle
= GetWindowLongW(This
->hWndList
, GWL_STYLE
);
317 SetWindowLongW(This
->hWndList
, GWL_STYLE
, dwAdd
| (tmpstyle
& ~dwRemove
));
320 static DWORD
ViewModeToListStyle(UINT ViewMode
)
324 TRACE("%d\n", ViewMode
);
328 case FVM_ICON
: dwStyle
= LVS_ICON
; break;
329 case FVM_DETAILS
: dwStyle
= LVS_REPORT
; break;
330 case FVM_SMALLICON
: dwStyle
= LVS_SMALLICON
; break;
331 case FVM_LIST
: dwStyle
= LVS_LIST
; break;
334 FIXME("ViewMode %d not implemented\n", ViewMode
);
343 /**********************************************************
344 * ShellView_CreateList()
346 * - creates the list view window
348 static BOOL
ShellView_CreateList (IShellViewImpl
* This
)
349 { DWORD dwStyle
, dwExStyle
;
353 dwStyle
= WS_TABSTOP
| WS_VISIBLE
| WS_CHILDWINDOW
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
|
354 LVS_SHAREIMAGELISTS
| LVS_EDITLABELS
| LVS_ALIGNLEFT
| LVS_AUTOARRANGE
;
355 dwExStyle
= WS_EX_CLIENTEDGE
;
357 dwStyle
|= ViewModeToListStyle(This
->FolderSettings
.ViewMode
);
359 if (This
->FolderSettings
.fFlags
& FWF_AUTOARRANGE
) dwStyle
|= LVS_AUTOARRANGE
;
360 if (This
->FolderSettings
.fFlags
& FWF_DESKTOP
)
361 This
->FolderSettings
.fFlags
|= FWF_NOCLIENTEDGE
| FWF_NOSCROLL
;
362 if (This
->FolderSettings
.fFlags
& FWF_SINGLESEL
) dwStyle
|= LVS_SINGLESEL
;
363 if (This
->FolderSettings
.fFlags
& FWF_NOCLIENTEDGE
)
364 dwExStyle
&= ~WS_EX_CLIENTEDGE
;
366 This
->hWndList
=CreateWindowExW( dwExStyle
,
379 This
->ListViewSortInfo
.bIsAscending
= TRUE
;
380 This
->ListViewSortInfo
.nHeaderID
= -1;
381 This
->ListViewSortInfo
.nLastHeaderID
= -1;
383 if (This
->FolderSettings
.fFlags
& FWF_DESKTOP
) {
385 * FIXME: look at the registry value
386 * HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ListviewShadow
387 * and activate drop shadows if necessary
390 SendMessageW(This
->hWndList
, LVM_SETTEXTBKCOLOR
, 0, CLR_NONE
);
392 SendMessageW(This
->hWndList
, LVM_SETTEXTBKCOLOR
, 0, GetSysColor(COLOR_DESKTOP
));
394 SendMessageW(This
->hWndList
, LVM_SETTEXTCOLOR
, 0, RGB(255,255,255));
397 /* UpdateShellSettings(); */
401 /**********************************************************
402 * ShellView_InitList()
404 * - adds all needed columns to the shellview
406 static void ShellView_InitList(IShellViewImpl
*This
)
408 IShellDetails
*details
= NULL
;
415 TRACE("(%p)\n", This
);
417 SendMessageW(This
->hWndList
, LVM_DELETEALLITEMS
, 0, 0);
418 SendMessageW(This
->hWndList
, LVM_SETIMAGELIST
, LVSIL_SMALL
, (LPARAM
)ShellSmallIconList
);
419 SendMessageW(This
->hWndList
, LVM_SETIMAGELIST
, LVSIL_NORMAL
, (LPARAM
)ShellBigIconList
);
421 lvColumn
.mask
= LVCF_FMT
| LVCF_WIDTH
| LVCF_TEXT
;
422 lvColumn
.pszText
= nameW
;
424 if (!This
->pSF2Parent
)
426 hr
= IShellFolder_QueryInterface(This
->pSFParent
, &IID_IShellDetails
, (void**)&details
);
429 WARN("IShellFolder2/IShellDetails not supported\n");
436 if (This
->pSF2Parent
)
437 hr
= IShellFolder2_GetDetailsOf(This
->pSF2Parent
, NULL
, i
, &sd
);
439 hr
= IShellDetails_GetDetailsOf(details
, NULL
, i
, &sd
);
440 if (FAILED(hr
)) break;
442 lvColumn
.fmt
= sd
.fmt
;
443 lvColumn
.cx
= sd
.cxChar
*8; /* chars->pixel */
444 StrRetToStrNW(nameW
, sizeof(nameW
)/sizeof(WCHAR
), &sd
.str
, NULL
);
445 SendMessageW(This
->hWndList
, LVM_INSERTCOLUMNW
, i
, (LPARAM
) &lvColumn
);
448 if (details
) IShellDetails_Release(details
);
451 /**********************************************************
452 * ShellView_CompareItems()
455 * internal, CALLBACK for DSA_Sort
457 static INT CALLBACK
ShellView_CompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
)
460 TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1
, lParam2
, (LPVOID
) lpData
);
462 if(!lpData
) return 0;
464 ret
= (SHORT
) SCODE_CODE(IShellFolder_CompareIDs((LPSHELLFOLDER
)lpData
, 0, (LPITEMIDLIST
)lParam1
, (LPITEMIDLIST
)lParam2
));
465 TRACE("ret=%i\n",ret
);
469 /*************************************************************************
470 * ShellView_ListViewCompareItems
472 * Compare Function for the Listview (FileOpen Dialog)
475 * lParam1 [I] the first ItemIdList to compare with
476 * lParam2 [I] the second ItemIdList to compare with
477 * lpData [I] The column ID for the header Ctrl to process
480 * A negative value if the first item should precede the second,
481 * a positive value if the first item should follow the second,
482 * or zero if the two items are equivalent
485 * FIXME: function does what ShellView_CompareItems is supposed to do.
486 * unify it and figure out how to use the undocumented first parameter
487 * of IShellFolder_CompareIDs to do the job this function does and
488 * move this code to IShellFolder.
489 * make LISTVIEW_SORT_INFO obsolete
490 * the way this function works is only usable if we had only
491 * filesystemfolders (25/10/99 jsch)
493 static INT CALLBACK
ShellView_ListViewCompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
)
497 char strName1
[MAX_PATH
], strName2
[MAX_PATH
];
498 BOOL bIsFolder1
, bIsFolder2
,bIsBothFolder
;
499 LPITEMIDLIST pItemIdList1
= lParam1
;
500 LPITEMIDLIST pItemIdList2
= lParam2
;
501 LISTVIEW_SORT_INFO
*pSortInfo
= (LPLISTVIEW_SORT_INFO
) lpData
;
504 bIsFolder1
= _ILIsFolder(pItemIdList1
);
505 bIsFolder2
= _ILIsFolder(pItemIdList2
);
506 bIsBothFolder
= bIsFolder1
&& bIsFolder2
;
508 /* When sorting between a File and a Folder, the Folder gets sorted first */
509 if( (bIsFolder1
|| bIsFolder2
) && !bIsBothFolder
)
511 nDiff
= bIsFolder1
? -1 : 1;
515 /* Sort by Time: Folders or Files can be sorted */
517 if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_TIME
)
519 _ILGetFileDateTime(pItemIdList1
, &fd1
);
520 _ILGetFileDateTime(pItemIdList2
, &fd2
);
521 nDiff
= CompareFileTime(&fd2
, &fd1
);
523 /* Sort by Attribute: Folder or Files can be sorted */
524 else if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_ATTRIB
)
526 _ILGetFileAttributes(pItemIdList1
, strName1
, MAX_PATH
);
527 _ILGetFileAttributes(pItemIdList2
, strName2
, MAX_PATH
);
528 nDiff
= lstrcmpiA(strName1
, strName2
);
530 /* Sort by FileName: Folder or Files can be sorted */
531 else if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_NAME
|| bIsBothFolder
)
534 _ILSimpleGetText(pItemIdList1
, strName1
, MAX_PATH
);
535 _ILSimpleGetText(pItemIdList2
, strName2
, MAX_PATH
);
536 nDiff
= lstrcmpiA(strName1
, strName2
);
538 /* Sort by File Size, Only valid for Files */
539 else if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_SIZE
)
541 nDiff
= (INT
)(_ILGetFileSize(pItemIdList1
, NULL
, 0) - _ILGetFileSize(pItemIdList2
, NULL
, 0));
543 /* Sort by File Type, Only valid for Files */
544 else if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_TYPE
)
547 _ILGetFileType(pItemIdList1
, strName1
, MAX_PATH
);
548 _ILGetFileType(pItemIdList2
, strName2
, MAX_PATH
);
549 nDiff
= lstrcmpiA(strName1
, strName2
);
552 /* If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
556 _ILSimpleGetText(pItemIdList1
, strName1
, MAX_PATH
);
557 _ILSimpleGetText(pItemIdList2
, strName2
, MAX_PATH
);
558 nDiff
= lstrcmpiA(strName1
, strName2
);
561 if(!pSortInfo
->bIsAscending
)
570 /**********************************************************
571 * LV_FindItemByPidl()
573 static int LV_FindItemByPidl(
574 IShellViewImpl
* This
,
579 lvItem
.mask
= LVIF_PARAM
;
580 for(lvItem
.iItem
= 0;
581 SendMessageW(This
->hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
584 LPITEMIDLIST currentpidl
= (LPITEMIDLIST
) lvItem
.lParam
;
585 HRESULT hr
= IShellFolder_CompareIDs(This
->pSFParent
, 0, pidl
, currentpidl
);
586 if(SUCCEEDED(hr
) && !HRESULT_CODE(hr
))
594 /**********************************************************
597 static BOOLEAN
LV_AddItem(IShellViewImpl
* This
, LPCITEMIDLIST pidl
)
601 TRACE("(%p)(pidl=%p)\n", This
, pidl
);
603 lvItem
.mask
= LVIF_TEXT
| LVIF_IMAGE
| LVIF_PARAM
; /*set the mask*/
604 lvItem
.iItem
= SendMessageW(This
->hWndList
, LVM_GETITEMCOUNT
, 0, 0); /*add the item to the end of the list*/
606 lvItem
.lParam
= (LPARAM
) ILClone(ILFindLastID(pidl
)); /*set the item's data*/
607 lvItem
.pszText
= LPSTR_TEXTCALLBACKW
; /*get text on a callback basis*/
608 lvItem
.iImage
= I_IMAGECALLBACK
; /*get the image on a callback basis*/
609 return (-1==ListView_InsertItemW(This
->hWndList
, &lvItem
))? FALSE
: TRUE
;
612 /**********************************************************
615 static BOOLEAN
LV_RenameItem(IShellViewImpl
* This
, LPCITEMIDLIST pidlOld
, LPCITEMIDLIST pidlNew
)
620 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", This
, pidlOld
, pidlNew
);
622 nItem
= LV_FindItemByPidl(This
, ILFindLastID(pidlOld
));
625 lvItem
.mask
= LVIF_PARAM
; /* only the pidl */
626 lvItem
.iItem
= nItem
;
627 SendMessageW(This
->hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
629 SHFree((LPITEMIDLIST
)lvItem
.lParam
);
630 lvItem
.mask
= LVIF_PARAM
;
631 lvItem
.iItem
= nItem
;
632 lvItem
.lParam
= (LPARAM
) ILClone(ILFindLastID(pidlNew
)); /* set the item's data */
633 SendMessageW(This
->hWndList
, LVM_SETITEMW
, 0, (LPARAM
) &lvItem
);
634 SendMessageW(This
->hWndList
, LVM_UPDATE
, nItem
, 0);
635 return TRUE
; /* FIXME: better handling */
639 /**********************************************************
640 * ShellView_FillList()
642 * - gets the objectlist from the shellfolder
644 * - fills the list into the view
647 static INT CALLBACK
fill_list( LPVOID ptr
, LPVOID arg
)
649 LPITEMIDLIST pidl
= ptr
;
650 IShellViewImpl
*This
= arg
;
651 /* in a commdlg This works as a filemask*/
652 if ( IncludeObject(This
, pidl
)==S_OK
) LV_AddItem(This
, pidl
);
657 static HRESULT
ShellView_FillList(IShellViewImpl
*This
)
659 IShellFolderView
*folderview
= &This
->IShellFolderView_iface
;
660 LPENUMIDLIST pEnumIDList
;
666 TRACE("(%p)\n", This
);
668 /* get the itemlist from the shfolder*/
669 hr
= IShellFolder_EnumObjects(This
->pSFParent
, This
->hWnd
, SHCONTF_NONFOLDERS
| SHCONTF_FOLDERS
, &pEnumIDList
);
670 if (hr
!= S_OK
) return hr
;
672 /* create a pointer array */
673 hdpa
= DPA_Create(16);
676 IEnumIDList_Release(pEnumIDList
);
677 return E_OUTOFMEMORY
;
680 /* copy the items into the array*/
681 while((S_OK
== IEnumIDList_Next(pEnumIDList
, 1, &pidl
, &fetched
)) && fetched
)
683 if (DPA_InsertPtr(hdpa
, DPA_GetPtrCount(hdpa
), pidl
) == -1)
690 DPA_Sort(hdpa
, ShellView_CompareItems
, (LPARAM
)This
->pSFParent
);
692 IShellFolderView_SetRedraw(folderview
, FALSE
);
693 DPA_DestroyCallback(hdpa
, fill_list
, This
);
694 IShellFolderView_SetRedraw(folderview
, TRUE
);
696 IEnumIDList_Release(pEnumIDList
);
701 /**********************************************************
702 * ShellView_OnCreate()
704 static LRESULT
ShellView_OnCreate(IShellViewImpl
*This
)
706 IShellView2
*iface
= &This
->IShellView2_iface
;
707 static const WCHAR accel_nameW
[] = {'s','h','v','_','a','c','c','e','l',0};
708 IPersistFolder2
*ppf2
;
712 TRACE("(%p)\n", This
);
714 if (ShellView_CreateList(This
))
716 ShellView_InitList(This
);
717 ShellView_FillList(This
);
720 hr
= IShellView2_QueryInterface(iface
, &IID_IDropTarget
, (LPVOID
*)&pdt
);
723 RegisterDragDrop(This
->hWnd
, pdt
);
724 IDropTarget_Release(pdt
);
727 /* register for receiving notifications */
728 hr
= IShellFolder_QueryInterface(This
->pSFParent
, &IID_IPersistFolder2
, (LPVOID
*)&ppf2
);
731 LPITEMIDLIST raw_pidl
;
732 SHChangeNotifyEntry ntreg
;
734 hr
= IPersistFolder2_GetCurFolder(ppf2
, (LPITEMIDLIST
*)&raw_pidl
);
737 LPITEMIDLIST computer_pidl
;
738 SHGetFolderLocation(NULL
,CSIDL_DRIVES
,NULL
,0,&computer_pidl
);
739 if(ILIsParent(computer_pidl
,raw_pidl
,FALSE
))
741 /* Normalize the pidl to unixfs to workaround an issue with
742 * sending notifications on dos paths
744 WCHAR path
[MAX_PATH
];
745 SHGetPathFromIDListW(raw_pidl
,path
);
746 SHParseDisplayName(path
,NULL
,(LPITEMIDLIST
*)&ntreg
.pidl
,0,NULL
);
750 ntreg
.pidl
= raw_pidl
;
751 ntreg
.fRecursive
= TRUE
;
752 This
->hNotify
= SHChangeNotifyRegister(This
->hWnd
, SHCNRF_InterruptLevel
, SHCNE_ALLEVENTS
,
753 SHV_CHANGE_NOTIFY
, 1, &ntreg
);
754 SHFree((LPITEMIDLIST
)ntreg
.pidl
);
756 IPersistFolder2_Release(ppf2
);
759 This
->hAccel
= LoadAcceleratorsW(shell32_hInstance
, accel_nameW
);
764 /**********************************************************
765 * #### Handling of the menus ####
768 /**********************************************************
769 * ShellView_BuildFileMenu()
771 static HMENU
ShellView_BuildFileMenu(IShellViewImpl
* This
)
772 { WCHAR szText
[MAX_PATH
];
777 TRACE("(%p)\n",This
);
779 hSubMenu
= CreatePopupMenu();
781 { /*get the number of items in our global array*/
782 for(nTools
= 0; Tools
[nTools
].idCommand
!= -1; nTools
++){}
784 /*add the menu items*/
785 for(i
= 0; i
< nTools
; i
++)
787 LoadStringW(shell32_hInstance
, Tools
[i
].idMenuString
, szText
, MAX_PATH
);
789 ZeroMemory(&mii
, sizeof(mii
));
790 mii
.cbSize
= sizeof(mii
);
791 mii
.fMask
= MIIM_TYPE
| MIIM_ID
| MIIM_STATE
;
793 if(BTNS_SEP
!= Tools
[i
].bStyle
) /* no separator*/
795 mii
.fType
= MFT_STRING
;
796 mii
.fState
= MFS_ENABLED
;
797 mii
.dwTypeData
= szText
;
798 mii
.wID
= Tools
[i
].idCommand
;
802 mii
.fType
= MFT_SEPARATOR
;
804 /* tack This item onto the end of the menu */
805 InsertMenuItemW(hSubMenu
, (UINT
)-1, TRUE
, &mii
);
808 TRACE("-- return (menu=%p)\n",hSubMenu
);
811 /**********************************************************
812 * ShellView_MergeFileMenu()
814 static void ShellView_MergeFileMenu(IShellViewImpl
*This
, HMENU hSubMenu
)
816 TRACE("(%p)->(submenu=%p) stub\n",This
,hSubMenu
);
820 static const WCHAR dummyW
[] = {'d','u','m','m','y','4','5',0};
823 /* insert This item at the beginning of the menu */
825 mii
.cbSize
= sizeof(mii
);
826 mii
.fMask
= MIIM_ID
| MIIM_TYPE
;
828 mii
.fType
= MFT_SEPARATOR
;
829 InsertMenuItemW(hSubMenu
, 0, TRUE
, &mii
);
831 mii
.cbSize
= sizeof(mii
);
832 mii
.fMask
= MIIM_ID
| MIIM_TYPE
| MIIM_STATE
;
833 mii
.dwTypeData
= (LPWSTR
)dummyW
;
834 mii
.fState
= MFS_ENABLED
;
835 mii
.wID
= IDM_MYFILEITEM
;
836 mii
.fType
= MFT_STRING
;
837 InsertMenuItemW(hSubMenu
, 0, TRUE
, &mii
);
843 /**********************************************************
844 * ShellView_MergeViewMenu()
847 static void ShellView_MergeViewMenu(IShellViewImpl
*This
, HMENU hSubMenu
)
849 TRACE("(%p)->(submenu=%p)\n",This
,hSubMenu
);
851 /* add a separator at the correct position in the menu */
854 static const WCHAR menuW
[] = {'M','E','N','U','_','0','0','1',0};
855 static const WCHAR viewW
[] = {'V','i','e','w',0};
858 memset(&mii
, 0, sizeof(mii
));
859 mii
.cbSize
= sizeof(mii
);
860 mii
.fMask
= MIIM_ID
| MIIM_TYPE
;
862 mii
.fType
= MFT_SEPARATOR
;
863 InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, &mii
);
865 mii
.cbSize
= sizeof(mii
);
866 mii
.fMask
= MIIM_SUBMENU
| MIIM_TYPE
| MIIM_DATA
;
867 mii
.fType
= MFT_STRING
;
868 mii
.dwTypeData
= (LPWSTR
)viewW
;
869 mii
.hSubMenu
= LoadMenuW(shell32_hInstance
, menuW
);
870 InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, &mii
);
874 /**********************************************************
875 * ShellView_GetSelections()
877 * - fills the this->apidl list with the selected objects
880 * number of selected items
882 static UINT
ShellView_GetSelections(IShellViewImpl
* This
)
889 This
->cidl
= SendMessageW(This
->hWndList
, LVM_GETSELECTEDCOUNT
, 0, 0);
890 This
->apidl
= SHAlloc(This
->cidl
* sizeof(LPITEMIDLIST
));
892 TRACE("selected=%i\n", This
->cidl
);
896 TRACE("-- Items selected =%u\n", This
->cidl
);
898 lvItem
.mask
= LVIF_STATE
| LVIF_PARAM
;
899 lvItem
.stateMask
= LVIS_SELECTED
;
903 while(ListView_GetItemW(This
->hWndList
, &lvItem
) && (i
< This
->cidl
))
905 if(lvItem
.state
& LVIS_SELECTED
)
907 This
->apidl
[i
] = (LPITEMIDLIST
)lvItem
.lParam
;
909 TRACE("-- selected Item found\n");
918 /**********************************************************
919 * ShellView_OpenSelectedItems()
921 static HRESULT
ShellView_OpenSelectedItems(IShellViewImpl
* This
)
923 static UINT CF_IDLIST
= 0;
925 IDataObject
* selection
;
929 LPCITEMIDLIST parent_pidl
;
930 WCHAR parent_path
[MAX_PATH
];
931 LPCWSTR parent_dir
= NULL
;
935 if (0 == ShellView_GetSelections(This
))
939 hr
= IShellFolder_GetUIObjectOf(This
->pSFParent
, This
->hWnd
, This
->cidl
,
940 (LPCITEMIDLIST
*)This
->apidl
, &IID_IDataObject
,
941 0, (LPVOID
*)&selection
);
947 CF_IDLIST
= RegisterClipboardFormatW(CFSTR_SHELLIDLISTW
);
949 fetc
.cfFormat
= CF_IDLIST
;
951 fetc
.dwAspect
= DVASPECT_CONTENT
;
953 fetc
.tymed
= TYMED_HGLOBAL
;
955 hr
= IDataObject_QueryGetData(selection
, &fetc
);
959 hr
= IDataObject_GetData(selection
, &fetc
, &stgm
);
963 pIDList
= GlobalLock(stgm
.u
.hGlobal
);
965 parent_pidl
= (LPCITEMIDLIST
) ((LPBYTE
)pIDList
+pIDList
->aoffset
[0]);
966 hr
= IShellFolder_GetAttributesOf(This
->pSFParent
, 1, &parent_pidl
, &attribs
);
967 if (SUCCEEDED(hr
) && (attribs
& SFGAO_FILESYSTEM
) &&
968 SHGetPathFromIDListW(parent_pidl
, parent_path
))
970 parent_dir
= parent_path
;
973 for (i
= pIDList
->cidl
; i
> 0; --i
)
977 pidl
= (LPCITEMIDLIST
)((LPBYTE
)pIDList
+pIDList
->aoffset
[i
]);
979 attribs
= SFGAO_FOLDER
;
980 hr
= IShellFolder_GetAttributesOf(This
->pSFParent
, 1, &pidl
, &attribs
);
982 if (SUCCEEDED(hr
) && ! (attribs
& SFGAO_FOLDER
))
984 SHELLEXECUTEINFOW shexinfo
;
986 shexinfo
.cbSize
= sizeof(SHELLEXECUTEINFOW
);
987 shexinfo
.fMask
= SEE_MASK_INVOKEIDLIST
; /* SEE_MASK_IDLIST is also possible. */
988 shexinfo
.hwnd
= NULL
;
989 shexinfo
.lpVerb
= NULL
;
990 shexinfo
.lpFile
= NULL
;
991 shexinfo
.lpParameters
= NULL
;
992 shexinfo
.lpDirectory
= parent_dir
;
993 shexinfo
.nShow
= SW_NORMAL
;
994 shexinfo
.lpIDList
= ILCombine(parent_pidl
, pidl
);
996 ShellExecuteExW(&shexinfo
); /* Discard error/success info */
998 ILFree(shexinfo
.lpIDList
);
1002 GlobalUnlock(stgm
.u
.hGlobal
);
1003 ReleaseStgMedium(&stgm
);
1005 IDataObject_Release(selection
);
1010 /**********************************************************
1011 * ShellView_DoContextMenu()
1013 static void ShellView_DoContextMenu(IShellViewImpl
* This
, WORD x
, WORD y
, BOOL bDefault
)
1017 BOOL fExplore
= FALSE
;
1019 LPCONTEXTMENU pContextMenu
= NULL
;
1020 IContextMenu2
*pCM
= NULL
;
1021 CMINVOKECOMMANDINFO cmi
;
1023 TRACE("(%p)->(0x%08x 0x%08x 0x%08x) stub\n",This
, x
, y
, bDefault
);
1025 /* look, what's selected and create a context menu object of it*/
1026 if( ShellView_GetSelections(This
) )
1028 IShellFolder_GetUIObjectOf( This
->pSFParent
, This
->hWndParent
, This
->cidl
, (LPCITEMIDLIST
*)This
->apidl
,
1029 &IID_IContextMenu
, NULL
, (LPVOID
*)&pContextMenu
);
1033 TRACE("-- pContextMenu\n");
1034 hMenu
= CreatePopupMenu();
1038 /* See if we are in Explore or Open mode. If the browser's tree is present, we are in Explore mode.*/
1039 if(SUCCEEDED(IShellBrowser_GetControlWindow(This
->pShellBrowser
,FCW_TREE
, &hwndTree
)) && hwndTree
)
1041 TRACE("-- explore mode\n");
1045 /* build the flags depending on what we can do with the selected item */
1046 wFlags
= CMF_NORMAL
| (This
->cidl
!= 1 ? 0 : CMF_CANRENAME
) | (fExplore
? CMF_EXPLORE
: 0);
1048 /* let the ContextMenu merge its items in */
1049 if (SUCCEEDED(IContextMenu_QueryContextMenu( pContextMenu
, hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, wFlags
)))
1051 if (This
->FolderSettings
.fFlags
& FWF_DESKTOP
)
1052 SetMenuDefaultItem(hMenu
, FCIDM_SHVIEW_OPEN
, MF_BYCOMMAND
);
1056 TRACE("-- get menu default command\n");
1057 uCommand
= GetMenuDefaultItem(hMenu
, FALSE
, GMDI_GOINTOPOPUPS
);
1061 TRACE("-- track popup\n");
1062 uCommand
= TrackPopupMenu( hMenu
,TPM_LEFTALIGN
| TPM_RETURNCMD
,x
,y
,0,This
->hWnd
,NULL
);
1067 TRACE("-- uCommand=%u\n", uCommand
);
1068 if (uCommand
==FCIDM_SHVIEW_OPEN
&& IsInCommDlg(This
))
1070 TRACE("-- dlg: OnDefaultCommand\n");
1071 if (OnDefaultCommand(This
) != S_OK
)
1073 ShellView_OpenSelectedItems(This
);
1078 TRACE("-- explore -- invoke command\n");
1079 ZeroMemory(&cmi
, sizeof(cmi
));
1080 cmi
.cbSize
= sizeof(cmi
);
1081 cmi
.hwnd
= This
->hWndParent
; /* this window has to answer CWM_GETISHELLBROWSER */
1082 cmi
.lpVerb
= MAKEINTRESOURCEA(uCommand
);
1083 IContextMenu_InvokeCommand(pContextMenu
, &cmi
);
1090 IContextMenu_Release(pContextMenu
);
1093 else /* background context menu */
1095 hMenu
= CreatePopupMenu();
1097 pCM
= ISvBgCm_Constructor(This
->pSFParent
, FALSE
);
1098 IContextMenu2_QueryContextMenu(pCM
, hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, 0);
1100 uCommand
= TrackPopupMenu( hMenu
, TPM_LEFTALIGN
| TPM_RETURNCMD
,x
,y
,0,This
->hWnd
,NULL
);
1103 TRACE("-- (%p)->(uCommand=0x%08x )\n",This
, uCommand
);
1105 ZeroMemory(&cmi
, sizeof(cmi
));
1106 cmi
.cbSize
= sizeof(cmi
);
1107 cmi
.lpVerb
= MAKEINTRESOURCEA(uCommand
);
1108 cmi
.hwnd
= This
->hWndParent
;
1109 IContextMenu2_InvokeCommand(pCM
, &cmi
);
1111 IContextMenu2_Release(pCM
);
1115 /**********************************************************
1116 * ##### message handling #####
1119 /**********************************************************
1120 * ShellView_OnSize()
1122 static LRESULT
ShellView_OnSize(IShellViewImpl
* This
, WORD wWidth
, WORD wHeight
)
1124 TRACE("%p width=%u height=%u\n",This
, wWidth
,wHeight
);
1126 /*resize the ListView to fit our window*/
1129 MoveWindow(This
->hWndList
, 0, 0, wWidth
, wHeight
, TRUE
);
1134 /**********************************************************
1135 * ShellView_OnDeactivate()
1140 static void ShellView_OnDeactivate(IShellViewImpl
* This
)
1144 if(This
->uState
!= SVUIA_DEACTIVATE
)
1148 IShellBrowser_SetMenuSB(This
->pShellBrowser
,0, 0, 0);
1149 IShellBrowser_RemoveMenusSB(This
->pShellBrowser
,This
->hMenu
);
1150 DestroyMenu(This
->hMenu
);
1154 This
->uState
= SVUIA_DEACTIVATE
;
1158 /**********************************************************
1159 * ShellView_OnActivate()
1161 static LRESULT
ShellView_OnActivate(IShellViewImpl
*This
, UINT uState
)
1163 OLEMENUGROUPWIDTHS omw
= { {0, 0, 0, 0, 0, 0} };
1166 TRACE("(%p) uState=%x\n",This
,uState
);
1168 /* don't do anything if the state isn't really changing */
1169 if (This
->uState
== uState
) return S_OK
;
1171 ShellView_OnDeactivate(This
);
1173 /* only do This if we are active */
1174 if (uState
!= SVUIA_DEACTIVATE
)
1176 /* merge the menus */
1177 This
->hMenu
= CreateMenu();
1181 static const WCHAR dummyW
[] = {'d','u','m','m','y',' ','3','1',0};
1183 IShellBrowser_InsertMenusSB(This
->pShellBrowser
, This
->hMenu
, &omw
);
1184 TRACE("-- after fnInsertMenusSB\n");
1186 mii
.cbSize
= sizeof(mii
);
1187 mii
.fMask
= MIIM_SUBMENU
| MIIM_TYPE
| MIIM_STATE
;
1188 mii
.fType
= MFT_STRING
;
1189 mii
.fState
= MFS_ENABLED
;
1191 mii
.hSubMenu
= ShellView_BuildFileMenu(This
);
1192 mii
.hbmpChecked
= NULL
;
1193 mii
.hbmpUnchecked
= NULL
;
1195 /* build the top level menu get the menu item's text */
1196 mii
.dwTypeData
= (LPWSTR
)dummyW
;
1198 mii
.hbmpItem
= NULL
;
1200 /* insert our menu into the menu bar */
1202 InsertMenuItemW(This
->hMenu
, FCIDM_MENU_HELP
, FALSE
, &mii
);
1204 /* get the view menu so we can merge with it */
1205 memset(&mii
, 0, sizeof(mii
));
1206 mii
.cbSize
= sizeof(mii
);
1207 mii
.fMask
= MIIM_SUBMENU
;
1209 if (GetMenuItemInfoW(This
->hMenu
, FCIDM_MENU_VIEW
, FALSE
, &mii
))
1210 ShellView_MergeViewMenu(This
, mii
.hSubMenu
);
1212 /* add the items that should only be added if we have the focus */
1213 if (SVUIA_ACTIVATE_FOCUS
== uState
)
1215 /* get the file menu so we can merge with it */
1216 memset(&mii
, 0, sizeof(mii
));
1217 mii
.cbSize
= sizeof(mii
);
1218 mii
.fMask
= MIIM_SUBMENU
;
1220 if (GetMenuItemInfoW(This
->hMenu
, FCIDM_MENU_FILE
, FALSE
, &mii
))
1221 ShellView_MergeFileMenu(This
, mii
.hSubMenu
);
1224 TRACE("-- before fnSetMenuSB\n");
1225 IShellBrowser_SetMenuSB(This
->pShellBrowser
, This
->hMenu
, 0, This
->hWnd
);
1228 This
->uState
= uState
;
1233 /**********************************************************
1234 * ShellView_OnSetFocus()
1237 static LRESULT
ShellView_OnSetFocus(IShellViewImpl
* This
)
1241 /* Tell the browser one of our windows has received the focus. This
1242 should always be done before merging menus (OnActivate merges the
1243 menus) if one of our windows has the focus.*/
1245 IShellBrowser_OnViewWindowActive(This
->pShellBrowser
,(IShellView
*) This
);
1246 ShellView_OnActivate(This
, SVUIA_ACTIVATE_FOCUS
);
1248 /* Set the focus to the listview */
1249 SetFocus(This
->hWndList
);
1251 /* Notify the ICommDlgBrowser interface */
1252 OnStateChange(This
,CDBOSC_SETFOCUS
);
1257 /**********************************************************
1258 * ShellView_OnKillFocus()
1260 static LRESULT
ShellView_OnKillFocus(IShellViewImpl
* This
)
1262 TRACE("(%p) stub\n",This
);
1264 ShellView_OnActivate(This
, SVUIA_ACTIVATE_NOFOCUS
);
1265 /* Notify the ICommDlgBrowser */
1266 OnStateChange(This
,CDBOSC_KILLFOCUS
);
1271 /**********************************************************
1272 * ShellView_OnCommand()
1275 * the CmdID's are the ones from the context menu
1277 static LRESULT
ShellView_OnCommand(IShellViewImpl
* This
,DWORD dwCmdID
, DWORD dwCmd
, HWND hwndCmd
)
1279 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n",This
, dwCmdID
, dwCmd
, hwndCmd
);
1283 case FCIDM_SHVIEW_SMALLICON
:
1284 This
->FolderSettings
.ViewMode
= FVM_SMALLICON
;
1285 SetStyle (This
, LVS_SMALLICON
, LVS_TYPEMASK
);
1289 case FCIDM_SHVIEW_BIGICON
:
1290 This
->FolderSettings
.ViewMode
= FVM_ICON
;
1291 SetStyle (This
, LVS_ICON
, LVS_TYPEMASK
);
1295 case FCIDM_SHVIEW_LISTVIEW
:
1296 This
->FolderSettings
.ViewMode
= FVM_LIST
;
1297 SetStyle (This
, LVS_LIST
, LVS_TYPEMASK
);
1301 case FCIDM_SHVIEW_REPORTVIEW
:
1302 This
->FolderSettings
.ViewMode
= FVM_DETAILS
;
1303 SetStyle (This
, LVS_REPORT
, LVS_TYPEMASK
);
1307 /* the menu-ID's for sorting are 0x30... see shell32.rc */
1312 This
->ListViewSortInfo
.nHeaderID
= dwCmdID
- 0x30;
1313 This
->ListViewSortInfo
.bIsAscending
= TRUE
;
1314 This
->ListViewSortInfo
.nLastHeaderID
= This
->ListViewSortInfo
.nHeaderID
;
1315 SendMessageW(This
->hWndList
, LVM_SORTITEMS
, (WPARAM
) &This
->ListViewSortInfo
, (LPARAM
)ShellView_ListViewCompareItems
);
1319 TRACE("-- COMMAND 0x%04x unhandled\n", dwCmdID
);
1324 /**********************************************************
1325 * ShellView_OnNotify()
1328 static LRESULT
ShellView_OnNotify(IShellViewImpl
* This
, UINT CtlID
, LPNMHDR lpnmh
)
1329 { LPNMLISTVIEW lpnmlv
= (LPNMLISTVIEW
)lpnmh
;
1330 NMLVDISPINFOW
*lpdi
= (NMLVDISPINFOW
*)lpnmh
;
1333 TRACE("%p CtlID=%u lpnmh->code=%x\n",This
,CtlID
,lpnmh
->code
);
1338 TRACE("-- NM_SETFOCUS %p\n",This
);
1339 ShellView_OnSetFocus(This
);
1343 TRACE("-- NM_KILLFOCUS %p\n",This
);
1344 ShellView_OnDeactivate(This
);
1345 /* Notify the ICommDlgBrowser interface */
1346 OnStateChange(This
,CDBOSC_KILLFOCUS
);
1350 TRACE("-- NM_CUSTOMDRAW %p\n",This
);
1351 return CDRF_DODEFAULT
;
1353 case NM_RELEASEDCAPTURE
:
1354 TRACE("-- NM_RELEASEDCAPTURE %p\n",This
);
1358 TRACE("-- NM_CLICK %p\n",This
);
1362 TRACE("-- NM_RCLICK %p\n",This
);
1366 TRACE("-- NM_DBLCLK %p\n",This
);
1367 if (OnDefaultCommand(This
) != S_OK
) ShellView_OpenSelectedItems(This
);
1371 TRACE("-- NM_RETURN %p\n",This
);
1372 if (OnDefaultCommand(This
) != S_OK
) ShellView_OpenSelectedItems(This
);
1376 TRACE("-- HDN_ENDTRACKW %p\n",This
);
1377 /*nColumn1 = ListView_GetColumnWidth(This->hWndList, 0);
1378 nColumn2 = ListView_GetColumnWidth(This->hWndList, 1);*/
1381 case LVN_DELETEITEM
:
1382 TRACE("-- LVN_DELETEITEM %p\n",This
);
1383 SHFree((LPITEMIDLIST
)lpnmlv
->lParam
); /*delete the pidl because we made a copy of it*/
1386 case LVN_DELETEALLITEMS
:
1387 TRACE("-- LVN_DELETEALLITEMS %p\n",This
);
1390 case LVN_INSERTITEM
:
1391 TRACE("-- LVN_INSERTITEM (STUB)%p\n",This
);
1394 case LVN_ITEMACTIVATE
:
1395 TRACE("-- LVN_ITEMACTIVATE %p\n",This
);
1396 OnStateChange(This
, CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1399 case LVN_COLUMNCLICK
:
1400 This
->ListViewSortInfo
.nHeaderID
= lpnmlv
->iSubItem
;
1401 if(This
->ListViewSortInfo
.nLastHeaderID
== This
->ListViewSortInfo
.nHeaderID
)
1403 This
->ListViewSortInfo
.bIsAscending
= !This
->ListViewSortInfo
.bIsAscending
;
1407 This
->ListViewSortInfo
.bIsAscending
= TRUE
;
1409 This
->ListViewSortInfo
.nLastHeaderID
= This
->ListViewSortInfo
.nHeaderID
;
1411 SendMessageW(lpnmlv
->hdr
.hwndFrom
, LVM_SORTITEMS
, (WPARAM
) &This
->ListViewSortInfo
, (LPARAM
)ShellView_ListViewCompareItems
);
1414 case LVN_GETDISPINFOA
:
1415 case LVN_GETDISPINFOW
:
1416 TRACE("-- LVN_GETDISPINFO %p\n",This
);
1417 pidl
= (LPITEMIDLIST
)lpdi
->item
.lParam
;
1419 if(lpdi
->item
.mask
& LVIF_TEXT
) /* text requested */
1421 static WCHAR emptyW
[] = { 0 };
1425 if (This
->pSF2Parent
)
1427 hr
= IShellFolder2_GetDetailsOf(This
->pSF2Parent
, pidl
, lpdi
->item
.iSubItem
, &sd
);
1431 IShellDetails
*details
;
1433 hr
= IShellFolder_QueryInterface(This
->pSFParent
, &IID_IShellDetails
, (void**)&details
);
1436 hr
= IShellDetails_GetDetailsOf(details
, pidl
, lpdi
->item
.iSubItem
, &sd
);
1437 IShellDetails_Release(details
);
1440 WARN("IShellFolder2/IShellDetails not supported\n");
1445 /* set to empty on failure */
1446 sd
.str
.uType
= STRRET_WSTR
;
1447 sd
.str
.u
.pOleStr
= emptyW
;
1450 if (lpnmh
->code
== LVN_GETDISPINFOW
)
1452 StrRetToStrNW( lpdi
->item
.pszText
, lpdi
->item
.cchTextMax
, &sd
.str
, NULL
);
1453 TRACE("-- text=%s\n", debugstr_w(lpdi
->item
.pszText
));
1457 /* LVN_GETDISPINFOA - shouldn't happen */
1458 NMLVDISPINFOA
*lpdiA
= (NMLVDISPINFOA
*)lpnmh
;
1459 StrRetToStrNA( lpdiA
->item
.pszText
, lpdiA
->item
.cchTextMax
, &sd
.str
, NULL
);
1460 TRACE("-- text=%s\n", lpdiA
->item
.pszText
);
1464 if(lpdi
->item
.mask
& LVIF_IMAGE
) /* image requested */
1466 lpdi
->item
.iImage
= SHMapPIDLToSystemImageListIndex(This
->pSFParent
, pidl
, 0);
1470 case LVN_ITEMCHANGED
:
1471 TRACE("-- LVN_ITEMCHANGED %p\n",This
);
1472 OnStateChange(This
, CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1476 case LVN_BEGINRDRAG
:
1477 TRACE("-- LVN_BEGINDRAG\n");
1479 if (ShellView_GetSelections(This
))
1482 DWORD dwAttributes
= SFGAO_CANLINK
;
1483 DWORD dwEffect
= DROPEFFECT_COPY
| DROPEFFECT_MOVE
;
1485 if (SUCCEEDED(IShellFolder_GetUIObjectOf(This
->pSFParent
, This
->hWnd
, This
->cidl
, (LPCITEMIDLIST
*)This
->apidl
, &IID_IDataObject
,0,(LPVOID
*)&pda
)))
1487 IDropSource
*pds
= &This
->IDropSource_iface
; /* own DropSource interface */
1489 if (SUCCEEDED(IShellFolder_GetAttributesOf(This
->pSFParent
, This
->cidl
, (LPCITEMIDLIST
*)This
->apidl
, &dwAttributes
)))
1491 if (dwAttributes
& SFGAO_CANLINK
)
1493 dwEffect
|= DROPEFFECT_LINK
;
1500 DoDragDrop(pda
, pds
, dwEffect
, &dwEffect2
);
1502 IDataObject_Release(pda
);
1507 case LVN_BEGINLABELEDITW
:
1509 DWORD dwAttr
= SFGAO_CANRENAME
;
1510 pidl
= (LPITEMIDLIST
)lpdi
->item
.lParam
;
1512 TRACE("-- LVN_BEGINLABELEDITW %p\n",This
);
1514 IShellFolder_GetAttributesOf(This
->pSFParent
, 1, (LPCITEMIDLIST
*)&pidl
, &dwAttr
);
1515 if (SFGAO_CANRENAME
& dwAttr
)
1522 case LVN_ENDLABELEDITW
:
1524 TRACE("-- LVN_ENDLABELEDITA %p\n",This
);
1525 if (lpdi
->item
.pszText
)
1530 lvItem
.iItem
= lpdi
->item
.iItem
;
1531 lvItem
.iSubItem
= 0;
1532 lvItem
.mask
= LVIF_PARAM
;
1533 SendMessageW(This
->hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
1535 pidl
= (LPITEMIDLIST
)lpdi
->item
.lParam
;
1536 hr
= IShellFolder_SetNameOf(This
->pSFParent
, 0, pidl
, lpdi
->item
.pszText
, SHGDN_INFOLDER
, &pidl
);
1538 if(SUCCEEDED(hr
) && pidl
)
1540 lvItem
.mask
= LVIF_PARAM
;
1541 lvItem
.lParam
= (LPARAM
)pidl
;
1542 SendMessageW(This
->hWndList
, LVM_SETITEMW
, 0, (LPARAM
) &lvItem
);
1551 LPNMLVKEYDOWN plvKeyDown
= (LPNMLVKEYDOWN
) lpnmh
;
1553 /* initiate a rename of the selected file or directory */
1554 switch (plvKeyDown
->wVKey
)
1558 INT i
= SendMessageW(This
->hWndList
, LVM_GETSELECTEDCOUNT
, 0, 0);
1562 /* get selected item */
1563 i
= SendMessageW(This
->hWndList
, LVM_GETNEXTITEM
, -1, MAKELPARAM (LVNI_SELECTED
, 0));
1565 SendMessageW(This
->hWndList
, LVM_ENSUREVISIBLE
, i
, 0);
1566 SendMessageW(This
->hWndList
, LVM_EDITLABELW
, i
, 0);
1575 LPITEMIDLIST
* pItems
;
1579 hr
= IShellFolder_QueryInterface(This
->pSFParent
, &IID_ISFHelper
, (void**)&psfhlp
);
1580 if (hr
!= S_OK
) return 0;
1582 if(!(count
= SendMessageW(This
->hWndList
, LVM_GETSELECTEDCOUNT
, 0, 0)))
1584 ISFHelper_Release(psfhlp
);
1588 /* allocate memory for the pidl array */
1589 pItems
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPITEMIDLIST
) * count
);
1591 /* retrieve all selected items */
1597 /* get selected item */
1598 item_index
= SendMessageW(This
->hWndList
, LVM_GETNEXTITEM
, item_index
,
1599 MAKELPARAM (LVNI_SELECTED
, 0));
1600 item
.iItem
= item_index
;
1601 item
.mask
= LVIF_PARAM
;
1602 SendMessageW(This
->hWndList
, LVM_GETITEMW
, 0, (LPARAM
)&item
);
1605 pItems
[i
] = (LPITEMIDLIST
)item
.lParam
;
1610 /* perform the item deletion */
1611 ISFHelper_DeleteItems(psfhlp
, i
, (LPCITEMIDLIST
*)pItems
);
1612 ISFHelper_Release(psfhlp
);
1614 /* free pidl array memory */
1615 HeapFree(GetProcessHeap(), 0, pItems
);
1620 /* Initiate a refresh */
1621 IShellView_Refresh((IShellView
*)This
);
1626 LPSHELLBROWSER lpSb
;
1627 if((lpSb
= (LPSHELLBROWSER
)SendMessageW(This
->hWndParent
, CWM_GETISHELLBROWSER
, 0, 0)))
1629 IShellBrowser_BrowseObject(lpSb
, NULL
, SBSP_PARENT
);
1635 FIXME("LVN_KEYDOWN key=0x%08x\n", plvKeyDown
->wVKey
);
1641 TRACE("-- %p WM_COMMAND %x unhandled\n", This
, lpnmh
->code
);
1647 /**********************************************************
1648 * ShellView_OnChange()
1651 static LRESULT
ShellView_OnChange(IShellViewImpl
* This
, const LPCITEMIDLIST
*pidls
, LONG event
)
1655 TRACE("(%p)->(%p, %p, 0x%08x)\n", This
, pidls
[0], pidls
[1], event
);
1661 LV_AddItem(This
, pidls
[0]);
1666 INT i
= LV_FindItemByPidl(This
, ILFindLastID(pidls
[0]));
1667 ret
= SendMessageW(This
->hWndList
, LVM_DELETEITEM
, i
, 0);
1670 case SHCNE_RENAMEFOLDER
:
1671 case SHCNE_RENAMEITEM
:
1672 LV_RenameItem(This
, pidls
[0], pidls
[1]);
1674 case SHCNE_UPDATEITEM
:
1679 /**********************************************************
1683 static LRESULT CALLBACK
ShellView_WndProc(HWND hWnd
, UINT uMessage
, WPARAM wParam
, LPARAM lParam
)
1685 IShellViewImpl
* pThis
= (IShellViewImpl
*)GetWindowLongPtrW(hWnd
, GWLP_USERDATA
);
1686 LPCREATESTRUCTW lpcs
;
1688 TRACE("(hwnd=%p msg=%x wparm=%lx lparm=%lx)\n",hWnd
, uMessage
, wParam
, lParam
);
1693 lpcs
= (LPCREATESTRUCTW
)lParam
;
1694 pThis
= lpcs
->lpCreateParams
;
1695 SetWindowLongPtrW(hWnd
, GWLP_USERDATA
, (ULONG_PTR
)pThis
);
1696 pThis
->hWnd
= hWnd
; /*set the window handle*/
1699 case WM_SIZE
: return ShellView_OnSize(pThis
,LOWORD(lParam
), HIWORD(lParam
));
1700 case WM_SETFOCUS
: return ShellView_OnSetFocus(pThis
);
1701 case WM_KILLFOCUS
: return ShellView_OnKillFocus(pThis
);
1702 case WM_CREATE
: return ShellView_OnCreate(pThis
);
1703 case WM_ACTIVATE
: return ShellView_OnActivate(pThis
, SVUIA_ACTIVATE_FOCUS
);
1704 case WM_NOTIFY
: return ShellView_OnNotify(pThis
,(UINT
)wParam
, (LPNMHDR
)lParam
);
1705 case WM_COMMAND
: return ShellView_OnCommand(pThis
,
1706 GET_WM_COMMAND_ID(wParam
, lParam
),
1707 GET_WM_COMMAND_CMD(wParam
, lParam
),
1708 GET_WM_COMMAND_HWND(wParam
, lParam
));
1709 case SHV_CHANGE_NOTIFY
: return ShellView_OnChange(pThis
, (const LPCITEMIDLIST
*)wParam
, (LONG
)lParam
);
1711 case WM_CONTEXTMENU
: ShellView_DoContextMenu(pThis
, LOWORD(lParam
), HIWORD(lParam
), FALSE
);
1714 case WM_SHOWWINDOW
: UpdateWindow(pThis
->hWndList
);
1717 case WM_GETDLGCODE
: return SendMessageW(pThis
->hWndList
, uMessage
, 0, 0);
1720 RevokeDragDrop(pThis
->hWnd
);
1721 SHChangeNotifyDeregister(pThis
->hNotify
);
1725 if ((pThis
->FolderSettings
.fFlags
& FWF_DESKTOP
) ||
1726 (pThis
->FolderSettings
.fFlags
& FWF_TRANSPARENT
))
1731 return DefWindowProcW(hWnd
, uMessage
, wParam
, lParam
);
1733 /**********************************************************
1736 * The INTERFACE of the IShellView object
1739 **********************************************************
1740 * IShellView_QueryInterface
1742 static HRESULT WINAPI
IShellView_fnQueryInterface(IShellView2
*iface
, REFIID riid
, void **ppvObj
)
1744 IShellViewImpl
*This
= impl_from_IShellView2(iface
);
1746 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This
,debugstr_guid(riid
),ppvObj
);
1750 if(IsEqualIID(riid
, &IID_IUnknown
))
1754 else if(IsEqualIID(riid
, &IID_IShellView
))
1758 else if(IsEqualIID(riid
, &IID_IShellView2
))
1762 else if(IsEqualIID(riid
, &IID_IShellFolderView
))
1764 *ppvObj
= &This
->IShellFolderView_iface
;
1766 else if(IsEqualIID(riid
, &IID_IFolderView
))
1768 *ppvObj
= &This
->IFolderView_iface
;
1770 else if(IsEqualIID(riid
, &IID_IOleCommandTarget
))
1772 *ppvObj
= &This
->IOleCommandTarget_iface
;
1774 else if(IsEqualIID(riid
, &IID_IDropTarget
))
1776 *ppvObj
= &This
->IDropTarget_iface
;
1778 else if(IsEqualIID(riid
, &IID_IDropSource
))
1780 *ppvObj
= &This
->IDropSource_iface
;
1782 else if(IsEqualIID(riid
, &IID_IViewObject
))
1784 *ppvObj
= &This
->IViewObject_iface
;
1789 IUnknown_AddRef( (IUnknown
*)*ppvObj
);
1790 TRACE("-- Interface: (%p)->(%p)\n",ppvObj
,*ppvObj
);
1793 TRACE("-- Interface: E_NOINTERFACE\n");
1794 return E_NOINTERFACE
;
1797 /**********************************************************
1800 static ULONG WINAPI
IShellView_fnAddRef(IShellView2
*iface
)
1802 IShellViewImpl
*This
= impl_from_IShellView2(iface
);
1803 ULONG refCount
= InterlockedIncrement(&This
->ref
);
1805 TRACE("(%p)->(count=%u)\n", This
, refCount
- 1);
1809 /**********************************************************
1810 * IShellView_Release
1812 static ULONG WINAPI
IShellView_fnRelease(IShellView2
*iface
)
1814 IShellViewImpl
*This
= impl_from_IShellView2(iface
);
1815 ULONG refCount
= InterlockedDecrement(&This
->ref
);
1817 TRACE("(%p)->(count=%i)\n", This
, refCount
+ 1);
1821 TRACE(" destroying IShellView(%p)\n",This
);
1823 DestroyWindow(This
->hWndList
);
1826 IShellFolder_Release(This
->pSFParent
);
1828 if(This
->pSF2Parent
)
1829 IShellFolder2_Release(This
->pSF2Parent
);
1831 SHFree(This
->apidl
);
1834 IAdviseSink_Release(This
->pAdvSink
);
1836 HeapFree(GetProcessHeap(),0,This
);
1841 /**********************************************************
1842 * ShellView_GetWindow
1844 static HRESULT WINAPI
IShellView_fnGetWindow(IShellView2
*iface
, HWND
*phWnd
)
1846 IShellViewImpl
*This
= impl_from_IShellView2(iface
);
1848 TRACE("(%p)\n",This
);
1850 *phWnd
= This
->hWnd
;
1855 static HRESULT WINAPI
IShellView_fnContextSensitiveHelp(IShellView2
*iface
, BOOL mode
)
1857 IShellViewImpl
*This
= impl_from_IShellView2(iface
);
1858 TRACE("(%p)->(%d)\n", This
, mode
);
1862 /**********************************************************
1863 * IShellView_TranslateAccelerator
1866 * use the accel functions
1868 static HRESULT WINAPI
IShellView_fnTranslateAccelerator(IShellView2
* iface
,LPMSG lpmsg
)
1871 IShellViewImpl
*This
= (IShellViewImpl
*)iface
;
1873 FIXME("(%p)->(%p: hwnd=%x msg=%x lp=%x wp=%x) stub\n",This
,lpmsg
, lpmsg
->hwnd
, lpmsg
->message
, lpmsg
->lParam
, lpmsg
->wParam
);
1876 if ((lpmsg
->message
>=WM_KEYFIRST
) && (lpmsg
->message
>=WM_KEYLAST
))
1878 TRACE("-- key=0x04%lx\n",lpmsg
->wParam
) ;
1880 return S_FALSE
; /* not handled */
1883 static HRESULT WINAPI
IShellView_fnEnableModeless(IShellView2
*iface
, BOOL fEnable
)
1885 IShellViewImpl
*This
= impl_from_IShellView2(iface
);
1887 FIXME("(%p) stub\n",This
);
1892 static HRESULT WINAPI
IShellView_fnUIActivate(IShellView2
*iface
, UINT uState
)
1894 IShellViewImpl
*This
= impl_from_IShellView2(iface
);
1897 CHAR szName[MAX_PATH];
1900 int nPartArray
[1] = {-1};
1902 TRACE("(%p)->(state=%x) stub\n",This
, uState
);
1904 /*don't do anything if the state isn't really changing*/
1905 if(This
->uState
== uState
)
1910 /*OnActivate handles the menu merging and internal state*/
1911 ShellView_OnActivate(This
, uState
);
1913 /*only do This if we are active*/
1914 if(uState
!= SVUIA_DEACTIVATE
)
1918 GetFolderPath is not a method of IShellFolder
1919 IShellFolder_GetFolderPath( This->pSFParent, szName, sizeof(szName) );
1921 /* set the number of parts */
1922 IShellBrowser_SendControlMsg(This
->pShellBrowser
, FCW_STATUS
, SB_SETPARTS
, 1,
1923 (LPARAM
)nPartArray
, &lResult
);
1925 /* set the text for the parts */
1927 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETTEXTA,
1928 0, (LPARAM)szName, &lResult);
1935 static HRESULT WINAPI
IShellView_fnRefresh(IShellView2
*iface
)
1937 IShellViewImpl
*This
= impl_from_IShellView2(iface
);
1939 TRACE("(%p)\n", This
);
1941 SendMessageW(This
->hWndList
, LVM_DELETEALLITEMS
, 0, 0);
1942 ShellView_FillList(This
);
1947 static HRESULT WINAPI
IShellView_fnCreateViewWindow(IShellView2
*iface
, IShellView
*lpPrevView
,
1948 LPCFOLDERSETTINGS lpfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
)
1951 SV2CVW2_PARAMS view_params
;
1952 view_params
.cbSize
= sizeof(view_params
);
1953 view_params
.psvPrev
= lpPrevView
;
1954 view_params
.pfs
= lpfs
;
1955 view_params
.psbOwner
= psb
;
1956 view_params
.prcView
= prcView
;
1957 view_params
.pvid
= NULL
;
1958 view_params
.hwndView
= 0;
1960 TRACE("(%p) Forwarding to CreateViewWindow2\n", iface
);
1962 hr
= IShellView2_CreateViewWindow2(iface
, &view_params
);
1963 *phWnd
= view_params
.hwndView
;
1968 static HRESULT WINAPI
IShellView_fnDestroyViewWindow(IShellView2
*iface
)
1970 IShellViewImpl
*This
= impl_from_IShellView2(iface
);
1972 TRACE("(%p)\n",This
);
1974 /*Make absolutely sure all our UI is cleaned up.*/
1975 IShellView_UIActivate((IShellView
*)This
, SVUIA_DEACTIVATE
);
1979 DestroyMenu(This
->hMenu
);
1982 DestroyWindow(This
->hWnd
);
1983 if(This
->pShellBrowser
) IShellBrowser_Release(This
->pShellBrowser
);
1984 if(This
->pCommDlgBrowser
) ICommDlgBrowser_Release(This
->pCommDlgBrowser
);
1990 static HRESULT WINAPI
IShellView_fnGetCurrentInfo(IShellView2
*iface
, LPFOLDERSETTINGS lpfs
)
1992 IShellViewImpl
*This
= impl_from_IShellView2(iface
);
1994 TRACE("(%p)->(%p) vmode=%x flags=%x\n",This
, lpfs
,
1995 This
->FolderSettings
.ViewMode
, This
->FolderSettings
.fFlags
);
1997 if (!lpfs
) return E_INVALIDARG
;
1999 *lpfs
= This
->FolderSettings
;
2003 static HRESULT WINAPI
IShellView_fnAddPropertySheetPages(IShellView2
*iface
, DWORD dwReserved
,
2004 LPFNADDPROPSHEETPAGE lpfn
, LPARAM lparam
)
2006 IShellViewImpl
*This
= impl_from_IShellView2(iface
);
2008 FIXME("(%p) stub\n",This
);
2013 static HRESULT WINAPI
IShellView_fnSaveViewState(IShellView2
*iface
)
2015 IShellViewImpl
*This
= impl_from_IShellView2(iface
);
2017 FIXME("(%p) stub\n",This
);
2022 static HRESULT WINAPI
IShellView_fnSelectItem(IShellView2
*iface
, LPCITEMIDLIST pidl
, UINT flags
)
2024 IShellViewImpl
*This
= impl_from_IShellView2(iface
);
2025 IFolderView
*view
= &This
->IFolderView_iface
;
2028 TRACE("(%p)->(pidl=%p, 0x%08x)\n",This
, pidl
, flags
);
2030 i
= LV_FindItemByPidl(This
, pidl
);
2031 if (i
== -1) return S_OK
;
2033 return IFolderView_SelectItem(view
, i
, flags
);
2036 static HRESULT WINAPI
IShellView_fnGetItemObject(IShellView2
*iface
, UINT uItem
, REFIID riid
,
2039 IShellViewImpl
*This
= impl_from_IShellView2(iface
);
2040 HRESULT hr
= E_NOINTERFACE
;
2042 TRACE("(%p)->(0x%08x, %s, %p)\n",This
, uItem
, debugstr_guid(riid
), ppvOut
);
2048 case SVGIO_BACKGROUND
:
2050 if (IsEqualIID(&IID_IContextMenu
, riid
))
2052 *ppvOut
= ISvBgCm_Constructor(This
->pSFParent
, FALSE
);
2056 FIXME("unsupported interface requested %s\n", debugstr_guid(riid
));
2060 case SVGIO_SELECTION
:
2061 ShellView_GetSelections(This
);
2062 hr
= IShellFolder_GetUIObjectOf(This
->pSFParent
, This
->hWnd
, This
->cidl
, (LPCITEMIDLIST
*)This
->apidl
, riid
, 0, ppvOut
);
2066 FIXME("unimplemented for uItem = 0x%08x\n", uItem
);
2068 TRACE("-- (%p)->(interface=%p)\n",This
, *ppvOut
);
2073 static HRESULT WINAPI
IShellView2_fnGetView(IShellView2
* iface
, SHELLVIEWID
*view_guid
, ULONG view_type
)
2075 FIXME("(%p)->(view_guid %s, view_type %#x) stub!\n", iface
, debugstr_guid(view_guid
), view_type
);
2079 static HRESULT WINAPI
IShellView2_fnCreateViewWindow2(IShellView2
*iface
,
2080 LPSV2CVW2_PARAMS view_params
)
2082 IShellViewImpl
*This
= impl_from_IShellView2(iface
);
2087 TRACE("(%p)->(view_params %p)\n", iface
, view_params
);
2089 if (view_params
->cbSize
!= sizeof(*view_params
))
2091 FIXME("Got unexpected cbSize %#x\n", view_params
->cbSize
);
2095 TRACE("-- psvPrev %p, pfs %p, psbOwner %p, prcView %p\n",
2096 view_params
->psvPrev
, view_params
->pfs
, view_params
->psbOwner
, view_params
->prcView
);
2097 TRACE("-- vmode %#x, flags %#x, left %d, top %d, right %d, bottom %d\n",
2098 view_params
->pfs
->ViewMode
, view_params
->pfs
->fFlags
, view_params
->prcView
->left
,
2099 view_params
->prcView
->top
, view_params
->prcView
->right
, view_params
->prcView
->bottom
);
2101 if (!view_params
->psbOwner
) return E_UNEXPECTED
;
2103 /* Set up the member variables */
2104 This
->pShellBrowser
= view_params
->psbOwner
;
2105 This
->FolderSettings
= *view_params
->pfs
;
2107 if (view_params
->pvid
)
2109 if (IsEqualGUID(view_params
->pvid
, &VID_LargeIcons
))
2110 This
->FolderSettings
.ViewMode
= FVM_ICON
;
2111 else if (IsEqualGUID(view_params
->pvid
, &VID_SmallIcons
))
2112 This
->FolderSettings
.ViewMode
= FVM_SMALLICON
;
2113 else if (IsEqualGUID(view_params
->pvid
, &VID_List
))
2114 This
->FolderSettings
.ViewMode
= FVM_LIST
;
2115 else if (IsEqualGUID(view_params
->pvid
, &VID_Details
))
2116 This
->FolderSettings
.ViewMode
= FVM_DETAILS
;
2117 else if (IsEqualGUID(view_params
->pvid
, &VID_Thumbnails
))
2118 This
->FolderSettings
.ViewMode
= FVM_THUMBNAIL
;
2119 else if (IsEqualGUID(view_params
->pvid
, &VID_Tile
))
2120 This
->FolderSettings
.ViewMode
= FVM_TILE
;
2121 else if (IsEqualGUID(view_params
->pvid
, &VID_ThumbStrip
))
2122 This
->FolderSettings
.ViewMode
= FVM_THUMBSTRIP
;
2124 FIXME("Ignoring unrecognized VID %s\n", debugstr_guid(view_params
->pvid
));
2127 /* Get our parent window */
2128 IShellBrowser_AddRef(This
->pShellBrowser
);
2129 IShellBrowser_GetWindow(This
->pShellBrowser
, &This
->hWndParent
);
2131 /* Try to get the ICommDlgBrowserInterface, adds a reference !!! */
2132 This
->pCommDlgBrowser
= NULL
;
2133 hr
= IShellBrowser_QueryInterface(This
->pShellBrowser
, &IID_ICommDlgBrowser
, (void **)&This
->pCommDlgBrowser
);
2135 TRACE("-- CommDlgBrowser %p\n", This
->pCommDlgBrowser
);
2137 /* If our window class has not been registered, then do so */
2138 if (!GetClassInfoW(shell32_hInstance
, SV_CLASS_NAME
, &wc
))
2140 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
2141 wc
.lpfnWndProc
= ShellView_WndProc
;
2144 wc
.hInstance
= shell32_hInstance
;
2146 wc
.hCursor
= LoadCursorW(0, (LPWSTR
)IDC_ARROW
);
2147 wc
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+ 1);
2148 wc
.lpszMenuName
= NULL
;
2149 wc
.lpszClassName
= SV_CLASS_NAME
;
2151 if (!RegisterClassW(&wc
)) return E_FAIL
;
2154 wnd
= CreateWindowExW(0, SV_CLASS_NAME
, NULL
, WS_CHILD
| WS_TABSTOP
,
2155 view_params
->prcView
->left
, view_params
->prcView
->top
,
2156 view_params
->prcView
->right
- view_params
->prcView
->left
,
2157 view_params
->prcView
->bottom
- view_params
->prcView
->top
,
2158 This
->hWndParent
, 0, shell32_hInstance
, This
);
2164 IShellBrowser_Release(This
->pShellBrowser
);
2168 SetWindowPos(wnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_SHOWWINDOW
);
2171 view_params
->hwndView
= wnd
;
2176 static HRESULT WINAPI
IShellView2_fnHandleRename(IShellView2
* iface
, LPCITEMIDLIST new_pidl
)
2178 FIXME("(%p)->(new_pidl %p) stub!\n", iface
, new_pidl
);
2182 static HRESULT WINAPI
IShellView2_fnSelectAndPositionItem(IShellView2
*iface
, LPCITEMIDLIST item
,
2183 UINT flags
, POINT
*point
)
2185 IShellViewImpl
*This
= impl_from_IShellView2(iface
);
2189 TRACE("(%p)->(item %p, flags %#x, point %p)\n", This
, item
, flags
, point
);
2191 hr
= IShellView2_QueryInterface(iface
, &IID_IFolderView
, (void**)&view
);
2194 hr
= IFolderView_SelectAndPositionItems(view
, 1, &item
, point
, flags
);
2195 IFolderView_Release(view
);
2201 static const IShellView2Vtbl svvt
=
2203 IShellView_fnQueryInterface
,
2204 IShellView_fnAddRef
,
2205 IShellView_fnRelease
,
2206 IShellView_fnGetWindow
,
2207 IShellView_fnContextSensitiveHelp
,
2208 IShellView_fnTranslateAccelerator
,
2209 IShellView_fnEnableModeless
,
2210 IShellView_fnUIActivate
,
2211 IShellView_fnRefresh
,
2212 IShellView_fnCreateViewWindow
,
2213 IShellView_fnDestroyViewWindow
,
2214 IShellView_fnGetCurrentInfo
,
2215 IShellView_fnAddPropertySheetPages
,
2216 IShellView_fnSaveViewState
,
2217 IShellView_fnSelectItem
,
2218 IShellView_fnGetItemObject
,
2219 IShellView2_fnGetView
,
2220 IShellView2_fnCreateViewWindow2
,
2221 IShellView2_fnHandleRename
,
2222 IShellView2_fnSelectAndPositionItem
,
2226 /**********************************************************
2227 * ISVOleCmdTarget_QueryInterface (IUnknown)
2229 static HRESULT WINAPI
ISVOleCmdTarget_QueryInterface(
2230 IOleCommandTarget
* iface
,
2234 IShellViewImpl
*This
= impl_from_IOleCommandTarget(iface
);
2236 return IShellView2_QueryInterface(&This
->IShellView2_iface
, iid
, ppvObj
);
2239 /**********************************************************
2240 * ISVOleCmdTarget_AddRef (IUnknown)
2242 static ULONG WINAPI
ISVOleCmdTarget_AddRef(
2243 IOleCommandTarget
* iface
)
2245 IShellViewImpl
*This
= impl_from_IOleCommandTarget(iface
);
2247 return IShellView2_AddRef(&This
->IShellView2_iface
);
2250 /**********************************************************
2251 * ISVOleCmdTarget_Release (IUnknown)
2253 static ULONG WINAPI
ISVOleCmdTarget_Release(
2254 IOleCommandTarget
* iface
)
2256 IShellViewImpl
*This
= impl_from_IOleCommandTarget(iface
);
2258 return IShellView2_Release(&This
->IShellView2_iface
);
2261 /**********************************************************
2262 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2264 static HRESULT WINAPI
ISVOleCmdTarget_QueryStatus(
2265 IOleCommandTarget
*iface
,
2266 const GUID
*pguidCmdGroup
,
2269 OLECMDTEXT
*pCmdText
)
2271 IShellViewImpl
*This
= impl_from_IOleCommandTarget(iface
);
2274 FIXME("(%p)->(%s %d %p %p)\n",
2275 This
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
2278 return E_INVALIDARG
;
2279 for (i
= 0; i
< cCmds
; i
++)
2281 FIXME("\tprgCmds[%d].cmdID = %d\n", i
, prgCmds
[i
].cmdID
);
2282 prgCmds
[i
].cmdf
= 0;
2284 return OLECMDERR_E_UNKNOWNGROUP
;
2287 /**********************************************************
2288 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2290 * nCmdID is the OLECMDID_* enumeration
2292 static HRESULT WINAPI
ISVOleCmdTarget_Exec(
2293 IOleCommandTarget
*iface
,
2294 const GUID
* pguidCmdGroup
,
2300 IShellViewImpl
*This
= impl_from_IOleCommandTarget(iface
);
2302 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2303 This
, debugstr_guid(pguidCmdGroup
), nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2306 return OLECMDERR_E_UNKNOWNGROUP
;
2307 if (IsEqualIID(pguidCmdGroup
, &CGID_Explorer
) &&
2309 (nCmdexecopt
== 4) && pvaOut
)
2311 if (IsEqualIID(pguidCmdGroup
, &CGID_ShellDocView
) &&
2316 return OLECMDERR_E_UNKNOWNGROUP
;
2319 static const IOleCommandTargetVtbl ctvt
=
2321 ISVOleCmdTarget_QueryInterface
,
2322 ISVOleCmdTarget_AddRef
,
2323 ISVOleCmdTarget_Release
,
2324 ISVOleCmdTarget_QueryStatus
,
2325 ISVOleCmdTarget_Exec
2328 /**********************************************************
2329 * ISVDropTarget implementation
2332 static HRESULT WINAPI
ISVDropTarget_QueryInterface(
2337 IShellViewImpl
*This
= impl_from_IDropTarget(iface
);
2339 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This
,debugstr_guid(riid
),ppvObj
);
2341 return IShellView2_QueryInterface(&This
->IShellView2_iface
, riid
, ppvObj
);
2344 static ULONG WINAPI
ISVDropTarget_AddRef( IDropTarget
*iface
)
2346 IShellViewImpl
*This
= impl_from_IDropTarget(iface
);
2348 TRACE("(%p)->(count=%u)\n",This
,This
->ref
);
2350 return IShellView2_AddRef(&This
->IShellView2_iface
);
2353 static ULONG WINAPI
ISVDropTarget_Release( IDropTarget
*iface
)
2355 IShellViewImpl
*This
= impl_from_IDropTarget(iface
);
2357 TRACE("(%p)->(count=%u)\n",This
,This
->ref
);
2359 return IShellView2_Release(&This
->IShellView2_iface
);
2362 /******************************************************************************
2363 * drag_notify_subitem [Internal]
2365 * Figure out the shellfolder object, which is currently under the mouse cursor
2366 * and notify it via the IDropTarget interface.
2369 #define SCROLLAREAWIDTH 20
2371 static HRESULT
drag_notify_subitem(IShellViewImpl
*This
, DWORD grfKeyState
, POINTL pt
,
2374 LVHITTESTINFO htinfo
;
2380 /* Map from global to client coordinates and query the index of the listview-item, which is
2381 * currently under the mouse cursor. */
2384 htinfo
.flags
= LVHT_ONITEM
;
2385 ScreenToClient(This
->hWndList
, &htinfo
.pt
);
2386 lResult
= SendMessageW(This
->hWndList
, LVM_HITTEST
, 0, (LPARAM
)&htinfo
);
2388 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2389 GetClientRect(This
->hWndList
, &clientRect
);
2390 if (htinfo
.pt
.x
== This
->ptLastMousePos
.x
&& htinfo
.pt
.y
== This
->ptLastMousePos
.y
&&
2391 (htinfo
.pt
.x
< SCROLLAREAWIDTH
|| htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
||
2392 htinfo
.pt
.y
< SCROLLAREAWIDTH
|| htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
))
2394 This
->cScrollDelay
= (This
->cScrollDelay
+ 1) % 5; /* DragOver is called every 50 ms */
2395 if (This
->cScrollDelay
== 0) { /* Mouse did hover another 250 ms over the scroll-area */
2396 if (htinfo
.pt
.x
< SCROLLAREAWIDTH
)
2397 SendMessageW(This
->hWndList
, WM_HSCROLL
, SB_LINEUP
, 0);
2398 if (htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
)
2399 SendMessageW(This
->hWndList
, WM_HSCROLL
, SB_LINEDOWN
, 0);
2400 if (htinfo
.pt
.y
< SCROLLAREAWIDTH
)
2401 SendMessageW(This
->hWndList
, WM_VSCROLL
, SB_LINEUP
, 0);
2402 if (htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
)
2403 SendMessageW(This
->hWndList
, WM_VSCROLL
, SB_LINEDOWN
, 0);
2406 This
->cScrollDelay
= 0; /* Reset, if the cursor is not over the listview's scroll-area */
2408 This
->ptLastMousePos
= htinfo
.pt
;
2410 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2411 if (This
->pCurDropTarget
&& lResult
== This
->iDragOverItem
)
2412 return IDropTarget_DragOver(This
->pCurDropTarget
, grfKeyState
, pt
, pdwEffect
);
2414 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2415 if (This
->pCurDropTarget
) {
2416 IDropTarget_DragLeave(This
->pCurDropTarget
);
2417 IDropTarget_Release(This
->pCurDropTarget
);
2418 This
->pCurDropTarget
= NULL
;
2421 This
->iDragOverItem
= lResult
;
2422 if (lResult
== -1) {
2423 /* We are not above one of the listview's subitems. Bind to the parent folder's
2424 * DropTarget interface. */
2425 hr
= IShellFolder_QueryInterface(This
->pSFParent
, &IID_IDropTarget
,
2426 (LPVOID
*)&This
->pCurDropTarget
);
2428 /* Query the relative PIDL of the shellfolder object represented by the currently
2429 * dragged over listview-item ... */
2430 lvItem
.mask
= LVIF_PARAM
;
2431 lvItem
.iItem
= lResult
;
2432 lvItem
.iSubItem
= 0;
2433 SendMessageW(This
->hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
2435 /* ... and bind pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2436 hr
= IShellFolder_GetUIObjectOf(This
->pSFParent
, This
->hWndList
, 1,
2437 (LPCITEMIDLIST
*)&lvItem
.lParam
, &IID_IDropTarget
, NULL
, (LPVOID
*)&This
->pCurDropTarget
);
2440 /* If anything failed, pCurDropTarget should be NULL now, which ought to be a save state. */
2444 /* Notify the item just entered via DragEnter. */
2445 return IDropTarget_DragEnter(This
->pCurDropTarget
, This
->pCurDataObject
, grfKeyState
, pt
, pdwEffect
);
2448 static HRESULT WINAPI
ISVDropTarget_DragEnter(IDropTarget
*iface
, IDataObject
*pDataObject
,
2449 DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2451 IShellViewImpl
*This
= impl_from_IDropTarget(iface
);
2453 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2454 This
->pCurDataObject
= pDataObject
;
2455 IDataObject_AddRef(pDataObject
);
2457 return drag_notify_subitem(This
, grfKeyState
, pt
, pdwEffect
);
2460 static HRESULT WINAPI
ISVDropTarget_DragOver(IDropTarget
*iface
, DWORD grfKeyState
, POINTL pt
,
2463 IShellViewImpl
*This
= impl_from_IDropTarget(iface
);
2464 return drag_notify_subitem(This
, grfKeyState
, pt
, pdwEffect
);
2467 static HRESULT WINAPI
ISVDropTarget_DragLeave(IDropTarget
*iface
)
2469 IShellViewImpl
*This
= impl_from_IDropTarget(iface
);
2471 if (This
->pCurDropTarget
)
2473 IDropTarget_DragLeave(This
->pCurDropTarget
);
2474 IDropTarget_Release(This
->pCurDropTarget
);
2475 This
->pCurDropTarget
= NULL
;
2478 if (This
->pCurDataObject
)
2480 IDataObject_Release(This
->pCurDataObject
);
2481 This
->pCurDataObject
= NULL
;
2484 This
->iDragOverItem
= 0;
2489 static HRESULT WINAPI
ISVDropTarget_Drop(IDropTarget
*iface
, IDataObject
* pDataObject
,
2490 DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2492 IShellViewImpl
*This
= impl_from_IDropTarget(iface
);
2494 IDropTarget_Drop(This
->pCurDropTarget
, pDataObject
, grfKeyState
, pt
, pdwEffect
);
2496 IDropTarget_Release(This
->pCurDropTarget
);
2497 IDataObject_Release(This
->pCurDataObject
);
2498 This
->pCurDataObject
= NULL
;
2499 This
->pCurDropTarget
= NULL
;
2500 This
->iDragOverItem
= 0;
2505 static const IDropTargetVtbl dtvt
=
2507 ISVDropTarget_QueryInterface
,
2508 ISVDropTarget_AddRef
,
2509 ISVDropTarget_Release
,
2510 ISVDropTarget_DragEnter
,
2511 ISVDropTarget_DragOver
,
2512 ISVDropTarget_DragLeave
,
2516 /**********************************************************
2517 * ISVDropSource implementation
2520 static HRESULT WINAPI
ISVDropSource_QueryInterface(
2525 IShellViewImpl
*This
= impl_from_IDropSource(iface
);
2527 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This
,debugstr_guid(riid
),ppvObj
);
2529 return IShellView2_QueryInterface(&This
->IShellView2_iface
, riid
, ppvObj
);
2532 static ULONG WINAPI
ISVDropSource_AddRef( IDropSource
*iface
)
2534 IShellViewImpl
*This
= impl_from_IDropSource(iface
);
2536 TRACE("(%p)->(count=%u)\n",This
,This
->ref
);
2538 return IShellView2_AddRef(&This
->IShellView2_iface
);
2541 static ULONG WINAPI
ISVDropSource_Release( IDropSource
*iface
)
2543 IShellViewImpl
*This
= impl_from_IDropSource(iface
);
2545 TRACE("(%p)->(count=%u)\n",This
,This
->ref
);
2547 return IShellView2_Release(&This
->IShellView2_iface
);
2550 static HRESULT WINAPI
ISVDropSource_QueryContinueDrag(
2552 BOOL fEscapePressed
,
2555 IShellViewImpl
*This
= impl_from_IDropSource(iface
);
2556 TRACE("(%p)\n",This
);
2559 return DRAGDROP_S_CANCEL
;
2560 else if (!(grfKeyState
& MK_LBUTTON
) && !(grfKeyState
& MK_RBUTTON
))
2561 return DRAGDROP_S_DROP
;
2566 static HRESULT WINAPI
ISVDropSource_GiveFeedback(
2570 IShellViewImpl
*This
= impl_from_IDropSource(iface
);
2571 TRACE("(%p)\n",This
);
2573 return DRAGDROP_S_USEDEFAULTCURSORS
;
2576 static const IDropSourceVtbl dsvt
=
2578 ISVDropSource_QueryInterface
,
2579 ISVDropSource_AddRef
,
2580 ISVDropSource_Release
,
2581 ISVDropSource_QueryContinueDrag
,
2582 ISVDropSource_GiveFeedback
2584 /**********************************************************
2585 * ISVViewObject implementation
2588 static HRESULT WINAPI
ISVViewObject_QueryInterface(
2593 IShellViewImpl
*This
= impl_from_IViewObject(iface
);
2595 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This
,debugstr_guid(riid
),ppvObj
);
2597 return IShellView2_QueryInterface(&This
->IShellView2_iface
, riid
, ppvObj
);
2600 static ULONG WINAPI
ISVViewObject_AddRef( IViewObject
*iface
)
2602 IShellViewImpl
*This
= impl_from_IViewObject(iface
);
2604 TRACE("(%p)->(count=%u)\n",This
,This
->ref
);
2606 return IShellView2_AddRef(&This
->IShellView2_iface
);
2609 static ULONG WINAPI
ISVViewObject_Release( IViewObject
*iface
)
2611 IShellViewImpl
*This
= impl_from_IViewObject(iface
);
2613 TRACE("(%p)->(count=%u)\n",This
,This
->ref
);
2615 return IShellView2_Release(&This
->IShellView2_iface
);
2618 static HRESULT WINAPI
ISVViewObject_Draw(
2623 DVTARGETDEVICE
* ptd
,
2626 LPCRECTL lprcBounds
,
2627 LPCRECTL lprcWBounds
,
2628 BOOL (CALLBACK
*pfnContinue
)(ULONG_PTR dwContinue
),
2629 ULONG_PTR dwContinue
)
2632 IShellViewImpl
*This
= impl_from_IViewObject(iface
);
2634 FIXME("Stub: This=%p\n",This
);
2638 static HRESULT WINAPI
ISVViewObject_GetColorSet(
2643 DVTARGETDEVICE
* ptd
,
2644 HDC hicTargetDevice
,
2645 LOGPALETTE
** ppColorSet
)
2648 IShellViewImpl
*This
= impl_from_IViewObject(iface
);
2650 FIXME("Stub: This=%p\n",This
);
2654 static HRESULT WINAPI
ISVViewObject_Freeze(
2662 IShellViewImpl
*This
= impl_from_IViewObject(iface
);
2664 FIXME("Stub: This=%p\n",This
);
2668 static HRESULT WINAPI
ISVViewObject_Unfreeze(
2673 IShellViewImpl
*This
= impl_from_IViewObject(iface
);
2675 FIXME("Stub: This=%p\n",This
);
2679 static HRESULT WINAPI
ISVViewObject_SetAdvise(
2683 IAdviseSink
* pAdvSink
)
2686 IShellViewImpl
*This
= impl_from_IViewObject(iface
);
2688 FIXME("partial stub: %p %08x %08x %p\n",
2689 This
, aspects
, advf
, pAdvSink
);
2691 /* FIXME: we set the AdviseSink, but never use it to send any advice */
2692 This
->pAdvSink
= pAdvSink
;
2693 This
->dwAspects
= aspects
;
2694 This
->dwAdvf
= advf
;
2699 static HRESULT WINAPI
ISVViewObject_GetAdvise(
2703 IAdviseSink
** ppAdvSink
)
2706 IShellViewImpl
*This
= impl_from_IViewObject(iface
);
2708 TRACE("This=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n",
2709 This
, pAspects
, pAdvf
, ppAdvSink
);
2713 IAdviseSink_AddRef( This
->pAdvSink
);
2714 *ppAdvSink
= This
->pAdvSink
;
2717 *pAspects
= This
->dwAspects
;
2719 *pAdvf
= This
->dwAdvf
;
2725 static const IViewObjectVtbl vovt
=
2727 ISVViewObject_QueryInterface
,
2728 ISVViewObject_AddRef
,
2729 ISVViewObject_Release
,
2731 ISVViewObject_GetColorSet
,
2732 ISVViewObject_Freeze
,
2733 ISVViewObject_Unfreeze
,
2734 ISVViewObject_SetAdvise
,
2735 ISVViewObject_GetAdvise
2739 static HRESULT WINAPI
IFView_QueryInterface(
2744 IShellViewImpl
*This
= impl_from_IFolderView(iface
);
2745 TRACE("(%p)->(IID:%s,%p)\n", This
, debugstr_guid(riid
), ppvObj
);
2746 return IShellView2_QueryInterface(&This
->IShellView2_iface
, riid
, ppvObj
);
2749 static ULONG WINAPI
IFView_AddRef( IFolderView
*iface
)
2751 IShellViewImpl
*This
= impl_from_IFolderView(iface
);
2752 TRACE("(%p)->(count=%u)\n", This
, This
->ref
);
2753 return IShellView2_AddRef(&This
->IShellView2_iface
);
2756 static ULONG WINAPI
IFView_Release( IFolderView
*iface
)
2758 IShellViewImpl
*This
= impl_from_IFolderView(iface
);
2759 TRACE("(%p)->(count=%u)\n", This
, This
->ref
);
2760 return IShellView2_Release(&This
->IShellView2_iface
);
2763 static HRESULT WINAPI
IFView_GetCurrentViewMode(IFolderView
*iface
, UINT
*mode
)
2765 IShellViewImpl
*This
= impl_from_IFolderView(iface
);
2766 TRACE("(%p)->(%p), stub\n", This
, mode
);
2769 return E_INVALIDARG
;
2771 *mode
= This
->FolderSettings
.ViewMode
;
2775 static HRESULT WINAPI
IFView_SetCurrentViewMode(IFolderView
*iface
, UINT mode
)
2777 IShellViewImpl
*This
= impl_from_IFolderView(iface
);
2779 TRACE("(%p)->(%u), stub\n", This
, mode
);
2781 if((mode
< FVM_FIRST
|| mode
> FVM_LAST
) &&
2783 return E_INVALIDARG
;
2785 /* Windows before Vista uses LVM_SETVIEW and possibly
2786 LVM_SETEXTENDEDLISTVIEWSTYLE to set the style of the listview,
2787 while later versions seem to accomplish this through other
2789 dwStyle
= ViewModeToListStyle(mode
);
2790 SetStyle(This
, dwStyle
, LVS_TYPEMASK
);
2792 /* This will not necessarily be the actual mode set above.
2793 This mimics the behavior of Windows XP. */
2794 This
->FolderSettings
.ViewMode
= mode
;
2799 static HRESULT WINAPI
IFView_GetFolder(IFolderView
*iface
, REFIID riid
, void **ppv
)
2801 IShellViewImpl
*This
= impl_from_IFolderView(iface
);
2803 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(riid
), ppv
);
2805 if (!ppv
) return E_POINTER
;
2807 if (IsEqualIID(riid
, &IID_IShellFolder
))
2809 *ppv
= This
->pSFParent
;
2813 return E_NOINTERFACE
;
2816 static HRESULT WINAPI
IFView_Item(IFolderView
*iface
, int index
, PITEMID_CHILD
*ppidl
)
2818 IShellViewImpl
*This
= impl_from_IFolderView(iface
);
2821 TRACE("(%p)->(%d %p)\n", This
, index
, ppidl
);
2823 item
.mask
= LVIF_PARAM
;
2826 if (SendMessageW(This
->hWndList
, LVM_GETITEMW
, 0, (LPARAM
)&item
))
2828 *ppidl
= ILClone((PITEMID_CHILD
)item
.lParam
);
2834 return E_INVALIDARG
;
2838 static HRESULT WINAPI
IFView_ItemCount(IFolderView
*iface
, UINT flags
, int *items
)
2840 IShellViewImpl
*This
= impl_from_IFolderView(iface
);
2842 TRACE("(%p)->(%u %p)\n", This
, flags
, items
);
2844 if (flags
!= SVGIO_ALLVIEW
)
2845 FIXME("some flags unsupported, %x\n", flags
& ~SVGIO_ALLVIEW
);
2847 *items
= SendMessageW(This
->hWndList
, LVM_GETITEMCOUNT
, 0, 0);
2852 static HRESULT WINAPI
IFView_Items(IFolderView
*iface
, UINT flags
, REFIID riid
, void **ppv
)
2854 IShellViewImpl
*This
= impl_from_IFolderView(iface
);
2855 FIXME("(%p)->(%u %s %p), stub\n", This
, flags
, debugstr_guid(riid
), ppv
);
2859 static HRESULT WINAPI
IFView_GetSelectionMarkedItem(IFolderView
*iface
, int *item
)
2861 IShellViewImpl
*This
= impl_from_IFolderView(iface
);
2863 TRACE("(%p)->(%p)\n", This
, item
);
2865 *item
= SendMessageW(This
->hWndList
, LVM_GETSELECTIONMARK
, 0, 0);
2870 static HRESULT WINAPI
IFView_GetFocusedItem(IFolderView
*iface
, int *item
)
2872 IShellViewImpl
*This
= impl_from_IFolderView(iface
);
2874 TRACE("(%p)->(%p)\n", This
, item
);
2876 *item
= SendMessageW(This
->hWndList
, LVM_GETNEXTITEM
, -1, LVNI_FOCUSED
);
2881 static HRESULT WINAPI
IFView_GetItemPosition(IFolderView
*iface
, PCUITEMID_CHILD pidl
, POINT
*ppt
)
2883 IShellViewImpl
*This
= impl_from_IFolderView(iface
);
2884 FIXME("(%p)->(%p %p), stub\n", This
, pidl
, ppt
);
2888 static HRESULT WINAPI
IFView_GetSpacing(IFolderView
*iface
, POINT
*pt
)
2890 IShellViewImpl
*This
= impl_from_IFolderView(iface
);
2892 TRACE("(%p)->(%p)\n", This
, pt
);
2894 if (!This
->hWndList
) return S_FALSE
;
2899 ret
= SendMessageW(This
->hWndList
, LVM_GETITEMSPACING
, 0, 0);
2901 pt
->x
= LOWORD(ret
);
2902 pt
->y
= HIWORD(ret
);
2908 static HRESULT WINAPI
IFView_GetDefaultSpacing(IFolderView
*iface
, POINT
*pt
)
2910 IShellViewImpl
*This
= impl_from_IFolderView(iface
);
2911 FIXME("(%p)->(%p), stub\n", This
, pt
);
2915 static HRESULT WINAPI
IFView_GetAutoArrange(IFolderView
*iface
)
2917 IShellViewImpl
*This
= impl_from_IFolderView(iface
);
2918 FIXME("(%p), stub\n", This
);
2922 static HRESULT WINAPI
IFView_SelectItem(IFolderView
*iface
, int item
, DWORD flags
)
2924 IShellViewImpl
*This
= impl_from_IFolderView(iface
);
2927 TRACE("(%p)->(%d, %x)\n", This
, item
, flags
);
2930 lvItem
.stateMask
= LVIS_SELECTED
;
2932 if (flags
& SVSI_ENSUREVISIBLE
)
2933 SendMessageW(This
->hWndList
, LVM_ENSUREVISIBLE
, item
, 0);
2936 if (flags
& SVSI_DESELECTOTHERS
)
2937 SendMessageW(This
->hWndList
, LVM_SETITEMSTATE
, -1, (LPARAM
)&lvItem
);
2940 if (flags
& SVSI_SELECT
)
2941 lvItem
.state
|= LVIS_SELECTED
;
2943 if (flags
& SVSI_FOCUSED
)
2944 lvItem
.stateMask
|= LVIS_FOCUSED
;
2946 SendMessageW(This
->hWndList
, LVM_SETITEMSTATE
, item
, (LPARAM
)&lvItem
);
2948 if (flags
& SVSI_EDIT
)
2949 SendMessageW(This
->hWndList
, LVM_EDITLABELW
, item
, 0);
2954 static HRESULT WINAPI
IFView_SelectAndPositionItems(IFolderView
*iface
, UINT cidl
,
2955 PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD flags
)
2957 IShellViewImpl
*This
= impl_from_IFolderView(iface
);
2958 FIXME("(%p)->(%u %p %p %x), stub\n", This
, cidl
, apidl
, apt
, flags
);
2962 static const IFolderViewVtbl fviewvt
=
2964 IFView_QueryInterface
,
2967 IFView_GetCurrentViewMode
,
2968 IFView_SetCurrentViewMode
,
2973 IFView_GetSelectionMarkedItem
,
2974 IFView_GetFocusedItem
,
2975 IFView_GetItemPosition
,
2977 IFView_GetDefaultSpacing
,
2978 IFView_GetAutoArrange
,
2980 IFView_SelectAndPositionItems
2983 /* IShellFolderView */
2984 static HRESULT WINAPI
IShellFolderView_fnQueryInterface(
2985 IShellFolderView
*iface
,
2989 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
2990 TRACE("(%p)->(IID:%s,%p)\n", This
, debugstr_guid(riid
), ppvObj
);
2991 return IShellView2_QueryInterface(&This
->IShellView2_iface
, riid
, ppvObj
);
2994 static ULONG WINAPI
IShellFolderView_fnAddRef(IShellFolderView
*iface
)
2996 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
2997 TRACE("(%p)->(count=%u)\n", This
, This
->ref
);
2998 return IShellView2_AddRef(&This
->IShellView2_iface
);
3001 static ULONG WINAPI
IShellFolderView_fnRelease(IShellFolderView
*iface
)
3003 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3004 TRACE("(%p)->(count=%u)\n", This
, This
->ref
);
3005 return IShellView2_Release(&This
->IShellView2_iface
);
3008 static HRESULT WINAPI
IShellFolderView_fnRearrange(IShellFolderView
*iface
, LPARAM sort
)
3010 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3011 FIXME("(%p)->(%ld) stub\n", This
, sort
);
3015 static HRESULT WINAPI
IShellFolderView_fnGetArrangeParam(IShellFolderView
*iface
, LPARAM
*sort
)
3017 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3018 FIXME("(%p)->(%p) stub\n", This
, sort
);
3022 static HRESULT WINAPI
IShellFolderView_fnArrangeGrid(IShellFolderView
*iface
)
3024 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3025 FIXME("(%p) stub\n", This
);
3029 static HRESULT WINAPI
IShellFolderView_fnAutoArrange(IShellFolderView
*iface
)
3031 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3032 FIXME("(%p) stub\n", This
);
3036 static HRESULT WINAPI
IShellFolderView_fnGetAutoArrange(IShellFolderView
*iface
)
3038 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3039 IFolderView
*view
= &This
->IFolderView_iface
;
3041 TRACE("(%p)\n", This
);
3042 return IFolderView_GetAutoArrange(view
);
3045 static HRESULT WINAPI
IShellFolderView_fnAddObject(
3046 IShellFolderView
*iface
,
3050 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3051 FIXME("(%p)->(%p %p) stub\n", This
, pidl
, item
);
3055 static HRESULT WINAPI
IShellFolderView_fnGetObject(
3056 IShellFolderView
*iface
,
3057 PITEMID_CHILD
*pidl
,
3060 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3061 IFolderView
*view
= &This
->IFolderView_iface
;
3063 TRACE("(%p)->(%p %d)\n", This
, pidl
, item
);
3064 return IFolderView_Item(view
, item
, pidl
);
3067 static HRESULT WINAPI
IShellFolderView_fnRemoveObject(
3068 IShellFolderView
*iface
,
3072 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3074 TRACE("(%p)->(%p %p)\n", This
, pidl
, item
);
3078 *item
= LV_FindItemByPidl(This
, ILFindLastID(pidl
));
3079 SendMessageW(This
->hWndList
, LVM_DELETEITEM
, *item
, 0);
3084 SendMessageW(This
->hWndList
, LVM_DELETEALLITEMS
, 0, 0);
3090 static HRESULT WINAPI
IShellFolderView_fnGetObjectCount(
3091 IShellFolderView
*iface
,
3094 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3095 IFolderView
*view
= &This
->IFolderView_iface
;
3097 TRACE("(%p)->(%p)\n", This
, count
);
3098 return IFolderView_ItemCount(view
, SVGIO_ALLVIEW
, (INT
*)count
);
3101 static HRESULT WINAPI
IShellFolderView_fnSetObjectCount(
3102 IShellFolderView
*iface
,
3106 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3107 FIXME("(%p)->(%d %x) stub\n", This
, count
, flags
);
3111 static HRESULT WINAPI
IShellFolderView_fnUpdateObject(
3112 IShellFolderView
*iface
,
3113 PITEMID_CHILD pidl_old
,
3114 PITEMID_CHILD pidl_new
,
3117 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3118 FIXME("(%p)->(%p %p %p) stub\n", This
, pidl_old
, pidl_new
, item
);
3122 static HRESULT WINAPI
IShellFolderView_fnRefreshObject(
3123 IShellFolderView
*iface
,
3127 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3128 FIXME("(%p)->(%p %p) stub\n", This
, pidl
, item
);
3132 static HRESULT WINAPI
IShellFolderView_fnSetRedraw(
3133 IShellFolderView
*iface
,
3136 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3137 TRACE("(%p)->(%d)\n", This
, redraw
);
3139 SendMessageW(This
->hWndList
, WM_SETREDRAW
, redraw
, 0);
3144 static HRESULT WINAPI
IShellFolderView_fnGetSelectedCount(
3145 IShellFolderView
*iface
,
3148 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3149 FIXME("(%p)->(%p) stub\n", This
, count
);
3153 static HRESULT WINAPI
IShellFolderView_fnGetSelectedObjects(
3154 IShellFolderView
*iface
,
3155 PCITEMID_CHILD
**pidl
,
3158 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3160 TRACE("(%p)->(%p %p)\n", This
, pidl
, items
);
3162 *items
= ShellView_GetSelections( This
);
3166 *pidl
= LocalAlloc(0, *items
*sizeof(LPITEMIDLIST
));
3167 if (!*pidl
) return E_OUTOFMEMORY
;
3169 /* it's documented that caller shouldn't free PIDLs, only array itself */
3170 memcpy((PITEMID_CHILD
*)*pidl
, This
->apidl
, *items
*sizeof(LPITEMIDLIST
));
3176 static HRESULT WINAPI
IShellFolderView_fnIsDropOnSource(
3177 IShellFolderView
*iface
,
3178 IDropTarget
*drop_target
)
3180 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3181 FIXME("(%p)->(%p) stub\n", This
, drop_target
);
3185 static HRESULT WINAPI
IShellFolderView_fnGetDragPoint(
3186 IShellFolderView
*iface
,
3189 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3190 FIXME("(%p)->(%p) stub\n", This
, pt
);
3194 static HRESULT WINAPI
IShellFolderView_fnGetDropPoint(
3195 IShellFolderView
*iface
,
3198 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3199 FIXME("(%p)->(%p) stub\n", This
, pt
);
3203 static HRESULT WINAPI
IShellFolderView_fnMoveIcons(
3204 IShellFolderView
*iface
,
3207 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3208 TRACE("(%p)->(%p)\n", This
, obj
);
3212 static HRESULT WINAPI
IShellFolderView_fnSetItemPos(
3213 IShellFolderView
*iface
,
3214 PCUITEMID_CHILD pidl
,
3217 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3218 FIXME("(%p)->(%p %p) stub\n", This
, pidl
, pt
);
3222 static HRESULT WINAPI
IShellFolderView_fnIsBkDropTarget(
3223 IShellFolderView
*iface
,
3224 IDropTarget
*drop_target
)
3226 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3227 FIXME("(%p)->(%p) stub\n", This
, drop_target
);
3231 static HRESULT WINAPI
IShellFolderView_fnSetClipboard(
3232 IShellFolderView
*iface
,
3235 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3236 FIXME("(%p)->(%d) stub\n", This
, move
);
3240 static HRESULT WINAPI
IShellFolderView_fnSetPoints(
3241 IShellFolderView
*iface
,
3244 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3245 FIXME("(%p)->(%p) stub\n", This
, obj
);
3249 static HRESULT WINAPI
IShellFolderView_fnGetItemSpacing(
3250 IShellFolderView
*iface
,
3251 ITEMSPACING
*spacing
)
3253 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3254 FIXME("(%p)->(%p) stub\n", This
, spacing
);
3258 static HRESULT WINAPI
IShellFolderView_fnSetCallback(
3259 IShellFolderView
*iface
,
3260 IShellFolderViewCB
*new_cb
,
3261 IShellFolderViewCB
**old_cb
)
3264 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3265 FIXME("(%p)->(%p %p) stub\n", This
, new_cb
, old_cb
);
3269 static HRESULT WINAPI
IShellFolderView_fnSelect(
3270 IShellFolderView
*iface
,
3273 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3274 FIXME("(%p)->(%d) stub\n", This
, flags
);
3278 static HRESULT WINAPI
IShellFolderView_fnQuerySupport(
3279 IShellFolderView
*iface
,
3282 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3283 TRACE("(%p)->(%p)\n", This
, support
);
3287 static HRESULT WINAPI
IShellFolderView_fnSetAutomationObject(
3288 IShellFolderView
*iface
,
3291 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3292 FIXME("(%p)->(%p) stub\n", This
, disp
);
3296 static const IShellFolderViewVtbl shellfolderviewvt
=
3298 IShellFolderView_fnQueryInterface
,
3299 IShellFolderView_fnAddRef
,
3300 IShellFolderView_fnRelease
,
3301 IShellFolderView_fnRearrange
,
3302 IShellFolderView_fnGetArrangeParam
,
3303 IShellFolderView_fnArrangeGrid
,
3304 IShellFolderView_fnAutoArrange
,
3305 IShellFolderView_fnGetAutoArrange
,
3306 IShellFolderView_fnAddObject
,
3307 IShellFolderView_fnGetObject
,
3308 IShellFolderView_fnRemoveObject
,
3309 IShellFolderView_fnGetObjectCount
,
3310 IShellFolderView_fnSetObjectCount
,
3311 IShellFolderView_fnUpdateObject
,
3312 IShellFolderView_fnRefreshObject
,
3313 IShellFolderView_fnSetRedraw
,
3314 IShellFolderView_fnGetSelectedCount
,
3315 IShellFolderView_fnGetSelectedObjects
,
3316 IShellFolderView_fnIsDropOnSource
,
3317 IShellFolderView_fnGetDragPoint
,
3318 IShellFolderView_fnGetDropPoint
,
3319 IShellFolderView_fnMoveIcons
,
3320 IShellFolderView_fnSetItemPos
,
3321 IShellFolderView_fnIsBkDropTarget
,
3322 IShellFolderView_fnSetClipboard
,
3323 IShellFolderView_fnSetPoints
,
3324 IShellFolderView_fnGetItemSpacing
,
3325 IShellFolderView_fnSetCallback
,
3326 IShellFolderView_fnSelect
,
3327 IShellFolderView_fnQuerySupport
,
3328 IShellFolderView_fnSetAutomationObject