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
;
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 ListView_InsertItemW(This
->hWndList
, &lvItem
) != -1;
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
, &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
);
755 SHFree(computer_pidl
);
757 IPersistFolder2_Release(ppf2
);
760 This
->hAccel
= LoadAcceleratorsW(shell32_hInstance
, accel_nameW
);
765 /**********************************************************
766 * #### Handling of the menus ####
769 /**********************************************************
770 * ShellView_BuildFileMenu()
772 static HMENU
ShellView_BuildFileMenu(IShellViewImpl
* This
)
773 { WCHAR szText
[MAX_PATH
];
778 TRACE("(%p)\n",This
);
780 hSubMenu
= CreatePopupMenu();
782 { /*get the number of items in our global array*/
783 for(nTools
= 0; Tools
[nTools
].idCommand
!= -1; nTools
++){}
785 /*add the menu items*/
786 for(i
= 0; i
< nTools
; i
++)
788 LoadStringW(shell32_hInstance
, Tools
[i
].idMenuString
, szText
, MAX_PATH
);
790 ZeroMemory(&mii
, sizeof(mii
));
791 mii
.cbSize
= sizeof(mii
);
792 mii
.fMask
= MIIM_TYPE
| MIIM_ID
| MIIM_STATE
;
794 if(BTNS_SEP
!= Tools
[i
].bStyle
) /* no separator*/
796 mii
.fType
= MFT_STRING
;
797 mii
.fState
= MFS_ENABLED
;
798 mii
.dwTypeData
= szText
;
799 mii
.wID
= Tools
[i
].idCommand
;
803 mii
.fType
= MFT_SEPARATOR
;
805 /* tack This item onto the end of the menu */
806 InsertMenuItemW(hSubMenu
, (UINT
)-1, TRUE
, &mii
);
809 TRACE("-- return (menu=%p)\n",hSubMenu
);
812 /**********************************************************
813 * ShellView_MergeFileMenu()
815 static void ShellView_MergeFileMenu(IShellViewImpl
*This
, HMENU hSubMenu
)
817 TRACE("(%p)->(submenu=%p) stub\n",This
,hSubMenu
);
821 static const WCHAR dummyW
[] = {'d','u','m','m','y','4','5',0};
824 /* insert This item at the beginning of the menu */
826 mii
.cbSize
= sizeof(mii
);
827 mii
.fMask
= MIIM_ID
| MIIM_TYPE
;
829 mii
.fType
= MFT_SEPARATOR
;
830 InsertMenuItemW(hSubMenu
, 0, TRUE
, &mii
);
832 mii
.cbSize
= sizeof(mii
);
833 mii
.fMask
= MIIM_ID
| MIIM_TYPE
| MIIM_STATE
;
834 mii
.dwTypeData
= (LPWSTR
)dummyW
;
835 mii
.fState
= MFS_ENABLED
;
836 mii
.wID
= IDM_MYFILEITEM
;
837 mii
.fType
= MFT_STRING
;
838 InsertMenuItemW(hSubMenu
, 0, TRUE
, &mii
);
844 /**********************************************************
845 * ShellView_MergeViewMenu()
848 static void ShellView_MergeViewMenu(IShellViewImpl
*This
, HMENU hSubMenu
)
850 TRACE("(%p)->(submenu=%p)\n",This
,hSubMenu
);
852 /* add a separator at the correct position in the menu */
855 static const WCHAR menuW
[] = {'M','E','N','U','_','0','0','1',0};
856 static const WCHAR viewW
[] = {'V','i','e','w',0};
859 memset(&mii
, 0, sizeof(mii
));
860 mii
.cbSize
= sizeof(mii
);
861 mii
.fMask
= MIIM_ID
| MIIM_TYPE
;
863 mii
.fType
= MFT_SEPARATOR
;
864 InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, &mii
);
866 mii
.cbSize
= sizeof(mii
);
867 mii
.fMask
= MIIM_SUBMENU
| MIIM_TYPE
| MIIM_DATA
;
868 mii
.fType
= MFT_STRING
;
869 mii
.dwTypeData
= (LPWSTR
)viewW
;
870 mii
.hSubMenu
= LoadMenuW(shell32_hInstance
, menuW
);
871 InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, &mii
);
875 /**********************************************************
876 * ShellView_GetSelections()
878 * - fills the this->apidl list with the selected objects
881 * number of selected items
883 static UINT
ShellView_GetSelections(IShellViewImpl
* This
)
890 This
->cidl
= SendMessageW(This
->hWndList
, LVM_GETSELECTEDCOUNT
, 0, 0);
891 This
->apidl
= SHAlloc(This
->cidl
* sizeof(LPITEMIDLIST
));
893 TRACE("selected=%i\n", This
->cidl
);
897 TRACE("-- Items selected =%u\n", This
->cidl
);
899 lvItem
.mask
= LVIF_STATE
| LVIF_PARAM
;
900 lvItem
.stateMask
= LVIS_SELECTED
;
904 while(ListView_GetItemW(This
->hWndList
, &lvItem
) && (i
< This
->cidl
))
906 if(lvItem
.state
& LVIS_SELECTED
)
908 This
->apidl
[i
] = (LPITEMIDLIST
)lvItem
.lParam
;
910 TRACE("-- selected Item found\n");
919 /**********************************************************
920 * ShellView_OpenSelectedItems()
922 static HRESULT
ShellView_OpenSelectedItems(IShellViewImpl
* This
)
924 static UINT CF_IDLIST
= 0;
926 IDataObject
* selection
;
930 LPCITEMIDLIST parent_pidl
;
931 WCHAR parent_path
[MAX_PATH
];
932 LPCWSTR parent_dir
= NULL
;
936 if (0 == ShellView_GetSelections(This
))
940 hr
= IShellFolder_GetUIObjectOf(This
->pSFParent
, This
->hWnd
, This
->cidl
,
941 (LPCITEMIDLIST
*)This
->apidl
, &IID_IDataObject
,
942 0, (LPVOID
*)&selection
);
948 CF_IDLIST
= RegisterClipboardFormatW(CFSTR_SHELLIDLISTW
);
950 fetc
.cfFormat
= CF_IDLIST
;
952 fetc
.dwAspect
= DVASPECT_CONTENT
;
954 fetc
.tymed
= TYMED_HGLOBAL
;
956 hr
= IDataObject_QueryGetData(selection
, &fetc
);
960 hr
= IDataObject_GetData(selection
, &fetc
, &stgm
);
964 pIDList
= GlobalLock(stgm
.u
.hGlobal
);
966 parent_pidl
= (LPCITEMIDLIST
) ((LPBYTE
)pIDList
+pIDList
->aoffset
[0]);
967 hr
= IShellFolder_GetAttributesOf(This
->pSFParent
, 1, &parent_pidl
, &attribs
);
968 if (SUCCEEDED(hr
) && (attribs
& SFGAO_FILESYSTEM
) &&
969 SHGetPathFromIDListW(parent_pidl
, parent_path
))
971 parent_dir
= parent_path
;
974 for (i
= pIDList
->cidl
; i
> 0; --i
)
978 pidl
= (LPCITEMIDLIST
)((LPBYTE
)pIDList
+pIDList
->aoffset
[i
]);
980 attribs
= SFGAO_FOLDER
;
981 hr
= IShellFolder_GetAttributesOf(This
->pSFParent
, 1, &pidl
, &attribs
);
983 if (SUCCEEDED(hr
) && ! (attribs
& SFGAO_FOLDER
))
985 SHELLEXECUTEINFOW shexinfo
;
987 shexinfo
.cbSize
= sizeof(SHELLEXECUTEINFOW
);
988 shexinfo
.fMask
= SEE_MASK_INVOKEIDLIST
; /* SEE_MASK_IDLIST is also possible. */
989 shexinfo
.hwnd
= NULL
;
990 shexinfo
.lpVerb
= NULL
;
991 shexinfo
.lpFile
= NULL
;
992 shexinfo
.lpParameters
= NULL
;
993 shexinfo
.lpDirectory
= parent_dir
;
994 shexinfo
.nShow
= SW_NORMAL
;
995 shexinfo
.lpIDList
= ILCombine(parent_pidl
, pidl
);
997 ShellExecuteExW(&shexinfo
); /* Discard error/success info */
999 ILFree(shexinfo
.lpIDList
);
1003 GlobalUnlock(stgm
.u
.hGlobal
);
1004 ReleaseStgMedium(&stgm
);
1006 IDataObject_Release(selection
);
1011 /**********************************************************
1012 * ShellView_DoContextMenu()
1014 static void ShellView_DoContextMenu(IShellViewImpl
* This
, WORD x
, WORD y
, BOOL bDefault
)
1018 BOOL fExplore
= FALSE
;
1020 LPCONTEXTMENU pContextMenu
= 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 */
1097 hMenu
= CreatePopupMenu();
1099 BackgroundMenu_Constructor(This
->pSFParent
, FALSE
, &IID_IContextMenu2
, (void**)&pCM
);
1100 IContextMenu2_QueryContextMenu(pCM
, hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, 0);
1102 uCommand
= TrackPopupMenu( hMenu
, TPM_LEFTALIGN
| TPM_RETURNCMD
,x
,y
,0,This
->hWnd
,NULL
);
1105 TRACE("-- (%p)->(uCommand=0x%08x )\n",This
, uCommand
);
1107 ZeroMemory(&cmi
, sizeof(cmi
));
1108 cmi
.cbSize
= sizeof(cmi
);
1109 cmi
.lpVerb
= MAKEINTRESOURCEA(uCommand
);
1110 cmi
.hwnd
= This
->hWndParent
;
1111 IContextMenu2_InvokeCommand(pCM
, &cmi
);
1113 IContextMenu2_Release(pCM
);
1117 /**********************************************************
1118 * ##### message handling #####
1121 /**********************************************************
1122 * ShellView_OnSize()
1124 static LRESULT
ShellView_OnSize(IShellViewImpl
* This
, WORD wWidth
, WORD wHeight
)
1126 TRACE("%p width=%u height=%u\n",This
, wWidth
,wHeight
);
1128 /*resize the ListView to fit our window*/
1131 MoveWindow(This
->hWndList
, 0, 0, wWidth
, wHeight
, TRUE
);
1136 /**********************************************************
1137 * ShellView_OnDeactivate()
1142 static void ShellView_OnDeactivate(IShellViewImpl
* This
)
1146 if(This
->uState
!= SVUIA_DEACTIVATE
)
1150 IShellBrowser_SetMenuSB(This
->pShellBrowser
,0, 0, 0);
1151 IShellBrowser_RemoveMenusSB(This
->pShellBrowser
,This
->hMenu
);
1152 DestroyMenu(This
->hMenu
);
1156 This
->uState
= SVUIA_DEACTIVATE
;
1160 /**********************************************************
1161 * ShellView_OnActivate()
1163 static LRESULT
ShellView_OnActivate(IShellViewImpl
*This
, UINT uState
)
1165 OLEMENUGROUPWIDTHS omw
= { {0, 0, 0, 0, 0, 0} };
1168 TRACE("(%p) uState=%x\n",This
,uState
);
1170 /* don't do anything if the state isn't really changing */
1171 if (This
->uState
== uState
) return S_OK
;
1173 ShellView_OnDeactivate(This
);
1175 /* only do This if we are active */
1176 if (uState
!= SVUIA_DEACTIVATE
)
1178 /* merge the menus */
1179 This
->hMenu
= CreateMenu();
1183 static const WCHAR dummyW
[] = {'d','u','m','m','y',' ','3','1',0};
1185 IShellBrowser_InsertMenusSB(This
->pShellBrowser
, This
->hMenu
, &omw
);
1186 TRACE("-- after fnInsertMenusSB\n");
1188 mii
.cbSize
= sizeof(mii
);
1189 mii
.fMask
= MIIM_SUBMENU
| MIIM_TYPE
| MIIM_STATE
;
1190 mii
.fType
= MFT_STRING
;
1191 mii
.fState
= MFS_ENABLED
;
1193 mii
.hSubMenu
= ShellView_BuildFileMenu(This
);
1194 mii
.hbmpChecked
= NULL
;
1195 mii
.hbmpUnchecked
= NULL
;
1197 /* build the top level menu get the menu item's text */
1198 mii
.dwTypeData
= (LPWSTR
)dummyW
;
1200 mii
.hbmpItem
= NULL
;
1202 /* insert our menu into the menu bar */
1204 InsertMenuItemW(This
->hMenu
, FCIDM_MENU_HELP
, FALSE
, &mii
);
1206 /* get the view menu so we can merge with it */
1207 memset(&mii
, 0, sizeof(mii
));
1208 mii
.cbSize
= sizeof(mii
);
1209 mii
.fMask
= MIIM_SUBMENU
;
1211 if (GetMenuItemInfoW(This
->hMenu
, FCIDM_MENU_VIEW
, FALSE
, &mii
))
1212 ShellView_MergeViewMenu(This
, mii
.hSubMenu
);
1214 /* add the items that should only be added if we have the focus */
1215 if (SVUIA_ACTIVATE_FOCUS
== uState
)
1217 /* get the file menu so we can merge with it */
1218 memset(&mii
, 0, sizeof(mii
));
1219 mii
.cbSize
= sizeof(mii
);
1220 mii
.fMask
= MIIM_SUBMENU
;
1222 if (GetMenuItemInfoW(This
->hMenu
, FCIDM_MENU_FILE
, FALSE
, &mii
))
1223 ShellView_MergeFileMenu(This
, mii
.hSubMenu
);
1226 TRACE("-- before fnSetMenuSB\n");
1227 IShellBrowser_SetMenuSB(This
->pShellBrowser
, This
->hMenu
, 0, This
->hWnd
);
1230 This
->uState
= uState
;
1235 /**********************************************************
1236 * ShellView_OnSetFocus()
1239 static LRESULT
ShellView_OnSetFocus(IShellViewImpl
* This
)
1243 /* Tell the browser one of our windows has received the focus. This
1244 should always be done before merging menus (OnActivate merges the
1245 menus) if one of our windows has the focus.*/
1247 IShellBrowser_OnViewWindowActive(This
->pShellBrowser
,(IShellView
*) This
);
1248 ShellView_OnActivate(This
, SVUIA_ACTIVATE_FOCUS
);
1250 /* Set the focus to the listview */
1251 SetFocus(This
->hWndList
);
1253 /* Notify the ICommDlgBrowser interface */
1254 OnStateChange(This
,CDBOSC_SETFOCUS
);
1259 /**********************************************************
1260 * ShellView_OnKillFocus()
1262 static LRESULT
ShellView_OnKillFocus(IShellViewImpl
* This
)
1264 TRACE("(%p) stub\n",This
);
1266 ShellView_OnActivate(This
, SVUIA_ACTIVATE_NOFOCUS
);
1267 /* Notify the ICommDlgBrowser */
1268 OnStateChange(This
,CDBOSC_KILLFOCUS
);
1273 /**********************************************************
1274 * ShellView_OnCommand()
1277 * the CmdIDs are the ones from the context menu
1279 static LRESULT
ShellView_OnCommand(IShellViewImpl
* This
,DWORD dwCmdID
, DWORD dwCmd
, HWND hwndCmd
)
1281 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n",This
, dwCmdID
, dwCmd
, hwndCmd
);
1285 case FCIDM_SHVIEW_SMALLICON
:
1286 This
->FolderSettings
.ViewMode
= FVM_SMALLICON
;
1287 SetStyle (This
, LVS_SMALLICON
, LVS_TYPEMASK
);
1291 case FCIDM_SHVIEW_BIGICON
:
1292 This
->FolderSettings
.ViewMode
= FVM_ICON
;
1293 SetStyle (This
, LVS_ICON
, LVS_TYPEMASK
);
1297 case FCIDM_SHVIEW_LISTVIEW
:
1298 This
->FolderSettings
.ViewMode
= FVM_LIST
;
1299 SetStyle (This
, LVS_LIST
, LVS_TYPEMASK
);
1303 case FCIDM_SHVIEW_REPORTVIEW
:
1304 This
->FolderSettings
.ViewMode
= FVM_DETAILS
;
1305 SetStyle (This
, LVS_REPORT
, LVS_TYPEMASK
);
1309 /* the menu IDs for sorting are 0x30... see shell32.rc */
1314 This
->ListViewSortInfo
.nHeaderID
= dwCmdID
- 0x30;
1315 This
->ListViewSortInfo
.bIsAscending
= TRUE
;
1316 This
->ListViewSortInfo
.nLastHeaderID
= This
->ListViewSortInfo
.nHeaderID
;
1317 SendMessageW(This
->hWndList
, LVM_SORTITEMS
, (WPARAM
) &This
->ListViewSortInfo
, (LPARAM
)ShellView_ListViewCompareItems
);
1321 TRACE("-- COMMAND 0x%04x unhandled\n", dwCmdID
);
1326 /**********************************************************
1327 * ShellView_OnNotify()
1330 static LRESULT
ShellView_OnNotify(IShellViewImpl
* This
, UINT CtlID
, LPNMHDR lpnmh
)
1331 { LPNMLISTVIEW lpnmlv
= (LPNMLISTVIEW
)lpnmh
;
1332 NMLVDISPINFOW
*lpdi
= (NMLVDISPINFOW
*)lpnmh
;
1335 TRACE("%p CtlID=%u lpnmh->code=%x\n",This
,CtlID
,lpnmh
->code
);
1340 TRACE("-- NM_SETFOCUS %p\n",This
);
1341 ShellView_OnSetFocus(This
);
1345 TRACE("-- NM_KILLFOCUS %p\n",This
);
1346 ShellView_OnDeactivate(This
);
1347 /* Notify the ICommDlgBrowser interface */
1348 OnStateChange(This
,CDBOSC_KILLFOCUS
);
1352 TRACE("-- NM_CUSTOMDRAW %p\n",This
);
1353 return CDRF_DODEFAULT
;
1355 case NM_RELEASEDCAPTURE
:
1356 TRACE("-- NM_RELEASEDCAPTURE %p\n",This
);
1360 TRACE("-- NM_CLICK %p\n",This
);
1364 TRACE("-- NM_RCLICK %p\n",This
);
1368 TRACE("-- NM_DBLCLK %p\n",This
);
1369 if (OnDefaultCommand(This
) != S_OK
) ShellView_OpenSelectedItems(This
);
1373 TRACE("-- NM_RETURN %p\n",This
);
1374 if (OnDefaultCommand(This
) != S_OK
) ShellView_OpenSelectedItems(This
);
1378 TRACE("-- HDN_ENDTRACKW %p\n",This
);
1379 /*nColumn1 = ListView_GetColumnWidth(This->hWndList, 0);
1380 nColumn2 = ListView_GetColumnWidth(This->hWndList, 1);*/
1383 case LVN_DELETEITEM
:
1384 TRACE("-- LVN_DELETEITEM %p\n",This
);
1385 SHFree((LPITEMIDLIST
)lpnmlv
->lParam
); /*delete the pidl because we made a copy of it*/
1388 case LVN_DELETEALLITEMS
:
1389 TRACE("-- LVN_DELETEALLITEMS %p\n",This
);
1392 case LVN_INSERTITEM
:
1393 TRACE("-- LVN_INSERTITEM (STUB)%p\n",This
);
1396 case LVN_ITEMACTIVATE
:
1397 TRACE("-- LVN_ITEMACTIVATE %p\n",This
);
1398 OnStateChange(This
, CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1401 case LVN_COLUMNCLICK
:
1402 This
->ListViewSortInfo
.nHeaderID
= lpnmlv
->iSubItem
;
1403 if(This
->ListViewSortInfo
.nLastHeaderID
== This
->ListViewSortInfo
.nHeaderID
)
1405 This
->ListViewSortInfo
.bIsAscending
= !This
->ListViewSortInfo
.bIsAscending
;
1409 This
->ListViewSortInfo
.bIsAscending
= TRUE
;
1411 This
->ListViewSortInfo
.nLastHeaderID
= This
->ListViewSortInfo
.nHeaderID
;
1413 SendMessageW(lpnmlv
->hdr
.hwndFrom
, LVM_SORTITEMS
, (WPARAM
) &This
->ListViewSortInfo
, (LPARAM
)ShellView_ListViewCompareItems
);
1416 case LVN_GETDISPINFOA
:
1417 case LVN_GETDISPINFOW
:
1418 TRACE("-- LVN_GETDISPINFO %p\n",This
);
1419 pidl
= (LPITEMIDLIST
)lpdi
->item
.lParam
;
1421 if(lpdi
->item
.mask
& LVIF_TEXT
) /* text requested */
1423 static WCHAR emptyW
[] = { 0 };
1427 if (This
->pSF2Parent
)
1429 hr
= IShellFolder2_GetDetailsOf(This
->pSF2Parent
, pidl
, lpdi
->item
.iSubItem
, &sd
);
1433 IShellDetails
*details
;
1435 hr
= IShellFolder_QueryInterface(This
->pSFParent
, &IID_IShellDetails
, (void**)&details
);
1438 hr
= IShellDetails_GetDetailsOf(details
, pidl
, lpdi
->item
.iSubItem
, &sd
);
1439 IShellDetails_Release(details
);
1442 WARN("IShellFolder2/IShellDetails not supported\n");
1447 /* set to empty on failure */
1448 sd
.str
.uType
= STRRET_WSTR
;
1449 sd
.str
.u
.pOleStr
= emptyW
;
1452 if (lpnmh
->code
== LVN_GETDISPINFOW
)
1454 StrRetToStrNW( lpdi
->item
.pszText
, lpdi
->item
.cchTextMax
, &sd
.str
, NULL
);
1455 TRACE("-- text=%s\n", debugstr_w(lpdi
->item
.pszText
));
1459 /* LVN_GETDISPINFOA - shouldn't happen */
1460 NMLVDISPINFOA
*lpdiA
= (NMLVDISPINFOA
*)lpnmh
;
1461 StrRetToStrNA( lpdiA
->item
.pszText
, lpdiA
->item
.cchTextMax
, &sd
.str
, NULL
);
1462 TRACE("-- text=%s\n", lpdiA
->item
.pszText
);
1466 if(lpdi
->item
.mask
& LVIF_IMAGE
) /* image requested */
1468 lpdi
->item
.iImage
= SHMapPIDLToSystemImageListIndex(This
->pSFParent
, pidl
, 0);
1472 case LVN_ITEMCHANGED
:
1473 TRACE("-- LVN_ITEMCHANGED %p\n",This
);
1474 OnStateChange(This
, CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1478 case LVN_BEGINRDRAG
:
1479 TRACE("-- LVN_BEGINDRAG\n");
1481 if (ShellView_GetSelections(This
))
1484 DWORD dwAttributes
= SFGAO_CANLINK
;
1485 DWORD dwEffect
= DROPEFFECT_COPY
| DROPEFFECT_MOVE
;
1487 if (SUCCEEDED(IShellFolder_GetUIObjectOf(This
->pSFParent
, This
->hWnd
, This
->cidl
, (LPCITEMIDLIST
*)This
->apidl
, &IID_IDataObject
,0,(LPVOID
*)&pda
)))
1489 IDropSource
*pds
= &This
->IDropSource_iface
; /* own DropSource interface */
1491 if (SUCCEEDED(IShellFolder_GetAttributesOf(This
->pSFParent
, This
->cidl
, (LPCITEMIDLIST
*)This
->apidl
, &dwAttributes
)))
1493 if (dwAttributes
& SFGAO_CANLINK
)
1495 dwEffect
|= DROPEFFECT_LINK
;
1502 DoDragDrop(pda
, pds
, dwEffect
, &dwEffect2
);
1504 IDataObject_Release(pda
);
1509 case LVN_BEGINLABELEDITW
:
1511 DWORD dwAttr
= SFGAO_CANRENAME
;
1512 pidl
= (LPITEMIDLIST
)lpdi
->item
.lParam
;
1514 TRACE("-- LVN_BEGINLABELEDITW %p\n",This
);
1516 IShellFolder_GetAttributesOf(This
->pSFParent
, 1, (LPCITEMIDLIST
*)&pidl
, &dwAttr
);
1517 if (SFGAO_CANRENAME
& dwAttr
)
1524 case LVN_ENDLABELEDITW
:
1526 TRACE("-- LVN_ENDLABELEDITA %p\n",This
);
1527 if (lpdi
->item
.pszText
)
1532 lvItem
.iItem
= lpdi
->item
.iItem
;
1533 lvItem
.iSubItem
= 0;
1534 lvItem
.mask
= LVIF_PARAM
;
1535 SendMessageW(This
->hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
1537 pidl
= (LPITEMIDLIST
)lpdi
->item
.lParam
;
1538 hr
= IShellFolder_SetNameOf(This
->pSFParent
, 0, pidl
, lpdi
->item
.pszText
, SHGDN_INFOLDER
, &pidl
);
1540 if(SUCCEEDED(hr
) && pidl
)
1542 lvItem
.mask
= LVIF_PARAM
;
1543 lvItem
.lParam
= (LPARAM
)pidl
;
1544 SendMessageW(This
->hWndList
, LVM_SETITEMW
, 0, (LPARAM
) &lvItem
);
1553 LPNMLVKEYDOWN plvKeyDown
= (LPNMLVKEYDOWN
) lpnmh
;
1555 /* initiate a rename of the selected file or directory */
1556 switch (plvKeyDown
->wVKey
)
1560 INT i
= SendMessageW(This
->hWndList
, LVM_GETSELECTEDCOUNT
, 0, 0);
1564 /* get selected item */
1565 i
= SendMessageW(This
->hWndList
, LVM_GETNEXTITEM
, -1, MAKELPARAM (LVNI_SELECTED
, 0));
1567 SendMessageW(This
->hWndList
, LVM_ENSUREVISIBLE
, i
, 0);
1568 SendMessageW(This
->hWndList
, LVM_EDITLABELW
, i
, 0);
1577 LPITEMIDLIST
* pItems
;
1581 hr
= IShellFolder_QueryInterface(This
->pSFParent
, &IID_ISFHelper
, (void**)&psfhlp
);
1582 if (hr
!= S_OK
) return 0;
1584 if(!(count
= SendMessageW(This
->hWndList
, LVM_GETSELECTEDCOUNT
, 0, 0)))
1586 ISFHelper_Release(psfhlp
);
1590 /* allocate memory for the pidl array */
1591 pItems
= HeapAlloc(GetProcessHeap(), 0, sizeof(LPITEMIDLIST
) * count
);
1593 /* retrieve all selected items */
1599 /* get selected item */
1600 item_index
= SendMessageW(This
->hWndList
, LVM_GETNEXTITEM
, item_index
,
1601 MAKELPARAM (LVNI_SELECTED
, 0));
1602 item
.iItem
= item_index
;
1603 item
.mask
= LVIF_PARAM
;
1604 SendMessageW(This
->hWndList
, LVM_GETITEMW
, 0, (LPARAM
)&item
);
1607 pItems
[i
] = (LPITEMIDLIST
)item
.lParam
;
1612 /* perform the item deletion */
1613 ISFHelper_DeleteItems(psfhlp
, i
, (LPCITEMIDLIST
*)pItems
);
1614 ISFHelper_Release(psfhlp
);
1616 /* free pidl array memory */
1617 HeapFree(GetProcessHeap(), 0, pItems
);
1622 /* Initiate a refresh */
1623 IShellView_Refresh((IShellView
*)This
);
1628 LPSHELLBROWSER lpSb
;
1629 if((lpSb
= (LPSHELLBROWSER
)SendMessageW(This
->hWndParent
, CWM_GETISHELLBROWSER
, 0, 0)))
1631 IShellBrowser_BrowseObject(lpSb
, NULL
, SBSP_PARENT
);
1637 FIXME("LVN_KEYDOWN key=0x%08x\n", plvKeyDown
->wVKey
);
1643 TRACE("-- %p WM_COMMAND %x unhandled\n", This
, lpnmh
->code
);
1649 /**********************************************************
1650 * ShellView_OnChange()
1653 static LRESULT
ShellView_OnChange(IShellViewImpl
* This
, const LPCITEMIDLIST
*pidls
, LONG event
)
1657 TRACE("(%p)->(%p, %p, 0x%08x)\n", This
, pidls
[0], pidls
[1], event
);
1663 LV_AddItem(This
, pidls
[0]);
1668 INT i
= LV_FindItemByPidl(This
, ILFindLastID(pidls
[0]));
1669 ret
= SendMessageW(This
->hWndList
, LVM_DELETEITEM
, i
, 0);
1672 case SHCNE_RENAMEFOLDER
:
1673 case SHCNE_RENAMEITEM
:
1674 LV_RenameItem(This
, pidls
[0], pidls
[1]);
1676 case SHCNE_UPDATEITEM
:
1681 /**********************************************************
1685 static LRESULT CALLBACK
ShellView_WndProc(HWND hWnd
, UINT uMessage
, WPARAM wParam
, LPARAM lParam
)
1687 IShellViewImpl
* pThis
= (IShellViewImpl
*)GetWindowLongPtrW(hWnd
, GWLP_USERDATA
);
1688 LPCREATESTRUCTW lpcs
;
1690 TRACE("(hwnd=%p msg=%x wparm=%lx lparm=%lx)\n",hWnd
, uMessage
, wParam
, lParam
);
1695 lpcs
= (LPCREATESTRUCTW
)lParam
;
1696 pThis
= lpcs
->lpCreateParams
;
1697 SetWindowLongPtrW(hWnd
, GWLP_USERDATA
, (ULONG_PTR
)pThis
);
1698 pThis
->hWnd
= hWnd
; /*set the window handle*/
1701 case WM_SIZE
: return ShellView_OnSize(pThis
,LOWORD(lParam
), HIWORD(lParam
));
1702 case WM_SETFOCUS
: return ShellView_OnSetFocus(pThis
);
1703 case WM_KILLFOCUS
: return ShellView_OnKillFocus(pThis
);
1704 case WM_CREATE
: return ShellView_OnCreate(pThis
);
1705 case WM_ACTIVATE
: return ShellView_OnActivate(pThis
, SVUIA_ACTIVATE_FOCUS
);
1706 case WM_NOTIFY
: return ShellView_OnNotify(pThis
,(UINT
)wParam
, (LPNMHDR
)lParam
);
1707 case WM_COMMAND
: return ShellView_OnCommand(pThis
,
1708 GET_WM_COMMAND_ID(wParam
, lParam
),
1709 GET_WM_COMMAND_CMD(wParam
, lParam
),
1710 GET_WM_COMMAND_HWND(wParam
, lParam
));
1711 case SHV_CHANGE_NOTIFY
: return ShellView_OnChange(pThis
, (const LPCITEMIDLIST
*)wParam
, (LONG
)lParam
);
1713 case WM_CONTEXTMENU
: ShellView_DoContextMenu(pThis
, LOWORD(lParam
), HIWORD(lParam
), FALSE
);
1716 case WM_SHOWWINDOW
: UpdateWindow(pThis
->hWndList
);
1719 case WM_GETDLGCODE
: return SendMessageW(pThis
->hWndList
, uMessage
, 0, 0);
1720 case WM_SETFONT
: return SendMessageW(pThis
->hWndList
, WM_SETFONT
, wParam
, lParam
);
1721 case WM_GETFONT
: return SendMessageW(pThis
->hWndList
, WM_GETFONT
, wParam
, lParam
);
1724 RevokeDragDrop(pThis
->hWnd
);
1725 SHChangeNotifyDeregister(pThis
->hNotify
);
1729 if ((pThis
->FolderSettings
.fFlags
& FWF_DESKTOP
) ||
1730 (pThis
->FolderSettings
.fFlags
& FWF_TRANSPARENT
))
1735 return DefWindowProcW(hWnd
, uMessage
, wParam
, lParam
);
1737 /**********************************************************
1740 * The INTERFACE of the IShellView object
1743 **********************************************************
1744 * IShellView_QueryInterface
1746 static HRESULT WINAPI
IShellView_fnQueryInterface(IShellView2
*iface
, REFIID riid
, void **ppvObj
)
1748 IShellViewImpl
*This
= impl_from_IShellView2(iface
);
1750 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This
,debugstr_guid(riid
),ppvObj
);
1754 if(IsEqualIID(riid
, &IID_IUnknown
) ||
1755 IsEqualIID(riid
, &IID_IShellView
) ||
1756 IsEqualIID(riid
, &IID_IShellView2
))
1758 *ppvObj
= &This
->IShellView2_iface
;
1760 else if(IsEqualIID(riid
, &IID_IShellFolderView
))
1762 *ppvObj
= &This
->IShellFolderView_iface
;
1764 else if(IsEqualIID(riid
, &IID_IFolderView
))
1766 *ppvObj
= &This
->IFolderView_iface
;
1768 else if(IsEqualIID(riid
, &IID_IOleCommandTarget
))
1770 *ppvObj
= &This
->IOleCommandTarget_iface
;
1772 else if(IsEqualIID(riid
, &IID_IDropTarget
))
1774 *ppvObj
= &This
->IDropTarget_iface
;
1776 else if(IsEqualIID(riid
, &IID_IDropSource
))
1778 *ppvObj
= &This
->IDropSource_iface
;
1780 else if(IsEqualIID(riid
, &IID_IViewObject
))
1782 *ppvObj
= &This
->IViewObject_iface
;
1787 IUnknown_AddRef( (IUnknown
*)*ppvObj
);
1788 TRACE("-- Interface: (%p)->(%p)\n",ppvObj
,*ppvObj
);
1791 TRACE("-- Interface: E_NOINTERFACE\n");
1792 return E_NOINTERFACE
;
1795 /**********************************************************
1798 static ULONG WINAPI
IShellView_fnAddRef(IShellView2
*iface
)
1800 IShellViewImpl
*This
= impl_from_IShellView2(iface
);
1801 ULONG refCount
= InterlockedIncrement(&This
->ref
);
1803 TRACE("(%p)->(count=%u)\n", This
, refCount
- 1);
1807 /**********************************************************
1808 * IShellView_Release
1810 static ULONG WINAPI
IShellView_fnRelease(IShellView2
*iface
)
1812 IShellViewImpl
*This
= impl_from_IShellView2(iface
);
1813 ULONG refCount
= InterlockedDecrement(&This
->ref
);
1815 TRACE("(%p)->(count=%i)\n", This
, refCount
+ 1);
1819 TRACE(" destroying IShellView(%p)\n",This
);
1821 DestroyWindow(This
->hWndList
);
1824 IShellFolder_Release(This
->pSFParent
);
1826 if(This
->pSF2Parent
)
1827 IShellFolder2_Release(This
->pSF2Parent
);
1829 SHFree(This
->apidl
);
1832 IAdviseSink_Release(This
->pAdvSink
);
1834 HeapFree(GetProcessHeap(),0,This
);
1839 /**********************************************************
1840 * ShellView_GetWindow
1842 static HRESULT WINAPI
IShellView_fnGetWindow(IShellView2
*iface
, HWND
*phWnd
)
1844 IShellViewImpl
*This
= impl_from_IShellView2(iface
);
1846 TRACE("(%p)\n",This
);
1848 *phWnd
= This
->hWnd
;
1853 static HRESULT WINAPI
IShellView_fnContextSensitiveHelp(IShellView2
*iface
, BOOL mode
)
1855 IShellViewImpl
*This
= impl_from_IShellView2(iface
);
1856 TRACE("(%p)->(%d)\n", This
, mode
);
1860 /**********************************************************
1861 * IShellView_TranslateAccelerator
1864 * use the accel functions
1866 static HRESULT WINAPI
IShellView_fnTranslateAccelerator(IShellView2
* iface
,LPMSG lpmsg
)
1869 IShellViewImpl
*This
= (IShellViewImpl
*)iface
;
1871 FIXME("(%p)->(%p: hwnd=%x msg=%x lp=%x wp=%x) stub\n",This
,lpmsg
, lpmsg
->hwnd
, lpmsg
->message
, lpmsg
->lParam
, lpmsg
->wParam
);
1874 if ((lpmsg
->message
>=WM_KEYFIRST
) && (lpmsg
->message
>=WM_KEYLAST
))
1876 TRACE("-- key=0x04%lx\n",lpmsg
->wParam
) ;
1878 return S_FALSE
; /* not handled */
1881 static HRESULT WINAPI
IShellView_fnEnableModeless(IShellView2
*iface
, BOOL fEnable
)
1883 IShellViewImpl
*This
= impl_from_IShellView2(iface
);
1885 FIXME("(%p) stub\n",This
);
1890 static HRESULT WINAPI
IShellView_fnUIActivate(IShellView2
*iface
, UINT uState
)
1892 IShellViewImpl
*This
= impl_from_IShellView2(iface
);
1895 CHAR szName[MAX_PATH];
1898 int nPartArray
[1] = {-1};
1900 TRACE("(%p)->(state=%x) stub\n",This
, uState
);
1902 /*don't do anything if the state isn't really changing*/
1903 if(This
->uState
== uState
)
1908 /*OnActivate handles the menu merging and internal state*/
1909 ShellView_OnActivate(This
, uState
);
1911 /*only do This if we are active*/
1912 if(uState
!= SVUIA_DEACTIVATE
)
1916 GetFolderPath is not a method of IShellFolder
1917 IShellFolder_GetFolderPath( This->pSFParent, szName, sizeof(szName) );
1919 /* set the number of parts */
1920 IShellBrowser_SendControlMsg(This
->pShellBrowser
, FCW_STATUS
, SB_SETPARTS
, 1,
1921 (LPARAM
)nPartArray
, &lResult
);
1923 /* set the text for the parts */
1925 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETTEXTA,
1926 0, (LPARAM)szName, &lResult);
1933 static HRESULT WINAPI
IShellView_fnRefresh(IShellView2
*iface
)
1935 IShellViewImpl
*This
= impl_from_IShellView2(iface
);
1937 TRACE("(%p)\n", This
);
1939 SendMessageW(This
->hWndList
, LVM_DELETEALLITEMS
, 0, 0);
1940 ShellView_FillList(This
);
1945 static HRESULT WINAPI
IShellView_fnCreateViewWindow(IShellView2
*iface
, IShellView
*lpPrevView
,
1946 LPCFOLDERSETTINGS lpfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
)
1949 SV2CVW2_PARAMS view_params
;
1950 view_params
.cbSize
= sizeof(view_params
);
1951 view_params
.psvPrev
= lpPrevView
;
1952 view_params
.pfs
= lpfs
;
1953 view_params
.psbOwner
= psb
;
1954 view_params
.prcView
= prcView
;
1955 view_params
.pvid
= NULL
;
1956 view_params
.hwndView
= 0;
1958 TRACE("(%p) Forwarding to CreateViewWindow2\n", iface
);
1960 hr
= IShellView2_CreateViewWindow2(iface
, &view_params
);
1961 *phWnd
= view_params
.hwndView
;
1966 static HRESULT WINAPI
IShellView_fnDestroyViewWindow(IShellView2
*iface
)
1968 IShellViewImpl
*This
= impl_from_IShellView2(iface
);
1970 TRACE("(%p)\n",This
);
1972 /*Make absolutely sure all our UI is cleaned up.*/
1973 IShellView_UIActivate((IShellView
*)This
, SVUIA_DEACTIVATE
);
1977 DestroyMenu(This
->hMenu
);
1980 DestroyWindow(This
->hWnd
);
1981 if(This
->pShellBrowser
) IShellBrowser_Release(This
->pShellBrowser
);
1982 if(This
->pCommDlgBrowser
) ICommDlgBrowser_Release(This
->pCommDlgBrowser
);
1988 static HRESULT WINAPI
IShellView_fnGetCurrentInfo(IShellView2
*iface
, LPFOLDERSETTINGS lpfs
)
1990 IShellViewImpl
*This
= impl_from_IShellView2(iface
);
1992 TRACE("(%p)->(%p) vmode=%x flags=%x\n",This
, lpfs
,
1993 This
->FolderSettings
.ViewMode
, This
->FolderSettings
.fFlags
);
1995 if (!lpfs
) return E_INVALIDARG
;
1997 *lpfs
= This
->FolderSettings
;
2001 static HRESULT WINAPI
IShellView_fnAddPropertySheetPages(IShellView2
*iface
, DWORD dwReserved
,
2002 LPFNADDPROPSHEETPAGE lpfn
, LPARAM lparam
)
2004 IShellViewImpl
*This
= impl_from_IShellView2(iface
);
2006 FIXME("(%p) stub\n",This
);
2011 static HRESULT WINAPI
IShellView_fnSaveViewState(IShellView2
*iface
)
2013 IShellViewImpl
*This
= impl_from_IShellView2(iface
);
2015 FIXME("(%p) stub\n",This
);
2020 static HRESULT WINAPI
IShellView_fnSelectItem(IShellView2
*iface
, LPCITEMIDLIST pidl
, UINT flags
)
2022 IShellViewImpl
*This
= impl_from_IShellView2(iface
);
2023 IFolderView
*view
= &This
->IFolderView_iface
;
2026 TRACE("(%p)->(pidl=%p, 0x%08x)\n",This
, pidl
, flags
);
2028 i
= LV_FindItemByPidl(This
, pidl
);
2029 if (i
== -1) return S_OK
;
2031 return IFolderView_SelectItem(view
, i
, flags
);
2034 static HRESULT WINAPI
IShellView_fnGetItemObject(IShellView2
*iface
, UINT uItem
, REFIID riid
,
2037 IShellViewImpl
*This
= impl_from_IShellView2(iface
);
2038 HRESULT hr
= E_NOINTERFACE
;
2040 TRACE("(%p)->(0x%08x, %s, %p)\n",This
, uItem
, debugstr_guid(riid
), ppvOut
);
2046 case SVGIO_BACKGROUND
:
2048 if (IsEqualIID(&IID_IContextMenu
, riid
))
2049 return BackgroundMenu_Constructor(This
->pSFParent
, FALSE
, riid
, ppvOut
);
2051 FIXME("unsupported interface requested %s\n", debugstr_guid(riid
));
2055 case SVGIO_SELECTION
:
2056 ShellView_GetSelections(This
);
2057 hr
= IShellFolder_GetUIObjectOf(This
->pSFParent
, This
->hWnd
, This
->cidl
, (LPCITEMIDLIST
*)This
->apidl
, riid
, 0, ppvOut
);
2061 FIXME("unimplemented for uItem = 0x%08x\n", uItem
);
2063 TRACE("-- (%p)->(interface=%p)\n",This
, *ppvOut
);
2068 static HRESULT WINAPI
IShellView2_fnGetView(IShellView2
* iface
, SHELLVIEWID
*view_guid
, ULONG view_type
)
2070 FIXME("(%p)->(view_guid %s, view_type %#x) stub!\n", iface
, debugstr_guid(view_guid
), view_type
);
2074 static HRESULT WINAPI
IShellView2_fnCreateViewWindow2(IShellView2
*iface
,
2075 LPSV2CVW2_PARAMS view_params
)
2077 IShellViewImpl
*This
= impl_from_IShellView2(iface
);
2082 TRACE("(%p)->(view_params %p)\n", iface
, view_params
);
2084 if (view_params
->cbSize
!= sizeof(*view_params
))
2086 FIXME("Got unexpected cbSize %#x\n", view_params
->cbSize
);
2090 TRACE("-- psvPrev %p, pfs %p, psbOwner %p, prcView %p\n",
2091 view_params
->psvPrev
, view_params
->pfs
, view_params
->psbOwner
, view_params
->prcView
);
2092 TRACE("-- vmode %#x, flags %#x, view %s\n", view_params
->pfs
->ViewMode
, view_params
->pfs
->fFlags
, wine_dbgstr_rect(view_params
->prcView
));
2094 if (!view_params
->psbOwner
) return E_UNEXPECTED
;
2096 /* Set up the member variables */
2097 This
->pShellBrowser
= view_params
->psbOwner
;
2098 This
->FolderSettings
= *view_params
->pfs
;
2100 if (view_params
->pvid
)
2102 if (IsEqualGUID(view_params
->pvid
, &VID_LargeIcons
))
2103 This
->FolderSettings
.ViewMode
= FVM_ICON
;
2104 else if (IsEqualGUID(view_params
->pvid
, &VID_SmallIcons
))
2105 This
->FolderSettings
.ViewMode
= FVM_SMALLICON
;
2106 else if (IsEqualGUID(view_params
->pvid
, &VID_List
))
2107 This
->FolderSettings
.ViewMode
= FVM_LIST
;
2108 else if (IsEqualGUID(view_params
->pvid
, &VID_Details
))
2109 This
->FolderSettings
.ViewMode
= FVM_DETAILS
;
2110 else if (IsEqualGUID(view_params
->pvid
, &VID_Thumbnails
))
2111 This
->FolderSettings
.ViewMode
= FVM_THUMBNAIL
;
2112 else if (IsEqualGUID(view_params
->pvid
, &VID_Tile
))
2113 This
->FolderSettings
.ViewMode
= FVM_TILE
;
2114 else if (IsEqualGUID(view_params
->pvid
, &VID_ThumbStrip
))
2115 This
->FolderSettings
.ViewMode
= FVM_THUMBSTRIP
;
2117 FIXME("Ignoring unrecognized VID %s\n", debugstr_guid(view_params
->pvid
));
2120 /* Get our parent window */
2121 IShellBrowser_AddRef(This
->pShellBrowser
);
2122 IShellBrowser_GetWindow(This
->pShellBrowser
, &This
->hWndParent
);
2124 /* Try to get the ICommDlgBrowserInterface, adds a reference !!! */
2125 This
->pCommDlgBrowser
= NULL
;
2126 hr
= IShellBrowser_QueryInterface(This
->pShellBrowser
, &IID_ICommDlgBrowser
, (void **)&This
->pCommDlgBrowser
);
2128 TRACE("-- CommDlgBrowser %p\n", This
->pCommDlgBrowser
);
2130 /* If our window class has not been registered, then do so */
2131 if (!GetClassInfoW(shell32_hInstance
, SV_CLASS_NAME
, &wc
))
2133 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
2134 wc
.lpfnWndProc
= ShellView_WndProc
;
2137 wc
.hInstance
= shell32_hInstance
;
2139 wc
.hCursor
= LoadCursorW(0, (LPWSTR
)IDC_ARROW
);
2140 wc
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+ 1);
2141 wc
.lpszMenuName
= NULL
;
2142 wc
.lpszClassName
= SV_CLASS_NAME
;
2144 if (!RegisterClassW(&wc
)) return E_FAIL
;
2147 wnd
= CreateWindowExW(0, SV_CLASS_NAME
, NULL
, WS_CHILD
| WS_TABSTOP
,
2148 view_params
->prcView
->left
, view_params
->prcView
->top
,
2149 view_params
->prcView
->right
- view_params
->prcView
->left
,
2150 view_params
->prcView
->bottom
- view_params
->prcView
->top
,
2151 This
->hWndParent
, 0, shell32_hInstance
, This
);
2157 IShellBrowser_Release(This
->pShellBrowser
);
2161 SetWindowPos(wnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_SHOWWINDOW
);
2164 view_params
->hwndView
= wnd
;
2169 static HRESULT WINAPI
IShellView2_fnHandleRename(IShellView2
* iface
, LPCITEMIDLIST new_pidl
)
2171 FIXME("(%p)->(new_pidl %p) stub!\n", iface
, new_pidl
);
2175 static HRESULT WINAPI
IShellView2_fnSelectAndPositionItem(IShellView2
*iface
, LPCITEMIDLIST item
,
2176 UINT flags
, POINT
*point
)
2178 IShellViewImpl
*This
= impl_from_IShellView2(iface
);
2182 TRACE("(%p)->(item %p, flags %#x, point %p)\n", This
, item
, flags
, point
);
2184 hr
= IShellView2_QueryInterface(iface
, &IID_IFolderView
, (void**)&view
);
2187 hr
= IFolderView_SelectAndPositionItems(view
, 1, &item
, point
, flags
);
2188 IFolderView_Release(view
);
2194 static const IShellView2Vtbl svvt
=
2196 IShellView_fnQueryInterface
,
2197 IShellView_fnAddRef
,
2198 IShellView_fnRelease
,
2199 IShellView_fnGetWindow
,
2200 IShellView_fnContextSensitiveHelp
,
2201 IShellView_fnTranslateAccelerator
,
2202 IShellView_fnEnableModeless
,
2203 IShellView_fnUIActivate
,
2204 IShellView_fnRefresh
,
2205 IShellView_fnCreateViewWindow
,
2206 IShellView_fnDestroyViewWindow
,
2207 IShellView_fnGetCurrentInfo
,
2208 IShellView_fnAddPropertySheetPages
,
2209 IShellView_fnSaveViewState
,
2210 IShellView_fnSelectItem
,
2211 IShellView_fnGetItemObject
,
2212 IShellView2_fnGetView
,
2213 IShellView2_fnCreateViewWindow2
,
2214 IShellView2_fnHandleRename
,
2215 IShellView2_fnSelectAndPositionItem
,
2219 /**********************************************************
2220 * ISVOleCmdTarget_QueryInterface (IUnknown)
2222 static HRESULT WINAPI
ISVOleCmdTarget_QueryInterface(
2223 IOleCommandTarget
* iface
,
2227 IShellViewImpl
*This
= impl_from_IOleCommandTarget(iface
);
2229 return IShellView2_QueryInterface(&This
->IShellView2_iface
, iid
, ppvObj
);
2232 /**********************************************************
2233 * ISVOleCmdTarget_AddRef (IUnknown)
2235 static ULONG WINAPI
ISVOleCmdTarget_AddRef(
2236 IOleCommandTarget
* iface
)
2238 IShellViewImpl
*This
= impl_from_IOleCommandTarget(iface
);
2240 return IShellView2_AddRef(&This
->IShellView2_iface
);
2243 /**********************************************************
2244 * ISVOleCmdTarget_Release (IUnknown)
2246 static ULONG WINAPI
ISVOleCmdTarget_Release(
2247 IOleCommandTarget
* iface
)
2249 IShellViewImpl
*This
= impl_from_IOleCommandTarget(iface
);
2251 return IShellView2_Release(&This
->IShellView2_iface
);
2254 /**********************************************************
2255 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2257 static HRESULT WINAPI
ISVOleCmdTarget_QueryStatus(
2258 IOleCommandTarget
*iface
,
2259 const GUID
*pguidCmdGroup
,
2262 OLECMDTEXT
*pCmdText
)
2264 IShellViewImpl
*This
= impl_from_IOleCommandTarget(iface
);
2267 FIXME("(%p)->(%s %d %p %p)\n",
2268 This
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
2271 return E_INVALIDARG
;
2272 for (i
= 0; i
< cCmds
; i
++)
2274 FIXME("\tprgCmds[%d].cmdID = %d\n", i
, prgCmds
[i
].cmdID
);
2275 prgCmds
[i
].cmdf
= 0;
2277 return OLECMDERR_E_UNKNOWNGROUP
;
2280 /**********************************************************
2281 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2283 * nCmdID is the OLECMDID_* enumeration
2285 static HRESULT WINAPI
ISVOleCmdTarget_Exec(
2286 IOleCommandTarget
*iface
,
2287 const GUID
* pguidCmdGroup
,
2293 IShellViewImpl
*This
= impl_from_IOleCommandTarget(iface
);
2295 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2296 This
, debugstr_guid(pguidCmdGroup
), nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2299 return OLECMDERR_E_UNKNOWNGROUP
;
2300 if (IsEqualIID(pguidCmdGroup
, &CGID_Explorer
) &&
2302 (nCmdexecopt
== 4) && pvaOut
)
2304 if (IsEqualIID(pguidCmdGroup
, &CGID_ShellDocView
) &&
2309 return OLECMDERR_E_UNKNOWNGROUP
;
2312 static const IOleCommandTargetVtbl ctvt
=
2314 ISVOleCmdTarget_QueryInterface
,
2315 ISVOleCmdTarget_AddRef
,
2316 ISVOleCmdTarget_Release
,
2317 ISVOleCmdTarget_QueryStatus
,
2318 ISVOleCmdTarget_Exec
2321 /**********************************************************
2322 * ISVDropTarget implementation
2325 static HRESULT WINAPI
ISVDropTarget_QueryInterface(
2330 IShellViewImpl
*This
= impl_from_IDropTarget(iface
);
2332 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This
,debugstr_guid(riid
),ppvObj
);
2334 return IShellView2_QueryInterface(&This
->IShellView2_iface
, riid
, ppvObj
);
2337 static ULONG WINAPI
ISVDropTarget_AddRef( IDropTarget
*iface
)
2339 IShellViewImpl
*This
= impl_from_IDropTarget(iface
);
2341 TRACE("(%p)->(count=%u)\n",This
,This
->ref
);
2343 return IShellView2_AddRef(&This
->IShellView2_iface
);
2346 static ULONG WINAPI
ISVDropTarget_Release( IDropTarget
*iface
)
2348 IShellViewImpl
*This
= impl_from_IDropTarget(iface
);
2350 TRACE("(%p)->(count=%u)\n",This
,This
->ref
);
2352 return IShellView2_Release(&This
->IShellView2_iface
);
2355 /******************************************************************************
2356 * drag_notify_subitem [Internal]
2358 * Figure out the shellfolder object, which is currently under the mouse cursor
2359 * and notify it via the IDropTarget interface.
2362 #define SCROLLAREAWIDTH 20
2364 static HRESULT
drag_notify_subitem(IShellViewImpl
*This
, DWORD grfKeyState
, POINTL pt
,
2367 LVHITTESTINFO htinfo
;
2373 /* Map from global to client coordinates and query the index of the listview-item, which is
2374 * currently under the mouse cursor. */
2377 htinfo
.flags
= LVHT_ONITEM
;
2378 ScreenToClient(This
->hWndList
, &htinfo
.pt
);
2379 lResult
= SendMessageW(This
->hWndList
, LVM_HITTEST
, 0, (LPARAM
)&htinfo
);
2381 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2382 GetClientRect(This
->hWndList
, &clientRect
);
2383 if (htinfo
.pt
.x
== This
->ptLastMousePos
.x
&& htinfo
.pt
.y
== This
->ptLastMousePos
.y
&&
2384 (htinfo
.pt
.x
< SCROLLAREAWIDTH
|| htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
||
2385 htinfo
.pt
.y
< SCROLLAREAWIDTH
|| htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
))
2387 This
->cScrollDelay
= (This
->cScrollDelay
+ 1) % 5; /* DragOver is called every 50 ms */
2388 if (This
->cScrollDelay
== 0) { /* Mouse did hover another 250 ms over the scroll-area */
2389 if (htinfo
.pt
.x
< SCROLLAREAWIDTH
)
2390 SendMessageW(This
->hWndList
, WM_HSCROLL
, SB_LINEUP
, 0);
2391 if (htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
)
2392 SendMessageW(This
->hWndList
, WM_HSCROLL
, SB_LINEDOWN
, 0);
2393 if (htinfo
.pt
.y
< SCROLLAREAWIDTH
)
2394 SendMessageW(This
->hWndList
, WM_VSCROLL
, SB_LINEUP
, 0);
2395 if (htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
)
2396 SendMessageW(This
->hWndList
, WM_VSCROLL
, SB_LINEDOWN
, 0);
2399 This
->cScrollDelay
= 0; /* Reset, if the cursor is not over the listview's scroll-area */
2401 This
->ptLastMousePos
= htinfo
.pt
;
2403 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2404 if (This
->pCurDropTarget
&& lResult
== This
->iDragOverItem
)
2405 return IDropTarget_DragOver(This
->pCurDropTarget
, grfKeyState
, pt
, pdwEffect
);
2407 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2408 if (This
->pCurDropTarget
) {
2409 IDropTarget_DragLeave(This
->pCurDropTarget
);
2410 IDropTarget_Release(This
->pCurDropTarget
);
2411 This
->pCurDropTarget
= NULL
;
2414 This
->iDragOverItem
= lResult
;
2415 if (lResult
== -1) {
2416 /* We are not above one of the listview's subitems. Bind to the parent folder's
2417 * DropTarget interface. */
2418 hr
= IShellFolder_QueryInterface(This
->pSFParent
, &IID_IDropTarget
,
2419 (LPVOID
*)&This
->pCurDropTarget
);
2421 /* Query the relative PIDL of the shellfolder object represented by the currently
2422 * dragged over listview-item ... */
2423 lvItem
.mask
= LVIF_PARAM
;
2424 lvItem
.iItem
= lResult
;
2425 lvItem
.iSubItem
= 0;
2426 SendMessageW(This
->hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
2428 /* ... and bind pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2429 hr
= IShellFolder_GetUIObjectOf(This
->pSFParent
, This
->hWndList
, 1,
2430 (LPCITEMIDLIST
*)&lvItem
.lParam
, &IID_IDropTarget
, NULL
, (LPVOID
*)&This
->pCurDropTarget
);
2433 /* If anything failed, pCurDropTarget should be NULL now, which ought to be a save state. */
2437 /* Notify the item just entered via DragEnter. */
2438 return IDropTarget_DragEnter(This
->pCurDropTarget
, This
->pCurDataObject
, grfKeyState
, pt
, pdwEffect
);
2441 static HRESULT WINAPI
ISVDropTarget_DragEnter(IDropTarget
*iface
, IDataObject
*pDataObject
,
2442 DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2444 IShellViewImpl
*This
= impl_from_IDropTarget(iface
);
2446 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2447 This
->pCurDataObject
= pDataObject
;
2448 IDataObject_AddRef(pDataObject
);
2450 return drag_notify_subitem(This
, grfKeyState
, pt
, pdwEffect
);
2453 static HRESULT WINAPI
ISVDropTarget_DragOver(IDropTarget
*iface
, DWORD grfKeyState
, POINTL pt
,
2456 IShellViewImpl
*This
= impl_from_IDropTarget(iface
);
2457 return drag_notify_subitem(This
, grfKeyState
, pt
, pdwEffect
);
2460 static HRESULT WINAPI
ISVDropTarget_DragLeave(IDropTarget
*iface
)
2462 IShellViewImpl
*This
= impl_from_IDropTarget(iface
);
2464 if (This
->pCurDropTarget
)
2466 IDropTarget_DragLeave(This
->pCurDropTarget
);
2467 IDropTarget_Release(This
->pCurDropTarget
);
2468 This
->pCurDropTarget
= NULL
;
2471 if (This
->pCurDataObject
)
2473 IDataObject_Release(This
->pCurDataObject
);
2474 This
->pCurDataObject
= NULL
;
2477 This
->iDragOverItem
= 0;
2482 static HRESULT WINAPI
ISVDropTarget_Drop(IDropTarget
*iface
, IDataObject
* pDataObject
,
2483 DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2485 IShellViewImpl
*This
= impl_from_IDropTarget(iface
);
2487 IDropTarget_Drop(This
->pCurDropTarget
, pDataObject
, grfKeyState
, pt
, pdwEffect
);
2489 IDropTarget_Release(This
->pCurDropTarget
);
2490 IDataObject_Release(This
->pCurDataObject
);
2491 This
->pCurDataObject
= NULL
;
2492 This
->pCurDropTarget
= NULL
;
2493 This
->iDragOverItem
= 0;
2498 static const IDropTargetVtbl dtvt
=
2500 ISVDropTarget_QueryInterface
,
2501 ISVDropTarget_AddRef
,
2502 ISVDropTarget_Release
,
2503 ISVDropTarget_DragEnter
,
2504 ISVDropTarget_DragOver
,
2505 ISVDropTarget_DragLeave
,
2509 /**********************************************************
2510 * ISVDropSource implementation
2513 static HRESULT WINAPI
ISVDropSource_QueryInterface(
2518 IShellViewImpl
*This
= impl_from_IDropSource(iface
);
2520 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This
,debugstr_guid(riid
),ppvObj
);
2522 return IShellView2_QueryInterface(&This
->IShellView2_iface
, riid
, ppvObj
);
2525 static ULONG WINAPI
ISVDropSource_AddRef( IDropSource
*iface
)
2527 IShellViewImpl
*This
= impl_from_IDropSource(iface
);
2529 TRACE("(%p)->(count=%u)\n",This
,This
->ref
);
2531 return IShellView2_AddRef(&This
->IShellView2_iface
);
2534 static ULONG WINAPI
ISVDropSource_Release( IDropSource
*iface
)
2536 IShellViewImpl
*This
= impl_from_IDropSource(iface
);
2538 TRACE("(%p)->(count=%u)\n",This
,This
->ref
);
2540 return IShellView2_Release(&This
->IShellView2_iface
);
2543 static HRESULT WINAPI
ISVDropSource_QueryContinueDrag(
2545 BOOL fEscapePressed
,
2548 IShellViewImpl
*This
= impl_from_IDropSource(iface
);
2549 TRACE("(%p)\n",This
);
2552 return DRAGDROP_S_CANCEL
;
2553 else if (!(grfKeyState
& MK_LBUTTON
) && !(grfKeyState
& MK_RBUTTON
))
2554 return DRAGDROP_S_DROP
;
2559 static HRESULT WINAPI
ISVDropSource_GiveFeedback(
2563 IShellViewImpl
*This
= impl_from_IDropSource(iface
);
2564 TRACE("(%p)\n",This
);
2566 return DRAGDROP_S_USEDEFAULTCURSORS
;
2569 static const IDropSourceVtbl dsvt
=
2571 ISVDropSource_QueryInterface
,
2572 ISVDropSource_AddRef
,
2573 ISVDropSource_Release
,
2574 ISVDropSource_QueryContinueDrag
,
2575 ISVDropSource_GiveFeedback
2577 /**********************************************************
2578 * ISVViewObject implementation
2581 static HRESULT WINAPI
ISVViewObject_QueryInterface(
2586 IShellViewImpl
*This
= impl_from_IViewObject(iface
);
2588 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This
,debugstr_guid(riid
),ppvObj
);
2590 return IShellView2_QueryInterface(&This
->IShellView2_iface
, riid
, ppvObj
);
2593 static ULONG WINAPI
ISVViewObject_AddRef( IViewObject
*iface
)
2595 IShellViewImpl
*This
= impl_from_IViewObject(iface
);
2597 TRACE("(%p)->(count=%u)\n",This
,This
->ref
);
2599 return IShellView2_AddRef(&This
->IShellView2_iface
);
2602 static ULONG WINAPI
ISVViewObject_Release( IViewObject
*iface
)
2604 IShellViewImpl
*This
= impl_from_IViewObject(iface
);
2606 TRACE("(%p)->(count=%u)\n",This
,This
->ref
);
2608 return IShellView2_Release(&This
->IShellView2_iface
);
2611 static HRESULT WINAPI
ISVViewObject_Draw(
2616 DVTARGETDEVICE
* ptd
,
2619 LPCRECTL lprcBounds
,
2620 LPCRECTL lprcWBounds
,
2621 BOOL (CALLBACK
*pfnContinue
)(ULONG_PTR dwContinue
),
2622 ULONG_PTR dwContinue
)
2625 IShellViewImpl
*This
= impl_from_IViewObject(iface
);
2627 FIXME("Stub: This=%p\n",This
);
2631 static HRESULT WINAPI
ISVViewObject_GetColorSet(
2636 DVTARGETDEVICE
* ptd
,
2637 HDC hicTargetDevice
,
2638 LOGPALETTE
** ppColorSet
)
2641 IShellViewImpl
*This
= impl_from_IViewObject(iface
);
2643 FIXME("Stub: This=%p\n",This
);
2647 static HRESULT WINAPI
ISVViewObject_Freeze(
2655 IShellViewImpl
*This
= impl_from_IViewObject(iface
);
2657 FIXME("Stub: This=%p\n",This
);
2661 static HRESULT WINAPI
ISVViewObject_Unfreeze(
2666 IShellViewImpl
*This
= impl_from_IViewObject(iface
);
2668 FIXME("Stub: This=%p\n",This
);
2672 static HRESULT WINAPI
ISVViewObject_SetAdvise(
2676 IAdviseSink
* pAdvSink
)
2679 IShellViewImpl
*This
= impl_from_IViewObject(iface
);
2681 FIXME("partial stub: %p %08x %08x %p\n",
2682 This
, aspects
, advf
, pAdvSink
);
2684 /* FIXME: we set the AdviseSink, but never use it to send any advice */
2685 This
->pAdvSink
= pAdvSink
;
2686 This
->dwAspects
= aspects
;
2687 This
->dwAdvf
= advf
;
2692 static HRESULT WINAPI
ISVViewObject_GetAdvise(
2696 IAdviseSink
** ppAdvSink
)
2699 IShellViewImpl
*This
= impl_from_IViewObject(iface
);
2701 TRACE("This=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n",
2702 This
, pAspects
, pAdvf
, ppAdvSink
);
2706 IAdviseSink_AddRef( This
->pAdvSink
);
2707 *ppAdvSink
= This
->pAdvSink
;
2710 *pAspects
= This
->dwAspects
;
2712 *pAdvf
= This
->dwAdvf
;
2718 static const IViewObjectVtbl vovt
=
2720 ISVViewObject_QueryInterface
,
2721 ISVViewObject_AddRef
,
2722 ISVViewObject_Release
,
2724 ISVViewObject_GetColorSet
,
2725 ISVViewObject_Freeze
,
2726 ISVViewObject_Unfreeze
,
2727 ISVViewObject_SetAdvise
,
2728 ISVViewObject_GetAdvise
2732 static HRESULT WINAPI
IFView_QueryInterface(
2737 IShellViewImpl
*This
= impl_from_IFolderView(iface
);
2738 TRACE("(%p)->(IID:%s,%p)\n", This
, debugstr_guid(riid
), ppvObj
);
2739 return IShellView2_QueryInterface(&This
->IShellView2_iface
, riid
, ppvObj
);
2742 static ULONG WINAPI
IFView_AddRef( IFolderView
*iface
)
2744 IShellViewImpl
*This
= impl_from_IFolderView(iface
);
2745 TRACE("(%p)->(count=%u)\n", This
, This
->ref
);
2746 return IShellView2_AddRef(&This
->IShellView2_iface
);
2749 static ULONG WINAPI
IFView_Release( IFolderView
*iface
)
2751 IShellViewImpl
*This
= impl_from_IFolderView(iface
);
2752 TRACE("(%p)->(count=%u)\n", This
, This
->ref
);
2753 return IShellView2_Release(&This
->IShellView2_iface
);
2756 static HRESULT WINAPI
IFView_GetCurrentViewMode(IFolderView
*iface
, UINT
*mode
)
2758 IShellViewImpl
*This
= impl_from_IFolderView(iface
);
2759 TRACE("(%p)->(%p), stub\n", This
, mode
);
2762 return E_INVALIDARG
;
2764 *mode
= This
->FolderSettings
.ViewMode
;
2768 static HRESULT WINAPI
IFView_SetCurrentViewMode(IFolderView
*iface
, UINT mode
)
2770 IShellViewImpl
*This
= impl_from_IFolderView(iface
);
2772 TRACE("(%p)->(%u), stub\n", This
, mode
);
2774 if((mode
< FVM_FIRST
|| mode
> FVM_LAST
) &&
2776 return E_INVALIDARG
;
2778 /* Windows before Vista uses LVM_SETVIEW and possibly
2779 LVM_SETEXTENDEDLISTVIEWSTYLE to set the style of the listview,
2780 while later versions seem to accomplish this through other
2782 dwStyle
= ViewModeToListStyle(mode
);
2783 SetStyle(This
, dwStyle
, LVS_TYPEMASK
);
2785 /* This will not necessarily be the actual mode set above.
2786 This mimics the behavior of Windows XP. */
2787 This
->FolderSettings
.ViewMode
= mode
;
2792 static HRESULT WINAPI
IFView_GetFolder(IFolderView
*iface
, REFIID riid
, void **ppv
)
2794 IShellViewImpl
*This
= impl_from_IFolderView(iface
);
2796 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(riid
), ppv
);
2798 if (!ppv
) return E_POINTER
;
2800 if (IsEqualIID(riid
, &IID_IShellFolder
))
2802 *ppv
= This
->pSFParent
;
2806 return E_NOINTERFACE
;
2809 static HRESULT WINAPI
IFView_Item(IFolderView
*iface
, int index
, PITEMID_CHILD
*ppidl
)
2811 IShellViewImpl
*This
= impl_from_IFolderView(iface
);
2814 TRACE("(%p)->(%d %p)\n", This
, index
, ppidl
);
2816 item
.mask
= LVIF_PARAM
;
2819 if (SendMessageW(This
->hWndList
, LVM_GETITEMW
, 0, (LPARAM
)&item
))
2821 *ppidl
= ILClone((PITEMID_CHILD
)item
.lParam
);
2827 return E_INVALIDARG
;
2831 static HRESULT WINAPI
IFView_ItemCount(IFolderView
*iface
, UINT flags
, int *items
)
2833 IShellViewImpl
*This
= impl_from_IFolderView(iface
);
2835 TRACE("(%p)->(%u %p)\n", This
, flags
, items
);
2837 if (flags
!= SVGIO_ALLVIEW
)
2838 FIXME("some flags unsupported, %x\n", flags
& ~SVGIO_ALLVIEW
);
2840 *items
= SendMessageW(This
->hWndList
, LVM_GETITEMCOUNT
, 0, 0);
2845 static HRESULT WINAPI
IFView_Items(IFolderView
*iface
, UINT flags
, REFIID riid
, void **ppv
)
2847 IShellViewImpl
*This
= impl_from_IFolderView(iface
);
2848 FIXME("(%p)->(%u %s %p), stub\n", This
, flags
, debugstr_guid(riid
), ppv
);
2852 static HRESULT WINAPI
IFView_GetSelectionMarkedItem(IFolderView
*iface
, int *item
)
2854 IShellViewImpl
*This
= impl_from_IFolderView(iface
);
2856 TRACE("(%p)->(%p)\n", This
, item
);
2858 *item
= SendMessageW(This
->hWndList
, LVM_GETSELECTIONMARK
, 0, 0);
2863 static HRESULT WINAPI
IFView_GetFocusedItem(IFolderView
*iface
, int *item
)
2865 IShellViewImpl
*This
= impl_from_IFolderView(iface
);
2867 TRACE("(%p)->(%p)\n", This
, item
);
2869 *item
= SendMessageW(This
->hWndList
, LVM_GETNEXTITEM
, -1, LVNI_FOCUSED
);
2874 static HRESULT WINAPI
IFView_GetItemPosition(IFolderView
*iface
, PCUITEMID_CHILD pidl
, POINT
*ppt
)
2876 IShellViewImpl
*This
= impl_from_IFolderView(iface
);
2877 FIXME("(%p)->(%p %p), stub\n", This
, pidl
, ppt
);
2881 static HRESULT WINAPI
IFView_GetSpacing(IFolderView
*iface
, POINT
*pt
)
2883 IShellViewImpl
*This
= impl_from_IFolderView(iface
);
2885 TRACE("(%p)->(%p)\n", This
, pt
);
2887 if (!This
->hWndList
) return S_FALSE
;
2892 ret
= SendMessageW(This
->hWndList
, LVM_GETITEMSPACING
, 0, 0);
2894 pt
->x
= LOWORD(ret
);
2895 pt
->y
= HIWORD(ret
);
2901 static HRESULT WINAPI
IFView_GetDefaultSpacing(IFolderView
*iface
, POINT
*pt
)
2903 IShellViewImpl
*This
= impl_from_IFolderView(iface
);
2904 FIXME("(%p)->(%p), stub\n", This
, pt
);
2908 static HRESULT WINAPI
IFView_GetAutoArrange(IFolderView
*iface
)
2910 IShellViewImpl
*This
= impl_from_IFolderView(iface
);
2911 FIXME("(%p), stub\n", This
);
2915 static HRESULT WINAPI
IFView_SelectItem(IFolderView
*iface
, int item
, DWORD flags
)
2917 IShellViewImpl
*This
= impl_from_IFolderView(iface
);
2920 TRACE("(%p)->(%d, %x)\n", This
, item
, flags
);
2923 lvItem
.stateMask
= LVIS_SELECTED
;
2925 if (flags
& SVSI_ENSUREVISIBLE
)
2926 SendMessageW(This
->hWndList
, LVM_ENSUREVISIBLE
, item
, 0);
2929 if (flags
& SVSI_DESELECTOTHERS
)
2930 SendMessageW(This
->hWndList
, LVM_SETITEMSTATE
, -1, (LPARAM
)&lvItem
);
2933 if (flags
& SVSI_SELECT
)
2934 lvItem
.state
|= LVIS_SELECTED
;
2936 if (flags
& SVSI_FOCUSED
)
2937 lvItem
.stateMask
|= LVIS_FOCUSED
;
2939 SendMessageW(This
->hWndList
, LVM_SETITEMSTATE
, item
, (LPARAM
)&lvItem
);
2941 if (flags
& SVSI_EDIT
)
2942 SendMessageW(This
->hWndList
, LVM_EDITLABELW
, item
, 0);
2947 static HRESULT WINAPI
IFView_SelectAndPositionItems(IFolderView
*iface
, UINT cidl
,
2948 PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD flags
)
2950 IShellViewImpl
*This
= impl_from_IFolderView(iface
);
2951 FIXME("(%p)->(%u %p %p %x), stub\n", This
, cidl
, apidl
, apt
, flags
);
2955 static const IFolderViewVtbl fviewvt
=
2957 IFView_QueryInterface
,
2960 IFView_GetCurrentViewMode
,
2961 IFView_SetCurrentViewMode
,
2966 IFView_GetSelectionMarkedItem
,
2967 IFView_GetFocusedItem
,
2968 IFView_GetItemPosition
,
2970 IFView_GetDefaultSpacing
,
2971 IFView_GetAutoArrange
,
2973 IFView_SelectAndPositionItems
2976 /* IShellFolderView */
2977 static HRESULT WINAPI
IShellFolderView_fnQueryInterface(
2978 IShellFolderView
*iface
,
2982 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
2983 TRACE("(%p)->(IID:%s,%p)\n", This
, debugstr_guid(riid
), ppvObj
);
2984 return IShellView2_QueryInterface(&This
->IShellView2_iface
, riid
, ppvObj
);
2987 static ULONG WINAPI
IShellFolderView_fnAddRef(IShellFolderView
*iface
)
2989 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
2990 TRACE("(%p)->(count=%u)\n", This
, This
->ref
);
2991 return IShellView2_AddRef(&This
->IShellView2_iface
);
2994 static ULONG WINAPI
IShellFolderView_fnRelease(IShellFolderView
*iface
)
2996 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
2997 TRACE("(%p)->(count=%u)\n", This
, This
->ref
);
2998 return IShellView2_Release(&This
->IShellView2_iface
);
3001 static HRESULT WINAPI
IShellFolderView_fnRearrange(IShellFolderView
*iface
, LPARAM sort
)
3003 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3004 FIXME("(%p)->(%ld) stub\n", This
, sort
);
3008 static HRESULT WINAPI
IShellFolderView_fnGetArrangeParam(IShellFolderView
*iface
, LPARAM
*sort
)
3010 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3011 FIXME("(%p)->(%p) stub\n", This
, sort
);
3015 static HRESULT WINAPI
IShellFolderView_fnArrangeGrid(IShellFolderView
*iface
)
3017 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3018 FIXME("(%p) stub\n", This
);
3022 static HRESULT WINAPI
IShellFolderView_fnAutoArrange(IShellFolderView
*iface
)
3024 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3025 FIXME("(%p) stub\n", This
);
3029 static HRESULT WINAPI
IShellFolderView_fnGetAutoArrange(IShellFolderView
*iface
)
3031 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3032 IFolderView
*view
= &This
->IFolderView_iface
;
3034 TRACE("(%p)\n", This
);
3035 return IFolderView_GetAutoArrange(view
);
3038 static HRESULT WINAPI
IShellFolderView_fnAddObject(
3039 IShellFolderView
*iface
,
3043 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3044 FIXME("(%p)->(%p %p) stub\n", This
, pidl
, item
);
3048 static HRESULT WINAPI
IShellFolderView_fnGetObject(
3049 IShellFolderView
*iface
,
3050 PITEMID_CHILD
*pidl
,
3053 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3054 IFolderView
*view
= &This
->IFolderView_iface
;
3056 TRACE("(%p)->(%p %d)\n", This
, pidl
, item
);
3057 return IFolderView_Item(view
, item
, pidl
);
3060 static HRESULT WINAPI
IShellFolderView_fnRemoveObject(
3061 IShellFolderView
*iface
,
3065 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3067 TRACE("(%p)->(%p %p)\n", This
, pidl
, item
);
3071 *item
= LV_FindItemByPidl(This
, ILFindLastID(pidl
));
3072 SendMessageW(This
->hWndList
, LVM_DELETEITEM
, *item
, 0);
3077 SendMessageW(This
->hWndList
, LVM_DELETEALLITEMS
, 0, 0);
3083 static HRESULT WINAPI
IShellFolderView_fnGetObjectCount(
3084 IShellFolderView
*iface
,
3087 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3088 IFolderView
*view
= &This
->IFolderView_iface
;
3090 TRACE("(%p)->(%p)\n", This
, count
);
3091 return IFolderView_ItemCount(view
, SVGIO_ALLVIEW
, (INT
*)count
);
3094 static HRESULT WINAPI
IShellFolderView_fnSetObjectCount(
3095 IShellFolderView
*iface
,
3099 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3100 FIXME("(%p)->(%d %x) stub\n", This
, count
, flags
);
3104 static HRESULT WINAPI
IShellFolderView_fnUpdateObject(
3105 IShellFolderView
*iface
,
3106 PITEMID_CHILD pidl_old
,
3107 PITEMID_CHILD pidl_new
,
3110 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3111 FIXME("(%p)->(%p %p %p) stub\n", This
, pidl_old
, pidl_new
, item
);
3115 static HRESULT WINAPI
IShellFolderView_fnRefreshObject(
3116 IShellFolderView
*iface
,
3120 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3121 FIXME("(%p)->(%p %p) stub\n", This
, pidl
, item
);
3125 static HRESULT WINAPI
IShellFolderView_fnSetRedraw(
3126 IShellFolderView
*iface
,
3129 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3130 TRACE("(%p)->(%d)\n", This
, redraw
);
3132 SendMessageW(This
->hWndList
, WM_SETREDRAW
, redraw
, 0);
3137 static HRESULT WINAPI
IShellFolderView_fnGetSelectedCount(
3138 IShellFolderView
*iface
,
3141 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3142 FIXME("(%p)->(%p) stub\n", This
, count
);
3146 static HRESULT WINAPI
IShellFolderView_fnGetSelectedObjects(
3147 IShellFolderView
*iface
,
3148 PCITEMID_CHILD
**pidl
,
3151 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3153 TRACE("(%p)->(%p %p)\n", This
, pidl
, items
);
3155 *items
= ShellView_GetSelections( This
);
3159 *pidl
= LocalAlloc(0, *items
*sizeof(LPITEMIDLIST
));
3160 if (!*pidl
) return E_OUTOFMEMORY
;
3162 /* it's documented that caller shouldn't free PIDLs, only array itself */
3163 memcpy((PITEMID_CHILD
*)*pidl
, This
->apidl
, *items
*sizeof(LPITEMIDLIST
));
3169 static HRESULT WINAPI
IShellFolderView_fnIsDropOnSource(
3170 IShellFolderView
*iface
,
3171 IDropTarget
*drop_target
)
3173 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3174 FIXME("(%p)->(%p) stub\n", This
, drop_target
);
3178 static HRESULT WINAPI
IShellFolderView_fnGetDragPoint(
3179 IShellFolderView
*iface
,
3182 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3183 FIXME("(%p)->(%p) stub\n", This
, pt
);
3187 static HRESULT WINAPI
IShellFolderView_fnGetDropPoint(
3188 IShellFolderView
*iface
,
3191 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3192 FIXME("(%p)->(%p) stub\n", This
, pt
);
3196 static HRESULT WINAPI
IShellFolderView_fnMoveIcons(
3197 IShellFolderView
*iface
,
3200 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3201 TRACE("(%p)->(%p)\n", This
, obj
);
3205 static HRESULT WINAPI
IShellFolderView_fnSetItemPos(
3206 IShellFolderView
*iface
,
3207 PCUITEMID_CHILD pidl
,
3210 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3211 FIXME("(%p)->(%p %p) stub\n", This
, pidl
, pt
);
3215 static HRESULT WINAPI
IShellFolderView_fnIsBkDropTarget(
3216 IShellFolderView
*iface
,
3217 IDropTarget
*drop_target
)
3219 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3220 FIXME("(%p)->(%p) stub\n", This
, drop_target
);
3224 static HRESULT WINAPI
IShellFolderView_fnSetClipboard(
3225 IShellFolderView
*iface
,
3228 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3229 FIXME("(%p)->(%d) stub\n", This
, move
);
3233 static HRESULT WINAPI
IShellFolderView_fnSetPoints(
3234 IShellFolderView
*iface
,
3237 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3238 FIXME("(%p)->(%p) stub\n", This
, obj
);
3242 static HRESULT WINAPI
IShellFolderView_fnGetItemSpacing(
3243 IShellFolderView
*iface
,
3244 ITEMSPACING
*spacing
)
3246 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3247 FIXME("(%p)->(%p) stub\n", This
, spacing
);
3251 static HRESULT WINAPI
IShellFolderView_fnSetCallback(
3252 IShellFolderView
*iface
,
3253 IShellFolderViewCB
*new_cb
,
3254 IShellFolderViewCB
**old_cb
)
3257 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3258 FIXME("(%p)->(%p %p) stub\n", This
, new_cb
, old_cb
);
3262 static HRESULT WINAPI
IShellFolderView_fnSelect(
3263 IShellFolderView
*iface
,
3266 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3267 FIXME("(%p)->(%d) stub\n", This
, flags
);
3271 static HRESULT WINAPI
IShellFolderView_fnQuerySupport(
3272 IShellFolderView
*iface
,
3275 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3276 TRACE("(%p)->(%p)\n", This
, support
);
3280 static HRESULT WINAPI
IShellFolderView_fnSetAutomationObject(
3281 IShellFolderView
*iface
,
3284 IShellViewImpl
*This
= impl_from_IShellFolderView(iface
);
3285 FIXME("(%p)->(%p) stub\n", This
, disp
);
3289 static const IShellFolderViewVtbl shellfolderviewvt
=
3291 IShellFolderView_fnQueryInterface
,
3292 IShellFolderView_fnAddRef
,
3293 IShellFolderView_fnRelease
,
3294 IShellFolderView_fnRearrange
,
3295 IShellFolderView_fnGetArrangeParam
,
3296 IShellFolderView_fnArrangeGrid
,
3297 IShellFolderView_fnAutoArrange
,
3298 IShellFolderView_fnGetAutoArrange
,
3299 IShellFolderView_fnAddObject
,
3300 IShellFolderView_fnGetObject
,
3301 IShellFolderView_fnRemoveObject
,
3302 IShellFolderView_fnGetObjectCount
,
3303 IShellFolderView_fnSetObjectCount
,
3304 IShellFolderView_fnUpdateObject
,
3305 IShellFolderView_fnRefreshObject
,
3306 IShellFolderView_fnSetRedraw
,
3307 IShellFolderView_fnGetSelectedCount
,
3308 IShellFolderView_fnGetSelectedObjects
,
3309 IShellFolderView_fnIsDropOnSource
,
3310 IShellFolderView_fnGetDragPoint
,
3311 IShellFolderView_fnGetDropPoint
,
3312 IShellFolderView_fnMoveIcons
,
3313 IShellFolderView_fnSetItemPos
,
3314 IShellFolderView_fnIsBkDropTarget
,
3315 IShellFolderView_fnSetClipboard
,
3316 IShellFolderView_fnSetPoints
,
3317 IShellFolderView_fnGetItemSpacing
,
3318 IShellFolderView_fnSetCallback
,
3319 IShellFolderView_fnSelect
,
3320 IShellFolderView_fnQuerySupport
,
3321 IShellFolderView_fnSetAutomationObject