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
57 public CWindowImpl
<CDefView
, CWindow
, CControlWinTraits
>,
58 public CComObjectRootEx
<CComMultiThreadModelNoCS
>,
61 public IShellFolderView
,
62 public IOleCommandTarget
,
66 public IServiceProvider
69 CComPtr
<IShellFolder
> m_pSFParent
;
70 CComPtr
<IShellFolder2
> m_pSF2Parent
;
71 CComPtr
<IShellBrowser
> m_pShellBrowser
;
72 CComPtr
<ICommDlgBrowser
> m_pCommDlgBrowser
;
73 CComPtr
<IShellFolderViewDual
> m_pShellFolderViewDual
;
76 FOLDERSETTINGS m_FolderSettings
;
77 HMENU m_hMenu
; /* Handle to the menu bar of the browser */
78 HMENU m_hMenuArrangeModes
; /* Handle to the popup menu with the arrange modes */
79 HMENU m_hMenuViewModes
; /* Handle to the popup menu with the view modes */
80 HMENU m_hContextMenu
; /* Handle to the open context menu */
81 BOOL m_bmenuBarInitialized
;
84 PCUITEMID_CHILD
*m_apidl
;
85 PIDLIST_ABSOLUTE m_pidlParent
;
86 LISTVIEW_SORT_INFO m_sortInfo
;
87 ULONG m_hNotify
; /* Change notification handle */
91 CComPtr
<IAdviseSink
> m_pAdvSink
;
93 CComPtr
<IDataObject
> m_pSourceDataObject
;
94 CComPtr
<IDropTarget
> m_pCurDropTarget
; /* The sub-item, which is currently dragged over */
95 CComPtr
<IDataObject
> m_pCurDataObject
; /* The dragged data-object */
96 LONG m_iDragOverItem
; /* Dragged over item's index, iff m_pCurDropTarget != NULL */
97 UINT m_cScrollDelay
; /* Send a WM_*SCROLL msg every 250 ms during drag-scroll */
98 POINT m_ptLastMousePos
; /* Mouse position at last DragOver call */
99 POINT m_ptFirstMousePos
; /* Mouse position when the drag operation started */
101 CComPtr
<IContextMenu
> m_pCM
;
109 HRESULT
_MergeToolbar();
114 HRESULT WINAPI
Initialize(IShellFolder
*shellFolder
);
115 HRESULT
IncludeObject(PCUITEMID_CHILD pidl
);
116 HRESULT
OnDefaultCommand();
117 HRESULT
OnStateChange(UINT uFlags
);
118 void UpdateStatusbar();
120 void SetStyle(DWORD dwAdd
, DWORD dwRemove
);
122 void UpdateListColors();
124 static INT CALLBACK
ListViewCompareItems(LPARAM lParam1
, LPARAM lParam2
, LPARAM lpData
);
126 PCUITEMID_CHILD
_PidlByItem(int i
);
127 PCUITEMID_CHILD
_PidlByItem(LVITEM
& lvItem
);
128 int LV_FindItemByPidl(PCUITEMID_CHILD pidl
);
129 BOOLEAN
LV_AddItem(PCUITEMID_CHILD pidl
);
130 BOOLEAN
LV_DeleteItem(PCUITEMID_CHILD pidl
);
131 BOOLEAN
LV_RenameItem(PCUITEMID_CHILD pidlOld
, PCUITEMID_CHILD pidlNew
);
132 BOOLEAN
LV_ProdItem(PCUITEMID_CHILD pidl
);
133 static INT CALLBACK
fill_list(LPVOID ptr
, LPVOID arg
);
135 HRESULT
FillFileMenu();
136 HRESULT
FillEditMenu();
137 HRESULT
FillViewMenu();
138 HRESULT
FillArrangeAsMenu(HMENU hmenuArrange
);
139 HRESULT
CheckViewMode(HMENU hmenuView
);
140 UINT
GetSelections();
141 HRESULT
OpenSelectedItems();
143 void DoActivate(UINT uState
);
144 HRESULT
drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
145 HRESULT
InvokeContextMenuCommand(UINT uCommand
);
146 LRESULT
OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
);
148 // *** IOleWindow methods ***
149 virtual HRESULT STDMETHODCALLTYPE
GetWindow(HWND
*lphwnd
);
150 virtual HRESULT STDMETHODCALLTYPE
ContextSensitiveHelp(BOOL fEnterMode
);
152 // *** IShellView methods ***
153 virtual HRESULT STDMETHODCALLTYPE
TranslateAccelerator(MSG
*pmsg
);
154 virtual HRESULT STDMETHODCALLTYPE
EnableModeless(BOOL fEnable
);
155 virtual HRESULT STDMETHODCALLTYPE
UIActivate(UINT uState
);
156 virtual HRESULT STDMETHODCALLTYPE
Refresh();
157 virtual HRESULT STDMETHODCALLTYPE
CreateViewWindow(IShellView
*psvPrevious
, LPCFOLDERSETTINGS pfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
);
158 virtual HRESULT STDMETHODCALLTYPE
DestroyViewWindow();
159 virtual HRESULT STDMETHODCALLTYPE
GetCurrentInfo(LPFOLDERSETTINGS pfs
);
160 virtual HRESULT STDMETHODCALLTYPE
AddPropertySheetPages(DWORD dwReserved
, LPFNSVADDPROPSHEETPAGE pfn
, LPARAM lparam
);
161 virtual HRESULT STDMETHODCALLTYPE
SaveViewState();
162 virtual HRESULT STDMETHODCALLTYPE
SelectItem(PCUITEMID_CHILD pidlItem
, SVSIF uFlags
);
163 virtual HRESULT STDMETHODCALLTYPE
GetItemObject(UINT uItem
, REFIID riid
, void **ppv
);
165 // *** IShellView2 methods ***
166 virtual HRESULT STDMETHODCALLTYPE
GetView(SHELLVIEWID
*view_guid
, ULONG view_type
);
167 virtual HRESULT STDMETHODCALLTYPE
CreateViewWindow2(LPSV2CVW2_PARAMS view_params
);
168 virtual HRESULT STDMETHODCALLTYPE
HandleRename(LPCITEMIDLIST new_pidl
);
169 virtual HRESULT STDMETHODCALLTYPE
SelectAndPositionItem(LPCITEMIDLIST item
, UINT flags
, POINT
*point
);
171 // *** IShellView3 methods ***
172 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
);
174 // *** IFolderView methods ***
175 virtual HRESULT STDMETHODCALLTYPE
GetCurrentViewMode(UINT
*pViewMode
);
176 virtual HRESULT STDMETHODCALLTYPE
SetCurrentViewMode(UINT ViewMode
);
177 virtual HRESULT STDMETHODCALLTYPE
GetFolder(REFIID riid
, void **ppv
);
178 virtual HRESULT STDMETHODCALLTYPE
Item(int iItemIndex
, PITEMID_CHILD
*ppidl
);
179 virtual HRESULT STDMETHODCALLTYPE
ItemCount(UINT uFlags
, int *pcItems
);
180 virtual HRESULT STDMETHODCALLTYPE
Items(UINT uFlags
, REFIID riid
, void **ppv
);
181 virtual HRESULT STDMETHODCALLTYPE
GetSelectionMarkedItem(int *piItem
);
182 virtual HRESULT STDMETHODCALLTYPE
GetFocusedItem(int *piItem
);
183 virtual HRESULT STDMETHODCALLTYPE
GetItemPosition(PCUITEMID_CHILD pidl
, POINT
*ppt
);
184 virtual HRESULT STDMETHODCALLTYPE
GetSpacing(POINT
*ppt
);
185 virtual HRESULT STDMETHODCALLTYPE
GetDefaultSpacing(POINT
*ppt
);
186 virtual HRESULT STDMETHODCALLTYPE
GetAutoArrange();
187 virtual HRESULT STDMETHODCALLTYPE
SelectItem(int iItem
, DWORD dwFlags
);
188 virtual HRESULT STDMETHODCALLTYPE
SelectAndPositionItems(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD dwFlags
);
190 // *** IShellFolderView methods ***
191 virtual HRESULT STDMETHODCALLTYPE
Rearrange(LPARAM sort
);
192 virtual HRESULT STDMETHODCALLTYPE
GetArrangeParam(LPARAM
*sort
);
193 virtual HRESULT STDMETHODCALLTYPE
ArrangeGrid();
194 virtual HRESULT STDMETHODCALLTYPE
AutoArrange();
195 virtual HRESULT STDMETHODCALLTYPE
AddObject(PITEMID_CHILD pidl
, UINT
*item
);
196 virtual HRESULT STDMETHODCALLTYPE
GetObject(PITEMID_CHILD
*pidl
, UINT item
);
197 virtual HRESULT STDMETHODCALLTYPE
RemoveObject(PITEMID_CHILD pidl
, UINT
*item
);
198 virtual HRESULT STDMETHODCALLTYPE
GetObjectCount(UINT
*count
);
199 virtual HRESULT STDMETHODCALLTYPE
SetObjectCount(UINT count
, UINT flags
);
200 virtual HRESULT STDMETHODCALLTYPE
UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
);
201 virtual HRESULT STDMETHODCALLTYPE
RefreshObject(PITEMID_CHILD pidl
, UINT
*item
);
202 virtual HRESULT STDMETHODCALLTYPE
SetRedraw(BOOL redraw
);
203 virtual HRESULT STDMETHODCALLTYPE
GetSelectedCount(UINT
*count
);
204 virtual HRESULT STDMETHODCALLTYPE
GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
);
205 virtual HRESULT STDMETHODCALLTYPE
IsDropOnSource(IDropTarget
*drop_target
);
206 virtual HRESULT STDMETHODCALLTYPE
GetDragPoint(POINT
*pt
);
207 virtual HRESULT STDMETHODCALLTYPE
GetDropPoint(POINT
*pt
);
208 virtual HRESULT STDMETHODCALLTYPE
MoveIcons(IDataObject
*obj
);
209 virtual HRESULT STDMETHODCALLTYPE
SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
);
210 virtual HRESULT STDMETHODCALLTYPE
IsBkDropTarget(IDropTarget
*drop_target
);
211 virtual HRESULT STDMETHODCALLTYPE
SetClipboard(BOOL move
);
212 virtual HRESULT STDMETHODCALLTYPE
SetPoints(IDataObject
*obj
);
213 virtual HRESULT STDMETHODCALLTYPE
GetItemSpacing(ITEMSPACING
*spacing
);
214 virtual HRESULT STDMETHODCALLTYPE
SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
);
215 virtual HRESULT STDMETHODCALLTYPE
Select(UINT flags
);
216 virtual HRESULT STDMETHODCALLTYPE
QuerySupport(UINT
*support
);
217 virtual HRESULT STDMETHODCALLTYPE
SetAutomationObject(IDispatch
*disp
);
219 // *** IOleCommandTarget methods ***
220 virtual HRESULT STDMETHODCALLTYPE
QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
);
221 virtual HRESULT STDMETHODCALLTYPE
Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
);
223 // *** IDropTarget methods ***
224 virtual HRESULT STDMETHODCALLTYPE
DragEnter(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
225 virtual HRESULT STDMETHODCALLTYPE
DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
226 virtual HRESULT STDMETHODCALLTYPE
DragLeave();
227 virtual HRESULT STDMETHODCALLTYPE
Drop(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
229 // *** IDropSource methods ***
230 virtual HRESULT STDMETHODCALLTYPE
QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
);
231 virtual HRESULT STDMETHODCALLTYPE
GiveFeedback(DWORD dwEffect
);
233 // *** IViewObject methods ***
234 virtual HRESULT STDMETHODCALLTYPE
Draw(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
,
235 HDC hdcTargetDev
, HDC hdcDraw
, LPCRECTL lprcBounds
, LPCRECTL lprcWBounds
,
236 BOOL ( STDMETHODCALLTYPE
*pfnContinue
)(ULONG_PTR dwContinue
), ULONG_PTR dwContinue
);
237 virtual HRESULT STDMETHODCALLTYPE
GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
,
238 DVTARGETDEVICE
*ptd
, HDC hicTargetDev
, LOGPALETTE
**ppColorSet
);
239 virtual HRESULT STDMETHODCALLTYPE
Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
);
240 virtual HRESULT STDMETHODCALLTYPE
Unfreeze(DWORD dwFreeze
);
241 virtual HRESULT STDMETHODCALLTYPE
SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
);
242 virtual HRESULT STDMETHODCALLTYPE
GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
);
244 // *** IServiceProvider methods ***
245 virtual HRESULT STDMETHODCALLTYPE
QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
);
248 LRESULT
OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
249 LRESULT
OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
250 LRESULT
OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
251 LRESULT
OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
252 LRESULT
OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
253 LRESULT
OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
254 LRESULT
OnNCCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
255 LRESULT
OnNCDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
256 LRESULT
OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
257 LRESULT
OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
258 LRESULT
OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
259 LRESULT
OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
260 LRESULT
OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
261 LRESULT
OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
262 LRESULT
OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
263 LRESULT
OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
264 LRESULT
OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
265 LRESULT
OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
266 LRESULT
OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
267 LRESULT
OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
269 static ATL::CWndClassInfo
& GetWndClassInfo()
271 static ATL::CWndClassInfo wc
=
273 { sizeof(WNDCLASSEX
), CS_PARENTDC
, StartWindowProc
,
275 LoadCursor(NULL
, IDC_ARROW
), (HBRUSH
)(COLOR_WINDOW
+ 1), NULL
, SV_CLASS_NAME
, NULL
277 NULL
, NULL
, IDC_ARROW
, TRUE
, 0, _T("")
282 virtual WNDPROC
GetWindowProc()
287 static LRESULT CALLBACK
WindowProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
292 // Must hold a reference during message handling
293 pThis
= reinterpret_cast<CDefView
*>(hWnd
);
295 result
= CWindowImpl
<CDefView
, CWindow
, CControlWinTraits
>::WindowProc(hWnd
, uMsg
, wParam
, lParam
);
300 BEGIN_MSG_MAP(CDefView
)
301 MESSAGE_HANDLER(WM_SIZE
, OnSize
)
302 MESSAGE_HANDLER(WM_SETFOCUS
, OnSetFocus
)
303 MESSAGE_HANDLER(WM_KILLFOCUS
, OnKillFocus
)
304 MESSAGE_HANDLER(WM_NCCREATE
, OnNCCreate
)
305 MESSAGE_HANDLER(WM_NCDESTROY
, OnNCDestroy
)
306 MESSAGE_HANDLER(WM_CREATE
, OnCreate
)
307 MESSAGE_HANDLER(WM_ACTIVATE
, OnActivate
)
308 MESSAGE_HANDLER(WM_NOTIFY
, OnNotify
)
309 MESSAGE_HANDLER(WM_COMMAND
, OnCommand
)
310 MESSAGE_HANDLER(SHV_CHANGE_NOTIFY
, OnChangeNotify
)
311 MESSAGE_HANDLER(WM_CONTEXTMENU
, OnContextMenu
)
312 MESSAGE_HANDLER(WM_DRAWITEM
, OnCustomItem
)
313 MESSAGE_HANDLER(WM_MEASUREITEM
, OnCustomItem
)
314 MESSAGE_HANDLER(WM_SHOWWINDOW
, OnShowWindow
)
315 MESSAGE_HANDLER(WM_GETDLGCODE
, OnGetDlgCode
)
316 MESSAGE_HANDLER(WM_DESTROY
, OnDestroy
)
317 MESSAGE_HANDLER(WM_ERASEBKGND
, OnEraseBackground
)
318 MESSAGE_HANDLER(WM_SYSCOLORCHANGE
, OnSysColorChange
)
319 MESSAGE_HANDLER(CWM_GETISHELLBROWSER
, OnGetShellBrowser
)
320 MESSAGE_HANDLER(WM_SETTINGCHANGE
, OnSettingChange
)
321 MESSAGE_HANDLER(WM_INITMENUPOPUP
, OnInitMenuPopup
)
324 BEGIN_COM_MAP(CDefView
)
325 // Windows returns E_NOINTERFACE for IOleWindow
326 // COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
327 COM_INTERFACE_ENTRY_IID(IID_IShellView
, IShellView
)
328 COM_INTERFACE_ENTRY_IID(IID_CDefView
, IShellView
)
329 COM_INTERFACE_ENTRY_IID(IID_IShellView2
, IShellView2
)
330 COM_INTERFACE_ENTRY_IID(IID_IFolderView
, IFolderView
)
331 COM_INTERFACE_ENTRY_IID(IID_IShellFolderView
, IShellFolderView
)
332 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget
, IOleCommandTarget
)
333 COM_INTERFACE_ENTRY_IID(IID_IDropTarget
, IDropTarget
)
334 COM_INTERFACE_ENTRY_IID(IID_IDropSource
, IDropSource
)
335 COM_INTERFACE_ENTRY_IID(IID_IViewObject
, IViewObject
)
336 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider
, IServiceProvider
)
341 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
342 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
343 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
345 #define ID_LISTVIEW 1
348 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
349 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
350 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
352 typedef void (CALLBACK
*PFNSHGETSETTINGSPROC
)(LPSHELLFLAGSTATE lpsfs
, DWORD dwMask
);
354 CDefView::CDefView() :
358 m_hMenuArrangeModes(NULL
),
359 m_hMenuViewModes(NULL
),
360 m_hContextMenu(NULL
),
361 m_bmenuBarInitialized(FALSE
),
375 ZeroMemory(&m_FolderSettings
, sizeof(m_FolderSettings
));
376 ZeroMemory(&m_sortInfo
, sizeof(m_sortInfo
));
377 ZeroMemory(&m_ptLastMousePos
, sizeof(m_ptLastMousePos
));
378 ZeroMemory(&m_Category
, sizeof(m_Category
));
381 CDefView::~CDefView()
383 TRACE(" destroying IShellView(%p)\n", this);
393 HRESULT WINAPI
CDefView::Initialize(IShellFolder
*shellFolder
)
395 m_pSFParent
= shellFolder
;
396 shellFolder
->QueryInterface(IID_PPV_ARG(IShellFolder2
, &m_pSF2Parent
));
401 /**********************************************************
403 * ##### helperfunctions for communication with ICommDlgBrowser #####
405 HRESULT
CDefView::IncludeObject(PCUITEMID_CHILD pidl
)
409 if (m_pCommDlgBrowser
.p
!= NULL
)
411 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl
);
412 ret
= m_pCommDlgBrowser
->IncludeObject(this, pidl
);
413 TRACE("--0x%08x\n", ret
);
419 HRESULT
CDefView::OnDefaultCommand()
421 HRESULT ret
= S_FALSE
;
423 if (m_pCommDlgBrowser
.p
!= NULL
)
425 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
426 ret
= m_pCommDlgBrowser
->OnDefaultCommand(this);
427 TRACE("-- returns %08x\n", ret
);
433 HRESULT
CDefView::OnStateChange(UINT uFlags
)
435 HRESULT ret
= S_FALSE
;
437 if (m_pCommDlgBrowser
.p
!= NULL
)
439 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags
);
440 ret
= m_pCommDlgBrowser
->OnStateChange(this, uFlags
);
446 /**********************************************************
447 * set the toolbar of the filedialog buttons
449 * - activates the buttons from the shellbrowser according to
452 void CDefView::CheckToolbar()
458 if (m_pCommDlgBrowser
!= NULL
)
460 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
461 FCIDM_TB_SMALLICON
, (m_FolderSettings
.ViewMode
== FVM_LIST
) ? TRUE
: FALSE
, &result
);
462 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
463 FCIDM_TB_REPORTVIEW
, (m_FolderSettings
.ViewMode
== FVM_DETAILS
) ? TRUE
: FALSE
, &result
);
464 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
465 FCIDM_TB_SMALLICON
, TRUE
, &result
);
466 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
467 FCIDM_TB_REPORTVIEW
, TRUE
, &result
);
471 void CDefView::UpdateStatusbar()
473 WCHAR szFormat
[MAX_PATH
] = {0};
474 WCHAR szObjects
[MAX_PATH
] = {0};
477 cSelectedItems
= m_ListView
.GetSelectedCount();
480 LoadStringW(shell32_hInstance
, IDS_OBJECTS_SELECTED
, szFormat
, _countof(szFormat
));
481 StringCchPrintfW(szObjects
, MAX_PATH
, szFormat
, cSelectedItems
);
485 LoadStringW(shell32_hInstance
, IDS_OBJECTS
, szFormat
, _countof(szFormat
));
486 StringCchPrintfW(szObjects
, MAX_PATH
, szFormat
, m_ListView
.GetItemCount());
488 m_pShellBrowser
->SetStatusTextSB(szObjects
);
491 /**********************************************************
493 * ##### helperfunctions for initializing the view #####
495 /**********************************************************
496 * change the style of the listview control
498 void CDefView::SetStyle(DWORD dwAdd
, DWORD dwRemove
)
502 TRACE("(%p)\n", this);
504 tmpstyle
= ::GetWindowLongPtrW(m_ListView
, GWL_STYLE
);
505 ::SetWindowLongPtrW(m_ListView
, GWL_STYLE
, dwAdd
| (tmpstyle
& ~dwRemove
));
508 /**********************************************************
509 * ShellView_CreateList()
511 * - creates the list view window
513 BOOL
CDefView::CreateList()
515 DWORD dwStyle
, dwExStyle
;
519 dwStyle
= WS_TABSTOP
| WS_VISIBLE
| WS_CHILDWINDOW
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
|
520 LVS_SHAREIMAGELISTS
| LVS_EDITLABELS
| LVS_AUTOARRANGE
;
521 dwExStyle
= WS_EX_CLIENTEDGE
;
523 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
524 dwStyle
|= LVS_ALIGNLEFT
;
526 dwStyle
|= LVS_ALIGNTOP
| LVS_SHOWSELALWAYS
;
528 switch (m_FolderSettings
.ViewMode
)
535 dwStyle
|= LVS_REPORT
;
539 dwStyle
|= LVS_SMALLICON
;
551 if (m_FolderSettings
.fFlags
& FWF_AUTOARRANGE
)
552 dwStyle
|= LVS_AUTOARRANGE
;
554 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
555 m_FolderSettings
.fFlags
|= FWF_NOCLIENTEDGE
| FWF_NOSCROLL
;
557 if (m_FolderSettings
.fFlags
& FWF_SINGLESEL
)
558 dwStyle
|= LVS_SINGLESEL
;
560 if (m_FolderSettings
.fFlags
& FWF_NOCLIENTEDGE
)
561 dwExStyle
&= ~WS_EX_CLIENTEDGE
;
563 RECT rcListView
= {0,0,0,0};
564 m_ListView
.Create(m_hWnd
, rcListView
, L
"FolderView", dwStyle
, dwExStyle
, ID_LISTVIEW
);
569 m_sortInfo
.bIsAscending
= TRUE
;
570 m_sortInfo
.nHeaderID
= -1;
571 m_sortInfo
.nLastHeaderID
= -1;
575 /* UpdateShellSettings(); */
579 void CDefView::UpdateListColors()
581 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
583 /* Check if drop shadows option is enabled */
584 BOOL bDropShadow
= FALSE
;
585 DWORD cbDropShadow
= sizeof(bDropShadow
);
588 * The desktop ListView always take the default desktop colours, by
589 * remaining transparent and letting user32/win32k paint itself the
590 * desktop background color, if any.
592 m_ListView
.SetBkColor(CLR_NONE
);
594 SHGetValueW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
595 L
"ListviewShadow", NULL
, &bDropShadow
, &cbDropShadow
);
598 /* Set the icon background transparent */
599 m_ListView
.SetTextBkColor(CLR_NONE
);
600 m_ListView
.SetTextColor(RGB(255, 255, 255));
601 m_ListView
.SetExtendedListViewStyle(LVS_EX_TRANSPARENTSHADOWTEXT
, LVS_EX_TRANSPARENTSHADOWTEXT
);
605 /* Set the icon background as the same colour as the desktop */
606 COLORREF crDesktop
= GetSysColor(COLOR_DESKTOP
);
607 m_ListView
.SetTextBkColor(crDesktop
);
608 if (GetRValue(crDesktop
) + GetGValue(crDesktop
) + GetBValue(crDesktop
) > 128 * 3)
609 m_ListView
.SetTextColor(RGB(0, 0, 0));
611 m_ListView
.SetTextColor(RGB(255, 255, 255));
612 m_ListView
.SetExtendedListViewStyle(0, LVS_EX_TRANSPARENTSHADOWTEXT
);
617 /**********************************************************
618 * ShellView_InitList()
620 * - adds all needed columns to the shellview
622 BOOL
CDefView::InitList()
626 HIMAGELIST big_icons
, small_icons
;
630 m_ListView
.DeleteAllItems();
632 m_hMenuArrangeModes
= CreateMenu();
636 for (int i
= 0; 1; i
++)
638 if (FAILED(m_pSF2Parent
->GetDetailsOf(NULL
, i
, &sd
)))
640 StrRetToStrNW( szTemp
, 50, &sd
.str
, NULL
);
641 m_ListView
.InsertColumn(i
, szTemp
, sd
.fmt
, sd
.cxChar
* 8);
643 InsertMenuW(m_hMenuArrangeModes
, -1, MF_STRING
, 0x30 + i
, szTemp
);
646 InsertMenuW(m_hMenuArrangeModes
, -1, MF_BYPOSITION
| MF_SEPARATOR
, 0, 0);
650 FIXME("no m_pSF2Parent\n");
653 Shell_GetImageLists(&big_icons
, &small_icons
);
654 m_ListView
.SetImageList(big_icons
, LVSIL_NORMAL
);
655 m_ListView
.SetImageList(small_icons
, LVSIL_SMALL
);
660 /*************************************************************************
661 * ShellView_ListViewCompareItems
663 * Compare Function for the Listview (FileOpen Dialog)
666 * lParam1 [I] the first ItemIdList to compare with
667 * lParam2 [I] the second ItemIdList to compare with
668 * lpData [I] The column ID for the header Ctrl to process
671 * A negative value if the first item should precede the second,
672 * a positive value if the first item should follow the second,
673 * or zero if the two items are equivalent
675 INT CALLBACK
CDefView::ListViewCompareItems(LPARAM lParam1
, LPARAM lParam2
, LPARAM lpData
)
677 PCUIDLIST_RELATIVE pidl1
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam1
);
678 PCUIDLIST_RELATIVE pidl2
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam2
);
679 CDefView
*pThis
= reinterpret_cast<CDefView
*>(lpData
);
681 HRESULT hres
= pThis
->m_pSFParent
->CompareIDs(pThis
->m_sortInfo
.nHeaderID
, pidl1
, pidl2
);
682 if (FAILED_UNEXPECTEDLY(hres
))
685 SHORT nDiff
= HRESULT_CODE(hres
);
686 if (!pThis
->m_sortInfo
.bIsAscending
)
691 PCUITEMID_CHILD
CDefView::_PidlByItem(int i
)
693 return reinterpret_cast<PCUITEMID_CHILD
>(m_ListView
.GetItemData(i
));
696 PCUITEMID_CHILD
CDefView::_PidlByItem(LVITEM
& lvItem
)
698 return reinterpret_cast<PCUITEMID_CHILD
>(lvItem
.lParam
);
701 /**********************************************************
702 * LV_FindItemByPidl()
704 int CDefView::LV_FindItemByPidl(PCUITEMID_CHILD pidl
)
706 int cItems
= m_ListView
.GetItemCount();
708 for (int i
= 0; i
<cItems
; i
++)
710 PCUITEMID_CHILD currentpidl
= _PidlByItem(i
);
711 HRESULT hr
= m_pSFParent
->CompareIDs(0, pidl
, currentpidl
);
713 if (SUCCEEDED(hr
) && !HRESULT_CODE(hr
))
721 /**********************************************************
724 BOOLEAN
CDefView::LV_AddItem(PCUITEMID_CHILD pidl
)
728 TRACE("(%p)(pidl=%p)\n", this, pidl
);
730 lvItem
.mask
= LVIF_TEXT
| LVIF_IMAGE
| LVIF_PARAM
; /*set the mask*/
731 lvItem
.iItem
= m_ListView
.GetItemCount(); /*add the item to the end of the list*/
733 lvItem
.lParam
= reinterpret_cast<LPARAM
>(ILClone(pidl
)); /*set the item's data*/
734 lvItem
.pszText
= LPSTR_TEXTCALLBACKW
; /*get text on a callback basis*/
735 lvItem
.iImage
= I_IMAGECALLBACK
; /*get the image on a callback basis*/
736 lvItem
.stateMask
= LVIS_CUT
;
738 if (m_ListView
.InsertItem(&lvItem
) == -1)
744 /**********************************************************
747 BOOLEAN
CDefView::LV_DeleteItem(PCUITEMID_CHILD pidl
)
751 TRACE("(%p)(pidl=%p)\n", this, pidl
);
753 nIndex
= LV_FindItemByPidl(pidl
);
755 return (-1 == m_ListView
.DeleteItem(nIndex
)) ? FALSE
: TRUE
;
758 /**********************************************************
761 BOOLEAN
CDefView::LV_RenameItem(PCUITEMID_CHILD pidlOld
, PCUITEMID_CHILD pidlNew
)
766 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", this, pidlOld
, pidlNew
);
768 nItem
= LV_FindItemByPidl(pidlOld
);
772 lvItem
.mask
= LVIF_PARAM
; /* only the pidl */
773 lvItem
.iItem
= nItem
;
775 m_ListView
.GetItem(&lvItem
);
777 SHFree(reinterpret_cast<LPVOID
>(lvItem
.lParam
));
778 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
779 lvItem
.iItem
= nItem
;
781 lvItem
.lParam
= reinterpret_cast<LPARAM
>(ILClone(pidlNew
)); /* set the item's data */
782 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
783 m_ListView
.SetItem(&lvItem
);
784 m_ListView
.Update(nItem
);
785 return TRUE
; /* FIXME: better handling */
791 /**********************************************************
794 BOOLEAN
CDefView::LV_ProdItem(PCUITEMID_CHILD pidl
)
799 TRACE("(%p)(pidl=%p)\n", this, pidl
);
801 nItem
= LV_FindItemByPidl(pidl
);
805 lvItem
.mask
= LVIF_IMAGE
;
806 lvItem
.iItem
= nItem
;
808 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
809 m_ListView
.SetItem(&lvItem
);
810 m_ListView
.Update(nItem
);
817 /**********************************************************
818 * ShellView_FillList()
820 * - gets the objectlist from the shellfolder
822 * - fills the list into the view
824 INT CALLBACK
CDefView::fill_list(LPVOID ptr
, LPVOID arg
)
826 PITEMID_CHILD pidl
= static_cast<PITEMID_CHILD
>(ptr
);
827 CDefView
*pThis
= static_cast<CDefView
*>(arg
);
829 /* in a commdlg This works as a filemask*/
830 if (pThis
->IncludeObject(pidl
) == S_OK
)
831 pThis
->LV_AddItem(pidl
);
837 HRESULT
CDefView::FillList()
839 CComPtr
<IEnumIDList
> pEnumIDList
;
845 DWORD dFlags
= SHCONTF_NONFOLDERS
| SHCONTF_FOLDERS
;
849 /* determine if there is a setting to show all the hidden files/folders */
850 if (RegOpenKeyExW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", 0, KEY_QUERY_VALUE
, &hKey
) == ERROR_SUCCESS
)
852 DWORD dataLength
, flagVal
;
854 dataLength
= sizeof(flagVal
);
855 if (RegQueryValueExW(hKey
, L
"Hidden", NULL
, NULL
, (LPBYTE
)&flagVal
, &dataLength
) == ERROR_SUCCESS
)
857 /* if the value is 1, then show all hidden files/folders */
860 dFlags
|= SHCONTF_INCLUDEHIDDEN
;
861 m_ListView
.SendMessageW(LVM_SETCALLBACKMASK
, LVIS_CUT
, 0);
869 /* get the itemlist from the shfolder */
870 hRes
= m_pSFParent
->EnumObjects(m_hWnd
, dFlags
, &pEnumIDList
);
878 /* create a pointer array */
879 hdpa
= DPA_Create(16);
882 return(E_OUTOFMEMORY
);
885 /* copy the items into the array*/
886 while((S_OK
== pEnumIDList
->Next(1, &pidl
, &dwFetched
)) && dwFetched
)
888 if (DPA_InsertPtr(hdpa
, 0x7fff, pidl
) == -1)
894 /*turn the listview's redrawing off*/
895 m_ListView
.SetRedraw(FALSE
);
897 DPA_DestroyCallback( hdpa
, fill_list
, this);
902 m_pSF2Parent
->GetDefaultColumn(NULL
, (ULONG
*)&m_sortInfo
.nHeaderID
, NULL
);
906 FIXME("no m_pSF2Parent\n");
908 m_sortInfo
.bIsAscending
= TRUE
;
909 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
910 m_ListView
.SortItems(ListViewCompareItems
, this);
912 /*turn the listview's redrawing back on and force it to draw*/
913 m_ListView
.SetRedraw(TRUE
);
918 LRESULT
CDefView::OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
920 m_ListView
.UpdateWindow();
925 LRESULT
CDefView::OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
927 return m_ListView
.SendMessageW(uMsg
, 0, 0);
930 LRESULT
CDefView::OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
937 DestroyMenu(m_hMenu
);
940 RevokeDragDrop(m_hWnd
);
941 SHChangeNotifyDeregister(m_hNotify
);
943 SHFree(m_pidlParent
);
950 LRESULT
CDefView::OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
952 /* redirect to parent */
953 if (m_FolderSettings
.fFlags
& (FWF_DESKTOP
| FWF_TRANSPARENT
))
954 return SendMessageW(GetParent(), WM_ERASEBKGND
, wParam
, lParam
);
960 LRESULT
CDefView::OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
962 /* Update desktop labels color */
965 /* Forward WM_SYSCOLORCHANGE to common controls */
966 return m_ListView
.SendMessageW(uMsg
, 0, 0);
969 LRESULT
CDefView::OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
971 return reinterpret_cast<LRESULT
>(m_pShellBrowser
.p
);
974 LRESULT
CDefView::OnNCCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
981 LRESULT
CDefView::OnNCDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
988 /**********************************************************
989 * ShellView_OnCreate()
991 LRESULT
CDefView::OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
993 CComPtr
<IDropTarget
> pdt
;
994 SHChangeNotifyEntry ntreg
;
995 CComPtr
<IPersistFolder2
> ppf2
;
1007 if (SUCCEEDED(QueryInterface(IID_PPV_ARG(IDropTarget
, &pdt
))))
1009 if (FAILED(RegisterDragDrop(m_hWnd
, pdt
)))
1010 ERR("Registering Drag Drop Failed");
1013 /* register for receiving notifications */
1014 m_pSFParent
->QueryInterface(IID_PPV_ARG(IPersistFolder2
, &ppf2
));
1017 ppf2
->GetCurFolder(&m_pidlParent
);
1018 ntreg
.fRecursive
= TRUE
;
1019 ntreg
.pidl
= m_pidlParent
;
1020 m_hNotify
= SHChangeNotifyRegister(m_hWnd
, SHCNRF_InterruptLevel
| SHCNRF_ShellLevel
, SHCNE_ALLEVENTS
, SHV_CHANGE_NOTIFY
, 1, &ntreg
);
1023 m_hAccel
= LoadAcceleratorsW(shell32_hInstance
, MAKEINTRESOURCEW(IDA_SHELLVIEW
));
1030 /**********************************************************
1031 * #### Handling of the menus ####
1034 extern "C" DWORD WINAPI
SHMenuIndexFromID(HMENU hMenu
, UINT uID
);
1036 HMENU
GetSubmenuByID(HMENU hmenu
, UINT id
)
1038 MENUITEMINFOW mii
= {sizeof(mii
), MIIM_SUBMENU
};
1039 if (::GetMenuItemInfoW(hmenu
, id
, FALSE
, &mii
))
1040 return mii
.hSubMenu
;
1045 /* ReallyGetMenuItemID returns the id of an item even if it opens a submenu,
1046 GetMenuItemID returns -1 if the specified item opens a submenu */
1047 UINT
ReallyGetMenuItemID(HMENU hmenu
, int i
)
1049 MENUITEMINFOW mii
= {sizeof(mii
), MIIM_ID
};
1050 if (::GetMenuItemInfoW(hmenu
, i
, TRUE
, &mii
))
1056 HRESULT
CDefView::FillFileMenu()
1058 HMENU hFileMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_FILE
);
1062 /* Cleanup the items added previously */
1063 for (int i
= GetMenuItemCount(hFileMenu
) - 1; i
>= 0; i
--)
1065 UINT id
= GetMenuItemID(hFileMenu
, i
);
1066 if (id
< FCIDM_BROWSERFIRST
|| id
> FCIDM_BROWSERLAST
)
1067 DeleteMenu(hFileMenu
, i
, MF_BYPOSITION
);
1070 /* Store the context menu in m_pCM and keep it in order to invoke the selected command later on */
1071 HRESULT hr
= GetItemObject(SVGIO_SELECTION
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1072 if (FAILED_UNEXPECTEDLY(hr
))
1075 IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1077 HMENU hmenu
= CreatePopupMenu();
1079 hr
= m_pCM
->QueryContextMenu(hmenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, 0);
1080 if (FAILED_UNEXPECTEDLY(hr
))
1083 // TODO: filter or something
1085 Shell_MergeMenus(hFileMenu
, hmenu
, 0, 0, 0xFFFF, MM_ADDSEPARATOR
| MM_SUBMENUSHAVEIDS
);
1087 ::DestroyMenu(hmenu
);
1092 HRESULT
CDefView::FillEditMenu()
1094 HMENU hEditMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_EDIT
);
1098 HMENU hmenuContents
= ::LoadMenuW(shell32_hInstance
, L
"MENU_003");
1102 Shell_MergeMenus(hEditMenu
, hmenuContents
, 0, 0, 0xFFFF, 0);
1104 ::DestroyMenu(hmenuContents
);
1109 HRESULT
CDefView::FillViewMenu()
1111 HMENU hViewMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_VIEW
);
1115 m_hMenuViewModes
= ::LoadMenuW(shell32_hInstance
, L
"MENU_001");
1116 if (!m_hMenuViewModes
)
1119 UINT i
= SHMenuIndexFromID(hViewMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
);
1120 Shell_MergeMenus(hViewMenu
, m_hMenuViewModes
, i
, 0, 0xFFFF, MM_ADDSEPARATOR
| MM_DONTREMOVESEPS
| MM_SUBMENUSHAVEIDS
);
1125 HRESULT
CDefView::FillArrangeAsMenu(HMENU hmenuArrange
)
1127 /* We only need to fill this once */
1128 if (GetMenuItemID(hmenuArrange
, 0) == FCIDM_SHVIEW_AUTOARRANGE
)
1130 Shell_MergeMenus(hmenuArrange
, m_hMenuArrangeModes
, 0, 0, 0xFFFF,0);
1133 /* Also check the menu item according to which we sort */
1134 CheckMenuRadioItem(hmenuArrange
,
1137 m_sortInfo
.nHeaderID
+ 0x30,
1143 HRESULT
CDefView::CheckViewMode(HMENU hmenuView
)
1145 if (m_FolderSettings
.ViewMode
>= FVM_FIRST
&& m_FolderSettings
.ViewMode
<= FVM_LAST
)
1147 UINT iItemFirst
= FCIDM_SHVIEW_BIGICON
;
1148 UINT iItemLast
= iItemFirst
+ FVM_LAST
- FVM_FIRST
;
1149 UINT iItem
= iItemFirst
+ m_FolderSettings
.ViewMode
- FVM_FIRST
;
1150 CheckMenuRadioItem(hmenuView
, iItemFirst
, iItemLast
, iItem
, MF_BYCOMMAND
);
1156 /**********************************************************
1157 * ShellView_GetSelections()
1159 * - fills the m_apidl list with the selected objects
1162 * number of selected items
1164 UINT
CDefView::GetSelections()
1168 m_cidl
= m_ListView
.GetSelectedCount();
1169 m_apidl
= static_cast<PCUITEMID_CHILD
*>(SHAlloc(m_cidl
* sizeof(PCUITEMID_CHILD
)));
1176 TRACE("-- Items selected =%u\n", m_cidl
);
1180 while ((lvIndex
= m_ListView
.GetNextItem(lvIndex
, LVNI_SELECTED
)) > -1)
1182 m_apidl
[i
] = _PidlByItem(lvIndex
);
1186 TRACE("-- selected Item found\n");
1192 HRESULT
CDefView::InvokeContextMenuCommand(UINT uCommand
)
1194 CMINVOKECOMMANDINFO cmi
;
1196 ZeroMemory(&cmi
, sizeof(cmi
));
1197 cmi
.cbSize
= sizeof(cmi
);
1198 cmi
.lpVerb
= MAKEINTRESOURCEA(uCommand
);
1201 if (GetKeyState(VK_SHIFT
) & 0x8000)
1202 cmi
.fMask
|= CMIC_MASK_SHIFT_DOWN
;
1204 if (GetKeyState(VK_CONTROL
) & 0x8000)
1205 cmi
.fMask
|= CMIC_MASK_CONTROL_DOWN
;
1207 HRESULT hr
= m_pCM
->InvokeCommand(&cmi
);
1208 if (FAILED_UNEXPECTEDLY(hr
))
1214 /**********************************************************
1215 * ShellView_OpenSelectedItems()
1217 HRESULT
CDefView::OpenSelectedItems()
1223 m_cidl
= m_ListView
.GetSelectedCount();
1227 hResult
= OnDefaultCommand();
1228 if (hResult
== S_OK
)
1231 hMenu
= CreatePopupMenu();
1235 hResult
= GetItemObject(SVGIO_SELECTION
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1236 if (FAILED_UNEXPECTEDLY(hResult
))
1239 IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1241 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, 0x20, 0x7fff, CMF_DEFAULTONLY
);
1242 if (FAILED_UNEXPECTEDLY(hResult
))
1245 uCommand
= GetMenuDefaultItem(hMenu
, FALSE
, 0);
1246 if (uCommand
== (UINT
)-1)
1252 InvokeContextMenuCommand(uCommand
);
1261 IUnknown_SetSite(m_pCM
, NULL
);
1268 /**********************************************************
1269 * ShellView_DoContextMenu()
1271 LRESULT
CDefView::OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1280 TRACE("(%p)->(0x%08x 0x%08x) stub\n", this, x
, y
);
1282 m_hContextMenu
= CreatePopupMenu();
1283 if (!m_hContextMenu
)
1286 m_cidl
= m_ListView
.GetSelectedCount();
1288 hResult
= GetItemObject( m_cidl
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1289 if (FAILED_UNEXPECTEDLY(hResult
))
1292 IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1294 hResult
= m_pCM
->QueryContextMenu(m_hContextMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1295 if (FAILED_UNEXPECTEDLY(hResult
))
1298 uCommand
= TrackPopupMenu(m_hContextMenu
,
1299 TPM_LEFTALIGN
| TPM_RETURNCMD
| TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
,
1300 x
, y
, 0, m_hWnd
, NULL
);
1304 if (uCommand
== FCIDM_SHVIEW_OPEN
&& OnDefaultCommand() == S_OK
)
1307 InvokeContextMenuCommand(uCommand
);
1312 IUnknown_SetSite(m_pCM
, NULL
);
1318 DestroyMenu(m_hContextMenu
);
1319 m_hContextMenu
= NULL
;
1325 LRESULT
CDefView::OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
)
1330 hMenu
= CreatePopupMenu();
1334 hResult
= GetItemObject( bUseSelection
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1335 if (FAILED_UNEXPECTEDLY( hResult
))
1338 IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1340 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1341 if (FAILED_UNEXPECTEDLY( hResult
))
1344 InvokeContextMenuCommand(uCommand
);
1349 IUnknown_SetSite(m_pCM
, NULL
);
1359 /**********************************************************
1360 * ##### message handling #####
1363 /**********************************************************
1364 * ShellView_OnSize()
1366 LRESULT
CDefView::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1368 WORD wWidth
, wHeight
;
1370 wWidth
= LOWORD(lParam
);
1371 wHeight
= HIWORD(lParam
);
1373 TRACE("%p width=%u height=%u\n", this, wWidth
, wHeight
);
1375 /* Resize the ListView to fit our window */
1378 ::MoveWindow(m_ListView
, 0, 0, wWidth
, wHeight
, TRUE
);
1384 /**********************************************************
1385 * ShellView_OnDeactivate()
1390 void CDefView::OnDeactivate()
1392 TRACE("%p\n", this);
1394 if (m_uState
!= SVUIA_DEACTIVATE
)
1396 // TODO: cleanup menu after deactivation
1398 m_uState
= SVUIA_DEACTIVATE
;
1402 void CDefView::DoActivate(UINT uState
)
1404 TRACE("%p uState=%x\n", this, uState
);
1406 /*don't do anything if the state isn't really changing */
1407 if (m_uState
== uState
)
1412 if (uState
== SVUIA_DEACTIVATE
)
1418 if(m_hMenu
&& !m_bmenuBarInitialized
)
1422 m_pShellBrowser
->SetMenuSB(m_hMenu
, 0, m_hWnd
);
1423 m_bmenuBarInitialized
= TRUE
;
1426 if (SVUIA_ACTIVATE_FOCUS
== uState
)
1428 m_ListView
.SetFocus();
1436 /**********************************************************
1437 * ShellView_OnActivate()
1439 LRESULT
CDefView::OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1441 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1445 /**********************************************************
1446 * ShellView_OnSetFocus()
1449 LRESULT
CDefView::OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1451 TRACE("%p\n", this);
1453 /* Tell the browser one of our windows has received the focus. This
1454 should always be done before merging menus (OnActivate merges the
1455 menus) if one of our windows has the focus.*/
1457 m_pShellBrowser
->OnViewWindowActive(this);
1458 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1460 /* Set the focus to the listview */
1461 m_ListView
.SetFocus();
1463 /* Notify the ICommDlgBrowser interface */
1464 OnStateChange(CDBOSC_SETFOCUS
);
1469 /**********************************************************
1470 * ShellView_OnKillFocus()
1472 LRESULT
CDefView::OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1474 TRACE("(%p) stub\n", this);
1476 DoActivate(SVUIA_ACTIVATE_NOFOCUS
);
1477 /* Notify the ICommDlgBrowser */
1478 OnStateChange(CDBOSC_KILLFOCUS
);
1483 /**********************************************************
1484 * ShellView_OnCommand()
1487 * the CmdID's are the ones from the context menu
1489 LRESULT
CDefView::OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1496 dwCmdID
= GET_WM_COMMAND_ID(wParam
, lParam
);
1497 dwCmd
= GET_WM_COMMAND_CMD(wParam
, lParam
);
1498 hwndCmd
= GET_WM_COMMAND_HWND(wParam
, lParam
);
1500 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n", this, dwCmdID
, dwCmd
, hwndCmd
);
1504 case FCIDM_SHVIEW_SMALLICON
:
1505 m_FolderSettings
.ViewMode
= FVM_SMALLICON
;
1506 SetStyle (LVS_SMALLICON
, LVS_TYPEMASK
);
1510 case FCIDM_SHVIEW_BIGICON
:
1511 m_FolderSettings
.ViewMode
= FVM_ICON
;
1512 SetStyle (LVS_ICON
, LVS_TYPEMASK
);
1516 case FCIDM_SHVIEW_LISTVIEW
:
1517 m_FolderSettings
.ViewMode
= FVM_LIST
;
1518 SetStyle (LVS_LIST
, LVS_TYPEMASK
);
1522 case FCIDM_SHVIEW_REPORTVIEW
:
1523 m_FolderSettings
.ViewMode
= FVM_DETAILS
;
1524 SetStyle (LVS_REPORT
, LVS_TYPEMASK
);
1528 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1533 m_sortInfo
.nHeaderID
= dwCmdID
- 0x30;
1534 m_sortInfo
.bIsAscending
= TRUE
;
1535 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
1536 m_ListView
.SortItems(ListViewCompareItems
, this);
1539 case FCIDM_SHVIEW_SNAPTOGRID
:
1540 case FCIDM_SHVIEW_AUTOARRANGE
:
1543 case FCIDM_SHVIEW_SELECTALL
:
1544 m_ListView
.SetItemState(-1, LVIS_SELECTED
, LVIS_SELECTED
);
1547 case FCIDM_SHVIEW_INVERTSELECTION
:
1548 nCount
= m_ListView
.GetItemCount();
1549 for (int i
=0; i
< nCount
; i
++)
1550 m_ListView
.SetItemState(i
, m_ListView
.GetItemState(i
, LVIS_SELECTED
) ? 0 : LVIS_SELECTED
, LVIS_SELECTED
);
1553 case FCIDM_SHVIEW_REFRESH
:
1557 case FCIDM_SHVIEW_DELETE
:
1558 case FCIDM_SHVIEW_CUT
:
1559 case FCIDM_SHVIEW_COPY
:
1560 case FCIDM_SHVIEW_RENAME
:
1561 return OnExplorerCommand(dwCmdID
, TRUE
);
1563 case FCIDM_SHVIEW_INSERT
:
1564 case FCIDM_SHVIEW_UNDO
:
1565 case FCIDM_SHVIEW_INSERTLINK
:
1566 case FCIDM_SHVIEW_NEWFOLDER
:
1567 return OnExplorerCommand(dwCmdID
, FALSE
);
1569 /* WM_COMMAND messages from the file menu are routed to the CDefView so as to let m_pCM handle the command */
1572 InvokeContextMenuCommand(dwCmdID
);
1579 /**********************************************************
1580 * ShellView_OnNotify()
1583 LRESULT
CDefView::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1587 LPNMLISTVIEW lpnmlv
;
1588 NMLVDISPINFOW
*lpdi
;
1589 PCUITEMID_CHILD pidl
;
1593 lpnmh
= (LPNMHDR
)lParam
;
1594 lpnmlv
= (LPNMLISTVIEW
)lpnmh
;
1595 lpdi
= (NMLVDISPINFOW
*)lpnmh
;
1597 TRACE("%p CtlID=%u lpnmh->code=%x\n", this, CtlID
, lpnmh
->code
);
1599 switch (lpnmh
->code
)
1602 TRACE("-- NM_SETFOCUS %p\n", this);
1603 OnSetFocus(0, 0, 0, unused
);
1607 TRACE("-- NM_KILLFOCUS %p\n", this);
1609 /* Notify the ICommDlgBrowser interface */
1610 OnStateChange(CDBOSC_KILLFOCUS
);
1614 TRACE("-- NM_CUSTOMDRAW %p\n", this);
1615 return CDRF_DODEFAULT
;
1617 case NM_RELEASEDCAPTURE
:
1618 TRACE("-- NM_RELEASEDCAPTURE %p\n", this);
1622 TRACE("-- NM_CLICK %p\n", this);
1626 TRACE("-- NM_RCLICK %p\n", this);
1630 TRACE("-- NM_DBLCLK %p\n", this);
1631 OpenSelectedItems();
1635 TRACE("-- NM_RETURN %p\n", this);
1636 OpenSelectedItems();
1640 TRACE("-- HDN_ENDTRACKW %p\n", this);
1641 /*nColumn1 = m_ListView.GetColumnWidth(0);
1642 nColumn2 = m_ListView.GetColumnWidth(1);*/
1645 case LVN_DELETEITEM
:
1646 TRACE("-- LVN_DELETEITEM %p\n", this);
1648 /*delete the pidl because we made a copy of it*/
1649 SHFree(reinterpret_cast<LPVOID
>(lpnmlv
->lParam
));
1653 case LVN_DELETEALLITEMS
:
1654 TRACE("-- LVN_DELETEALLITEMS %p\n", this);
1657 case LVN_INSERTITEM
:
1658 TRACE("-- LVN_INSERTITEM (STUB)%p\n", this);
1661 case LVN_ITEMACTIVATE
:
1662 TRACE("-- LVN_ITEMACTIVATE %p\n", this);
1663 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1666 case LVN_COLUMNCLICK
:
1667 m_sortInfo
.nHeaderID
= lpnmlv
->iSubItem
;
1668 if (m_sortInfo
.nLastHeaderID
== m_sortInfo
.nHeaderID
)
1669 m_sortInfo
.bIsAscending
= !m_sortInfo
.bIsAscending
;
1671 m_sortInfo
.bIsAscending
= TRUE
;
1672 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
1674 m_ListView
.SortItems(ListViewCompareItems
, this);
1677 case LVN_GETDISPINFOA
:
1678 case LVN_GETDISPINFOW
:
1679 TRACE("-- LVN_GETDISPINFO %p\n", this);
1680 pidl
= _PidlByItem(lpdi
->item
);
1682 if (lpdi
->item
.mask
& LVIF_TEXT
) /* text requested */
1687 if (FAILED_UNEXPECTEDLY(m_pSF2Parent
->GetDetailsOf(pidl
, lpdi
->item
.iSubItem
, &sd
)))
1690 if (lpnmh
->code
== LVN_GETDISPINFOA
)
1692 /* shouldn't happen */
1693 NMLVDISPINFOA
*lpdiA
= (NMLVDISPINFOA
*)lpnmh
;
1694 StrRetToStrNA( lpdiA
->item
.pszText
, lpdiA
->item
.cchTextMax
, &sd
.str
, NULL
);
1695 TRACE("-- text=%s\n", lpdiA
->item
.pszText
);
1697 else /* LVN_GETDISPINFOW */
1699 StrRetToStrNW( lpdi
->item
.pszText
, lpdi
->item
.cchTextMax
, &sd
.str
, NULL
);
1700 TRACE("-- text=%s\n", debugstr_w(lpdi
->item
.pszText
));
1705 FIXME("no m_pSF2Parent\n");
1708 if(lpdi
->item
.mask
& LVIF_IMAGE
) /* image requested */
1710 lpdi
->item
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
1712 if(lpdi
->item
.mask
& LVIF_STATE
)
1714 ULONG attributes
= SFGAO_HIDDEN
;
1715 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(1, &pidl
, &attributes
)))
1717 if (attributes
& SFGAO_HIDDEN
)
1719 lpdi
->item
.state
|= LVIS_CUT
;
1723 lpdi
->item
.mask
|= LVIF_DI_SETITEM
;
1726 case LVN_ITEMCHANGED
:
1727 TRACE("-- LVN_ITEMCHANGED %p\n", this);
1728 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1733 case LVN_BEGINRDRAG
:
1734 TRACE("-- LVN_BEGINDRAG\n");
1736 if (GetSelections())
1738 CComPtr
<IDataObject
> pda
;
1739 DWORD dwAttributes
= SFGAO_CANLINK
;
1740 DWORD dwEffect
= DROPEFFECT_COPY
| DROPEFFECT_MOVE
;
1742 if (SUCCEEDED(m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, IID_NULL_PPV_ARG(IDataObject
, &pda
))))
1744 LPNMLISTVIEW params
= (LPNMLISTVIEW
)lParam
;
1746 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(m_cidl
, m_apidl
, &dwAttributes
)))
1748 if (dwAttributes
& SFGAO_CANLINK
)
1750 dwEffect
|= DROPEFFECT_LINK
;
1754 CComPtr
<IAsyncOperation
> piaso
;
1755 if (SUCCEEDED(pda
->QueryInterface(IID_PPV_ARG(IAsyncOperation
, &piaso
))))
1757 piaso
->SetAsyncMode(TRUE
);
1762 m_pSourceDataObject
= pda
;
1763 m_ptFirstMousePos
= params
->ptAction
;
1764 ClientToScreen(&m_ptFirstMousePos
);
1766 HIMAGELIST big_icons
, small_icons
;
1767 Shell_GetImageLists(&big_icons
, &small_icons
);
1768 PCUITEMID_CHILD pidl
= _PidlByItem(params
->iItem
);
1769 int iIcon
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
1771 m_ListView
.GetItemPosition(params
->iItem
, &ptItem
);
1773 ImageList_BeginDrag(big_icons
, iIcon
, params
->ptAction
.x
- ptItem
.x
, params
->ptAction
.y
- ptItem
.y
);
1775 DoDragDrop(pda
, this, dwEffect
, &dwEffect2
);
1777 m_pSourceDataObject
.Release();
1782 case LVN_BEGINLABELEDITW
:
1784 DWORD dwAttr
= SFGAO_CANRENAME
;
1785 pidl
= _PidlByItem(lpdi
->item
);
1787 TRACE("-- LVN_BEGINLABELEDITW %p\n", this);
1789 m_pSFParent
->GetAttributesOf(1, &pidl
, &dwAttr
);
1790 if (SFGAO_CANRENAME
& dwAttr
)
1798 case LVN_ENDLABELEDITW
:
1800 TRACE("-- LVN_ENDLABELEDITW %p\n", this);
1802 m_isEditing
= FALSE
;
1804 if (lpdi
->item
.pszText
)
1809 pidl
= _PidlByItem(lpdi
->item
);
1810 PITEMID_CHILD pidlNew
;
1811 hr
= m_pSFParent
->SetNameOf(0, pidl
, lpdi
->item
.pszText
, SHGDN_INFOLDER
, &pidlNew
);
1813 if (SUCCEEDED(hr
) && pidlNew
)
1815 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
1816 lvItem
.iItem
= lpdi
->item
.iItem
;
1817 lvItem
.iSubItem
= 0;
1818 lvItem
.lParam
= reinterpret_cast<LPARAM
>(pidlNew
);
1819 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
1820 m_ListView
.SetItem(&lvItem
);
1821 m_ListView
.Update(lpdi
->item
.iItem
);
1830 TRACE("-- %p WM_COMMAND %x unhandled\n", this, lpnmh
->code
);
1838 * This is just a quick hack to make the desktop work correctly.
1839 * ITranslateShellChangeNotify's IsChildID is undocumented, but most likely the way that
1840 * a folder should know if it should update upon a change notification.
1841 * It is exported by merged folders at a minimum.
1843 static BOOL
ILIsParentOrSpecialParent(PCIDLIST_ABSOLUTE pidl1
, PCIDLIST_ABSOLUTE pidl2
)
1845 if (!pidl1
|| !pidl2
)
1847 if (ILIsParent(pidl1
, pidl2
, TRUE
))
1850 if (_ILIsDesktop(pidl1
))
1852 PIDLIST_ABSOLUTE deskpidl
;
1853 SHGetFolderLocation(NULL
, CSIDL_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
1854 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
1860 SHGetFolderLocation(NULL
, CSIDL_COMMON_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
1861 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
1871 /**********************************************************
1872 * ShellView_OnChange()
1874 LRESULT
CDefView::OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1876 PCIDLIST_ABSOLUTE
*Pidls
= reinterpret_cast<PCIDLIST_ABSOLUTE
*>(wParam
);
1877 BOOL bParent0
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[0]);
1878 BOOL bParent1
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[1]);
1880 TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls
[0], Pidls
[1], lParam
);
1882 switch (lParam
&~ SHCNE_INTERRUPT
)
1888 if (LV_FindItemByPidl(ILFindLastID(Pidls
[0])) == -1)
1890 LV_AddItem(ILFindLastID(Pidls
[0]));
1894 LV_ProdItem(ILFindLastID(Pidls
[0]));
1902 LV_DeleteItem(ILFindLastID(Pidls
[0]));
1905 case SHCNE_RENAMEFOLDER
:
1906 case SHCNE_RENAMEITEM
:
1907 if (bParent0
&& bParent1
)
1908 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[1]));
1910 LV_DeleteItem(ILFindLastID(Pidls
[0]));
1912 LV_AddItem(ILFindLastID(Pidls
[1]));
1915 case SHCNE_UPDATEITEM
:
1917 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[0]));
1920 case SHCNE_UPDATEDIR
:
1927 /**********************************************************
1928 * CDefView::OnCustomItem
1930 LRESULT
CDefView::OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1935 ERR("no menu!!!\n");
1940 HRESULT hres
= SHForwardContextMenuMsg(m_pCM
, uMsg
, wParam
, lParam
, &result
, TRUE
);
1941 if (SUCCEEDED(hres
))
1947 LRESULT
CDefView::OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1949 /* Wallpaper setting affects drop shadows effect */
1950 if (wParam
== SPI_SETDESKWALLPAPER
|| wParam
== 0)
1956 /**********************************************************
1957 * CDefView::OnInitMenuPopup
1959 LRESULT
CDefView::OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1961 HMENU hmenu
= (HMENU
) wParam
;
1962 int nPos
= LOWORD(lParam
);
1965 OnCustomItem(uMsg
, wParam
, lParam
, bHandled
);
1967 HMENU hViewMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_VIEW
);
1969 /* Lets try to find out what the hell wParam is */
1970 if (hmenu
== GetSubMenu(m_hMenu
, nPos
))
1971 menuItemId
= ReallyGetMenuItemID(m_hMenu
, nPos
);
1972 else if (hViewMenu
&& hmenu
== GetSubMenu(hViewMenu
, nPos
))
1973 menuItemId
= ReallyGetMenuItemID(hViewMenu
, nPos
);
1974 else if (m_hContextMenu
&& hmenu
== GetSubMenu(m_hContextMenu
, nPos
))
1975 menuItemId
= ReallyGetMenuItemID(m_hContextMenu
, nPos
);
1981 case FCIDM_MENU_FILE
:
1984 case FCIDM_MENU_VIEW
:
1985 case FCIDM_SHVIEW_VIEW
:
1986 CheckViewMode(hmenu
);
1988 case FCIDM_SHVIEW_ARRANGE
:
1989 FillArrangeAsMenu(hmenu
);
1996 /**********************************************************
1999 * The INTERFACE of the IShellView object
2002 **********************************************************
2005 /**********************************************************
2006 * ShellView_GetWindow
2008 HRESULT WINAPI
CDefView::GetWindow(HWND
*phWnd
)
2010 TRACE("(%p)\n", this);
2017 HRESULT WINAPI
CDefView::ContextSensitiveHelp(BOOL fEnterMode
)
2019 FIXME("(%p) stub\n", this);
2024 /**********************************************************
2025 * IShellView_TranslateAccelerator
2028 * use the accel functions
2030 HRESULT WINAPI
CDefView::TranslateAccelerator(LPMSG lpmsg
)
2035 if (lpmsg
->message
>= WM_KEYFIRST
&& lpmsg
->message
<= WM_KEYLAST
)
2037 if (::TranslateAcceleratorW(m_hWnd
, m_hAccel
, lpmsg
) != 0)
2040 TRACE("-- key=0x04%lx\n", lpmsg
->wParam
) ;
2043 return m_pShellBrowser
->TranslateAcceleratorSB(lpmsg
, 0);
2046 HRESULT WINAPI
CDefView::EnableModeless(BOOL fEnable
)
2048 FIXME("(%p) stub\n", this);
2053 HRESULT WINAPI
CDefView::UIActivate(UINT uState
)
2055 // CHAR szName[MAX_PATH];
2057 int nPartArray
[1] = { -1};
2059 TRACE("(%p)->(state=%x) stub\n", this, uState
);
2061 /* don't do anything if the state isn't really changing */
2062 if (m_uState
== uState
)
2067 /* OnActivate handles the menu merging and internal state */
2070 /* only do This if we are active */
2071 if (uState
!= SVUIA_DEACTIVATE
)
2075 GetFolderPath is not a method of IShellFolder
2076 IShellFolder_GetFolderPath( m_pSFParent, szName, sizeof(szName) );
2078 /* set the number of parts */
2079 m_pShellBrowser
->SendControlMsg(FCW_STATUS
, SB_SETPARTS
, 1, (LPARAM
)nPartArray
, &lResult
);
2081 /* set the text for the parts */
2083 m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXTA, 0, (LPARAM)szName, &lResult);
2090 HRESULT WINAPI
CDefView::Refresh()
2092 TRACE("(%p)\n", this);
2094 m_ListView
.DeleteAllItems();
2100 HRESULT WINAPI
CDefView::CreateViewWindow(IShellView
*lpPrevView
, LPCFOLDERSETTINGS lpfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
)
2102 return CreateViewWindow3(psb
, lpPrevView
, SV3CVW3_DEFAULT
,
2103 (FOLDERFLAGS
)lpfs
->fFlags
, (FOLDERFLAGS
)lpfs
->fFlags
, (FOLDERVIEWMODE
)lpfs
->ViewMode
, NULL
, prcView
, phWnd
);
2106 HRESULT WINAPI
CDefView::DestroyViewWindow()
2108 TRACE("(%p)\n", this);
2110 /* Make absolutely sure all our UI is cleaned up */
2111 UIActivate(SVUIA_DEACTIVATE
);
2115 // "Accelerator tables loaded from resources are freed automatically when the application terminates." -- MSDN
2119 if (m_hMenuViewModes
)
2121 DestroyMenu(m_hMenuViewModes
);
2122 m_hMenuViewModes
= NULL
;
2127 DestroyMenu(m_hMenu
);
2133 m_ListView
.DestroyWindow();
2141 m_pShellBrowser
.Release();
2142 m_pCommDlgBrowser
.Release();
2147 HRESULT WINAPI
CDefView::GetCurrentInfo(LPFOLDERSETTINGS lpfs
)
2149 TRACE("(%p)->(%p) vmode=%x flags=%x\n", this, lpfs
,
2150 m_FolderSettings
.ViewMode
, m_FolderSettings
.fFlags
);
2153 return E_INVALIDARG
;
2155 *lpfs
= m_FolderSettings
;
2159 HRESULT WINAPI
CDefView::AddPropertySheetPages(DWORD dwReserved
, LPFNADDPROPSHEETPAGE lpfn
, LPARAM lparam
)
2161 FIXME("(%p) stub\n", this);
2166 HRESULT WINAPI
CDefView::SaveViewState()
2168 FIXME("(%p) stub\n", this);
2173 HRESULT WINAPI
CDefView::SelectItem(PCUITEMID_CHILD pidl
, UINT uFlags
)
2177 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n", this, pidl
, uFlags
);
2179 i
= LV_FindItemByPidl(pidl
);
2183 if(uFlags
& SVSI_ENSUREVISIBLE
)
2184 m_ListView
.EnsureVisible(i
, FALSE
);
2186 LVITEMW lvItem
= {0};
2187 lvItem
.mask
= LVIF_STATE
;
2188 lvItem
.stateMask
= LVIS_SELECTED
| LVIS_FOCUSED
;
2190 while (m_ListView
.GetItem(&lvItem
))
2192 if (lvItem
.iItem
== i
)
2194 if (uFlags
& SVSI_SELECT
)
2195 lvItem
.state
|= LVIS_SELECTED
;
2197 lvItem
.state
&= ~LVIS_SELECTED
;
2199 if (uFlags
& SVSI_FOCUSED
)
2200 lvItem
.state
&= ~LVIS_FOCUSED
;
2204 if (uFlags
& SVSI_DESELECTOTHERS
)
2205 lvItem
.state
&= ~LVIS_SELECTED
;
2208 m_ListView
.SetItem(&lvItem
);
2212 if((uFlags
& SVSI_EDIT
) == SVSI_EDIT
)
2213 m_ListView
.EditLabel(i
);
2218 HRESULT WINAPI
CDefView::GetItemObject(UINT uItem
, REFIID riid
, LPVOID
*ppvOut
)
2220 HRESULT hr
= E_NOINTERFACE
;
2222 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n", this, uItem
, debugstr_guid(&riid
), ppvOut
);
2228 case SVGIO_BACKGROUND
:
2229 if (IsEqualIID(riid
, IID_IContextMenu
))
2234 hr
= CDefViewBckgrndMenu_CreateInstance(m_pSF2Parent
, riid
, ppvOut
);
2235 if (FAILED_UNEXPECTEDLY(hr
))
2239 else if (IsEqualIID(riid
, IID_IDispatch
))
2241 if (m_pShellFolderViewDual
== NULL
)
2243 hr
= CDefViewDual_Constructor(riid
, (LPVOID
*)&m_pShellFolderViewDual
);
2244 if (FAILED_UNEXPECTEDLY(hr
))
2247 hr
= m_pShellFolderViewDual
->QueryInterface(riid
, ppvOut
);
2251 case SVGIO_SELECTION
:
2253 hr
= m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, riid
, 0, ppvOut
);
2254 if (FAILED_UNEXPECTEDLY(hr
))
2259 TRACE("-- (%p)->(interface=%p)\n", this, *ppvOut
);
2264 HRESULT STDMETHODCALLTYPE
CDefView::GetCurrentViewMode(UINT
*pViewMode
)
2266 TRACE("(%p)->(%p), stub\n", this, pViewMode
);
2269 return E_INVALIDARG
;
2271 *pViewMode
= m_FolderSettings
.ViewMode
;
2275 HRESULT STDMETHODCALLTYPE
CDefView::SetCurrentViewMode(UINT ViewMode
)
2278 TRACE("(%p)->(%u), stub\n", this, ViewMode
);
2280 /* It's not redundant to check FVM_AUTO because it's a (UINT)-1 */
2281 if (((INT
)ViewMode
< FVM_FIRST
|| (INT
)ViewMode
> FVM_LAST
) && ((INT
)ViewMode
!= FVM_AUTO
))
2282 return E_INVALIDARG
;
2284 /* Windows before Vista uses LVM_SETVIEW and possibly
2285 LVM_SETEXTENDEDLISTVIEWSTYLE to set the style of the listview,
2286 while later versions seem to accomplish this through other
2294 dwStyle
= LVS_REPORT
;
2297 dwStyle
= LVS_SMALLICON
;
2304 FIXME("ViewMode %d not implemented\n", ViewMode
);
2310 SetStyle(dwStyle
, LVS_TYPEMASK
);
2312 /* This will not necessarily be the actual mode set above.
2313 This mimics the behavior of Windows XP. */
2314 m_FolderSettings
.ViewMode
= ViewMode
;
2319 HRESULT STDMETHODCALLTYPE
CDefView::GetFolder(REFIID riid
, void **ppv
)
2321 if (m_pSFParent
== NULL
)
2324 return m_pSFParent
->QueryInterface(riid
, ppv
);
2327 HRESULT STDMETHODCALLTYPE
CDefView::Item(int iItemIndex
, PITEMID_CHILD
*ppidl
)
2329 PCUITEMID_CHILD pidl
= _PidlByItem(iItemIndex
);
2332 *ppidl
= ILClone(pidl
);
2337 return E_INVALIDARG
;
2340 HRESULT STDMETHODCALLTYPE
CDefView::ItemCount(UINT uFlags
, int *pcItems
)
2342 TRACE("(%p)->(%u %p)\n", this, uFlags
, pcItems
);
2344 if (uFlags
!= SVGIO_ALLVIEW
)
2345 FIXME("some flags unsupported, %x\n", uFlags
& ~SVGIO_ALLVIEW
);
2347 *pcItems
= m_ListView
.GetItemCount();
2352 HRESULT STDMETHODCALLTYPE
CDefView::Items(UINT uFlags
, REFIID riid
, void **ppv
)
2357 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectionMarkedItem(int *piItem
)
2359 TRACE("(%p)->(%p)\n", this, piItem
);
2361 *piItem
= m_ListView
.GetSelectionMark();
2366 HRESULT STDMETHODCALLTYPE
CDefView::GetFocusedItem(int *piItem
)
2368 TRACE("(%p)->(%p)\n", this, piItem
);
2370 *piItem
= m_ListView
.GetNextItem(-1, LVNI_FOCUSED
);
2375 HRESULT STDMETHODCALLTYPE
CDefView::GetItemPosition(PCUITEMID_CHILD pidl
, POINT
*ppt
)
2380 HRESULT STDMETHODCALLTYPE
CDefView::GetSpacing(POINT
*ppt
)
2382 TRACE("(%p)->(%p)\n", this, ppt
);
2390 m_ListView
.GetItemSpacing(spacing
);
2392 ppt
->x
= spacing
.cx
;
2393 ppt
->y
= spacing
.cy
;
2399 HRESULT STDMETHODCALLTYPE
CDefView::GetDefaultSpacing(POINT
*ppt
)
2404 HRESULT STDMETHODCALLTYPE
CDefView::GetAutoArrange()
2409 HRESULT STDMETHODCALLTYPE
CDefView::SelectItem(int iItem
, DWORD dwFlags
)
2413 TRACE("(%p)->(%d, %x)\n", this, iItem
, dwFlags
);
2416 lvItem
.stateMask
= LVIS_SELECTED
;
2418 if (dwFlags
& SVSI_ENSUREVISIBLE
)
2419 m_ListView
.EnsureVisible(iItem
, 0);
2422 if (dwFlags
& SVSI_DESELECTOTHERS
)
2423 m_ListView
.SetItemState(-1, 0, LVIS_SELECTED
);
2426 if (dwFlags
& SVSI_SELECT
)
2427 lvItem
.state
|= LVIS_SELECTED
;
2429 if (dwFlags
& SVSI_FOCUSED
)
2430 lvItem
.stateMask
|= LVIS_FOCUSED
;
2432 m_ListView
.SetItemState(iItem
, lvItem
.state
, lvItem
.stateMask
);
2434 if ((dwFlags
& SVSI_EDIT
) == SVSI_EDIT
)
2435 m_ListView
.EditLabel(iItem
);
2440 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItems(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD dwFlags
)
2445 /**********************************************************
2446 * IShellView2 implementation
2449 HRESULT STDMETHODCALLTYPE
CDefView::GetView(SHELLVIEWID
*view_guid
, ULONG view_type
)
2451 FIXME("(%p)->(%p, %lu) stub\n", this, view_guid
, view_type
);
2455 HRESULT STDMETHODCALLTYPE
CDefView::CreateViewWindow2(LPSV2CVW2_PARAMS view_params
)
2457 return CreateViewWindow3(view_params
->psbOwner
, view_params
->psvPrev
,
2458 SV3CVW3_DEFAULT
, (FOLDERFLAGS
)view_params
->pfs
->fFlags
, (FOLDERFLAGS
)view_params
->pfs
->fFlags
,
2459 (FOLDERVIEWMODE
)view_params
->pfs
->ViewMode
, view_params
->pvid
, view_params
->prcView
, &view_params
->hwndView
);
2462 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
)
2464 OLEMENUGROUPWIDTHS omw
= { { 0, 0, 0, 0, 0, 0 } };
2468 TRACE("(%p)->(shlview=%p shlbrs=%p rec=%p hwnd=%p vmode=%x flags=%x)\n", this, psvPrevious
, psb
, prcView
, hwnd
, mode
, flags
);
2469 if (prcView
!= NULL
)
2470 TRACE("-- left=%i top=%i right=%i bottom=%i\n", prcView
->left
, prcView
->top
, prcView
->right
, prcView
->bottom
);
2472 /* Validate the Shell Browser */
2473 if (psb
== NULL
|| m_hWnd
)
2474 return E_UNEXPECTED
;
2476 if (view_flags
!= SV3CVW3_DEFAULT
)
2477 FIXME("unsupported view flags 0x%08x\n", view_flags
);
2479 /* Set up the member variables */
2480 m_pShellBrowser
= psb
;
2481 m_FolderSettings
.ViewMode
= mode
;
2482 m_FolderSettings
.fFlags
= mask
& flags
;
2486 if (IsEqualIID(*view_id
, VID_LargeIcons
))
2487 m_FolderSettings
.ViewMode
= FVM_ICON
;
2488 else if (IsEqualIID(*view_id
, VID_SmallIcons
))
2489 m_FolderSettings
.ViewMode
= FVM_SMALLICON
;
2490 else if (IsEqualIID(*view_id
, VID_List
))
2491 m_FolderSettings
.ViewMode
= FVM_LIST
;
2492 else if (IsEqualIID(*view_id
, VID_Details
))
2493 m_FolderSettings
.ViewMode
= FVM_DETAILS
;
2494 else if (IsEqualIID(*view_id
, VID_Thumbnails
))
2495 m_FolderSettings
.ViewMode
= FVM_THUMBNAIL
;
2496 else if (IsEqualIID(*view_id
, VID_Tile
))
2497 m_FolderSettings
.ViewMode
= FVM_TILE
;
2498 else if (IsEqualIID(*view_id
, VID_ThumbStrip
))
2499 m_FolderSettings
.ViewMode
= FVM_THUMBSTRIP
;
2501 FIXME("Ignoring unrecognized VID %s\n", debugstr_guid(view_id
));
2504 /* Get our parent window */
2505 m_pShellBrowser
->GetWindow(&m_hWndParent
);
2507 /* Try to get the ICommDlgBrowserInterface, adds a reference !!! */
2508 m_pCommDlgBrowser
= NULL
;
2509 if (SUCCEEDED(m_pShellBrowser
->QueryInterface(IID_PPV_ARG(ICommDlgBrowser
, &m_pCommDlgBrowser
))))
2511 TRACE("-- CommDlgBrowser\n");
2514 Create(m_hWndParent
, prcView
, NULL
, WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
| WS_TABSTOP
, 0, 0U);
2525 SetWindowPos(HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_SHOWWINDOW
);
2530 m_hMenu
= CreateMenu();
2531 m_pShellBrowser
->InsertMenusSB(m_hMenu
, &omw
);
2532 TRACE("-- after fnInsertMenusSB\n");
2540 HRESULT STDMETHODCALLTYPE
CDefView::HandleRename(LPCITEMIDLIST new_pidl
)
2542 FIXME("(%p)->(%p) stub\n", this, new_pidl
);
2546 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItem(LPCITEMIDLIST item
, UINT flags
, POINT
*point
)
2548 FIXME("(%p)->(%p, %u, %p) stub\n", this, item
, flags
, point
);
2552 /**********************************************************
2553 * IShellFolderView implementation
2555 HRESULT STDMETHODCALLTYPE
CDefView::Rearrange(LPARAM sort
)
2557 FIXME("(%p)->(%ld) stub\n", this, sort
);
2561 HRESULT STDMETHODCALLTYPE
CDefView::GetArrangeParam(LPARAM
*sort
)
2563 FIXME("(%p)->(%p) stub\n", this, sort
);
2567 HRESULT STDMETHODCALLTYPE
CDefView::ArrangeGrid()
2569 FIXME("(%p) stub\n", this);
2573 HRESULT STDMETHODCALLTYPE
CDefView::AutoArrange()
2575 FIXME("(%p) stub\n", this);
2579 HRESULT STDMETHODCALLTYPE
CDefView::AddObject(PITEMID_CHILD pidl
, UINT
*item
)
2581 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2585 HRESULT STDMETHODCALLTYPE
CDefView::GetObject(PITEMID_CHILD
*pidl
, UINT item
)
2587 TRACE("(%p)->(%p %d)\n", this, pidl
, item
);
2588 return Item(item
, pidl
);
2591 HRESULT STDMETHODCALLTYPE
CDefView::RemoveObject(PITEMID_CHILD pidl
, UINT
*item
)
2594 TRACE("(%p)->(%p %p)\n", this, pidl
, item
);
2598 *item
= LV_FindItemByPidl(ILFindLastID(pidl
));
2599 m_ListView
.DeleteItem(*item
);
2604 m_ListView
.DeleteAllItems();
2610 HRESULT STDMETHODCALLTYPE
CDefView::GetObjectCount(UINT
*count
)
2612 TRACE("(%p)->(%p)\n", this, count
);
2613 *count
= m_ListView
.GetItemCount();
2617 HRESULT STDMETHODCALLTYPE
CDefView::SetObjectCount(UINT count
, UINT flags
)
2619 FIXME("(%p)->(%d %x) stub\n", this, count
, flags
);
2623 HRESULT STDMETHODCALLTYPE
CDefView::UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
)
2625 FIXME("(%p)->(%p %p %p) stub\n", this, pidl_old
, pidl_new
, item
);
2629 HRESULT STDMETHODCALLTYPE
CDefView::RefreshObject(PITEMID_CHILD pidl
, UINT
*item
)
2631 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2635 HRESULT STDMETHODCALLTYPE
CDefView::SetRedraw(BOOL redraw
)
2637 TRACE("(%p)->(%d)\n", this, redraw
);
2638 m_ListView
.SetRedraw(redraw
);
2642 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedCount(UINT
*count
)
2644 FIXME("(%p)->(%p) stub\n", this, count
);
2648 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
)
2650 TRACE("(%p)->(%p %p)\n", this, pidl
, items
);
2652 *items
= GetSelections();
2656 *pidl
= static_cast<PCUITEMID_CHILD
*>(LocalAlloc(0, *items
* sizeof(PCUITEMID_CHILD
)));
2659 return E_OUTOFMEMORY
;
2662 /* it's documented that caller shouldn't PIDLs, only array itself */
2663 memcpy(*pidl
, m_apidl
, *items
* sizeof(PCUITEMID_CHILD
));
2669 HRESULT STDMETHODCALLTYPE
CDefView::IsDropOnSource(IDropTarget
*drop_target
)
2671 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2675 HRESULT STDMETHODCALLTYPE
CDefView::GetDragPoint(POINT
*pt
)
2677 FIXME("(%p)->(%p) stub\n", this, pt
);
2681 HRESULT STDMETHODCALLTYPE
CDefView::GetDropPoint(POINT
*pt
)
2683 FIXME("(%p)->(%p) stub\n", this, pt
);
2687 HRESULT STDMETHODCALLTYPE
CDefView::MoveIcons(IDataObject
*obj
)
2689 TRACE("(%p)->(%p)\n", this, obj
);
2693 HRESULT STDMETHODCALLTYPE
CDefView::SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
)
2695 FIXME("(%p)->(%p %p) stub\n", this, pidl
, pt
);
2699 HRESULT STDMETHODCALLTYPE
CDefView::IsBkDropTarget(IDropTarget
*drop_target
)
2701 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2705 HRESULT STDMETHODCALLTYPE
CDefView::SetClipboard(BOOL move
)
2707 FIXME("(%p)->(%d) stub\n", this, move
);
2711 HRESULT STDMETHODCALLTYPE
CDefView::SetPoints(IDataObject
*obj
)
2713 FIXME("(%p)->(%p) stub\n", this, obj
);
2717 HRESULT STDMETHODCALLTYPE
CDefView::GetItemSpacing(ITEMSPACING
*spacing
)
2719 FIXME("(%p)->(%p) stub\n", this, spacing
);
2723 HRESULT STDMETHODCALLTYPE
CDefView::SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
)
2725 FIXME("(%p)->(%p %p) stub\n", this, new_cb
, old_cb
);
2729 HRESULT STDMETHODCALLTYPE
CDefView::Select(UINT flags
)
2731 FIXME("(%p)->(%d) stub\n", this, flags
);
2735 HRESULT STDMETHODCALLTYPE
CDefView::QuerySupport(UINT
*support
)
2737 TRACE("(%p)->(%p)\n", this, support
);
2741 HRESULT STDMETHODCALLTYPE
CDefView::SetAutomationObject(IDispatch
*disp
)
2743 FIXME("(%p)->(%p) stub\n", this, disp
);
2747 /**********************************************************
2748 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2750 HRESULT WINAPI
CDefView::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD
*prgCmds
, OLECMDTEXT
*pCmdText
)
2752 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
2753 this, pguidCmdGroup
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
2756 return E_INVALIDARG
;
2758 for (UINT i
= 0; i
< cCmds
; i
++)
2760 FIXME("\tprgCmds[%d].cmdID = %d\n", i
, prgCmds
[i
].cmdID
);
2761 prgCmds
[i
].cmdf
= 0;
2764 return OLECMDERR_E_UNKNOWNGROUP
;
2767 /**********************************************************
2768 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2770 * nCmdID is the OLECMDID_* enumeration
2772 HRESULT WINAPI
CDefView::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
2774 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2775 this, debugstr_guid(pguidCmdGroup
), nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2778 return OLECMDERR_E_UNKNOWNGROUP
;
2780 if (IsEqualCLSID(*pguidCmdGroup
, m_Category
))
2782 if (nCmdID
== FCIDM_SHVIEW_AUTOARRANGE
)
2784 if (V_VT(pvaIn
) != VT_INT_PTR
)
2785 return OLECMDERR_E_NOTSUPPORTED
;
2788 params
.cbSize
= sizeof(params
);
2789 params
.rcExclude
= *(RECT
*) V_INTREF(pvaIn
);
2791 if (m_hMenuViewModes
)
2793 /* Duplicate all but the last two items of the view modes menu */
2794 HMENU hmenuViewPopup
= CreatePopupMenu();
2795 Shell_MergeMenus(hmenuViewPopup
, m_hMenuViewModes
, 0, 0, 0xFFFF, 0);
2796 DeleteMenu(hmenuViewPopup
, GetMenuItemCount(hmenuViewPopup
) - 1, MF_BYPOSITION
);
2797 DeleteMenu(hmenuViewPopup
, GetMenuItemCount(hmenuViewPopup
) - 1, MF_BYPOSITION
);
2798 CheckViewMode(hmenuViewPopup
);
2799 TrackPopupMenuEx(hmenuViewPopup
, TPM_LEFTALIGN
| TPM_TOPALIGN
, params
.rcExclude
.left
, params
.rcExclude
.bottom
, m_hWndParent
, ¶ms
);
2800 ::DestroyMenu(hmenuViewPopup
);
2803 // pvaOut is VT_I4 with value 0x403 (cmd id of the new mode maybe?)
2804 V_VT(pvaOut
) = VT_I4
;
2805 V_I4(pvaOut
) = 0x403;
2809 if (IsEqualIID(*pguidCmdGroup
, CGID_Explorer
) &&
2811 (nCmdexecopt
== 4) && pvaOut
)
2814 if (IsEqualIID(*pguidCmdGroup
, CGID_ShellDocView
) &&
2819 return OLECMDERR_E_UNKNOWNGROUP
;
2822 /**********************************************************
2823 * ISVDropTarget implementation
2826 /******************************************************************************
2827 * drag_notify_subitem [Internal]
2829 * Figure out the shellfolder object, which is currently under the mouse cursor
2830 * and notify it via the IDropTarget interface.
2833 #define SCROLLAREAWIDTH 20
2835 HRESULT
CDefView::drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2841 /* Map from global to client coordinates and query the index of the listview-item, which is
2842 * currently under the mouse cursor. */
2843 LVHITTESTINFO htinfo
= {{pt
.x
, pt
.y
}, LVHT_ONITEM
};
2844 ScreenToClient(&htinfo
.pt
);
2845 lResult
= m_ListView
.HitTest(&htinfo
);
2847 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2848 ::GetClientRect(m_ListView
, &clientRect
);
2849 if (htinfo
.pt
.x
== m_ptLastMousePos
.x
&& htinfo
.pt
.y
== m_ptLastMousePos
.y
&&
2850 (htinfo
.pt
.x
< SCROLLAREAWIDTH
|| htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
||
2851 htinfo
.pt
.y
< SCROLLAREAWIDTH
|| htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
))
2853 m_cScrollDelay
= (m_cScrollDelay
+ 1) % 5; /* DragOver is called every 50 ms */
2854 if (m_cScrollDelay
== 0)
2856 /* Mouse did hover another 250 ms over the scroll-area */
2857 if (htinfo
.pt
.x
< SCROLLAREAWIDTH
)
2858 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEUP
, 0);
2860 if (htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
)
2861 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEDOWN
, 0);
2863 if (htinfo
.pt
.y
< SCROLLAREAWIDTH
)
2864 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEUP
, 0);
2866 if (htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
)
2867 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEDOWN
, 0);
2872 m_cScrollDelay
= 0; /* Reset, if the cursor is not over the listview's scroll-area */
2875 m_ptLastMousePos
= htinfo
.pt
;
2877 /* We need to check if we drag the selection over itself */
2878 if (lResult
!= -1 && m_pSourceDataObject
.p
!= NULL
)
2880 PCUITEMID_CHILD pidl
= _PidlByItem(lResult
);
2882 for (UINT i
= 0; i
< m_cidl
; i
++)
2884 if (pidl
== m_apidl
[i
])
2886 /* The item that is being draged is hovering itself. */
2893 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2894 if (m_pCurDropTarget
&& lResult
== m_iDragOverItem
)
2895 return m_pCurDropTarget
->DragOver(grfKeyState
, pt
, pdwEffect
);
2897 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2898 if (m_pCurDropTarget
)
2900 PCUITEMID_CHILD pidl
= _PidlByItem(m_iDragOverItem
);
2902 SelectItem(pidl
, 0);
2904 m_pCurDropTarget
->DragLeave();
2905 m_pCurDropTarget
.Release();
2908 m_iDragOverItem
= lResult
;
2912 /* We are not above one of the listview's subitems. Bind to the parent folder's
2913 * DropTarget interface. */
2914 hr
= m_pSFParent
->CreateViewObject(NULL
, IID_PPV_ARG(IDropTarget
,&m_pCurDropTarget
));
2918 /* Query the relative PIDL of the shellfolder object represented by the currently
2919 * dragged over listview-item ... */
2920 PCUITEMID_CHILD pidl
= _PidlByItem(lResult
);
2922 /* ... and bind m_pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2923 hr
= m_pSFParent
->GetUIObjectOf(m_ListView
, 1, &pidl
, IID_NULL_PPV_ARG(IDropTarget
, &m_pCurDropTarget
));
2926 /* If anything failed, m_pCurDropTarget should be NULL now, which ought to be a save state. */
2929 *pdwEffect
= DROPEFFECT_NONE
;
2933 if (m_iDragOverItem
!= -1)
2935 SelectItem(m_iDragOverItem
, SVSI_SELECT
);
2938 /* Notify the item just entered via DragEnter. */
2939 return m_pCurDropTarget
->DragEnter(m_pCurDataObject
, grfKeyState
, pt
, pdwEffect
);
2942 HRESULT WINAPI
CDefView::DragEnter(IDataObject
*pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2944 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2945 m_pCurDataObject
= pDataObject
;
2947 HRESULT hr
= drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2950 POINT ptClient
= {pt
.x
, pt
.y
};
2951 ScreenToClient(&ptClient
);
2952 ImageList_DragEnter(m_hWnd
, ptClient
.x
, ptClient
.y
);
2958 HRESULT WINAPI
CDefView::DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2960 POINT ptClient
= {pt
.x
, pt
.y
};
2961 ScreenToClient(&ptClient
);
2962 ImageList_DragMove(ptClient
.x
, ptClient
.y
);
2963 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2966 HRESULT WINAPI
CDefView::DragLeave()
2968 ImageList_DragLeave(m_hWnd
);
2970 if (m_pCurDropTarget
)
2972 m_pCurDropTarget
->DragLeave();
2973 m_pCurDropTarget
.Release();
2976 if (m_pCurDataObject
!= NULL
)
2978 m_pCurDataObject
.Release();
2981 m_iDragOverItem
= 0;
2986 HRESULT WINAPI
CDefView::Drop(IDataObject
* pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2988 ERR("GetKeyState(VK_LBUTTON): %d\n", GetKeyState(VK_LBUTTON
));
2990 ImageList_DragLeave(m_hWnd
);
2991 ImageList_EndDrag();
2993 if ((m_iDragOverItem
== -1 || m_pCurDropTarget
== NULL
) &&
2994 (*pdwEffect
& DROPEFFECT_MOVE
) &&
2995 /*(GetKeyState(VK_LBUTTON) != 0) &&*/
2996 (m_pSourceDataObject
.p
) &&
2997 (SHIsSameObject(pDataObject
, m_pSourceDataObject
)))
2999 if (m_pCurDropTarget
)
3001 m_pCurDropTarget
->DragLeave();
3002 m_pCurDropTarget
.Release();
3005 /* Restore the selection */
3006 m_ListView
.SetItemState(-1, 0, LVIS_SELECTED
);
3007 for (UINT i
= 0 ; i
< m_cidl
; i
++)
3008 SelectItem(m_apidl
[i
], SVSI_SELECT
);
3010 /* Reposition the items */
3012 while ((lvIndex
= m_ListView
.GetNextItem(lvIndex
, LVNI_SELECTED
)) > -1)
3015 if (m_ListView
.GetItemPosition(lvIndex
, &ptItem
))
3017 ptItem
.x
+= pt
.x
- m_ptFirstMousePos
.x
;
3018 ptItem
.y
+= pt
.y
- m_ptFirstMousePos
.y
;
3019 m_ListView
.SetItemPosition(lvIndex
, &ptItem
);
3023 else if (m_pCurDropTarget
)
3025 m_pCurDropTarget
->Drop(pDataObject
, grfKeyState
, pt
, pdwEffect
);
3026 m_pCurDropTarget
.Release();
3029 m_pCurDataObject
.Release();
3030 m_iDragOverItem
= 0;
3034 /**********************************************************
3035 * ISVDropSource implementation
3038 HRESULT WINAPI
CDefView::QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
)
3040 TRACE("(%p)\n", this);
3043 return DRAGDROP_S_CANCEL
;
3044 else if (!(grfKeyState
& MK_LBUTTON
) && !(grfKeyState
& MK_RBUTTON
))
3045 return DRAGDROP_S_DROP
;
3050 HRESULT WINAPI
CDefView::GiveFeedback(DWORD dwEffect
)
3052 TRACE("(%p)\n", this);
3054 return DRAGDROP_S_USEDEFAULTCURSORS
;
3057 /**********************************************************
3058 * ISVViewObject implementation
3061 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
)
3063 FIXME("Stub: this=%p\n", this);
3068 HRESULT WINAPI
CDefView::GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
, HDC hicTargetDevice
, LOGPALETTE
**ppColorSet
)
3070 FIXME("Stub: this=%p\n", this);
3075 HRESULT WINAPI
CDefView::Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
)
3077 FIXME("Stub: this=%p\n", this);
3082 HRESULT WINAPI
CDefView::Unfreeze(DWORD dwFreeze
)
3084 FIXME("Stub: this=%p\n", this);
3089 HRESULT WINAPI
CDefView::SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
)
3091 FIXME("partial stub: %p %08x %08x %p\n", this, aspects
, advf
, pAdvSink
);
3093 /* FIXME: we set the AdviseSink, but never use it to send any advice */
3094 m_pAdvSink
= pAdvSink
;
3095 m_dwAspects
= aspects
;
3101 HRESULT WINAPI
CDefView::GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
)
3103 TRACE("this=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n", this, pAspects
, pAdvf
, ppAdvSink
);
3107 *ppAdvSink
= m_pAdvSink
;
3108 m_pAdvSink
.p
->AddRef();
3112 *pAspects
= m_dwAspects
;
3120 HRESULT STDMETHODCALLTYPE
CDefView::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
3122 if (IsEqualIID(guidService
, SID_IShellBrowser
))
3123 return m_pShellBrowser
->QueryInterface(riid
, ppvObject
);
3124 else if(IsEqualIID(guidService
, SID_IFolderView
))
3125 return QueryInterface(riid
, ppvObject
);
3127 return E_NOINTERFACE
;
3130 HRESULT
CDefView::_MergeToolbar()
3132 CComPtr
<IExplorerToolbar
> ptb
;
3135 hr
= IUnknown_QueryService(m_pShellBrowser
, IID_IExplorerToolbar
, IID_PPV_ARG(IExplorerToolbar
, &ptb
));
3139 m_Category
= CGID_DefViewFrame
;
3141 hr
= ptb
->SetCommandTarget(static_cast<IOleCommandTarget
*>(this), &m_Category
, 0);
3149 hr
= ptb
->AddButtons(&m_Category
, buttonsCount
, buttons
);
3157 HRESULT
CDefView_CreateInstance(IShellFolder
*pFolder
, REFIID riid
, LPVOID
* ppvOut
)
3159 return ShellObjectCreatorInit
<CDefView
>(pFolder
, riid
, ppvOut
);
3162 HRESULT WINAPI
SHCreateShellFolderViewEx(
3163 LPCSFV psvcbi
, /* [in] shelltemplate struct */
3164 IShellView
**ppsv
) /* [out] IShellView pointer */
3166 CComPtr
<IShellView
> psv
;
3169 TRACE("sf=%p pidl=%p cb=%p mode=0x%08x parm=%p\n",
3170 psvcbi
->pshf
, psvcbi
->pidl
, psvcbi
->pfnCallback
,
3171 psvcbi
->fvm
, psvcbi
->psvOuter
);
3174 hRes
= CDefView_CreateInstance(psvcbi
->pshf
, IID_PPV_ARG(IShellView
, &psv
));
3175 if (FAILED_UNEXPECTEDLY(hRes
))
3178 *ppsv
= psv
.Detach();
3182 HRESULT WINAPI
SHCreateShellFolderView(const SFV_CREATE
*pcsfv
,
3185 CComPtr
<IShellView
> psv
;
3189 if (!pcsfv
|| pcsfv
->cbSize
!= sizeof(*pcsfv
))
3190 return E_INVALIDARG
;
3192 TRACE("sf=%p outer=%p callback=%p\n",
3193 pcsfv
->pshf
, pcsfv
->psvOuter
, pcsfv
->psfvcb
);
3195 hRes
= CDefView_CreateInstance(pcsfv
->pshf
, IID_PPV_ARG(IShellView
, &psv
));
3199 *ppsv
= psv
.Detach();