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
;
113 SFVM_CUSTOMVIEWINFO_DATA m_viewinfo_data
;
116 HRESULT
_MergeToolbar();
118 HRESULT
_DoFolderViewCB(UINT uMsg
, WPARAM wParam
, LPARAM lParam
);
123 HRESULT WINAPI
Initialize(IShellFolder
*shellFolder
);
124 HRESULT
IncludeObject(PCUITEMID_CHILD pidl
);
125 HRESULT
OnDefaultCommand();
126 HRESULT
OnStateChange(UINT uFlags
);
127 void UpdateStatusbar();
130 void UpdateListColors();
132 HRESULT
DefMessageSFVCB(UINT uMsg
, WPARAM wParam
, LPARAM lParam
);
133 static INT CALLBACK
ListViewCompareItems(LPARAM lParam1
, LPARAM lParam2
, LPARAM lpData
);
135 PCUITEMID_CHILD
_PidlByItem(int i
);
136 PCUITEMID_CHILD
_PidlByItem(LVITEM
& lvItem
);
137 int LV_FindItemByPidl(PCUITEMID_CHILD pidl
);
138 int LV_AddItem(PCUITEMID_CHILD pidl
);
139 BOOLEAN
LV_DeleteItem(PCUITEMID_CHILD pidl
);
140 BOOLEAN
LV_RenameItem(PCUITEMID_CHILD pidlOld
, PCUITEMID_CHILD pidlNew
);
141 BOOLEAN
LV_ProdItem(PCUITEMID_CHILD pidl
);
142 static INT CALLBACK
fill_list(LPVOID ptr
, LPVOID arg
);
144 HRESULT
FillFileMenu();
145 HRESULT
FillEditMenu();
146 HRESULT
FillViewMenu();
147 HRESULT
FillArrangeAsMenu(HMENU hmenuArrange
);
148 HRESULT
CheckViewMode(HMENU hmenuView
);
149 UINT
GetSelections();
150 HRESULT
OpenSelectedItems();
152 void DoActivate(UINT uState
);
153 HRESULT
drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
154 HRESULT
InvokeContextMenuCommand(UINT uCommand
);
155 LRESULT
OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
);
157 // *** IOleWindow methods ***
158 virtual HRESULT STDMETHODCALLTYPE
GetWindow(HWND
*lphwnd
);
159 virtual HRESULT STDMETHODCALLTYPE
ContextSensitiveHelp(BOOL fEnterMode
);
161 // *** IShellView methods ***
162 virtual HRESULT STDMETHODCALLTYPE
TranslateAccelerator(MSG
*pmsg
);
163 virtual HRESULT STDMETHODCALLTYPE
EnableModeless(BOOL fEnable
);
164 virtual HRESULT STDMETHODCALLTYPE
UIActivate(UINT uState
);
165 virtual HRESULT STDMETHODCALLTYPE
Refresh();
166 virtual HRESULT STDMETHODCALLTYPE
CreateViewWindow(IShellView
*psvPrevious
, LPCFOLDERSETTINGS pfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
);
167 virtual HRESULT STDMETHODCALLTYPE
DestroyViewWindow();
168 virtual HRESULT STDMETHODCALLTYPE
GetCurrentInfo(LPFOLDERSETTINGS pfs
);
169 virtual HRESULT STDMETHODCALLTYPE
AddPropertySheetPages(DWORD dwReserved
, LPFNSVADDPROPSHEETPAGE pfn
, LPARAM lparam
);
170 virtual HRESULT STDMETHODCALLTYPE
SaveViewState();
171 virtual HRESULT STDMETHODCALLTYPE
SelectItem(PCUITEMID_CHILD pidlItem
, SVSIF uFlags
);
172 virtual HRESULT STDMETHODCALLTYPE
GetItemObject(UINT uItem
, REFIID riid
, void **ppv
);
174 // *** IShellView2 methods ***
175 virtual HRESULT STDMETHODCALLTYPE
GetView(SHELLVIEWID
*view_guid
, ULONG view_type
);
176 virtual HRESULT STDMETHODCALLTYPE
CreateViewWindow2(LPSV2CVW2_PARAMS view_params
);
177 virtual HRESULT STDMETHODCALLTYPE
HandleRename(LPCITEMIDLIST new_pidl
);
178 virtual HRESULT STDMETHODCALLTYPE
SelectAndPositionItem(LPCITEMIDLIST item
, UINT flags
, POINT
*point
);
180 // *** IShellView3 methods ***
181 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
);
183 // *** IFolderView methods ***
184 virtual HRESULT STDMETHODCALLTYPE
GetCurrentViewMode(UINT
*pViewMode
);
185 virtual HRESULT STDMETHODCALLTYPE
SetCurrentViewMode(UINT ViewMode
);
186 virtual HRESULT STDMETHODCALLTYPE
GetFolder(REFIID riid
, void **ppv
);
187 virtual HRESULT STDMETHODCALLTYPE
Item(int iItemIndex
, PITEMID_CHILD
*ppidl
);
188 virtual HRESULT STDMETHODCALLTYPE
ItemCount(UINT uFlags
, int *pcItems
);
189 virtual HRESULT STDMETHODCALLTYPE
Items(UINT uFlags
, REFIID riid
, void **ppv
);
190 virtual HRESULT STDMETHODCALLTYPE
GetSelectionMarkedItem(int *piItem
);
191 virtual HRESULT STDMETHODCALLTYPE
GetFocusedItem(int *piItem
);
192 virtual HRESULT STDMETHODCALLTYPE
GetItemPosition(PCUITEMID_CHILD pidl
, POINT
*ppt
);
193 virtual HRESULT STDMETHODCALLTYPE
GetSpacing(POINT
*ppt
);
194 virtual HRESULT STDMETHODCALLTYPE
GetDefaultSpacing(POINT
*ppt
);
195 virtual HRESULT STDMETHODCALLTYPE
GetAutoArrange();
196 virtual HRESULT STDMETHODCALLTYPE
SelectItem(int iItem
, DWORD dwFlags
);
197 virtual HRESULT STDMETHODCALLTYPE
SelectAndPositionItems(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD dwFlags
);
199 // *** IShellFolderView methods ***
200 virtual HRESULT STDMETHODCALLTYPE
Rearrange(LPARAM sort
);
201 virtual HRESULT STDMETHODCALLTYPE
GetArrangeParam(LPARAM
*sort
);
202 virtual HRESULT STDMETHODCALLTYPE
ArrangeGrid();
203 virtual HRESULT STDMETHODCALLTYPE
AutoArrange();
204 virtual HRESULT STDMETHODCALLTYPE
AddObject(PITEMID_CHILD pidl
, UINT
*item
);
205 virtual HRESULT STDMETHODCALLTYPE
GetObject(PITEMID_CHILD
*pidl
, UINT item
);
206 virtual HRESULT STDMETHODCALLTYPE
RemoveObject(PITEMID_CHILD pidl
, UINT
*item
);
207 virtual HRESULT STDMETHODCALLTYPE
GetObjectCount(UINT
*count
);
208 virtual HRESULT STDMETHODCALLTYPE
SetObjectCount(UINT count
, UINT flags
);
209 virtual HRESULT STDMETHODCALLTYPE
UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
);
210 virtual HRESULT STDMETHODCALLTYPE
RefreshObject(PITEMID_CHILD pidl
, UINT
*item
);
211 virtual HRESULT STDMETHODCALLTYPE
SetRedraw(BOOL redraw
);
212 virtual HRESULT STDMETHODCALLTYPE
GetSelectedCount(UINT
*count
);
213 virtual HRESULT STDMETHODCALLTYPE
GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
);
214 virtual HRESULT STDMETHODCALLTYPE
IsDropOnSource(IDropTarget
*drop_target
);
215 virtual HRESULT STDMETHODCALLTYPE
GetDragPoint(POINT
*pt
);
216 virtual HRESULT STDMETHODCALLTYPE
GetDropPoint(POINT
*pt
);
217 virtual HRESULT STDMETHODCALLTYPE
MoveIcons(IDataObject
*obj
);
218 virtual HRESULT STDMETHODCALLTYPE
SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
);
219 virtual HRESULT STDMETHODCALLTYPE
IsBkDropTarget(IDropTarget
*drop_target
);
220 virtual HRESULT STDMETHODCALLTYPE
SetClipboard(BOOL move
);
221 virtual HRESULT STDMETHODCALLTYPE
SetPoints(IDataObject
*obj
);
222 virtual HRESULT STDMETHODCALLTYPE
GetItemSpacing(ITEMSPACING
*spacing
);
223 virtual HRESULT STDMETHODCALLTYPE
SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
);
224 virtual HRESULT STDMETHODCALLTYPE
Select(UINT flags
);
225 virtual HRESULT STDMETHODCALLTYPE
QuerySupport(UINT
*support
);
226 virtual HRESULT STDMETHODCALLTYPE
SetAutomationObject(IDispatch
*disp
);
228 // *** IOleCommandTarget methods ***
229 virtual HRESULT STDMETHODCALLTYPE
QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
);
230 virtual HRESULT STDMETHODCALLTYPE
Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
);
232 // *** IDropTarget methods ***
233 virtual HRESULT STDMETHODCALLTYPE
DragEnter(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
234 virtual HRESULT STDMETHODCALLTYPE
DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
235 virtual HRESULT STDMETHODCALLTYPE
DragLeave();
236 virtual HRESULT STDMETHODCALLTYPE
Drop(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
238 // *** IDropSource methods ***
239 virtual HRESULT STDMETHODCALLTYPE
QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
);
240 virtual HRESULT STDMETHODCALLTYPE
GiveFeedback(DWORD dwEffect
);
242 // *** IViewObject methods ***
243 virtual HRESULT STDMETHODCALLTYPE
Draw(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
,
244 HDC hdcTargetDev
, HDC hdcDraw
, LPCRECTL lprcBounds
, LPCRECTL lprcWBounds
,
245 BOOL ( STDMETHODCALLTYPE
*pfnContinue
)(ULONG_PTR dwContinue
), ULONG_PTR dwContinue
);
246 virtual HRESULT STDMETHODCALLTYPE
GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
,
247 DVTARGETDEVICE
*ptd
, HDC hicTargetDev
, LOGPALETTE
**ppColorSet
);
248 virtual HRESULT STDMETHODCALLTYPE
Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
);
249 virtual HRESULT STDMETHODCALLTYPE
Unfreeze(DWORD dwFreeze
);
250 virtual HRESULT STDMETHODCALLTYPE
SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
);
251 virtual HRESULT STDMETHODCALLTYPE
GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
);
253 // *** IServiceProvider methods ***
254 virtual HRESULT STDMETHODCALLTYPE
QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
);
257 LRESULT
OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
258 LRESULT
OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
259 LRESULT
OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
260 LRESULT
OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
261 LRESULT
OnPrintClient(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
262 LRESULT
OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
263 LRESULT
OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
264 LRESULT
OnNCCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
265 LRESULT
OnNCDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
266 LRESULT
OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
267 LRESULT
OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
268 LRESULT
OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
269 LRESULT
OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
270 LRESULT
OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
271 LRESULT
OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
272 LRESULT
OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
273 LRESULT
OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
274 LRESULT
OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
275 LRESULT
OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
276 LRESULT
OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
277 LRESULT
OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
279 static ATL::CWndClassInfo
& GetWndClassInfo()
281 static ATL::CWndClassInfo wc
=
283 { sizeof(WNDCLASSEX
), CS_PARENTDC
, StartWindowProc
,
285 LoadCursor(NULL
, IDC_ARROW
), NULL
, NULL
, SV_CLASS_NAME
, NULL
287 NULL
, NULL
, IDC_ARROW
, TRUE
, 0, _T("")
292 virtual WNDPROC
GetWindowProc()
297 static LRESULT CALLBACK
WindowProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
302 // Must hold a reference during message handling
303 pThis
= reinterpret_cast<CDefView
*>(hWnd
);
305 result
= CWindowImpl
<CDefView
, CWindow
, CControlWinTraits
>::WindowProc(hWnd
, uMsg
, wParam
, lParam
);
310 BEGIN_MSG_MAP(CDefView
)
311 MESSAGE_HANDLER(WM_SIZE
, OnSize
)
312 MESSAGE_HANDLER(WM_SETFOCUS
, OnSetFocus
)
313 MESSAGE_HANDLER(WM_KILLFOCUS
, OnKillFocus
)
314 MESSAGE_HANDLER(WM_NCCREATE
, OnNCCreate
)
315 MESSAGE_HANDLER(WM_NCDESTROY
, OnNCDestroy
)
316 MESSAGE_HANDLER(WM_CREATE
, OnCreate
)
317 MESSAGE_HANDLER(WM_ACTIVATE
, OnActivate
)
318 MESSAGE_HANDLER(WM_NOTIFY
, OnNotify
)
319 MESSAGE_HANDLER(WM_COMMAND
, OnCommand
)
320 MESSAGE_HANDLER(SHV_CHANGE_NOTIFY
, OnChangeNotify
)
321 MESSAGE_HANDLER(WM_CONTEXTMENU
, OnContextMenu
)
322 MESSAGE_HANDLER(WM_DRAWITEM
, OnCustomItem
)
323 MESSAGE_HANDLER(WM_MEASUREITEM
, OnCustomItem
)
324 MESSAGE_HANDLER(WM_SHOWWINDOW
, OnShowWindow
)
325 MESSAGE_HANDLER(WM_GETDLGCODE
, OnGetDlgCode
)
326 MESSAGE_HANDLER(WM_DESTROY
, OnDestroy
)
327 MESSAGE_HANDLER(WM_ERASEBKGND
, OnEraseBackground
)
328 MESSAGE_HANDLER(WM_PRINTCLIENT
, OnPrintClient
)
329 MESSAGE_HANDLER(WM_SYSCOLORCHANGE
, OnSysColorChange
)
330 MESSAGE_HANDLER(CWM_GETISHELLBROWSER
, OnGetShellBrowser
)
331 MESSAGE_HANDLER(WM_SETTINGCHANGE
, OnSettingChange
)
332 MESSAGE_HANDLER(WM_INITMENUPOPUP
, OnInitMenuPopup
)
335 BEGIN_COM_MAP(CDefView
)
336 // Windows returns E_NOINTERFACE for IOleWindow
337 // COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
338 COM_INTERFACE_ENTRY_IID(IID_IShellView
, IShellView
)
339 COM_INTERFACE_ENTRY_IID(IID_CDefView
, IShellView
)
340 COM_INTERFACE_ENTRY_IID(IID_IShellView2
, IShellView2
)
341 COM_INTERFACE_ENTRY_IID(IID_IFolderView
, IFolderView
)
342 COM_INTERFACE_ENTRY_IID(IID_IShellFolderView
, IShellFolderView
)
343 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget
, IOleCommandTarget
)
344 COM_INTERFACE_ENTRY_IID(IID_IDropTarget
, IDropTarget
)
345 COM_INTERFACE_ENTRY_IID(IID_IDropSource
, IDropSource
)
346 COM_INTERFACE_ENTRY_IID(IID_IViewObject
, IViewObject
)
347 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider
, IServiceProvider
)
352 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
353 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
354 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
356 #define ID_LISTVIEW 1
359 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
360 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
361 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
363 typedef void (CALLBACK
*PFNSHGETSETTINGSPROC
)(LPSHELLFLAGSTATE lpsfs
, DWORD dwMask
);
365 CDefView::CDefView() :
369 m_hMenuArrangeModes(NULL
),
370 m_hMenuViewModes(NULL
),
371 m_hContextMenu(NULL
),
372 m_bmenuBarInitialized(FALSE
),
386 ZeroMemory(&m_FolderSettings
, sizeof(m_FolderSettings
));
387 ZeroMemory(&m_sortInfo
, sizeof(m_sortInfo
));
388 ZeroMemory(&m_ptLastMousePos
, sizeof(m_ptLastMousePos
));
389 ZeroMemory(&m_Category
, sizeof(m_Category
));
390 m_viewinfo_data
.clrText
= GetSysColor(COLOR_WINDOWTEXT
);
391 m_viewinfo_data
.clrTextBack
= GetSysColor(COLOR_WINDOW
);
392 m_viewinfo_data
.hbmBack
= NULL
;
395 CDefView::~CDefView()
397 TRACE(" destroying IShellView(%p)\n", this);
399 if (m_viewinfo_data
.hbmBack
)
401 ::DeleteObject(m_viewinfo_data
.hbmBack
);
402 m_viewinfo_data
.hbmBack
= NULL
;
413 HRESULT WINAPI
CDefView::Initialize(IShellFolder
*shellFolder
)
415 m_pSFParent
= shellFolder
;
416 shellFolder
->QueryInterface(IID_PPV_ARG(IShellFolder2
, &m_pSF2Parent
));
421 /**********************************************************
423 * ##### helperfunctions for communication with ICommDlgBrowser #####
425 HRESULT
CDefView::IncludeObject(PCUITEMID_CHILD pidl
)
429 if (m_pCommDlgBrowser
.p
!= NULL
)
431 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl
);
432 ret
= m_pCommDlgBrowser
->IncludeObject(this, pidl
);
433 TRACE("-- returns 0x%08x\n", ret
);
439 HRESULT
CDefView::OnDefaultCommand()
441 HRESULT ret
= S_FALSE
;
443 if (m_pCommDlgBrowser
.p
!= NULL
)
445 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
446 ret
= m_pCommDlgBrowser
->OnDefaultCommand(this);
447 TRACE("-- returns 0x%08x\n", ret
);
453 HRESULT
CDefView::OnStateChange(UINT uFlags
)
455 HRESULT ret
= S_FALSE
;
457 if (m_pCommDlgBrowser
.p
!= NULL
)
459 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags
);
460 ret
= m_pCommDlgBrowser
->OnStateChange(this, uFlags
);
466 /**********************************************************
467 * set the toolbar of the filedialog buttons
469 * - activates the buttons from the shellbrowser according to
472 void CDefView::CheckToolbar()
478 if (m_pCommDlgBrowser
!= NULL
)
480 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
481 FCIDM_TB_SMALLICON
, (m_FolderSettings
.ViewMode
== FVM_LIST
) ? TRUE
: FALSE
, &result
);
482 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
483 FCIDM_TB_REPORTVIEW
, (m_FolderSettings
.ViewMode
== FVM_DETAILS
) ? TRUE
: FALSE
, &result
);
484 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
485 FCIDM_TB_SMALLICON
, TRUE
, &result
);
486 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
487 FCIDM_TB_REPORTVIEW
, TRUE
, &result
);
491 void CDefView::UpdateStatusbar()
493 WCHAR szFormat
[MAX_PATH
] = {0};
494 WCHAR szObjects
[MAX_PATH
] = {0};
497 cSelectedItems
= m_ListView
.GetSelectedCount();
500 LoadStringW(shell32_hInstance
, IDS_OBJECTS_SELECTED
, szFormat
, _countof(szFormat
));
501 StringCchPrintfW(szObjects
, MAX_PATH
, szFormat
, cSelectedItems
);
505 LoadStringW(shell32_hInstance
, IDS_OBJECTS
, szFormat
, _countof(szFormat
));
506 StringCchPrintfW(szObjects
, MAX_PATH
, szFormat
, m_ListView
.GetItemCount());
508 m_pShellBrowser
->SetStatusTextSB(szObjects
);
511 /**********************************************************
513 * ##### helperfunctions for initializing the view #####
516 /**********************************************************
517 * ShellView_CreateList()
519 * - creates the list view window
521 BOOL
CDefView::CreateList()
524 DWORD dwStyle
, dwExStyle
;
529 dwStyle
= WS_TABSTOP
| WS_VISIBLE
| WS_CHILDWINDOW
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
|
530 LVS_SHAREIMAGELISTS
| LVS_EDITLABELS
| LVS_AUTOARRANGE
;
531 dwExStyle
= WS_EX_CLIENTEDGE
;
533 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
534 dwStyle
|= LVS_ALIGNLEFT
;
536 dwStyle
|= LVS_ALIGNTOP
| LVS_SHOWSELALWAYS
;
538 ViewMode
= m_FolderSettings
.ViewMode
;
539 hr
= _DoFolderViewCB(SFVM_DEFVIEWMODE
, NULL
, (LPARAM
)&ViewMode
);
542 if (ViewMode
>= FVM_FIRST
&& ViewMode
<= FVM_LAST
)
543 m_FolderSettings
.ViewMode
= ViewMode
;
545 ERR("Ignoring invalid ViewMode from SFVM_DEFVIEWMODE: %u (was: %u)\n", ViewMode
, m_FolderSettings
.ViewMode
);
548 switch (m_FolderSettings
.ViewMode
)
555 dwStyle
|= LVS_REPORT
;
559 dwStyle
|= LVS_SMALLICON
;
571 if (m_FolderSettings
.fFlags
& FWF_AUTOARRANGE
)
572 dwStyle
|= LVS_AUTOARRANGE
;
574 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
575 m_FolderSettings
.fFlags
|= FWF_NOCLIENTEDGE
| FWF_NOSCROLL
;
577 if (m_FolderSettings
.fFlags
& FWF_SINGLESEL
)
578 dwStyle
|= LVS_SINGLESEL
;
580 if (m_FolderSettings
.fFlags
& FWF_NOCLIENTEDGE
)
581 dwExStyle
&= ~WS_EX_CLIENTEDGE
;
583 RECT rcListView
= {0,0,0,0};
584 m_ListView
.Create(m_hWnd
, rcListView
, L
"FolderView", dwStyle
, dwExStyle
, ID_LISTVIEW
);
589 m_sortInfo
.bIsAscending
= TRUE
;
590 m_sortInfo
.nHeaderID
= -1;
591 m_sortInfo
.nLastHeaderID
= -1;
593 /* UpdateShellSettings(); */
597 void CDefView::UpdateListColors()
599 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
601 /* Check if drop shadows option is enabled */
602 BOOL bDropShadow
= FALSE
;
603 DWORD cbDropShadow
= sizeof(bDropShadow
);
606 * The desktop ListView always take the default desktop colours, by
607 * remaining transparent and letting user32/win32k paint itself the
608 * desktop background color, if any.
610 m_ListView
.SetBkColor(CLR_NONE
);
612 SHGetValueW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
613 L
"ListviewShadow", NULL
, &bDropShadow
, &cbDropShadow
);
616 /* Set the icon background transparent */
617 m_ListView
.SetTextBkColor(CLR_NONE
);
618 m_ListView
.SetTextColor(RGB(255, 255, 255));
619 m_ListView
.SetExtendedListViewStyle(LVS_EX_TRANSPARENTSHADOWTEXT
, LVS_EX_TRANSPARENTSHADOWTEXT
);
623 /* Set the icon background as the same colour as the desktop */
624 COLORREF crDesktop
= GetSysColor(COLOR_DESKTOP
);
625 m_ListView
.SetTextBkColor(crDesktop
);
626 if (GetRValue(crDesktop
) + GetGValue(crDesktop
) + GetBValue(crDesktop
) > 128 * 3)
627 m_ListView
.SetTextColor(RGB(0, 0, 0));
629 m_ListView
.SetTextColor(RGB(255, 255, 255));
630 m_ListView
.SetExtendedListViewStyle(0, LVS_EX_TRANSPARENTSHADOWTEXT
);
635 // text background color
636 COLORREF clrTextBack
= m_viewinfo_data
.clrTextBack
;
637 m_ListView
.SetTextBkColor(clrTextBack
);
641 if (m_viewinfo_data
.clrText
!= CLR_INVALID
)
642 clrText
= m_viewinfo_data
.clrText
;
644 clrText
= GetSysColor(COLOR_WINDOWTEXT
);
646 m_ListView
.SetTextColor(clrText
);
648 // Background is painted by the parent via WM_PRINTCLIENT.
649 m_ListView
.SetExtendedListViewStyle(LVS_EX_TRANSPARENTBKGND
, LVS_EX_TRANSPARENTBKGND
);
653 /**********************************************************
654 * ShellView_InitList()
656 * - adds all needed columns to the shellview
658 BOOL
CDefView::InitList()
662 HIMAGELIST big_icons
, small_icons
;
666 m_ListView
.DeleteAllItems();
668 m_hMenuArrangeModes
= CreateMenu();
672 for (int i
= 0; 1; i
++)
674 if (FAILED(m_pSF2Parent
->GetDetailsOf(NULL
, i
, &sd
)))
676 StrRetToStrNW( szTemp
, 50, &sd
.str
, NULL
);
677 m_ListView
.InsertColumn(i
, szTemp
, sd
.fmt
, sd
.cxChar
* 8);
679 InsertMenuW(m_hMenuArrangeModes
, -1, MF_STRING
, 0x30 + i
, szTemp
);
682 InsertMenuW(m_hMenuArrangeModes
, -1, MF_BYPOSITION
| MF_SEPARATOR
, 0, 0);
686 FIXME("no m_pSF2Parent\n");
689 Shell_GetImageLists(&big_icons
, &small_icons
);
690 m_ListView
.SetImageList(big_icons
, LVSIL_NORMAL
);
691 m_ListView
.SetImageList(small_icons
, LVSIL_SMALL
);
696 /*************************************************************************
697 * ShellView_ListViewCompareItems
699 * Compare Function for the Listview (FileOpen Dialog)
702 * lParam1 [I] the first ItemIdList to compare with
703 * lParam2 [I] the second ItemIdList to compare with
704 * lpData [I] The column ID for the header Ctrl to process
707 * A negative value if the first item should precede the second,
708 * a positive value if the first item should follow the second,
709 * or zero if the two items are equivalent
711 INT CALLBACK
CDefView::ListViewCompareItems(LPARAM lParam1
, LPARAM lParam2
, LPARAM lpData
)
713 PCUIDLIST_RELATIVE pidl1
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam1
);
714 PCUIDLIST_RELATIVE pidl2
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam2
);
715 CDefView
*pThis
= reinterpret_cast<CDefView
*>(lpData
);
717 HRESULT hres
= pThis
->m_pSFParent
->CompareIDs(pThis
->m_sortInfo
.nHeaderID
, pidl1
, pidl2
);
718 if (FAILED_UNEXPECTEDLY(hres
))
721 SHORT nDiff
= HRESULT_CODE(hres
);
722 if (!pThis
->m_sortInfo
.bIsAscending
)
727 BOOL
CDefView::_Sort()
732 if (m_ListView
.GetWindowLongPtr(GWL_STYLE
) & LVS_NOSORTHEADER
)
735 hHeader
= (HWND
)m_ListView
.SendMessage(LVM_GETHEADER
, 0, 0);
736 ZeroMemory(&hColumn
, sizeof(hColumn
));
738 /* If the sorting column changed, remove the sorting style from the old column */
739 if ( (m_sortInfo
.nLastHeaderID
!= -1) &&
740 (m_sortInfo
.nLastHeaderID
!= m_sortInfo
.nHeaderID
) )
742 hColumn
.mask
= HDI_FORMAT
;
743 Header_GetItem(hHeader
, m_sortInfo
.nLastHeaderID
, &hColumn
);
744 hColumn
.fmt
&= ~(HDF_SORTUP
| HDF_SORTDOWN
);
745 Header_SetItem(hHeader
, m_sortInfo
.nLastHeaderID
, &hColumn
);
748 /* Set the sorting style to the new column */
749 hColumn
.mask
= HDI_FORMAT
;
750 Header_GetItem(hHeader
, m_sortInfo
.nHeaderID
, &hColumn
);
752 hColumn
.fmt
&= (m_sortInfo
.bIsAscending
? ~HDF_SORTDOWN
: ~HDF_SORTUP
);
753 hColumn
.fmt
|= (m_sortInfo
.bIsAscending
? HDF_SORTUP
: HDF_SORTDOWN
);
754 Header_SetItem(hHeader
, m_sortInfo
.nHeaderID
, &hColumn
);
756 /* Sort the list, using the current values of nHeaderID and bIsAscending */
757 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
758 return m_ListView
.SortItems(ListViewCompareItems
, this);
761 PCUITEMID_CHILD
CDefView::_PidlByItem(int i
)
763 return reinterpret_cast<PCUITEMID_CHILD
>(m_ListView
.GetItemData(i
));
766 PCUITEMID_CHILD
CDefView::_PidlByItem(LVITEM
& lvItem
)
768 return reinterpret_cast<PCUITEMID_CHILD
>(lvItem
.lParam
);
771 /**********************************************************
772 * LV_FindItemByPidl()
774 int CDefView::LV_FindItemByPidl(PCUITEMID_CHILD pidl
)
776 int cItems
= m_ListView
.GetItemCount();
778 for (int i
= 0; i
<cItems
; i
++)
780 PCUITEMID_CHILD currentpidl
= _PidlByItem(i
);
781 HRESULT hr
= m_pSFParent
->CompareIDs(0, pidl
, currentpidl
);
783 if (SUCCEEDED(hr
) && !HRESULT_CODE(hr
))
791 /**********************************************************
794 int CDefView::LV_AddItem(PCUITEMID_CHILD pidl
)
798 TRACE("(%p)(pidl=%p)\n", this, pidl
);
800 lvItem
.mask
= LVIF_TEXT
| LVIF_IMAGE
| LVIF_PARAM
; /*set the mask*/
801 lvItem
.iItem
= m_ListView
.GetItemCount(); /*add the item to the end of the list*/
803 lvItem
.lParam
= reinterpret_cast<LPARAM
>(ILClone(pidl
)); /*set the item's data*/
804 lvItem
.pszText
= LPSTR_TEXTCALLBACKW
; /*get text on a callback basis*/
805 lvItem
.iImage
= I_IMAGECALLBACK
; /*get the image on a callback basis*/
806 lvItem
.stateMask
= LVIS_CUT
;
808 return m_ListView
.InsertItem(&lvItem
);
811 /**********************************************************
814 BOOLEAN
CDefView::LV_DeleteItem(PCUITEMID_CHILD pidl
)
818 TRACE("(%p)(pidl=%p)\n", this, pidl
);
820 nIndex
= LV_FindItemByPidl(pidl
);
822 return (-1 == m_ListView
.DeleteItem(nIndex
)) ? FALSE
: TRUE
;
825 /**********************************************************
828 BOOLEAN
CDefView::LV_RenameItem(PCUITEMID_CHILD pidlOld
, PCUITEMID_CHILD pidlNew
)
833 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", this, pidlOld
, pidlNew
);
835 nItem
= LV_FindItemByPidl(pidlOld
);
839 lvItem
.mask
= LVIF_PARAM
; /* only the pidl */
840 lvItem
.iItem
= nItem
;
842 m_ListView
.GetItem(&lvItem
);
844 SHFree(reinterpret_cast<LPVOID
>(lvItem
.lParam
));
845 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
846 lvItem
.iItem
= nItem
;
848 lvItem
.lParam
= reinterpret_cast<LPARAM
>(ILClone(pidlNew
)); /* set the item's data */
849 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
850 m_ListView
.SetItem(&lvItem
);
851 m_ListView
.Update(nItem
);
852 return TRUE
; /* FIXME: better handling */
858 /**********************************************************
861 BOOLEAN
CDefView::LV_ProdItem(PCUITEMID_CHILD pidl
)
866 TRACE("(%p)(pidl=%p)\n", this, pidl
);
868 nItem
= LV_FindItemByPidl(pidl
);
872 lvItem
.mask
= LVIF_IMAGE
;
873 lvItem
.iItem
= nItem
;
875 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
876 m_ListView
.SetItem(&lvItem
);
877 m_ListView
.Update(nItem
);
884 /**********************************************************
885 * ShellView_FillList()
887 * - gets the objectlist from the shellfolder
889 * - fills the list into the view
891 INT CALLBACK
CDefView::fill_list(LPVOID ptr
, LPVOID arg
)
893 PITEMID_CHILD pidl
= static_cast<PITEMID_CHILD
>(ptr
);
894 CDefView
*pThis
= static_cast<CDefView
*>(arg
);
896 /* in a commdlg This works as a filemask*/
897 if (pThis
->IncludeObject(pidl
) == S_OK
)
898 pThis
->LV_AddItem(pidl
);
904 HRESULT
CDefView::FillList()
906 CComPtr
<IEnumIDList
> pEnumIDList
;
911 DWORD dFlags
= SHCONTF_NONFOLDERS
| SHCONTF_FOLDERS
;
912 DWORD dwValue
, cbValue
;
916 /* determine if there is a setting to show all the hidden files/folders */
918 cbValue
= sizeof(dwValue
);
919 SHGetValueW(HKEY_CURRENT_USER
,
920 L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
921 L
"Hidden", NULL
, &dwValue
, &cbValue
);
924 dFlags
|= SHCONTF_INCLUDEHIDDEN
;
925 m_ListView
.SendMessageW(LVM_SETCALLBACKMASK
, LVIS_CUT
, 0);
929 cbValue
= sizeof(dwValue
);
930 SHGetValueW(HKEY_CURRENT_USER
,
931 L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
932 L
"ShowSuperHidden", NULL
, &dwValue
, &cbValue
);
935 dFlags
|= SHCONTF_INCLUDESUPERHIDDEN
;
936 m_ListView
.SendMessageW(LVM_SETCALLBACKMASK
, LVIS_CUT
, 0);
939 /* get the itemlist from the shfolder */
940 hRes
= m_pSFParent
->EnumObjects(m_hWnd
, dFlags
, &pEnumIDList
);
948 /* create a pointer array */
949 hdpa
= DPA_Create(16);
952 return(E_OUTOFMEMORY
);
955 /* copy the items into the array*/
956 while((S_OK
== pEnumIDList
->Next(1, &pidl
, &dwFetched
)) && dwFetched
)
958 if (DPA_InsertPtr(hdpa
, 0x7fff, pidl
) == -1)
964 /*turn the listview's redrawing off*/
965 m_ListView
.SetRedraw(FALSE
);
967 DPA_DestroyCallback( hdpa
, fill_list
, this);
972 m_pSF2Parent
->GetDefaultColumn(NULL
, (ULONG
*)&m_sortInfo
.nHeaderID
, NULL
);
976 FIXME("no m_pSF2Parent\n");
978 m_sortInfo
.bIsAscending
= TRUE
;
981 if (m_viewinfo_data
.hbmBack
)
983 ::DeleteObject(m_viewinfo_data
.hbmBack
);
984 m_viewinfo_data
.hbmBack
= NULL
;
987 // load custom background image and custom text color
988 m_viewinfo_data
.cbSize
= sizeof(m_viewinfo_data
);
989 _DoFolderViewCB(SFVM_GET_CUSTOMVIEWINFO
, 0, (LPARAM
)&m_viewinfo_data
);
991 /*turn the listview's redrawing back on and force it to draw*/
992 m_ListView
.SetRedraw(TRUE
);
996 if (!(m_FolderSettings
.fFlags
& FWF_DESKTOP
))
999 m_ListView
.InvalidateRect(NULL
, TRUE
);
1002 _DoFolderViewCB(SFVM_LISTREFRESHED
, NULL
, NULL
);
1007 LRESULT
CDefView::OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1009 m_ListView
.UpdateWindow();
1014 LRESULT
CDefView::OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1016 return m_ListView
.SendMessageW(uMsg
, 0, 0);
1019 LRESULT
CDefView::OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1026 DestroyMenu(m_hMenu
);
1029 RevokeDragDrop(m_hWnd
);
1030 SHChangeNotifyDeregister(m_hNotify
);
1032 SHFree(m_pidlParent
);
1033 m_pidlParent
= NULL
;
1039 LRESULT
CDefView::OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1041 /* redirect to parent */
1042 if (m_FolderSettings
.fFlags
& (FWF_DESKTOP
| FWF_TRANSPARENT
))
1043 return SendMessageW(GetParent(), WM_ERASEBKGND
, wParam
, lParam
);
1050 DrawTileBitmap(HDC hDC
, LPCRECT prc
, HBITMAP hbm
, INT nWidth
, INT nHeight
, INT dx
, INT dy
)
1052 INT x0
= prc
->left
, y0
= prc
->top
, x1
= prc
->right
, y1
= prc
->bottom
;
1056 HDC hMemDC
= CreateCompatibleDC(hDC
);
1057 HGDIOBJ hbmOld
= SelectObject(hMemDC
, hbm
);
1059 for (INT y
= y0
; y
< y1
; y
+= nHeight
)
1061 for (INT x
= x0
; x
< x1
; x
+= nWidth
)
1063 BitBlt(hDC
, x
, y
, nWidth
, nHeight
, hMemDC
, 0, 0, SRCCOPY
);
1067 SelectObject(hMemDC
, hbmOld
);
1071 LRESULT
CDefView::OnPrintClient(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1073 HDC hDC
= (HDC
)wParam
;
1076 ::GetClientRect(m_ListView
, &rc
);
1078 if (m_viewinfo_data
.hbmBack
)
1081 if (::GetObject(m_viewinfo_data
.hbmBack
, sizeof(BITMAP
), &bm
))
1083 INT dx
= -(::GetScrollPos(m_ListView
, SB_HORZ
) % bm
.bmWidth
);
1084 INT dy
= -(::GetScrollPos(m_ListView
, SB_VERT
) % bm
.bmHeight
);
1085 DrawTileBitmap(hDC
, &rc
, m_viewinfo_data
.hbmBack
, bm
.bmWidth
, bm
.bmHeight
, dx
, dy
);
1090 FillRect(hDC
, &rc
, GetSysColorBrush(COLOR_WINDOW
));
1098 LRESULT
CDefView::OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1100 /* Update desktop labels color */
1103 /* Forward WM_SYSCOLORCHANGE to common controls */
1104 return m_ListView
.SendMessageW(uMsg
, 0, 0);
1107 LRESULT
CDefView::OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1109 return reinterpret_cast<LRESULT
>(m_pShellBrowser
.p
);
1112 LRESULT
CDefView::OnNCCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1119 LRESULT
CDefView::OnNCDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1126 /**********************************************************
1127 * ShellView_OnCreate()
1129 LRESULT
CDefView::OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1131 CComPtr
<IDropTarget
> pdt
;
1132 SHChangeNotifyEntry ntreg
;
1133 CComPtr
<IPersistFolder2
> ppf2
;
1135 TRACE("%p\n", this);
1137 if (SUCCEEDED(QueryInterface(IID_PPV_ARG(IDropTarget
, &pdt
))))
1139 if (FAILED(RegisterDragDrop(m_hWnd
, pdt
)))
1140 ERR("Registering Drag Drop Failed");
1143 /* register for receiving notifications */
1144 m_pSFParent
->QueryInterface(IID_PPV_ARG(IPersistFolder2
, &ppf2
));
1147 ppf2
->GetCurFolder(&m_pidlParent
);
1148 ntreg
.fRecursive
= TRUE
;
1149 ntreg
.pidl
= m_pidlParent
;
1150 m_hNotify
= SHChangeNotifyRegister(m_hWnd
, SHCNRF_InterruptLevel
| SHCNRF_ShellLevel
, SHCNE_ALLEVENTS
, SHV_CHANGE_NOTIFY
, 1, &ntreg
);
1161 /* _DoFolderViewCB(SFVM_GETNOTIFY, ?? ??) */
1163 m_hAccel
= LoadAcceleratorsW(shell32_hInstance
, MAKEINTRESOURCEW(IDA_SHELLVIEW
));
1170 /**********************************************************
1171 * #### Handling of the menus ####
1174 extern "C" DWORD WINAPI
SHMenuIndexFromID(HMENU hMenu
, UINT uID
);
1176 HMENU
GetSubmenuByID(HMENU hmenu
, UINT id
)
1178 MENUITEMINFOW mii
= {sizeof(mii
), MIIM_SUBMENU
};
1179 if (::GetMenuItemInfoW(hmenu
, id
, FALSE
, &mii
))
1180 return mii
.hSubMenu
;
1185 /* ReallyGetMenuItemID returns the id of an item even if it opens a submenu,
1186 GetMenuItemID returns -1 if the specified item opens a submenu */
1187 UINT
ReallyGetMenuItemID(HMENU hmenu
, int i
)
1189 MENUITEMINFOW mii
= {sizeof(mii
), MIIM_ID
};
1190 if (::GetMenuItemInfoW(hmenu
, i
, TRUE
, &mii
))
1196 HRESULT
CDefView::FillFileMenu()
1198 HMENU hFileMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_FILE
);
1202 /* Cleanup the items added previously */
1203 for (int i
= GetMenuItemCount(hFileMenu
) - 1; i
>= 0; i
--)
1205 UINT id
= GetMenuItemID(hFileMenu
, i
);
1206 if (id
< FCIDM_BROWSERFIRST
|| id
> FCIDM_BROWSERLAST
)
1207 DeleteMenu(hFileMenu
, i
, MF_BYPOSITION
);
1210 m_cidl
= m_ListView
.GetSelectedCount();
1212 /* Store the context menu in m_pCM and keep it in order to invoke the selected command later on */
1213 HRESULT hr
= GetItemObject((m_cidl
? SVGIO_SELECTION
: SVGIO_BACKGROUND
),
1214 IID_PPV_ARG(IContextMenu
, &m_pCM
));
1215 if (FAILED_UNEXPECTEDLY(hr
))
1218 HMENU hmenu
= CreatePopupMenu();
1220 hr
= m_pCM
->QueryContextMenu(hmenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, 0);
1221 if (FAILED_UNEXPECTEDLY(hr
))
1224 // TODO: filter or something
1226 Shell_MergeMenus(hFileMenu
, hmenu
, 0, 0, 0xFFFF, MM_ADDSEPARATOR
| MM_SUBMENUSHAVEIDS
);
1228 ::DestroyMenu(hmenu
);
1233 HRESULT
CDefView::FillEditMenu()
1235 HMENU hEditMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_EDIT
);
1239 HMENU hmenuContents
= ::LoadMenuW(shell32_hInstance
, L
"MENU_003");
1243 Shell_MergeMenus(hEditMenu
, hmenuContents
, 0, 0, 0xFFFF, 0);
1245 ::DestroyMenu(hmenuContents
);
1250 HRESULT
CDefView::FillViewMenu()
1252 HMENU hViewMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_VIEW
);
1256 m_hMenuViewModes
= ::LoadMenuW(shell32_hInstance
, L
"MENU_001");
1257 if (!m_hMenuViewModes
)
1260 UINT i
= SHMenuIndexFromID(hViewMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
);
1261 Shell_MergeMenus(hViewMenu
, m_hMenuViewModes
, i
, 0, 0xFFFF, MM_ADDSEPARATOR
| MM_DONTREMOVESEPS
| MM_SUBMENUSHAVEIDS
);
1266 HRESULT
CDefView::FillArrangeAsMenu(HMENU hmenuArrange
)
1268 /* We only need to fill this once */
1269 if (GetMenuItemID(hmenuArrange
, 0) == FCIDM_SHVIEW_AUTOARRANGE
)
1271 Shell_MergeMenus(hmenuArrange
, m_hMenuArrangeModes
, 0, 0, 0xFFFF,0);
1274 /* Also check the menu item according to which we sort */
1275 CheckMenuRadioItem(hmenuArrange
,
1278 m_sortInfo
.nHeaderID
+ 0x30,
1281 if (m_FolderSettings
.ViewMode
== FVM_DETAILS
|| m_FolderSettings
.ViewMode
== FVM_LIST
)
1283 EnableMenuItem(hmenuArrange
, FCIDM_SHVIEW_AUTOARRANGE
, MF_BYCOMMAND
| MF_GRAYED
);
1287 EnableMenuItem(hmenuArrange
, FCIDM_SHVIEW_AUTOARRANGE
, MF_BYCOMMAND
);
1289 if (GetAutoArrange() == S_OK
)
1290 CheckMenuItem(hmenuArrange
, FCIDM_SHVIEW_AUTOARRANGE
, MF_CHECKED
);
1297 HRESULT
CDefView::CheckViewMode(HMENU hmenuView
)
1299 if (m_FolderSettings
.ViewMode
>= FVM_FIRST
&& m_FolderSettings
.ViewMode
<= FVM_LAST
)
1301 UINT iItemFirst
= FCIDM_SHVIEW_BIGICON
;
1302 UINT iItemLast
= iItemFirst
+ FVM_LAST
- FVM_FIRST
;
1303 UINT iItem
= iItemFirst
+ m_FolderSettings
.ViewMode
- FVM_FIRST
;
1304 CheckMenuRadioItem(hmenuView
, iItemFirst
, iItemLast
, iItem
, MF_BYCOMMAND
);
1310 /**********************************************************
1311 * ShellView_GetSelections()
1313 * - fills the m_apidl list with the selected objects
1316 * number of selected items
1318 UINT
CDefView::GetSelections()
1322 m_cidl
= m_ListView
.GetSelectedCount();
1323 m_apidl
= static_cast<PCUITEMID_CHILD
*>(SHAlloc(m_cidl
* sizeof(PCUITEMID_CHILD
)));
1330 TRACE("-- Items selected =%u\n", m_cidl
);
1334 while ((lvIndex
= m_ListView
.GetNextItem(lvIndex
, LVNI_SELECTED
)) > -1)
1336 m_apidl
[i
] = _PidlByItem(lvIndex
);
1340 TRACE("-- selected Item found\n");
1346 HRESULT
CDefView::InvokeContextMenuCommand(UINT uCommand
)
1348 CMINVOKECOMMANDINFO cmi
;
1350 ZeroMemory(&cmi
, sizeof(cmi
));
1351 cmi
.cbSize
= sizeof(cmi
);
1352 cmi
.lpVerb
= MAKEINTRESOURCEA(uCommand
);
1355 if (GetKeyState(VK_SHIFT
) & 0x8000)
1356 cmi
.fMask
|= CMIC_MASK_SHIFT_DOWN
;
1358 if (GetKeyState(VK_CONTROL
) & 0x8000)
1359 cmi
.fMask
|= CMIC_MASK_CONTROL_DOWN
;
1361 HRESULT hr
= m_pCM
->InvokeCommand(&cmi
);
1362 if (FAILED_UNEXPECTEDLY(hr
))
1368 /**********************************************************
1369 * ShellView_OpenSelectedItems()
1371 HRESULT
CDefView::OpenSelectedItems()
1377 m_cidl
= m_ListView
.GetSelectedCount();
1381 hResult
= OnDefaultCommand();
1382 if (hResult
== S_OK
)
1385 hMenu
= CreatePopupMenu();
1389 hResult
= GetItemObject(SVGIO_SELECTION
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1390 if (FAILED_UNEXPECTEDLY(hResult
))
1393 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_DEFAULTONLY
);
1394 if (FAILED_UNEXPECTEDLY(hResult
))
1397 uCommand
= GetMenuDefaultItem(hMenu
, FALSE
, 0);
1398 if (uCommand
== (UINT
)-1)
1404 InvokeContextMenuCommand(uCommand
);
1413 IUnknown_SetSite(m_pCM
, NULL
);
1420 /**********************************************************
1421 * ShellView_DoContextMenu()
1423 LRESULT
CDefView::OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1429 TRACE("(%p)\n", this);
1431 m_hContextMenu
= CreatePopupMenu();
1432 if (!m_hContextMenu
)
1435 if (lParam
!= ~0) // unless app key (menu key) was pressed
1437 x
= GET_X_LPARAM(lParam
);
1438 y
= GET_Y_LPARAM(lParam
);
1440 LV_HITTESTINFO hittest
= { { x
, y
} };
1441 ScreenToClient(&hittest
.pt
);
1442 m_ListView
.HitTest(&hittest
);
1444 // Right-Clicked item is selected? If selected, no selection change.
1445 // If not selected, then reset the selection and select the item.
1446 if ((hittest
.flags
& LVHT_ONITEM
) &&
1447 m_ListView
.GetItemState(hittest
.iItem
, LVIS_SELECTED
) != LVIS_SELECTED
)
1449 SelectItem(hittest
.iItem
, SVSI_SELECT
| SVSI_DESELECTOTHERS
| SVSI_ENSUREVISIBLE
);
1453 m_cidl
= m_ListView
.GetSelectedCount();
1455 hResult
= GetItemObject( m_cidl
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1456 if (FAILED_UNEXPECTEDLY(hResult
))
1459 /* Use 1 as the first id as we want 0 the mean that the user canceled the menu */
1460 hResult
= m_pCM
->QueryContextMenu(m_hContextMenu
, 0, CONTEXT_MENU_BASE_ID
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1461 if (FAILED_UNEXPECTEDLY(hResult
))
1464 /* There is no position requested, so try to find one */
1467 HWND hFocus
= ::GetFocus();
1471 if (hFocus
== m_ListView
.m_hWnd
|| m_ListView
.IsChild(hFocus
))
1473 /* Is there an item focused and selected? */
1474 lvIndex
= m_ListView
.GetNextItem(-1, LVIS_SELECTED
|LVIS_FOCUSED
);
1475 /* If not, find the first selected item */
1477 lvIndex
= m_ListView
.GetNextItem(-1, LVIS_SELECTED
);
1480 /* We got something */
1483 /* Let's find the center of the icon */
1484 RECT rc
= { LVIR_ICON
};
1485 m_ListView
.SendMessage(LVM_GETITEMRECT
, lvIndex
, (LPARAM
)&rc
);
1486 pt
.x
= (rc
.right
+ rc
.left
) / 2;
1487 pt
.y
= (rc
.bottom
+ rc
.top
) / 2;
1491 /* We have to drop it somewhere.. */
1495 m_ListView
.ClientToScreen(&pt
);
1500 uCommand
= TrackPopupMenu(m_hContextMenu
,
1501 TPM_LEFTALIGN
| TPM_RETURNCMD
| TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
,
1502 x
, y
, 0, m_hWnd
, NULL
);
1506 if (uCommand
== FCIDM_SHVIEW_OPEN
&& OnDefaultCommand() == S_OK
)
1509 InvokeContextMenuCommand(uCommand
- CONTEXT_MENU_BASE_ID
);
1514 IUnknown_SetSite(m_pCM
, NULL
);
1520 DestroyMenu(m_hContextMenu
);
1521 m_hContextMenu
= NULL
;
1527 LRESULT
CDefView::OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
)
1532 hMenu
= CreatePopupMenu();
1536 hResult
= GetItemObject( bUseSelection
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1537 if (FAILED_UNEXPECTEDLY( hResult
))
1540 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1541 if (FAILED_UNEXPECTEDLY( hResult
))
1544 InvokeContextMenuCommand(uCommand
);
1549 IUnknown_SetSite(m_pCM
, NULL
);
1559 /**********************************************************
1560 * ##### message handling #####
1563 /**********************************************************
1564 * ShellView_OnSize()
1566 LRESULT
CDefView::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1568 WORD wWidth
, wHeight
;
1570 wWidth
= LOWORD(lParam
);
1571 wHeight
= HIWORD(lParam
);
1573 TRACE("%p width=%u height=%u\n", this, wWidth
, wHeight
);
1575 /* Resize the ListView to fit our window */
1578 ::MoveWindow(m_ListView
, 0, 0, wWidth
, wHeight
, TRUE
);
1581 _DoFolderViewCB(SFVM_SIZE
, 0, 0);
1586 /**********************************************************
1587 * ShellView_OnDeactivate()
1592 void CDefView::OnDeactivate()
1594 TRACE("%p\n", this);
1596 if (m_uState
!= SVUIA_DEACTIVATE
)
1598 // TODO: cleanup menu after deactivation
1600 m_uState
= SVUIA_DEACTIVATE
;
1604 void CDefView::DoActivate(UINT uState
)
1606 TRACE("%p uState=%x\n", this, uState
);
1608 /*don't do anything if the state isn't really changing */
1609 if (m_uState
== uState
)
1614 if (uState
== SVUIA_DEACTIVATE
)
1620 if(m_hMenu
&& !m_bmenuBarInitialized
)
1624 m_pShellBrowser
->SetMenuSB(m_hMenu
, 0, m_hWnd
);
1625 m_bmenuBarInitialized
= TRUE
;
1628 if (SVUIA_ACTIVATE_FOCUS
== uState
)
1630 m_ListView
.SetFocus();
1638 /**********************************************************
1639 * ShellView_OnActivate()
1641 LRESULT
CDefView::OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1643 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1647 /**********************************************************
1648 * ShellView_OnSetFocus()
1651 LRESULT
CDefView::OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1653 TRACE("%p\n", this);
1655 /* Tell the browser one of our windows has received the focus. This
1656 should always be done before merging menus (OnActivate merges the
1657 menus) if one of our windows has the focus.*/
1659 m_pShellBrowser
->OnViewWindowActive(this);
1660 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1662 /* Set the focus to the listview */
1663 m_ListView
.SetFocus();
1665 /* Notify the ICommDlgBrowser interface */
1666 OnStateChange(CDBOSC_SETFOCUS
);
1671 /**********************************************************
1672 * ShellView_OnKillFocus()
1674 LRESULT
CDefView::OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1676 TRACE("(%p) stub\n", this);
1678 DoActivate(SVUIA_ACTIVATE_NOFOCUS
);
1679 /* Notify the ICommDlgBrowser */
1680 OnStateChange(CDBOSC_KILLFOCUS
);
1685 /**********************************************************
1686 * ShellView_OnCommand()
1689 * the CmdID's are the ones from the context menu
1691 LRESULT
CDefView::OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1698 dwCmdID
= GET_WM_COMMAND_ID(wParam
, lParam
);
1699 dwCmd
= GET_WM_COMMAND_CMD(wParam
, lParam
);
1700 hwndCmd
= GET_WM_COMMAND_HWND(wParam
, lParam
);
1702 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n", this, dwCmdID
, dwCmd
, hwndCmd
);
1706 case FCIDM_SHVIEW_SMALLICON
:
1707 m_FolderSettings
.ViewMode
= FVM_SMALLICON
;
1708 m_ListView
.ModifyStyle(LVS_TYPEMASK
, LVS_SMALLICON
);
1712 case FCIDM_SHVIEW_BIGICON
:
1713 m_FolderSettings
.ViewMode
= FVM_ICON
;
1714 m_ListView
.ModifyStyle(LVS_TYPEMASK
, LVS_ICON
);
1718 case FCIDM_SHVIEW_LISTVIEW
:
1719 m_FolderSettings
.ViewMode
= FVM_LIST
;
1720 m_ListView
.ModifyStyle(LVS_TYPEMASK
, LVS_LIST
);
1724 case FCIDM_SHVIEW_REPORTVIEW
:
1725 m_FolderSettings
.ViewMode
= FVM_DETAILS
;
1726 m_ListView
.ModifyStyle(LVS_TYPEMASK
, LVS_REPORT
);
1730 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1735 m_sortInfo
.nHeaderID
= dwCmdID
- 0x30;
1736 m_sortInfo
.bIsAscending
= TRUE
;
1740 case FCIDM_SHVIEW_SNAPTOGRID
:
1743 case FCIDM_SHVIEW_AUTOARRANGE
:
1744 if (GetAutoArrange() == S_OK
)
1745 m_ListView
.ModifyStyle(LVS_AUTOARRANGE
, 0);
1749 case FCIDM_SHVIEW_SELECTALL
:
1750 m_ListView
.SetItemState(-1, LVIS_SELECTED
, LVIS_SELECTED
);
1753 case FCIDM_SHVIEW_INVERTSELECTION
:
1754 nCount
= m_ListView
.GetItemCount();
1755 for (int i
=0; i
< nCount
; i
++)
1756 m_ListView
.SetItemState(i
, m_ListView
.GetItemState(i
, LVIS_SELECTED
) ? 0 : LVIS_SELECTED
, LVIS_SELECTED
);
1759 case FCIDM_SHVIEW_REFRESH
:
1763 case FCIDM_SHVIEW_DELETE
:
1764 case FCIDM_SHVIEW_CUT
:
1765 case FCIDM_SHVIEW_COPY
:
1766 case FCIDM_SHVIEW_RENAME
:
1767 case FCIDM_SHVIEW_PROPERTIES
:
1768 return OnExplorerCommand(dwCmdID
, TRUE
);
1770 case FCIDM_SHVIEW_INSERT
:
1771 case FCIDM_SHVIEW_UNDO
:
1772 case FCIDM_SHVIEW_INSERTLINK
:
1773 case FCIDM_SHVIEW_NEWFOLDER
:
1774 return OnExplorerCommand(dwCmdID
, FALSE
);
1776 /* WM_COMMAND messages from the file menu are routed to the CDefView so as to let m_pCM handle the command */
1777 if (m_pCM
&& dwCmd
== 0)
1779 InvokeContextMenuCommand(dwCmdID
);
1786 /**********************************************************
1787 * ShellView_OnNotify()
1790 LRESULT
CDefView::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1794 LPNMLISTVIEW lpnmlv
;
1795 NMLVDISPINFOW
*lpdi
;
1796 PCUITEMID_CHILD pidl
;
1800 lpnmh
= (LPNMHDR
)lParam
;
1801 lpnmlv
= (LPNMLISTVIEW
)lpnmh
;
1802 lpdi
= (NMLVDISPINFOW
*)lpnmh
;
1804 TRACE("%p CtlID=%u lpnmh->code=%x\n", this, CtlID
, lpnmh
->code
);
1806 switch (lpnmh
->code
)
1809 TRACE("-- NM_SETFOCUS %p\n", this);
1810 OnSetFocus(0, 0, 0, unused
);
1814 TRACE("-- NM_KILLFOCUS %p\n", this);
1816 /* Notify the ICommDlgBrowser interface */
1817 OnStateChange(CDBOSC_KILLFOCUS
);
1821 TRACE("-- NM_CUSTOMDRAW %p\n", this);
1822 return CDRF_DODEFAULT
;
1824 case NM_RELEASEDCAPTURE
:
1825 TRACE("-- NM_RELEASEDCAPTURE %p\n", this);
1829 TRACE("-- NM_CLICK %p\n", this);
1833 TRACE("-- NM_RCLICK %p\n", this);
1837 TRACE("-- NM_DBLCLK %p\n", this);
1838 OpenSelectedItems();
1842 TRACE("-- NM_RETURN %p\n", this);
1843 OpenSelectedItems();
1847 TRACE("-- HDN_ENDTRACKW %p\n", this);
1848 /*nColumn1 = m_ListView.GetColumnWidth(0);
1849 nColumn2 = m_ListView.GetColumnWidth(1);*/
1852 case LVN_DELETEITEM
:
1853 TRACE("-- LVN_DELETEITEM %p\n", this);
1855 /*delete the pidl because we made a copy of it*/
1856 SHFree(reinterpret_cast<LPVOID
>(lpnmlv
->lParam
));
1860 case LVN_DELETEALLITEMS
:
1861 TRACE("-- LVN_DELETEALLITEMS %p\n", this);
1864 case LVN_INSERTITEM
:
1865 TRACE("-- LVN_INSERTITEM (STUB)%p\n", this);
1868 case LVN_ITEMACTIVATE
:
1869 TRACE("-- LVN_ITEMACTIVATE %p\n", this);
1870 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1873 case LVN_COLUMNCLICK
:
1874 m_sortInfo
.nHeaderID
= lpnmlv
->iSubItem
;
1875 if (m_sortInfo
.nLastHeaderID
== m_sortInfo
.nHeaderID
)
1876 m_sortInfo
.bIsAscending
= !m_sortInfo
.bIsAscending
;
1878 m_sortInfo
.bIsAscending
= TRUE
;
1882 case LVN_GETDISPINFOA
:
1883 case LVN_GETDISPINFOW
:
1884 TRACE("-- LVN_GETDISPINFO %p\n", this);
1885 pidl
= _PidlByItem(lpdi
->item
);
1887 if (lpdi
->item
.mask
& LVIF_TEXT
) /* text requested */
1892 if (FAILED_UNEXPECTEDLY(m_pSF2Parent
->GetDetailsOf(pidl
, lpdi
->item
.iSubItem
, &sd
)))
1895 if (lpnmh
->code
== LVN_GETDISPINFOA
)
1897 /* shouldn't happen */
1898 NMLVDISPINFOA
*lpdiA
= (NMLVDISPINFOA
*)lpnmh
;
1899 StrRetToStrNA( lpdiA
->item
.pszText
, lpdiA
->item
.cchTextMax
, &sd
.str
, NULL
);
1900 TRACE("-- text=%s\n", lpdiA
->item
.pszText
);
1902 else /* LVN_GETDISPINFOW */
1904 StrRetToStrNW( lpdi
->item
.pszText
, lpdi
->item
.cchTextMax
, &sd
.str
, NULL
);
1905 TRACE("-- text=%s\n", debugstr_w(lpdi
->item
.pszText
));
1910 FIXME("no m_pSF2Parent\n");
1913 if(lpdi
->item
.mask
& LVIF_IMAGE
) /* image requested */
1915 lpdi
->item
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
1917 if(lpdi
->item
.mask
& LVIF_STATE
)
1919 ULONG attributes
= SFGAO_HIDDEN
;
1920 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(1, &pidl
, &attributes
)))
1922 if (attributes
& SFGAO_HIDDEN
)
1924 lpdi
->item
.state
|= LVIS_CUT
;
1928 lpdi
->item
.mask
|= LVIF_DI_SETITEM
;
1931 case LVN_ITEMCHANGED
:
1932 TRACE("-- LVN_ITEMCHANGED %p\n", this);
1933 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1935 _DoFolderViewCB(SFVM_SELECTIONCHANGED
, NULL
/* FIXME */, NULL
/* FIXME */);
1939 case LVN_BEGINRDRAG
:
1940 TRACE("-- LVN_BEGINDRAG\n");
1942 if (GetSelections())
1944 CComPtr
<IDataObject
> pda
;
1945 DWORD dwAttributes
= SFGAO_CANCOPY
| SFGAO_CANLINK
;
1946 DWORD dwEffect
= DROPEFFECT_MOVE
;
1948 if (SUCCEEDED(m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, IID_NULL_PPV_ARG(IDataObject
, &pda
))))
1950 LPNMLISTVIEW params
= (LPNMLISTVIEW
)lParam
;
1952 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(m_cidl
, m_apidl
, &dwAttributes
)))
1954 dwEffect
|= dwAttributes
& (SFGAO_CANCOPY
| SFGAO_CANLINK
);
1957 CComPtr
<IAsyncOperation
> piaso
;
1958 if (SUCCEEDED(pda
->QueryInterface(IID_PPV_ARG(IAsyncOperation
, &piaso
))))
1960 piaso
->SetAsyncMode(TRUE
);
1965 m_pSourceDataObject
= pda
;
1966 m_ptFirstMousePos
= params
->ptAction
;
1967 ClientToScreen(&m_ptFirstMousePos
);
1969 HIMAGELIST big_icons
, small_icons
;
1970 Shell_GetImageLists(&big_icons
, &small_icons
);
1971 PCUITEMID_CHILD pidl
= _PidlByItem(params
->iItem
);
1972 int iIcon
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
1974 m_ListView
.GetItemPosition(params
->iItem
, &ptItem
);
1976 ImageList_BeginDrag(big_icons
, iIcon
, params
->ptAction
.x
- ptItem
.x
, params
->ptAction
.y
- ptItem
.y
);
1978 DoDragDrop(pda
, this, dwEffect
, &dwEffect2
);
1980 m_pSourceDataObject
.Release();
1985 case LVN_BEGINLABELEDITW
:
1987 DWORD dwAttr
= SFGAO_CANRENAME
;
1988 pidl
= _PidlByItem(lpdi
->item
);
1990 TRACE("-- LVN_BEGINLABELEDITW %p\n", this);
1992 m_pSFParent
->GetAttributesOf(1, &pidl
, &dwAttr
);
1993 if (SFGAO_CANRENAME
& dwAttr
)
1995 HWND hEdit
= reinterpret_cast<HWND
>(m_ListView
.SendMessage(LVM_GETEDITCONTROL
));
1996 SHLimitInputEdit(hEdit
, m_pSFParent
);
2005 case LVN_ENDLABELEDITW
:
2007 TRACE("-- LVN_ENDLABELEDITW %p\n", this);
2009 m_isEditing
= FALSE
;
2011 if (lpdi
->item
.pszText
)
2016 pidl
= _PidlByItem(lpdi
->item
);
2017 PITEMID_CHILD pidlNew
= NULL
;
2018 hr
= m_pSFParent
->SetNameOf(0, pidl
, lpdi
->item
.pszText
, SHGDN_INFOLDER
, &pidlNew
);
2020 if (SUCCEEDED(hr
) && pidlNew
)
2022 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
2023 lvItem
.iItem
= lpdi
->item
.iItem
;
2024 lvItem
.iSubItem
= 0;
2025 lvItem
.lParam
= reinterpret_cast<LPARAM
>(pidlNew
);
2026 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
2027 m_ListView
.SetItem(&lvItem
);
2028 m_ListView
.Update(lpdi
->item
.iItem
);
2037 TRACE("-- %p WM_COMMAND %x unhandled\n", this, lpnmh
->code
);
2045 * This is just a quick hack to make the desktop work correctly.
2046 * ITranslateShellChangeNotify's IsChildID is undocumented, but most likely the way that
2047 * a folder should know if it should update upon a change notification.
2048 * It is exported by merged folders at a minimum.
2050 static BOOL
ILIsParentOrSpecialParent(PCIDLIST_ABSOLUTE pidl1
, PCIDLIST_ABSOLUTE pidl2
)
2052 if (!pidl1
|| !pidl2
)
2054 if (ILIsParent(pidl1
, pidl2
, TRUE
))
2057 if (_ILIsDesktop(pidl1
))
2059 PIDLIST_ABSOLUTE deskpidl
;
2060 SHGetFolderLocation(NULL
, CSIDL_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
2061 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
2067 SHGetFolderLocation(NULL
, CSIDL_COMMON_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
2068 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
2078 /**********************************************************
2079 * ShellView_OnChange()
2081 LRESULT
CDefView::OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
2083 PCIDLIST_ABSOLUTE
*Pidls
= reinterpret_cast<PCIDLIST_ABSOLUTE
*>(wParam
);
2084 BOOL bParent0
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[0]);
2085 BOOL bParent1
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[1]);
2087 TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls
[0], Pidls
[1], lParam
);
2089 switch (lParam
&~ SHCNE_INTERRUPT
)
2095 if (LV_FindItemByPidl(ILFindLastID(Pidls
[0])) == -1)
2097 LV_AddItem(ILFindLastID(Pidls
[0]));
2101 LV_ProdItem(ILFindLastID(Pidls
[0]));
2109 LV_DeleteItem(ILFindLastID(Pidls
[0]));
2112 case SHCNE_RENAMEFOLDER
:
2113 case SHCNE_RENAMEITEM
:
2114 if (bParent0
&& bParent1
)
2115 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[1]));
2117 LV_DeleteItem(ILFindLastID(Pidls
[0]));
2119 LV_AddItem(ILFindLastID(Pidls
[1]));
2122 case SHCNE_UPDATEITEM
:
2124 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[0]));
2127 case SHCNE_UPDATEDIR
:
2134 HRESULT
SHGetMenuIdFromMenuMsg(UINT uMsg
, LPARAM lParam
, UINT
*CmdId
);
2135 HRESULT
SHSetMenuIdInMenuMsg(UINT uMsg
, LPARAM lParam
, UINT CmdId
);
2137 /**********************************************************
2138 * CDefView::OnCustomItem
2140 LRESULT
CDefView::OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
2145 ERR("no menu!!!\n");
2149 /* The lParam of WM_DRAWITEM WM_MEASUREITEM contain a menu id and this also needs to
2150 be changed to a menu identifier offset */
2152 HRESULT hres
= SHGetMenuIdFromMenuMsg(uMsg
, lParam
, &CmdID
);
2153 if (SUCCEEDED(hres
))
2154 SHSetMenuIdInMenuMsg(uMsg
, lParam
, CmdID
- CONTEXT_MENU_BASE_ID
);
2156 /* Forward the message to the IContextMenu2 */
2158 hres
= SHForwardContextMenuMsg(m_pCM
, uMsg
, wParam
, lParam
, &result
, TRUE
);
2160 return (SUCCEEDED(hres
));
2163 LRESULT
CDefView::OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
2165 /* Wallpaper setting affects drop shadows effect */
2166 if (wParam
== SPI_SETDESKWALLPAPER
|| wParam
== 0)
2172 /**********************************************************
2173 * CDefView::OnInitMenuPopup
2175 LRESULT
CDefView::OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
2177 HMENU hmenu
= (HMENU
) wParam
;
2178 int nPos
= LOWORD(lParam
);
2181 OnCustomItem(uMsg
, wParam
, lParam
, bHandled
);
2183 HMENU hViewMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_VIEW
);
2185 /* Lets try to find out what the hell wParam is */
2186 if (hmenu
== GetSubMenu(m_hMenu
, nPos
))
2187 menuItemId
= ReallyGetMenuItemID(m_hMenu
, nPos
);
2188 else if (hViewMenu
&& hmenu
== GetSubMenu(hViewMenu
, nPos
))
2189 menuItemId
= ReallyGetMenuItemID(hViewMenu
, nPos
);
2190 else if (m_hContextMenu
&& hmenu
== GetSubMenu(m_hContextMenu
, nPos
))
2191 menuItemId
= ReallyGetMenuItemID(m_hContextMenu
, nPos
);
2197 case FCIDM_MENU_FILE
:
2200 case FCIDM_MENU_VIEW
:
2201 case FCIDM_SHVIEW_VIEW
:
2202 CheckViewMode(hmenu
);
2204 case FCIDM_SHVIEW_ARRANGE
:
2205 FillArrangeAsMenu(hmenu
);
2212 /**********************************************************
2215 * The INTERFACE of the IShellView object
2218 **********************************************************
2221 /**********************************************************
2222 * ShellView_GetWindow
2224 HRESULT WINAPI
CDefView::GetWindow(HWND
*phWnd
)
2226 TRACE("(%p)\n", this);
2233 HRESULT WINAPI
CDefView::ContextSensitiveHelp(BOOL fEnterMode
)
2235 FIXME("(%p) stub\n", this);
2240 /**********************************************************
2241 * IShellView_TranslateAccelerator
2244 * use the accel functions
2246 HRESULT WINAPI
CDefView::TranslateAccelerator(LPMSG lpmsg
)
2251 if (lpmsg
->message
>= WM_KEYFIRST
&& lpmsg
->message
<= WM_KEYLAST
)
2253 if (::TranslateAcceleratorW(m_hWnd
, m_hAccel
, lpmsg
) != 0)
2256 TRACE("-- key=0x%04lx\n", lpmsg
->wParam
) ;
2259 return m_pShellBrowser
->TranslateAcceleratorSB(lpmsg
, 0);
2262 HRESULT WINAPI
CDefView::EnableModeless(BOOL fEnable
)
2264 FIXME("(%p) stub\n", this);
2269 HRESULT WINAPI
CDefView::UIActivate(UINT uState
)
2271 // CHAR szName[MAX_PATH];
2273 int nPartArray
[1] = { -1};
2275 TRACE("(%p)->(state=%x) stub\n", this, uState
);
2277 /* don't do anything if the state isn't really changing */
2278 if (m_uState
== uState
)
2283 /* OnActivate handles the menu merging and internal state */
2286 /* only do This if we are active */
2287 if (uState
!= SVUIA_DEACTIVATE
)
2291 GetFolderPath is not a method of IShellFolder
2292 IShellFolder_GetFolderPath( m_pSFParent, szName, sizeof(szName) );
2294 /* set the number of parts */
2295 m_pShellBrowser
->SendControlMsg(FCW_STATUS
, SB_SETPARTS
, 1, (LPARAM
)nPartArray
, &lResult
);
2297 /* set the text for the parts */
2299 m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXTA, 0, (LPARAM)szName, &lResult);
2306 HRESULT WINAPI
CDefView::Refresh()
2308 TRACE("(%p)\n", this);
2310 m_ListView
.DeleteAllItems();
2316 HRESULT WINAPI
CDefView::CreateViewWindow(IShellView
*lpPrevView
, LPCFOLDERSETTINGS lpfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
)
2318 return CreateViewWindow3(psb
, lpPrevView
, SV3CVW3_DEFAULT
,
2319 (FOLDERFLAGS
)lpfs
->fFlags
, (FOLDERFLAGS
)lpfs
->fFlags
, (FOLDERVIEWMODE
)lpfs
->ViewMode
, NULL
, prcView
, phWnd
);
2322 HRESULT WINAPI
CDefView::DestroyViewWindow()
2324 TRACE("(%p)\n", this);
2326 /* Make absolutely sure all our UI is cleaned up */
2327 UIActivate(SVUIA_DEACTIVATE
);
2331 // "Accelerator tables loaded from resources are freed automatically when the application terminates." -- MSDN
2335 if (m_hMenuArrangeModes
)
2337 DestroyMenu(m_hMenuArrangeModes
);
2338 m_hMenuArrangeModes
= NULL
;
2341 if (m_hMenuViewModes
)
2343 DestroyMenu(m_hMenuViewModes
);
2344 m_hMenuViewModes
= NULL
;
2349 DestroyMenu(m_hMenu
);
2355 m_ListView
.DestroyWindow();
2363 m_pShellBrowser
.Release();
2364 m_pCommDlgBrowser
.Release();
2369 HRESULT WINAPI
CDefView::GetCurrentInfo(LPFOLDERSETTINGS lpfs
)
2371 TRACE("(%p)->(%p) vmode=%x flags=%x\n", this, lpfs
,
2372 m_FolderSettings
.ViewMode
, m_FolderSettings
.fFlags
);
2375 return E_INVALIDARG
;
2377 *lpfs
= m_FolderSettings
;
2381 HRESULT WINAPI
CDefView::AddPropertySheetPages(DWORD dwReserved
, LPFNADDPROPSHEETPAGE lpfn
, LPARAM lparam
)
2383 FIXME("(%p) stub\n", this);
2388 HRESULT WINAPI
CDefView::SaveViewState()
2390 FIXME("(%p) stub\n", this);
2395 HRESULT WINAPI
CDefView::SelectItem(PCUITEMID_CHILD pidl
, UINT uFlags
)
2399 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n", this, pidl
, uFlags
);
2401 i
= LV_FindItemByPidl(pidl
);
2405 LVITEMW lvItem
= {0};
2406 lvItem
.mask
= LVIF_STATE
;
2407 lvItem
.stateMask
= LVIS_SELECTED
| LVIS_FOCUSED
;
2409 while (m_ListView
.GetItem(&lvItem
))
2411 if (lvItem
.iItem
== i
)
2413 if (uFlags
& SVSI_SELECT
)
2414 lvItem
.state
|= LVIS_SELECTED
;
2416 lvItem
.state
&= ~LVIS_SELECTED
;
2418 if (uFlags
& SVSI_FOCUSED
)
2419 lvItem
.state
|= LVIS_FOCUSED
;
2421 lvItem
.state
&= ~LVIS_FOCUSED
;
2425 if (uFlags
& SVSI_DESELECTOTHERS
)
2427 lvItem
.state
&= ~LVIS_SELECTED
;
2429 lvItem
.state
&= ~LVIS_FOCUSED
;
2432 m_ListView
.SetItem(&lvItem
);
2436 if (uFlags
& SVSI_ENSUREVISIBLE
)
2437 m_ListView
.EnsureVisible(i
, FALSE
);
2439 if((uFlags
& SVSI_EDIT
) == SVSI_EDIT
)
2440 m_ListView
.EditLabel(i
);
2445 HRESULT WINAPI
CDefView::GetItemObject(UINT uItem
, REFIID riid
, LPVOID
*ppvOut
)
2447 HRESULT hr
= E_NOINTERFACE
;
2449 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n", this, uItem
, debugstr_guid(&riid
), ppvOut
);
2452 return E_INVALIDARG
;
2458 case SVGIO_BACKGROUND
:
2459 if (IsEqualIID(riid
, IID_IContextMenu
))
2461 hr
= CDefViewBckgrndMenu_CreateInstance(m_pSF2Parent
, riid
, ppvOut
);
2462 if (FAILED_UNEXPECTEDLY(hr
))
2465 IUnknown_SetSite(*((IUnknown
**)ppvOut
), (IShellView
*)this);
2467 else if (IsEqualIID(riid
, IID_IDispatch
))
2469 if (m_pShellFolderViewDual
== NULL
)
2471 hr
= CDefViewDual_Constructor(riid
, (LPVOID
*)&m_pShellFolderViewDual
);
2472 if (FAILED_UNEXPECTEDLY(hr
))
2475 hr
= m_pShellFolderViewDual
->QueryInterface(riid
, ppvOut
);
2479 case SVGIO_SELECTION
:
2481 hr
= m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, riid
, 0, ppvOut
);
2482 if (FAILED_UNEXPECTEDLY(hr
))
2485 if (IsEqualIID(riid
, IID_IContextMenu
))
2486 IUnknown_SetSite(*((IUnknown
**)ppvOut
), (IShellView
*)this);
2491 TRACE("-- (%p)->(interface=%p)\n", this, *ppvOut
);
2496 HRESULT STDMETHODCALLTYPE
CDefView::GetCurrentViewMode(UINT
*pViewMode
)
2498 TRACE("(%p)->(%p), stub\n", this, pViewMode
);
2501 return E_INVALIDARG
;
2503 *pViewMode
= m_FolderSettings
.ViewMode
;
2507 HRESULT STDMETHODCALLTYPE
CDefView::SetCurrentViewMode(UINT ViewMode
)
2510 TRACE("(%p)->(%u), stub\n", this, ViewMode
);
2512 /* It's not redundant to check FVM_AUTO because it's a (UINT)-1 */
2513 if (((INT
)ViewMode
< FVM_FIRST
|| (INT
)ViewMode
> FVM_LAST
) && ((INT
)ViewMode
!= FVM_AUTO
))
2514 return E_INVALIDARG
;
2516 /* Windows before Vista uses LVM_SETVIEW and possibly
2517 LVM_SETEXTENDEDLISTVIEWSTYLE to set the style of the listview,
2518 while later versions seem to accomplish this through other
2526 dwStyle
= LVS_REPORT
;
2529 dwStyle
= LVS_SMALLICON
;
2536 FIXME("ViewMode %d not implemented\n", ViewMode
);
2542 m_ListView
.ModifyStyle(LVS_TYPEMASK
, dwStyle
);
2544 /* This will not necessarily be the actual mode set above.
2545 This mimics the behavior of Windows XP. */
2546 m_FolderSettings
.ViewMode
= ViewMode
;
2551 HRESULT STDMETHODCALLTYPE
CDefView::GetFolder(REFIID riid
, void **ppv
)
2553 if (m_pSFParent
== NULL
)
2556 return m_pSFParent
->QueryInterface(riid
, ppv
);
2559 HRESULT STDMETHODCALLTYPE
CDefView::Item(int iItemIndex
, PITEMID_CHILD
*ppidl
)
2561 PCUITEMID_CHILD pidl
= _PidlByItem(iItemIndex
);
2564 *ppidl
= ILClone(pidl
);
2569 return E_INVALIDARG
;
2572 HRESULT STDMETHODCALLTYPE
CDefView::ItemCount(UINT uFlags
, int *pcItems
)
2574 TRACE("(%p)->(%u %p)\n", this, uFlags
, pcItems
);
2576 if (uFlags
!= SVGIO_ALLVIEW
)
2577 FIXME("some flags unsupported, %x\n", uFlags
& ~SVGIO_ALLVIEW
);
2579 *pcItems
= m_ListView
.GetItemCount();
2584 HRESULT STDMETHODCALLTYPE
CDefView::Items(UINT uFlags
, REFIID riid
, void **ppv
)
2589 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectionMarkedItem(int *piItem
)
2591 TRACE("(%p)->(%p)\n", this, piItem
);
2593 *piItem
= m_ListView
.GetSelectionMark();
2598 HRESULT STDMETHODCALLTYPE
CDefView::GetFocusedItem(int *piItem
)
2600 TRACE("(%p)->(%p)\n", this, piItem
);
2602 *piItem
= m_ListView
.GetNextItem(-1, LVNI_FOCUSED
);
2607 HRESULT STDMETHODCALLTYPE
CDefView::GetItemPosition(PCUITEMID_CHILD pidl
, POINT
*ppt
)
2609 int lvIndex
= LV_FindItemByPidl(pidl
);
2610 if (lvIndex
== -1 || ppt
== NULL
)
2611 return E_INVALIDARG
;
2613 m_ListView
.GetItemPosition(lvIndex
, ppt
);
2617 HRESULT STDMETHODCALLTYPE
CDefView::GetSpacing(POINT
*ppt
)
2619 TRACE("(%p)->(%p)\n", this, ppt
);
2627 m_ListView
.GetItemSpacing(spacing
);
2629 ppt
->x
= spacing
.cx
;
2630 ppt
->y
= spacing
.cy
;
2636 HRESULT STDMETHODCALLTYPE
CDefView::GetDefaultSpacing(POINT
*ppt
)
2641 HRESULT STDMETHODCALLTYPE
CDefView::GetAutoArrange()
2643 return ((m_ListView
.GetStyle() & LVS_AUTOARRANGE
) ? S_OK
: S_FALSE
);
2646 HRESULT STDMETHODCALLTYPE
CDefView::SelectItem(int iItem
, DWORD dwFlags
)
2650 TRACE("(%p)->(%d, %x)\n", this, iItem
, dwFlags
);
2653 lvItem
.stateMask
= LVIS_SELECTED
;
2655 if (dwFlags
& SVSI_ENSUREVISIBLE
)
2656 m_ListView
.EnsureVisible(iItem
, 0);
2659 if (dwFlags
& SVSI_DESELECTOTHERS
)
2660 m_ListView
.SetItemState(-1, 0, LVIS_SELECTED
);
2663 if (dwFlags
& SVSI_SELECT
)
2664 lvItem
.state
|= LVIS_SELECTED
;
2666 if (dwFlags
& SVSI_FOCUSED
)
2667 lvItem
.stateMask
|= LVIS_FOCUSED
;
2669 m_ListView
.SetItemState(iItem
, lvItem
.state
, lvItem
.stateMask
);
2671 if ((dwFlags
& SVSI_EDIT
) == SVSI_EDIT
)
2672 m_ListView
.EditLabel(iItem
);
2677 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItems(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD dwFlags
)
2679 /* Reset the selection */
2680 m_ListView
.SetItemState(-1, 0, LVIS_SELECTED
);
2683 for (UINT i
= 0 ; i
< m_cidl
; i
++)
2685 lvIndex
= LV_FindItemByPidl(apidl
[i
]);
2688 SelectItem(lvIndex
, dwFlags
);
2689 m_ListView
.SetItemPosition(lvIndex
, &apt
[i
]);
2696 /**********************************************************
2697 * IShellView2 implementation
2700 HRESULT STDMETHODCALLTYPE
CDefView::GetView(SHELLVIEWID
*view_guid
, ULONG view_type
)
2702 FIXME("(%p)->(%p, %lu) stub\n", this, view_guid
, view_type
);
2706 HRESULT STDMETHODCALLTYPE
CDefView::CreateViewWindow2(LPSV2CVW2_PARAMS view_params
)
2708 return CreateViewWindow3(view_params
->psbOwner
, view_params
->psvPrev
,
2709 SV3CVW3_DEFAULT
, (FOLDERFLAGS
)view_params
->pfs
->fFlags
, (FOLDERFLAGS
)view_params
->pfs
->fFlags
,
2710 (FOLDERVIEWMODE
)view_params
->pfs
->ViewMode
, view_params
->pvid
, view_params
->prcView
, &view_params
->hwndView
);
2713 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
)
2715 OLEMENUGROUPWIDTHS omw
= { { 0, 0, 0, 0, 0, 0 } };
2719 TRACE("(%p)->(shlview=%p shlbrs=%p rec=%p hwnd=%p vmode=%x flags=%x)\n", this, psvPrevious
, psb
, prcView
, hwnd
, mode
, flags
);
2720 if (prcView
!= NULL
)
2721 TRACE("-- left=%i top=%i right=%i bottom=%i\n", prcView
->left
, prcView
->top
, prcView
->right
, prcView
->bottom
);
2723 /* Validate the Shell Browser */
2724 if (psb
== NULL
|| m_hWnd
)
2725 return E_UNEXPECTED
;
2727 if (view_flags
!= SV3CVW3_DEFAULT
)
2728 FIXME("unsupported view flags 0x%08x\n", view_flags
);
2730 /* Set up the member variables */
2731 m_pShellBrowser
= psb
;
2732 m_FolderSettings
.ViewMode
= mode
;
2733 m_FolderSettings
.fFlags
= mask
& flags
;
2737 if (IsEqualIID(*view_id
, VID_LargeIcons
))
2738 m_FolderSettings
.ViewMode
= FVM_ICON
;
2739 else if (IsEqualIID(*view_id
, VID_SmallIcons
))
2740 m_FolderSettings
.ViewMode
= FVM_SMALLICON
;
2741 else if (IsEqualIID(*view_id
, VID_List
))
2742 m_FolderSettings
.ViewMode
= FVM_LIST
;
2743 else if (IsEqualIID(*view_id
, VID_Details
))
2744 m_FolderSettings
.ViewMode
= FVM_DETAILS
;
2745 else if (IsEqualIID(*view_id
, VID_Thumbnails
))
2746 m_FolderSettings
.ViewMode
= FVM_THUMBNAIL
;
2747 else if (IsEqualIID(*view_id
, VID_Tile
))
2748 m_FolderSettings
.ViewMode
= FVM_TILE
;
2749 else if (IsEqualIID(*view_id
, VID_ThumbStrip
))
2750 m_FolderSettings
.ViewMode
= FVM_THUMBSTRIP
;
2752 FIXME("Ignoring unrecognized VID %s\n", debugstr_guid(view_id
));
2755 /* Get our parent window */
2756 m_pShellBrowser
->GetWindow(&m_hWndParent
);
2758 /* Try to get the ICommDlgBrowserInterface, adds a reference !!! */
2759 m_pCommDlgBrowser
= NULL
;
2760 if (SUCCEEDED(m_pShellBrowser
->QueryInterface(IID_PPV_ARG(ICommDlgBrowser
, &m_pCommDlgBrowser
))))
2762 TRACE("-- CommDlgBrowser\n");
2765 Create(m_hWndParent
, prcView
, NULL
, WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
| WS_TABSTOP
, 0, 0U);
2776 _DoFolderViewCB(SFVM_WINDOWCREATED
, (WPARAM
)m_hWnd
, NULL
);
2778 SetWindowPos(HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_SHOWWINDOW
);
2783 m_hMenu
= CreateMenu();
2784 m_pShellBrowser
->InsertMenusSB(m_hMenu
, &omw
);
2785 TRACE("-- after fnInsertMenusSB\n");
2793 HRESULT STDMETHODCALLTYPE
CDefView::HandleRename(LPCITEMIDLIST new_pidl
)
2795 FIXME("(%p)->(%p) stub\n", this, new_pidl
);
2799 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItem(LPCITEMIDLIST item
, UINT flags
, POINT
*point
)
2801 FIXME("(%p)->(%p, %u, %p) stub\n", this, item
, flags
, point
);
2805 /**********************************************************
2806 * IShellFolderView implementation
2808 HRESULT STDMETHODCALLTYPE
CDefView::Rearrange(LPARAM sort
)
2810 FIXME("(%p)->(%ld) stub\n", this, sort
);
2814 HRESULT STDMETHODCALLTYPE
CDefView::GetArrangeParam(LPARAM
*sort
)
2816 FIXME("(%p)->(%p) stub\n", this, sort
);
2820 HRESULT STDMETHODCALLTYPE
CDefView::ArrangeGrid()
2822 FIXME("(%p) stub\n", this);
2826 HRESULT STDMETHODCALLTYPE
CDefView::AutoArrange()
2828 m_ListView
.ModifyStyle(0, LVS_AUTOARRANGE
);
2829 m_ListView
.Arrange(LVA_DEFAULT
);
2833 HRESULT STDMETHODCALLTYPE
CDefView::AddObject(PITEMID_CHILD pidl
, UINT
*item
)
2835 TRACE("(%p)->(%p %p)\n", this, pidl
, item
);
2836 *item
= LV_AddItem(pidl
);
2837 return (int)*item
>= 0 ? S_OK
: E_OUTOFMEMORY
;
2840 HRESULT STDMETHODCALLTYPE
CDefView::GetObject(PITEMID_CHILD
*pidl
, UINT item
)
2842 TRACE("(%p)->(%p %d)\n", this, pidl
, item
);
2843 return Item(item
, pidl
);
2846 HRESULT STDMETHODCALLTYPE
CDefView::RemoveObject(PITEMID_CHILD pidl
, UINT
*item
)
2849 TRACE("(%p)->(%p %p)\n", this, pidl
, item
);
2853 *item
= LV_FindItemByPidl(ILFindLastID(pidl
));
2854 m_ListView
.DeleteItem(*item
);
2859 m_ListView
.DeleteAllItems();
2865 HRESULT STDMETHODCALLTYPE
CDefView::GetObjectCount(UINT
*count
)
2867 TRACE("(%p)->(%p)\n", this, count
);
2868 *count
= m_ListView
.GetItemCount();
2872 HRESULT STDMETHODCALLTYPE
CDefView::SetObjectCount(UINT count
, UINT flags
)
2874 FIXME("(%p)->(%d %x) stub\n", this, count
, flags
);
2878 HRESULT STDMETHODCALLTYPE
CDefView::UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
)
2880 FIXME("(%p)->(%p %p %p) stub\n", this, pidl_old
, pidl_new
, item
);
2884 HRESULT STDMETHODCALLTYPE
CDefView::RefreshObject(PITEMID_CHILD pidl
, UINT
*item
)
2886 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2890 HRESULT STDMETHODCALLTYPE
CDefView::SetRedraw(BOOL redraw
)
2892 TRACE("(%p)->(%d)\n", this, redraw
);
2893 m_ListView
.SetRedraw(redraw
);
2897 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedCount(UINT
*count
)
2899 FIXME("(%p)->(%p) stub\n", this, count
);
2903 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
)
2905 TRACE("(%p)->(%p %p)\n", this, pidl
, items
);
2907 *items
= GetSelections();
2911 *pidl
= static_cast<PCUITEMID_CHILD
*>(LocalAlloc(0, *items
* sizeof(PCUITEMID_CHILD
)));
2914 return E_OUTOFMEMORY
;
2917 /* it's documented that caller shouldn't PIDLs, only array itself */
2918 memcpy(*pidl
, m_apidl
, *items
* sizeof(PCUITEMID_CHILD
));
2924 HRESULT STDMETHODCALLTYPE
CDefView::IsDropOnSource(IDropTarget
*drop_target
)
2926 if ((m_iDragOverItem
== -1 || m_pCurDropTarget
== NULL
) &&
2927 (m_pSourceDataObject
.p
))
2935 HRESULT STDMETHODCALLTYPE
CDefView::GetDragPoint(POINT
*pt
)
2938 return E_INVALIDARG
;
2940 *pt
= m_ptFirstMousePos
;
2944 HRESULT STDMETHODCALLTYPE
CDefView::GetDropPoint(POINT
*pt
)
2946 FIXME("(%p)->(%p) stub\n", this, pt
);
2950 HRESULT STDMETHODCALLTYPE
CDefView::MoveIcons(IDataObject
*obj
)
2952 TRACE("(%p)->(%p)\n", this, obj
);
2956 HRESULT STDMETHODCALLTYPE
CDefView::SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
)
2958 FIXME("(%p)->(%p %p) stub\n", this, pidl
, pt
);
2962 HRESULT STDMETHODCALLTYPE
CDefView::IsBkDropTarget(IDropTarget
*drop_target
)
2964 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2968 HRESULT STDMETHODCALLTYPE
CDefView::SetClipboard(BOOL move
)
2970 FIXME("(%p)->(%d) stub\n", this, move
);
2974 HRESULT STDMETHODCALLTYPE
CDefView::SetPoints(IDataObject
*obj
)
2976 FIXME("(%p)->(%p) stub\n", this, obj
);
2980 HRESULT STDMETHODCALLTYPE
CDefView::GetItemSpacing(ITEMSPACING
*spacing
)
2982 FIXME("(%p)->(%p) stub\n", this, spacing
);
2986 HRESULT STDMETHODCALLTYPE
CDefView::SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
)
2989 *old_cb
= m_pShellFolderViewCB
.Detach();
2991 m_pShellFolderViewCB
= new_cb
;
2995 HRESULT STDMETHODCALLTYPE
CDefView::Select(UINT flags
)
2997 FIXME("(%p)->(%d) stub\n", this, flags
);
3001 HRESULT STDMETHODCALLTYPE
CDefView::QuerySupport(UINT
*support
)
3003 TRACE("(%p)->(%p)\n", this, support
);
3007 HRESULT STDMETHODCALLTYPE
CDefView::SetAutomationObject(IDispatch
*disp
)
3009 FIXME("(%p)->(%p) stub\n", this, disp
);
3013 /**********************************************************
3014 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
3016 HRESULT WINAPI
CDefView::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD
*prgCmds
, OLECMDTEXT
*pCmdText
)
3018 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
3019 this, pguidCmdGroup
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
3022 return E_INVALIDARG
;
3024 for (UINT i
= 0; i
< cCmds
; i
++)
3026 FIXME("\tprgCmds[%d].cmdID = %d\n", i
, prgCmds
[i
].cmdID
);
3027 prgCmds
[i
].cmdf
= 0;
3030 return OLECMDERR_E_UNKNOWNGROUP
;
3033 /**********************************************************
3034 * ISVOleCmdTarget_Exec (IOleCommandTarget)
3036 * nCmdID is the OLECMDID_* enumeration
3038 HRESULT WINAPI
CDefView::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
3040 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
3041 this, debugstr_guid(pguidCmdGroup
), nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
3044 return OLECMDERR_E_UNKNOWNGROUP
;
3046 if (IsEqualCLSID(*pguidCmdGroup
, m_Category
))
3048 if (nCmdID
== FCIDM_SHVIEW_AUTOARRANGE
)
3050 if (V_VT(pvaIn
) != VT_INT_PTR
)
3051 return OLECMDERR_E_NOTSUPPORTED
;
3054 params
.cbSize
= sizeof(params
);
3055 params
.rcExclude
= *(RECT
*) V_INTREF(pvaIn
);
3057 if (m_hMenuViewModes
)
3059 /* Duplicate all but the last two items of the view modes menu */
3060 HMENU hmenuViewPopup
= CreatePopupMenu();
3061 Shell_MergeMenus(hmenuViewPopup
, m_hMenuViewModes
, 0, 0, 0xFFFF, 0);
3062 DeleteMenu(hmenuViewPopup
, GetMenuItemCount(hmenuViewPopup
) - 1, MF_BYPOSITION
);
3063 DeleteMenu(hmenuViewPopup
, GetMenuItemCount(hmenuViewPopup
) - 1, MF_BYPOSITION
);
3064 CheckViewMode(hmenuViewPopup
);
3065 TrackPopupMenuEx(hmenuViewPopup
, TPM_LEFTALIGN
| TPM_TOPALIGN
, params
.rcExclude
.left
, params
.rcExclude
.bottom
, m_hWndParent
, ¶ms
);
3066 ::DestroyMenu(hmenuViewPopup
);
3069 // pvaOut is VT_I4 with value 0x403 (cmd id of the new mode maybe?)
3070 V_VT(pvaOut
) = VT_I4
;
3071 V_I4(pvaOut
) = 0x403;
3075 if (IsEqualIID(*pguidCmdGroup
, CGID_Explorer
) &&
3077 (nCmdexecopt
== 4) && pvaOut
)
3080 if (IsEqualIID(*pguidCmdGroup
, CGID_ShellDocView
) &&
3085 return OLECMDERR_E_UNKNOWNGROUP
;
3088 /**********************************************************
3089 * ISVDropTarget implementation
3092 /******************************************************************************
3093 * drag_notify_subitem [Internal]
3095 * Figure out the shellfolder object, which is currently under the mouse cursor
3096 * and notify it via the IDropTarget interface.
3099 #define SCROLLAREAWIDTH 20
3101 HRESULT
CDefView::drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
3107 /* The key state on drop doesn't have MK_LBUTTON or MK_RBUTTON because it
3108 reflects the key state after the user released the button, so we need
3109 to remember the last key state when the button was pressed */
3110 m_grfKeyState
= grfKeyState
;
3112 /* Map from global to client coordinates and query the index of the listview-item, which is
3113 * currently under the mouse cursor. */
3114 LVHITTESTINFO htinfo
= {{pt
.x
, pt
.y
}, LVHT_ONITEM
};
3115 ScreenToClient(&htinfo
.pt
);
3116 lResult
= m_ListView
.HitTest(&htinfo
);
3118 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
3119 ::GetClientRect(m_ListView
, &clientRect
);
3120 if (htinfo
.pt
.x
== m_ptLastMousePos
.x
&& htinfo
.pt
.y
== m_ptLastMousePos
.y
&&
3121 (htinfo
.pt
.x
< SCROLLAREAWIDTH
|| htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
||
3122 htinfo
.pt
.y
< SCROLLAREAWIDTH
|| htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
))
3124 m_cScrollDelay
= (m_cScrollDelay
+ 1) % 5; /* DragOver is called every 50 ms */
3125 if (m_cScrollDelay
== 0)
3127 /* Mouse did hover another 250 ms over the scroll-area */
3128 if (htinfo
.pt
.x
< SCROLLAREAWIDTH
)
3129 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEUP
, 0);
3131 if (htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
)
3132 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEDOWN
, 0);
3134 if (htinfo
.pt
.y
< SCROLLAREAWIDTH
)
3135 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEUP
, 0);
3137 if (htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
)
3138 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEDOWN
, 0);
3143 m_cScrollDelay
= 0; /* Reset, if the cursor is not over the listview's scroll-area */
3146 m_ptLastMousePos
= htinfo
.pt
;
3148 /* We need to check if we drag the selection over itself */
3149 if (lResult
!= -1 && m_pSourceDataObject
.p
!= NULL
)
3151 PCUITEMID_CHILD pidl
= _PidlByItem(lResult
);
3153 for (UINT i
= 0; i
< m_cidl
; i
++)
3155 if (pidl
== m_apidl
[i
])
3157 /* The item that is being draged is hovering itself. */
3164 /* If we are still over the previous sub-item, notify it via DragOver and return. */
3165 if (m_pCurDropTarget
&& lResult
== m_iDragOverItem
)
3166 return m_pCurDropTarget
->DragOver(grfKeyState
, pt
, pdwEffect
);
3168 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
3169 if (m_pCurDropTarget
)
3171 PCUITEMID_CHILD pidl
= _PidlByItem(m_iDragOverItem
);
3173 SelectItem(pidl
, 0);
3175 m_pCurDropTarget
->DragLeave();
3176 m_pCurDropTarget
.Release();
3179 m_iDragOverItem
= lResult
;
3183 /* We are not above one of the listview's subitems. Bind to the parent folder's
3184 * DropTarget interface. */
3185 hr
= m_pSFParent
->CreateViewObject(NULL
, IID_PPV_ARG(IDropTarget
,&m_pCurDropTarget
));
3189 /* Query the relative PIDL of the shellfolder object represented by the currently
3190 * dragged over listview-item ... */
3191 PCUITEMID_CHILD pidl
= _PidlByItem(lResult
);
3193 /* ... and bind m_pCurDropTarget to the IDropTarget interface of an UIObject of this object */
3194 hr
= m_pSFParent
->GetUIObjectOf(m_ListView
, 1, &pidl
, IID_NULL_PPV_ARG(IDropTarget
, &m_pCurDropTarget
));
3197 IUnknown_SetSite(m_pCurDropTarget
, (IShellView
*)this);
3199 /* If anything failed, m_pCurDropTarget should be NULL now, which ought to be a save state. */
3202 *pdwEffect
= DROPEFFECT_NONE
;
3206 if (m_iDragOverItem
!= -1)
3208 SelectItem(m_iDragOverItem
, SVSI_SELECT
);
3211 /* Notify the item just entered via DragEnter. */
3212 return m_pCurDropTarget
->DragEnter(m_pCurDataObject
, grfKeyState
, pt
, pdwEffect
);
3215 HRESULT WINAPI
CDefView::DragEnter(IDataObject
*pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
3217 if (*pdwEffect
== DROPEFFECT_NONE
)
3220 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
3221 m_pCurDataObject
= pDataObject
;
3223 HRESULT hr
= drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
3226 POINT ptClient
= {pt
.x
, pt
.y
};
3227 ScreenToClient(&ptClient
);
3228 ImageList_DragEnter(m_hWnd
, ptClient
.x
, ptClient
.y
);
3234 HRESULT WINAPI
CDefView::DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
3236 POINT ptClient
= {pt
.x
, pt
.y
};
3237 ScreenToClient(&ptClient
);
3238 ImageList_DragMove(ptClient
.x
, ptClient
.y
);
3239 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
3242 HRESULT WINAPI
CDefView::DragLeave()
3244 ImageList_DragLeave(m_hWnd
);
3246 if (m_pCurDropTarget
)
3248 m_pCurDropTarget
->DragLeave();
3249 m_pCurDropTarget
.Release();
3252 if (m_pCurDataObject
!= NULL
)
3254 m_pCurDataObject
.Release();
3257 m_iDragOverItem
= 0;
3262 HRESULT WINAPI
CDefView::Drop(IDataObject
* pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
3264 ImageList_DragLeave(m_hWnd
);
3265 ImageList_EndDrag();
3267 if ((IsDropOnSource(NULL
) == S_OK
) &&
3268 (*pdwEffect
& DROPEFFECT_MOVE
) &&
3269 (m_grfKeyState
& MK_LBUTTON
))
3271 if (m_pCurDropTarget
)
3273 m_pCurDropTarget
->DragLeave();
3274 m_pCurDropTarget
.Release();
3277 /* Restore the selection */
3278 m_ListView
.SetItemState(-1, 0, LVIS_SELECTED
);
3279 for (UINT i
= 0 ; i
< m_cidl
; i
++)
3280 SelectItem(m_apidl
[i
], SVSI_SELECT
);
3282 /* Reposition the items */
3284 while ((lvIndex
= m_ListView
.GetNextItem(lvIndex
, LVNI_SELECTED
)) > -1)
3287 if (m_ListView
.GetItemPosition(lvIndex
, &ptItem
))
3289 ptItem
.x
+= pt
.x
- m_ptFirstMousePos
.x
;
3290 ptItem
.y
+= pt
.y
- m_ptFirstMousePos
.y
;
3291 m_ListView
.SetItemPosition(lvIndex
, &ptItem
);
3295 else if (m_pCurDropTarget
)
3297 m_pCurDropTarget
->Drop(pDataObject
, grfKeyState
, pt
, pdwEffect
);
3298 m_pCurDropTarget
.Release();
3301 m_pCurDataObject
.Release();
3302 m_iDragOverItem
= 0;
3306 /**********************************************************
3307 * ISVDropSource implementation
3310 HRESULT WINAPI
CDefView::QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
)
3312 TRACE("(%p)\n", this);
3315 return DRAGDROP_S_CANCEL
;
3316 else if (!(grfKeyState
& MK_LBUTTON
) && !(grfKeyState
& MK_RBUTTON
))
3317 return DRAGDROP_S_DROP
;
3322 HRESULT WINAPI
CDefView::GiveFeedback(DWORD dwEffect
)
3324 TRACE("(%p)\n", this);
3326 return DRAGDROP_S_USEDEFAULTCURSORS
;
3329 /**********************************************************
3330 * ISVViewObject implementation
3333 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
)
3335 FIXME("Stub: this=%p\n", this);
3340 HRESULT WINAPI
CDefView::GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
, HDC hicTargetDevice
, LOGPALETTE
**ppColorSet
)
3342 FIXME("Stub: this=%p\n", this);
3347 HRESULT WINAPI
CDefView::Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
)
3349 FIXME("Stub: this=%p\n", this);
3354 HRESULT WINAPI
CDefView::Unfreeze(DWORD dwFreeze
)
3356 FIXME("Stub: this=%p\n", this);
3361 HRESULT WINAPI
CDefView::SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
)
3363 FIXME("partial stub: %p 0x%08x 0x%08x %p\n", this, aspects
, advf
, pAdvSink
);
3365 /* FIXME: we set the AdviseSink, but never use it to send any advice */
3366 m_pAdvSink
= pAdvSink
;
3367 m_dwAspects
= aspects
;
3373 HRESULT WINAPI
CDefView::GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
)
3375 TRACE("this=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n", this, pAspects
, pAdvf
, ppAdvSink
);
3379 *ppAdvSink
= m_pAdvSink
;
3380 m_pAdvSink
.p
->AddRef();
3384 *pAspects
= m_dwAspects
;
3392 HRESULT STDMETHODCALLTYPE
CDefView::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
3394 if (IsEqualIID(guidService
, SID_IShellBrowser
))
3395 return m_pShellBrowser
->QueryInterface(riid
, ppvObject
);
3396 else if(IsEqualIID(guidService
, SID_IFolderView
))
3397 return QueryInterface(riid
, ppvObject
);
3399 return E_NOINTERFACE
;
3402 HRESULT
CDefView::_MergeToolbar()
3404 CComPtr
<IExplorerToolbar
> ptb
;
3407 hr
= IUnknown_QueryService(m_pShellBrowser
, IID_IExplorerToolbar
, IID_PPV_ARG(IExplorerToolbar
, &ptb
));
3411 m_Category
= CGID_DefViewFrame
;
3413 hr
= ptb
->SetCommandTarget(static_cast<IOleCommandTarget
*>(this), &m_Category
, 0);
3421 hr
= ptb
->AddButtons(&m_Category
, buttonsCount
, buttons
);
3429 // The default processing of IShellFolderView callbacks
3430 HRESULT
CDefView::DefMessageSFVCB(UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3432 // TODO: SFVM_GET_CUSTOMVIEWINFO, SFVM_WINDOWCREATED
3433 TRACE("CDefView::DefMessageSFVCB uMsg=%u\n", uMsg
);
3437 HRESULT
CDefView::_DoFolderViewCB(UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3439 HRESULT hr
= E_NOTIMPL
;
3441 if (m_pShellFolderViewCB
)
3443 hr
= m_pShellFolderViewCB
->MessageSFVCB(uMsg
, wParam
, lParam
);
3446 if (hr
== E_NOTIMPL
)
3448 hr
= DefMessageSFVCB(uMsg
, wParam
, lParam
);
3454 HRESULT
CDefView_CreateInstance(IShellFolder
*pFolder
, REFIID riid
, LPVOID
* ppvOut
)
3456 return ShellObjectCreatorInit
<CDefView
>(pFolder
, riid
, ppvOut
);
3459 HRESULT WINAPI
SHCreateShellFolderViewEx(
3460 LPCSFV psvcbi
, /* [in] shelltemplate struct */
3461 IShellView
**ppsv
) /* [out] IShellView pointer */
3463 CComPtr
<IShellView
> psv
;
3466 TRACE("sf=%p pidl=%p cb=%p mode=0x%08x parm=%p\n",
3467 psvcbi
->pshf
, psvcbi
->pidl
, psvcbi
->pfnCallback
,
3468 psvcbi
->fvm
, psvcbi
->psvOuter
);
3471 hRes
= CDefView_CreateInstance(psvcbi
->pshf
, IID_PPV_ARG(IShellView
, &psv
));
3472 if (FAILED_UNEXPECTEDLY(hRes
))
3475 *ppsv
= psv
.Detach();
3479 HRESULT WINAPI
SHCreateShellFolderView(const SFV_CREATE
*pcsfv
,
3482 CComPtr
<IShellView
> psv
;
3486 return E_INVALIDARG
;
3490 if (!pcsfv
|| pcsfv
->cbSize
!= sizeof(*pcsfv
))
3491 return E_INVALIDARG
;
3493 TRACE("sf=%p outer=%p callback=%p\n",
3494 pcsfv
->pshf
, pcsfv
->psvOuter
, pcsfv
->psfvcb
);
3496 hRes
= CDefView_CreateInstance(pcsfv
->pshf
, IID_PPV_ARG(IShellView
, &psv
));
3502 CComPtr
<IShellFolderView
> sfv
;
3503 if (SUCCEEDED(psv
->QueryInterface(IID_PPV_ARG(IShellFolderView
, &sfv
))))
3505 sfv
->SetCallback(pcsfv
->psfvcb
, NULL
);
3509 *ppsv
= psv
.Detach();