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: The order by part of the background context menu should be
24 * built according to the columns shown.
26 * FIXME: CheckToolbar: handle the "new folder" and "folder up" button
31 - Load/Save the view state from/into the stream provided by the ShellBrowser.
32 - Code to merge menus in the shellbrowser is incorrect.
33 - Move the background context menu creation into shell view. It should store the
34 shell view HWND to send commands.
35 - Shell view should do SetCommandTarget on internet toolbar.
36 - When editing starts on item, set edit text to for editing value.
37 - When shell view is called back for item info, let listview save the value.
38 - Fix shell view to handle view mode popup exec.
39 - The background context menu should have a pidl just like foreground menus. This
40 causes crashes when dynamic handlers try to use the NULL pidl.
41 - The SHELLDLL_DefView should not be filled with blue unconditionally. This causes
42 annoying flashing of blue even on XP, and is not correct.
43 - Reorder of columns doesn't work - might be bug in comctl32
51 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
55 static const WCHAR SV_CLASS_NAME
[] = {'S', 'H', 'E', 'L', 'L', 'D', 'L', 'L', '_', 'D', 'e', 'f', 'V', 'i', 'e', 'w', 0};
62 } LISTVIEW_SORT_INFO
, *LPLISTVIEW_SORT_INFO
;
64 #define SHV_CHANGE_NOTIFY WM_USER + 0x1111
67 public CWindowImpl
<CDefView
, CWindow
, CControlWinTraits
>,
68 public CComObjectRootEx
<CComMultiThreadModelNoCS
>,
71 public IShellFolderView
,
72 public IOleCommandTarget
,
76 public IServiceProvider
79 CComPtr
<IShellFolder
> m_pSFParent
;
80 CComPtr
<IShellFolder2
> m_pSF2Parent
;
81 CComPtr
<IShellBrowser
> m_pShellBrowser
;
82 CComPtr
<ICommDlgBrowser
> m_pCommDlgBrowser
;
83 CComPtr
<IShellFolderViewDual
> m_pShellFolderViewDual
;
86 FOLDERSETTINGS m_FolderSettings
;
87 HMENU m_hMenu
; /* Handle to the menu bar of the browser */
88 HMENU m_hMenuArrangeModes
; /* Handle to the popup menu with the arrange modes */
89 HMENU m_hMenuViewModes
; /* Handle to the popup menu with the view modes */
90 HMENU m_hContextMenu
; /* Handle to the open context menu */
91 BOOL m_bmenuBarInitialized
;
94 PCUITEMID_CHILD
*m_apidl
;
95 PIDLIST_ABSOLUTE m_pidlParent
;
96 LISTVIEW_SORT_INFO m_sortInfo
;
97 ULONG m_hNotify
; /* Change notification handle */
101 CComPtr
<IAdviseSink
> m_pAdvSink
;
103 CComPtr
<IDataObject
> m_pSourceDataObject
;
104 CComPtr
<IDropTarget
> m_pCurDropTarget
; /* The sub-item, which is currently dragged over */
105 CComPtr
<IDataObject
> m_pCurDataObject
; /* The dragged data-object */
106 LONG m_iDragOverItem
; /* Dragged over item's index, iff m_pCurDropTarget != NULL */
107 UINT m_cScrollDelay
; /* Send a WM_*SCROLL msg every 250 ms during drag-scroll */
108 POINT m_ptLastMousePos
; /* Mouse position at last DragOver call */
110 CComPtr
<IContextMenu
> m_pCM
;
118 HRESULT
_MergeToolbar();
123 HRESULT WINAPI
Initialize(IShellFolder
*shellFolder
);
124 HRESULT
IncludeObject(PCUITEMID_CHILD pidl
);
125 HRESULT
OnDefaultCommand();
126 HRESULT
OnStateChange(UINT uFlags
);
127 void UpdateStatusbar();
129 void SetStyle(DWORD dwAdd
, DWORD dwRemove
);
131 void UpdateListColors();
133 static INT CALLBACK
ListViewCompareItems(LPARAM lParam1
, LPARAM lParam2
, LPARAM lpData
);
135 PCUITEMID_CHILD
_PidlByItem(int i
);
136 PCUITEMID_CHILD
_PidlByItem(LVITEM
& lvItem
);
137 int LV_FindItemByPidl(PCUITEMID_CHILD pidl
);
138 BOOLEAN
LV_AddItem(PCUITEMID_CHILD pidl
);
139 BOOLEAN
LV_DeleteItem(PCUITEMID_CHILD pidl
);
140 BOOLEAN
LV_RenameItem(PCUITEMID_CHILD pidlOld
, PCUITEMID_CHILD pidlNew
);
141 BOOLEAN
LV_ProdItem(PCUITEMID_CHILD pidl
);
142 static INT CALLBACK
fill_list(LPVOID ptr
, LPVOID arg
);
144 HRESULT
FillFileMenu();
145 HRESULT
FillEditMenu();
146 HRESULT
FillViewMenu();
147 HRESULT
FillArrangeAsMenu(HMENU hmenuArrange
);
148 HRESULT
CheckViewMode(HMENU hmenuView
);
149 UINT
GetSelections();
150 HRESULT
OpenSelectedItems();
152 void DoActivate(UINT uState
);
153 HRESULT
drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
154 HRESULT
InvokeContextMenuCommand(UINT uCommand
);
155 LRESULT
OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
);
157 // *** IOleWindow methods ***
158 virtual HRESULT STDMETHODCALLTYPE
GetWindow(HWND
*lphwnd
);
159 virtual HRESULT STDMETHODCALLTYPE
ContextSensitiveHelp(BOOL fEnterMode
);
161 // *** IShellView methods ***
162 virtual HRESULT STDMETHODCALLTYPE
TranslateAccelerator(MSG
*pmsg
);
163 virtual HRESULT STDMETHODCALLTYPE
EnableModeless(BOOL fEnable
);
164 virtual HRESULT STDMETHODCALLTYPE
UIActivate(UINT uState
);
165 virtual HRESULT STDMETHODCALLTYPE
Refresh();
166 virtual HRESULT STDMETHODCALLTYPE
CreateViewWindow(IShellView
*psvPrevious
, LPCFOLDERSETTINGS pfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
);
167 virtual HRESULT STDMETHODCALLTYPE
DestroyViewWindow();
168 virtual HRESULT STDMETHODCALLTYPE
GetCurrentInfo(LPFOLDERSETTINGS pfs
);
169 virtual HRESULT STDMETHODCALLTYPE
AddPropertySheetPages(DWORD dwReserved
, LPFNSVADDPROPSHEETPAGE pfn
, LPARAM lparam
);
170 virtual HRESULT STDMETHODCALLTYPE
SaveViewState();
171 virtual HRESULT STDMETHODCALLTYPE
SelectItem(PCUITEMID_CHILD pidlItem
, SVSIF uFlags
);
172 virtual HRESULT STDMETHODCALLTYPE
GetItemObject(UINT uItem
, REFIID riid
, void **ppv
);
174 // *** IShellView2 methods ***
175 virtual HRESULT STDMETHODCALLTYPE
GetView(SHELLVIEWID
*view_guid
, ULONG view_type
);
176 virtual HRESULT STDMETHODCALLTYPE
CreateViewWindow2(LPSV2CVW2_PARAMS view_params
);
177 virtual HRESULT STDMETHODCALLTYPE
HandleRename(LPCITEMIDLIST new_pidl
);
178 virtual HRESULT STDMETHODCALLTYPE
SelectAndPositionItem(LPCITEMIDLIST item
, UINT flags
, POINT
*point
);
180 // *** IShellView3 methods ***
181 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
);
183 // *** IFolderView methods ***
184 virtual HRESULT STDMETHODCALLTYPE
GetCurrentViewMode(UINT
*pViewMode
);
185 virtual HRESULT STDMETHODCALLTYPE
SetCurrentViewMode(UINT ViewMode
);
186 virtual HRESULT STDMETHODCALLTYPE
GetFolder(REFIID riid
, void **ppv
);
187 virtual HRESULT STDMETHODCALLTYPE
Item(int iItemIndex
, PITEMID_CHILD
*ppidl
);
188 virtual HRESULT STDMETHODCALLTYPE
ItemCount(UINT uFlags
, int *pcItems
);
189 virtual HRESULT STDMETHODCALLTYPE
Items(UINT uFlags
, REFIID riid
, void **ppv
);
190 virtual HRESULT STDMETHODCALLTYPE
GetSelectionMarkedItem(int *piItem
);
191 virtual HRESULT STDMETHODCALLTYPE
GetFocusedItem(int *piItem
);
192 virtual HRESULT STDMETHODCALLTYPE
GetItemPosition(PCUITEMID_CHILD pidl
, POINT
*ppt
);
193 virtual HRESULT STDMETHODCALLTYPE
GetSpacing(POINT
*ppt
);
194 virtual HRESULT STDMETHODCALLTYPE
GetDefaultSpacing(POINT
*ppt
);
195 virtual HRESULT STDMETHODCALLTYPE
GetAutoArrange();
196 virtual HRESULT STDMETHODCALLTYPE
SelectItem(int iItem
, DWORD dwFlags
);
197 virtual HRESULT STDMETHODCALLTYPE
SelectAndPositionItems(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD dwFlags
);
199 // *** IShellFolderView methods ***
200 virtual HRESULT STDMETHODCALLTYPE
Rearrange(LPARAM sort
);
201 virtual HRESULT STDMETHODCALLTYPE
GetArrangeParam(LPARAM
*sort
);
202 virtual HRESULT STDMETHODCALLTYPE
ArrangeGrid();
203 virtual HRESULT STDMETHODCALLTYPE
AutoArrange();
204 virtual HRESULT STDMETHODCALLTYPE
AddObject(PITEMID_CHILD pidl
, UINT
*item
);
205 virtual HRESULT STDMETHODCALLTYPE
GetObject(PITEMID_CHILD
*pidl
, UINT item
);
206 virtual HRESULT STDMETHODCALLTYPE
RemoveObject(PITEMID_CHILD pidl
, UINT
*item
);
207 virtual HRESULT STDMETHODCALLTYPE
GetObjectCount(UINT
*count
);
208 virtual HRESULT STDMETHODCALLTYPE
SetObjectCount(UINT count
, UINT flags
);
209 virtual HRESULT STDMETHODCALLTYPE
UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
);
210 virtual HRESULT STDMETHODCALLTYPE
RefreshObject(PITEMID_CHILD pidl
, UINT
*item
);
211 virtual HRESULT STDMETHODCALLTYPE
SetRedraw(BOOL redraw
);
212 virtual HRESULT STDMETHODCALLTYPE
GetSelectedCount(UINT
*count
);
213 virtual HRESULT STDMETHODCALLTYPE
GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
);
214 virtual HRESULT STDMETHODCALLTYPE
IsDropOnSource(IDropTarget
*drop_target
);
215 virtual HRESULT STDMETHODCALLTYPE
GetDragPoint(POINT
*pt
);
216 virtual HRESULT STDMETHODCALLTYPE
GetDropPoint(POINT
*pt
);
217 virtual HRESULT STDMETHODCALLTYPE
MoveIcons(IDataObject
*obj
);
218 virtual HRESULT STDMETHODCALLTYPE
SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
);
219 virtual HRESULT STDMETHODCALLTYPE
IsBkDropTarget(IDropTarget
*drop_target
);
220 virtual HRESULT STDMETHODCALLTYPE
SetClipboard(BOOL move
);
221 virtual HRESULT STDMETHODCALLTYPE
SetPoints(IDataObject
*obj
);
222 virtual HRESULT STDMETHODCALLTYPE
GetItemSpacing(ITEMSPACING
*spacing
);
223 virtual HRESULT STDMETHODCALLTYPE
SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
);
224 virtual HRESULT STDMETHODCALLTYPE
Select(UINT flags
);
225 virtual HRESULT STDMETHODCALLTYPE
QuerySupport(UINT
*support
);
226 virtual HRESULT STDMETHODCALLTYPE
SetAutomationObject(IDispatch
*disp
);
228 // *** IOleCommandTarget methods ***
229 virtual HRESULT STDMETHODCALLTYPE
QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
);
230 virtual HRESULT STDMETHODCALLTYPE
Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
);
232 // *** IDropTarget methods ***
233 virtual HRESULT STDMETHODCALLTYPE
DragEnter(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
234 virtual HRESULT STDMETHODCALLTYPE
DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
235 virtual HRESULT STDMETHODCALLTYPE
DragLeave();
236 virtual HRESULT STDMETHODCALLTYPE
Drop(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
238 // *** IDropSource methods ***
239 virtual HRESULT STDMETHODCALLTYPE
QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
);
240 virtual HRESULT STDMETHODCALLTYPE
GiveFeedback(DWORD dwEffect
);
242 // *** IViewObject methods ***
243 virtual HRESULT STDMETHODCALLTYPE
Draw(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
,
244 HDC hdcTargetDev
, HDC hdcDraw
, LPCRECTL lprcBounds
, LPCRECTL lprcWBounds
,
245 BOOL ( STDMETHODCALLTYPE
*pfnContinue
)(ULONG_PTR dwContinue
), ULONG_PTR dwContinue
);
246 virtual HRESULT STDMETHODCALLTYPE
GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
,
247 DVTARGETDEVICE
*ptd
, HDC hicTargetDev
, LOGPALETTE
**ppColorSet
);
248 virtual HRESULT STDMETHODCALLTYPE
Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
);
249 virtual HRESULT STDMETHODCALLTYPE
Unfreeze(DWORD dwFreeze
);
250 virtual HRESULT STDMETHODCALLTYPE
SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
);
251 virtual HRESULT STDMETHODCALLTYPE
GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
);
253 // *** IServiceProvider methods ***
254 virtual HRESULT STDMETHODCALLTYPE
QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
);
257 LRESULT
OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
258 LRESULT
OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
259 LRESULT
OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
260 LRESULT
OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
261 LRESULT
OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
262 LRESULT
OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
263 LRESULT
OnNCCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
264 LRESULT
OnNCDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
265 LRESULT
OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
266 LRESULT
OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
267 LRESULT
OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
268 LRESULT
OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
269 LRESULT
OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
270 LRESULT
OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
271 LRESULT
OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
272 LRESULT
OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
273 LRESULT
OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
274 LRESULT
OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
275 LRESULT
OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
276 LRESULT
OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
278 static ATL::CWndClassInfo
& GetWndClassInfo()
280 static ATL::CWndClassInfo wc
=
282 { sizeof(WNDCLASSEX
), CS_PARENTDC
, StartWindowProc
,
284 LoadCursor(NULL
, IDC_ARROW
), (HBRUSH
)(COLOR_WINDOW
+ 1), NULL
, SV_CLASS_NAME
, NULL
286 NULL
, NULL
, IDC_ARROW
, TRUE
, 0, _T("")
291 virtual WNDPROC
GetWindowProc()
296 static LRESULT CALLBACK
WindowProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
301 // Must hold a reference during message handling
302 pThis
= reinterpret_cast<CDefView
*>(hWnd
);
304 result
= CWindowImpl
<CDefView
, CWindow
, CControlWinTraits
>::WindowProc(hWnd
, uMsg
, wParam
, lParam
);
309 BEGIN_MSG_MAP(CDefView
)
310 MESSAGE_HANDLER(WM_SIZE
, OnSize
)
311 MESSAGE_HANDLER(WM_SETFOCUS
, OnSetFocus
)
312 MESSAGE_HANDLER(WM_KILLFOCUS
, OnKillFocus
)
313 MESSAGE_HANDLER(WM_NCCREATE
, OnNCCreate
)
314 MESSAGE_HANDLER(WM_NCDESTROY
, OnNCDestroy
)
315 MESSAGE_HANDLER(WM_CREATE
, OnCreate
)
316 MESSAGE_HANDLER(WM_ACTIVATE
, OnActivate
)
317 MESSAGE_HANDLER(WM_NOTIFY
, OnNotify
)
318 MESSAGE_HANDLER(WM_COMMAND
, OnCommand
)
319 MESSAGE_HANDLER(SHV_CHANGE_NOTIFY
, OnChangeNotify
)
320 MESSAGE_HANDLER(WM_CONTEXTMENU
, OnContextMenu
)
321 MESSAGE_HANDLER(WM_DRAWITEM
, OnCustomItem
)
322 MESSAGE_HANDLER(WM_MEASUREITEM
, OnCustomItem
)
323 MESSAGE_HANDLER(WM_SHOWWINDOW
, OnShowWindow
)
324 MESSAGE_HANDLER(WM_GETDLGCODE
, OnGetDlgCode
)
325 MESSAGE_HANDLER(WM_DESTROY
, OnDestroy
)
326 MESSAGE_HANDLER(WM_ERASEBKGND
, OnEraseBackground
)
327 MESSAGE_HANDLER(WM_SYSCOLORCHANGE
, OnSysColorChange
)
328 MESSAGE_HANDLER(CWM_GETISHELLBROWSER
, OnGetShellBrowser
)
329 MESSAGE_HANDLER(WM_SETTINGCHANGE
, OnSettingChange
)
330 MESSAGE_HANDLER(WM_INITMENUPOPUP
, OnInitMenuPopup
)
333 BEGIN_COM_MAP(CDefView
)
334 // Windows returns E_NOINTERFACE for IOleWindow
335 // COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
336 COM_INTERFACE_ENTRY_IID(IID_IShellView
, IShellView
)
337 COM_INTERFACE_ENTRY_IID(IID_IShellView2
, IShellView2
)
338 COM_INTERFACE_ENTRY_IID(IID_IFolderView
, IFolderView
)
339 COM_INTERFACE_ENTRY_IID(IID_IShellFolderView
, IShellFolderView
)
340 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget
, IOleCommandTarget
)
341 COM_INTERFACE_ENTRY_IID(IID_IDropTarget
, IDropTarget
)
342 COM_INTERFACE_ENTRY_IID(IID_IDropSource
, IDropSource
)
343 COM_INTERFACE_ENTRY_IID(IID_IViewObject
, IViewObject
)
344 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider
, IServiceProvider
)
349 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
350 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
351 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
353 #define ID_LISTVIEW 1
356 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
357 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
358 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
360 typedef void (CALLBACK
*PFNSHGETSETTINGSPROC
)(LPSHELLFLAGSTATE lpsfs
, DWORD dwMask
);
362 CDefView::CDefView() :
366 m_hMenuArrangeModes(NULL
),
367 m_hMenuViewModes(NULL
),
368 m_hContextMenu(NULL
),
369 m_bmenuBarInitialized(FALSE
),
383 ZeroMemory(&m_FolderSettings
, sizeof(m_FolderSettings
));
384 ZeroMemory(&m_sortInfo
, sizeof(m_sortInfo
));
385 ZeroMemory(&m_ptLastMousePos
, sizeof(m_ptLastMousePos
));
386 ZeroMemory(&m_Category
, sizeof(m_Category
));
389 CDefView::~CDefView()
391 TRACE(" destroying IShellView(%p)\n", this);
401 HRESULT WINAPI
CDefView::Initialize(IShellFolder
*shellFolder
)
403 m_pSFParent
= shellFolder
;
404 shellFolder
->QueryInterface(IID_PPV_ARG(IShellFolder2
, &m_pSF2Parent
));
409 /**********************************************************
411 * ##### helperfunctions for communication with ICommDlgBrowser #####
413 HRESULT
CDefView::IncludeObject(PCUITEMID_CHILD pidl
)
417 if (m_pCommDlgBrowser
.p
!= NULL
)
419 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl
);
420 ret
= m_pCommDlgBrowser
->IncludeObject(this, pidl
);
421 TRACE("--0x%08x\n", ret
);
427 HRESULT
CDefView::OnDefaultCommand()
429 HRESULT ret
= S_FALSE
;
431 if (m_pCommDlgBrowser
.p
!= NULL
)
433 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
434 ret
= m_pCommDlgBrowser
->OnDefaultCommand(this);
435 TRACE("-- returns %08x\n", ret
);
441 HRESULT
CDefView::OnStateChange(UINT uFlags
)
443 HRESULT ret
= S_FALSE
;
445 if (m_pCommDlgBrowser
.p
!= NULL
)
447 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags
);
448 ret
= m_pCommDlgBrowser
->OnStateChange(this, uFlags
);
454 /**********************************************************
455 * set the toolbar of the filedialog buttons
457 * - activates the buttons from the shellbrowser according to
460 void CDefView::CheckToolbar()
466 if (m_pCommDlgBrowser
!= NULL
)
468 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
469 FCIDM_TB_SMALLICON
, (m_FolderSettings
.ViewMode
== FVM_LIST
) ? TRUE
: FALSE
, &result
);
470 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
471 FCIDM_TB_REPORTVIEW
, (m_FolderSettings
.ViewMode
== FVM_DETAILS
) ? TRUE
: FALSE
, &result
);
472 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
473 FCIDM_TB_SMALLICON
, TRUE
, &result
);
474 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
475 FCIDM_TB_REPORTVIEW
, TRUE
, &result
);
479 void CDefView::UpdateStatusbar()
481 WCHAR szFormat
[MAX_PATH
] = {0};
482 WCHAR szObjects
[MAX_PATH
] = {0};
485 cSelectedItems
= m_ListView
.GetSelectedCount();
488 LoadStringW(shell32_hInstance
, IDS_OBJECTS_SELECTED
, szFormat
, _countof(szFormat
));
489 StringCchPrintfW(szObjects
, MAX_PATH
, szFormat
, cSelectedItems
);
493 LoadStringW(shell32_hInstance
, IDS_OBJECTS
, szFormat
, _countof(szFormat
));
494 StringCchPrintfW(szObjects
, MAX_PATH
, szFormat
, m_ListView
.GetItemCount());
496 m_pShellBrowser
->SetStatusTextSB(szObjects
);
499 /**********************************************************
501 * ##### helperfunctions for initializing the view #####
503 /**********************************************************
504 * change the style of the listview control
506 void CDefView::SetStyle(DWORD dwAdd
, DWORD dwRemove
)
510 TRACE("(%p)\n", this);
512 tmpstyle
= ::GetWindowLongPtrW(m_ListView
, GWL_STYLE
);
513 ::SetWindowLongPtrW(m_ListView
, GWL_STYLE
, dwAdd
| (tmpstyle
& ~dwRemove
));
516 /**********************************************************
517 * ShellView_CreateList()
519 * - creates the list view window
521 BOOL
CDefView::CreateList()
523 DWORD dwStyle
, dwExStyle
;
527 dwStyle
= WS_TABSTOP
| WS_VISIBLE
| WS_CHILDWINDOW
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
|
528 LVS_SHAREIMAGELISTS
| LVS_EDITLABELS
| LVS_AUTOARRANGE
;
529 dwExStyle
= WS_EX_CLIENTEDGE
;
531 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
532 dwStyle
|= LVS_ALIGNLEFT
;
534 dwStyle
|= LVS_ALIGNTOP
| LVS_SHOWSELALWAYS
;
536 switch (m_FolderSettings
.ViewMode
)
543 dwStyle
|= LVS_REPORT
;
547 dwStyle
|= LVS_SMALLICON
;
559 if (m_FolderSettings
.fFlags
& FWF_AUTOARRANGE
)
560 dwStyle
|= LVS_AUTOARRANGE
;
562 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
563 m_FolderSettings
.fFlags
|= FWF_NOCLIENTEDGE
| FWF_NOSCROLL
;
565 if (m_FolderSettings
.fFlags
& FWF_SINGLESEL
)
566 dwStyle
|= LVS_SINGLESEL
;
568 if (m_FolderSettings
.fFlags
& FWF_NOCLIENTEDGE
)
569 dwExStyle
&= ~WS_EX_CLIENTEDGE
;
571 RECT rcListView
= {0,0,0,0};
572 m_ListView
.Create(m_hWnd
, rcListView
, L
"FolderView", dwStyle
, dwExStyle
, ID_LISTVIEW
);
577 m_sortInfo
.bIsAscending
= TRUE
;
578 m_sortInfo
.nHeaderID
= -1;
579 m_sortInfo
.nLastHeaderID
= -1;
583 /* UpdateShellSettings(); */
587 void CDefView::UpdateListColors()
589 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
591 /* Check if drop shadows option is enabled */
592 BOOL bDropShadow
= FALSE
;
593 DWORD cbDropShadow
= sizeof(bDropShadow
);
596 * The desktop ListView always take the default desktop colours, by
597 * remaining transparent and letting user32/win32k paint itself the
598 * desktop background color, if any.
600 m_ListView
.SetBkColor(CLR_NONE
);
602 SHGetValueW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
603 L
"ListviewShadow", NULL
, &bDropShadow
, &cbDropShadow
);
606 /* Set the icon background transparent */
607 m_ListView
.SetTextBkColor(CLR_NONE
);
608 m_ListView
.SetTextColor(RGB(255, 255, 255));
609 m_ListView
.SetExtendedListViewStyle(LVS_EX_TRANSPARENTSHADOWTEXT
, LVS_EX_TRANSPARENTSHADOWTEXT
);
613 /* Set the icon background as the same colour as the desktop */
614 COLORREF crDesktop
= GetSysColor(COLOR_DESKTOP
);
615 m_ListView
.SetTextBkColor(crDesktop
);
616 if (GetRValue(crDesktop
) + GetGValue(crDesktop
) + GetBValue(crDesktop
) > 128 * 3)
617 m_ListView
.SetTextColor(RGB(0, 0, 0));
619 m_ListView
.SetTextColor(RGB(255, 255, 255));
620 m_ListView
.SetExtendedListViewStyle(0, LVS_EX_TRANSPARENTSHADOWTEXT
);
625 /**********************************************************
626 * ShellView_InitList()
628 * - adds all needed columns to the shellview
630 BOOL
CDefView::InitList()
634 HIMAGELIST big_icons
, small_icons
;
638 m_ListView
.DeleteAllItems();
640 m_hMenuArrangeModes
= CreateMenu();
644 for (int i
= 0; 1; i
++)
646 if (FAILED(m_pSF2Parent
->GetDetailsOf(NULL
, i
, &sd
)))
648 StrRetToStrNW( szTemp
, 50, &sd
.str
, NULL
);
649 m_ListView
.InsertColumn(i
, szTemp
, sd
.fmt
, sd
.cxChar
* 8);
651 InsertMenuW(m_hMenuArrangeModes
, -1, MF_STRING
, 0x30 + i
, szTemp
);
654 InsertMenuW(m_hMenuArrangeModes
, -1, MF_BYPOSITION
| MF_SEPARATOR
, 0, 0);
658 FIXME("no m_pSF2Parent\n");
661 Shell_GetImageLists(&big_icons
, &small_icons
);
662 m_ListView
.SetImageList(big_icons
, LVSIL_NORMAL
);
663 m_ListView
.SetImageList(small_icons
, LVSIL_SMALL
);
668 /*************************************************************************
669 * ShellView_ListViewCompareItems
671 * Compare Function for the Listview (FileOpen Dialog)
674 * lParam1 [I] the first ItemIdList to compare with
675 * lParam2 [I] the second ItemIdList to compare with
676 * lpData [I] The column ID for the header Ctrl to process
679 * A negative value if the first item should precede the second,
680 * a positive value if the first item should follow the second,
681 * or zero if the two items are equivalent
683 INT CALLBACK
CDefView::ListViewCompareItems(LPARAM lParam1
, LPARAM lParam2
, LPARAM lpData
)
685 PCUIDLIST_RELATIVE pidl1
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam1
);
686 PCUIDLIST_RELATIVE pidl2
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam2
);
687 CDefView
*pThis
= reinterpret_cast<CDefView
*>(lpData
);
689 HRESULT hres
= pThis
->m_pSFParent
->CompareIDs(pThis
->m_sortInfo
.nHeaderID
, pidl1
, pidl2
);
690 if (FAILED_UNEXPECTEDLY(hres
))
693 SHORT nDiff
= HRESULT_CODE(hres
);
694 if (!pThis
->m_sortInfo
.bIsAscending
)
699 PCUITEMID_CHILD
CDefView::_PidlByItem(int i
)
701 return reinterpret_cast<PCUITEMID_CHILD
>(m_ListView
.GetItemData(i
));
704 PCUITEMID_CHILD
CDefView::_PidlByItem(LVITEM
& lvItem
)
706 return reinterpret_cast<PCUITEMID_CHILD
>(lvItem
.lParam
);
709 /**********************************************************
710 * LV_FindItemByPidl()
712 int CDefView::LV_FindItemByPidl(PCUITEMID_CHILD pidl
)
714 int cItems
= m_ListView
.GetItemCount();
716 for (int i
= 0; i
<cItems
; i
++)
718 PCUITEMID_CHILD currentpidl
= _PidlByItem(i
);
719 HRESULT hr
= m_pSFParent
->CompareIDs(0, pidl
, currentpidl
);
721 if (SUCCEEDED(hr
) && !HRESULT_CODE(hr
))
729 /**********************************************************
732 BOOLEAN
CDefView::LV_AddItem(PCUITEMID_CHILD pidl
)
736 TRACE("(%p)(pidl=%p)\n", this, pidl
);
738 lvItem
.mask
= LVIF_TEXT
| LVIF_IMAGE
| LVIF_PARAM
; /*set the mask*/
739 lvItem
.iItem
= m_ListView
.GetItemCount(); /*add the item to the end of the list*/
741 lvItem
.lParam
= reinterpret_cast<LPARAM
>(ILClone(pidl
)); /*set the item's data*/
742 lvItem
.pszText
= LPSTR_TEXTCALLBACKW
; /*get text on a callback basis*/
743 lvItem
.iImage
= I_IMAGECALLBACK
; /*get the image on a callback basis*/
744 lvItem
.stateMask
= LVIS_CUT
;
746 if (m_ListView
.InsertItem(&lvItem
) == -1)
752 /**********************************************************
755 BOOLEAN
CDefView::LV_DeleteItem(PCUITEMID_CHILD pidl
)
759 TRACE("(%p)(pidl=%p)\n", this, pidl
);
761 nIndex
= LV_FindItemByPidl(pidl
);
763 return (-1 == m_ListView
.DeleteItem(nIndex
)) ? FALSE
: TRUE
;
766 /**********************************************************
769 BOOLEAN
CDefView::LV_RenameItem(PCUITEMID_CHILD pidlOld
, PCUITEMID_CHILD pidlNew
)
774 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", this, pidlOld
, pidlNew
);
776 nItem
= LV_FindItemByPidl(pidlOld
);
780 lvItem
.mask
= LVIF_PARAM
; /* only the pidl */
781 lvItem
.iItem
= nItem
;
783 m_ListView
.GetItem(&lvItem
);
785 SHFree(reinterpret_cast<LPVOID
>(lvItem
.lParam
));
786 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
787 lvItem
.iItem
= nItem
;
789 lvItem
.lParam
= reinterpret_cast<LPARAM
>(ILClone(pidlNew
)); /* set the item's data */
790 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
791 m_ListView
.SetItem(&lvItem
);
792 m_ListView
.Update(nItem
);
793 return TRUE
; /* FIXME: better handling */
799 /**********************************************************
802 BOOLEAN
CDefView::LV_ProdItem(PCUITEMID_CHILD pidl
)
807 TRACE("(%p)(pidl=%p)\n", this, pidl
);
809 nItem
= LV_FindItemByPidl(pidl
);
813 lvItem
.mask
= LVIF_IMAGE
;
814 lvItem
.iItem
= nItem
;
816 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
817 m_ListView
.SetItem(&lvItem
);
818 m_ListView
.Update(nItem
);
825 /**********************************************************
826 * ShellView_FillList()
828 * - gets the objectlist from the shellfolder
830 * - fills the list into the view
832 INT CALLBACK
CDefView::fill_list(LPVOID ptr
, LPVOID arg
)
834 PITEMID_CHILD pidl
= static_cast<PITEMID_CHILD
>(ptr
);
835 CDefView
*pThis
= static_cast<CDefView
*>(arg
);
837 /* in a commdlg This works as a filemask*/
838 if (pThis
->IncludeObject(pidl
) == S_OK
)
839 pThis
->LV_AddItem(pidl
);
845 HRESULT
CDefView::FillList()
847 CComPtr
<IEnumIDList
> pEnumIDList
;
853 DWORD dFlags
= SHCONTF_NONFOLDERS
| SHCONTF_FOLDERS
;
857 /* determine if there is a setting to show all the hidden files/folders */
858 if (RegOpenKeyExW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", 0, KEY_QUERY_VALUE
, &hKey
) == ERROR_SUCCESS
)
860 DWORD dataLength
, flagVal
;
862 dataLength
= sizeof(flagVal
);
863 if (RegQueryValueExW(hKey
, L
"Hidden", NULL
, NULL
, (LPBYTE
)&flagVal
, &dataLength
) == ERROR_SUCCESS
)
865 /* if the value is 1, then show all hidden files/folders */
868 dFlags
|= SHCONTF_INCLUDEHIDDEN
;
869 m_ListView
.SendMessageW(LVM_SETCALLBACKMASK
, LVIS_CUT
, 0);
877 /* get the itemlist from the shfolder */
878 hRes
= m_pSFParent
->EnumObjects(m_hWnd
, dFlags
, &pEnumIDList
);
886 /* create a pointer array */
887 hdpa
= DPA_Create(16);
890 return(E_OUTOFMEMORY
);
893 /* copy the items into the array*/
894 while((S_OK
== pEnumIDList
->Next(1, &pidl
, &dwFetched
)) && dwFetched
)
896 if (DPA_InsertPtr(hdpa
, 0x7fff, pidl
) == -1)
902 /*turn the listview's redrawing off*/
903 m_ListView
.SetRedraw(FALSE
);
905 DPA_DestroyCallback( hdpa
, fill_list
, this);
910 m_pSF2Parent
->GetDefaultColumn(NULL
, (ULONG
*)&m_sortInfo
.nHeaderID
, NULL
);
914 FIXME("no m_pSF2Parent\n");
916 m_sortInfo
.bIsAscending
= TRUE
;
917 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
918 m_ListView
.SortItems(ListViewCompareItems
, this);
920 /*turn the listview's redrawing back on and force it to draw*/
921 m_ListView
.SetRedraw(TRUE
);
926 LRESULT
CDefView::OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
928 m_ListView
.UpdateWindow();
933 LRESULT
CDefView::OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
935 return m_ListView
.SendMessageW(uMsg
, 0, 0);
938 LRESULT
CDefView::OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
945 DestroyMenu(m_hMenu
);
948 RevokeDragDrop(m_hWnd
);
949 SHChangeNotifyDeregister(m_hNotify
);
951 SHFree(m_pidlParent
);
958 LRESULT
CDefView::OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
960 /* redirect to parent */
961 if (m_FolderSettings
.fFlags
& (FWF_DESKTOP
| FWF_TRANSPARENT
))
962 return SendMessageW(GetParent(), WM_ERASEBKGND
, wParam
, lParam
);
968 LRESULT
CDefView::OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
970 /* Update desktop labels color */
973 /* Forward WM_SYSCOLORCHANGE to common controls */
974 return m_ListView
.SendMessageW(uMsg
, 0, 0);
977 LRESULT
CDefView::OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
979 return reinterpret_cast<LRESULT
>(m_pShellBrowser
.p
);
982 LRESULT
CDefView::OnNCCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
989 LRESULT
CDefView::OnNCDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
996 /**********************************************************
997 * ShellView_OnCreate()
999 LRESULT
CDefView::OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1001 CComPtr
<IDropTarget
> pdt
;
1002 SHChangeNotifyEntry ntreg
;
1003 CComPtr
<IPersistFolder2
> ppf2
;
1005 TRACE("%p\n", this);
1015 if (SUCCEEDED(QueryInterface(IID_PPV_ARG(IDropTarget
, &pdt
))))
1017 if (FAILED(RegisterDragDrop(m_hWnd
, pdt
)))
1018 ERR("Registering Drag Drop Failed");
1021 /* register for receiving notifications */
1022 m_pSFParent
->QueryInterface(IID_PPV_ARG(IPersistFolder2
, &ppf2
));
1025 ppf2
->GetCurFolder(&m_pidlParent
);
1026 ntreg
.fRecursive
= TRUE
;
1027 ntreg
.pidl
= m_pidlParent
;
1028 m_hNotify
= SHChangeNotifyRegister(m_hWnd
, SHCNRF_InterruptLevel
| SHCNRF_ShellLevel
, SHCNE_ALLEVENTS
, SHV_CHANGE_NOTIFY
, 1, &ntreg
);
1031 m_hAccel
= LoadAcceleratorsW(shell32_hInstance
, MAKEINTRESOURCEW(IDA_SHELLVIEW
));
1038 /**********************************************************
1039 * #### Handling of the menus ####
1042 extern "C" DWORD WINAPI
SHMenuIndexFromID(HMENU hMenu
, UINT uID
);
1044 HMENU
GetSubmenuByID(HMENU hmenu
, UINT id
)
1046 MENUITEMINFOW mii
= {sizeof(mii
), MIIM_SUBMENU
};
1047 if (::GetMenuItemInfoW(hmenu
, id
, FALSE
, &mii
))
1048 return mii
.hSubMenu
;
1053 /* ReallyGetMenuItemID returns the id of an item even if it opens a submenu,
1054 GetMenuItemID returns -1 if the specified item opens a submenu */
1055 UINT
ReallyGetMenuItemID(HMENU hmenu
, int i
)
1057 MENUITEMINFOW mii
= {sizeof(mii
), MIIM_ID
};
1058 if (::GetMenuItemInfoW(hmenu
, i
, TRUE
, &mii
))
1064 HRESULT
CDefView::FillFileMenu()
1066 HMENU hFileMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_FILE
);
1070 /* Cleanup the items added previously */
1071 for (int i
= GetMenuItemCount(hFileMenu
) - 1; i
>= 0; i
--)
1073 UINT id
= GetMenuItemID(hFileMenu
, i
);
1074 if (id
< FCIDM_BROWSERFIRST
|| id
> FCIDM_BROWSERLAST
)
1075 DeleteMenu(hFileMenu
, i
, MF_BYPOSITION
);
1078 /* Store the context menu in m_pCM and keep it in order to invoke the selected command later on */
1079 HRESULT hr
= GetItemObject(SVGIO_SELECTION
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1080 if (FAILED_UNEXPECTEDLY(hr
))
1083 IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1085 HMENU hmenu
= CreatePopupMenu();
1087 hr
= m_pCM
->QueryContextMenu(hmenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, 0);
1088 if (FAILED_UNEXPECTEDLY(hr
))
1091 // TODO: filter or something
1093 Shell_MergeMenus(hFileMenu
, hmenu
, 0, 0, 0xFFFF, MM_ADDSEPARATOR
| MM_SUBMENUSHAVEIDS
);
1095 ::DestroyMenu(hmenu
);
1100 HRESULT
CDefView::FillEditMenu()
1102 HMENU hEditMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_EDIT
);
1106 HMENU hmenuContents
= ::LoadMenuW(shell32_hInstance
, L
"MENU_003");
1110 Shell_MergeMenus(hEditMenu
, hmenuContents
, 0, 0, 0xFFFF, 0);
1112 ::DestroyMenu(hmenuContents
);
1117 HRESULT
CDefView::FillViewMenu()
1119 HMENU hViewMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_VIEW
);
1123 m_hMenuViewModes
= ::LoadMenuW(shell32_hInstance
, L
"MENU_001");
1124 if (!m_hMenuViewModes
)
1127 UINT i
= SHMenuIndexFromID(hViewMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
);
1128 Shell_MergeMenus(hViewMenu
, m_hMenuViewModes
, i
, 0, 0xFFFF, MM_ADDSEPARATOR
| MM_DONTREMOVESEPS
| MM_SUBMENUSHAVEIDS
);
1133 HRESULT
CDefView::FillArrangeAsMenu(HMENU hmenuArrange
)
1135 /* We only need to fill this once */
1136 if (GetMenuItemID(hmenuArrange
, 0) == FCIDM_SHVIEW_AUTOARRANGE
)
1138 Shell_MergeMenus(hmenuArrange
, m_hMenuArrangeModes
, 0, 0, 0xFFFF,0);
1141 /* Also check the menu item according to which we sort */
1142 CheckMenuRadioItem(hmenuArrange
,
1145 m_sortInfo
.nHeaderID
+ 0x30,
1151 HRESULT
CDefView::CheckViewMode(HMENU hmenuView
)
1153 if (m_FolderSettings
.ViewMode
>= FVM_FIRST
&& m_FolderSettings
.ViewMode
<= FVM_LAST
)
1155 UINT iItemFirst
= FCIDM_SHVIEW_BIGICON
;
1156 UINT iItemLast
= iItemFirst
+ FVM_LAST
- FVM_FIRST
;
1157 UINT iItem
= iItemFirst
+ m_FolderSettings
.ViewMode
- FVM_FIRST
;
1158 CheckMenuRadioItem(hmenuView
, iItemFirst
, iItemLast
, iItem
, MF_BYCOMMAND
);
1164 /**********************************************************
1165 * ShellView_GetSelections()
1167 * - fills the m_apidl list with the selected objects
1170 * number of selected items
1172 UINT
CDefView::GetSelections()
1176 m_cidl
= m_ListView
.GetSelectedCount();
1177 m_apidl
= static_cast<PCUITEMID_CHILD
*>(SHAlloc(m_cidl
* sizeof(PCUITEMID_CHILD
)));
1184 TRACE("-- Items selected =%u\n", m_cidl
);
1188 while ((lvIndex
= m_ListView
.GetNextItem(lvIndex
, LVNI_SELECTED
)) > -1)
1190 m_apidl
[i
] = _PidlByItem(lvIndex
);
1194 TRACE("-- selected Item found\n");
1200 HRESULT
CDefView::InvokeContextMenuCommand(UINT uCommand
)
1202 CMINVOKECOMMANDINFO cmi
;
1204 ZeroMemory(&cmi
, sizeof(cmi
));
1205 cmi
.cbSize
= sizeof(cmi
);
1206 cmi
.lpVerb
= MAKEINTRESOURCEA(uCommand
);
1209 if (GetKeyState(VK_SHIFT
) & 0x8000)
1210 cmi
.fMask
|= CMIC_MASK_SHIFT_DOWN
;
1212 if (GetKeyState(VK_CONTROL
) & 0x8000)
1213 cmi
.fMask
|= CMIC_MASK_CONTROL_DOWN
;
1215 return m_pCM
->InvokeCommand(&cmi
);
1218 /**********************************************************
1219 * ShellView_OpenSelectedItems()
1221 HRESULT
CDefView::OpenSelectedItems()
1227 m_cidl
= m_ListView
.GetSelectedCount();
1231 hResult
= OnDefaultCommand();
1232 if (hResult
== S_OK
)
1235 hMenu
= CreatePopupMenu();
1239 hResult
= GetItemObject(SVGIO_SELECTION
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1240 if (FAILED(hResult
))
1243 IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1245 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, 0x20, 0x7fff, CMF_DEFAULTONLY
);
1246 if (FAILED(hResult
))
1249 uCommand
= GetMenuDefaultItem(hMenu
, FALSE
, 0);
1250 if (uCommand
== (UINT
)-1)
1256 InvokeContextMenuCommand(uCommand
);
1265 IUnknown_SetSite(m_pCM
, NULL
);
1272 /**********************************************************
1273 * ShellView_DoContextMenu()
1275 LRESULT
CDefView::OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1284 TRACE("(%p)->(0x%08x 0x%08x) stub\n", this, x
, y
);
1286 m_hContextMenu
= CreatePopupMenu();
1287 if (!m_hContextMenu
)
1290 m_cidl
= m_ListView
.GetSelectedCount();
1292 hResult
= GetItemObject( m_cidl
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1293 if (FAILED( hResult
))
1296 IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1298 hResult
= m_pCM
->QueryContextMenu(m_hContextMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1299 if (FAILED( hResult
))
1302 uCommand
= TrackPopupMenu(m_hContextMenu
,
1303 TPM_LEFTALIGN
| TPM_RETURNCMD
| TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
,
1304 x
, y
, 0, m_hWnd
, NULL
);
1308 if (uCommand
== FCIDM_SHVIEW_OPEN
&& OnDefaultCommand() == S_OK
)
1311 InvokeContextMenuCommand(uCommand
);
1316 IUnknown_SetSite(m_pCM
, NULL
);
1322 DestroyMenu(m_hContextMenu
);
1323 m_hContextMenu
= NULL
;
1329 LRESULT
CDefView::OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
)
1334 hMenu
= CreatePopupMenu();
1338 hResult
= GetItemObject( bUseSelection
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1339 if (FAILED( hResult
))
1342 IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1344 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1345 if (FAILED( hResult
))
1348 InvokeContextMenuCommand(uCommand
);
1353 IUnknown_SetSite(m_pCM
, NULL
);
1363 /**********************************************************
1364 * ##### message handling #####
1367 /**********************************************************
1368 * ShellView_OnSize()
1370 LRESULT
CDefView::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1372 WORD wWidth
, wHeight
;
1374 wWidth
= LOWORD(lParam
);
1375 wHeight
= HIWORD(lParam
);
1377 TRACE("%p width=%u height=%u\n", this, wWidth
, wHeight
);
1379 /* Resize the ListView to fit our window */
1382 ::MoveWindow(m_ListView
, 0, 0, wWidth
, wHeight
, TRUE
);
1388 /**********************************************************
1389 * ShellView_OnDeactivate()
1394 void CDefView::OnDeactivate()
1396 TRACE("%p\n", this);
1398 if (m_uState
!= SVUIA_DEACTIVATE
)
1400 // TODO: cleanup menu after deactivation
1402 m_uState
= SVUIA_DEACTIVATE
;
1406 void CDefView::DoActivate(UINT uState
)
1408 TRACE("%p uState=%x\n", this, uState
);
1410 /*don't do anything if the state isn't really changing */
1411 if (m_uState
== uState
)
1416 if (uState
== SVUIA_DEACTIVATE
)
1422 if(m_hMenu
&& !m_bmenuBarInitialized
)
1426 m_pShellBrowser
->SetMenuSB(m_hMenu
, 0, m_hWnd
);
1427 m_bmenuBarInitialized
= TRUE
;
1430 if (SVUIA_ACTIVATE_FOCUS
== uState
)
1432 m_ListView
.SetFocus();
1440 /**********************************************************
1441 * ShellView_OnActivate()
1443 LRESULT
CDefView::OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1445 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1449 /**********************************************************
1450 * ShellView_OnSetFocus()
1453 LRESULT
CDefView::OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1455 TRACE("%p\n", this);
1457 /* Tell the browser one of our windows has received the focus. This
1458 should always be done before merging menus (OnActivate merges the
1459 menus) if one of our windows has the focus.*/
1461 m_pShellBrowser
->OnViewWindowActive(this);
1462 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1464 /* Set the focus to the listview */
1465 m_ListView
.SetFocus();
1467 /* Notify the ICommDlgBrowser interface */
1468 OnStateChange(CDBOSC_SETFOCUS
);
1473 /**********************************************************
1474 * ShellView_OnKillFocus()
1476 LRESULT
CDefView::OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1478 TRACE("(%p) stub\n", this);
1480 DoActivate(SVUIA_ACTIVATE_NOFOCUS
);
1481 /* Notify the ICommDlgBrowser */
1482 OnStateChange(CDBOSC_KILLFOCUS
);
1487 /**********************************************************
1488 * ShellView_OnCommand()
1491 * the CmdID's are the ones from the context menu
1493 LRESULT
CDefView::OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1500 dwCmdID
= GET_WM_COMMAND_ID(wParam
, lParam
);
1501 dwCmd
= GET_WM_COMMAND_CMD(wParam
, lParam
);
1502 hwndCmd
= GET_WM_COMMAND_HWND(wParam
, lParam
);
1504 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n", this, dwCmdID
, dwCmd
, hwndCmd
);
1508 case FCIDM_SHVIEW_SMALLICON
:
1509 m_FolderSettings
.ViewMode
= FVM_SMALLICON
;
1510 SetStyle (LVS_SMALLICON
, LVS_TYPEMASK
);
1514 case FCIDM_SHVIEW_BIGICON
:
1515 m_FolderSettings
.ViewMode
= FVM_ICON
;
1516 SetStyle (LVS_ICON
, LVS_TYPEMASK
);
1520 case FCIDM_SHVIEW_LISTVIEW
:
1521 m_FolderSettings
.ViewMode
= FVM_LIST
;
1522 SetStyle (LVS_LIST
, LVS_TYPEMASK
);
1526 case FCIDM_SHVIEW_REPORTVIEW
:
1527 m_FolderSettings
.ViewMode
= FVM_DETAILS
;
1528 SetStyle (LVS_REPORT
, LVS_TYPEMASK
);
1532 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1537 m_sortInfo
.nHeaderID
= dwCmdID
- 0x30;
1538 m_sortInfo
.bIsAscending
= TRUE
;
1539 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
1540 m_ListView
.SortItems(ListViewCompareItems
, this);
1543 case FCIDM_SHVIEW_SNAPTOGRID
:
1544 case FCIDM_SHVIEW_AUTOARRANGE
:
1547 case FCIDM_SHVIEW_SELECTALL
:
1548 m_ListView
.SetItemState(-1, LVIS_SELECTED
, LVIS_SELECTED
);
1551 case FCIDM_SHVIEW_INVERTSELECTION
:
1552 nCount
= m_ListView
.GetItemCount();
1553 for (int i
=0; i
< nCount
; i
++)
1554 m_ListView
.SetItemState(i
, m_ListView
.GetItemState(i
, LVIS_SELECTED
) ? 0 : LVIS_SELECTED
, LVIS_SELECTED
);
1557 case FCIDM_SHVIEW_REFRESH
:
1561 case FCIDM_SHVIEW_DELETE
:
1562 case FCIDM_SHVIEW_CUT
:
1563 case FCIDM_SHVIEW_COPY
:
1564 case FCIDM_SHVIEW_RENAME
:
1565 return OnExplorerCommand(dwCmdID
, TRUE
);
1567 case FCIDM_SHVIEW_INSERT
:
1568 case FCIDM_SHVIEW_UNDO
:
1569 case FCIDM_SHVIEW_INSERTLINK
:
1570 case FCIDM_SHVIEW_NEWFOLDER
:
1571 return OnExplorerCommand(dwCmdID
, FALSE
);
1573 /* WM_COMMAND messages from the file menu are routed to the CDefView so as to let m_pCM handle the command */
1576 InvokeContextMenuCommand(dwCmdID
);
1583 /**********************************************************
1584 * ShellView_OnNotify()
1587 LRESULT
CDefView::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1591 LPNMLISTVIEW lpnmlv
;
1592 NMLVDISPINFOW
*lpdi
;
1593 PCUITEMID_CHILD pidl
;
1597 lpnmh
= (LPNMHDR
)lParam
;
1598 lpnmlv
= (LPNMLISTVIEW
)lpnmh
;
1599 lpdi
= (NMLVDISPINFOW
*)lpnmh
;
1601 TRACE("%p CtlID=%u lpnmh->code=%x\n", this, CtlID
, lpnmh
->code
);
1603 switch (lpnmh
->code
)
1606 TRACE("-- NM_SETFOCUS %p\n", this);
1607 OnSetFocus(0, 0, 0, unused
);
1611 TRACE("-- NM_KILLFOCUS %p\n", this);
1613 /* Notify the ICommDlgBrowser interface */
1614 OnStateChange(CDBOSC_KILLFOCUS
);
1618 TRACE("-- NM_CUSTOMDRAW %p\n", this);
1619 return CDRF_DODEFAULT
;
1621 case NM_RELEASEDCAPTURE
:
1622 TRACE("-- NM_RELEASEDCAPTURE %p\n", this);
1626 TRACE("-- NM_CLICK %p\n", this);
1630 TRACE("-- NM_RCLICK %p\n", this);
1634 TRACE("-- NM_DBLCLK %p\n", this);
1635 OpenSelectedItems();
1639 TRACE("-- NM_RETURN %p\n", this);
1640 OpenSelectedItems();
1644 TRACE("-- HDN_ENDTRACKW %p\n", this);
1645 /*nColumn1 = m_ListView.GetColumnWidth(0);
1646 nColumn2 = m_ListView.GetColumnWidth(1);*/
1649 case LVN_DELETEITEM
:
1650 TRACE("-- LVN_DELETEITEM %p\n", this);
1652 /*delete the pidl because we made a copy of it*/
1653 SHFree(reinterpret_cast<LPVOID
>(lpnmlv
->lParam
));
1657 case LVN_DELETEALLITEMS
:
1658 TRACE("-- LVN_DELETEALLITEMS %p\n", this);
1661 case LVN_INSERTITEM
:
1662 TRACE("-- LVN_INSERTITEM (STUB)%p\n", this);
1665 case LVN_ITEMACTIVATE
:
1666 TRACE("-- LVN_ITEMACTIVATE %p\n", this);
1667 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1670 case LVN_COLUMNCLICK
:
1671 m_sortInfo
.nHeaderID
= lpnmlv
->iSubItem
;
1672 if (m_sortInfo
.nLastHeaderID
== m_sortInfo
.nHeaderID
)
1673 m_sortInfo
.bIsAscending
= !m_sortInfo
.bIsAscending
;
1675 m_sortInfo
.bIsAscending
= TRUE
;
1676 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
1678 m_ListView
.SortItems(ListViewCompareItems
, this);
1681 case LVN_GETDISPINFOA
:
1682 case LVN_GETDISPINFOW
:
1683 TRACE("-- LVN_GETDISPINFO %p\n", this);
1684 pidl
= _PidlByItem(lpdi
->item
);
1686 if (lpdi
->item
.mask
& LVIF_TEXT
) /* text requested */
1691 if (FAILED(m_pSF2Parent
->GetDetailsOf(pidl
, lpdi
->item
.iSubItem
, &sd
)))
1693 FIXME("failed to get details\n");
1697 if (lpnmh
->code
== LVN_GETDISPINFOA
)
1699 /* shouldn't happen */
1700 NMLVDISPINFOA
*lpdiA
= (NMLVDISPINFOA
*)lpnmh
;
1701 StrRetToStrNA( lpdiA
->item
.pszText
, lpdiA
->item
.cchTextMax
, &sd
.str
, NULL
);
1702 TRACE("-- text=%s\n", lpdiA
->item
.pszText
);
1704 else /* LVN_GETDISPINFOW */
1706 StrRetToStrNW( lpdi
->item
.pszText
, lpdi
->item
.cchTextMax
, &sd
.str
, NULL
);
1707 TRACE("-- text=%s\n", debugstr_w(lpdi
->item
.pszText
));
1712 FIXME("no m_pSF2Parent\n");
1715 if(lpdi
->item
.mask
& LVIF_IMAGE
) /* image requested */
1717 lpdi
->item
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
1719 if(lpdi
->item
.mask
& LVIF_STATE
)
1721 ULONG attributes
= SFGAO_HIDDEN
;
1722 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(1, &pidl
, &attributes
)))
1724 if (attributes
& SFGAO_HIDDEN
)
1726 lpdi
->item
.state
|= LVIS_CUT
;
1730 lpdi
->item
.mask
|= LVIF_DI_SETITEM
;
1733 case LVN_ITEMCHANGED
:
1734 TRACE("-- LVN_ITEMCHANGED %p\n", this);
1735 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1740 case LVN_BEGINRDRAG
:
1741 TRACE("-- LVN_BEGINDRAG\n");
1743 if (GetSelections())
1745 CComPtr
<IDataObject
> pda
;
1746 DWORD dwAttributes
= SFGAO_CANLINK
;
1747 DWORD dwEffect
= DROPEFFECT_COPY
| DROPEFFECT_MOVE
;
1749 if (SUCCEEDED(m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, IID_NULL_PPV_ARG(IDataObject
, &pda
))))
1751 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(m_cidl
, m_apidl
, &dwAttributes
)))
1753 if (dwAttributes
& SFGAO_CANLINK
)
1755 dwEffect
|= DROPEFFECT_LINK
;
1759 CComPtr
<IAsyncOperation
> piaso
;
1760 if (SUCCEEDED(pda
->QueryInterface(IID_PPV_ARG(IAsyncOperation
, &piaso
))))
1762 piaso
->SetAsyncMode(TRUE
);
1767 m_pSourceDataObject
= pda
;
1769 DoDragDrop(pda
, this, dwEffect
, &dwEffect2
);
1771 m_pSourceDataObject
.Release();
1776 case LVN_BEGINLABELEDITW
:
1778 DWORD dwAttr
= SFGAO_CANRENAME
;
1779 pidl
= _PidlByItem(lpdi
->item
);
1781 TRACE("-- LVN_BEGINLABELEDITW %p\n", this);
1783 m_pSFParent
->GetAttributesOf(1, &pidl
, &dwAttr
);
1784 if (SFGAO_CANRENAME
& dwAttr
)
1792 case LVN_ENDLABELEDITW
:
1794 TRACE("-- LVN_ENDLABELEDITW %p\n", this);
1796 m_isEditing
= FALSE
;
1798 if (lpdi
->item
.pszText
)
1803 pidl
= _PidlByItem(lpdi
->item
);
1804 PITEMID_CHILD pidlNew
;
1805 hr
= m_pSFParent
->SetNameOf(0, pidl
, lpdi
->item
.pszText
, SHGDN_INFOLDER
, &pidlNew
);
1807 if (SUCCEEDED(hr
) && pidlNew
)
1809 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
1810 lvItem
.iItem
= lpdi
->item
.iItem
;
1811 lvItem
.iSubItem
= 0;
1812 lvItem
.lParam
= reinterpret_cast<LPARAM
>(pidlNew
);
1813 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
1814 m_ListView
.SetItem(&lvItem
);
1815 m_ListView
.Update(lpdi
->item
.iItem
);
1824 TRACE("-- %p WM_COMMAND %x unhandled\n", this, lpnmh
->code
);
1832 * This is just a quick hack to make the desktop work correctly.
1833 * ITranslateShellChangeNotify's IsChildID is undocumented, but most likely the way that
1834 * a folder should know if it should update upon a change notification.
1835 * It is exported by merged folders at a minimum.
1837 static BOOL
ILIsParentOrSpecialParent(PCIDLIST_ABSOLUTE pidl1
, PCIDLIST_ABSOLUTE pidl2
)
1839 if (!pidl1
|| !pidl2
)
1841 if (ILIsParent(pidl1
, pidl2
, TRUE
))
1844 if (_ILIsDesktop(pidl1
))
1846 PIDLIST_ABSOLUTE deskpidl
;
1847 SHGetFolderLocation(NULL
, CSIDL_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
1848 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
1854 SHGetFolderLocation(NULL
, CSIDL_COMMON_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
1855 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
1865 /**********************************************************
1866 * ShellView_OnChange()
1868 LRESULT
CDefView::OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1870 PCIDLIST_ABSOLUTE
*Pidls
= reinterpret_cast<PCIDLIST_ABSOLUTE
*>(wParam
);
1871 BOOL bParent0
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[0]);
1872 BOOL bParent1
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[1]);
1874 TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls
[0], Pidls
[1], lParam
);
1876 switch (lParam
&~ SHCNE_INTERRUPT
)
1882 if (LV_FindItemByPidl(ILFindLastID(Pidls
[0])) == -1)
1884 LV_AddItem(ILFindLastID(Pidls
[0]));
1888 LV_ProdItem(ILFindLastID(Pidls
[0]));
1896 LV_DeleteItem(ILFindLastID(Pidls
[0]));
1899 case SHCNE_RENAMEFOLDER
:
1900 case SHCNE_RENAMEITEM
:
1901 if (bParent0
&& bParent1
)
1902 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[1]));
1904 LV_DeleteItem(ILFindLastID(Pidls
[0]));
1906 LV_AddItem(ILFindLastID(Pidls
[1]));
1909 case SHCNE_UPDATEITEM
:
1911 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[0]));
1914 case SHCNE_UPDATEDIR
:
1921 /**********************************************************
1922 * CDefView::OnCustomItem
1924 LRESULT
CDefView::OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1929 ERR("no menu!!!\n");
1934 HRESULT hres
= SHForwardContextMenuMsg(m_pCM
, uMsg
, wParam
, lParam
, &result
, TRUE
);
1935 if (SUCCEEDED(hres
))
1941 LRESULT
CDefView::OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1943 /* Wallpaper setting affects drop shadows effect */
1944 if (wParam
== SPI_SETDESKWALLPAPER
|| wParam
== 0)
1950 /**********************************************************
1951 * CDefView::OnInitMenuPopup
1953 LRESULT
CDefView::OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1955 HMENU hmenu
= (HMENU
) wParam
;
1956 int nPos
= LOWORD(lParam
);
1959 OnCustomItem(uMsg
, wParam
, lParam
, bHandled
);
1961 HMENU hViewMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_VIEW
);
1963 /* Lets try to find out what the hell wParam is */
1964 if (hmenu
== GetSubMenu(m_hMenu
, nPos
))
1965 menuItemId
= ReallyGetMenuItemID(m_hMenu
, nPos
);
1966 else if (hViewMenu
&& hmenu
== GetSubMenu(hViewMenu
, nPos
))
1967 menuItemId
= ReallyGetMenuItemID(hViewMenu
, nPos
);
1968 else if (m_hContextMenu
&& hmenu
== GetSubMenu(m_hContextMenu
, nPos
))
1969 menuItemId
= ReallyGetMenuItemID(m_hContextMenu
, nPos
);
1975 case FCIDM_MENU_FILE
:
1978 case FCIDM_MENU_VIEW
:
1979 case FCIDM_SHVIEW_VIEW
:
1980 CheckViewMode(hmenu
);
1982 case FCIDM_SHVIEW_ARRANGE
:
1983 FillArrangeAsMenu(hmenu
);
1990 /**********************************************************
1993 * The INTERFACE of the IShellView object
1996 **********************************************************
1999 /**********************************************************
2000 * ShellView_GetWindow
2002 HRESULT WINAPI
CDefView::GetWindow(HWND
*phWnd
)
2004 TRACE("(%p)\n", this);
2011 HRESULT WINAPI
CDefView::ContextSensitiveHelp(BOOL fEnterMode
)
2013 FIXME("(%p) stub\n", this);
2018 /**********************************************************
2019 * IShellView_TranslateAccelerator
2022 * use the accel functions
2024 HRESULT WINAPI
CDefView::TranslateAccelerator(LPMSG lpmsg
)
2029 if (lpmsg
->message
>= WM_KEYFIRST
&& lpmsg
->message
<= WM_KEYLAST
)
2031 if (::TranslateAcceleratorW(m_hWnd
, m_hAccel
, lpmsg
) != 0)
2034 TRACE("-- key=0x04%lx\n", lpmsg
->wParam
) ;
2037 return m_pShellBrowser
->TranslateAcceleratorSB(lpmsg
, 0);
2040 HRESULT WINAPI
CDefView::EnableModeless(BOOL fEnable
)
2042 FIXME("(%p) stub\n", this);
2047 HRESULT WINAPI
CDefView::UIActivate(UINT uState
)
2049 // CHAR szName[MAX_PATH];
2051 int nPartArray
[1] = { -1};
2053 TRACE("(%p)->(state=%x) stub\n", this, uState
);
2055 /* don't do anything if the state isn't really changing */
2056 if (m_uState
== uState
)
2061 /* OnActivate handles the menu merging and internal state */
2064 /* only do This if we are active */
2065 if (uState
!= SVUIA_DEACTIVATE
)
2069 GetFolderPath is not a method of IShellFolder
2070 IShellFolder_GetFolderPath( m_pSFParent, szName, sizeof(szName) );
2072 /* set the number of parts */
2073 m_pShellBrowser
->SendControlMsg(FCW_STATUS
, SB_SETPARTS
, 1, (LPARAM
)nPartArray
, &lResult
);
2075 /* set the text for the parts */
2077 m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXTA, 0, (LPARAM)szName, &lResult);
2084 HRESULT WINAPI
CDefView::Refresh()
2086 TRACE("(%p)\n", this);
2088 m_ListView
.DeleteAllItems();
2094 HRESULT WINAPI
CDefView::CreateViewWindow(IShellView
*lpPrevView
, LPCFOLDERSETTINGS lpfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
)
2096 return CreateViewWindow3(psb
, lpPrevView
, SV3CVW3_DEFAULT
,
2097 (FOLDERFLAGS
)lpfs
->fFlags
, (FOLDERFLAGS
)lpfs
->fFlags
, (FOLDERVIEWMODE
)lpfs
->ViewMode
, NULL
, prcView
, phWnd
);
2100 HRESULT WINAPI
CDefView::DestroyViewWindow()
2102 TRACE("(%p)\n", this);
2104 /* Make absolutely sure all our UI is cleaned up */
2105 UIActivate(SVUIA_DEACTIVATE
);
2109 // "Accelerator tables loaded from resources are freed automatically when the application terminates." -- MSDN
2113 if (m_hMenuViewModes
)
2115 DestroyMenu(m_hMenuViewModes
);
2116 m_hMenuViewModes
= NULL
;
2121 DestroyMenu(m_hMenu
);
2127 m_ListView
.DestroyWindow();
2135 m_pShellBrowser
.Release();
2136 m_pCommDlgBrowser
.Release();
2141 HRESULT WINAPI
CDefView::GetCurrentInfo(LPFOLDERSETTINGS lpfs
)
2143 TRACE("(%p)->(%p) vmode=%x flags=%x\n", this, lpfs
,
2144 m_FolderSettings
.ViewMode
, m_FolderSettings
.fFlags
);
2147 return E_INVALIDARG
;
2149 *lpfs
= m_FolderSettings
;
2153 HRESULT WINAPI
CDefView::AddPropertySheetPages(DWORD dwReserved
, LPFNADDPROPSHEETPAGE lpfn
, LPARAM lparam
)
2155 FIXME("(%p) stub\n", this);
2160 HRESULT WINAPI
CDefView::SaveViewState()
2162 FIXME("(%p) stub\n", this);
2167 HRESULT WINAPI
CDefView::SelectItem(PCUITEMID_CHILD pidl
, UINT uFlags
)
2171 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n", this, pidl
, uFlags
);
2173 i
= LV_FindItemByPidl(pidl
);
2177 if(uFlags
& SVSI_ENSUREVISIBLE
)
2178 m_ListView
.EnsureVisible(i
, FALSE
);
2180 LVITEMW lvItem
= {0};
2181 lvItem
.mask
= LVIF_STATE
;
2182 lvItem
.stateMask
= LVIS_SELECTED
| LVIS_FOCUSED
;
2184 while (m_ListView
.GetItem(&lvItem
))
2186 if (lvItem
.iItem
== i
)
2188 if (uFlags
& SVSI_SELECT
)
2189 lvItem
.state
|= LVIS_SELECTED
;
2191 lvItem
.state
&= ~LVIS_SELECTED
;
2193 if (uFlags
& SVSI_FOCUSED
)
2194 lvItem
.state
&= ~LVIS_FOCUSED
;
2198 if (uFlags
& SVSI_DESELECTOTHERS
)
2199 lvItem
.state
&= ~LVIS_SELECTED
;
2202 m_ListView
.SetItem(&lvItem
);
2206 if(uFlags
& SVSI_EDIT
)
2207 m_ListView
.EditLabel(i
);
2212 HRESULT WINAPI
CDefView::GetItemObject(UINT uItem
, REFIID riid
, LPVOID
*ppvOut
)
2214 HRESULT hr
= E_NOINTERFACE
;
2216 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n", this, uItem
, debugstr_guid(&riid
), ppvOut
);
2222 case SVGIO_BACKGROUND
:
2223 if (IsEqualIID(riid
, IID_IContextMenu
))
2225 //*ppvOut = ISvBgCm_Constructor(m_pSFParent, FALSE);
2230 hr
= CDefFolderMenu_Create2(NULL
, NULL
, 0, NULL
, m_pSFParent
, NULL
, 0, NULL
, &pcm
);
2235 else if (IsEqualIID(riid
, IID_IDispatch
))
2237 if (m_pShellFolderViewDual
== NULL
)
2239 hr
= CDefViewDual_Constructor(riid
, (LPVOID
*)&m_pShellFolderViewDual
);
2240 if (FAILED_UNEXPECTEDLY(hr
))
2245 hr
= m_pShellFolderViewDual
->QueryInterface(riid
, ppvOut
);
2249 case SVGIO_SELECTION
:
2251 hr
= m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, riid
, 0, ppvOut
);
2255 TRACE("-- (%p)->(interface=%p)\n", this, *ppvOut
);
2260 HRESULT STDMETHODCALLTYPE
CDefView::GetCurrentViewMode(UINT
*pViewMode
)
2262 TRACE("(%p)->(%p), stub\n", this, pViewMode
);
2265 return E_INVALIDARG
;
2267 *pViewMode
= m_FolderSettings
.ViewMode
;
2271 HRESULT STDMETHODCALLTYPE
CDefView::SetCurrentViewMode(UINT ViewMode
)
2274 TRACE("(%p)->(%u), stub\n", this, ViewMode
);
2276 /* It's not redundant to check FVM_AUTO because it's a (UINT)-1 */
2277 if (((INT
)ViewMode
< FVM_FIRST
|| (INT
)ViewMode
> FVM_LAST
) && ((INT
)ViewMode
!= FVM_AUTO
))
2278 return E_INVALIDARG
;
2280 /* Windows before Vista uses LVM_SETVIEW and possibly
2281 LVM_SETEXTENDEDLISTVIEWSTYLE to set the style of the listview,
2282 while later versions seem to accomplish this through other
2290 dwStyle
= LVS_REPORT
;
2293 dwStyle
= LVS_SMALLICON
;
2300 FIXME("ViewMode %d not implemented\n", ViewMode
);
2306 SetStyle(dwStyle
, LVS_TYPEMASK
);
2308 /* This will not necessarily be the actual mode set above.
2309 This mimics the behavior of Windows XP. */
2310 m_FolderSettings
.ViewMode
= ViewMode
;
2315 HRESULT STDMETHODCALLTYPE
CDefView::GetFolder(REFIID riid
, void **ppv
)
2317 if (m_pSFParent
== NULL
)
2320 return m_pSFParent
->QueryInterface(riid
, ppv
);
2323 HRESULT STDMETHODCALLTYPE
CDefView::Item(int iItemIndex
, PITEMID_CHILD
*ppidl
)
2325 PCUITEMID_CHILD pidl
= _PidlByItem(iItemIndex
);
2328 *ppidl
= ILClone(pidl
);
2333 return E_INVALIDARG
;
2336 HRESULT STDMETHODCALLTYPE
CDefView::ItemCount(UINT uFlags
, int *pcItems
)
2338 TRACE("(%p)->(%u %p)\n", this, uFlags
, pcItems
);
2340 if (uFlags
!= SVGIO_ALLVIEW
)
2341 FIXME("some flags unsupported, %x\n", uFlags
& ~SVGIO_ALLVIEW
);
2343 *pcItems
= m_ListView
.GetItemCount();
2348 HRESULT STDMETHODCALLTYPE
CDefView::Items(UINT uFlags
, REFIID riid
, void **ppv
)
2353 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectionMarkedItem(int *piItem
)
2355 TRACE("(%p)->(%p)\n", this, piItem
);
2357 *piItem
= m_ListView
.GetSelectionMark();
2362 HRESULT STDMETHODCALLTYPE
CDefView::GetFocusedItem(int *piItem
)
2364 TRACE("(%p)->(%p)\n", this, piItem
);
2366 *piItem
= m_ListView
.GetNextItem(-1, LVNI_FOCUSED
);
2371 HRESULT STDMETHODCALLTYPE
CDefView::GetItemPosition(PCUITEMID_CHILD pidl
, POINT
*ppt
)
2376 HRESULT STDMETHODCALLTYPE
CDefView::GetSpacing(POINT
*ppt
)
2378 TRACE("(%p)->(%p)\n", this, ppt
);
2386 m_ListView
.GetItemSpacing(spacing
);
2388 ppt
->x
= spacing
.cx
;
2389 ppt
->y
= spacing
.cy
;
2395 HRESULT STDMETHODCALLTYPE
CDefView::GetDefaultSpacing(POINT
*ppt
)
2400 HRESULT STDMETHODCALLTYPE
CDefView::GetAutoArrange()
2405 HRESULT STDMETHODCALLTYPE
CDefView::SelectItem(int iItem
, DWORD dwFlags
)
2409 TRACE("(%p)->(%d, %x)\n", this, iItem
, dwFlags
);
2412 lvItem
.stateMask
= LVIS_SELECTED
;
2414 if (dwFlags
& SVSI_ENSUREVISIBLE
)
2415 m_ListView
.EnsureVisible(iItem
, 0);
2418 if (dwFlags
& SVSI_DESELECTOTHERS
)
2419 m_ListView
.SetItemState(-1, 0, LVIS_SELECTED
);
2422 if (dwFlags
& SVSI_SELECT
)
2423 lvItem
.state
|= LVIS_SELECTED
;
2425 if (dwFlags
& SVSI_FOCUSED
)
2426 lvItem
.stateMask
|= LVIS_FOCUSED
;
2428 m_ListView
.SetItemState(iItem
, lvItem
.state
, lvItem
.stateMask
);
2430 if (dwFlags
& SVSI_EDIT
)
2431 m_ListView
.EditLabel(iItem
);
2436 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItems(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD dwFlags
)
2441 /**********************************************************
2442 * IShellView2 implementation
2445 HRESULT STDMETHODCALLTYPE
CDefView::GetView(SHELLVIEWID
*view_guid
, ULONG view_type
)
2447 FIXME("(%p)->(%p, %lu) stub\n", this, view_guid
, view_type
);
2451 HRESULT STDMETHODCALLTYPE
CDefView::CreateViewWindow2(LPSV2CVW2_PARAMS view_params
)
2453 return CreateViewWindow3(view_params
->psbOwner
, view_params
->psvPrev
,
2454 SV3CVW3_DEFAULT
, (FOLDERFLAGS
)view_params
->pfs
->fFlags
, (FOLDERFLAGS
)view_params
->pfs
->fFlags
,
2455 (FOLDERVIEWMODE
)view_params
->pfs
->ViewMode
, view_params
->pvid
, view_params
->prcView
, &view_params
->hwndView
);
2458 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
)
2460 OLEMENUGROUPWIDTHS omw
= { { 0, 0, 0, 0, 0, 0 } };
2464 TRACE("(%p)->(shlview=%p shlbrs=%p rec=%p hwnd=%p vmode=%x flags=%x)\n", this, psvPrevious
, psb
, prcView
, hwnd
, mode
, flags
);
2465 if (prcView
!= NULL
)
2466 TRACE("-- left=%i top=%i right=%i bottom=%i\n", prcView
->left
, prcView
->top
, prcView
->right
, prcView
->bottom
);
2468 /* Validate the Shell Browser */
2469 if (psb
== NULL
|| m_hWnd
)
2470 return E_UNEXPECTED
;
2472 if (view_flags
!= SV3CVW3_DEFAULT
)
2473 FIXME("unsupported view flags 0x%08x\n", view_flags
);
2475 /* Set up the member variables */
2476 m_pShellBrowser
= psb
;
2477 m_FolderSettings
.ViewMode
= mode
;
2478 m_FolderSettings
.fFlags
= mask
& flags
;
2482 if (IsEqualIID(*view_id
, VID_LargeIcons
))
2483 m_FolderSettings
.ViewMode
= FVM_ICON
;
2484 else if (IsEqualIID(*view_id
, VID_SmallIcons
))
2485 m_FolderSettings
.ViewMode
= FVM_SMALLICON
;
2486 else if (IsEqualIID(*view_id
, VID_List
))
2487 m_FolderSettings
.ViewMode
= FVM_LIST
;
2488 else if (IsEqualIID(*view_id
, VID_Details
))
2489 m_FolderSettings
.ViewMode
= FVM_DETAILS
;
2490 else if (IsEqualIID(*view_id
, VID_Thumbnails
))
2491 m_FolderSettings
.ViewMode
= FVM_THUMBNAIL
;
2492 else if (IsEqualIID(*view_id
, VID_Tile
))
2493 m_FolderSettings
.ViewMode
= FVM_TILE
;
2494 else if (IsEqualIID(*view_id
, VID_ThumbStrip
))
2495 m_FolderSettings
.ViewMode
= FVM_THUMBSTRIP
;
2497 FIXME("Ignoring unrecognized VID %s\n", debugstr_guid(view_id
));
2500 /* Get our parent window */
2501 m_pShellBrowser
->GetWindow(&m_hWndParent
);
2503 /* Try to get the ICommDlgBrowserInterface, adds a reference !!! */
2504 m_pCommDlgBrowser
= NULL
;
2505 if (SUCCEEDED(m_pShellBrowser
->QueryInterface(IID_PPV_ARG(ICommDlgBrowser
, &m_pCommDlgBrowser
))))
2507 TRACE("-- CommDlgBrowser\n");
2510 Create(m_hWndParent
, prcView
, NULL
, WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
| WS_TABSTOP
, 0, 0U);
2521 SetWindowPos(HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_SHOWWINDOW
);
2526 m_hMenu
= CreateMenu();
2527 m_pShellBrowser
->InsertMenusSB(m_hMenu
, &omw
);
2528 TRACE("-- after fnInsertMenusSB\n");
2536 HRESULT STDMETHODCALLTYPE
CDefView::HandleRename(LPCITEMIDLIST new_pidl
)
2538 FIXME("(%p)->(%p) stub\n", this, new_pidl
);
2542 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItem(LPCITEMIDLIST item
, UINT flags
, POINT
*point
)
2544 FIXME("(%p)->(%p, %u, %p) stub\n", this, item
, flags
, point
);
2548 /**********************************************************
2549 * IShellFolderView implementation
2551 HRESULT STDMETHODCALLTYPE
CDefView::Rearrange(LPARAM sort
)
2553 FIXME("(%p)->(%ld) stub\n", this, sort
);
2557 HRESULT STDMETHODCALLTYPE
CDefView::GetArrangeParam(LPARAM
*sort
)
2559 FIXME("(%p)->(%p) stub\n", this, sort
);
2563 HRESULT STDMETHODCALLTYPE
CDefView::ArrangeGrid()
2565 FIXME("(%p) stub\n", this);
2569 HRESULT STDMETHODCALLTYPE
CDefView::AutoArrange()
2571 FIXME("(%p) stub\n", this);
2575 HRESULT STDMETHODCALLTYPE
CDefView::AddObject(PITEMID_CHILD pidl
, UINT
*item
)
2577 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2581 HRESULT STDMETHODCALLTYPE
CDefView::GetObject(PITEMID_CHILD
*pidl
, UINT item
)
2583 TRACE("(%p)->(%p %d)\n", this, pidl
, item
);
2584 return Item(item
, pidl
);
2587 HRESULT STDMETHODCALLTYPE
CDefView::RemoveObject(PITEMID_CHILD pidl
, UINT
*item
)
2590 TRACE("(%p)->(%p %p)\n", this, pidl
, item
);
2594 *item
= LV_FindItemByPidl(ILFindLastID(pidl
));
2595 m_ListView
.DeleteItem(*item
);
2600 m_ListView
.DeleteAllItems();
2606 HRESULT STDMETHODCALLTYPE
CDefView::GetObjectCount(UINT
*count
)
2608 TRACE("(%p)->(%p)\n", this, count
);
2609 *count
= m_ListView
.GetItemCount();
2613 HRESULT STDMETHODCALLTYPE
CDefView::SetObjectCount(UINT count
, UINT flags
)
2615 FIXME("(%p)->(%d %x) stub\n", this, count
, flags
);
2619 HRESULT STDMETHODCALLTYPE
CDefView::UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
)
2621 FIXME("(%p)->(%p %p %p) stub\n", this, pidl_old
, pidl_new
, item
);
2625 HRESULT STDMETHODCALLTYPE
CDefView::RefreshObject(PITEMID_CHILD pidl
, UINT
*item
)
2627 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2631 HRESULT STDMETHODCALLTYPE
CDefView::SetRedraw(BOOL redraw
)
2633 TRACE("(%p)->(%d)\n", this, redraw
);
2634 m_ListView
.SetRedraw(redraw
);
2638 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedCount(UINT
*count
)
2640 FIXME("(%p)->(%p) stub\n", this, count
);
2644 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
)
2646 TRACE("(%p)->(%p %p)\n", this, pidl
, items
);
2648 *items
= GetSelections();
2652 *pidl
= static_cast<PCUITEMID_CHILD
*>(LocalAlloc(0, *items
* sizeof(PCUITEMID_CHILD
)));
2655 return E_OUTOFMEMORY
;
2658 /* it's documented that caller shouldn't PIDLs, only array itself */
2659 memcpy(*pidl
, m_apidl
, *items
* sizeof(PCUITEMID_CHILD
));
2665 HRESULT STDMETHODCALLTYPE
CDefView::IsDropOnSource(IDropTarget
*drop_target
)
2667 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2671 HRESULT STDMETHODCALLTYPE
CDefView::GetDragPoint(POINT
*pt
)
2673 FIXME("(%p)->(%p) stub\n", this, pt
);
2677 HRESULT STDMETHODCALLTYPE
CDefView::GetDropPoint(POINT
*pt
)
2679 FIXME("(%p)->(%p) stub\n", this, pt
);
2683 HRESULT STDMETHODCALLTYPE
CDefView::MoveIcons(IDataObject
*obj
)
2685 TRACE("(%p)->(%p)\n", this, obj
);
2689 HRESULT STDMETHODCALLTYPE
CDefView::SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
)
2691 FIXME("(%p)->(%p %p) stub\n", this, pidl
, pt
);
2695 HRESULT STDMETHODCALLTYPE
CDefView::IsBkDropTarget(IDropTarget
*drop_target
)
2697 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2701 HRESULT STDMETHODCALLTYPE
CDefView::SetClipboard(BOOL move
)
2703 FIXME("(%p)->(%d) stub\n", this, move
);
2707 HRESULT STDMETHODCALLTYPE
CDefView::SetPoints(IDataObject
*obj
)
2709 FIXME("(%p)->(%p) stub\n", this, obj
);
2713 HRESULT STDMETHODCALLTYPE
CDefView::GetItemSpacing(ITEMSPACING
*spacing
)
2715 FIXME("(%p)->(%p) stub\n", this, spacing
);
2719 HRESULT STDMETHODCALLTYPE
CDefView::SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
)
2721 FIXME("(%p)->(%p %p) stub\n", this, new_cb
, old_cb
);
2725 HRESULT STDMETHODCALLTYPE
CDefView::Select(UINT flags
)
2727 FIXME("(%p)->(%d) stub\n", this, flags
);
2731 HRESULT STDMETHODCALLTYPE
CDefView::QuerySupport(UINT
*support
)
2733 TRACE("(%p)->(%p)\n", this, support
);
2737 HRESULT STDMETHODCALLTYPE
CDefView::SetAutomationObject(IDispatch
*disp
)
2739 FIXME("(%p)->(%p) stub\n", this, disp
);
2743 /**********************************************************
2744 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2746 HRESULT WINAPI
CDefView::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD
*prgCmds
, OLECMDTEXT
*pCmdText
)
2748 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
2749 this, pguidCmdGroup
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
2752 return E_INVALIDARG
;
2754 for (UINT i
= 0; i
< cCmds
; i
++)
2756 FIXME("\tprgCmds[%d].cmdID = %d\n", i
, prgCmds
[i
].cmdID
);
2757 prgCmds
[i
].cmdf
= 0;
2760 return OLECMDERR_E_UNKNOWNGROUP
;
2763 /**********************************************************
2764 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2766 * nCmdID is the OLECMDID_* enumeration
2768 HRESULT WINAPI
CDefView::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
2770 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2771 this, debugstr_guid(pguidCmdGroup
), nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2774 return OLECMDERR_E_UNKNOWNGROUP
;
2776 if (IsEqualCLSID(*pguidCmdGroup
, m_Category
))
2778 if (nCmdID
== FCIDM_SHVIEW_AUTOARRANGE
)
2780 if (V_VT(pvaIn
) != VT_INT_PTR
)
2781 return OLECMDERR_E_NOTSUPPORTED
;
2784 params
.cbSize
= sizeof(params
);
2785 params
.rcExclude
= *(RECT
*) V_INTREF(pvaIn
);
2787 if (m_hMenuViewModes
)
2789 /* Duplicate all but the last two items of the view modes menu */
2790 HMENU hmenuViewPopup
= CreatePopupMenu();
2791 Shell_MergeMenus(hmenuViewPopup
, m_hMenuViewModes
, 0, 0, 0xFFFF, 0);
2792 DeleteMenu(hmenuViewPopup
, GetMenuItemCount(hmenuViewPopup
) - 1, MF_BYPOSITION
);
2793 DeleteMenu(hmenuViewPopup
, GetMenuItemCount(hmenuViewPopup
) - 1, MF_BYPOSITION
);
2794 CheckViewMode(hmenuViewPopup
);
2795 TrackPopupMenuEx(hmenuViewPopup
, TPM_LEFTALIGN
| TPM_TOPALIGN
, params
.rcExclude
.left
, params
.rcExclude
.bottom
, m_hWndParent
, ¶ms
);
2796 ::DestroyMenu(hmenuViewPopup
);
2799 // pvaOut is VT_I4 with value 0x403 (cmd id of the new mode maybe?)
2800 V_VT(pvaOut
) = VT_I4
;
2801 V_I4(pvaOut
) = 0x403;
2805 if (IsEqualIID(*pguidCmdGroup
, CGID_Explorer
) &&
2807 (nCmdexecopt
== 4) && pvaOut
)
2810 if (IsEqualIID(*pguidCmdGroup
, CGID_ShellDocView
) &&
2815 return OLECMDERR_E_UNKNOWNGROUP
;
2818 /**********************************************************
2819 * ISVDropTarget implementation
2822 /******************************************************************************
2823 * drag_notify_subitem [Internal]
2825 * Figure out the shellfolder object, which is currently under the mouse cursor
2826 * and notify it via the IDropTarget interface.
2829 #define SCROLLAREAWIDTH 20
2831 HRESULT
CDefView::drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2833 LVHITTESTINFO htinfo
;
2838 /* Map from global to client coordinates and query the index of the listview-item, which is
2839 * currently under the mouse cursor. */
2842 htinfo
.flags
= LVHT_ONITEM
;
2843 ::ScreenToClient(m_ListView
, &htinfo
.pt
);
2844 lResult
= m_ListView
.HitTest(&htinfo
);
2846 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2847 ::GetClientRect(m_ListView
, &clientRect
);
2848 if (htinfo
.pt
.x
== m_ptLastMousePos
.x
&& htinfo
.pt
.y
== m_ptLastMousePos
.y
&&
2849 (htinfo
.pt
.x
< SCROLLAREAWIDTH
|| htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
||
2850 htinfo
.pt
.y
< SCROLLAREAWIDTH
|| htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
))
2852 m_cScrollDelay
= (m_cScrollDelay
+ 1) % 5; /* DragOver is called every 50 ms */
2853 if (m_cScrollDelay
== 0)
2855 /* Mouse did hover another 250 ms over the scroll-area */
2856 if (htinfo
.pt
.x
< SCROLLAREAWIDTH
)
2857 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEUP
, 0);
2859 if (htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
)
2860 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEDOWN
, 0);
2862 if (htinfo
.pt
.y
< SCROLLAREAWIDTH
)
2863 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEUP
, 0);
2865 if (htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
)
2866 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEDOWN
, 0);
2871 m_cScrollDelay
= 0; /* Reset, if the cursor is not over the listview's scroll-area */
2874 m_ptLastMousePos
= htinfo
.pt
;
2876 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2877 if (m_pCurDropTarget
&& lResult
== m_iDragOverItem
)
2878 return m_pCurDropTarget
->DragOver(grfKeyState
, pt
, pdwEffect
);
2880 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2881 if (m_pCurDropTarget
)
2883 m_pCurDropTarget
->DragLeave();
2884 m_pCurDropTarget
.Release();
2887 m_iDragOverItem
= lResult
;
2890 /* We are not above one of the listview's subitems. Bind to the parent folder's
2891 * DropTarget interface. */
2892 hr
= m_pSFParent
->CreateViewObject(NULL
, IID_PPV_ARG(IDropTarget
,&m_pCurDropTarget
));
2896 /* Query the relative PIDL of the shellfolder object represented by the currently
2897 * dragged over listview-item ... */
2898 PCUITEMID_CHILD pidl
= _PidlByItem(lResult
);
2900 /* ... and bind m_pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2901 hr
= m_pSFParent
->GetUIObjectOf(m_ListView
, 1, &pidl
, IID_NULL_PPV_ARG(IDropTarget
, &m_pCurDropTarget
));
2904 /* If anything failed, m_pCurDropTarget should be NULL now, which ought to be a save state. */
2908 /* Notify the item just entered via DragEnter. */
2909 return m_pCurDropTarget
->DragEnter(m_pCurDataObject
, grfKeyState
, pt
, pdwEffect
);
2912 HRESULT WINAPI
CDefView::DragEnter(IDataObject
*pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2914 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2915 m_pCurDataObject
= pDataObject
;
2916 pDataObject
->AddRef();
2918 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2921 HRESULT WINAPI
CDefView::DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2923 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2926 HRESULT WINAPI
CDefView::DragLeave()
2928 if (m_pCurDropTarget
)
2930 m_pCurDropTarget
->DragLeave();
2931 m_pCurDropTarget
.Release();
2934 if (m_pCurDataObject
!= NULL
)
2936 m_pCurDataObject
.Release();
2939 m_iDragOverItem
= 0;
2944 HRESULT WINAPI
CDefView::Drop(IDataObject
* pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2946 ERR("GetKeyState(VK_LBUTTON): %d\n", GetKeyState(VK_LBUTTON
));
2948 if ((m_iDragOverItem
== -1) &&
2949 (*pdwEffect
& DROPEFFECT_MOVE
) &&
2950 (GetKeyState(VK_LBUTTON
) != 0) &&
2951 (m_pSourceDataObject
.p
) &&
2952 (SHIsSameObject(pDataObject
, m_pSourceDataObject
)))
2954 ERR("Should implement moving items here!\n");
2956 if (m_pCurDropTarget
)
2958 m_pCurDropTarget
->DragLeave();
2959 m_pCurDropTarget
.Release();
2962 else if (m_pCurDropTarget
)
2964 m_pCurDropTarget
->Drop(pDataObject
, grfKeyState
, pt
, pdwEffect
);
2965 m_pCurDropTarget
.Release();
2968 m_pCurDataObject
.Release();
2969 m_iDragOverItem
= 0;
2973 /**********************************************************
2974 * ISVDropSource implementation
2977 HRESULT WINAPI
CDefView::QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
)
2979 TRACE("(%p)\n", this);
2982 return DRAGDROP_S_CANCEL
;
2983 else if (!(grfKeyState
& MK_LBUTTON
) && !(grfKeyState
& MK_RBUTTON
))
2984 return DRAGDROP_S_DROP
;
2989 HRESULT WINAPI
CDefView::GiveFeedback(DWORD dwEffect
)
2991 TRACE("(%p)\n", this);
2993 return DRAGDROP_S_USEDEFAULTCURSORS
;
2996 /**********************************************************
2997 * ISVViewObject implementation
3000 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
)
3002 FIXME("Stub: this=%p\n", this);
3007 HRESULT WINAPI
CDefView::GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
, HDC hicTargetDevice
, LOGPALETTE
**ppColorSet
)
3009 FIXME("Stub: this=%p\n", this);
3014 HRESULT WINAPI
CDefView::Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
)
3016 FIXME("Stub: this=%p\n", this);
3021 HRESULT WINAPI
CDefView::Unfreeze(DWORD dwFreeze
)
3023 FIXME("Stub: this=%p\n", this);
3028 HRESULT WINAPI
CDefView::SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
)
3030 FIXME("partial stub: %p %08x %08x %p\n", this, aspects
, advf
, pAdvSink
);
3032 /* FIXME: we set the AdviseSink, but never use it to send any advice */
3033 m_pAdvSink
= pAdvSink
;
3034 m_dwAspects
= aspects
;
3040 HRESULT WINAPI
CDefView::GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
)
3042 TRACE("this=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n", this, pAspects
, pAdvf
, ppAdvSink
);
3046 *ppAdvSink
= m_pAdvSink
;
3047 m_pAdvSink
.p
->AddRef();
3051 *pAspects
= m_dwAspects
;
3059 HRESULT STDMETHODCALLTYPE
CDefView::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
3061 if (IsEqualIID(guidService
, SID_IShellBrowser
))
3062 return m_pShellBrowser
->QueryInterface(riid
, ppvObject
);
3063 else if(IsEqualIID(guidService
, SID_IFolderView
))
3064 return QueryInterface(riid
, ppvObject
);
3066 return E_NOINTERFACE
;
3069 HRESULT
CDefView::_MergeToolbar()
3071 CComPtr
<IExplorerToolbar
> ptb
;
3074 hr
= IUnknown_QueryService(m_pShellBrowser
, IID_IExplorerToolbar
, IID_PPV_ARG(IExplorerToolbar
, &ptb
));
3078 m_Category
= CGID_DefViewFrame
;
3080 hr
= ptb
->SetCommandTarget(static_cast<IOleCommandTarget
*>(this), &m_Category
, 0);
3088 hr
= ptb
->AddButtons(&m_Category
, buttonsCount
, buttons
);
3095 /**********************************************************
3096 * IShellView_Constructor
3098 HRESULT WINAPI
IShellView_Constructor(IShellFolder
*pFolder
, IShellView
**newView
)
3100 return ShellObjectCreatorInit
<CDefView
>(pFolder
, IID_IShellView
, newView
);
3103 HRESULT WINAPI
CDefView_Constructor(IShellFolder
*pFolder
, REFIID riid
, LPVOID
* ppvOut
)
3105 return ShellObjectCreatorInit
<CDefView
>(pFolder
, riid
, ppvOut
);