4 * Copyright 1998,1999 <juergen.schmied@debitel.net>
6 * This is the view visualizing the data provided by the shellfolder.
7 * No direct access to data from pidls should be done from here.
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 * FIXME: CheckToolbar: handle the "new folder" and "folder up" button
28 - Load/Save the view state from/into the stream provided by the ShellBrowser.
29 - When editing starts on item, set edit text to for editing value.
30 - Fix shell view to handle view mode popup exec.
31 - The background context menu should have a pidl just like foreground menus. This
32 causes crashes when dynamic handlers try to use the NULL pidl.
33 - Reorder of columns doesn't work - might be bug in comctl32
41 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
45 static const WCHAR SV_CLASS_NAME
[] = {'S', 'H', 'E', 'L', 'L', 'D', 'L', 'L', '_', 'D', 'e', 'f', 'V', 'i', 'e', 'w', 0};
52 } LISTVIEW_SORT_INFO
, *LPLISTVIEW_SORT_INFO
;
54 #define SHV_CHANGE_NOTIFY WM_USER + 0x1111
56 /* For the context menu of the def view, the id of the items are based on 1 because we need
57 to call TrackPopupMenu and let it use the 0 value as an indication that the menu was canceled */
58 #define CONTEXT_MENU_BASE_ID 1
61 public CWindowImpl
<CDefView
, CWindow
, CControlWinTraits
>,
62 public CComObjectRootEx
<CComMultiThreadModelNoCS
>,
65 public IShellFolderView
,
66 public IOleCommandTarget
,
70 public IServiceProvider
73 CComPtr
<IShellFolder
> m_pSFParent
;
74 CComPtr
<IShellFolder2
> m_pSF2Parent
;
75 CComPtr
<IShellBrowser
> m_pShellBrowser
;
76 CComPtr
<ICommDlgBrowser
> m_pCommDlgBrowser
;
77 CComPtr
<IShellFolderViewDual
> m_pShellFolderViewDual
;
80 FOLDERSETTINGS m_FolderSettings
;
81 HMENU m_hMenu
; /* Handle to the menu bar of the browser */
82 HMENU m_hMenuArrangeModes
; /* Handle to the popup menu with the arrange modes */
83 HMENU m_hMenuViewModes
; /* Handle to the popup menu with the view modes */
84 HMENU m_hContextMenu
; /* Handle to the open context menu */
85 BOOL m_bmenuBarInitialized
;
88 PCUITEMID_CHILD
*m_apidl
;
89 PIDLIST_ABSOLUTE m_pidlParent
;
90 LISTVIEW_SORT_INFO m_sortInfo
;
91 ULONG m_hNotify
; /* Change notification handle */
95 CComPtr
<IAdviseSink
> m_pAdvSink
;
97 CComPtr
<IDataObject
> m_pSourceDataObject
;
98 CComPtr
<IDropTarget
> m_pCurDropTarget
; /* The sub-item, which is currently dragged over */
99 CComPtr
<IDataObject
> m_pCurDataObject
; /* The dragged data-object */
100 LONG m_iDragOverItem
; /* Dragged over item's index, iff m_pCurDropTarget != NULL */
101 UINT m_cScrollDelay
; /* Send a WM_*SCROLL msg every 250 ms during drag-scroll */
102 POINT m_ptLastMousePos
; /* Mouse position at last DragOver call */
103 POINT m_ptFirstMousePos
; /* Mouse position when the drag operation started */
105 CComPtr
<IContextMenu
> m_pCM
;
113 HRESULT
_MergeToolbar();
119 HRESULT WINAPI
Initialize(IShellFolder
*shellFolder
);
120 HRESULT
IncludeObject(PCUITEMID_CHILD pidl
);
121 HRESULT
OnDefaultCommand();
122 HRESULT
OnStateChange(UINT uFlags
);
123 void UpdateStatusbar();
125 void SetStyle(DWORD dwAdd
, DWORD dwRemove
);
127 void UpdateListColors();
129 static INT CALLBACK
ListViewCompareItems(LPARAM lParam1
, LPARAM lParam2
, LPARAM lpData
);
131 PCUITEMID_CHILD
_PidlByItem(int i
);
132 PCUITEMID_CHILD
_PidlByItem(LVITEM
& lvItem
);
133 int LV_FindItemByPidl(PCUITEMID_CHILD pidl
);
134 BOOLEAN
LV_AddItem(PCUITEMID_CHILD pidl
);
135 BOOLEAN
LV_DeleteItem(PCUITEMID_CHILD pidl
);
136 BOOLEAN
LV_RenameItem(PCUITEMID_CHILD pidlOld
, PCUITEMID_CHILD pidlNew
);
137 BOOLEAN
LV_ProdItem(PCUITEMID_CHILD pidl
);
138 static INT CALLBACK
fill_list(LPVOID ptr
, LPVOID arg
);
140 HRESULT
FillFileMenu();
141 HRESULT
FillEditMenu();
142 HRESULT
FillViewMenu();
143 HRESULT
FillArrangeAsMenu(HMENU hmenuArrange
);
144 HRESULT
CheckViewMode(HMENU hmenuView
);
145 UINT
GetSelections();
146 HRESULT
OpenSelectedItems();
148 void DoActivate(UINT uState
);
149 HRESULT
drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
150 HRESULT
InvokeContextMenuCommand(UINT uCommand
);
151 LRESULT
OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
);
153 // *** IOleWindow methods ***
154 virtual HRESULT STDMETHODCALLTYPE
GetWindow(HWND
*lphwnd
);
155 virtual HRESULT STDMETHODCALLTYPE
ContextSensitiveHelp(BOOL fEnterMode
);
157 // *** IShellView methods ***
158 virtual HRESULT STDMETHODCALLTYPE
TranslateAccelerator(MSG
*pmsg
);
159 virtual HRESULT STDMETHODCALLTYPE
EnableModeless(BOOL fEnable
);
160 virtual HRESULT STDMETHODCALLTYPE
UIActivate(UINT uState
);
161 virtual HRESULT STDMETHODCALLTYPE
Refresh();
162 virtual HRESULT STDMETHODCALLTYPE
CreateViewWindow(IShellView
*psvPrevious
, LPCFOLDERSETTINGS pfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
);
163 virtual HRESULT STDMETHODCALLTYPE
DestroyViewWindow();
164 virtual HRESULT STDMETHODCALLTYPE
GetCurrentInfo(LPFOLDERSETTINGS pfs
);
165 virtual HRESULT STDMETHODCALLTYPE
AddPropertySheetPages(DWORD dwReserved
, LPFNSVADDPROPSHEETPAGE pfn
, LPARAM lparam
);
166 virtual HRESULT STDMETHODCALLTYPE
SaveViewState();
167 virtual HRESULT STDMETHODCALLTYPE
SelectItem(PCUITEMID_CHILD pidlItem
, SVSIF uFlags
);
168 virtual HRESULT STDMETHODCALLTYPE
GetItemObject(UINT uItem
, REFIID riid
, void **ppv
);
170 // *** IShellView2 methods ***
171 virtual HRESULT STDMETHODCALLTYPE
GetView(SHELLVIEWID
*view_guid
, ULONG view_type
);
172 virtual HRESULT STDMETHODCALLTYPE
CreateViewWindow2(LPSV2CVW2_PARAMS view_params
);
173 virtual HRESULT STDMETHODCALLTYPE
HandleRename(LPCITEMIDLIST new_pidl
);
174 virtual HRESULT STDMETHODCALLTYPE
SelectAndPositionItem(LPCITEMIDLIST item
, UINT flags
, POINT
*point
);
176 // *** IShellView3 methods ***
177 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
);
179 // *** IFolderView methods ***
180 virtual HRESULT STDMETHODCALLTYPE
GetCurrentViewMode(UINT
*pViewMode
);
181 virtual HRESULT STDMETHODCALLTYPE
SetCurrentViewMode(UINT ViewMode
);
182 virtual HRESULT STDMETHODCALLTYPE
GetFolder(REFIID riid
, void **ppv
);
183 virtual HRESULT STDMETHODCALLTYPE
Item(int iItemIndex
, PITEMID_CHILD
*ppidl
);
184 virtual HRESULT STDMETHODCALLTYPE
ItemCount(UINT uFlags
, int *pcItems
);
185 virtual HRESULT STDMETHODCALLTYPE
Items(UINT uFlags
, REFIID riid
, void **ppv
);
186 virtual HRESULT STDMETHODCALLTYPE
GetSelectionMarkedItem(int *piItem
);
187 virtual HRESULT STDMETHODCALLTYPE
GetFocusedItem(int *piItem
);
188 virtual HRESULT STDMETHODCALLTYPE
GetItemPosition(PCUITEMID_CHILD pidl
, POINT
*ppt
);
189 virtual HRESULT STDMETHODCALLTYPE
GetSpacing(POINT
*ppt
);
190 virtual HRESULT STDMETHODCALLTYPE
GetDefaultSpacing(POINT
*ppt
);
191 virtual HRESULT STDMETHODCALLTYPE
GetAutoArrange();
192 virtual HRESULT STDMETHODCALLTYPE
SelectItem(int iItem
, DWORD dwFlags
);
193 virtual HRESULT STDMETHODCALLTYPE
SelectAndPositionItems(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD dwFlags
);
195 // *** IShellFolderView methods ***
196 virtual HRESULT STDMETHODCALLTYPE
Rearrange(LPARAM sort
);
197 virtual HRESULT STDMETHODCALLTYPE
GetArrangeParam(LPARAM
*sort
);
198 virtual HRESULT STDMETHODCALLTYPE
ArrangeGrid();
199 virtual HRESULT STDMETHODCALLTYPE
AutoArrange();
200 virtual HRESULT STDMETHODCALLTYPE
AddObject(PITEMID_CHILD pidl
, UINT
*item
);
201 virtual HRESULT STDMETHODCALLTYPE
GetObject(PITEMID_CHILD
*pidl
, UINT item
);
202 virtual HRESULT STDMETHODCALLTYPE
RemoveObject(PITEMID_CHILD pidl
, UINT
*item
);
203 virtual HRESULT STDMETHODCALLTYPE
GetObjectCount(UINT
*count
);
204 virtual HRESULT STDMETHODCALLTYPE
SetObjectCount(UINT count
, UINT flags
);
205 virtual HRESULT STDMETHODCALLTYPE
UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
);
206 virtual HRESULT STDMETHODCALLTYPE
RefreshObject(PITEMID_CHILD pidl
, UINT
*item
);
207 virtual HRESULT STDMETHODCALLTYPE
SetRedraw(BOOL redraw
);
208 virtual HRESULT STDMETHODCALLTYPE
GetSelectedCount(UINT
*count
);
209 virtual HRESULT STDMETHODCALLTYPE
GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
);
210 virtual HRESULT STDMETHODCALLTYPE
IsDropOnSource(IDropTarget
*drop_target
);
211 virtual HRESULT STDMETHODCALLTYPE
GetDragPoint(POINT
*pt
);
212 virtual HRESULT STDMETHODCALLTYPE
GetDropPoint(POINT
*pt
);
213 virtual HRESULT STDMETHODCALLTYPE
MoveIcons(IDataObject
*obj
);
214 virtual HRESULT STDMETHODCALLTYPE
SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
);
215 virtual HRESULT STDMETHODCALLTYPE
IsBkDropTarget(IDropTarget
*drop_target
);
216 virtual HRESULT STDMETHODCALLTYPE
SetClipboard(BOOL move
);
217 virtual HRESULT STDMETHODCALLTYPE
SetPoints(IDataObject
*obj
);
218 virtual HRESULT STDMETHODCALLTYPE
GetItemSpacing(ITEMSPACING
*spacing
);
219 virtual HRESULT STDMETHODCALLTYPE
SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
);
220 virtual HRESULT STDMETHODCALLTYPE
Select(UINT flags
);
221 virtual HRESULT STDMETHODCALLTYPE
QuerySupport(UINT
*support
);
222 virtual HRESULT STDMETHODCALLTYPE
SetAutomationObject(IDispatch
*disp
);
224 // *** IOleCommandTarget methods ***
225 virtual HRESULT STDMETHODCALLTYPE
QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
);
226 virtual HRESULT STDMETHODCALLTYPE
Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
);
228 // *** IDropTarget methods ***
229 virtual HRESULT STDMETHODCALLTYPE
DragEnter(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
230 virtual HRESULT STDMETHODCALLTYPE
DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
231 virtual HRESULT STDMETHODCALLTYPE
DragLeave();
232 virtual HRESULT STDMETHODCALLTYPE
Drop(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
234 // *** IDropSource methods ***
235 virtual HRESULT STDMETHODCALLTYPE
QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
);
236 virtual HRESULT STDMETHODCALLTYPE
GiveFeedback(DWORD dwEffect
);
238 // *** IViewObject methods ***
239 virtual HRESULT STDMETHODCALLTYPE
Draw(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
,
240 HDC hdcTargetDev
, HDC hdcDraw
, LPCRECTL lprcBounds
, LPCRECTL lprcWBounds
,
241 BOOL ( STDMETHODCALLTYPE
*pfnContinue
)(ULONG_PTR dwContinue
), ULONG_PTR dwContinue
);
242 virtual HRESULT STDMETHODCALLTYPE
GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
,
243 DVTARGETDEVICE
*ptd
, HDC hicTargetDev
, LOGPALETTE
**ppColorSet
);
244 virtual HRESULT STDMETHODCALLTYPE
Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
);
245 virtual HRESULT STDMETHODCALLTYPE
Unfreeze(DWORD dwFreeze
);
246 virtual HRESULT STDMETHODCALLTYPE
SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
);
247 virtual HRESULT STDMETHODCALLTYPE
GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
);
249 // *** IServiceProvider methods ***
250 virtual HRESULT STDMETHODCALLTYPE
QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
);
253 LRESULT
OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
254 LRESULT
OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
255 LRESULT
OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
256 LRESULT
OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
257 LRESULT
OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
258 LRESULT
OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
259 LRESULT
OnNCCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
260 LRESULT
OnNCDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
261 LRESULT
OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
262 LRESULT
OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
263 LRESULT
OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
264 LRESULT
OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
265 LRESULT
OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
266 LRESULT
OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
267 LRESULT
OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
268 LRESULT
OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
269 LRESULT
OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
270 LRESULT
OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
271 LRESULT
OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
272 LRESULT
OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
274 static ATL::CWndClassInfo
& GetWndClassInfo()
276 static ATL::CWndClassInfo wc
=
278 { sizeof(WNDCLASSEX
), CS_PARENTDC
, StartWindowProc
,
280 LoadCursor(NULL
, IDC_ARROW
), (HBRUSH
)(COLOR_WINDOW
+ 1), NULL
, SV_CLASS_NAME
, NULL
282 NULL
, NULL
, IDC_ARROW
, TRUE
, 0, _T("")
287 virtual WNDPROC
GetWindowProc()
292 static LRESULT CALLBACK
WindowProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
297 // Must hold a reference during message handling
298 pThis
= reinterpret_cast<CDefView
*>(hWnd
);
300 result
= CWindowImpl
<CDefView
, CWindow
, CControlWinTraits
>::WindowProc(hWnd
, uMsg
, wParam
, lParam
);
305 BEGIN_MSG_MAP(CDefView
)
306 MESSAGE_HANDLER(WM_SIZE
, OnSize
)
307 MESSAGE_HANDLER(WM_SETFOCUS
, OnSetFocus
)
308 MESSAGE_HANDLER(WM_KILLFOCUS
, OnKillFocus
)
309 MESSAGE_HANDLER(WM_NCCREATE
, OnNCCreate
)
310 MESSAGE_HANDLER(WM_NCDESTROY
, OnNCDestroy
)
311 MESSAGE_HANDLER(WM_CREATE
, OnCreate
)
312 MESSAGE_HANDLER(WM_ACTIVATE
, OnActivate
)
313 MESSAGE_HANDLER(WM_NOTIFY
, OnNotify
)
314 MESSAGE_HANDLER(WM_COMMAND
, OnCommand
)
315 MESSAGE_HANDLER(SHV_CHANGE_NOTIFY
, OnChangeNotify
)
316 MESSAGE_HANDLER(WM_CONTEXTMENU
, OnContextMenu
)
317 MESSAGE_HANDLER(WM_DRAWITEM
, OnCustomItem
)
318 MESSAGE_HANDLER(WM_MEASUREITEM
, OnCustomItem
)
319 MESSAGE_HANDLER(WM_SHOWWINDOW
, OnShowWindow
)
320 MESSAGE_HANDLER(WM_GETDLGCODE
, OnGetDlgCode
)
321 MESSAGE_HANDLER(WM_DESTROY
, OnDestroy
)
322 MESSAGE_HANDLER(WM_ERASEBKGND
, OnEraseBackground
)
323 MESSAGE_HANDLER(WM_SYSCOLORCHANGE
, OnSysColorChange
)
324 MESSAGE_HANDLER(CWM_GETISHELLBROWSER
, OnGetShellBrowser
)
325 MESSAGE_HANDLER(WM_SETTINGCHANGE
, OnSettingChange
)
326 MESSAGE_HANDLER(WM_INITMENUPOPUP
, OnInitMenuPopup
)
329 BEGIN_COM_MAP(CDefView
)
330 // Windows returns E_NOINTERFACE for IOleWindow
331 // COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
332 COM_INTERFACE_ENTRY_IID(IID_IShellView
, IShellView
)
333 COM_INTERFACE_ENTRY_IID(IID_CDefView
, IShellView
)
334 COM_INTERFACE_ENTRY_IID(IID_IShellView2
, IShellView2
)
335 COM_INTERFACE_ENTRY_IID(IID_IFolderView
, IFolderView
)
336 COM_INTERFACE_ENTRY_IID(IID_IShellFolderView
, IShellFolderView
)
337 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget
, IOleCommandTarget
)
338 COM_INTERFACE_ENTRY_IID(IID_IDropTarget
, IDropTarget
)
339 COM_INTERFACE_ENTRY_IID(IID_IDropSource
, IDropSource
)
340 COM_INTERFACE_ENTRY_IID(IID_IViewObject
, IViewObject
)
341 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider
, IServiceProvider
)
346 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
347 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
348 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
350 #define ID_LISTVIEW 1
353 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
354 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
355 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
357 typedef void (CALLBACK
*PFNSHGETSETTINGSPROC
)(LPSHELLFLAGSTATE lpsfs
, DWORD dwMask
);
359 CDefView::CDefView() :
363 m_hMenuArrangeModes(NULL
),
364 m_hMenuViewModes(NULL
),
365 m_hContextMenu(NULL
),
366 m_bmenuBarInitialized(FALSE
),
380 ZeroMemory(&m_FolderSettings
, sizeof(m_FolderSettings
));
381 ZeroMemory(&m_sortInfo
, sizeof(m_sortInfo
));
382 ZeroMemory(&m_ptLastMousePos
, sizeof(m_ptLastMousePos
));
383 ZeroMemory(&m_Category
, sizeof(m_Category
));
386 CDefView::~CDefView()
388 TRACE(" destroying IShellView(%p)\n", this);
398 HRESULT WINAPI
CDefView::Initialize(IShellFolder
*shellFolder
)
400 m_pSFParent
= shellFolder
;
401 shellFolder
->QueryInterface(IID_PPV_ARG(IShellFolder2
, &m_pSF2Parent
));
406 /**********************************************************
408 * ##### helperfunctions for communication with ICommDlgBrowser #####
410 HRESULT
CDefView::IncludeObject(PCUITEMID_CHILD pidl
)
414 if (m_pCommDlgBrowser
.p
!= NULL
)
416 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl
);
417 ret
= m_pCommDlgBrowser
->IncludeObject(this, pidl
);
418 TRACE("--0x%08x\n", ret
);
424 HRESULT
CDefView::OnDefaultCommand()
426 HRESULT ret
= S_FALSE
;
428 if (m_pCommDlgBrowser
.p
!= NULL
)
430 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
431 ret
= m_pCommDlgBrowser
->OnDefaultCommand(this);
432 TRACE("-- returns %08x\n", ret
);
438 HRESULT
CDefView::OnStateChange(UINT uFlags
)
440 HRESULT ret
= S_FALSE
;
442 if (m_pCommDlgBrowser
.p
!= NULL
)
444 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags
);
445 ret
= m_pCommDlgBrowser
->OnStateChange(this, uFlags
);
451 /**********************************************************
452 * set the toolbar of the filedialog buttons
454 * - activates the buttons from the shellbrowser according to
457 void CDefView::CheckToolbar()
463 if (m_pCommDlgBrowser
!= NULL
)
465 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
466 FCIDM_TB_SMALLICON
, (m_FolderSettings
.ViewMode
== FVM_LIST
) ? TRUE
: FALSE
, &result
);
467 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
468 FCIDM_TB_REPORTVIEW
, (m_FolderSettings
.ViewMode
== FVM_DETAILS
) ? TRUE
: FALSE
, &result
);
469 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
470 FCIDM_TB_SMALLICON
, TRUE
, &result
);
471 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
472 FCIDM_TB_REPORTVIEW
, TRUE
, &result
);
476 void CDefView::UpdateStatusbar()
478 WCHAR szFormat
[MAX_PATH
] = {0};
479 WCHAR szObjects
[MAX_PATH
] = {0};
482 cSelectedItems
= m_ListView
.GetSelectedCount();
485 LoadStringW(shell32_hInstance
, IDS_OBJECTS_SELECTED
, szFormat
, _countof(szFormat
));
486 StringCchPrintfW(szObjects
, MAX_PATH
, szFormat
, cSelectedItems
);
490 LoadStringW(shell32_hInstance
, IDS_OBJECTS
, szFormat
, _countof(szFormat
));
491 StringCchPrintfW(szObjects
, MAX_PATH
, szFormat
, m_ListView
.GetItemCount());
493 m_pShellBrowser
->SetStatusTextSB(szObjects
);
496 /**********************************************************
498 * ##### helperfunctions for initializing the view #####
500 /**********************************************************
501 * change the style of the listview control
503 void CDefView::SetStyle(DWORD dwAdd
, DWORD dwRemove
)
507 TRACE("(%p)\n", this);
509 tmpstyle
= ::GetWindowLongPtrW(m_ListView
, GWL_STYLE
);
510 ::SetWindowLongPtrW(m_ListView
, GWL_STYLE
, dwAdd
| (tmpstyle
& ~dwRemove
));
513 /**********************************************************
514 * ShellView_CreateList()
516 * - creates the list view window
518 BOOL
CDefView::CreateList()
520 DWORD dwStyle
, dwExStyle
;
524 dwStyle
= WS_TABSTOP
| WS_VISIBLE
| WS_CHILDWINDOW
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
|
525 LVS_SHAREIMAGELISTS
| LVS_EDITLABELS
| LVS_AUTOARRANGE
;
526 dwExStyle
= WS_EX_CLIENTEDGE
;
528 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
529 dwStyle
|= LVS_ALIGNLEFT
;
531 dwStyle
|= LVS_ALIGNTOP
| LVS_SHOWSELALWAYS
;
533 switch (m_FolderSettings
.ViewMode
)
540 dwStyle
|= LVS_REPORT
;
544 dwStyle
|= LVS_SMALLICON
;
556 if (m_FolderSettings
.fFlags
& FWF_AUTOARRANGE
)
557 dwStyle
|= LVS_AUTOARRANGE
;
559 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
560 m_FolderSettings
.fFlags
|= FWF_NOCLIENTEDGE
| FWF_NOSCROLL
;
562 if (m_FolderSettings
.fFlags
& FWF_SINGLESEL
)
563 dwStyle
|= LVS_SINGLESEL
;
565 if (m_FolderSettings
.fFlags
& FWF_NOCLIENTEDGE
)
566 dwExStyle
&= ~WS_EX_CLIENTEDGE
;
568 RECT rcListView
= {0,0,0,0};
569 m_ListView
.Create(m_hWnd
, rcListView
, L
"FolderView", dwStyle
, dwExStyle
, ID_LISTVIEW
);
574 m_sortInfo
.bIsAscending
= TRUE
;
575 m_sortInfo
.nHeaderID
= -1;
576 m_sortInfo
.nLastHeaderID
= -1;
580 /* UpdateShellSettings(); */
584 void CDefView::UpdateListColors()
586 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
588 /* Check if drop shadows option is enabled */
589 BOOL bDropShadow
= FALSE
;
590 DWORD cbDropShadow
= sizeof(bDropShadow
);
593 * The desktop ListView always take the default desktop colours, by
594 * remaining transparent and letting user32/win32k paint itself the
595 * desktop background color, if any.
597 m_ListView
.SetBkColor(CLR_NONE
);
599 SHGetValueW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
600 L
"ListviewShadow", NULL
, &bDropShadow
, &cbDropShadow
);
603 /* Set the icon background transparent */
604 m_ListView
.SetTextBkColor(CLR_NONE
);
605 m_ListView
.SetTextColor(RGB(255, 255, 255));
606 m_ListView
.SetExtendedListViewStyle(LVS_EX_TRANSPARENTSHADOWTEXT
, LVS_EX_TRANSPARENTSHADOWTEXT
);
610 /* Set the icon background as the same colour as the desktop */
611 COLORREF crDesktop
= GetSysColor(COLOR_DESKTOP
);
612 m_ListView
.SetTextBkColor(crDesktop
);
613 if (GetRValue(crDesktop
) + GetGValue(crDesktop
) + GetBValue(crDesktop
) > 128 * 3)
614 m_ListView
.SetTextColor(RGB(0, 0, 0));
616 m_ListView
.SetTextColor(RGB(255, 255, 255));
617 m_ListView
.SetExtendedListViewStyle(0, LVS_EX_TRANSPARENTSHADOWTEXT
);
622 /**********************************************************
623 * ShellView_InitList()
625 * - adds all needed columns to the shellview
627 BOOL
CDefView::InitList()
631 HIMAGELIST big_icons
, small_icons
;
635 m_ListView
.DeleteAllItems();
637 m_hMenuArrangeModes
= CreateMenu();
641 for (int i
= 0; 1; i
++)
643 if (FAILED(m_pSF2Parent
->GetDetailsOf(NULL
, i
, &sd
)))
645 StrRetToStrNW( szTemp
, 50, &sd
.str
, NULL
);
646 m_ListView
.InsertColumn(i
, szTemp
, sd
.fmt
, sd
.cxChar
* 8);
648 InsertMenuW(m_hMenuArrangeModes
, -1, MF_STRING
, 0x30 + i
, szTemp
);
651 InsertMenuW(m_hMenuArrangeModes
, -1, MF_BYPOSITION
| MF_SEPARATOR
, 0, 0);
655 FIXME("no m_pSF2Parent\n");
658 Shell_GetImageLists(&big_icons
, &small_icons
);
659 m_ListView
.SetImageList(big_icons
, LVSIL_NORMAL
);
660 m_ListView
.SetImageList(small_icons
, LVSIL_SMALL
);
665 /*************************************************************************
666 * ShellView_ListViewCompareItems
668 * Compare Function for the Listview (FileOpen Dialog)
671 * lParam1 [I] the first ItemIdList to compare with
672 * lParam2 [I] the second ItemIdList to compare with
673 * lpData [I] The column ID for the header Ctrl to process
676 * A negative value if the first item should precede the second,
677 * a positive value if the first item should follow the second,
678 * or zero if the two items are equivalent
680 INT CALLBACK
CDefView::ListViewCompareItems(LPARAM lParam1
, LPARAM lParam2
, LPARAM lpData
)
682 PCUIDLIST_RELATIVE pidl1
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam1
);
683 PCUIDLIST_RELATIVE pidl2
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam2
);
684 CDefView
*pThis
= reinterpret_cast<CDefView
*>(lpData
);
686 HRESULT hres
= pThis
->m_pSFParent
->CompareIDs(pThis
->m_sortInfo
.nHeaderID
, pidl1
, pidl2
);
687 if (FAILED_UNEXPECTEDLY(hres
))
690 SHORT nDiff
= HRESULT_CODE(hres
);
691 if (!pThis
->m_sortInfo
.bIsAscending
)
696 BOOL
CDefView::_Sort()
701 if (m_ListView
.GetWindowLongPtr(GWL_STYLE
) & LVS_NOSORTHEADER
)
704 hHeader
= (HWND
)m_ListView
.SendMessage(LVM_GETHEADER
, 0, 0);
705 ZeroMemory(&hColumn
, sizeof(hColumn
));
707 /* If the sorting column changed, remove the sorting style from the old column */
708 if ( (m_sortInfo
.nLastHeaderID
!= -1) &&
709 (m_sortInfo
.nLastHeaderID
!= m_sortInfo
.nHeaderID
) )
711 hColumn
.mask
= HDI_FORMAT
;
712 Header_GetItem(hHeader
, m_sortInfo
.nLastHeaderID
, &hColumn
);
713 hColumn
.fmt
&= ~(HDF_SORTUP
| HDF_SORTDOWN
);
714 Header_SetItem(hHeader
, m_sortInfo
.nLastHeaderID
, &hColumn
);
717 /* Set the sorting style to the new column */
718 hColumn
.mask
= HDI_FORMAT
;
719 Header_GetItem(hHeader
, m_sortInfo
.nHeaderID
, &hColumn
);
721 hColumn
.fmt
&= (m_sortInfo
.bIsAscending
? ~HDF_SORTDOWN
: ~HDF_SORTUP
);
722 hColumn
.fmt
|= (m_sortInfo
.bIsAscending
? HDF_SORTUP
: HDF_SORTDOWN
);
723 Header_SetItem(hHeader
, m_sortInfo
.nHeaderID
, &hColumn
);
725 /* Sort the list, using the current values of nHeaderID and bIsAscending */
726 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
727 return m_ListView
.SortItems(ListViewCompareItems
, this);
730 PCUITEMID_CHILD
CDefView::_PidlByItem(int i
)
732 return reinterpret_cast<PCUITEMID_CHILD
>(m_ListView
.GetItemData(i
));
735 PCUITEMID_CHILD
CDefView::_PidlByItem(LVITEM
& lvItem
)
737 return reinterpret_cast<PCUITEMID_CHILD
>(lvItem
.lParam
);
740 /**********************************************************
741 * LV_FindItemByPidl()
743 int CDefView::LV_FindItemByPidl(PCUITEMID_CHILD pidl
)
745 int cItems
= m_ListView
.GetItemCount();
747 for (int i
= 0; i
<cItems
; i
++)
749 PCUITEMID_CHILD currentpidl
= _PidlByItem(i
);
750 HRESULT hr
= m_pSFParent
->CompareIDs(0, pidl
, currentpidl
);
752 if (SUCCEEDED(hr
) && !HRESULT_CODE(hr
))
760 /**********************************************************
763 BOOLEAN
CDefView::LV_AddItem(PCUITEMID_CHILD pidl
)
767 TRACE("(%p)(pidl=%p)\n", this, pidl
);
769 lvItem
.mask
= LVIF_TEXT
| LVIF_IMAGE
| LVIF_PARAM
; /*set the mask*/
770 lvItem
.iItem
= m_ListView
.GetItemCount(); /*add the item to the end of the list*/
772 lvItem
.lParam
= reinterpret_cast<LPARAM
>(ILClone(pidl
)); /*set the item's data*/
773 lvItem
.pszText
= LPSTR_TEXTCALLBACKW
; /*get text on a callback basis*/
774 lvItem
.iImage
= I_IMAGECALLBACK
; /*get the image on a callback basis*/
775 lvItem
.stateMask
= LVIS_CUT
;
777 if (m_ListView
.InsertItem(&lvItem
) == -1)
783 /**********************************************************
786 BOOLEAN
CDefView::LV_DeleteItem(PCUITEMID_CHILD pidl
)
790 TRACE("(%p)(pidl=%p)\n", this, pidl
);
792 nIndex
= LV_FindItemByPidl(pidl
);
794 return (-1 == m_ListView
.DeleteItem(nIndex
)) ? FALSE
: TRUE
;
797 /**********************************************************
800 BOOLEAN
CDefView::LV_RenameItem(PCUITEMID_CHILD pidlOld
, PCUITEMID_CHILD pidlNew
)
805 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", this, pidlOld
, pidlNew
);
807 nItem
= LV_FindItemByPidl(pidlOld
);
811 lvItem
.mask
= LVIF_PARAM
; /* only the pidl */
812 lvItem
.iItem
= nItem
;
814 m_ListView
.GetItem(&lvItem
);
816 SHFree(reinterpret_cast<LPVOID
>(lvItem
.lParam
));
817 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
818 lvItem
.iItem
= nItem
;
820 lvItem
.lParam
= reinterpret_cast<LPARAM
>(ILClone(pidlNew
)); /* set the item's data */
821 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
822 m_ListView
.SetItem(&lvItem
);
823 m_ListView
.Update(nItem
);
824 return TRUE
; /* FIXME: better handling */
830 /**********************************************************
833 BOOLEAN
CDefView::LV_ProdItem(PCUITEMID_CHILD pidl
)
838 TRACE("(%p)(pidl=%p)\n", this, pidl
);
840 nItem
= LV_FindItemByPidl(pidl
);
844 lvItem
.mask
= LVIF_IMAGE
;
845 lvItem
.iItem
= nItem
;
847 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
848 m_ListView
.SetItem(&lvItem
);
849 m_ListView
.Update(nItem
);
856 /**********************************************************
857 * ShellView_FillList()
859 * - gets the objectlist from the shellfolder
861 * - fills the list into the view
863 INT CALLBACK
CDefView::fill_list(LPVOID ptr
, LPVOID arg
)
865 PITEMID_CHILD pidl
= static_cast<PITEMID_CHILD
>(ptr
);
866 CDefView
*pThis
= static_cast<CDefView
*>(arg
);
868 /* in a commdlg This works as a filemask*/
869 if (pThis
->IncludeObject(pidl
) == S_OK
)
870 pThis
->LV_AddItem(pidl
);
876 HRESULT
CDefView::FillList()
878 CComPtr
<IEnumIDList
> pEnumIDList
;
884 DWORD dFlags
= SHCONTF_NONFOLDERS
| SHCONTF_FOLDERS
;
888 /* determine if there is a setting to show all the hidden files/folders */
889 if (RegOpenKeyExW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", 0, KEY_QUERY_VALUE
, &hKey
) == ERROR_SUCCESS
)
891 DWORD dataLength
, flagVal
;
893 dataLength
= sizeof(flagVal
);
894 if (RegQueryValueExW(hKey
, L
"Hidden", NULL
, NULL
, (LPBYTE
)&flagVal
, &dataLength
) == ERROR_SUCCESS
)
896 /* if the value is 1, then show all hidden files/folders */
899 dFlags
|= SHCONTF_INCLUDEHIDDEN
;
900 m_ListView
.SendMessageW(LVM_SETCALLBACKMASK
, LVIS_CUT
, 0);
908 /* get the itemlist from the shfolder */
909 hRes
= m_pSFParent
->EnumObjects(m_hWnd
, dFlags
, &pEnumIDList
);
917 /* create a pointer array */
918 hdpa
= DPA_Create(16);
921 return(E_OUTOFMEMORY
);
924 /* copy the items into the array*/
925 while((S_OK
== pEnumIDList
->Next(1, &pidl
, &dwFetched
)) && dwFetched
)
927 if (DPA_InsertPtr(hdpa
, 0x7fff, pidl
) == -1)
933 /*turn the listview's redrawing off*/
934 m_ListView
.SetRedraw(FALSE
);
936 DPA_DestroyCallback( hdpa
, fill_list
, this);
941 m_pSF2Parent
->GetDefaultColumn(NULL
, (ULONG
*)&m_sortInfo
.nHeaderID
, NULL
);
945 FIXME("no m_pSF2Parent\n");
947 m_sortInfo
.bIsAscending
= TRUE
;
950 /*turn the listview's redrawing back on and force it to draw*/
951 m_ListView
.SetRedraw(TRUE
);
956 LRESULT
CDefView::OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
958 m_ListView
.UpdateWindow();
963 LRESULT
CDefView::OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
965 return m_ListView
.SendMessageW(uMsg
, 0, 0);
968 LRESULT
CDefView::OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
975 DestroyMenu(m_hMenu
);
978 RevokeDragDrop(m_hWnd
);
979 SHChangeNotifyDeregister(m_hNotify
);
981 SHFree(m_pidlParent
);
988 LRESULT
CDefView::OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
990 /* redirect to parent */
991 if (m_FolderSettings
.fFlags
& (FWF_DESKTOP
| FWF_TRANSPARENT
))
992 return SendMessageW(GetParent(), WM_ERASEBKGND
, wParam
, lParam
);
998 LRESULT
CDefView::OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1000 /* Update desktop labels color */
1003 /* Forward WM_SYSCOLORCHANGE to common controls */
1004 return m_ListView
.SendMessageW(uMsg
, 0, 0);
1007 LRESULT
CDefView::OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1009 return reinterpret_cast<LRESULT
>(m_pShellBrowser
.p
);
1012 LRESULT
CDefView::OnNCCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1019 LRESULT
CDefView::OnNCDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1026 /**********************************************************
1027 * ShellView_OnCreate()
1029 LRESULT
CDefView::OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1031 CComPtr
<IDropTarget
> pdt
;
1032 SHChangeNotifyEntry ntreg
;
1033 CComPtr
<IPersistFolder2
> ppf2
;
1035 TRACE("%p\n", this);
1045 if (SUCCEEDED(QueryInterface(IID_PPV_ARG(IDropTarget
, &pdt
))))
1047 if (FAILED(RegisterDragDrop(m_hWnd
, pdt
)))
1048 ERR("Registering Drag Drop Failed");
1051 /* register for receiving notifications */
1052 m_pSFParent
->QueryInterface(IID_PPV_ARG(IPersistFolder2
, &ppf2
));
1055 ppf2
->GetCurFolder(&m_pidlParent
);
1056 ntreg
.fRecursive
= TRUE
;
1057 ntreg
.pidl
= m_pidlParent
;
1058 m_hNotify
= SHChangeNotifyRegister(m_hWnd
, SHCNRF_InterruptLevel
| SHCNRF_ShellLevel
, SHCNE_ALLEVENTS
, SHV_CHANGE_NOTIFY
, 1, &ntreg
);
1061 m_hAccel
= LoadAcceleratorsW(shell32_hInstance
, MAKEINTRESOURCEW(IDA_SHELLVIEW
));
1068 /**********************************************************
1069 * #### Handling of the menus ####
1072 extern "C" DWORD WINAPI
SHMenuIndexFromID(HMENU hMenu
, UINT uID
);
1074 HMENU
GetSubmenuByID(HMENU hmenu
, UINT id
)
1076 MENUITEMINFOW mii
= {sizeof(mii
), MIIM_SUBMENU
};
1077 if (::GetMenuItemInfoW(hmenu
, id
, FALSE
, &mii
))
1078 return mii
.hSubMenu
;
1083 /* ReallyGetMenuItemID returns the id of an item even if it opens a submenu,
1084 GetMenuItemID returns -1 if the specified item opens a submenu */
1085 UINT
ReallyGetMenuItemID(HMENU hmenu
, int i
)
1087 MENUITEMINFOW mii
= {sizeof(mii
), MIIM_ID
};
1088 if (::GetMenuItemInfoW(hmenu
, i
, TRUE
, &mii
))
1094 HRESULT
CDefView::FillFileMenu()
1096 HMENU hFileMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_FILE
);
1100 /* Cleanup the items added previously */
1101 for (int i
= GetMenuItemCount(hFileMenu
) - 1; i
>= 0; i
--)
1103 UINT id
= GetMenuItemID(hFileMenu
, i
);
1104 if (id
< FCIDM_BROWSERFIRST
|| id
> FCIDM_BROWSERLAST
)
1105 DeleteMenu(hFileMenu
, i
, MF_BYPOSITION
);
1108 /* Store the context menu in m_pCM and keep it in order to invoke the selected command later on */
1109 HRESULT hr
= GetItemObject(SVGIO_SELECTION
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1110 if (FAILED_UNEXPECTEDLY(hr
))
1113 HMENU hmenu
= CreatePopupMenu();
1115 hr
= m_pCM
->QueryContextMenu(hmenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, 0);
1116 if (FAILED_UNEXPECTEDLY(hr
))
1119 // TODO: filter or something
1121 Shell_MergeMenus(hFileMenu
, hmenu
, 0, 0, 0xFFFF, MM_ADDSEPARATOR
| MM_SUBMENUSHAVEIDS
);
1123 ::DestroyMenu(hmenu
);
1128 HRESULT
CDefView::FillEditMenu()
1130 HMENU hEditMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_EDIT
);
1134 HMENU hmenuContents
= ::LoadMenuW(shell32_hInstance
, L
"MENU_003");
1138 Shell_MergeMenus(hEditMenu
, hmenuContents
, 0, 0, 0xFFFF, 0);
1140 ::DestroyMenu(hmenuContents
);
1145 HRESULT
CDefView::FillViewMenu()
1147 HMENU hViewMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_VIEW
);
1151 m_hMenuViewModes
= ::LoadMenuW(shell32_hInstance
, L
"MENU_001");
1152 if (!m_hMenuViewModes
)
1155 UINT i
= SHMenuIndexFromID(hViewMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
);
1156 Shell_MergeMenus(hViewMenu
, m_hMenuViewModes
, i
, 0, 0xFFFF, MM_ADDSEPARATOR
| MM_DONTREMOVESEPS
| MM_SUBMENUSHAVEIDS
);
1161 HRESULT
CDefView::FillArrangeAsMenu(HMENU hmenuArrange
)
1163 /* We only need to fill this once */
1164 if (GetMenuItemID(hmenuArrange
, 0) == FCIDM_SHVIEW_AUTOARRANGE
)
1166 Shell_MergeMenus(hmenuArrange
, m_hMenuArrangeModes
, 0, 0, 0xFFFF,0);
1169 /* Also check the menu item according to which we sort */
1170 CheckMenuRadioItem(hmenuArrange
,
1173 m_sortInfo
.nHeaderID
+ 0x30,
1179 HRESULT
CDefView::CheckViewMode(HMENU hmenuView
)
1181 if (m_FolderSettings
.ViewMode
>= FVM_FIRST
&& m_FolderSettings
.ViewMode
<= FVM_LAST
)
1183 UINT iItemFirst
= FCIDM_SHVIEW_BIGICON
;
1184 UINT iItemLast
= iItemFirst
+ FVM_LAST
- FVM_FIRST
;
1185 UINT iItem
= iItemFirst
+ m_FolderSettings
.ViewMode
- FVM_FIRST
;
1186 CheckMenuRadioItem(hmenuView
, iItemFirst
, iItemLast
, iItem
, MF_BYCOMMAND
);
1192 /**********************************************************
1193 * ShellView_GetSelections()
1195 * - fills the m_apidl list with the selected objects
1198 * number of selected items
1200 UINT
CDefView::GetSelections()
1204 m_cidl
= m_ListView
.GetSelectedCount();
1205 m_apidl
= static_cast<PCUITEMID_CHILD
*>(SHAlloc(m_cidl
* sizeof(PCUITEMID_CHILD
)));
1212 TRACE("-- Items selected =%u\n", m_cidl
);
1216 while ((lvIndex
= m_ListView
.GetNextItem(lvIndex
, LVNI_SELECTED
)) > -1)
1218 m_apidl
[i
] = _PidlByItem(lvIndex
);
1222 TRACE("-- selected Item found\n");
1228 HRESULT
CDefView::InvokeContextMenuCommand(UINT uCommand
)
1230 CMINVOKECOMMANDINFO cmi
;
1232 ZeroMemory(&cmi
, sizeof(cmi
));
1233 cmi
.cbSize
= sizeof(cmi
);
1234 cmi
.lpVerb
= MAKEINTRESOURCEA(uCommand
);
1237 if (GetKeyState(VK_SHIFT
) & 0x8000)
1238 cmi
.fMask
|= CMIC_MASK_SHIFT_DOWN
;
1240 if (GetKeyState(VK_CONTROL
) & 0x8000)
1241 cmi
.fMask
|= CMIC_MASK_CONTROL_DOWN
;
1243 HRESULT hr
= m_pCM
->InvokeCommand(&cmi
);
1244 if (FAILED_UNEXPECTEDLY(hr
))
1250 /**********************************************************
1251 * ShellView_OpenSelectedItems()
1253 HRESULT
CDefView::OpenSelectedItems()
1259 m_cidl
= m_ListView
.GetSelectedCount();
1263 hResult
= OnDefaultCommand();
1264 if (hResult
== S_OK
)
1267 hMenu
= CreatePopupMenu();
1271 hResult
= GetItemObject(SVGIO_SELECTION
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1272 if (FAILED_UNEXPECTEDLY(hResult
))
1275 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_DEFAULTONLY
);
1276 if (FAILED_UNEXPECTEDLY(hResult
))
1279 uCommand
= GetMenuDefaultItem(hMenu
, FALSE
, 0);
1280 if (uCommand
== (UINT
)-1)
1286 InvokeContextMenuCommand(uCommand
);
1295 IUnknown_SetSite(m_pCM
, NULL
);
1302 /**********************************************************
1303 * ShellView_DoContextMenu()
1305 LRESULT
CDefView::OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1314 TRACE("(%p)->(0x%08x 0x%08x) stub\n", this, x
, y
);
1316 m_hContextMenu
= CreatePopupMenu();
1317 if (!m_hContextMenu
)
1320 m_cidl
= m_ListView
.GetSelectedCount();
1322 hResult
= GetItemObject( m_cidl
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1323 if (FAILED_UNEXPECTEDLY(hResult
))
1326 /* Use 1 as the first id as we want 0 the mean that the user canceled the menu */
1327 hResult
= m_pCM
->QueryContextMenu(m_hContextMenu
, 0, CONTEXT_MENU_BASE_ID
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1328 if (FAILED_UNEXPECTEDLY(hResult
))
1331 uCommand
= TrackPopupMenu(m_hContextMenu
,
1332 TPM_LEFTALIGN
| TPM_RETURNCMD
| TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
,
1333 x
, y
, 0, m_hWnd
, NULL
);
1337 if (uCommand
== FCIDM_SHVIEW_OPEN
&& OnDefaultCommand() == S_OK
)
1340 InvokeContextMenuCommand(uCommand
- CONTEXT_MENU_BASE_ID
);
1345 IUnknown_SetSite(m_pCM
, NULL
);
1351 DestroyMenu(m_hContextMenu
);
1352 m_hContextMenu
= NULL
;
1358 LRESULT
CDefView::OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
)
1363 hMenu
= CreatePopupMenu();
1367 hResult
= GetItemObject( bUseSelection
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1368 if (FAILED_UNEXPECTEDLY( hResult
))
1371 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1372 if (FAILED_UNEXPECTEDLY( hResult
))
1375 InvokeContextMenuCommand(uCommand
);
1380 IUnknown_SetSite(m_pCM
, NULL
);
1390 /**********************************************************
1391 * ##### message handling #####
1394 /**********************************************************
1395 * ShellView_OnSize()
1397 LRESULT
CDefView::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1399 WORD wWidth
, wHeight
;
1401 wWidth
= LOWORD(lParam
);
1402 wHeight
= HIWORD(lParam
);
1404 TRACE("%p width=%u height=%u\n", this, wWidth
, wHeight
);
1406 /* Resize the ListView to fit our window */
1409 ::MoveWindow(m_ListView
, 0, 0, wWidth
, wHeight
, TRUE
);
1415 /**********************************************************
1416 * ShellView_OnDeactivate()
1421 void CDefView::OnDeactivate()
1423 TRACE("%p\n", this);
1425 if (m_uState
!= SVUIA_DEACTIVATE
)
1427 // TODO: cleanup menu after deactivation
1429 m_uState
= SVUIA_DEACTIVATE
;
1433 void CDefView::DoActivate(UINT uState
)
1435 TRACE("%p uState=%x\n", this, uState
);
1437 /*don't do anything if the state isn't really changing */
1438 if (m_uState
== uState
)
1443 if (uState
== SVUIA_DEACTIVATE
)
1449 if(m_hMenu
&& !m_bmenuBarInitialized
)
1453 m_pShellBrowser
->SetMenuSB(m_hMenu
, 0, m_hWnd
);
1454 m_bmenuBarInitialized
= TRUE
;
1457 if (SVUIA_ACTIVATE_FOCUS
== uState
)
1459 m_ListView
.SetFocus();
1467 /**********************************************************
1468 * ShellView_OnActivate()
1470 LRESULT
CDefView::OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1472 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1476 /**********************************************************
1477 * ShellView_OnSetFocus()
1480 LRESULT
CDefView::OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1482 TRACE("%p\n", this);
1484 /* Tell the browser one of our windows has received the focus. This
1485 should always be done before merging menus (OnActivate merges the
1486 menus) if one of our windows has the focus.*/
1488 m_pShellBrowser
->OnViewWindowActive(this);
1489 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1491 /* Set the focus to the listview */
1492 m_ListView
.SetFocus();
1494 /* Notify the ICommDlgBrowser interface */
1495 OnStateChange(CDBOSC_SETFOCUS
);
1500 /**********************************************************
1501 * ShellView_OnKillFocus()
1503 LRESULT
CDefView::OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1505 TRACE("(%p) stub\n", this);
1507 DoActivate(SVUIA_ACTIVATE_NOFOCUS
);
1508 /* Notify the ICommDlgBrowser */
1509 OnStateChange(CDBOSC_KILLFOCUS
);
1514 /**********************************************************
1515 * ShellView_OnCommand()
1518 * the CmdID's are the ones from the context menu
1520 LRESULT
CDefView::OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1527 dwCmdID
= GET_WM_COMMAND_ID(wParam
, lParam
);
1528 dwCmd
= GET_WM_COMMAND_CMD(wParam
, lParam
);
1529 hwndCmd
= GET_WM_COMMAND_HWND(wParam
, lParam
);
1531 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n", this, dwCmdID
, dwCmd
, hwndCmd
);
1535 case FCIDM_SHVIEW_SMALLICON
:
1536 m_FolderSettings
.ViewMode
= FVM_SMALLICON
;
1537 SetStyle (LVS_SMALLICON
, LVS_TYPEMASK
);
1541 case FCIDM_SHVIEW_BIGICON
:
1542 m_FolderSettings
.ViewMode
= FVM_ICON
;
1543 SetStyle (LVS_ICON
, LVS_TYPEMASK
);
1547 case FCIDM_SHVIEW_LISTVIEW
:
1548 m_FolderSettings
.ViewMode
= FVM_LIST
;
1549 SetStyle (LVS_LIST
, LVS_TYPEMASK
);
1553 case FCIDM_SHVIEW_REPORTVIEW
:
1554 m_FolderSettings
.ViewMode
= FVM_DETAILS
;
1555 SetStyle (LVS_REPORT
, LVS_TYPEMASK
);
1559 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1564 m_sortInfo
.nHeaderID
= dwCmdID
- 0x30;
1565 m_sortInfo
.bIsAscending
= TRUE
;
1569 case FCIDM_SHVIEW_SNAPTOGRID
:
1570 case FCIDM_SHVIEW_AUTOARRANGE
:
1573 case FCIDM_SHVIEW_SELECTALL
:
1574 m_ListView
.SetItemState(-1, LVIS_SELECTED
, LVIS_SELECTED
);
1577 case FCIDM_SHVIEW_INVERTSELECTION
:
1578 nCount
= m_ListView
.GetItemCount();
1579 for (int i
=0; i
< nCount
; i
++)
1580 m_ListView
.SetItemState(i
, m_ListView
.GetItemState(i
, LVIS_SELECTED
) ? 0 : LVIS_SELECTED
, LVIS_SELECTED
);
1583 case FCIDM_SHVIEW_REFRESH
:
1587 case FCIDM_SHVIEW_DELETE
:
1588 case FCIDM_SHVIEW_CUT
:
1589 case FCIDM_SHVIEW_COPY
:
1590 case FCIDM_SHVIEW_RENAME
:
1591 case FCIDM_SHVIEW_PROPERTIES
:
1592 return OnExplorerCommand(dwCmdID
, TRUE
);
1594 case FCIDM_SHVIEW_INSERT
:
1595 case FCIDM_SHVIEW_UNDO
:
1596 case FCIDM_SHVIEW_INSERTLINK
:
1597 case FCIDM_SHVIEW_NEWFOLDER
:
1598 return OnExplorerCommand(dwCmdID
, FALSE
);
1600 /* WM_COMMAND messages from the file menu are routed to the CDefView so as to let m_pCM handle the command */
1601 if (m_pCM
&& dwCmd
== 0)
1603 InvokeContextMenuCommand(dwCmdID
);
1610 /**********************************************************
1611 * ShellView_OnNotify()
1614 LRESULT
CDefView::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1618 LPNMLISTVIEW lpnmlv
;
1619 NMLVDISPINFOW
*lpdi
;
1620 PCUITEMID_CHILD pidl
;
1624 lpnmh
= (LPNMHDR
)lParam
;
1625 lpnmlv
= (LPNMLISTVIEW
)lpnmh
;
1626 lpdi
= (NMLVDISPINFOW
*)lpnmh
;
1628 TRACE("%p CtlID=%u lpnmh->code=%x\n", this, CtlID
, lpnmh
->code
);
1630 switch (lpnmh
->code
)
1633 TRACE("-- NM_SETFOCUS %p\n", this);
1634 OnSetFocus(0, 0, 0, unused
);
1638 TRACE("-- NM_KILLFOCUS %p\n", this);
1640 /* Notify the ICommDlgBrowser interface */
1641 OnStateChange(CDBOSC_KILLFOCUS
);
1645 TRACE("-- NM_CUSTOMDRAW %p\n", this);
1646 return CDRF_DODEFAULT
;
1648 case NM_RELEASEDCAPTURE
:
1649 TRACE("-- NM_RELEASEDCAPTURE %p\n", this);
1653 TRACE("-- NM_CLICK %p\n", this);
1657 TRACE("-- NM_RCLICK %p\n", this);
1661 TRACE("-- NM_DBLCLK %p\n", this);
1662 OpenSelectedItems();
1666 TRACE("-- NM_RETURN %p\n", this);
1667 OpenSelectedItems();
1671 TRACE("-- HDN_ENDTRACKW %p\n", this);
1672 /*nColumn1 = m_ListView.GetColumnWidth(0);
1673 nColumn2 = m_ListView.GetColumnWidth(1);*/
1676 case LVN_DELETEITEM
:
1677 TRACE("-- LVN_DELETEITEM %p\n", this);
1679 /*delete the pidl because we made a copy of it*/
1680 SHFree(reinterpret_cast<LPVOID
>(lpnmlv
->lParam
));
1684 case LVN_DELETEALLITEMS
:
1685 TRACE("-- LVN_DELETEALLITEMS %p\n", this);
1688 case LVN_INSERTITEM
:
1689 TRACE("-- LVN_INSERTITEM (STUB)%p\n", this);
1692 case LVN_ITEMACTIVATE
:
1693 TRACE("-- LVN_ITEMACTIVATE %p\n", this);
1694 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1697 case LVN_COLUMNCLICK
:
1698 m_sortInfo
.nHeaderID
= lpnmlv
->iSubItem
;
1699 if (m_sortInfo
.nLastHeaderID
== m_sortInfo
.nHeaderID
)
1700 m_sortInfo
.bIsAscending
= !m_sortInfo
.bIsAscending
;
1702 m_sortInfo
.bIsAscending
= TRUE
;
1706 case LVN_GETDISPINFOA
:
1707 case LVN_GETDISPINFOW
:
1708 TRACE("-- LVN_GETDISPINFO %p\n", this);
1709 pidl
= _PidlByItem(lpdi
->item
);
1711 if (lpdi
->item
.mask
& LVIF_TEXT
) /* text requested */
1716 if (FAILED_UNEXPECTEDLY(m_pSF2Parent
->GetDetailsOf(pidl
, lpdi
->item
.iSubItem
, &sd
)))
1719 if (lpnmh
->code
== LVN_GETDISPINFOA
)
1721 /* shouldn't happen */
1722 NMLVDISPINFOA
*lpdiA
= (NMLVDISPINFOA
*)lpnmh
;
1723 StrRetToStrNA( lpdiA
->item
.pszText
, lpdiA
->item
.cchTextMax
, &sd
.str
, NULL
);
1724 TRACE("-- text=%s\n", lpdiA
->item
.pszText
);
1726 else /* LVN_GETDISPINFOW */
1728 StrRetToStrNW( lpdi
->item
.pszText
, lpdi
->item
.cchTextMax
, &sd
.str
, NULL
);
1729 TRACE("-- text=%s\n", debugstr_w(lpdi
->item
.pszText
));
1734 FIXME("no m_pSF2Parent\n");
1737 if(lpdi
->item
.mask
& LVIF_IMAGE
) /* image requested */
1739 lpdi
->item
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
1741 if(lpdi
->item
.mask
& LVIF_STATE
)
1743 ULONG attributes
= SFGAO_HIDDEN
;
1744 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(1, &pidl
, &attributes
)))
1746 if (attributes
& SFGAO_HIDDEN
)
1748 lpdi
->item
.state
|= LVIS_CUT
;
1752 lpdi
->item
.mask
|= LVIF_DI_SETITEM
;
1755 case LVN_ITEMCHANGED
:
1756 TRACE("-- LVN_ITEMCHANGED %p\n", this);
1757 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1762 case LVN_BEGINRDRAG
:
1763 TRACE("-- LVN_BEGINDRAG\n");
1765 if (GetSelections())
1767 CComPtr
<IDataObject
> pda
;
1768 DWORD dwAttributes
= SFGAO_CANLINK
;
1769 DWORD dwEffect
= DROPEFFECT_COPY
| DROPEFFECT_MOVE
;
1771 if (SUCCEEDED(m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, IID_NULL_PPV_ARG(IDataObject
, &pda
))))
1773 LPNMLISTVIEW params
= (LPNMLISTVIEW
)lParam
;
1775 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(m_cidl
, m_apidl
, &dwAttributes
)))
1777 if (dwAttributes
& SFGAO_CANLINK
)
1779 dwEffect
|= DROPEFFECT_LINK
;
1783 CComPtr
<IAsyncOperation
> piaso
;
1784 if (SUCCEEDED(pda
->QueryInterface(IID_PPV_ARG(IAsyncOperation
, &piaso
))))
1786 piaso
->SetAsyncMode(TRUE
);
1791 m_pSourceDataObject
= pda
;
1792 m_ptFirstMousePos
= params
->ptAction
;
1793 ClientToScreen(&m_ptFirstMousePos
);
1795 HIMAGELIST big_icons
, small_icons
;
1796 Shell_GetImageLists(&big_icons
, &small_icons
);
1797 PCUITEMID_CHILD pidl
= _PidlByItem(params
->iItem
);
1798 int iIcon
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
1800 m_ListView
.GetItemPosition(params
->iItem
, &ptItem
);
1802 ImageList_BeginDrag(big_icons
, iIcon
, params
->ptAction
.x
- ptItem
.x
, params
->ptAction
.y
- ptItem
.y
);
1804 DoDragDrop(pda
, this, dwEffect
, &dwEffect2
);
1806 m_pSourceDataObject
.Release();
1811 case LVN_BEGINLABELEDITW
:
1813 DWORD dwAttr
= SFGAO_CANRENAME
;
1814 pidl
= _PidlByItem(lpdi
->item
);
1816 TRACE("-- LVN_BEGINLABELEDITW %p\n", this);
1818 m_pSFParent
->GetAttributesOf(1, &pidl
, &dwAttr
);
1819 if (SFGAO_CANRENAME
& dwAttr
)
1827 case LVN_ENDLABELEDITW
:
1829 TRACE("-- LVN_ENDLABELEDITW %p\n", this);
1831 m_isEditing
= FALSE
;
1833 if (lpdi
->item
.pszText
)
1838 pidl
= _PidlByItem(lpdi
->item
);
1839 PITEMID_CHILD pidlNew
;
1840 hr
= m_pSFParent
->SetNameOf(0, pidl
, lpdi
->item
.pszText
, SHGDN_INFOLDER
, &pidlNew
);
1842 if (SUCCEEDED(hr
) && pidlNew
)
1844 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
1845 lvItem
.iItem
= lpdi
->item
.iItem
;
1846 lvItem
.iSubItem
= 0;
1847 lvItem
.lParam
= reinterpret_cast<LPARAM
>(pidlNew
);
1848 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
1849 m_ListView
.SetItem(&lvItem
);
1850 m_ListView
.Update(lpdi
->item
.iItem
);
1859 TRACE("-- %p WM_COMMAND %x unhandled\n", this, lpnmh
->code
);
1867 * This is just a quick hack to make the desktop work correctly.
1868 * ITranslateShellChangeNotify's IsChildID is undocumented, but most likely the way that
1869 * a folder should know if it should update upon a change notification.
1870 * It is exported by merged folders at a minimum.
1872 static BOOL
ILIsParentOrSpecialParent(PCIDLIST_ABSOLUTE pidl1
, PCIDLIST_ABSOLUTE pidl2
)
1874 if (!pidl1
|| !pidl2
)
1876 if (ILIsParent(pidl1
, pidl2
, TRUE
))
1879 if (_ILIsDesktop(pidl1
))
1881 PIDLIST_ABSOLUTE deskpidl
;
1882 SHGetFolderLocation(NULL
, CSIDL_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
1883 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
1889 SHGetFolderLocation(NULL
, CSIDL_COMMON_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
1890 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
1900 /**********************************************************
1901 * ShellView_OnChange()
1903 LRESULT
CDefView::OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1905 PCIDLIST_ABSOLUTE
*Pidls
= reinterpret_cast<PCIDLIST_ABSOLUTE
*>(wParam
);
1906 BOOL bParent0
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[0]);
1907 BOOL bParent1
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[1]);
1909 TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls
[0], Pidls
[1], lParam
);
1911 switch (lParam
&~ SHCNE_INTERRUPT
)
1917 if (LV_FindItemByPidl(ILFindLastID(Pidls
[0])) == -1)
1919 LV_AddItem(ILFindLastID(Pidls
[0]));
1923 LV_ProdItem(ILFindLastID(Pidls
[0]));
1931 LV_DeleteItem(ILFindLastID(Pidls
[0]));
1934 case SHCNE_RENAMEFOLDER
:
1935 case SHCNE_RENAMEITEM
:
1936 if (bParent0
&& bParent1
)
1937 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[1]));
1939 LV_DeleteItem(ILFindLastID(Pidls
[0]));
1941 LV_AddItem(ILFindLastID(Pidls
[1]));
1944 case SHCNE_UPDATEITEM
:
1946 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[0]));
1949 case SHCNE_UPDATEDIR
:
1956 HRESULT
SHGetMenuIdFromMenuMsg(UINT uMsg
, LPARAM lParam
, UINT
*CmdId
);
1957 HRESULT
SHSetMenuIdInMenuMsg(UINT uMsg
, LPARAM lParam
, UINT CmdId
);
1959 /**********************************************************
1960 * CDefView::OnCustomItem
1962 LRESULT
CDefView::OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1967 ERR("no menu!!!\n");
1971 /* The lParam of WM_DRAWITEM WM_MEASUREITEM contain a menu id and this also needs to
1972 be changed to a menu identifier offset */
1974 HRESULT hres
= SHGetMenuIdFromMenuMsg(uMsg
, lParam
, &CmdID
);
1975 if (SUCCEEDED(hres
))
1976 SHSetMenuIdInMenuMsg(uMsg
, lParam
, CmdID
- CONTEXT_MENU_BASE_ID
);
1978 /* Forward the message to the IContextMenu2 */
1980 hres
= SHForwardContextMenuMsg(m_pCM
, uMsg
, wParam
, lParam
, &result
, TRUE
);
1982 return (SUCCEEDED(hres
));
1985 LRESULT
CDefView::OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1987 /* Wallpaper setting affects drop shadows effect */
1988 if (wParam
== SPI_SETDESKWALLPAPER
|| wParam
== 0)
1994 /**********************************************************
1995 * CDefView::OnInitMenuPopup
1997 LRESULT
CDefView::OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1999 HMENU hmenu
= (HMENU
) wParam
;
2000 int nPos
= LOWORD(lParam
);
2003 OnCustomItem(uMsg
, wParam
, lParam
, bHandled
);
2005 HMENU hViewMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_VIEW
);
2007 /* Lets try to find out what the hell wParam is */
2008 if (hmenu
== GetSubMenu(m_hMenu
, nPos
))
2009 menuItemId
= ReallyGetMenuItemID(m_hMenu
, nPos
);
2010 else if (hViewMenu
&& hmenu
== GetSubMenu(hViewMenu
, nPos
))
2011 menuItemId
= ReallyGetMenuItemID(hViewMenu
, nPos
);
2012 else if (m_hContextMenu
&& hmenu
== GetSubMenu(m_hContextMenu
, nPos
))
2013 menuItemId
= ReallyGetMenuItemID(m_hContextMenu
, nPos
);
2019 case FCIDM_MENU_FILE
:
2022 case FCIDM_MENU_VIEW
:
2023 case FCIDM_SHVIEW_VIEW
:
2024 CheckViewMode(hmenu
);
2026 case FCIDM_SHVIEW_ARRANGE
:
2027 FillArrangeAsMenu(hmenu
);
2034 /**********************************************************
2037 * The INTERFACE of the IShellView object
2040 **********************************************************
2043 /**********************************************************
2044 * ShellView_GetWindow
2046 HRESULT WINAPI
CDefView::GetWindow(HWND
*phWnd
)
2048 TRACE("(%p)\n", this);
2055 HRESULT WINAPI
CDefView::ContextSensitiveHelp(BOOL fEnterMode
)
2057 FIXME("(%p) stub\n", this);
2062 /**********************************************************
2063 * IShellView_TranslateAccelerator
2066 * use the accel functions
2068 HRESULT WINAPI
CDefView::TranslateAccelerator(LPMSG lpmsg
)
2073 if (lpmsg
->message
>= WM_KEYFIRST
&& lpmsg
->message
<= WM_KEYLAST
)
2075 if (::TranslateAcceleratorW(m_hWnd
, m_hAccel
, lpmsg
) != 0)
2078 TRACE("-- key=0x04%lx\n", lpmsg
->wParam
) ;
2081 return m_pShellBrowser
->TranslateAcceleratorSB(lpmsg
, 0);
2084 HRESULT WINAPI
CDefView::EnableModeless(BOOL fEnable
)
2086 FIXME("(%p) stub\n", this);
2091 HRESULT WINAPI
CDefView::UIActivate(UINT uState
)
2093 // CHAR szName[MAX_PATH];
2095 int nPartArray
[1] = { -1};
2097 TRACE("(%p)->(state=%x) stub\n", this, uState
);
2099 /* don't do anything if the state isn't really changing */
2100 if (m_uState
== uState
)
2105 /* OnActivate handles the menu merging and internal state */
2108 /* only do This if we are active */
2109 if (uState
!= SVUIA_DEACTIVATE
)
2113 GetFolderPath is not a method of IShellFolder
2114 IShellFolder_GetFolderPath( m_pSFParent, szName, sizeof(szName) );
2116 /* set the number of parts */
2117 m_pShellBrowser
->SendControlMsg(FCW_STATUS
, SB_SETPARTS
, 1, (LPARAM
)nPartArray
, &lResult
);
2119 /* set the text for the parts */
2121 m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXTA, 0, (LPARAM)szName, &lResult);
2128 HRESULT WINAPI
CDefView::Refresh()
2130 TRACE("(%p)\n", this);
2132 m_ListView
.DeleteAllItems();
2138 HRESULT WINAPI
CDefView::CreateViewWindow(IShellView
*lpPrevView
, LPCFOLDERSETTINGS lpfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
)
2140 return CreateViewWindow3(psb
, lpPrevView
, SV3CVW3_DEFAULT
,
2141 (FOLDERFLAGS
)lpfs
->fFlags
, (FOLDERFLAGS
)lpfs
->fFlags
, (FOLDERVIEWMODE
)lpfs
->ViewMode
, NULL
, prcView
, phWnd
);
2144 HRESULT WINAPI
CDefView::DestroyViewWindow()
2146 TRACE("(%p)\n", this);
2148 /* Make absolutely sure all our UI is cleaned up */
2149 UIActivate(SVUIA_DEACTIVATE
);
2153 // "Accelerator tables loaded from resources are freed automatically when the application terminates." -- MSDN
2157 if (m_hMenuArrangeModes
)
2159 DestroyMenu(m_hMenuArrangeModes
);
2160 m_hMenuArrangeModes
= NULL
;
2163 if (m_hMenuViewModes
)
2165 DestroyMenu(m_hMenuViewModes
);
2166 m_hMenuViewModes
= NULL
;
2171 DestroyMenu(m_hMenu
);
2177 m_ListView
.DestroyWindow();
2185 m_pShellBrowser
.Release();
2186 m_pCommDlgBrowser
.Release();
2191 HRESULT WINAPI
CDefView::GetCurrentInfo(LPFOLDERSETTINGS lpfs
)
2193 TRACE("(%p)->(%p) vmode=%x flags=%x\n", this, lpfs
,
2194 m_FolderSettings
.ViewMode
, m_FolderSettings
.fFlags
);
2197 return E_INVALIDARG
;
2199 *lpfs
= m_FolderSettings
;
2203 HRESULT WINAPI
CDefView::AddPropertySheetPages(DWORD dwReserved
, LPFNADDPROPSHEETPAGE lpfn
, LPARAM lparam
)
2205 FIXME("(%p) stub\n", this);
2210 HRESULT WINAPI
CDefView::SaveViewState()
2212 FIXME("(%p) stub\n", this);
2217 HRESULT WINAPI
CDefView::SelectItem(PCUITEMID_CHILD pidl
, UINT uFlags
)
2221 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n", this, pidl
, uFlags
);
2223 i
= LV_FindItemByPidl(pidl
);
2227 if(uFlags
& SVSI_ENSUREVISIBLE
)
2228 m_ListView
.EnsureVisible(i
, FALSE
);
2230 LVITEMW lvItem
= {0};
2231 lvItem
.mask
= LVIF_STATE
;
2232 lvItem
.stateMask
= LVIS_SELECTED
| LVIS_FOCUSED
;
2234 while (m_ListView
.GetItem(&lvItem
))
2236 if (lvItem
.iItem
== i
)
2238 if (uFlags
& SVSI_SELECT
)
2239 lvItem
.state
|= LVIS_SELECTED
;
2241 lvItem
.state
&= ~LVIS_SELECTED
;
2243 if (uFlags
& SVSI_FOCUSED
)
2244 lvItem
.state
&= ~LVIS_FOCUSED
;
2248 if (uFlags
& SVSI_DESELECTOTHERS
)
2249 lvItem
.state
&= ~LVIS_SELECTED
;
2252 m_ListView
.SetItem(&lvItem
);
2256 if((uFlags
& SVSI_EDIT
) == SVSI_EDIT
)
2257 m_ListView
.EditLabel(i
);
2262 HRESULT WINAPI
CDefView::GetItemObject(UINT uItem
, REFIID riid
, LPVOID
*ppvOut
)
2264 HRESULT hr
= E_NOINTERFACE
;
2266 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n", this, uItem
, debugstr_guid(&riid
), ppvOut
);
2272 case SVGIO_BACKGROUND
:
2273 if (IsEqualIID(riid
, IID_IContextMenu
))
2278 hr
= CDefViewBckgrndMenu_CreateInstance(m_pSF2Parent
, riid
, ppvOut
);
2279 if (FAILED_UNEXPECTEDLY(hr
))
2282 IUnknown_SetSite(*((IUnknown
**)ppvOut
), (IShellView
*)this);
2284 else if (IsEqualIID(riid
, IID_IDispatch
))
2286 if (m_pShellFolderViewDual
== NULL
)
2288 hr
= CDefViewDual_Constructor(riid
, (LPVOID
*)&m_pShellFolderViewDual
);
2289 if (FAILED_UNEXPECTEDLY(hr
))
2292 hr
= m_pShellFolderViewDual
->QueryInterface(riid
, ppvOut
);
2296 case SVGIO_SELECTION
:
2298 hr
= m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, riid
, 0, ppvOut
);
2299 if (FAILED_UNEXPECTEDLY(hr
))
2302 if (IsEqualIID(riid
, IID_IContextMenu
))
2303 IUnknown_SetSite(*((IUnknown
**)ppvOut
), (IShellView
*)this);
2308 TRACE("-- (%p)->(interface=%p)\n", this, *ppvOut
);
2313 HRESULT STDMETHODCALLTYPE
CDefView::GetCurrentViewMode(UINT
*pViewMode
)
2315 TRACE("(%p)->(%p), stub\n", this, pViewMode
);
2318 return E_INVALIDARG
;
2320 *pViewMode
= m_FolderSettings
.ViewMode
;
2324 HRESULT STDMETHODCALLTYPE
CDefView::SetCurrentViewMode(UINT ViewMode
)
2327 TRACE("(%p)->(%u), stub\n", this, ViewMode
);
2329 /* It's not redundant to check FVM_AUTO because it's a (UINT)-1 */
2330 if (((INT
)ViewMode
< FVM_FIRST
|| (INT
)ViewMode
> FVM_LAST
) && ((INT
)ViewMode
!= FVM_AUTO
))
2331 return E_INVALIDARG
;
2333 /* Windows before Vista uses LVM_SETVIEW and possibly
2334 LVM_SETEXTENDEDLISTVIEWSTYLE to set the style of the listview,
2335 while later versions seem to accomplish this through other
2343 dwStyle
= LVS_REPORT
;
2346 dwStyle
= LVS_SMALLICON
;
2353 FIXME("ViewMode %d not implemented\n", ViewMode
);
2359 SetStyle(dwStyle
, LVS_TYPEMASK
);
2361 /* This will not necessarily be the actual mode set above.
2362 This mimics the behavior of Windows XP. */
2363 m_FolderSettings
.ViewMode
= ViewMode
;
2368 HRESULT STDMETHODCALLTYPE
CDefView::GetFolder(REFIID riid
, void **ppv
)
2370 if (m_pSFParent
== NULL
)
2373 return m_pSFParent
->QueryInterface(riid
, ppv
);
2376 HRESULT STDMETHODCALLTYPE
CDefView::Item(int iItemIndex
, PITEMID_CHILD
*ppidl
)
2378 PCUITEMID_CHILD pidl
= _PidlByItem(iItemIndex
);
2381 *ppidl
= ILClone(pidl
);
2386 return E_INVALIDARG
;
2389 HRESULT STDMETHODCALLTYPE
CDefView::ItemCount(UINT uFlags
, int *pcItems
)
2391 TRACE("(%p)->(%u %p)\n", this, uFlags
, pcItems
);
2393 if (uFlags
!= SVGIO_ALLVIEW
)
2394 FIXME("some flags unsupported, %x\n", uFlags
& ~SVGIO_ALLVIEW
);
2396 *pcItems
= m_ListView
.GetItemCount();
2401 HRESULT STDMETHODCALLTYPE
CDefView::Items(UINT uFlags
, REFIID riid
, void **ppv
)
2406 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectionMarkedItem(int *piItem
)
2408 TRACE("(%p)->(%p)\n", this, piItem
);
2410 *piItem
= m_ListView
.GetSelectionMark();
2415 HRESULT STDMETHODCALLTYPE
CDefView::GetFocusedItem(int *piItem
)
2417 TRACE("(%p)->(%p)\n", this, piItem
);
2419 *piItem
= m_ListView
.GetNextItem(-1, LVNI_FOCUSED
);
2424 HRESULT STDMETHODCALLTYPE
CDefView::GetItemPosition(PCUITEMID_CHILD pidl
, POINT
*ppt
)
2429 HRESULT STDMETHODCALLTYPE
CDefView::GetSpacing(POINT
*ppt
)
2431 TRACE("(%p)->(%p)\n", this, ppt
);
2439 m_ListView
.GetItemSpacing(spacing
);
2441 ppt
->x
= spacing
.cx
;
2442 ppt
->y
= spacing
.cy
;
2448 HRESULT STDMETHODCALLTYPE
CDefView::GetDefaultSpacing(POINT
*ppt
)
2453 HRESULT STDMETHODCALLTYPE
CDefView::GetAutoArrange()
2458 HRESULT STDMETHODCALLTYPE
CDefView::SelectItem(int iItem
, DWORD dwFlags
)
2462 TRACE("(%p)->(%d, %x)\n", this, iItem
, dwFlags
);
2465 lvItem
.stateMask
= LVIS_SELECTED
;
2467 if (dwFlags
& SVSI_ENSUREVISIBLE
)
2468 m_ListView
.EnsureVisible(iItem
, 0);
2471 if (dwFlags
& SVSI_DESELECTOTHERS
)
2472 m_ListView
.SetItemState(-1, 0, LVIS_SELECTED
);
2475 if (dwFlags
& SVSI_SELECT
)
2476 lvItem
.state
|= LVIS_SELECTED
;
2478 if (dwFlags
& SVSI_FOCUSED
)
2479 lvItem
.stateMask
|= LVIS_FOCUSED
;
2481 m_ListView
.SetItemState(iItem
, lvItem
.state
, lvItem
.stateMask
);
2483 if ((dwFlags
& SVSI_EDIT
) == SVSI_EDIT
)
2484 m_ListView
.EditLabel(iItem
);
2489 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItems(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD dwFlags
)
2494 /**********************************************************
2495 * IShellView2 implementation
2498 HRESULT STDMETHODCALLTYPE
CDefView::GetView(SHELLVIEWID
*view_guid
, ULONG view_type
)
2500 FIXME("(%p)->(%p, %lu) stub\n", this, view_guid
, view_type
);
2504 HRESULT STDMETHODCALLTYPE
CDefView::CreateViewWindow2(LPSV2CVW2_PARAMS view_params
)
2506 return CreateViewWindow3(view_params
->psbOwner
, view_params
->psvPrev
,
2507 SV3CVW3_DEFAULT
, (FOLDERFLAGS
)view_params
->pfs
->fFlags
, (FOLDERFLAGS
)view_params
->pfs
->fFlags
,
2508 (FOLDERVIEWMODE
)view_params
->pfs
->ViewMode
, view_params
->pvid
, view_params
->prcView
, &view_params
->hwndView
);
2511 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
)
2513 OLEMENUGROUPWIDTHS omw
= { { 0, 0, 0, 0, 0, 0 } };
2517 TRACE("(%p)->(shlview=%p shlbrs=%p rec=%p hwnd=%p vmode=%x flags=%x)\n", this, psvPrevious
, psb
, prcView
, hwnd
, mode
, flags
);
2518 if (prcView
!= NULL
)
2519 TRACE("-- left=%i top=%i right=%i bottom=%i\n", prcView
->left
, prcView
->top
, prcView
->right
, prcView
->bottom
);
2521 /* Validate the Shell Browser */
2522 if (psb
== NULL
|| m_hWnd
)
2523 return E_UNEXPECTED
;
2525 if (view_flags
!= SV3CVW3_DEFAULT
)
2526 FIXME("unsupported view flags 0x%08x\n", view_flags
);
2528 /* Set up the member variables */
2529 m_pShellBrowser
= psb
;
2530 m_FolderSettings
.ViewMode
= mode
;
2531 m_FolderSettings
.fFlags
= mask
& flags
;
2535 if (IsEqualIID(*view_id
, VID_LargeIcons
))
2536 m_FolderSettings
.ViewMode
= FVM_ICON
;
2537 else if (IsEqualIID(*view_id
, VID_SmallIcons
))
2538 m_FolderSettings
.ViewMode
= FVM_SMALLICON
;
2539 else if (IsEqualIID(*view_id
, VID_List
))
2540 m_FolderSettings
.ViewMode
= FVM_LIST
;
2541 else if (IsEqualIID(*view_id
, VID_Details
))
2542 m_FolderSettings
.ViewMode
= FVM_DETAILS
;
2543 else if (IsEqualIID(*view_id
, VID_Thumbnails
))
2544 m_FolderSettings
.ViewMode
= FVM_THUMBNAIL
;
2545 else if (IsEqualIID(*view_id
, VID_Tile
))
2546 m_FolderSettings
.ViewMode
= FVM_TILE
;
2547 else if (IsEqualIID(*view_id
, VID_ThumbStrip
))
2548 m_FolderSettings
.ViewMode
= FVM_THUMBSTRIP
;
2550 FIXME("Ignoring unrecognized VID %s\n", debugstr_guid(view_id
));
2553 /* Get our parent window */
2554 m_pShellBrowser
->GetWindow(&m_hWndParent
);
2556 /* Try to get the ICommDlgBrowserInterface, adds a reference !!! */
2557 m_pCommDlgBrowser
= NULL
;
2558 if (SUCCEEDED(m_pShellBrowser
->QueryInterface(IID_PPV_ARG(ICommDlgBrowser
, &m_pCommDlgBrowser
))))
2560 TRACE("-- CommDlgBrowser\n");
2563 Create(m_hWndParent
, prcView
, NULL
, WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
| WS_TABSTOP
, 0, 0U);
2574 SetWindowPos(HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_SHOWWINDOW
);
2579 m_hMenu
= CreateMenu();
2580 m_pShellBrowser
->InsertMenusSB(m_hMenu
, &omw
);
2581 TRACE("-- after fnInsertMenusSB\n");
2589 HRESULT STDMETHODCALLTYPE
CDefView::HandleRename(LPCITEMIDLIST new_pidl
)
2591 FIXME("(%p)->(%p) stub\n", this, new_pidl
);
2595 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItem(LPCITEMIDLIST item
, UINT flags
, POINT
*point
)
2597 FIXME("(%p)->(%p, %u, %p) stub\n", this, item
, flags
, point
);
2601 /**********************************************************
2602 * IShellFolderView implementation
2604 HRESULT STDMETHODCALLTYPE
CDefView::Rearrange(LPARAM sort
)
2606 FIXME("(%p)->(%ld) stub\n", this, sort
);
2610 HRESULT STDMETHODCALLTYPE
CDefView::GetArrangeParam(LPARAM
*sort
)
2612 FIXME("(%p)->(%p) stub\n", this, sort
);
2616 HRESULT STDMETHODCALLTYPE
CDefView::ArrangeGrid()
2618 FIXME("(%p) stub\n", this);
2622 HRESULT STDMETHODCALLTYPE
CDefView::AutoArrange()
2624 FIXME("(%p) stub\n", this);
2628 HRESULT STDMETHODCALLTYPE
CDefView::AddObject(PITEMID_CHILD pidl
, UINT
*item
)
2630 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2634 HRESULT STDMETHODCALLTYPE
CDefView::GetObject(PITEMID_CHILD
*pidl
, UINT item
)
2636 TRACE("(%p)->(%p %d)\n", this, pidl
, item
);
2637 return Item(item
, pidl
);
2640 HRESULT STDMETHODCALLTYPE
CDefView::RemoveObject(PITEMID_CHILD pidl
, UINT
*item
)
2643 TRACE("(%p)->(%p %p)\n", this, pidl
, item
);
2647 *item
= LV_FindItemByPidl(ILFindLastID(pidl
));
2648 m_ListView
.DeleteItem(*item
);
2653 m_ListView
.DeleteAllItems();
2659 HRESULT STDMETHODCALLTYPE
CDefView::GetObjectCount(UINT
*count
)
2661 TRACE("(%p)->(%p)\n", this, count
);
2662 *count
= m_ListView
.GetItemCount();
2666 HRESULT STDMETHODCALLTYPE
CDefView::SetObjectCount(UINT count
, UINT flags
)
2668 FIXME("(%p)->(%d %x) stub\n", this, count
, flags
);
2672 HRESULT STDMETHODCALLTYPE
CDefView::UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
)
2674 FIXME("(%p)->(%p %p %p) stub\n", this, pidl_old
, pidl_new
, item
);
2678 HRESULT STDMETHODCALLTYPE
CDefView::RefreshObject(PITEMID_CHILD pidl
, UINT
*item
)
2680 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2684 HRESULT STDMETHODCALLTYPE
CDefView::SetRedraw(BOOL redraw
)
2686 TRACE("(%p)->(%d)\n", this, redraw
);
2687 m_ListView
.SetRedraw(redraw
);
2691 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedCount(UINT
*count
)
2693 FIXME("(%p)->(%p) stub\n", this, count
);
2697 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
)
2699 TRACE("(%p)->(%p %p)\n", this, pidl
, items
);
2701 *items
= GetSelections();
2705 *pidl
= static_cast<PCUITEMID_CHILD
*>(LocalAlloc(0, *items
* sizeof(PCUITEMID_CHILD
)));
2708 return E_OUTOFMEMORY
;
2711 /* it's documented that caller shouldn't PIDLs, only array itself */
2712 memcpy(*pidl
, m_apidl
, *items
* sizeof(PCUITEMID_CHILD
));
2718 HRESULT STDMETHODCALLTYPE
CDefView::IsDropOnSource(IDropTarget
*drop_target
)
2720 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2724 HRESULT STDMETHODCALLTYPE
CDefView::GetDragPoint(POINT
*pt
)
2726 FIXME("(%p)->(%p) stub\n", this, pt
);
2730 HRESULT STDMETHODCALLTYPE
CDefView::GetDropPoint(POINT
*pt
)
2732 FIXME("(%p)->(%p) stub\n", this, pt
);
2736 HRESULT STDMETHODCALLTYPE
CDefView::MoveIcons(IDataObject
*obj
)
2738 TRACE("(%p)->(%p)\n", this, obj
);
2742 HRESULT STDMETHODCALLTYPE
CDefView::SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
)
2744 FIXME("(%p)->(%p %p) stub\n", this, pidl
, pt
);
2748 HRESULT STDMETHODCALLTYPE
CDefView::IsBkDropTarget(IDropTarget
*drop_target
)
2750 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2754 HRESULT STDMETHODCALLTYPE
CDefView::SetClipboard(BOOL move
)
2756 FIXME("(%p)->(%d) stub\n", this, move
);
2760 HRESULT STDMETHODCALLTYPE
CDefView::SetPoints(IDataObject
*obj
)
2762 FIXME("(%p)->(%p) stub\n", this, obj
);
2766 HRESULT STDMETHODCALLTYPE
CDefView::GetItemSpacing(ITEMSPACING
*spacing
)
2768 FIXME("(%p)->(%p) stub\n", this, spacing
);
2772 HRESULT STDMETHODCALLTYPE
CDefView::SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
)
2774 FIXME("(%p)->(%p %p) stub\n", this, new_cb
, old_cb
);
2778 HRESULT STDMETHODCALLTYPE
CDefView::Select(UINT flags
)
2780 FIXME("(%p)->(%d) stub\n", this, flags
);
2784 HRESULT STDMETHODCALLTYPE
CDefView::QuerySupport(UINT
*support
)
2786 TRACE("(%p)->(%p)\n", this, support
);
2790 HRESULT STDMETHODCALLTYPE
CDefView::SetAutomationObject(IDispatch
*disp
)
2792 FIXME("(%p)->(%p) stub\n", this, disp
);
2796 /**********************************************************
2797 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2799 HRESULT WINAPI
CDefView::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD
*prgCmds
, OLECMDTEXT
*pCmdText
)
2801 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
2802 this, pguidCmdGroup
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
2805 return E_INVALIDARG
;
2807 for (UINT i
= 0; i
< cCmds
; i
++)
2809 FIXME("\tprgCmds[%d].cmdID = %d\n", i
, prgCmds
[i
].cmdID
);
2810 prgCmds
[i
].cmdf
= 0;
2813 return OLECMDERR_E_UNKNOWNGROUP
;
2816 /**********************************************************
2817 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2819 * nCmdID is the OLECMDID_* enumeration
2821 HRESULT WINAPI
CDefView::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
2823 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2824 this, debugstr_guid(pguidCmdGroup
), nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2827 return OLECMDERR_E_UNKNOWNGROUP
;
2829 if (IsEqualCLSID(*pguidCmdGroup
, m_Category
))
2831 if (nCmdID
== FCIDM_SHVIEW_AUTOARRANGE
)
2833 if (V_VT(pvaIn
) != VT_INT_PTR
)
2834 return OLECMDERR_E_NOTSUPPORTED
;
2837 params
.cbSize
= sizeof(params
);
2838 params
.rcExclude
= *(RECT
*) V_INTREF(pvaIn
);
2840 if (m_hMenuViewModes
)
2842 /* Duplicate all but the last two items of the view modes menu */
2843 HMENU hmenuViewPopup
= CreatePopupMenu();
2844 Shell_MergeMenus(hmenuViewPopup
, m_hMenuViewModes
, 0, 0, 0xFFFF, 0);
2845 DeleteMenu(hmenuViewPopup
, GetMenuItemCount(hmenuViewPopup
) - 1, MF_BYPOSITION
);
2846 DeleteMenu(hmenuViewPopup
, GetMenuItemCount(hmenuViewPopup
) - 1, MF_BYPOSITION
);
2847 CheckViewMode(hmenuViewPopup
);
2848 TrackPopupMenuEx(hmenuViewPopup
, TPM_LEFTALIGN
| TPM_TOPALIGN
, params
.rcExclude
.left
, params
.rcExclude
.bottom
, m_hWndParent
, ¶ms
);
2849 ::DestroyMenu(hmenuViewPopup
);
2852 // pvaOut is VT_I4 with value 0x403 (cmd id of the new mode maybe?)
2853 V_VT(pvaOut
) = VT_I4
;
2854 V_I4(pvaOut
) = 0x403;
2858 if (IsEqualIID(*pguidCmdGroup
, CGID_Explorer
) &&
2860 (nCmdexecopt
== 4) && pvaOut
)
2863 if (IsEqualIID(*pguidCmdGroup
, CGID_ShellDocView
) &&
2868 return OLECMDERR_E_UNKNOWNGROUP
;
2871 /**********************************************************
2872 * ISVDropTarget implementation
2875 /******************************************************************************
2876 * drag_notify_subitem [Internal]
2878 * Figure out the shellfolder object, which is currently under the mouse cursor
2879 * and notify it via the IDropTarget interface.
2882 #define SCROLLAREAWIDTH 20
2884 HRESULT
CDefView::drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2890 /* Map from global to client coordinates and query the index of the listview-item, which is
2891 * currently under the mouse cursor. */
2892 LVHITTESTINFO htinfo
= {{pt
.x
, pt
.y
}, LVHT_ONITEM
};
2893 ScreenToClient(&htinfo
.pt
);
2894 lResult
= m_ListView
.HitTest(&htinfo
);
2896 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2897 ::GetClientRect(m_ListView
, &clientRect
);
2898 if (htinfo
.pt
.x
== m_ptLastMousePos
.x
&& htinfo
.pt
.y
== m_ptLastMousePos
.y
&&
2899 (htinfo
.pt
.x
< SCROLLAREAWIDTH
|| htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
||
2900 htinfo
.pt
.y
< SCROLLAREAWIDTH
|| htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
))
2902 m_cScrollDelay
= (m_cScrollDelay
+ 1) % 5; /* DragOver is called every 50 ms */
2903 if (m_cScrollDelay
== 0)
2905 /* Mouse did hover another 250 ms over the scroll-area */
2906 if (htinfo
.pt
.x
< SCROLLAREAWIDTH
)
2907 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEUP
, 0);
2909 if (htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
)
2910 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEDOWN
, 0);
2912 if (htinfo
.pt
.y
< SCROLLAREAWIDTH
)
2913 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEUP
, 0);
2915 if (htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
)
2916 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEDOWN
, 0);
2921 m_cScrollDelay
= 0; /* Reset, if the cursor is not over the listview's scroll-area */
2924 m_ptLastMousePos
= htinfo
.pt
;
2926 /* We need to check if we drag the selection over itself */
2927 if (lResult
!= -1 && m_pSourceDataObject
.p
!= NULL
)
2929 PCUITEMID_CHILD pidl
= _PidlByItem(lResult
);
2931 for (UINT i
= 0; i
< m_cidl
; i
++)
2933 if (pidl
== m_apidl
[i
])
2935 /* The item that is being draged is hovering itself. */
2942 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2943 if (m_pCurDropTarget
&& lResult
== m_iDragOverItem
)
2944 return m_pCurDropTarget
->DragOver(grfKeyState
, pt
, pdwEffect
);
2946 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2947 if (m_pCurDropTarget
)
2949 PCUITEMID_CHILD pidl
= _PidlByItem(m_iDragOverItem
);
2951 SelectItem(pidl
, 0);
2953 m_pCurDropTarget
->DragLeave();
2954 m_pCurDropTarget
.Release();
2957 m_iDragOverItem
= lResult
;
2961 /* We are not above one of the listview's subitems. Bind to the parent folder's
2962 * DropTarget interface. */
2963 hr
= m_pSFParent
->CreateViewObject(NULL
, IID_PPV_ARG(IDropTarget
,&m_pCurDropTarget
));
2967 /* Query the relative PIDL of the shellfolder object represented by the currently
2968 * dragged over listview-item ... */
2969 PCUITEMID_CHILD pidl
= _PidlByItem(lResult
);
2971 /* ... and bind m_pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2972 hr
= m_pSFParent
->GetUIObjectOf(m_ListView
, 1, &pidl
, IID_NULL_PPV_ARG(IDropTarget
, &m_pCurDropTarget
));
2975 /* If anything failed, m_pCurDropTarget should be NULL now, which ought to be a save state. */
2978 *pdwEffect
= DROPEFFECT_NONE
;
2982 if (m_iDragOverItem
!= -1)
2984 SelectItem(m_iDragOverItem
, SVSI_SELECT
);
2987 /* Notify the item just entered via DragEnter. */
2988 return m_pCurDropTarget
->DragEnter(m_pCurDataObject
, grfKeyState
, pt
, pdwEffect
);
2991 HRESULT WINAPI
CDefView::DragEnter(IDataObject
*pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2993 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2994 m_pCurDataObject
= pDataObject
;
2996 HRESULT hr
= drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2999 POINT ptClient
= {pt
.x
, pt
.y
};
3000 ScreenToClient(&ptClient
);
3001 ImageList_DragEnter(m_hWnd
, ptClient
.x
, ptClient
.y
);
3007 HRESULT WINAPI
CDefView::DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
3009 POINT ptClient
= {pt
.x
, pt
.y
};
3010 ScreenToClient(&ptClient
);
3011 ImageList_DragMove(ptClient
.x
, ptClient
.y
);
3012 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
3015 HRESULT WINAPI
CDefView::DragLeave()
3017 ImageList_DragLeave(m_hWnd
);
3019 if (m_pCurDropTarget
)
3021 m_pCurDropTarget
->DragLeave();
3022 m_pCurDropTarget
.Release();
3025 if (m_pCurDataObject
!= NULL
)
3027 m_pCurDataObject
.Release();
3030 m_iDragOverItem
= 0;
3035 HRESULT WINAPI
CDefView::Drop(IDataObject
* pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
3037 ERR("GetKeyState(VK_LBUTTON): %d\n", GetKeyState(VK_LBUTTON
));
3039 ImageList_DragLeave(m_hWnd
);
3040 ImageList_EndDrag();
3042 if ((m_iDragOverItem
== -1 || m_pCurDropTarget
== NULL
) &&
3043 (*pdwEffect
& DROPEFFECT_MOVE
) &&
3044 /*(GetKeyState(VK_LBUTTON) != 0) &&*/
3045 (m_pSourceDataObject
.p
) &&
3046 (SHIsSameObject(pDataObject
, m_pSourceDataObject
)))
3048 if (m_pCurDropTarget
)
3050 m_pCurDropTarget
->DragLeave();
3051 m_pCurDropTarget
.Release();
3054 /* Restore the selection */
3055 m_ListView
.SetItemState(-1, 0, LVIS_SELECTED
);
3056 for (UINT i
= 0 ; i
< m_cidl
; i
++)
3057 SelectItem(m_apidl
[i
], SVSI_SELECT
);
3059 /* Reposition the items */
3061 while ((lvIndex
= m_ListView
.GetNextItem(lvIndex
, LVNI_SELECTED
)) > -1)
3064 if (m_ListView
.GetItemPosition(lvIndex
, &ptItem
))
3066 ptItem
.x
+= pt
.x
- m_ptFirstMousePos
.x
;
3067 ptItem
.y
+= pt
.y
- m_ptFirstMousePos
.y
;
3068 m_ListView
.SetItemPosition(lvIndex
, &ptItem
);
3072 else if (m_pCurDropTarget
)
3074 m_pCurDropTarget
->Drop(pDataObject
, grfKeyState
, pt
, pdwEffect
);
3075 m_pCurDropTarget
.Release();
3078 m_pCurDataObject
.Release();
3079 m_iDragOverItem
= 0;
3083 /**********************************************************
3084 * ISVDropSource implementation
3087 HRESULT WINAPI
CDefView::QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
)
3089 TRACE("(%p)\n", this);
3092 return DRAGDROP_S_CANCEL
;
3093 else if (!(grfKeyState
& MK_LBUTTON
) && !(grfKeyState
& MK_RBUTTON
))
3094 return DRAGDROP_S_DROP
;
3099 HRESULT WINAPI
CDefView::GiveFeedback(DWORD dwEffect
)
3101 TRACE("(%p)\n", this);
3103 return DRAGDROP_S_USEDEFAULTCURSORS
;
3106 /**********************************************************
3107 * ISVViewObject implementation
3110 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
)
3112 FIXME("Stub: this=%p\n", this);
3117 HRESULT WINAPI
CDefView::GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
, HDC hicTargetDevice
, LOGPALETTE
**ppColorSet
)
3119 FIXME("Stub: this=%p\n", this);
3124 HRESULT WINAPI
CDefView::Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
)
3126 FIXME("Stub: this=%p\n", this);
3131 HRESULT WINAPI
CDefView::Unfreeze(DWORD dwFreeze
)
3133 FIXME("Stub: this=%p\n", this);
3138 HRESULT WINAPI
CDefView::SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
)
3140 FIXME("partial stub: %p %08x %08x %p\n", this, aspects
, advf
, pAdvSink
);
3142 /* FIXME: we set the AdviseSink, but never use it to send any advice */
3143 m_pAdvSink
= pAdvSink
;
3144 m_dwAspects
= aspects
;
3150 HRESULT WINAPI
CDefView::GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
)
3152 TRACE("this=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n", this, pAspects
, pAdvf
, ppAdvSink
);
3156 *ppAdvSink
= m_pAdvSink
;
3157 m_pAdvSink
.p
->AddRef();
3161 *pAspects
= m_dwAspects
;
3169 HRESULT STDMETHODCALLTYPE
CDefView::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
3171 if (IsEqualIID(guidService
, SID_IShellBrowser
))
3172 return m_pShellBrowser
->QueryInterface(riid
, ppvObject
);
3173 else if(IsEqualIID(guidService
, SID_IFolderView
))
3174 return QueryInterface(riid
, ppvObject
);
3176 return E_NOINTERFACE
;
3179 HRESULT
CDefView::_MergeToolbar()
3181 CComPtr
<IExplorerToolbar
> ptb
;
3184 hr
= IUnknown_QueryService(m_pShellBrowser
, IID_IExplorerToolbar
, IID_PPV_ARG(IExplorerToolbar
, &ptb
));
3188 m_Category
= CGID_DefViewFrame
;
3190 hr
= ptb
->SetCommandTarget(static_cast<IOleCommandTarget
*>(this), &m_Category
, 0);
3198 hr
= ptb
->AddButtons(&m_Category
, buttonsCount
, buttons
);
3206 HRESULT
CDefView_CreateInstance(IShellFolder
*pFolder
, REFIID riid
, LPVOID
* ppvOut
)
3208 return ShellObjectCreatorInit
<CDefView
>(pFolder
, riid
, ppvOut
);
3211 HRESULT WINAPI
SHCreateShellFolderViewEx(
3212 LPCSFV psvcbi
, /* [in] shelltemplate struct */
3213 IShellView
**ppsv
) /* [out] IShellView pointer */
3215 CComPtr
<IShellView
> psv
;
3218 TRACE("sf=%p pidl=%p cb=%p mode=0x%08x parm=%p\n",
3219 psvcbi
->pshf
, psvcbi
->pidl
, psvcbi
->pfnCallback
,
3220 psvcbi
->fvm
, psvcbi
->psvOuter
);
3223 hRes
= CDefView_CreateInstance(psvcbi
->pshf
, IID_PPV_ARG(IShellView
, &psv
));
3224 if (FAILED_UNEXPECTEDLY(hRes
))
3227 *ppsv
= psv
.Detach();
3231 HRESULT WINAPI
SHCreateShellFolderView(const SFV_CREATE
*pcsfv
,
3234 CComPtr
<IShellView
> psv
;
3238 if (!pcsfv
|| pcsfv
->cbSize
!= sizeof(*pcsfv
))
3239 return E_INVALIDARG
;
3241 TRACE("sf=%p outer=%p callback=%p\n",
3242 pcsfv
->pshf
, pcsfv
->psvOuter
, pcsfv
->psfvcb
);
3244 hRes
= CDefView_CreateInstance(pcsfv
->pshf
, IID_PPV_ARG(IShellView
, &psv
));
3248 *ppsv
= psv
.Detach();