4 * Copyright 1998,1999 <juergen.schmied@debitel.net>
6 * This is the view visualizing the data provided by the shellfolder.
7 * No direct access to data from pidls should be done from here.
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 * FIXME: CheckToolbar: handle the "new folder" and "folder up" button
28 - Load/Save the view state from/into the stream provided by the ShellBrowser.
29 - When editing starts on item, set edit text to for editing value.
30 - Fix shell view to handle view mode popup exec.
31 - The background context menu should have a pidl just like foreground menus. This
32 causes crashes when dynamic handlers try to use the NULL pidl.
33 - Reorder of columns doesn't work - might be bug in comctl32
41 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
45 static const WCHAR SV_CLASS_NAME
[] = {'S', 'H', 'E', 'L', 'L', 'D', 'L', 'L', '_', 'D', 'e', 'f', 'V', 'i', 'e', 'w', 0};
52 } LISTVIEW_SORT_INFO
, *LPLISTVIEW_SORT_INFO
;
54 #define SHV_CHANGE_NOTIFY WM_USER + 0x1111
56 /* For the context menu of the def view, the id of the items are based on 1 because we need
57 to call TrackPopupMenu and let it use the 0 value as an indication that the menu was canceled */
58 #define CONTEXT_MENU_BASE_ID 1
61 public CWindowImpl
<CDefView
, CWindow
, CControlWinTraits
>,
62 public CComObjectRootEx
<CComMultiThreadModelNoCS
>,
65 public IShellFolderView
,
66 public IOleCommandTarget
,
70 public IServiceProvider
73 CComPtr
<IShellFolder
> m_pSFParent
;
74 CComPtr
<IShellFolder2
> m_pSF2Parent
;
75 CComPtr
<IShellFolderViewCB
> m_pShellFolderViewCB
;
76 CComPtr
<IShellBrowser
> m_pShellBrowser
;
77 CComPtr
<ICommDlgBrowser
> m_pCommDlgBrowser
;
78 CComPtr
<IShellFolderViewDual
> m_pShellFolderViewDual
;
81 FOLDERSETTINGS m_FolderSettings
;
82 HMENU m_hMenu
; /* Handle to the menu bar of the browser */
83 HMENU m_hMenuArrangeModes
; /* Handle to the popup menu with the arrange modes */
84 HMENU m_hMenuViewModes
; /* Handle to the popup menu with the view modes */
85 HMENU m_hContextMenu
; /* Handle to the open context menu */
86 BOOL m_bmenuBarInitialized
;
89 PCUITEMID_CHILD
*m_apidl
;
90 PIDLIST_ABSOLUTE m_pidlParent
;
91 LISTVIEW_SORT_INFO m_sortInfo
;
92 ULONG m_hNotify
; /* Change notification handle */
96 CComPtr
<IAdviseSink
> m_pAdvSink
;
98 CComPtr
<IDataObject
> m_pSourceDataObject
;
99 CComPtr
<IDropTarget
> m_pCurDropTarget
; /* The sub-item, which is currently dragged over */
100 CComPtr
<IDataObject
> m_pCurDataObject
; /* The dragged data-object */
101 LONG m_iDragOverItem
; /* Dragged over item's index, iff m_pCurDropTarget != NULL */
102 UINT m_cScrollDelay
; /* Send a WM_*SCROLL msg every 250 ms during drag-scroll */
103 POINT m_ptLastMousePos
; /* Mouse position at last DragOver call */
104 POINT m_ptFirstMousePos
; /* Mouse position when the drag operation started */
107 CComPtr
<IContextMenu
> m_pCM
;
115 HRESULT
_MergeToolbar();
117 HRESULT
_DoFolderViewCB(UINT uMsg
, WPARAM wParam
, LPARAM lParam
);
122 HRESULT WINAPI
Initialize(IShellFolder
*shellFolder
);
123 HRESULT
IncludeObject(PCUITEMID_CHILD pidl
);
124 HRESULT
OnDefaultCommand();
125 HRESULT
OnStateChange(UINT uFlags
);
126 void UpdateStatusbar();
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()
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;
595 /* UpdateShellSettings(); */
599 void CDefView::UpdateListColors()
601 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
603 /* Check if drop shadows option is enabled */
604 BOOL bDropShadow
= FALSE
;
605 DWORD cbDropShadow
= sizeof(bDropShadow
);
608 * The desktop ListView always take the default desktop colours, by
609 * remaining transparent and letting user32/win32k paint itself the
610 * desktop background color, if any.
612 m_ListView
.SetBkColor(CLR_NONE
);
614 SHGetValueW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
615 L
"ListviewShadow", NULL
, &bDropShadow
, &cbDropShadow
);
618 /* Set the icon background transparent */
619 m_ListView
.SetTextBkColor(CLR_NONE
);
620 m_ListView
.SetTextColor(RGB(255, 255, 255));
621 m_ListView
.SetExtendedListViewStyle(LVS_EX_TRANSPARENTSHADOWTEXT
, LVS_EX_TRANSPARENTSHADOWTEXT
);
625 /* Set the icon background as the same colour as the desktop */
626 COLORREF crDesktop
= GetSysColor(COLOR_DESKTOP
);
627 m_ListView
.SetTextBkColor(crDesktop
);
628 if (GetRValue(crDesktop
) + GetGValue(crDesktop
) + GetBValue(crDesktop
) > 128 * 3)
629 m_ListView
.SetTextColor(RGB(0, 0, 0));
631 m_ListView
.SetTextColor(RGB(255, 255, 255));
632 m_ListView
.SetExtendedListViewStyle(0, LVS_EX_TRANSPARENTSHADOWTEXT
);
637 /**********************************************************
638 * ShellView_InitList()
640 * - adds all needed columns to the shellview
642 BOOL
CDefView::InitList()
646 HIMAGELIST big_icons
, small_icons
;
650 m_ListView
.DeleteAllItems();
652 m_hMenuArrangeModes
= CreateMenu();
656 for (int i
= 0; 1; i
++)
658 if (FAILED(m_pSF2Parent
->GetDetailsOf(NULL
, i
, &sd
)))
660 StrRetToStrNW( szTemp
, 50, &sd
.str
, NULL
);
661 m_ListView
.InsertColumn(i
, szTemp
, sd
.fmt
, sd
.cxChar
* 8);
663 InsertMenuW(m_hMenuArrangeModes
, -1, MF_STRING
, 0x30 + i
, szTemp
);
666 InsertMenuW(m_hMenuArrangeModes
, -1, MF_BYPOSITION
| MF_SEPARATOR
, 0, 0);
670 FIXME("no m_pSF2Parent\n");
673 Shell_GetImageLists(&big_icons
, &small_icons
);
674 m_ListView
.SetImageList(big_icons
, LVSIL_NORMAL
);
675 m_ListView
.SetImageList(small_icons
, LVSIL_SMALL
);
680 /*************************************************************************
681 * ShellView_ListViewCompareItems
683 * Compare Function for the Listview (FileOpen Dialog)
686 * lParam1 [I] the first ItemIdList to compare with
687 * lParam2 [I] the second ItemIdList to compare with
688 * lpData [I] The column ID for the header Ctrl to process
691 * A negative value if the first item should precede the second,
692 * a positive value if the first item should follow the second,
693 * or zero if the two items are equivalent
695 INT CALLBACK
CDefView::ListViewCompareItems(LPARAM lParam1
, LPARAM lParam2
, LPARAM lpData
)
697 PCUIDLIST_RELATIVE pidl1
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam1
);
698 PCUIDLIST_RELATIVE pidl2
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam2
);
699 CDefView
*pThis
= reinterpret_cast<CDefView
*>(lpData
);
701 HRESULT hres
= pThis
->m_pSFParent
->CompareIDs(pThis
->m_sortInfo
.nHeaderID
, pidl1
, pidl2
);
702 if (FAILED_UNEXPECTEDLY(hres
))
705 SHORT nDiff
= HRESULT_CODE(hres
);
706 if (!pThis
->m_sortInfo
.bIsAscending
)
711 BOOL
CDefView::_Sort()
716 if (m_ListView
.GetWindowLongPtr(GWL_STYLE
) & LVS_NOSORTHEADER
)
719 hHeader
= (HWND
)m_ListView
.SendMessage(LVM_GETHEADER
, 0, 0);
720 ZeroMemory(&hColumn
, sizeof(hColumn
));
722 /* If the sorting column changed, remove the sorting style from the old column */
723 if ( (m_sortInfo
.nLastHeaderID
!= -1) &&
724 (m_sortInfo
.nLastHeaderID
!= m_sortInfo
.nHeaderID
) )
726 hColumn
.mask
= HDI_FORMAT
;
727 Header_GetItem(hHeader
, m_sortInfo
.nLastHeaderID
, &hColumn
);
728 hColumn
.fmt
&= ~(HDF_SORTUP
| HDF_SORTDOWN
);
729 Header_SetItem(hHeader
, m_sortInfo
.nLastHeaderID
, &hColumn
);
732 /* Set the sorting style to the new column */
733 hColumn
.mask
= HDI_FORMAT
;
734 Header_GetItem(hHeader
, m_sortInfo
.nHeaderID
, &hColumn
);
736 hColumn
.fmt
&= (m_sortInfo
.bIsAscending
? ~HDF_SORTDOWN
: ~HDF_SORTUP
);
737 hColumn
.fmt
|= (m_sortInfo
.bIsAscending
? HDF_SORTUP
: HDF_SORTDOWN
);
738 Header_SetItem(hHeader
, m_sortInfo
.nHeaderID
, &hColumn
);
740 /* Sort the list, using the current values of nHeaderID and bIsAscending */
741 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
742 return m_ListView
.SortItems(ListViewCompareItems
, this);
745 PCUITEMID_CHILD
CDefView::_PidlByItem(int i
)
747 return reinterpret_cast<PCUITEMID_CHILD
>(m_ListView
.GetItemData(i
));
750 PCUITEMID_CHILD
CDefView::_PidlByItem(LVITEM
& lvItem
)
752 return reinterpret_cast<PCUITEMID_CHILD
>(lvItem
.lParam
);
755 /**********************************************************
756 * LV_FindItemByPidl()
758 int CDefView::LV_FindItemByPidl(PCUITEMID_CHILD pidl
)
760 int cItems
= m_ListView
.GetItemCount();
762 for (int i
= 0; i
<cItems
; i
++)
764 PCUITEMID_CHILD currentpidl
= _PidlByItem(i
);
765 HRESULT hr
= m_pSFParent
->CompareIDs(0, pidl
, currentpidl
);
767 if (SUCCEEDED(hr
) && !HRESULT_CODE(hr
))
775 /**********************************************************
778 BOOLEAN
CDefView::LV_AddItem(PCUITEMID_CHILD pidl
)
782 TRACE("(%p)(pidl=%p)\n", this, pidl
);
784 lvItem
.mask
= LVIF_TEXT
| LVIF_IMAGE
| LVIF_PARAM
; /*set the mask*/
785 lvItem
.iItem
= m_ListView
.GetItemCount(); /*add the item to the end of the list*/
787 lvItem
.lParam
= reinterpret_cast<LPARAM
>(ILClone(pidl
)); /*set the item's data*/
788 lvItem
.pszText
= LPSTR_TEXTCALLBACKW
; /*get text on a callback basis*/
789 lvItem
.iImage
= I_IMAGECALLBACK
; /*get the image on a callback basis*/
790 lvItem
.stateMask
= LVIS_CUT
;
792 if (m_ListView
.InsertItem(&lvItem
) == -1)
798 /**********************************************************
801 BOOLEAN
CDefView::LV_DeleteItem(PCUITEMID_CHILD pidl
)
805 TRACE("(%p)(pidl=%p)\n", this, pidl
);
807 nIndex
= LV_FindItemByPidl(pidl
);
809 return (-1 == m_ListView
.DeleteItem(nIndex
)) ? FALSE
: TRUE
;
812 /**********************************************************
815 BOOLEAN
CDefView::LV_RenameItem(PCUITEMID_CHILD pidlOld
, PCUITEMID_CHILD pidlNew
)
820 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", this, pidlOld
, pidlNew
);
822 nItem
= LV_FindItemByPidl(pidlOld
);
826 lvItem
.mask
= LVIF_PARAM
; /* only the pidl */
827 lvItem
.iItem
= nItem
;
829 m_ListView
.GetItem(&lvItem
);
831 SHFree(reinterpret_cast<LPVOID
>(lvItem
.lParam
));
832 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
833 lvItem
.iItem
= nItem
;
835 lvItem
.lParam
= reinterpret_cast<LPARAM
>(ILClone(pidlNew
)); /* set the item's data */
836 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
837 m_ListView
.SetItem(&lvItem
);
838 m_ListView
.Update(nItem
);
839 return TRUE
; /* FIXME: better handling */
845 /**********************************************************
848 BOOLEAN
CDefView::LV_ProdItem(PCUITEMID_CHILD pidl
)
853 TRACE("(%p)(pidl=%p)\n", this, pidl
);
855 nItem
= LV_FindItemByPidl(pidl
);
859 lvItem
.mask
= LVIF_IMAGE
;
860 lvItem
.iItem
= nItem
;
862 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
863 m_ListView
.SetItem(&lvItem
);
864 m_ListView
.Update(nItem
);
871 /**********************************************************
872 * ShellView_FillList()
874 * - gets the objectlist from the shellfolder
876 * - fills the list into the view
878 INT CALLBACK
CDefView::fill_list(LPVOID ptr
, LPVOID arg
)
880 PITEMID_CHILD pidl
= static_cast<PITEMID_CHILD
>(ptr
);
881 CDefView
*pThis
= static_cast<CDefView
*>(arg
);
883 /* in a commdlg This works as a filemask*/
884 if (pThis
->IncludeObject(pidl
) == S_OK
)
885 pThis
->LV_AddItem(pidl
);
891 HRESULT
CDefView::FillList()
893 CComPtr
<IEnumIDList
> pEnumIDList
;
899 DWORD dFlags
= SHCONTF_NONFOLDERS
| SHCONTF_FOLDERS
;
903 /* determine if there is a setting to show all the hidden files/folders */
904 if (RegOpenKeyExW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", 0, KEY_QUERY_VALUE
, &hKey
) == ERROR_SUCCESS
)
906 DWORD dataLength
, flagVal
;
908 dataLength
= sizeof(flagVal
);
909 if (RegQueryValueExW(hKey
, L
"Hidden", NULL
, NULL
, (LPBYTE
)&flagVal
, &dataLength
) == ERROR_SUCCESS
)
911 /* if the value is 1, then show all hidden files/folders */
914 dFlags
|= SHCONTF_INCLUDEHIDDEN
;
915 m_ListView
.SendMessageW(LVM_SETCALLBACKMASK
, LVIS_CUT
, 0);
923 /* get the itemlist from the shfolder */
924 hRes
= m_pSFParent
->EnumObjects(m_hWnd
, dFlags
, &pEnumIDList
);
932 /* create a pointer array */
933 hdpa
= DPA_Create(16);
936 return(E_OUTOFMEMORY
);
939 /* copy the items into the array*/
940 while((S_OK
== pEnumIDList
->Next(1, &pidl
, &dwFetched
)) && dwFetched
)
942 if (DPA_InsertPtr(hdpa
, 0x7fff, pidl
) == -1)
948 /*turn the listview's redrawing off*/
949 m_ListView
.SetRedraw(FALSE
);
951 DPA_DestroyCallback( hdpa
, fill_list
, this);
956 m_pSF2Parent
->GetDefaultColumn(NULL
, (ULONG
*)&m_sortInfo
.nHeaderID
, NULL
);
960 FIXME("no m_pSF2Parent\n");
962 m_sortInfo
.bIsAscending
= TRUE
;
965 /*turn the listview's redrawing back on and force it to draw*/
966 m_ListView
.SetRedraw(TRUE
);
968 _DoFolderViewCB(SFVM_LISTREFRESHED
, NULL
, NULL
);
973 LRESULT
CDefView::OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
975 m_ListView
.UpdateWindow();
980 LRESULT
CDefView::OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
982 return m_ListView
.SendMessageW(uMsg
, 0, 0);
985 LRESULT
CDefView::OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
992 DestroyMenu(m_hMenu
);
995 RevokeDragDrop(m_hWnd
);
996 SHChangeNotifyDeregister(m_hNotify
);
998 SHFree(m_pidlParent
);
1005 LRESULT
CDefView::OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1007 /* redirect to parent */
1008 if (m_FolderSettings
.fFlags
& (FWF_DESKTOP
| FWF_TRANSPARENT
))
1009 return SendMessageW(GetParent(), WM_ERASEBKGND
, wParam
, lParam
);
1015 LRESULT
CDefView::OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1017 /* Update desktop labels color */
1020 /* Forward WM_SYSCOLORCHANGE to common controls */
1021 return m_ListView
.SendMessageW(uMsg
, 0, 0);
1024 LRESULT
CDefView::OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1026 return reinterpret_cast<LRESULT
>(m_pShellBrowser
.p
);
1029 LRESULT
CDefView::OnNCCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1036 LRESULT
CDefView::OnNCDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1043 /**********************************************************
1044 * ShellView_OnCreate()
1046 LRESULT
CDefView::OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1048 CComPtr
<IDropTarget
> pdt
;
1049 SHChangeNotifyEntry ntreg
;
1050 CComPtr
<IPersistFolder2
> ppf2
;
1052 TRACE("%p\n", this);
1062 if (SUCCEEDED(QueryInterface(IID_PPV_ARG(IDropTarget
, &pdt
))))
1064 if (FAILED(RegisterDragDrop(m_hWnd
, pdt
)))
1065 ERR("Registering Drag Drop Failed");
1068 /* register for receiving notifications */
1069 m_pSFParent
->QueryInterface(IID_PPV_ARG(IPersistFolder2
, &ppf2
));
1072 ppf2
->GetCurFolder(&m_pidlParent
);
1073 ntreg
.fRecursive
= TRUE
;
1074 ntreg
.pidl
= m_pidlParent
;
1075 m_hNotify
= SHChangeNotifyRegister(m_hWnd
, SHCNRF_InterruptLevel
| SHCNRF_ShellLevel
, SHCNE_ALLEVENTS
, SHV_CHANGE_NOTIFY
, 1, &ntreg
);
1078 /* _DoFolderViewCB(SFVM_GETNOTIFY, ?? ??) */
1080 m_hAccel
= LoadAcceleratorsW(shell32_hInstance
, MAKEINTRESOURCEW(IDA_SHELLVIEW
));
1087 /**********************************************************
1088 * #### Handling of the menus ####
1091 extern "C" DWORD WINAPI
SHMenuIndexFromID(HMENU hMenu
, UINT uID
);
1093 HMENU
GetSubmenuByID(HMENU hmenu
, UINT id
)
1095 MENUITEMINFOW mii
= {sizeof(mii
), MIIM_SUBMENU
};
1096 if (::GetMenuItemInfoW(hmenu
, id
, FALSE
, &mii
))
1097 return mii
.hSubMenu
;
1102 /* ReallyGetMenuItemID returns the id of an item even if it opens a submenu,
1103 GetMenuItemID returns -1 if the specified item opens a submenu */
1104 UINT
ReallyGetMenuItemID(HMENU hmenu
, int i
)
1106 MENUITEMINFOW mii
= {sizeof(mii
), MIIM_ID
};
1107 if (::GetMenuItemInfoW(hmenu
, i
, TRUE
, &mii
))
1113 HRESULT
CDefView::FillFileMenu()
1115 HMENU hFileMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_FILE
);
1119 /* Cleanup the items added previously */
1120 for (int i
= GetMenuItemCount(hFileMenu
) - 1; i
>= 0; i
--)
1122 UINT id
= GetMenuItemID(hFileMenu
, i
);
1123 if (id
< FCIDM_BROWSERFIRST
|| id
> FCIDM_BROWSERLAST
)
1124 DeleteMenu(hFileMenu
, i
, MF_BYPOSITION
);
1127 /* Store the context menu in m_pCM and keep it in order to invoke the selected command later on */
1128 HRESULT hr
= GetItemObject(SVGIO_SELECTION
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1129 if (FAILED_UNEXPECTEDLY(hr
))
1132 HMENU hmenu
= CreatePopupMenu();
1134 hr
= m_pCM
->QueryContextMenu(hmenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, 0);
1135 if (FAILED_UNEXPECTEDLY(hr
))
1138 // TODO: filter or something
1140 Shell_MergeMenus(hFileMenu
, hmenu
, 0, 0, 0xFFFF, MM_ADDSEPARATOR
| MM_SUBMENUSHAVEIDS
);
1142 ::DestroyMenu(hmenu
);
1147 HRESULT
CDefView::FillEditMenu()
1149 HMENU hEditMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_EDIT
);
1153 HMENU hmenuContents
= ::LoadMenuW(shell32_hInstance
, L
"MENU_003");
1157 Shell_MergeMenus(hEditMenu
, hmenuContents
, 0, 0, 0xFFFF, 0);
1159 ::DestroyMenu(hmenuContents
);
1164 HRESULT
CDefView::FillViewMenu()
1166 HMENU hViewMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_VIEW
);
1170 m_hMenuViewModes
= ::LoadMenuW(shell32_hInstance
, L
"MENU_001");
1171 if (!m_hMenuViewModes
)
1174 UINT i
= SHMenuIndexFromID(hViewMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
);
1175 Shell_MergeMenus(hViewMenu
, m_hMenuViewModes
, i
, 0, 0xFFFF, MM_ADDSEPARATOR
| MM_DONTREMOVESEPS
| MM_SUBMENUSHAVEIDS
);
1180 HRESULT
CDefView::FillArrangeAsMenu(HMENU hmenuArrange
)
1182 /* We only need to fill this once */
1183 if (GetMenuItemID(hmenuArrange
, 0) == FCIDM_SHVIEW_AUTOARRANGE
)
1185 Shell_MergeMenus(hmenuArrange
, m_hMenuArrangeModes
, 0, 0, 0xFFFF,0);
1188 /* Also check the menu item according to which we sort */
1189 CheckMenuRadioItem(hmenuArrange
,
1192 m_sortInfo
.nHeaderID
+ 0x30,
1198 HRESULT
CDefView::CheckViewMode(HMENU hmenuView
)
1200 if (m_FolderSettings
.ViewMode
>= FVM_FIRST
&& m_FolderSettings
.ViewMode
<= FVM_LAST
)
1202 UINT iItemFirst
= FCIDM_SHVIEW_BIGICON
;
1203 UINT iItemLast
= iItemFirst
+ FVM_LAST
- FVM_FIRST
;
1204 UINT iItem
= iItemFirst
+ m_FolderSettings
.ViewMode
- FVM_FIRST
;
1205 CheckMenuRadioItem(hmenuView
, iItemFirst
, iItemLast
, iItem
, MF_BYCOMMAND
);
1211 /**********************************************************
1212 * ShellView_GetSelections()
1214 * - fills the m_apidl list with the selected objects
1217 * number of selected items
1219 UINT
CDefView::GetSelections()
1223 m_cidl
= m_ListView
.GetSelectedCount();
1224 m_apidl
= static_cast<PCUITEMID_CHILD
*>(SHAlloc(m_cidl
* sizeof(PCUITEMID_CHILD
)));
1231 TRACE("-- Items selected =%u\n", m_cidl
);
1235 while ((lvIndex
= m_ListView
.GetNextItem(lvIndex
, LVNI_SELECTED
)) > -1)
1237 m_apidl
[i
] = _PidlByItem(lvIndex
);
1241 TRACE("-- selected Item found\n");
1247 HRESULT
CDefView::InvokeContextMenuCommand(UINT uCommand
)
1249 CMINVOKECOMMANDINFO cmi
;
1251 ZeroMemory(&cmi
, sizeof(cmi
));
1252 cmi
.cbSize
= sizeof(cmi
);
1253 cmi
.lpVerb
= MAKEINTRESOURCEA(uCommand
);
1256 if (GetKeyState(VK_SHIFT
) & 0x8000)
1257 cmi
.fMask
|= CMIC_MASK_SHIFT_DOWN
;
1259 if (GetKeyState(VK_CONTROL
) & 0x8000)
1260 cmi
.fMask
|= CMIC_MASK_CONTROL_DOWN
;
1262 HRESULT hr
= m_pCM
->InvokeCommand(&cmi
);
1263 if (FAILED_UNEXPECTEDLY(hr
))
1269 /**********************************************************
1270 * ShellView_OpenSelectedItems()
1272 HRESULT
CDefView::OpenSelectedItems()
1278 m_cidl
= m_ListView
.GetSelectedCount();
1282 hResult
= OnDefaultCommand();
1283 if (hResult
== S_OK
)
1286 hMenu
= CreatePopupMenu();
1290 hResult
= GetItemObject(SVGIO_SELECTION
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1291 if (FAILED_UNEXPECTEDLY(hResult
))
1294 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_DEFAULTONLY
);
1295 if (FAILED_UNEXPECTEDLY(hResult
))
1298 uCommand
= GetMenuDefaultItem(hMenu
, FALSE
, 0);
1299 if (uCommand
== (UINT
)-1)
1305 InvokeContextMenuCommand(uCommand
);
1314 IUnknown_SetSite(m_pCM
, NULL
);
1321 /**********************************************************
1322 * ShellView_DoContextMenu()
1324 LRESULT
CDefView::OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1333 TRACE("(%p)->(0x%08x 0x%08x) stub\n", this, x
, y
);
1335 m_hContextMenu
= CreatePopupMenu();
1336 if (!m_hContextMenu
)
1339 m_cidl
= m_ListView
.GetSelectedCount();
1341 hResult
= GetItemObject( m_cidl
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1342 if (FAILED_UNEXPECTEDLY(hResult
))
1345 /* Use 1 as the first id as we want 0 the mean that the user canceled the menu */
1346 hResult
= m_pCM
->QueryContextMenu(m_hContextMenu
, 0, CONTEXT_MENU_BASE_ID
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1347 if (FAILED_UNEXPECTEDLY(hResult
))
1350 uCommand
= TrackPopupMenu(m_hContextMenu
,
1351 TPM_LEFTALIGN
| TPM_RETURNCMD
| TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
,
1352 x
, y
, 0, m_hWnd
, NULL
);
1356 if (uCommand
== FCIDM_SHVIEW_OPEN
&& OnDefaultCommand() == S_OK
)
1359 InvokeContextMenuCommand(uCommand
- CONTEXT_MENU_BASE_ID
);
1364 IUnknown_SetSite(m_pCM
, NULL
);
1370 DestroyMenu(m_hContextMenu
);
1371 m_hContextMenu
= NULL
;
1377 LRESULT
CDefView::OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
)
1382 hMenu
= CreatePopupMenu();
1386 hResult
= GetItemObject( bUseSelection
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1387 if (FAILED_UNEXPECTEDLY( hResult
))
1390 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1391 if (FAILED_UNEXPECTEDLY( hResult
))
1394 InvokeContextMenuCommand(uCommand
);
1399 IUnknown_SetSite(m_pCM
, NULL
);
1409 /**********************************************************
1410 * ##### message handling #####
1413 /**********************************************************
1414 * ShellView_OnSize()
1416 LRESULT
CDefView::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1418 WORD wWidth
, wHeight
;
1420 wWidth
= LOWORD(lParam
);
1421 wHeight
= HIWORD(lParam
);
1423 TRACE("%p width=%u height=%u\n", this, wWidth
, wHeight
);
1425 /* Resize the ListView to fit our window */
1428 ::MoveWindow(m_ListView
, 0, 0, wWidth
, wHeight
, TRUE
);
1431 _DoFolderViewCB(SFVM_SIZE
, 0, 0);
1436 /**********************************************************
1437 * ShellView_OnDeactivate()
1442 void CDefView::OnDeactivate()
1444 TRACE("%p\n", this);
1446 if (m_uState
!= SVUIA_DEACTIVATE
)
1448 // TODO: cleanup menu after deactivation
1450 m_uState
= SVUIA_DEACTIVATE
;
1454 void CDefView::DoActivate(UINT uState
)
1456 TRACE("%p uState=%x\n", this, uState
);
1458 /*don't do anything if the state isn't really changing */
1459 if (m_uState
== uState
)
1464 if (uState
== SVUIA_DEACTIVATE
)
1470 if(m_hMenu
&& !m_bmenuBarInitialized
)
1474 m_pShellBrowser
->SetMenuSB(m_hMenu
, 0, m_hWnd
);
1475 m_bmenuBarInitialized
= TRUE
;
1478 if (SVUIA_ACTIVATE_FOCUS
== uState
)
1480 m_ListView
.SetFocus();
1488 /**********************************************************
1489 * ShellView_OnActivate()
1491 LRESULT
CDefView::OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1493 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1497 /**********************************************************
1498 * ShellView_OnSetFocus()
1501 LRESULT
CDefView::OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1503 TRACE("%p\n", this);
1505 /* Tell the browser one of our windows has received the focus. This
1506 should always be done before merging menus (OnActivate merges the
1507 menus) if one of our windows has the focus.*/
1509 m_pShellBrowser
->OnViewWindowActive(this);
1510 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1512 /* Set the focus to the listview */
1513 m_ListView
.SetFocus();
1515 /* Notify the ICommDlgBrowser interface */
1516 OnStateChange(CDBOSC_SETFOCUS
);
1521 /**********************************************************
1522 * ShellView_OnKillFocus()
1524 LRESULT
CDefView::OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1526 TRACE("(%p) stub\n", this);
1528 DoActivate(SVUIA_ACTIVATE_NOFOCUS
);
1529 /* Notify the ICommDlgBrowser */
1530 OnStateChange(CDBOSC_KILLFOCUS
);
1535 /**********************************************************
1536 * ShellView_OnCommand()
1539 * the CmdID's are the ones from the context menu
1541 LRESULT
CDefView::OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1548 dwCmdID
= GET_WM_COMMAND_ID(wParam
, lParam
);
1549 dwCmd
= GET_WM_COMMAND_CMD(wParam
, lParam
);
1550 hwndCmd
= GET_WM_COMMAND_HWND(wParam
, lParam
);
1552 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n", this, dwCmdID
, dwCmd
, hwndCmd
);
1556 case FCIDM_SHVIEW_SMALLICON
:
1557 m_FolderSettings
.ViewMode
= FVM_SMALLICON
;
1558 SetStyle (LVS_SMALLICON
, LVS_TYPEMASK
);
1562 case FCIDM_SHVIEW_BIGICON
:
1563 m_FolderSettings
.ViewMode
= FVM_ICON
;
1564 SetStyle (LVS_ICON
, LVS_TYPEMASK
);
1568 case FCIDM_SHVIEW_LISTVIEW
:
1569 m_FolderSettings
.ViewMode
= FVM_LIST
;
1570 SetStyle (LVS_LIST
, LVS_TYPEMASK
);
1574 case FCIDM_SHVIEW_REPORTVIEW
:
1575 m_FolderSettings
.ViewMode
= FVM_DETAILS
;
1576 SetStyle (LVS_REPORT
, LVS_TYPEMASK
);
1580 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1585 m_sortInfo
.nHeaderID
= dwCmdID
- 0x30;
1586 m_sortInfo
.bIsAscending
= TRUE
;
1590 case FCIDM_SHVIEW_SNAPTOGRID
:
1591 case FCIDM_SHVIEW_AUTOARRANGE
:
1594 case FCIDM_SHVIEW_SELECTALL
:
1595 m_ListView
.SetItemState(-1, LVIS_SELECTED
, LVIS_SELECTED
);
1598 case FCIDM_SHVIEW_INVERTSELECTION
:
1599 nCount
= m_ListView
.GetItemCount();
1600 for (int i
=0; i
< nCount
; i
++)
1601 m_ListView
.SetItemState(i
, m_ListView
.GetItemState(i
, LVIS_SELECTED
) ? 0 : LVIS_SELECTED
, LVIS_SELECTED
);
1604 case FCIDM_SHVIEW_REFRESH
:
1608 case FCIDM_SHVIEW_DELETE
:
1609 case FCIDM_SHVIEW_CUT
:
1610 case FCIDM_SHVIEW_COPY
:
1611 case FCIDM_SHVIEW_RENAME
:
1612 case FCIDM_SHVIEW_PROPERTIES
:
1613 return OnExplorerCommand(dwCmdID
, TRUE
);
1615 case FCIDM_SHVIEW_INSERT
:
1616 case FCIDM_SHVIEW_UNDO
:
1617 case FCIDM_SHVIEW_INSERTLINK
:
1618 case FCIDM_SHVIEW_NEWFOLDER
:
1619 return OnExplorerCommand(dwCmdID
, FALSE
);
1621 /* WM_COMMAND messages from the file menu are routed to the CDefView so as to let m_pCM handle the command */
1622 if (m_pCM
&& dwCmd
== 0)
1624 InvokeContextMenuCommand(dwCmdID
);
1631 /**********************************************************
1632 * ShellView_OnNotify()
1635 LRESULT
CDefView::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1639 LPNMLISTVIEW lpnmlv
;
1640 NMLVDISPINFOW
*lpdi
;
1641 PCUITEMID_CHILD pidl
;
1645 lpnmh
= (LPNMHDR
)lParam
;
1646 lpnmlv
= (LPNMLISTVIEW
)lpnmh
;
1647 lpdi
= (NMLVDISPINFOW
*)lpnmh
;
1649 TRACE("%p CtlID=%u lpnmh->code=%x\n", this, CtlID
, lpnmh
->code
);
1651 switch (lpnmh
->code
)
1654 TRACE("-- NM_SETFOCUS %p\n", this);
1655 OnSetFocus(0, 0, 0, unused
);
1659 TRACE("-- NM_KILLFOCUS %p\n", this);
1661 /* Notify the ICommDlgBrowser interface */
1662 OnStateChange(CDBOSC_KILLFOCUS
);
1666 TRACE("-- NM_CUSTOMDRAW %p\n", this);
1667 return CDRF_DODEFAULT
;
1669 case NM_RELEASEDCAPTURE
:
1670 TRACE("-- NM_RELEASEDCAPTURE %p\n", this);
1674 TRACE("-- NM_CLICK %p\n", this);
1678 TRACE("-- NM_RCLICK %p\n", this);
1682 TRACE("-- NM_DBLCLK %p\n", this);
1683 OpenSelectedItems();
1687 TRACE("-- NM_RETURN %p\n", this);
1688 OpenSelectedItems();
1692 TRACE("-- HDN_ENDTRACKW %p\n", this);
1693 /*nColumn1 = m_ListView.GetColumnWidth(0);
1694 nColumn2 = m_ListView.GetColumnWidth(1);*/
1697 case LVN_DELETEITEM
:
1698 TRACE("-- LVN_DELETEITEM %p\n", this);
1700 /*delete the pidl because we made a copy of it*/
1701 SHFree(reinterpret_cast<LPVOID
>(lpnmlv
->lParam
));
1705 case LVN_DELETEALLITEMS
:
1706 TRACE("-- LVN_DELETEALLITEMS %p\n", this);
1709 case LVN_INSERTITEM
:
1710 TRACE("-- LVN_INSERTITEM (STUB)%p\n", this);
1713 case LVN_ITEMACTIVATE
:
1714 TRACE("-- LVN_ITEMACTIVATE %p\n", this);
1715 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1718 case LVN_COLUMNCLICK
:
1719 m_sortInfo
.nHeaderID
= lpnmlv
->iSubItem
;
1720 if (m_sortInfo
.nLastHeaderID
== m_sortInfo
.nHeaderID
)
1721 m_sortInfo
.bIsAscending
= !m_sortInfo
.bIsAscending
;
1723 m_sortInfo
.bIsAscending
= TRUE
;
1727 case LVN_GETDISPINFOA
:
1728 case LVN_GETDISPINFOW
:
1729 TRACE("-- LVN_GETDISPINFO %p\n", this);
1730 pidl
= _PidlByItem(lpdi
->item
);
1732 if (lpdi
->item
.mask
& LVIF_TEXT
) /* text requested */
1737 if (FAILED_UNEXPECTEDLY(m_pSF2Parent
->GetDetailsOf(pidl
, lpdi
->item
.iSubItem
, &sd
)))
1740 if (lpnmh
->code
== LVN_GETDISPINFOA
)
1742 /* shouldn't happen */
1743 NMLVDISPINFOA
*lpdiA
= (NMLVDISPINFOA
*)lpnmh
;
1744 StrRetToStrNA( lpdiA
->item
.pszText
, lpdiA
->item
.cchTextMax
, &sd
.str
, NULL
);
1745 TRACE("-- text=%s\n", lpdiA
->item
.pszText
);
1747 else /* LVN_GETDISPINFOW */
1749 StrRetToStrNW( lpdi
->item
.pszText
, lpdi
->item
.cchTextMax
, &sd
.str
, NULL
);
1750 TRACE("-- text=%s\n", debugstr_w(lpdi
->item
.pszText
));
1755 FIXME("no m_pSF2Parent\n");
1758 if(lpdi
->item
.mask
& LVIF_IMAGE
) /* image requested */
1760 lpdi
->item
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
1762 if(lpdi
->item
.mask
& LVIF_STATE
)
1764 ULONG attributes
= SFGAO_HIDDEN
;
1765 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(1, &pidl
, &attributes
)))
1767 if (attributes
& SFGAO_HIDDEN
)
1769 lpdi
->item
.state
|= LVIS_CUT
;
1773 lpdi
->item
.mask
|= LVIF_DI_SETITEM
;
1776 case LVN_ITEMCHANGED
:
1777 TRACE("-- LVN_ITEMCHANGED %p\n", this);
1778 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1780 _DoFolderViewCB(SFVM_SELECTIONCHANGED
, NULL
/* FIXME */, NULL
/* FIXME */);
1784 case LVN_BEGINRDRAG
:
1785 TRACE("-- LVN_BEGINDRAG\n");
1787 if (GetSelections())
1789 CComPtr
<IDataObject
> pda
;
1790 DWORD dwAttributes
= SFGAO_CANCOPY
| SFGAO_CANLINK
;
1791 DWORD dwEffect
= DROPEFFECT_MOVE
;
1793 if (SUCCEEDED(m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, IID_NULL_PPV_ARG(IDataObject
, &pda
))))
1795 LPNMLISTVIEW params
= (LPNMLISTVIEW
)lParam
;
1797 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(m_cidl
, m_apidl
, &dwAttributes
)))
1799 dwEffect
|= dwAttributes
& (SFGAO_CANCOPY
| SFGAO_CANLINK
);
1802 CComPtr
<IAsyncOperation
> piaso
;
1803 if (SUCCEEDED(pda
->QueryInterface(IID_PPV_ARG(IAsyncOperation
, &piaso
))))
1805 piaso
->SetAsyncMode(TRUE
);
1810 m_pSourceDataObject
= pda
;
1811 m_ptFirstMousePos
= params
->ptAction
;
1812 ClientToScreen(&m_ptFirstMousePos
);
1814 HIMAGELIST big_icons
, small_icons
;
1815 Shell_GetImageLists(&big_icons
, &small_icons
);
1816 PCUITEMID_CHILD pidl
= _PidlByItem(params
->iItem
);
1817 int iIcon
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
1819 m_ListView
.GetItemPosition(params
->iItem
, &ptItem
);
1821 ImageList_BeginDrag(big_icons
, iIcon
, params
->ptAction
.x
- ptItem
.x
, params
->ptAction
.y
- ptItem
.y
);
1823 DoDragDrop(pda
, this, dwEffect
, &dwEffect2
);
1825 m_pSourceDataObject
.Release();
1830 case LVN_BEGINLABELEDITW
:
1832 DWORD dwAttr
= SFGAO_CANRENAME
;
1833 pidl
= _PidlByItem(lpdi
->item
);
1835 TRACE("-- LVN_BEGINLABELEDITW %p\n", this);
1837 m_pSFParent
->GetAttributesOf(1, &pidl
, &dwAttr
);
1838 if (SFGAO_CANRENAME
& dwAttr
)
1846 case LVN_ENDLABELEDITW
:
1848 TRACE("-- LVN_ENDLABELEDITW %p\n", this);
1850 m_isEditing
= FALSE
;
1852 if (lpdi
->item
.pszText
)
1857 pidl
= _PidlByItem(lpdi
->item
);
1858 PITEMID_CHILD pidlNew
;
1859 hr
= m_pSFParent
->SetNameOf(0, pidl
, lpdi
->item
.pszText
, SHGDN_INFOLDER
, &pidlNew
);
1861 if (SUCCEEDED(hr
) && pidlNew
)
1863 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
1864 lvItem
.iItem
= lpdi
->item
.iItem
;
1865 lvItem
.iSubItem
= 0;
1866 lvItem
.lParam
= reinterpret_cast<LPARAM
>(pidlNew
);
1867 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
1868 m_ListView
.SetItem(&lvItem
);
1869 m_ListView
.Update(lpdi
->item
.iItem
);
1878 TRACE("-- %p WM_COMMAND %x unhandled\n", this, lpnmh
->code
);
1886 * This is just a quick hack to make the desktop work correctly.
1887 * ITranslateShellChangeNotify's IsChildID is undocumented, but most likely the way that
1888 * a folder should know if it should update upon a change notification.
1889 * It is exported by merged folders at a minimum.
1891 static BOOL
ILIsParentOrSpecialParent(PCIDLIST_ABSOLUTE pidl1
, PCIDLIST_ABSOLUTE pidl2
)
1893 if (!pidl1
|| !pidl2
)
1895 if (ILIsParent(pidl1
, pidl2
, TRUE
))
1898 if (_ILIsDesktop(pidl1
))
1900 PIDLIST_ABSOLUTE deskpidl
;
1901 SHGetFolderLocation(NULL
, CSIDL_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
1902 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
1908 SHGetFolderLocation(NULL
, CSIDL_COMMON_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
1909 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
1919 /**********************************************************
1920 * ShellView_OnChange()
1922 LRESULT
CDefView::OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1924 PCIDLIST_ABSOLUTE
*Pidls
= reinterpret_cast<PCIDLIST_ABSOLUTE
*>(wParam
);
1925 BOOL bParent0
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[0]);
1926 BOOL bParent1
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[1]);
1928 TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls
[0], Pidls
[1], lParam
);
1930 switch (lParam
&~ SHCNE_INTERRUPT
)
1936 if (LV_FindItemByPidl(ILFindLastID(Pidls
[0])) == -1)
1938 LV_AddItem(ILFindLastID(Pidls
[0]));
1942 LV_ProdItem(ILFindLastID(Pidls
[0]));
1950 LV_DeleteItem(ILFindLastID(Pidls
[0]));
1953 case SHCNE_RENAMEFOLDER
:
1954 case SHCNE_RENAMEITEM
:
1955 if (bParent0
&& bParent1
)
1956 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[1]));
1958 LV_DeleteItem(ILFindLastID(Pidls
[0]));
1960 LV_AddItem(ILFindLastID(Pidls
[1]));
1963 case SHCNE_UPDATEITEM
:
1965 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[0]));
1968 case SHCNE_UPDATEDIR
:
1975 HRESULT
SHGetMenuIdFromMenuMsg(UINT uMsg
, LPARAM lParam
, UINT
*CmdId
);
1976 HRESULT
SHSetMenuIdInMenuMsg(UINT uMsg
, LPARAM lParam
, UINT CmdId
);
1978 /**********************************************************
1979 * CDefView::OnCustomItem
1981 LRESULT
CDefView::OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1986 ERR("no menu!!!\n");
1990 /* The lParam of WM_DRAWITEM WM_MEASUREITEM contain a menu id and this also needs to
1991 be changed to a menu identifier offset */
1993 HRESULT hres
= SHGetMenuIdFromMenuMsg(uMsg
, lParam
, &CmdID
);
1994 if (SUCCEEDED(hres
))
1995 SHSetMenuIdInMenuMsg(uMsg
, lParam
, CmdID
- CONTEXT_MENU_BASE_ID
);
1997 /* Forward the message to the IContextMenu2 */
1999 hres
= SHForwardContextMenuMsg(m_pCM
, uMsg
, wParam
, lParam
, &result
, TRUE
);
2001 return (SUCCEEDED(hres
));
2004 LRESULT
CDefView::OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
2006 /* Wallpaper setting affects drop shadows effect */
2007 if (wParam
== SPI_SETDESKWALLPAPER
|| wParam
== 0)
2013 /**********************************************************
2014 * CDefView::OnInitMenuPopup
2016 LRESULT
CDefView::OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
2018 HMENU hmenu
= (HMENU
) wParam
;
2019 int nPos
= LOWORD(lParam
);
2022 OnCustomItem(uMsg
, wParam
, lParam
, bHandled
);
2024 HMENU hViewMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_VIEW
);
2026 /* Lets try to find out what the hell wParam is */
2027 if (hmenu
== GetSubMenu(m_hMenu
, nPos
))
2028 menuItemId
= ReallyGetMenuItemID(m_hMenu
, nPos
);
2029 else if (hViewMenu
&& hmenu
== GetSubMenu(hViewMenu
, nPos
))
2030 menuItemId
= ReallyGetMenuItemID(hViewMenu
, nPos
);
2031 else if (m_hContextMenu
&& hmenu
== GetSubMenu(m_hContextMenu
, nPos
))
2032 menuItemId
= ReallyGetMenuItemID(m_hContextMenu
, nPos
);
2038 case FCIDM_MENU_FILE
:
2041 case FCIDM_MENU_VIEW
:
2042 case FCIDM_SHVIEW_VIEW
:
2043 CheckViewMode(hmenu
);
2045 case FCIDM_SHVIEW_ARRANGE
:
2046 FillArrangeAsMenu(hmenu
);
2053 /**********************************************************
2056 * The INTERFACE of the IShellView object
2059 **********************************************************
2062 /**********************************************************
2063 * ShellView_GetWindow
2065 HRESULT WINAPI
CDefView::GetWindow(HWND
*phWnd
)
2067 TRACE("(%p)\n", this);
2074 HRESULT WINAPI
CDefView::ContextSensitiveHelp(BOOL fEnterMode
)
2076 FIXME("(%p) stub\n", this);
2081 /**********************************************************
2082 * IShellView_TranslateAccelerator
2085 * use the accel functions
2087 HRESULT WINAPI
CDefView::TranslateAccelerator(LPMSG lpmsg
)
2092 if (lpmsg
->message
>= WM_KEYFIRST
&& lpmsg
->message
<= WM_KEYLAST
)
2094 if (::TranslateAcceleratorW(m_hWnd
, m_hAccel
, lpmsg
) != 0)
2097 TRACE("-- key=0x%04lx\n", lpmsg
->wParam
) ;
2100 return m_pShellBrowser
->TranslateAcceleratorSB(lpmsg
, 0);
2103 HRESULT WINAPI
CDefView::EnableModeless(BOOL fEnable
)
2105 FIXME("(%p) stub\n", this);
2110 HRESULT WINAPI
CDefView::UIActivate(UINT uState
)
2112 // CHAR szName[MAX_PATH];
2114 int nPartArray
[1] = { -1};
2116 TRACE("(%p)->(state=%x) stub\n", this, uState
);
2118 /* don't do anything if the state isn't really changing */
2119 if (m_uState
== uState
)
2124 /* OnActivate handles the menu merging and internal state */
2127 /* only do This if we are active */
2128 if (uState
!= SVUIA_DEACTIVATE
)
2132 GetFolderPath is not a method of IShellFolder
2133 IShellFolder_GetFolderPath( m_pSFParent, szName, sizeof(szName) );
2135 /* set the number of parts */
2136 m_pShellBrowser
->SendControlMsg(FCW_STATUS
, SB_SETPARTS
, 1, (LPARAM
)nPartArray
, &lResult
);
2138 /* set the text for the parts */
2140 m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXTA, 0, (LPARAM)szName, &lResult);
2147 HRESULT WINAPI
CDefView::Refresh()
2149 TRACE("(%p)\n", this);
2151 m_ListView
.DeleteAllItems();
2157 HRESULT WINAPI
CDefView::CreateViewWindow(IShellView
*lpPrevView
, LPCFOLDERSETTINGS lpfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
)
2159 return CreateViewWindow3(psb
, lpPrevView
, SV3CVW3_DEFAULT
,
2160 (FOLDERFLAGS
)lpfs
->fFlags
, (FOLDERFLAGS
)lpfs
->fFlags
, (FOLDERVIEWMODE
)lpfs
->ViewMode
, NULL
, prcView
, phWnd
);
2163 HRESULT WINAPI
CDefView::DestroyViewWindow()
2165 TRACE("(%p)\n", this);
2167 /* Make absolutely sure all our UI is cleaned up */
2168 UIActivate(SVUIA_DEACTIVATE
);
2172 // "Accelerator tables loaded from resources are freed automatically when the application terminates." -- MSDN
2176 if (m_hMenuArrangeModes
)
2178 DestroyMenu(m_hMenuArrangeModes
);
2179 m_hMenuArrangeModes
= NULL
;
2182 if (m_hMenuViewModes
)
2184 DestroyMenu(m_hMenuViewModes
);
2185 m_hMenuViewModes
= NULL
;
2190 DestroyMenu(m_hMenu
);
2196 m_ListView
.DestroyWindow();
2204 m_pShellBrowser
.Release();
2205 m_pCommDlgBrowser
.Release();
2210 HRESULT WINAPI
CDefView::GetCurrentInfo(LPFOLDERSETTINGS lpfs
)
2212 TRACE("(%p)->(%p) vmode=%x flags=%x\n", this, lpfs
,
2213 m_FolderSettings
.ViewMode
, m_FolderSettings
.fFlags
);
2216 return E_INVALIDARG
;
2218 *lpfs
= m_FolderSettings
;
2222 HRESULT WINAPI
CDefView::AddPropertySheetPages(DWORD dwReserved
, LPFNADDPROPSHEETPAGE lpfn
, LPARAM lparam
)
2224 FIXME("(%p) stub\n", this);
2229 HRESULT WINAPI
CDefView::SaveViewState()
2231 FIXME("(%p) stub\n", this);
2236 HRESULT WINAPI
CDefView::SelectItem(PCUITEMID_CHILD pidl
, UINT uFlags
)
2240 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n", this, pidl
, uFlags
);
2242 i
= LV_FindItemByPidl(pidl
);
2246 if(uFlags
& SVSI_ENSUREVISIBLE
)
2247 m_ListView
.EnsureVisible(i
, FALSE
);
2249 LVITEMW lvItem
= {0};
2250 lvItem
.mask
= LVIF_STATE
;
2251 lvItem
.stateMask
= LVIS_SELECTED
| LVIS_FOCUSED
;
2253 while (m_ListView
.GetItem(&lvItem
))
2255 if (lvItem
.iItem
== i
)
2257 if (uFlags
& SVSI_SELECT
)
2258 lvItem
.state
|= LVIS_SELECTED
;
2260 lvItem
.state
&= ~LVIS_SELECTED
;
2262 if (uFlags
& SVSI_FOCUSED
)
2263 lvItem
.state
&= ~LVIS_FOCUSED
;
2267 if (uFlags
& SVSI_DESELECTOTHERS
)
2268 lvItem
.state
&= ~LVIS_SELECTED
;
2271 m_ListView
.SetItem(&lvItem
);
2275 if((uFlags
& SVSI_EDIT
) == SVSI_EDIT
)
2276 m_ListView
.EditLabel(i
);
2281 HRESULT WINAPI
CDefView::GetItemObject(UINT uItem
, REFIID riid
, LPVOID
*ppvOut
)
2283 HRESULT hr
= E_NOINTERFACE
;
2285 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n", this, uItem
, debugstr_guid(&riid
), ppvOut
);
2291 case SVGIO_BACKGROUND
:
2292 if (IsEqualIID(riid
, IID_IContextMenu
))
2297 hr
= CDefViewBckgrndMenu_CreateInstance(m_pSF2Parent
, riid
, ppvOut
);
2298 if (FAILED_UNEXPECTEDLY(hr
))
2301 IUnknown_SetSite(*((IUnknown
**)ppvOut
), (IShellView
*)this);
2303 else if (IsEqualIID(riid
, IID_IDispatch
))
2305 if (m_pShellFolderViewDual
== NULL
)
2307 hr
= CDefViewDual_Constructor(riid
, (LPVOID
*)&m_pShellFolderViewDual
);
2308 if (FAILED_UNEXPECTEDLY(hr
))
2311 hr
= m_pShellFolderViewDual
->QueryInterface(riid
, ppvOut
);
2315 case SVGIO_SELECTION
:
2317 hr
= m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, riid
, 0, ppvOut
);
2318 if (FAILED_UNEXPECTEDLY(hr
))
2321 if (IsEqualIID(riid
, IID_IContextMenu
))
2322 IUnknown_SetSite(*((IUnknown
**)ppvOut
), (IShellView
*)this);
2327 TRACE("-- (%p)->(interface=%p)\n", this, *ppvOut
);
2332 HRESULT STDMETHODCALLTYPE
CDefView::GetCurrentViewMode(UINT
*pViewMode
)
2334 TRACE("(%p)->(%p), stub\n", this, pViewMode
);
2337 return E_INVALIDARG
;
2339 *pViewMode
= m_FolderSettings
.ViewMode
;
2343 HRESULT STDMETHODCALLTYPE
CDefView::SetCurrentViewMode(UINT ViewMode
)
2346 TRACE("(%p)->(%u), stub\n", this, ViewMode
);
2348 /* It's not redundant to check FVM_AUTO because it's a (UINT)-1 */
2349 if (((INT
)ViewMode
< FVM_FIRST
|| (INT
)ViewMode
> FVM_LAST
) && ((INT
)ViewMode
!= FVM_AUTO
))
2350 return E_INVALIDARG
;
2352 /* Windows before Vista uses LVM_SETVIEW and possibly
2353 LVM_SETEXTENDEDLISTVIEWSTYLE to set the style of the listview,
2354 while later versions seem to accomplish this through other
2362 dwStyle
= LVS_REPORT
;
2365 dwStyle
= LVS_SMALLICON
;
2372 FIXME("ViewMode %d not implemented\n", ViewMode
);
2378 SetStyle(dwStyle
, LVS_TYPEMASK
);
2380 /* This will not necessarily be the actual mode set above.
2381 This mimics the behavior of Windows XP. */
2382 m_FolderSettings
.ViewMode
= ViewMode
;
2387 HRESULT STDMETHODCALLTYPE
CDefView::GetFolder(REFIID riid
, void **ppv
)
2389 if (m_pSFParent
== NULL
)
2392 return m_pSFParent
->QueryInterface(riid
, ppv
);
2395 HRESULT STDMETHODCALLTYPE
CDefView::Item(int iItemIndex
, PITEMID_CHILD
*ppidl
)
2397 PCUITEMID_CHILD pidl
= _PidlByItem(iItemIndex
);
2400 *ppidl
= ILClone(pidl
);
2405 return E_INVALIDARG
;
2408 HRESULT STDMETHODCALLTYPE
CDefView::ItemCount(UINT uFlags
, int *pcItems
)
2410 TRACE("(%p)->(%u %p)\n", this, uFlags
, pcItems
);
2412 if (uFlags
!= SVGIO_ALLVIEW
)
2413 FIXME("some flags unsupported, %x\n", uFlags
& ~SVGIO_ALLVIEW
);
2415 *pcItems
= m_ListView
.GetItemCount();
2420 HRESULT STDMETHODCALLTYPE
CDefView::Items(UINT uFlags
, REFIID riid
, void **ppv
)
2425 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectionMarkedItem(int *piItem
)
2427 TRACE("(%p)->(%p)\n", this, piItem
);
2429 *piItem
= m_ListView
.GetSelectionMark();
2434 HRESULT STDMETHODCALLTYPE
CDefView::GetFocusedItem(int *piItem
)
2436 TRACE("(%p)->(%p)\n", this, piItem
);
2438 *piItem
= m_ListView
.GetNextItem(-1, LVNI_FOCUSED
);
2443 HRESULT STDMETHODCALLTYPE
CDefView::GetItemPosition(PCUITEMID_CHILD pidl
, POINT
*ppt
)
2445 int lvIndex
= LV_FindItemByPidl(pidl
);
2446 if (lvIndex
== -1 || ppt
== NULL
)
2447 return E_INVALIDARG
;
2449 m_ListView
.GetItemPosition(lvIndex
, ppt
);
2453 HRESULT STDMETHODCALLTYPE
CDefView::GetSpacing(POINT
*ppt
)
2455 TRACE("(%p)->(%p)\n", this, ppt
);
2463 m_ListView
.GetItemSpacing(spacing
);
2465 ppt
->x
= spacing
.cx
;
2466 ppt
->y
= spacing
.cy
;
2472 HRESULT STDMETHODCALLTYPE
CDefView::GetDefaultSpacing(POINT
*ppt
)
2477 HRESULT STDMETHODCALLTYPE
CDefView::GetAutoArrange()
2482 HRESULT STDMETHODCALLTYPE
CDefView::SelectItem(int iItem
, DWORD dwFlags
)
2486 TRACE("(%p)->(%d, %x)\n", this, iItem
, dwFlags
);
2489 lvItem
.stateMask
= LVIS_SELECTED
;
2491 if (dwFlags
& SVSI_ENSUREVISIBLE
)
2492 m_ListView
.EnsureVisible(iItem
, 0);
2495 if (dwFlags
& SVSI_DESELECTOTHERS
)
2496 m_ListView
.SetItemState(-1, 0, LVIS_SELECTED
);
2499 if (dwFlags
& SVSI_SELECT
)
2500 lvItem
.state
|= LVIS_SELECTED
;
2502 if (dwFlags
& SVSI_FOCUSED
)
2503 lvItem
.stateMask
|= LVIS_FOCUSED
;
2505 m_ListView
.SetItemState(iItem
, lvItem
.state
, lvItem
.stateMask
);
2507 if ((dwFlags
& SVSI_EDIT
) == SVSI_EDIT
)
2508 m_ListView
.EditLabel(iItem
);
2513 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItems(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD dwFlags
)
2515 /* Reset the selection */
2516 m_ListView
.SetItemState(-1, 0, LVIS_SELECTED
);
2519 for (UINT i
= 0 ; i
< m_cidl
; i
++)
2521 lvIndex
= LV_FindItemByPidl(apidl
[i
]);
2524 SelectItem(lvIndex
, dwFlags
);
2525 m_ListView
.SetItemPosition(lvIndex
, &apt
[i
]);
2532 /**********************************************************
2533 * IShellView2 implementation
2536 HRESULT STDMETHODCALLTYPE
CDefView::GetView(SHELLVIEWID
*view_guid
, ULONG view_type
)
2538 FIXME("(%p)->(%p, %lu) stub\n", this, view_guid
, view_type
);
2542 HRESULT STDMETHODCALLTYPE
CDefView::CreateViewWindow2(LPSV2CVW2_PARAMS view_params
)
2544 return CreateViewWindow3(view_params
->psbOwner
, view_params
->psvPrev
,
2545 SV3CVW3_DEFAULT
, (FOLDERFLAGS
)view_params
->pfs
->fFlags
, (FOLDERFLAGS
)view_params
->pfs
->fFlags
,
2546 (FOLDERVIEWMODE
)view_params
->pfs
->ViewMode
, view_params
->pvid
, view_params
->prcView
, &view_params
->hwndView
);
2549 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
)
2551 OLEMENUGROUPWIDTHS omw
= { { 0, 0, 0, 0, 0, 0 } };
2555 TRACE("(%p)->(shlview=%p shlbrs=%p rec=%p hwnd=%p vmode=%x flags=%x)\n", this, psvPrevious
, psb
, prcView
, hwnd
, mode
, flags
);
2556 if (prcView
!= NULL
)
2557 TRACE("-- left=%i top=%i right=%i bottom=%i\n", prcView
->left
, prcView
->top
, prcView
->right
, prcView
->bottom
);
2559 /* Validate the Shell Browser */
2560 if (psb
== NULL
|| m_hWnd
)
2561 return E_UNEXPECTED
;
2563 if (view_flags
!= SV3CVW3_DEFAULT
)
2564 FIXME("unsupported view flags 0x%08x\n", view_flags
);
2566 /* Set up the member variables */
2567 m_pShellBrowser
= psb
;
2568 m_FolderSettings
.ViewMode
= mode
;
2569 m_FolderSettings
.fFlags
= mask
& flags
;
2573 if (IsEqualIID(*view_id
, VID_LargeIcons
))
2574 m_FolderSettings
.ViewMode
= FVM_ICON
;
2575 else if (IsEqualIID(*view_id
, VID_SmallIcons
))
2576 m_FolderSettings
.ViewMode
= FVM_SMALLICON
;
2577 else if (IsEqualIID(*view_id
, VID_List
))
2578 m_FolderSettings
.ViewMode
= FVM_LIST
;
2579 else if (IsEqualIID(*view_id
, VID_Details
))
2580 m_FolderSettings
.ViewMode
= FVM_DETAILS
;
2581 else if (IsEqualIID(*view_id
, VID_Thumbnails
))
2582 m_FolderSettings
.ViewMode
= FVM_THUMBNAIL
;
2583 else if (IsEqualIID(*view_id
, VID_Tile
))
2584 m_FolderSettings
.ViewMode
= FVM_TILE
;
2585 else if (IsEqualIID(*view_id
, VID_ThumbStrip
))
2586 m_FolderSettings
.ViewMode
= FVM_THUMBSTRIP
;
2588 FIXME("Ignoring unrecognized VID %s\n", debugstr_guid(view_id
));
2591 /* Get our parent window */
2592 m_pShellBrowser
->GetWindow(&m_hWndParent
);
2594 /* Try to get the ICommDlgBrowserInterface, adds a reference !!! */
2595 m_pCommDlgBrowser
= NULL
;
2596 if (SUCCEEDED(m_pShellBrowser
->QueryInterface(IID_PPV_ARG(ICommDlgBrowser
, &m_pCommDlgBrowser
))))
2598 TRACE("-- CommDlgBrowser\n");
2601 Create(m_hWndParent
, prcView
, NULL
, WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
| WS_TABSTOP
, 0, 0U);
2612 _DoFolderViewCB(SFVM_WINDOWCREATED
, (WPARAM
)m_hWnd
, NULL
);
2614 SetWindowPos(HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_SHOWWINDOW
);
2619 m_hMenu
= CreateMenu();
2620 m_pShellBrowser
->InsertMenusSB(m_hMenu
, &omw
);
2621 TRACE("-- after fnInsertMenusSB\n");
2629 HRESULT STDMETHODCALLTYPE
CDefView::HandleRename(LPCITEMIDLIST new_pidl
)
2631 FIXME("(%p)->(%p) stub\n", this, new_pidl
);
2635 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItem(LPCITEMIDLIST item
, UINT flags
, POINT
*point
)
2637 FIXME("(%p)->(%p, %u, %p) stub\n", this, item
, flags
, point
);
2641 /**********************************************************
2642 * IShellFolderView implementation
2644 HRESULT STDMETHODCALLTYPE
CDefView::Rearrange(LPARAM sort
)
2646 FIXME("(%p)->(%ld) stub\n", this, sort
);
2650 HRESULT STDMETHODCALLTYPE
CDefView::GetArrangeParam(LPARAM
*sort
)
2652 FIXME("(%p)->(%p) stub\n", this, sort
);
2656 HRESULT STDMETHODCALLTYPE
CDefView::ArrangeGrid()
2658 FIXME("(%p) stub\n", this);
2662 HRESULT STDMETHODCALLTYPE
CDefView::AutoArrange()
2664 FIXME("(%p) stub\n", this);
2668 HRESULT STDMETHODCALLTYPE
CDefView::AddObject(PITEMID_CHILD pidl
, UINT
*item
)
2670 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2674 HRESULT STDMETHODCALLTYPE
CDefView::GetObject(PITEMID_CHILD
*pidl
, UINT item
)
2676 TRACE("(%p)->(%p %d)\n", this, pidl
, item
);
2677 return Item(item
, pidl
);
2680 HRESULT STDMETHODCALLTYPE
CDefView::RemoveObject(PITEMID_CHILD pidl
, UINT
*item
)
2683 TRACE("(%p)->(%p %p)\n", this, pidl
, item
);
2687 *item
= LV_FindItemByPidl(ILFindLastID(pidl
));
2688 m_ListView
.DeleteItem(*item
);
2693 m_ListView
.DeleteAllItems();
2699 HRESULT STDMETHODCALLTYPE
CDefView::GetObjectCount(UINT
*count
)
2701 TRACE("(%p)->(%p)\n", this, count
);
2702 *count
= m_ListView
.GetItemCount();
2706 HRESULT STDMETHODCALLTYPE
CDefView::SetObjectCount(UINT count
, UINT flags
)
2708 FIXME("(%p)->(%d %x) stub\n", this, count
, flags
);
2712 HRESULT STDMETHODCALLTYPE
CDefView::UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
)
2714 FIXME("(%p)->(%p %p %p) stub\n", this, pidl_old
, pidl_new
, item
);
2718 HRESULT STDMETHODCALLTYPE
CDefView::RefreshObject(PITEMID_CHILD pidl
, UINT
*item
)
2720 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2724 HRESULT STDMETHODCALLTYPE
CDefView::SetRedraw(BOOL redraw
)
2726 TRACE("(%p)->(%d)\n", this, redraw
);
2727 m_ListView
.SetRedraw(redraw
);
2731 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedCount(UINT
*count
)
2733 FIXME("(%p)->(%p) stub\n", this, count
);
2737 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
)
2739 TRACE("(%p)->(%p %p)\n", this, pidl
, items
);
2741 *items
= GetSelections();
2745 *pidl
= static_cast<PCUITEMID_CHILD
*>(LocalAlloc(0, *items
* sizeof(PCUITEMID_CHILD
)));
2748 return E_OUTOFMEMORY
;
2751 /* it's documented that caller shouldn't PIDLs, only array itself */
2752 memcpy(*pidl
, m_apidl
, *items
* sizeof(PCUITEMID_CHILD
));
2758 HRESULT STDMETHODCALLTYPE
CDefView::IsDropOnSource(IDropTarget
*drop_target
)
2760 if ((m_iDragOverItem
== -1 || m_pCurDropTarget
== NULL
) &&
2761 (m_pSourceDataObject
.p
))
2769 HRESULT STDMETHODCALLTYPE
CDefView::GetDragPoint(POINT
*pt
)
2772 return E_INVALIDARG
;
2774 *pt
= m_ptFirstMousePos
;
2778 HRESULT STDMETHODCALLTYPE
CDefView::GetDropPoint(POINT
*pt
)
2780 FIXME("(%p)->(%p) stub\n", this, pt
);
2784 HRESULT STDMETHODCALLTYPE
CDefView::MoveIcons(IDataObject
*obj
)
2786 TRACE("(%p)->(%p)\n", this, obj
);
2790 HRESULT STDMETHODCALLTYPE
CDefView::SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
)
2792 FIXME("(%p)->(%p %p) stub\n", this, pidl
, pt
);
2796 HRESULT STDMETHODCALLTYPE
CDefView::IsBkDropTarget(IDropTarget
*drop_target
)
2798 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2802 HRESULT STDMETHODCALLTYPE
CDefView::SetClipboard(BOOL move
)
2804 FIXME("(%p)->(%d) stub\n", this, move
);
2808 HRESULT STDMETHODCALLTYPE
CDefView::SetPoints(IDataObject
*obj
)
2810 FIXME("(%p)->(%p) stub\n", this, obj
);
2814 HRESULT STDMETHODCALLTYPE
CDefView::GetItemSpacing(ITEMSPACING
*spacing
)
2816 FIXME("(%p)->(%p) stub\n", this, spacing
);
2820 HRESULT STDMETHODCALLTYPE
CDefView::SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
)
2823 *old_cb
= m_pShellFolderViewCB
.Detach();
2825 m_pShellFolderViewCB
= new_cb
;
2829 HRESULT STDMETHODCALLTYPE
CDefView::Select(UINT flags
)
2831 FIXME("(%p)->(%d) stub\n", this, flags
);
2835 HRESULT STDMETHODCALLTYPE
CDefView::QuerySupport(UINT
*support
)
2837 TRACE("(%p)->(%p)\n", this, support
);
2841 HRESULT STDMETHODCALLTYPE
CDefView::SetAutomationObject(IDispatch
*disp
)
2843 FIXME("(%p)->(%p) stub\n", this, disp
);
2847 /**********************************************************
2848 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2850 HRESULT WINAPI
CDefView::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD
*prgCmds
, OLECMDTEXT
*pCmdText
)
2852 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
2853 this, pguidCmdGroup
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
2856 return E_INVALIDARG
;
2858 for (UINT i
= 0; i
< cCmds
; i
++)
2860 FIXME("\tprgCmds[%d].cmdID = %d\n", i
, prgCmds
[i
].cmdID
);
2861 prgCmds
[i
].cmdf
= 0;
2864 return OLECMDERR_E_UNKNOWNGROUP
;
2867 /**********************************************************
2868 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2870 * nCmdID is the OLECMDID_* enumeration
2872 HRESULT WINAPI
CDefView::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
2874 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2875 this, debugstr_guid(pguidCmdGroup
), nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2878 return OLECMDERR_E_UNKNOWNGROUP
;
2880 if (IsEqualCLSID(*pguidCmdGroup
, m_Category
))
2882 if (nCmdID
== FCIDM_SHVIEW_AUTOARRANGE
)
2884 if (V_VT(pvaIn
) != VT_INT_PTR
)
2885 return OLECMDERR_E_NOTSUPPORTED
;
2888 params
.cbSize
= sizeof(params
);
2889 params
.rcExclude
= *(RECT
*) V_INTREF(pvaIn
);
2891 if (m_hMenuViewModes
)
2893 /* Duplicate all but the last two items of the view modes menu */
2894 HMENU hmenuViewPopup
= CreatePopupMenu();
2895 Shell_MergeMenus(hmenuViewPopup
, m_hMenuViewModes
, 0, 0, 0xFFFF, 0);
2896 DeleteMenu(hmenuViewPopup
, GetMenuItemCount(hmenuViewPopup
) - 1, MF_BYPOSITION
);
2897 DeleteMenu(hmenuViewPopup
, GetMenuItemCount(hmenuViewPopup
) - 1, MF_BYPOSITION
);
2898 CheckViewMode(hmenuViewPopup
);
2899 TrackPopupMenuEx(hmenuViewPopup
, TPM_LEFTALIGN
| TPM_TOPALIGN
, params
.rcExclude
.left
, params
.rcExclude
.bottom
, m_hWndParent
, ¶ms
);
2900 ::DestroyMenu(hmenuViewPopup
);
2903 // pvaOut is VT_I4 with value 0x403 (cmd id of the new mode maybe?)
2904 V_VT(pvaOut
) = VT_I4
;
2905 V_I4(pvaOut
) = 0x403;
2909 if (IsEqualIID(*pguidCmdGroup
, CGID_Explorer
) &&
2911 (nCmdexecopt
== 4) && pvaOut
)
2914 if (IsEqualIID(*pguidCmdGroup
, CGID_ShellDocView
) &&
2919 return OLECMDERR_E_UNKNOWNGROUP
;
2922 /**********************************************************
2923 * ISVDropTarget implementation
2926 /******************************************************************************
2927 * drag_notify_subitem [Internal]
2929 * Figure out the shellfolder object, which is currently under the mouse cursor
2930 * and notify it via the IDropTarget interface.
2933 #define SCROLLAREAWIDTH 20
2935 HRESULT
CDefView::drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2941 /* The key state on drop doesn't have MK_LBUTTON or MK_RBUTTON because it
2942 reflects the key state after the user released the button, so we need
2943 to remember the last key state when the button was pressed */
2944 m_grfKeyState
= grfKeyState
;
2946 /* Map from global to client coordinates and query the index of the listview-item, which is
2947 * currently under the mouse cursor. */
2948 LVHITTESTINFO htinfo
= {{pt
.x
, pt
.y
}, LVHT_ONITEM
};
2949 ScreenToClient(&htinfo
.pt
);
2950 lResult
= m_ListView
.HitTest(&htinfo
);
2952 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2953 ::GetClientRect(m_ListView
, &clientRect
);
2954 if (htinfo
.pt
.x
== m_ptLastMousePos
.x
&& htinfo
.pt
.y
== m_ptLastMousePos
.y
&&
2955 (htinfo
.pt
.x
< SCROLLAREAWIDTH
|| htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
||
2956 htinfo
.pt
.y
< SCROLLAREAWIDTH
|| htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
))
2958 m_cScrollDelay
= (m_cScrollDelay
+ 1) % 5; /* DragOver is called every 50 ms */
2959 if (m_cScrollDelay
== 0)
2961 /* Mouse did hover another 250 ms over the scroll-area */
2962 if (htinfo
.pt
.x
< SCROLLAREAWIDTH
)
2963 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEUP
, 0);
2965 if (htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
)
2966 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEDOWN
, 0);
2968 if (htinfo
.pt
.y
< SCROLLAREAWIDTH
)
2969 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEUP
, 0);
2971 if (htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
)
2972 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEDOWN
, 0);
2977 m_cScrollDelay
= 0; /* Reset, if the cursor is not over the listview's scroll-area */
2980 m_ptLastMousePos
= htinfo
.pt
;
2982 /* We need to check if we drag the selection over itself */
2983 if (lResult
!= -1 && m_pSourceDataObject
.p
!= NULL
)
2985 PCUITEMID_CHILD pidl
= _PidlByItem(lResult
);
2987 for (UINT i
= 0; i
< m_cidl
; i
++)
2989 if (pidl
== m_apidl
[i
])
2991 /* The item that is being draged is hovering itself. */
2998 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2999 if (m_pCurDropTarget
&& lResult
== m_iDragOverItem
)
3000 return m_pCurDropTarget
->DragOver(grfKeyState
, pt
, pdwEffect
);
3002 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
3003 if (m_pCurDropTarget
)
3005 PCUITEMID_CHILD pidl
= _PidlByItem(m_iDragOverItem
);
3007 SelectItem(pidl
, 0);
3009 m_pCurDropTarget
->DragLeave();
3010 m_pCurDropTarget
.Release();
3013 m_iDragOverItem
= lResult
;
3017 /* We are not above one of the listview's subitems. Bind to the parent folder's
3018 * DropTarget interface. */
3019 hr
= m_pSFParent
->CreateViewObject(NULL
, IID_PPV_ARG(IDropTarget
,&m_pCurDropTarget
));
3023 /* Query the relative PIDL of the shellfolder object represented by the currently
3024 * dragged over listview-item ... */
3025 PCUITEMID_CHILD pidl
= _PidlByItem(lResult
);
3027 /* ... and bind m_pCurDropTarget to the IDropTarget interface of an UIObject of this object */
3028 hr
= m_pSFParent
->GetUIObjectOf(m_ListView
, 1, &pidl
, IID_NULL_PPV_ARG(IDropTarget
, &m_pCurDropTarget
));
3031 IUnknown_SetSite(m_pCurDropTarget
, (IShellView
*)this);
3033 /* If anything failed, m_pCurDropTarget should be NULL now, which ought to be a save state. */
3036 *pdwEffect
= DROPEFFECT_NONE
;
3040 if (m_iDragOverItem
!= -1)
3042 SelectItem(m_iDragOverItem
, SVSI_SELECT
);
3045 /* Notify the item just entered via DragEnter. */
3046 return m_pCurDropTarget
->DragEnter(m_pCurDataObject
, grfKeyState
, pt
, pdwEffect
);
3049 HRESULT WINAPI
CDefView::DragEnter(IDataObject
*pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
3051 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
3052 m_pCurDataObject
= pDataObject
;
3054 HRESULT hr
= drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
3057 POINT ptClient
= {pt
.x
, pt
.y
};
3058 ScreenToClient(&ptClient
);
3059 ImageList_DragEnter(m_hWnd
, ptClient
.x
, ptClient
.y
);
3065 HRESULT WINAPI
CDefView::DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
3067 POINT ptClient
= {pt
.x
, pt
.y
};
3068 ScreenToClient(&ptClient
);
3069 ImageList_DragMove(ptClient
.x
, ptClient
.y
);
3070 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
3073 HRESULT WINAPI
CDefView::DragLeave()
3075 ImageList_DragLeave(m_hWnd
);
3077 if (m_pCurDropTarget
)
3079 m_pCurDropTarget
->DragLeave();
3080 m_pCurDropTarget
.Release();
3083 if (m_pCurDataObject
!= NULL
)
3085 m_pCurDataObject
.Release();
3088 m_iDragOverItem
= 0;
3093 HRESULT WINAPI
CDefView::Drop(IDataObject
* pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
3095 ImageList_DragLeave(m_hWnd
);
3096 ImageList_EndDrag();
3098 if ((IsDropOnSource(NULL
) == S_OK
) &&
3099 (*pdwEffect
& DROPEFFECT_MOVE
) &&
3100 (m_grfKeyState
& MK_LBUTTON
))
3102 if (m_pCurDropTarget
)
3104 m_pCurDropTarget
->DragLeave();
3105 m_pCurDropTarget
.Release();
3108 /* Restore the selection */
3109 m_ListView
.SetItemState(-1, 0, LVIS_SELECTED
);
3110 for (UINT i
= 0 ; i
< m_cidl
; i
++)
3111 SelectItem(m_apidl
[i
], SVSI_SELECT
);
3113 /* Reposition the items */
3115 while ((lvIndex
= m_ListView
.GetNextItem(lvIndex
, LVNI_SELECTED
)) > -1)
3118 if (m_ListView
.GetItemPosition(lvIndex
, &ptItem
))
3120 ptItem
.x
+= pt
.x
- m_ptFirstMousePos
.x
;
3121 ptItem
.y
+= pt
.y
- m_ptFirstMousePos
.y
;
3122 m_ListView
.SetItemPosition(lvIndex
, &ptItem
);
3126 else if (m_pCurDropTarget
)
3128 m_pCurDropTarget
->Drop(pDataObject
, grfKeyState
, pt
, pdwEffect
);
3129 m_pCurDropTarget
.Release();
3132 m_pCurDataObject
.Release();
3133 m_iDragOverItem
= 0;
3137 /**********************************************************
3138 * ISVDropSource implementation
3141 HRESULT WINAPI
CDefView::QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
)
3143 TRACE("(%p)\n", this);
3146 return DRAGDROP_S_CANCEL
;
3147 else if (!(grfKeyState
& MK_LBUTTON
) && !(grfKeyState
& MK_RBUTTON
))
3148 return DRAGDROP_S_DROP
;
3153 HRESULT WINAPI
CDefView::GiveFeedback(DWORD dwEffect
)
3155 TRACE("(%p)\n", this);
3157 return DRAGDROP_S_USEDEFAULTCURSORS
;
3160 /**********************************************************
3161 * ISVViewObject implementation
3164 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
)
3166 FIXME("Stub: this=%p\n", this);
3171 HRESULT WINAPI
CDefView::GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
, HDC hicTargetDevice
, LOGPALETTE
**ppColorSet
)
3173 FIXME("Stub: this=%p\n", this);
3178 HRESULT WINAPI
CDefView::Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
)
3180 FIXME("Stub: this=%p\n", this);
3185 HRESULT WINAPI
CDefView::Unfreeze(DWORD dwFreeze
)
3187 FIXME("Stub: this=%p\n", this);
3192 HRESULT WINAPI
CDefView::SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
)
3194 FIXME("partial stub: %p 0x%08x 0x%08x %p\n", this, aspects
, advf
, pAdvSink
);
3196 /* FIXME: we set the AdviseSink, but never use it to send any advice */
3197 m_pAdvSink
= pAdvSink
;
3198 m_dwAspects
= aspects
;
3204 HRESULT WINAPI
CDefView::GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
)
3206 TRACE("this=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n", this, pAspects
, pAdvf
, ppAdvSink
);
3210 *ppAdvSink
= m_pAdvSink
;
3211 m_pAdvSink
.p
->AddRef();
3215 *pAspects
= m_dwAspects
;
3223 HRESULT STDMETHODCALLTYPE
CDefView::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
3225 if (IsEqualIID(guidService
, SID_IShellBrowser
))
3226 return m_pShellBrowser
->QueryInterface(riid
, ppvObject
);
3227 else if(IsEqualIID(guidService
, SID_IFolderView
))
3228 return QueryInterface(riid
, ppvObject
);
3230 return E_NOINTERFACE
;
3233 HRESULT
CDefView::_MergeToolbar()
3235 CComPtr
<IExplorerToolbar
> ptb
;
3238 hr
= IUnknown_QueryService(m_pShellBrowser
, IID_IExplorerToolbar
, IID_PPV_ARG(IExplorerToolbar
, &ptb
));
3242 m_Category
= CGID_DefViewFrame
;
3244 hr
= ptb
->SetCommandTarget(static_cast<IOleCommandTarget
*>(this), &m_Category
, 0);
3252 hr
= ptb
->AddButtons(&m_Category
, buttonsCount
, buttons
);
3260 HRESULT
CDefView::_DoFolderViewCB(UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3262 if (m_pShellFolderViewCB
)
3264 return m_pShellFolderViewCB
->MessageSFVCB(uMsg
, wParam
, lParam
);
3266 return E_NOINTERFACE
;
3269 HRESULT
CDefView_CreateInstance(IShellFolder
*pFolder
, REFIID riid
, LPVOID
* ppvOut
)
3271 return ShellObjectCreatorInit
<CDefView
>(pFolder
, riid
, ppvOut
);
3274 HRESULT WINAPI
SHCreateShellFolderViewEx(
3275 LPCSFV psvcbi
, /* [in] shelltemplate struct */
3276 IShellView
**ppsv
) /* [out] IShellView pointer */
3278 CComPtr
<IShellView
> psv
;
3281 TRACE("sf=%p pidl=%p cb=%p mode=0x%08x parm=%p\n",
3282 psvcbi
->pshf
, psvcbi
->pidl
, psvcbi
->pfnCallback
,
3283 psvcbi
->fvm
, psvcbi
->psvOuter
);
3286 hRes
= CDefView_CreateInstance(psvcbi
->pshf
, IID_PPV_ARG(IShellView
, &psv
));
3287 if (FAILED_UNEXPECTEDLY(hRes
))
3290 *ppsv
= psv
.Detach();
3294 HRESULT WINAPI
SHCreateShellFolderView(const SFV_CREATE
*pcsfv
,
3297 CComPtr
<IShellView
> psv
;
3301 if (!pcsfv
|| pcsfv
->cbSize
!= sizeof(*pcsfv
))
3302 return E_INVALIDARG
;
3304 TRACE("sf=%p outer=%p callback=%p\n",
3305 pcsfv
->pshf
, pcsfv
->psvOuter
, pcsfv
->psfvcb
);
3307 hRes
= CDefView_CreateInstance(pcsfv
->pshf
, IID_PPV_ARG(IShellView
, &psv
));
3313 CComPtr
<IShellFolderView
> sfv
;
3314 if (SUCCEEDED(psv
->QueryInterface(IID_PPV_ARG(IShellFolderView
, &sfv
))))
3316 sfv
->SetCallback(pcsfv
->psfvcb
, NULL
);
3320 *ppsv
= psv
.Detach();