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 IDs */
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
, &result
);
294 IShellBrowser_SendControlMsg(This
->pShellBrowser
, FCW_TOOLBAR
, TB_CHECKBUTTON
,
295 FCIDM_TB_REPORTVIEW
, This
->FolderSettings
.ViewMode
== FVM_DETAILS
, &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
;
409 HIMAGELIST big_icons
, small_icons
;
416 TRACE("(%p)\n", This
);
418 Shell_GetImageLists( &big_icons
, &small_icons
);
419 SendMessageW(This
->hWndList
, LVM_DELETEALLITEMS
, 0, 0);
420 SendMessageW(This
->hWndList
, LVM_SETIMAGELIST
, LVSIL_SMALL
, (LPARAM
)small_icons
);
421 SendMessageW(This
->hWndList
, LVM_SETIMAGELIST
, LVSIL_NORMAL
, (LPARAM
)big_icons
);
423 lvColumn
.mask
= LVCF_FMT
| LVCF_WIDTH
| LVCF_TEXT
;
424 lvColumn
.pszText
= nameW
;
426 if (!This
->pSF2Parent
)
428 hr
= IShellFolder_QueryInterface(This
->pSFParent
, &IID_IShellDetails
, (void**)&details
);
431 WARN("IShellFolder2/IShellDetails not supported\n");
438 if (This
->pSF2Parent
)
439 hr
= IShellFolder2_GetDetailsOf(This
->pSF2Parent
, NULL
, i
, &sd
);
441 hr
= IShellDetails_GetDetailsOf(details
, NULL
, i
, &sd
);
442 if (FAILED(hr
)) break;
444 lvColumn
.fmt
= sd
.fmt
;
445 lvColumn
.cx
= sd
.cxChar
*8; /* chars->pixel */
446 StrRetToStrNW(nameW
, sizeof(nameW
)/sizeof(WCHAR
), &sd
.str
, NULL
);
447 SendMessageW(This
->hWndList
, LVM_INSERTCOLUMNW
, i
, (LPARAM
) &lvColumn
);
450 if (details
) IShellDetails_Release(details
);
453 /**********************************************************
454 * ShellView_CompareItems()
457 * internal, CALLBACK for DSA_Sort
459 static INT CALLBACK
ShellView_CompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
)
462 TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1
, lParam2
, (LPVOID
) lpData
);
464 if(!lpData
) return 0;
466 ret
= (SHORT
) SCODE_CODE(IShellFolder_CompareIDs((LPSHELLFOLDER
)lpData
, 0, (LPITEMIDLIST
)lParam1
, (LPITEMIDLIST
)lParam2
));
467 TRACE("ret=%i\n",ret
);
471 /*************************************************************************
472 * ShellView_ListViewCompareItems
474 * Compare Function for the Listview (FileOpen Dialog)
477 * lParam1 [I] the first ItemIdList to compare with
478 * lParam2 [I] the second ItemIdList to compare with
479 * lpData [I] The column ID for the header Ctrl to process
482 * A negative value if the first item should precede the second,
483 * a positive value if the first item should follow the second,
484 * or zero if the two items are equivalent
487 * FIXME: function does what ShellView_CompareItems is supposed to do.
488 * unify it and figure out how to use the undocumented first parameter
489 * of IShellFolder_CompareIDs to do the job this function does and
490 * move this code to IShellFolder.
491 * make LISTVIEW_SORT_INFO obsolete
492 * the way this function works is only usable if we had only
493 * filesystemfolders (25/10/99 jsch)
495 static INT CALLBACK
ShellView_ListViewCompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
)
499 char strName1
[MAX_PATH
], strName2
[MAX_PATH
];
500 BOOL bIsFolder1
, bIsFolder2
,bIsBothFolder
;
501 LPITEMIDLIST pItemIdList1
= lParam1
;
502 LPITEMIDLIST pItemIdList2
= lParam2
;
503 LISTVIEW_SORT_INFO
*pSortInfo
= (LPLISTVIEW_SORT_INFO
) lpData
;
506 bIsFolder1
= _ILIsFolder(pItemIdList1
);
507 bIsFolder2
= _ILIsFolder(pItemIdList2
);
508 bIsBothFolder
= bIsFolder1
&& bIsFolder2
;
510 /* When sorting between a File and a Folder, the Folder gets sorted first */
511 if( (bIsFolder1
|| bIsFolder2
) && !bIsBothFolder
)
513 nDiff
= bIsFolder1
? -1 : 1;
517 /* Sort by Time: Folders or Files can be sorted */
519 if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_TIME
)
521 _ILGetFileDateTime(pItemIdList1
, &fd1
);
522 _ILGetFileDateTime(pItemIdList2
, &fd2
);
523 nDiff
= CompareFileTime(&fd2
, &fd1
);
525 /* Sort by Attribute: Folder or Files can be sorted */
526 else if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_ATTRIB
)
528 _ILGetFileAttributes(pItemIdList1
, strName1
, MAX_PATH
);
529 _ILGetFileAttributes(pItemIdList2
, strName2
, MAX_PATH
);
530 nDiff
= lstrcmpiA(strName1
, strName2
);
532 /* Sort by FileName: Folder or Files can be sorted */
533 else if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_NAME
|| bIsBothFolder
)
536 _ILSimpleGetText(pItemIdList1
, strName1
, MAX_PATH
);
537 _ILSimpleGetText(pItemIdList2
, strName2
, MAX_PATH
);
538 nDiff
= lstrcmpiA(strName1
, strName2
);
540 /* Sort by File Size, Only valid for Files */
541 else if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_SIZE
)
543 nDiff
= (INT
)(_ILGetFileSize(pItemIdList1
, NULL
, 0) - _ILGetFileSize(pItemIdList2
, NULL
, 0));
545 /* Sort by File Type, Only valid for Files */
546 else if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_TYPE
)
549 _ILGetFileType(pItemIdList1
, strName1
, MAX_PATH
);
550 _ILGetFileType(pItemIdList2
, strName2
, MAX_PATH
);
551 nDiff
= lstrcmpiA(strName1
, strName2
);
554 /* If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
558 _ILSimpleGetText(pItemIdList1
, strName1
, MAX_PATH
);
559 _ILSimpleGetText(pItemIdList2
, strName2
, MAX_PATH
);
560 nDiff
= lstrcmpiA(strName1
, strName2
);
563 if(!pSortInfo
->bIsAscending
)
572 /**********************************************************
573 * LV_FindItemByPidl()
575 static int LV_FindItemByPidl(
576 IShellViewImpl
* This
,
581 lvItem
.mask
= LVIF_PARAM
;
582 for(lvItem
.iItem
= 0;
583 SendMessageW(This
->hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
586 LPITEMIDLIST currentpidl
= (LPITEMIDLIST
) lvItem
.lParam
;
587 HRESULT hr
= IShellFolder_CompareIDs(This
->pSFParent
, 0, pidl
, currentpidl
);
588 if(SUCCEEDED(hr
) && !HRESULT_CODE(hr
))
596 /**********************************************************
599 static BOOLEAN
LV_AddItem(IShellViewImpl
* This
, LPCITEMIDLIST pidl
)
603 TRACE("(%p)(pidl=%p)\n", This
, pidl
);
605 lvItem
.mask
= LVIF_TEXT
| LVIF_IMAGE
| LVIF_PARAM
; /*set the mask*/
606 lvItem
.iItem
= SendMessageW(This
->hWndList
, LVM_GETITEMCOUNT
, 0, 0); /*add the item to the end of the list*/
608 lvItem
.lParam
= (LPARAM
) ILClone(ILFindLastID(pidl
)); /*set the item's data*/
609 lvItem
.pszText
= LPSTR_TEXTCALLBACKW
; /*get text on a callback basis*/
610 lvItem
.iImage
= I_IMAGECALLBACK
; /*get the image on a callback basis*/
611 return ListView_InsertItemW(This
->hWndList
, &lvItem
) != -1;
614 /**********************************************************
617 static BOOLEAN
LV_RenameItem(IShellViewImpl
* This
, LPCITEMIDLIST pidlOld
, LPCITEMIDLIST pidlNew
)
622 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", This
, pidlOld
, pidlNew
);
624 nItem
= LV_FindItemByPidl(This
, ILFindLastID(pidlOld
));
627 lvItem
.mask
= LVIF_PARAM
; /* only the pidl */
628 lvItem
.iItem
= nItem
;
629 SendMessageW(This
->hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
631 SHFree((LPITEMIDLIST
)lvItem
.lParam
);
632 lvItem
.mask
= LVIF_PARAM
;
633 lvItem
.iItem
= nItem
;
634 lvItem
.lParam
= (LPARAM
) ILClone(ILFindLastID(pidlNew
)); /* set the item's data */
635 SendMessageW(This
->hWndList
, LVM_SETITEMW
, 0, (LPARAM
) &lvItem
);
636 SendMessageW(This
->hWndList
, LVM_UPDATE
, nItem
, 0);
637 return TRUE
; /* FIXME: better handling */
641 /**********************************************************
642 * ShellView_FillList()
644 * - gets the objectlist from the shellfolder
646 * - fills the list into the view
649 static INT CALLBACK
fill_list( LPVOID ptr
, LPVOID arg
)
651 LPITEMIDLIST pidl
= ptr
;
652 IShellViewImpl
*This
= arg
;
653 /* in a commdlg This works as a filemask*/
654 if ( IncludeObject(This
, pidl
)==S_OK
) LV_AddItem(This
, pidl
);
659 static HRESULT
ShellView_FillList(IShellViewImpl
*This
)
661 IShellFolderView
*folderview
= &This
->IShellFolderView_iface
;
662 LPENUMIDLIST pEnumIDList
;
668 TRACE("(%p)\n", This
);
670 /* get the itemlist from the shfolder*/
671 hr
= IShellFolder_EnumObjects(This
->pSFParent
, This
->hWnd
, SHCONTF_NONFOLDERS
| SHCONTF_FOLDERS
, &pEnumIDList
);
672 if (hr
!= S_OK
) return hr
;
674 /* create a pointer array */
675 hdpa
= DPA_Create(16);
678 IEnumIDList_Release(pEnumIDList
);
679 return E_OUTOFMEMORY
;
682 /* copy the items into the array*/
683 while((S_OK
== IEnumIDList_Next(pEnumIDList
, 1, &pidl
, &fetched
)) && fetched
)
685 if (DPA_InsertPtr(hdpa
, DPA_GetPtrCount(hdpa
), pidl
) == -1)
692 DPA_Sort(hdpa
, ShellView_CompareItems
, (LPARAM
)This
->pSFParent
);
694 IShellFolderView_SetRedraw(folderview
, FALSE
);
695 DPA_DestroyCallback(hdpa
, fill_list
, This
);
696 IShellFolderView_SetRedraw(folderview
, TRUE
);
698 IEnumIDList_Release(pEnumIDList
);
703 /**********************************************************
704 * ShellView_OnCreate()
706 static LRESULT
ShellView_OnCreate(IShellViewImpl
*This
)
708 IShellView2
*iface
= &This
->IShellView2_iface
;
709 static const WCHAR accel_nameW
[] = {'s','h','v','_','a','c','c','e','l',0};
710 IPersistFolder2
*ppf2
;
714 TRACE("(%p)\n", This
);
716 if (ShellView_CreateList(This
))
718 ShellView_InitList(This
);
719 ShellView_FillList(This
);
722 hr
= IShellView2_QueryInterface(iface
, &IID_IDropTarget
, (LPVOID
*)&pdt
);
725 RegisterDragDrop(This
->hWnd
, pdt
);
726 IDropTarget_Release(pdt
);
729 /* register for receiving notifications */
730 hr
= IShellFolder_QueryInterface(This
->pSFParent
, &IID_IPersistFolder2
, (LPVOID
*)&ppf2
);
733 LPITEMIDLIST raw_pidl
;
734 SHChangeNotifyEntry ntreg
;
736 hr
= IPersistFolder2_GetCurFolder(ppf2
, &raw_pidl
);
739 LPITEMIDLIST computer_pidl
;
740 SHGetFolderLocation(NULL
,CSIDL_DRIVES
,NULL
,0,&computer_pidl
);
741 if(ILIsParent(computer_pidl
,raw_pidl
,FALSE
))
743 /* Normalize the pidl to unixfs to workaround an issue with
744 * sending notifications on dos paths
746 WCHAR path
[MAX_PATH
];
747 SHGetPathFromIDListW(raw_pidl
,path
);
748 SHParseDisplayName(path
,NULL
,(LPITEMIDLIST
*)&ntreg
.pidl
,0,NULL
);
752 ntreg
.pidl
= raw_pidl
;
753 ntreg
.fRecursive
= TRUE
;
754 This
->hNotify
= SHChangeNotifyRegister(This
->hWnd
, SHCNRF_InterruptLevel
, SHCNE_ALLEVENTS
,
755 SHV_CHANGE_NOTIFY
, 1, &ntreg
);
756 SHFree((LPITEMIDLIST
)ntreg
.pidl
);
757 SHFree(computer_pidl
);
759 IPersistFolder2_Release(ppf2
);
762 This
->hAccel
= LoadAcceleratorsW(shell32_hInstance
, accel_nameW
);
767 /**********************************************************
768 * #### Handling of the menus ####
771 /**********************************************************
772 * ShellView_BuildFileMenu()
774 static HMENU
ShellView_BuildFileMenu(IShellViewImpl
* This
)
775 { WCHAR szText
[MAX_PATH
];
780 TRACE("(%p)\n",This
);
782 hSubMenu
= CreatePopupMenu();
784 { /*get the number of items in our global array*/
785 for(nTools
= 0; Tools
[nTools
].idCommand
!= -1; nTools
++){}
787 /*add the menu items*/
788 for(i
= 0; i
< nTools
; i
++)
790 LoadStringW(shell32_hInstance
, Tools
[i
].idMenuString
, szText
, MAX_PATH
);
792 ZeroMemory(&mii
, sizeof(mii
));
793 mii
.cbSize
= sizeof(mii
);
794 mii
.fMask
= MIIM_TYPE
| MIIM_ID
| MIIM_STATE
;
796 if(BTNS_SEP
!= Tools
[i
].bStyle
) /* no separator*/
798 mii
.fType
= MFT_STRING
;
799 mii
.fState
= MFS_ENABLED
;
800 mii
.dwTypeData
= szText
;
801 mii
.wID
= Tools
[i
].idCommand
;
805 mii
.fType
= MFT_SEPARATOR
;
807 /* tack This item onto the end of the menu */
808 InsertMenuItemW(hSubMenu
, (UINT
)-1, TRUE
, &mii
);
811 TRACE("-- return (menu=%p)\n",hSubMenu
);
814 /**********************************************************
815 * ShellView_MergeFileMenu()
817 static void ShellView_MergeFileMenu(IShellViewImpl
*This
, HMENU hSubMenu
)
819 TRACE("(%p)->(submenu=%p) stub\n",This
,hSubMenu
);
823 static const WCHAR dummyW
[] = {'d','u','m','m','y','4','5',0};
826 /* insert This item at the beginning of the menu */
828 mii
.cbSize
= sizeof(mii
);
829 mii
.fMask
= MIIM_ID
| MIIM_TYPE
;
831 mii
.fType
= MFT_SEPARATOR
;
832 InsertMenuItemW(hSubMenu
, 0, TRUE
, &mii
);
834 mii
.cbSize
= sizeof(mii
);
835 mii
.fMask
= MIIM_ID
| MIIM_TYPE
| MIIM_STATE
;
836 mii
.dwTypeData
= (LPWSTR
)dummyW
;
837 mii
.fState
= MFS_ENABLED
;
838 mii
.wID
= IDM_MYFILEITEM
;
839 mii
.fType
= MFT_STRING
;
840 InsertMenuItemW(hSubMenu
, 0, TRUE
, &mii
);
846 /**********************************************************
847 * ShellView_MergeViewMenu()
850 static void ShellView_MergeViewMenu(IShellViewImpl
*This
, HMENU hSubMenu
)
852 TRACE("(%p)->(submenu=%p)\n",This
,hSubMenu
);
854 /* add a separator at the correct position in the menu */
857 static const WCHAR menuW
[] = {'M','E','N','U','_','0','0','1',0};
858 static const WCHAR viewW
[] = {'V','i','e','w',0};
861 memset(&mii
, 0, sizeof(mii
));
862 mii
.cbSize
= sizeof(mii
);
863 mii
.fMask
= MIIM_ID
| MIIM_TYPE
;
865 mii
.fType
= MFT_SEPARATOR
;
866 InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, &mii
);
868 mii
.cbSize
= sizeof(mii
);
869 mii
.fMask
= MIIM_SUBMENU
| MIIM_TYPE
| MIIM_DATA
;
870 mii
.fType
= MFT_STRING
;
871 mii
.dwTypeData
= (LPWSTR
)viewW
;
872 mii
.hSubMenu
= LoadMenuW(shell32_hInstance
, menuW
);
873 InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, &mii
);
877 /**********************************************************
878 * ShellView_GetSelections()
880 * - fills the this->apidl list with the selected objects
883 * number of selected items
885 static UINT
ShellView_GetSelections(IShellViewImpl
* This
)
892 This
->cidl
= SendMessageW(This
->hWndList
, LVM_GETSELECTEDCOUNT
, 0, 0);
893 This
->apidl
= SHAlloc(This
->cidl
* sizeof(LPITEMIDLIST
));
895 TRACE("selected=%i\n", This
->cidl
);
899 TRACE("-- Items selected =%u\n", This
->cidl
);
901 lvItem
.mask
= LVIF_STATE
| LVIF_PARAM
;
902 lvItem
.stateMask
= LVIS_SELECTED
;
906 while(ListView_GetItemW(This
->hWndList
, &lvItem
) && (i
< This
->cidl
))
908 if(lvItem
.state
& LVIS_SELECTED
)
910 This
->apidl
[i
] = (LPITEMIDLIST
)lvItem
.lParam
;
912 TRACE("-- selected Item found\n");
921 /**********************************************************
922 * ShellView_OpenSelectedItems()
924 static HRESULT
ShellView_OpenSelectedItems(IShellViewImpl
* This
)
926 static UINT CF_IDLIST
= 0;
928 IDataObject
* selection
;
932 LPCITEMIDLIST parent_pidl
;
933 WCHAR parent_path
[MAX_PATH
];
934 LPCWSTR parent_dir
= NULL
;
938 if (0 == ShellView_GetSelections(This
))
942 hr
= IShellFolder_GetUIObjectOf(This
->pSFParent
, This
->hWnd
, This
->cidl
,
943 (LPCITEMIDLIST
*)This
->apidl
, &IID_IDataObject
,
944 0, (LPVOID
*)&selection
);
950 CF_IDLIST
= RegisterClipboardFormatW(CFSTR_SHELLIDLISTW
);
952 fetc
.cfFormat
= CF_IDLIST
;
954 fetc
.dwAspect
= DVASPECT_CONTENT
;
956 fetc
.tymed
= TYMED_HGLOBAL
;
958 hr
= IDataObject_QueryGetData(selection
, &fetc
);
962 hr
= IDataObject_GetData(selection
, &fetc
, &stgm
);
966 pIDList
= GlobalLock(stgm
.u
.hGlobal
);
968 parent_pidl
= (LPCITEMIDLIST
) ((LPBYTE
)pIDList
+pIDList
->aoffset
[0]);
969 hr
= IShellFolder_GetAttributesOf(This
->pSFParent
, 1, &parent_pidl
, &attribs
);
970 if (SUCCEEDED(hr
) && (attribs
& SFGAO_FILESYSTEM
) &&
971 SHGetPathFromIDListW(parent_pidl
, parent_path
))
973 parent_dir
= parent_path
;
976 for (i
= pIDList
->cidl
; i
> 0; --i
)
980 pidl
= (LPCITEMIDLIST
)((LPBYTE
)pIDList
+pIDList
->aoffset
[i
]);
982 attribs
= SFGAO_FOLDER
;
983 hr
= IShellFolder_GetAttributesOf(This
->pSFParent
, 1, &pidl
, &attribs
);
985 if (SUCCEEDED(hr
) && ! (attribs
& SFGAO_FOLDER
))
987 SHELLEXECUTEINFOW shexinfo
;
989 shexinfo
.cbSize
= sizeof(SHELLEXECUTEINFOW
);
990 shexinfo
.fMask
= SEE_MASK_INVOKEIDLIST
; /* SEE_MASK_IDLIST is also possible. */
991 shexinfo
.hwnd
= NULL
;
992 shexinfo
.lpVerb
= NULL
;
993 shexinfo
.lpFile
= NULL
;
994 shexinfo
.lpParameters
= NULL
;
995 shexinfo
.lpDirectory
= parent_dir
;
996 shexinfo
.nShow
= SW_NORMAL
;
997 shexinfo
.lpIDList
= ILCombine(parent_pidl
, pidl
);
999 ShellExecuteExW(&shexinfo
); /* Discard error/success info */
1001 ILFree(shexinfo
.lpIDList
);
1005 GlobalUnlock(stgm
.u
.hGlobal
);
1006 ReleaseStgMedium(&stgm
);
1008 IDataObject_Release(selection
);
1013 /**********************************************************
1014 * ShellView_DoContextMenu()
1016 static void ShellView_DoContextMenu(IShellViewImpl
* This
, WORD x
, WORD y
, BOOL bDefault
)
1020 BOOL fExplore
= FALSE
;
1022 LPCONTEXTMENU pContextMenu
= NULL
;
1023 CMINVOKECOMMANDINFO cmi
;
1025 TRACE("(%p)->(0x%08x 0x%08x 0x%08x) stub\n",This
, x
, y
, bDefault
);
1027 /* look, what's selected and create a context menu object of it*/
1028 if( ShellView_GetSelections(This
) )
1030 IShellFolder_GetUIObjectOf( This
->pSFParent
, This
->hWndParent
, This
->cidl
, (LPCITEMIDLIST
*)This
->apidl
,
1031 &IID_IContextMenu
, NULL
, (LPVOID
*)&pContextMenu
);
1035 TRACE("-- pContextMenu\n");
1036 hMenu
= CreatePopupMenu();
1040 /* See if we are in Explore or Open mode. If the browser's tree is present, we are in Explore mode.*/
1041 if(SUCCEEDED(IShellBrowser_GetControlWindow(This
->pShellBrowser
,FCW_TREE
, &hwndTree
)) && hwndTree
)
1043 TRACE("-- explore mode\n");
1047 /* build the flags depending on what we can do with the selected item */
1048 wFlags
= CMF_NORMAL
| (This
->cidl
!= 1 ? 0 : CMF_CANRENAME
) | (fExplore
? CMF_EXPLORE
: 0);
1050 /* let the ContextMenu merge its items in */
1051 if (SUCCEEDED(IContextMenu_QueryContextMenu( pContextMenu
, hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, wFlags
)))
1053 if (This
->FolderSettings
.fFlags
& FWF_DESKTOP
)
1054 SetMenuDefaultItem(hMenu
, FCIDM_SHVIEW_OPEN
, MF_BYCOMMAND
);
1058 TRACE("-- get menu default command\n");
1059 uCommand
= GetMenuDefaultItem(hMenu
, FALSE
, GMDI_GOINTOPOPUPS
);
1063 TRACE("-- track popup\n");
1064 uCommand
= TrackPopupMenu( hMenu
,TPM_LEFTALIGN
| TPM_RETURNCMD
,x
,y
,0,This
->hWnd
,NULL
);
1069 TRACE("-- uCommand=%u\n", uCommand
);
1070 if (uCommand
==FCIDM_SHVIEW_OPEN
&& IsInCommDlg(This
))
1072 TRACE("-- dlg: OnDefaultCommand\n");
1073 if (OnDefaultCommand(This
) != S_OK
)
1075 ShellView_OpenSelectedItems(This
);
1080 TRACE("-- explore -- invoke command\n");
1081 ZeroMemory(&cmi
, sizeof(cmi
));
1082 cmi
.cbSize
= sizeof(cmi
);
1083 cmi
.hwnd
= This
->hWndParent
; /* this window has to answer CWM_GETISHELLBROWSER */
1084 cmi
.lpVerb
= MAKEINTRESOURCEA(uCommand
);
1085 IContextMenu_InvokeCommand(pContextMenu
, &cmi
);
1092 IContextMenu_Release(pContextMenu
);
1095 else /* background context menu */
1099 hMenu
= CreatePopupMenu();
1101 BackgroundMenu_Constructor(This
->pSFParent
, FALSE
, &IID_IContextMenu2
, (void**)&pCM
);
1102 IContextMenu2_QueryContextMenu(pCM
, hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, 0);
1104 uCommand
= TrackPopupMenu( hMenu
, TPM_LEFTALIGN
| TPM_RETURNCMD
,x
,y
,0,This
->hWnd
,NULL
);
1107 TRACE("-- (%p)->(uCommand=0x%08x )\n",This
, uCommand
);
1109 ZeroMemory(&cmi
, sizeof(cmi
));
1110 cmi
.cbSize
= sizeof(cmi
);
1111 cmi
.lpVerb
= MAKEINTRESOURCEA(uCommand
);
1112 cmi
.hwnd
= This
->hWndParent
;
1113 IContextMenu2_InvokeCommand(pCM
, &cmi
);
1115 IContextMenu2_Release(pCM
);
1119 /**********************************************************
1120 * ##### message handling #####
1123 /**********************************************************
1124 * ShellView_OnSize()
1126 static LRESULT
ShellView_OnSize(IShellViewImpl
* This
, WORD wWidth
, WORD wHeight
)
1128 TRACE("%p width=%u height=%u\n",This
, wWidth
,wHeight
);
1130 /*resize the ListView to fit our window*/
1133 MoveWindow(This
->hWndList
, 0, 0, wWidth
, wHeight
, TRUE
);
1138 /**********************************************************
1139 * ShellView_OnDeactivate()
1144 static void ShellView_OnDeactivate(IShellViewImpl
* This
)
1148 if(This
->uState
!= SVUIA_DEACTIVATE
)
1152 IShellBrowser_SetMenuSB(This
->pShellBrowser
,0, 0, 0);
1153 IShellBrowser_RemoveMenusSB(This
->pShellBrowser
,This
->hMenu
);
1154 DestroyMenu(This
->hMenu
);
1158 This
->uState
= SVUIA_DEACTIVATE
;
1162 /**********************************************************
1163 * ShellView_OnActivate()
1165 static LRESULT
ShellView_OnActivate(IShellViewImpl
*This
, UINT uState
)
1167 OLEMENUGROUPWIDTHS omw
= { {0, 0, 0, 0, 0, 0} };
1170 TRACE("(%p) uState=%x\n",This
,uState
);
1172 /* don't do anything if the state isn't really changing */
1173 if (This
->uState
== uState
) return S_OK
;
1175 ShellView_OnDeactivate(This
);
1177 /* only do This if we are active */
1178 if (uState
!= SVUIA_DEACTIVATE
)
1180 /* merge the menus */
1181 This
->hMenu
= CreateMenu();
1185 static const WCHAR dummyW
[] = {'d','u','m','m','y',' ','3','1',0};
1187 IShellBrowser_InsertMenusSB(This
->pShellBrowser
, This
->hMenu
, &omw
);
1188 TRACE("-- after fnInsertMenusSB\n");
1190 mii
.cbSize
= sizeof(mii
);
1191 mii
.fMask
= MIIM_SUBMENU
| MIIM_TYPE
| MIIM_STATE
;
1192 mii
.fType
= MFT_STRING
;
1193 mii
.fState
= MFS_ENABLED
;
1195 mii
.hSubMenu
= ShellView_BuildFileMenu(This
);
1196 mii
.hbmpChecked
= NULL
;
1197 mii
.hbmpUnchecked
= NULL
;
1199 /* build the top level menu get the menu item's text */
1200 mii
.dwTypeData
= (LPWSTR
)dummyW
;
1202 mii
.hbmpItem
= NULL
;
1204 /* insert our menu into the menu bar */
1206 InsertMenuItemW(This
->hMenu
, FCIDM_MENU_HELP
, FALSE
, &mii
);
1208 /* get the view menu so we can merge with it */
1209 memset(&mii
, 0, sizeof(mii
));
1210 mii
.cbSize
= sizeof(mii
);
1211 mii
.fMask
= MIIM_SUBMENU
;
1213 if (GetMenuItemInfoW(This
->hMenu
, FCIDM_MENU_VIEW
, FALSE
, &mii
))
1214 ShellView_MergeViewMenu(This
, mii
.hSubMenu
);
1216 /* add the items that should only be added if we have the focus */
1217 if (SVUIA_ACTIVATE_FOCUS
== uState
)
1219 /* get the file menu so we can merge with it */
1220 memset(&mii
, 0, sizeof(mii
));
1221 mii
.cbSize
= sizeof(mii
);
1222 mii
.fMask
= MIIM_SUBMENU
;
1224 if (GetMenuItemInfoW(This
->hMenu
, FCIDM_MENU_FILE
, FALSE
, &mii
))
1225 ShellView_MergeFileMenu(This
, mii
.hSubMenu
);
1228 TRACE("-- before fnSetMenuSB\n");
1229 IShellBrowser_SetMenuSB(This
->pShellBrowser
, This
->hMenu
, 0, This
->hWnd
);
1232 This
->uState
= uState
;
1237 /**********************************************************
1238 * ShellView_OnSetFocus()
1241 static LRESULT
ShellView_OnSetFocus(IShellViewImpl
* This
)
1245 /* Tell the browser one of our windows has received the focus. This
1246 should always be done before merging menus (OnActivate merges the
1247 menus) if one of our windows has the focus.*/
1249 IShellBrowser_OnViewWindowActive(This
->pShellBrowser
,(IShellView
*) This
);
1250 ShellView_OnActivate(This
, SVUIA_ACTIVATE_FOCUS
);
1252 /* Set the focus to the listview */
1253 SetFocus(This
->hWndList
);
1255 /* Notify the ICommDlgBrowser interface */
1256 OnStateChange(This
,CDBOSC_SETFOCUS
);
1261 /**********************************************************
1262 * ShellView_OnKillFocus()
1264 static LRESULT
ShellView_OnKillFocus(IShellViewImpl
* This
)
1266 TRACE("(%p) stub\n",This
);
1268 ShellView_OnActivate(This
, SVUIA_ACTIVATE_NOFOCUS
);
1269 /* Notify the ICommDlgBrowser */
1270 OnStateChange(This
,CDBOSC_KILLFOCUS
);
1275 /**********************************************************
1276 * ShellView_OnCommand()
1279 * the CmdIDs are the ones from the context menu
1281 static LRESULT
ShellView_OnCommand(IShellViewImpl
* This
,DWORD dwCmdID
, DWORD dwCmd
, HWND hwndCmd
)
1283 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n",This
, dwCmdID
, dwCmd
, hwndCmd
);
1287 case FCIDM_SHVIEW_SMALLICON
:
1288 This
->FolderSettings
.ViewMode
= FVM_SMALLICON
;
1289 SetStyle (This
, LVS_SMALLICON
, LVS_TYPEMASK
);
1293 case FCIDM_SHVIEW_BIGICON
:
1294 This
->FolderSettings
.ViewMode
= FVM_ICON
;
1295 SetStyle (This
, LVS_ICON
, LVS_TYPEMASK
);
1299 case FCIDM_SHVIEW_LISTVIEW
:
1300 This
->FolderSettings
.ViewMode
= FVM_LIST
;
1301 SetStyle (This
, LVS_LIST
, LVS_TYPEMASK
);
1305 case FCIDM_SHVIEW_REPORTVIEW
:
1306 This
->FolderSettings
.ViewMode
= FVM_DETAILS
;
1307 SetStyle (This
, LVS_REPORT
, LVS_TYPEMASK
);
1311 /* the menu IDs for sorting are 0x30... see shell32.rc */
1316 This
->ListViewSortInfo
.nHeaderID
= dwCmdID
- 0x30;
1317 This
->ListViewSortInfo
.bIsAscending
= TRUE
;
1318 This
->ListViewSortInfo
.nLastHeaderID
= This
->ListViewSortInfo
.nHeaderID
;
1319 SendMessageW(This
->hWndList
, LVM_SORTITEMS
, (WPARAM
) &This
->ListViewSortInfo
, (LPARAM
)ShellView_ListViewCompareItems
);
1323 TRACE("-- COMMAND 0x%04x unhandled\n", dwCmdID
);
1328 /**********************************************************
1329 * ShellView_OnNotify()
1332 static LRESULT
ShellView_OnNotify(IShellViewImpl
* This
, UINT CtlID
, LPNMHDR lpnmh
)
1333 { LPNMLISTVIEW lpnmlv
= (LPNMLISTVIEW
)lpnmh
;
1334 NMLVDISPINFOW
*lpdi
= (NMLVDISPINFOW
*)lpnmh
;
1337 TRACE("%p CtlID=%u lpnmh->code=%x\n",This
,CtlID
,lpnmh
->code
);
1342 TRACE("-- NM_SETFOCUS %p\n",This
);
1343 ShellView_OnSetFocus(This
);
1347 TRACE("-- NM_KILLFOCUS %p\n",This
);
1348 ShellView_OnDeactivate(This
);
1349 /* Notify the ICommDlgBrowser interface */
1350 OnStateChange(This
,CDBOSC_KILLFOCUS
);
1354 TRACE("-- NM_CUSTOMDRAW %p\n",This
);
1355 return CDRF_DODEFAULT
;
1357 case NM_RELEASEDCAPTURE
:
1358 TRACE("-- NM_RELEASEDCAPTURE %p\n",This
);
1362 TRACE("-- NM_CLICK %p\n",This
);
1366 TRACE("-- NM_RCLICK %p\n",This
);
1370 TRACE("-- NM_DBLCLK %p\n",This
);
1371 if (OnDefaultCommand(This
) != S_OK
) ShellView_OpenSelectedItems(This
);
1375 TRACE("-- NM_RETURN %p\n",This
);
1376 if (OnDefaultCommand(This
) != S_OK
) ShellView_OpenSelectedItems(This
);
1380 TRACE("-- HDN_ENDTRACKW %p\n",This
);
1381 /*nColumn1 = ListView_GetColumnWidth(This->hWndList, 0);
1382 nColumn2 = ListView_GetColumnWidth(This->hWndList, 1);*/
1385 case LVN_DELETEITEM
:
1386 TRACE("-- LVN_DELETEITEM %p\n",This
);
1387 SHFree((LPITEMIDLIST
)lpnmlv
->lParam
); /*delete the pidl because we made a copy of it*/
1390 case LVN_DELETEALLITEMS
:
1391 TRACE("-- LVN_DELETEALLITEMS %p\n",This
);
1394 case LVN_INSERTITEM
:
1395 TRACE("-- LVN_INSERTITEM (STUB)%p\n",This
);
1398 case LVN_ITEMACTIVATE
:
1399 TRACE("-- LVN_ITEMACTIVATE %p\n",This
);
1400 OnStateChange(This
, CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1403 case LVN_COLUMNCLICK
:
1404 This
->ListViewSortInfo
.nHeaderID
= lpnmlv
->iSubItem
;
1405 if(This
->ListViewSortInfo
.nLastHeaderID
== This
->ListViewSortInfo
.nHeaderID
)
1407 This
->ListViewSortInfo
.bIsAscending
= !This
->ListViewSortInfo
.bIsAscending
;
1411 This
->ListViewSortInfo
.bIsAscending
= TRUE
;
1413 This
->ListViewSortInfo
.nLastHeaderID
= This
->ListViewSortInfo
.nHeaderID
;
1415 SendMessageW(lpnmlv
->hdr
.hwndFrom
, LVM_SORTITEMS
, (WPARAM
) &This
->ListViewSortInfo
, (LPARAM
)ShellView_ListViewCompareItems
);
1418 case LVN_GETDISPINFOA
:
1419 case LVN_GETDISPINFOW
:
1420 TRACE("-- LVN_GETDISPINFO %p\n",This
);
1421 pidl
= (LPITEMIDLIST
)lpdi
->item
.lParam
;
1423 if(lpdi
->item
.mask
& LVIF_TEXT
) /* text requested */
1425 static WCHAR emptyW
[] = { 0 };
1429 if (This
->pSF2Parent
)
1431 hr
= IShellFolder2_GetDetailsOf(This
->pSF2Parent
, pidl
, lpdi
->item
.iSubItem
, &sd
);
1435 IShellDetails
*details
;
1437 hr
= IShellFolder_QueryInterface(This
->pSFParent
, &IID_IShellDetails
, (void**)&details
);
1440 hr
= IShellDetails_GetDetailsOf(details
, pidl
, lpdi
->item
.iSubItem
, &sd
);
1441 IShellDetails_Release(details
);
1444 WARN("IShellFolder2/IShellDetails not supported\n");
1449 /* set to empty on failure */
1450 sd
.str
.uType
= STRRET_WSTR
;
1451 sd
.str
.u
.pOleStr
= emptyW
;
1454 if (lpnmh
->code
== LVN_GETDISPINFOW
)
1456 StrRetToStrNW( lpdi
->item
.pszText
, lpdi
->item
.cchTextMax
, &sd
.str
, NULL
);
1457 TRACE("-- text=%s\n", debugstr_w(lpdi
->item
.pszText
));
1461 /* LVN_GETDISPINFOA - shouldn't happen */
1462 NMLVDISPINFOA
*lpdiA
= (NMLVDISPINFOA
*)lpnmh
;
1463 StrRetToStrNA( lpdiA
->item
.pszText
, lpdiA
->item
.cchTextMax
, &sd
.str
, NULL
);
1464 TRACE("-- text=%s\n", lpdiA
->item
.pszText
);
1468 if(lpdi
->item
.mask
& LVIF_IMAGE
) /* image requested */
1470 lpdi
->item
.iImage
= SHMapPIDLToSystemImageListIndex(This
->pSFParent
, pidl
, 0);
1474 case LVN_ITEMCHANGED
:
1475 TRACE("-- LVN_ITEMCHANGED %p\n",This
);
1476 OnStateChange(This
, CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1480 case LVN_BEGINRDRAG
:
1481 TRACE("-- LVN_BEGINDRAG\n");
1483 if (ShellView_GetSelections(This
))
1486 DWORD dwAttributes
= SFGAO_CANLINK
;
1487 DWORD dwEffect
= DROPEFFECT_COPY
| DROPEFFECT_MOVE
;
1489 if (SUCCEEDED(IShellFolder_GetUIObjectOf(This
->pSFParent
, This
->hWnd
, This
->cidl
, (LPCITEMIDLIST
*)This
->apidl
, &IID_IDataObject
,0,(LPVOID
*)&pda
)))
1491 IDropSource
*pds
= &This
->IDropSource_iface
; /* own DropSource interface */
1493 if (SUCCEEDED(IShellFolder_GetAttributesOf(This
->pSFParent
, This
->cidl
, (LPCITEMIDLIST
*)This
->apidl
, &dwAttributes
)))
1495 if (dwAttributes
& SFGAO_CANLINK
)
1497 dwEffect
|= DROPEFFECT_LINK
;
1504 DoDragDrop(pda
, pds
, dwEffect
, &dwEffect2
);
1506 IDataObject_Release(pda
);
1511 case LVN_BEGINLABELEDITW
:
1513 DWORD dwAttr
= SFGAO_CANRENAME
;
1514 pidl
= (LPITEMIDLIST
)lpdi
->item
.lParam
;
1516 TRACE("-- LVN_BEGINLABELEDITW %p\n",This
);
1518 IShellFolder_GetAttributesOf(This
->pSFParent
, 1, (LPCITEMIDLIST
*)&pidl
, &dwAttr
);
1519 if (SFGAO_CANRENAME
& dwAttr
)
1526 case LVN_ENDLABELEDITW
:
1528 TRACE("-- LVN_ENDLABELEDITA %p\n",This
);
1529 if (lpdi
->item
.pszText
)
1534 lvItem
.iItem
= lpdi
->item
.iItem
;
1535 lvItem
.iSubItem
= 0;
1536 lvItem
.mask
= LVIF_PARAM
;
1537 SendMessageW(This
->hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
1539 pidl
= (LPITEMIDLIST
)lpdi
->item
.lParam
;
1540 hr
= IShellFolder_SetNameOf(This
->pSFParent
, 0, pidl
, lpdi
->item
.pszText
, SHGDN_INFOLDER
, &pidl
);
1542 if(SUCCEEDED(hr
) && pidl
)
1544 lvItem
.mask
= LVIF_PARAM
;
1545 lvItem
.lParam
= (LPARAM
)pidl
;
1546 SendMessageW(This
->hWndList
, LVM_SETITEMW
, 0, (LPARAM
) &lvItem
);
1555 LPNMLVKEYDOWN plvKeyDown
= (LPNMLVKEYDOWN
) lpnmh
;
1557 /* initiate a rename of the selected file or directory */
1558 switch (plvKeyDown
->wVKey
)
1562 INT i
= SendMessageW(This
->hWndList
, LVM_GETSELECTEDCOUNT
, 0, 0);
1566 /* get selected item */
1567 i
= SendMessageW(This
->hWndList
, LVM_GETNEXTITEM
, -1, MAKELPARAM (LVNI_SELECTED
, 0));
1569 SendMessageW(This
->hWndList
, LVM_ENSUREVISIBLE
, i
, 0);
1570 SendMessageW(This
->hWndList
, LVM_EDITLABELW
, i
, 0);
1579 LPITEMIDLIST
* pItems
;
1583 hr
= IShellFolder_QueryInterface(This
->pSFParent
, &IID_ISFHelper
, (void**)&psfhlp
);
1584 if (hr
!= S_OK
) return 0;
1586 if(!(count
= SendMessageW(This
->hWndList
, LVM_GETSELECTEDCOUNT
, 0, 0)))
1588 ISFHelper_Release(psfhlp
);
1592 /* allocate memory for the pidl array */
1593 pItems
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPITEMIDLIST
) * count
);
1595 /* retrieve all selected items */
1601 /* get selected item */
1602 item_index
= SendMessageW(This
->hWndList
, LVM_GETNEXTITEM
, item_index
,
1603 MAKELPARAM (LVNI_SELECTED
, 0));
1604 item
.iItem
= item_index
;
1605 item
.mask
= LVIF_PARAM
;
1606 SendMessageW(This
->hWndList
, LVM_GETITEMW
, 0, (LPARAM
)&item
);
1609 pItems
[i
] = (LPITEMIDLIST
)item
.lParam
;
1614 /* perform the item deletion */
1615 ISFHelper_DeleteItems(psfhlp
, i
, (LPCITEMIDLIST
*)pItems
);
1616 ISFHelper_Release(psfhlp
);
1618 /* free pidl array memory */
1619 HeapFree(GetProcessHeap(), 0, pItems
);
1624 /* Initiate a refresh */
1625 IShellView_Refresh((IShellView
*)This
);
1630 LPSHELLBROWSER lpSb
;
1631 if((lpSb
= (LPSHELLBROWSER
)SendMessageW(This
->hWndParent
, CWM_GETISHELLBROWSER
, 0, 0)))
1633 IShellBrowser_BrowseObject(lpSb
, NULL
, SBSP_PARENT
);
1639 FIXME("LVN_KEYDOWN key=0x%08x\n", plvKeyDown
->wVKey
);
1645 TRACE("-- %p WM_COMMAND %x unhandled\n", This
, lpnmh
->code
);
1651 /**********************************************************
1652 * ShellView_OnChange()
1655 static LRESULT
ShellView_OnChange(IShellViewImpl
* This
, const LPCITEMIDLIST
*pidls
, LONG event
)
1659 TRACE("(%p)->(%p, %p, 0x%08x)\n", This
, pidls
[0], pidls
[1], event
);
1665 LV_AddItem(This
, pidls
[0]);
1670 INT i
= LV_FindItemByPidl(This
, ILFindLastID(pidls
[0]));
1671 ret
= SendMessageW(This
->hWndList
, LVM_DELETEITEM
, i
, 0);
1674 case SHCNE_RENAMEFOLDER
:
1675 case SHCNE_RENAMEITEM
:
1676 LV_RenameItem(This
, pidls
[0], pidls
[1]);
1678 case SHCNE_UPDATEITEM
:
1683 /**********************************************************
1687 static LRESULT CALLBACK
ShellView_WndProc(HWND hWnd
, UINT uMessage
, WPARAM wParam
, LPARAM lParam
)
1689 IShellViewImpl
* pThis
= (IShellViewImpl
*)GetWindowLongPtrW(hWnd
, GWLP_USERDATA
);
1690 LPCREATESTRUCTW lpcs
;
1692 TRACE("(hwnd=%p msg=%x wparm=%lx lparm=%lx)\n",hWnd
, uMessage
, wParam
, lParam
);
1697 lpcs
= (LPCREATESTRUCTW
)lParam
;
1698 pThis
= lpcs
->lpCreateParams
;
1699 SetWindowLongPtrW(hWnd
, GWLP_USERDATA
, (ULONG_PTR
)pThis
);
1700 pThis
->hWnd
= hWnd
; /*set the window handle*/
1703 case WM_SIZE
: return ShellView_OnSize(pThis
,LOWORD(lParam
), HIWORD(lParam
));
1704 case WM_SETFOCUS
: return ShellView_OnSetFocus(pThis
);
1705 case WM_KILLFOCUS
: return ShellView_OnKillFocus(pThis
);
1706 case WM_CREATE
: return ShellView_OnCreate(pThis
);
1707 case WM_ACTIVATE
: return ShellView_OnActivate(pThis
, SVUIA_ACTIVATE_FOCUS
);
1708 case WM_NOTIFY
: return ShellView_OnNotify(pThis
,(UINT
)wParam
, (LPNMHDR
)lParam
);
1709 case WM_COMMAND
: return ShellView_OnCommand(pThis
,
1710 GET_WM_COMMAND_ID(wParam
, lParam
),
1711 GET_WM_COMMAND_CMD(wParam
, lParam
),
1712 GET_WM_COMMAND_HWND(wParam
, lParam
));
1713 case SHV_CHANGE_NOTIFY
: return ShellView_OnChange(pThis
, (const LPCITEMIDLIST
*)wParam
, (LONG
)lParam
);
1715 case WM_CONTEXTMENU
: ShellView_DoContextMenu(pThis
, LOWORD(lParam
), HIWORD(lParam
), FALSE
);
1718 case WM_SHOWWINDOW
: UpdateWindow(pThis
->hWndList
);
1721 case WM_GETDLGCODE
: return SendMessageW(pThis
->hWndList
, uMessage
, 0, 0);
1722 case WM_SETFONT
: return SendMessageW(pThis
->hWndList
, WM_SETFONT
, wParam
, lParam
);
1723 case WM_GETFONT
: return SendMessageW(pThis
->hWndList
, WM_GETFONT
, wParam
, lParam
);
1726 RevokeDragDrop(pThis
->hWnd
);
1727 SHChangeNotifyDeregister(pThis
->hNotify
);
1731 if ((pThis
->FolderSettings
.fFlags
& FWF_DESKTOP
) ||
1732 (pThis
->FolderSettings
.fFlags
& FWF_TRANSPARENT
))
1737 return DefWindowProcW(hWnd
, uMessage
, wParam
, lParam
);
1739 /**********************************************************
1742 * The INTERFACE of the IShellView object
1745 **********************************************************
1746 * IShellView_QueryInterface
1748 static HRESULT WINAPI
IShellView_fnQueryInterface(IShellView2
*iface
, REFIID riid
, void **ppvObj
)
1750 IShellViewImpl
*This
= impl_from_IShellView2(iface
);
1752 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This
,debugstr_guid(riid
),ppvObj
);
1756 if(IsEqualIID(riid
, &IID_IUnknown
) ||
1757 IsEqualIID(riid
, &IID_IShellView
) ||
1758 IsEqualIID(riid
, &IID_IShellView2
))
1760 *ppvObj
= &This
->IShellView2_iface
;
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
))
2051 return BackgroundMenu_Constructor(This
->pSFParent
, FALSE
, riid
, ppvOut
);
2053 FIXME("unsupported interface requested %s\n", debugstr_guid(riid
));
2057 case SVGIO_SELECTION
:
2058 ShellView_GetSelections(This
);
2059 hr
= IShellFolder_GetUIObjectOf(This
->pSFParent
, This
->hWnd
, This
->cidl
, (LPCITEMIDLIST
*)This
->apidl
, riid
, 0, ppvOut
);
2063 FIXME("unimplemented for uItem = 0x%08x\n", uItem
);
2065 TRACE("-- (%p)->(interface=%p)\n",This
, *ppvOut
);
2070 static HRESULT WINAPI
IShellView2_fnGetView(IShellView2
* iface
, SHELLVIEWID
*view_guid
, ULONG view_type
)
2072 FIXME("(%p)->(view_guid %s, view_type %#x) stub!\n", iface
, debugstr_guid(view_guid
), view_type
);
2076 static HRESULT WINAPI
IShellView2_fnCreateViewWindow2(IShellView2
*iface
,
2077 LPSV2CVW2_PARAMS view_params
)
2079 IShellViewImpl
*This
= impl_from_IShellView2(iface
);
2080 INITCOMMONCONTROLSEX icex
;
2085 icex
.dwSize
= sizeof( icex
);
2086 icex
.dwICC
= ICC_LISTVIEW_CLASSES
;
2087 InitCommonControlsEx( &icex
);
2089 TRACE("(%p)->(view_params %p)\n", iface
, view_params
);
2091 if (view_params
->cbSize
!= sizeof(*view_params
))
2093 FIXME("Got unexpected cbSize %#x\n", view_params
->cbSize
);
2097 TRACE("-- psvPrev %p, pfs %p, psbOwner %p, prcView %p\n",
2098 view_params
->psvPrev
, view_params
->pfs
, view_params
->psbOwner
, view_params
->prcView
);
2099 TRACE("-- vmode %#x, flags %#x, view %s\n", view_params
->pfs
->ViewMode
, view_params
->pfs
->fFlags
, wine_dbgstr_rect(view_params
->prcView
));
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