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
41 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
45 static const WCHAR SV_CLASS_NAME
[] = {'S','H','E','L','L','D','L','L','_','D','e','f','V','i','e','w',0};
51 }LISTVIEW_SORT_INFO
, *LPLISTVIEW_SORT_INFO
;
55 const IShellViewVtbl
* lpVtbl
;
57 const IOleCommandTargetVtbl
* lpvtblOleCommandTarget
;
58 const IDropTargetVtbl
* lpvtblDropTarget
;
59 const IDropSourceVtbl
* lpvtblDropSource
;
60 const IViewObjectVtbl
* lpvtblViewObject
;
61 IShellFolder
* pSFParent
;
62 IShellFolder2
* pSF2Parent
;
63 IShellBrowser
* pShellBrowser
;
64 ICommDlgBrowser
* pCommDlgBrowser
;
65 HWND hWnd
; /* SHELLDLL_DefView */
66 HWND hWndList
; /* ListView control */
68 FOLDERSETTINGS FolderSettings
;
73 LISTVIEW_SORT_INFO ListViewSortInfo
;
74 ULONG hNotify
; /* change notification handle */
78 IAdviseSink
*pAdvSink
;
79 IDropTarget
* pCurDropTarget
; /* The sub-item, which is currently dragged over */
80 IDataObject
* pCurDataObject
; /* The dragged data-object */
81 LONG iDragOverItem
; /* Dragged over item's index, iff pCurDropTarget != NULL */
82 UINT cScrollDelay
; /* Send a WM_*SCROLL msg every 250 ms during drag-scroll */
83 POINT ptLastMousePos
; /* Mouse position at last DragOver call */
85 } IShellViewImpl
, *LPIShellViewImpl
;
87 static const IShellViewVtbl svvt
;
88 static const IOleCommandTargetVtbl ctvt
;
89 static const IDropTargetVtbl dtvt
;
90 static const IDropSourceVtbl dsvt
;
91 static const IViewObjectVtbl vovt
;
94 static LPIShellViewImpl __inline
impl_from_IOleCommandTarget( IOleCommandTarget
*iface
)
96 return (LPIShellViewImpl
)((char*)iface
- FIELD_OFFSET(IShellViewImpl
, lpvtblOleCommandTarget
));
99 static LPIShellViewImpl __inline
impl_from_IDropTarget( IDropTarget
*iface
)
101 return (LPIShellViewImpl
)((char*)iface
- FIELD_OFFSET(IShellViewImpl
, lpvtblDropTarget
));
104 static LPIShellViewImpl __inline
impl_from_IDropSource( IDropSource
*iface
)
106 return (LPIShellViewImpl
)((char*)iface
- FIELD_OFFSET(IShellViewImpl
, lpvtblDropSource
));
109 static LPIShellViewImpl __inline
impl_from_IViewObject( IViewObject
*iface
)
111 return (LPIShellViewImpl
)((char*)iface
- FIELD_OFFSET(IShellViewImpl
, lpvtblViewObject
));
114 /* ListView Header ID's */
115 #define LISTVIEW_COLUMN_NAME 0
116 #define LISTVIEW_COLUMN_SIZE 1
117 #define LISTVIEW_COLUMN_TYPE 2
118 #define LISTVIEW_COLUMN_TIME 3
119 #define LISTVIEW_COLUMN_ATTRIB 4
122 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
123 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
124 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
126 #define ID_LISTVIEW 1
128 #define SHV_CHANGE_NOTIFY WM_USER + 0x1111
131 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
132 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
133 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
136 Items merged into the toolbar and the filemenu
145 } MYTOOLINFO
, *LPMYTOOLINFO
;
147 static const MYTOOLINFO Tools
[] =
149 { FCIDM_SHVIEW_BIGICON
, 0, 0, IDS_VIEW_LARGE
, TBSTATE_ENABLED
, BTNS_BUTTON
},
150 { FCIDM_SHVIEW_SMALLICON
, 0, 0, IDS_VIEW_SMALL
, TBSTATE_ENABLED
, BTNS_BUTTON
},
151 { FCIDM_SHVIEW_LISTVIEW
, 0, 0, IDS_VIEW_LIST
, TBSTATE_ENABLED
, BTNS_BUTTON
},
152 { FCIDM_SHVIEW_REPORTVIEW
, 0, 0, IDS_VIEW_DETAILS
, TBSTATE_ENABLED
, BTNS_BUTTON
},
156 typedef void (CALLBACK
*PFNSHGETSETTINGSPROC
)(LPSHELLFLAGSTATE lpsfs
, DWORD dwMask
);
158 /**********************************************************
159 * IShellView_Constructor
161 IShellView
* IShellView_Constructor( IShellFolder
* pFolder
)
162 { IShellViewImpl
* sv
;
163 sv
=HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IShellViewImpl
));
166 sv
->lpvtblOleCommandTarget
=&ctvt
;
167 sv
->lpvtblDropTarget
=&dtvt
;
168 sv
->lpvtblDropSource
=&dsvt
;
169 sv
->lpvtblViewObject
=&vovt
;
171 sv
->pSFParent
= pFolder
;
172 if(pFolder
) IShellFolder_AddRef(pFolder
);
173 IShellFolder_QueryInterface(sv
->pSFParent
, &IID_IShellFolder2
, (LPVOID
*)&sv
->pSF2Parent
);
175 sv
->pCurDropTarget
= NULL
;
176 sv
->pCurDataObject
= NULL
;
177 sv
->iDragOverItem
= 0;
178 sv
->cScrollDelay
= 0;
179 sv
->ptLastMousePos
.x
= 0;
180 sv
->ptLastMousePos
.y
= 0;
182 TRACE("(%p)->(%p)\n",sv
, pFolder
);
183 return (IShellView
*) sv
;
186 /**********************************************************
188 * ##### helperfunctions for communication with ICommDlgBrowser #####
190 static BOOL
IsInCommDlg(IShellViewImpl
* This
)
191 { return(This
->pCommDlgBrowser
!= NULL
);
194 static HRESULT
IncludeObject(IShellViewImpl
* This
, LPCITEMIDLIST pidl
)
198 if ( IsInCommDlg(This
) )
200 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl
);
201 ret
= ICommDlgBrowser_IncludeObject(This
->pCommDlgBrowser
, (IShellView
*)This
, pidl
);
202 TRACE("--0x%08x\n", ret
);
207 static HRESULT
OnDefaultCommand(IShellViewImpl
* This
)
209 HRESULT ret
= S_FALSE
;
211 if (IsInCommDlg(This
))
213 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
214 ret
= ICommDlgBrowser_OnDefaultCommand(This
->pCommDlgBrowser
, (IShellView
*)This
);
215 TRACE("-- returns %08x\n", ret
);
220 static HRESULT
OnStateChange(IShellViewImpl
* This
, UINT uFlags
)
222 HRESULT ret
= S_FALSE
;
224 if (IsInCommDlg(This
))
226 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags
);
227 ret
= ICommDlgBrowser_OnStateChange(This
->pCommDlgBrowser
, (IShellView
*)This
, uFlags
);
232 /**********************************************************
233 * set the toolbar of the filedialog buttons
235 * - activates the buttons from the shellbrowser according to
238 static void CheckToolbar(IShellViewImpl
* This
)
244 if (IsInCommDlg(This
))
246 IShellBrowser_SendControlMsg(This
->pShellBrowser
, FCW_TOOLBAR
, TB_CHECKBUTTON
,
247 FCIDM_TB_SMALLICON
, (This
->FolderSettings
.ViewMode
==FVM_LIST
)? TRUE
: FALSE
, &result
);
248 IShellBrowser_SendControlMsg(This
->pShellBrowser
, FCW_TOOLBAR
, TB_CHECKBUTTON
,
249 FCIDM_TB_REPORTVIEW
, (This
->FolderSettings
.ViewMode
==FVM_DETAILS
)? TRUE
: FALSE
, &result
);
250 IShellBrowser_SendControlMsg(This
->pShellBrowser
, FCW_TOOLBAR
, TB_ENABLEBUTTON
,
251 FCIDM_TB_SMALLICON
, TRUE
, &result
);
252 IShellBrowser_SendControlMsg(This
->pShellBrowser
, FCW_TOOLBAR
, TB_ENABLEBUTTON
,
253 FCIDM_TB_REPORTVIEW
, TRUE
, &result
);
257 /**********************************************************
259 * ##### helperfunctions for initializing the view #####
261 /**********************************************************
262 * change the style of the listview control
264 static void SetStyle(IShellViewImpl
* This
, DWORD dwAdd
, DWORD dwRemove
)
268 TRACE("(%p)\n", This
);
270 tmpstyle
= GetWindowLongPtrW(This
->hWndList
, GWL_STYLE
);
271 SetWindowLongPtrW(This
->hWndList
, GWL_STYLE
, dwAdd
| (tmpstyle
& ~dwRemove
));
274 /**********************************************************
275 * ShellView_CreateList()
277 * - creates the list view window
279 static BOOL
ShellView_CreateList (IShellViewImpl
* This
)
280 { DWORD dwStyle
, dwExStyle
;
284 dwStyle
= WS_TABSTOP
| WS_VISIBLE
| WS_CHILDWINDOW
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
|
285 LVS_SHAREIMAGELISTS
| LVS_EDITLABELS
| LVS_AUTOARRANGE
;
286 dwExStyle
= WS_EX_CLIENTEDGE
;
288 if (This
->FolderSettings
.fFlags
& FWF_DESKTOP
)
289 dwStyle
|= LVS_ALIGNLEFT
;
291 dwStyle
|= LVS_ALIGNTOP
;
293 switch (This
->FolderSettings
.ViewMode
)
295 case FVM_ICON
: dwStyle
|= LVS_ICON
; break;
296 case FVM_DETAILS
: dwStyle
|= LVS_REPORT
; break;
297 case FVM_SMALLICON
: dwStyle
|= LVS_SMALLICON
; break;
298 case FVM_LIST
: dwStyle
|= LVS_LIST
; break;
299 default: dwStyle
|= LVS_LIST
; break;
302 if (This
->FolderSettings
.fFlags
& FWF_AUTOARRANGE
) dwStyle
|= LVS_AUTOARRANGE
;
303 if (This
->FolderSettings
.fFlags
& FWF_DESKTOP
)
304 This
->FolderSettings
.fFlags
|= FWF_NOCLIENTEDGE
| FWF_NOSCROLL
;
305 if (This
->FolderSettings
.fFlags
& FWF_SINGLESEL
) dwStyle
|= LVS_SINGLESEL
;
306 if (This
->FolderSettings
.fFlags
& FWF_NOCLIENTEDGE
)
307 dwExStyle
&= ~WS_EX_CLIENTEDGE
;
309 This
->hWndList
=CreateWindowExW( dwExStyle
,
322 This
->ListViewSortInfo
.bIsAscending
= TRUE
;
323 This
->ListViewSortInfo
.nHeaderID
= -1;
324 This
->ListViewSortInfo
.nLastHeaderID
= -1;
326 if (This
->FolderSettings
.fFlags
& FWF_DESKTOP
) {
328 * FIXME: look at the registry value
329 * HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ListviewShadow
330 * and activate drop shadows if necessary
334 SendMessageW(This
->hWndList
, LVM_SETTEXTBKCOLOR
, 0, CLR_NONE
);
335 SendMessageW(This
->hWndList
, LVM_SETBKCOLOR
, 0, CLR_NONE
);
339 SendMessageW(This
->hWndList
, LVM_SETTEXTBKCOLOR
, 0, GetSysColor(COLOR_DESKTOP
));
340 SendMessageW(This
->hWndList
, LVM_SETBKCOLOR
, 0, GetSysColor(COLOR_DESKTOP
));
343 SendMessageW(This
->hWndList
, LVM_SETTEXTCOLOR
, 0, RGB(255,255,255));
346 /* UpdateShellSettings(); */
350 /**********************************************************
351 * ShellView_InitList()
353 * - adds all needed columns to the shellview
355 static BOOL
ShellView_InitList(IShellViewImpl
* This
)
364 SendMessageW(This
->hWndList
, LVM_DELETEALLITEMS
, 0, 0);
366 lvColumn
.mask
= LVCF_FMT
| LVCF_WIDTH
| LVCF_TEXT
;
367 lvColumn
.pszText
= szTemp
;
369 if (This
->pSF2Parent
)
373 if (FAILED(IShellFolder2_GetDetailsOf(This
->pSF2Parent
, NULL
, i
, &sd
)))
375 lvColumn
.fmt
= sd
.fmt
;
376 lvColumn
.cx
= sd
.cxChar
*8; /* chars->pixel */
377 StrRetToStrNW( szTemp
, 50, &sd
.str
, NULL
);
378 SendMessageW(This
->hWndList
, LVM_INSERTCOLUMNW
, i
, (LPARAM
) &lvColumn
);
386 SendMessageW(This
->hWndList
, LVM_SETIMAGELIST
, LVSIL_SMALL
, (LPARAM
)ShellSmallIconList
);
387 SendMessageW(This
->hWndList
, LVM_SETIMAGELIST
, LVSIL_NORMAL
, (LPARAM
)ShellBigIconList
);
391 /**********************************************************
392 * ShellView_CompareItems()
395 * internal, CALLBACK for DSA_Sort
397 static INT CALLBACK
ShellView_CompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
)
400 TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1
, lParam2
, (LPVOID
) lpData
);
402 if(!lpData
) return 0;
404 ret
= (SHORT
) SCODE_CODE(IShellFolder_CompareIDs((LPSHELLFOLDER
)lpData
, 0, (LPITEMIDLIST
)lParam1
, (LPITEMIDLIST
)lParam2
));
405 TRACE("ret=%i\n",ret
);
409 /*************************************************************************
410 * ShellView_ListViewCompareItems
412 * Compare Function for the Listview (FileOpen Dialog)
415 * lParam1 [I] the first ItemIdList to compare with
416 * lParam2 [I] the second ItemIdList to compare with
417 * lpData [I] The column ID for the header Ctrl to process
420 * A negative value if the first item should precede the second,
421 * a positive value if the first item should follow the second,
422 * or zero if the two items are equivalent
425 * FIXME: function does what ShellView_CompareItems is supposed to do.
426 * unify it and figure out how to use the undocumented first parameter
427 * of IShellFolder_CompareIDs to do the job this function does and
428 * move this code to IShellFolder.
429 * make LISTVIEW_SORT_INFO obsolete
430 * the way this function works is only usable if we had only
431 * filesystemfolders (25/10/99 jsch)
433 static INT CALLBACK
ShellView_ListViewCompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
)
437 char strName1
[MAX_PATH
], strName2
[MAX_PATH
];
438 BOOL bIsFolder1
, bIsFolder2
,bIsBothFolder
;
439 LPITEMIDLIST pItemIdList1
= lParam1
;
440 LPITEMIDLIST pItemIdList2
= lParam2
;
441 LISTVIEW_SORT_INFO
*pSortInfo
= (LPLISTVIEW_SORT_INFO
) lpData
;
444 bIsFolder1
= _ILIsFolder(pItemIdList1
);
445 bIsFolder2
= _ILIsFolder(pItemIdList2
);
446 bIsBothFolder
= bIsFolder1
&& bIsFolder2
;
448 /* When sorting between a File and a Folder, the Folder gets sorted first */
449 if( (bIsFolder1
|| bIsFolder2
) && !bIsBothFolder
)
451 nDiff
= bIsFolder1
? -1 : 1;
455 /* Sort by Time: Folders or Files can be sorted */
457 if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_TIME
)
459 _ILGetFileDateTime(pItemIdList1
, &fd1
);
460 _ILGetFileDateTime(pItemIdList2
, &fd2
);
461 nDiff
= CompareFileTime(&fd2
, &fd1
);
463 /* Sort by Attribute: Folder or Files can be sorted */
464 else if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_ATTRIB
)
466 _ILGetFileAttributes(pItemIdList1
, strName1
, MAX_PATH
);
467 _ILGetFileAttributes(pItemIdList2
, strName2
, MAX_PATH
);
468 nDiff
= lstrcmpiA(strName1
, strName2
);
470 /* Sort by FileName: Folder or Files can be sorted */
471 else if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_NAME
|| bIsBothFolder
)
474 _ILSimpleGetText(pItemIdList1
, strName1
, MAX_PATH
);
475 _ILSimpleGetText(pItemIdList2
, strName2
, MAX_PATH
);
476 nDiff
= lstrcmpiA(strName1
, strName2
);
478 /* Sort by File Size, Only valid for Files */
479 else if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_SIZE
)
481 nDiff
= (INT
)(_ILGetFileSize(pItemIdList1
, NULL
, 0) - _ILGetFileSize(pItemIdList2
, NULL
, 0));
483 /* Sort by File Type, Only valid for Files */
484 else if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_TYPE
)
487 _ILGetFileType(pItemIdList1
, strName1
, MAX_PATH
);
488 _ILGetFileType(pItemIdList2
, strName2
, MAX_PATH
);
489 nDiff
= lstrcmpiA(strName1
, strName2
);
492 /* If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
496 _ILSimpleGetText(pItemIdList1
, strName1
, MAX_PATH
);
497 _ILSimpleGetText(pItemIdList2
, strName2
, MAX_PATH
);
498 nDiff
= lstrcmpiA(strName1
, strName2
);
501 if(!pSortInfo
->bIsAscending
)
510 /**********************************************************
511 * LV_FindItemByPidl()
513 static int LV_FindItemByPidl(
514 IShellViewImpl
* This
,
519 lvItem
.mask
= LVIF_PARAM
;
520 for(lvItem
.iItem
= 0;
521 SendMessageW(This
->hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
524 LPITEMIDLIST currentpidl
= (LPITEMIDLIST
) lvItem
.lParam
;
525 HRESULT hr
= IShellFolder_CompareIDs(This
->pSFParent
, 0, pidl
, currentpidl
);
526 if(SUCCEEDED(hr
) && !HRESULT_CODE(hr
))
534 /**********************************************************
537 static BOOLEAN
LV_AddItem(IShellViewImpl
* This
, LPCITEMIDLIST pidl
)
541 TRACE("(%p)(pidl=%p)\n", This
, pidl
);
543 lvItem
.mask
= LVIF_TEXT
| LVIF_IMAGE
| LVIF_PARAM
; /*set the mask*/
544 lvItem
.iItem
= ListView_GetItemCount(This
->hWndList
); /*add the item to the end of the list*/
546 lvItem
.lParam
= (LPARAM
) ILClone(ILFindLastID(pidl
)); /*set the item's data*/
547 lvItem
.pszText
= LPSTR_TEXTCALLBACKW
; /*get text on a callback basis*/
548 lvItem
.iImage
= I_IMAGECALLBACK
; /*get the image on a callback basis*/
549 if (SendMessageW(This
->hWndList
, LVM_INSERTITEMW
, 0, (LPARAM
)&lvItem
) == -1)
555 /**********************************************************
558 static BOOLEAN
LV_DeleteItem(IShellViewImpl
* This
, LPCITEMIDLIST pidl
)
562 TRACE("(%p)(pidl=%p)\n", This
, pidl
);
564 nIndex
= LV_FindItemByPidl(This
, ILFindLastID(pidl
));
565 return (-1==ListView_DeleteItem(This
->hWndList
, nIndex
))? FALSE
: TRUE
;
568 /**********************************************************
571 static BOOLEAN
LV_RenameItem(IShellViewImpl
* This
, LPCITEMIDLIST pidlOld
, LPCITEMIDLIST pidlNew
)
576 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", This
, pidlOld
, pidlNew
);
578 nItem
= LV_FindItemByPidl(This
, ILFindLastID(pidlOld
));
581 lvItem
.mask
= LVIF_PARAM
; /* only the pidl */
582 lvItem
.iItem
= nItem
;
583 SendMessageW(This
->hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
585 SHFree((LPITEMIDLIST
)lvItem
.lParam
);
586 lvItem
.mask
= LVIF_PARAM
;
587 lvItem
.iItem
= nItem
;
588 lvItem
.lParam
= (LPARAM
) ILClone(ILFindLastID(pidlNew
)); /* set the item's data */
589 SendMessageW(This
->hWndList
, LVM_SETITEMW
, 0, (LPARAM
) &lvItem
);
590 SendMessageW(This
->hWndList
, LVM_UPDATE
, nItem
, 0);
591 return TRUE
; /* FIXME: better handling */
595 /**********************************************************
596 * ShellView_FillList()
598 * - gets the objectlist from the shellfolder
600 * - fills the list into the view
603 static INT CALLBACK
fill_list( LPVOID ptr
, LPVOID arg
)
605 LPITEMIDLIST pidl
= ptr
;
606 IShellViewImpl
*This
= arg
;
607 /* in a commdlg This works as a filemask*/
608 if ( IncludeObject(This
, pidl
)==S_OK
) LV_AddItem(This
, pidl
);
613 static HRESULT
ShellView_FillList(IShellViewImpl
* This
)
615 LPENUMIDLIST pEnumIDList
;
623 /* get the itemlist from the shfolder*/
624 hRes
= IShellFolder_EnumObjects(This
->pSFParent
,This
->hWnd
, SHCONTF_NONFOLDERS
| SHCONTF_FOLDERS
, &pEnumIDList
);
632 /* create a pointer array */
633 hdpa
= DPA_Create(16);
636 return(E_OUTOFMEMORY
);
639 /* copy the items into the array*/
640 while((S_OK
== IEnumIDList_Next(pEnumIDList
,1, &pidl
, &dwFetched
)) && dwFetched
)
642 if (DPA_InsertPtr(hdpa
, 0x7fff, pidl
) == -1)
649 DPA_Sort(hdpa
, ShellView_CompareItems
, (LPARAM
)This
->pSFParent
);
651 /*turn the listview's redrawing off*/
652 SendMessageA(This
->hWndList
, WM_SETREDRAW
, FALSE
, 0);
654 DPA_DestroyCallback( hdpa
, fill_list
, This
);
656 /*turn the listview's redrawing back on and force it to draw*/
657 SendMessageA(This
->hWndList
, WM_SETREDRAW
, TRUE
, 0);
659 IEnumIDList_Release(pEnumIDList
); /* destroy the list*/
664 /**********************************************************
665 * ShellView_OnCreate()
667 static LRESULT
ShellView_OnCreate(IShellViewImpl
* This
)
670 SHChangeNotifyEntry ntreg
;
671 IPersistFolder2
* ppf2
= NULL
;
675 if(ShellView_CreateList(This
))
677 if(ShellView_InitList(This
))
679 ShellView_FillList(This
);
683 if (SUCCEEDED(IUnknown_QueryInterface((IUnknown
*)&This
->lpVtbl
, &IID_IDropTarget
, (LPVOID
*)&pdt
)))
685 RegisterDragDrop(This
->hWnd
, pdt
);
686 IDropTarget_Release(pdt
);
689 /* register for receiving notifications */
690 IShellFolder_QueryInterface(This
->pSFParent
, &IID_IPersistFolder2
, (LPVOID
*)&ppf2
);
693 IPersistFolder2_GetCurFolder(ppf2
, (LPITEMIDLIST
*)&ntreg
.pidl
);
694 ntreg
.fRecursive
= TRUE
;
695 This
->hNotify
= SHChangeNotifyRegister(This
->hWnd
, SHCNF_IDLIST
, SHCNE_ALLEVENTS
, SHV_CHANGE_NOTIFY
, 1, &ntreg
);
696 SHFree((LPITEMIDLIST
)ntreg
.pidl
);
697 IPersistFolder2_Release(ppf2
);
700 This
->hAccel
= LoadAcceleratorsA(shell32_hInstance
, "shv_accel");
705 /**********************************************************
706 * #### Handling of the menus ####
709 /**********************************************************
710 * ShellView_BuildFileMenu()
712 static HMENU
ShellView_BuildFileMenu(IShellViewImpl
* This
)
713 { WCHAR szText
[MAX_PATH
];
718 TRACE("(%p)\n",This
);
720 hSubMenu
= CreatePopupMenu();
722 { /*get the number of items in our global array*/
723 for(nTools
= 0; Tools
[nTools
].idCommand
!= -1; nTools
++){}
725 /*add the menu items*/
726 for(i
= 0; i
< nTools
; i
++)
728 LoadStringW(shell32_hInstance
, Tools
[i
].idMenuString
, szText
, MAX_PATH
);
730 ZeroMemory(&mii
, sizeof(mii
));
731 mii
.cbSize
= sizeof(mii
);
732 mii
.fMask
= MIIM_TYPE
| MIIM_ID
| MIIM_STATE
;
734 if(BTNS_SEP
!= Tools
[i
].bStyle
) /* no separator*/
736 mii
.fType
= MFT_STRING
;
737 mii
.fState
= MFS_ENABLED
;
738 mii
.dwTypeData
= szText
;
739 mii
.wID
= Tools
[i
].idCommand
;
743 mii
.fType
= MFT_SEPARATOR
;
745 /* tack This item onto the end of the menu */
746 InsertMenuItemW(hSubMenu
, (UINT
)-1, TRUE
, &mii
);
749 TRACE("-- return (menu=%p)\n",hSubMenu
);
752 /**********************************************************
753 * ShellView_MergeFileMenu()
755 static void ShellView_MergeFileMenu(IShellViewImpl
* This
, HMENU hSubMenu
)
756 { TRACE("(%p)->(submenu=%p) stub\n",This
,hSubMenu
);
759 { /*insert This item at the beginning of the menu */
760 _InsertMenuItemW(hSubMenu
, 0, TRUE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
761 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
, MFT_STRING
, L
"dummy45", MFS_ENABLED
);
767 /**********************************************************
768 * ShellView_MergeViewMenu()
771 static void ShellView_MergeViewMenu(IShellViewImpl
* This
, HMENU hSubMenu
)
773 TRACE("(%p)->(submenu=%p)\n",This
,hSubMenu
);
776 { /*add a separator at the correct position in the menu*/
778 static WCHAR view
[] = L
"View";
780 _InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
782 ZeroMemory(&mii
, sizeof(mii
));
783 mii
.cbSize
= sizeof(mii
);
784 mii
.fMask
= MIIM_SUBMENU
| MIIM_TYPE
| MIIM_DATA
;
785 mii
.fType
= MFT_STRING
;
786 mii
.dwTypeData
= view
;
787 mii
.hSubMenu
= LoadMenuW(shell32_hInstance
, L
"MENU_001");
788 InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, &mii
);
792 /**********************************************************
793 * ShellView_GetSelections()
795 * - fills the this->apidl list with the selected objects
798 * number of selected items
800 static UINT
ShellView_GetSelections(IShellViewImpl
* This
)
807 This
->cidl
= ListView_GetSelectedCount(This
->hWndList
);
808 This
->apidl
= (LPITEMIDLIST
*)SHAlloc(This
->cidl
* sizeof(LPITEMIDLIST
));
810 TRACE("selected=%i\n", This
->cidl
);
814 TRACE("-- Items selected =%u\n", This
->cidl
);
816 lvItem
.mask
= LVIF_STATE
| LVIF_PARAM
;
817 lvItem
.stateMask
= LVIS_SELECTED
;
821 while(SendMessageW(This
->hWndList
, LVM_GETITEMW
, 0, (LPARAM
)&lvItem
) && (i
< This
->cidl
))
823 if(lvItem
.state
& LVIS_SELECTED
)
825 This
->apidl
[i
] = (LPITEMIDLIST
)lvItem
.lParam
;
829 TRACE("-- selected Item found\n");
838 /**********************************************************
839 * ShellView_OpenSelectedItems()
841 static HRESULT
ShellView_OpenSelectedItems(IShellViewImpl
* This
)
843 static UINT CF_IDLIST
= 0;
845 IDataObject
* selection
;
851 LPCITEMIDLIST parent_pidl
;
852 WCHAR parent_path
[MAX_PATH
];
853 LPCWSTR parent_dir
= NULL
;
856 CMINVOKECOMMANDINFOEX ici
;
859 if (0 == ShellView_GetSelections(This
))
864 hr
= IShellFolder_GetUIObjectOf(This
->pSFParent
, This
->hWnd
, This
->cidl
,
865 (LPCITEMIDLIST
*)This
->apidl
, &IID_IContextMenu
,
870 hmenu
= CreatePopupMenu();
873 if (SUCCEEDED(IContextMenu_QueryContextMenu( cm
, hmenu
, 0, 0x20, 0x7fff, CMF_DEFAULTONLY
)))
875 INT def
= -1, n
= GetMenuItemCount(hmenu
);
877 for ( i
= 0; i
< n
; i
++ )
879 memset( &info
, 0, sizeof info
);
880 info
.cbSize
= sizeof info
;
881 info
.fMask
= MIIM_FTYPE
| MIIM_STATE
| MIIM_ID
;
882 if (GetMenuItemInfoW( hmenu
, i
, TRUE
, &info
))
884 if (info
.fState
& MFS_DEFAULT
)
893 memset( &ici
, 0, sizeof ici
);
894 ici
.cbSize
= sizeof ici
;
895 ici
.lpVerb
= MAKEINTRESOURCEA( def
);
896 ici
.hwnd
= This
->hWnd
;
898 if (IContextMenu_InvokeCommand(cm
, (LPCMINVOKECOMMANDINFO
) &ici
) == S_OK
)
900 IContextMenu_Release(cm
);
901 DestroyMenu( hmenu
);
907 DestroyMenu( hmenu
);
909 IContextMenu_Release(cm
);
914 hr
= IShellFolder_GetUIObjectOf(This
->pSFParent
, This
->hWnd
, This
->cidl
,
915 (LPCITEMIDLIST
*)This
->apidl
, &IID_IDataObject
,
916 0, (LPVOID
*)&selection
);
925 CF_IDLIST
= RegisterClipboardFormatW(CFSTR_SHELLIDLIST
);
927 fetc
.cfFormat
= CF_IDLIST
;
929 fetc
.dwAspect
= DVASPECT_CONTENT
;
931 fetc
.tymed
= TYMED_HGLOBAL
;
933 hr
= IDataObject_QueryGetData(selection
, &fetc
);
937 hr
= IDataObject_GetData(selection
, &fetc
, &stgm
);
941 pIDList
= GlobalLock(stgm
.u
.hGlobal
);
943 parent_pidl
= (LPCITEMIDLIST
) ((LPBYTE
)pIDList
+pIDList
->aoffset
[0]);
944 hr
= IShellFolder_GetAttributesOf(This
->pSFParent
, 1, &parent_pidl
, &attribs
);
945 if (SUCCEEDED(hr
) && (attribs
& SFGAO_FILESYSTEM
) &&
946 SHGetPathFromIDListW(parent_pidl
, parent_path
))
948 parent_dir
= parent_path
;
951 for (i
= pIDList
->cidl
; i
> 0; --i
)
955 pidl
= (LPCITEMIDLIST
)((LPBYTE
)pIDList
+pIDList
->aoffset
[i
]);
957 attribs
= SFGAO_FOLDER
;
958 hr
= IShellFolder_GetAttributesOf(This
->pSFParent
, 1, &pidl
, &attribs
);
960 if (SUCCEEDED(hr
) && ! (attribs
& SFGAO_FOLDER
))
962 SHELLEXECUTEINFOW shexinfo
;
964 shexinfo
.cbSize
= sizeof(SHELLEXECUTEINFOW
);
965 shexinfo
.fMask
= SEE_MASK_INVOKEIDLIST
; /* SEE_MASK_IDLIST is also possible. */
966 shexinfo
.hwnd
= NULL
;
967 shexinfo
.lpVerb
= NULL
;
968 shexinfo
.lpFile
= NULL
;
969 shexinfo
.lpParameters
= NULL
;
970 shexinfo
.lpDirectory
= parent_dir
;
971 shexinfo
.nShow
= SW_NORMAL
;
972 shexinfo
.lpIDList
= ILCombine(parent_pidl
, pidl
);
974 ShellExecuteExW(&shexinfo
); /* Discard error/success info */
976 ILFree((LPITEMIDLIST
)shexinfo
.lpIDList
);
980 GlobalUnlock(stgm
.u
.hGlobal
);
981 ReleaseStgMedium(&stgm
);
983 IDataObject_Release(selection
);
988 /**********************************************************
989 * ShellView_DoContextMenu()
991 static void ShellView_DoContextMenu(IShellViewImpl
* This
, WORD x
, WORD y
, BOOL bDefault
)
995 BOOL fExplore
= FALSE
;
997 CMINVOKECOMMANDINFO cmi
;
999 TRACE("(%p)->(0x%08x 0x%08x 0x%08x) stub\n",This
, x
, y
, bDefault
);
1001 /* look, what's selected and create a context menu object of it*/
1002 if( ShellView_GetSelections(This
) )
1004 IShellFolder_GetUIObjectOf( This
->pSFParent
, This
->hWndParent
, This
->cidl
, (LPCITEMIDLIST
*)This
->apidl
,
1005 (REFIID
)&IID_IContextMenu
, NULL
, (LPVOID
*)&This
->pCM
);
1009 TRACE("-- pContextMenu\n");
1010 hMenu
= CreatePopupMenu();
1014 /* See if we are in Explore or Open mode. If the browser's tree is present, we are in Explore mode.*/
1015 if(SUCCEEDED(IShellBrowser_GetControlWindow(This
->pShellBrowser
,FCW_TREE
, &hwndTree
)) && hwndTree
)
1017 TRACE("-- explore mode\n");
1021 /* build the flags depending on what we can do with the selected item */
1022 wFlags
= CMF_NORMAL
| (This
->cidl
!= 1 ? 0 : CMF_CANRENAME
) | (fExplore
? CMF_EXPLORE
: 0);
1024 /* let the ContextMenu merge its items in */
1025 if (SUCCEEDED(IContextMenu_QueryContextMenu( This
->pCM
, hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, wFlags
)))
1027 if (This
->FolderSettings
.fFlags
& FWF_DESKTOP
)
1028 SetMenuDefaultItem(hMenu
, FCIDM_SHVIEW_OPEN
, MF_BYCOMMAND
);
1032 TRACE("-- get menu default command\n");
1033 uCommand
= GetMenuDefaultItem(hMenu
, FALSE
, GMDI_GOINTOPOPUPS
);
1037 TRACE("-- track popup\n");
1038 uCommand
= TrackPopupMenu( hMenu
,TPM_LEFTALIGN
| TPM_RETURNCMD
,x
,y
,0,This
->hWnd
,NULL
);
1043 TRACE("-- uCommand=%u\n", uCommand
);
1044 if (uCommand
==FCIDM_SHVIEW_OPEN
&& IsInCommDlg(This
))
1046 TRACE("-- dlg: OnDefaultCommand\n");
1047 if (OnDefaultCommand(This
) != S_OK
)
1049 ShellView_OpenSelectedItems(This
);
1054 TRACE("-- explore -- invoke command\n");
1055 ZeroMemory(&cmi
, sizeof(cmi
));
1056 cmi
.cbSize
= sizeof(cmi
);
1057 cmi
.hwnd
= This
->hWndParent
; /* this window has to answer CWM_GETISHELLBROWSER */
1058 cmi
.lpVerb
= (LPCSTR
)MAKEINTRESOURCEA(uCommand
);
1059 IContextMenu_InvokeCommand(This
->pCM
, &cmi
);
1067 IContextMenu_Release(This
->pCM
);
1072 else /* background context menu */
1074 hMenu
= CreatePopupMenu();
1076 CDefFolderMenu_Create2(NULL
, NULL
, This
->cidl
, (LPCITEMIDLIST
*)This
->apidl
, This
->pSFParent
, NULL
, 0, NULL
, (IContextMenu
**)&This
->pCM
);
1077 IContextMenu2_QueryContextMenu(This
->pCM
, hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, 0);
1079 uCommand
= TrackPopupMenu( hMenu
, TPM_LEFTALIGN
| TPM_RETURNCMD
,x
,y
,0,This
->hWnd
,NULL
);
1082 TRACE("-- (%p)->(uCommand=0x%08x )\n",This
, uCommand
);
1084 ZeroMemory(&cmi
, sizeof(cmi
));
1085 cmi
.cbSize
= sizeof(cmi
);
1086 cmi
.lpVerb
= (LPCSTR
)MAKEINTRESOURCEA(uCommand
);
1087 cmi
.hwnd
= This
->hWndParent
;
1088 IContextMenu2_InvokeCommand(This
->pCM
, &cmi
);
1090 IContextMenu2_Release(This
->pCM
);
1095 /**********************************************************
1096 * ##### message handling #####
1099 /**********************************************************
1100 * ShellView_OnSize()
1102 static LRESULT
ShellView_OnSize(IShellViewImpl
* This
, WORD wWidth
, WORD wHeight
)
1104 TRACE("%p width=%u height=%u\n",This
, wWidth
,wHeight
);
1106 /*resize the ListView to fit our window*/
1109 MoveWindow(This
->hWndList
, 0, 0, wWidth
, wHeight
, TRUE
);
1114 /**********************************************************
1115 * ShellView_OnDeactivate()
1120 static void ShellView_OnDeactivate(IShellViewImpl
* This
)
1124 if(This
->uState
!= SVUIA_DEACTIVATE
)
1128 IShellBrowser_SetMenuSB(This
->pShellBrowser
,0, 0, 0);
1129 IShellBrowser_RemoveMenusSB(This
->pShellBrowser
,This
->hMenu
);
1130 DestroyMenu(This
->hMenu
);
1134 This
->uState
= SVUIA_DEACTIVATE
;
1138 /**********************************************************
1139 * ShellView_OnActivate()
1141 static LRESULT
ShellView_OnActivate(IShellViewImpl
* This
, UINT uState
)
1142 { OLEMENUGROUPWIDTHS omw
= { {0, 0, 0, 0, 0, 0} };
1144 CHAR szText
[MAX_PATH
];
1146 TRACE("%p uState=%x\n",This
,uState
);
1148 /*don't do anything if the state isn't really changing */
1149 if(This
->uState
== uState
)
1154 ShellView_OnDeactivate(This
);
1156 /*only do This if we are active */
1157 if(uState
!= SVUIA_DEACTIVATE
)
1159 /*merge the menus */
1160 This
->hMenu
= CreateMenu();
1164 IShellBrowser_InsertMenusSB(This
->pShellBrowser
, This
->hMenu
, &omw
);
1165 TRACE("-- after fnInsertMenusSB\n");
1167 /*build the top level menu get the menu item's text*/
1168 strcpy(szText
,"dummy 31");
1170 ZeroMemory(&mii
, sizeof(mii
));
1171 mii
.cbSize
= sizeof(mii
);
1172 mii
.fMask
= MIIM_SUBMENU
| MIIM_TYPE
| MIIM_STATE
;
1173 mii
.fType
= MFT_STRING
;
1174 mii
.fState
= MFS_ENABLED
;
1175 mii
.dwTypeData
= szText
;
1176 mii
.hSubMenu
= ShellView_BuildFileMenu(This
);
1178 /*insert our menu into the menu bar*/
1181 InsertMenuItemA(This
->hMenu
, FCIDM_MENU_HELP
, FALSE
, &mii
);
1184 /*get the view menu so we can merge with it*/
1185 ZeroMemory(&mii
, sizeof(mii
));
1186 mii
.cbSize
= sizeof(mii
);
1187 mii
.fMask
= MIIM_SUBMENU
;
1189 if(GetMenuItemInfoA(This
->hMenu
, FCIDM_MENU_VIEW
, FALSE
, &mii
))
1191 ShellView_MergeViewMenu(This
, mii
.hSubMenu
);
1194 /*add the items that should only be added if we have the focus*/
1195 if(SVUIA_ACTIVATE_FOCUS
== uState
)
1197 /*get the file menu so we can merge with it */
1198 ZeroMemory(&mii
, sizeof(mii
));
1199 mii
.cbSize
= sizeof(mii
);
1200 mii
.fMask
= MIIM_SUBMENU
;
1202 if(GetMenuItemInfoA(This
->hMenu
, FCIDM_MENU_FILE
, FALSE
, &mii
))
1204 ShellView_MergeFileMenu(This
, mii
.hSubMenu
);
1207 TRACE("-- before fnSetMenuSB\n");
1208 IShellBrowser_SetMenuSB(This
->pShellBrowser
, This
->hMenu
, 0, This
->hWnd
);
1211 This
->uState
= uState
;
1216 /**********************************************************
1217 * ShellView_OnSetFocus()
1220 static LRESULT
ShellView_OnSetFocus(IShellViewImpl
* This
)
1224 /* Tell the browser one of our windows has received the focus. This
1225 should always be done before merging menus (OnActivate merges the
1226 menus) if one of our windows has the focus.*/
1228 IShellBrowser_OnViewWindowActive(This
->pShellBrowser
,(IShellView
*) This
);
1229 ShellView_OnActivate(This
, SVUIA_ACTIVATE_FOCUS
);
1231 /* Set the focus to the listview */
1232 SetFocus(This
->hWndList
);
1234 /* Notify the ICommDlgBrowser interface */
1235 OnStateChange(This
,CDBOSC_SETFOCUS
);
1240 /**********************************************************
1241 * ShellView_OnKillFocus()
1243 static LRESULT
ShellView_OnKillFocus(IShellViewImpl
* This
)
1245 TRACE("(%p) stub\n",This
);
1247 ShellView_OnActivate(This
, SVUIA_ACTIVATE_NOFOCUS
);
1248 /* Notify the ICommDlgBrowser */
1249 OnStateChange(This
,CDBOSC_KILLFOCUS
);
1254 /**********************************************************
1255 * ShellView_OnCommand()
1258 * the CmdID's are the ones from the context menu
1260 static LRESULT
ShellView_OnCommand(IShellViewImpl
* This
,DWORD dwCmdID
, DWORD dwCmd
, HWND hwndCmd
)
1262 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n",This
, dwCmdID
, dwCmd
, hwndCmd
);
1266 case FCIDM_SHVIEW_SMALLICON
:
1267 This
->FolderSettings
.ViewMode
= FVM_SMALLICON
;
1268 SetStyle (This
, LVS_SMALLICON
, LVS_TYPEMASK
);
1272 case FCIDM_SHVIEW_BIGICON
:
1273 This
->FolderSettings
.ViewMode
= FVM_ICON
;
1274 SetStyle (This
, LVS_ICON
, LVS_TYPEMASK
);
1278 case FCIDM_SHVIEW_LISTVIEW
:
1279 This
->FolderSettings
.ViewMode
= FVM_LIST
;
1280 SetStyle (This
, LVS_LIST
, LVS_TYPEMASK
);
1284 case FCIDM_SHVIEW_REPORTVIEW
:
1285 This
->FolderSettings
.ViewMode
= FVM_DETAILS
;
1286 SetStyle (This
, LVS_REPORT
, LVS_TYPEMASK
);
1290 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1295 This
->ListViewSortInfo
.nHeaderID
= (LPARAM
) (dwCmdID
- 0x30);
1296 This
->ListViewSortInfo
.bIsAscending
= TRUE
;
1297 This
->ListViewSortInfo
.nLastHeaderID
= This
->ListViewSortInfo
.nHeaderID
;
1298 SendMessageA(This
->hWndList
, LVM_SORTITEMS
, (WPARAM
) &This
->ListViewSortInfo
, (LPARAM
)ShellView_ListViewCompareItems
);
1302 TRACE("-- COMMAND 0x%04x unhandled\n", dwCmdID
);
1307 /**********************************************************
1308 * ShellView_OnNotify()
1311 static LRESULT
ShellView_OnNotify(IShellViewImpl
* This
, UINT CtlID
, LPNMHDR lpnmh
)
1312 { LPNMLISTVIEW lpnmlv
= (LPNMLISTVIEW
)lpnmh
;
1313 NMLVDISPINFOW
*lpdi
= (NMLVDISPINFOW
*)lpnmh
;
1316 TRACE("%p CtlID=%u lpnmh->code=%x\n",This
,CtlID
,lpnmh
->code
);
1321 TRACE("-- NM_SETFOCUS %p\n",This
);
1322 ShellView_OnSetFocus(This
);
1326 TRACE("-- NM_KILLFOCUS %p\n",This
);
1327 ShellView_OnDeactivate(This
);
1328 /* Notify the ICommDlgBrowser interface */
1329 OnStateChange(This
,CDBOSC_KILLFOCUS
);
1333 TRACE("-- NM_CUSTOMDRAW %p\n",This
);
1334 return CDRF_DODEFAULT
;
1336 case NM_RELEASEDCAPTURE
:
1337 TRACE("-- NM_RELEASEDCAPTURE %p\n",This
);
1341 TRACE("-- NM_CLICK %p\n",This
);
1345 TRACE("-- NM_RCLICK %p\n",This
);
1349 TRACE("-- NM_DBLCLK %p\n",This
);
1350 if (OnDefaultCommand(This
) != S_OK
) ShellView_OpenSelectedItems(This
);
1354 TRACE("-- NM_RETURN %p\n",This
);
1355 if (OnDefaultCommand(This
) != S_OK
) ShellView_OpenSelectedItems(This
);
1359 TRACE("-- HDN_ENDTRACKW %p\n",This
);
1360 /*nColumn1 = ListView_GetColumnWidth(This->hWndList, 0);
1361 nColumn2 = ListView_GetColumnWidth(This->hWndList, 1);*/
1364 case LVN_DELETEITEM
:
1365 TRACE("-- LVN_DELETEITEM %p\n",This
);
1366 SHFree((LPITEMIDLIST
)lpnmlv
->lParam
); /*delete the pidl because we made a copy of it*/
1369 case LVN_DELETEALLITEMS
:
1370 TRACE("-- LVN_DELETEALLITEMS %p\n",This
);
1373 case LVN_INSERTITEM
:
1374 TRACE("-- LVN_INSERTITEM (STUB)%p\n",This
);
1377 case LVN_ITEMACTIVATE
:
1378 TRACE("-- LVN_ITEMACTIVATE %p\n",This
);
1379 OnStateChange(This
, CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1382 case LVN_COLUMNCLICK
:
1383 This
->ListViewSortInfo
.nHeaderID
= lpnmlv
->iSubItem
;
1384 if(This
->ListViewSortInfo
.nLastHeaderID
== This
->ListViewSortInfo
.nHeaderID
)
1386 This
->ListViewSortInfo
.bIsAscending
= !This
->ListViewSortInfo
.bIsAscending
;
1390 This
->ListViewSortInfo
.bIsAscending
= TRUE
;
1392 This
->ListViewSortInfo
.nLastHeaderID
= This
->ListViewSortInfo
.nHeaderID
;
1394 SendMessageW(lpnmlv
->hdr
.hwndFrom
, LVM_SORTITEMS
, (WPARAM
) &This
->ListViewSortInfo
, (LPARAM
)ShellView_ListViewCompareItems
);
1397 case LVN_GETDISPINFOA
:
1398 case LVN_GETDISPINFOW
:
1399 TRACE("-- LVN_GETDISPINFO %p\n",This
);
1400 pidl
= (LPITEMIDLIST
)lpdi
->item
.lParam
;
1402 if(lpdi
->item
.mask
& LVIF_TEXT
) /* text requested */
1404 if (This
->pSF2Parent
)
1407 IShellFolder2_GetDetailsOf(This
->pSF2Parent
, pidl
, lpdi
->item
.iSubItem
, &sd
);
1408 if (lpnmh
->code
== LVN_GETDISPINFOA
)
1410 /* shouldn't happen */
1411 NMLVDISPINFOA
*lpdiA
= (NMLVDISPINFOA
*)lpnmh
;
1412 StrRetToStrNA( lpdiA
->item
.pszText
, lpdiA
->item
.cchTextMax
, &sd
.str
, NULL
);
1413 TRACE("-- text=%s\n",lpdiA
->item
.pszText
);
1415 else /* LVN_GETDISPINFOW */
1417 StrRetToStrNW( lpdi
->item
.pszText
, lpdi
->item
.cchTextMax
, &sd
.str
, NULL
);
1418 TRACE("-- text=%s\n",debugstr_w(lpdi
->item
.pszText
));
1426 if(lpdi
->item
.mask
& LVIF_IMAGE
) /* image requested */
1428 lpdi
->item
.iImage
= SHMapPIDLToSystemImageListIndex(This
->pSFParent
, pidl
, 0);
1432 case LVN_ITEMCHANGED
:
1433 TRACE("-- LVN_ITEMCHANGED %p\n",This
);
1434 OnStateChange(This
, CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1438 case LVN_BEGINRDRAG
:
1439 TRACE("-- LVN_BEGINDRAG\n");
1441 if (ShellView_GetSelections(This
))
1444 DWORD dwAttributes
= SFGAO_CANLINK
;
1445 DWORD dwEffect
= DROPEFFECT_COPY
| DROPEFFECT_MOVE
;
1447 if (SUCCEEDED(IShellFolder_GetUIObjectOf(This
->pSFParent
, This
->hWnd
, This
->cidl
, (LPCITEMIDLIST
*)This
->apidl
, &IID_IDataObject
,0,(LPVOID
*)&pda
)))
1449 IDropSource
* pds
= (IDropSource
*)&(This
->lpvtblDropSource
); /* own DropSource interface */
1451 if (SUCCEEDED(IShellFolder_GetAttributesOf(This
->pSFParent
, This
->cidl
, (LPCITEMIDLIST
*)This
->apidl
, &dwAttributes
)))
1453 if (dwAttributes
& SFGAO_CANLINK
)
1455 dwEffect
|= DROPEFFECT_LINK
;
1462 DoDragDrop(pda
, pds
, dwEffect
, &dwEffect2
);
1464 IDataObject_Release(pda
);
1469 case LVN_BEGINLABELEDITW
:
1471 DWORD dwAttr
= SFGAO_CANRENAME
;
1472 pidl
= (LPITEMIDLIST
)lpdi
->item
.lParam
;
1474 TRACE("-- LVN_BEGINLABELEDITW %p\n",This
);
1476 IShellFolder_GetAttributesOf(This
->pSFParent
, 1, (LPCITEMIDLIST
*)&pidl
, &dwAttr
);
1477 if (SFGAO_CANRENAME
& dwAttr
)
1484 case LVN_ENDLABELEDITW
:
1486 TRACE("-- LVN_ENDLABELEDITW %p\n",This
);
1487 if (lpdi
->item
.pszText
)
1492 lvItem
.iItem
= lpdi
->item
.iItem
;
1493 lvItem
.iSubItem
= 0;
1494 lvItem
.mask
= LVIF_PARAM
;
1495 SendMessageW(This
->hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
1497 pidl
= (LPITEMIDLIST
)lpdi
->item
.lParam
;
1498 hr
= IShellFolder_SetNameOf(This
->pSFParent
, 0, pidl
, lpdi
->item
.pszText
, SHGDN_INFOLDER
, &pidl
);
1500 if(SUCCEEDED(hr
) && pidl
)
1502 lvItem
.mask
= LVIF_PARAM
;
1503 lvItem
.lParam
= (LPARAM
)pidl
;
1504 SendMessageW(This
->hWndList
, LVM_SETITEMW
, 0, (LPARAM
) &lvItem
);
1514 msg.hwnd = This->hWnd;
1515 msg.message = WM_KEYDOWN;
1516 msg.wParam = plvKeyDown->wVKey;
1521 LPNMLVKEYDOWN plvKeyDown
= (LPNMLVKEYDOWN
) lpnmh
;
1522 SHORT ctrl
= GetKeyState(VK_CONTROL
) & 0x8000;
1524 /* initiate a rename of the selected file or directory */
1525 if(plvKeyDown
->wVKey
== VK_F2
)
1527 /* see how many files are selected */
1528 int i
= ListView_GetSelectedCount(This
->hWndList
);
1530 /* get selected item */
1533 /* get selected item */
1534 i
= ListView_GetNextItem(This
->hWndList
, -1,
1537 SendMessageW(This
->hWndList
, LVM_ENSUREVISIBLE
, i
, 0);
1538 SendMessageW(This
->hWndList
, LVM_EDITLABELW
, i
, 0);
1542 TranslateAccelerator(This
->hWnd
, This
->hAccel
, &msg
)
1544 else if(plvKeyDown
->wVKey
== VK_DELETE
)
1549 LPITEMIDLIST
* pItems
;
1552 IShellFolder_QueryInterface(This
->pSFParent
, &IID_ISFHelper
,
1558 if(!(i
= ListView_GetSelectedCount(This
->hWndList
)))
1561 /* allocate memory for the pidl array */
1562 pItems
= HeapAlloc(GetProcessHeap(), 0,
1563 sizeof(LPITEMIDLIST
) * i
);
1565 /* retrieve all selected items */
1568 while(ListView_GetSelectedCount(This
->hWndList
) > i
)
1570 /* get selected item */
1571 item_index
= ListView_GetNextItem(This
->hWndList
,
1572 item_index
, LVNI_SELECTED
);
1573 item
.iItem
= item_index
;
1574 item
.mask
= LVIF_PARAM
;
1575 SendMessageA(This
->hWndList
, LVM_GETITEMA
, 0, (LPARAM
) &item
);
1578 pItems
[i
] = (LPITEMIDLIST
)item
.lParam
;
1583 /* perform the item deletion */
1584 ISFHelper_DeleteItems(psfhlp
, i
, (LPCITEMIDLIST
*)pItems
);
1586 /* free pidl array memory */
1587 HeapFree(GetProcessHeap(), 0, pItems
);
1590 /* Initiate a refresh */
1591 else if(plvKeyDown
->wVKey
== VK_F5
)
1593 IShellView_Refresh((IShellView
*)This
);
1595 else if(plvKeyDown
->wVKey
== VK_BACK
)
1597 LPSHELLBROWSER lpSb
;
1598 if((lpSb
= (LPSHELLBROWSER
)SendMessageW(This
->hWndParent
, CWM_GETISHELLBROWSER
, 0, 0)))
1600 IShellBrowser_BrowseObject(lpSb
, NULL
, SBSP_PARENT
);
1603 else if(plvKeyDown
->wVKey
== 'C' && ctrl
)
1605 if (ShellView_GetSelections(This
))
1609 if (SUCCEEDED(IShellFolder_GetUIObjectOf(This
->pSFParent
, This
->hWnd
, This
->cidl
, (LPCITEMIDLIST
*)This
->apidl
, &IID_IDataObject
,0,(LPVOID
*)&pda
)))
1611 HRESULT hr
= OleSetClipboard(pda
);
1614 WARN("OleSetClipboard failed");
1616 IDataObject_Release(pda
);
1621 else if(plvKeyDown
->wVKey
== 'V' && ctrl
)
1625 FORMATETC formatetc
;
1626 LPITEMIDLIST
* apidl
;
1628 IShellFolder
*psfFrom
= NULL
, *psfDesktop
, *psfTarget
= NULL
;
1630 ISFHelper
*psfhlpdst
, *psfhlpsrc
;
1633 hr
= OleGetClipboard(&pda
);
1636 ERR("Failed to get clipboard with %lx\n", hr
);
1640 InitFormatEtc(formatetc
, RegisterClipboardFormatW(CFSTR_SHELLIDLIST
), TYMED_HGLOBAL
);
1641 hr
= IDataObject_GetData(pda
,&formatetc
,&medium
);
1645 ERR("Failed to get clipboard data with %lx\n", hr
);
1646 IDataObject_Release(pda
);
1650 /* lock the handle */
1651 lpcida
= GlobalLock(medium
.u
.hGlobal
);
1654 ERR("failed to lock pidl\n");
1655 ReleaseStgMedium(&medium
);
1656 IDataObject_Release(pda
);
1660 /* convert the data into pidl */
1661 apidl
= _ILCopyCidaToaPidl(&pidl
, lpcida
);
1665 ERR("failed to copy pidl\n");
1669 if (FAILED(SHGetDesktopFolder(&psfDesktop
)))
1671 ERR("failed to get desktop folder\n");
1673 _ILFreeaPidl(apidl
, lpcida
->cidl
);
1674 ReleaseStgMedium(&medium
);
1675 IDataObject_Release(pda
);
1679 if (_ILIsDesktop(pidl
))
1681 /* use desktop shellfolder */
1682 psfFrom
= psfDesktop
;
1684 else if (FAILED(IShellFolder_BindToObject(psfDesktop
, pidl
, NULL
, &IID_IShellFolder
, (LPVOID
*)&psfFrom
)))
1686 ERR("no IShellFolder\n");
1688 IShellFolder_Release(psfDesktop
);
1690 _ILFreeaPidl(apidl
, lpcida
->cidl
);
1691 ReleaseStgMedium(&medium
);
1692 IDataObject_Release(pda
);
1697 psfTarget
= This
->pSFParent
;
1700 /* get source and destination shellfolder */
1701 if (FAILED(IShellFolder_QueryInterface(psfTarget
, &IID_ISFHelper
, (LPVOID
*)&psfhlpdst
)))
1703 ERR("no IID_ISFHelper for destination\n");
1705 IShellFolder_Release(psfFrom
);
1706 IShellFolder_Release(psfTarget
);
1708 _ILFreeaPidl(apidl
, lpcida
->cidl
);
1709 ReleaseStgMedium(&medium
);
1710 IDataObject_Release(pda
);
1715 if (FAILED(IShellFolder_QueryInterface(psfFrom
, &IID_ISFHelper
, (LPVOID
*)&psfhlpsrc
)))
1717 ERR("no IID_ISFHelper for source\n");
1719 ISFHelper_Release(psfhlpdst
);
1720 IShellFolder_Release(psfFrom
);
1721 IShellFolder_Release(psfTarget
);
1723 _ILFreeaPidl(apidl
, lpcida
->cidl
);
1724 ReleaseStgMedium(&medium
);
1725 IDataObject_Release(pda
);
1730 * do we want to perform a copy or move ???
1732 hr
= ISFHelper_CopyItems(psfhlpdst
, psfFrom
, lpcida
->cidl
, (LPCITEMIDLIST
*)apidl
);
1734 ISFHelper_Release(psfhlpdst
);
1735 ISFHelper_Release(psfhlpsrc
);
1736 IShellFolder_Release(psfFrom
);
1738 _ILFreeaPidl(apidl
, lpcida
->cidl
);
1739 ReleaseStgMedium(&medium
);
1740 IDataObject_Release(pda
);
1741 TRACE("paste end hr %x\n", hr
);
1745 FIXME("LVN_KEYDOWN key=0x%08x\n",plvKeyDown
->wVKey
);
1750 TRACE("-- %p WM_COMMAND %x unhandled\n", This
, lpnmh
->code
);
1756 /**********************************************************
1757 * ShellView_OnChange()
1760 static LRESULT
ShellView_OnChange(IShellViewImpl
* This
, LPITEMIDLIST
* Pidls
, LONG wEventId
)
1763 TRACE("(%p)(%p,%p,0x%08x)\n", This
, Pidls
[0], Pidls
[1], wEventId
);
1768 LV_AddItem(This
, Pidls
[0]);
1772 LV_DeleteItem(This
, Pidls
[0]);
1774 case SHCNE_RENAMEFOLDER
:
1775 case SHCNE_RENAMEITEM
:
1776 LV_RenameItem(This
, Pidls
[0], Pidls
[1]);
1778 case SHCNE_UPDATEITEM
:
1784 /**********************************************************
1785 * ShellView_DoMeasureItem
1788 static LRESULT
ShellView_DoCustomItem(IShellViewImpl
* pThis
, HWND hWnd
, UINT uMsg
, LPARAM lParam
)
1793 ERR("no menu!!!\n");
1797 if (pThis
->pCM
->lpVtbl
->HandleMenuMsg(pThis
->pCM
, uMsg
, (WPARAM
)hWnd
, lParam
) == S_OK
)
1803 /**********************************************************
1807 static LRESULT CALLBACK
ShellView_WndProc(HWND hWnd
, UINT uMessage
, WPARAM wParam
, LPARAM lParam
)
1809 IShellViewImpl
* pThis
= (IShellViewImpl
*)GetWindowLongPtrW(hWnd
, GWLP_USERDATA
);
1810 LPCREATESTRUCTW lpcs
;
1812 TRACE("(hwnd=%p msg=%x wparm=%lx lparm=%lx)\n",hWnd
, uMessage
, wParam
, lParam
);
1817 lpcs
= (LPCREATESTRUCTW
)lParam
;
1818 pThis
= (IShellViewImpl
*)(lpcs
->lpCreateParams
);
1819 SetWindowLongPtrW(hWnd
, GWLP_USERDATA
, (ULONG_PTR
)pThis
);
1820 pThis
->hWnd
= hWnd
; /*set the window handle*/
1823 case WM_SIZE
: return ShellView_OnSize(pThis
,LOWORD(lParam
), HIWORD(lParam
));
1824 case WM_SETFOCUS
: return ShellView_OnSetFocus(pThis
);
1825 case WM_KILLFOCUS
: return ShellView_OnKillFocus(pThis
);
1826 case WM_CREATE
: return ShellView_OnCreate(pThis
);
1827 case WM_ACTIVATE
: return ShellView_OnActivate(pThis
, SVUIA_ACTIVATE_FOCUS
);
1828 case WM_NOTIFY
: return ShellView_OnNotify(pThis
,(UINT
)wParam
, (LPNMHDR
)lParam
);
1829 case WM_COMMAND
: return ShellView_OnCommand(pThis
,
1830 GET_WM_COMMAND_ID(wParam
, lParam
),
1831 GET_WM_COMMAND_CMD(wParam
, lParam
),
1832 GET_WM_COMMAND_HWND(wParam
, lParam
));
1833 case SHV_CHANGE_NOTIFY
: return ShellView_OnChange(pThis
, (LPITEMIDLIST
*)wParam
, (LONG
)lParam
);
1835 case WM_CONTEXTMENU
: ShellView_DoContextMenu(pThis
, LOWORD(lParam
), HIWORD(lParam
), FALSE
);
1838 case WM_MEASUREITEM
:
1839 return ShellView_DoCustomItem(pThis
, hWnd
, uMessage
, lParam
);
1841 case WM_SHOWWINDOW
: UpdateWindow(pThis
->hWndList
);
1844 case WM_GETDLGCODE
: return SendMessageW(pThis
->hWndList
,uMessage
,0,0);
1847 RevokeDragDrop(pThis
->hWnd
);
1848 SHChangeNotifyDeregister(pThis
->hNotify
);
1852 if ((pThis
->FolderSettings
.fFlags
& FWF_DESKTOP
) ||
1853 (pThis
->FolderSettings
.fFlags
& FWF_TRANSPARENT
))
1854 return SendMessageW(pThis
->hWndParent
, WM_ERASEBKGND
, wParam
, lParam
); /* redirect to parent */
1857 case WM_SYSCOLORCHANGE
:
1858 /* Forward WM_SYSCOLORCHANGE to common controls */
1859 SendMessage(pThis
->hWndList
, WM_SYSCOLORCHANGE
, 0, 0);
1862 case CWM_GETISHELLBROWSER
:
1863 return (LRESULT
)pThis
->pShellBrowser
;
1865 return DefWindowProcW(hWnd
, uMessage
, wParam
, lParam
);
1867 /**********************************************************
1870 * The INTERFACE of the IShellView object
1873 **********************************************************
1874 * IShellView_QueryInterface
1876 static HRESULT WINAPI
IShellView_fnQueryInterface(IShellView
* iface
,REFIID riid
, LPVOID
*ppvObj
)
1878 IShellViewImpl
*This
= (IShellViewImpl
*)iface
;
1880 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This
,debugstr_guid(riid
),ppvObj
);
1884 if(IsEqualIID(riid
, &IID_IUnknown
))
1888 else if(IsEqualIID(riid
, &IID_IShellView
))
1890 *ppvObj
= (IShellView
*)This
;
1892 else if(IsEqualIID(riid
, &IID_IOleCommandTarget
))
1894 *ppvObj
= (IOleCommandTarget
*)&(This
->lpvtblOleCommandTarget
);
1896 else if(IsEqualIID(riid
, &IID_IDropTarget
))
1898 *ppvObj
= (IDropTarget
*)&(This
->lpvtblDropTarget
);
1900 else if(IsEqualIID(riid
, &IID_IDropSource
))
1902 *ppvObj
= (IDropSource
*)&(This
->lpvtblDropSource
);
1904 else if(IsEqualIID(riid
, &IID_IViewObject
))
1906 *ppvObj
= (IViewObject
*)&(This
->lpvtblViewObject
);
1911 IUnknown_AddRef( (IUnknown
*)*ppvObj
);
1912 TRACE("-- Interface: (%p)->(%p)\n",ppvObj
,*ppvObj
);
1915 TRACE("-- Interface: E_NOINTERFACE\n");
1916 return E_NOINTERFACE
;
1919 /**********************************************************
1922 static ULONG WINAPI
IShellView_fnAddRef(IShellView
* iface
)
1924 IShellViewImpl
*This
= (IShellViewImpl
*)iface
;
1925 ULONG refCount
= InterlockedIncrement(&This
->ref
);
1927 TRACE("(%p)->(count=%u)\n", This
, refCount
- 1);
1931 /**********************************************************
1932 * IShellView_Release
1934 static ULONG WINAPI
IShellView_fnRelease(IShellView
* iface
)
1936 IShellViewImpl
*This
= (IShellViewImpl
*)iface
;
1937 ULONG refCount
= InterlockedDecrement(&This
->ref
);
1939 TRACE("(%p)->(count=%i)\n", This
, refCount
+ 1);
1943 TRACE(" destroying IShellView(%p)\n",This
);
1945 DestroyWindow(This
->hWndList
);
1948 IShellFolder_Release(This
->pSFParent
);
1950 if(This
->pSF2Parent
)
1951 IShellFolder2_Release(This
->pSF2Parent
);
1953 SHFree(This
->apidl
);
1956 IAdviseSink_Release(This
->pAdvSink
);
1959 IContextMenu_Release(This
->pCM
);
1961 HeapFree(GetProcessHeap(),0,This
);
1966 /**********************************************************
1967 * ShellView_GetWindow
1969 static HRESULT WINAPI
IShellView_fnGetWindow(IShellView
* iface
,HWND
* phWnd
)
1971 IShellViewImpl
*This
= (IShellViewImpl
*)iface
;
1973 TRACE("(%p)\n",This
);
1975 *phWnd
= This
->hWnd
;
1980 static HRESULT WINAPI
IShellView_fnContextSensitiveHelp(IShellView
* iface
,BOOL fEnterMode
)
1982 IShellViewImpl
*This
= (IShellViewImpl
*)iface
;
1984 FIXME("(%p) stub\n",This
);
1989 /**********************************************************
1990 * IShellView_TranslateAccelerator
1993 * use the accel functions
1995 static HRESULT WINAPI
IShellView_fnTranslateAccelerator(IShellView
* iface
,LPMSG lpmsg
)
1998 IShellViewImpl
*This
= (IShellViewImpl
*)iface
;
2000 FIXME("(%p)->(%p: hwnd=%x msg=%x lp=%x wp=%x) stub\n",This
,lpmsg
, lpmsg
->hwnd
, lpmsg
->message
, lpmsg
->lParam
, lpmsg
->wParam
);
2003 if ((lpmsg
->message
>=WM_KEYFIRST
) && (lpmsg
->message
>=WM_KEYLAST
))
2005 TRACE("-- key=0x04%lx\n",lpmsg
->wParam
) ;
2007 return S_FALSE
; /* not handled */
2010 static HRESULT WINAPI
IShellView_fnEnableModeless(IShellView
* iface
,BOOL fEnable
)
2012 IShellViewImpl
*This
= (IShellViewImpl
*)iface
;
2014 FIXME("(%p) stub\n",This
);
2019 static HRESULT WINAPI
IShellView_fnUIActivate(IShellView
* iface
,UINT uState
)
2021 IShellViewImpl
*This
= (IShellViewImpl
*)iface
;
2024 CHAR szName[MAX_PATH];
2027 int nPartArray
[1] = {-1};
2029 TRACE("(%p)->(state=%x) stub\n",This
, uState
);
2031 /*don't do anything if the state isn't really changing*/
2032 if(This
->uState
== uState
)
2037 /*OnActivate handles the menu merging and internal state*/
2038 ShellView_OnActivate(This
, uState
);
2040 /*only do This if we are active*/
2041 if(uState
!= SVUIA_DEACTIVATE
)
2045 GetFolderPath is not a method of IShellFolder
2046 IShellFolder_GetFolderPath( This->pSFParent, szName, sizeof(szName) );
2048 /* set the number of parts */
2049 IShellBrowser_SendControlMsg(This
->pShellBrowser
, FCW_STATUS
, SB_SETPARTS
, 1,
2050 (LPARAM
)nPartArray
, &lResult
);
2052 /* set the text for the parts */
2054 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETTEXTA,
2055 0, (LPARAM)szName, &lResult);
2062 static HRESULT WINAPI
IShellView_fnRefresh(IShellView
* iface
)
2064 IShellViewImpl
*This
= (IShellViewImpl
*)iface
;
2066 TRACE("(%p)\n",This
);
2068 SendMessageW(This
->hWndList
, LVM_DELETEALLITEMS
, 0, 0);
2069 ShellView_FillList(This
);
2074 static HRESULT WINAPI
IShellView_fnCreateViewWindow(
2076 IShellView
*lpPrevView
,
2077 LPCFOLDERSETTINGS lpfs
,
2078 IShellBrowser
* psb
,
2082 IShellViewImpl
*This
= (IShellViewImpl
*)iface
;
2088 TRACE("(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n",This
, lpPrevView
,lpfs
, psb
, prcView
, phWnd
);
2090 TRACE("-- vmode=%x flags=%x\n", lpfs
->ViewMode
, lpfs
->fFlags
);
2091 if (prcView
!= NULL
)
2092 TRACE("-- left=%i top=%i right=%i bottom=%i\n", prcView
->left
, prcView
->top
, prcView
->right
, prcView
->bottom
);
2094 /* Validate the Shell Browser */
2096 return E_UNEXPECTED
;
2098 /*set up the member variables*/
2099 This
->pShellBrowser
= psb
;
2100 This
->FolderSettings
= *lpfs
;
2102 /*get our parent window*/
2103 IShellBrowser_AddRef(This
->pShellBrowser
);
2104 IShellBrowser_GetWindow(This
->pShellBrowser
, &(This
->hWndParent
));
2106 /* try to get the ICommDlgBrowserInterface, adds a reference !!! */
2107 This
->pCommDlgBrowser
=NULL
;
2108 if ( SUCCEEDED (IShellBrowser_QueryInterface( This
->pShellBrowser
,
2109 (REFIID
)&IID_ICommDlgBrowser
, (LPVOID
*) &This
->pCommDlgBrowser
)))
2111 TRACE("-- CommDlgBrowser\n");
2114 /*if our window class has not been registered, then do so*/
2115 if(!GetClassInfoW(shell32_hInstance
, SV_CLASS_NAME
, &wc
))
2117 ZeroMemory(&wc
, sizeof(wc
));
2118 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
2119 wc
.lpfnWndProc
= ShellView_WndProc
;
2122 wc
.hInstance
= shell32_hInstance
;
2124 wc
.hCursor
= LoadCursorW(0, (LPWSTR
)IDC_ARROW
);
2125 wc
.hbrBackground
= (HBRUSH
) (COLOR_BACKGROUND
+1);
2126 wc
.lpszMenuName
= NULL
;
2127 wc
.lpszClassName
= SV_CLASS_NAME
;
2129 if(!RegisterClassW(&wc
))
2133 *phWnd
= CreateWindowExW(0,
2136 WS_CHILD
| WS_TABSTOP
,
2139 prcView
->right
- prcView
->left
,
2140 prcView
->bottom
- prcView
->top
,
2148 if(!*phWnd
) return E_FAIL
;
2150 SetWindowPos(*phWnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_SHOWWINDOW
);
2151 UpdateWindow(*phWnd
);
2156 static HRESULT WINAPI
IShellView_fnDestroyViewWindow(IShellView
* iface
)
2158 IShellViewImpl
*This
= (IShellViewImpl
*)iface
;
2160 TRACE("(%p)\n",This
);
2162 /*Make absolutely sure all our UI is cleaned up.*/
2163 IShellView_UIActivate((IShellView
*)This
, SVUIA_DEACTIVATE
);
2167 DestroyMenu(This
->hMenu
);
2170 DestroyWindow(This
->hWnd
);
2171 if(This
->pShellBrowser
) IShellBrowser_Release(This
->pShellBrowser
);
2172 if(This
->pCommDlgBrowser
) ICommDlgBrowser_Release(This
->pCommDlgBrowser
);
2178 static HRESULT WINAPI
IShellView_fnGetCurrentInfo(IShellView
* iface
, LPFOLDERSETTINGS lpfs
)
2180 IShellViewImpl
*This
= (IShellViewImpl
*)iface
;
2182 TRACE("(%p)->(%p) vmode=%x flags=%x\n",This
, lpfs
,
2183 This
->FolderSettings
.ViewMode
, This
->FolderSettings
.fFlags
);
2185 if (!lpfs
) return E_INVALIDARG
;
2187 *lpfs
= This
->FolderSettings
;
2191 static HRESULT WINAPI
IShellView_fnAddPropertySheetPages(IShellView
* iface
, DWORD dwReserved
,LPFNADDPROPSHEETPAGE lpfn
, LPARAM lparam
)
2193 IShellViewImpl
*This
= (IShellViewImpl
*)iface
;
2195 FIXME("(%p) stub\n",This
);
2200 static HRESULT WINAPI
IShellView_fnSaveViewState(IShellView
* iface
)
2202 IShellViewImpl
*This
= (IShellViewImpl
*)iface
;
2204 FIXME("(%p) stub\n",This
);
2209 static HRESULT WINAPI
IShellView_fnSelectItem(
2214 IShellViewImpl
*This
= (IShellViewImpl
*)iface
;
2217 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n",This
, pidl
, uFlags
);
2219 i
= LV_FindItemByPidl(This
, pidl
);
2225 if(uFlags
& SVSI_ENSUREVISIBLE
)
2226 SendMessageW(This
->hWndList
, LVM_ENSUREVISIBLE
, i
, 0);
2228 lvItem
.mask
= LVIF_STATE
;
2229 lvItem
.stateMask
= LVIS_SELECTED
| LVIS_FOCUSED
;
2231 lvItem
.iSubItem
= 0;
2233 while(SendMessageW(This
->hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
))
2235 if (lvItem
.iItem
== i
)
2237 if (uFlags
& SVSI_SELECT
)
2238 lvItem
.state
|= LVIS_SELECTED
;
2240 lvItem
.state
&= ~LVIS_SELECTED
;
2242 if(uFlags
& SVSI_FOCUSED
)
2243 lvItem
.state
&= ~LVIS_FOCUSED
;
2247 if (uFlags
& SVSI_DESELECTOTHERS
)
2248 lvItem
.state
&= ~LVIS_SELECTED
;
2250 SendMessageW(This
->hWndList
, LVM_SETITEMW
, 0, (LPARAM
) &lvItem
);
2255 if(uFlags
& SVSI_EDIT
)
2256 SendMessageW(This
->hWndList
, LVM_EDITLABELW
, i
, 0);
2262 static HRESULT WINAPI
IShellView_fnGetItemObject(IShellView
* iface
, UINT uItem
, REFIID riid
, LPVOID
*ppvOut
)
2264 HRESULT hr
= E_FAIL
;
2265 IShellViewImpl
*This
= (IShellViewImpl
*)iface
;
2267 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n",This
, uItem
, debugstr_guid(riid
), ppvOut
);
2273 case SVGIO_BACKGROUND
:
2274 //*ppvOut = ISvBgCm_Constructor(This->pSFParent, FALSE);
2275 CDefFolderMenu_Create2(NULL
, NULL
, This
->cidl
, (LPCITEMIDLIST
*)This
->apidl
, This
->pSFParent
, NULL
, 0, NULL
, (IContextMenu
**)ppvOut
);
2276 if (!ppvOut
) hr
= E_OUTOFMEMORY
;
2279 case SVGIO_SELECTION
:
2280 ShellView_GetSelections(This
);
2281 hr
= IShellFolder_GetUIObjectOf(This
->pSFParent
, This
->hWnd
, This
->cidl
, (LPCITEMIDLIST
*)This
->apidl
, riid
, 0, ppvOut
);
2284 TRACE("-- (%p)->(interface=%p)\n",This
, *ppvOut
);
2289 static const IShellViewVtbl svvt
=
2291 IShellView_fnQueryInterface
,
2292 IShellView_fnAddRef
,
2293 IShellView_fnRelease
,
2294 IShellView_fnGetWindow
,
2295 IShellView_fnContextSensitiveHelp
,
2296 IShellView_fnTranslateAccelerator
,
2297 IShellView_fnEnableModeless
,
2298 IShellView_fnUIActivate
,
2299 IShellView_fnRefresh
,
2300 IShellView_fnCreateViewWindow
,
2301 IShellView_fnDestroyViewWindow
,
2302 IShellView_fnGetCurrentInfo
,
2303 IShellView_fnAddPropertySheetPages
,
2304 IShellView_fnSaveViewState
,
2305 IShellView_fnSelectItem
,
2306 IShellView_fnGetItemObject
2310 /**********************************************************
2311 * ISVOleCmdTarget_QueryInterface (IUnknown)
2313 static HRESULT WINAPI
ISVOleCmdTarget_QueryInterface(
2314 IOleCommandTarget
* iface
,
2318 IShellViewImpl
*This
= impl_from_IOleCommandTarget(iface
);
2320 return IShellFolder_QueryInterface((IShellFolder
*)This
, iid
, ppvObj
);
2323 /**********************************************************
2324 * ISVOleCmdTarget_AddRef (IUnknown)
2326 static ULONG WINAPI
ISVOleCmdTarget_AddRef(
2327 IOleCommandTarget
* iface
)
2329 IShellViewImpl
*This
= impl_from_IOleCommandTarget(iface
);
2331 return IShellFolder_AddRef((IShellFolder
*)This
);
2334 /**********************************************************
2335 * ISVOleCmdTarget_Release (IUnknown)
2337 static ULONG WINAPI
ISVOleCmdTarget_Release(
2338 IOleCommandTarget
* iface
)
2340 IShellViewImpl
*This
= impl_from_IOleCommandTarget(iface
);
2342 return IShellFolder_Release((IShellFolder
*)This
);
2345 /**********************************************************
2346 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2348 static HRESULT WINAPI
ISVOleCmdTarget_QueryStatus(
2349 IOleCommandTarget
*iface
,
2350 const GUID
* pguidCmdGroup
,
2353 OLECMDTEXT
* pCmdText
)
2356 IShellViewImpl
*This
= impl_from_IOleCommandTarget(iface
);
2358 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
2359 This
, pguidCmdGroup
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
2363 for (i
= 0; i
< cCmds
; i
++)
2365 FIXME("\tprgCmds[%d].cmdID = %d\n", i
, prgCmds
[i
].cmdID
);
2366 prgCmds
[i
].cmdf
= 0;
2368 return OLECMDERR_E_UNKNOWNGROUP
;
2371 /**********************************************************
2372 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2374 * nCmdID is the OLECMDID_* enumeration
2376 static HRESULT WINAPI
ISVOleCmdTarget_Exec(
2377 IOleCommandTarget
*iface
,
2378 const GUID
* pguidCmdGroup
,
2384 IShellViewImpl
*This
= impl_from_IOleCommandTarget(iface
);
2386 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2387 This
, debugstr_guid(pguidCmdGroup
), nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2389 if (IsEqualIID(pguidCmdGroup
, &CGID_Explorer
) &&
2391 (nCmdexecopt
== 4) && pvaOut
)
2393 if (IsEqualIID(pguidCmdGroup
, &CGID_ShellDocView
) &&
2398 return OLECMDERR_E_UNKNOWNGROUP
;
2401 static const IOleCommandTargetVtbl ctvt
=
2403 ISVOleCmdTarget_QueryInterface
,
2404 ISVOleCmdTarget_AddRef
,
2405 ISVOleCmdTarget_Release
,
2406 ISVOleCmdTarget_QueryStatus
,
2407 ISVOleCmdTarget_Exec
2410 /**********************************************************
2411 * ISVDropTarget implementation
2414 static HRESULT WINAPI
ISVDropTarget_QueryInterface(
2419 IShellViewImpl
*This
= impl_from_IDropTarget(iface
);
2421 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This
,debugstr_guid(riid
),ppvObj
);
2423 return IShellFolder_QueryInterface((IShellFolder
*)This
, riid
, ppvObj
);
2426 static ULONG WINAPI
ISVDropTarget_AddRef( IDropTarget
*iface
)
2428 IShellViewImpl
*This
= impl_from_IDropTarget(iface
);
2430 TRACE("(%p)->(count=%u)\n",This
,This
->ref
);
2432 return IShellFolder_AddRef((IShellFolder
*)This
);
2435 static ULONG WINAPI
ISVDropTarget_Release( IDropTarget
*iface
)
2437 IShellViewImpl
*This
= impl_from_IDropTarget(iface
);
2439 TRACE("(%p)->(count=%u)\n",This
,This
->ref
);
2441 return IShellFolder_Release((IShellFolder
*)This
);
2444 /******************************************************************************
2445 * drag_notify_subitem [Internal]
2447 * Figure out the shellfolder object, which is currently under the mouse cursor
2448 * and notify it via the IDropTarget interface.
2451 #define SCROLLAREAWIDTH 20
2453 static HRESULT
drag_notify_subitem(IShellViewImpl
*This
, DWORD grfKeyState
, POINTL pt
,
2456 LVHITTESTINFO htinfo
;
2462 /* Map from global to client coordinates and query the index of the listview-item, which is
2463 * currently under the mouse cursor. */
2466 htinfo
.flags
= LVHT_ONITEM
;
2467 ScreenToClient(This
->hWndList
, &htinfo
.pt
);
2468 lResult
= SendMessageW(This
->hWndList
, LVM_HITTEST
, 0, (LPARAM
)&htinfo
);
2470 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2471 GetClientRect(This
->hWndList
, &clientRect
);
2472 if (htinfo
.pt
.x
== This
->ptLastMousePos
.x
&& htinfo
.pt
.y
== This
->ptLastMousePos
.y
&&
2473 (htinfo
.pt
.x
< SCROLLAREAWIDTH
|| htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
||
2474 htinfo
.pt
.y
< SCROLLAREAWIDTH
|| htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
))
2476 This
->cScrollDelay
= (This
->cScrollDelay
+ 1) % 5; /* DragOver is called every 50 ms */
2477 if (This
->cScrollDelay
== 0) { /* Mouse did hover another 250 ms over the scroll-area */
2478 if (htinfo
.pt
.x
< SCROLLAREAWIDTH
)
2479 SendMessageW(This
->hWndList
, WM_HSCROLL
, SB_LINEUP
, 0);
2480 if (htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
)
2481 SendMessageW(This
->hWndList
, WM_HSCROLL
, SB_LINEDOWN
, 0);
2482 if (htinfo
.pt
.y
< SCROLLAREAWIDTH
)
2483 SendMessageW(This
->hWndList
, WM_VSCROLL
, SB_LINEUP
, 0);
2484 if (htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
)
2485 SendMessageW(This
->hWndList
, WM_VSCROLL
, SB_LINEDOWN
, 0);
2488 This
->cScrollDelay
= 0; /* Reset, if the cursor is not over the listview's scroll-area */
2490 This
->ptLastMousePos
= htinfo
.pt
;
2492 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2493 if (This
->pCurDropTarget
&& lResult
== This
->iDragOverItem
)
2494 return IDropTarget_DragOver(This
->pCurDropTarget
, grfKeyState
, pt
, pdwEffect
);
2496 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2497 if (This
->pCurDropTarget
) {
2498 IDropTarget_DragLeave(This
->pCurDropTarget
);
2499 IDropTarget_Release(This
->pCurDropTarget
);
2500 This
->pCurDropTarget
= NULL
;
2503 This
->iDragOverItem
= lResult
;
2504 if (lResult
== -1) {
2505 /* We are not above one of the listview's subitems. Bind to the parent folder's
2506 * DropTarget interface. */
2507 hr
= IShellFolder_QueryInterface(This
->pSFParent
, &IID_IDropTarget
,
2508 (LPVOID
*)&This
->pCurDropTarget
);
2510 /* Query the relative PIDL of the shellfolder object represented by the currently
2511 * dragged over listview-item ... */
2512 lvItem
.mask
= LVIF_PARAM
;
2513 lvItem
.iItem
= lResult
;
2514 lvItem
.iSubItem
= 0;
2515 SendMessageW(This
->hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
2517 /* ... and bind pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2518 hr
= IShellFolder_GetUIObjectOf(This
->pSFParent
, This
->hWndList
, 1,
2519 (LPCITEMIDLIST
*)&lvItem
.lParam
, &IID_IDropTarget
, NULL
, (LPVOID
*)&This
->pCurDropTarget
);
2522 /* If anything failed, pCurDropTarget should be NULL now, which ought to be a save state. */
2526 /* Notify the item just entered via DragEnter. */
2527 return IDropTarget_DragEnter(This
->pCurDropTarget
, This
->pCurDataObject
, grfKeyState
, pt
, pdwEffect
);
2530 static HRESULT WINAPI
ISVDropTarget_DragEnter(IDropTarget
*iface
, IDataObject
*pDataObject
,
2531 DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2533 IShellViewImpl
*This
= impl_from_IDropTarget(iface
);
2535 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2536 This
->pCurDataObject
= pDataObject
;
2537 IDataObject_AddRef(pDataObject
);
2539 return drag_notify_subitem(This
, grfKeyState
, pt
, pdwEffect
);
2542 static HRESULT WINAPI
ISVDropTarget_DragOver(IDropTarget
*iface
, DWORD grfKeyState
, POINTL pt
,
2545 IShellViewImpl
*This
= impl_from_IDropTarget(iface
);
2546 return drag_notify_subitem(This
, grfKeyState
, pt
, pdwEffect
);
2549 static HRESULT WINAPI
ISVDropTarget_DragLeave(IDropTarget
*iface
) {
2550 IShellViewImpl
*This
= impl_from_IDropTarget(iface
);
2552 if (This
->pCurDropTarget
)
2554 IDropTarget_DragLeave(This
->pCurDropTarget
);
2555 IDropTarget_Release(This
->pCurDropTarget
);
2556 This
->pCurDropTarget
= NULL
;
2559 if (This
->pCurDataObject
!= NULL
)
2561 IDataObject_Release(This
->pCurDataObject
);
2562 This
->pCurDataObject
= NULL
;
2565 This
->iDragOverItem
= 0;
2570 static HRESULT WINAPI
ISVDropTarget_Drop(IDropTarget
*iface
, IDataObject
* pDataObject
,
2571 DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2573 IShellViewImpl
*This
= impl_from_IDropTarget(iface
);
2575 if (This
->pCurDropTarget
)
2577 IDropTarget_Drop(This
->pCurDropTarget
, pDataObject
, grfKeyState
, pt
, pdwEffect
);
2578 IDropTarget_Release(This
->pCurDropTarget
);
2579 This
->pCurDropTarget
= NULL
;
2582 if (This
->pCurDataObject
!= NULL
)
2584 IDataObject_Release(This
->pCurDataObject
);
2585 This
->pCurDataObject
= NULL
;
2588 This
->iDragOverItem
= 0;
2593 static const IDropTargetVtbl dtvt
=
2595 ISVDropTarget_QueryInterface
,
2596 ISVDropTarget_AddRef
,
2597 ISVDropTarget_Release
,
2598 ISVDropTarget_DragEnter
,
2599 ISVDropTarget_DragOver
,
2600 ISVDropTarget_DragLeave
,
2604 /**********************************************************
2605 * ISVDropSource implementation
2608 static HRESULT WINAPI
ISVDropSource_QueryInterface(
2613 IShellViewImpl
*This
= impl_from_IDropSource(iface
);
2615 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This
,debugstr_guid(riid
),ppvObj
);
2617 return IShellFolder_QueryInterface((IShellFolder
*)This
, riid
, ppvObj
);
2620 static ULONG WINAPI
ISVDropSource_AddRef( IDropSource
*iface
)
2622 IShellViewImpl
*This
= impl_from_IDropSource(iface
);
2624 TRACE("(%p)->(count=%u)\n",This
,This
->ref
);
2626 return IShellFolder_AddRef((IShellFolder
*)This
);
2629 static ULONG WINAPI
ISVDropSource_Release( IDropSource
*iface
)
2631 IShellViewImpl
*This
= impl_from_IDropSource(iface
);
2633 TRACE("(%p)->(count=%u)\n",This
,This
->ref
);
2635 return IShellFolder_Release((IShellFolder
*)This
);
2637 static HRESULT WINAPI
ISVDropSource_QueryContinueDrag(
2639 BOOL fEscapePressed
,
2642 IShellViewImpl
*This
= impl_from_IDropSource(iface
);
2643 TRACE("(%p)\n",This
);
2646 return DRAGDROP_S_CANCEL
;
2647 else if (!(grfKeyState
& MK_LBUTTON
) && !(grfKeyState
& MK_RBUTTON
))
2648 return DRAGDROP_S_DROP
;
2653 static HRESULT WINAPI
ISVDropSource_GiveFeedback(
2657 IShellViewImpl
*This
= impl_from_IDropSource(iface
);
2658 TRACE("(%p)\n",This
);
2660 return DRAGDROP_S_USEDEFAULTCURSORS
;
2663 static const IDropSourceVtbl dsvt
=
2665 ISVDropSource_QueryInterface
,
2666 ISVDropSource_AddRef
,
2667 ISVDropSource_Release
,
2668 ISVDropSource_QueryContinueDrag
,
2669 ISVDropSource_GiveFeedback
2671 /**********************************************************
2672 * ISVViewObject implementation
2675 static HRESULT WINAPI
ISVViewObject_QueryInterface(
2680 IShellViewImpl
*This
= impl_from_IViewObject(iface
);
2682 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This
,debugstr_guid(riid
),ppvObj
);
2684 return IShellFolder_QueryInterface((IShellFolder
*)This
, riid
, ppvObj
);
2687 static ULONG WINAPI
ISVViewObject_AddRef( IViewObject
*iface
)
2689 IShellViewImpl
*This
= impl_from_IViewObject(iface
);
2691 TRACE("(%p)->(count=%u)\n",This
,This
->ref
);
2693 return IShellFolder_AddRef((IShellFolder
*)This
);
2696 static ULONG WINAPI
ISVViewObject_Release( IViewObject
*iface
)
2698 IShellViewImpl
*This
= impl_from_IViewObject(iface
);
2700 TRACE("(%p)->(count=%u)\n",This
,This
->ref
);
2702 return IShellFolder_Release((IShellFolder
*)This
);
2705 static HRESULT WINAPI
ISVViewObject_Draw(
2710 DVTARGETDEVICE
* ptd
,
2713 LPCRECTL lprcBounds
,
2714 LPCRECTL lprcWBounds
,
2715 BOOL (CALLBACK
*pfnContinue
)(ULONG_PTR dwContinue
),
2716 ULONG_PTR dwContinue
)
2719 IShellViewImpl
*This
= impl_from_IViewObject(iface
);
2721 FIXME("Stub: This=%p\n",This
);
2725 static HRESULT WINAPI
ISVViewObject_GetColorSet(
2730 DVTARGETDEVICE
* ptd
,
2731 HDC hicTargetDevice
,
2732 LOGPALETTE
** ppColorSet
)
2735 IShellViewImpl
*This
= impl_from_IViewObject(iface
);
2737 FIXME("Stub: This=%p\n",This
);
2741 static HRESULT WINAPI
ISVViewObject_Freeze(
2749 IShellViewImpl
*This
= impl_from_IViewObject(iface
);
2751 FIXME("Stub: This=%p\n",This
);
2755 static HRESULT WINAPI
ISVViewObject_Unfreeze(
2760 IShellViewImpl
*This
= impl_from_IViewObject(iface
);
2762 FIXME("Stub: This=%p\n",This
);
2766 static HRESULT WINAPI
ISVViewObject_SetAdvise(
2770 IAdviseSink
* pAdvSink
)
2773 IShellViewImpl
*This
= impl_from_IViewObject(iface
);
2775 FIXME("partial stub: %p %08x %08x %p\n",
2776 This
, aspects
, advf
, pAdvSink
);
2778 /* FIXME: we set the AdviseSink, but never use it to send any advice */
2779 This
->pAdvSink
= pAdvSink
;
2780 This
->dwAspects
= aspects
;
2781 This
->dwAdvf
= advf
;
2786 static HRESULT WINAPI
ISVViewObject_GetAdvise(
2790 IAdviseSink
** ppAdvSink
)
2793 IShellViewImpl
*This
= impl_from_IViewObject(iface
);
2795 TRACE("This=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n",
2796 This
, pAspects
, pAdvf
, ppAdvSink
);
2800 IAdviseSink_AddRef( This
->pAdvSink
);
2801 *ppAdvSink
= This
->pAdvSink
;
2804 *pAspects
= This
->dwAspects
;
2806 *pAdvf
= This
->dwAdvf
;
2812 static const IViewObjectVtbl vovt
=
2814 ISVViewObject_QueryInterface
,
2815 ISVViewObject_AddRef
,
2816 ISVViewObject_Release
,
2818 ISVViewObject_GetColorSet
,
2819 ISVViewObject_Freeze
,
2820 ISVViewObject_Unfreeze
,
2821 ISVViewObject_SetAdvise
,
2822 ISVViewObject_GetAdvise