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: CheckToolbar: handle the "new folder" and "folder up" button
28 - Load/Save the view state from/into the stream provided by the ShellBrowser.
29 - When editing starts on item, set edit text to for editing value.
30 - Fix shell view to handle view mode popup exec.
31 - The background context menu should have a pidl just like foreground menus. This
32 causes crashes when dynamic handlers try to use the NULL pidl.
33 - Reorder of columns doesn't work - might be bug in comctl32
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};
52 } LISTVIEW_SORT_INFO
, *LPLISTVIEW_SORT_INFO
;
54 #define SHV_CHANGE_NOTIFY WM_USER + 0x1111
56 /* For the context menu of the def view, the id of the items are based on 1 because we need
57 to call TrackPopupMenu and let it use the 0 value as an indication that the menu was canceled */
58 #define CONTEXT_MENU_BASE_ID 1
61 public CWindowImpl
<CDefView
, CWindow
, CControlWinTraits
>,
62 public CComObjectRootEx
<CComMultiThreadModelNoCS
>,
65 public IShellFolderView
,
66 public IOleCommandTarget
,
70 public IServiceProvider
73 CComPtr
<IShellFolder
> m_pSFParent
;
74 CComPtr
<IShellFolder2
> m_pSF2Parent
;
75 CComPtr
<IShellFolderViewCB
> m_pShellFolderViewCB
;
76 CComPtr
<IShellBrowser
> m_pShellBrowser
;
77 CComPtr
<ICommDlgBrowser
> m_pCommDlgBrowser
;
78 CComPtr
<IShellFolderViewDual
> m_pShellFolderViewDual
;
81 FOLDERSETTINGS m_FolderSettings
;
82 HMENU m_hMenu
; /* Handle to the menu bar of the browser */
83 HMENU m_hMenuArrangeModes
; /* Handle to the popup menu with the arrange modes */
84 HMENU m_hMenuViewModes
; /* Handle to the popup menu with the view modes */
85 HMENU m_hContextMenu
; /* Handle to the open context menu */
86 BOOL m_bmenuBarInitialized
;
89 PCUITEMID_CHILD
*m_apidl
;
90 PIDLIST_ABSOLUTE m_pidlParent
;
91 LISTVIEW_SORT_INFO m_sortInfo
;
92 ULONG m_hNotify
; /* Change notification handle */
96 CComPtr
<IAdviseSink
> m_pAdvSink
;
98 CComPtr
<IDataObject
> m_pSourceDataObject
;
99 CComPtr
<IDropTarget
> m_pCurDropTarget
; /* The sub-item, which is currently dragged over */
100 CComPtr
<IDataObject
> m_pCurDataObject
; /* The dragged data-object */
101 LONG m_iDragOverItem
; /* Dragged over item's index, iff m_pCurDropTarget != NULL */
102 UINT m_cScrollDelay
; /* Send a WM_*SCROLL msg every 250 ms during drag-scroll */
103 POINT m_ptLastMousePos
; /* Mouse position at last DragOver call */
104 POINT m_ptFirstMousePos
; /* Mouse position when the drag operation started */
107 CComPtr
<IContextMenu
> m_pCM
;
115 HRESULT
_MergeToolbar();
117 HRESULT
_DoFolderViewCB(UINT uMsg
, WPARAM wParam
, LPARAM lParam
);
122 HRESULT WINAPI
Initialize(IShellFolder
*shellFolder
);
123 HRESULT
IncludeObject(PCUITEMID_CHILD pidl
);
124 HRESULT
OnDefaultCommand();
125 HRESULT
OnStateChange(UINT uFlags
);
126 void UpdateStatusbar();
129 void UpdateListColors();
131 HRESULT
DefMessageSFVCB(UINT uMsg
, WPARAM wParam
, LPARAM lParam
);
132 static INT CALLBACK
ListViewCompareItems(LPARAM lParam1
, LPARAM lParam2
, LPARAM lpData
);
134 PCUITEMID_CHILD
_PidlByItem(int i
);
135 PCUITEMID_CHILD
_PidlByItem(LVITEM
& lvItem
);
136 int LV_FindItemByPidl(PCUITEMID_CHILD pidl
);
137 BOOLEAN
LV_AddItem(PCUITEMID_CHILD pidl
);
138 BOOLEAN
LV_DeleteItem(PCUITEMID_CHILD pidl
);
139 BOOLEAN
LV_RenameItem(PCUITEMID_CHILD pidlOld
, PCUITEMID_CHILD pidlNew
);
140 BOOLEAN
LV_ProdItem(PCUITEMID_CHILD pidl
);
141 static INT CALLBACK
fill_list(LPVOID ptr
, LPVOID arg
);
143 HRESULT
FillFileMenu();
144 HRESULT
FillEditMenu();
145 HRESULT
FillViewMenu();
146 HRESULT
FillArrangeAsMenu(HMENU hmenuArrange
);
147 HRESULT
CheckViewMode(HMENU hmenuView
);
148 UINT
GetSelections();
149 HRESULT
OpenSelectedItems();
151 void DoActivate(UINT uState
);
152 HRESULT
drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
153 HRESULT
InvokeContextMenuCommand(UINT uCommand
);
154 LRESULT
OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
);
156 // *** IOleWindow methods ***
157 virtual HRESULT STDMETHODCALLTYPE
GetWindow(HWND
*lphwnd
);
158 virtual HRESULT STDMETHODCALLTYPE
ContextSensitiveHelp(BOOL fEnterMode
);
160 // *** IShellView methods ***
161 virtual HRESULT STDMETHODCALLTYPE
TranslateAccelerator(MSG
*pmsg
);
162 virtual HRESULT STDMETHODCALLTYPE
EnableModeless(BOOL fEnable
);
163 virtual HRESULT STDMETHODCALLTYPE
UIActivate(UINT uState
);
164 virtual HRESULT STDMETHODCALLTYPE
Refresh();
165 virtual HRESULT STDMETHODCALLTYPE
CreateViewWindow(IShellView
*psvPrevious
, LPCFOLDERSETTINGS pfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
);
166 virtual HRESULT STDMETHODCALLTYPE
DestroyViewWindow();
167 virtual HRESULT STDMETHODCALLTYPE
GetCurrentInfo(LPFOLDERSETTINGS pfs
);
168 virtual HRESULT STDMETHODCALLTYPE
AddPropertySheetPages(DWORD dwReserved
, LPFNSVADDPROPSHEETPAGE pfn
, LPARAM lparam
);
169 virtual HRESULT STDMETHODCALLTYPE
SaveViewState();
170 virtual HRESULT STDMETHODCALLTYPE
SelectItem(PCUITEMID_CHILD pidlItem
, SVSIF uFlags
);
171 virtual HRESULT STDMETHODCALLTYPE
GetItemObject(UINT uItem
, REFIID riid
, void **ppv
);
173 // *** IShellView2 methods ***
174 virtual HRESULT STDMETHODCALLTYPE
GetView(SHELLVIEWID
*view_guid
, ULONG view_type
);
175 virtual HRESULT STDMETHODCALLTYPE
CreateViewWindow2(LPSV2CVW2_PARAMS view_params
);
176 virtual HRESULT STDMETHODCALLTYPE
HandleRename(LPCITEMIDLIST new_pidl
);
177 virtual HRESULT STDMETHODCALLTYPE
SelectAndPositionItem(LPCITEMIDLIST item
, UINT flags
, POINT
*point
);
179 // *** IShellView3 methods ***
180 virtual HRESULT STDMETHODCALLTYPE
CreateViewWindow3(IShellBrowser
*psb
, IShellView
*psvPrevious
, SV3CVW3_FLAGS view_flags
, FOLDERFLAGS mask
, FOLDERFLAGS flags
, FOLDERVIEWMODE mode
, const SHELLVIEWID
*view_id
, RECT
*prcView
, HWND
*hwnd
);
182 // *** IFolderView methods ***
183 virtual HRESULT STDMETHODCALLTYPE
GetCurrentViewMode(UINT
*pViewMode
);
184 virtual HRESULT STDMETHODCALLTYPE
SetCurrentViewMode(UINT ViewMode
);
185 virtual HRESULT STDMETHODCALLTYPE
GetFolder(REFIID riid
, void **ppv
);
186 virtual HRESULT STDMETHODCALLTYPE
Item(int iItemIndex
, PITEMID_CHILD
*ppidl
);
187 virtual HRESULT STDMETHODCALLTYPE
ItemCount(UINT uFlags
, int *pcItems
);
188 virtual HRESULT STDMETHODCALLTYPE
Items(UINT uFlags
, REFIID riid
, void **ppv
);
189 virtual HRESULT STDMETHODCALLTYPE
GetSelectionMarkedItem(int *piItem
);
190 virtual HRESULT STDMETHODCALLTYPE
GetFocusedItem(int *piItem
);
191 virtual HRESULT STDMETHODCALLTYPE
GetItemPosition(PCUITEMID_CHILD pidl
, POINT
*ppt
);
192 virtual HRESULT STDMETHODCALLTYPE
GetSpacing(POINT
*ppt
);
193 virtual HRESULT STDMETHODCALLTYPE
GetDefaultSpacing(POINT
*ppt
);
194 virtual HRESULT STDMETHODCALLTYPE
GetAutoArrange();
195 virtual HRESULT STDMETHODCALLTYPE
SelectItem(int iItem
, DWORD dwFlags
);
196 virtual HRESULT STDMETHODCALLTYPE
SelectAndPositionItems(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD dwFlags
);
198 // *** IShellFolderView methods ***
199 virtual HRESULT STDMETHODCALLTYPE
Rearrange(LPARAM sort
);
200 virtual HRESULT STDMETHODCALLTYPE
GetArrangeParam(LPARAM
*sort
);
201 virtual HRESULT STDMETHODCALLTYPE
ArrangeGrid();
202 virtual HRESULT STDMETHODCALLTYPE
AutoArrange();
203 virtual HRESULT STDMETHODCALLTYPE
AddObject(PITEMID_CHILD pidl
, UINT
*item
);
204 virtual HRESULT STDMETHODCALLTYPE
GetObject(PITEMID_CHILD
*pidl
, UINT item
);
205 virtual HRESULT STDMETHODCALLTYPE
RemoveObject(PITEMID_CHILD pidl
, UINT
*item
);
206 virtual HRESULT STDMETHODCALLTYPE
GetObjectCount(UINT
*count
);
207 virtual HRESULT STDMETHODCALLTYPE
SetObjectCount(UINT count
, UINT flags
);
208 virtual HRESULT STDMETHODCALLTYPE
UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
);
209 virtual HRESULT STDMETHODCALLTYPE
RefreshObject(PITEMID_CHILD pidl
, UINT
*item
);
210 virtual HRESULT STDMETHODCALLTYPE
SetRedraw(BOOL redraw
);
211 virtual HRESULT STDMETHODCALLTYPE
GetSelectedCount(UINT
*count
);
212 virtual HRESULT STDMETHODCALLTYPE
GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
);
213 virtual HRESULT STDMETHODCALLTYPE
IsDropOnSource(IDropTarget
*drop_target
);
214 virtual HRESULT STDMETHODCALLTYPE
GetDragPoint(POINT
*pt
);
215 virtual HRESULT STDMETHODCALLTYPE
GetDropPoint(POINT
*pt
);
216 virtual HRESULT STDMETHODCALLTYPE
MoveIcons(IDataObject
*obj
);
217 virtual HRESULT STDMETHODCALLTYPE
SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
);
218 virtual HRESULT STDMETHODCALLTYPE
IsBkDropTarget(IDropTarget
*drop_target
);
219 virtual HRESULT STDMETHODCALLTYPE
SetClipboard(BOOL move
);
220 virtual HRESULT STDMETHODCALLTYPE
SetPoints(IDataObject
*obj
);
221 virtual HRESULT STDMETHODCALLTYPE
GetItemSpacing(ITEMSPACING
*spacing
);
222 virtual HRESULT STDMETHODCALLTYPE
SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
);
223 virtual HRESULT STDMETHODCALLTYPE
Select(UINT flags
);
224 virtual HRESULT STDMETHODCALLTYPE
QuerySupport(UINT
*support
);
225 virtual HRESULT STDMETHODCALLTYPE
SetAutomationObject(IDispatch
*disp
);
227 // *** IOleCommandTarget methods ***
228 virtual HRESULT STDMETHODCALLTYPE
QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
);
229 virtual HRESULT STDMETHODCALLTYPE
Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
);
231 // *** IDropTarget methods ***
232 virtual HRESULT STDMETHODCALLTYPE
DragEnter(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
233 virtual HRESULT STDMETHODCALLTYPE
DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
234 virtual HRESULT STDMETHODCALLTYPE
DragLeave();
235 virtual HRESULT STDMETHODCALLTYPE
Drop(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
237 // *** IDropSource methods ***
238 virtual HRESULT STDMETHODCALLTYPE
QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
);
239 virtual HRESULT STDMETHODCALLTYPE
GiveFeedback(DWORD dwEffect
);
241 // *** IViewObject methods ***
242 virtual HRESULT STDMETHODCALLTYPE
Draw(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
,
243 HDC hdcTargetDev
, HDC hdcDraw
, LPCRECTL lprcBounds
, LPCRECTL lprcWBounds
,
244 BOOL ( STDMETHODCALLTYPE
*pfnContinue
)(ULONG_PTR dwContinue
), ULONG_PTR dwContinue
);
245 virtual HRESULT STDMETHODCALLTYPE
GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
,
246 DVTARGETDEVICE
*ptd
, HDC hicTargetDev
, LOGPALETTE
**ppColorSet
);
247 virtual HRESULT STDMETHODCALLTYPE
Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
);
248 virtual HRESULT STDMETHODCALLTYPE
Unfreeze(DWORD dwFreeze
);
249 virtual HRESULT STDMETHODCALLTYPE
SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
);
250 virtual HRESULT STDMETHODCALLTYPE
GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
);
252 // *** IServiceProvider methods ***
253 virtual HRESULT STDMETHODCALLTYPE
QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
);
256 LRESULT
OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
257 LRESULT
OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
258 LRESULT
OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
259 LRESULT
OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
260 LRESULT
OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
261 LRESULT
OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
262 LRESULT
OnNCCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
263 LRESULT
OnNCDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
264 LRESULT
OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
265 LRESULT
OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
266 LRESULT
OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
267 LRESULT
OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
268 LRESULT
OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
269 LRESULT
OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
270 LRESULT
OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
271 LRESULT
OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
272 LRESULT
OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
273 LRESULT
OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
274 LRESULT
OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
275 LRESULT
OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
277 static ATL::CWndClassInfo
& GetWndClassInfo()
279 static ATL::CWndClassInfo wc
=
281 { sizeof(WNDCLASSEX
), CS_PARENTDC
, StartWindowProc
,
283 LoadCursor(NULL
, IDC_ARROW
), (HBRUSH
)(COLOR_WINDOW
+ 1), NULL
, SV_CLASS_NAME
, NULL
285 NULL
, NULL
, IDC_ARROW
, TRUE
, 0, _T("")
290 virtual WNDPROC
GetWindowProc()
295 static LRESULT CALLBACK
WindowProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
300 // Must hold a reference during message handling
301 pThis
= reinterpret_cast<CDefView
*>(hWnd
);
303 result
= CWindowImpl
<CDefView
, CWindow
, CControlWinTraits
>::WindowProc(hWnd
, uMsg
, wParam
, lParam
);
308 BEGIN_MSG_MAP(CDefView
)
309 MESSAGE_HANDLER(WM_SIZE
, OnSize
)
310 MESSAGE_HANDLER(WM_SETFOCUS
, OnSetFocus
)
311 MESSAGE_HANDLER(WM_KILLFOCUS
, OnKillFocus
)
312 MESSAGE_HANDLER(WM_NCCREATE
, OnNCCreate
)
313 MESSAGE_HANDLER(WM_NCDESTROY
, OnNCDestroy
)
314 MESSAGE_HANDLER(WM_CREATE
, OnCreate
)
315 MESSAGE_HANDLER(WM_ACTIVATE
, OnActivate
)
316 MESSAGE_HANDLER(WM_NOTIFY
, OnNotify
)
317 MESSAGE_HANDLER(WM_COMMAND
, OnCommand
)
318 MESSAGE_HANDLER(SHV_CHANGE_NOTIFY
, OnChangeNotify
)
319 MESSAGE_HANDLER(WM_CONTEXTMENU
, OnContextMenu
)
320 MESSAGE_HANDLER(WM_DRAWITEM
, OnCustomItem
)
321 MESSAGE_HANDLER(WM_MEASUREITEM
, OnCustomItem
)
322 MESSAGE_HANDLER(WM_SHOWWINDOW
, OnShowWindow
)
323 MESSAGE_HANDLER(WM_GETDLGCODE
, OnGetDlgCode
)
324 MESSAGE_HANDLER(WM_DESTROY
, OnDestroy
)
325 MESSAGE_HANDLER(WM_ERASEBKGND
, OnEraseBackground
)
326 MESSAGE_HANDLER(WM_SYSCOLORCHANGE
, OnSysColorChange
)
327 MESSAGE_HANDLER(CWM_GETISHELLBROWSER
, OnGetShellBrowser
)
328 MESSAGE_HANDLER(WM_SETTINGCHANGE
, OnSettingChange
)
329 MESSAGE_HANDLER(WM_INITMENUPOPUP
, OnInitMenuPopup
)
332 BEGIN_COM_MAP(CDefView
)
333 // Windows returns E_NOINTERFACE for IOleWindow
334 // COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
335 COM_INTERFACE_ENTRY_IID(IID_IShellView
, IShellView
)
336 COM_INTERFACE_ENTRY_IID(IID_CDefView
, IShellView
)
337 COM_INTERFACE_ENTRY_IID(IID_IShellView2
, IShellView2
)
338 COM_INTERFACE_ENTRY_IID(IID_IFolderView
, IFolderView
)
339 COM_INTERFACE_ENTRY_IID(IID_IShellFolderView
, IShellFolderView
)
340 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget
, IOleCommandTarget
)
341 COM_INTERFACE_ENTRY_IID(IID_IDropTarget
, IDropTarget
)
342 COM_INTERFACE_ENTRY_IID(IID_IDropSource
, IDropSource
)
343 COM_INTERFACE_ENTRY_IID(IID_IViewObject
, IViewObject
)
344 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider
, IServiceProvider
)
349 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
350 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
351 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
353 #define ID_LISTVIEW 1
356 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
357 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
358 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
360 typedef void (CALLBACK
*PFNSHGETSETTINGSPROC
)(LPSHELLFLAGSTATE lpsfs
, DWORD dwMask
);
362 CDefView::CDefView() :
366 m_hMenuArrangeModes(NULL
),
367 m_hMenuViewModes(NULL
),
368 m_hContextMenu(NULL
),
369 m_bmenuBarInitialized(FALSE
),
383 ZeroMemory(&m_FolderSettings
, sizeof(m_FolderSettings
));
384 ZeroMemory(&m_sortInfo
, sizeof(m_sortInfo
));
385 ZeroMemory(&m_ptLastMousePos
, sizeof(m_ptLastMousePos
));
386 ZeroMemory(&m_Category
, sizeof(m_Category
));
389 CDefView::~CDefView()
391 TRACE(" destroying IShellView(%p)\n", this);
401 HRESULT WINAPI
CDefView::Initialize(IShellFolder
*shellFolder
)
403 m_pSFParent
= shellFolder
;
404 shellFolder
->QueryInterface(IID_PPV_ARG(IShellFolder2
, &m_pSF2Parent
));
409 /**********************************************************
411 * ##### helperfunctions for communication with ICommDlgBrowser #####
413 HRESULT
CDefView::IncludeObject(PCUITEMID_CHILD pidl
)
417 if (m_pCommDlgBrowser
.p
!= NULL
)
419 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl
);
420 ret
= m_pCommDlgBrowser
->IncludeObject(this, pidl
);
421 TRACE("-- returns 0x%08x\n", ret
);
427 HRESULT
CDefView::OnDefaultCommand()
429 HRESULT ret
= S_FALSE
;
431 if (m_pCommDlgBrowser
.p
!= NULL
)
433 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
434 ret
= m_pCommDlgBrowser
->OnDefaultCommand(this);
435 TRACE("-- returns 0x%08x\n", ret
);
441 HRESULT
CDefView::OnStateChange(UINT uFlags
)
443 HRESULT ret
= S_FALSE
;
445 if (m_pCommDlgBrowser
.p
!= NULL
)
447 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags
);
448 ret
= m_pCommDlgBrowser
->OnStateChange(this, uFlags
);
454 /**********************************************************
455 * set the toolbar of the filedialog buttons
457 * - activates the buttons from the shellbrowser according to
460 void CDefView::CheckToolbar()
466 if (m_pCommDlgBrowser
!= NULL
)
468 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
469 FCIDM_TB_SMALLICON
, (m_FolderSettings
.ViewMode
== FVM_LIST
) ? TRUE
: FALSE
, &result
);
470 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
471 FCIDM_TB_REPORTVIEW
, (m_FolderSettings
.ViewMode
== FVM_DETAILS
) ? TRUE
: FALSE
, &result
);
472 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
473 FCIDM_TB_SMALLICON
, TRUE
, &result
);
474 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
475 FCIDM_TB_REPORTVIEW
, TRUE
, &result
);
479 void CDefView::UpdateStatusbar()
481 WCHAR szFormat
[MAX_PATH
] = {0};
482 WCHAR szObjects
[MAX_PATH
] = {0};
485 cSelectedItems
= m_ListView
.GetSelectedCount();
488 LoadStringW(shell32_hInstance
, IDS_OBJECTS_SELECTED
, szFormat
, _countof(szFormat
));
489 StringCchPrintfW(szObjects
, MAX_PATH
, szFormat
, cSelectedItems
);
493 LoadStringW(shell32_hInstance
, IDS_OBJECTS
, szFormat
, _countof(szFormat
));
494 StringCchPrintfW(szObjects
, MAX_PATH
, szFormat
, m_ListView
.GetItemCount());
496 m_pShellBrowser
->SetStatusTextSB(szObjects
);
499 /**********************************************************
501 * ##### helperfunctions for initializing the view #####
504 /**********************************************************
505 * ShellView_CreateList()
507 * - creates the list view window
509 BOOL
CDefView::CreateList()
512 DWORD dwStyle
, dwExStyle
;
517 dwStyle
= WS_TABSTOP
| WS_VISIBLE
| WS_CHILDWINDOW
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
|
518 LVS_SHAREIMAGELISTS
| LVS_EDITLABELS
| LVS_AUTOARRANGE
;
519 dwExStyle
= WS_EX_CLIENTEDGE
;
521 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
522 dwStyle
|= LVS_ALIGNLEFT
;
524 dwStyle
|= LVS_ALIGNTOP
| LVS_SHOWSELALWAYS
;
526 ViewMode
= m_FolderSettings
.ViewMode
;
527 hr
= _DoFolderViewCB(SFVM_DEFVIEWMODE
, NULL
, (LPARAM
)&ViewMode
);
530 if (ViewMode
>= FVM_FIRST
&& ViewMode
<= FVM_LAST
)
531 m_FolderSettings
.ViewMode
= ViewMode
;
533 ERR("Ignoring invalid ViewMode from SFVM_DEFVIEWMODE: %u (was: %u)\n", ViewMode
, m_FolderSettings
.ViewMode
);
536 switch (m_FolderSettings
.ViewMode
)
543 dwStyle
|= LVS_REPORT
;
547 dwStyle
|= LVS_SMALLICON
;
559 if (m_FolderSettings
.fFlags
& FWF_AUTOARRANGE
)
560 dwStyle
|= LVS_AUTOARRANGE
;
562 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
563 m_FolderSettings
.fFlags
|= FWF_NOCLIENTEDGE
| FWF_NOSCROLL
;
565 if (m_FolderSettings
.fFlags
& FWF_SINGLESEL
)
566 dwStyle
|= LVS_SINGLESEL
;
568 if (m_FolderSettings
.fFlags
& FWF_NOCLIENTEDGE
)
569 dwExStyle
&= ~WS_EX_CLIENTEDGE
;
571 RECT rcListView
= {0,0,0,0};
572 m_ListView
.Create(m_hWnd
, rcListView
, L
"FolderView", dwStyle
, dwExStyle
, ID_LISTVIEW
);
577 m_sortInfo
.bIsAscending
= TRUE
;
578 m_sortInfo
.nHeaderID
= -1;
579 m_sortInfo
.nLastHeaderID
= -1;
583 /* UpdateShellSettings(); */
587 void CDefView::UpdateListColors()
589 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
591 /* Check if drop shadows option is enabled */
592 BOOL bDropShadow
= FALSE
;
593 DWORD cbDropShadow
= sizeof(bDropShadow
);
596 * The desktop ListView always take the default desktop colours, by
597 * remaining transparent and letting user32/win32k paint itself the
598 * desktop background color, if any.
600 m_ListView
.SetBkColor(CLR_NONE
);
602 SHGetValueW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
603 L
"ListviewShadow", NULL
, &bDropShadow
, &cbDropShadow
);
606 /* Set the icon background transparent */
607 m_ListView
.SetTextBkColor(CLR_NONE
);
608 m_ListView
.SetTextColor(RGB(255, 255, 255));
609 m_ListView
.SetExtendedListViewStyle(LVS_EX_TRANSPARENTSHADOWTEXT
, LVS_EX_TRANSPARENTSHADOWTEXT
);
613 /* Set the icon background as the same colour as the desktop */
614 COLORREF crDesktop
= GetSysColor(COLOR_DESKTOP
);
615 m_ListView
.SetTextBkColor(crDesktop
);
616 if (GetRValue(crDesktop
) + GetGValue(crDesktop
) + GetBValue(crDesktop
) > 128 * 3)
617 m_ListView
.SetTextColor(RGB(0, 0, 0));
619 m_ListView
.SetTextColor(RGB(255, 255, 255));
620 m_ListView
.SetExtendedListViewStyle(0, LVS_EX_TRANSPARENTSHADOWTEXT
);
625 /**********************************************************
626 * ShellView_InitList()
628 * - adds all needed columns to the shellview
630 BOOL
CDefView::InitList()
634 HIMAGELIST big_icons
, small_icons
;
638 m_ListView
.DeleteAllItems();
640 m_hMenuArrangeModes
= CreateMenu();
644 for (int i
= 0; 1; i
++)
646 if (FAILED(m_pSF2Parent
->GetDetailsOf(NULL
, i
, &sd
)))
648 StrRetToStrNW( szTemp
, 50, &sd
.str
, NULL
);
649 m_ListView
.InsertColumn(i
, szTemp
, sd
.fmt
, sd
.cxChar
* 8);
651 InsertMenuW(m_hMenuArrangeModes
, -1, MF_STRING
, 0x30 + i
, szTemp
);
654 InsertMenuW(m_hMenuArrangeModes
, -1, MF_BYPOSITION
| MF_SEPARATOR
, 0, 0);
658 FIXME("no m_pSF2Parent\n");
661 Shell_GetImageLists(&big_icons
, &small_icons
);
662 m_ListView
.SetImageList(big_icons
, LVSIL_NORMAL
);
663 m_ListView
.SetImageList(small_icons
, LVSIL_SMALL
);
668 /*************************************************************************
669 * ShellView_ListViewCompareItems
671 * Compare Function for the Listview (FileOpen Dialog)
674 * lParam1 [I] the first ItemIdList to compare with
675 * lParam2 [I] the second ItemIdList to compare with
676 * lpData [I] The column ID for the header Ctrl to process
679 * A negative value if the first item should precede the second,
680 * a positive value if the first item should follow the second,
681 * or zero if the two items are equivalent
683 INT CALLBACK
CDefView::ListViewCompareItems(LPARAM lParam1
, LPARAM lParam2
, LPARAM lpData
)
685 PCUIDLIST_RELATIVE pidl1
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam1
);
686 PCUIDLIST_RELATIVE pidl2
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam2
);
687 CDefView
*pThis
= reinterpret_cast<CDefView
*>(lpData
);
689 HRESULT hres
= pThis
->m_pSFParent
->CompareIDs(pThis
->m_sortInfo
.nHeaderID
, pidl1
, pidl2
);
690 if (FAILED_UNEXPECTEDLY(hres
))
693 SHORT nDiff
= HRESULT_CODE(hres
);
694 if (!pThis
->m_sortInfo
.bIsAscending
)
699 BOOL
CDefView::_Sort()
704 if (m_ListView
.GetWindowLongPtr(GWL_STYLE
) & LVS_NOSORTHEADER
)
707 hHeader
= (HWND
)m_ListView
.SendMessage(LVM_GETHEADER
, 0, 0);
708 ZeroMemory(&hColumn
, sizeof(hColumn
));
710 /* If the sorting column changed, remove the sorting style from the old column */
711 if ( (m_sortInfo
.nLastHeaderID
!= -1) &&
712 (m_sortInfo
.nLastHeaderID
!= m_sortInfo
.nHeaderID
) )
714 hColumn
.mask
= HDI_FORMAT
;
715 Header_GetItem(hHeader
, m_sortInfo
.nLastHeaderID
, &hColumn
);
716 hColumn
.fmt
&= ~(HDF_SORTUP
| HDF_SORTDOWN
);
717 Header_SetItem(hHeader
, m_sortInfo
.nLastHeaderID
, &hColumn
);
720 /* Set the sorting style to the new column */
721 hColumn
.mask
= HDI_FORMAT
;
722 Header_GetItem(hHeader
, m_sortInfo
.nHeaderID
, &hColumn
);
724 hColumn
.fmt
&= (m_sortInfo
.bIsAscending
? ~HDF_SORTDOWN
: ~HDF_SORTUP
);
725 hColumn
.fmt
|= (m_sortInfo
.bIsAscending
? HDF_SORTUP
: HDF_SORTDOWN
);
726 Header_SetItem(hHeader
, m_sortInfo
.nHeaderID
, &hColumn
);
728 /* Sort the list, using the current values of nHeaderID and bIsAscending */
729 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
730 return m_ListView
.SortItems(ListViewCompareItems
, this);
733 PCUITEMID_CHILD
CDefView::_PidlByItem(int i
)
735 return reinterpret_cast<PCUITEMID_CHILD
>(m_ListView
.GetItemData(i
));
738 PCUITEMID_CHILD
CDefView::_PidlByItem(LVITEM
& lvItem
)
740 return reinterpret_cast<PCUITEMID_CHILD
>(lvItem
.lParam
);
743 /**********************************************************
744 * LV_FindItemByPidl()
746 int CDefView::LV_FindItemByPidl(PCUITEMID_CHILD pidl
)
748 int cItems
= m_ListView
.GetItemCount();
750 for (int i
= 0; i
<cItems
; i
++)
752 PCUITEMID_CHILD currentpidl
= _PidlByItem(i
);
753 HRESULT hr
= m_pSFParent
->CompareIDs(0, pidl
, currentpidl
);
755 if (SUCCEEDED(hr
) && !HRESULT_CODE(hr
))
763 /**********************************************************
766 BOOLEAN
CDefView::LV_AddItem(PCUITEMID_CHILD pidl
)
770 TRACE("(%p)(pidl=%p)\n", this, pidl
);
772 lvItem
.mask
= LVIF_TEXT
| LVIF_IMAGE
| LVIF_PARAM
; /*set the mask*/
773 lvItem
.iItem
= m_ListView
.GetItemCount(); /*add the item to the end of the list*/
775 lvItem
.lParam
= reinterpret_cast<LPARAM
>(ILClone(pidl
)); /*set the item's data*/
776 lvItem
.pszText
= LPSTR_TEXTCALLBACKW
; /*get text on a callback basis*/
777 lvItem
.iImage
= I_IMAGECALLBACK
; /*get the image on a callback basis*/
778 lvItem
.stateMask
= LVIS_CUT
;
780 if (m_ListView
.InsertItem(&lvItem
) == -1)
786 /**********************************************************
789 BOOLEAN
CDefView::LV_DeleteItem(PCUITEMID_CHILD pidl
)
793 TRACE("(%p)(pidl=%p)\n", this, pidl
);
795 nIndex
= LV_FindItemByPidl(pidl
);
797 return (-1 == m_ListView
.DeleteItem(nIndex
)) ? FALSE
: TRUE
;
800 /**********************************************************
803 BOOLEAN
CDefView::LV_RenameItem(PCUITEMID_CHILD pidlOld
, PCUITEMID_CHILD pidlNew
)
808 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", this, pidlOld
, pidlNew
);
810 nItem
= LV_FindItemByPidl(pidlOld
);
814 lvItem
.mask
= LVIF_PARAM
; /* only the pidl */
815 lvItem
.iItem
= nItem
;
817 m_ListView
.GetItem(&lvItem
);
819 SHFree(reinterpret_cast<LPVOID
>(lvItem
.lParam
));
820 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
821 lvItem
.iItem
= nItem
;
823 lvItem
.lParam
= reinterpret_cast<LPARAM
>(ILClone(pidlNew
)); /* set the item's data */
824 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
825 m_ListView
.SetItem(&lvItem
);
826 m_ListView
.Update(nItem
);
827 return TRUE
; /* FIXME: better handling */
833 /**********************************************************
836 BOOLEAN
CDefView::LV_ProdItem(PCUITEMID_CHILD pidl
)
841 TRACE("(%p)(pidl=%p)\n", this, pidl
);
843 nItem
= LV_FindItemByPidl(pidl
);
847 lvItem
.mask
= LVIF_IMAGE
;
848 lvItem
.iItem
= nItem
;
850 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
851 m_ListView
.SetItem(&lvItem
);
852 m_ListView
.Update(nItem
);
859 /**********************************************************
860 * ShellView_FillList()
862 * - gets the objectlist from the shellfolder
864 * - fills the list into the view
866 INT CALLBACK
CDefView::fill_list(LPVOID ptr
, LPVOID arg
)
868 PITEMID_CHILD pidl
= static_cast<PITEMID_CHILD
>(ptr
);
869 CDefView
*pThis
= static_cast<CDefView
*>(arg
);
871 /* in a commdlg This works as a filemask*/
872 if (pThis
->IncludeObject(pidl
) == S_OK
)
873 pThis
->LV_AddItem(pidl
);
879 HRESULT
CDefView::FillList()
881 CComPtr
<IEnumIDList
> pEnumIDList
;
887 DWORD dFlags
= SHCONTF_NONFOLDERS
| SHCONTF_FOLDERS
;
891 /* determine if there is a setting to show all the hidden files/folders */
892 if (RegOpenKeyExW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", 0, KEY_QUERY_VALUE
, &hKey
) == ERROR_SUCCESS
)
894 DWORD dataLength
, flagVal
;
896 dataLength
= sizeof(flagVal
);
897 if (RegQueryValueExW(hKey
, L
"Hidden", NULL
, NULL
, (LPBYTE
)&flagVal
, &dataLength
) == ERROR_SUCCESS
)
899 /* if the value is 1, then show all hidden files/folders */
902 dFlags
|= SHCONTF_INCLUDEHIDDEN
;
903 m_ListView
.SendMessageW(LVM_SETCALLBACKMASK
, LVIS_CUT
, 0);
911 /* get the itemlist from the shfolder */
912 hRes
= m_pSFParent
->EnumObjects(m_hWnd
, dFlags
, &pEnumIDList
);
920 /* create a pointer array */
921 hdpa
= DPA_Create(16);
924 return(E_OUTOFMEMORY
);
927 /* copy the items into the array*/
928 while((S_OK
== pEnumIDList
->Next(1, &pidl
, &dwFetched
)) && dwFetched
)
930 if (DPA_InsertPtr(hdpa
, 0x7fff, pidl
) == -1)
936 /*turn the listview's redrawing off*/
937 m_ListView
.SetRedraw(FALSE
);
939 DPA_DestroyCallback( hdpa
, fill_list
, this);
944 m_pSF2Parent
->GetDefaultColumn(NULL
, (ULONG
*)&m_sortInfo
.nHeaderID
, NULL
);
948 FIXME("no m_pSF2Parent\n");
950 m_sortInfo
.bIsAscending
= TRUE
;
953 /*turn the listview's redrawing back on and force it to draw*/
954 m_ListView
.SetRedraw(TRUE
);
956 _DoFolderViewCB(SFVM_LISTREFRESHED
, NULL
, NULL
);
961 LRESULT
CDefView::OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
963 m_ListView
.UpdateWindow();
968 LRESULT
CDefView::OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
970 return m_ListView
.SendMessageW(uMsg
, 0, 0);
973 LRESULT
CDefView::OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
980 DestroyMenu(m_hMenu
);
983 RevokeDragDrop(m_hWnd
);
984 SHChangeNotifyDeregister(m_hNotify
);
986 SHFree(m_pidlParent
);
993 LRESULT
CDefView::OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
995 /* redirect to parent */
996 if (m_FolderSettings
.fFlags
& (FWF_DESKTOP
| FWF_TRANSPARENT
))
997 return SendMessageW(GetParent(), WM_ERASEBKGND
, wParam
, lParam
);
1003 LRESULT
CDefView::OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1005 /* Update desktop labels color */
1008 /* Forward WM_SYSCOLORCHANGE to common controls */
1009 return m_ListView
.SendMessageW(uMsg
, 0, 0);
1012 LRESULT
CDefView::OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1014 return reinterpret_cast<LRESULT
>(m_pShellBrowser
.p
);
1017 LRESULT
CDefView::OnNCCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1024 LRESULT
CDefView::OnNCDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1031 /**********************************************************
1032 * ShellView_OnCreate()
1034 LRESULT
CDefView::OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1036 CComPtr
<IDropTarget
> pdt
;
1037 SHChangeNotifyEntry ntreg
;
1038 CComPtr
<IPersistFolder2
> ppf2
;
1040 TRACE("%p\n", this);
1050 if (SUCCEEDED(QueryInterface(IID_PPV_ARG(IDropTarget
, &pdt
))))
1052 if (FAILED(RegisterDragDrop(m_hWnd
, pdt
)))
1053 ERR("Registering Drag Drop Failed");
1056 /* register for receiving notifications */
1057 m_pSFParent
->QueryInterface(IID_PPV_ARG(IPersistFolder2
, &ppf2
));
1060 ppf2
->GetCurFolder(&m_pidlParent
);
1061 ntreg
.fRecursive
= TRUE
;
1062 ntreg
.pidl
= m_pidlParent
;
1063 m_hNotify
= SHChangeNotifyRegister(m_hWnd
, SHCNRF_InterruptLevel
| SHCNRF_ShellLevel
, SHCNE_ALLEVENTS
, SHV_CHANGE_NOTIFY
, 1, &ntreg
);
1066 /* _DoFolderViewCB(SFVM_GETNOTIFY, ?? ??) */
1068 m_hAccel
= LoadAcceleratorsW(shell32_hInstance
, MAKEINTRESOURCEW(IDA_SHELLVIEW
));
1075 /**********************************************************
1076 * #### Handling of the menus ####
1079 extern "C" DWORD WINAPI
SHMenuIndexFromID(HMENU hMenu
, UINT uID
);
1081 HMENU
GetSubmenuByID(HMENU hmenu
, UINT id
)
1083 MENUITEMINFOW mii
= {sizeof(mii
), MIIM_SUBMENU
};
1084 if (::GetMenuItemInfoW(hmenu
, id
, FALSE
, &mii
))
1085 return mii
.hSubMenu
;
1090 /* ReallyGetMenuItemID returns the id of an item even if it opens a submenu,
1091 GetMenuItemID returns -1 if the specified item opens a submenu */
1092 UINT
ReallyGetMenuItemID(HMENU hmenu
, int i
)
1094 MENUITEMINFOW mii
= {sizeof(mii
), MIIM_ID
};
1095 if (::GetMenuItemInfoW(hmenu
, i
, TRUE
, &mii
))
1101 HRESULT
CDefView::FillFileMenu()
1103 HMENU hFileMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_FILE
);
1107 /* Cleanup the items added previously */
1108 for (int i
= GetMenuItemCount(hFileMenu
) - 1; i
>= 0; i
--)
1110 UINT id
= GetMenuItemID(hFileMenu
, i
);
1111 if (id
< FCIDM_BROWSERFIRST
|| id
> FCIDM_BROWSERLAST
)
1112 DeleteMenu(hFileMenu
, i
, MF_BYPOSITION
);
1115 /* Store the context menu in m_pCM and keep it in order to invoke the selected command later on */
1116 HRESULT hr
= GetItemObject(SVGIO_SELECTION
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1117 if (FAILED_UNEXPECTEDLY(hr
))
1120 HMENU hmenu
= CreatePopupMenu();
1122 hr
= m_pCM
->QueryContextMenu(hmenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, 0);
1123 if (FAILED_UNEXPECTEDLY(hr
))
1126 // TODO: filter or something
1128 Shell_MergeMenus(hFileMenu
, hmenu
, 0, 0, 0xFFFF, MM_ADDSEPARATOR
| MM_SUBMENUSHAVEIDS
);
1130 ::DestroyMenu(hmenu
);
1135 HRESULT
CDefView::FillEditMenu()
1137 HMENU hEditMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_EDIT
);
1141 HMENU hmenuContents
= ::LoadMenuW(shell32_hInstance
, L
"MENU_003");
1145 Shell_MergeMenus(hEditMenu
, hmenuContents
, 0, 0, 0xFFFF, 0);
1147 ::DestroyMenu(hmenuContents
);
1152 HRESULT
CDefView::FillViewMenu()
1154 HMENU hViewMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_VIEW
);
1158 m_hMenuViewModes
= ::LoadMenuW(shell32_hInstance
, L
"MENU_001");
1159 if (!m_hMenuViewModes
)
1162 UINT i
= SHMenuIndexFromID(hViewMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
);
1163 Shell_MergeMenus(hViewMenu
, m_hMenuViewModes
, i
, 0, 0xFFFF, MM_ADDSEPARATOR
| MM_DONTREMOVESEPS
| MM_SUBMENUSHAVEIDS
);
1168 HRESULT
CDefView::FillArrangeAsMenu(HMENU hmenuArrange
)
1170 /* We only need to fill this once */
1171 if (GetMenuItemID(hmenuArrange
, 0) == FCIDM_SHVIEW_AUTOARRANGE
)
1173 Shell_MergeMenus(hmenuArrange
, m_hMenuArrangeModes
, 0, 0, 0xFFFF,0);
1176 /* Also check the menu item according to which we sort */
1177 CheckMenuRadioItem(hmenuArrange
,
1180 m_sortInfo
.nHeaderID
+ 0x30,
1183 if (m_FolderSettings
.ViewMode
== FVM_DETAILS
|| m_FolderSettings
.ViewMode
== FVM_LIST
)
1185 EnableMenuItem(hmenuArrange
, FCIDM_SHVIEW_AUTOARRANGE
, MF_BYCOMMAND
| MF_GRAYED
);
1189 EnableMenuItem(hmenuArrange
, FCIDM_SHVIEW_AUTOARRANGE
, MF_BYCOMMAND
);
1191 if (GetAutoArrange() == S_OK
)
1192 CheckMenuItem(hmenuArrange
, FCIDM_SHVIEW_AUTOARRANGE
, MF_CHECKED
);
1199 HRESULT
CDefView::CheckViewMode(HMENU hmenuView
)
1201 if (m_FolderSettings
.ViewMode
>= FVM_FIRST
&& m_FolderSettings
.ViewMode
<= FVM_LAST
)
1203 UINT iItemFirst
= FCIDM_SHVIEW_BIGICON
;
1204 UINT iItemLast
= iItemFirst
+ FVM_LAST
- FVM_FIRST
;
1205 UINT iItem
= iItemFirst
+ m_FolderSettings
.ViewMode
- FVM_FIRST
;
1206 CheckMenuRadioItem(hmenuView
, iItemFirst
, iItemLast
, iItem
, MF_BYCOMMAND
);
1212 /**********************************************************
1213 * ShellView_GetSelections()
1215 * - fills the m_apidl list with the selected objects
1218 * number of selected items
1220 UINT
CDefView::GetSelections()
1224 m_cidl
= m_ListView
.GetSelectedCount();
1225 m_apidl
= static_cast<PCUITEMID_CHILD
*>(SHAlloc(m_cidl
* sizeof(PCUITEMID_CHILD
)));
1232 TRACE("-- Items selected =%u\n", m_cidl
);
1236 while ((lvIndex
= m_ListView
.GetNextItem(lvIndex
, LVNI_SELECTED
)) > -1)
1238 m_apidl
[i
] = _PidlByItem(lvIndex
);
1242 TRACE("-- selected Item found\n");
1248 HRESULT
CDefView::InvokeContextMenuCommand(UINT uCommand
)
1250 CMINVOKECOMMANDINFO cmi
;
1252 ZeroMemory(&cmi
, sizeof(cmi
));
1253 cmi
.cbSize
= sizeof(cmi
);
1254 cmi
.lpVerb
= MAKEINTRESOURCEA(uCommand
);
1257 if (GetKeyState(VK_SHIFT
) & 0x8000)
1258 cmi
.fMask
|= CMIC_MASK_SHIFT_DOWN
;
1260 if (GetKeyState(VK_CONTROL
) & 0x8000)
1261 cmi
.fMask
|= CMIC_MASK_CONTROL_DOWN
;
1263 HRESULT hr
= m_pCM
->InvokeCommand(&cmi
);
1264 if (FAILED_UNEXPECTEDLY(hr
))
1270 /**********************************************************
1271 * ShellView_OpenSelectedItems()
1273 HRESULT
CDefView::OpenSelectedItems()
1279 m_cidl
= m_ListView
.GetSelectedCount();
1283 hResult
= OnDefaultCommand();
1284 if (hResult
== S_OK
)
1287 hMenu
= CreatePopupMenu();
1291 hResult
= GetItemObject(SVGIO_SELECTION
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1292 if (FAILED_UNEXPECTEDLY(hResult
))
1295 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_DEFAULTONLY
);
1296 if (FAILED_UNEXPECTEDLY(hResult
))
1299 uCommand
= GetMenuDefaultItem(hMenu
, FALSE
, 0);
1300 if (uCommand
== (UINT
)-1)
1306 InvokeContextMenuCommand(uCommand
);
1315 IUnknown_SetSite(m_pCM
, NULL
);
1322 /**********************************************************
1323 * ShellView_DoContextMenu()
1325 LRESULT
CDefView::OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1331 TRACE("(%p)\n", this);
1333 m_hContextMenu
= CreatePopupMenu();
1334 if (!m_hContextMenu
)
1337 m_cidl
= m_ListView
.GetSelectedCount();
1339 hResult
= GetItemObject( m_cidl
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1340 if (FAILED_UNEXPECTEDLY(hResult
))
1343 /* Use 1 as the first id as we want 0 the mean that the user canceled the menu */
1344 hResult
= m_pCM
->QueryContextMenu(m_hContextMenu
, 0, CONTEXT_MENU_BASE_ID
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1345 if (FAILED_UNEXPECTEDLY(hResult
))
1348 /* There is no position requested, so try to find one */
1354 /* Do we have a focused item, */
1355 if ((lvIndex
= m_ListView
.GetNextItem(-1, LVIS_FOCUSED
)) < 0)
1357 /* or a selected item? */
1358 lvIndex
= m_ListView
.GetNextItem(-1, LVIS_SELECTED
);
1360 /* We got something */
1363 /* Let's find the center of the icon */
1364 RECT rc
= { LVIR_ICON
};
1365 m_ListView
.SendMessage(LVM_GETITEMRECT
, lvIndex
, (LPARAM
)&rc
);
1366 pt
.x
= (rc
.right
+ rc
.left
) / 2;
1367 pt
.y
= (rc
.bottom
+ rc
.top
) / 2;
1371 /* We have to drop it somewhere.. */
1375 m_ListView
.ClientToScreen(&pt
);
1381 x
= GET_X_LPARAM(lParam
);
1382 y
= GET_Y_LPARAM(lParam
);
1385 uCommand
= TrackPopupMenu(m_hContextMenu
,
1386 TPM_LEFTALIGN
| TPM_RETURNCMD
| TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
,
1387 x
, y
, 0, m_hWnd
, NULL
);
1391 if (uCommand
== FCIDM_SHVIEW_OPEN
&& OnDefaultCommand() == S_OK
)
1394 InvokeContextMenuCommand(uCommand
- CONTEXT_MENU_BASE_ID
);
1399 IUnknown_SetSite(m_pCM
, NULL
);
1405 DestroyMenu(m_hContextMenu
);
1406 m_hContextMenu
= NULL
;
1412 LRESULT
CDefView::OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
)
1417 hMenu
= CreatePopupMenu();
1421 hResult
= GetItemObject( bUseSelection
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1422 if (FAILED_UNEXPECTEDLY( hResult
))
1425 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1426 if (FAILED_UNEXPECTEDLY( hResult
))
1429 InvokeContextMenuCommand(uCommand
);
1434 IUnknown_SetSite(m_pCM
, NULL
);
1444 /**********************************************************
1445 * ##### message handling #####
1448 /**********************************************************
1449 * ShellView_OnSize()
1451 LRESULT
CDefView::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1453 WORD wWidth
, wHeight
;
1455 wWidth
= LOWORD(lParam
);
1456 wHeight
= HIWORD(lParam
);
1458 TRACE("%p width=%u height=%u\n", this, wWidth
, wHeight
);
1460 /* Resize the ListView to fit our window */
1463 ::MoveWindow(m_ListView
, 0, 0, wWidth
, wHeight
, TRUE
);
1466 _DoFolderViewCB(SFVM_SIZE
, 0, 0);
1471 /**********************************************************
1472 * ShellView_OnDeactivate()
1477 void CDefView::OnDeactivate()
1479 TRACE("%p\n", this);
1481 if (m_uState
!= SVUIA_DEACTIVATE
)
1483 // TODO: cleanup menu after deactivation
1485 m_uState
= SVUIA_DEACTIVATE
;
1489 void CDefView::DoActivate(UINT uState
)
1491 TRACE("%p uState=%x\n", this, uState
);
1493 /*don't do anything if the state isn't really changing */
1494 if (m_uState
== uState
)
1499 if (uState
== SVUIA_DEACTIVATE
)
1505 if(m_hMenu
&& !m_bmenuBarInitialized
)
1509 m_pShellBrowser
->SetMenuSB(m_hMenu
, 0, m_hWnd
);
1510 m_bmenuBarInitialized
= TRUE
;
1513 if (SVUIA_ACTIVATE_FOCUS
== uState
)
1515 m_ListView
.SetFocus();
1523 /**********************************************************
1524 * ShellView_OnActivate()
1526 LRESULT
CDefView::OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1528 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1532 /**********************************************************
1533 * ShellView_OnSetFocus()
1536 LRESULT
CDefView::OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1538 TRACE("%p\n", this);
1540 /* Tell the browser one of our windows has received the focus. This
1541 should always be done before merging menus (OnActivate merges the
1542 menus) if one of our windows has the focus.*/
1544 m_pShellBrowser
->OnViewWindowActive(this);
1545 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1547 /* Set the focus to the listview */
1548 m_ListView
.SetFocus();
1550 /* Notify the ICommDlgBrowser interface */
1551 OnStateChange(CDBOSC_SETFOCUS
);
1556 /**********************************************************
1557 * ShellView_OnKillFocus()
1559 LRESULT
CDefView::OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1561 TRACE("(%p) stub\n", this);
1563 DoActivate(SVUIA_ACTIVATE_NOFOCUS
);
1564 /* Notify the ICommDlgBrowser */
1565 OnStateChange(CDBOSC_KILLFOCUS
);
1570 /**********************************************************
1571 * ShellView_OnCommand()
1574 * the CmdID's are the ones from the context menu
1576 LRESULT
CDefView::OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1583 dwCmdID
= GET_WM_COMMAND_ID(wParam
, lParam
);
1584 dwCmd
= GET_WM_COMMAND_CMD(wParam
, lParam
);
1585 hwndCmd
= GET_WM_COMMAND_HWND(wParam
, lParam
);
1587 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n", this, dwCmdID
, dwCmd
, hwndCmd
);
1591 case FCIDM_SHVIEW_SMALLICON
:
1592 m_FolderSettings
.ViewMode
= FVM_SMALLICON
;
1593 m_ListView
.ModifyStyle(LVS_TYPEMASK
, LVS_SMALLICON
);
1597 case FCIDM_SHVIEW_BIGICON
:
1598 m_FolderSettings
.ViewMode
= FVM_ICON
;
1599 m_ListView
.ModifyStyle(LVS_TYPEMASK
, LVS_ICON
);
1603 case FCIDM_SHVIEW_LISTVIEW
:
1604 m_FolderSettings
.ViewMode
= FVM_LIST
;
1605 m_ListView
.ModifyStyle(LVS_TYPEMASK
, LVS_LIST
);
1609 case FCIDM_SHVIEW_REPORTVIEW
:
1610 m_FolderSettings
.ViewMode
= FVM_DETAILS
;
1611 m_ListView
.ModifyStyle(LVS_TYPEMASK
, LVS_REPORT
);
1615 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1620 m_sortInfo
.nHeaderID
= dwCmdID
- 0x30;
1621 m_sortInfo
.bIsAscending
= TRUE
;
1625 case FCIDM_SHVIEW_SNAPTOGRID
:
1628 case FCIDM_SHVIEW_AUTOARRANGE
:
1629 if (GetAutoArrange() == S_OK
)
1630 m_ListView
.ModifyStyle(LVS_AUTOARRANGE
, 0);
1634 case FCIDM_SHVIEW_SELECTALL
:
1635 m_ListView
.SetItemState(-1, LVIS_SELECTED
, LVIS_SELECTED
);
1638 case FCIDM_SHVIEW_INVERTSELECTION
:
1639 nCount
= m_ListView
.GetItemCount();
1640 for (int i
=0; i
< nCount
; i
++)
1641 m_ListView
.SetItemState(i
, m_ListView
.GetItemState(i
, LVIS_SELECTED
) ? 0 : LVIS_SELECTED
, LVIS_SELECTED
);
1644 case FCIDM_SHVIEW_REFRESH
:
1648 case FCIDM_SHVIEW_DELETE
:
1649 case FCIDM_SHVIEW_CUT
:
1650 case FCIDM_SHVIEW_COPY
:
1651 case FCIDM_SHVIEW_RENAME
:
1652 case FCIDM_SHVIEW_PROPERTIES
:
1653 return OnExplorerCommand(dwCmdID
, TRUE
);
1655 case FCIDM_SHVIEW_INSERT
:
1656 case FCIDM_SHVIEW_UNDO
:
1657 case FCIDM_SHVIEW_INSERTLINK
:
1658 case FCIDM_SHVIEW_NEWFOLDER
:
1659 return OnExplorerCommand(dwCmdID
, FALSE
);
1661 /* WM_COMMAND messages from the file menu are routed to the CDefView so as to let m_pCM handle the command */
1662 if (m_pCM
&& dwCmd
== 0)
1664 InvokeContextMenuCommand(dwCmdID
);
1671 /**********************************************************
1672 * ShellView_OnNotify()
1675 LRESULT
CDefView::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1679 LPNMLISTVIEW lpnmlv
;
1680 NMLVDISPINFOW
*lpdi
;
1681 PCUITEMID_CHILD pidl
;
1685 lpnmh
= (LPNMHDR
)lParam
;
1686 lpnmlv
= (LPNMLISTVIEW
)lpnmh
;
1687 lpdi
= (NMLVDISPINFOW
*)lpnmh
;
1689 TRACE("%p CtlID=%u lpnmh->code=%x\n", this, CtlID
, lpnmh
->code
);
1691 switch (lpnmh
->code
)
1694 TRACE("-- NM_SETFOCUS %p\n", this);
1695 OnSetFocus(0, 0, 0, unused
);
1699 TRACE("-- NM_KILLFOCUS %p\n", this);
1701 /* Notify the ICommDlgBrowser interface */
1702 OnStateChange(CDBOSC_KILLFOCUS
);
1706 TRACE("-- NM_CUSTOMDRAW %p\n", this);
1707 return CDRF_DODEFAULT
;
1709 case NM_RELEASEDCAPTURE
:
1710 TRACE("-- NM_RELEASEDCAPTURE %p\n", this);
1714 TRACE("-- NM_CLICK %p\n", this);
1718 TRACE("-- NM_RCLICK %p\n", this);
1722 TRACE("-- NM_DBLCLK %p\n", this);
1723 OpenSelectedItems();
1727 TRACE("-- NM_RETURN %p\n", this);
1728 OpenSelectedItems();
1732 TRACE("-- HDN_ENDTRACKW %p\n", this);
1733 /*nColumn1 = m_ListView.GetColumnWidth(0);
1734 nColumn2 = m_ListView.GetColumnWidth(1);*/
1737 case LVN_DELETEITEM
:
1738 TRACE("-- LVN_DELETEITEM %p\n", this);
1740 /*delete the pidl because we made a copy of it*/
1741 SHFree(reinterpret_cast<LPVOID
>(lpnmlv
->lParam
));
1745 case LVN_DELETEALLITEMS
:
1746 TRACE("-- LVN_DELETEALLITEMS %p\n", this);
1749 case LVN_INSERTITEM
:
1750 TRACE("-- LVN_INSERTITEM (STUB)%p\n", this);
1753 case LVN_ITEMACTIVATE
:
1754 TRACE("-- LVN_ITEMACTIVATE %p\n", this);
1755 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1758 case LVN_COLUMNCLICK
:
1759 m_sortInfo
.nHeaderID
= lpnmlv
->iSubItem
;
1760 if (m_sortInfo
.nLastHeaderID
== m_sortInfo
.nHeaderID
)
1761 m_sortInfo
.bIsAscending
= !m_sortInfo
.bIsAscending
;
1763 m_sortInfo
.bIsAscending
= TRUE
;
1767 case LVN_GETDISPINFOA
:
1768 case LVN_GETDISPINFOW
:
1769 TRACE("-- LVN_GETDISPINFO %p\n", this);
1770 pidl
= _PidlByItem(lpdi
->item
);
1772 if (lpdi
->item
.mask
& LVIF_TEXT
) /* text requested */
1777 if (FAILED_UNEXPECTEDLY(m_pSF2Parent
->GetDetailsOf(pidl
, lpdi
->item
.iSubItem
, &sd
)))
1780 if (lpnmh
->code
== LVN_GETDISPINFOA
)
1782 /* shouldn't happen */
1783 NMLVDISPINFOA
*lpdiA
= (NMLVDISPINFOA
*)lpnmh
;
1784 StrRetToStrNA( lpdiA
->item
.pszText
, lpdiA
->item
.cchTextMax
, &sd
.str
, NULL
);
1785 TRACE("-- text=%s\n", lpdiA
->item
.pszText
);
1787 else /* LVN_GETDISPINFOW */
1789 StrRetToStrNW( lpdi
->item
.pszText
, lpdi
->item
.cchTextMax
, &sd
.str
, NULL
);
1790 TRACE("-- text=%s\n", debugstr_w(lpdi
->item
.pszText
));
1795 FIXME("no m_pSF2Parent\n");
1798 if(lpdi
->item
.mask
& LVIF_IMAGE
) /* image requested */
1800 lpdi
->item
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
1802 if(lpdi
->item
.mask
& LVIF_STATE
)
1804 ULONG attributes
= SFGAO_HIDDEN
;
1805 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(1, &pidl
, &attributes
)))
1807 if (attributes
& SFGAO_HIDDEN
)
1809 lpdi
->item
.state
|= LVIS_CUT
;
1813 lpdi
->item
.mask
|= LVIF_DI_SETITEM
;
1816 case LVN_ITEMCHANGED
:
1817 TRACE("-- LVN_ITEMCHANGED %p\n", this);
1818 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1820 _DoFolderViewCB(SFVM_SELECTIONCHANGED
, NULL
/* FIXME */, NULL
/* FIXME */);
1824 case LVN_BEGINRDRAG
:
1825 TRACE("-- LVN_BEGINDRAG\n");
1827 if (GetSelections())
1829 CComPtr
<IDataObject
> pda
;
1830 DWORD dwAttributes
= SFGAO_CANCOPY
| SFGAO_CANLINK
;
1831 DWORD dwEffect
= DROPEFFECT_MOVE
;
1833 if (SUCCEEDED(m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, IID_NULL_PPV_ARG(IDataObject
, &pda
))))
1835 LPNMLISTVIEW params
= (LPNMLISTVIEW
)lParam
;
1837 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(m_cidl
, m_apidl
, &dwAttributes
)))
1839 dwEffect
|= dwAttributes
& (SFGAO_CANCOPY
| SFGAO_CANLINK
);
1842 CComPtr
<IAsyncOperation
> piaso
;
1843 if (SUCCEEDED(pda
->QueryInterface(IID_PPV_ARG(IAsyncOperation
, &piaso
))))
1845 piaso
->SetAsyncMode(TRUE
);
1850 m_pSourceDataObject
= pda
;
1851 m_ptFirstMousePos
= params
->ptAction
;
1852 ClientToScreen(&m_ptFirstMousePos
);
1854 HIMAGELIST big_icons
, small_icons
;
1855 Shell_GetImageLists(&big_icons
, &small_icons
);
1856 PCUITEMID_CHILD pidl
= _PidlByItem(params
->iItem
);
1857 int iIcon
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
1859 m_ListView
.GetItemPosition(params
->iItem
, &ptItem
);
1861 ImageList_BeginDrag(big_icons
, iIcon
, params
->ptAction
.x
- ptItem
.x
, params
->ptAction
.y
- ptItem
.y
);
1863 DoDragDrop(pda
, this, dwEffect
, &dwEffect2
);
1865 m_pSourceDataObject
.Release();
1870 case LVN_BEGINLABELEDITW
:
1872 DWORD dwAttr
= SFGAO_CANRENAME
;
1873 pidl
= _PidlByItem(lpdi
->item
);
1875 TRACE("-- LVN_BEGINLABELEDITW %p\n", this);
1877 m_pSFParent
->GetAttributesOf(1, &pidl
, &dwAttr
);
1878 if (SFGAO_CANRENAME
& dwAttr
)
1886 case LVN_ENDLABELEDITW
:
1888 TRACE("-- LVN_ENDLABELEDITW %p\n", this);
1890 m_isEditing
= FALSE
;
1892 if (lpdi
->item
.pszText
)
1897 pidl
= _PidlByItem(lpdi
->item
);
1898 PITEMID_CHILD pidlNew
= NULL
;
1899 hr
= m_pSFParent
->SetNameOf(0, pidl
, lpdi
->item
.pszText
, SHGDN_INFOLDER
, &pidlNew
);
1901 if (SUCCEEDED(hr
) && pidlNew
)
1903 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
1904 lvItem
.iItem
= lpdi
->item
.iItem
;
1905 lvItem
.iSubItem
= 0;
1906 lvItem
.lParam
= reinterpret_cast<LPARAM
>(pidlNew
);
1907 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
1908 m_ListView
.SetItem(&lvItem
);
1909 m_ListView
.Update(lpdi
->item
.iItem
);
1918 TRACE("-- %p WM_COMMAND %x unhandled\n", this, lpnmh
->code
);
1926 * This is just a quick hack to make the desktop work correctly.
1927 * ITranslateShellChangeNotify's IsChildID is undocumented, but most likely the way that
1928 * a folder should know if it should update upon a change notification.
1929 * It is exported by merged folders at a minimum.
1931 static BOOL
ILIsParentOrSpecialParent(PCIDLIST_ABSOLUTE pidl1
, PCIDLIST_ABSOLUTE pidl2
)
1933 if (!pidl1
|| !pidl2
)
1935 if (ILIsParent(pidl1
, pidl2
, TRUE
))
1938 if (_ILIsDesktop(pidl1
))
1940 PIDLIST_ABSOLUTE deskpidl
;
1941 SHGetFolderLocation(NULL
, CSIDL_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
1942 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
1948 SHGetFolderLocation(NULL
, CSIDL_COMMON_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
1949 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
1959 /**********************************************************
1960 * ShellView_OnChange()
1962 LRESULT
CDefView::OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1964 PCIDLIST_ABSOLUTE
*Pidls
= reinterpret_cast<PCIDLIST_ABSOLUTE
*>(wParam
);
1965 BOOL bParent0
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[0]);
1966 BOOL bParent1
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[1]);
1968 TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls
[0], Pidls
[1], lParam
);
1970 switch (lParam
&~ SHCNE_INTERRUPT
)
1976 if (LV_FindItemByPidl(ILFindLastID(Pidls
[0])) == -1)
1978 LV_AddItem(ILFindLastID(Pidls
[0]));
1982 LV_ProdItem(ILFindLastID(Pidls
[0]));
1990 LV_DeleteItem(ILFindLastID(Pidls
[0]));
1993 case SHCNE_RENAMEFOLDER
:
1994 case SHCNE_RENAMEITEM
:
1995 if (bParent0
&& bParent1
)
1996 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[1]));
1998 LV_DeleteItem(ILFindLastID(Pidls
[0]));
2000 LV_AddItem(ILFindLastID(Pidls
[1]));
2003 case SHCNE_UPDATEITEM
:
2005 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[0]));
2008 case SHCNE_UPDATEDIR
:
2015 HRESULT
SHGetMenuIdFromMenuMsg(UINT uMsg
, LPARAM lParam
, UINT
*CmdId
);
2016 HRESULT
SHSetMenuIdInMenuMsg(UINT uMsg
, LPARAM lParam
, UINT CmdId
);
2018 /**********************************************************
2019 * CDefView::OnCustomItem
2021 LRESULT
CDefView::OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
2026 ERR("no menu!!!\n");
2030 /* The lParam of WM_DRAWITEM WM_MEASUREITEM contain a menu id and this also needs to
2031 be changed to a menu identifier offset */
2033 HRESULT hres
= SHGetMenuIdFromMenuMsg(uMsg
, lParam
, &CmdID
);
2034 if (SUCCEEDED(hres
))
2035 SHSetMenuIdInMenuMsg(uMsg
, lParam
, CmdID
- CONTEXT_MENU_BASE_ID
);
2037 /* Forward the message to the IContextMenu2 */
2039 hres
= SHForwardContextMenuMsg(m_pCM
, uMsg
, wParam
, lParam
, &result
, TRUE
);
2041 return (SUCCEEDED(hres
));
2044 LRESULT
CDefView::OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
2046 /* Wallpaper setting affects drop shadows effect */
2047 if (wParam
== SPI_SETDESKWALLPAPER
|| wParam
== 0)
2053 /**********************************************************
2054 * CDefView::OnInitMenuPopup
2056 LRESULT
CDefView::OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
2058 HMENU hmenu
= (HMENU
) wParam
;
2059 int nPos
= LOWORD(lParam
);
2062 OnCustomItem(uMsg
, wParam
, lParam
, bHandled
);
2064 HMENU hViewMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_VIEW
);
2066 /* Lets try to find out what the hell wParam is */
2067 if (hmenu
== GetSubMenu(m_hMenu
, nPos
))
2068 menuItemId
= ReallyGetMenuItemID(m_hMenu
, nPos
);
2069 else if (hViewMenu
&& hmenu
== GetSubMenu(hViewMenu
, nPos
))
2070 menuItemId
= ReallyGetMenuItemID(hViewMenu
, nPos
);
2071 else if (m_hContextMenu
&& hmenu
== GetSubMenu(m_hContextMenu
, nPos
))
2072 menuItemId
= ReallyGetMenuItemID(m_hContextMenu
, nPos
);
2078 case FCIDM_MENU_FILE
:
2081 case FCIDM_MENU_VIEW
:
2082 case FCIDM_SHVIEW_VIEW
:
2083 CheckViewMode(hmenu
);
2085 case FCIDM_SHVIEW_ARRANGE
:
2086 FillArrangeAsMenu(hmenu
);
2093 /**********************************************************
2096 * The INTERFACE of the IShellView object
2099 **********************************************************
2102 /**********************************************************
2103 * ShellView_GetWindow
2105 HRESULT WINAPI
CDefView::GetWindow(HWND
*phWnd
)
2107 TRACE("(%p)\n", this);
2114 HRESULT WINAPI
CDefView::ContextSensitiveHelp(BOOL fEnterMode
)
2116 FIXME("(%p) stub\n", this);
2121 /**********************************************************
2122 * IShellView_TranslateAccelerator
2125 * use the accel functions
2127 HRESULT WINAPI
CDefView::TranslateAccelerator(LPMSG lpmsg
)
2132 if (lpmsg
->message
>= WM_KEYFIRST
&& lpmsg
->message
<= WM_KEYLAST
)
2134 if (::TranslateAcceleratorW(m_hWnd
, m_hAccel
, lpmsg
) != 0)
2137 TRACE("-- key=0x%04lx\n", lpmsg
->wParam
) ;
2140 return m_pShellBrowser
->TranslateAcceleratorSB(lpmsg
, 0);
2143 HRESULT WINAPI
CDefView::EnableModeless(BOOL fEnable
)
2145 FIXME("(%p) stub\n", this);
2150 HRESULT WINAPI
CDefView::UIActivate(UINT uState
)
2152 // CHAR szName[MAX_PATH];
2154 int nPartArray
[1] = { -1};
2156 TRACE("(%p)->(state=%x) stub\n", this, uState
);
2158 /* don't do anything if the state isn't really changing */
2159 if (m_uState
== uState
)
2164 /* OnActivate handles the menu merging and internal state */
2167 /* only do This if we are active */
2168 if (uState
!= SVUIA_DEACTIVATE
)
2172 GetFolderPath is not a method of IShellFolder
2173 IShellFolder_GetFolderPath( m_pSFParent, szName, sizeof(szName) );
2175 /* set the number of parts */
2176 m_pShellBrowser
->SendControlMsg(FCW_STATUS
, SB_SETPARTS
, 1, (LPARAM
)nPartArray
, &lResult
);
2178 /* set the text for the parts */
2180 m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXTA, 0, (LPARAM)szName, &lResult);
2187 HRESULT WINAPI
CDefView::Refresh()
2189 TRACE("(%p)\n", this);
2191 m_ListView
.DeleteAllItems();
2197 HRESULT WINAPI
CDefView::CreateViewWindow(IShellView
*lpPrevView
, LPCFOLDERSETTINGS lpfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
)
2199 return CreateViewWindow3(psb
, lpPrevView
, SV3CVW3_DEFAULT
,
2200 (FOLDERFLAGS
)lpfs
->fFlags
, (FOLDERFLAGS
)lpfs
->fFlags
, (FOLDERVIEWMODE
)lpfs
->ViewMode
, NULL
, prcView
, phWnd
);
2203 HRESULT WINAPI
CDefView::DestroyViewWindow()
2205 TRACE("(%p)\n", this);
2207 /* Make absolutely sure all our UI is cleaned up */
2208 UIActivate(SVUIA_DEACTIVATE
);
2212 // "Accelerator tables loaded from resources are freed automatically when the application terminates." -- MSDN
2216 if (m_hMenuArrangeModes
)
2218 DestroyMenu(m_hMenuArrangeModes
);
2219 m_hMenuArrangeModes
= NULL
;
2222 if (m_hMenuViewModes
)
2224 DestroyMenu(m_hMenuViewModes
);
2225 m_hMenuViewModes
= NULL
;
2230 DestroyMenu(m_hMenu
);
2236 m_ListView
.DestroyWindow();
2244 m_pShellBrowser
.Release();
2245 m_pCommDlgBrowser
.Release();
2250 HRESULT WINAPI
CDefView::GetCurrentInfo(LPFOLDERSETTINGS lpfs
)
2252 TRACE("(%p)->(%p) vmode=%x flags=%x\n", this, lpfs
,
2253 m_FolderSettings
.ViewMode
, m_FolderSettings
.fFlags
);
2256 return E_INVALIDARG
;
2258 *lpfs
= m_FolderSettings
;
2262 HRESULT WINAPI
CDefView::AddPropertySheetPages(DWORD dwReserved
, LPFNADDPROPSHEETPAGE lpfn
, LPARAM lparam
)
2264 FIXME("(%p) stub\n", this);
2269 HRESULT WINAPI
CDefView::SaveViewState()
2271 FIXME("(%p) stub\n", this);
2276 HRESULT WINAPI
CDefView::SelectItem(PCUITEMID_CHILD pidl
, UINT uFlags
)
2280 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n", this, pidl
, uFlags
);
2282 i
= LV_FindItemByPidl(pidl
);
2286 if(uFlags
& SVSI_ENSUREVISIBLE
)
2287 m_ListView
.EnsureVisible(i
, FALSE
);
2289 LVITEMW lvItem
= {0};
2290 lvItem
.mask
= LVIF_STATE
;
2291 lvItem
.stateMask
= LVIS_SELECTED
| LVIS_FOCUSED
;
2293 while (m_ListView
.GetItem(&lvItem
))
2295 if (lvItem
.iItem
== i
)
2297 if (uFlags
& SVSI_SELECT
)
2298 lvItem
.state
|= LVIS_SELECTED
;
2300 lvItem
.state
&= ~LVIS_SELECTED
;
2302 if (uFlags
& SVSI_FOCUSED
)
2303 lvItem
.state
&= ~LVIS_FOCUSED
;
2307 if (uFlags
& SVSI_DESELECTOTHERS
)
2308 lvItem
.state
&= ~LVIS_SELECTED
;
2311 m_ListView
.SetItem(&lvItem
);
2315 if((uFlags
& SVSI_EDIT
) == SVSI_EDIT
)
2316 m_ListView
.EditLabel(i
);
2321 HRESULT WINAPI
CDefView::GetItemObject(UINT uItem
, REFIID riid
, LPVOID
*ppvOut
)
2323 HRESULT hr
= E_NOINTERFACE
;
2325 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n", this, uItem
, debugstr_guid(&riid
), ppvOut
);
2331 case SVGIO_BACKGROUND
:
2332 if (IsEqualIID(riid
, IID_IContextMenu
))
2337 hr
= CDefViewBckgrndMenu_CreateInstance(m_pSF2Parent
, riid
, ppvOut
);
2338 if (FAILED_UNEXPECTEDLY(hr
))
2341 IUnknown_SetSite(*((IUnknown
**)ppvOut
), (IShellView
*)this);
2343 else if (IsEqualIID(riid
, IID_IDispatch
))
2345 if (m_pShellFolderViewDual
== NULL
)
2347 hr
= CDefViewDual_Constructor(riid
, (LPVOID
*)&m_pShellFolderViewDual
);
2348 if (FAILED_UNEXPECTEDLY(hr
))
2351 hr
= m_pShellFolderViewDual
->QueryInterface(riid
, ppvOut
);
2355 case SVGIO_SELECTION
:
2357 hr
= m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, riid
, 0, ppvOut
);
2358 if (FAILED_UNEXPECTEDLY(hr
))
2361 if (IsEqualIID(riid
, IID_IContextMenu
))
2362 IUnknown_SetSite(*((IUnknown
**)ppvOut
), (IShellView
*)this);
2367 TRACE("-- (%p)->(interface=%p)\n", this, *ppvOut
);
2372 HRESULT STDMETHODCALLTYPE
CDefView::GetCurrentViewMode(UINT
*pViewMode
)
2374 TRACE("(%p)->(%p), stub\n", this, pViewMode
);
2377 return E_INVALIDARG
;
2379 *pViewMode
= m_FolderSettings
.ViewMode
;
2383 HRESULT STDMETHODCALLTYPE
CDefView::SetCurrentViewMode(UINT ViewMode
)
2386 TRACE("(%p)->(%u), stub\n", this, ViewMode
);
2388 /* It's not redundant to check FVM_AUTO because it's a (UINT)-1 */
2389 if (((INT
)ViewMode
< FVM_FIRST
|| (INT
)ViewMode
> FVM_LAST
) && ((INT
)ViewMode
!= FVM_AUTO
))
2390 return E_INVALIDARG
;
2392 /* Windows before Vista uses LVM_SETVIEW and possibly
2393 LVM_SETEXTENDEDLISTVIEWSTYLE to set the style of the listview,
2394 while later versions seem to accomplish this through other
2402 dwStyle
= LVS_REPORT
;
2405 dwStyle
= LVS_SMALLICON
;
2412 FIXME("ViewMode %d not implemented\n", ViewMode
);
2418 m_ListView
.ModifyStyle(LVS_TYPEMASK
, dwStyle
);
2420 /* This will not necessarily be the actual mode set above.
2421 This mimics the behavior of Windows XP. */
2422 m_FolderSettings
.ViewMode
= ViewMode
;
2427 HRESULT STDMETHODCALLTYPE
CDefView::GetFolder(REFIID riid
, void **ppv
)
2429 if (m_pSFParent
== NULL
)
2432 return m_pSFParent
->QueryInterface(riid
, ppv
);
2435 HRESULT STDMETHODCALLTYPE
CDefView::Item(int iItemIndex
, PITEMID_CHILD
*ppidl
)
2437 PCUITEMID_CHILD pidl
= _PidlByItem(iItemIndex
);
2440 *ppidl
= ILClone(pidl
);
2445 return E_INVALIDARG
;
2448 HRESULT STDMETHODCALLTYPE
CDefView::ItemCount(UINT uFlags
, int *pcItems
)
2450 TRACE("(%p)->(%u %p)\n", this, uFlags
, pcItems
);
2452 if (uFlags
!= SVGIO_ALLVIEW
)
2453 FIXME("some flags unsupported, %x\n", uFlags
& ~SVGIO_ALLVIEW
);
2455 *pcItems
= m_ListView
.GetItemCount();
2460 HRESULT STDMETHODCALLTYPE
CDefView::Items(UINT uFlags
, REFIID riid
, void **ppv
)
2465 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectionMarkedItem(int *piItem
)
2467 TRACE("(%p)->(%p)\n", this, piItem
);
2469 *piItem
= m_ListView
.GetSelectionMark();
2474 HRESULT STDMETHODCALLTYPE
CDefView::GetFocusedItem(int *piItem
)
2476 TRACE("(%p)->(%p)\n", this, piItem
);
2478 *piItem
= m_ListView
.GetNextItem(-1, LVNI_FOCUSED
);
2483 HRESULT STDMETHODCALLTYPE
CDefView::GetItemPosition(PCUITEMID_CHILD pidl
, POINT
*ppt
)
2485 int lvIndex
= LV_FindItemByPidl(pidl
);
2486 if (lvIndex
== -1 || ppt
== NULL
)
2487 return E_INVALIDARG
;
2489 m_ListView
.GetItemPosition(lvIndex
, ppt
);
2493 HRESULT STDMETHODCALLTYPE
CDefView::GetSpacing(POINT
*ppt
)
2495 TRACE("(%p)->(%p)\n", this, ppt
);
2503 m_ListView
.GetItemSpacing(spacing
);
2505 ppt
->x
= spacing
.cx
;
2506 ppt
->y
= spacing
.cy
;
2512 HRESULT STDMETHODCALLTYPE
CDefView::GetDefaultSpacing(POINT
*ppt
)
2517 HRESULT STDMETHODCALLTYPE
CDefView::GetAutoArrange()
2519 return ((m_ListView
.GetStyle() & LVS_AUTOARRANGE
) ? S_OK
: S_FALSE
);
2522 HRESULT STDMETHODCALLTYPE
CDefView::SelectItem(int iItem
, DWORD dwFlags
)
2526 TRACE("(%p)->(%d, %x)\n", this, iItem
, dwFlags
);
2529 lvItem
.stateMask
= LVIS_SELECTED
;
2531 if (dwFlags
& SVSI_ENSUREVISIBLE
)
2532 m_ListView
.EnsureVisible(iItem
, 0);
2535 if (dwFlags
& SVSI_DESELECTOTHERS
)
2536 m_ListView
.SetItemState(-1, 0, LVIS_SELECTED
);
2539 if (dwFlags
& SVSI_SELECT
)
2540 lvItem
.state
|= LVIS_SELECTED
;
2542 if (dwFlags
& SVSI_FOCUSED
)
2543 lvItem
.stateMask
|= LVIS_FOCUSED
;
2545 m_ListView
.SetItemState(iItem
, lvItem
.state
, lvItem
.stateMask
);
2547 if ((dwFlags
& SVSI_EDIT
) == SVSI_EDIT
)
2548 m_ListView
.EditLabel(iItem
);
2553 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItems(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD dwFlags
)
2555 /* Reset the selection */
2556 m_ListView
.SetItemState(-1, 0, LVIS_SELECTED
);
2559 for (UINT i
= 0 ; i
< m_cidl
; i
++)
2561 lvIndex
= LV_FindItemByPidl(apidl
[i
]);
2564 SelectItem(lvIndex
, dwFlags
);
2565 m_ListView
.SetItemPosition(lvIndex
, &apt
[i
]);
2572 /**********************************************************
2573 * IShellView2 implementation
2576 HRESULT STDMETHODCALLTYPE
CDefView::GetView(SHELLVIEWID
*view_guid
, ULONG view_type
)
2578 FIXME("(%p)->(%p, %lu) stub\n", this, view_guid
, view_type
);
2582 HRESULT STDMETHODCALLTYPE
CDefView::CreateViewWindow2(LPSV2CVW2_PARAMS view_params
)
2584 return CreateViewWindow3(view_params
->psbOwner
, view_params
->psvPrev
,
2585 SV3CVW3_DEFAULT
, (FOLDERFLAGS
)view_params
->pfs
->fFlags
, (FOLDERFLAGS
)view_params
->pfs
->fFlags
,
2586 (FOLDERVIEWMODE
)view_params
->pfs
->ViewMode
, view_params
->pvid
, view_params
->prcView
, &view_params
->hwndView
);
2589 HRESULT STDMETHODCALLTYPE
CDefView::CreateViewWindow3(IShellBrowser
*psb
, IShellView
*psvPrevious
, SV3CVW3_FLAGS view_flags
, FOLDERFLAGS mask
, FOLDERFLAGS flags
, FOLDERVIEWMODE mode
, const SHELLVIEWID
*view_id
, RECT
*prcView
, HWND
*hwnd
)
2591 OLEMENUGROUPWIDTHS omw
= { { 0, 0, 0, 0, 0, 0 } };
2595 TRACE("(%p)->(shlview=%p shlbrs=%p rec=%p hwnd=%p vmode=%x flags=%x)\n", this, psvPrevious
, psb
, prcView
, hwnd
, mode
, flags
);
2596 if (prcView
!= NULL
)
2597 TRACE("-- left=%i top=%i right=%i bottom=%i\n", prcView
->left
, prcView
->top
, prcView
->right
, prcView
->bottom
);
2599 /* Validate the Shell Browser */
2600 if (psb
== NULL
|| m_hWnd
)
2601 return E_UNEXPECTED
;
2603 if (view_flags
!= SV3CVW3_DEFAULT
)
2604 FIXME("unsupported view flags 0x%08x\n", view_flags
);
2606 /* Set up the member variables */
2607 m_pShellBrowser
= psb
;
2608 m_FolderSettings
.ViewMode
= mode
;
2609 m_FolderSettings
.fFlags
= mask
& flags
;
2613 if (IsEqualIID(*view_id
, VID_LargeIcons
))
2614 m_FolderSettings
.ViewMode
= FVM_ICON
;
2615 else if (IsEqualIID(*view_id
, VID_SmallIcons
))
2616 m_FolderSettings
.ViewMode
= FVM_SMALLICON
;
2617 else if (IsEqualIID(*view_id
, VID_List
))
2618 m_FolderSettings
.ViewMode
= FVM_LIST
;
2619 else if (IsEqualIID(*view_id
, VID_Details
))
2620 m_FolderSettings
.ViewMode
= FVM_DETAILS
;
2621 else if (IsEqualIID(*view_id
, VID_Thumbnails
))
2622 m_FolderSettings
.ViewMode
= FVM_THUMBNAIL
;
2623 else if (IsEqualIID(*view_id
, VID_Tile
))
2624 m_FolderSettings
.ViewMode
= FVM_TILE
;
2625 else if (IsEqualIID(*view_id
, VID_ThumbStrip
))
2626 m_FolderSettings
.ViewMode
= FVM_THUMBSTRIP
;
2628 FIXME("Ignoring unrecognized VID %s\n", debugstr_guid(view_id
));
2631 /* Get our parent window */
2632 m_pShellBrowser
->GetWindow(&m_hWndParent
);
2634 /* Try to get the ICommDlgBrowserInterface, adds a reference !!! */
2635 m_pCommDlgBrowser
= NULL
;
2636 if (SUCCEEDED(m_pShellBrowser
->QueryInterface(IID_PPV_ARG(ICommDlgBrowser
, &m_pCommDlgBrowser
))))
2638 TRACE("-- CommDlgBrowser\n");
2641 Create(m_hWndParent
, prcView
, NULL
, WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
| WS_TABSTOP
, 0, 0U);
2652 _DoFolderViewCB(SFVM_WINDOWCREATED
, (WPARAM
)m_hWnd
, NULL
);
2654 SetWindowPos(HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_SHOWWINDOW
);
2659 m_hMenu
= CreateMenu();
2660 m_pShellBrowser
->InsertMenusSB(m_hMenu
, &omw
);
2661 TRACE("-- after fnInsertMenusSB\n");
2669 HRESULT STDMETHODCALLTYPE
CDefView::HandleRename(LPCITEMIDLIST new_pidl
)
2671 FIXME("(%p)->(%p) stub\n", this, new_pidl
);
2675 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItem(LPCITEMIDLIST item
, UINT flags
, POINT
*point
)
2677 FIXME("(%p)->(%p, %u, %p) stub\n", this, item
, flags
, point
);
2681 /**********************************************************
2682 * IShellFolderView implementation
2684 HRESULT STDMETHODCALLTYPE
CDefView::Rearrange(LPARAM sort
)
2686 FIXME("(%p)->(%ld) stub\n", this, sort
);
2690 HRESULT STDMETHODCALLTYPE
CDefView::GetArrangeParam(LPARAM
*sort
)
2692 FIXME("(%p)->(%p) stub\n", this, sort
);
2696 HRESULT STDMETHODCALLTYPE
CDefView::ArrangeGrid()
2698 FIXME("(%p) stub\n", this);
2702 HRESULT STDMETHODCALLTYPE
CDefView::AutoArrange()
2704 m_ListView
.ModifyStyle(0, LVS_AUTOARRANGE
);
2705 m_ListView
.Arrange(LVA_DEFAULT
);
2709 HRESULT STDMETHODCALLTYPE
CDefView::AddObject(PITEMID_CHILD pidl
, UINT
*item
)
2711 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2715 HRESULT STDMETHODCALLTYPE
CDefView::GetObject(PITEMID_CHILD
*pidl
, UINT item
)
2717 TRACE("(%p)->(%p %d)\n", this, pidl
, item
);
2718 return Item(item
, pidl
);
2721 HRESULT STDMETHODCALLTYPE
CDefView::RemoveObject(PITEMID_CHILD pidl
, UINT
*item
)
2724 TRACE("(%p)->(%p %p)\n", this, pidl
, item
);
2728 *item
= LV_FindItemByPidl(ILFindLastID(pidl
));
2729 m_ListView
.DeleteItem(*item
);
2734 m_ListView
.DeleteAllItems();
2740 HRESULT STDMETHODCALLTYPE
CDefView::GetObjectCount(UINT
*count
)
2742 TRACE("(%p)->(%p)\n", this, count
);
2743 *count
= m_ListView
.GetItemCount();
2747 HRESULT STDMETHODCALLTYPE
CDefView::SetObjectCount(UINT count
, UINT flags
)
2749 FIXME("(%p)->(%d %x) stub\n", this, count
, flags
);
2753 HRESULT STDMETHODCALLTYPE
CDefView::UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
)
2755 FIXME("(%p)->(%p %p %p) stub\n", this, pidl_old
, pidl_new
, item
);
2759 HRESULT STDMETHODCALLTYPE
CDefView::RefreshObject(PITEMID_CHILD pidl
, UINT
*item
)
2761 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2765 HRESULT STDMETHODCALLTYPE
CDefView::SetRedraw(BOOL redraw
)
2767 TRACE("(%p)->(%d)\n", this, redraw
);
2768 m_ListView
.SetRedraw(redraw
);
2772 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedCount(UINT
*count
)
2774 FIXME("(%p)->(%p) stub\n", this, count
);
2778 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
)
2780 TRACE("(%p)->(%p %p)\n", this, pidl
, items
);
2782 *items
= GetSelections();
2786 *pidl
= static_cast<PCUITEMID_CHILD
*>(LocalAlloc(0, *items
* sizeof(PCUITEMID_CHILD
)));
2789 return E_OUTOFMEMORY
;
2792 /* it's documented that caller shouldn't PIDLs, only array itself */
2793 memcpy(*pidl
, m_apidl
, *items
* sizeof(PCUITEMID_CHILD
));
2799 HRESULT STDMETHODCALLTYPE
CDefView::IsDropOnSource(IDropTarget
*drop_target
)
2801 if ((m_iDragOverItem
== -1 || m_pCurDropTarget
== NULL
) &&
2802 (m_pSourceDataObject
.p
))
2810 HRESULT STDMETHODCALLTYPE
CDefView::GetDragPoint(POINT
*pt
)
2813 return E_INVALIDARG
;
2815 *pt
= m_ptFirstMousePos
;
2819 HRESULT STDMETHODCALLTYPE
CDefView::GetDropPoint(POINT
*pt
)
2821 FIXME("(%p)->(%p) stub\n", this, pt
);
2825 HRESULT STDMETHODCALLTYPE
CDefView::MoveIcons(IDataObject
*obj
)
2827 TRACE("(%p)->(%p)\n", this, obj
);
2831 HRESULT STDMETHODCALLTYPE
CDefView::SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
)
2833 FIXME("(%p)->(%p %p) stub\n", this, pidl
, pt
);
2837 HRESULT STDMETHODCALLTYPE
CDefView::IsBkDropTarget(IDropTarget
*drop_target
)
2839 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2843 HRESULT STDMETHODCALLTYPE
CDefView::SetClipboard(BOOL move
)
2845 FIXME("(%p)->(%d) stub\n", this, move
);
2849 HRESULT STDMETHODCALLTYPE
CDefView::SetPoints(IDataObject
*obj
)
2851 FIXME("(%p)->(%p) stub\n", this, obj
);
2855 HRESULT STDMETHODCALLTYPE
CDefView::GetItemSpacing(ITEMSPACING
*spacing
)
2857 FIXME("(%p)->(%p) stub\n", this, spacing
);
2861 HRESULT STDMETHODCALLTYPE
CDefView::SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
)
2864 *old_cb
= m_pShellFolderViewCB
.Detach();
2866 m_pShellFolderViewCB
= new_cb
;
2870 HRESULT STDMETHODCALLTYPE
CDefView::Select(UINT flags
)
2872 FIXME("(%p)->(%d) stub\n", this, flags
);
2876 HRESULT STDMETHODCALLTYPE
CDefView::QuerySupport(UINT
*support
)
2878 TRACE("(%p)->(%p)\n", this, support
);
2882 HRESULT STDMETHODCALLTYPE
CDefView::SetAutomationObject(IDispatch
*disp
)
2884 FIXME("(%p)->(%p) stub\n", this, disp
);
2888 /**********************************************************
2889 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2891 HRESULT WINAPI
CDefView::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD
*prgCmds
, OLECMDTEXT
*pCmdText
)
2893 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
2894 this, pguidCmdGroup
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
2897 return E_INVALIDARG
;
2899 for (UINT i
= 0; i
< cCmds
; i
++)
2901 FIXME("\tprgCmds[%d].cmdID = %d\n", i
, prgCmds
[i
].cmdID
);
2902 prgCmds
[i
].cmdf
= 0;
2905 return OLECMDERR_E_UNKNOWNGROUP
;
2908 /**********************************************************
2909 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2911 * nCmdID is the OLECMDID_* enumeration
2913 HRESULT WINAPI
CDefView::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
2915 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2916 this, debugstr_guid(pguidCmdGroup
), nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2919 return OLECMDERR_E_UNKNOWNGROUP
;
2921 if (IsEqualCLSID(*pguidCmdGroup
, m_Category
))
2923 if (nCmdID
== FCIDM_SHVIEW_AUTOARRANGE
)
2925 if (V_VT(pvaIn
) != VT_INT_PTR
)
2926 return OLECMDERR_E_NOTSUPPORTED
;
2929 params
.cbSize
= sizeof(params
);
2930 params
.rcExclude
= *(RECT
*) V_INTREF(pvaIn
);
2932 if (m_hMenuViewModes
)
2934 /* Duplicate all but the last two items of the view modes menu */
2935 HMENU hmenuViewPopup
= CreatePopupMenu();
2936 Shell_MergeMenus(hmenuViewPopup
, m_hMenuViewModes
, 0, 0, 0xFFFF, 0);
2937 DeleteMenu(hmenuViewPopup
, GetMenuItemCount(hmenuViewPopup
) - 1, MF_BYPOSITION
);
2938 DeleteMenu(hmenuViewPopup
, GetMenuItemCount(hmenuViewPopup
) - 1, MF_BYPOSITION
);
2939 CheckViewMode(hmenuViewPopup
);
2940 TrackPopupMenuEx(hmenuViewPopup
, TPM_LEFTALIGN
| TPM_TOPALIGN
, params
.rcExclude
.left
, params
.rcExclude
.bottom
, m_hWndParent
, ¶ms
);
2941 ::DestroyMenu(hmenuViewPopup
);
2944 // pvaOut is VT_I4 with value 0x403 (cmd id of the new mode maybe?)
2945 V_VT(pvaOut
) = VT_I4
;
2946 V_I4(pvaOut
) = 0x403;
2950 if (IsEqualIID(*pguidCmdGroup
, CGID_Explorer
) &&
2952 (nCmdexecopt
== 4) && pvaOut
)
2955 if (IsEqualIID(*pguidCmdGroup
, CGID_ShellDocView
) &&
2960 return OLECMDERR_E_UNKNOWNGROUP
;
2963 /**********************************************************
2964 * ISVDropTarget implementation
2967 /******************************************************************************
2968 * drag_notify_subitem [Internal]
2970 * Figure out the shellfolder object, which is currently under the mouse cursor
2971 * and notify it via the IDropTarget interface.
2974 #define SCROLLAREAWIDTH 20
2976 HRESULT
CDefView::drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2982 /* The key state on drop doesn't have MK_LBUTTON or MK_RBUTTON because it
2983 reflects the key state after the user released the button, so we need
2984 to remember the last key state when the button was pressed */
2985 m_grfKeyState
= grfKeyState
;
2987 /* Map from global to client coordinates and query the index of the listview-item, which is
2988 * currently under the mouse cursor. */
2989 LVHITTESTINFO htinfo
= {{pt
.x
, pt
.y
}, LVHT_ONITEM
};
2990 ScreenToClient(&htinfo
.pt
);
2991 lResult
= m_ListView
.HitTest(&htinfo
);
2993 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2994 ::GetClientRect(m_ListView
, &clientRect
);
2995 if (htinfo
.pt
.x
== m_ptLastMousePos
.x
&& htinfo
.pt
.y
== m_ptLastMousePos
.y
&&
2996 (htinfo
.pt
.x
< SCROLLAREAWIDTH
|| htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
||
2997 htinfo
.pt
.y
< SCROLLAREAWIDTH
|| htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
))
2999 m_cScrollDelay
= (m_cScrollDelay
+ 1) % 5; /* DragOver is called every 50 ms */
3000 if (m_cScrollDelay
== 0)
3002 /* Mouse did hover another 250 ms over the scroll-area */
3003 if (htinfo
.pt
.x
< SCROLLAREAWIDTH
)
3004 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEUP
, 0);
3006 if (htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
)
3007 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEDOWN
, 0);
3009 if (htinfo
.pt
.y
< SCROLLAREAWIDTH
)
3010 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEUP
, 0);
3012 if (htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
)
3013 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEDOWN
, 0);
3018 m_cScrollDelay
= 0; /* Reset, if the cursor is not over the listview's scroll-area */
3021 m_ptLastMousePos
= htinfo
.pt
;
3023 /* We need to check if we drag the selection over itself */
3024 if (lResult
!= -1 && m_pSourceDataObject
.p
!= NULL
)
3026 PCUITEMID_CHILD pidl
= _PidlByItem(lResult
);
3028 for (UINT i
= 0; i
< m_cidl
; i
++)
3030 if (pidl
== m_apidl
[i
])
3032 /* The item that is being draged is hovering itself. */
3039 /* If we are still over the previous sub-item, notify it via DragOver and return. */
3040 if (m_pCurDropTarget
&& lResult
== m_iDragOverItem
)
3041 return m_pCurDropTarget
->DragOver(grfKeyState
, pt
, pdwEffect
);
3043 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
3044 if (m_pCurDropTarget
)
3046 PCUITEMID_CHILD pidl
= _PidlByItem(m_iDragOverItem
);
3048 SelectItem(pidl
, 0);
3050 m_pCurDropTarget
->DragLeave();
3051 m_pCurDropTarget
.Release();
3054 m_iDragOverItem
= lResult
;
3058 /* We are not above one of the listview's subitems. Bind to the parent folder's
3059 * DropTarget interface. */
3060 hr
= m_pSFParent
->CreateViewObject(NULL
, IID_PPV_ARG(IDropTarget
,&m_pCurDropTarget
));
3064 /* Query the relative PIDL of the shellfolder object represented by the currently
3065 * dragged over listview-item ... */
3066 PCUITEMID_CHILD pidl
= _PidlByItem(lResult
);
3068 /* ... and bind m_pCurDropTarget to the IDropTarget interface of an UIObject of this object */
3069 hr
= m_pSFParent
->GetUIObjectOf(m_ListView
, 1, &pidl
, IID_NULL_PPV_ARG(IDropTarget
, &m_pCurDropTarget
));
3072 IUnknown_SetSite(m_pCurDropTarget
, (IShellView
*)this);
3074 /* If anything failed, m_pCurDropTarget should be NULL now, which ought to be a save state. */
3077 *pdwEffect
= DROPEFFECT_NONE
;
3081 if (m_iDragOverItem
!= -1)
3083 SelectItem(m_iDragOverItem
, SVSI_SELECT
);
3086 /* Notify the item just entered via DragEnter. */
3087 return m_pCurDropTarget
->DragEnter(m_pCurDataObject
, grfKeyState
, pt
, pdwEffect
);
3090 HRESULT WINAPI
CDefView::DragEnter(IDataObject
*pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
3092 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
3093 m_pCurDataObject
= pDataObject
;
3095 HRESULT hr
= drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
3098 POINT ptClient
= {pt
.x
, pt
.y
};
3099 ScreenToClient(&ptClient
);
3100 ImageList_DragEnter(m_hWnd
, ptClient
.x
, ptClient
.y
);
3106 HRESULT WINAPI
CDefView::DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
3108 POINT ptClient
= {pt
.x
, pt
.y
};
3109 ScreenToClient(&ptClient
);
3110 ImageList_DragMove(ptClient
.x
, ptClient
.y
);
3111 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
3114 HRESULT WINAPI
CDefView::DragLeave()
3116 ImageList_DragLeave(m_hWnd
);
3118 if (m_pCurDropTarget
)
3120 m_pCurDropTarget
->DragLeave();
3121 m_pCurDropTarget
.Release();
3124 if (m_pCurDataObject
!= NULL
)
3126 m_pCurDataObject
.Release();
3129 m_iDragOverItem
= 0;
3134 HRESULT WINAPI
CDefView::Drop(IDataObject
* pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
3136 ImageList_DragLeave(m_hWnd
);
3137 ImageList_EndDrag();
3139 if ((IsDropOnSource(NULL
) == S_OK
) &&
3140 (*pdwEffect
& DROPEFFECT_MOVE
) &&
3141 (m_grfKeyState
& MK_LBUTTON
))
3143 if (m_pCurDropTarget
)
3145 m_pCurDropTarget
->DragLeave();
3146 m_pCurDropTarget
.Release();
3149 /* Restore the selection */
3150 m_ListView
.SetItemState(-1, 0, LVIS_SELECTED
);
3151 for (UINT i
= 0 ; i
< m_cidl
; i
++)
3152 SelectItem(m_apidl
[i
], SVSI_SELECT
);
3154 /* Reposition the items */
3156 while ((lvIndex
= m_ListView
.GetNextItem(lvIndex
, LVNI_SELECTED
)) > -1)
3159 if (m_ListView
.GetItemPosition(lvIndex
, &ptItem
))
3161 ptItem
.x
+= pt
.x
- m_ptFirstMousePos
.x
;
3162 ptItem
.y
+= pt
.y
- m_ptFirstMousePos
.y
;
3163 m_ListView
.SetItemPosition(lvIndex
, &ptItem
);
3167 else if (m_pCurDropTarget
)
3169 m_pCurDropTarget
->Drop(pDataObject
, grfKeyState
, pt
, pdwEffect
);
3170 m_pCurDropTarget
.Release();
3173 m_pCurDataObject
.Release();
3174 m_iDragOverItem
= 0;
3178 /**********************************************************
3179 * ISVDropSource implementation
3182 HRESULT WINAPI
CDefView::QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
)
3184 TRACE("(%p)\n", this);
3187 return DRAGDROP_S_CANCEL
;
3188 else if (!(grfKeyState
& MK_LBUTTON
) && !(grfKeyState
& MK_RBUTTON
))
3189 return DRAGDROP_S_DROP
;
3194 HRESULT WINAPI
CDefView::GiveFeedback(DWORD dwEffect
)
3196 TRACE("(%p)\n", this);
3198 return DRAGDROP_S_USEDEFAULTCURSORS
;
3201 /**********************************************************
3202 * ISVViewObject implementation
3205 HRESULT WINAPI
CDefView::Draw(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
, HDC hdcTargetDev
, HDC hdcDraw
, LPCRECTL lprcBounds
, LPCRECTL lprcWBounds
, BOOL (CALLBACK
*pfnContinue
)(ULONG_PTR dwContinue
), ULONG_PTR dwContinue
)
3207 FIXME("Stub: this=%p\n", this);
3212 HRESULT WINAPI
CDefView::GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
, HDC hicTargetDevice
, LOGPALETTE
**ppColorSet
)
3214 FIXME("Stub: this=%p\n", this);
3219 HRESULT WINAPI
CDefView::Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
)
3221 FIXME("Stub: this=%p\n", this);
3226 HRESULT WINAPI
CDefView::Unfreeze(DWORD dwFreeze
)
3228 FIXME("Stub: this=%p\n", this);
3233 HRESULT WINAPI
CDefView::SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
)
3235 FIXME("partial stub: %p 0x%08x 0x%08x %p\n", this, aspects
, advf
, pAdvSink
);
3237 /* FIXME: we set the AdviseSink, but never use it to send any advice */
3238 m_pAdvSink
= pAdvSink
;
3239 m_dwAspects
= aspects
;
3245 HRESULT WINAPI
CDefView::GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
)
3247 TRACE("this=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n", this, pAspects
, pAdvf
, ppAdvSink
);
3251 *ppAdvSink
= m_pAdvSink
;
3252 m_pAdvSink
.p
->AddRef();
3256 *pAspects
= m_dwAspects
;
3264 HRESULT STDMETHODCALLTYPE
CDefView::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
3266 if (IsEqualIID(guidService
, SID_IShellBrowser
))
3267 return m_pShellBrowser
->QueryInterface(riid
, ppvObject
);
3268 else if(IsEqualIID(guidService
, SID_IFolderView
))
3269 return QueryInterface(riid
, ppvObject
);
3271 return E_NOINTERFACE
;
3274 HRESULT
CDefView::_MergeToolbar()
3276 CComPtr
<IExplorerToolbar
> ptb
;
3279 hr
= IUnknown_QueryService(m_pShellBrowser
, IID_IExplorerToolbar
, IID_PPV_ARG(IExplorerToolbar
, &ptb
));
3283 m_Category
= CGID_DefViewFrame
;
3285 hr
= ptb
->SetCommandTarget(static_cast<IOleCommandTarget
*>(this), &m_Category
, 0);
3293 hr
= ptb
->AddButtons(&m_Category
, buttonsCount
, buttons
);
3301 // The default processing of IShellFolderView callbacks
3302 HRESULT
CDefView::DefMessageSFVCB(UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3304 // TODO: SFVM_GET_CUSTOMVIEWINFO, SFVM_WINDOWCREATED
3305 TRACE("CDefView::DefMessageSFVCB uMsg=%u\n", uMsg
);
3309 HRESULT
CDefView::_DoFolderViewCB(UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3311 HRESULT hr
= E_NOTIMPL
;
3313 if (m_pShellFolderViewCB
)
3315 hr
= m_pShellFolderViewCB
->MessageSFVCB(uMsg
, wParam
, lParam
);
3318 if (hr
== E_NOTIMPL
)
3320 hr
= DefMessageSFVCB(uMsg
, wParam
, lParam
);
3326 HRESULT
CDefView_CreateInstance(IShellFolder
*pFolder
, REFIID riid
, LPVOID
* ppvOut
)
3328 return ShellObjectCreatorInit
<CDefView
>(pFolder
, riid
, ppvOut
);
3331 HRESULT WINAPI
SHCreateShellFolderViewEx(
3332 LPCSFV psvcbi
, /* [in] shelltemplate struct */
3333 IShellView
**ppsv
) /* [out] IShellView pointer */
3335 CComPtr
<IShellView
> psv
;
3338 TRACE("sf=%p pidl=%p cb=%p mode=0x%08x parm=%p\n",
3339 psvcbi
->pshf
, psvcbi
->pidl
, psvcbi
->pfnCallback
,
3340 psvcbi
->fvm
, psvcbi
->psvOuter
);
3343 hRes
= CDefView_CreateInstance(psvcbi
->pshf
, IID_PPV_ARG(IShellView
, &psv
));
3344 if (FAILED_UNEXPECTEDLY(hRes
))
3347 *ppsv
= psv
.Detach();
3351 HRESULT WINAPI
SHCreateShellFolderView(const SFV_CREATE
*pcsfv
,
3354 CComPtr
<IShellView
> psv
;
3358 if (!pcsfv
|| pcsfv
->cbSize
!= sizeof(*pcsfv
))
3359 return E_INVALIDARG
;
3361 TRACE("sf=%p outer=%p callback=%p\n",
3362 pcsfv
->pshf
, pcsfv
->psvOuter
, pcsfv
->psfvcb
);
3364 hRes
= CDefView_CreateInstance(pcsfv
->pshf
, IID_PPV_ARG(IShellView
, &psv
));
3370 CComPtr
<IShellFolderView
> sfv
;
3371 if (SUCCEEDED(psv
->QueryInterface(IID_PPV_ARG(IShellFolderView
, &sfv
))))
3373 sfv
->SetCallback(pcsfv
->psfvcb
, NULL
);
3377 *ppsv
= psv
.Detach();