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();
115 HRESULT WINAPI
Initialize(IShellFolder
*shellFolder
);
116 HRESULT
IncludeObject(PCUITEMID_CHILD pidl
);
117 HRESULT
OnDefaultCommand();
118 HRESULT
OnStateChange(UINT uFlags
);
119 void UpdateStatusbar();
121 void SetStyle(DWORD dwAdd
, DWORD dwRemove
);
123 void UpdateListColors();
125 static INT CALLBACK
ListViewCompareItems(LPARAM lParam1
, LPARAM lParam2
, LPARAM lpData
);
127 PCUITEMID_CHILD
_PidlByItem(int i
);
128 PCUITEMID_CHILD
_PidlByItem(LVITEM
& lvItem
);
129 int LV_FindItemByPidl(PCUITEMID_CHILD pidl
);
130 BOOLEAN
LV_AddItem(PCUITEMID_CHILD pidl
);
131 BOOLEAN
LV_DeleteItem(PCUITEMID_CHILD pidl
);
132 BOOLEAN
LV_RenameItem(PCUITEMID_CHILD pidlOld
, PCUITEMID_CHILD pidlNew
);
133 BOOLEAN
LV_ProdItem(PCUITEMID_CHILD pidl
);
134 static INT CALLBACK
fill_list(LPVOID ptr
, LPVOID arg
);
136 HRESULT
FillFileMenu();
137 HRESULT
FillEditMenu();
138 HRESULT
FillViewMenu();
139 HRESULT
FillArrangeAsMenu(HMENU hmenuArrange
);
140 HRESULT
CheckViewMode(HMENU hmenuView
);
141 UINT
GetSelections();
142 HRESULT
OpenSelectedItems();
144 void DoActivate(UINT uState
);
145 HRESULT
drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
146 HRESULT
InvokeContextMenuCommand(UINT uCommand
);
147 LRESULT
OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
);
149 // *** IOleWindow methods ***
150 virtual HRESULT STDMETHODCALLTYPE
GetWindow(HWND
*lphwnd
);
151 virtual HRESULT STDMETHODCALLTYPE
ContextSensitiveHelp(BOOL fEnterMode
);
153 // *** IShellView methods ***
154 virtual HRESULT STDMETHODCALLTYPE
TranslateAccelerator(MSG
*pmsg
);
155 virtual HRESULT STDMETHODCALLTYPE
EnableModeless(BOOL fEnable
);
156 virtual HRESULT STDMETHODCALLTYPE
UIActivate(UINT uState
);
157 virtual HRESULT STDMETHODCALLTYPE
Refresh();
158 virtual HRESULT STDMETHODCALLTYPE
CreateViewWindow(IShellView
*psvPrevious
, LPCFOLDERSETTINGS pfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
);
159 virtual HRESULT STDMETHODCALLTYPE
DestroyViewWindow();
160 virtual HRESULT STDMETHODCALLTYPE
GetCurrentInfo(LPFOLDERSETTINGS pfs
);
161 virtual HRESULT STDMETHODCALLTYPE
AddPropertySheetPages(DWORD dwReserved
, LPFNSVADDPROPSHEETPAGE pfn
, LPARAM lparam
);
162 virtual HRESULT STDMETHODCALLTYPE
SaveViewState();
163 virtual HRESULT STDMETHODCALLTYPE
SelectItem(PCUITEMID_CHILD pidlItem
, SVSIF uFlags
);
164 virtual HRESULT STDMETHODCALLTYPE
GetItemObject(UINT uItem
, REFIID riid
, void **ppv
);
166 // *** IShellView2 methods ***
167 virtual HRESULT STDMETHODCALLTYPE
GetView(SHELLVIEWID
*view_guid
, ULONG view_type
);
168 virtual HRESULT STDMETHODCALLTYPE
CreateViewWindow2(LPSV2CVW2_PARAMS view_params
);
169 virtual HRESULT STDMETHODCALLTYPE
HandleRename(LPCITEMIDLIST new_pidl
);
170 virtual HRESULT STDMETHODCALLTYPE
SelectAndPositionItem(LPCITEMIDLIST item
, UINT flags
, POINT
*point
);
172 // *** IShellView3 methods ***
173 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
);
175 // *** IFolderView methods ***
176 virtual HRESULT STDMETHODCALLTYPE
GetCurrentViewMode(UINT
*pViewMode
);
177 virtual HRESULT STDMETHODCALLTYPE
SetCurrentViewMode(UINT ViewMode
);
178 virtual HRESULT STDMETHODCALLTYPE
GetFolder(REFIID riid
, void **ppv
);
179 virtual HRESULT STDMETHODCALLTYPE
Item(int iItemIndex
, PITEMID_CHILD
*ppidl
);
180 virtual HRESULT STDMETHODCALLTYPE
ItemCount(UINT uFlags
, int *pcItems
);
181 virtual HRESULT STDMETHODCALLTYPE
Items(UINT uFlags
, REFIID riid
, void **ppv
);
182 virtual HRESULT STDMETHODCALLTYPE
GetSelectionMarkedItem(int *piItem
);
183 virtual HRESULT STDMETHODCALLTYPE
GetFocusedItem(int *piItem
);
184 virtual HRESULT STDMETHODCALLTYPE
GetItemPosition(PCUITEMID_CHILD pidl
, POINT
*ppt
);
185 virtual HRESULT STDMETHODCALLTYPE
GetSpacing(POINT
*ppt
);
186 virtual HRESULT STDMETHODCALLTYPE
GetDefaultSpacing(POINT
*ppt
);
187 virtual HRESULT STDMETHODCALLTYPE
GetAutoArrange();
188 virtual HRESULT STDMETHODCALLTYPE
SelectItem(int iItem
, DWORD dwFlags
);
189 virtual HRESULT STDMETHODCALLTYPE
SelectAndPositionItems(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD dwFlags
);
191 // *** IShellFolderView methods ***
192 virtual HRESULT STDMETHODCALLTYPE
Rearrange(LPARAM sort
);
193 virtual HRESULT STDMETHODCALLTYPE
GetArrangeParam(LPARAM
*sort
);
194 virtual HRESULT STDMETHODCALLTYPE
ArrangeGrid();
195 virtual HRESULT STDMETHODCALLTYPE
AutoArrange();
196 virtual HRESULT STDMETHODCALLTYPE
AddObject(PITEMID_CHILD pidl
, UINT
*item
);
197 virtual HRESULT STDMETHODCALLTYPE
GetObject(PITEMID_CHILD
*pidl
, UINT item
);
198 virtual HRESULT STDMETHODCALLTYPE
RemoveObject(PITEMID_CHILD pidl
, UINT
*item
);
199 virtual HRESULT STDMETHODCALLTYPE
GetObjectCount(UINT
*count
);
200 virtual HRESULT STDMETHODCALLTYPE
SetObjectCount(UINT count
, UINT flags
);
201 virtual HRESULT STDMETHODCALLTYPE
UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
);
202 virtual HRESULT STDMETHODCALLTYPE
RefreshObject(PITEMID_CHILD pidl
, UINT
*item
);
203 virtual HRESULT STDMETHODCALLTYPE
SetRedraw(BOOL redraw
);
204 virtual HRESULT STDMETHODCALLTYPE
GetSelectedCount(UINT
*count
);
205 virtual HRESULT STDMETHODCALLTYPE
GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
);
206 virtual HRESULT STDMETHODCALLTYPE
IsDropOnSource(IDropTarget
*drop_target
);
207 virtual HRESULT STDMETHODCALLTYPE
GetDragPoint(POINT
*pt
);
208 virtual HRESULT STDMETHODCALLTYPE
GetDropPoint(POINT
*pt
);
209 virtual HRESULT STDMETHODCALLTYPE
MoveIcons(IDataObject
*obj
);
210 virtual HRESULT STDMETHODCALLTYPE
SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
);
211 virtual HRESULT STDMETHODCALLTYPE
IsBkDropTarget(IDropTarget
*drop_target
);
212 virtual HRESULT STDMETHODCALLTYPE
SetClipboard(BOOL move
);
213 virtual HRESULT STDMETHODCALLTYPE
SetPoints(IDataObject
*obj
);
214 virtual HRESULT STDMETHODCALLTYPE
GetItemSpacing(ITEMSPACING
*spacing
);
215 virtual HRESULT STDMETHODCALLTYPE
SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
);
216 virtual HRESULT STDMETHODCALLTYPE
Select(UINT flags
);
217 virtual HRESULT STDMETHODCALLTYPE
QuerySupport(UINT
*support
);
218 virtual HRESULT STDMETHODCALLTYPE
SetAutomationObject(IDispatch
*disp
);
220 // *** IOleCommandTarget methods ***
221 virtual HRESULT STDMETHODCALLTYPE
QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
);
222 virtual HRESULT STDMETHODCALLTYPE
Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
);
224 // *** IDropTarget methods ***
225 virtual HRESULT STDMETHODCALLTYPE
DragEnter(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
226 virtual HRESULT STDMETHODCALLTYPE
DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
227 virtual HRESULT STDMETHODCALLTYPE
DragLeave();
228 virtual HRESULT STDMETHODCALLTYPE
Drop(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
230 // *** IDropSource methods ***
231 virtual HRESULT STDMETHODCALLTYPE
QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
);
232 virtual HRESULT STDMETHODCALLTYPE
GiveFeedback(DWORD dwEffect
);
234 // *** IViewObject methods ***
235 virtual HRESULT STDMETHODCALLTYPE
Draw(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
,
236 HDC hdcTargetDev
, HDC hdcDraw
, LPCRECTL lprcBounds
, LPCRECTL lprcWBounds
,
237 BOOL ( STDMETHODCALLTYPE
*pfnContinue
)(ULONG_PTR dwContinue
), ULONG_PTR dwContinue
);
238 virtual HRESULT STDMETHODCALLTYPE
GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
,
239 DVTARGETDEVICE
*ptd
, HDC hicTargetDev
, LOGPALETTE
**ppColorSet
);
240 virtual HRESULT STDMETHODCALLTYPE
Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
);
241 virtual HRESULT STDMETHODCALLTYPE
Unfreeze(DWORD dwFreeze
);
242 virtual HRESULT STDMETHODCALLTYPE
SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
);
243 virtual HRESULT STDMETHODCALLTYPE
GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
);
245 // *** IServiceProvider methods ***
246 virtual HRESULT STDMETHODCALLTYPE
QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
);
249 LRESULT
OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
250 LRESULT
OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
251 LRESULT
OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
252 LRESULT
OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
253 LRESULT
OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
254 LRESULT
OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
255 LRESULT
OnNCCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
256 LRESULT
OnNCDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
257 LRESULT
OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
258 LRESULT
OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
259 LRESULT
OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
260 LRESULT
OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
261 LRESULT
OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
262 LRESULT
OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
263 LRESULT
OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
264 LRESULT
OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
265 LRESULT
OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
266 LRESULT
OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
267 LRESULT
OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
268 LRESULT
OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
270 static ATL::CWndClassInfo
& GetWndClassInfo()
272 static ATL::CWndClassInfo wc
=
274 { sizeof(WNDCLASSEX
), CS_PARENTDC
, StartWindowProc
,
276 LoadCursor(NULL
, IDC_ARROW
), (HBRUSH
)(COLOR_WINDOW
+ 1), NULL
, SV_CLASS_NAME
, NULL
278 NULL
, NULL
, IDC_ARROW
, TRUE
, 0, _T("")
283 virtual WNDPROC
GetWindowProc()
288 static LRESULT CALLBACK
WindowProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
293 // Must hold a reference during message handling
294 pThis
= reinterpret_cast<CDefView
*>(hWnd
);
296 result
= CWindowImpl
<CDefView
, CWindow
, CControlWinTraits
>::WindowProc(hWnd
, uMsg
, wParam
, lParam
);
301 BEGIN_MSG_MAP(CDefView
)
302 MESSAGE_HANDLER(WM_SIZE
, OnSize
)
303 MESSAGE_HANDLER(WM_SETFOCUS
, OnSetFocus
)
304 MESSAGE_HANDLER(WM_KILLFOCUS
, OnKillFocus
)
305 MESSAGE_HANDLER(WM_NCCREATE
, OnNCCreate
)
306 MESSAGE_HANDLER(WM_NCDESTROY
, OnNCDestroy
)
307 MESSAGE_HANDLER(WM_CREATE
, OnCreate
)
308 MESSAGE_HANDLER(WM_ACTIVATE
, OnActivate
)
309 MESSAGE_HANDLER(WM_NOTIFY
, OnNotify
)
310 MESSAGE_HANDLER(WM_COMMAND
, OnCommand
)
311 MESSAGE_HANDLER(SHV_CHANGE_NOTIFY
, OnChangeNotify
)
312 MESSAGE_HANDLER(WM_CONTEXTMENU
, OnContextMenu
)
313 MESSAGE_HANDLER(WM_DRAWITEM
, OnCustomItem
)
314 MESSAGE_HANDLER(WM_MEASUREITEM
, OnCustomItem
)
315 MESSAGE_HANDLER(WM_SHOWWINDOW
, OnShowWindow
)
316 MESSAGE_HANDLER(WM_GETDLGCODE
, OnGetDlgCode
)
317 MESSAGE_HANDLER(WM_DESTROY
, OnDestroy
)
318 MESSAGE_HANDLER(WM_ERASEBKGND
, OnEraseBackground
)
319 MESSAGE_HANDLER(WM_SYSCOLORCHANGE
, OnSysColorChange
)
320 MESSAGE_HANDLER(CWM_GETISHELLBROWSER
, OnGetShellBrowser
)
321 MESSAGE_HANDLER(WM_SETTINGCHANGE
, OnSettingChange
)
322 MESSAGE_HANDLER(WM_INITMENUPOPUP
, OnInitMenuPopup
)
325 BEGIN_COM_MAP(CDefView
)
326 // Windows returns E_NOINTERFACE for IOleWindow
327 // COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
328 COM_INTERFACE_ENTRY_IID(IID_IShellView
, IShellView
)
329 COM_INTERFACE_ENTRY_IID(IID_CDefView
, IShellView
)
330 COM_INTERFACE_ENTRY_IID(IID_IShellView2
, IShellView2
)
331 COM_INTERFACE_ENTRY_IID(IID_IFolderView
, IFolderView
)
332 COM_INTERFACE_ENTRY_IID(IID_IShellFolderView
, IShellFolderView
)
333 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget
, IOleCommandTarget
)
334 COM_INTERFACE_ENTRY_IID(IID_IDropTarget
, IDropTarget
)
335 COM_INTERFACE_ENTRY_IID(IID_IDropSource
, IDropSource
)
336 COM_INTERFACE_ENTRY_IID(IID_IViewObject
, IViewObject
)
337 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider
, IServiceProvider
)
342 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
343 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
344 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
346 #define ID_LISTVIEW 1
349 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
350 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
351 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
353 typedef void (CALLBACK
*PFNSHGETSETTINGSPROC
)(LPSHELLFLAGSTATE lpsfs
, DWORD dwMask
);
355 CDefView::CDefView() :
359 m_hMenuArrangeModes(NULL
),
360 m_hMenuViewModes(NULL
),
361 m_hContextMenu(NULL
),
362 m_bmenuBarInitialized(FALSE
),
376 ZeroMemory(&m_FolderSettings
, sizeof(m_FolderSettings
));
377 ZeroMemory(&m_sortInfo
, sizeof(m_sortInfo
));
378 ZeroMemory(&m_ptLastMousePos
, sizeof(m_ptLastMousePos
));
379 ZeroMemory(&m_Category
, sizeof(m_Category
));
382 CDefView::~CDefView()
384 TRACE(" destroying IShellView(%p)\n", this);
394 HRESULT WINAPI
CDefView::Initialize(IShellFolder
*shellFolder
)
396 m_pSFParent
= shellFolder
;
397 shellFolder
->QueryInterface(IID_PPV_ARG(IShellFolder2
, &m_pSF2Parent
));
402 /**********************************************************
404 * ##### helperfunctions for communication with ICommDlgBrowser #####
406 HRESULT
CDefView::IncludeObject(PCUITEMID_CHILD pidl
)
410 if (m_pCommDlgBrowser
.p
!= NULL
)
412 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl
);
413 ret
= m_pCommDlgBrowser
->IncludeObject(this, pidl
);
414 TRACE("--0x%08x\n", ret
);
420 HRESULT
CDefView::OnDefaultCommand()
422 HRESULT ret
= S_FALSE
;
424 if (m_pCommDlgBrowser
.p
!= NULL
)
426 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
427 ret
= m_pCommDlgBrowser
->OnDefaultCommand(this);
428 TRACE("-- returns %08x\n", ret
);
434 HRESULT
CDefView::OnStateChange(UINT uFlags
)
436 HRESULT ret
= S_FALSE
;
438 if (m_pCommDlgBrowser
.p
!= NULL
)
440 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags
);
441 ret
= m_pCommDlgBrowser
->OnStateChange(this, uFlags
);
447 /**********************************************************
448 * set the toolbar of the filedialog buttons
450 * - activates the buttons from the shellbrowser according to
453 void CDefView::CheckToolbar()
459 if (m_pCommDlgBrowser
!= NULL
)
461 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
462 FCIDM_TB_SMALLICON
, (m_FolderSettings
.ViewMode
== FVM_LIST
) ? TRUE
: FALSE
, &result
);
463 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
464 FCIDM_TB_REPORTVIEW
, (m_FolderSettings
.ViewMode
== FVM_DETAILS
) ? TRUE
: FALSE
, &result
);
465 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
466 FCIDM_TB_SMALLICON
, TRUE
, &result
);
467 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
468 FCIDM_TB_REPORTVIEW
, TRUE
, &result
);
472 void CDefView::UpdateStatusbar()
474 WCHAR szFormat
[MAX_PATH
] = {0};
475 WCHAR szObjects
[MAX_PATH
] = {0};
478 cSelectedItems
= m_ListView
.GetSelectedCount();
481 LoadStringW(shell32_hInstance
, IDS_OBJECTS_SELECTED
, szFormat
, _countof(szFormat
));
482 StringCchPrintfW(szObjects
, MAX_PATH
, szFormat
, cSelectedItems
);
486 LoadStringW(shell32_hInstance
, IDS_OBJECTS
, szFormat
, _countof(szFormat
));
487 StringCchPrintfW(szObjects
, MAX_PATH
, szFormat
, m_ListView
.GetItemCount());
489 m_pShellBrowser
->SetStatusTextSB(szObjects
);
492 /**********************************************************
494 * ##### helperfunctions for initializing the view #####
496 /**********************************************************
497 * change the style of the listview control
499 void CDefView::SetStyle(DWORD dwAdd
, DWORD dwRemove
)
503 TRACE("(%p)\n", this);
505 tmpstyle
= ::GetWindowLongPtrW(m_ListView
, GWL_STYLE
);
506 ::SetWindowLongPtrW(m_ListView
, GWL_STYLE
, dwAdd
| (tmpstyle
& ~dwRemove
));
509 /**********************************************************
510 * ShellView_CreateList()
512 * - creates the list view window
514 BOOL
CDefView::CreateList()
516 DWORD dwStyle
, dwExStyle
;
520 dwStyle
= WS_TABSTOP
| WS_VISIBLE
| WS_CHILDWINDOW
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
|
521 LVS_SHAREIMAGELISTS
| LVS_EDITLABELS
| LVS_AUTOARRANGE
;
522 dwExStyle
= WS_EX_CLIENTEDGE
;
524 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
525 dwStyle
|= LVS_ALIGNLEFT
;
527 dwStyle
|= LVS_ALIGNTOP
| LVS_SHOWSELALWAYS
;
529 switch (m_FolderSettings
.ViewMode
)
536 dwStyle
|= LVS_REPORT
;
540 dwStyle
|= LVS_SMALLICON
;
552 if (m_FolderSettings
.fFlags
& FWF_AUTOARRANGE
)
553 dwStyle
|= LVS_AUTOARRANGE
;
555 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
556 m_FolderSettings
.fFlags
|= FWF_NOCLIENTEDGE
| FWF_NOSCROLL
;
558 if (m_FolderSettings
.fFlags
& FWF_SINGLESEL
)
559 dwStyle
|= LVS_SINGLESEL
;
561 if (m_FolderSettings
.fFlags
& FWF_NOCLIENTEDGE
)
562 dwExStyle
&= ~WS_EX_CLIENTEDGE
;
564 RECT rcListView
= {0,0,0,0};
565 m_ListView
.Create(m_hWnd
, rcListView
, L
"FolderView", dwStyle
, dwExStyle
, ID_LISTVIEW
);
570 m_sortInfo
.bIsAscending
= TRUE
;
571 m_sortInfo
.nHeaderID
= -1;
572 m_sortInfo
.nLastHeaderID
= -1;
576 /* UpdateShellSettings(); */
580 void CDefView::UpdateListColors()
582 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
584 /* Check if drop shadows option is enabled */
585 BOOL bDropShadow
= FALSE
;
586 DWORD cbDropShadow
= sizeof(bDropShadow
);
589 * The desktop ListView always take the default desktop colours, by
590 * remaining transparent and letting user32/win32k paint itself the
591 * desktop background color, if any.
593 m_ListView
.SetBkColor(CLR_NONE
);
595 SHGetValueW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
596 L
"ListviewShadow", NULL
, &bDropShadow
, &cbDropShadow
);
599 /* Set the icon background transparent */
600 m_ListView
.SetTextBkColor(CLR_NONE
);
601 m_ListView
.SetTextColor(RGB(255, 255, 255));
602 m_ListView
.SetExtendedListViewStyle(LVS_EX_TRANSPARENTSHADOWTEXT
, LVS_EX_TRANSPARENTSHADOWTEXT
);
606 /* Set the icon background as the same colour as the desktop */
607 COLORREF crDesktop
= GetSysColor(COLOR_DESKTOP
);
608 m_ListView
.SetTextBkColor(crDesktop
);
609 if (GetRValue(crDesktop
) + GetGValue(crDesktop
) + GetBValue(crDesktop
) > 128 * 3)
610 m_ListView
.SetTextColor(RGB(0, 0, 0));
612 m_ListView
.SetTextColor(RGB(255, 255, 255));
613 m_ListView
.SetExtendedListViewStyle(0, LVS_EX_TRANSPARENTSHADOWTEXT
);
618 /**********************************************************
619 * ShellView_InitList()
621 * - adds all needed columns to the shellview
623 BOOL
CDefView::InitList()
627 HIMAGELIST big_icons
, small_icons
;
631 m_ListView
.DeleteAllItems();
633 m_hMenuArrangeModes
= CreateMenu();
637 for (int i
= 0; 1; i
++)
639 if (FAILED(m_pSF2Parent
->GetDetailsOf(NULL
, i
, &sd
)))
641 StrRetToStrNW( szTemp
, 50, &sd
.str
, NULL
);
642 m_ListView
.InsertColumn(i
, szTemp
, sd
.fmt
, sd
.cxChar
* 8);
644 InsertMenuW(m_hMenuArrangeModes
, -1, MF_STRING
, 0x30 + i
, szTemp
);
647 InsertMenuW(m_hMenuArrangeModes
, -1, MF_BYPOSITION
| MF_SEPARATOR
, 0, 0);
651 FIXME("no m_pSF2Parent\n");
654 Shell_GetImageLists(&big_icons
, &small_icons
);
655 m_ListView
.SetImageList(big_icons
, LVSIL_NORMAL
);
656 m_ListView
.SetImageList(small_icons
, LVSIL_SMALL
);
661 /*************************************************************************
662 * ShellView_ListViewCompareItems
664 * Compare Function for the Listview (FileOpen Dialog)
667 * lParam1 [I] the first ItemIdList to compare with
668 * lParam2 [I] the second ItemIdList to compare with
669 * lpData [I] The column ID for the header Ctrl to process
672 * A negative value if the first item should precede the second,
673 * a positive value if the first item should follow the second,
674 * or zero if the two items are equivalent
676 INT CALLBACK
CDefView::ListViewCompareItems(LPARAM lParam1
, LPARAM lParam2
, LPARAM lpData
)
678 PCUIDLIST_RELATIVE pidl1
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam1
);
679 PCUIDLIST_RELATIVE pidl2
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam2
);
680 CDefView
*pThis
= reinterpret_cast<CDefView
*>(lpData
);
682 HRESULT hres
= pThis
->m_pSFParent
->CompareIDs(pThis
->m_sortInfo
.nHeaderID
, pidl1
, pidl2
);
683 if (FAILED_UNEXPECTEDLY(hres
))
686 SHORT nDiff
= HRESULT_CODE(hres
);
687 if (!pThis
->m_sortInfo
.bIsAscending
)
692 BOOL
CDefView::_Sort()
697 if ((m_ListView
.GetWindowLongPtr(GWL_STYLE
) & ~LVS_NOSORTHEADER
) == 0)
700 hHeader
= (HWND
)m_ListView
.SendMessage(LVM_GETHEADER
, 0, 0);
701 ZeroMemory(&hColumn
, sizeof(hColumn
));
703 /* If the sorting column changed, remove the sorting style from the old column */
704 if ( (m_sortInfo
.nLastHeaderID
!= -1) &&
705 (m_sortInfo
.nLastHeaderID
!= m_sortInfo
.nHeaderID
) )
707 hColumn
.mask
= HDI_FORMAT
;
708 Header_GetItem(hHeader
, m_sortInfo
.nLastHeaderID
, &hColumn
);
709 hColumn
.fmt
&= ~(HDF_SORTUP
| HDF_SORTDOWN
);
710 Header_SetItem(hHeader
, m_sortInfo
.nLastHeaderID
, &hColumn
);
713 /* Set the sorting style to the new column */
714 hColumn
.mask
= HDI_FORMAT
;
715 Header_GetItem(hHeader
, m_sortInfo
.nHeaderID
, &hColumn
);
717 hColumn
.fmt
&= (m_sortInfo
.bIsAscending
? ~HDF_SORTDOWN
: ~HDF_SORTUP
);
718 hColumn
.fmt
|= (m_sortInfo
.bIsAscending
? HDF_SORTUP
: HDF_SORTDOWN
);
719 Header_SetItem(hHeader
, m_sortInfo
.nHeaderID
, &hColumn
);
721 /* Sort the list, using the current values of nHeaderID and bIsAscending */
722 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
723 return m_ListView
.SortItems(ListViewCompareItems
, this);
726 PCUITEMID_CHILD
CDefView::_PidlByItem(int i
)
728 return reinterpret_cast<PCUITEMID_CHILD
>(m_ListView
.GetItemData(i
));
731 PCUITEMID_CHILD
CDefView::_PidlByItem(LVITEM
& lvItem
)
733 return reinterpret_cast<PCUITEMID_CHILD
>(lvItem
.lParam
);
736 /**********************************************************
737 * LV_FindItemByPidl()
739 int CDefView::LV_FindItemByPidl(PCUITEMID_CHILD pidl
)
741 int cItems
= m_ListView
.GetItemCount();
743 for (int i
= 0; i
<cItems
; i
++)
745 PCUITEMID_CHILD currentpidl
= _PidlByItem(i
);
746 HRESULT hr
= m_pSFParent
->CompareIDs(0, pidl
, currentpidl
);
748 if (SUCCEEDED(hr
) && !HRESULT_CODE(hr
))
756 /**********************************************************
759 BOOLEAN
CDefView::LV_AddItem(PCUITEMID_CHILD pidl
)
763 TRACE("(%p)(pidl=%p)\n", this, pidl
);
765 lvItem
.mask
= LVIF_TEXT
| LVIF_IMAGE
| LVIF_PARAM
; /*set the mask*/
766 lvItem
.iItem
= m_ListView
.GetItemCount(); /*add the item to the end of the list*/
768 lvItem
.lParam
= reinterpret_cast<LPARAM
>(ILClone(pidl
)); /*set the item's data*/
769 lvItem
.pszText
= LPSTR_TEXTCALLBACKW
; /*get text on a callback basis*/
770 lvItem
.iImage
= I_IMAGECALLBACK
; /*get the image on a callback basis*/
771 lvItem
.stateMask
= LVIS_CUT
;
773 if (m_ListView
.InsertItem(&lvItem
) == -1)
779 /**********************************************************
782 BOOLEAN
CDefView::LV_DeleteItem(PCUITEMID_CHILD pidl
)
786 TRACE("(%p)(pidl=%p)\n", this, pidl
);
788 nIndex
= LV_FindItemByPidl(pidl
);
790 return (-1 == m_ListView
.DeleteItem(nIndex
)) ? FALSE
: TRUE
;
793 /**********************************************************
796 BOOLEAN
CDefView::LV_RenameItem(PCUITEMID_CHILD pidlOld
, PCUITEMID_CHILD pidlNew
)
801 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", this, pidlOld
, pidlNew
);
803 nItem
= LV_FindItemByPidl(pidlOld
);
807 lvItem
.mask
= LVIF_PARAM
; /* only the pidl */
808 lvItem
.iItem
= nItem
;
810 m_ListView
.GetItem(&lvItem
);
812 SHFree(reinterpret_cast<LPVOID
>(lvItem
.lParam
));
813 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
814 lvItem
.iItem
= nItem
;
816 lvItem
.lParam
= reinterpret_cast<LPARAM
>(ILClone(pidlNew
)); /* set the item's data */
817 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
818 m_ListView
.SetItem(&lvItem
);
819 m_ListView
.Update(nItem
);
820 return TRUE
; /* FIXME: better handling */
826 /**********************************************************
829 BOOLEAN
CDefView::LV_ProdItem(PCUITEMID_CHILD pidl
)
834 TRACE("(%p)(pidl=%p)\n", this, pidl
);
836 nItem
= LV_FindItemByPidl(pidl
);
840 lvItem
.mask
= LVIF_IMAGE
;
841 lvItem
.iItem
= nItem
;
843 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
844 m_ListView
.SetItem(&lvItem
);
845 m_ListView
.Update(nItem
);
852 /**********************************************************
853 * ShellView_FillList()
855 * - gets the objectlist from the shellfolder
857 * - fills the list into the view
859 INT CALLBACK
CDefView::fill_list(LPVOID ptr
, LPVOID arg
)
861 PITEMID_CHILD pidl
= static_cast<PITEMID_CHILD
>(ptr
);
862 CDefView
*pThis
= static_cast<CDefView
*>(arg
);
864 /* in a commdlg This works as a filemask*/
865 if (pThis
->IncludeObject(pidl
) == S_OK
)
866 pThis
->LV_AddItem(pidl
);
872 HRESULT
CDefView::FillList()
874 CComPtr
<IEnumIDList
> pEnumIDList
;
880 DWORD dFlags
= SHCONTF_NONFOLDERS
| SHCONTF_FOLDERS
;
884 /* determine if there is a setting to show all the hidden files/folders */
885 if (RegOpenKeyExW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", 0, KEY_QUERY_VALUE
, &hKey
) == ERROR_SUCCESS
)
887 DWORD dataLength
, flagVal
;
889 dataLength
= sizeof(flagVal
);
890 if (RegQueryValueExW(hKey
, L
"Hidden", NULL
, NULL
, (LPBYTE
)&flagVal
, &dataLength
) == ERROR_SUCCESS
)
892 /* if the value is 1, then show all hidden files/folders */
895 dFlags
|= SHCONTF_INCLUDEHIDDEN
;
896 m_ListView
.SendMessageW(LVM_SETCALLBACKMASK
, LVIS_CUT
, 0);
904 /* get the itemlist from the shfolder */
905 hRes
= m_pSFParent
->EnumObjects(m_hWnd
, dFlags
, &pEnumIDList
);
913 /* create a pointer array */
914 hdpa
= DPA_Create(16);
917 return(E_OUTOFMEMORY
);
920 /* copy the items into the array*/
921 while((S_OK
== pEnumIDList
->Next(1, &pidl
, &dwFetched
)) && dwFetched
)
923 if (DPA_InsertPtr(hdpa
, 0x7fff, pidl
) == -1)
929 /*turn the listview's redrawing off*/
930 m_ListView
.SetRedraw(FALSE
);
932 DPA_DestroyCallback( hdpa
, fill_list
, this);
937 m_pSF2Parent
->GetDefaultColumn(NULL
, (ULONG
*)&m_sortInfo
.nHeaderID
, NULL
);
941 FIXME("no m_pSF2Parent\n");
943 m_sortInfo
.bIsAscending
= TRUE
;
946 /*turn the listview's redrawing back on and force it to draw*/
947 m_ListView
.SetRedraw(TRUE
);
952 LRESULT
CDefView::OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
954 m_ListView
.UpdateWindow();
959 LRESULT
CDefView::OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
961 return m_ListView
.SendMessageW(uMsg
, 0, 0);
964 LRESULT
CDefView::OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
971 DestroyMenu(m_hMenu
);
974 RevokeDragDrop(m_hWnd
);
975 SHChangeNotifyDeregister(m_hNotify
);
977 SHFree(m_pidlParent
);
984 LRESULT
CDefView::OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
986 /* redirect to parent */
987 if (m_FolderSettings
.fFlags
& (FWF_DESKTOP
| FWF_TRANSPARENT
))
988 return SendMessageW(GetParent(), WM_ERASEBKGND
, wParam
, lParam
);
994 LRESULT
CDefView::OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
996 /* Update desktop labels color */
999 /* Forward WM_SYSCOLORCHANGE to common controls */
1000 return m_ListView
.SendMessageW(uMsg
, 0, 0);
1003 LRESULT
CDefView::OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1005 return reinterpret_cast<LRESULT
>(m_pShellBrowser
.p
);
1008 LRESULT
CDefView::OnNCCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1015 LRESULT
CDefView::OnNCDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1022 /**********************************************************
1023 * ShellView_OnCreate()
1025 LRESULT
CDefView::OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1027 CComPtr
<IDropTarget
> pdt
;
1028 SHChangeNotifyEntry ntreg
;
1029 CComPtr
<IPersistFolder2
> ppf2
;
1031 TRACE("%p\n", this);
1041 if (SUCCEEDED(QueryInterface(IID_PPV_ARG(IDropTarget
, &pdt
))))
1043 if (FAILED(RegisterDragDrop(m_hWnd
, pdt
)))
1044 ERR("Registering Drag Drop Failed");
1047 /* register for receiving notifications */
1048 m_pSFParent
->QueryInterface(IID_PPV_ARG(IPersistFolder2
, &ppf2
));
1051 ppf2
->GetCurFolder(&m_pidlParent
);
1052 ntreg
.fRecursive
= TRUE
;
1053 ntreg
.pidl
= m_pidlParent
;
1054 m_hNotify
= SHChangeNotifyRegister(m_hWnd
, SHCNRF_InterruptLevel
| SHCNRF_ShellLevel
, SHCNE_ALLEVENTS
, SHV_CHANGE_NOTIFY
, 1, &ntreg
);
1057 m_hAccel
= LoadAcceleratorsW(shell32_hInstance
, MAKEINTRESOURCEW(IDA_SHELLVIEW
));
1064 /**********************************************************
1065 * #### Handling of the menus ####
1068 extern "C" DWORD WINAPI
SHMenuIndexFromID(HMENU hMenu
, UINT uID
);
1070 HMENU
GetSubmenuByID(HMENU hmenu
, UINT id
)
1072 MENUITEMINFOW mii
= {sizeof(mii
), MIIM_SUBMENU
};
1073 if (::GetMenuItemInfoW(hmenu
, id
, FALSE
, &mii
))
1074 return mii
.hSubMenu
;
1079 /* ReallyGetMenuItemID returns the id of an item even if it opens a submenu,
1080 GetMenuItemID returns -1 if the specified item opens a submenu */
1081 UINT
ReallyGetMenuItemID(HMENU hmenu
, int i
)
1083 MENUITEMINFOW mii
= {sizeof(mii
), MIIM_ID
};
1084 if (::GetMenuItemInfoW(hmenu
, i
, TRUE
, &mii
))
1090 HRESULT
CDefView::FillFileMenu()
1092 HMENU hFileMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_FILE
);
1096 /* Cleanup the items added previously */
1097 for (int i
= GetMenuItemCount(hFileMenu
) - 1; i
>= 0; i
--)
1099 UINT id
= GetMenuItemID(hFileMenu
, i
);
1100 if (id
< FCIDM_BROWSERFIRST
|| id
> FCIDM_BROWSERLAST
)
1101 DeleteMenu(hFileMenu
, i
, MF_BYPOSITION
);
1104 /* Store the context menu in m_pCM and keep it in order to invoke the selected command later on */
1105 HRESULT hr
= GetItemObject(SVGIO_SELECTION
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1106 if (FAILED_UNEXPECTEDLY(hr
))
1109 IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1111 HMENU hmenu
= CreatePopupMenu();
1113 hr
= m_pCM
->QueryContextMenu(hmenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, 0);
1114 if (FAILED_UNEXPECTEDLY(hr
))
1117 // TODO: filter or something
1119 Shell_MergeMenus(hFileMenu
, hmenu
, 0, 0, 0xFFFF, MM_ADDSEPARATOR
| MM_SUBMENUSHAVEIDS
);
1121 ::DestroyMenu(hmenu
);
1126 HRESULT
CDefView::FillEditMenu()
1128 HMENU hEditMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_EDIT
);
1132 HMENU hmenuContents
= ::LoadMenuW(shell32_hInstance
, L
"MENU_003");
1136 Shell_MergeMenus(hEditMenu
, hmenuContents
, 0, 0, 0xFFFF, 0);
1138 ::DestroyMenu(hmenuContents
);
1143 HRESULT
CDefView::FillViewMenu()
1145 HMENU hViewMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_VIEW
);
1149 m_hMenuViewModes
= ::LoadMenuW(shell32_hInstance
, L
"MENU_001");
1150 if (!m_hMenuViewModes
)
1153 UINT i
= SHMenuIndexFromID(hViewMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
);
1154 Shell_MergeMenus(hViewMenu
, m_hMenuViewModes
, i
, 0, 0xFFFF, MM_ADDSEPARATOR
| MM_DONTREMOVESEPS
| MM_SUBMENUSHAVEIDS
);
1159 HRESULT
CDefView::FillArrangeAsMenu(HMENU hmenuArrange
)
1161 /* We only need to fill this once */
1162 if (GetMenuItemID(hmenuArrange
, 0) == FCIDM_SHVIEW_AUTOARRANGE
)
1164 Shell_MergeMenus(hmenuArrange
, m_hMenuArrangeModes
, 0, 0, 0xFFFF,0);
1167 /* Also check the menu item according to which we sort */
1168 CheckMenuRadioItem(hmenuArrange
,
1171 m_sortInfo
.nHeaderID
+ 0x30,
1177 HRESULT
CDefView::CheckViewMode(HMENU hmenuView
)
1179 if (m_FolderSettings
.ViewMode
>= FVM_FIRST
&& m_FolderSettings
.ViewMode
<= FVM_LAST
)
1181 UINT iItemFirst
= FCIDM_SHVIEW_BIGICON
;
1182 UINT iItemLast
= iItemFirst
+ FVM_LAST
- FVM_FIRST
;
1183 UINT iItem
= iItemFirst
+ m_FolderSettings
.ViewMode
- FVM_FIRST
;
1184 CheckMenuRadioItem(hmenuView
, iItemFirst
, iItemLast
, iItem
, MF_BYCOMMAND
);
1190 /**********************************************************
1191 * ShellView_GetSelections()
1193 * - fills the m_apidl list with the selected objects
1196 * number of selected items
1198 UINT
CDefView::GetSelections()
1202 m_cidl
= m_ListView
.GetSelectedCount();
1203 m_apidl
= static_cast<PCUITEMID_CHILD
*>(SHAlloc(m_cidl
* sizeof(PCUITEMID_CHILD
)));
1210 TRACE("-- Items selected =%u\n", m_cidl
);
1214 while ((lvIndex
= m_ListView
.GetNextItem(lvIndex
, LVNI_SELECTED
)) > -1)
1216 m_apidl
[i
] = _PidlByItem(lvIndex
);
1220 TRACE("-- selected Item found\n");
1226 HRESULT
CDefView::InvokeContextMenuCommand(UINT uCommand
)
1228 CMINVOKECOMMANDINFO cmi
;
1230 ZeroMemory(&cmi
, sizeof(cmi
));
1231 cmi
.cbSize
= sizeof(cmi
);
1232 cmi
.lpVerb
= MAKEINTRESOURCEA(uCommand
);
1235 if (GetKeyState(VK_SHIFT
) & 0x8000)
1236 cmi
.fMask
|= CMIC_MASK_SHIFT_DOWN
;
1238 if (GetKeyState(VK_CONTROL
) & 0x8000)
1239 cmi
.fMask
|= CMIC_MASK_CONTROL_DOWN
;
1241 HRESULT hr
= m_pCM
->InvokeCommand(&cmi
);
1242 if (FAILED_UNEXPECTEDLY(hr
))
1248 /**********************************************************
1249 * ShellView_OpenSelectedItems()
1251 HRESULT
CDefView::OpenSelectedItems()
1257 m_cidl
= m_ListView
.GetSelectedCount();
1261 hResult
= OnDefaultCommand();
1262 if (hResult
== S_OK
)
1265 hMenu
= CreatePopupMenu();
1269 hResult
= GetItemObject(SVGIO_SELECTION
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1270 if (FAILED_UNEXPECTEDLY(hResult
))
1273 IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1275 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, 0x20, 0x7fff, 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 IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1328 hResult
= m_pCM
->QueryContextMenu(m_hContextMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1329 if (FAILED_UNEXPECTEDLY(hResult
))
1332 uCommand
= TrackPopupMenu(m_hContextMenu
,
1333 TPM_LEFTALIGN
| TPM_RETURNCMD
| TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
,
1334 x
, y
, 0, m_hWnd
, NULL
);
1338 if (uCommand
== FCIDM_SHVIEW_OPEN
&& OnDefaultCommand() == S_OK
)
1341 InvokeContextMenuCommand(uCommand
);
1346 IUnknown_SetSite(m_pCM
, NULL
);
1352 DestroyMenu(m_hContextMenu
);
1353 m_hContextMenu
= NULL
;
1359 LRESULT
CDefView::OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
)
1364 hMenu
= CreatePopupMenu();
1368 hResult
= GetItemObject( bUseSelection
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1369 if (FAILED_UNEXPECTEDLY( hResult
))
1372 IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1374 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1375 if (FAILED_UNEXPECTEDLY( hResult
))
1378 InvokeContextMenuCommand(uCommand
);
1383 IUnknown_SetSite(m_pCM
, NULL
);
1393 /**********************************************************
1394 * ##### message handling #####
1397 /**********************************************************
1398 * ShellView_OnSize()
1400 LRESULT
CDefView::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1402 WORD wWidth
, wHeight
;
1404 wWidth
= LOWORD(lParam
);
1405 wHeight
= HIWORD(lParam
);
1407 TRACE("%p width=%u height=%u\n", this, wWidth
, wHeight
);
1409 /* Resize the ListView to fit our window */
1412 ::MoveWindow(m_ListView
, 0, 0, wWidth
, wHeight
, TRUE
);
1418 /**********************************************************
1419 * ShellView_OnDeactivate()
1424 void CDefView::OnDeactivate()
1426 TRACE("%p\n", this);
1428 if (m_uState
!= SVUIA_DEACTIVATE
)
1430 // TODO: cleanup menu after deactivation
1432 m_uState
= SVUIA_DEACTIVATE
;
1436 void CDefView::DoActivate(UINT uState
)
1438 TRACE("%p uState=%x\n", this, uState
);
1440 /*don't do anything if the state isn't really changing */
1441 if (m_uState
== uState
)
1446 if (uState
== SVUIA_DEACTIVATE
)
1452 if(m_hMenu
&& !m_bmenuBarInitialized
)
1456 m_pShellBrowser
->SetMenuSB(m_hMenu
, 0, m_hWnd
);
1457 m_bmenuBarInitialized
= TRUE
;
1460 if (SVUIA_ACTIVATE_FOCUS
== uState
)
1462 m_ListView
.SetFocus();
1470 /**********************************************************
1471 * ShellView_OnActivate()
1473 LRESULT
CDefView::OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1475 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1479 /**********************************************************
1480 * ShellView_OnSetFocus()
1483 LRESULT
CDefView::OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1485 TRACE("%p\n", this);
1487 /* Tell the browser one of our windows has received the focus. This
1488 should always be done before merging menus (OnActivate merges the
1489 menus) if one of our windows has the focus.*/
1491 m_pShellBrowser
->OnViewWindowActive(this);
1492 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1494 /* Set the focus to the listview */
1495 m_ListView
.SetFocus();
1497 /* Notify the ICommDlgBrowser interface */
1498 OnStateChange(CDBOSC_SETFOCUS
);
1503 /**********************************************************
1504 * ShellView_OnKillFocus()
1506 LRESULT
CDefView::OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1508 TRACE("(%p) stub\n", this);
1510 DoActivate(SVUIA_ACTIVATE_NOFOCUS
);
1511 /* Notify the ICommDlgBrowser */
1512 OnStateChange(CDBOSC_KILLFOCUS
);
1517 /**********************************************************
1518 * ShellView_OnCommand()
1521 * the CmdID's are the ones from the context menu
1523 LRESULT
CDefView::OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1530 dwCmdID
= GET_WM_COMMAND_ID(wParam
, lParam
);
1531 dwCmd
= GET_WM_COMMAND_CMD(wParam
, lParam
);
1532 hwndCmd
= GET_WM_COMMAND_HWND(wParam
, lParam
);
1534 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n", this, dwCmdID
, dwCmd
, hwndCmd
);
1538 case FCIDM_SHVIEW_SMALLICON
:
1539 m_FolderSettings
.ViewMode
= FVM_SMALLICON
;
1540 SetStyle (LVS_SMALLICON
, LVS_TYPEMASK
);
1544 case FCIDM_SHVIEW_BIGICON
:
1545 m_FolderSettings
.ViewMode
= FVM_ICON
;
1546 SetStyle (LVS_ICON
, LVS_TYPEMASK
);
1550 case FCIDM_SHVIEW_LISTVIEW
:
1551 m_FolderSettings
.ViewMode
= FVM_LIST
;
1552 SetStyle (LVS_LIST
, LVS_TYPEMASK
);
1556 case FCIDM_SHVIEW_REPORTVIEW
:
1557 m_FolderSettings
.ViewMode
= FVM_DETAILS
;
1558 SetStyle (LVS_REPORT
, LVS_TYPEMASK
);
1562 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1567 m_sortInfo
.nHeaderID
= dwCmdID
- 0x30;
1568 m_sortInfo
.bIsAscending
= TRUE
;
1572 case FCIDM_SHVIEW_SNAPTOGRID
:
1573 case FCIDM_SHVIEW_AUTOARRANGE
:
1576 case FCIDM_SHVIEW_SELECTALL
:
1577 m_ListView
.SetItemState(-1, LVIS_SELECTED
, LVIS_SELECTED
);
1580 case FCIDM_SHVIEW_INVERTSELECTION
:
1581 nCount
= m_ListView
.GetItemCount();
1582 for (int i
=0; i
< nCount
; i
++)
1583 m_ListView
.SetItemState(i
, m_ListView
.GetItemState(i
, LVIS_SELECTED
) ? 0 : LVIS_SELECTED
, LVIS_SELECTED
);
1586 case FCIDM_SHVIEW_REFRESH
:
1590 case FCIDM_SHVIEW_DELETE
:
1591 case FCIDM_SHVIEW_CUT
:
1592 case FCIDM_SHVIEW_COPY
:
1593 case FCIDM_SHVIEW_RENAME
:
1594 return OnExplorerCommand(dwCmdID
, TRUE
);
1596 case FCIDM_SHVIEW_INSERT
:
1597 case FCIDM_SHVIEW_UNDO
:
1598 case FCIDM_SHVIEW_INSERTLINK
:
1599 case FCIDM_SHVIEW_NEWFOLDER
:
1600 return OnExplorerCommand(dwCmdID
, FALSE
);
1602 /* WM_COMMAND messages from the file menu are routed to the CDefView so as to let m_pCM handle the command */
1605 InvokeContextMenuCommand(dwCmdID
);
1612 /**********************************************************
1613 * ShellView_OnNotify()
1616 LRESULT
CDefView::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1620 LPNMLISTVIEW lpnmlv
;
1621 NMLVDISPINFOW
*lpdi
;
1622 PCUITEMID_CHILD pidl
;
1626 lpnmh
= (LPNMHDR
)lParam
;
1627 lpnmlv
= (LPNMLISTVIEW
)lpnmh
;
1628 lpdi
= (NMLVDISPINFOW
*)lpnmh
;
1630 TRACE("%p CtlID=%u lpnmh->code=%x\n", this, CtlID
, lpnmh
->code
);
1632 switch (lpnmh
->code
)
1635 TRACE("-- NM_SETFOCUS %p\n", this);
1636 OnSetFocus(0, 0, 0, unused
);
1640 TRACE("-- NM_KILLFOCUS %p\n", this);
1642 /* Notify the ICommDlgBrowser interface */
1643 OnStateChange(CDBOSC_KILLFOCUS
);
1647 TRACE("-- NM_CUSTOMDRAW %p\n", this);
1648 return CDRF_DODEFAULT
;
1650 case NM_RELEASEDCAPTURE
:
1651 TRACE("-- NM_RELEASEDCAPTURE %p\n", this);
1655 TRACE("-- NM_CLICK %p\n", this);
1659 TRACE("-- NM_RCLICK %p\n", this);
1663 TRACE("-- NM_DBLCLK %p\n", this);
1664 OpenSelectedItems();
1668 TRACE("-- NM_RETURN %p\n", this);
1669 OpenSelectedItems();
1673 TRACE("-- HDN_ENDTRACKW %p\n", this);
1674 /*nColumn1 = m_ListView.GetColumnWidth(0);
1675 nColumn2 = m_ListView.GetColumnWidth(1);*/
1678 case LVN_DELETEITEM
:
1679 TRACE("-- LVN_DELETEITEM %p\n", this);
1681 /*delete the pidl because we made a copy of it*/
1682 SHFree(reinterpret_cast<LPVOID
>(lpnmlv
->lParam
));
1686 case LVN_DELETEALLITEMS
:
1687 TRACE("-- LVN_DELETEALLITEMS %p\n", this);
1690 case LVN_INSERTITEM
:
1691 TRACE("-- LVN_INSERTITEM (STUB)%p\n", this);
1694 case LVN_ITEMACTIVATE
:
1695 TRACE("-- LVN_ITEMACTIVATE %p\n", this);
1696 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1699 case LVN_COLUMNCLICK
:
1700 m_sortInfo
.nHeaderID
= lpnmlv
->iSubItem
;
1701 if (m_sortInfo
.nLastHeaderID
== m_sortInfo
.nHeaderID
)
1702 m_sortInfo
.bIsAscending
= !m_sortInfo
.bIsAscending
;
1704 m_sortInfo
.bIsAscending
= TRUE
;
1708 case LVN_GETDISPINFOA
:
1709 case LVN_GETDISPINFOW
:
1710 TRACE("-- LVN_GETDISPINFO %p\n", this);
1711 pidl
= _PidlByItem(lpdi
->item
);
1713 if (lpdi
->item
.mask
& LVIF_TEXT
) /* text requested */
1718 if (FAILED_UNEXPECTEDLY(m_pSF2Parent
->GetDetailsOf(pidl
, lpdi
->item
.iSubItem
, &sd
)))
1721 if (lpnmh
->code
== LVN_GETDISPINFOA
)
1723 /* shouldn't happen */
1724 NMLVDISPINFOA
*lpdiA
= (NMLVDISPINFOA
*)lpnmh
;
1725 StrRetToStrNA( lpdiA
->item
.pszText
, lpdiA
->item
.cchTextMax
, &sd
.str
, NULL
);
1726 TRACE("-- text=%s\n", lpdiA
->item
.pszText
);
1728 else /* LVN_GETDISPINFOW */
1730 StrRetToStrNW( lpdi
->item
.pszText
, lpdi
->item
.cchTextMax
, &sd
.str
, NULL
);
1731 TRACE("-- text=%s\n", debugstr_w(lpdi
->item
.pszText
));
1736 FIXME("no m_pSF2Parent\n");
1739 if(lpdi
->item
.mask
& LVIF_IMAGE
) /* image requested */
1741 lpdi
->item
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
1743 if(lpdi
->item
.mask
& LVIF_STATE
)
1745 ULONG attributes
= SFGAO_HIDDEN
;
1746 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(1, &pidl
, &attributes
)))
1748 if (attributes
& SFGAO_HIDDEN
)
1750 lpdi
->item
.state
|= LVIS_CUT
;
1754 lpdi
->item
.mask
|= LVIF_DI_SETITEM
;
1757 case LVN_ITEMCHANGED
:
1758 TRACE("-- LVN_ITEMCHANGED %p\n", this);
1759 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1764 case LVN_BEGINRDRAG
:
1765 TRACE("-- LVN_BEGINDRAG\n");
1767 if (GetSelections())
1769 CComPtr
<IDataObject
> pda
;
1770 DWORD dwAttributes
= SFGAO_CANLINK
;
1771 DWORD dwEffect
= DROPEFFECT_COPY
| DROPEFFECT_MOVE
;
1773 if (SUCCEEDED(m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, IID_NULL_PPV_ARG(IDataObject
, &pda
))))
1775 LPNMLISTVIEW params
= (LPNMLISTVIEW
)lParam
;
1777 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(m_cidl
, m_apidl
, &dwAttributes
)))
1779 if (dwAttributes
& SFGAO_CANLINK
)
1781 dwEffect
|= DROPEFFECT_LINK
;
1785 CComPtr
<IAsyncOperation
> piaso
;
1786 if (SUCCEEDED(pda
->QueryInterface(IID_PPV_ARG(IAsyncOperation
, &piaso
))))
1788 piaso
->SetAsyncMode(TRUE
);
1793 m_pSourceDataObject
= pda
;
1794 m_ptFirstMousePos
= params
->ptAction
;
1795 ClientToScreen(&m_ptFirstMousePos
);
1797 HIMAGELIST big_icons
, small_icons
;
1798 Shell_GetImageLists(&big_icons
, &small_icons
);
1799 PCUITEMID_CHILD pidl
= _PidlByItem(params
->iItem
);
1800 int iIcon
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
1802 m_ListView
.GetItemPosition(params
->iItem
, &ptItem
);
1804 ImageList_BeginDrag(big_icons
, iIcon
, params
->ptAction
.x
- ptItem
.x
, params
->ptAction
.y
- ptItem
.y
);
1806 DoDragDrop(pda
, this, dwEffect
, &dwEffect2
);
1808 m_pSourceDataObject
.Release();
1813 case LVN_BEGINLABELEDITW
:
1815 DWORD dwAttr
= SFGAO_CANRENAME
;
1816 pidl
= _PidlByItem(lpdi
->item
);
1818 TRACE("-- LVN_BEGINLABELEDITW %p\n", this);
1820 m_pSFParent
->GetAttributesOf(1, &pidl
, &dwAttr
);
1821 if (SFGAO_CANRENAME
& dwAttr
)
1829 case LVN_ENDLABELEDITW
:
1831 TRACE("-- LVN_ENDLABELEDITW %p\n", this);
1833 m_isEditing
= FALSE
;
1835 if (lpdi
->item
.pszText
)
1840 pidl
= _PidlByItem(lpdi
->item
);
1841 PITEMID_CHILD pidlNew
;
1842 hr
= m_pSFParent
->SetNameOf(0, pidl
, lpdi
->item
.pszText
, SHGDN_INFOLDER
, &pidlNew
);
1844 if (SUCCEEDED(hr
) && pidlNew
)
1846 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
1847 lvItem
.iItem
= lpdi
->item
.iItem
;
1848 lvItem
.iSubItem
= 0;
1849 lvItem
.lParam
= reinterpret_cast<LPARAM
>(pidlNew
);
1850 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
1851 m_ListView
.SetItem(&lvItem
);
1852 m_ListView
.Update(lpdi
->item
.iItem
);
1861 TRACE("-- %p WM_COMMAND %x unhandled\n", this, lpnmh
->code
);
1869 * This is just a quick hack to make the desktop work correctly.
1870 * ITranslateShellChangeNotify's IsChildID is undocumented, but most likely the way that
1871 * a folder should know if it should update upon a change notification.
1872 * It is exported by merged folders at a minimum.
1874 static BOOL
ILIsParentOrSpecialParent(PCIDLIST_ABSOLUTE pidl1
, PCIDLIST_ABSOLUTE pidl2
)
1876 if (!pidl1
|| !pidl2
)
1878 if (ILIsParent(pidl1
, pidl2
, TRUE
))
1881 if (_ILIsDesktop(pidl1
))
1883 PIDLIST_ABSOLUTE deskpidl
;
1884 SHGetFolderLocation(NULL
, CSIDL_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
1885 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
1891 SHGetFolderLocation(NULL
, CSIDL_COMMON_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
1892 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
1902 /**********************************************************
1903 * ShellView_OnChange()
1905 LRESULT
CDefView::OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1907 PCIDLIST_ABSOLUTE
*Pidls
= reinterpret_cast<PCIDLIST_ABSOLUTE
*>(wParam
);
1908 BOOL bParent0
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[0]);
1909 BOOL bParent1
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[1]);
1911 TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls
[0], Pidls
[1], lParam
);
1913 switch (lParam
&~ SHCNE_INTERRUPT
)
1919 if (LV_FindItemByPidl(ILFindLastID(Pidls
[0])) == -1)
1921 LV_AddItem(ILFindLastID(Pidls
[0]));
1925 LV_ProdItem(ILFindLastID(Pidls
[0]));
1933 LV_DeleteItem(ILFindLastID(Pidls
[0]));
1936 case SHCNE_RENAMEFOLDER
:
1937 case SHCNE_RENAMEITEM
:
1938 if (bParent0
&& bParent1
)
1939 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[1]));
1941 LV_DeleteItem(ILFindLastID(Pidls
[0]));
1943 LV_AddItem(ILFindLastID(Pidls
[1]));
1946 case SHCNE_UPDATEITEM
:
1948 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[0]));
1951 case SHCNE_UPDATEDIR
:
1958 /**********************************************************
1959 * CDefView::OnCustomItem
1961 LRESULT
CDefView::OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1966 ERR("no menu!!!\n");
1971 HRESULT hres
= SHForwardContextMenuMsg(m_pCM
, uMsg
, wParam
, lParam
, &result
, TRUE
);
1972 if (SUCCEEDED(hres
))
1978 LRESULT
CDefView::OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1980 /* Wallpaper setting affects drop shadows effect */
1981 if (wParam
== SPI_SETDESKWALLPAPER
|| wParam
== 0)
1987 /**********************************************************
1988 * CDefView::OnInitMenuPopup
1990 LRESULT
CDefView::OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1992 HMENU hmenu
= (HMENU
) wParam
;
1993 int nPos
= LOWORD(lParam
);
1996 OnCustomItem(uMsg
, wParam
, lParam
, bHandled
);
1998 HMENU hViewMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_VIEW
);
2000 /* Lets try to find out what the hell wParam is */
2001 if (hmenu
== GetSubMenu(m_hMenu
, nPos
))
2002 menuItemId
= ReallyGetMenuItemID(m_hMenu
, nPos
);
2003 else if (hViewMenu
&& hmenu
== GetSubMenu(hViewMenu
, nPos
))
2004 menuItemId
= ReallyGetMenuItemID(hViewMenu
, nPos
);
2005 else if (m_hContextMenu
&& hmenu
== GetSubMenu(m_hContextMenu
, nPos
))
2006 menuItemId
= ReallyGetMenuItemID(m_hContextMenu
, nPos
);
2012 case FCIDM_MENU_FILE
:
2015 case FCIDM_MENU_VIEW
:
2016 case FCIDM_SHVIEW_VIEW
:
2017 CheckViewMode(hmenu
);
2019 case FCIDM_SHVIEW_ARRANGE
:
2020 FillArrangeAsMenu(hmenu
);
2027 /**********************************************************
2030 * The INTERFACE of the IShellView object
2033 **********************************************************
2036 /**********************************************************
2037 * ShellView_GetWindow
2039 HRESULT WINAPI
CDefView::GetWindow(HWND
*phWnd
)
2041 TRACE("(%p)\n", this);
2048 HRESULT WINAPI
CDefView::ContextSensitiveHelp(BOOL fEnterMode
)
2050 FIXME("(%p) stub\n", this);
2055 /**********************************************************
2056 * IShellView_TranslateAccelerator
2059 * use the accel functions
2061 HRESULT WINAPI
CDefView::TranslateAccelerator(LPMSG lpmsg
)
2066 if (lpmsg
->message
>= WM_KEYFIRST
&& lpmsg
->message
<= WM_KEYLAST
)
2068 if (::TranslateAcceleratorW(m_hWnd
, m_hAccel
, lpmsg
) != 0)
2071 TRACE("-- key=0x04%lx\n", lpmsg
->wParam
) ;
2074 return m_pShellBrowser
->TranslateAcceleratorSB(lpmsg
, 0);
2077 HRESULT WINAPI
CDefView::EnableModeless(BOOL fEnable
)
2079 FIXME("(%p) stub\n", this);
2084 HRESULT WINAPI
CDefView::UIActivate(UINT uState
)
2086 // CHAR szName[MAX_PATH];
2088 int nPartArray
[1] = { -1};
2090 TRACE("(%p)->(state=%x) stub\n", this, uState
);
2092 /* don't do anything if the state isn't really changing */
2093 if (m_uState
== uState
)
2098 /* OnActivate handles the menu merging and internal state */
2101 /* only do This if we are active */
2102 if (uState
!= SVUIA_DEACTIVATE
)
2106 GetFolderPath is not a method of IShellFolder
2107 IShellFolder_GetFolderPath( m_pSFParent, szName, sizeof(szName) );
2109 /* set the number of parts */
2110 m_pShellBrowser
->SendControlMsg(FCW_STATUS
, SB_SETPARTS
, 1, (LPARAM
)nPartArray
, &lResult
);
2112 /* set the text for the parts */
2114 m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXTA, 0, (LPARAM)szName, &lResult);
2121 HRESULT WINAPI
CDefView::Refresh()
2123 TRACE("(%p)\n", this);
2125 m_ListView
.DeleteAllItems();
2131 HRESULT WINAPI
CDefView::CreateViewWindow(IShellView
*lpPrevView
, LPCFOLDERSETTINGS lpfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
)
2133 return CreateViewWindow3(psb
, lpPrevView
, SV3CVW3_DEFAULT
,
2134 (FOLDERFLAGS
)lpfs
->fFlags
, (FOLDERFLAGS
)lpfs
->fFlags
, (FOLDERVIEWMODE
)lpfs
->ViewMode
, NULL
, prcView
, phWnd
);
2137 HRESULT WINAPI
CDefView::DestroyViewWindow()
2139 TRACE("(%p)\n", this);
2141 /* Make absolutely sure all our UI is cleaned up */
2142 UIActivate(SVUIA_DEACTIVATE
);
2146 // "Accelerator tables loaded from resources are freed automatically when the application terminates." -- MSDN
2150 if (m_hMenuViewModes
)
2152 DestroyMenu(m_hMenuViewModes
);
2153 m_hMenuViewModes
= NULL
;
2158 DestroyMenu(m_hMenu
);
2164 m_ListView
.DestroyWindow();
2172 m_pShellBrowser
.Release();
2173 m_pCommDlgBrowser
.Release();
2178 HRESULT WINAPI
CDefView::GetCurrentInfo(LPFOLDERSETTINGS lpfs
)
2180 TRACE("(%p)->(%p) vmode=%x flags=%x\n", this, lpfs
,
2181 m_FolderSettings
.ViewMode
, m_FolderSettings
.fFlags
);
2184 return E_INVALIDARG
;
2186 *lpfs
= m_FolderSettings
;
2190 HRESULT WINAPI
CDefView::AddPropertySheetPages(DWORD dwReserved
, LPFNADDPROPSHEETPAGE lpfn
, LPARAM lparam
)
2192 FIXME("(%p) stub\n", this);
2197 HRESULT WINAPI
CDefView::SaveViewState()
2199 FIXME("(%p) stub\n", this);
2204 HRESULT WINAPI
CDefView::SelectItem(PCUITEMID_CHILD pidl
, UINT uFlags
)
2208 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n", this, pidl
, uFlags
);
2210 i
= LV_FindItemByPidl(pidl
);
2214 if(uFlags
& SVSI_ENSUREVISIBLE
)
2215 m_ListView
.EnsureVisible(i
, FALSE
);
2217 LVITEMW lvItem
= {0};
2218 lvItem
.mask
= LVIF_STATE
;
2219 lvItem
.stateMask
= LVIS_SELECTED
| LVIS_FOCUSED
;
2221 while (m_ListView
.GetItem(&lvItem
))
2223 if (lvItem
.iItem
== i
)
2225 if (uFlags
& SVSI_SELECT
)
2226 lvItem
.state
|= LVIS_SELECTED
;
2228 lvItem
.state
&= ~LVIS_SELECTED
;
2230 if (uFlags
& SVSI_FOCUSED
)
2231 lvItem
.state
&= ~LVIS_FOCUSED
;
2235 if (uFlags
& SVSI_DESELECTOTHERS
)
2236 lvItem
.state
&= ~LVIS_SELECTED
;
2239 m_ListView
.SetItem(&lvItem
);
2243 if((uFlags
& SVSI_EDIT
) == SVSI_EDIT
)
2244 m_ListView
.EditLabel(i
);
2249 HRESULT WINAPI
CDefView::GetItemObject(UINT uItem
, REFIID riid
, LPVOID
*ppvOut
)
2251 HRESULT hr
= E_NOINTERFACE
;
2253 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n", this, uItem
, debugstr_guid(&riid
), ppvOut
);
2259 case SVGIO_BACKGROUND
:
2260 if (IsEqualIID(riid
, IID_IContextMenu
))
2265 hr
= CDefViewBckgrndMenu_CreateInstance(m_pSF2Parent
, riid
, ppvOut
);
2266 if (FAILED_UNEXPECTEDLY(hr
))
2270 else if (IsEqualIID(riid
, IID_IDispatch
))
2272 if (m_pShellFolderViewDual
== NULL
)
2274 hr
= CDefViewDual_Constructor(riid
, (LPVOID
*)&m_pShellFolderViewDual
);
2275 if (FAILED_UNEXPECTEDLY(hr
))
2278 hr
= m_pShellFolderViewDual
->QueryInterface(riid
, ppvOut
);
2282 case SVGIO_SELECTION
:
2284 hr
= m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, riid
, 0, ppvOut
);
2285 if (FAILED_UNEXPECTEDLY(hr
))
2290 TRACE("-- (%p)->(interface=%p)\n", this, *ppvOut
);
2295 HRESULT STDMETHODCALLTYPE
CDefView::GetCurrentViewMode(UINT
*pViewMode
)
2297 TRACE("(%p)->(%p), stub\n", this, pViewMode
);
2300 return E_INVALIDARG
;
2302 *pViewMode
= m_FolderSettings
.ViewMode
;
2306 HRESULT STDMETHODCALLTYPE
CDefView::SetCurrentViewMode(UINT ViewMode
)
2309 TRACE("(%p)->(%u), stub\n", this, ViewMode
);
2311 /* It's not redundant to check FVM_AUTO because it's a (UINT)-1 */
2312 if (((INT
)ViewMode
< FVM_FIRST
|| (INT
)ViewMode
> FVM_LAST
) && ((INT
)ViewMode
!= FVM_AUTO
))
2313 return E_INVALIDARG
;
2315 /* Windows before Vista uses LVM_SETVIEW and possibly
2316 LVM_SETEXTENDEDLISTVIEWSTYLE to set the style of the listview,
2317 while later versions seem to accomplish this through other
2325 dwStyle
= LVS_REPORT
;
2328 dwStyle
= LVS_SMALLICON
;
2335 FIXME("ViewMode %d not implemented\n", ViewMode
);
2341 SetStyle(dwStyle
, LVS_TYPEMASK
);
2343 /* This will not necessarily be the actual mode set above.
2344 This mimics the behavior of Windows XP. */
2345 m_FolderSettings
.ViewMode
= ViewMode
;
2350 HRESULT STDMETHODCALLTYPE
CDefView::GetFolder(REFIID riid
, void **ppv
)
2352 if (m_pSFParent
== NULL
)
2355 return m_pSFParent
->QueryInterface(riid
, ppv
);
2358 HRESULT STDMETHODCALLTYPE
CDefView::Item(int iItemIndex
, PITEMID_CHILD
*ppidl
)
2360 PCUITEMID_CHILD pidl
= _PidlByItem(iItemIndex
);
2363 *ppidl
= ILClone(pidl
);
2368 return E_INVALIDARG
;
2371 HRESULT STDMETHODCALLTYPE
CDefView::ItemCount(UINT uFlags
, int *pcItems
)
2373 TRACE("(%p)->(%u %p)\n", this, uFlags
, pcItems
);
2375 if (uFlags
!= SVGIO_ALLVIEW
)
2376 FIXME("some flags unsupported, %x\n", uFlags
& ~SVGIO_ALLVIEW
);
2378 *pcItems
= m_ListView
.GetItemCount();
2383 HRESULT STDMETHODCALLTYPE
CDefView::Items(UINT uFlags
, REFIID riid
, void **ppv
)
2388 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectionMarkedItem(int *piItem
)
2390 TRACE("(%p)->(%p)\n", this, piItem
);
2392 *piItem
= m_ListView
.GetSelectionMark();
2397 HRESULT STDMETHODCALLTYPE
CDefView::GetFocusedItem(int *piItem
)
2399 TRACE("(%p)->(%p)\n", this, piItem
);
2401 *piItem
= m_ListView
.GetNextItem(-1, LVNI_FOCUSED
);
2406 HRESULT STDMETHODCALLTYPE
CDefView::GetItemPosition(PCUITEMID_CHILD pidl
, POINT
*ppt
)
2411 HRESULT STDMETHODCALLTYPE
CDefView::GetSpacing(POINT
*ppt
)
2413 TRACE("(%p)->(%p)\n", this, ppt
);
2421 m_ListView
.GetItemSpacing(spacing
);
2423 ppt
->x
= spacing
.cx
;
2424 ppt
->y
= spacing
.cy
;
2430 HRESULT STDMETHODCALLTYPE
CDefView::GetDefaultSpacing(POINT
*ppt
)
2435 HRESULT STDMETHODCALLTYPE
CDefView::GetAutoArrange()
2440 HRESULT STDMETHODCALLTYPE
CDefView::SelectItem(int iItem
, DWORD dwFlags
)
2444 TRACE("(%p)->(%d, %x)\n", this, iItem
, dwFlags
);
2447 lvItem
.stateMask
= LVIS_SELECTED
;
2449 if (dwFlags
& SVSI_ENSUREVISIBLE
)
2450 m_ListView
.EnsureVisible(iItem
, 0);
2453 if (dwFlags
& SVSI_DESELECTOTHERS
)
2454 m_ListView
.SetItemState(-1, 0, LVIS_SELECTED
);
2457 if (dwFlags
& SVSI_SELECT
)
2458 lvItem
.state
|= LVIS_SELECTED
;
2460 if (dwFlags
& SVSI_FOCUSED
)
2461 lvItem
.stateMask
|= LVIS_FOCUSED
;
2463 m_ListView
.SetItemState(iItem
, lvItem
.state
, lvItem
.stateMask
);
2465 if ((dwFlags
& SVSI_EDIT
) == SVSI_EDIT
)
2466 m_ListView
.EditLabel(iItem
);
2471 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItems(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD dwFlags
)
2476 /**********************************************************
2477 * IShellView2 implementation
2480 HRESULT STDMETHODCALLTYPE
CDefView::GetView(SHELLVIEWID
*view_guid
, ULONG view_type
)
2482 FIXME("(%p)->(%p, %lu) stub\n", this, view_guid
, view_type
);
2486 HRESULT STDMETHODCALLTYPE
CDefView::CreateViewWindow2(LPSV2CVW2_PARAMS view_params
)
2488 return CreateViewWindow3(view_params
->psbOwner
, view_params
->psvPrev
,
2489 SV3CVW3_DEFAULT
, (FOLDERFLAGS
)view_params
->pfs
->fFlags
, (FOLDERFLAGS
)view_params
->pfs
->fFlags
,
2490 (FOLDERVIEWMODE
)view_params
->pfs
->ViewMode
, view_params
->pvid
, view_params
->prcView
, &view_params
->hwndView
);
2493 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
)
2495 OLEMENUGROUPWIDTHS omw
= { { 0, 0, 0, 0, 0, 0 } };
2499 TRACE("(%p)->(shlview=%p shlbrs=%p rec=%p hwnd=%p vmode=%x flags=%x)\n", this, psvPrevious
, psb
, prcView
, hwnd
, mode
, flags
);
2500 if (prcView
!= NULL
)
2501 TRACE("-- left=%i top=%i right=%i bottom=%i\n", prcView
->left
, prcView
->top
, prcView
->right
, prcView
->bottom
);
2503 /* Validate the Shell Browser */
2504 if (psb
== NULL
|| m_hWnd
)
2505 return E_UNEXPECTED
;
2507 if (view_flags
!= SV3CVW3_DEFAULT
)
2508 FIXME("unsupported view flags 0x%08x\n", view_flags
);
2510 /* Set up the member variables */
2511 m_pShellBrowser
= psb
;
2512 m_FolderSettings
.ViewMode
= mode
;
2513 m_FolderSettings
.fFlags
= mask
& flags
;
2517 if (IsEqualIID(*view_id
, VID_LargeIcons
))
2518 m_FolderSettings
.ViewMode
= FVM_ICON
;
2519 else if (IsEqualIID(*view_id
, VID_SmallIcons
))
2520 m_FolderSettings
.ViewMode
= FVM_SMALLICON
;
2521 else if (IsEqualIID(*view_id
, VID_List
))
2522 m_FolderSettings
.ViewMode
= FVM_LIST
;
2523 else if (IsEqualIID(*view_id
, VID_Details
))
2524 m_FolderSettings
.ViewMode
= FVM_DETAILS
;
2525 else if (IsEqualIID(*view_id
, VID_Thumbnails
))
2526 m_FolderSettings
.ViewMode
= FVM_THUMBNAIL
;
2527 else if (IsEqualIID(*view_id
, VID_Tile
))
2528 m_FolderSettings
.ViewMode
= FVM_TILE
;
2529 else if (IsEqualIID(*view_id
, VID_ThumbStrip
))
2530 m_FolderSettings
.ViewMode
= FVM_THUMBSTRIP
;
2532 FIXME("Ignoring unrecognized VID %s\n", debugstr_guid(view_id
));
2535 /* Get our parent window */
2536 m_pShellBrowser
->GetWindow(&m_hWndParent
);
2538 /* Try to get the ICommDlgBrowserInterface, adds a reference !!! */
2539 m_pCommDlgBrowser
= NULL
;
2540 if (SUCCEEDED(m_pShellBrowser
->QueryInterface(IID_PPV_ARG(ICommDlgBrowser
, &m_pCommDlgBrowser
))))
2542 TRACE("-- CommDlgBrowser\n");
2545 Create(m_hWndParent
, prcView
, NULL
, WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
| WS_TABSTOP
, 0, 0U);
2556 SetWindowPos(HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_SHOWWINDOW
);
2561 m_hMenu
= CreateMenu();
2562 m_pShellBrowser
->InsertMenusSB(m_hMenu
, &omw
);
2563 TRACE("-- after fnInsertMenusSB\n");
2571 HRESULT STDMETHODCALLTYPE
CDefView::HandleRename(LPCITEMIDLIST new_pidl
)
2573 FIXME("(%p)->(%p) stub\n", this, new_pidl
);
2577 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItem(LPCITEMIDLIST item
, UINT flags
, POINT
*point
)
2579 FIXME("(%p)->(%p, %u, %p) stub\n", this, item
, flags
, point
);
2583 /**********************************************************
2584 * IShellFolderView implementation
2586 HRESULT STDMETHODCALLTYPE
CDefView::Rearrange(LPARAM sort
)
2588 FIXME("(%p)->(%ld) stub\n", this, sort
);
2592 HRESULT STDMETHODCALLTYPE
CDefView::GetArrangeParam(LPARAM
*sort
)
2594 FIXME("(%p)->(%p) stub\n", this, sort
);
2598 HRESULT STDMETHODCALLTYPE
CDefView::ArrangeGrid()
2600 FIXME("(%p) stub\n", this);
2604 HRESULT STDMETHODCALLTYPE
CDefView::AutoArrange()
2606 FIXME("(%p) stub\n", this);
2610 HRESULT STDMETHODCALLTYPE
CDefView::AddObject(PITEMID_CHILD pidl
, UINT
*item
)
2612 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2616 HRESULT STDMETHODCALLTYPE
CDefView::GetObject(PITEMID_CHILD
*pidl
, UINT item
)
2618 TRACE("(%p)->(%p %d)\n", this, pidl
, item
);
2619 return Item(item
, pidl
);
2622 HRESULT STDMETHODCALLTYPE
CDefView::RemoveObject(PITEMID_CHILD pidl
, UINT
*item
)
2625 TRACE("(%p)->(%p %p)\n", this, pidl
, item
);
2629 *item
= LV_FindItemByPidl(ILFindLastID(pidl
));
2630 m_ListView
.DeleteItem(*item
);
2635 m_ListView
.DeleteAllItems();
2641 HRESULT STDMETHODCALLTYPE
CDefView::GetObjectCount(UINT
*count
)
2643 TRACE("(%p)->(%p)\n", this, count
);
2644 *count
= m_ListView
.GetItemCount();
2648 HRESULT STDMETHODCALLTYPE
CDefView::SetObjectCount(UINT count
, UINT flags
)
2650 FIXME("(%p)->(%d %x) stub\n", this, count
, flags
);
2654 HRESULT STDMETHODCALLTYPE
CDefView::UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
)
2656 FIXME("(%p)->(%p %p %p) stub\n", this, pidl_old
, pidl_new
, item
);
2660 HRESULT STDMETHODCALLTYPE
CDefView::RefreshObject(PITEMID_CHILD pidl
, UINT
*item
)
2662 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2666 HRESULT STDMETHODCALLTYPE
CDefView::SetRedraw(BOOL redraw
)
2668 TRACE("(%p)->(%d)\n", this, redraw
);
2669 m_ListView
.SetRedraw(redraw
);
2673 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedCount(UINT
*count
)
2675 FIXME("(%p)->(%p) stub\n", this, count
);
2679 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
)
2681 TRACE("(%p)->(%p %p)\n", this, pidl
, items
);
2683 *items
= GetSelections();
2687 *pidl
= static_cast<PCUITEMID_CHILD
*>(LocalAlloc(0, *items
* sizeof(PCUITEMID_CHILD
)));
2690 return E_OUTOFMEMORY
;
2693 /* it's documented that caller shouldn't PIDLs, only array itself */
2694 memcpy(*pidl
, m_apidl
, *items
* sizeof(PCUITEMID_CHILD
));
2700 HRESULT STDMETHODCALLTYPE
CDefView::IsDropOnSource(IDropTarget
*drop_target
)
2702 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2706 HRESULT STDMETHODCALLTYPE
CDefView::GetDragPoint(POINT
*pt
)
2708 FIXME("(%p)->(%p) stub\n", this, pt
);
2712 HRESULT STDMETHODCALLTYPE
CDefView::GetDropPoint(POINT
*pt
)
2714 FIXME("(%p)->(%p) stub\n", this, pt
);
2718 HRESULT STDMETHODCALLTYPE
CDefView::MoveIcons(IDataObject
*obj
)
2720 TRACE("(%p)->(%p)\n", this, obj
);
2724 HRESULT STDMETHODCALLTYPE
CDefView::SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
)
2726 FIXME("(%p)->(%p %p) stub\n", this, pidl
, pt
);
2730 HRESULT STDMETHODCALLTYPE
CDefView::IsBkDropTarget(IDropTarget
*drop_target
)
2732 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2736 HRESULT STDMETHODCALLTYPE
CDefView::SetClipboard(BOOL move
)
2738 FIXME("(%p)->(%d) stub\n", this, move
);
2742 HRESULT STDMETHODCALLTYPE
CDefView::SetPoints(IDataObject
*obj
)
2744 FIXME("(%p)->(%p) stub\n", this, obj
);
2748 HRESULT STDMETHODCALLTYPE
CDefView::GetItemSpacing(ITEMSPACING
*spacing
)
2750 FIXME("(%p)->(%p) stub\n", this, spacing
);
2754 HRESULT STDMETHODCALLTYPE
CDefView::SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
)
2756 FIXME("(%p)->(%p %p) stub\n", this, new_cb
, old_cb
);
2760 HRESULT STDMETHODCALLTYPE
CDefView::Select(UINT flags
)
2762 FIXME("(%p)->(%d) stub\n", this, flags
);
2766 HRESULT STDMETHODCALLTYPE
CDefView::QuerySupport(UINT
*support
)
2768 TRACE("(%p)->(%p)\n", this, support
);
2772 HRESULT STDMETHODCALLTYPE
CDefView::SetAutomationObject(IDispatch
*disp
)
2774 FIXME("(%p)->(%p) stub\n", this, disp
);
2778 /**********************************************************
2779 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2781 HRESULT WINAPI
CDefView::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD
*prgCmds
, OLECMDTEXT
*pCmdText
)
2783 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
2784 this, pguidCmdGroup
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
2787 return E_INVALIDARG
;
2789 for (UINT i
= 0; i
< cCmds
; i
++)
2791 FIXME("\tprgCmds[%d].cmdID = %d\n", i
, prgCmds
[i
].cmdID
);
2792 prgCmds
[i
].cmdf
= 0;
2795 return OLECMDERR_E_UNKNOWNGROUP
;
2798 /**********************************************************
2799 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2801 * nCmdID is the OLECMDID_* enumeration
2803 HRESULT WINAPI
CDefView::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
2805 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2806 this, debugstr_guid(pguidCmdGroup
), nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2809 return OLECMDERR_E_UNKNOWNGROUP
;
2811 if (IsEqualCLSID(*pguidCmdGroup
, m_Category
))
2813 if (nCmdID
== FCIDM_SHVIEW_AUTOARRANGE
)
2815 if (V_VT(pvaIn
) != VT_INT_PTR
)
2816 return OLECMDERR_E_NOTSUPPORTED
;
2819 params
.cbSize
= sizeof(params
);
2820 params
.rcExclude
= *(RECT
*) V_INTREF(pvaIn
);
2822 if (m_hMenuViewModes
)
2824 /* Duplicate all but the last two items of the view modes menu */
2825 HMENU hmenuViewPopup
= CreatePopupMenu();
2826 Shell_MergeMenus(hmenuViewPopup
, m_hMenuViewModes
, 0, 0, 0xFFFF, 0);
2827 DeleteMenu(hmenuViewPopup
, GetMenuItemCount(hmenuViewPopup
) - 1, MF_BYPOSITION
);
2828 DeleteMenu(hmenuViewPopup
, GetMenuItemCount(hmenuViewPopup
) - 1, MF_BYPOSITION
);
2829 CheckViewMode(hmenuViewPopup
);
2830 TrackPopupMenuEx(hmenuViewPopup
, TPM_LEFTALIGN
| TPM_TOPALIGN
, params
.rcExclude
.left
, params
.rcExclude
.bottom
, m_hWndParent
, ¶ms
);
2831 ::DestroyMenu(hmenuViewPopup
);
2834 // pvaOut is VT_I4 with value 0x403 (cmd id of the new mode maybe?)
2835 V_VT(pvaOut
) = VT_I4
;
2836 V_I4(pvaOut
) = 0x403;
2840 if (IsEqualIID(*pguidCmdGroup
, CGID_Explorer
) &&
2842 (nCmdexecopt
== 4) && pvaOut
)
2845 if (IsEqualIID(*pguidCmdGroup
, CGID_ShellDocView
) &&
2850 return OLECMDERR_E_UNKNOWNGROUP
;
2853 /**********************************************************
2854 * ISVDropTarget implementation
2857 /******************************************************************************
2858 * drag_notify_subitem [Internal]
2860 * Figure out the shellfolder object, which is currently under the mouse cursor
2861 * and notify it via the IDropTarget interface.
2864 #define SCROLLAREAWIDTH 20
2866 HRESULT
CDefView::drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2872 /* Map from global to client coordinates and query the index of the listview-item, which is
2873 * currently under the mouse cursor. */
2874 LVHITTESTINFO htinfo
= {{pt
.x
, pt
.y
}, LVHT_ONITEM
};
2875 ScreenToClient(&htinfo
.pt
);
2876 lResult
= m_ListView
.HitTest(&htinfo
);
2878 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2879 ::GetClientRect(m_ListView
, &clientRect
);
2880 if (htinfo
.pt
.x
== m_ptLastMousePos
.x
&& htinfo
.pt
.y
== m_ptLastMousePos
.y
&&
2881 (htinfo
.pt
.x
< SCROLLAREAWIDTH
|| htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
||
2882 htinfo
.pt
.y
< SCROLLAREAWIDTH
|| htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
))
2884 m_cScrollDelay
= (m_cScrollDelay
+ 1) % 5; /* DragOver is called every 50 ms */
2885 if (m_cScrollDelay
== 0)
2887 /* Mouse did hover another 250 ms over the scroll-area */
2888 if (htinfo
.pt
.x
< SCROLLAREAWIDTH
)
2889 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEUP
, 0);
2891 if (htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
)
2892 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEDOWN
, 0);
2894 if (htinfo
.pt
.y
< SCROLLAREAWIDTH
)
2895 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEUP
, 0);
2897 if (htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
)
2898 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEDOWN
, 0);
2903 m_cScrollDelay
= 0; /* Reset, if the cursor is not over the listview's scroll-area */
2906 m_ptLastMousePos
= htinfo
.pt
;
2908 /* We need to check if we drag the selection over itself */
2909 if (lResult
!= -1 && m_pSourceDataObject
.p
!= NULL
)
2911 PCUITEMID_CHILD pidl
= _PidlByItem(lResult
);
2913 for (UINT i
= 0; i
< m_cidl
; i
++)
2915 if (pidl
== m_apidl
[i
])
2917 /* The item that is being draged is hovering itself. */
2924 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2925 if (m_pCurDropTarget
&& lResult
== m_iDragOverItem
)
2926 return m_pCurDropTarget
->DragOver(grfKeyState
, pt
, pdwEffect
);
2928 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2929 if (m_pCurDropTarget
)
2931 PCUITEMID_CHILD pidl
= _PidlByItem(m_iDragOverItem
);
2933 SelectItem(pidl
, 0);
2935 m_pCurDropTarget
->DragLeave();
2936 m_pCurDropTarget
.Release();
2939 m_iDragOverItem
= lResult
;
2943 /* We are not above one of the listview's subitems. Bind to the parent folder's
2944 * DropTarget interface. */
2945 hr
= m_pSFParent
->CreateViewObject(NULL
, IID_PPV_ARG(IDropTarget
,&m_pCurDropTarget
));
2949 /* Query the relative PIDL of the shellfolder object represented by the currently
2950 * dragged over listview-item ... */
2951 PCUITEMID_CHILD pidl
= _PidlByItem(lResult
);
2953 /* ... and bind m_pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2954 hr
= m_pSFParent
->GetUIObjectOf(m_ListView
, 1, &pidl
, IID_NULL_PPV_ARG(IDropTarget
, &m_pCurDropTarget
));
2957 /* If anything failed, m_pCurDropTarget should be NULL now, which ought to be a save state. */
2960 *pdwEffect
= DROPEFFECT_NONE
;
2964 if (m_iDragOverItem
!= -1)
2966 SelectItem(m_iDragOverItem
, SVSI_SELECT
);
2969 /* Notify the item just entered via DragEnter. */
2970 return m_pCurDropTarget
->DragEnter(m_pCurDataObject
, grfKeyState
, pt
, pdwEffect
);
2973 HRESULT WINAPI
CDefView::DragEnter(IDataObject
*pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2975 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2976 m_pCurDataObject
= pDataObject
;
2978 HRESULT hr
= drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2981 POINT ptClient
= {pt
.x
, pt
.y
};
2982 ScreenToClient(&ptClient
);
2983 ImageList_DragEnter(m_hWnd
, ptClient
.x
, ptClient
.y
);
2989 HRESULT WINAPI
CDefView::DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2991 POINT ptClient
= {pt
.x
, pt
.y
};
2992 ScreenToClient(&ptClient
);
2993 ImageList_DragMove(ptClient
.x
, ptClient
.y
);
2994 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2997 HRESULT WINAPI
CDefView::DragLeave()
2999 ImageList_DragLeave(m_hWnd
);
3001 if (m_pCurDropTarget
)
3003 m_pCurDropTarget
->DragLeave();
3004 m_pCurDropTarget
.Release();
3007 if (m_pCurDataObject
!= NULL
)
3009 m_pCurDataObject
.Release();
3012 m_iDragOverItem
= 0;
3017 HRESULT WINAPI
CDefView::Drop(IDataObject
* pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
3019 ERR("GetKeyState(VK_LBUTTON): %d\n", GetKeyState(VK_LBUTTON
));
3021 ImageList_DragLeave(m_hWnd
);
3022 ImageList_EndDrag();
3024 if ((m_iDragOverItem
== -1 || m_pCurDropTarget
== NULL
) &&
3025 (*pdwEffect
& DROPEFFECT_MOVE
) &&
3026 /*(GetKeyState(VK_LBUTTON) != 0) &&*/
3027 (m_pSourceDataObject
.p
) &&
3028 (SHIsSameObject(pDataObject
, m_pSourceDataObject
)))
3030 if (m_pCurDropTarget
)
3032 m_pCurDropTarget
->DragLeave();
3033 m_pCurDropTarget
.Release();
3036 /* Restore the selection */
3037 m_ListView
.SetItemState(-1, 0, LVIS_SELECTED
);
3038 for (UINT i
= 0 ; i
< m_cidl
; i
++)
3039 SelectItem(m_apidl
[i
], SVSI_SELECT
);
3041 /* Reposition the items */
3043 while ((lvIndex
= m_ListView
.GetNextItem(lvIndex
, LVNI_SELECTED
)) > -1)
3046 if (m_ListView
.GetItemPosition(lvIndex
, &ptItem
))
3048 ptItem
.x
+= pt
.x
- m_ptFirstMousePos
.x
;
3049 ptItem
.y
+= pt
.y
- m_ptFirstMousePos
.y
;
3050 m_ListView
.SetItemPosition(lvIndex
, &ptItem
);
3054 else if (m_pCurDropTarget
)
3056 m_pCurDropTarget
->Drop(pDataObject
, grfKeyState
, pt
, pdwEffect
);
3057 m_pCurDropTarget
.Release();
3060 m_pCurDataObject
.Release();
3061 m_iDragOverItem
= 0;
3065 /**********************************************************
3066 * ISVDropSource implementation
3069 HRESULT WINAPI
CDefView::QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
)
3071 TRACE("(%p)\n", this);
3074 return DRAGDROP_S_CANCEL
;
3075 else if (!(grfKeyState
& MK_LBUTTON
) && !(grfKeyState
& MK_RBUTTON
))
3076 return DRAGDROP_S_DROP
;
3081 HRESULT WINAPI
CDefView::GiveFeedback(DWORD dwEffect
)
3083 TRACE("(%p)\n", this);
3085 return DRAGDROP_S_USEDEFAULTCURSORS
;
3088 /**********************************************************
3089 * ISVViewObject implementation
3092 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
)
3094 FIXME("Stub: this=%p\n", this);
3099 HRESULT WINAPI
CDefView::GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
, HDC hicTargetDevice
, LOGPALETTE
**ppColorSet
)
3101 FIXME("Stub: this=%p\n", this);
3106 HRESULT WINAPI
CDefView::Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
)
3108 FIXME("Stub: this=%p\n", this);
3113 HRESULT WINAPI
CDefView::Unfreeze(DWORD dwFreeze
)
3115 FIXME("Stub: this=%p\n", this);
3120 HRESULT WINAPI
CDefView::SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
)
3122 FIXME("partial stub: %p %08x %08x %p\n", this, aspects
, advf
, pAdvSink
);
3124 /* FIXME: we set the AdviseSink, but never use it to send any advice */
3125 m_pAdvSink
= pAdvSink
;
3126 m_dwAspects
= aspects
;
3132 HRESULT WINAPI
CDefView::GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
)
3134 TRACE("this=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n", this, pAspects
, pAdvf
, ppAdvSink
);
3138 *ppAdvSink
= m_pAdvSink
;
3139 m_pAdvSink
.p
->AddRef();
3143 *pAspects
= m_dwAspects
;
3151 HRESULT STDMETHODCALLTYPE
CDefView::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
3153 if (IsEqualIID(guidService
, SID_IShellBrowser
))
3154 return m_pShellBrowser
->QueryInterface(riid
, ppvObject
);
3155 else if(IsEqualIID(guidService
, SID_IFolderView
))
3156 return QueryInterface(riid
, ppvObject
);
3158 return E_NOINTERFACE
;
3161 HRESULT
CDefView::_MergeToolbar()
3163 CComPtr
<IExplorerToolbar
> ptb
;
3166 hr
= IUnknown_QueryService(m_pShellBrowser
, IID_IExplorerToolbar
, IID_PPV_ARG(IExplorerToolbar
, &ptb
));
3170 m_Category
= CGID_DefViewFrame
;
3172 hr
= ptb
->SetCommandTarget(static_cast<IOleCommandTarget
*>(this), &m_Category
, 0);
3180 hr
= ptb
->AddButtons(&m_Category
, buttonsCount
, buttons
);
3188 HRESULT
CDefView_CreateInstance(IShellFolder
*pFolder
, REFIID riid
, LPVOID
* ppvOut
)
3190 return ShellObjectCreatorInit
<CDefView
>(pFolder
, riid
, ppvOut
);
3193 HRESULT WINAPI
SHCreateShellFolderViewEx(
3194 LPCSFV psvcbi
, /* [in] shelltemplate struct */
3195 IShellView
**ppsv
) /* [out] IShellView pointer */
3197 CComPtr
<IShellView
> psv
;
3200 TRACE("sf=%p pidl=%p cb=%p mode=0x%08x parm=%p\n",
3201 psvcbi
->pshf
, psvcbi
->pidl
, psvcbi
->pfnCallback
,
3202 psvcbi
->fvm
, psvcbi
->psvOuter
);
3205 hRes
= CDefView_CreateInstance(psvcbi
->pshf
, IID_PPV_ARG(IShellView
, &psv
));
3206 if (FAILED_UNEXPECTEDLY(hRes
))
3209 *ppsv
= psv
.Detach();
3213 HRESULT WINAPI
SHCreateShellFolderView(const SFV_CREATE
*pcsfv
,
3216 CComPtr
<IShellView
> psv
;
3220 if (!pcsfv
|| pcsfv
->cbSize
!= sizeof(*pcsfv
))
3221 return E_INVALIDARG
;
3223 TRACE("sf=%p outer=%p callback=%p\n",
3224 pcsfv
->pshf
, pcsfv
->psvOuter
, pcsfv
->psfvcb
);
3226 hRes
= CDefView_CreateInstance(pcsfv
->pshf
, IID_PPV_ARG(IShellView
, &psv
));
3230 *ppsv
= psv
.Detach();