4 * Copyright 1998,1999 <juergen.schmied@debitel.net>
6 * This is the view visualizing the data provided by the shellfolder.
7 * No direct access to data from pidls should be done from here.
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 * FIXME: The order by part of the background context menu should be
24 * built according to the columns shown.
26 * FIXME: CheckToolbar: handle the "new folder" and "folder up" button
31 - Load/Save the view state from/into the stream provided by the ShellBrowser.
32 - Code to merge menus in the shellbrowser is incorrect.
33 - Move the background context menu creation into shell view. It should store the
34 shell view HWND to send commands.
35 - Shell view should do SetCommandTarget on internet toolbar.
36 - When editing starts on item, set edit text to for editing value.
37 - When shell view is called back for item info, let listview save the value.
38 - Fix shell view to handle view mode popup exec.
39 - The background context menu should have a pidl just like foreground menus. This
40 causes crashes when dynamic handlers try to use the NULL pidl.
41 - The SHELLDLL_DefView should not be filled with blue unconditionally. This causes
42 annoying flashing of blue even on XP, and is not correct.
43 - Reorder of columns doesn't work - might be bug in comctl32
51 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
55 static const WCHAR SV_CLASS_NAME
[] = {'S', 'H', 'E', 'L', 'L', 'D', 'L', 'L', '_', 'D', 'e', 'f', 'V', 'i', 'e', 'w', 0};
62 } LISTVIEW_SORT_INFO
, *LPLISTVIEW_SORT_INFO
;
64 #define SHV_CHANGE_NOTIFY WM_USER + 0x1111
67 public CWindowImpl
<CDefView
, CWindow
, CControlWinTraits
>,
68 public CComObjectRootEx
<CComMultiThreadModelNoCS
>,
71 public IShellFolderView
,
72 public IOleCommandTarget
,
76 public IServiceProvider
79 CComPtr
<IShellFolder
> m_pSFParent
;
80 CComPtr
<IShellFolder2
> m_pSF2Parent
;
81 CComPtr
<IShellBrowser
> m_pShellBrowser
;
82 CComPtr
<ICommDlgBrowser
> m_pCommDlgBrowser
;
83 CComPtr
<IShellFolderViewDual
> m_pShellFolderViewDual
;
86 FOLDERSETTINGS m_FolderSettings
;
91 PCUITEMID_CHILD
*m_apidl
;
92 PIDLIST_ABSOLUTE m_pidlParent
;
93 LISTVIEW_SORT_INFO m_sortInfo
;
94 ULONG m_hNotify
; /* Change notification handle */
98 CComPtr
<IAdviseSink
> m_pAdvSink
;
100 CComPtr
<IDataObject
> m_pSourceDataObject
;
101 CComPtr
<IDropTarget
> m_pCurDropTarget
; /* The sub-item, which is currently dragged over */
102 CComPtr
<IDataObject
> m_pCurDataObject
; /* The dragged data-object */
103 LONG m_iDragOverItem
; /* Dragged over item's index, iff m_pCurDropTarget != NULL */
104 UINT m_cScrollDelay
; /* Send a WM_*SCROLL msg every 250 ms during drag-scroll */
105 POINT m_ptLastMousePos
; /* Mouse position at last DragOver call */
107 CComPtr
<IContextMenu
> m_pCM
;
116 HRESULT
_MergeToolbar();
121 HRESULT WINAPI
Initialize(IShellFolder
*shellFolder
);
122 HRESULT
IncludeObject(PCUITEMID_CHILD pidl
);
123 HRESULT
OnDefaultCommand();
124 HRESULT
OnStateChange(UINT uFlags
);
125 void UpdateStatusbar();
127 void SetStyle(DWORD dwAdd
, DWORD dwRemove
);
129 void UpdateListColors();
131 static INT CALLBACK
ListViewCompareItems(LPARAM lParam1
, LPARAM lParam2
, LPARAM lpData
);
133 PCUITEMID_CHILD
_PidlByItem(int i
);
134 PCUITEMID_CHILD
_PidlByItem(LVITEM
& lvItem
);
135 int LV_FindItemByPidl(PCUITEMID_CHILD pidl
);
136 BOOLEAN
LV_AddItem(PCUITEMID_CHILD pidl
);
137 BOOLEAN
LV_DeleteItem(PCUITEMID_CHILD pidl
);
138 BOOLEAN
LV_RenameItem(PCUITEMID_CHILD pidlOld
, PCUITEMID_CHILD pidlNew
);
139 BOOLEAN
LV_ProdItem(PCUITEMID_CHILD pidl
);
140 static INT CALLBACK
fill_list(LPVOID ptr
, LPVOID arg
);
142 HMENU
BuildFileMenu();
143 void PrepareShowFileMenu(HMENU hSubMenu
);
144 void PrepareShowViewMenu(HMENU hSubMenu
);
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 // *** IFolderView methods ***
177 virtual HRESULT STDMETHODCALLTYPE
GetCurrentViewMode(UINT
*pViewMode
);
178 virtual HRESULT STDMETHODCALLTYPE
SetCurrentViewMode(UINT ViewMode
);
179 virtual HRESULT STDMETHODCALLTYPE
GetFolder(REFIID riid
, void **ppv
);
180 virtual HRESULT STDMETHODCALLTYPE
Item(int iItemIndex
, PITEMID_CHILD
*ppidl
);
181 virtual HRESULT STDMETHODCALLTYPE
ItemCount(UINT uFlags
, int *pcItems
);
182 virtual HRESULT STDMETHODCALLTYPE
Items(UINT uFlags
, REFIID riid
, void **ppv
);
183 virtual HRESULT STDMETHODCALLTYPE
GetSelectionMarkedItem(int *piItem
);
184 virtual HRESULT STDMETHODCALLTYPE
GetFocusedItem(int *piItem
);
185 virtual HRESULT STDMETHODCALLTYPE
GetItemPosition(PCUITEMID_CHILD pidl
, POINT
*ppt
);
186 virtual HRESULT STDMETHODCALLTYPE
GetSpacing(POINT
*ppt
);
187 virtual HRESULT STDMETHODCALLTYPE
GetDefaultSpacing(POINT
*ppt
);
188 virtual HRESULT STDMETHODCALLTYPE
GetAutoArrange();
189 virtual HRESULT STDMETHODCALLTYPE
SelectItem(int iItem
, DWORD dwFlags
);
190 virtual HRESULT STDMETHODCALLTYPE
SelectAndPositionItems(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD dwFlags
);
192 // *** IShellFolderView methods ***
193 virtual HRESULT STDMETHODCALLTYPE
Rearrange(LPARAM sort
);
194 virtual HRESULT STDMETHODCALLTYPE
GetArrangeParam(LPARAM
*sort
);
195 virtual HRESULT STDMETHODCALLTYPE
ArrangeGrid();
196 virtual HRESULT STDMETHODCALLTYPE
AutoArrange();
197 virtual HRESULT STDMETHODCALLTYPE
AddObject(PITEMID_CHILD pidl
, UINT
*item
);
198 virtual HRESULT STDMETHODCALLTYPE
GetObject(PITEMID_CHILD
*pidl
, UINT item
);
199 virtual HRESULT STDMETHODCALLTYPE
RemoveObject(PITEMID_CHILD pidl
, UINT
*item
);
200 virtual HRESULT STDMETHODCALLTYPE
GetObjectCount(UINT
*count
);
201 virtual HRESULT STDMETHODCALLTYPE
SetObjectCount(UINT count
, UINT flags
);
202 virtual HRESULT STDMETHODCALLTYPE
UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
);
203 virtual HRESULT STDMETHODCALLTYPE
RefreshObject(PITEMID_CHILD pidl
, UINT
*item
);
204 virtual HRESULT STDMETHODCALLTYPE
SetRedraw(BOOL redraw
);
205 virtual HRESULT STDMETHODCALLTYPE
GetSelectedCount(UINT
*count
);
206 virtual HRESULT STDMETHODCALLTYPE
GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
);
207 virtual HRESULT STDMETHODCALLTYPE
IsDropOnSource(IDropTarget
*drop_target
);
208 virtual HRESULT STDMETHODCALLTYPE
GetDragPoint(POINT
*pt
);
209 virtual HRESULT STDMETHODCALLTYPE
GetDropPoint(POINT
*pt
);
210 virtual HRESULT STDMETHODCALLTYPE
MoveIcons(IDataObject
*obj
);
211 virtual HRESULT STDMETHODCALLTYPE
SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
);
212 virtual HRESULT STDMETHODCALLTYPE
IsBkDropTarget(IDropTarget
*drop_target
);
213 virtual HRESULT STDMETHODCALLTYPE
SetClipboard(BOOL move
);
214 virtual HRESULT STDMETHODCALLTYPE
SetPoints(IDataObject
*obj
);
215 virtual HRESULT STDMETHODCALLTYPE
GetItemSpacing(ITEMSPACING
*spacing
);
216 virtual HRESULT STDMETHODCALLTYPE
SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
);
217 virtual HRESULT STDMETHODCALLTYPE
Select(UINT flags
);
218 virtual HRESULT STDMETHODCALLTYPE
QuerySupport(UINT
*support
);
219 virtual HRESULT STDMETHODCALLTYPE
SetAutomationObject(IDispatch
*disp
);
221 // *** IOleCommandTarget methods ***
222 virtual HRESULT STDMETHODCALLTYPE
QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
);
223 virtual HRESULT STDMETHODCALLTYPE
Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
);
225 // *** IDropTarget methods ***
226 virtual HRESULT STDMETHODCALLTYPE
DragEnter(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
227 virtual HRESULT STDMETHODCALLTYPE
DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
228 virtual HRESULT STDMETHODCALLTYPE
DragLeave();
229 virtual HRESULT STDMETHODCALLTYPE
Drop(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
231 // *** IDropSource methods ***
232 virtual HRESULT STDMETHODCALLTYPE
QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
);
233 virtual HRESULT STDMETHODCALLTYPE
GiveFeedback(DWORD dwEffect
);
235 // *** IViewObject methods ***
236 virtual HRESULT STDMETHODCALLTYPE
Draw(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
,
237 HDC hdcTargetDev
, HDC hdcDraw
, LPCRECTL lprcBounds
, LPCRECTL lprcWBounds
,
238 BOOL ( STDMETHODCALLTYPE
*pfnContinue
)(ULONG_PTR dwContinue
), ULONG_PTR dwContinue
);
239 virtual HRESULT STDMETHODCALLTYPE
GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
,
240 DVTARGETDEVICE
*ptd
, HDC hicTargetDev
, LOGPALETTE
**ppColorSet
);
241 virtual HRESULT STDMETHODCALLTYPE
Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
);
242 virtual HRESULT STDMETHODCALLTYPE
Unfreeze(DWORD dwFreeze
);
243 virtual HRESULT STDMETHODCALLTYPE
SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
);
244 virtual HRESULT STDMETHODCALLTYPE
GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
);
246 // *** IServiceProvider methods ***
247 virtual HRESULT STDMETHODCALLTYPE
QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
);
250 LRESULT
OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
251 LRESULT
OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
252 LRESULT
OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
253 LRESULT
OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
254 LRESULT
OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
255 LRESULT
OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
256 LRESULT
OnNCCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
257 LRESULT
OnNCDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
258 LRESULT
OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
259 LRESULT
OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
260 LRESULT
OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
261 LRESULT
OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
262 LRESULT
OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
263 LRESULT
OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
264 LRESULT
OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
265 LRESULT
OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
266 LRESULT
OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
267 LRESULT
OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
268 LRESULT
OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
269 LRESULT
OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
271 static ATL::CWndClassInfo
& GetWndClassInfo()
273 static ATL::CWndClassInfo wc
=
275 { sizeof(WNDCLASSEX
), CS_PARENTDC
, StartWindowProc
,
277 LoadCursor(NULL
, IDC_ARROW
), (HBRUSH
)(COLOR_WINDOW
+ 1), NULL
, SV_CLASS_NAME
, NULL
279 NULL
, NULL
, IDC_ARROW
, TRUE
, 0, _T("")
284 virtual WNDPROC
GetWindowProc()
289 static LRESULT CALLBACK
WindowProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
294 // Must hold a reference during message handling
295 pThis
= reinterpret_cast<CDefView
*>(hWnd
);
297 result
= CWindowImpl
<CDefView
, CWindow
, CControlWinTraits
>::WindowProc(hWnd
, uMsg
, wParam
, lParam
);
302 BEGIN_MSG_MAP(CDefView
)
303 MESSAGE_HANDLER(WM_SIZE
, OnSize
)
304 MESSAGE_HANDLER(WM_SETFOCUS
, OnSetFocus
)
305 MESSAGE_HANDLER(WM_KILLFOCUS
, OnKillFocus
)
306 MESSAGE_HANDLER(WM_NCCREATE
, OnNCCreate
)
307 MESSAGE_HANDLER(WM_NCDESTROY
, OnNCDestroy
)
308 MESSAGE_HANDLER(WM_CREATE
, OnCreate
)
309 MESSAGE_HANDLER(WM_ACTIVATE
, OnActivate
)
310 MESSAGE_HANDLER(WM_NOTIFY
, OnNotify
)
311 MESSAGE_HANDLER(WM_COMMAND
, OnCommand
)
312 MESSAGE_HANDLER(SHV_CHANGE_NOTIFY
, OnChangeNotify
)
313 MESSAGE_HANDLER(WM_CONTEXTMENU
, OnContextMenu
)
314 MESSAGE_HANDLER(WM_DRAWITEM
, OnCustomItem
)
315 MESSAGE_HANDLER(WM_MEASUREITEM
, OnCustomItem
)
316 MESSAGE_HANDLER(WM_SHOWWINDOW
, OnShowWindow
)
317 MESSAGE_HANDLER(WM_GETDLGCODE
, OnGetDlgCode
)
318 MESSAGE_HANDLER(WM_DESTROY
, OnDestroy
)
319 MESSAGE_HANDLER(WM_ERASEBKGND
, OnEraseBackground
)
320 MESSAGE_HANDLER(WM_SYSCOLORCHANGE
, OnSysColorChange
)
321 MESSAGE_HANDLER(CWM_GETISHELLBROWSER
, OnGetShellBrowser
)
322 MESSAGE_HANDLER(WM_SETTINGCHANGE
, OnSettingChange
)
323 MESSAGE_HANDLER(WM_INITMENUPOPUP
, OnInitMenuPopup
)
326 BEGIN_COM_MAP(CDefView
)
327 // Windows returns E_NOINTERFACE for IOleWindow
328 // COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
329 COM_INTERFACE_ENTRY_IID(IID_IShellView
, 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_menusLoaded(FALSE
),
374 ZeroMemory(&m_FolderSettings
, sizeof(m_FolderSettings
));
375 ZeroMemory(&m_sortInfo
, sizeof(m_sortInfo
));
376 ZeroMemory(&m_ptLastMousePos
, sizeof(m_ptLastMousePos
));
377 ZeroMemory(&m_Category
, sizeof(m_Category
));
380 CDefView::~CDefView()
382 TRACE(" destroying IShellView(%p)\n", this);
392 HRESULT WINAPI
CDefView::Initialize(IShellFolder
*shellFolder
)
394 m_pSFParent
= shellFolder
;
395 shellFolder
->QueryInterface(IID_PPV_ARG(IShellFolder2
, &m_pSF2Parent
));
400 /**********************************************************
402 * ##### helperfunctions for communication with ICommDlgBrowser #####
404 HRESULT
CDefView::IncludeObject(PCUITEMID_CHILD pidl
)
408 if (m_pCommDlgBrowser
.p
!= NULL
)
410 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl
);
411 ret
= m_pCommDlgBrowser
->IncludeObject(this, pidl
);
412 TRACE("--0x%08x\n", ret
);
418 HRESULT
CDefView::OnDefaultCommand()
420 HRESULT ret
= S_FALSE
;
422 if (m_pCommDlgBrowser
.p
!= NULL
)
424 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
425 ret
= m_pCommDlgBrowser
->OnDefaultCommand(this);
426 TRACE("-- returns %08x\n", ret
);
432 HRESULT
CDefView::OnStateChange(UINT uFlags
)
434 HRESULT ret
= S_FALSE
;
436 if (m_pCommDlgBrowser
.p
!= NULL
)
438 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags
);
439 ret
= m_pCommDlgBrowser
->OnStateChange(this, uFlags
);
445 /**********************************************************
446 * set the toolbar of the filedialog buttons
448 * - activates the buttons from the shellbrowser according to
451 void CDefView::CheckToolbar()
457 if (m_pCommDlgBrowser
!= NULL
)
459 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
460 FCIDM_TB_SMALLICON
, (m_FolderSettings
.ViewMode
== FVM_LIST
) ? TRUE
: FALSE
, &result
);
461 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
462 FCIDM_TB_REPORTVIEW
, (m_FolderSettings
.ViewMode
== FVM_DETAILS
) ? TRUE
: FALSE
, &result
);
463 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
464 FCIDM_TB_SMALLICON
, TRUE
, &result
);
465 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
466 FCIDM_TB_REPORTVIEW
, TRUE
, &result
);
470 void CDefView::UpdateStatusbar()
472 WCHAR szFormat
[MAX_PATH
] = {0};
473 WCHAR szObjects
[MAX_PATH
] = {0};
476 cSelectedItems
= m_ListView
.GetSelectedCount();
479 LoadStringW(shell32_hInstance
, IDS_OBJECTS_SELECTED
, szFormat
, _countof(szFormat
));
480 StringCchPrintfW(szObjects
, MAX_PATH
, szFormat
, cSelectedItems
);
484 LoadStringW(shell32_hInstance
, IDS_OBJECTS
, szFormat
, _countof(szFormat
));
485 StringCchPrintfW(szObjects
, MAX_PATH
, szFormat
, m_ListView
.GetItemCount());
487 m_pShellBrowser
->SetStatusTextSB(szObjects
);
490 /**********************************************************
492 * ##### helperfunctions for initializing the view #####
494 /**********************************************************
495 * change the style of the listview control
497 void CDefView::SetStyle(DWORD dwAdd
, DWORD dwRemove
)
501 TRACE("(%p)\n", this);
503 tmpstyle
= ::GetWindowLongPtrW(m_ListView
, GWL_STYLE
);
504 ::SetWindowLongPtrW(m_ListView
, GWL_STYLE
, dwAdd
| (tmpstyle
& ~dwRemove
));
507 /**********************************************************
508 * ShellView_CreateList()
510 * - creates the list view window
512 BOOL
CDefView::CreateList()
514 DWORD dwStyle
, dwExStyle
;
518 dwStyle
= WS_TABSTOP
| WS_VISIBLE
| WS_CHILDWINDOW
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
|
519 LVS_SHAREIMAGELISTS
| LVS_EDITLABELS
| LVS_AUTOARRANGE
;
520 dwExStyle
= WS_EX_CLIENTEDGE
;
522 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
523 dwStyle
|= LVS_ALIGNLEFT
;
525 dwStyle
|= LVS_ALIGNTOP
| LVS_SHOWSELALWAYS
;
527 switch (m_FolderSettings
.ViewMode
)
534 dwStyle
|= LVS_REPORT
;
538 dwStyle
|= LVS_SMALLICON
;
550 if (m_FolderSettings
.fFlags
& FWF_AUTOARRANGE
)
551 dwStyle
|= LVS_AUTOARRANGE
;
553 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
554 m_FolderSettings
.fFlags
|= FWF_NOCLIENTEDGE
| FWF_NOSCROLL
;
556 if (m_FolderSettings
.fFlags
& FWF_SINGLESEL
)
557 dwStyle
|= LVS_SINGLESEL
;
559 if (m_FolderSettings
.fFlags
& FWF_NOCLIENTEDGE
)
560 dwExStyle
&= ~WS_EX_CLIENTEDGE
;
562 RECT rcListView
= {0,0,0,0};
563 m_ListView
.Create(m_hWnd
, rcListView
, L
"FolderView", dwStyle
, dwExStyle
, ID_LISTVIEW
);
568 m_sortInfo
.bIsAscending
= TRUE
;
569 m_sortInfo
.nHeaderID
= -1;
570 m_sortInfo
.nLastHeaderID
= -1;
574 /* UpdateShellSettings(); */
578 void CDefView::UpdateListColors()
580 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
582 /* Check if drop shadows option is enabled */
583 BOOL bDropShadow
= FALSE
;
584 DWORD cbDropShadow
= sizeof(bDropShadow
);
587 * The desktop ListView always take the default desktop colours, by
588 * remaining transparent and letting user32/win32k paint itself the
589 * desktop background color, if any.
591 m_ListView
.SetBkColor(CLR_NONE
);
593 RegGetValueW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
594 L
"ListviewShadow", RRF_RT_DWORD
, NULL
, &bDropShadow
, &cbDropShadow
);
597 /* Set the icon background transparent */
598 m_ListView
.SetTextBkColor(CLR_NONE
);
599 m_ListView
.SetTextColor(RGB(255, 255, 255));
600 m_ListView
.SetExtendedListViewStyle(LVS_EX_TRANSPARENTSHADOWTEXT
, LVS_EX_TRANSPARENTSHADOWTEXT
);
604 /* Set the icon background as the same colour as the desktop */
605 COLORREF crDesktop
= GetSysColor(COLOR_DESKTOP
);
606 m_ListView
.SetTextBkColor(crDesktop
);
607 if (GetRValue(crDesktop
) + GetGValue(crDesktop
) + GetBValue(crDesktop
) > 128 * 3)
608 m_ListView
.SetTextColor(RGB(0, 0, 0));
610 m_ListView
.SetTextColor(RGB(255, 255, 255));
611 m_ListView
.SetExtendedListViewStyle(0, LVS_EX_TRANSPARENTSHADOWTEXT
);
616 /**********************************************************
617 * ShellView_InitList()
619 * - adds all needed columns to the shellview
621 BOOL
CDefView::InitList()
625 HIMAGELIST big_icons
, small_icons
;
629 m_ListView
.DeleteAllItems();
633 for (int i
= 0; 1; i
++)
635 if (FAILED(m_pSF2Parent
->GetDetailsOf(NULL
, i
, &sd
)))
637 StrRetToStrNW( szTemp
, 50, &sd
.str
, NULL
);
638 m_ListView
.InsertColumn(i
, szTemp
, sd
.fmt
, sd
.cxChar
* 8);
644 FIXME("no m_pSF2Parent\n");
647 Shell_GetImageLists(&big_icons
, &small_icons
);
648 m_ListView
.SetImageList(big_icons
, LVSIL_NORMAL
);
649 m_ListView
.SetImageList(small_icons
, LVSIL_SMALL
);
654 /*************************************************************************
655 * ShellView_ListViewCompareItems
657 * Compare Function for the Listview (FileOpen Dialog)
660 * lParam1 [I] the first ItemIdList to compare with
661 * lParam2 [I] the second ItemIdList to compare with
662 * lpData [I] The column ID for the header Ctrl to process
665 * A negative value if the first item should precede the second,
666 * a positive value if the first item should follow the second,
667 * or zero if the two items are equivalent
669 INT CALLBACK
CDefView::ListViewCompareItems(LPARAM lParam1
, LPARAM lParam2
, LPARAM lpData
)
671 PCUIDLIST_RELATIVE pidl1
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam1
);
672 PCUIDLIST_RELATIVE pidl2
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam2
);
673 CDefView
*pThis
= reinterpret_cast<CDefView
*>(lpData
);
675 HRESULT hres
= pThis
->m_pSFParent
->CompareIDs(pThis
->m_sortInfo
.nHeaderID
, pidl1
, pidl2
);
676 if (FAILED_UNEXPECTEDLY(hres
))
679 SHORT nDiff
= HRESULT_CODE(hres
);
680 if (!pThis
->m_sortInfo
.bIsAscending
)
685 PCUITEMID_CHILD
CDefView::_PidlByItem(int i
)
687 return reinterpret_cast<PCUITEMID_CHILD
>(m_ListView
.GetItemData(i
));
690 PCUITEMID_CHILD
CDefView::_PidlByItem(LVITEM
& lvItem
)
692 return reinterpret_cast<PCUITEMID_CHILD
>(lvItem
.lParam
);
695 /**********************************************************
696 * LV_FindItemByPidl()
698 int CDefView::LV_FindItemByPidl(PCUITEMID_CHILD pidl
)
700 int cItems
= m_ListView
.GetItemCount();
702 for (int i
= 0; i
<cItems
; i
++)
704 PCUITEMID_CHILD currentpidl
= _PidlByItem(i
);
705 HRESULT hr
= m_pSFParent
->CompareIDs(0, pidl
, currentpidl
);
707 if (SUCCEEDED(hr
) && !HRESULT_CODE(hr
))
715 /**********************************************************
718 BOOLEAN
CDefView::LV_AddItem(PCUITEMID_CHILD pidl
)
722 TRACE("(%p)(pidl=%p)\n", this, pidl
);
724 lvItem
.mask
= LVIF_TEXT
| LVIF_IMAGE
| LVIF_PARAM
; /*set the mask*/
725 lvItem
.iItem
= m_ListView
.GetItemCount(); /*add the item to the end of the list*/
727 lvItem
.lParam
= reinterpret_cast<LPARAM
>(ILClone(pidl
)); /*set the item's data*/
728 lvItem
.pszText
= LPSTR_TEXTCALLBACKW
; /*get text on a callback basis*/
729 lvItem
.iImage
= I_IMAGECALLBACK
; /*get the image on a callback basis*/
730 lvItem
.stateMask
= LVIS_CUT
;
732 if (m_ListView
.InsertItem(&lvItem
) == -1)
738 /**********************************************************
741 BOOLEAN
CDefView::LV_DeleteItem(PCUITEMID_CHILD pidl
)
745 TRACE("(%p)(pidl=%p)\n", this, pidl
);
747 nIndex
= LV_FindItemByPidl(pidl
);
749 return (-1 == m_ListView
.DeleteItem(nIndex
)) ? FALSE
: TRUE
;
752 /**********************************************************
755 BOOLEAN
CDefView::LV_RenameItem(PCUITEMID_CHILD pidlOld
, PCUITEMID_CHILD pidlNew
)
760 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", this, pidlOld
, pidlNew
);
762 nItem
= LV_FindItemByPidl(pidlOld
);
766 lvItem
.mask
= LVIF_PARAM
; /* only the pidl */
767 lvItem
.iItem
= nItem
;
769 m_ListView
.GetItem(&lvItem
);
771 SHFree(reinterpret_cast<LPVOID
>(lvItem
.lParam
));
772 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
773 lvItem
.iItem
= nItem
;
775 lvItem
.lParam
= reinterpret_cast<LPARAM
>(ILClone(pidlNew
)); /* set the item's data */
776 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
777 m_ListView
.SetItem(&lvItem
);
778 m_ListView
.Update(nItem
);
779 return TRUE
; /* FIXME: better handling */
785 /**********************************************************
788 BOOLEAN
CDefView::LV_ProdItem(PCUITEMID_CHILD pidl
)
793 TRACE("(%p)(pidl=%p)\n", this, pidl
);
795 nItem
= LV_FindItemByPidl(pidl
);
799 lvItem
.mask
= LVIF_IMAGE
;
800 lvItem
.iItem
= nItem
;
802 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
803 m_ListView
.SetItem(&lvItem
);
804 m_ListView
.Update(nItem
);
811 /**********************************************************
812 * ShellView_FillList()
814 * - gets the objectlist from the shellfolder
816 * - fills the list into the view
818 INT CALLBACK
CDefView::fill_list(LPVOID ptr
, LPVOID arg
)
820 PITEMID_CHILD pidl
= static_cast<PITEMID_CHILD
>(ptr
);
821 CDefView
*pThis
= static_cast<CDefView
*>(arg
);
823 /* in a commdlg This works as a filemask*/
824 if (pThis
->IncludeObject(pidl
) == S_OK
)
825 pThis
->LV_AddItem(pidl
);
831 HRESULT
CDefView::FillList()
833 CComPtr
<IEnumIDList
> pEnumIDList
;
839 DWORD dFlags
= SHCONTF_NONFOLDERS
| SHCONTF_FOLDERS
;
843 /* determine if there is a setting to show all the hidden files/folders */
844 if (RegOpenKeyExW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", 0, KEY_QUERY_VALUE
, &hKey
) == ERROR_SUCCESS
)
846 DWORD dataLength
, flagVal
;
848 dataLength
= sizeof(flagVal
);
849 if (RegQueryValueExW(hKey
, L
"Hidden", NULL
, NULL
, (LPBYTE
)&flagVal
, &dataLength
) == ERROR_SUCCESS
)
851 /* if the value is 1, then show all hidden files/folders */
854 dFlags
|= SHCONTF_INCLUDEHIDDEN
;
855 m_ListView
.SendMessageW(LVM_SETCALLBACKMASK
, LVIS_CUT
, 0);
863 /* get the itemlist from the shfolder */
864 hRes
= m_pSFParent
->EnumObjects(m_hWnd
, dFlags
, &pEnumIDList
);
872 /* create a pointer array */
873 hdpa
= DPA_Create(16);
876 return(E_OUTOFMEMORY
);
879 /* copy the items into the array*/
880 while((S_OK
== pEnumIDList
->Next(1, &pidl
, &dwFetched
)) && dwFetched
)
882 if (DPA_InsertPtr(hdpa
, 0x7fff, pidl
) == -1)
888 /*turn the listview's redrawing off*/
889 m_ListView
.SetRedraw(FALSE
);
891 DPA_DestroyCallback( hdpa
, fill_list
, this);
896 m_pSF2Parent
->GetDefaultColumn(NULL
, (ULONG
*)&m_sortInfo
.nHeaderID
, NULL
);
900 FIXME("no m_pSF2Parent\n");
902 m_sortInfo
.bIsAscending
= TRUE
;
903 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
904 m_ListView
.SortItems(ListViewCompareItems
, this);
906 /*turn the listview's redrawing back on and force it to draw*/
907 m_ListView
.SetRedraw(TRUE
);
912 LRESULT
CDefView::OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
914 m_ListView
.UpdateWindow();
919 LRESULT
CDefView::OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
921 return m_ListView
.SendMessageW(uMsg
, 0, 0);
924 LRESULT
CDefView::OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
931 DestroyMenu(m_hMenu
);
934 RevokeDragDrop(m_hWnd
);
935 SHChangeNotifyDeregister(m_hNotify
);
937 SHFree(m_pidlParent
);
944 LRESULT
CDefView::OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
946 /* redirect to parent */
947 if (m_FolderSettings
.fFlags
& (FWF_DESKTOP
| FWF_TRANSPARENT
))
948 return SendMessageW(GetParent(), WM_ERASEBKGND
, wParam
, lParam
);
954 LRESULT
CDefView::OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
956 /* Update desktop labels color */
959 /* Forward WM_SYSCOLORCHANGE to common controls */
960 return m_ListView
.SendMessageW(uMsg
, 0, 0);
963 LRESULT
CDefView::OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
965 return reinterpret_cast<LRESULT
>(m_pShellBrowser
.p
);
968 LRESULT
CDefView::OnNCCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
975 LRESULT
CDefView::OnNCDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
982 /**********************************************************
983 * ShellView_OnCreate()
985 LRESULT
CDefView::OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
987 CComPtr
<IDropTarget
> pdt
;
988 SHChangeNotifyEntry ntreg
;
989 CComPtr
<IPersistFolder2
> ppf2
;
1001 if (SUCCEEDED(QueryInterface(IID_PPV_ARG(IDropTarget
, &pdt
))))
1003 if (FAILED(RegisterDragDrop(m_hWnd
, pdt
)))
1004 ERR("Registering Drag Drop Failed");
1007 /* register for receiving notifications */
1008 m_pSFParent
->QueryInterface(IID_PPV_ARG(IPersistFolder2
, &ppf2
));
1011 ppf2
->GetCurFolder(&m_pidlParent
);
1012 ntreg
.fRecursive
= TRUE
;
1013 ntreg
.pidl
= m_pidlParent
;
1014 m_hNotify
= SHChangeNotifyRegister(m_hWnd
, SHCNRF_InterruptLevel
| SHCNRF_ShellLevel
, SHCNE_ALLEVENTS
, SHV_CHANGE_NOTIFY
, 1, &ntreg
);
1017 m_hAccel
= LoadAcceleratorsW(shell32_hInstance
, MAKEINTRESOURCEW(IDA_SHELLVIEW
));
1024 /**********************************************************
1025 * #### Handling of the menus ####
1028 HMENU
CDefView::BuildFileMenu()
1031 CComPtr
<IContextMenu
> cm
;
1035 hr
= m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, IID_NULL_PPV_ARG(IContextMenu
, &cm
));
1039 HMENU hmenu
= CreatePopupMenu();
1041 // FIXME: get proper numbers ?
1042 const UINT first
= 0x7800;
1043 const UINT last
= 0x7A00;
1044 hr
= cm
->QueryContextMenu(hmenu
, 0, first
, last
, 0);
1048 // TODO: filter or something
1053 void CDefView::PrepareShowFileMenu(HMENU hSubMenu
)
1055 TRACE("(%p)->(submenu=%p) stub\n", this, hSubMenu
);
1060 /* Cleanup the items added previously */
1061 for (int i
= 0; i
< GetMenuItemCount(hSubMenu
); )
1064 mii
.cbSize
= sizeof(mii
);
1065 mii
.fMask
= MIIM_ID
;
1066 GetMenuItemInfoW(hSubMenu
, i
, TRUE
, &mii
);
1068 if (mii
.wID
< 0x8000)
1070 DeleteMenu(hSubMenu
, i
, MF_BYPOSITION
);
1079 /* FIXME/TODO: Reenable when they implemented AND localizable (not hardcoded). */
1080 /* Insert This item at the beginning of the menu. */
1081 _InsertMenuItemW(hSubMenu
, 0, TRUE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1082 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
+ 4, MFT_STRING
, L
"Properties", MFS_DISABLED
);
1083 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
+ 3, MFT_STRING
, L
"Rename", MFS_DISABLED
);
1084 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
+ 2, MFT_STRING
, L
"Delete", MFS_DISABLED
);
1085 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
+ 1, MFT_STRING
, L
"Create Shortcut", MFS_DISABLED
);
1086 _InsertMenuItemW(hSubMenu
, 0, TRUE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1087 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
, MFT_STRING
, L
"New", MFS_ENABLED
);
1090 HMENU menubase
= BuildFileMenu();
1093 int count
= ::GetMenuItemCount(menubase
);
1094 int count2
= ::GetMenuItemCount(hSubMenu
);
1096 if (count2
> 0 && count
> 0)
1098 _InsertMenuItemW(hSubMenu
, 0, TRUE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1101 for (int i
= count
-1; i
>= 0; i
--)
1105 MENUITEMINFOW mii
= { 0 };
1106 mii
.cbSize
= sizeof(mii
);
1107 mii
.fMask
= MIIM_STATE
| MIIM_ID
| MIIM_SUBMENU
| MIIM_CHECKMARKS
| MIIM_DATA
| MIIM_STRING
| MIIM_BITMAP
| MIIM_FTYPE
;
1108 mii
.dwTypeData
= label
;
1109 mii
.cch
= _countof(label
);
1110 ::GetMenuItemInfoW(menubase
, i
, TRUE
, &mii
);
1112 TRACE("Adding item %d label %S type %d\n", mii
.wID
, mii
.dwTypeData
, mii
.fType
);
1114 mii
.fType
|= MFT_RADIOCHECK
;
1116 ::InsertMenuItemW(hSubMenu
, 0, TRUE
, &mii
);
1120 ::DestroyMenu(menubase
);
1125 void CDefView::PrepareShowViewMenu(HMENU hSubMenu
)
1127 TRACE("(%p)->(submenu=%p)\n", this, hSubMenu
);
1132 if (m_FolderSettings
.ViewMode
>= FVM_FIRST
&& m_FolderSettings
.ViewMode
<= FVM_LAST
)
1134 UINT iItemFirst
= FCIDM_SHVIEW_BIGICON
;
1135 UINT iItemLast
= iItemFirst
+ FVM_LAST
- FVM_FIRST
;
1136 UINT iItem
= iItemFirst
+ m_FolderSettings
.ViewMode
- FVM_FIRST
;
1137 CheckMenuRadioItem(hSubMenu
, iItemFirst
, iItemLast
, iItem
, MF_BYCOMMAND
);
1141 /**********************************************************
1142 * ShellView_GetSelections()
1144 * - fills the m_apidl list with the selected objects
1147 * number of selected items
1149 UINT
CDefView::GetSelections()
1153 m_cidl
= m_ListView
.GetSelectedCount();
1154 m_apidl
= static_cast<PCUITEMID_CHILD
*>(SHAlloc(m_cidl
* sizeof(PCUITEMID_CHILD
)));
1161 TRACE("-- Items selected =%u\n", m_cidl
);
1165 while ((lvIndex
= m_ListView
.GetNextItem(lvIndex
, LVNI_SELECTED
)) > -1)
1167 m_apidl
[i
] = _PidlByItem(lvIndex
);
1171 TRACE("-- selected Item found\n");
1177 HRESULT
CDefView::InvokeContextMenuCommand(UINT uCommand
)
1179 CMINVOKECOMMANDINFO cmi
;
1181 ZeroMemory(&cmi
, sizeof(cmi
));
1182 cmi
.cbSize
= sizeof(cmi
);
1183 cmi
.lpVerb
= MAKEINTRESOURCEA(uCommand
);
1186 if (GetKeyState(VK_SHIFT
) & 0x8000)
1187 cmi
.fMask
|= CMIC_MASK_SHIFT_DOWN
;
1189 if (GetKeyState(VK_CONTROL
) & 0x8000)
1190 cmi
.fMask
|= CMIC_MASK_CONTROL_DOWN
;
1192 return m_pCM
->InvokeCommand(&cmi
);
1195 /**********************************************************
1196 * ShellView_OpenSelectedItems()
1198 HRESULT
CDefView::OpenSelectedItems()
1204 m_cidl
= m_ListView
.GetSelectedCount();
1208 hResult
= OnDefaultCommand();
1209 if (hResult
== S_OK
)
1212 hMenu
= CreatePopupMenu();
1216 hResult
= GetItemObject(SVGIO_SELECTION
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1217 if (FAILED(hResult
))
1220 IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1222 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, 0x20, 0x7fff, CMF_DEFAULTONLY
);
1223 if (FAILED(hResult
))
1226 uCommand
= GetMenuDefaultItem(hMenu
, FALSE
, 0);
1227 if (uCommand
== (UINT
)-1)
1233 InvokeContextMenuCommand(uCommand
);
1242 IUnknown_SetSite(m_pCM
, NULL
);
1249 /**********************************************************
1250 * ShellView_DoContextMenu()
1252 LRESULT
CDefView::OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1259 // for some reason I haven't figured out, we sometimes recurse into this method
1266 TRACE("(%p)->(0x%08x 0x%08x) stub\n", this, x
, y
);
1268 hMenu
= CreatePopupMenu();
1272 m_cidl
= m_ListView
.GetSelectedCount();
1274 hResult
= GetItemObject( m_cidl
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1275 if (FAILED( hResult
))
1278 IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1280 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1281 if (FAILED( hResult
))
1284 uCommand
= TrackPopupMenu(hMenu
,
1285 TPM_LEFTALIGN
| TPM_RETURNCMD
| TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
,
1286 x
, y
, 0, m_hWnd
, NULL
);
1290 if (uCommand
== FCIDM_SHVIEW_OPEN
&& OnDefaultCommand() == S_OK
)
1293 InvokeContextMenuCommand(uCommand
);
1298 IUnknown_SetSite(m_pCM
, NULL
);
1308 LRESULT
CDefView::OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
)
1313 hMenu
= CreatePopupMenu();
1317 hResult
= GetItemObject( bUseSelection
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1318 if (FAILED( hResult
))
1321 IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1323 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1324 if (FAILED( hResult
))
1327 InvokeContextMenuCommand(uCommand
);
1332 IUnknown_SetSite(m_pCM
, NULL
);
1342 /**********************************************************
1343 * ##### message handling #####
1346 /**********************************************************
1347 * ShellView_OnSize()
1349 LRESULT
CDefView::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1351 WORD wWidth
, wHeight
;
1353 wWidth
= LOWORD(lParam
);
1354 wHeight
= HIWORD(lParam
);
1356 TRACE("%p width=%u height=%u\n", this, wWidth
, wHeight
);
1358 /* Resize the ListView to fit our window */
1361 ::MoveWindow(m_ListView
, 0, 0, wWidth
, wHeight
, TRUE
);
1367 /**********************************************************
1368 * ShellView_OnDeactivate()
1373 void CDefView::OnDeactivate()
1375 TRACE("%p\n", this);
1377 if (m_uState
!= SVUIA_DEACTIVATE
)
1379 // TODO: cleanup menu after deactivation
1381 m_uState
= SVUIA_DEACTIVATE
;
1385 void CDefView::DoActivate(UINT uState
)
1387 TRACE("%p uState=%x\n", this, uState
);
1389 /*don't do anything if the state isn't really changing */
1390 if (m_uState
== uState
)
1395 if (uState
== SVUIA_DEACTIVATE
)
1405 MENUITEMINFOW mii
= { 0 };
1407 /* initialize EDIT menu */
1408 mii
.cbSize
= sizeof(mii
);
1409 mii
.fMask
= MIIM_SUBMENU
;
1410 if (::GetMenuItemInfoW(m_hMenu
, FCIDM_MENU_EDIT
, FALSE
, &mii
))
1412 HMENU hSubMenu
= mii
.hSubMenu
;
1414 HMENU menubase
= ::LoadMenuW(shell32_hInstance
, L
"MENU_003");
1416 int count
= ::GetMenuItemCount(menubase
);
1417 for (int i
= 0; i
< count
; i
++)
1421 ZeroMemory(&mii
, sizeof(mii
));
1422 mii
.cbSize
= sizeof(mii
);
1423 mii
.fMask
= MIIM_STATE
| MIIM_ID
| MIIM_SUBMENU
| MIIM_CHECKMARKS
| MIIM_DATA
| MIIM_STRING
| MIIM_BITMAP
| MIIM_FTYPE
;
1424 mii
.dwTypeData
= label
;
1425 mii
.cch
= _countof(label
);
1426 ::GetMenuItemInfoW(menubase
, i
, TRUE
, &mii
);
1428 TRACE("Adding item %d label %S type %d\n", mii
.wID
, mii
.dwTypeData
, mii
.fType
);
1430 mii
.fType
|= MFT_RADIOCHECK
;
1432 ::InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, &mii
);
1435 ::DestroyMenu(menubase
);
1438 /* initialize VIEW menu */
1440 mii
.cbSize
= sizeof(mii
);
1441 mii
.fMask
= MIIM_SUBMENU
;
1442 if (::GetMenuItemInfoW(m_hMenu
, FCIDM_MENU_VIEW
, FALSE
, &mii
))
1444 HMENU menubase
= ::LoadMenuW(shell32_hInstance
, L
"MENU_001");
1446 HMENU hSubMenu
= mii
.hSubMenu
;
1448 m_hView
= CreatePopupMenu();
1450 _InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1452 int count
= ::GetMenuItemCount(menubase
);
1453 for (int i
= 0; i
< count
; i
++)
1457 ZeroMemory(&mii
, sizeof(mii
));
1458 mii
.cbSize
= sizeof(mii
);
1459 mii
.fMask
= MIIM_STATE
| MIIM_ID
| MIIM_SUBMENU
| MIIM_CHECKMARKS
| MIIM_DATA
| MIIM_STRING
| MIIM_BITMAP
| MIIM_FTYPE
;
1460 mii
.dwTypeData
= label
;
1461 mii
.cch
= _countof(label
);
1462 ::GetMenuItemInfoW(menubase
, i
, TRUE
, &mii
);
1464 ::AppendMenuW(m_hView
, mii
.fType
, mii
.wID
, mii
.dwTypeData
);
1466 TRACE("Adding item %d label %S type %d\n", mii
.wID
, mii
.dwTypeData
, mii
.fType
);
1468 mii
.fType
|= MFT_RADIOCHECK
;
1470 ::InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, &mii
);
1473 ::DestroyMenu(menubase
);
1477 TRACE("-- before fnSetMenuSB\n");
1478 m_pShellBrowser
->SetMenuSB(m_hMenu
, 0, m_hWnd
);
1480 m_menusLoaded
= TRUE
;
1484 if (SVUIA_ACTIVATE_FOCUS
== uState
)
1486 m_ListView
.SetFocus();
1494 /**********************************************************
1495 * ShellView_OnActivate()
1497 LRESULT
CDefView::OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1499 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1503 /**********************************************************
1504 * ShellView_OnSetFocus()
1507 LRESULT
CDefView::OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1509 TRACE("%p\n", this);
1511 /* Tell the browser one of our windows has received the focus. This
1512 should always be done before merging menus (OnActivate merges the
1513 menus) if one of our windows has the focus.*/
1515 m_pShellBrowser
->OnViewWindowActive(this);
1516 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1518 /* Set the focus to the listview */
1519 m_ListView
.SetFocus();
1521 /* Notify the ICommDlgBrowser interface */
1522 OnStateChange(CDBOSC_SETFOCUS
);
1527 /**********************************************************
1528 * ShellView_OnKillFocus()
1530 LRESULT
CDefView::OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1532 TRACE("(%p) stub\n", this);
1534 DoActivate(SVUIA_ACTIVATE_NOFOCUS
);
1535 /* Notify the ICommDlgBrowser */
1536 OnStateChange(CDBOSC_KILLFOCUS
);
1541 /**********************************************************
1542 * ShellView_OnCommand()
1545 * the CmdID's are the ones from the context menu
1547 LRESULT
CDefView::OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1554 dwCmdID
= GET_WM_COMMAND_ID(wParam
, lParam
);
1555 dwCmd
= GET_WM_COMMAND_CMD(wParam
, lParam
);
1556 hwndCmd
= GET_WM_COMMAND_HWND(wParam
, lParam
);
1558 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n", this, dwCmdID
, dwCmd
, hwndCmd
);
1562 case FCIDM_SHVIEW_SMALLICON
:
1563 m_FolderSettings
.ViewMode
= FVM_SMALLICON
;
1564 SetStyle (LVS_SMALLICON
, LVS_TYPEMASK
);
1568 case FCIDM_SHVIEW_BIGICON
:
1569 m_FolderSettings
.ViewMode
= FVM_ICON
;
1570 SetStyle (LVS_ICON
, LVS_TYPEMASK
);
1574 case FCIDM_SHVIEW_LISTVIEW
:
1575 m_FolderSettings
.ViewMode
= FVM_LIST
;
1576 SetStyle (LVS_LIST
, LVS_TYPEMASK
);
1580 case FCIDM_SHVIEW_REPORTVIEW
:
1581 m_FolderSettings
.ViewMode
= FVM_DETAILS
;
1582 SetStyle (LVS_REPORT
, LVS_TYPEMASK
);
1586 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1591 m_sortInfo
.nHeaderID
= dwCmdID
- 0x30;
1592 m_sortInfo
.bIsAscending
= TRUE
;
1593 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
1594 m_ListView
.SortItems(ListViewCompareItems
, this);
1597 case FCIDM_SHVIEW_SELECTALL
:
1598 m_ListView
.SetItemState(-1, LVIS_SELECTED
, LVIS_SELECTED
);
1601 case FCIDM_SHVIEW_INVERTSELECTION
:
1602 nCount
= m_ListView
.GetItemCount();
1603 for (int i
=0; i
< nCount
; i
++)
1604 m_ListView
.SetItemState(i
, m_ListView
.GetItemState(i
, LVIS_SELECTED
) ? 0 : LVIS_SELECTED
, LVIS_SELECTED
);
1607 case FCIDM_SHVIEW_REFRESH
:
1611 case FCIDM_SHVIEW_DELETE
:
1612 case FCIDM_SHVIEW_CUT
:
1613 case FCIDM_SHVIEW_COPY
:
1614 case FCIDM_SHVIEW_RENAME
:
1615 return OnExplorerCommand(dwCmdID
, TRUE
);
1617 case FCIDM_SHVIEW_INSERT
:
1618 case FCIDM_SHVIEW_UNDO
:
1619 case FCIDM_SHVIEW_INSERTLINK
:
1620 case FCIDM_SHVIEW_NEWFOLDER
:
1621 return OnExplorerCommand(dwCmdID
, FALSE
);
1623 TRACE("-- COMMAND 0x%04x unhandled\n", dwCmdID
);
1629 /**********************************************************
1630 * ShellView_OnNotify()
1633 LRESULT
CDefView::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1637 LPNMLISTVIEW lpnmlv
;
1638 NMLVDISPINFOW
*lpdi
;
1639 PCUITEMID_CHILD pidl
;
1643 lpnmh
= (LPNMHDR
)lParam
;
1644 lpnmlv
= (LPNMLISTVIEW
)lpnmh
;
1645 lpdi
= (NMLVDISPINFOW
*)lpnmh
;
1647 TRACE("%p CtlID=%u lpnmh->code=%x\n", this, CtlID
, lpnmh
->code
);
1649 switch (lpnmh
->code
)
1652 TRACE("-- NM_SETFOCUS %p\n", this);
1653 OnSetFocus(0, 0, 0, unused
);
1657 TRACE("-- NM_KILLFOCUS %p\n", this);
1659 /* Notify the ICommDlgBrowser interface */
1660 OnStateChange(CDBOSC_KILLFOCUS
);
1664 TRACE("-- NM_CUSTOMDRAW %p\n", this);
1665 return CDRF_DODEFAULT
;
1667 case NM_RELEASEDCAPTURE
:
1668 TRACE("-- NM_RELEASEDCAPTURE %p\n", this);
1672 TRACE("-- NM_CLICK %p\n", this);
1676 TRACE("-- NM_RCLICK %p\n", this);
1680 TRACE("-- NM_DBLCLK %p\n", this);
1681 OpenSelectedItems();
1685 TRACE("-- NM_RETURN %p\n", this);
1686 OpenSelectedItems();
1690 TRACE("-- HDN_ENDTRACKW %p\n", this);
1691 /*nColumn1 = m_ListView.GetColumnWidth(0);
1692 nColumn2 = m_ListView.GetColumnWidth(1);*/
1695 case LVN_DELETEITEM
:
1696 TRACE("-- LVN_DELETEITEM %p\n", this);
1698 /*delete the pidl because we made a copy of it*/
1699 SHFree(reinterpret_cast<LPVOID
>(lpnmlv
->lParam
));
1703 case LVN_DELETEALLITEMS
:
1704 TRACE("-- LVN_DELETEALLITEMS %p\n", this);
1707 case LVN_INSERTITEM
:
1708 TRACE("-- LVN_INSERTITEM (STUB)%p\n", this);
1711 case LVN_ITEMACTIVATE
:
1712 TRACE("-- LVN_ITEMACTIVATE %p\n", this);
1713 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1716 case LVN_COLUMNCLICK
:
1717 m_sortInfo
.nHeaderID
= lpnmlv
->iSubItem
;
1718 if (m_sortInfo
.nLastHeaderID
== m_sortInfo
.nHeaderID
)
1719 m_sortInfo
.bIsAscending
= !m_sortInfo
.bIsAscending
;
1721 m_sortInfo
.bIsAscending
= TRUE
;
1722 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
1724 m_ListView
.SortItems(ListViewCompareItems
, this);
1727 case LVN_GETDISPINFOA
:
1728 case LVN_GETDISPINFOW
:
1729 TRACE("-- LVN_GETDISPINFO %p\n", this);
1730 pidl
= _PidlByItem(lpdi
->item
);
1732 if (lpdi
->item
.mask
& LVIF_TEXT
) /* text requested */
1737 if (FAILED(m_pSF2Parent
->GetDetailsOf(pidl
, lpdi
->item
.iSubItem
, &sd
)))
1739 FIXME("failed to get details\n");
1743 if (lpnmh
->code
== LVN_GETDISPINFOA
)
1745 /* shouldn't happen */
1746 NMLVDISPINFOA
*lpdiA
= (NMLVDISPINFOA
*)lpnmh
;
1747 StrRetToStrNA( lpdiA
->item
.pszText
, lpdiA
->item
.cchTextMax
, &sd
.str
, NULL
);
1748 TRACE("-- text=%s\n", lpdiA
->item
.pszText
);
1750 else /* LVN_GETDISPINFOW */
1752 StrRetToStrNW( lpdi
->item
.pszText
, lpdi
->item
.cchTextMax
, &sd
.str
, NULL
);
1753 TRACE("-- text=%s\n", debugstr_w(lpdi
->item
.pszText
));
1758 FIXME("no m_pSF2Parent\n");
1761 if(lpdi
->item
.mask
& LVIF_IMAGE
) /* image requested */
1763 lpdi
->item
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
1765 if(lpdi
->item
.mask
& LVIF_STATE
)
1767 ULONG attributes
= SFGAO_HIDDEN
;
1768 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(1, &pidl
, &attributes
)))
1770 if (attributes
& SFGAO_HIDDEN
)
1772 lpdi
->item
.state
|= LVIS_CUT
;
1776 lpdi
->item
.mask
|= LVIF_DI_SETITEM
;
1779 case LVN_ITEMCHANGED
:
1780 TRACE("-- LVN_ITEMCHANGED %p\n", this);
1781 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1786 case LVN_BEGINRDRAG
:
1787 TRACE("-- LVN_BEGINDRAG\n");
1789 if (GetSelections())
1791 CComPtr
<IDataObject
> pda
;
1792 DWORD dwAttributes
= SFGAO_CANLINK
;
1793 DWORD dwEffect
= DROPEFFECT_COPY
| DROPEFFECT_MOVE
;
1795 if (SUCCEEDED(m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, IID_NULL_PPV_ARG(IDataObject
, &pda
))))
1797 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(m_cidl
, m_apidl
, &dwAttributes
)))
1799 if (dwAttributes
& SFGAO_CANLINK
)
1801 dwEffect
|= DROPEFFECT_LINK
;
1805 CComPtr
<IAsyncOperation
> piaso
;
1806 if (SUCCEEDED(pda
->QueryInterface(IID_PPV_ARG(IAsyncOperation
, &piaso
))))
1808 piaso
->SetAsyncMode(TRUE
);
1813 m_pSourceDataObject
= pda
;
1815 DoDragDrop(pda
, this, dwEffect
, &dwEffect2
);
1817 m_pSourceDataObject
.Release();
1822 case LVN_BEGINLABELEDITW
:
1824 DWORD dwAttr
= SFGAO_CANRENAME
;
1825 pidl
= _PidlByItem(lpdi
->item
);
1827 TRACE("-- LVN_BEGINLABELEDITW %p\n", this);
1829 m_pSFParent
->GetAttributesOf(1, &pidl
, &dwAttr
);
1830 if (SFGAO_CANRENAME
& dwAttr
)
1838 case LVN_ENDLABELEDITW
:
1840 TRACE("-- LVN_ENDLABELEDITW %p\n", this);
1842 m_isEditing
= FALSE
;
1844 if (lpdi
->item
.pszText
)
1849 pidl
= _PidlByItem(lpdi
->item
);
1850 PITEMID_CHILD pidlNew
;
1851 hr
= m_pSFParent
->SetNameOf(0, pidl
, lpdi
->item
.pszText
, SHGDN_INFOLDER
, &pidlNew
);
1853 if (SUCCEEDED(hr
) && pidlNew
)
1855 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
1856 lvItem
.iItem
= lpdi
->item
.iItem
;
1857 lvItem
.iSubItem
= 0;
1858 lvItem
.lParam
= reinterpret_cast<LPARAM
>(pidlNew
);
1859 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
1860 m_ListView
.SetItem(&lvItem
);
1861 m_ListView
.Update(lpdi
->item
.iItem
);
1870 TRACE("-- %p WM_COMMAND %x unhandled\n", this, lpnmh
->code
);
1878 * This is just a quick hack to make the desktop work correctly.
1879 * ITranslateShellChangeNotify's IsChildID is undocumented, but most likely the way that
1880 * a folder should know if it should update upon a change notification.
1881 * It is exported by merged folders at a minimum.
1883 static BOOL
ILIsParentOrSpecialParent(PCIDLIST_ABSOLUTE pidl1
, PCIDLIST_ABSOLUTE pidl2
)
1885 if (!pidl1
|| !pidl2
)
1887 if (ILIsParent(pidl1
, pidl2
, TRUE
))
1890 if (_ILIsDesktop(pidl1
))
1892 PIDLIST_ABSOLUTE deskpidl
;
1893 SHGetFolderLocation(NULL
, CSIDL_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
1894 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
1900 SHGetFolderLocation(NULL
, CSIDL_COMMON_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
1901 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
1911 /**********************************************************
1912 * ShellView_OnChange()
1914 LRESULT
CDefView::OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1916 PCIDLIST_ABSOLUTE
*Pidls
= reinterpret_cast<PCIDLIST_ABSOLUTE
*>(wParam
);
1917 BOOL bParent0
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[0]);
1918 BOOL bParent1
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[1]);
1920 TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls
[0], Pidls
[1], lParam
);
1922 switch (lParam
&~ SHCNE_INTERRUPT
)
1928 if (LV_FindItemByPidl(ILFindLastID(Pidls
[0])) == -1)
1930 LV_AddItem(ILFindLastID(Pidls
[0]));
1934 LV_ProdItem(ILFindLastID(Pidls
[0]));
1942 LV_DeleteItem(ILFindLastID(Pidls
[0]));
1945 case SHCNE_RENAMEFOLDER
:
1946 case SHCNE_RENAMEITEM
:
1947 if (bParent0
&& bParent1
)
1948 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[1]));
1950 LV_DeleteItem(ILFindLastID(Pidls
[0]));
1952 LV_AddItem(ILFindLastID(Pidls
[1]));
1955 case SHCNE_UPDATEITEM
:
1957 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[0]));
1960 case SHCNE_UPDATEDIR
:
1967 /**********************************************************
1968 * CDefView::OnCustomItem
1970 LRESULT
CDefView::OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1975 ERR("no menu!!!\n");
1980 HRESULT hres
= SHForwardContextMenuMsg(m_pCM
, uMsg
, wParam
, lParam
, &result
, TRUE
);
1981 if (SUCCEEDED(hres
))
1987 LRESULT
CDefView::OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1989 /* Wallpaper setting affects drop shadows effect */
1990 if (wParam
== SPI_SETDESKWALLPAPER
|| wParam
== 0)
1996 /**********************************************************
1997 * CDefView::OnInitMenuPopup
1999 LRESULT
CDefView::OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
2001 MENUITEMINFOW mii
= { 0 };
2002 HMENU hSubmenu
= (HMENU
) wParam
;
2004 TRACE("OnInitMenuPopup lParam=%d\n", lParam
);
2006 mii
.cbSize
= sizeof(mii
);
2007 mii
.fMask
= MIIM_ID
| MIIM_SUBMENU
;
2009 if (!GetMenuItemInfoW(this->m_hMenu
, lParam
, TRUE
, &mii
))
2011 TRACE("OnInitMenuPopup GetMenuItemInfoW failed!\n");
2015 UINT menuItemId
= mii
.wID
;
2017 if (mii
.hSubMenu
!= hSubmenu
)
2019 TRACE("OnInitMenuPopup submenu does not match!!!!\n");
2023 TRACE("OnInitMenuPopup id=%d\n", menuItemId
);
2027 case FCIDM_MENU_FILE
:
2028 PrepareShowFileMenu(hSubmenu
);
2030 case FCIDM_MENU_EDIT
:
2031 //PrepareShowEditMenu(hSubmenu);
2033 case FCIDM_MENU_VIEW
:
2034 PrepareShowViewMenu(hSubmenu
);
2041 /**********************************************************
2044 * The INTERFACE of the IShellView object
2047 **********************************************************
2050 /**********************************************************
2051 * ShellView_GetWindow
2053 HRESULT WINAPI
CDefView::GetWindow(HWND
*phWnd
)
2055 TRACE("(%p)\n", this);
2062 HRESULT WINAPI
CDefView::ContextSensitiveHelp(BOOL fEnterMode
)
2064 FIXME("(%p) stub\n", this);
2069 /**********************************************************
2070 * IShellView_TranslateAccelerator
2073 * use the accel functions
2075 HRESULT WINAPI
CDefView::TranslateAccelerator(LPMSG lpmsg
)
2080 if (lpmsg
->message
>= WM_KEYFIRST
&& lpmsg
->message
<= WM_KEYLAST
)
2082 if (::TranslateAcceleratorW(m_hWnd
, m_hAccel
, lpmsg
) != 0)
2085 TRACE("-- key=0x04%lx\n", lpmsg
->wParam
) ;
2088 return m_pShellBrowser
->TranslateAcceleratorSB(lpmsg
, 0);
2091 HRESULT WINAPI
CDefView::EnableModeless(BOOL fEnable
)
2093 FIXME("(%p) stub\n", this);
2098 HRESULT WINAPI
CDefView::UIActivate(UINT uState
)
2100 // CHAR szName[MAX_PATH];
2102 int nPartArray
[1] = { -1};
2104 TRACE("(%p)->(state=%x) stub\n", this, uState
);
2106 /* don't do anything if the state isn't really changing */
2107 if (m_uState
== uState
)
2112 /* OnActivate handles the menu merging and internal state */
2115 /* only do This if we are active */
2116 if (uState
!= SVUIA_DEACTIVATE
)
2120 GetFolderPath is not a method of IShellFolder
2121 IShellFolder_GetFolderPath( m_pSFParent, szName, sizeof(szName) );
2123 /* set the number of parts */
2124 m_pShellBrowser
->SendControlMsg(FCW_STATUS
, SB_SETPARTS
, 1, (LPARAM
)nPartArray
, &lResult
);
2126 /* set the text for the parts */
2128 m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXTA, 0, (LPARAM)szName, &lResult);
2135 HRESULT WINAPI
CDefView::Refresh()
2137 TRACE("(%p)\n", this);
2139 m_ListView
.DeleteAllItems();
2145 HRESULT WINAPI
CDefView::CreateViewWindow(IShellView
*lpPrevView
, LPCFOLDERSETTINGS lpfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
)
2147 OLEMENUGROUPWIDTHS omw
= { { 0, 0, 0, 0, 0, 0 } };
2151 TRACE("(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n", this, lpPrevView
, lpfs
, psb
, prcView
, phWnd
);
2154 TRACE("-- vmode=%x flags=%x\n", lpfs
->ViewMode
, lpfs
->fFlags
);
2155 if (prcView
!= NULL
)
2156 TRACE("-- left=%i top=%i right=%i bottom=%i\n", prcView
->left
, prcView
->top
, prcView
->right
, prcView
->bottom
);
2158 /* Validate the Shell Browser */
2159 if (psb
== NULL
|| m_hWnd
)
2160 return E_UNEXPECTED
;
2162 /* Set up the member variables */
2163 m_pShellBrowser
= psb
;
2164 m_FolderSettings
= *lpfs
;
2166 /* Get our parent window */
2167 m_pShellBrowser
->GetWindow(&m_hWndParent
);
2169 /* Try to get the ICommDlgBrowserInterface, adds a reference !!! */
2170 m_pCommDlgBrowser
= NULL
;
2171 if (SUCCEEDED(m_pShellBrowser
->QueryInterface(IID_PPV_ARG(ICommDlgBrowser
, &m_pCommDlgBrowser
))))
2173 TRACE("-- CommDlgBrowser\n");
2176 Create(m_hWndParent
, prcView
, NULL
, WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
| WS_TABSTOP
, 0, 0U);
2187 SetWindowPos(HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_SHOWWINDOW
);
2192 m_hMenu
= CreateMenu();
2193 m_pShellBrowser
->InsertMenusSB(m_hMenu
, &omw
);
2194 TRACE("-- after fnInsertMenusSB\n");
2202 HRESULT WINAPI
CDefView::DestroyViewWindow()
2204 TRACE("(%p)\n", this);
2206 /* Make absolutely sure all our UI is cleaned up */
2207 UIActivate(SVUIA_DEACTIVATE
);
2211 // "Accelerator tables loaded from resources are freed automatically when the application terminates." -- MSDN
2217 DestroyMenu(m_hView
);
2223 DestroyMenu(m_hMenu
);
2229 m_ListView
.DestroyWindow();
2237 m_pShellBrowser
.Release();
2238 m_pCommDlgBrowser
.Release();
2243 HRESULT WINAPI
CDefView::GetCurrentInfo(LPFOLDERSETTINGS lpfs
)
2245 TRACE("(%p)->(%p) vmode=%x flags=%x\n", this, lpfs
,
2246 m_FolderSettings
.ViewMode
, m_FolderSettings
.fFlags
);
2249 return E_INVALIDARG
;
2251 *lpfs
= m_FolderSettings
;
2255 HRESULT WINAPI
CDefView::AddPropertySheetPages(DWORD dwReserved
, LPFNADDPROPSHEETPAGE lpfn
, LPARAM lparam
)
2257 FIXME("(%p) stub\n", this);
2262 HRESULT WINAPI
CDefView::SaveViewState()
2264 FIXME("(%p) stub\n", this);
2269 HRESULT WINAPI
CDefView::SelectItem(PCUITEMID_CHILD pidl
, UINT uFlags
)
2273 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n", this, pidl
, uFlags
);
2275 i
= LV_FindItemByPidl(pidl
);
2279 if(uFlags
& SVSI_ENSUREVISIBLE
)
2280 m_ListView
.EnsureVisible(i
, FALSE
);
2282 LVITEMW lvItem
= {0};
2283 lvItem
.mask
= LVIF_STATE
;
2284 lvItem
.stateMask
= LVIS_SELECTED
| LVIS_FOCUSED
;
2286 while (m_ListView
.GetItem(&lvItem
))
2288 if (lvItem
.iItem
== i
)
2290 if (uFlags
& SVSI_SELECT
)
2291 lvItem
.state
|= LVIS_SELECTED
;
2293 lvItem
.state
&= ~LVIS_SELECTED
;
2295 if (uFlags
& SVSI_FOCUSED
)
2296 lvItem
.state
&= ~LVIS_FOCUSED
;
2300 if (uFlags
& SVSI_DESELECTOTHERS
)
2301 lvItem
.state
&= ~LVIS_SELECTED
;
2304 m_ListView
.SetItem(&lvItem
);
2308 if(uFlags
& SVSI_EDIT
)
2309 m_ListView
.EditLabel(i
);
2314 HRESULT WINAPI
CDefView::GetItemObject(UINT uItem
, REFIID riid
, LPVOID
*ppvOut
)
2316 HRESULT hr
= E_NOINTERFACE
;
2318 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n", this, uItem
, debugstr_guid(&riid
), ppvOut
);
2324 case SVGIO_BACKGROUND
:
2325 if (IsEqualIID(riid
, IID_IContextMenu
))
2327 //*ppvOut = ISvBgCm_Constructor(m_pSFParent, FALSE);
2332 hr
= CDefFolderMenu_Create2(NULL
, NULL
, 0, NULL
, m_pSFParent
, NULL
, 0, NULL
, &pcm
);
2337 else if (IsEqualIID(riid
, IID_IDispatch
))
2339 if (m_pShellFolderViewDual
== NULL
)
2341 hr
= CDefViewDual_Constructor(riid
, (LPVOID
*)&m_pShellFolderViewDual
);
2342 if (FAILED_UNEXPECTEDLY(hr
))
2347 hr
= m_pShellFolderViewDual
->QueryInterface(riid
, ppvOut
);
2351 case SVGIO_SELECTION
:
2353 hr
= m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, riid
, 0, ppvOut
);
2357 TRACE("-- (%p)->(interface=%p)\n", this, *ppvOut
);
2362 HRESULT STDMETHODCALLTYPE
CDefView::GetCurrentViewMode(UINT
*pViewMode
)
2364 TRACE("(%p)->(%p), stub\n", this, pViewMode
);
2367 return E_INVALIDARG
;
2369 *pViewMode
= m_FolderSettings
.ViewMode
;
2373 HRESULT STDMETHODCALLTYPE
CDefView::SetCurrentViewMode(UINT ViewMode
)
2376 TRACE("(%p)->(%u), stub\n", this, ViewMode
);
2378 /* It's not redundant to check FVM_AUTO because it's a (UINT)-1 */
2379 if (((INT
)ViewMode
< FVM_FIRST
|| (INT
)ViewMode
> FVM_LAST
) && ((INT
)ViewMode
!= FVM_AUTO
))
2380 return E_INVALIDARG
;
2382 /* Windows before Vista uses LVM_SETVIEW and possibly
2383 LVM_SETEXTENDEDLISTVIEWSTYLE to set the style of the listview,
2384 while later versions seem to accomplish this through other
2392 dwStyle
= LVS_REPORT
;
2395 dwStyle
= LVS_SMALLICON
;
2402 FIXME("ViewMode %d not implemented\n", ViewMode
);
2408 SetStyle(dwStyle
, LVS_TYPEMASK
);
2410 /* This will not necessarily be the actual mode set above.
2411 This mimics the behavior of Windows XP. */
2412 m_FolderSettings
.ViewMode
= ViewMode
;
2417 HRESULT STDMETHODCALLTYPE
CDefView::GetFolder(REFIID riid
, void **ppv
)
2419 if (m_pSFParent
== NULL
)
2422 return m_pSFParent
->QueryInterface(riid
, ppv
);
2425 HRESULT STDMETHODCALLTYPE
CDefView::Item(int iItemIndex
, PITEMID_CHILD
*ppidl
)
2427 PCUITEMID_CHILD pidl
= _PidlByItem(iItemIndex
);
2430 *ppidl
= ILClone(pidl
);
2435 return E_INVALIDARG
;
2438 HRESULT STDMETHODCALLTYPE
CDefView::ItemCount(UINT uFlags
, int *pcItems
)
2440 TRACE("(%p)->(%u %p)\n", this, uFlags
, pcItems
);
2442 if (uFlags
!= SVGIO_ALLVIEW
)
2443 FIXME("some flags unsupported, %x\n", uFlags
& ~SVGIO_ALLVIEW
);
2445 *pcItems
= m_ListView
.GetItemCount();
2450 HRESULT STDMETHODCALLTYPE
CDefView::Items(UINT uFlags
, REFIID riid
, void **ppv
)
2455 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectionMarkedItem(int *piItem
)
2457 TRACE("(%p)->(%p)\n", this, piItem
);
2459 *piItem
= m_ListView
.GetSelectionMark();
2464 HRESULT STDMETHODCALLTYPE
CDefView::GetFocusedItem(int *piItem
)
2466 TRACE("(%p)->(%p)\n", this, piItem
);
2468 *piItem
= m_ListView
.GetNextItem(-1, LVNI_FOCUSED
);
2473 HRESULT STDMETHODCALLTYPE
CDefView::GetItemPosition(PCUITEMID_CHILD pidl
, POINT
*ppt
)
2478 HRESULT STDMETHODCALLTYPE
CDefView::GetSpacing(POINT
*ppt
)
2480 TRACE("(%p)->(%p)\n", this, ppt
);
2488 m_ListView
.GetItemSpacing(spacing
);
2490 ppt
->x
= spacing
.cx
;
2491 ppt
->y
= spacing
.cy
;
2497 HRESULT STDMETHODCALLTYPE
CDefView::GetDefaultSpacing(POINT
*ppt
)
2502 HRESULT STDMETHODCALLTYPE
CDefView::GetAutoArrange()
2507 HRESULT STDMETHODCALLTYPE
CDefView::SelectItem(int iItem
, DWORD dwFlags
)
2511 TRACE("(%p)->(%d, %x)\n", this, iItem
, dwFlags
);
2514 lvItem
.stateMask
= LVIS_SELECTED
;
2516 if (dwFlags
& SVSI_ENSUREVISIBLE
)
2517 m_ListView
.EnsureVisible(iItem
, 0);
2520 if (dwFlags
& SVSI_DESELECTOTHERS
)
2521 m_ListView
.SetItemState(-1, 0, LVIS_SELECTED
);
2524 if (dwFlags
& SVSI_SELECT
)
2525 lvItem
.state
|= LVIS_SELECTED
;
2527 if (dwFlags
& SVSI_FOCUSED
)
2528 lvItem
.stateMask
|= LVIS_FOCUSED
;
2530 m_ListView
.SetItemState(iItem
, lvItem
.state
, lvItem
.stateMask
);
2532 if (dwFlags
& SVSI_EDIT
)
2533 m_ListView
.EditLabel(iItem
);
2538 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItems(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD dwFlags
)
2543 /**********************************************************
2544 * IShellView2 implementation
2547 HRESULT STDMETHODCALLTYPE
CDefView::GetView(SHELLVIEWID
*view_guid
, ULONG view_type
)
2549 FIXME("(%p)->(%p, %lu) stub\n", this, view_guid
, view_type
);
2553 HRESULT STDMETHODCALLTYPE
CDefView::CreateViewWindow2(LPSV2CVW2_PARAMS view_params
)
2555 FIXME("(%p)->(%p) stub\n", this, view_params
);
2559 HRESULT STDMETHODCALLTYPE
CDefView::HandleRename(LPCITEMIDLIST new_pidl
)
2561 FIXME("(%p)->(%p) stub\n", this, new_pidl
);
2565 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItem(LPCITEMIDLIST item
, UINT flags
, POINT
*point
)
2567 FIXME("(%p)->(%p, %u, %p) stub\n", this, item
, flags
, point
);
2571 /**********************************************************
2572 * IShellFolderView implementation
2574 HRESULT STDMETHODCALLTYPE
CDefView::Rearrange(LPARAM sort
)
2576 FIXME("(%p)->(%ld) stub\n", this, sort
);
2580 HRESULT STDMETHODCALLTYPE
CDefView::GetArrangeParam(LPARAM
*sort
)
2582 FIXME("(%p)->(%p) stub\n", this, sort
);
2586 HRESULT STDMETHODCALLTYPE
CDefView::ArrangeGrid()
2588 FIXME("(%p) stub\n", this);
2592 HRESULT STDMETHODCALLTYPE
CDefView::AutoArrange()
2594 FIXME("(%p) stub\n", this);
2598 HRESULT STDMETHODCALLTYPE
CDefView::AddObject(PITEMID_CHILD pidl
, UINT
*item
)
2600 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2604 HRESULT STDMETHODCALLTYPE
CDefView::GetObject(PITEMID_CHILD
*pidl
, UINT item
)
2606 TRACE("(%p)->(%p %d)\n", this, pidl
, item
);
2607 return Item(item
, pidl
);
2610 HRESULT STDMETHODCALLTYPE
CDefView::RemoveObject(PITEMID_CHILD pidl
, UINT
*item
)
2613 TRACE("(%p)->(%p %p)\n", this, pidl
, item
);
2617 *item
= LV_FindItemByPidl(ILFindLastID(pidl
));
2618 m_ListView
.DeleteItem(*item
);
2623 m_ListView
.DeleteAllItems();
2629 HRESULT STDMETHODCALLTYPE
CDefView::GetObjectCount(UINT
*count
)
2631 TRACE("(%p)->(%p)\n", this, count
);
2632 *count
= m_ListView
.GetItemCount();
2636 HRESULT STDMETHODCALLTYPE
CDefView::SetObjectCount(UINT count
, UINT flags
)
2638 FIXME("(%p)->(%d %x) stub\n", this, count
, flags
);
2642 HRESULT STDMETHODCALLTYPE
CDefView::UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
)
2644 FIXME("(%p)->(%p %p %p) stub\n", this, pidl_old
, pidl_new
, item
);
2648 HRESULT STDMETHODCALLTYPE
CDefView::RefreshObject(PITEMID_CHILD pidl
, UINT
*item
)
2650 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2654 HRESULT STDMETHODCALLTYPE
CDefView::SetRedraw(BOOL redraw
)
2656 TRACE("(%p)->(%d)\n", this, redraw
);
2657 m_ListView
.SetRedraw(redraw
);
2661 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedCount(UINT
*count
)
2663 FIXME("(%p)->(%p) stub\n", this, count
);
2667 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
)
2669 TRACE("(%p)->(%p %p)\n", this, pidl
, items
);
2671 *items
= GetSelections();
2675 *pidl
= static_cast<PCUITEMID_CHILD
*>(LocalAlloc(0, *items
* sizeof(PCUITEMID_CHILD
)));
2678 return E_OUTOFMEMORY
;
2681 /* it's documented that caller shouldn't PIDLs, only array itself */
2682 memcpy(*pidl
, m_apidl
, *items
* sizeof(PCUITEMID_CHILD
));
2688 HRESULT STDMETHODCALLTYPE
CDefView::IsDropOnSource(IDropTarget
*drop_target
)
2690 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2694 HRESULT STDMETHODCALLTYPE
CDefView::GetDragPoint(POINT
*pt
)
2696 FIXME("(%p)->(%p) stub\n", this, pt
);
2700 HRESULT STDMETHODCALLTYPE
CDefView::GetDropPoint(POINT
*pt
)
2702 FIXME("(%p)->(%p) stub\n", this, pt
);
2706 HRESULT STDMETHODCALLTYPE
CDefView::MoveIcons(IDataObject
*obj
)
2708 TRACE("(%p)->(%p)\n", this, obj
);
2712 HRESULT STDMETHODCALLTYPE
CDefView::SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
)
2714 FIXME("(%p)->(%p %p) stub\n", this, pidl
, pt
);
2718 HRESULT STDMETHODCALLTYPE
CDefView::IsBkDropTarget(IDropTarget
*drop_target
)
2720 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2724 HRESULT STDMETHODCALLTYPE
CDefView::SetClipboard(BOOL move
)
2726 FIXME("(%p)->(%d) stub\n", this, move
);
2730 HRESULT STDMETHODCALLTYPE
CDefView::SetPoints(IDataObject
*obj
)
2732 FIXME("(%p)->(%p) stub\n", this, obj
);
2736 HRESULT STDMETHODCALLTYPE
CDefView::GetItemSpacing(ITEMSPACING
*spacing
)
2738 FIXME("(%p)->(%p) stub\n", this, spacing
);
2742 HRESULT STDMETHODCALLTYPE
CDefView::SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
)
2744 FIXME("(%p)->(%p %p) stub\n", this, new_cb
, old_cb
);
2748 HRESULT STDMETHODCALLTYPE
CDefView::Select(UINT flags
)
2750 FIXME("(%p)->(%d) stub\n", this, flags
);
2754 HRESULT STDMETHODCALLTYPE
CDefView::QuerySupport(UINT
*support
)
2756 TRACE("(%p)->(%p)\n", this, support
);
2760 HRESULT STDMETHODCALLTYPE
CDefView::SetAutomationObject(IDispatch
*disp
)
2762 FIXME("(%p)->(%p) stub\n", this, disp
);
2766 /**********************************************************
2767 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2769 HRESULT WINAPI
CDefView::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD
*prgCmds
, OLECMDTEXT
*pCmdText
)
2771 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
2772 this, pguidCmdGroup
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
2775 return E_INVALIDARG
;
2777 for (UINT i
= 0; i
< cCmds
; i
++)
2779 FIXME("\tprgCmds[%d].cmdID = %d\n", i
, prgCmds
[i
].cmdID
);
2780 prgCmds
[i
].cmdf
= 0;
2783 return OLECMDERR_E_UNKNOWNGROUP
;
2786 /**********************************************************
2787 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2789 * nCmdID is the OLECMDID_* enumeration
2791 HRESULT WINAPI
CDefView::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
2793 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2794 this, debugstr_guid(pguidCmdGroup
), nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2797 return OLECMDERR_E_UNKNOWNGROUP
;
2799 if (IsEqualCLSID(*pguidCmdGroup
, m_Category
))
2801 if (nCmdID
== FCIDM_SHVIEW_AUTOARRANGE
)
2803 if (V_VT(pvaIn
) != VT_INT_PTR
)
2804 return OLECMDERR_E_NOTSUPPORTED
;
2808 params
.cbSize
= sizeof(params
);
2809 params
.rcExclude
= *(RECT
*) V_INTREF(pvaIn
);
2811 HMENU hView
= m_hView
;
2813 hView
= CreatePopupMenu();
2814 AppendMenuW(hView
, MF_STRING
, FCIDM_SHVIEW_BIGICON
, L
"Big!");
2815 AppendMenuW(hView
, MF_STRING
, FCIDM_SHVIEW_SMALLICON
, L
"Small!");
2816 AppendMenuW(hView
, MF_STRING
, FCIDM_SHVIEW_LISTVIEW
, L
"List!");
2817 AppendMenuW(hView
, MF_STRING
, FCIDM_SHVIEW_REPORTVIEW
, L
"Report!");
2822 PrepareShowViewMenu(hView
);
2824 TrackPopupMenuEx(hView
, TPM_LEFTALIGN
| TPM_TOPALIGN
, params
.rcExclude
.left
, params
.rcExclude
.bottom
, m_hWndParent
, ¶ms
);
2827 // pvaOut is VT_I4 with value 0x403 (cmd id of the new mode maybe?)
2828 V_VT(pvaOut
) = VT_I4
;
2829 V_I4(pvaOut
) = 0x403;
2833 if (IsEqualIID(*pguidCmdGroup
, CGID_Explorer
) &&
2835 (nCmdexecopt
== 4) && pvaOut
)
2838 if (IsEqualIID(*pguidCmdGroup
, CGID_ShellDocView
) &&
2843 return OLECMDERR_E_UNKNOWNGROUP
;
2846 /**********************************************************
2847 * ISVDropTarget implementation
2850 /******************************************************************************
2851 * drag_notify_subitem [Internal]
2853 * Figure out the shellfolder object, which is currently under the mouse cursor
2854 * and notify it via the IDropTarget interface.
2857 #define SCROLLAREAWIDTH 20
2859 HRESULT
CDefView::drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2861 LVHITTESTINFO htinfo
;
2866 /* Map from global to client coordinates and query the index of the listview-item, which is
2867 * currently under the mouse cursor. */
2870 htinfo
.flags
= LVHT_ONITEM
;
2871 ::ScreenToClient(m_ListView
, &htinfo
.pt
);
2872 lResult
= m_ListView
.HitTest(&htinfo
);
2874 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2875 ::GetClientRect(m_ListView
, &clientRect
);
2876 if (htinfo
.pt
.x
== m_ptLastMousePos
.x
&& htinfo
.pt
.y
== m_ptLastMousePos
.y
&&
2877 (htinfo
.pt
.x
< SCROLLAREAWIDTH
|| htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
||
2878 htinfo
.pt
.y
< SCROLLAREAWIDTH
|| htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
))
2880 m_cScrollDelay
= (m_cScrollDelay
+ 1) % 5; /* DragOver is called every 50 ms */
2881 if (m_cScrollDelay
== 0)
2883 /* Mouse did hover another 250 ms over the scroll-area */
2884 if (htinfo
.pt
.x
< SCROLLAREAWIDTH
)
2885 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEUP
, 0);
2887 if (htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
)
2888 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEDOWN
, 0);
2890 if (htinfo
.pt
.y
< SCROLLAREAWIDTH
)
2891 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEUP
, 0);
2893 if (htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
)
2894 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEDOWN
, 0);
2899 m_cScrollDelay
= 0; /* Reset, if the cursor is not over the listview's scroll-area */
2902 m_ptLastMousePos
= htinfo
.pt
;
2904 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2905 if (m_pCurDropTarget
&& lResult
== m_iDragOverItem
)
2906 return m_pCurDropTarget
->DragOver(grfKeyState
, pt
, pdwEffect
);
2908 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2909 if (m_pCurDropTarget
)
2911 m_pCurDropTarget
->DragLeave();
2912 m_pCurDropTarget
.Release();
2915 m_iDragOverItem
= lResult
;
2918 /* We are not above one of the listview's subitems. Bind to the parent folder's
2919 * DropTarget interface. */
2920 hr
= m_pSFParent
->CreateViewObject(NULL
, IID_PPV_ARG(IDropTarget
,&m_pCurDropTarget
));
2924 /* Query the relative PIDL of the shellfolder object represented by the currently
2925 * dragged over listview-item ... */
2926 PCUITEMID_CHILD pidl
= _PidlByItem(lResult
);
2928 /* ... and bind m_pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2929 hr
= m_pSFParent
->GetUIObjectOf(m_ListView
, 1, &pidl
, IID_NULL_PPV_ARG(IDropTarget
, &m_pCurDropTarget
));
2932 /* If anything failed, m_pCurDropTarget should be NULL now, which ought to be a save state. */
2936 /* Notify the item just entered via DragEnter. */
2937 return m_pCurDropTarget
->DragEnter(m_pCurDataObject
, grfKeyState
, pt
, pdwEffect
);
2940 HRESULT WINAPI
CDefView::DragEnter(IDataObject
*pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2942 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2943 m_pCurDataObject
= pDataObject
;
2944 pDataObject
->AddRef();
2946 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2949 HRESULT WINAPI
CDefView::DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2951 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2954 HRESULT WINAPI
CDefView::DragLeave()
2956 if (m_pCurDropTarget
)
2958 m_pCurDropTarget
->DragLeave();
2959 m_pCurDropTarget
.Release();
2962 if (m_pCurDataObject
!= NULL
)
2964 m_pCurDataObject
.Release();
2967 m_iDragOverItem
= 0;
2972 HRESULT WINAPI
CDefView::Drop(IDataObject
* pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2974 ERR("GetKeyState(VK_LBUTTON): %d\n", GetKeyState(VK_LBUTTON
));
2976 if ((m_iDragOverItem
== -1) &&
2977 (*pdwEffect
& DROPEFFECT_MOVE
) &&
2978 (GetKeyState(VK_LBUTTON
) != 0) &&
2979 (m_pSourceDataObject
.p
) &&
2980 (SHIsSameObject(pDataObject
, m_pSourceDataObject
)))
2982 ERR("Should implement moving items here!\n");
2984 if (m_pCurDropTarget
)
2986 m_pCurDropTarget
->DragLeave();
2987 m_pCurDropTarget
.Release();
2990 else if (m_pCurDropTarget
)
2992 m_pCurDropTarget
->Drop(pDataObject
, grfKeyState
, pt
, pdwEffect
);
2993 m_pCurDropTarget
.Release();
2996 m_pCurDataObject
.Release();
2997 m_iDragOverItem
= 0;
3001 /**********************************************************
3002 * ISVDropSource implementation
3005 HRESULT WINAPI
CDefView::QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
)
3007 TRACE("(%p)\n", this);
3010 return DRAGDROP_S_CANCEL
;
3011 else if (!(grfKeyState
& MK_LBUTTON
) && !(grfKeyState
& MK_RBUTTON
))
3012 return DRAGDROP_S_DROP
;
3017 HRESULT WINAPI
CDefView::GiveFeedback(DWORD dwEffect
)
3019 TRACE("(%p)\n", this);
3021 return DRAGDROP_S_USEDEFAULTCURSORS
;
3024 /**********************************************************
3025 * ISVViewObject implementation
3028 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
)
3030 FIXME("Stub: this=%p\n", this);
3035 HRESULT WINAPI
CDefView::GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
, HDC hicTargetDevice
, LOGPALETTE
**ppColorSet
)
3037 FIXME("Stub: this=%p\n", this);
3042 HRESULT WINAPI
CDefView::Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
)
3044 FIXME("Stub: this=%p\n", this);
3049 HRESULT WINAPI
CDefView::Unfreeze(DWORD dwFreeze
)
3051 FIXME("Stub: this=%p\n", this);
3056 HRESULT WINAPI
CDefView::SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
)
3058 FIXME("partial stub: %p %08x %08x %p\n", this, aspects
, advf
, pAdvSink
);
3060 /* FIXME: we set the AdviseSink, but never use it to send any advice */
3061 m_pAdvSink
= pAdvSink
;
3062 m_dwAspects
= aspects
;
3068 HRESULT WINAPI
CDefView::GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
)
3070 TRACE("this=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n", this, pAspects
, pAdvf
, ppAdvSink
);
3074 *ppAdvSink
= m_pAdvSink
;
3075 m_pAdvSink
.p
->AddRef();
3079 *pAspects
= m_dwAspects
;
3087 HRESULT STDMETHODCALLTYPE
CDefView::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
3089 if (IsEqualIID(guidService
, SID_IShellBrowser
))
3090 return m_pShellBrowser
->QueryInterface(riid
, ppvObject
);
3091 else if(IsEqualIID(guidService
, SID_IFolderView
))
3092 return QueryInterface(riid
, ppvObject
);
3094 return E_NOINTERFACE
;
3097 HRESULT
CDefView::_MergeToolbar()
3099 CComPtr
<IExplorerToolbar
> ptb
;
3102 hr
= IUnknown_QueryService(m_pShellBrowser
, IID_IExplorerToolbar
, IID_PPV_ARG(IExplorerToolbar
, &ptb
));
3106 m_Category
= CGID_DefViewFrame
;
3108 hr
= ptb
->SetCommandTarget(static_cast<IOleCommandTarget
*>(this), &m_Category
, 0);
3116 hr
= ptb
->AddButtons(&m_Category
, buttonsCount
, buttons
);
3123 /**********************************************************
3124 * IShellView_Constructor
3126 HRESULT WINAPI
IShellView_Constructor(IShellFolder
*pFolder
, IShellView
**newView
)
3128 return ShellObjectCreatorInit
<CDefView
>(pFolder
, IID_IShellView
, newView
);
3131 HRESULT WINAPI
CDefView_Constructor(IShellFolder
*pFolder
, REFIID riid
, LPVOID
* ppvOut
)
3133 return ShellObjectCreatorInit
<CDefView
>(pFolder
, riid
, ppvOut
);