4 * Copyright 1998,1999 <juergen.schmied@debitel.net>
6 * This is the view visualizing the data provided by the shellfolder.
7 * No direct access to data from pidls should be done from here.
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 * FIXME: CheckToolbar: handle the "new folder" and "folder up" button
28 - Load/Save the view state from/into the stream provided by the ShellBrowser.
29 - When editing starts on item, set edit text to for editing value.
30 - Fix shell view to handle view mode popup exec.
31 - The background context menu should have a pidl just like foreground menus. This
32 causes crashes when dynamic handlers try to use the NULL pidl.
33 - Reorder of columns doesn't work - might be bug in comctl32
41 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
45 static const WCHAR SV_CLASS_NAME
[] = {'S', 'H', 'E', 'L', 'L', 'D', 'L', 'L', '_', 'D', 'e', 'f', 'V', 'i', 'e', 'w', 0};
52 } LISTVIEW_SORT_INFO
, *LPLISTVIEW_SORT_INFO
;
54 #define SHV_CHANGE_NOTIFY WM_USER + 0x1111
56 /* For the context menu of the def view, the id of the items are based on 1 because we need
57 to call TrackPopupMenu and let it use the 0 value as an indication that the menu was canceled */
58 #define CONTEXT_MENU_BASE_ID 1
61 public CWindowImpl
<CDefView
, CWindow
, CControlWinTraits
>,
62 public CComObjectRootEx
<CComMultiThreadModelNoCS
>,
65 public IShellFolderView
,
66 public IOleCommandTarget
,
70 public IServiceProvider
73 CComPtr
<IShellFolder
> m_pSFParent
;
74 CComPtr
<IShellFolder2
> m_pSF2Parent
;
75 CComPtr
<IShellFolderViewCB
> m_pShellFolderViewCB
;
76 CComPtr
<IShellBrowser
> m_pShellBrowser
;
77 CComPtr
<ICommDlgBrowser
> m_pCommDlgBrowser
;
78 CComPtr
<IShellFolderViewDual
> m_pShellFolderViewDual
;
81 FOLDERSETTINGS m_FolderSettings
;
82 HMENU m_hMenu
; /* Handle to the menu bar of the browser */
83 HMENU m_hMenuArrangeModes
; /* Handle to the popup menu with the arrange modes */
84 HMENU m_hMenuViewModes
; /* Handle to the popup menu with the view modes */
85 HMENU m_hContextMenu
; /* Handle to the open context menu */
86 BOOL m_bmenuBarInitialized
;
89 PCUITEMID_CHILD
*m_apidl
;
90 PIDLIST_ABSOLUTE m_pidlParent
;
91 LISTVIEW_SORT_INFO m_sortInfo
;
92 ULONG m_hNotify
; /* Change notification handle */
96 CComPtr
<IAdviseSink
> m_pAdvSink
;
98 CComPtr
<IDataObject
> m_pSourceDataObject
;
99 CComPtr
<IDropTarget
> m_pCurDropTarget
; /* The sub-item, which is currently dragged over */
100 CComPtr
<IDataObject
> m_pCurDataObject
; /* The dragged data-object */
101 LONG m_iDragOverItem
; /* Dragged over item's index, iff m_pCurDropTarget != NULL */
102 UINT m_cScrollDelay
; /* Send a WM_*SCROLL msg every 250 ms during drag-scroll */
103 POINT m_ptLastMousePos
; /* Mouse position at last DragOver call */
104 POINT m_ptFirstMousePos
; /* Mouse position when the drag operation started */
107 CComPtr
<IContextMenu
> m_pCM
;
115 HRESULT
_MergeToolbar();
117 HRESULT
_DoFolderViewCB(UINT uMsg
, WPARAM wParam
, LPARAM lParam
);
122 HRESULT WINAPI
Initialize(IShellFolder
*shellFolder
);
123 HRESULT
IncludeObject(PCUITEMID_CHILD pidl
);
124 HRESULT
OnDefaultCommand();
125 HRESULT
OnStateChange(UINT uFlags
);
126 void UpdateStatusbar();
129 void UpdateListColors();
131 static INT CALLBACK
ListViewCompareItems(LPARAM lParam1
, LPARAM lParam2
, LPARAM lpData
);
133 PCUITEMID_CHILD
_PidlByItem(int i
);
134 PCUITEMID_CHILD
_PidlByItem(LVITEM
& lvItem
);
135 int LV_FindItemByPidl(PCUITEMID_CHILD pidl
);
136 BOOLEAN
LV_AddItem(PCUITEMID_CHILD pidl
);
137 BOOLEAN
LV_DeleteItem(PCUITEMID_CHILD pidl
);
138 BOOLEAN
LV_RenameItem(PCUITEMID_CHILD pidlOld
, PCUITEMID_CHILD pidlNew
);
139 BOOLEAN
LV_ProdItem(PCUITEMID_CHILD pidl
);
140 static INT CALLBACK
fill_list(LPVOID ptr
, LPVOID arg
);
142 HRESULT
FillFileMenu();
143 HRESULT
FillEditMenu();
144 HRESULT
FillViewMenu();
145 HRESULT
FillArrangeAsMenu(HMENU hmenuArrange
);
146 HRESULT
CheckViewMode(HMENU hmenuView
);
147 UINT
GetSelections();
148 HRESULT
OpenSelectedItems();
150 void DoActivate(UINT uState
);
151 HRESULT
drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
152 HRESULT
InvokeContextMenuCommand(UINT uCommand
);
153 LRESULT
OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
);
155 // *** IOleWindow methods ***
156 virtual HRESULT STDMETHODCALLTYPE
GetWindow(HWND
*lphwnd
);
157 virtual HRESULT STDMETHODCALLTYPE
ContextSensitiveHelp(BOOL fEnterMode
);
159 // *** IShellView methods ***
160 virtual HRESULT STDMETHODCALLTYPE
TranslateAccelerator(MSG
*pmsg
);
161 virtual HRESULT STDMETHODCALLTYPE
EnableModeless(BOOL fEnable
);
162 virtual HRESULT STDMETHODCALLTYPE
UIActivate(UINT uState
);
163 virtual HRESULT STDMETHODCALLTYPE
Refresh();
164 virtual HRESULT STDMETHODCALLTYPE
CreateViewWindow(IShellView
*psvPrevious
, LPCFOLDERSETTINGS pfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
);
165 virtual HRESULT STDMETHODCALLTYPE
DestroyViewWindow();
166 virtual HRESULT STDMETHODCALLTYPE
GetCurrentInfo(LPFOLDERSETTINGS pfs
);
167 virtual HRESULT STDMETHODCALLTYPE
AddPropertySheetPages(DWORD dwReserved
, LPFNSVADDPROPSHEETPAGE pfn
, LPARAM lparam
);
168 virtual HRESULT STDMETHODCALLTYPE
SaveViewState();
169 virtual HRESULT STDMETHODCALLTYPE
SelectItem(PCUITEMID_CHILD pidlItem
, SVSIF uFlags
);
170 virtual HRESULT STDMETHODCALLTYPE
GetItemObject(UINT uItem
, REFIID riid
, void **ppv
);
172 // *** IShellView2 methods ***
173 virtual HRESULT STDMETHODCALLTYPE
GetView(SHELLVIEWID
*view_guid
, ULONG view_type
);
174 virtual HRESULT STDMETHODCALLTYPE
CreateViewWindow2(LPSV2CVW2_PARAMS view_params
);
175 virtual HRESULT STDMETHODCALLTYPE
HandleRename(LPCITEMIDLIST new_pidl
);
176 virtual HRESULT STDMETHODCALLTYPE
SelectAndPositionItem(LPCITEMIDLIST item
, UINT flags
, POINT
*point
);
178 // *** IShellView3 methods ***
179 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
);
181 // *** IFolderView methods ***
182 virtual HRESULT STDMETHODCALLTYPE
GetCurrentViewMode(UINT
*pViewMode
);
183 virtual HRESULT STDMETHODCALLTYPE
SetCurrentViewMode(UINT ViewMode
);
184 virtual HRESULT STDMETHODCALLTYPE
GetFolder(REFIID riid
, void **ppv
);
185 virtual HRESULT STDMETHODCALLTYPE
Item(int iItemIndex
, PITEMID_CHILD
*ppidl
);
186 virtual HRESULT STDMETHODCALLTYPE
ItemCount(UINT uFlags
, int *pcItems
);
187 virtual HRESULT STDMETHODCALLTYPE
Items(UINT uFlags
, REFIID riid
, void **ppv
);
188 virtual HRESULT STDMETHODCALLTYPE
GetSelectionMarkedItem(int *piItem
);
189 virtual HRESULT STDMETHODCALLTYPE
GetFocusedItem(int *piItem
);
190 virtual HRESULT STDMETHODCALLTYPE
GetItemPosition(PCUITEMID_CHILD pidl
, POINT
*ppt
);
191 virtual HRESULT STDMETHODCALLTYPE
GetSpacing(POINT
*ppt
);
192 virtual HRESULT STDMETHODCALLTYPE
GetDefaultSpacing(POINT
*ppt
);
193 virtual HRESULT STDMETHODCALLTYPE
GetAutoArrange();
194 virtual HRESULT STDMETHODCALLTYPE
SelectItem(int iItem
, DWORD dwFlags
);
195 virtual HRESULT STDMETHODCALLTYPE
SelectAndPositionItems(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD dwFlags
);
197 // *** IShellFolderView methods ***
198 virtual HRESULT STDMETHODCALLTYPE
Rearrange(LPARAM sort
);
199 virtual HRESULT STDMETHODCALLTYPE
GetArrangeParam(LPARAM
*sort
);
200 virtual HRESULT STDMETHODCALLTYPE
ArrangeGrid();
201 virtual HRESULT STDMETHODCALLTYPE
AutoArrange();
202 virtual HRESULT STDMETHODCALLTYPE
AddObject(PITEMID_CHILD pidl
, UINT
*item
);
203 virtual HRESULT STDMETHODCALLTYPE
GetObject(PITEMID_CHILD
*pidl
, UINT item
);
204 virtual HRESULT STDMETHODCALLTYPE
RemoveObject(PITEMID_CHILD pidl
, UINT
*item
);
205 virtual HRESULT STDMETHODCALLTYPE
GetObjectCount(UINT
*count
);
206 virtual HRESULT STDMETHODCALLTYPE
SetObjectCount(UINT count
, UINT flags
);
207 virtual HRESULT STDMETHODCALLTYPE
UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
);
208 virtual HRESULT STDMETHODCALLTYPE
RefreshObject(PITEMID_CHILD pidl
, UINT
*item
);
209 virtual HRESULT STDMETHODCALLTYPE
SetRedraw(BOOL redraw
);
210 virtual HRESULT STDMETHODCALLTYPE
GetSelectedCount(UINT
*count
);
211 virtual HRESULT STDMETHODCALLTYPE
GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
);
212 virtual HRESULT STDMETHODCALLTYPE
IsDropOnSource(IDropTarget
*drop_target
);
213 virtual HRESULT STDMETHODCALLTYPE
GetDragPoint(POINT
*pt
);
214 virtual HRESULT STDMETHODCALLTYPE
GetDropPoint(POINT
*pt
);
215 virtual HRESULT STDMETHODCALLTYPE
MoveIcons(IDataObject
*obj
);
216 virtual HRESULT STDMETHODCALLTYPE
SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
);
217 virtual HRESULT STDMETHODCALLTYPE
IsBkDropTarget(IDropTarget
*drop_target
);
218 virtual HRESULT STDMETHODCALLTYPE
SetClipboard(BOOL move
);
219 virtual HRESULT STDMETHODCALLTYPE
SetPoints(IDataObject
*obj
);
220 virtual HRESULT STDMETHODCALLTYPE
GetItemSpacing(ITEMSPACING
*spacing
);
221 virtual HRESULT STDMETHODCALLTYPE
SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
);
222 virtual HRESULT STDMETHODCALLTYPE
Select(UINT flags
);
223 virtual HRESULT STDMETHODCALLTYPE
QuerySupport(UINT
*support
);
224 virtual HRESULT STDMETHODCALLTYPE
SetAutomationObject(IDispatch
*disp
);
226 // *** IOleCommandTarget methods ***
227 virtual HRESULT STDMETHODCALLTYPE
QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
);
228 virtual HRESULT STDMETHODCALLTYPE
Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
);
230 // *** IDropTarget methods ***
231 virtual HRESULT STDMETHODCALLTYPE
DragEnter(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
232 virtual HRESULT STDMETHODCALLTYPE
DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
233 virtual HRESULT STDMETHODCALLTYPE
DragLeave();
234 virtual HRESULT STDMETHODCALLTYPE
Drop(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
236 // *** IDropSource methods ***
237 virtual HRESULT STDMETHODCALLTYPE
QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
);
238 virtual HRESULT STDMETHODCALLTYPE
GiveFeedback(DWORD dwEffect
);
240 // *** IViewObject methods ***
241 virtual HRESULT STDMETHODCALLTYPE
Draw(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
,
242 HDC hdcTargetDev
, HDC hdcDraw
, LPCRECTL lprcBounds
, LPCRECTL lprcWBounds
,
243 BOOL ( STDMETHODCALLTYPE
*pfnContinue
)(ULONG_PTR dwContinue
), ULONG_PTR dwContinue
);
244 virtual HRESULT STDMETHODCALLTYPE
GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
,
245 DVTARGETDEVICE
*ptd
, HDC hicTargetDev
, LOGPALETTE
**ppColorSet
);
246 virtual HRESULT STDMETHODCALLTYPE
Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
);
247 virtual HRESULT STDMETHODCALLTYPE
Unfreeze(DWORD dwFreeze
);
248 virtual HRESULT STDMETHODCALLTYPE
SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
);
249 virtual HRESULT STDMETHODCALLTYPE
GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
);
251 // *** IServiceProvider methods ***
252 virtual HRESULT STDMETHODCALLTYPE
QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
);
255 LRESULT
OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
256 LRESULT
OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
257 LRESULT
OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
258 LRESULT
OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
259 LRESULT
OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
260 LRESULT
OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
261 LRESULT
OnNCCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
262 LRESULT
OnNCDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
263 LRESULT
OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
264 LRESULT
OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
265 LRESULT
OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
266 LRESULT
OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
267 LRESULT
OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
268 LRESULT
OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
269 LRESULT
OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
270 LRESULT
OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
271 LRESULT
OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
272 LRESULT
OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
273 LRESULT
OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
274 LRESULT
OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
276 static ATL::CWndClassInfo
& GetWndClassInfo()
278 static ATL::CWndClassInfo wc
=
280 { sizeof(WNDCLASSEX
), CS_PARENTDC
, StartWindowProc
,
282 LoadCursor(NULL
, IDC_ARROW
), (HBRUSH
)(COLOR_WINDOW
+ 1), NULL
, SV_CLASS_NAME
, NULL
284 NULL
, NULL
, IDC_ARROW
, TRUE
, 0, _T("")
289 virtual WNDPROC
GetWindowProc()
294 static LRESULT CALLBACK
WindowProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
299 // Must hold a reference during message handling
300 pThis
= reinterpret_cast<CDefView
*>(hWnd
);
302 result
= CWindowImpl
<CDefView
, CWindow
, CControlWinTraits
>::WindowProc(hWnd
, uMsg
, wParam
, lParam
);
307 BEGIN_MSG_MAP(CDefView
)
308 MESSAGE_HANDLER(WM_SIZE
, OnSize
)
309 MESSAGE_HANDLER(WM_SETFOCUS
, OnSetFocus
)
310 MESSAGE_HANDLER(WM_KILLFOCUS
, OnKillFocus
)
311 MESSAGE_HANDLER(WM_NCCREATE
, OnNCCreate
)
312 MESSAGE_HANDLER(WM_NCDESTROY
, OnNCDestroy
)
313 MESSAGE_HANDLER(WM_CREATE
, OnCreate
)
314 MESSAGE_HANDLER(WM_ACTIVATE
, OnActivate
)
315 MESSAGE_HANDLER(WM_NOTIFY
, OnNotify
)
316 MESSAGE_HANDLER(WM_COMMAND
, OnCommand
)
317 MESSAGE_HANDLER(SHV_CHANGE_NOTIFY
, OnChangeNotify
)
318 MESSAGE_HANDLER(WM_CONTEXTMENU
, OnContextMenu
)
319 MESSAGE_HANDLER(WM_DRAWITEM
, OnCustomItem
)
320 MESSAGE_HANDLER(WM_MEASUREITEM
, OnCustomItem
)
321 MESSAGE_HANDLER(WM_SHOWWINDOW
, OnShowWindow
)
322 MESSAGE_HANDLER(WM_GETDLGCODE
, OnGetDlgCode
)
323 MESSAGE_HANDLER(WM_DESTROY
, OnDestroy
)
324 MESSAGE_HANDLER(WM_ERASEBKGND
, OnEraseBackground
)
325 MESSAGE_HANDLER(WM_SYSCOLORCHANGE
, OnSysColorChange
)
326 MESSAGE_HANDLER(CWM_GETISHELLBROWSER
, OnGetShellBrowser
)
327 MESSAGE_HANDLER(WM_SETTINGCHANGE
, OnSettingChange
)
328 MESSAGE_HANDLER(WM_INITMENUPOPUP
, OnInitMenuPopup
)
331 BEGIN_COM_MAP(CDefView
)
332 // Windows returns E_NOINTERFACE for IOleWindow
333 // COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
334 COM_INTERFACE_ENTRY_IID(IID_IShellView
, IShellView
)
335 COM_INTERFACE_ENTRY_IID(IID_CDefView
, IShellView
)
336 COM_INTERFACE_ENTRY_IID(IID_IShellView2
, IShellView2
)
337 COM_INTERFACE_ENTRY_IID(IID_IFolderView
, IFolderView
)
338 COM_INTERFACE_ENTRY_IID(IID_IShellFolderView
, IShellFolderView
)
339 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget
, IOleCommandTarget
)
340 COM_INTERFACE_ENTRY_IID(IID_IDropTarget
, IDropTarget
)
341 COM_INTERFACE_ENTRY_IID(IID_IDropSource
, IDropSource
)
342 COM_INTERFACE_ENTRY_IID(IID_IViewObject
, IViewObject
)
343 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider
, IServiceProvider
)
348 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
349 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
350 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
352 #define ID_LISTVIEW 1
355 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
356 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
357 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
359 typedef void (CALLBACK
*PFNSHGETSETTINGSPROC
)(LPSHELLFLAGSTATE lpsfs
, DWORD dwMask
);
361 CDefView::CDefView() :
365 m_hMenuArrangeModes(NULL
),
366 m_hMenuViewModes(NULL
),
367 m_hContextMenu(NULL
),
368 m_bmenuBarInitialized(FALSE
),
382 ZeroMemory(&m_FolderSettings
, sizeof(m_FolderSettings
));
383 ZeroMemory(&m_sortInfo
, sizeof(m_sortInfo
));
384 ZeroMemory(&m_ptLastMousePos
, sizeof(m_ptLastMousePos
));
385 ZeroMemory(&m_Category
, sizeof(m_Category
));
388 CDefView::~CDefView()
390 TRACE(" destroying IShellView(%p)\n", this);
400 HRESULT WINAPI
CDefView::Initialize(IShellFolder
*shellFolder
)
402 m_pSFParent
= shellFolder
;
403 shellFolder
->QueryInterface(IID_PPV_ARG(IShellFolder2
, &m_pSF2Parent
));
408 /**********************************************************
410 * ##### helperfunctions for communication with ICommDlgBrowser #####
412 HRESULT
CDefView::IncludeObject(PCUITEMID_CHILD pidl
)
416 if (m_pCommDlgBrowser
.p
!= NULL
)
418 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl
);
419 ret
= m_pCommDlgBrowser
->IncludeObject(this, pidl
);
420 TRACE("-- returns 0x%08x\n", ret
);
426 HRESULT
CDefView::OnDefaultCommand()
428 HRESULT ret
= S_FALSE
;
430 if (m_pCommDlgBrowser
.p
!= NULL
)
432 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
433 ret
= m_pCommDlgBrowser
->OnDefaultCommand(this);
434 TRACE("-- returns 0x%08x\n", ret
);
440 HRESULT
CDefView::OnStateChange(UINT uFlags
)
442 HRESULT ret
= S_FALSE
;
444 if (m_pCommDlgBrowser
.p
!= NULL
)
446 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags
);
447 ret
= m_pCommDlgBrowser
->OnStateChange(this, uFlags
);
453 /**********************************************************
454 * set the toolbar of the filedialog buttons
456 * - activates the buttons from the shellbrowser according to
459 void CDefView::CheckToolbar()
465 if (m_pCommDlgBrowser
!= NULL
)
467 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
468 FCIDM_TB_SMALLICON
, (m_FolderSettings
.ViewMode
== FVM_LIST
) ? TRUE
: FALSE
, &result
);
469 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
470 FCIDM_TB_REPORTVIEW
, (m_FolderSettings
.ViewMode
== FVM_DETAILS
) ? TRUE
: FALSE
, &result
);
471 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
472 FCIDM_TB_SMALLICON
, TRUE
, &result
);
473 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
474 FCIDM_TB_REPORTVIEW
, TRUE
, &result
);
478 void CDefView::UpdateStatusbar()
480 WCHAR szFormat
[MAX_PATH
] = {0};
481 WCHAR szObjects
[MAX_PATH
] = {0};
484 cSelectedItems
= m_ListView
.GetSelectedCount();
487 LoadStringW(shell32_hInstance
, IDS_OBJECTS_SELECTED
, szFormat
, _countof(szFormat
));
488 StringCchPrintfW(szObjects
, MAX_PATH
, szFormat
, cSelectedItems
);
492 LoadStringW(shell32_hInstance
, IDS_OBJECTS
, szFormat
, _countof(szFormat
));
493 StringCchPrintfW(szObjects
, MAX_PATH
, szFormat
, m_ListView
.GetItemCount());
495 m_pShellBrowser
->SetStatusTextSB(szObjects
);
498 /**********************************************************
500 * ##### helperfunctions for initializing the view #####
503 /**********************************************************
504 * ShellView_CreateList()
506 * - creates the list view window
508 BOOL
CDefView::CreateList()
511 DWORD dwStyle
, dwExStyle
;
516 dwStyle
= WS_TABSTOP
| WS_VISIBLE
| WS_CHILDWINDOW
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
|
517 LVS_SHAREIMAGELISTS
| LVS_EDITLABELS
| LVS_AUTOARRANGE
;
518 dwExStyle
= WS_EX_CLIENTEDGE
;
520 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
521 dwStyle
|= LVS_ALIGNLEFT
;
523 dwStyle
|= LVS_ALIGNTOP
| LVS_SHOWSELALWAYS
;
525 ViewMode
= m_FolderSettings
.ViewMode
;
526 hr
= _DoFolderViewCB(SFVM_DEFVIEWMODE
, NULL
, (LPARAM
)&ViewMode
);
529 if (ViewMode
>= FVM_FIRST
&& ViewMode
<= FVM_LAST
)
530 m_FolderSettings
.ViewMode
= ViewMode
;
532 ERR("Ignoring invalid ViewMode from SFVM_DEFVIEWMODE: %u (was: %u)\n", ViewMode
, m_FolderSettings
.ViewMode
);
535 switch (m_FolderSettings
.ViewMode
)
542 dwStyle
|= LVS_REPORT
;
546 dwStyle
|= LVS_SMALLICON
;
558 if (m_FolderSettings
.fFlags
& FWF_AUTOARRANGE
)
559 dwStyle
|= LVS_AUTOARRANGE
;
561 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
562 m_FolderSettings
.fFlags
|= FWF_NOCLIENTEDGE
| FWF_NOSCROLL
;
564 if (m_FolderSettings
.fFlags
& FWF_SINGLESEL
)
565 dwStyle
|= LVS_SINGLESEL
;
567 if (m_FolderSettings
.fFlags
& FWF_NOCLIENTEDGE
)
568 dwExStyle
&= ~WS_EX_CLIENTEDGE
;
570 RECT rcListView
= {0,0,0,0};
571 m_ListView
.Create(m_hWnd
, rcListView
, L
"FolderView", dwStyle
, dwExStyle
, ID_LISTVIEW
);
576 m_sortInfo
.bIsAscending
= TRUE
;
577 m_sortInfo
.nHeaderID
= -1;
578 m_sortInfo
.nLastHeaderID
= -1;
582 /* UpdateShellSettings(); */
586 void CDefView::UpdateListColors()
588 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
590 /* Check if drop shadows option is enabled */
591 BOOL bDropShadow
= FALSE
;
592 DWORD cbDropShadow
= sizeof(bDropShadow
);
595 * The desktop ListView always take the default desktop colours, by
596 * remaining transparent and letting user32/win32k paint itself the
597 * desktop background color, if any.
599 m_ListView
.SetBkColor(CLR_NONE
);
601 SHGetValueW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
602 L
"ListviewShadow", NULL
, &bDropShadow
, &cbDropShadow
);
605 /* Set the icon background transparent */
606 m_ListView
.SetTextBkColor(CLR_NONE
);
607 m_ListView
.SetTextColor(RGB(255, 255, 255));
608 m_ListView
.SetExtendedListViewStyle(LVS_EX_TRANSPARENTSHADOWTEXT
, LVS_EX_TRANSPARENTSHADOWTEXT
);
612 /* Set the icon background as the same colour as the desktop */
613 COLORREF crDesktop
= GetSysColor(COLOR_DESKTOP
);
614 m_ListView
.SetTextBkColor(crDesktop
);
615 if (GetRValue(crDesktop
) + GetGValue(crDesktop
) + GetBValue(crDesktop
) > 128 * 3)
616 m_ListView
.SetTextColor(RGB(0, 0, 0));
618 m_ListView
.SetTextColor(RGB(255, 255, 255));
619 m_ListView
.SetExtendedListViewStyle(0, LVS_EX_TRANSPARENTSHADOWTEXT
);
624 /**********************************************************
625 * ShellView_InitList()
627 * - adds all needed columns to the shellview
629 BOOL
CDefView::InitList()
633 HIMAGELIST big_icons
, small_icons
;
637 m_ListView
.DeleteAllItems();
639 m_hMenuArrangeModes
= CreateMenu();
643 for (int i
= 0; 1; i
++)
645 if (FAILED(m_pSF2Parent
->GetDetailsOf(NULL
, i
, &sd
)))
647 StrRetToStrNW( szTemp
, 50, &sd
.str
, NULL
);
648 m_ListView
.InsertColumn(i
, szTemp
, sd
.fmt
, sd
.cxChar
* 8);
650 InsertMenuW(m_hMenuArrangeModes
, -1, MF_STRING
, 0x30 + i
, szTemp
);
653 InsertMenuW(m_hMenuArrangeModes
, -1, MF_BYPOSITION
| MF_SEPARATOR
, 0, 0);
657 FIXME("no m_pSF2Parent\n");
660 Shell_GetImageLists(&big_icons
, &small_icons
);
661 m_ListView
.SetImageList(big_icons
, LVSIL_NORMAL
);
662 m_ListView
.SetImageList(small_icons
, LVSIL_SMALL
);
667 /*************************************************************************
668 * ShellView_ListViewCompareItems
670 * Compare Function for the Listview (FileOpen Dialog)
673 * lParam1 [I] the first ItemIdList to compare with
674 * lParam2 [I] the second ItemIdList to compare with
675 * lpData [I] The column ID for the header Ctrl to process
678 * A negative value if the first item should precede the second,
679 * a positive value if the first item should follow the second,
680 * or zero if the two items are equivalent
682 INT CALLBACK
CDefView::ListViewCompareItems(LPARAM lParam1
, LPARAM lParam2
, LPARAM lpData
)
684 PCUIDLIST_RELATIVE pidl1
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam1
);
685 PCUIDLIST_RELATIVE pidl2
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam2
);
686 CDefView
*pThis
= reinterpret_cast<CDefView
*>(lpData
);
688 HRESULT hres
= pThis
->m_pSFParent
->CompareIDs(pThis
->m_sortInfo
.nHeaderID
, pidl1
, pidl2
);
689 if (FAILED_UNEXPECTEDLY(hres
))
692 SHORT nDiff
= HRESULT_CODE(hres
);
693 if (!pThis
->m_sortInfo
.bIsAscending
)
698 BOOL
CDefView::_Sort()
703 if (m_ListView
.GetWindowLongPtr(GWL_STYLE
) & LVS_NOSORTHEADER
)
706 hHeader
= (HWND
)m_ListView
.SendMessage(LVM_GETHEADER
, 0, 0);
707 ZeroMemory(&hColumn
, sizeof(hColumn
));
709 /* If the sorting column changed, remove the sorting style from the old column */
710 if ( (m_sortInfo
.nLastHeaderID
!= -1) &&
711 (m_sortInfo
.nLastHeaderID
!= m_sortInfo
.nHeaderID
) )
713 hColumn
.mask
= HDI_FORMAT
;
714 Header_GetItem(hHeader
, m_sortInfo
.nLastHeaderID
, &hColumn
);
715 hColumn
.fmt
&= ~(HDF_SORTUP
| HDF_SORTDOWN
);
716 Header_SetItem(hHeader
, m_sortInfo
.nLastHeaderID
, &hColumn
);
719 /* Set the sorting style to the new column */
720 hColumn
.mask
= HDI_FORMAT
;
721 Header_GetItem(hHeader
, m_sortInfo
.nHeaderID
, &hColumn
);
723 hColumn
.fmt
&= (m_sortInfo
.bIsAscending
? ~HDF_SORTDOWN
: ~HDF_SORTUP
);
724 hColumn
.fmt
|= (m_sortInfo
.bIsAscending
? HDF_SORTUP
: HDF_SORTDOWN
);
725 Header_SetItem(hHeader
, m_sortInfo
.nHeaderID
, &hColumn
);
727 /* Sort the list, using the current values of nHeaderID and bIsAscending */
728 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
729 return m_ListView
.SortItems(ListViewCompareItems
, this);
732 PCUITEMID_CHILD
CDefView::_PidlByItem(int i
)
734 return reinterpret_cast<PCUITEMID_CHILD
>(m_ListView
.GetItemData(i
));
737 PCUITEMID_CHILD
CDefView::_PidlByItem(LVITEM
& lvItem
)
739 return reinterpret_cast<PCUITEMID_CHILD
>(lvItem
.lParam
);
742 /**********************************************************
743 * LV_FindItemByPidl()
745 int CDefView::LV_FindItemByPidl(PCUITEMID_CHILD pidl
)
747 int cItems
= m_ListView
.GetItemCount();
749 for (int i
= 0; i
<cItems
; i
++)
751 PCUITEMID_CHILD currentpidl
= _PidlByItem(i
);
752 HRESULT hr
= m_pSFParent
->CompareIDs(0, pidl
, currentpidl
);
754 if (SUCCEEDED(hr
) && !HRESULT_CODE(hr
))
762 /**********************************************************
765 BOOLEAN
CDefView::LV_AddItem(PCUITEMID_CHILD pidl
)
769 TRACE("(%p)(pidl=%p)\n", this, pidl
);
771 lvItem
.mask
= LVIF_TEXT
| LVIF_IMAGE
| LVIF_PARAM
; /*set the mask*/
772 lvItem
.iItem
= m_ListView
.GetItemCount(); /*add the item to the end of the list*/
774 lvItem
.lParam
= reinterpret_cast<LPARAM
>(ILClone(pidl
)); /*set the item's data*/
775 lvItem
.pszText
= LPSTR_TEXTCALLBACKW
; /*get text on a callback basis*/
776 lvItem
.iImage
= I_IMAGECALLBACK
; /*get the image on a callback basis*/
777 lvItem
.stateMask
= LVIS_CUT
;
779 if (m_ListView
.InsertItem(&lvItem
) == -1)
785 /**********************************************************
788 BOOLEAN
CDefView::LV_DeleteItem(PCUITEMID_CHILD pidl
)
792 TRACE("(%p)(pidl=%p)\n", this, pidl
);
794 nIndex
= LV_FindItemByPidl(pidl
);
796 return (-1 == m_ListView
.DeleteItem(nIndex
)) ? FALSE
: TRUE
;
799 /**********************************************************
802 BOOLEAN
CDefView::LV_RenameItem(PCUITEMID_CHILD pidlOld
, PCUITEMID_CHILD pidlNew
)
807 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", this, pidlOld
, pidlNew
);
809 nItem
= LV_FindItemByPidl(pidlOld
);
813 lvItem
.mask
= LVIF_PARAM
; /* only the pidl */
814 lvItem
.iItem
= nItem
;
816 m_ListView
.GetItem(&lvItem
);
818 SHFree(reinterpret_cast<LPVOID
>(lvItem
.lParam
));
819 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
820 lvItem
.iItem
= nItem
;
822 lvItem
.lParam
= reinterpret_cast<LPARAM
>(ILClone(pidlNew
)); /* set the item's data */
823 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
824 m_ListView
.SetItem(&lvItem
);
825 m_ListView
.Update(nItem
);
826 return TRUE
; /* FIXME: better handling */
832 /**********************************************************
835 BOOLEAN
CDefView::LV_ProdItem(PCUITEMID_CHILD pidl
)
840 TRACE("(%p)(pidl=%p)\n", this, pidl
);
842 nItem
= LV_FindItemByPidl(pidl
);
846 lvItem
.mask
= LVIF_IMAGE
;
847 lvItem
.iItem
= nItem
;
849 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
850 m_ListView
.SetItem(&lvItem
);
851 m_ListView
.Update(nItem
);
858 /**********************************************************
859 * ShellView_FillList()
861 * - gets the objectlist from the shellfolder
863 * - fills the list into the view
865 INT CALLBACK
CDefView::fill_list(LPVOID ptr
, LPVOID arg
)
867 PITEMID_CHILD pidl
= static_cast<PITEMID_CHILD
>(ptr
);
868 CDefView
*pThis
= static_cast<CDefView
*>(arg
);
870 /* in a commdlg This works as a filemask*/
871 if (pThis
->IncludeObject(pidl
) == S_OK
)
872 pThis
->LV_AddItem(pidl
);
878 HRESULT
CDefView::FillList()
880 CComPtr
<IEnumIDList
> pEnumIDList
;
886 DWORD dFlags
= SHCONTF_NONFOLDERS
| SHCONTF_FOLDERS
;
890 /* determine if there is a setting to show all the hidden files/folders */
891 if (RegOpenKeyExW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", 0, KEY_QUERY_VALUE
, &hKey
) == ERROR_SUCCESS
)
893 DWORD dataLength
, flagVal
;
895 dataLength
= sizeof(flagVal
);
896 if (RegQueryValueExW(hKey
, L
"Hidden", NULL
, NULL
, (LPBYTE
)&flagVal
, &dataLength
) == ERROR_SUCCESS
)
898 /* if the value is 1, then show all hidden files/folders */
901 dFlags
|= SHCONTF_INCLUDEHIDDEN
;
902 m_ListView
.SendMessageW(LVM_SETCALLBACKMASK
, LVIS_CUT
, 0);
910 /* get the itemlist from the shfolder */
911 hRes
= m_pSFParent
->EnumObjects(m_hWnd
, dFlags
, &pEnumIDList
);
919 /* create a pointer array */
920 hdpa
= DPA_Create(16);
923 return(E_OUTOFMEMORY
);
926 /* copy the items into the array*/
927 while((S_OK
== pEnumIDList
->Next(1, &pidl
, &dwFetched
)) && dwFetched
)
929 if (DPA_InsertPtr(hdpa
, 0x7fff, pidl
) == -1)
935 /*turn the listview's redrawing off*/
936 m_ListView
.SetRedraw(FALSE
);
938 DPA_DestroyCallback( hdpa
, fill_list
, this);
943 m_pSF2Parent
->GetDefaultColumn(NULL
, (ULONG
*)&m_sortInfo
.nHeaderID
, NULL
);
947 FIXME("no m_pSF2Parent\n");
949 m_sortInfo
.bIsAscending
= TRUE
;
952 /*turn the listview's redrawing back on and force it to draw*/
953 m_ListView
.SetRedraw(TRUE
);
955 _DoFolderViewCB(SFVM_LISTREFRESHED
, NULL
, NULL
);
960 LRESULT
CDefView::OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
962 m_ListView
.UpdateWindow();
967 LRESULT
CDefView::OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
969 return m_ListView
.SendMessageW(uMsg
, 0, 0);
972 LRESULT
CDefView::OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
979 DestroyMenu(m_hMenu
);
982 RevokeDragDrop(m_hWnd
);
983 SHChangeNotifyDeregister(m_hNotify
);
985 SHFree(m_pidlParent
);
992 LRESULT
CDefView::OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
994 /* redirect to parent */
995 if (m_FolderSettings
.fFlags
& (FWF_DESKTOP
| FWF_TRANSPARENT
))
996 return SendMessageW(GetParent(), WM_ERASEBKGND
, wParam
, lParam
);
1002 LRESULT
CDefView::OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1004 /* Update desktop labels color */
1007 /* Forward WM_SYSCOLORCHANGE to common controls */
1008 return m_ListView
.SendMessageW(uMsg
, 0, 0);
1011 LRESULT
CDefView::OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1013 return reinterpret_cast<LRESULT
>(m_pShellBrowser
.p
);
1016 LRESULT
CDefView::OnNCCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1023 LRESULT
CDefView::OnNCDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1030 /**********************************************************
1031 * ShellView_OnCreate()
1033 LRESULT
CDefView::OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1035 CComPtr
<IDropTarget
> pdt
;
1036 SHChangeNotifyEntry ntreg
;
1037 CComPtr
<IPersistFolder2
> ppf2
;
1039 TRACE("%p\n", this);
1049 if (SUCCEEDED(QueryInterface(IID_PPV_ARG(IDropTarget
, &pdt
))))
1051 if (FAILED(RegisterDragDrop(m_hWnd
, pdt
)))
1052 ERR("Registering Drag Drop Failed");
1055 /* register for receiving notifications */
1056 m_pSFParent
->QueryInterface(IID_PPV_ARG(IPersistFolder2
, &ppf2
));
1059 ppf2
->GetCurFolder(&m_pidlParent
);
1060 ntreg
.fRecursive
= TRUE
;
1061 ntreg
.pidl
= m_pidlParent
;
1062 m_hNotify
= SHChangeNotifyRegister(m_hWnd
, SHCNRF_InterruptLevel
| SHCNRF_ShellLevel
, SHCNE_ALLEVENTS
, SHV_CHANGE_NOTIFY
, 1, &ntreg
);
1065 /* _DoFolderViewCB(SFVM_GETNOTIFY, ?? ??) */
1067 m_hAccel
= LoadAcceleratorsW(shell32_hInstance
, MAKEINTRESOURCEW(IDA_SHELLVIEW
));
1074 /**********************************************************
1075 * #### Handling of the menus ####
1078 extern "C" DWORD WINAPI
SHMenuIndexFromID(HMENU hMenu
, UINT uID
);
1080 HMENU
GetSubmenuByID(HMENU hmenu
, UINT id
)
1082 MENUITEMINFOW mii
= {sizeof(mii
), MIIM_SUBMENU
};
1083 if (::GetMenuItemInfoW(hmenu
, id
, FALSE
, &mii
))
1084 return mii
.hSubMenu
;
1089 /* ReallyGetMenuItemID returns the id of an item even if it opens a submenu,
1090 GetMenuItemID returns -1 if the specified item opens a submenu */
1091 UINT
ReallyGetMenuItemID(HMENU hmenu
, int i
)
1093 MENUITEMINFOW mii
= {sizeof(mii
), MIIM_ID
};
1094 if (::GetMenuItemInfoW(hmenu
, i
, TRUE
, &mii
))
1100 HRESULT
CDefView::FillFileMenu()
1102 HMENU hFileMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_FILE
);
1106 /* Cleanup the items added previously */
1107 for (int i
= GetMenuItemCount(hFileMenu
) - 1; i
>= 0; i
--)
1109 UINT id
= GetMenuItemID(hFileMenu
, i
);
1110 if (id
< FCIDM_BROWSERFIRST
|| id
> FCIDM_BROWSERLAST
)
1111 DeleteMenu(hFileMenu
, i
, MF_BYPOSITION
);
1114 /* Store the context menu in m_pCM and keep it in order to invoke the selected command later on */
1115 HRESULT hr
= GetItemObject(SVGIO_SELECTION
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1116 if (FAILED_UNEXPECTEDLY(hr
))
1119 HMENU hmenu
= CreatePopupMenu();
1121 hr
= m_pCM
->QueryContextMenu(hmenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, 0);
1122 if (FAILED_UNEXPECTEDLY(hr
))
1125 // TODO: filter or something
1127 Shell_MergeMenus(hFileMenu
, hmenu
, 0, 0, 0xFFFF, MM_ADDSEPARATOR
| MM_SUBMENUSHAVEIDS
);
1129 ::DestroyMenu(hmenu
);
1134 HRESULT
CDefView::FillEditMenu()
1136 HMENU hEditMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_EDIT
);
1140 HMENU hmenuContents
= ::LoadMenuW(shell32_hInstance
, L
"MENU_003");
1144 Shell_MergeMenus(hEditMenu
, hmenuContents
, 0, 0, 0xFFFF, 0);
1146 ::DestroyMenu(hmenuContents
);
1151 HRESULT
CDefView::FillViewMenu()
1153 HMENU hViewMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_VIEW
);
1157 m_hMenuViewModes
= ::LoadMenuW(shell32_hInstance
, L
"MENU_001");
1158 if (!m_hMenuViewModes
)
1161 UINT i
= SHMenuIndexFromID(hViewMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
);
1162 Shell_MergeMenus(hViewMenu
, m_hMenuViewModes
, i
, 0, 0xFFFF, MM_ADDSEPARATOR
| MM_DONTREMOVESEPS
| MM_SUBMENUSHAVEIDS
);
1167 HRESULT
CDefView::FillArrangeAsMenu(HMENU hmenuArrange
)
1169 /* We only need to fill this once */
1170 if (GetMenuItemID(hmenuArrange
, 0) == FCIDM_SHVIEW_AUTOARRANGE
)
1172 Shell_MergeMenus(hmenuArrange
, m_hMenuArrangeModes
, 0, 0, 0xFFFF,0);
1175 /* Also check the menu item according to which we sort */
1176 CheckMenuRadioItem(hmenuArrange
,
1179 m_sortInfo
.nHeaderID
+ 0x30,
1182 if (m_FolderSettings
.ViewMode
== FVM_DETAILS
|| m_FolderSettings
.ViewMode
== FVM_LIST
)
1184 EnableMenuItem(hmenuArrange
, FCIDM_SHVIEW_AUTOARRANGE
, MF_BYCOMMAND
| MF_GRAYED
);
1188 EnableMenuItem(hmenuArrange
, FCIDM_SHVIEW_AUTOARRANGE
, MF_BYCOMMAND
);
1190 if (GetAutoArrange() == S_OK
)
1191 CheckMenuItem(hmenuArrange
, FCIDM_SHVIEW_AUTOARRANGE
, MF_CHECKED
);
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 m_ListView
.ModifyStyle(LVS_TYPEMASK
, LVS_SMALLICON
);
1562 case FCIDM_SHVIEW_BIGICON
:
1563 m_FolderSettings
.ViewMode
= FVM_ICON
;
1564 m_ListView
.ModifyStyle(LVS_TYPEMASK
, LVS_ICON
);
1568 case FCIDM_SHVIEW_LISTVIEW
:
1569 m_FolderSettings
.ViewMode
= FVM_LIST
;
1570 m_ListView
.ModifyStyle(LVS_TYPEMASK
, LVS_LIST
);
1574 case FCIDM_SHVIEW_REPORTVIEW
:
1575 m_FolderSettings
.ViewMode
= FVM_DETAILS
;
1576 m_ListView
.ModifyStyle(LVS_TYPEMASK
, LVS_REPORT
);
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
:
1593 case FCIDM_SHVIEW_AUTOARRANGE
:
1594 if (GetAutoArrange() == S_OK
)
1595 m_ListView
.ModifyStyle(LVS_AUTOARRANGE
, 0);
1599 case FCIDM_SHVIEW_SELECTALL
:
1600 m_ListView
.SetItemState(-1, LVIS_SELECTED
, LVIS_SELECTED
);
1603 case FCIDM_SHVIEW_INVERTSELECTION
:
1604 nCount
= m_ListView
.GetItemCount();
1605 for (int i
=0; i
< nCount
; i
++)
1606 m_ListView
.SetItemState(i
, m_ListView
.GetItemState(i
, LVIS_SELECTED
) ? 0 : LVIS_SELECTED
, LVIS_SELECTED
);
1609 case FCIDM_SHVIEW_REFRESH
:
1613 case FCIDM_SHVIEW_DELETE
:
1614 case FCIDM_SHVIEW_CUT
:
1615 case FCIDM_SHVIEW_COPY
:
1616 case FCIDM_SHVIEW_RENAME
:
1617 case FCIDM_SHVIEW_PROPERTIES
:
1618 return OnExplorerCommand(dwCmdID
, TRUE
);
1620 case FCIDM_SHVIEW_INSERT
:
1621 case FCIDM_SHVIEW_UNDO
:
1622 case FCIDM_SHVIEW_INSERTLINK
:
1623 case FCIDM_SHVIEW_NEWFOLDER
:
1624 return OnExplorerCommand(dwCmdID
, FALSE
);
1626 /* WM_COMMAND messages from the file menu are routed to the CDefView so as to let m_pCM handle the command */
1627 if (m_pCM
&& dwCmd
== 0)
1629 InvokeContextMenuCommand(dwCmdID
);
1636 /**********************************************************
1637 * ShellView_OnNotify()
1640 LRESULT
CDefView::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1644 LPNMLISTVIEW lpnmlv
;
1645 NMLVDISPINFOW
*lpdi
;
1646 PCUITEMID_CHILD pidl
;
1650 lpnmh
= (LPNMHDR
)lParam
;
1651 lpnmlv
= (LPNMLISTVIEW
)lpnmh
;
1652 lpdi
= (NMLVDISPINFOW
*)lpnmh
;
1654 TRACE("%p CtlID=%u lpnmh->code=%x\n", this, CtlID
, lpnmh
->code
);
1656 switch (lpnmh
->code
)
1659 TRACE("-- NM_SETFOCUS %p\n", this);
1660 OnSetFocus(0, 0, 0, unused
);
1664 TRACE("-- NM_KILLFOCUS %p\n", this);
1666 /* Notify the ICommDlgBrowser interface */
1667 OnStateChange(CDBOSC_KILLFOCUS
);
1671 TRACE("-- NM_CUSTOMDRAW %p\n", this);
1672 return CDRF_DODEFAULT
;
1674 case NM_RELEASEDCAPTURE
:
1675 TRACE("-- NM_RELEASEDCAPTURE %p\n", this);
1679 TRACE("-- NM_CLICK %p\n", this);
1683 TRACE("-- NM_RCLICK %p\n", this);
1687 TRACE("-- NM_DBLCLK %p\n", this);
1688 OpenSelectedItems();
1692 TRACE("-- NM_RETURN %p\n", this);
1693 OpenSelectedItems();
1697 TRACE("-- HDN_ENDTRACKW %p\n", this);
1698 /*nColumn1 = m_ListView.GetColumnWidth(0);
1699 nColumn2 = m_ListView.GetColumnWidth(1);*/
1702 case LVN_DELETEITEM
:
1703 TRACE("-- LVN_DELETEITEM %p\n", this);
1705 /*delete the pidl because we made a copy of it*/
1706 SHFree(reinterpret_cast<LPVOID
>(lpnmlv
->lParam
));
1710 case LVN_DELETEALLITEMS
:
1711 TRACE("-- LVN_DELETEALLITEMS %p\n", this);
1714 case LVN_INSERTITEM
:
1715 TRACE("-- LVN_INSERTITEM (STUB)%p\n", this);
1718 case LVN_ITEMACTIVATE
:
1719 TRACE("-- LVN_ITEMACTIVATE %p\n", this);
1720 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1723 case LVN_COLUMNCLICK
:
1724 m_sortInfo
.nHeaderID
= lpnmlv
->iSubItem
;
1725 if (m_sortInfo
.nLastHeaderID
== m_sortInfo
.nHeaderID
)
1726 m_sortInfo
.bIsAscending
= !m_sortInfo
.bIsAscending
;
1728 m_sortInfo
.bIsAscending
= TRUE
;
1732 case LVN_GETDISPINFOA
:
1733 case LVN_GETDISPINFOW
:
1734 TRACE("-- LVN_GETDISPINFO %p\n", this);
1735 pidl
= _PidlByItem(lpdi
->item
);
1737 if (lpdi
->item
.mask
& LVIF_TEXT
) /* text requested */
1742 if (FAILED_UNEXPECTEDLY(m_pSF2Parent
->GetDetailsOf(pidl
, lpdi
->item
.iSubItem
, &sd
)))
1745 if (lpnmh
->code
== LVN_GETDISPINFOA
)
1747 /* shouldn't happen */
1748 NMLVDISPINFOA
*lpdiA
= (NMLVDISPINFOA
*)lpnmh
;
1749 StrRetToStrNA( lpdiA
->item
.pszText
, lpdiA
->item
.cchTextMax
, &sd
.str
, NULL
);
1750 TRACE("-- text=%s\n", lpdiA
->item
.pszText
);
1752 else /* LVN_GETDISPINFOW */
1754 StrRetToStrNW( lpdi
->item
.pszText
, lpdi
->item
.cchTextMax
, &sd
.str
, NULL
);
1755 TRACE("-- text=%s\n", debugstr_w(lpdi
->item
.pszText
));
1760 FIXME("no m_pSF2Parent\n");
1763 if(lpdi
->item
.mask
& LVIF_IMAGE
) /* image requested */
1765 lpdi
->item
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
1767 if(lpdi
->item
.mask
& LVIF_STATE
)
1769 ULONG attributes
= SFGAO_HIDDEN
;
1770 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(1, &pidl
, &attributes
)))
1772 if (attributes
& SFGAO_HIDDEN
)
1774 lpdi
->item
.state
|= LVIS_CUT
;
1778 lpdi
->item
.mask
|= LVIF_DI_SETITEM
;
1781 case LVN_ITEMCHANGED
:
1782 TRACE("-- LVN_ITEMCHANGED %p\n", this);
1783 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1785 _DoFolderViewCB(SFVM_SELECTIONCHANGED
, NULL
/* FIXME */, NULL
/* FIXME */);
1789 case LVN_BEGINRDRAG
:
1790 TRACE("-- LVN_BEGINDRAG\n");
1792 if (GetSelections())
1794 CComPtr
<IDataObject
> pda
;
1795 DWORD dwAttributes
= SFGAO_CANCOPY
| SFGAO_CANLINK
;
1796 DWORD dwEffect
= DROPEFFECT_MOVE
;
1798 if (SUCCEEDED(m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, IID_NULL_PPV_ARG(IDataObject
, &pda
))))
1800 LPNMLISTVIEW params
= (LPNMLISTVIEW
)lParam
;
1802 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(m_cidl
, m_apidl
, &dwAttributes
)))
1804 dwEffect
|= dwAttributes
& (SFGAO_CANCOPY
| SFGAO_CANLINK
);
1807 CComPtr
<IAsyncOperation
> piaso
;
1808 if (SUCCEEDED(pda
->QueryInterface(IID_PPV_ARG(IAsyncOperation
, &piaso
))))
1810 piaso
->SetAsyncMode(TRUE
);
1815 m_pSourceDataObject
= pda
;
1816 m_ptFirstMousePos
= params
->ptAction
;
1817 ClientToScreen(&m_ptFirstMousePos
);
1819 HIMAGELIST big_icons
, small_icons
;
1820 Shell_GetImageLists(&big_icons
, &small_icons
);
1821 PCUITEMID_CHILD pidl
= _PidlByItem(params
->iItem
);
1822 int iIcon
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
1824 m_ListView
.GetItemPosition(params
->iItem
, &ptItem
);
1826 ImageList_BeginDrag(big_icons
, iIcon
, params
->ptAction
.x
- ptItem
.x
, params
->ptAction
.y
- ptItem
.y
);
1828 DoDragDrop(pda
, this, dwEffect
, &dwEffect2
);
1830 m_pSourceDataObject
.Release();
1835 case LVN_BEGINLABELEDITW
:
1837 DWORD dwAttr
= SFGAO_CANRENAME
;
1838 pidl
= _PidlByItem(lpdi
->item
);
1840 TRACE("-- LVN_BEGINLABELEDITW %p\n", this);
1842 m_pSFParent
->GetAttributesOf(1, &pidl
, &dwAttr
);
1843 if (SFGAO_CANRENAME
& dwAttr
)
1851 case LVN_ENDLABELEDITW
:
1853 TRACE("-- LVN_ENDLABELEDITW %p\n", this);
1855 m_isEditing
= FALSE
;
1857 if (lpdi
->item
.pszText
)
1862 pidl
= _PidlByItem(lpdi
->item
);
1863 PITEMID_CHILD pidlNew
;
1864 hr
= m_pSFParent
->SetNameOf(0, pidl
, lpdi
->item
.pszText
, SHGDN_INFOLDER
, &pidlNew
);
1866 if (SUCCEEDED(hr
) && pidlNew
)
1868 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
1869 lvItem
.iItem
= lpdi
->item
.iItem
;
1870 lvItem
.iSubItem
= 0;
1871 lvItem
.lParam
= reinterpret_cast<LPARAM
>(pidlNew
);
1872 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
1873 m_ListView
.SetItem(&lvItem
);
1874 m_ListView
.Update(lpdi
->item
.iItem
);
1883 TRACE("-- %p WM_COMMAND %x unhandled\n", this, lpnmh
->code
);
1891 * This is just a quick hack to make the desktop work correctly.
1892 * ITranslateShellChangeNotify's IsChildID is undocumented, but most likely the way that
1893 * a folder should know if it should update upon a change notification.
1894 * It is exported by merged folders at a minimum.
1896 static BOOL
ILIsParentOrSpecialParent(PCIDLIST_ABSOLUTE pidl1
, PCIDLIST_ABSOLUTE pidl2
)
1898 if (!pidl1
|| !pidl2
)
1900 if (ILIsParent(pidl1
, pidl2
, TRUE
))
1903 if (_ILIsDesktop(pidl1
))
1905 PIDLIST_ABSOLUTE deskpidl
;
1906 SHGetFolderLocation(NULL
, CSIDL_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
1907 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
1913 SHGetFolderLocation(NULL
, CSIDL_COMMON_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
1914 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
1924 /**********************************************************
1925 * ShellView_OnChange()
1927 LRESULT
CDefView::OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1929 PCIDLIST_ABSOLUTE
*Pidls
= reinterpret_cast<PCIDLIST_ABSOLUTE
*>(wParam
);
1930 BOOL bParent0
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[0]);
1931 BOOL bParent1
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[1]);
1933 TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls
[0], Pidls
[1], lParam
);
1935 switch (lParam
&~ SHCNE_INTERRUPT
)
1941 if (LV_FindItemByPidl(ILFindLastID(Pidls
[0])) == -1)
1943 LV_AddItem(ILFindLastID(Pidls
[0]));
1947 LV_ProdItem(ILFindLastID(Pidls
[0]));
1955 LV_DeleteItem(ILFindLastID(Pidls
[0]));
1958 case SHCNE_RENAMEFOLDER
:
1959 case SHCNE_RENAMEITEM
:
1960 if (bParent0
&& bParent1
)
1961 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[1]));
1963 LV_DeleteItem(ILFindLastID(Pidls
[0]));
1965 LV_AddItem(ILFindLastID(Pidls
[1]));
1968 case SHCNE_UPDATEITEM
:
1970 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[0]));
1973 case SHCNE_UPDATEDIR
:
1980 HRESULT
SHGetMenuIdFromMenuMsg(UINT uMsg
, LPARAM lParam
, UINT
*CmdId
);
1981 HRESULT
SHSetMenuIdInMenuMsg(UINT uMsg
, LPARAM lParam
, UINT CmdId
);
1983 /**********************************************************
1984 * CDefView::OnCustomItem
1986 LRESULT
CDefView::OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1991 ERR("no menu!!!\n");
1995 /* The lParam of WM_DRAWITEM WM_MEASUREITEM contain a menu id and this also needs to
1996 be changed to a menu identifier offset */
1998 HRESULT hres
= SHGetMenuIdFromMenuMsg(uMsg
, lParam
, &CmdID
);
1999 if (SUCCEEDED(hres
))
2000 SHSetMenuIdInMenuMsg(uMsg
, lParam
, CmdID
- CONTEXT_MENU_BASE_ID
);
2002 /* Forward the message to the IContextMenu2 */
2004 hres
= SHForwardContextMenuMsg(m_pCM
, uMsg
, wParam
, lParam
, &result
, TRUE
);
2006 return (SUCCEEDED(hres
));
2009 LRESULT
CDefView::OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
2011 /* Wallpaper setting affects drop shadows effect */
2012 if (wParam
== SPI_SETDESKWALLPAPER
|| wParam
== 0)
2018 /**********************************************************
2019 * CDefView::OnInitMenuPopup
2021 LRESULT
CDefView::OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
2023 HMENU hmenu
= (HMENU
) wParam
;
2024 int nPos
= LOWORD(lParam
);
2027 OnCustomItem(uMsg
, wParam
, lParam
, bHandled
);
2029 HMENU hViewMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_VIEW
);
2031 /* Lets try to find out what the hell wParam is */
2032 if (hmenu
== GetSubMenu(m_hMenu
, nPos
))
2033 menuItemId
= ReallyGetMenuItemID(m_hMenu
, nPos
);
2034 else if (hViewMenu
&& hmenu
== GetSubMenu(hViewMenu
, nPos
))
2035 menuItemId
= ReallyGetMenuItemID(hViewMenu
, nPos
);
2036 else if (m_hContextMenu
&& hmenu
== GetSubMenu(m_hContextMenu
, nPos
))
2037 menuItemId
= ReallyGetMenuItemID(m_hContextMenu
, nPos
);
2043 case FCIDM_MENU_FILE
:
2046 case FCIDM_MENU_VIEW
:
2047 case FCIDM_SHVIEW_VIEW
:
2048 CheckViewMode(hmenu
);
2050 case FCIDM_SHVIEW_ARRANGE
:
2051 FillArrangeAsMenu(hmenu
);
2058 /**********************************************************
2061 * The INTERFACE of the IShellView object
2064 **********************************************************
2067 /**********************************************************
2068 * ShellView_GetWindow
2070 HRESULT WINAPI
CDefView::GetWindow(HWND
*phWnd
)
2072 TRACE("(%p)\n", this);
2079 HRESULT WINAPI
CDefView::ContextSensitiveHelp(BOOL fEnterMode
)
2081 FIXME("(%p) stub\n", this);
2086 /**********************************************************
2087 * IShellView_TranslateAccelerator
2090 * use the accel functions
2092 HRESULT WINAPI
CDefView::TranslateAccelerator(LPMSG lpmsg
)
2097 if (lpmsg
->message
>= WM_KEYFIRST
&& lpmsg
->message
<= WM_KEYLAST
)
2099 if (::TranslateAcceleratorW(m_hWnd
, m_hAccel
, lpmsg
) != 0)
2102 TRACE("-- key=0x%04lx\n", lpmsg
->wParam
) ;
2105 return m_pShellBrowser
->TranslateAcceleratorSB(lpmsg
, 0);
2108 HRESULT WINAPI
CDefView::EnableModeless(BOOL fEnable
)
2110 FIXME("(%p) stub\n", this);
2115 HRESULT WINAPI
CDefView::UIActivate(UINT uState
)
2117 // CHAR szName[MAX_PATH];
2119 int nPartArray
[1] = { -1};
2121 TRACE("(%p)->(state=%x) stub\n", this, uState
);
2123 /* don't do anything if the state isn't really changing */
2124 if (m_uState
== uState
)
2129 /* OnActivate handles the menu merging and internal state */
2132 /* only do This if we are active */
2133 if (uState
!= SVUIA_DEACTIVATE
)
2137 GetFolderPath is not a method of IShellFolder
2138 IShellFolder_GetFolderPath( m_pSFParent, szName, sizeof(szName) );
2140 /* set the number of parts */
2141 m_pShellBrowser
->SendControlMsg(FCW_STATUS
, SB_SETPARTS
, 1, (LPARAM
)nPartArray
, &lResult
);
2143 /* set the text for the parts */
2145 m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXTA, 0, (LPARAM)szName, &lResult);
2152 HRESULT WINAPI
CDefView::Refresh()
2154 TRACE("(%p)\n", this);
2156 m_ListView
.DeleteAllItems();
2162 HRESULT WINAPI
CDefView::CreateViewWindow(IShellView
*lpPrevView
, LPCFOLDERSETTINGS lpfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
)
2164 return CreateViewWindow3(psb
, lpPrevView
, SV3CVW3_DEFAULT
,
2165 (FOLDERFLAGS
)lpfs
->fFlags
, (FOLDERFLAGS
)lpfs
->fFlags
, (FOLDERVIEWMODE
)lpfs
->ViewMode
, NULL
, prcView
, phWnd
);
2168 HRESULT WINAPI
CDefView::DestroyViewWindow()
2170 TRACE("(%p)\n", this);
2172 /* Make absolutely sure all our UI is cleaned up */
2173 UIActivate(SVUIA_DEACTIVATE
);
2177 // "Accelerator tables loaded from resources are freed automatically when the application terminates." -- MSDN
2181 if (m_hMenuArrangeModes
)
2183 DestroyMenu(m_hMenuArrangeModes
);
2184 m_hMenuArrangeModes
= NULL
;
2187 if (m_hMenuViewModes
)
2189 DestroyMenu(m_hMenuViewModes
);
2190 m_hMenuViewModes
= NULL
;
2195 DestroyMenu(m_hMenu
);
2201 m_ListView
.DestroyWindow();
2209 m_pShellBrowser
.Release();
2210 m_pCommDlgBrowser
.Release();
2215 HRESULT WINAPI
CDefView::GetCurrentInfo(LPFOLDERSETTINGS lpfs
)
2217 TRACE("(%p)->(%p) vmode=%x flags=%x\n", this, lpfs
,
2218 m_FolderSettings
.ViewMode
, m_FolderSettings
.fFlags
);
2221 return E_INVALIDARG
;
2223 *lpfs
= m_FolderSettings
;
2227 HRESULT WINAPI
CDefView::AddPropertySheetPages(DWORD dwReserved
, LPFNADDPROPSHEETPAGE lpfn
, LPARAM lparam
)
2229 FIXME("(%p) stub\n", this);
2234 HRESULT WINAPI
CDefView::SaveViewState()
2236 FIXME("(%p) stub\n", this);
2241 HRESULT WINAPI
CDefView::SelectItem(PCUITEMID_CHILD pidl
, UINT uFlags
)
2245 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n", this, pidl
, uFlags
);
2247 i
= LV_FindItemByPidl(pidl
);
2251 if(uFlags
& SVSI_ENSUREVISIBLE
)
2252 m_ListView
.EnsureVisible(i
, FALSE
);
2254 LVITEMW lvItem
= {0};
2255 lvItem
.mask
= LVIF_STATE
;
2256 lvItem
.stateMask
= LVIS_SELECTED
| LVIS_FOCUSED
;
2258 while (m_ListView
.GetItem(&lvItem
))
2260 if (lvItem
.iItem
== i
)
2262 if (uFlags
& SVSI_SELECT
)
2263 lvItem
.state
|= LVIS_SELECTED
;
2265 lvItem
.state
&= ~LVIS_SELECTED
;
2267 if (uFlags
& SVSI_FOCUSED
)
2268 lvItem
.state
&= ~LVIS_FOCUSED
;
2272 if (uFlags
& SVSI_DESELECTOTHERS
)
2273 lvItem
.state
&= ~LVIS_SELECTED
;
2276 m_ListView
.SetItem(&lvItem
);
2280 if((uFlags
& SVSI_EDIT
) == SVSI_EDIT
)
2281 m_ListView
.EditLabel(i
);
2286 HRESULT WINAPI
CDefView::GetItemObject(UINT uItem
, REFIID riid
, LPVOID
*ppvOut
)
2288 HRESULT hr
= E_NOINTERFACE
;
2290 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n", this, uItem
, debugstr_guid(&riid
), ppvOut
);
2296 case SVGIO_BACKGROUND
:
2297 if (IsEqualIID(riid
, IID_IContextMenu
))
2302 hr
= CDefViewBckgrndMenu_CreateInstance(m_pSF2Parent
, riid
, ppvOut
);
2303 if (FAILED_UNEXPECTEDLY(hr
))
2306 IUnknown_SetSite(*((IUnknown
**)ppvOut
), (IShellView
*)this);
2308 else if (IsEqualIID(riid
, IID_IDispatch
))
2310 if (m_pShellFolderViewDual
== NULL
)
2312 hr
= CDefViewDual_Constructor(riid
, (LPVOID
*)&m_pShellFolderViewDual
);
2313 if (FAILED_UNEXPECTEDLY(hr
))
2316 hr
= m_pShellFolderViewDual
->QueryInterface(riid
, ppvOut
);
2320 case SVGIO_SELECTION
:
2322 hr
= m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, riid
, 0, ppvOut
);
2323 if (FAILED_UNEXPECTEDLY(hr
))
2326 if (IsEqualIID(riid
, IID_IContextMenu
))
2327 IUnknown_SetSite(*((IUnknown
**)ppvOut
), (IShellView
*)this);
2332 TRACE("-- (%p)->(interface=%p)\n", this, *ppvOut
);
2337 HRESULT STDMETHODCALLTYPE
CDefView::GetCurrentViewMode(UINT
*pViewMode
)
2339 TRACE("(%p)->(%p), stub\n", this, pViewMode
);
2342 return E_INVALIDARG
;
2344 *pViewMode
= m_FolderSettings
.ViewMode
;
2348 HRESULT STDMETHODCALLTYPE
CDefView::SetCurrentViewMode(UINT ViewMode
)
2351 TRACE("(%p)->(%u), stub\n", this, ViewMode
);
2353 /* It's not redundant to check FVM_AUTO because it's a (UINT)-1 */
2354 if (((INT
)ViewMode
< FVM_FIRST
|| (INT
)ViewMode
> FVM_LAST
) && ((INT
)ViewMode
!= FVM_AUTO
))
2355 return E_INVALIDARG
;
2357 /* Windows before Vista uses LVM_SETVIEW and possibly
2358 LVM_SETEXTENDEDLISTVIEWSTYLE to set the style of the listview,
2359 while later versions seem to accomplish this through other
2367 dwStyle
= LVS_REPORT
;
2370 dwStyle
= LVS_SMALLICON
;
2377 FIXME("ViewMode %d not implemented\n", ViewMode
);
2383 m_ListView
.ModifyStyle(LVS_TYPEMASK
, dwStyle
);
2385 /* This will not necessarily be the actual mode set above.
2386 This mimics the behavior of Windows XP. */
2387 m_FolderSettings
.ViewMode
= ViewMode
;
2392 HRESULT STDMETHODCALLTYPE
CDefView::GetFolder(REFIID riid
, void **ppv
)
2394 if (m_pSFParent
== NULL
)
2397 return m_pSFParent
->QueryInterface(riid
, ppv
);
2400 HRESULT STDMETHODCALLTYPE
CDefView::Item(int iItemIndex
, PITEMID_CHILD
*ppidl
)
2402 PCUITEMID_CHILD pidl
= _PidlByItem(iItemIndex
);
2405 *ppidl
= ILClone(pidl
);
2410 return E_INVALIDARG
;
2413 HRESULT STDMETHODCALLTYPE
CDefView::ItemCount(UINT uFlags
, int *pcItems
)
2415 TRACE("(%p)->(%u %p)\n", this, uFlags
, pcItems
);
2417 if (uFlags
!= SVGIO_ALLVIEW
)
2418 FIXME("some flags unsupported, %x\n", uFlags
& ~SVGIO_ALLVIEW
);
2420 *pcItems
= m_ListView
.GetItemCount();
2425 HRESULT STDMETHODCALLTYPE
CDefView::Items(UINT uFlags
, REFIID riid
, void **ppv
)
2430 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectionMarkedItem(int *piItem
)
2432 TRACE("(%p)->(%p)\n", this, piItem
);
2434 *piItem
= m_ListView
.GetSelectionMark();
2439 HRESULT STDMETHODCALLTYPE
CDefView::GetFocusedItem(int *piItem
)
2441 TRACE("(%p)->(%p)\n", this, piItem
);
2443 *piItem
= m_ListView
.GetNextItem(-1, LVNI_FOCUSED
);
2448 HRESULT STDMETHODCALLTYPE
CDefView::GetItemPosition(PCUITEMID_CHILD pidl
, POINT
*ppt
)
2450 int lvIndex
= LV_FindItemByPidl(pidl
);
2451 if (lvIndex
== -1 || ppt
== NULL
)
2452 return E_INVALIDARG
;
2454 m_ListView
.GetItemPosition(lvIndex
, ppt
);
2458 HRESULT STDMETHODCALLTYPE
CDefView::GetSpacing(POINT
*ppt
)
2460 TRACE("(%p)->(%p)\n", this, ppt
);
2468 m_ListView
.GetItemSpacing(spacing
);
2470 ppt
->x
= spacing
.cx
;
2471 ppt
->y
= spacing
.cy
;
2477 HRESULT STDMETHODCALLTYPE
CDefView::GetDefaultSpacing(POINT
*ppt
)
2482 HRESULT STDMETHODCALLTYPE
CDefView::GetAutoArrange()
2484 return ((m_ListView
.GetStyle() & LVS_AUTOARRANGE
) ? S_OK
: S_FALSE
);
2487 HRESULT STDMETHODCALLTYPE
CDefView::SelectItem(int iItem
, DWORD dwFlags
)
2491 TRACE("(%p)->(%d, %x)\n", this, iItem
, dwFlags
);
2494 lvItem
.stateMask
= LVIS_SELECTED
;
2496 if (dwFlags
& SVSI_ENSUREVISIBLE
)
2497 m_ListView
.EnsureVisible(iItem
, 0);
2500 if (dwFlags
& SVSI_DESELECTOTHERS
)
2501 m_ListView
.SetItemState(-1, 0, LVIS_SELECTED
);
2504 if (dwFlags
& SVSI_SELECT
)
2505 lvItem
.state
|= LVIS_SELECTED
;
2507 if (dwFlags
& SVSI_FOCUSED
)
2508 lvItem
.stateMask
|= LVIS_FOCUSED
;
2510 m_ListView
.SetItemState(iItem
, lvItem
.state
, lvItem
.stateMask
);
2512 if ((dwFlags
& SVSI_EDIT
) == SVSI_EDIT
)
2513 m_ListView
.EditLabel(iItem
);
2518 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItems(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD dwFlags
)
2520 /* Reset the selection */
2521 m_ListView
.SetItemState(-1, 0, LVIS_SELECTED
);
2524 for (UINT i
= 0 ; i
< m_cidl
; i
++)
2526 lvIndex
= LV_FindItemByPidl(apidl
[i
]);
2529 SelectItem(lvIndex
, dwFlags
);
2530 m_ListView
.SetItemPosition(lvIndex
, &apt
[i
]);
2537 /**********************************************************
2538 * IShellView2 implementation
2541 HRESULT STDMETHODCALLTYPE
CDefView::GetView(SHELLVIEWID
*view_guid
, ULONG view_type
)
2543 FIXME("(%p)->(%p, %lu) stub\n", this, view_guid
, view_type
);
2547 HRESULT STDMETHODCALLTYPE
CDefView::CreateViewWindow2(LPSV2CVW2_PARAMS view_params
)
2549 return CreateViewWindow3(view_params
->psbOwner
, view_params
->psvPrev
,
2550 SV3CVW3_DEFAULT
, (FOLDERFLAGS
)view_params
->pfs
->fFlags
, (FOLDERFLAGS
)view_params
->pfs
->fFlags
,
2551 (FOLDERVIEWMODE
)view_params
->pfs
->ViewMode
, view_params
->pvid
, view_params
->prcView
, &view_params
->hwndView
);
2554 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
)
2556 OLEMENUGROUPWIDTHS omw
= { { 0, 0, 0, 0, 0, 0 } };
2560 TRACE("(%p)->(shlview=%p shlbrs=%p rec=%p hwnd=%p vmode=%x flags=%x)\n", this, psvPrevious
, psb
, prcView
, hwnd
, mode
, flags
);
2561 if (prcView
!= NULL
)
2562 TRACE("-- left=%i top=%i right=%i bottom=%i\n", prcView
->left
, prcView
->top
, prcView
->right
, prcView
->bottom
);
2564 /* Validate the Shell Browser */
2565 if (psb
== NULL
|| m_hWnd
)
2566 return E_UNEXPECTED
;
2568 if (view_flags
!= SV3CVW3_DEFAULT
)
2569 FIXME("unsupported view flags 0x%08x\n", view_flags
);
2571 /* Set up the member variables */
2572 m_pShellBrowser
= psb
;
2573 m_FolderSettings
.ViewMode
= mode
;
2574 m_FolderSettings
.fFlags
= mask
& flags
;
2578 if (IsEqualIID(*view_id
, VID_LargeIcons
))
2579 m_FolderSettings
.ViewMode
= FVM_ICON
;
2580 else if (IsEqualIID(*view_id
, VID_SmallIcons
))
2581 m_FolderSettings
.ViewMode
= FVM_SMALLICON
;
2582 else if (IsEqualIID(*view_id
, VID_List
))
2583 m_FolderSettings
.ViewMode
= FVM_LIST
;
2584 else if (IsEqualIID(*view_id
, VID_Details
))
2585 m_FolderSettings
.ViewMode
= FVM_DETAILS
;
2586 else if (IsEqualIID(*view_id
, VID_Thumbnails
))
2587 m_FolderSettings
.ViewMode
= FVM_THUMBNAIL
;
2588 else if (IsEqualIID(*view_id
, VID_Tile
))
2589 m_FolderSettings
.ViewMode
= FVM_TILE
;
2590 else if (IsEqualIID(*view_id
, VID_ThumbStrip
))
2591 m_FolderSettings
.ViewMode
= FVM_THUMBSTRIP
;
2593 FIXME("Ignoring unrecognized VID %s\n", debugstr_guid(view_id
));
2596 /* Get our parent window */
2597 m_pShellBrowser
->GetWindow(&m_hWndParent
);
2599 /* Try to get the ICommDlgBrowserInterface, adds a reference !!! */
2600 m_pCommDlgBrowser
= NULL
;
2601 if (SUCCEEDED(m_pShellBrowser
->QueryInterface(IID_PPV_ARG(ICommDlgBrowser
, &m_pCommDlgBrowser
))))
2603 TRACE("-- CommDlgBrowser\n");
2606 Create(m_hWndParent
, prcView
, NULL
, WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
| WS_TABSTOP
, 0, 0U);
2617 _DoFolderViewCB(SFVM_WINDOWCREATED
, (WPARAM
)m_hWnd
, NULL
);
2619 SetWindowPos(HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_SHOWWINDOW
);
2624 m_hMenu
= CreateMenu();
2625 m_pShellBrowser
->InsertMenusSB(m_hMenu
, &omw
);
2626 TRACE("-- after fnInsertMenusSB\n");
2634 HRESULT STDMETHODCALLTYPE
CDefView::HandleRename(LPCITEMIDLIST new_pidl
)
2636 FIXME("(%p)->(%p) stub\n", this, new_pidl
);
2640 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItem(LPCITEMIDLIST item
, UINT flags
, POINT
*point
)
2642 FIXME("(%p)->(%p, %u, %p) stub\n", this, item
, flags
, point
);
2646 /**********************************************************
2647 * IShellFolderView implementation
2649 HRESULT STDMETHODCALLTYPE
CDefView::Rearrange(LPARAM sort
)
2651 FIXME("(%p)->(%ld) stub\n", this, sort
);
2655 HRESULT STDMETHODCALLTYPE
CDefView::GetArrangeParam(LPARAM
*sort
)
2657 FIXME("(%p)->(%p) stub\n", this, sort
);
2661 HRESULT STDMETHODCALLTYPE
CDefView::ArrangeGrid()
2663 FIXME("(%p) stub\n", this);
2667 HRESULT STDMETHODCALLTYPE
CDefView::AutoArrange()
2669 m_ListView
.ModifyStyle(0, LVS_AUTOARRANGE
);
2670 m_ListView
.Arrange(LVA_DEFAULT
);
2674 HRESULT STDMETHODCALLTYPE
CDefView::AddObject(PITEMID_CHILD pidl
, UINT
*item
)
2676 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2680 HRESULT STDMETHODCALLTYPE
CDefView::GetObject(PITEMID_CHILD
*pidl
, UINT item
)
2682 TRACE("(%p)->(%p %d)\n", this, pidl
, item
);
2683 return Item(item
, pidl
);
2686 HRESULT STDMETHODCALLTYPE
CDefView::RemoveObject(PITEMID_CHILD pidl
, UINT
*item
)
2689 TRACE("(%p)->(%p %p)\n", this, pidl
, item
);
2693 *item
= LV_FindItemByPidl(ILFindLastID(pidl
));
2694 m_ListView
.DeleteItem(*item
);
2699 m_ListView
.DeleteAllItems();
2705 HRESULT STDMETHODCALLTYPE
CDefView::GetObjectCount(UINT
*count
)
2707 TRACE("(%p)->(%p)\n", this, count
);
2708 *count
= m_ListView
.GetItemCount();
2712 HRESULT STDMETHODCALLTYPE
CDefView::SetObjectCount(UINT count
, UINT flags
)
2714 FIXME("(%p)->(%d %x) stub\n", this, count
, flags
);
2718 HRESULT STDMETHODCALLTYPE
CDefView::UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
)
2720 FIXME("(%p)->(%p %p %p) stub\n", this, pidl_old
, pidl_new
, item
);
2724 HRESULT STDMETHODCALLTYPE
CDefView::RefreshObject(PITEMID_CHILD pidl
, UINT
*item
)
2726 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2730 HRESULT STDMETHODCALLTYPE
CDefView::SetRedraw(BOOL redraw
)
2732 TRACE("(%p)->(%d)\n", this, redraw
);
2733 m_ListView
.SetRedraw(redraw
);
2737 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedCount(UINT
*count
)
2739 FIXME("(%p)->(%p) stub\n", this, count
);
2743 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
)
2745 TRACE("(%p)->(%p %p)\n", this, pidl
, items
);
2747 *items
= GetSelections();
2751 *pidl
= static_cast<PCUITEMID_CHILD
*>(LocalAlloc(0, *items
* sizeof(PCUITEMID_CHILD
)));
2754 return E_OUTOFMEMORY
;
2757 /* it's documented that caller shouldn't PIDLs, only array itself */
2758 memcpy(*pidl
, m_apidl
, *items
* sizeof(PCUITEMID_CHILD
));
2764 HRESULT STDMETHODCALLTYPE
CDefView::IsDropOnSource(IDropTarget
*drop_target
)
2766 if ((m_iDragOverItem
== -1 || m_pCurDropTarget
== NULL
) &&
2767 (m_pSourceDataObject
.p
))
2775 HRESULT STDMETHODCALLTYPE
CDefView::GetDragPoint(POINT
*pt
)
2778 return E_INVALIDARG
;
2780 *pt
= m_ptFirstMousePos
;
2784 HRESULT STDMETHODCALLTYPE
CDefView::GetDropPoint(POINT
*pt
)
2786 FIXME("(%p)->(%p) stub\n", this, pt
);
2790 HRESULT STDMETHODCALLTYPE
CDefView::MoveIcons(IDataObject
*obj
)
2792 TRACE("(%p)->(%p)\n", this, obj
);
2796 HRESULT STDMETHODCALLTYPE
CDefView::SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
)
2798 FIXME("(%p)->(%p %p) stub\n", this, pidl
, pt
);
2802 HRESULT STDMETHODCALLTYPE
CDefView::IsBkDropTarget(IDropTarget
*drop_target
)
2804 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2808 HRESULT STDMETHODCALLTYPE
CDefView::SetClipboard(BOOL move
)
2810 FIXME("(%p)->(%d) stub\n", this, move
);
2814 HRESULT STDMETHODCALLTYPE
CDefView::SetPoints(IDataObject
*obj
)
2816 FIXME("(%p)->(%p) stub\n", this, obj
);
2820 HRESULT STDMETHODCALLTYPE
CDefView::GetItemSpacing(ITEMSPACING
*spacing
)
2822 FIXME("(%p)->(%p) stub\n", this, spacing
);
2826 HRESULT STDMETHODCALLTYPE
CDefView::SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
)
2829 *old_cb
= m_pShellFolderViewCB
.Detach();
2831 m_pShellFolderViewCB
= new_cb
;
2835 HRESULT STDMETHODCALLTYPE
CDefView::Select(UINT flags
)
2837 FIXME("(%p)->(%d) stub\n", this, flags
);
2841 HRESULT STDMETHODCALLTYPE
CDefView::QuerySupport(UINT
*support
)
2843 TRACE("(%p)->(%p)\n", this, support
);
2847 HRESULT STDMETHODCALLTYPE
CDefView::SetAutomationObject(IDispatch
*disp
)
2849 FIXME("(%p)->(%p) stub\n", this, disp
);
2853 /**********************************************************
2854 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2856 HRESULT WINAPI
CDefView::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD
*prgCmds
, OLECMDTEXT
*pCmdText
)
2858 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
2859 this, pguidCmdGroup
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
2862 return E_INVALIDARG
;
2864 for (UINT i
= 0; i
< cCmds
; i
++)
2866 FIXME("\tprgCmds[%d].cmdID = %d\n", i
, prgCmds
[i
].cmdID
);
2867 prgCmds
[i
].cmdf
= 0;
2870 return OLECMDERR_E_UNKNOWNGROUP
;
2873 /**********************************************************
2874 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2876 * nCmdID is the OLECMDID_* enumeration
2878 HRESULT WINAPI
CDefView::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
2880 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2881 this, debugstr_guid(pguidCmdGroup
), nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2884 return OLECMDERR_E_UNKNOWNGROUP
;
2886 if (IsEqualCLSID(*pguidCmdGroup
, m_Category
))
2888 if (nCmdID
== FCIDM_SHVIEW_AUTOARRANGE
)
2890 if (V_VT(pvaIn
) != VT_INT_PTR
)
2891 return OLECMDERR_E_NOTSUPPORTED
;
2894 params
.cbSize
= sizeof(params
);
2895 params
.rcExclude
= *(RECT
*) V_INTREF(pvaIn
);
2897 if (m_hMenuViewModes
)
2899 /* Duplicate all but the last two items of the view modes menu */
2900 HMENU hmenuViewPopup
= CreatePopupMenu();
2901 Shell_MergeMenus(hmenuViewPopup
, m_hMenuViewModes
, 0, 0, 0xFFFF, 0);
2902 DeleteMenu(hmenuViewPopup
, GetMenuItemCount(hmenuViewPopup
) - 1, MF_BYPOSITION
);
2903 DeleteMenu(hmenuViewPopup
, GetMenuItemCount(hmenuViewPopup
) - 1, MF_BYPOSITION
);
2904 CheckViewMode(hmenuViewPopup
);
2905 TrackPopupMenuEx(hmenuViewPopup
, TPM_LEFTALIGN
| TPM_TOPALIGN
, params
.rcExclude
.left
, params
.rcExclude
.bottom
, m_hWndParent
, ¶ms
);
2906 ::DestroyMenu(hmenuViewPopup
);
2909 // pvaOut is VT_I4 with value 0x403 (cmd id of the new mode maybe?)
2910 V_VT(pvaOut
) = VT_I4
;
2911 V_I4(pvaOut
) = 0x403;
2915 if (IsEqualIID(*pguidCmdGroup
, CGID_Explorer
) &&
2917 (nCmdexecopt
== 4) && pvaOut
)
2920 if (IsEqualIID(*pguidCmdGroup
, CGID_ShellDocView
) &&
2925 return OLECMDERR_E_UNKNOWNGROUP
;
2928 /**********************************************************
2929 * ISVDropTarget implementation
2932 /******************************************************************************
2933 * drag_notify_subitem [Internal]
2935 * Figure out the shellfolder object, which is currently under the mouse cursor
2936 * and notify it via the IDropTarget interface.
2939 #define SCROLLAREAWIDTH 20
2941 HRESULT
CDefView::drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2947 /* The key state on drop doesn't have MK_LBUTTON or MK_RBUTTON because it
2948 reflects the key state after the user released the button, so we need
2949 to remember the last key state when the button was pressed */
2950 m_grfKeyState
= grfKeyState
;
2952 /* Map from global to client coordinates and query the index of the listview-item, which is
2953 * currently under the mouse cursor. */
2954 LVHITTESTINFO htinfo
= {{pt
.x
, pt
.y
}, LVHT_ONITEM
};
2955 ScreenToClient(&htinfo
.pt
);
2956 lResult
= m_ListView
.HitTest(&htinfo
);
2958 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2959 ::GetClientRect(m_ListView
, &clientRect
);
2960 if (htinfo
.pt
.x
== m_ptLastMousePos
.x
&& htinfo
.pt
.y
== m_ptLastMousePos
.y
&&
2961 (htinfo
.pt
.x
< SCROLLAREAWIDTH
|| htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
||
2962 htinfo
.pt
.y
< SCROLLAREAWIDTH
|| htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
))
2964 m_cScrollDelay
= (m_cScrollDelay
+ 1) % 5; /* DragOver is called every 50 ms */
2965 if (m_cScrollDelay
== 0)
2967 /* Mouse did hover another 250 ms over the scroll-area */
2968 if (htinfo
.pt
.x
< SCROLLAREAWIDTH
)
2969 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEUP
, 0);
2971 if (htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
)
2972 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEDOWN
, 0);
2974 if (htinfo
.pt
.y
< SCROLLAREAWIDTH
)
2975 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEUP
, 0);
2977 if (htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
)
2978 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEDOWN
, 0);
2983 m_cScrollDelay
= 0; /* Reset, if the cursor is not over the listview's scroll-area */
2986 m_ptLastMousePos
= htinfo
.pt
;
2988 /* We need to check if we drag the selection over itself */
2989 if (lResult
!= -1 && m_pSourceDataObject
.p
!= NULL
)
2991 PCUITEMID_CHILD pidl
= _PidlByItem(lResult
);
2993 for (UINT i
= 0; i
< m_cidl
; i
++)
2995 if (pidl
== m_apidl
[i
])
2997 /* The item that is being draged is hovering itself. */
3004 /* If we are still over the previous sub-item, notify it via DragOver and return. */
3005 if (m_pCurDropTarget
&& lResult
== m_iDragOverItem
)
3006 return m_pCurDropTarget
->DragOver(grfKeyState
, pt
, pdwEffect
);
3008 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
3009 if (m_pCurDropTarget
)
3011 PCUITEMID_CHILD pidl
= _PidlByItem(m_iDragOverItem
);
3013 SelectItem(pidl
, 0);
3015 m_pCurDropTarget
->DragLeave();
3016 m_pCurDropTarget
.Release();
3019 m_iDragOverItem
= lResult
;
3023 /* We are not above one of the listview's subitems. Bind to the parent folder's
3024 * DropTarget interface. */
3025 hr
= m_pSFParent
->CreateViewObject(NULL
, IID_PPV_ARG(IDropTarget
,&m_pCurDropTarget
));
3029 /* Query the relative PIDL of the shellfolder object represented by the currently
3030 * dragged over listview-item ... */
3031 PCUITEMID_CHILD pidl
= _PidlByItem(lResult
);
3033 /* ... and bind m_pCurDropTarget to the IDropTarget interface of an UIObject of this object */
3034 hr
= m_pSFParent
->GetUIObjectOf(m_ListView
, 1, &pidl
, IID_NULL_PPV_ARG(IDropTarget
, &m_pCurDropTarget
));
3037 IUnknown_SetSite(m_pCurDropTarget
, (IShellView
*)this);
3039 /* If anything failed, m_pCurDropTarget should be NULL now, which ought to be a save state. */
3042 *pdwEffect
= DROPEFFECT_NONE
;
3046 if (m_iDragOverItem
!= -1)
3048 SelectItem(m_iDragOverItem
, SVSI_SELECT
);
3051 /* Notify the item just entered via DragEnter. */
3052 return m_pCurDropTarget
->DragEnter(m_pCurDataObject
, grfKeyState
, pt
, pdwEffect
);
3055 HRESULT WINAPI
CDefView::DragEnter(IDataObject
*pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
3057 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
3058 m_pCurDataObject
= pDataObject
;
3060 HRESULT hr
= drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
3063 POINT ptClient
= {pt
.x
, pt
.y
};
3064 ScreenToClient(&ptClient
);
3065 ImageList_DragEnter(m_hWnd
, ptClient
.x
, ptClient
.y
);
3071 HRESULT WINAPI
CDefView::DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
3073 POINT ptClient
= {pt
.x
, pt
.y
};
3074 ScreenToClient(&ptClient
);
3075 ImageList_DragMove(ptClient
.x
, ptClient
.y
);
3076 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
3079 HRESULT WINAPI
CDefView::DragLeave()
3081 ImageList_DragLeave(m_hWnd
);
3083 if (m_pCurDropTarget
)
3085 m_pCurDropTarget
->DragLeave();
3086 m_pCurDropTarget
.Release();
3089 if (m_pCurDataObject
!= NULL
)
3091 m_pCurDataObject
.Release();
3094 m_iDragOverItem
= 0;
3099 HRESULT WINAPI
CDefView::Drop(IDataObject
* pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
3101 ImageList_DragLeave(m_hWnd
);
3102 ImageList_EndDrag();
3104 if ((IsDropOnSource(NULL
) == S_OK
) &&
3105 (*pdwEffect
& DROPEFFECT_MOVE
) &&
3106 (m_grfKeyState
& MK_LBUTTON
))
3108 if (m_pCurDropTarget
)
3110 m_pCurDropTarget
->DragLeave();
3111 m_pCurDropTarget
.Release();
3114 /* Restore the selection */
3115 m_ListView
.SetItemState(-1, 0, LVIS_SELECTED
);
3116 for (UINT i
= 0 ; i
< m_cidl
; i
++)
3117 SelectItem(m_apidl
[i
], SVSI_SELECT
);
3119 /* Reposition the items */
3121 while ((lvIndex
= m_ListView
.GetNextItem(lvIndex
, LVNI_SELECTED
)) > -1)
3124 if (m_ListView
.GetItemPosition(lvIndex
, &ptItem
))
3126 ptItem
.x
+= pt
.x
- m_ptFirstMousePos
.x
;
3127 ptItem
.y
+= pt
.y
- m_ptFirstMousePos
.y
;
3128 m_ListView
.SetItemPosition(lvIndex
, &ptItem
);
3132 else if (m_pCurDropTarget
)
3134 m_pCurDropTarget
->Drop(pDataObject
, grfKeyState
, pt
, pdwEffect
);
3135 m_pCurDropTarget
.Release();
3138 m_pCurDataObject
.Release();
3139 m_iDragOverItem
= 0;
3143 /**********************************************************
3144 * ISVDropSource implementation
3147 HRESULT WINAPI
CDefView::QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
)
3149 TRACE("(%p)\n", this);
3152 return DRAGDROP_S_CANCEL
;
3153 else if (!(grfKeyState
& MK_LBUTTON
) && !(grfKeyState
& MK_RBUTTON
))
3154 return DRAGDROP_S_DROP
;
3159 HRESULT WINAPI
CDefView::GiveFeedback(DWORD dwEffect
)
3161 TRACE("(%p)\n", this);
3163 return DRAGDROP_S_USEDEFAULTCURSORS
;
3166 /**********************************************************
3167 * ISVViewObject implementation
3170 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
)
3172 FIXME("Stub: this=%p\n", this);
3177 HRESULT WINAPI
CDefView::GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
, HDC hicTargetDevice
, LOGPALETTE
**ppColorSet
)
3179 FIXME("Stub: this=%p\n", this);
3184 HRESULT WINAPI
CDefView::Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
)
3186 FIXME("Stub: this=%p\n", this);
3191 HRESULT WINAPI
CDefView::Unfreeze(DWORD dwFreeze
)
3193 FIXME("Stub: this=%p\n", this);
3198 HRESULT WINAPI
CDefView::SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
)
3200 FIXME("partial stub: %p 0x%08x 0x%08x %p\n", this, aspects
, advf
, pAdvSink
);
3202 /* FIXME: we set the AdviseSink, but never use it to send any advice */
3203 m_pAdvSink
= pAdvSink
;
3204 m_dwAspects
= aspects
;
3210 HRESULT WINAPI
CDefView::GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
)
3212 TRACE("this=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n", this, pAspects
, pAdvf
, ppAdvSink
);
3216 *ppAdvSink
= m_pAdvSink
;
3217 m_pAdvSink
.p
->AddRef();
3221 *pAspects
= m_dwAspects
;
3229 HRESULT STDMETHODCALLTYPE
CDefView::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
3231 if (IsEqualIID(guidService
, SID_IShellBrowser
))
3232 return m_pShellBrowser
->QueryInterface(riid
, ppvObject
);
3233 else if(IsEqualIID(guidService
, SID_IFolderView
))
3234 return QueryInterface(riid
, ppvObject
);
3236 return E_NOINTERFACE
;
3239 HRESULT
CDefView::_MergeToolbar()
3241 CComPtr
<IExplorerToolbar
> ptb
;
3244 hr
= IUnknown_QueryService(m_pShellBrowser
, IID_IExplorerToolbar
, IID_PPV_ARG(IExplorerToolbar
, &ptb
));
3248 m_Category
= CGID_DefViewFrame
;
3250 hr
= ptb
->SetCommandTarget(static_cast<IOleCommandTarget
*>(this), &m_Category
, 0);
3258 hr
= ptb
->AddButtons(&m_Category
, buttonsCount
, buttons
);
3266 HRESULT
CDefView::_DoFolderViewCB(UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
3268 if (m_pShellFolderViewCB
)
3270 return m_pShellFolderViewCB
->MessageSFVCB(uMsg
, wParam
, lParam
);
3272 return E_NOINTERFACE
;
3275 HRESULT
CDefView_CreateInstance(IShellFolder
*pFolder
, REFIID riid
, LPVOID
* ppvOut
)
3277 return ShellObjectCreatorInit
<CDefView
>(pFolder
, riid
, ppvOut
);
3280 HRESULT WINAPI
SHCreateShellFolderViewEx(
3281 LPCSFV psvcbi
, /* [in] shelltemplate struct */
3282 IShellView
**ppsv
) /* [out] IShellView pointer */
3284 CComPtr
<IShellView
> psv
;
3287 TRACE("sf=%p pidl=%p cb=%p mode=0x%08x parm=%p\n",
3288 psvcbi
->pshf
, psvcbi
->pidl
, psvcbi
->pfnCallback
,
3289 psvcbi
->fvm
, psvcbi
->psvOuter
);
3292 hRes
= CDefView_CreateInstance(psvcbi
->pshf
, IID_PPV_ARG(IShellView
, &psv
));
3293 if (FAILED_UNEXPECTEDLY(hRes
))
3296 *ppsv
= psv
.Detach();
3300 HRESULT WINAPI
SHCreateShellFolderView(const SFV_CREATE
*pcsfv
,
3303 CComPtr
<IShellView
> psv
;
3307 if (!pcsfv
|| pcsfv
->cbSize
!= sizeof(*pcsfv
))
3308 return E_INVALIDARG
;
3310 TRACE("sf=%p outer=%p callback=%p\n",
3311 pcsfv
->pshf
, pcsfv
->psvOuter
, pcsfv
->psfvcb
);
3313 hRes
= CDefView_CreateInstance(pcsfv
->pshf
, IID_PPV_ARG(IShellView
, &psv
));
3319 CComPtr
<IShellFolderView
> sfv
;
3320 if (SUCCEEDED(psv
->QueryInterface(IID_PPV_ARG(IShellFolderView
, &sfv
))))
3322 sfv
->SetCallback(pcsfv
->psfvcb
, NULL
);
3326 *ppsv
= psv
.Detach();