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 LPNMLISTVIEW params
= (LPNMLISTVIEW
)lParam
;
1745 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(m_cidl
, m_apidl
, &dwAttributes
)))
1747 if (dwAttributes
& SFGAO_CANLINK
)
1749 dwEffect
|= DROPEFFECT_LINK
;
1753 CComPtr
<IAsyncOperation
> piaso
;
1754 if (SUCCEEDED(pda
->QueryInterface(IID_PPV_ARG(IAsyncOperation
, &piaso
))))
1756 piaso
->SetAsyncMode(TRUE
);
1761 m_pSourceDataObject
= pda
;
1762 m_ptFirstMousePos
= params
->ptAction
;
1763 ClientToScreen(&m_ptFirstMousePos
);
1765 HIMAGELIST big_icons
, small_icons
;
1766 Shell_GetImageLists(&big_icons
, &small_icons
);
1767 PCUITEMID_CHILD pidl
= _PidlByItem(params
->iItem
);
1768 int iIcon
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
1770 m_ListView
.GetItemPosition(params
->iItem
, &ptItem
);
1772 ImageList_BeginDrag(big_icons
, iIcon
, params
->ptAction
.x
- ptItem
.x
, params
->ptAction
.y
- ptItem
.y
);
1774 DoDragDrop(pda
, this, dwEffect
, &dwEffect2
);
1776 m_pSourceDataObject
.Release();
1781 case LVN_BEGINLABELEDITW
:
1783 DWORD dwAttr
= SFGAO_CANRENAME
;
1784 pidl
= _PidlByItem(lpdi
->item
);
1786 TRACE("-- LVN_BEGINLABELEDITW %p\n", this);
1788 m_pSFParent
->GetAttributesOf(1, &pidl
, &dwAttr
);
1789 if (SFGAO_CANRENAME
& dwAttr
)
1797 case LVN_ENDLABELEDITW
:
1799 TRACE("-- LVN_ENDLABELEDITW %p\n", this);
1801 m_isEditing
= FALSE
;
1803 if (lpdi
->item
.pszText
)
1808 pidl
= _PidlByItem(lpdi
->item
);
1809 PITEMID_CHILD pidlNew
;
1810 hr
= m_pSFParent
->SetNameOf(0, pidl
, lpdi
->item
.pszText
, SHGDN_INFOLDER
, &pidlNew
);
1812 if (SUCCEEDED(hr
) && pidlNew
)
1814 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
1815 lvItem
.iItem
= lpdi
->item
.iItem
;
1816 lvItem
.iSubItem
= 0;
1817 lvItem
.lParam
= reinterpret_cast<LPARAM
>(pidlNew
);
1818 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
1819 m_ListView
.SetItem(&lvItem
);
1820 m_ListView
.Update(lpdi
->item
.iItem
);
1829 TRACE("-- %p WM_COMMAND %x unhandled\n", this, lpnmh
->code
);
1837 * This is just a quick hack to make the desktop work correctly.
1838 * ITranslateShellChangeNotify's IsChildID is undocumented, but most likely the way that
1839 * a folder should know if it should update upon a change notification.
1840 * It is exported by merged folders at a minimum.
1842 static BOOL
ILIsParentOrSpecialParent(PCIDLIST_ABSOLUTE pidl1
, PCIDLIST_ABSOLUTE pidl2
)
1844 if (!pidl1
|| !pidl2
)
1846 if (ILIsParent(pidl1
, pidl2
, TRUE
))
1849 if (_ILIsDesktop(pidl1
))
1851 PIDLIST_ABSOLUTE deskpidl
;
1852 SHGetFolderLocation(NULL
, CSIDL_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
1853 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
1859 SHGetFolderLocation(NULL
, CSIDL_COMMON_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
1860 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
1870 /**********************************************************
1871 * ShellView_OnChange()
1873 LRESULT
CDefView::OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1875 PCIDLIST_ABSOLUTE
*Pidls
= reinterpret_cast<PCIDLIST_ABSOLUTE
*>(wParam
);
1876 BOOL bParent0
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[0]);
1877 BOOL bParent1
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[1]);
1879 TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls
[0], Pidls
[1], lParam
);
1881 switch (lParam
&~ SHCNE_INTERRUPT
)
1887 if (LV_FindItemByPidl(ILFindLastID(Pidls
[0])) == -1)
1889 LV_AddItem(ILFindLastID(Pidls
[0]));
1893 LV_ProdItem(ILFindLastID(Pidls
[0]));
1901 LV_DeleteItem(ILFindLastID(Pidls
[0]));
1904 case SHCNE_RENAMEFOLDER
:
1905 case SHCNE_RENAMEITEM
:
1906 if (bParent0
&& bParent1
)
1907 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[1]));
1909 LV_DeleteItem(ILFindLastID(Pidls
[0]));
1911 LV_AddItem(ILFindLastID(Pidls
[1]));
1914 case SHCNE_UPDATEITEM
:
1916 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[0]));
1919 case SHCNE_UPDATEDIR
:
1926 /**********************************************************
1927 * CDefView::OnCustomItem
1929 LRESULT
CDefView::OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1934 ERR("no menu!!!\n");
1939 HRESULT hres
= SHForwardContextMenuMsg(m_pCM
, uMsg
, wParam
, lParam
, &result
, TRUE
);
1940 if (SUCCEEDED(hres
))
1946 LRESULT
CDefView::OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1948 /* Wallpaper setting affects drop shadows effect */
1949 if (wParam
== SPI_SETDESKWALLPAPER
|| wParam
== 0)
1955 /**********************************************************
1956 * CDefView::OnInitMenuPopup
1958 LRESULT
CDefView::OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1960 HMENU hmenu
= (HMENU
) wParam
;
1961 int nPos
= LOWORD(lParam
);
1964 OnCustomItem(uMsg
, wParam
, lParam
, bHandled
);
1966 HMENU hViewMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_VIEW
);
1968 /* Lets try to find out what the hell wParam is */
1969 if (hmenu
== GetSubMenu(m_hMenu
, nPos
))
1970 menuItemId
= ReallyGetMenuItemID(m_hMenu
, nPos
);
1971 else if (hViewMenu
&& hmenu
== GetSubMenu(hViewMenu
, nPos
))
1972 menuItemId
= ReallyGetMenuItemID(hViewMenu
, nPos
);
1973 else if (m_hContextMenu
&& hmenu
== GetSubMenu(m_hContextMenu
, nPos
))
1974 menuItemId
= ReallyGetMenuItemID(m_hContextMenu
, nPos
);
1980 case FCIDM_MENU_FILE
:
1983 case FCIDM_MENU_VIEW
:
1984 case FCIDM_SHVIEW_VIEW
:
1985 CheckViewMode(hmenu
);
1987 case FCIDM_SHVIEW_ARRANGE
:
1988 FillArrangeAsMenu(hmenu
);
1995 /**********************************************************
1998 * The INTERFACE of the IShellView object
2001 **********************************************************
2004 /**********************************************************
2005 * ShellView_GetWindow
2007 HRESULT WINAPI
CDefView::GetWindow(HWND
*phWnd
)
2009 TRACE("(%p)\n", this);
2016 HRESULT WINAPI
CDefView::ContextSensitiveHelp(BOOL fEnterMode
)
2018 FIXME("(%p) stub\n", this);
2023 /**********************************************************
2024 * IShellView_TranslateAccelerator
2027 * use the accel functions
2029 HRESULT WINAPI
CDefView::TranslateAccelerator(LPMSG lpmsg
)
2034 if (lpmsg
->message
>= WM_KEYFIRST
&& lpmsg
->message
<= WM_KEYLAST
)
2036 if (::TranslateAcceleratorW(m_hWnd
, m_hAccel
, lpmsg
) != 0)
2039 TRACE("-- key=0x04%lx\n", lpmsg
->wParam
) ;
2042 return m_pShellBrowser
->TranslateAcceleratorSB(lpmsg
, 0);
2045 HRESULT WINAPI
CDefView::EnableModeless(BOOL fEnable
)
2047 FIXME("(%p) stub\n", this);
2052 HRESULT WINAPI
CDefView::UIActivate(UINT uState
)
2054 // CHAR szName[MAX_PATH];
2056 int nPartArray
[1] = { -1};
2058 TRACE("(%p)->(state=%x) stub\n", this, uState
);
2060 /* don't do anything if the state isn't really changing */
2061 if (m_uState
== uState
)
2066 /* OnActivate handles the menu merging and internal state */
2069 /* only do This if we are active */
2070 if (uState
!= SVUIA_DEACTIVATE
)
2074 GetFolderPath is not a method of IShellFolder
2075 IShellFolder_GetFolderPath( m_pSFParent, szName, sizeof(szName) );
2077 /* set the number of parts */
2078 m_pShellBrowser
->SendControlMsg(FCW_STATUS
, SB_SETPARTS
, 1, (LPARAM
)nPartArray
, &lResult
);
2080 /* set the text for the parts */
2082 m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXTA, 0, (LPARAM)szName, &lResult);
2089 HRESULT WINAPI
CDefView::Refresh()
2091 TRACE("(%p)\n", this);
2093 m_ListView
.DeleteAllItems();
2099 HRESULT WINAPI
CDefView::CreateViewWindow(IShellView
*lpPrevView
, LPCFOLDERSETTINGS lpfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
)
2101 return CreateViewWindow3(psb
, lpPrevView
, SV3CVW3_DEFAULT
,
2102 (FOLDERFLAGS
)lpfs
->fFlags
, (FOLDERFLAGS
)lpfs
->fFlags
, (FOLDERVIEWMODE
)lpfs
->ViewMode
, NULL
, prcView
, phWnd
);
2105 HRESULT WINAPI
CDefView::DestroyViewWindow()
2107 TRACE("(%p)\n", this);
2109 /* Make absolutely sure all our UI is cleaned up */
2110 UIActivate(SVUIA_DEACTIVATE
);
2114 // "Accelerator tables loaded from resources are freed automatically when the application terminates." -- MSDN
2118 if (m_hMenuViewModes
)
2120 DestroyMenu(m_hMenuViewModes
);
2121 m_hMenuViewModes
= NULL
;
2126 DestroyMenu(m_hMenu
);
2132 m_ListView
.DestroyWindow();
2140 m_pShellBrowser
.Release();
2141 m_pCommDlgBrowser
.Release();
2146 HRESULT WINAPI
CDefView::GetCurrentInfo(LPFOLDERSETTINGS lpfs
)
2148 TRACE("(%p)->(%p) vmode=%x flags=%x\n", this, lpfs
,
2149 m_FolderSettings
.ViewMode
, m_FolderSettings
.fFlags
);
2152 return E_INVALIDARG
;
2154 *lpfs
= m_FolderSettings
;
2158 HRESULT WINAPI
CDefView::AddPropertySheetPages(DWORD dwReserved
, LPFNADDPROPSHEETPAGE lpfn
, LPARAM lparam
)
2160 FIXME("(%p) stub\n", this);
2165 HRESULT WINAPI
CDefView::SaveViewState()
2167 FIXME("(%p) stub\n", this);
2172 HRESULT WINAPI
CDefView::SelectItem(PCUITEMID_CHILD pidl
, UINT uFlags
)
2176 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n", this, pidl
, uFlags
);
2178 i
= LV_FindItemByPidl(pidl
);
2182 if(uFlags
& SVSI_ENSUREVISIBLE
)
2183 m_ListView
.EnsureVisible(i
, FALSE
);
2185 LVITEMW lvItem
= {0};
2186 lvItem
.mask
= LVIF_STATE
;
2187 lvItem
.stateMask
= LVIS_SELECTED
| LVIS_FOCUSED
;
2189 while (m_ListView
.GetItem(&lvItem
))
2191 if (lvItem
.iItem
== i
)
2193 if (uFlags
& SVSI_SELECT
)
2194 lvItem
.state
|= LVIS_SELECTED
;
2196 lvItem
.state
&= ~LVIS_SELECTED
;
2198 if (uFlags
& SVSI_FOCUSED
)
2199 lvItem
.state
&= ~LVIS_FOCUSED
;
2203 if (uFlags
& SVSI_DESELECTOTHERS
)
2204 lvItem
.state
&= ~LVIS_SELECTED
;
2207 m_ListView
.SetItem(&lvItem
);
2211 if((uFlags
& SVSI_EDIT
) == SVSI_EDIT
)
2212 m_ListView
.EditLabel(i
);
2217 HRESULT WINAPI
CDefView::GetItemObject(UINT uItem
, REFIID riid
, LPVOID
*ppvOut
)
2219 HRESULT hr
= E_NOINTERFACE
;
2221 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n", this, uItem
, debugstr_guid(&riid
), ppvOut
);
2227 case SVGIO_BACKGROUND
:
2228 if (IsEqualIID(riid
, IID_IContextMenu
))
2233 hr
= CDefViewBckgrndMenu_CreateInstance(m_pSF2Parent
, riid
, ppvOut
);
2234 if (FAILED_UNEXPECTEDLY(hr
))
2238 else if (IsEqualIID(riid
, IID_IDispatch
))
2240 if (m_pShellFolderViewDual
== NULL
)
2242 hr
= CDefViewDual_Constructor(riid
, (LPVOID
*)&m_pShellFolderViewDual
);
2243 if (FAILED_UNEXPECTEDLY(hr
))
2246 hr
= m_pShellFolderViewDual
->QueryInterface(riid
, ppvOut
);
2250 case SVGIO_SELECTION
:
2252 hr
= m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, riid
, 0, ppvOut
);
2253 if (FAILED_UNEXPECTEDLY(hr
))
2258 TRACE("-- (%p)->(interface=%p)\n", this, *ppvOut
);
2263 HRESULT STDMETHODCALLTYPE
CDefView::GetCurrentViewMode(UINT
*pViewMode
)
2265 TRACE("(%p)->(%p), stub\n", this, pViewMode
);
2268 return E_INVALIDARG
;
2270 *pViewMode
= m_FolderSettings
.ViewMode
;
2274 HRESULT STDMETHODCALLTYPE
CDefView::SetCurrentViewMode(UINT ViewMode
)
2277 TRACE("(%p)->(%u), stub\n", this, ViewMode
);
2279 /* It's not redundant to check FVM_AUTO because it's a (UINT)-1 */
2280 if (((INT
)ViewMode
< FVM_FIRST
|| (INT
)ViewMode
> FVM_LAST
) && ((INT
)ViewMode
!= FVM_AUTO
))
2281 return E_INVALIDARG
;
2283 /* Windows before Vista uses LVM_SETVIEW and possibly
2284 LVM_SETEXTENDEDLISTVIEWSTYLE to set the style of the listview,
2285 while later versions seem to accomplish this through other
2293 dwStyle
= LVS_REPORT
;
2296 dwStyle
= LVS_SMALLICON
;
2303 FIXME("ViewMode %d not implemented\n", ViewMode
);
2309 SetStyle(dwStyle
, LVS_TYPEMASK
);
2311 /* This will not necessarily be the actual mode set above.
2312 This mimics the behavior of Windows XP. */
2313 m_FolderSettings
.ViewMode
= ViewMode
;
2318 HRESULT STDMETHODCALLTYPE
CDefView::GetFolder(REFIID riid
, void **ppv
)
2320 if (m_pSFParent
== NULL
)
2323 return m_pSFParent
->QueryInterface(riid
, ppv
);
2326 HRESULT STDMETHODCALLTYPE
CDefView::Item(int iItemIndex
, PITEMID_CHILD
*ppidl
)
2328 PCUITEMID_CHILD pidl
= _PidlByItem(iItemIndex
);
2331 *ppidl
= ILClone(pidl
);
2336 return E_INVALIDARG
;
2339 HRESULT STDMETHODCALLTYPE
CDefView::ItemCount(UINT uFlags
, int *pcItems
)
2341 TRACE("(%p)->(%u %p)\n", this, uFlags
, pcItems
);
2343 if (uFlags
!= SVGIO_ALLVIEW
)
2344 FIXME("some flags unsupported, %x\n", uFlags
& ~SVGIO_ALLVIEW
);
2346 *pcItems
= m_ListView
.GetItemCount();
2351 HRESULT STDMETHODCALLTYPE
CDefView::Items(UINT uFlags
, REFIID riid
, void **ppv
)
2356 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectionMarkedItem(int *piItem
)
2358 TRACE("(%p)->(%p)\n", this, piItem
);
2360 *piItem
= m_ListView
.GetSelectionMark();
2365 HRESULT STDMETHODCALLTYPE
CDefView::GetFocusedItem(int *piItem
)
2367 TRACE("(%p)->(%p)\n", this, piItem
);
2369 *piItem
= m_ListView
.GetNextItem(-1, LVNI_FOCUSED
);
2374 HRESULT STDMETHODCALLTYPE
CDefView::GetItemPosition(PCUITEMID_CHILD pidl
, POINT
*ppt
)
2379 HRESULT STDMETHODCALLTYPE
CDefView::GetSpacing(POINT
*ppt
)
2381 TRACE("(%p)->(%p)\n", this, ppt
);
2389 m_ListView
.GetItemSpacing(spacing
);
2391 ppt
->x
= spacing
.cx
;
2392 ppt
->y
= spacing
.cy
;
2398 HRESULT STDMETHODCALLTYPE
CDefView::GetDefaultSpacing(POINT
*ppt
)
2403 HRESULT STDMETHODCALLTYPE
CDefView::GetAutoArrange()
2408 HRESULT STDMETHODCALLTYPE
CDefView::SelectItem(int iItem
, DWORD dwFlags
)
2412 TRACE("(%p)->(%d, %x)\n", this, iItem
, dwFlags
);
2415 lvItem
.stateMask
= LVIS_SELECTED
;
2417 if (dwFlags
& SVSI_ENSUREVISIBLE
)
2418 m_ListView
.EnsureVisible(iItem
, 0);
2421 if (dwFlags
& SVSI_DESELECTOTHERS
)
2422 m_ListView
.SetItemState(-1, 0, LVIS_SELECTED
);
2425 if (dwFlags
& SVSI_SELECT
)
2426 lvItem
.state
|= LVIS_SELECTED
;
2428 if (dwFlags
& SVSI_FOCUSED
)
2429 lvItem
.stateMask
|= LVIS_FOCUSED
;
2431 m_ListView
.SetItemState(iItem
, lvItem
.state
, lvItem
.stateMask
);
2433 if ((dwFlags
& SVSI_EDIT
) == SVSI_EDIT
)
2434 m_ListView
.EditLabel(iItem
);
2439 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItems(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD dwFlags
)
2444 /**********************************************************
2445 * IShellView2 implementation
2448 HRESULT STDMETHODCALLTYPE
CDefView::GetView(SHELLVIEWID
*view_guid
, ULONG view_type
)
2450 FIXME("(%p)->(%p, %lu) stub\n", this, view_guid
, view_type
);
2454 HRESULT STDMETHODCALLTYPE
CDefView::CreateViewWindow2(LPSV2CVW2_PARAMS view_params
)
2456 return CreateViewWindow3(view_params
->psbOwner
, view_params
->psvPrev
,
2457 SV3CVW3_DEFAULT
, (FOLDERFLAGS
)view_params
->pfs
->fFlags
, (FOLDERFLAGS
)view_params
->pfs
->fFlags
,
2458 (FOLDERVIEWMODE
)view_params
->pfs
->ViewMode
, view_params
->pvid
, view_params
->prcView
, &view_params
->hwndView
);
2461 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
)
2463 OLEMENUGROUPWIDTHS omw
= { { 0, 0, 0, 0, 0, 0 } };
2467 TRACE("(%p)->(shlview=%p shlbrs=%p rec=%p hwnd=%p vmode=%x flags=%x)\n", this, psvPrevious
, psb
, prcView
, hwnd
, mode
, flags
);
2468 if (prcView
!= NULL
)
2469 TRACE("-- left=%i top=%i right=%i bottom=%i\n", prcView
->left
, prcView
->top
, prcView
->right
, prcView
->bottom
);
2471 /* Validate the Shell Browser */
2472 if (psb
== NULL
|| m_hWnd
)
2473 return E_UNEXPECTED
;
2475 if (view_flags
!= SV3CVW3_DEFAULT
)
2476 FIXME("unsupported view flags 0x%08x\n", view_flags
);
2478 /* Set up the member variables */
2479 m_pShellBrowser
= psb
;
2480 m_FolderSettings
.ViewMode
= mode
;
2481 m_FolderSettings
.fFlags
= mask
& flags
;
2485 if (IsEqualIID(*view_id
, VID_LargeIcons
))
2486 m_FolderSettings
.ViewMode
= FVM_ICON
;
2487 else if (IsEqualIID(*view_id
, VID_SmallIcons
))
2488 m_FolderSettings
.ViewMode
= FVM_SMALLICON
;
2489 else if (IsEqualIID(*view_id
, VID_List
))
2490 m_FolderSettings
.ViewMode
= FVM_LIST
;
2491 else if (IsEqualIID(*view_id
, VID_Details
))
2492 m_FolderSettings
.ViewMode
= FVM_DETAILS
;
2493 else if (IsEqualIID(*view_id
, VID_Thumbnails
))
2494 m_FolderSettings
.ViewMode
= FVM_THUMBNAIL
;
2495 else if (IsEqualIID(*view_id
, VID_Tile
))
2496 m_FolderSettings
.ViewMode
= FVM_TILE
;
2497 else if (IsEqualIID(*view_id
, VID_ThumbStrip
))
2498 m_FolderSettings
.ViewMode
= FVM_THUMBSTRIP
;
2500 FIXME("Ignoring unrecognized VID %s\n", debugstr_guid(view_id
));
2503 /* Get our parent window */
2504 m_pShellBrowser
->GetWindow(&m_hWndParent
);
2506 /* Try to get the ICommDlgBrowserInterface, adds a reference !!! */
2507 m_pCommDlgBrowser
= NULL
;
2508 if (SUCCEEDED(m_pShellBrowser
->QueryInterface(IID_PPV_ARG(ICommDlgBrowser
, &m_pCommDlgBrowser
))))
2510 TRACE("-- CommDlgBrowser\n");
2513 Create(m_hWndParent
, prcView
, NULL
, WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
| WS_TABSTOP
, 0, 0U);
2524 SetWindowPos(HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_SHOWWINDOW
);
2529 m_hMenu
= CreateMenu();
2530 m_pShellBrowser
->InsertMenusSB(m_hMenu
, &omw
);
2531 TRACE("-- after fnInsertMenusSB\n");
2539 HRESULT STDMETHODCALLTYPE
CDefView::HandleRename(LPCITEMIDLIST new_pidl
)
2541 FIXME("(%p)->(%p) stub\n", this, new_pidl
);
2545 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItem(LPCITEMIDLIST item
, UINT flags
, POINT
*point
)
2547 FIXME("(%p)->(%p, %u, %p) stub\n", this, item
, flags
, point
);
2551 /**********************************************************
2552 * IShellFolderView implementation
2554 HRESULT STDMETHODCALLTYPE
CDefView::Rearrange(LPARAM sort
)
2556 FIXME("(%p)->(%ld) stub\n", this, sort
);
2560 HRESULT STDMETHODCALLTYPE
CDefView::GetArrangeParam(LPARAM
*sort
)
2562 FIXME("(%p)->(%p) stub\n", this, sort
);
2566 HRESULT STDMETHODCALLTYPE
CDefView::ArrangeGrid()
2568 FIXME("(%p) stub\n", this);
2572 HRESULT STDMETHODCALLTYPE
CDefView::AutoArrange()
2574 FIXME("(%p) stub\n", this);
2578 HRESULT STDMETHODCALLTYPE
CDefView::AddObject(PITEMID_CHILD pidl
, UINT
*item
)
2580 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2584 HRESULT STDMETHODCALLTYPE
CDefView::GetObject(PITEMID_CHILD
*pidl
, UINT item
)
2586 TRACE("(%p)->(%p %d)\n", this, pidl
, item
);
2587 return Item(item
, pidl
);
2590 HRESULT STDMETHODCALLTYPE
CDefView::RemoveObject(PITEMID_CHILD pidl
, UINT
*item
)
2593 TRACE("(%p)->(%p %p)\n", this, pidl
, item
);
2597 *item
= LV_FindItemByPidl(ILFindLastID(pidl
));
2598 m_ListView
.DeleteItem(*item
);
2603 m_ListView
.DeleteAllItems();
2609 HRESULT STDMETHODCALLTYPE
CDefView::GetObjectCount(UINT
*count
)
2611 TRACE("(%p)->(%p)\n", this, count
);
2612 *count
= m_ListView
.GetItemCount();
2616 HRESULT STDMETHODCALLTYPE
CDefView::SetObjectCount(UINT count
, UINT flags
)
2618 FIXME("(%p)->(%d %x) stub\n", this, count
, flags
);
2622 HRESULT STDMETHODCALLTYPE
CDefView::UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
)
2624 FIXME("(%p)->(%p %p %p) stub\n", this, pidl_old
, pidl_new
, item
);
2628 HRESULT STDMETHODCALLTYPE
CDefView::RefreshObject(PITEMID_CHILD pidl
, UINT
*item
)
2630 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2634 HRESULT STDMETHODCALLTYPE
CDefView::SetRedraw(BOOL redraw
)
2636 TRACE("(%p)->(%d)\n", this, redraw
);
2637 m_ListView
.SetRedraw(redraw
);
2641 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedCount(UINT
*count
)
2643 FIXME("(%p)->(%p) stub\n", this, count
);
2647 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
)
2649 TRACE("(%p)->(%p %p)\n", this, pidl
, items
);
2651 *items
= GetSelections();
2655 *pidl
= static_cast<PCUITEMID_CHILD
*>(LocalAlloc(0, *items
* sizeof(PCUITEMID_CHILD
)));
2658 return E_OUTOFMEMORY
;
2661 /* it's documented that caller shouldn't PIDLs, only array itself */
2662 memcpy(*pidl
, m_apidl
, *items
* sizeof(PCUITEMID_CHILD
));
2668 HRESULT STDMETHODCALLTYPE
CDefView::IsDropOnSource(IDropTarget
*drop_target
)
2670 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2674 HRESULT STDMETHODCALLTYPE
CDefView::GetDragPoint(POINT
*pt
)
2676 FIXME("(%p)->(%p) stub\n", this, pt
);
2680 HRESULT STDMETHODCALLTYPE
CDefView::GetDropPoint(POINT
*pt
)
2682 FIXME("(%p)->(%p) stub\n", this, pt
);
2686 HRESULT STDMETHODCALLTYPE
CDefView::MoveIcons(IDataObject
*obj
)
2688 TRACE("(%p)->(%p)\n", this, obj
);
2692 HRESULT STDMETHODCALLTYPE
CDefView::SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
)
2694 FIXME("(%p)->(%p %p) stub\n", this, pidl
, pt
);
2698 HRESULT STDMETHODCALLTYPE
CDefView::IsBkDropTarget(IDropTarget
*drop_target
)
2700 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2704 HRESULT STDMETHODCALLTYPE
CDefView::SetClipboard(BOOL move
)
2706 FIXME("(%p)->(%d) stub\n", this, move
);
2710 HRESULT STDMETHODCALLTYPE
CDefView::SetPoints(IDataObject
*obj
)
2712 FIXME("(%p)->(%p) stub\n", this, obj
);
2716 HRESULT STDMETHODCALLTYPE
CDefView::GetItemSpacing(ITEMSPACING
*spacing
)
2718 FIXME("(%p)->(%p) stub\n", this, spacing
);
2722 HRESULT STDMETHODCALLTYPE
CDefView::SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
)
2724 FIXME("(%p)->(%p %p) stub\n", this, new_cb
, old_cb
);
2728 HRESULT STDMETHODCALLTYPE
CDefView::Select(UINT flags
)
2730 FIXME("(%p)->(%d) stub\n", this, flags
);
2734 HRESULT STDMETHODCALLTYPE
CDefView::QuerySupport(UINT
*support
)
2736 TRACE("(%p)->(%p)\n", this, support
);
2740 HRESULT STDMETHODCALLTYPE
CDefView::SetAutomationObject(IDispatch
*disp
)
2742 FIXME("(%p)->(%p) stub\n", this, disp
);
2746 /**********************************************************
2747 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2749 HRESULT WINAPI
CDefView::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD
*prgCmds
, OLECMDTEXT
*pCmdText
)
2751 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
2752 this, pguidCmdGroup
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
2755 return E_INVALIDARG
;
2757 for (UINT i
= 0; i
< cCmds
; i
++)
2759 FIXME("\tprgCmds[%d].cmdID = %d\n", i
, prgCmds
[i
].cmdID
);
2760 prgCmds
[i
].cmdf
= 0;
2763 return OLECMDERR_E_UNKNOWNGROUP
;
2766 /**********************************************************
2767 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2769 * nCmdID is the OLECMDID_* enumeration
2771 HRESULT WINAPI
CDefView::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
2773 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2774 this, debugstr_guid(pguidCmdGroup
), nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2777 return OLECMDERR_E_UNKNOWNGROUP
;
2779 if (IsEqualCLSID(*pguidCmdGroup
, m_Category
))
2781 if (nCmdID
== FCIDM_SHVIEW_AUTOARRANGE
)
2783 if (V_VT(pvaIn
) != VT_INT_PTR
)
2784 return OLECMDERR_E_NOTSUPPORTED
;
2787 params
.cbSize
= sizeof(params
);
2788 params
.rcExclude
= *(RECT
*) V_INTREF(pvaIn
);
2790 if (m_hMenuViewModes
)
2792 /* Duplicate all but the last two items of the view modes menu */
2793 HMENU hmenuViewPopup
= CreatePopupMenu();
2794 Shell_MergeMenus(hmenuViewPopup
, m_hMenuViewModes
, 0, 0, 0xFFFF, 0);
2795 DeleteMenu(hmenuViewPopup
, GetMenuItemCount(hmenuViewPopup
) - 1, MF_BYPOSITION
);
2796 DeleteMenu(hmenuViewPopup
, GetMenuItemCount(hmenuViewPopup
) - 1, MF_BYPOSITION
);
2797 CheckViewMode(hmenuViewPopup
);
2798 TrackPopupMenuEx(hmenuViewPopup
, TPM_LEFTALIGN
| TPM_TOPALIGN
, params
.rcExclude
.left
, params
.rcExclude
.bottom
, m_hWndParent
, ¶ms
);
2799 ::DestroyMenu(hmenuViewPopup
);
2802 // pvaOut is VT_I4 with value 0x403 (cmd id of the new mode maybe?)
2803 V_VT(pvaOut
) = VT_I4
;
2804 V_I4(pvaOut
) = 0x403;
2808 if (IsEqualIID(*pguidCmdGroup
, CGID_Explorer
) &&
2810 (nCmdexecopt
== 4) && pvaOut
)
2813 if (IsEqualIID(*pguidCmdGroup
, CGID_ShellDocView
) &&
2818 return OLECMDERR_E_UNKNOWNGROUP
;
2821 /**********************************************************
2822 * ISVDropTarget implementation
2825 /******************************************************************************
2826 * drag_notify_subitem [Internal]
2828 * Figure out the shellfolder object, which is currently under the mouse cursor
2829 * and notify it via the IDropTarget interface.
2832 #define SCROLLAREAWIDTH 20
2834 HRESULT
CDefView::drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2840 /* Map from global to client coordinates and query the index of the listview-item, which is
2841 * currently under the mouse cursor. */
2842 LVHITTESTINFO htinfo
= {{pt
.x
, pt
.y
}, LVHT_ONITEM
};
2843 ScreenToClient(&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 /* We need to check if we drag the selection over itself */
2877 if (lResult
!= -1 && m_pSourceDataObject
.p
!= NULL
)
2879 PCUITEMID_CHILD pidl
= _PidlByItem(lResult
);
2881 for (UINT i
= 0; i
< m_cidl
; i
++)
2883 if (pidl
== m_apidl
[i
])
2885 /* The item that is being draged is hovering itself. */
2892 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2893 if (m_pCurDropTarget
&& lResult
== m_iDragOverItem
)
2894 return m_pCurDropTarget
->DragOver(grfKeyState
, pt
, pdwEffect
);
2896 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2897 if (m_pCurDropTarget
)
2899 PCUITEMID_CHILD pidl
= _PidlByItem(m_iDragOverItem
);
2901 SelectItem(pidl
, 0);
2903 m_pCurDropTarget
->DragLeave();
2904 m_pCurDropTarget
.Release();
2907 m_iDragOverItem
= lResult
;
2911 /* We are not above one of the listview's subitems. Bind to the parent folder's
2912 * DropTarget interface. */
2913 hr
= m_pSFParent
->CreateViewObject(NULL
, IID_PPV_ARG(IDropTarget
,&m_pCurDropTarget
));
2917 /* Query the relative PIDL of the shellfolder object represented by the currently
2918 * dragged over listview-item ... */
2919 PCUITEMID_CHILD pidl
= _PidlByItem(lResult
);
2921 /* ... and bind m_pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2922 hr
= m_pSFParent
->GetUIObjectOf(m_ListView
, 1, &pidl
, IID_NULL_PPV_ARG(IDropTarget
, &m_pCurDropTarget
));
2925 /* If anything failed, m_pCurDropTarget should be NULL now, which ought to be a save state. */
2928 *pdwEffect
= DROPEFFECT_NONE
;
2932 if (m_iDragOverItem
!= -1)
2934 SelectItem(m_iDragOverItem
, SVSI_SELECT
);
2937 /* Notify the item just entered via DragEnter. */
2938 return m_pCurDropTarget
->DragEnter(m_pCurDataObject
, grfKeyState
, pt
, pdwEffect
);
2941 HRESULT WINAPI
CDefView::DragEnter(IDataObject
*pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2943 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2944 m_pCurDataObject
= pDataObject
;
2946 HRESULT hr
= drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2949 POINT ptClient
= {pt
.x
, pt
.y
};
2950 ScreenToClient(&ptClient
);
2951 ImageList_DragEnter(m_hWnd
, ptClient
.x
, ptClient
.y
);
2957 HRESULT WINAPI
CDefView::DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2959 POINT ptClient
= {pt
.x
, pt
.y
};
2960 ScreenToClient(&ptClient
);
2961 ImageList_DragMove(ptClient
.x
, ptClient
.y
);
2962 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2965 HRESULT WINAPI
CDefView::DragLeave()
2967 ImageList_DragLeave(m_hWnd
);
2969 if (m_pCurDropTarget
)
2971 m_pCurDropTarget
->DragLeave();
2972 m_pCurDropTarget
.Release();
2975 if (m_pCurDataObject
!= NULL
)
2977 m_pCurDataObject
.Release();
2980 m_iDragOverItem
= 0;
2985 HRESULT WINAPI
CDefView::Drop(IDataObject
* pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2987 ERR("GetKeyState(VK_LBUTTON): %d\n", GetKeyState(VK_LBUTTON
));
2989 ImageList_EndDrag();
2991 if ((m_iDragOverItem
== -1 || m_pCurDropTarget
== NULL
) &&
2992 (*pdwEffect
& DROPEFFECT_MOVE
) &&
2993 /*(GetKeyState(VK_LBUTTON) != 0) &&*/
2994 (m_pSourceDataObject
.p
) &&
2995 (SHIsSameObject(pDataObject
, m_pSourceDataObject
)))
2997 if (m_pCurDropTarget
)
2999 m_pCurDropTarget
->DragLeave();
3000 m_pCurDropTarget
.Release();
3003 /* Restore the selection */
3004 m_ListView
.SetItemState(-1, 0, LVIS_SELECTED
);
3005 for (UINT i
= 0 ; i
< m_cidl
; i
++)
3006 SelectItem(m_apidl
[i
], SVSI_SELECT
);
3008 /* Reposition the items */
3010 while ((lvIndex
= m_ListView
.GetNextItem(lvIndex
, LVNI_SELECTED
)) > -1)
3013 if (m_ListView
.GetItemPosition(lvIndex
, &ptItem
))
3015 ptItem
.x
+= pt
.x
- m_ptFirstMousePos
.x
;
3016 ptItem
.y
+= pt
.y
- m_ptFirstMousePos
.y
;
3017 m_ListView
.SetItemPosition(lvIndex
, &ptItem
);
3021 else if (m_pCurDropTarget
)
3023 m_pCurDropTarget
->Drop(pDataObject
, grfKeyState
, pt
, pdwEffect
);
3024 m_pCurDropTarget
.Release();
3027 m_pCurDataObject
.Release();
3028 m_iDragOverItem
= 0;
3032 /**********************************************************
3033 * ISVDropSource implementation
3036 HRESULT WINAPI
CDefView::QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
)
3038 TRACE("(%p)\n", this);
3041 return DRAGDROP_S_CANCEL
;
3042 else if (!(grfKeyState
& MK_LBUTTON
) && !(grfKeyState
& MK_RBUTTON
))
3043 return DRAGDROP_S_DROP
;
3048 HRESULT WINAPI
CDefView::GiveFeedback(DWORD dwEffect
)
3050 TRACE("(%p)\n", this);
3052 return DRAGDROP_S_USEDEFAULTCURSORS
;
3055 /**********************************************************
3056 * ISVViewObject implementation
3059 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
)
3061 FIXME("Stub: this=%p\n", this);
3066 HRESULT WINAPI
CDefView::GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
, HDC hicTargetDevice
, LOGPALETTE
**ppColorSet
)
3068 FIXME("Stub: this=%p\n", this);
3073 HRESULT WINAPI
CDefView::Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
)
3075 FIXME("Stub: this=%p\n", this);
3080 HRESULT WINAPI
CDefView::Unfreeze(DWORD dwFreeze
)
3082 FIXME("Stub: this=%p\n", this);
3087 HRESULT WINAPI
CDefView::SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
)
3089 FIXME("partial stub: %p %08x %08x %p\n", this, aspects
, advf
, pAdvSink
);
3091 /* FIXME: we set the AdviseSink, but never use it to send any advice */
3092 m_pAdvSink
= pAdvSink
;
3093 m_dwAspects
= aspects
;
3099 HRESULT WINAPI
CDefView::GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
)
3101 TRACE("this=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n", this, pAspects
, pAdvf
, ppAdvSink
);
3105 *ppAdvSink
= m_pAdvSink
;
3106 m_pAdvSink
.p
->AddRef();
3110 *pAspects
= m_dwAspects
;
3118 HRESULT STDMETHODCALLTYPE
CDefView::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
3120 if (IsEqualIID(guidService
, SID_IShellBrowser
))
3121 return m_pShellBrowser
->QueryInterface(riid
, ppvObject
);
3122 else if(IsEqualIID(guidService
, SID_IFolderView
))
3123 return QueryInterface(riid
, ppvObject
);
3125 return E_NOINTERFACE
;
3128 HRESULT
CDefView::_MergeToolbar()
3130 CComPtr
<IExplorerToolbar
> ptb
;
3133 hr
= IUnknown_QueryService(m_pShellBrowser
, IID_IExplorerToolbar
, IID_PPV_ARG(IExplorerToolbar
, &ptb
));
3137 m_Category
= CGID_DefViewFrame
;
3139 hr
= ptb
->SetCommandTarget(static_cast<IOleCommandTarget
*>(this), &m_Category
, 0);
3147 hr
= ptb
->AddButtons(&m_Category
, buttonsCount
, buttons
);
3154 /**********************************************************
3155 * IShellView_Constructor
3157 HRESULT WINAPI
IShellView_Constructor(IShellFolder
*pFolder
, IShellView
**newView
)
3159 return ShellObjectCreatorInit
<CDefView
>(pFolder
, IID_IShellView
, newView
);
3162 HRESULT WINAPI
CDefView_Constructor(IShellFolder
*pFolder
, REFIID riid
, LPVOID
* ppvOut
)
3164 return ShellObjectCreatorInit
<CDefView
>(pFolder
, riid
, ppvOut
);