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 VOID
_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();
128 void SetStyle(DWORD dwAdd
, DWORD dwRemove
);
130 void UpdateListColors();
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 #####
503 /**********************************************************
504 * change the style of the listview control
506 void CDefView::SetStyle(DWORD dwAdd
, DWORD dwRemove
)
510 TRACE("(%p)\n", this);
512 tmpstyle
= ::GetWindowLongPtrW(m_ListView
, GWL_STYLE
);
513 ::SetWindowLongPtrW(m_ListView
, GWL_STYLE
, dwAdd
| (tmpstyle
& ~dwRemove
));
516 /**********************************************************
517 * ShellView_CreateList()
519 * - creates the list view window
521 BOOL
CDefView::CreateList()
523 DWORD dwStyle
, dwExStyle
;
527 dwStyle
= WS_TABSTOP
| WS_VISIBLE
| WS_CHILDWINDOW
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
|
528 LVS_SHAREIMAGELISTS
| LVS_EDITLABELS
| LVS_AUTOARRANGE
;
529 dwExStyle
= WS_EX_CLIENTEDGE
;
531 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
532 dwStyle
|= LVS_ALIGNLEFT
;
534 dwStyle
|= LVS_ALIGNTOP
| LVS_SHOWSELALWAYS
;
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,
1186 HRESULT
CDefView::CheckViewMode(HMENU hmenuView
)
1188 if (m_FolderSettings
.ViewMode
>= FVM_FIRST
&& m_FolderSettings
.ViewMode
<= FVM_LAST
)
1190 UINT iItemFirst
= FCIDM_SHVIEW_BIGICON
;
1191 UINT iItemLast
= iItemFirst
+ FVM_LAST
- FVM_FIRST
;
1192 UINT iItem
= iItemFirst
+ m_FolderSettings
.ViewMode
- FVM_FIRST
;
1193 CheckMenuRadioItem(hmenuView
, iItemFirst
, iItemLast
, iItem
, MF_BYCOMMAND
);
1199 /**********************************************************
1200 * ShellView_GetSelections()
1202 * - fills the m_apidl list with the selected objects
1205 * number of selected items
1207 UINT
CDefView::GetSelections()
1211 m_cidl
= m_ListView
.GetSelectedCount();
1212 m_apidl
= static_cast<PCUITEMID_CHILD
*>(SHAlloc(m_cidl
* sizeof(PCUITEMID_CHILD
)));
1219 TRACE("-- Items selected =%u\n", m_cidl
);
1223 while ((lvIndex
= m_ListView
.GetNextItem(lvIndex
, LVNI_SELECTED
)) > -1)
1225 m_apidl
[i
] = _PidlByItem(lvIndex
);
1229 TRACE("-- selected Item found\n");
1235 HRESULT
CDefView::InvokeContextMenuCommand(UINT uCommand
)
1237 CMINVOKECOMMANDINFO cmi
;
1239 ZeroMemory(&cmi
, sizeof(cmi
));
1240 cmi
.cbSize
= sizeof(cmi
);
1241 cmi
.lpVerb
= MAKEINTRESOURCEA(uCommand
);
1244 if (GetKeyState(VK_SHIFT
) & 0x8000)
1245 cmi
.fMask
|= CMIC_MASK_SHIFT_DOWN
;
1247 if (GetKeyState(VK_CONTROL
) & 0x8000)
1248 cmi
.fMask
|= CMIC_MASK_CONTROL_DOWN
;
1250 HRESULT hr
= m_pCM
->InvokeCommand(&cmi
);
1251 if (FAILED_UNEXPECTEDLY(hr
))
1257 /**********************************************************
1258 * ShellView_OpenSelectedItems()
1260 HRESULT
CDefView::OpenSelectedItems()
1266 m_cidl
= m_ListView
.GetSelectedCount();
1270 hResult
= OnDefaultCommand();
1271 if (hResult
== S_OK
)
1274 hMenu
= CreatePopupMenu();
1278 hResult
= GetItemObject(SVGIO_SELECTION
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1279 if (FAILED_UNEXPECTEDLY(hResult
))
1282 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_DEFAULTONLY
);
1283 if (FAILED_UNEXPECTEDLY(hResult
))
1286 uCommand
= GetMenuDefaultItem(hMenu
, FALSE
, 0);
1287 if (uCommand
== (UINT
)-1)
1293 InvokeContextMenuCommand(uCommand
);
1302 IUnknown_SetSite(m_pCM
, NULL
);
1309 /**********************************************************
1310 * ShellView_DoContextMenu()
1312 LRESULT
CDefView::OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1321 TRACE("(%p)->(0x%08x 0x%08x) stub\n", this, x
, y
);
1323 m_hContextMenu
= CreatePopupMenu();
1324 if (!m_hContextMenu
)
1327 m_cidl
= m_ListView
.GetSelectedCount();
1329 hResult
= GetItemObject( m_cidl
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1330 if (FAILED_UNEXPECTEDLY(hResult
))
1333 /* Use 1 as the first id as we want 0 the mean that the user canceled the menu */
1334 hResult
= m_pCM
->QueryContextMenu(m_hContextMenu
, 0, CONTEXT_MENU_BASE_ID
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1335 if (FAILED_UNEXPECTEDLY(hResult
))
1338 uCommand
= TrackPopupMenu(m_hContextMenu
,
1339 TPM_LEFTALIGN
| TPM_RETURNCMD
| TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
,
1340 x
, y
, 0, m_hWnd
, NULL
);
1344 if (uCommand
== FCIDM_SHVIEW_OPEN
&& OnDefaultCommand() == S_OK
)
1347 InvokeContextMenuCommand(uCommand
- CONTEXT_MENU_BASE_ID
);
1352 IUnknown_SetSite(m_pCM
, NULL
);
1358 DestroyMenu(m_hContextMenu
);
1359 m_hContextMenu
= NULL
;
1365 LRESULT
CDefView::OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
)
1370 hMenu
= CreatePopupMenu();
1374 hResult
= GetItemObject( bUseSelection
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1375 if (FAILED_UNEXPECTEDLY( hResult
))
1378 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1379 if (FAILED_UNEXPECTEDLY( hResult
))
1382 InvokeContextMenuCommand(uCommand
);
1387 IUnknown_SetSite(m_pCM
, NULL
);
1397 /**********************************************************
1398 * ##### message handling #####
1401 /**********************************************************
1402 * ShellView_OnSize()
1404 LRESULT
CDefView::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1406 WORD wWidth
, wHeight
;
1408 wWidth
= LOWORD(lParam
);
1409 wHeight
= HIWORD(lParam
);
1411 TRACE("%p width=%u height=%u\n", this, wWidth
, wHeight
);
1413 /* Resize the ListView to fit our window */
1416 ::MoveWindow(m_ListView
, 0, 0, wWidth
, wHeight
, TRUE
);
1419 _DoFolderViewCB(SFVM_SIZE
, 0, 0);
1424 /**********************************************************
1425 * ShellView_OnDeactivate()
1430 void CDefView::OnDeactivate()
1432 TRACE("%p\n", this);
1434 if (m_uState
!= SVUIA_DEACTIVATE
)
1436 // TODO: cleanup menu after deactivation
1438 m_uState
= SVUIA_DEACTIVATE
;
1442 void CDefView::DoActivate(UINT uState
)
1444 TRACE("%p uState=%x\n", this, uState
);
1446 /*don't do anything if the state isn't really changing */
1447 if (m_uState
== uState
)
1452 if (uState
== SVUIA_DEACTIVATE
)
1458 if(m_hMenu
&& !m_bmenuBarInitialized
)
1462 m_pShellBrowser
->SetMenuSB(m_hMenu
, 0, m_hWnd
);
1463 m_bmenuBarInitialized
= TRUE
;
1466 if (SVUIA_ACTIVATE_FOCUS
== uState
)
1468 m_ListView
.SetFocus();
1476 /**********************************************************
1477 * ShellView_OnActivate()
1479 LRESULT
CDefView::OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1481 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1485 /**********************************************************
1486 * ShellView_OnSetFocus()
1489 LRESULT
CDefView::OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1491 TRACE("%p\n", this);
1493 /* Tell the browser one of our windows has received the focus. This
1494 should always be done before merging menus (OnActivate merges the
1495 menus) if one of our windows has the focus.*/
1497 m_pShellBrowser
->OnViewWindowActive(this);
1498 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1500 /* Set the focus to the listview */
1501 m_ListView
.SetFocus();
1503 /* Notify the ICommDlgBrowser interface */
1504 OnStateChange(CDBOSC_SETFOCUS
);
1509 /**********************************************************
1510 * ShellView_OnKillFocus()
1512 LRESULT
CDefView::OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1514 TRACE("(%p) stub\n", this);
1516 DoActivate(SVUIA_ACTIVATE_NOFOCUS
);
1517 /* Notify the ICommDlgBrowser */
1518 OnStateChange(CDBOSC_KILLFOCUS
);
1523 /**********************************************************
1524 * ShellView_OnCommand()
1527 * the CmdID's are the ones from the context menu
1529 LRESULT
CDefView::OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1536 dwCmdID
= GET_WM_COMMAND_ID(wParam
, lParam
);
1537 dwCmd
= GET_WM_COMMAND_CMD(wParam
, lParam
);
1538 hwndCmd
= GET_WM_COMMAND_HWND(wParam
, lParam
);
1540 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n", this, dwCmdID
, dwCmd
, hwndCmd
);
1544 case FCIDM_SHVIEW_SMALLICON
:
1545 m_FolderSettings
.ViewMode
= FVM_SMALLICON
;
1546 SetStyle (LVS_SMALLICON
, LVS_TYPEMASK
);
1550 case FCIDM_SHVIEW_BIGICON
:
1551 m_FolderSettings
.ViewMode
= FVM_ICON
;
1552 SetStyle (LVS_ICON
, LVS_TYPEMASK
);
1556 case FCIDM_SHVIEW_LISTVIEW
:
1557 m_FolderSettings
.ViewMode
= FVM_LIST
;
1558 SetStyle (LVS_LIST
, LVS_TYPEMASK
);
1562 case FCIDM_SHVIEW_REPORTVIEW
:
1563 m_FolderSettings
.ViewMode
= FVM_DETAILS
;
1564 SetStyle (LVS_REPORT
, LVS_TYPEMASK
);
1568 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1573 m_sortInfo
.nHeaderID
= dwCmdID
- 0x30;
1574 m_sortInfo
.bIsAscending
= TRUE
;
1578 case FCIDM_SHVIEW_SNAPTOGRID
:
1579 case FCIDM_SHVIEW_AUTOARRANGE
:
1582 case FCIDM_SHVIEW_SELECTALL
:
1583 m_ListView
.SetItemState(-1, LVIS_SELECTED
, LVIS_SELECTED
);
1586 case FCIDM_SHVIEW_INVERTSELECTION
:
1587 nCount
= m_ListView
.GetItemCount();
1588 for (int i
=0; i
< nCount
; i
++)
1589 m_ListView
.SetItemState(i
, m_ListView
.GetItemState(i
, LVIS_SELECTED
) ? 0 : LVIS_SELECTED
, LVIS_SELECTED
);
1592 case FCIDM_SHVIEW_REFRESH
:
1596 case FCIDM_SHVIEW_DELETE
:
1597 case FCIDM_SHVIEW_CUT
:
1598 case FCIDM_SHVIEW_COPY
:
1599 case FCIDM_SHVIEW_RENAME
:
1600 case FCIDM_SHVIEW_PROPERTIES
:
1601 return OnExplorerCommand(dwCmdID
, TRUE
);
1603 case FCIDM_SHVIEW_INSERT
:
1604 case FCIDM_SHVIEW_UNDO
:
1605 case FCIDM_SHVIEW_INSERTLINK
:
1606 case FCIDM_SHVIEW_NEWFOLDER
:
1607 return OnExplorerCommand(dwCmdID
, FALSE
);
1609 /* WM_COMMAND messages from the file menu are routed to the CDefView so as to let m_pCM handle the command */
1610 if (m_pCM
&& dwCmd
== 0)
1612 InvokeContextMenuCommand(dwCmdID
);
1619 /**********************************************************
1620 * ShellView_OnNotify()
1623 LRESULT
CDefView::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1627 LPNMLISTVIEW lpnmlv
;
1628 NMLVDISPINFOW
*lpdi
;
1629 PCUITEMID_CHILD pidl
;
1633 lpnmh
= (LPNMHDR
)lParam
;
1634 lpnmlv
= (LPNMLISTVIEW
)lpnmh
;
1635 lpdi
= (NMLVDISPINFOW
*)lpnmh
;
1637 TRACE("%p CtlID=%u lpnmh->code=%x\n", this, CtlID
, lpnmh
->code
);
1639 switch (lpnmh
->code
)
1642 TRACE("-- NM_SETFOCUS %p\n", this);
1643 OnSetFocus(0, 0, 0, unused
);
1647 TRACE("-- NM_KILLFOCUS %p\n", this);
1649 /* Notify the ICommDlgBrowser interface */
1650 OnStateChange(CDBOSC_KILLFOCUS
);
1654 TRACE("-- NM_CUSTOMDRAW %p\n", this);
1655 return CDRF_DODEFAULT
;
1657 case NM_RELEASEDCAPTURE
:
1658 TRACE("-- NM_RELEASEDCAPTURE %p\n", this);
1662 TRACE("-- NM_CLICK %p\n", this);
1666 TRACE("-- NM_RCLICK %p\n", this);
1670 TRACE("-- NM_DBLCLK %p\n", this);
1671 OpenSelectedItems();
1675 TRACE("-- NM_RETURN %p\n", this);
1676 OpenSelectedItems();
1680 TRACE("-- HDN_ENDTRACKW %p\n", this);
1681 /*nColumn1 = m_ListView.GetColumnWidth(0);
1682 nColumn2 = m_ListView.GetColumnWidth(1);*/
1685 case LVN_DELETEITEM
:
1686 TRACE("-- LVN_DELETEITEM %p\n", this);
1688 /*delete the pidl because we made a copy of it*/
1689 SHFree(reinterpret_cast<LPVOID
>(lpnmlv
->lParam
));
1693 case LVN_DELETEALLITEMS
:
1694 TRACE("-- LVN_DELETEALLITEMS %p\n", this);
1697 case LVN_INSERTITEM
:
1698 TRACE("-- LVN_INSERTITEM (STUB)%p\n", this);
1701 case LVN_ITEMACTIVATE
:
1702 TRACE("-- LVN_ITEMACTIVATE %p\n", this);
1703 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1706 case LVN_COLUMNCLICK
:
1707 m_sortInfo
.nHeaderID
= lpnmlv
->iSubItem
;
1708 if (m_sortInfo
.nLastHeaderID
== m_sortInfo
.nHeaderID
)
1709 m_sortInfo
.bIsAscending
= !m_sortInfo
.bIsAscending
;
1711 m_sortInfo
.bIsAscending
= TRUE
;
1715 case LVN_GETDISPINFOA
:
1716 case LVN_GETDISPINFOW
:
1717 TRACE("-- LVN_GETDISPINFO %p\n", this);
1718 pidl
= _PidlByItem(lpdi
->item
);
1720 if (lpdi
->item
.mask
& LVIF_TEXT
) /* text requested */
1725 if (FAILED_UNEXPECTEDLY(m_pSF2Parent
->GetDetailsOf(pidl
, lpdi
->item
.iSubItem
, &sd
)))
1728 if (lpnmh
->code
== LVN_GETDISPINFOA
)
1730 /* shouldn't happen */
1731 NMLVDISPINFOA
*lpdiA
= (NMLVDISPINFOA
*)lpnmh
;
1732 StrRetToStrNA( lpdiA
->item
.pszText
, lpdiA
->item
.cchTextMax
, &sd
.str
, NULL
);
1733 TRACE("-- text=%s\n", lpdiA
->item
.pszText
);
1735 else /* LVN_GETDISPINFOW */
1737 StrRetToStrNW( lpdi
->item
.pszText
, lpdi
->item
.cchTextMax
, &sd
.str
, NULL
);
1738 TRACE("-- text=%s\n", debugstr_w(lpdi
->item
.pszText
));
1743 FIXME("no m_pSF2Parent\n");
1746 if(lpdi
->item
.mask
& LVIF_IMAGE
) /* image requested */
1748 lpdi
->item
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
1750 if(lpdi
->item
.mask
& LVIF_STATE
)
1752 ULONG attributes
= SFGAO_HIDDEN
;
1753 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(1, &pidl
, &attributes
)))
1755 if (attributes
& SFGAO_HIDDEN
)
1757 lpdi
->item
.state
|= LVIS_CUT
;
1761 lpdi
->item
.mask
|= LVIF_DI_SETITEM
;
1764 case LVN_ITEMCHANGED
:
1765 TRACE("-- LVN_ITEMCHANGED %p\n", this);
1766 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1768 _DoFolderViewCB(SFVM_SELECTIONCHANGED
, NULL
/* FIXME */, NULL
/* FIXME */);
1772 case LVN_BEGINRDRAG
:
1773 TRACE("-- LVN_BEGINDRAG\n");
1775 if (GetSelections())
1777 CComPtr
<IDataObject
> pda
;
1778 DWORD dwAttributes
= SFGAO_CANCOPY
| SFGAO_CANLINK
;
1779 DWORD dwEffect
= DROPEFFECT_MOVE
;
1781 if (SUCCEEDED(m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, IID_NULL_PPV_ARG(IDataObject
, &pda
))))
1783 LPNMLISTVIEW params
= (LPNMLISTVIEW
)lParam
;
1785 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(m_cidl
, m_apidl
, &dwAttributes
)))
1787 dwEffect
|= dwAttributes
& (SFGAO_CANCOPY
| SFGAO_CANLINK
);
1790 CComPtr
<IAsyncOperation
> piaso
;
1791 if (SUCCEEDED(pda
->QueryInterface(IID_PPV_ARG(IAsyncOperation
, &piaso
))))
1793 piaso
->SetAsyncMode(TRUE
);
1798 m_pSourceDataObject
= pda
;
1799 m_ptFirstMousePos
= params
->ptAction
;
1800 ClientToScreen(&m_ptFirstMousePos
);
1802 HIMAGELIST big_icons
, small_icons
;
1803 Shell_GetImageLists(&big_icons
, &small_icons
);
1804 PCUITEMID_CHILD pidl
= _PidlByItem(params
->iItem
);
1805 int iIcon
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
1807 m_ListView
.GetItemPosition(params
->iItem
, &ptItem
);
1809 ImageList_BeginDrag(big_icons
, iIcon
, params
->ptAction
.x
- ptItem
.x
, params
->ptAction
.y
- ptItem
.y
);
1811 DoDragDrop(pda
, this, dwEffect
, &dwEffect2
);
1813 m_pSourceDataObject
.Release();
1818 case LVN_BEGINLABELEDITW
:
1820 DWORD dwAttr
= SFGAO_CANRENAME
;
1821 pidl
= _PidlByItem(lpdi
->item
);
1823 TRACE("-- LVN_BEGINLABELEDITW %p\n", this);
1825 m_pSFParent
->GetAttributesOf(1, &pidl
, &dwAttr
);
1826 if (SFGAO_CANRENAME
& dwAttr
)
1834 case LVN_ENDLABELEDITW
:
1836 TRACE("-- LVN_ENDLABELEDITW %p\n", this);
1838 m_isEditing
= FALSE
;
1840 if (lpdi
->item
.pszText
)
1845 pidl
= _PidlByItem(lpdi
->item
);
1846 PITEMID_CHILD pidlNew
;
1847 hr
= m_pSFParent
->SetNameOf(0, pidl
, lpdi
->item
.pszText
, SHGDN_INFOLDER
, &pidlNew
);
1849 if (SUCCEEDED(hr
) && pidlNew
)
1851 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
1852 lvItem
.iItem
= lpdi
->item
.iItem
;
1853 lvItem
.iSubItem
= 0;
1854 lvItem
.lParam
= reinterpret_cast<LPARAM
>(pidlNew
);
1855 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
1856 m_ListView
.SetItem(&lvItem
);
1857 m_ListView
.Update(lpdi
->item
.iItem
);
1866 TRACE("-- %p WM_COMMAND %x unhandled\n", this, lpnmh
->code
);
1874 * This is just a quick hack to make the desktop work correctly.
1875 * ITranslateShellChangeNotify's IsChildID is undocumented, but most likely the way that
1876 * a folder should know if it should update upon a change notification.
1877 * It is exported by merged folders at a minimum.
1879 static BOOL
ILIsParentOrSpecialParent(PCIDLIST_ABSOLUTE pidl1
, PCIDLIST_ABSOLUTE pidl2
)
1881 if (!pidl1
|| !pidl2
)
1883 if (ILIsParent(pidl1
, pidl2
, TRUE
))
1886 if (_ILIsDesktop(pidl1
))
1888 PIDLIST_ABSOLUTE deskpidl
;
1889 SHGetFolderLocation(NULL
, CSIDL_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
1890 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
1896 SHGetFolderLocation(NULL
, CSIDL_COMMON_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
1897 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
1907 /**********************************************************
1908 * ShellView_OnChange()
1910 LRESULT
CDefView::OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1912 PCIDLIST_ABSOLUTE
*Pidls
= reinterpret_cast<PCIDLIST_ABSOLUTE
*>(wParam
);
1913 BOOL bParent0
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[0]);
1914 BOOL bParent1
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[1]);
1916 TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls
[0], Pidls
[1], lParam
);
1918 switch (lParam
&~ SHCNE_INTERRUPT
)
1924 if (LV_FindItemByPidl(ILFindLastID(Pidls
[0])) == -1)
1926 LV_AddItem(ILFindLastID(Pidls
[0]));
1930 LV_ProdItem(ILFindLastID(Pidls
[0]));
1938 LV_DeleteItem(ILFindLastID(Pidls
[0]));
1941 case SHCNE_RENAMEFOLDER
:
1942 case SHCNE_RENAMEITEM
:
1943 if (bParent0
&& bParent1
)
1944 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[1]));
1946 LV_DeleteItem(ILFindLastID(Pidls
[0]));
1948 LV_AddItem(ILFindLastID(Pidls
[1]));
1951 case SHCNE_UPDATEITEM
:
1953 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[0]));
1956 case SHCNE_UPDATEDIR
:
1963 HRESULT
SHGetMenuIdFromMenuMsg(UINT uMsg
, LPARAM lParam
, UINT
*CmdId
);
1964 HRESULT
SHSetMenuIdInMenuMsg(UINT uMsg
, LPARAM lParam
, UINT CmdId
);
1966 /**********************************************************
1967 * CDefView::OnCustomItem
1969 LRESULT
CDefView::OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1974 ERR("no menu!!!\n");
1978 /* The lParam of WM_DRAWITEM WM_MEASUREITEM contain a menu id and this also needs to
1979 be changed to a menu identifier offset */
1981 HRESULT hres
= SHGetMenuIdFromMenuMsg(uMsg
, lParam
, &CmdID
);
1982 if (SUCCEEDED(hres
))
1983 SHSetMenuIdInMenuMsg(uMsg
, lParam
, CmdID
- CONTEXT_MENU_BASE_ID
);
1985 /* Forward the message to the IContextMenu2 */
1987 hres
= SHForwardContextMenuMsg(m_pCM
, uMsg
, wParam
, lParam
, &result
, TRUE
);
1989 return (SUCCEEDED(hres
));
1992 LRESULT
CDefView::OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1994 /* Wallpaper setting affects drop shadows effect */
1995 if (wParam
== SPI_SETDESKWALLPAPER
|| wParam
== 0)
2001 /**********************************************************
2002 * CDefView::OnInitMenuPopup
2004 LRESULT
CDefView::OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
2006 HMENU hmenu
= (HMENU
) wParam
;
2007 int nPos
= LOWORD(lParam
);
2010 OnCustomItem(uMsg
, wParam
, lParam
, bHandled
);
2012 HMENU hViewMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_VIEW
);
2014 /* Lets try to find out what the hell wParam is */
2015 if (hmenu
== GetSubMenu(m_hMenu
, nPos
))
2016 menuItemId
= ReallyGetMenuItemID(m_hMenu
, nPos
);
2017 else if (hViewMenu
&& hmenu
== GetSubMenu(hViewMenu
, nPos
))
2018 menuItemId
= ReallyGetMenuItemID(hViewMenu
, nPos
);
2019 else if (m_hContextMenu
&& hmenu
== GetSubMenu(m_hContextMenu
, nPos
))
2020 menuItemId
= ReallyGetMenuItemID(m_hContextMenu
, nPos
);
2026 case FCIDM_MENU_FILE
:
2029 case FCIDM_MENU_VIEW
:
2030 case FCIDM_SHVIEW_VIEW
:
2031 CheckViewMode(hmenu
);
2033 case FCIDM_SHVIEW_ARRANGE
:
2034 FillArrangeAsMenu(hmenu
);
2041 /**********************************************************
2044 * The INTERFACE of the IShellView object
2047 **********************************************************
2050 /**********************************************************
2051 * ShellView_GetWindow
2053 HRESULT WINAPI
CDefView::GetWindow(HWND
*phWnd
)
2055 TRACE("(%p)\n", this);
2062 HRESULT WINAPI
CDefView::ContextSensitiveHelp(BOOL fEnterMode
)
2064 FIXME("(%p) stub\n", this);
2069 /**********************************************************
2070 * IShellView_TranslateAccelerator
2073 * use the accel functions
2075 HRESULT WINAPI
CDefView::TranslateAccelerator(LPMSG lpmsg
)
2080 if (lpmsg
->message
>= WM_KEYFIRST
&& lpmsg
->message
<= WM_KEYLAST
)
2082 if (::TranslateAcceleratorW(m_hWnd
, m_hAccel
, lpmsg
) != 0)
2085 TRACE("-- key=0x%04lx\n", lpmsg
->wParam
) ;
2088 return m_pShellBrowser
->TranslateAcceleratorSB(lpmsg
, 0);
2091 HRESULT WINAPI
CDefView::EnableModeless(BOOL fEnable
)
2093 FIXME("(%p) stub\n", this);
2098 HRESULT WINAPI
CDefView::UIActivate(UINT uState
)
2100 // CHAR szName[MAX_PATH];
2102 int nPartArray
[1] = { -1};
2104 TRACE("(%p)->(state=%x) stub\n", this, uState
);
2106 /* don't do anything if the state isn't really changing */
2107 if (m_uState
== uState
)
2112 /* OnActivate handles the menu merging and internal state */
2115 /* only do This if we are active */
2116 if (uState
!= SVUIA_DEACTIVATE
)
2120 GetFolderPath is not a method of IShellFolder
2121 IShellFolder_GetFolderPath( m_pSFParent, szName, sizeof(szName) );
2123 /* set the number of parts */
2124 m_pShellBrowser
->SendControlMsg(FCW_STATUS
, SB_SETPARTS
, 1, (LPARAM
)nPartArray
, &lResult
);
2126 /* set the text for the parts */
2128 m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXTA, 0, (LPARAM)szName, &lResult);
2135 HRESULT WINAPI
CDefView::Refresh()
2137 TRACE("(%p)\n", this);
2139 m_ListView
.DeleteAllItems();
2145 HRESULT WINAPI
CDefView::CreateViewWindow(IShellView
*lpPrevView
, LPCFOLDERSETTINGS lpfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
)
2147 return CreateViewWindow3(psb
, lpPrevView
, SV3CVW3_DEFAULT
,
2148 (FOLDERFLAGS
)lpfs
->fFlags
, (FOLDERFLAGS
)lpfs
->fFlags
, (FOLDERVIEWMODE
)lpfs
->ViewMode
, NULL
, prcView
, phWnd
);
2151 HRESULT WINAPI
CDefView::DestroyViewWindow()
2153 TRACE("(%p)\n", this);
2155 /* Make absolutely sure all our UI is cleaned up */
2156 UIActivate(SVUIA_DEACTIVATE
);
2160 // "Accelerator tables loaded from resources are freed automatically when the application terminates." -- MSDN
2164 if (m_hMenuArrangeModes
)
2166 DestroyMenu(m_hMenuArrangeModes
);
2167 m_hMenuArrangeModes
= NULL
;
2170 if (m_hMenuViewModes
)
2172 DestroyMenu(m_hMenuViewModes
);
2173 m_hMenuViewModes
= NULL
;
2178 DestroyMenu(m_hMenu
);
2184 m_ListView
.DestroyWindow();
2192 m_pShellBrowser
.Release();
2193 m_pCommDlgBrowser
.Release();
2198 HRESULT WINAPI
CDefView::GetCurrentInfo(LPFOLDERSETTINGS lpfs
)
2200 TRACE("(%p)->(%p) vmode=%x flags=%x\n", this, lpfs
,
2201 m_FolderSettings
.ViewMode
, m_FolderSettings
.fFlags
);
2204 return E_INVALIDARG
;
2206 *lpfs
= m_FolderSettings
;
2210 HRESULT WINAPI
CDefView::AddPropertySheetPages(DWORD dwReserved
, LPFNADDPROPSHEETPAGE lpfn
, LPARAM lparam
)
2212 FIXME("(%p) stub\n", this);
2217 HRESULT WINAPI
CDefView::SaveViewState()
2219 FIXME("(%p) stub\n", this);
2224 HRESULT WINAPI
CDefView::SelectItem(PCUITEMID_CHILD pidl
, UINT uFlags
)
2228 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n", this, pidl
, uFlags
);
2230 i
= LV_FindItemByPidl(pidl
);
2234 if(uFlags
& SVSI_ENSUREVISIBLE
)
2235 m_ListView
.EnsureVisible(i
, FALSE
);
2237 LVITEMW lvItem
= {0};
2238 lvItem
.mask
= LVIF_STATE
;
2239 lvItem
.stateMask
= LVIS_SELECTED
| LVIS_FOCUSED
;
2241 while (m_ListView
.GetItem(&lvItem
))
2243 if (lvItem
.iItem
== i
)
2245 if (uFlags
& SVSI_SELECT
)
2246 lvItem
.state
|= LVIS_SELECTED
;
2248 lvItem
.state
&= ~LVIS_SELECTED
;
2250 if (uFlags
& SVSI_FOCUSED
)
2251 lvItem
.state
&= ~LVIS_FOCUSED
;
2255 if (uFlags
& SVSI_DESELECTOTHERS
)
2256 lvItem
.state
&= ~LVIS_SELECTED
;
2259 m_ListView
.SetItem(&lvItem
);
2263 if((uFlags
& SVSI_EDIT
) == SVSI_EDIT
)
2264 m_ListView
.EditLabel(i
);
2269 HRESULT WINAPI
CDefView::GetItemObject(UINT uItem
, REFIID riid
, LPVOID
*ppvOut
)
2271 HRESULT hr
= E_NOINTERFACE
;
2273 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n", this, uItem
, debugstr_guid(&riid
), ppvOut
);
2279 case SVGIO_BACKGROUND
:
2280 if (IsEqualIID(riid
, IID_IContextMenu
))
2285 hr
= CDefViewBckgrndMenu_CreateInstance(m_pSF2Parent
, riid
, ppvOut
);
2286 if (FAILED_UNEXPECTEDLY(hr
))
2289 IUnknown_SetSite(*((IUnknown
**)ppvOut
), (IShellView
*)this);
2291 else if (IsEqualIID(riid
, IID_IDispatch
))
2293 if (m_pShellFolderViewDual
== NULL
)
2295 hr
= CDefViewDual_Constructor(riid
, (LPVOID
*)&m_pShellFolderViewDual
);
2296 if (FAILED_UNEXPECTEDLY(hr
))
2299 hr
= m_pShellFolderViewDual
->QueryInterface(riid
, ppvOut
);
2303 case SVGIO_SELECTION
:
2305 hr
= m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, riid
, 0, ppvOut
);
2306 if (FAILED_UNEXPECTEDLY(hr
))
2309 if (IsEqualIID(riid
, IID_IContextMenu
))
2310 IUnknown_SetSite(*((IUnknown
**)ppvOut
), (IShellView
*)this);
2315 TRACE("-- (%p)->(interface=%p)\n", this, *ppvOut
);
2320 HRESULT STDMETHODCALLTYPE
CDefView::GetCurrentViewMode(UINT
*pViewMode
)
2322 TRACE("(%p)->(%p), stub\n", this, pViewMode
);
2325 return E_INVALIDARG
;
2327 *pViewMode
= m_FolderSettings
.ViewMode
;
2331 HRESULT STDMETHODCALLTYPE
CDefView::SetCurrentViewMode(UINT ViewMode
)
2334 TRACE("(%p)->(%u), stub\n", this, ViewMode
);
2336 /* It's not redundant to check FVM_AUTO because it's a (UINT)-1 */
2337 if (((INT
)ViewMode
< FVM_FIRST
|| (INT
)ViewMode
> FVM_LAST
) && ((INT
)ViewMode
!= FVM_AUTO
))
2338 return E_INVALIDARG
;
2340 /* Windows before Vista uses LVM_SETVIEW and possibly
2341 LVM_SETEXTENDEDLISTVIEWSTYLE to set the style of the listview,
2342 while later versions seem to accomplish this through other
2350 dwStyle
= LVS_REPORT
;
2353 dwStyle
= LVS_SMALLICON
;
2360 FIXME("ViewMode %d not implemented\n", ViewMode
);
2366 SetStyle(dwStyle
, LVS_TYPEMASK
);
2368 /* This will not necessarily be the actual mode set above.
2369 This mimics the behavior of Windows XP. */
2370 m_FolderSettings
.ViewMode
= ViewMode
;
2375 HRESULT STDMETHODCALLTYPE
CDefView::GetFolder(REFIID riid
, void **ppv
)
2377 if (m_pSFParent
== NULL
)
2380 return m_pSFParent
->QueryInterface(riid
, ppv
);
2383 HRESULT STDMETHODCALLTYPE
CDefView::Item(int iItemIndex
, PITEMID_CHILD
*ppidl
)
2385 PCUITEMID_CHILD pidl
= _PidlByItem(iItemIndex
);
2388 *ppidl
= ILClone(pidl
);
2393 return E_INVALIDARG
;
2396 HRESULT STDMETHODCALLTYPE
CDefView::ItemCount(UINT uFlags
, int *pcItems
)
2398 TRACE("(%p)->(%u %p)\n", this, uFlags
, pcItems
);
2400 if (uFlags
!= SVGIO_ALLVIEW
)
2401 FIXME("some flags unsupported, %x\n", uFlags
& ~SVGIO_ALLVIEW
);
2403 *pcItems
= m_ListView
.GetItemCount();
2408 HRESULT STDMETHODCALLTYPE
CDefView::Items(UINT uFlags
, REFIID riid
, void **ppv
)
2413 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectionMarkedItem(int *piItem
)
2415 TRACE("(%p)->(%p)\n", this, piItem
);
2417 *piItem
= m_ListView
.GetSelectionMark();
2422 HRESULT STDMETHODCALLTYPE
CDefView::GetFocusedItem(int *piItem
)
2424 TRACE("(%p)->(%p)\n", this, piItem
);
2426 *piItem
= m_ListView
.GetNextItem(-1, LVNI_FOCUSED
);
2431 HRESULT STDMETHODCALLTYPE
CDefView::GetItemPosition(PCUITEMID_CHILD pidl
, POINT
*ppt
)
2433 int lvIndex
= LV_FindItemByPidl(pidl
);
2434 if (lvIndex
== -1 || ppt
== NULL
)
2435 return E_INVALIDARG
;
2437 m_ListView
.GetItemPosition(lvIndex
, ppt
);
2441 HRESULT STDMETHODCALLTYPE
CDefView::GetSpacing(POINT
*ppt
)
2443 TRACE("(%p)->(%p)\n", this, ppt
);
2451 m_ListView
.GetItemSpacing(spacing
);
2453 ppt
->x
= spacing
.cx
;
2454 ppt
->y
= spacing
.cy
;
2460 HRESULT STDMETHODCALLTYPE
CDefView::GetDefaultSpacing(POINT
*ppt
)
2465 HRESULT STDMETHODCALLTYPE
CDefView::GetAutoArrange()
2470 HRESULT STDMETHODCALLTYPE
CDefView::SelectItem(int iItem
, DWORD dwFlags
)
2474 TRACE("(%p)->(%d, %x)\n", this, iItem
, dwFlags
);
2477 lvItem
.stateMask
= LVIS_SELECTED
;
2479 if (dwFlags
& SVSI_ENSUREVISIBLE
)
2480 m_ListView
.EnsureVisible(iItem
, 0);
2483 if (dwFlags
& SVSI_DESELECTOTHERS
)
2484 m_ListView
.SetItemState(-1, 0, LVIS_SELECTED
);
2487 if (dwFlags
& SVSI_SELECT
)
2488 lvItem
.state
|= LVIS_SELECTED
;
2490 if (dwFlags
& SVSI_FOCUSED
)
2491 lvItem
.stateMask
|= LVIS_FOCUSED
;
2493 m_ListView
.SetItemState(iItem
, lvItem
.state
, lvItem
.stateMask
);
2495 if ((dwFlags
& SVSI_EDIT
) == SVSI_EDIT
)
2496 m_ListView
.EditLabel(iItem
);
2501 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItems(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD dwFlags
)
2503 /* Reset the selection */
2504 m_ListView
.SetItemState(-1, 0, LVIS_SELECTED
);
2507 for (UINT i
= 0 ; i
< m_cidl
; i
++)
2509 lvIndex
= LV_FindItemByPidl(apidl
[i
]);
2512 SelectItem(lvIndex
, dwFlags
);
2513 m_ListView
.SetItemPosition(lvIndex
, &apt
[i
]);
2520 /**********************************************************
2521 * IShellView2 implementation
2524 HRESULT STDMETHODCALLTYPE
CDefView::GetView(SHELLVIEWID
*view_guid
, ULONG view_type
)
2526 FIXME("(%p)->(%p, %lu) stub\n", this, view_guid
, view_type
);
2530 HRESULT STDMETHODCALLTYPE
CDefView::CreateViewWindow2(LPSV2CVW2_PARAMS view_params
)
2532 return CreateViewWindow3(view_params
->psbOwner
, view_params
->psvPrev
,
2533 SV3CVW3_DEFAULT
, (FOLDERFLAGS
)view_params
->pfs
->fFlags
, (FOLDERFLAGS
)view_params
->pfs
->fFlags
,
2534 (FOLDERVIEWMODE
)view_params
->pfs
->ViewMode
, view_params
->pvid
, view_params
->prcView
, &view_params
->hwndView
);
2537 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
)
2539 OLEMENUGROUPWIDTHS omw
= { { 0, 0, 0, 0, 0, 0 } };
2543 TRACE("(%p)->(shlview=%p shlbrs=%p rec=%p hwnd=%p vmode=%x flags=%x)\n", this, psvPrevious
, psb
, prcView
, hwnd
, mode
, flags
);
2544 if (prcView
!= NULL
)
2545 TRACE("-- left=%i top=%i right=%i bottom=%i\n", prcView
->left
, prcView
->top
, prcView
->right
, prcView
->bottom
);
2547 /* Validate the Shell Browser */
2548 if (psb
== NULL
|| m_hWnd
)
2549 return E_UNEXPECTED
;
2551 if (view_flags
!= SV3CVW3_DEFAULT
)
2552 FIXME("unsupported view flags 0x%08x\n", view_flags
);
2554 /* Set up the member variables */
2555 m_pShellBrowser
= psb
;
2556 m_FolderSettings
.ViewMode
= mode
;
2557 m_FolderSettings
.fFlags
= mask
& flags
;
2561 if (IsEqualIID(*view_id
, VID_LargeIcons
))
2562 m_FolderSettings
.ViewMode
= FVM_ICON
;
2563 else if (IsEqualIID(*view_id
, VID_SmallIcons
))
2564 m_FolderSettings
.ViewMode
= FVM_SMALLICON
;
2565 else if (IsEqualIID(*view_id
, VID_List
))
2566 m_FolderSettings
.ViewMode
= FVM_LIST
;
2567 else if (IsEqualIID(*view_id
, VID_Details
))
2568 m_FolderSettings
.ViewMode
= FVM_DETAILS
;
2569 else if (IsEqualIID(*view_id
, VID_Thumbnails
))
2570 m_FolderSettings
.ViewMode
= FVM_THUMBNAIL
;
2571 else if (IsEqualIID(*view_id
, VID_Tile
))
2572 m_FolderSettings
.ViewMode
= FVM_TILE
;
2573 else if (IsEqualIID(*view_id
, VID_ThumbStrip
))
2574 m_FolderSettings
.ViewMode
= FVM_THUMBSTRIP
;
2576 FIXME("Ignoring unrecognized VID %s\n", debugstr_guid(view_id
));
2579 /* Get our parent window */
2580 m_pShellBrowser
->GetWindow(&m_hWndParent
);
2582 /* Try to get the ICommDlgBrowserInterface, adds a reference !!! */
2583 m_pCommDlgBrowser
= NULL
;
2584 if (SUCCEEDED(m_pShellBrowser
->QueryInterface(IID_PPV_ARG(ICommDlgBrowser
, &m_pCommDlgBrowser
))))
2586 TRACE("-- CommDlgBrowser\n");
2589 Create(m_hWndParent
, prcView
, NULL
, WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
| WS_TABSTOP
, 0, 0U);
2600 _DoFolderViewCB(SFVM_WINDOWCREATED
, (WPARAM
)m_hWnd
, NULL
);
2602 SetWindowPos(HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_SHOWWINDOW
);
2607 m_hMenu
= CreateMenu();
2608 m_pShellBrowser
->InsertMenusSB(m_hMenu
, &omw
);
2609 TRACE("-- after fnInsertMenusSB\n");
2617 HRESULT STDMETHODCALLTYPE
CDefView::HandleRename(LPCITEMIDLIST new_pidl
)
2619 FIXME("(%p)->(%p) stub\n", this, new_pidl
);
2623 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItem(LPCITEMIDLIST item
, UINT flags
, POINT
*point
)
2625 FIXME("(%p)->(%p, %u, %p) stub\n", this, item
, flags
, point
);
2629 /**********************************************************
2630 * IShellFolderView implementation
2632 HRESULT STDMETHODCALLTYPE
CDefView::Rearrange(LPARAM sort
)
2634 FIXME("(%p)->(%ld) stub\n", this, sort
);
2638 HRESULT STDMETHODCALLTYPE
CDefView::GetArrangeParam(LPARAM
*sort
)
2640 FIXME("(%p)->(%p) stub\n", this, sort
);
2644 HRESULT STDMETHODCALLTYPE
CDefView::ArrangeGrid()
2646 FIXME("(%p) stub\n", this);
2650 HRESULT STDMETHODCALLTYPE
CDefView::AutoArrange()
2652 FIXME("(%p) stub\n", this);
2656 HRESULT STDMETHODCALLTYPE
CDefView::AddObject(PITEMID_CHILD pidl
, UINT
*item
)
2658 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2662 HRESULT STDMETHODCALLTYPE
CDefView::GetObject(PITEMID_CHILD
*pidl
, UINT item
)
2664 TRACE("(%p)->(%p %d)\n", this, pidl
, item
);
2665 return Item(item
, pidl
);
2668 HRESULT STDMETHODCALLTYPE
CDefView::RemoveObject(PITEMID_CHILD pidl
, UINT
*item
)
2671 TRACE("(%p)->(%p %p)\n", this, pidl
, item
);
2675 *item
= LV_FindItemByPidl(ILFindLastID(pidl
));
2676 m_ListView
.DeleteItem(*item
);
2681 m_ListView
.DeleteAllItems();
2687 HRESULT STDMETHODCALLTYPE
CDefView::GetObjectCount(UINT
*count
)
2689 TRACE("(%p)->(%p)\n", this, count
);
2690 *count
= m_ListView
.GetItemCount();
2694 HRESULT STDMETHODCALLTYPE
CDefView::SetObjectCount(UINT count
, UINT flags
)
2696 FIXME("(%p)->(%d %x) stub\n", this, count
, flags
);
2700 HRESULT STDMETHODCALLTYPE
CDefView::UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
)
2702 FIXME("(%p)->(%p %p %p) stub\n", this, pidl_old
, pidl_new
, item
);
2706 HRESULT STDMETHODCALLTYPE
CDefView::RefreshObject(PITEMID_CHILD pidl
, UINT
*item
)
2708 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2712 HRESULT STDMETHODCALLTYPE
CDefView::SetRedraw(BOOL redraw
)
2714 TRACE("(%p)->(%d)\n", this, redraw
);
2715 m_ListView
.SetRedraw(redraw
);
2719 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedCount(UINT
*count
)
2721 FIXME("(%p)->(%p) stub\n", this, count
);
2725 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
)
2727 TRACE("(%p)->(%p %p)\n", this, pidl
, items
);
2729 *items
= GetSelections();
2733 *pidl
= static_cast<PCUITEMID_CHILD
*>(LocalAlloc(0, *items
* sizeof(PCUITEMID_CHILD
)));
2736 return E_OUTOFMEMORY
;
2739 /* it's documented that caller shouldn't PIDLs, only array itself */
2740 memcpy(*pidl
, m_apidl
, *items
* sizeof(PCUITEMID_CHILD
));
2746 HRESULT STDMETHODCALLTYPE
CDefView::IsDropOnSource(IDropTarget
*drop_target
)
2748 if ((m_iDragOverItem
== -1 || m_pCurDropTarget
== NULL
) &&
2749 (m_pSourceDataObject
.p
))
2757 HRESULT STDMETHODCALLTYPE
CDefView::GetDragPoint(POINT
*pt
)
2760 return E_INVALIDARG
;
2762 *pt
= m_ptFirstMousePos
;
2766 HRESULT STDMETHODCALLTYPE
CDefView::GetDropPoint(POINT
*pt
)
2768 FIXME("(%p)->(%p) stub\n", this, pt
);
2772 HRESULT STDMETHODCALLTYPE
CDefView::MoveIcons(IDataObject
*obj
)
2774 TRACE("(%p)->(%p)\n", this, obj
);
2778 HRESULT STDMETHODCALLTYPE
CDefView::SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
)
2780 FIXME("(%p)->(%p %p) stub\n", this, pidl
, pt
);
2784 HRESULT STDMETHODCALLTYPE
CDefView::IsBkDropTarget(IDropTarget
*drop_target
)
2786 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2790 HRESULT STDMETHODCALLTYPE
CDefView::SetClipboard(BOOL move
)
2792 FIXME("(%p)->(%d) stub\n", this, move
);
2796 HRESULT STDMETHODCALLTYPE
CDefView::SetPoints(IDataObject
*obj
)
2798 FIXME("(%p)->(%p) stub\n", this, obj
);
2802 HRESULT STDMETHODCALLTYPE
CDefView::GetItemSpacing(ITEMSPACING
*spacing
)
2804 FIXME("(%p)->(%p) stub\n", this, spacing
);
2808 HRESULT STDMETHODCALLTYPE
CDefView::SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
)
2811 *old_cb
= m_pShellFolderViewCB
.Detach();
2813 m_pShellFolderViewCB
= new_cb
;
2817 HRESULT STDMETHODCALLTYPE
CDefView::Select(UINT flags
)
2819 FIXME("(%p)->(%d) stub\n", this, flags
);
2823 HRESULT STDMETHODCALLTYPE
CDefView::QuerySupport(UINT
*support
)
2825 TRACE("(%p)->(%p)\n", this, support
);
2829 HRESULT STDMETHODCALLTYPE
CDefView::SetAutomationObject(IDispatch
*disp
)
2831 FIXME("(%p)->(%p) stub\n", this, disp
);
2835 /**********************************************************
2836 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2838 HRESULT WINAPI
CDefView::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD
*prgCmds
, OLECMDTEXT
*pCmdText
)
2840 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
2841 this, pguidCmdGroup
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
2844 return E_INVALIDARG
;
2846 for (UINT i
= 0; i
< cCmds
; i
++)
2848 FIXME("\tprgCmds[%d].cmdID = %d\n", i
, prgCmds
[i
].cmdID
);
2849 prgCmds
[i
].cmdf
= 0;
2852 return OLECMDERR_E_UNKNOWNGROUP
;
2855 /**********************************************************
2856 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2858 * nCmdID is the OLECMDID_* enumeration
2860 HRESULT WINAPI
CDefView::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
2862 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2863 this, debugstr_guid(pguidCmdGroup
), nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2866 return OLECMDERR_E_UNKNOWNGROUP
;
2868 if (IsEqualCLSID(*pguidCmdGroup
, m_Category
))
2870 if (nCmdID
== FCIDM_SHVIEW_AUTOARRANGE
)
2872 if (V_VT(pvaIn
) != VT_INT_PTR
)
2873 return OLECMDERR_E_NOTSUPPORTED
;
2876 params
.cbSize
= sizeof(params
);
2877 params
.rcExclude
= *(RECT
*) V_INTREF(pvaIn
);
2879 if (m_hMenuViewModes
)
2881 /* Duplicate all but the last two items of the view modes menu */
2882 HMENU hmenuViewPopup
= CreatePopupMenu();
2883 Shell_MergeMenus(hmenuViewPopup
, m_hMenuViewModes
, 0, 0, 0xFFFF, 0);
2884 DeleteMenu(hmenuViewPopup
, GetMenuItemCount(hmenuViewPopup
) - 1, MF_BYPOSITION
);
2885 DeleteMenu(hmenuViewPopup
, GetMenuItemCount(hmenuViewPopup
) - 1, MF_BYPOSITION
);
2886 CheckViewMode(hmenuViewPopup
);
2887 TrackPopupMenuEx(hmenuViewPopup
, TPM_LEFTALIGN
| TPM_TOPALIGN
, params
.rcExclude
.left
, params
.rcExclude
.bottom
, m_hWndParent
, ¶ms
);
2888 ::DestroyMenu(hmenuViewPopup
);
2891 // pvaOut is VT_I4 with value 0x403 (cmd id of the new mode maybe?)
2892 V_VT(pvaOut
) = VT_I4
;
2893 V_I4(pvaOut
) = 0x403;
2897 if (IsEqualIID(*pguidCmdGroup
, CGID_Explorer
) &&
2899 (nCmdexecopt
== 4) && pvaOut
)
2902 if (IsEqualIID(*pguidCmdGroup
, CGID_ShellDocView
) &&
2907 return OLECMDERR_E_UNKNOWNGROUP
;
2910 /**********************************************************
2911 * ISVDropTarget implementation
2914 /******************************************************************************
2915 * drag_notify_subitem [Internal]
2917 * Figure out the shellfolder object, which is currently under the mouse cursor
2918 * and notify it via the IDropTarget interface.
2921 #define SCROLLAREAWIDTH 20
2923 HRESULT
CDefView::drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2929 /* The key state on drop doesn't have MK_LBUTTON or MK_RBUTTON because it
2930 reflects the key state after the user released the button, so we need
2931 to remember the last key state when the button was pressed */
2932 m_grfKeyState
= grfKeyState
;
2934 /* Map from global to client coordinates and query the index of the listview-item, which is
2935 * currently under the mouse cursor. */
2936 LVHITTESTINFO htinfo
= {{pt
.x
, pt
.y
}, LVHT_ONITEM
};
2937 ScreenToClient(&htinfo
.pt
);
2938 lResult
= m_ListView
.HitTest(&htinfo
);
2940 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2941 ::GetClientRect(m_ListView
, &clientRect
);
2942 if (htinfo
.pt
.x
== m_ptLastMousePos
.x
&& htinfo
.pt
.y
== m_ptLastMousePos
.y
&&
2943 (htinfo
.pt
.x
< SCROLLAREAWIDTH
|| htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
||
2944 htinfo
.pt
.y
< SCROLLAREAWIDTH
|| htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
))
2946 m_cScrollDelay
= (m_cScrollDelay
+ 1) % 5; /* DragOver is called every 50 ms */
2947 if (m_cScrollDelay
== 0)
2949 /* Mouse did hover another 250 ms over the scroll-area */
2950 if (htinfo
.pt
.x
< SCROLLAREAWIDTH
)
2951 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEUP
, 0);
2953 if (htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
)
2954 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEDOWN
, 0);
2956 if (htinfo
.pt
.y
< SCROLLAREAWIDTH
)
2957 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEUP
, 0);
2959 if (htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
)
2960 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEDOWN
, 0);
2965 m_cScrollDelay
= 0; /* Reset, if the cursor is not over the listview's scroll-area */
2968 m_ptLastMousePos
= htinfo
.pt
;
2970 /* We need to check if we drag the selection over itself */
2971 if (lResult
!= -1 && m_pSourceDataObject
.p
!= NULL
)
2973 PCUITEMID_CHILD pidl
= _PidlByItem(lResult
);
2975 for (UINT i
= 0; i
< m_cidl
; i
++)
2977 if (pidl
== m_apidl
[i
])
2979 /* The item that is being draged is hovering itself. */
2986 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2987 if (m_pCurDropTarget
&& lResult
== m_iDragOverItem
)
2988 return m_pCurDropTarget
->DragOver(grfKeyState
, pt
, pdwEffect
);
2990 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2991 if (m_pCurDropTarget
)
2993 PCUITEMID_CHILD pidl
= _PidlByItem(m_iDragOverItem
);
2995 SelectItem(pidl
, 0);
2997 m_pCurDropTarget
->DragLeave();
2998 m_pCurDropTarget
.Release();
3001 m_iDragOverItem
= lResult
;
3005 /* We are not above one of the listview's subitems. Bind to the parent folder's
3006 * DropTarget interface. */
3007 hr
= m_pSFParent
->CreateViewObject(NULL
, IID_PPV_ARG(IDropTarget
,&m_pCurDropTarget
));
3011 /* Query the relative PIDL of the shellfolder object represented by the currently
3012 * dragged over listview-item ... */
3013 PCUITEMID_CHILD pidl
= _PidlByItem(lResult
);
3015 /* ... and bind m_pCurDropTarget to the IDropTarget interface of an UIObject of this object */
3016 hr
= m_pSFParent
->GetUIObjectOf(m_ListView
, 1, &pidl
, IID_NULL_PPV_ARG(IDropTarget
, &m_pCurDropTarget
));
3019 IUnknown_SetSite(m_pCurDropTarget
, (IShellView
*)this);
3021 /* If anything failed, m_pCurDropTarget should be NULL now, which ought to be a save state. */
3024 *pdwEffect
= DROPEFFECT_NONE
;
3028 if (m_iDragOverItem
!= -1)
3030 SelectItem(m_iDragOverItem
, SVSI_SELECT
);
3033 /* Notify the item just entered via DragEnter. */
3034 return m_pCurDropTarget
->DragEnter(m_pCurDataObject
, grfKeyState
, pt
, pdwEffect
);
3037 HRESULT WINAPI
CDefView::DragEnter(IDataObject
*pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
3039 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
3040 m_pCurDataObject
= pDataObject
;
3042 HRESULT hr
= drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
3045 POINT ptClient
= {pt
.x
, pt
.y
};
3046 ScreenToClient(&ptClient
);
3047 ImageList_DragEnter(m_hWnd
, ptClient
.x
, ptClient
.y
);
3053 HRESULT WINAPI
CDefView::DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
3055 POINT ptClient
= {pt
.x
, pt
.y
};
3056 ScreenToClient(&ptClient
);
3057 ImageList_DragMove(ptClient
.x
, ptClient
.y
);
3058 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
3061 HRESULT WINAPI
CDefView::DragLeave()
3063 ImageList_DragLeave(m_hWnd
);
3065 if (m_pCurDropTarget
)
3067 m_pCurDropTarget
->DragLeave();
3068 m_pCurDropTarget
.Release();
3071 if (m_pCurDataObject
!= NULL
)
3073 m_pCurDataObject
.Release();
3076 m_iDragOverItem
= 0;
3081 HRESULT WINAPI
CDefView::Drop(IDataObject
* pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
3083 ImageList_DragLeave(m_hWnd
);
3084 ImageList_EndDrag();
3086 if ((IsDropOnSource(NULL
) == S_OK
) &&
3087 (*pdwEffect
& DROPEFFECT_MOVE
) &&
3088 (m_grfKeyState
& MK_LBUTTON
))
3090 if (m_pCurDropTarget
)
3092 m_pCurDropTarget
->DragLeave();
3093 m_pCurDropTarget
.Release();
3096 /* Restore the selection */
3097 m_ListView
.SetItemState(-1, 0, LVIS_SELECTED
);
3098 for (UINT i
= 0 ; i
< m_cidl
; i
++)
3099 SelectItem(m_apidl
[i
], SVSI_SELECT
);
3101 /* Reposition the items */
3103 while ((lvIndex
= m_ListView
.GetNextItem(lvIndex
, LVNI_SELECTED
)) > -1)
3106 if (m_ListView
.GetItemPosition(lvIndex
, &ptItem
))
3108 ptItem
.x
+= pt
.x
- m_ptFirstMousePos
.x
;
3109 ptItem
.y
+= pt
.y
- m_ptFirstMousePos
.y
;
3110 m_ListView
.SetItemPosition(lvIndex
, &ptItem
);
3114 else if (m_pCurDropTarget
)
3116 m_pCurDropTarget
->Drop(pDataObject
, grfKeyState
, pt
, pdwEffect
);
3117 m_pCurDropTarget
.Release();
3120 m_pCurDataObject
.Release();
3121 m_iDragOverItem
= 0;
3125 /**********************************************************
3126 * ISVDropSource implementation
3129 HRESULT WINAPI
CDefView::QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
)
3131 TRACE("(%p)\n", this);
3134 return DRAGDROP_S_CANCEL
;
3135 else if (!(grfKeyState
& MK_LBUTTON
) && !(grfKeyState
& MK_RBUTTON
))
3136 return DRAGDROP_S_DROP
;
3141 HRESULT WINAPI
CDefView::GiveFeedback(DWORD dwEffect
)
3143 TRACE("(%p)\n", this);
3145 return DRAGDROP_S_USEDEFAULTCURSORS
;
3148 /**********************************************************
3149 * ISVViewObject implementation
3152 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
)
3154 FIXME("Stub: this=%p\n", this);
3159 HRESULT WINAPI
CDefView::GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
, HDC hicTargetDevice
, LOGPALETTE
**ppColorSet
)
3161 FIXME("Stub: this=%p\n", this);
3166 HRESULT WINAPI
CDefView::Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
)
3168 FIXME("Stub: this=%p\n", this);
3173 HRESULT WINAPI
CDefView::Unfreeze(DWORD dwFreeze
)
3175 FIXME("Stub: this=%p\n", this);
3180 HRESULT WINAPI
CDefView::SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
)
3182 FIXME("partial stub: %p 0x%08x 0x%08x %p\n", this, aspects
, advf
, pAdvSink
);
3184 /* FIXME: we set the AdviseSink, but never use it to send any advice */
3185 m_pAdvSink
= pAdvSink
;
3186 m_dwAspects
= aspects
;
3192 HRESULT WINAPI
CDefView::GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
)
3194 TRACE("this=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n", this, pAspects
, pAdvf
, ppAdvSink
);
3198 *ppAdvSink
= m_pAdvSink
;
3199 m_pAdvSink
.p
->AddRef();
3203 *pAspects
= m_dwAspects
;
3211 HRESULT STDMETHODCALLTYPE
CDefView::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
3213 if (IsEqualIID(guidService
, SID_IShellBrowser
))
3214 return m_pShellBrowser
->QueryInterface(riid
, ppvObject
);
3215 else if(IsEqualIID(guidService
, SID_IFolderView
))
3216 return QueryInterface(riid
, ppvObject
);
3218 return E_NOINTERFACE
;
3221 HRESULT
CDefView::_MergeToolbar()
3223 CComPtr
<IExplorerToolbar
> ptb
;
3226 hr
= IUnknown_QueryService(m_pShellBrowser
, IID_IExplorerToolbar
, IID_PPV_ARG(IExplorerToolbar
, &ptb
));
3230 m_Category
= CGID_DefViewFrame
;
3232 hr
= ptb
->SetCommandTarget(static_cast<IOleCommandTarget
*>(this), &m_Category
, 0);
3240 hr
= ptb
->AddButtons(&m_Category
, buttonsCount
, buttons
);
3248 VOID
CDefView::_DoFolderViewCB(UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3250 if (m_pShellFolderViewCB
)
3252 m_pShellFolderViewCB
->MessageSFVCB(uMsg
, wParam
, lParam
);
3256 HRESULT
CDefView_CreateInstance(IShellFolder
*pFolder
, REFIID riid
, LPVOID
* ppvOut
)
3258 return ShellObjectCreatorInit
<CDefView
>(pFolder
, riid
, ppvOut
);
3261 HRESULT WINAPI
SHCreateShellFolderViewEx(
3262 LPCSFV psvcbi
, /* [in] shelltemplate struct */
3263 IShellView
**ppsv
) /* [out] IShellView pointer */
3265 CComPtr
<IShellView
> psv
;
3268 TRACE("sf=%p pidl=%p cb=%p mode=0x%08x parm=%p\n",
3269 psvcbi
->pshf
, psvcbi
->pidl
, psvcbi
->pfnCallback
,
3270 psvcbi
->fvm
, psvcbi
->psvOuter
);
3273 hRes
= CDefView_CreateInstance(psvcbi
->pshf
, IID_PPV_ARG(IShellView
, &psv
));
3274 if (FAILED_UNEXPECTEDLY(hRes
))
3277 *ppsv
= psv
.Detach();
3281 HRESULT WINAPI
SHCreateShellFolderView(const SFV_CREATE
*pcsfv
,
3284 CComPtr
<IShellView
> psv
;
3288 if (!pcsfv
|| pcsfv
->cbSize
!= sizeof(*pcsfv
))
3289 return E_INVALIDARG
;
3291 TRACE("sf=%p outer=%p callback=%p\n",
3292 pcsfv
->pshf
, pcsfv
->psvOuter
, pcsfv
->psfvcb
);
3294 hRes
= CDefView_CreateInstance(pcsfv
->pshf
, IID_PPV_ARG(IShellView
, &psv
));
3300 CComPtr
<IShellFolderView
> sfv
;
3301 if (SUCCEEDED(psv
->QueryInterface(IID_PPV_ARG(IShellFolderView
, &sfv
))))
3303 sfv
->SetCallback(pcsfv
->psfvcb
, NULL
);
3307 *ppsv
= psv
.Detach();