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_IShellView2
, IShellView2
)
329 COM_INTERFACE_ENTRY_IID(IID_IFolderView
, IFolderView
)
330 COM_INTERFACE_ENTRY_IID(IID_IShellFolderView
, IShellFolderView
)
331 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget
, IOleCommandTarget
)
332 COM_INTERFACE_ENTRY_IID(IID_IDropTarget
, IDropTarget
)
333 COM_INTERFACE_ENTRY_IID(IID_IDropSource
, IDropSource
)
334 COM_INTERFACE_ENTRY_IID(IID_IViewObject
, IViewObject
)
335 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider
, IServiceProvider
)
340 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
341 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
342 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
344 #define ID_LISTVIEW 1
347 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
348 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
349 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
351 typedef void (CALLBACK
*PFNSHGETSETTINGSPROC
)(LPSHELLFLAGSTATE lpsfs
, DWORD dwMask
);
353 CDefView::CDefView() :
357 m_hMenuArrangeModes(NULL
),
358 m_hMenuViewModes(NULL
),
359 m_hContextMenu(NULL
),
360 m_bmenuBarInitialized(FALSE
),
374 ZeroMemory(&m_FolderSettings
, sizeof(m_FolderSettings
));
375 ZeroMemory(&m_sortInfo
, sizeof(m_sortInfo
));
376 ZeroMemory(&m_ptLastMousePos
, sizeof(m_ptLastMousePos
));
377 ZeroMemory(&m_Category
, sizeof(m_Category
));
380 CDefView::~CDefView()
382 TRACE(" destroying IShellView(%p)\n", this);
392 HRESULT WINAPI
CDefView::Initialize(IShellFolder
*shellFolder
)
394 m_pSFParent
= shellFolder
;
395 shellFolder
->QueryInterface(IID_PPV_ARG(IShellFolder2
, &m_pSF2Parent
));
400 /**********************************************************
402 * ##### helperfunctions for communication with ICommDlgBrowser #####
404 HRESULT
CDefView::IncludeObject(PCUITEMID_CHILD pidl
)
408 if (m_pCommDlgBrowser
.p
!= NULL
)
410 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl
);
411 ret
= m_pCommDlgBrowser
->IncludeObject(this, pidl
);
412 TRACE("--0x%08x\n", ret
);
418 HRESULT
CDefView::OnDefaultCommand()
420 HRESULT ret
= S_FALSE
;
422 if (m_pCommDlgBrowser
.p
!= NULL
)
424 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
425 ret
= m_pCommDlgBrowser
->OnDefaultCommand(this);
426 TRACE("-- returns %08x\n", ret
);
432 HRESULT
CDefView::OnStateChange(UINT uFlags
)
434 HRESULT ret
= S_FALSE
;
436 if (m_pCommDlgBrowser
.p
!= NULL
)
438 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags
);
439 ret
= m_pCommDlgBrowser
->OnStateChange(this, uFlags
);
445 /**********************************************************
446 * set the toolbar of the filedialog buttons
448 * - activates the buttons from the shellbrowser according to
451 void CDefView::CheckToolbar()
457 if (m_pCommDlgBrowser
!= NULL
)
459 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
460 FCIDM_TB_SMALLICON
, (m_FolderSettings
.ViewMode
== FVM_LIST
) ? TRUE
: FALSE
, &result
);
461 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
462 FCIDM_TB_REPORTVIEW
, (m_FolderSettings
.ViewMode
== FVM_DETAILS
) ? TRUE
: FALSE
, &result
);
463 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
464 FCIDM_TB_SMALLICON
, TRUE
, &result
);
465 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
466 FCIDM_TB_REPORTVIEW
, TRUE
, &result
);
470 void CDefView::UpdateStatusbar()
472 WCHAR szFormat
[MAX_PATH
] = {0};
473 WCHAR szObjects
[MAX_PATH
] = {0};
476 cSelectedItems
= m_ListView
.GetSelectedCount();
479 LoadStringW(shell32_hInstance
, IDS_OBJECTS_SELECTED
, szFormat
, _countof(szFormat
));
480 StringCchPrintfW(szObjects
, MAX_PATH
, szFormat
, cSelectedItems
);
484 LoadStringW(shell32_hInstance
, IDS_OBJECTS
, szFormat
, _countof(szFormat
));
485 StringCchPrintfW(szObjects
, MAX_PATH
, szFormat
, m_ListView
.GetItemCount());
487 m_pShellBrowser
->SetStatusTextSB(szObjects
);
490 /**********************************************************
492 * ##### helperfunctions for initializing the view #####
494 /**********************************************************
495 * change the style of the listview control
497 void CDefView::SetStyle(DWORD dwAdd
, DWORD dwRemove
)
501 TRACE("(%p)\n", this);
503 tmpstyle
= ::GetWindowLongPtrW(m_ListView
, GWL_STYLE
);
504 ::SetWindowLongPtrW(m_ListView
, GWL_STYLE
, dwAdd
| (tmpstyle
& ~dwRemove
));
507 /**********************************************************
508 * ShellView_CreateList()
510 * - creates the list view window
512 BOOL
CDefView::CreateList()
514 DWORD dwStyle
, dwExStyle
;
518 dwStyle
= WS_TABSTOP
| WS_VISIBLE
| WS_CHILDWINDOW
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
|
519 LVS_SHAREIMAGELISTS
| LVS_EDITLABELS
| LVS_AUTOARRANGE
;
520 dwExStyle
= WS_EX_CLIENTEDGE
;
522 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
523 dwStyle
|= LVS_ALIGNLEFT
;
525 dwStyle
|= LVS_ALIGNTOP
| LVS_SHOWSELALWAYS
;
527 switch (m_FolderSettings
.ViewMode
)
534 dwStyle
|= LVS_REPORT
;
538 dwStyle
|= LVS_SMALLICON
;
550 if (m_FolderSettings
.fFlags
& FWF_AUTOARRANGE
)
551 dwStyle
|= LVS_AUTOARRANGE
;
553 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
554 m_FolderSettings
.fFlags
|= FWF_NOCLIENTEDGE
| FWF_NOSCROLL
;
556 if (m_FolderSettings
.fFlags
& FWF_SINGLESEL
)
557 dwStyle
|= LVS_SINGLESEL
;
559 if (m_FolderSettings
.fFlags
& FWF_NOCLIENTEDGE
)
560 dwExStyle
&= ~WS_EX_CLIENTEDGE
;
562 RECT rcListView
= {0,0,0,0};
563 m_ListView
.Create(m_hWnd
, rcListView
, L
"FolderView", dwStyle
, dwExStyle
, ID_LISTVIEW
);
568 m_sortInfo
.bIsAscending
= TRUE
;
569 m_sortInfo
.nHeaderID
= -1;
570 m_sortInfo
.nLastHeaderID
= -1;
574 /* UpdateShellSettings(); */
578 void CDefView::UpdateListColors()
580 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
582 /* Check if drop shadows option is enabled */
583 BOOL bDropShadow
= FALSE
;
584 DWORD cbDropShadow
= sizeof(bDropShadow
);
587 * The desktop ListView always take the default desktop colours, by
588 * remaining transparent and letting user32/win32k paint itself the
589 * desktop background color, if any.
591 m_ListView
.SetBkColor(CLR_NONE
);
593 SHGetValueW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
594 L
"ListviewShadow", NULL
, &bDropShadow
, &cbDropShadow
);
597 /* Set the icon background transparent */
598 m_ListView
.SetTextBkColor(CLR_NONE
);
599 m_ListView
.SetTextColor(RGB(255, 255, 255));
600 m_ListView
.SetExtendedListViewStyle(LVS_EX_TRANSPARENTSHADOWTEXT
, LVS_EX_TRANSPARENTSHADOWTEXT
);
604 /* Set the icon background as the same colour as the desktop */
605 COLORREF crDesktop
= GetSysColor(COLOR_DESKTOP
);
606 m_ListView
.SetTextBkColor(crDesktop
);
607 if (GetRValue(crDesktop
) + GetGValue(crDesktop
) + GetBValue(crDesktop
) > 128 * 3)
608 m_ListView
.SetTextColor(RGB(0, 0, 0));
610 m_ListView
.SetTextColor(RGB(255, 255, 255));
611 m_ListView
.SetExtendedListViewStyle(0, LVS_EX_TRANSPARENTSHADOWTEXT
);
616 /**********************************************************
617 * ShellView_InitList()
619 * - adds all needed columns to the shellview
621 BOOL
CDefView::InitList()
625 HIMAGELIST big_icons
, small_icons
;
629 m_ListView
.DeleteAllItems();
631 m_hMenuArrangeModes
= CreateMenu();
635 for (int i
= 0; 1; i
++)
637 if (FAILED(m_pSF2Parent
->GetDetailsOf(NULL
, i
, &sd
)))
639 StrRetToStrNW( szTemp
, 50, &sd
.str
, NULL
);
640 m_ListView
.InsertColumn(i
, szTemp
, sd
.fmt
, sd
.cxChar
* 8);
642 InsertMenuW(m_hMenuArrangeModes
, -1, MF_STRING
, 0x30 + i
, szTemp
);
645 InsertMenuW(m_hMenuArrangeModes
, -1, MF_BYPOSITION
| MF_SEPARATOR
, 0, 0);
649 FIXME("no m_pSF2Parent\n");
652 Shell_GetImageLists(&big_icons
, &small_icons
);
653 m_ListView
.SetImageList(big_icons
, LVSIL_NORMAL
);
654 m_ListView
.SetImageList(small_icons
, LVSIL_SMALL
);
659 /*************************************************************************
660 * ShellView_ListViewCompareItems
662 * Compare Function for the Listview (FileOpen Dialog)
665 * lParam1 [I] the first ItemIdList to compare with
666 * lParam2 [I] the second ItemIdList to compare with
667 * lpData [I] The column ID for the header Ctrl to process
670 * A negative value if the first item should precede the second,
671 * a positive value if the first item should follow the second,
672 * or zero if the two items are equivalent
674 INT CALLBACK
CDefView::ListViewCompareItems(LPARAM lParam1
, LPARAM lParam2
, LPARAM lpData
)
676 PCUIDLIST_RELATIVE pidl1
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam1
);
677 PCUIDLIST_RELATIVE pidl2
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam2
);
678 CDefView
*pThis
= reinterpret_cast<CDefView
*>(lpData
);
680 HRESULT hres
= pThis
->m_pSFParent
->CompareIDs(pThis
->m_sortInfo
.nHeaderID
, pidl1
, pidl2
);
681 if (FAILED_UNEXPECTEDLY(hres
))
684 SHORT nDiff
= HRESULT_CODE(hres
);
685 if (!pThis
->m_sortInfo
.bIsAscending
)
690 PCUITEMID_CHILD
CDefView::_PidlByItem(int i
)
692 return reinterpret_cast<PCUITEMID_CHILD
>(m_ListView
.GetItemData(i
));
695 PCUITEMID_CHILD
CDefView::_PidlByItem(LVITEM
& lvItem
)
697 return reinterpret_cast<PCUITEMID_CHILD
>(lvItem
.lParam
);
700 /**********************************************************
701 * LV_FindItemByPidl()
703 int CDefView::LV_FindItemByPidl(PCUITEMID_CHILD pidl
)
705 int cItems
= m_ListView
.GetItemCount();
707 for (int i
= 0; i
<cItems
; i
++)
709 PCUITEMID_CHILD currentpidl
= _PidlByItem(i
);
710 HRESULT hr
= m_pSFParent
->CompareIDs(0, pidl
, currentpidl
);
712 if (SUCCEEDED(hr
) && !HRESULT_CODE(hr
))
720 /**********************************************************
723 BOOLEAN
CDefView::LV_AddItem(PCUITEMID_CHILD pidl
)
727 TRACE("(%p)(pidl=%p)\n", this, pidl
);
729 lvItem
.mask
= LVIF_TEXT
| LVIF_IMAGE
| LVIF_PARAM
; /*set the mask*/
730 lvItem
.iItem
= m_ListView
.GetItemCount(); /*add the item to the end of the list*/
732 lvItem
.lParam
= reinterpret_cast<LPARAM
>(ILClone(pidl
)); /*set the item's data*/
733 lvItem
.pszText
= LPSTR_TEXTCALLBACKW
; /*get text on a callback basis*/
734 lvItem
.iImage
= I_IMAGECALLBACK
; /*get the image on a callback basis*/
735 lvItem
.stateMask
= LVIS_CUT
;
737 if (m_ListView
.InsertItem(&lvItem
) == -1)
743 /**********************************************************
746 BOOLEAN
CDefView::LV_DeleteItem(PCUITEMID_CHILD pidl
)
750 TRACE("(%p)(pidl=%p)\n", this, pidl
);
752 nIndex
= LV_FindItemByPidl(pidl
);
754 return (-1 == m_ListView
.DeleteItem(nIndex
)) ? FALSE
: TRUE
;
757 /**********************************************************
760 BOOLEAN
CDefView::LV_RenameItem(PCUITEMID_CHILD pidlOld
, PCUITEMID_CHILD pidlNew
)
765 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", this, pidlOld
, pidlNew
);
767 nItem
= LV_FindItemByPidl(pidlOld
);
771 lvItem
.mask
= LVIF_PARAM
; /* only the pidl */
772 lvItem
.iItem
= nItem
;
774 m_ListView
.GetItem(&lvItem
);
776 SHFree(reinterpret_cast<LPVOID
>(lvItem
.lParam
));
777 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
778 lvItem
.iItem
= nItem
;
780 lvItem
.lParam
= reinterpret_cast<LPARAM
>(ILClone(pidlNew
)); /* set the item's data */
781 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
782 m_ListView
.SetItem(&lvItem
);
783 m_ListView
.Update(nItem
);
784 return TRUE
; /* FIXME: better handling */
790 /**********************************************************
793 BOOLEAN
CDefView::LV_ProdItem(PCUITEMID_CHILD pidl
)
798 TRACE("(%p)(pidl=%p)\n", this, pidl
);
800 nItem
= LV_FindItemByPidl(pidl
);
804 lvItem
.mask
= LVIF_IMAGE
;
805 lvItem
.iItem
= nItem
;
807 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
808 m_ListView
.SetItem(&lvItem
);
809 m_ListView
.Update(nItem
);
816 /**********************************************************
817 * ShellView_FillList()
819 * - gets the objectlist from the shellfolder
821 * - fills the list into the view
823 INT CALLBACK
CDefView::fill_list(LPVOID ptr
, LPVOID arg
)
825 PITEMID_CHILD pidl
= static_cast<PITEMID_CHILD
>(ptr
);
826 CDefView
*pThis
= static_cast<CDefView
*>(arg
);
828 /* in a commdlg This works as a filemask*/
829 if (pThis
->IncludeObject(pidl
) == S_OK
)
830 pThis
->LV_AddItem(pidl
);
836 HRESULT
CDefView::FillList()
838 CComPtr
<IEnumIDList
> pEnumIDList
;
844 DWORD dFlags
= SHCONTF_NONFOLDERS
| SHCONTF_FOLDERS
;
848 /* determine if there is a setting to show all the hidden files/folders */
849 if (RegOpenKeyExW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", 0, KEY_QUERY_VALUE
, &hKey
) == ERROR_SUCCESS
)
851 DWORD dataLength
, flagVal
;
853 dataLength
= sizeof(flagVal
);
854 if (RegQueryValueExW(hKey
, L
"Hidden", NULL
, NULL
, (LPBYTE
)&flagVal
, &dataLength
) == ERROR_SUCCESS
)
856 /* if the value is 1, then show all hidden files/folders */
859 dFlags
|= SHCONTF_INCLUDEHIDDEN
;
860 m_ListView
.SendMessageW(LVM_SETCALLBACKMASK
, LVIS_CUT
, 0);
868 /* get the itemlist from the shfolder */
869 hRes
= m_pSFParent
->EnumObjects(m_hWnd
, dFlags
, &pEnumIDList
);
877 /* create a pointer array */
878 hdpa
= DPA_Create(16);
881 return(E_OUTOFMEMORY
);
884 /* copy the items into the array*/
885 while((S_OK
== pEnumIDList
->Next(1, &pidl
, &dwFetched
)) && dwFetched
)
887 if (DPA_InsertPtr(hdpa
, 0x7fff, pidl
) == -1)
893 /*turn the listview's redrawing off*/
894 m_ListView
.SetRedraw(FALSE
);
896 DPA_DestroyCallback( hdpa
, fill_list
, this);
901 m_pSF2Parent
->GetDefaultColumn(NULL
, (ULONG
*)&m_sortInfo
.nHeaderID
, NULL
);
905 FIXME("no m_pSF2Parent\n");
907 m_sortInfo
.bIsAscending
= TRUE
;
908 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
909 m_ListView
.SortItems(ListViewCompareItems
, this);
911 /*turn the listview's redrawing back on and force it to draw*/
912 m_ListView
.SetRedraw(TRUE
);
917 LRESULT
CDefView::OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
919 m_ListView
.UpdateWindow();
924 LRESULT
CDefView::OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
926 return m_ListView
.SendMessageW(uMsg
, 0, 0);
929 LRESULT
CDefView::OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
936 DestroyMenu(m_hMenu
);
939 RevokeDragDrop(m_hWnd
);
940 SHChangeNotifyDeregister(m_hNotify
);
942 SHFree(m_pidlParent
);
949 LRESULT
CDefView::OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
951 /* redirect to parent */
952 if (m_FolderSettings
.fFlags
& (FWF_DESKTOP
| FWF_TRANSPARENT
))
953 return SendMessageW(GetParent(), WM_ERASEBKGND
, wParam
, lParam
);
959 LRESULT
CDefView::OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
961 /* Update desktop labels color */
964 /* Forward WM_SYSCOLORCHANGE to common controls */
965 return m_ListView
.SendMessageW(uMsg
, 0, 0);
968 LRESULT
CDefView::OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
970 return reinterpret_cast<LRESULT
>(m_pShellBrowser
.p
);
973 LRESULT
CDefView::OnNCCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
980 LRESULT
CDefView::OnNCDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
987 /**********************************************************
988 * ShellView_OnCreate()
990 LRESULT
CDefView::OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
992 CComPtr
<IDropTarget
> pdt
;
993 SHChangeNotifyEntry ntreg
;
994 CComPtr
<IPersistFolder2
> ppf2
;
1006 if (SUCCEEDED(QueryInterface(IID_PPV_ARG(IDropTarget
, &pdt
))))
1008 if (FAILED(RegisterDragDrop(m_hWnd
, pdt
)))
1009 ERR("Registering Drag Drop Failed");
1012 /* register for receiving notifications */
1013 m_pSFParent
->QueryInterface(IID_PPV_ARG(IPersistFolder2
, &ppf2
));
1016 ppf2
->GetCurFolder(&m_pidlParent
);
1017 ntreg
.fRecursive
= TRUE
;
1018 ntreg
.pidl
= m_pidlParent
;
1019 m_hNotify
= SHChangeNotifyRegister(m_hWnd
, SHCNRF_InterruptLevel
| SHCNRF_ShellLevel
, SHCNE_ALLEVENTS
, SHV_CHANGE_NOTIFY
, 1, &ntreg
);
1022 m_hAccel
= LoadAcceleratorsW(shell32_hInstance
, MAKEINTRESOURCEW(IDA_SHELLVIEW
));
1029 /**********************************************************
1030 * #### Handling of the menus ####
1033 extern "C" DWORD WINAPI
SHMenuIndexFromID(HMENU hMenu
, UINT uID
);
1035 HMENU
GetSubmenuByID(HMENU hmenu
, UINT id
)
1037 MENUITEMINFOW mii
= {sizeof(mii
), MIIM_SUBMENU
};
1038 if (::GetMenuItemInfoW(hmenu
, id
, FALSE
, &mii
))
1039 return mii
.hSubMenu
;
1044 /* ReallyGetMenuItemID returns the id of an item even if it opens a submenu,
1045 GetMenuItemID returns -1 if the specified item opens a submenu */
1046 UINT
ReallyGetMenuItemID(HMENU hmenu
, int i
)
1048 MENUITEMINFOW mii
= {sizeof(mii
), MIIM_ID
};
1049 if (::GetMenuItemInfoW(hmenu
, i
, TRUE
, &mii
))
1055 HRESULT
CDefView::FillFileMenu()
1057 HMENU hFileMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_FILE
);
1061 /* Cleanup the items added previously */
1062 for (int i
= GetMenuItemCount(hFileMenu
) - 1; i
>= 0; i
--)
1064 UINT id
= GetMenuItemID(hFileMenu
, i
);
1065 if (id
< FCIDM_BROWSERFIRST
|| id
> FCIDM_BROWSERLAST
)
1066 DeleteMenu(hFileMenu
, i
, MF_BYPOSITION
);
1069 /* Store the context menu in m_pCM and keep it in order to invoke the selected command later on */
1070 HRESULT hr
= GetItemObject(SVGIO_SELECTION
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1071 if (FAILED_UNEXPECTEDLY(hr
))
1074 IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1076 HMENU hmenu
= CreatePopupMenu();
1078 hr
= m_pCM
->QueryContextMenu(hmenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, 0);
1079 if (FAILED_UNEXPECTEDLY(hr
))
1082 // TODO: filter or something
1084 Shell_MergeMenus(hFileMenu
, hmenu
, 0, 0, 0xFFFF, MM_ADDSEPARATOR
| MM_SUBMENUSHAVEIDS
);
1086 ::DestroyMenu(hmenu
);
1091 HRESULT
CDefView::FillEditMenu()
1093 HMENU hEditMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_EDIT
);
1097 HMENU hmenuContents
= ::LoadMenuW(shell32_hInstance
, L
"MENU_003");
1101 Shell_MergeMenus(hEditMenu
, hmenuContents
, 0, 0, 0xFFFF, 0);
1103 ::DestroyMenu(hmenuContents
);
1108 HRESULT
CDefView::FillViewMenu()
1110 HMENU hViewMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_VIEW
);
1114 m_hMenuViewModes
= ::LoadMenuW(shell32_hInstance
, L
"MENU_001");
1115 if (!m_hMenuViewModes
)
1118 UINT i
= SHMenuIndexFromID(hViewMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
);
1119 Shell_MergeMenus(hViewMenu
, m_hMenuViewModes
, i
, 0, 0xFFFF, MM_ADDSEPARATOR
| MM_DONTREMOVESEPS
| MM_SUBMENUSHAVEIDS
);
1124 HRESULT
CDefView::FillArrangeAsMenu(HMENU hmenuArrange
)
1126 /* We only need to fill this once */
1127 if (GetMenuItemID(hmenuArrange
, 0) == FCIDM_SHVIEW_AUTOARRANGE
)
1129 Shell_MergeMenus(hmenuArrange
, m_hMenuArrangeModes
, 0, 0, 0xFFFF,0);
1132 /* Also check the menu item according to which we sort */
1133 CheckMenuRadioItem(hmenuArrange
,
1136 m_sortInfo
.nHeaderID
+ 0x30,
1142 HRESULT
CDefView::CheckViewMode(HMENU hmenuView
)
1144 if (m_FolderSettings
.ViewMode
>= FVM_FIRST
&& m_FolderSettings
.ViewMode
<= FVM_LAST
)
1146 UINT iItemFirst
= FCIDM_SHVIEW_BIGICON
;
1147 UINT iItemLast
= iItemFirst
+ FVM_LAST
- FVM_FIRST
;
1148 UINT iItem
= iItemFirst
+ m_FolderSettings
.ViewMode
- FVM_FIRST
;
1149 CheckMenuRadioItem(hmenuView
, iItemFirst
, iItemLast
, iItem
, MF_BYCOMMAND
);
1155 /**********************************************************
1156 * ShellView_GetSelections()
1158 * - fills the m_apidl list with the selected objects
1161 * number of selected items
1163 UINT
CDefView::GetSelections()
1167 m_cidl
= m_ListView
.GetSelectedCount();
1168 m_apidl
= static_cast<PCUITEMID_CHILD
*>(SHAlloc(m_cidl
* sizeof(PCUITEMID_CHILD
)));
1175 TRACE("-- Items selected =%u\n", m_cidl
);
1179 while ((lvIndex
= m_ListView
.GetNextItem(lvIndex
, LVNI_SELECTED
)) > -1)
1181 m_apidl
[i
] = _PidlByItem(lvIndex
);
1185 TRACE("-- selected Item found\n");
1191 HRESULT
CDefView::InvokeContextMenuCommand(UINT uCommand
)
1193 CMINVOKECOMMANDINFO cmi
;
1195 ZeroMemory(&cmi
, sizeof(cmi
));
1196 cmi
.cbSize
= sizeof(cmi
);
1197 cmi
.lpVerb
= MAKEINTRESOURCEA(uCommand
);
1200 if (GetKeyState(VK_SHIFT
) & 0x8000)
1201 cmi
.fMask
|= CMIC_MASK_SHIFT_DOWN
;
1203 if (GetKeyState(VK_CONTROL
) & 0x8000)
1204 cmi
.fMask
|= CMIC_MASK_CONTROL_DOWN
;
1206 HRESULT hr
= m_pCM
->InvokeCommand(&cmi
);
1207 if (FAILED_UNEXPECTEDLY(hr
))
1213 /**********************************************************
1214 * ShellView_OpenSelectedItems()
1216 HRESULT
CDefView::OpenSelectedItems()
1222 m_cidl
= m_ListView
.GetSelectedCount();
1226 hResult
= OnDefaultCommand();
1227 if (hResult
== S_OK
)
1230 hMenu
= CreatePopupMenu();
1234 hResult
= GetItemObject(SVGIO_SELECTION
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1235 if (FAILED_UNEXPECTEDLY(hResult
))
1238 IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1240 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, 0x20, 0x7fff, CMF_DEFAULTONLY
);
1241 if (FAILED_UNEXPECTEDLY(hResult
))
1244 uCommand
= GetMenuDefaultItem(hMenu
, FALSE
, 0);
1245 if (uCommand
== (UINT
)-1)
1251 InvokeContextMenuCommand(uCommand
);
1260 IUnknown_SetSite(m_pCM
, NULL
);
1267 /**********************************************************
1268 * ShellView_DoContextMenu()
1270 LRESULT
CDefView::OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1279 TRACE("(%p)->(0x%08x 0x%08x) stub\n", this, x
, y
);
1281 m_hContextMenu
= CreatePopupMenu();
1282 if (!m_hContextMenu
)
1285 m_cidl
= m_ListView
.GetSelectedCount();
1287 hResult
= GetItemObject( m_cidl
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1288 if (FAILED_UNEXPECTEDLY(hResult
))
1291 IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1293 hResult
= m_pCM
->QueryContextMenu(m_hContextMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1294 if (FAILED_UNEXPECTEDLY(hResult
))
1297 uCommand
= TrackPopupMenu(m_hContextMenu
,
1298 TPM_LEFTALIGN
| TPM_RETURNCMD
| TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
,
1299 x
, y
, 0, m_hWnd
, NULL
);
1303 if (uCommand
== FCIDM_SHVIEW_OPEN
&& OnDefaultCommand() == S_OK
)
1306 InvokeContextMenuCommand(uCommand
);
1311 IUnknown_SetSite(m_pCM
, NULL
);
1317 DestroyMenu(m_hContextMenu
);
1318 m_hContextMenu
= NULL
;
1324 LRESULT
CDefView::OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
)
1329 hMenu
= CreatePopupMenu();
1333 hResult
= GetItemObject( bUseSelection
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1334 if (FAILED_UNEXPECTEDLY( hResult
))
1337 IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1339 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1340 if (FAILED_UNEXPECTEDLY( hResult
))
1343 InvokeContextMenuCommand(uCommand
);
1348 IUnknown_SetSite(m_pCM
, NULL
);
1358 /**********************************************************
1359 * ##### message handling #####
1362 /**********************************************************
1363 * ShellView_OnSize()
1365 LRESULT
CDefView::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1367 WORD wWidth
, wHeight
;
1369 wWidth
= LOWORD(lParam
);
1370 wHeight
= HIWORD(lParam
);
1372 TRACE("%p width=%u height=%u\n", this, wWidth
, wHeight
);
1374 /* Resize the ListView to fit our window */
1377 ::MoveWindow(m_ListView
, 0, 0, wWidth
, wHeight
, TRUE
);
1383 /**********************************************************
1384 * ShellView_OnDeactivate()
1389 void CDefView::OnDeactivate()
1391 TRACE("%p\n", this);
1393 if (m_uState
!= SVUIA_DEACTIVATE
)
1395 // TODO: cleanup menu after deactivation
1397 m_uState
= SVUIA_DEACTIVATE
;
1401 void CDefView::DoActivate(UINT uState
)
1403 TRACE("%p uState=%x\n", this, uState
);
1405 /*don't do anything if the state isn't really changing */
1406 if (m_uState
== uState
)
1411 if (uState
== SVUIA_DEACTIVATE
)
1417 if(m_hMenu
&& !m_bmenuBarInitialized
)
1421 m_pShellBrowser
->SetMenuSB(m_hMenu
, 0, m_hWnd
);
1422 m_bmenuBarInitialized
= TRUE
;
1425 if (SVUIA_ACTIVATE_FOCUS
== uState
)
1427 m_ListView
.SetFocus();
1435 /**********************************************************
1436 * ShellView_OnActivate()
1438 LRESULT
CDefView::OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1440 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1444 /**********************************************************
1445 * ShellView_OnSetFocus()
1448 LRESULT
CDefView::OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1450 TRACE("%p\n", this);
1452 /* Tell the browser one of our windows has received the focus. This
1453 should always be done before merging menus (OnActivate merges the
1454 menus) if one of our windows has the focus.*/
1456 m_pShellBrowser
->OnViewWindowActive(this);
1457 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1459 /* Set the focus to the listview */
1460 m_ListView
.SetFocus();
1462 /* Notify the ICommDlgBrowser interface */
1463 OnStateChange(CDBOSC_SETFOCUS
);
1468 /**********************************************************
1469 * ShellView_OnKillFocus()
1471 LRESULT
CDefView::OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1473 TRACE("(%p) stub\n", this);
1475 DoActivate(SVUIA_ACTIVATE_NOFOCUS
);
1476 /* Notify the ICommDlgBrowser */
1477 OnStateChange(CDBOSC_KILLFOCUS
);
1482 /**********************************************************
1483 * ShellView_OnCommand()
1486 * the CmdID's are the ones from the context menu
1488 LRESULT
CDefView::OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1495 dwCmdID
= GET_WM_COMMAND_ID(wParam
, lParam
);
1496 dwCmd
= GET_WM_COMMAND_CMD(wParam
, lParam
);
1497 hwndCmd
= GET_WM_COMMAND_HWND(wParam
, lParam
);
1499 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n", this, dwCmdID
, dwCmd
, hwndCmd
);
1503 case FCIDM_SHVIEW_SMALLICON
:
1504 m_FolderSettings
.ViewMode
= FVM_SMALLICON
;
1505 SetStyle (LVS_SMALLICON
, LVS_TYPEMASK
);
1509 case FCIDM_SHVIEW_BIGICON
:
1510 m_FolderSettings
.ViewMode
= FVM_ICON
;
1511 SetStyle (LVS_ICON
, LVS_TYPEMASK
);
1515 case FCIDM_SHVIEW_LISTVIEW
:
1516 m_FolderSettings
.ViewMode
= FVM_LIST
;
1517 SetStyle (LVS_LIST
, LVS_TYPEMASK
);
1521 case FCIDM_SHVIEW_REPORTVIEW
:
1522 m_FolderSettings
.ViewMode
= FVM_DETAILS
;
1523 SetStyle (LVS_REPORT
, LVS_TYPEMASK
);
1527 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1532 m_sortInfo
.nHeaderID
= dwCmdID
- 0x30;
1533 m_sortInfo
.bIsAscending
= TRUE
;
1534 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
1535 m_ListView
.SortItems(ListViewCompareItems
, this);
1538 case FCIDM_SHVIEW_SNAPTOGRID
:
1539 case FCIDM_SHVIEW_AUTOARRANGE
:
1542 case FCIDM_SHVIEW_SELECTALL
:
1543 m_ListView
.SetItemState(-1, LVIS_SELECTED
, LVIS_SELECTED
);
1546 case FCIDM_SHVIEW_INVERTSELECTION
:
1547 nCount
= m_ListView
.GetItemCount();
1548 for (int i
=0; i
< nCount
; i
++)
1549 m_ListView
.SetItemState(i
, m_ListView
.GetItemState(i
, LVIS_SELECTED
) ? 0 : LVIS_SELECTED
, LVIS_SELECTED
);
1552 case FCIDM_SHVIEW_REFRESH
:
1556 case FCIDM_SHVIEW_DELETE
:
1557 case FCIDM_SHVIEW_CUT
:
1558 case FCIDM_SHVIEW_COPY
:
1559 case FCIDM_SHVIEW_RENAME
:
1560 return OnExplorerCommand(dwCmdID
, TRUE
);
1562 case FCIDM_SHVIEW_INSERT
:
1563 case FCIDM_SHVIEW_UNDO
:
1564 case FCIDM_SHVIEW_INSERTLINK
:
1565 case FCIDM_SHVIEW_NEWFOLDER
:
1566 return OnExplorerCommand(dwCmdID
, FALSE
);
1568 /* WM_COMMAND messages from the file menu are routed to the CDefView so as to let m_pCM handle the command */
1571 InvokeContextMenuCommand(dwCmdID
);
1578 /**********************************************************
1579 * ShellView_OnNotify()
1582 LRESULT
CDefView::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1586 LPNMLISTVIEW lpnmlv
;
1587 NMLVDISPINFOW
*lpdi
;
1588 PCUITEMID_CHILD pidl
;
1592 lpnmh
= (LPNMHDR
)lParam
;
1593 lpnmlv
= (LPNMLISTVIEW
)lpnmh
;
1594 lpdi
= (NMLVDISPINFOW
*)lpnmh
;
1596 TRACE("%p CtlID=%u lpnmh->code=%x\n", this, CtlID
, lpnmh
->code
);
1598 switch (lpnmh
->code
)
1601 TRACE("-- NM_SETFOCUS %p\n", this);
1602 OnSetFocus(0, 0, 0, unused
);
1606 TRACE("-- NM_KILLFOCUS %p\n", this);
1608 /* Notify the ICommDlgBrowser interface */
1609 OnStateChange(CDBOSC_KILLFOCUS
);
1613 TRACE("-- NM_CUSTOMDRAW %p\n", this);
1614 return CDRF_DODEFAULT
;
1616 case NM_RELEASEDCAPTURE
:
1617 TRACE("-- NM_RELEASEDCAPTURE %p\n", this);
1621 TRACE("-- NM_CLICK %p\n", this);
1625 TRACE("-- NM_RCLICK %p\n", this);
1629 TRACE("-- NM_DBLCLK %p\n", this);
1630 OpenSelectedItems();
1634 TRACE("-- NM_RETURN %p\n", this);
1635 OpenSelectedItems();
1639 TRACE("-- HDN_ENDTRACKW %p\n", this);
1640 /*nColumn1 = m_ListView.GetColumnWidth(0);
1641 nColumn2 = m_ListView.GetColumnWidth(1);*/
1644 case LVN_DELETEITEM
:
1645 TRACE("-- LVN_DELETEITEM %p\n", this);
1647 /*delete the pidl because we made a copy of it*/
1648 SHFree(reinterpret_cast<LPVOID
>(lpnmlv
->lParam
));
1652 case LVN_DELETEALLITEMS
:
1653 TRACE("-- LVN_DELETEALLITEMS %p\n", this);
1656 case LVN_INSERTITEM
:
1657 TRACE("-- LVN_INSERTITEM (STUB)%p\n", this);
1660 case LVN_ITEMACTIVATE
:
1661 TRACE("-- LVN_ITEMACTIVATE %p\n", this);
1662 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1665 case LVN_COLUMNCLICK
:
1666 m_sortInfo
.nHeaderID
= lpnmlv
->iSubItem
;
1667 if (m_sortInfo
.nLastHeaderID
== m_sortInfo
.nHeaderID
)
1668 m_sortInfo
.bIsAscending
= !m_sortInfo
.bIsAscending
;
1670 m_sortInfo
.bIsAscending
= TRUE
;
1671 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
1673 m_ListView
.SortItems(ListViewCompareItems
, this);
1676 case LVN_GETDISPINFOA
:
1677 case LVN_GETDISPINFOW
:
1678 TRACE("-- LVN_GETDISPINFO %p\n", this);
1679 pidl
= _PidlByItem(lpdi
->item
);
1681 if (lpdi
->item
.mask
& LVIF_TEXT
) /* text requested */
1686 if (FAILED_UNEXPECTEDLY(m_pSF2Parent
->GetDetailsOf(pidl
, lpdi
->item
.iSubItem
, &sd
)))
1689 if (lpnmh
->code
== LVN_GETDISPINFOA
)
1691 /* shouldn't happen */
1692 NMLVDISPINFOA
*lpdiA
= (NMLVDISPINFOA
*)lpnmh
;
1693 StrRetToStrNA( lpdiA
->item
.pszText
, lpdiA
->item
.cchTextMax
, &sd
.str
, NULL
);
1694 TRACE("-- text=%s\n", lpdiA
->item
.pszText
);
1696 else /* LVN_GETDISPINFOW */
1698 StrRetToStrNW( lpdi
->item
.pszText
, lpdi
->item
.cchTextMax
, &sd
.str
, NULL
);
1699 TRACE("-- text=%s\n", debugstr_w(lpdi
->item
.pszText
));
1704 FIXME("no m_pSF2Parent\n");
1707 if(lpdi
->item
.mask
& LVIF_IMAGE
) /* image requested */
1709 lpdi
->item
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
1711 if(lpdi
->item
.mask
& LVIF_STATE
)
1713 ULONG attributes
= SFGAO_HIDDEN
;
1714 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(1, &pidl
, &attributes
)))
1716 if (attributes
& SFGAO_HIDDEN
)
1718 lpdi
->item
.state
|= LVIS_CUT
;
1722 lpdi
->item
.mask
|= LVIF_DI_SETITEM
;
1725 case LVN_ITEMCHANGED
:
1726 TRACE("-- LVN_ITEMCHANGED %p\n", this);
1727 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1732 case LVN_BEGINRDRAG
:
1733 TRACE("-- LVN_BEGINDRAG\n");
1735 if (GetSelections())
1737 CComPtr
<IDataObject
> pda
;
1738 DWORD dwAttributes
= SFGAO_CANLINK
;
1739 DWORD dwEffect
= DROPEFFECT_COPY
| DROPEFFECT_MOVE
;
1741 if (SUCCEEDED(m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, IID_NULL_PPV_ARG(IDataObject
, &pda
))))
1743 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(m_cidl
, m_apidl
, &dwAttributes
)))
1745 if (dwAttributes
& SFGAO_CANLINK
)
1747 dwEffect
|= DROPEFFECT_LINK
;
1751 CComPtr
<IAsyncOperation
> piaso
;
1752 if (SUCCEEDED(pda
->QueryInterface(IID_PPV_ARG(IAsyncOperation
, &piaso
))))
1754 piaso
->SetAsyncMode(TRUE
);
1759 m_pSourceDataObject
= pda
;
1760 m_ptFirstMousePos
= ((LPNMLISTVIEW
)lParam
)->ptAction
;
1761 ClientToScreen(&m_ptFirstMousePos
);
1763 DoDragDrop(pda
, this, dwEffect
, &dwEffect2
);
1765 m_pSourceDataObject
.Release();
1770 case LVN_BEGINLABELEDITW
:
1772 DWORD dwAttr
= SFGAO_CANRENAME
;
1773 pidl
= _PidlByItem(lpdi
->item
);
1775 TRACE("-- LVN_BEGINLABELEDITW %p\n", this);
1777 m_pSFParent
->GetAttributesOf(1, &pidl
, &dwAttr
);
1778 if (SFGAO_CANRENAME
& dwAttr
)
1786 case LVN_ENDLABELEDITW
:
1788 TRACE("-- LVN_ENDLABELEDITW %p\n", this);
1790 m_isEditing
= FALSE
;
1792 if (lpdi
->item
.pszText
)
1797 pidl
= _PidlByItem(lpdi
->item
);
1798 PITEMID_CHILD pidlNew
;
1799 hr
= m_pSFParent
->SetNameOf(0, pidl
, lpdi
->item
.pszText
, SHGDN_INFOLDER
, &pidlNew
);
1801 if (SUCCEEDED(hr
) && pidlNew
)
1803 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
1804 lvItem
.iItem
= lpdi
->item
.iItem
;
1805 lvItem
.iSubItem
= 0;
1806 lvItem
.lParam
= reinterpret_cast<LPARAM
>(pidlNew
);
1807 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
1808 m_ListView
.SetItem(&lvItem
);
1809 m_ListView
.Update(lpdi
->item
.iItem
);
1818 TRACE("-- %p WM_COMMAND %x unhandled\n", this, lpnmh
->code
);
1826 * This is just a quick hack to make the desktop work correctly.
1827 * ITranslateShellChangeNotify's IsChildID is undocumented, but most likely the way that
1828 * a folder should know if it should update upon a change notification.
1829 * It is exported by merged folders at a minimum.
1831 static BOOL
ILIsParentOrSpecialParent(PCIDLIST_ABSOLUTE pidl1
, PCIDLIST_ABSOLUTE pidl2
)
1833 if (!pidl1
|| !pidl2
)
1835 if (ILIsParent(pidl1
, pidl2
, TRUE
))
1838 if (_ILIsDesktop(pidl1
))
1840 PIDLIST_ABSOLUTE deskpidl
;
1841 SHGetFolderLocation(NULL
, CSIDL_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
1842 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
1848 SHGetFolderLocation(NULL
, CSIDL_COMMON_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
1849 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
1859 /**********************************************************
1860 * ShellView_OnChange()
1862 LRESULT
CDefView::OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1864 PCIDLIST_ABSOLUTE
*Pidls
= reinterpret_cast<PCIDLIST_ABSOLUTE
*>(wParam
);
1865 BOOL bParent0
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[0]);
1866 BOOL bParent1
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[1]);
1868 TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls
[0], Pidls
[1], lParam
);
1870 switch (lParam
&~ SHCNE_INTERRUPT
)
1876 if (LV_FindItemByPidl(ILFindLastID(Pidls
[0])) == -1)
1878 LV_AddItem(ILFindLastID(Pidls
[0]));
1882 LV_ProdItem(ILFindLastID(Pidls
[0]));
1890 LV_DeleteItem(ILFindLastID(Pidls
[0]));
1893 case SHCNE_RENAMEFOLDER
:
1894 case SHCNE_RENAMEITEM
:
1895 if (bParent0
&& bParent1
)
1896 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[1]));
1898 LV_DeleteItem(ILFindLastID(Pidls
[0]));
1900 LV_AddItem(ILFindLastID(Pidls
[1]));
1903 case SHCNE_UPDATEITEM
:
1905 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[0]));
1908 case SHCNE_UPDATEDIR
:
1915 /**********************************************************
1916 * CDefView::OnCustomItem
1918 LRESULT
CDefView::OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1923 ERR("no menu!!!\n");
1928 HRESULT hres
= SHForwardContextMenuMsg(m_pCM
, uMsg
, wParam
, lParam
, &result
, TRUE
);
1929 if (SUCCEEDED(hres
))
1935 LRESULT
CDefView::OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1937 /* Wallpaper setting affects drop shadows effect */
1938 if (wParam
== SPI_SETDESKWALLPAPER
|| wParam
== 0)
1944 /**********************************************************
1945 * CDefView::OnInitMenuPopup
1947 LRESULT
CDefView::OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1949 HMENU hmenu
= (HMENU
) wParam
;
1950 int nPos
= LOWORD(lParam
);
1953 OnCustomItem(uMsg
, wParam
, lParam
, bHandled
);
1955 HMENU hViewMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_VIEW
);
1957 /* Lets try to find out what the hell wParam is */
1958 if (hmenu
== GetSubMenu(m_hMenu
, nPos
))
1959 menuItemId
= ReallyGetMenuItemID(m_hMenu
, nPos
);
1960 else if (hViewMenu
&& hmenu
== GetSubMenu(hViewMenu
, nPos
))
1961 menuItemId
= ReallyGetMenuItemID(hViewMenu
, nPos
);
1962 else if (m_hContextMenu
&& hmenu
== GetSubMenu(m_hContextMenu
, nPos
))
1963 menuItemId
= ReallyGetMenuItemID(m_hContextMenu
, nPos
);
1969 case FCIDM_MENU_FILE
:
1972 case FCIDM_MENU_VIEW
:
1973 case FCIDM_SHVIEW_VIEW
:
1974 CheckViewMode(hmenu
);
1976 case FCIDM_SHVIEW_ARRANGE
:
1977 FillArrangeAsMenu(hmenu
);
1984 /**********************************************************
1987 * The INTERFACE of the IShellView object
1990 **********************************************************
1993 /**********************************************************
1994 * ShellView_GetWindow
1996 HRESULT WINAPI
CDefView::GetWindow(HWND
*phWnd
)
1998 TRACE("(%p)\n", this);
2005 HRESULT WINAPI
CDefView::ContextSensitiveHelp(BOOL fEnterMode
)
2007 FIXME("(%p) stub\n", this);
2012 /**********************************************************
2013 * IShellView_TranslateAccelerator
2016 * use the accel functions
2018 HRESULT WINAPI
CDefView::TranslateAccelerator(LPMSG lpmsg
)
2023 if (lpmsg
->message
>= WM_KEYFIRST
&& lpmsg
->message
<= WM_KEYLAST
)
2025 if (::TranslateAcceleratorW(m_hWnd
, m_hAccel
, lpmsg
) != 0)
2028 TRACE("-- key=0x04%lx\n", lpmsg
->wParam
) ;
2031 return m_pShellBrowser
->TranslateAcceleratorSB(lpmsg
, 0);
2034 HRESULT WINAPI
CDefView::EnableModeless(BOOL fEnable
)
2036 FIXME("(%p) stub\n", this);
2041 HRESULT WINAPI
CDefView::UIActivate(UINT uState
)
2043 // CHAR szName[MAX_PATH];
2045 int nPartArray
[1] = { -1};
2047 TRACE("(%p)->(state=%x) stub\n", this, uState
);
2049 /* don't do anything if the state isn't really changing */
2050 if (m_uState
== uState
)
2055 /* OnActivate handles the menu merging and internal state */
2058 /* only do This if we are active */
2059 if (uState
!= SVUIA_DEACTIVATE
)
2063 GetFolderPath is not a method of IShellFolder
2064 IShellFolder_GetFolderPath( m_pSFParent, szName, sizeof(szName) );
2066 /* set the number of parts */
2067 m_pShellBrowser
->SendControlMsg(FCW_STATUS
, SB_SETPARTS
, 1, (LPARAM
)nPartArray
, &lResult
);
2069 /* set the text for the parts */
2071 m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXTA, 0, (LPARAM)szName, &lResult);
2078 HRESULT WINAPI
CDefView::Refresh()
2080 TRACE("(%p)\n", this);
2082 m_ListView
.DeleteAllItems();
2088 HRESULT WINAPI
CDefView::CreateViewWindow(IShellView
*lpPrevView
, LPCFOLDERSETTINGS lpfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
)
2090 return CreateViewWindow3(psb
, lpPrevView
, SV3CVW3_DEFAULT
,
2091 (FOLDERFLAGS
)lpfs
->fFlags
, (FOLDERFLAGS
)lpfs
->fFlags
, (FOLDERVIEWMODE
)lpfs
->ViewMode
, NULL
, prcView
, phWnd
);
2094 HRESULT WINAPI
CDefView::DestroyViewWindow()
2096 TRACE("(%p)\n", this);
2098 /* Make absolutely sure all our UI is cleaned up */
2099 UIActivate(SVUIA_DEACTIVATE
);
2103 // "Accelerator tables loaded from resources are freed automatically when the application terminates." -- MSDN
2107 if (m_hMenuViewModes
)
2109 DestroyMenu(m_hMenuViewModes
);
2110 m_hMenuViewModes
= NULL
;
2115 DestroyMenu(m_hMenu
);
2121 m_ListView
.DestroyWindow();
2129 m_pShellBrowser
.Release();
2130 m_pCommDlgBrowser
.Release();
2135 HRESULT WINAPI
CDefView::GetCurrentInfo(LPFOLDERSETTINGS lpfs
)
2137 TRACE("(%p)->(%p) vmode=%x flags=%x\n", this, lpfs
,
2138 m_FolderSettings
.ViewMode
, m_FolderSettings
.fFlags
);
2141 return E_INVALIDARG
;
2143 *lpfs
= m_FolderSettings
;
2147 HRESULT WINAPI
CDefView::AddPropertySheetPages(DWORD dwReserved
, LPFNADDPROPSHEETPAGE lpfn
, LPARAM lparam
)
2149 FIXME("(%p) stub\n", this);
2154 HRESULT WINAPI
CDefView::SaveViewState()
2156 FIXME("(%p) stub\n", this);
2161 HRESULT WINAPI
CDefView::SelectItem(PCUITEMID_CHILD pidl
, UINT uFlags
)
2165 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n", this, pidl
, uFlags
);
2167 i
= LV_FindItemByPidl(pidl
);
2171 if(uFlags
& SVSI_ENSUREVISIBLE
)
2172 m_ListView
.EnsureVisible(i
, FALSE
);
2174 LVITEMW lvItem
= {0};
2175 lvItem
.mask
= LVIF_STATE
;
2176 lvItem
.stateMask
= LVIS_SELECTED
| LVIS_FOCUSED
;
2178 while (m_ListView
.GetItem(&lvItem
))
2180 if (lvItem
.iItem
== i
)
2182 if (uFlags
& SVSI_SELECT
)
2183 lvItem
.state
|= LVIS_SELECTED
;
2185 lvItem
.state
&= ~LVIS_SELECTED
;
2187 if (uFlags
& SVSI_FOCUSED
)
2188 lvItem
.state
&= ~LVIS_FOCUSED
;
2192 if (uFlags
& SVSI_DESELECTOTHERS
)
2193 lvItem
.state
&= ~LVIS_SELECTED
;
2196 m_ListView
.SetItem(&lvItem
);
2200 if((uFlags
& SVSI_EDIT
) == SVSI_EDIT
)
2201 m_ListView
.EditLabel(i
);
2206 HRESULT WINAPI
CDefView::GetItemObject(UINT uItem
, REFIID riid
, LPVOID
*ppvOut
)
2208 HRESULT hr
= E_NOINTERFACE
;
2210 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n", this, uItem
, debugstr_guid(&riid
), ppvOut
);
2216 case SVGIO_BACKGROUND
:
2217 if (IsEqualIID(riid
, IID_IContextMenu
))
2222 hr
= CDefViewBckgrndMenu_CreateInstance(m_pSF2Parent
, riid
, ppvOut
);
2223 if (FAILED_UNEXPECTEDLY(hr
))
2227 else if (IsEqualIID(riid
, IID_IDispatch
))
2229 if (m_pShellFolderViewDual
== NULL
)
2231 hr
= CDefViewDual_Constructor(riid
, (LPVOID
*)&m_pShellFolderViewDual
);
2232 if (FAILED_UNEXPECTEDLY(hr
))
2235 hr
= m_pShellFolderViewDual
->QueryInterface(riid
, ppvOut
);
2239 case SVGIO_SELECTION
:
2241 hr
= m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, riid
, 0, ppvOut
);
2242 if (FAILED_UNEXPECTEDLY(hr
))
2247 TRACE("-- (%p)->(interface=%p)\n", this, *ppvOut
);
2252 HRESULT STDMETHODCALLTYPE
CDefView::GetCurrentViewMode(UINT
*pViewMode
)
2254 TRACE("(%p)->(%p), stub\n", this, pViewMode
);
2257 return E_INVALIDARG
;
2259 *pViewMode
= m_FolderSettings
.ViewMode
;
2263 HRESULT STDMETHODCALLTYPE
CDefView::SetCurrentViewMode(UINT ViewMode
)
2266 TRACE("(%p)->(%u), stub\n", this, ViewMode
);
2268 /* It's not redundant to check FVM_AUTO because it's a (UINT)-1 */
2269 if (((INT
)ViewMode
< FVM_FIRST
|| (INT
)ViewMode
> FVM_LAST
) && ((INT
)ViewMode
!= FVM_AUTO
))
2270 return E_INVALIDARG
;
2272 /* Windows before Vista uses LVM_SETVIEW and possibly
2273 LVM_SETEXTENDEDLISTVIEWSTYLE to set the style of the listview,
2274 while later versions seem to accomplish this through other
2282 dwStyle
= LVS_REPORT
;
2285 dwStyle
= LVS_SMALLICON
;
2292 FIXME("ViewMode %d not implemented\n", ViewMode
);
2298 SetStyle(dwStyle
, LVS_TYPEMASK
);
2300 /* This will not necessarily be the actual mode set above.
2301 This mimics the behavior of Windows XP. */
2302 m_FolderSettings
.ViewMode
= ViewMode
;
2307 HRESULT STDMETHODCALLTYPE
CDefView::GetFolder(REFIID riid
, void **ppv
)
2309 if (m_pSFParent
== NULL
)
2312 return m_pSFParent
->QueryInterface(riid
, ppv
);
2315 HRESULT STDMETHODCALLTYPE
CDefView::Item(int iItemIndex
, PITEMID_CHILD
*ppidl
)
2317 PCUITEMID_CHILD pidl
= _PidlByItem(iItemIndex
);
2320 *ppidl
= ILClone(pidl
);
2325 return E_INVALIDARG
;
2328 HRESULT STDMETHODCALLTYPE
CDefView::ItemCount(UINT uFlags
, int *pcItems
)
2330 TRACE("(%p)->(%u %p)\n", this, uFlags
, pcItems
);
2332 if (uFlags
!= SVGIO_ALLVIEW
)
2333 FIXME("some flags unsupported, %x\n", uFlags
& ~SVGIO_ALLVIEW
);
2335 *pcItems
= m_ListView
.GetItemCount();
2340 HRESULT STDMETHODCALLTYPE
CDefView::Items(UINT uFlags
, REFIID riid
, void **ppv
)
2345 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectionMarkedItem(int *piItem
)
2347 TRACE("(%p)->(%p)\n", this, piItem
);
2349 *piItem
= m_ListView
.GetSelectionMark();
2354 HRESULT STDMETHODCALLTYPE
CDefView::GetFocusedItem(int *piItem
)
2356 TRACE("(%p)->(%p)\n", this, piItem
);
2358 *piItem
= m_ListView
.GetNextItem(-1, LVNI_FOCUSED
);
2363 HRESULT STDMETHODCALLTYPE
CDefView::GetItemPosition(PCUITEMID_CHILD pidl
, POINT
*ppt
)
2368 HRESULT STDMETHODCALLTYPE
CDefView::GetSpacing(POINT
*ppt
)
2370 TRACE("(%p)->(%p)\n", this, ppt
);
2378 m_ListView
.GetItemSpacing(spacing
);
2380 ppt
->x
= spacing
.cx
;
2381 ppt
->y
= spacing
.cy
;
2387 HRESULT STDMETHODCALLTYPE
CDefView::GetDefaultSpacing(POINT
*ppt
)
2392 HRESULT STDMETHODCALLTYPE
CDefView::GetAutoArrange()
2397 HRESULT STDMETHODCALLTYPE
CDefView::SelectItem(int iItem
, DWORD dwFlags
)
2401 TRACE("(%p)->(%d, %x)\n", this, iItem
, dwFlags
);
2404 lvItem
.stateMask
= LVIS_SELECTED
;
2406 if (dwFlags
& SVSI_ENSUREVISIBLE
)
2407 m_ListView
.EnsureVisible(iItem
, 0);
2410 if (dwFlags
& SVSI_DESELECTOTHERS
)
2411 m_ListView
.SetItemState(-1, 0, LVIS_SELECTED
);
2414 if (dwFlags
& SVSI_SELECT
)
2415 lvItem
.state
|= LVIS_SELECTED
;
2417 if (dwFlags
& SVSI_FOCUSED
)
2418 lvItem
.stateMask
|= LVIS_FOCUSED
;
2420 m_ListView
.SetItemState(iItem
, lvItem
.state
, lvItem
.stateMask
);
2422 if ((dwFlags
& SVSI_EDIT
) == SVSI_EDIT
)
2423 m_ListView
.EditLabel(iItem
);
2428 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItems(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD dwFlags
)
2433 /**********************************************************
2434 * IShellView2 implementation
2437 HRESULT STDMETHODCALLTYPE
CDefView::GetView(SHELLVIEWID
*view_guid
, ULONG view_type
)
2439 FIXME("(%p)->(%p, %lu) stub\n", this, view_guid
, view_type
);
2443 HRESULT STDMETHODCALLTYPE
CDefView::CreateViewWindow2(LPSV2CVW2_PARAMS view_params
)
2445 return CreateViewWindow3(view_params
->psbOwner
, view_params
->psvPrev
,
2446 SV3CVW3_DEFAULT
, (FOLDERFLAGS
)view_params
->pfs
->fFlags
, (FOLDERFLAGS
)view_params
->pfs
->fFlags
,
2447 (FOLDERVIEWMODE
)view_params
->pfs
->ViewMode
, view_params
->pvid
, view_params
->prcView
, &view_params
->hwndView
);
2450 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
)
2452 OLEMENUGROUPWIDTHS omw
= { { 0, 0, 0, 0, 0, 0 } };
2456 TRACE("(%p)->(shlview=%p shlbrs=%p rec=%p hwnd=%p vmode=%x flags=%x)\n", this, psvPrevious
, psb
, prcView
, hwnd
, mode
, flags
);
2457 if (prcView
!= NULL
)
2458 TRACE("-- left=%i top=%i right=%i bottom=%i\n", prcView
->left
, prcView
->top
, prcView
->right
, prcView
->bottom
);
2460 /* Validate the Shell Browser */
2461 if (psb
== NULL
|| m_hWnd
)
2462 return E_UNEXPECTED
;
2464 if (view_flags
!= SV3CVW3_DEFAULT
)
2465 FIXME("unsupported view flags 0x%08x\n", view_flags
);
2467 /* Set up the member variables */
2468 m_pShellBrowser
= psb
;
2469 m_FolderSettings
.ViewMode
= mode
;
2470 m_FolderSettings
.fFlags
= mask
& flags
;
2474 if (IsEqualIID(*view_id
, VID_LargeIcons
))
2475 m_FolderSettings
.ViewMode
= FVM_ICON
;
2476 else if (IsEqualIID(*view_id
, VID_SmallIcons
))
2477 m_FolderSettings
.ViewMode
= FVM_SMALLICON
;
2478 else if (IsEqualIID(*view_id
, VID_List
))
2479 m_FolderSettings
.ViewMode
= FVM_LIST
;
2480 else if (IsEqualIID(*view_id
, VID_Details
))
2481 m_FolderSettings
.ViewMode
= FVM_DETAILS
;
2482 else if (IsEqualIID(*view_id
, VID_Thumbnails
))
2483 m_FolderSettings
.ViewMode
= FVM_THUMBNAIL
;
2484 else if (IsEqualIID(*view_id
, VID_Tile
))
2485 m_FolderSettings
.ViewMode
= FVM_TILE
;
2486 else if (IsEqualIID(*view_id
, VID_ThumbStrip
))
2487 m_FolderSettings
.ViewMode
= FVM_THUMBSTRIP
;
2489 FIXME("Ignoring unrecognized VID %s\n", debugstr_guid(view_id
));
2492 /* Get our parent window */
2493 m_pShellBrowser
->GetWindow(&m_hWndParent
);
2495 /* Try to get the ICommDlgBrowserInterface, adds a reference !!! */
2496 m_pCommDlgBrowser
= NULL
;
2497 if (SUCCEEDED(m_pShellBrowser
->QueryInterface(IID_PPV_ARG(ICommDlgBrowser
, &m_pCommDlgBrowser
))))
2499 TRACE("-- CommDlgBrowser\n");
2502 Create(m_hWndParent
, prcView
, NULL
, WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
| WS_TABSTOP
, 0, 0U);
2513 SetWindowPos(HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_SHOWWINDOW
);
2518 m_hMenu
= CreateMenu();
2519 m_pShellBrowser
->InsertMenusSB(m_hMenu
, &omw
);
2520 TRACE("-- after fnInsertMenusSB\n");
2528 HRESULT STDMETHODCALLTYPE
CDefView::HandleRename(LPCITEMIDLIST new_pidl
)
2530 FIXME("(%p)->(%p) stub\n", this, new_pidl
);
2534 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItem(LPCITEMIDLIST item
, UINT flags
, POINT
*point
)
2536 FIXME("(%p)->(%p, %u, %p) stub\n", this, item
, flags
, point
);
2540 /**********************************************************
2541 * IShellFolderView implementation
2543 HRESULT STDMETHODCALLTYPE
CDefView::Rearrange(LPARAM sort
)
2545 FIXME("(%p)->(%ld) stub\n", this, sort
);
2549 HRESULT STDMETHODCALLTYPE
CDefView::GetArrangeParam(LPARAM
*sort
)
2551 FIXME("(%p)->(%p) stub\n", this, sort
);
2555 HRESULT STDMETHODCALLTYPE
CDefView::ArrangeGrid()
2557 FIXME("(%p) stub\n", this);
2561 HRESULT STDMETHODCALLTYPE
CDefView::AutoArrange()
2563 FIXME("(%p) stub\n", this);
2567 HRESULT STDMETHODCALLTYPE
CDefView::AddObject(PITEMID_CHILD pidl
, UINT
*item
)
2569 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2573 HRESULT STDMETHODCALLTYPE
CDefView::GetObject(PITEMID_CHILD
*pidl
, UINT item
)
2575 TRACE("(%p)->(%p %d)\n", this, pidl
, item
);
2576 return Item(item
, pidl
);
2579 HRESULT STDMETHODCALLTYPE
CDefView::RemoveObject(PITEMID_CHILD pidl
, UINT
*item
)
2582 TRACE("(%p)->(%p %p)\n", this, pidl
, item
);
2586 *item
= LV_FindItemByPidl(ILFindLastID(pidl
));
2587 m_ListView
.DeleteItem(*item
);
2592 m_ListView
.DeleteAllItems();
2598 HRESULT STDMETHODCALLTYPE
CDefView::GetObjectCount(UINT
*count
)
2600 TRACE("(%p)->(%p)\n", this, count
);
2601 *count
= m_ListView
.GetItemCount();
2605 HRESULT STDMETHODCALLTYPE
CDefView::SetObjectCount(UINT count
, UINT flags
)
2607 FIXME("(%p)->(%d %x) stub\n", this, count
, flags
);
2611 HRESULT STDMETHODCALLTYPE
CDefView::UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
)
2613 FIXME("(%p)->(%p %p %p) stub\n", this, pidl_old
, pidl_new
, item
);
2617 HRESULT STDMETHODCALLTYPE
CDefView::RefreshObject(PITEMID_CHILD pidl
, UINT
*item
)
2619 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2623 HRESULT STDMETHODCALLTYPE
CDefView::SetRedraw(BOOL redraw
)
2625 TRACE("(%p)->(%d)\n", this, redraw
);
2626 m_ListView
.SetRedraw(redraw
);
2630 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedCount(UINT
*count
)
2632 FIXME("(%p)->(%p) stub\n", this, count
);
2636 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
)
2638 TRACE("(%p)->(%p %p)\n", this, pidl
, items
);
2640 *items
= GetSelections();
2644 *pidl
= static_cast<PCUITEMID_CHILD
*>(LocalAlloc(0, *items
* sizeof(PCUITEMID_CHILD
)));
2647 return E_OUTOFMEMORY
;
2650 /* it's documented that caller shouldn't PIDLs, only array itself */
2651 memcpy(*pidl
, m_apidl
, *items
* sizeof(PCUITEMID_CHILD
));
2657 HRESULT STDMETHODCALLTYPE
CDefView::IsDropOnSource(IDropTarget
*drop_target
)
2659 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2663 HRESULT STDMETHODCALLTYPE
CDefView::GetDragPoint(POINT
*pt
)
2665 FIXME("(%p)->(%p) stub\n", this, pt
);
2669 HRESULT STDMETHODCALLTYPE
CDefView::GetDropPoint(POINT
*pt
)
2671 FIXME("(%p)->(%p) stub\n", this, pt
);
2675 HRESULT STDMETHODCALLTYPE
CDefView::MoveIcons(IDataObject
*obj
)
2677 TRACE("(%p)->(%p)\n", this, obj
);
2681 HRESULT STDMETHODCALLTYPE
CDefView::SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
)
2683 FIXME("(%p)->(%p %p) stub\n", this, pidl
, pt
);
2687 HRESULT STDMETHODCALLTYPE
CDefView::IsBkDropTarget(IDropTarget
*drop_target
)
2689 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2693 HRESULT STDMETHODCALLTYPE
CDefView::SetClipboard(BOOL move
)
2695 FIXME("(%p)->(%d) stub\n", this, move
);
2699 HRESULT STDMETHODCALLTYPE
CDefView::SetPoints(IDataObject
*obj
)
2701 FIXME("(%p)->(%p) stub\n", this, obj
);
2705 HRESULT STDMETHODCALLTYPE
CDefView::GetItemSpacing(ITEMSPACING
*spacing
)
2707 FIXME("(%p)->(%p) stub\n", this, spacing
);
2711 HRESULT STDMETHODCALLTYPE
CDefView::SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
)
2713 FIXME("(%p)->(%p %p) stub\n", this, new_cb
, old_cb
);
2717 HRESULT STDMETHODCALLTYPE
CDefView::Select(UINT flags
)
2719 FIXME("(%p)->(%d) stub\n", this, flags
);
2723 HRESULT STDMETHODCALLTYPE
CDefView::QuerySupport(UINT
*support
)
2725 TRACE("(%p)->(%p)\n", this, support
);
2729 HRESULT STDMETHODCALLTYPE
CDefView::SetAutomationObject(IDispatch
*disp
)
2731 FIXME("(%p)->(%p) stub\n", this, disp
);
2735 /**********************************************************
2736 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2738 HRESULT WINAPI
CDefView::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD
*prgCmds
, OLECMDTEXT
*pCmdText
)
2740 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
2741 this, pguidCmdGroup
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
2744 return E_INVALIDARG
;
2746 for (UINT i
= 0; i
< cCmds
; i
++)
2748 FIXME("\tprgCmds[%d].cmdID = %d\n", i
, prgCmds
[i
].cmdID
);
2749 prgCmds
[i
].cmdf
= 0;
2752 return OLECMDERR_E_UNKNOWNGROUP
;
2755 /**********************************************************
2756 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2758 * nCmdID is the OLECMDID_* enumeration
2760 HRESULT WINAPI
CDefView::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
2762 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2763 this, debugstr_guid(pguidCmdGroup
), nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2766 return OLECMDERR_E_UNKNOWNGROUP
;
2768 if (IsEqualCLSID(*pguidCmdGroup
, m_Category
))
2770 if (nCmdID
== FCIDM_SHVIEW_AUTOARRANGE
)
2772 if (V_VT(pvaIn
) != VT_INT_PTR
)
2773 return OLECMDERR_E_NOTSUPPORTED
;
2776 params
.cbSize
= sizeof(params
);
2777 params
.rcExclude
= *(RECT
*) V_INTREF(pvaIn
);
2779 if (m_hMenuViewModes
)
2781 /* Duplicate all but the last two items of the view modes menu */
2782 HMENU hmenuViewPopup
= CreatePopupMenu();
2783 Shell_MergeMenus(hmenuViewPopup
, m_hMenuViewModes
, 0, 0, 0xFFFF, 0);
2784 DeleteMenu(hmenuViewPopup
, GetMenuItemCount(hmenuViewPopup
) - 1, MF_BYPOSITION
);
2785 DeleteMenu(hmenuViewPopup
, GetMenuItemCount(hmenuViewPopup
) - 1, MF_BYPOSITION
);
2786 CheckViewMode(hmenuViewPopup
);
2787 TrackPopupMenuEx(hmenuViewPopup
, TPM_LEFTALIGN
| TPM_TOPALIGN
, params
.rcExclude
.left
, params
.rcExclude
.bottom
, m_hWndParent
, ¶ms
);
2788 ::DestroyMenu(hmenuViewPopup
);
2791 // pvaOut is VT_I4 with value 0x403 (cmd id of the new mode maybe?)
2792 V_VT(pvaOut
) = VT_I4
;
2793 V_I4(pvaOut
) = 0x403;
2797 if (IsEqualIID(*pguidCmdGroup
, CGID_Explorer
) &&
2799 (nCmdexecopt
== 4) && pvaOut
)
2802 if (IsEqualIID(*pguidCmdGroup
, CGID_ShellDocView
) &&
2807 return OLECMDERR_E_UNKNOWNGROUP
;
2810 /**********************************************************
2811 * ISVDropTarget implementation
2814 /******************************************************************************
2815 * drag_notify_subitem [Internal]
2817 * Figure out the shellfolder object, which is currently under the mouse cursor
2818 * and notify it via the IDropTarget interface.
2821 #define SCROLLAREAWIDTH 20
2823 HRESULT
CDefView::drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2829 /* Map from global to client coordinates and query the index of the listview-item, which is
2830 * currently under the mouse cursor. */
2831 LVHITTESTINFO htinfo
{ {pt
.x
, pt
.y
}, LVHT_ONITEM
};
2832 ScreenToClient(&htinfo
.pt
);
2833 lResult
= m_ListView
.HitTest(&htinfo
);
2835 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2836 ::GetClientRect(m_ListView
, &clientRect
);
2837 if (htinfo
.pt
.x
== m_ptLastMousePos
.x
&& htinfo
.pt
.y
== m_ptLastMousePos
.y
&&
2838 (htinfo
.pt
.x
< SCROLLAREAWIDTH
|| htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
||
2839 htinfo
.pt
.y
< SCROLLAREAWIDTH
|| htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
))
2841 m_cScrollDelay
= (m_cScrollDelay
+ 1) % 5; /* DragOver is called every 50 ms */
2842 if (m_cScrollDelay
== 0)
2844 /* Mouse did hover another 250 ms over the scroll-area */
2845 if (htinfo
.pt
.x
< SCROLLAREAWIDTH
)
2846 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEUP
, 0);
2848 if (htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
)
2849 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEDOWN
, 0);
2851 if (htinfo
.pt
.y
< SCROLLAREAWIDTH
)
2852 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEUP
, 0);
2854 if (htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
)
2855 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEDOWN
, 0);
2860 m_cScrollDelay
= 0; /* Reset, if the cursor is not over the listview's scroll-area */
2863 m_ptLastMousePos
= htinfo
.pt
;
2865 /* We need to check if we drag the selection over itself */
2866 if (lResult
!= -1 && m_pSourceDataObject
.p
!= NULL
)
2868 PCUITEMID_CHILD pidl
= _PidlByItem(lResult
);
2870 for (UINT i
= 0; i
< m_cidl
; i
++)
2872 if (pidl
== m_apidl
[i
])
2874 /* The item that is being draged is hovering itself. */
2881 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2882 if (m_pCurDropTarget
&& lResult
== m_iDragOverItem
)
2883 return m_pCurDropTarget
->DragOver(grfKeyState
, pt
, pdwEffect
);
2885 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2886 if (m_pCurDropTarget
)
2888 PCUITEMID_CHILD pidl
= _PidlByItem(m_iDragOverItem
);
2890 SelectItem(pidl
, 0);
2892 m_pCurDropTarget
->DragLeave();
2893 m_pCurDropTarget
.Release();
2896 m_iDragOverItem
= lResult
;
2900 /* We are not above one of the listview's subitems. Bind to the parent folder's
2901 * DropTarget interface. */
2902 hr
= m_pSFParent
->CreateViewObject(NULL
, IID_PPV_ARG(IDropTarget
,&m_pCurDropTarget
));
2906 /* Query the relative PIDL of the shellfolder object represented by the currently
2907 * dragged over listview-item ... */
2908 PCUITEMID_CHILD pidl
= _PidlByItem(lResult
);
2910 /* ... and bind m_pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2911 hr
= m_pSFParent
->GetUIObjectOf(m_ListView
, 1, &pidl
, IID_NULL_PPV_ARG(IDropTarget
, &m_pCurDropTarget
));
2914 /* If anything failed, m_pCurDropTarget should be NULL now, which ought to be a save state. */
2918 /* Notify the item just entered via DragEnter. */
2919 hr
= m_pCurDropTarget
->DragEnter(m_pCurDataObject
, grfKeyState
, pt
, pdwEffect
);
2921 if (m_iDragOverItem
!= -1 && pdwEffect
!= DROPEFFECT_NONE
)
2923 SelectItem(m_iDragOverItem
, SVSI_SELECT
);
2929 HRESULT WINAPI
CDefView::DragEnter(IDataObject
*pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2931 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2932 m_pCurDataObject
= pDataObject
;
2934 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2937 HRESULT WINAPI
CDefView::DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2939 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2942 HRESULT WINAPI
CDefView::DragLeave()
2944 if (m_pCurDropTarget
)
2946 m_pCurDropTarget
->DragLeave();
2947 m_pCurDropTarget
.Release();
2950 if (m_pCurDataObject
!= NULL
)
2952 m_pCurDataObject
.Release();
2955 m_iDragOverItem
= 0;
2960 HRESULT WINAPI
CDefView::Drop(IDataObject
* pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2962 ERR("GetKeyState(VK_LBUTTON): %d\n", GetKeyState(VK_LBUTTON
));
2964 if ((m_iDragOverItem
== -1 || m_pCurDropTarget
== NULL
) &&
2965 (*pdwEffect
& DROPEFFECT_MOVE
) &&
2966 /*(GetKeyState(VK_LBUTTON) != 0) &&*/
2967 (m_pSourceDataObject
.p
) &&
2968 (SHIsSameObject(pDataObject
, m_pSourceDataObject
)))
2970 if (m_pCurDropTarget
)
2972 m_pCurDropTarget
->DragLeave();
2973 m_pCurDropTarget
.Release();
2976 /* Restore the selection */
2977 m_ListView
.SetItemState(-1, 0, LVIS_SELECTED
);
2978 for (UINT i
= 0 ; i
< m_cidl
; i
++)
2979 SelectItem(m_apidl
[i
], SVSI_SELECT
);
2981 /* Reposition the items */
2983 while ((lvIndex
= m_ListView
.GetNextItem(lvIndex
, LVNI_SELECTED
)) > -1)
2986 if (m_ListView
.GetItemPosition(lvIndex
, &ptItem
))
2988 ptItem
.x
+= pt
.x
- m_ptFirstMousePos
.x
;
2989 ptItem
.y
+= pt
.y
- m_ptFirstMousePos
.y
;
2990 m_ListView
.SetItemPosition(lvIndex
, &ptItem
);
2994 else if (m_pCurDropTarget
)
2996 m_pCurDropTarget
->Drop(pDataObject
, grfKeyState
, pt
, pdwEffect
);
2997 m_pCurDropTarget
.Release();
3000 m_pCurDataObject
.Release();
3001 m_iDragOverItem
= 0;
3005 /**********************************************************
3006 * ISVDropSource implementation
3009 HRESULT WINAPI
CDefView::QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
)
3011 TRACE("(%p)\n", this);
3014 return DRAGDROP_S_CANCEL
;
3015 else if (!(grfKeyState
& MK_LBUTTON
) && !(grfKeyState
& MK_RBUTTON
))
3016 return DRAGDROP_S_DROP
;
3021 HRESULT WINAPI
CDefView::GiveFeedback(DWORD dwEffect
)
3023 TRACE("(%p)\n", this);
3025 return DRAGDROP_S_USEDEFAULTCURSORS
;
3028 /**********************************************************
3029 * ISVViewObject implementation
3032 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
)
3034 FIXME("Stub: this=%p\n", this);
3039 HRESULT WINAPI
CDefView::GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
, HDC hicTargetDevice
, LOGPALETTE
**ppColorSet
)
3041 FIXME("Stub: this=%p\n", this);
3046 HRESULT WINAPI
CDefView::Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
)
3048 FIXME("Stub: this=%p\n", this);
3053 HRESULT WINAPI
CDefView::Unfreeze(DWORD dwFreeze
)
3055 FIXME("Stub: this=%p\n", this);
3060 HRESULT WINAPI
CDefView::SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
)
3062 FIXME("partial stub: %p %08x %08x %p\n", this, aspects
, advf
, pAdvSink
);
3064 /* FIXME: we set the AdviseSink, but never use it to send any advice */
3065 m_pAdvSink
= pAdvSink
;
3066 m_dwAspects
= aspects
;
3072 HRESULT WINAPI
CDefView::GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
)
3074 TRACE("this=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n", this, pAspects
, pAdvf
, ppAdvSink
);
3078 *ppAdvSink
= m_pAdvSink
;
3079 m_pAdvSink
.p
->AddRef();
3083 *pAspects
= m_dwAspects
;
3091 HRESULT STDMETHODCALLTYPE
CDefView::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
3093 if (IsEqualIID(guidService
, SID_IShellBrowser
))
3094 return m_pShellBrowser
->QueryInterface(riid
, ppvObject
);
3095 else if(IsEqualIID(guidService
, SID_IFolderView
))
3096 return QueryInterface(riid
, ppvObject
);
3098 return E_NOINTERFACE
;
3101 HRESULT
CDefView::_MergeToolbar()
3103 CComPtr
<IExplorerToolbar
> ptb
;
3106 hr
= IUnknown_QueryService(m_pShellBrowser
, IID_IExplorerToolbar
, IID_PPV_ARG(IExplorerToolbar
, &ptb
));
3110 m_Category
= CGID_DefViewFrame
;
3112 hr
= ptb
->SetCommandTarget(static_cast<IOleCommandTarget
*>(this), &m_Category
, 0);
3120 hr
= ptb
->AddButtons(&m_Category
, buttonsCount
, buttons
);
3127 /**********************************************************
3128 * IShellView_Constructor
3130 HRESULT WINAPI
IShellView_Constructor(IShellFolder
*pFolder
, IShellView
**newView
)
3132 return ShellObjectCreatorInit
<CDefView
>(pFolder
, IID_IShellView
, newView
);
3135 HRESULT WINAPI
CDefView_Constructor(IShellFolder
*pFolder
, REFIID riid
, LPVOID
* ppvOut
)
3137 return ShellObjectCreatorInit
<CDefView
>(pFolder
, riid
, ppvOut
);