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
<IDropTarget
> m_pCurDropTarget
; /* The sub-item, which is currently dragged over */
101 CComPtr
<IDataObject
> m_pCurDataObject
; /* The dragged data-object */
102 LONG m_iDragOverItem
; /* Dragged over item's index, iff m_pCurDropTarget != NULL */
103 UINT m_cScrollDelay
; /* Send a WM_*SCROLL msg every 250 ms during drag-scroll */
104 POINT m_ptLastMousePos
; /* Mouse position at last DragOver call */
106 CComPtr
<IContextMenu
> m_pCM
;
115 HRESULT
_MergeToolbar();
120 HRESULT WINAPI
Initialize(IShellFolder
*shellFolder
);
121 HRESULT
IncludeObject(PCUITEMID_CHILD pidl
);
122 HRESULT
OnDefaultCommand();
123 HRESULT
OnStateChange(UINT uFlags
);
124 void UpdateStatusbar();
126 void SetStyle(DWORD dwAdd
, DWORD dwRemove
);
128 void UpdateListColors();
130 static INT CALLBACK
ListViewCompareItems(LPARAM lParam1
, LPARAM lParam2
, LPARAM lpData
);
132 PCUITEMID_CHILD
_PidlByItem(int i
);
133 PCUITEMID_CHILD
_PidlByItem(LVITEM
& lvItem
);
134 int LV_FindItemByPidl(PCUITEMID_CHILD pidl
);
135 BOOLEAN
LV_AddItem(PCUITEMID_CHILD pidl
);
136 BOOLEAN
LV_DeleteItem(PCUITEMID_CHILD pidl
);
137 BOOLEAN
LV_RenameItem(PCUITEMID_CHILD pidlOld
, PCUITEMID_CHILD pidlNew
);
138 BOOLEAN
LV_ProdItem(PCUITEMID_CHILD pidl
);
139 static INT CALLBACK
fill_list(LPVOID ptr
, LPVOID arg
);
141 HMENU
BuildFileMenu();
142 void PrepareShowFileMenu(HMENU hSubMenu
);
143 void PrepareShowViewMenu(HMENU hSubMenu
);
144 UINT
GetSelections();
145 HRESULT
OpenSelectedItems();
147 void DoActivate(UINT uState
);
148 HRESULT
drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
149 HRESULT
InvokeContextMenuCommand(UINT uCommand
);
150 LRESULT
OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
);
152 // *** IOleWindow methods ***
153 virtual HRESULT STDMETHODCALLTYPE
GetWindow(HWND
*lphwnd
);
154 virtual HRESULT STDMETHODCALLTYPE
ContextSensitiveHelp(BOOL fEnterMode
);
156 // *** IShellView methods ***
157 virtual HRESULT STDMETHODCALLTYPE
TranslateAccelerator(MSG
*pmsg
);
158 virtual HRESULT STDMETHODCALLTYPE
EnableModeless(BOOL fEnable
);
159 virtual HRESULT STDMETHODCALLTYPE
UIActivate(UINT uState
);
160 virtual HRESULT STDMETHODCALLTYPE
Refresh();
161 virtual HRESULT STDMETHODCALLTYPE
CreateViewWindow(IShellView
*psvPrevious
, LPCFOLDERSETTINGS pfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
);
162 virtual HRESULT STDMETHODCALLTYPE
DestroyViewWindow();
163 virtual HRESULT STDMETHODCALLTYPE
GetCurrentInfo(LPFOLDERSETTINGS pfs
);
164 virtual HRESULT STDMETHODCALLTYPE
AddPropertySheetPages(DWORD dwReserved
, LPFNSVADDPROPSHEETPAGE pfn
, LPARAM lparam
);
165 virtual HRESULT STDMETHODCALLTYPE
SaveViewState();
166 virtual HRESULT STDMETHODCALLTYPE
SelectItem(PCUITEMID_CHILD pidlItem
, SVSIF uFlags
);
167 virtual HRESULT STDMETHODCALLTYPE
GetItemObject(UINT uItem
, REFIID riid
, void **ppv
);
169 // *** IShellView2 methods ***
170 virtual HRESULT STDMETHODCALLTYPE
GetView(SHELLVIEWID
*view_guid
, ULONG view_type
);
171 virtual HRESULT STDMETHODCALLTYPE
CreateViewWindow2(LPSV2CVW2_PARAMS view_params
);
172 virtual HRESULT STDMETHODCALLTYPE
HandleRename(LPCITEMIDLIST new_pidl
);
173 virtual HRESULT STDMETHODCALLTYPE
SelectAndPositionItem(LPCITEMIDLIST item
, UINT flags
, POINT
*point
);
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
), 0, 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_IShellView2
, IShellView2
)
330 COM_INTERFACE_ENTRY_IID(IID_IFolderView
, IFolderView
)
331 COM_INTERFACE_ENTRY_IID(IID_IShellFolderView
, IShellFolderView
)
332 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget
, IOleCommandTarget
)
333 COM_INTERFACE_ENTRY_IID(IID_IDropTarget
, IDropTarget
)
334 COM_INTERFACE_ENTRY_IID(IID_IDropSource
, IDropSource
)
335 COM_INTERFACE_ENTRY_IID(IID_IViewObject
, IViewObject
)
336 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider
, IServiceProvider
)
341 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
342 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
343 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
345 #define ID_LISTVIEW 1
348 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
349 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
350 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
352 typedef void (CALLBACK
*PFNSHGETSETTINGSPROC
)(LPSHELLFLAGSTATE lpsfs
, DWORD dwMask
);
354 CDefView::CDefView() :
358 m_menusLoaded(FALSE
),
373 ZeroMemory(&m_FolderSettings
, sizeof(m_FolderSettings
));
374 ZeroMemory(&m_sortInfo
, sizeof(m_sortInfo
));
375 ZeroMemory(&m_ptLastMousePos
, sizeof(m_ptLastMousePos
));
376 ZeroMemory(&m_Category
, sizeof(m_Category
));
379 CDefView::~CDefView()
381 TRACE(" destroying IShellView(%p)\n", this);
391 HRESULT WINAPI
CDefView::Initialize(IShellFolder
*shellFolder
)
393 m_pSFParent
= shellFolder
;
394 shellFolder
->QueryInterface(IID_PPV_ARG(IShellFolder2
, &m_pSF2Parent
));
399 /**********************************************************
401 * ##### helperfunctions for communication with ICommDlgBrowser #####
403 HRESULT
CDefView::IncludeObject(PCUITEMID_CHILD pidl
)
407 if (m_pCommDlgBrowser
.p
!= NULL
)
409 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl
);
410 ret
= m_pCommDlgBrowser
->IncludeObject(this, pidl
);
411 TRACE("--0x%08x\n", ret
);
417 HRESULT
CDefView::OnDefaultCommand()
419 HRESULT ret
= S_FALSE
;
421 if (m_pCommDlgBrowser
.p
!= NULL
)
423 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
424 ret
= m_pCommDlgBrowser
->OnDefaultCommand(this);
425 TRACE("-- returns %08x\n", ret
);
431 HRESULT
CDefView::OnStateChange(UINT uFlags
)
433 HRESULT ret
= S_FALSE
;
435 if (m_pCommDlgBrowser
.p
!= NULL
)
437 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags
);
438 ret
= m_pCommDlgBrowser
->OnStateChange(this, uFlags
);
444 /**********************************************************
445 * set the toolbar of the filedialog buttons
447 * - activates the buttons from the shellbrowser according to
450 void CDefView::CheckToolbar()
456 if (m_pCommDlgBrowser
!= NULL
)
458 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
459 FCIDM_TB_SMALLICON
, (m_FolderSettings
.ViewMode
== FVM_LIST
) ? TRUE
: FALSE
, &result
);
460 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
461 FCIDM_TB_REPORTVIEW
, (m_FolderSettings
.ViewMode
== FVM_DETAILS
) ? TRUE
: FALSE
, &result
);
462 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
463 FCIDM_TB_SMALLICON
, TRUE
, &result
);
464 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
465 FCIDM_TB_REPORTVIEW
, TRUE
, &result
);
469 void CDefView::UpdateStatusbar()
471 WCHAR szFormat
[MAX_PATH
] = {0};
472 WCHAR szObjects
[MAX_PATH
] = {0};
475 cSelectedItems
= m_ListView
.GetSelectedCount();
478 LoadStringW(shell32_hInstance
, IDS_OBJECTS_SELECTED
, szFormat
, _countof(szFormat
));
479 StringCchPrintfW(szObjects
, MAX_PATH
, szFormat
, cSelectedItems
);
483 LoadStringW(shell32_hInstance
, IDS_OBJECTS
, szFormat
, _countof(szFormat
));
484 StringCchPrintfW(szObjects
, MAX_PATH
, szFormat
, m_ListView
.GetItemCount());
486 m_pShellBrowser
->SetStatusTextSB(szObjects
);
489 /**********************************************************
491 * ##### helperfunctions for initializing the view #####
493 /**********************************************************
494 * change the style of the listview control
496 void CDefView::SetStyle(DWORD dwAdd
, DWORD dwRemove
)
500 TRACE("(%p)\n", this);
502 tmpstyle
= ::GetWindowLongPtrW(m_ListView
, GWL_STYLE
);
503 ::SetWindowLongPtrW(m_ListView
, GWL_STYLE
, dwAdd
| (tmpstyle
& ~dwRemove
));
506 /**********************************************************
507 * ShellView_CreateList()
509 * - creates the list view window
511 BOOL
CDefView::CreateList()
512 { DWORD dwStyle
, dwExStyle
;
516 dwStyle
= WS_TABSTOP
| WS_VISIBLE
| WS_CHILDWINDOW
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
|
517 LVS_SHAREIMAGELISTS
| LVS_EDITLABELS
| LVS_AUTOARRANGE
;
518 dwExStyle
= WS_EX_CLIENTEDGE
;
520 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
521 dwStyle
|= LVS_ALIGNLEFT
;
523 dwStyle
|= LVS_ALIGNTOP
| LVS_SHOWSELALWAYS
;
525 switch (m_FolderSettings
.ViewMode
)
532 dwStyle
|= LVS_REPORT
;
536 dwStyle
|= LVS_SMALLICON
;
548 if (m_FolderSettings
.fFlags
& FWF_AUTOARRANGE
)
549 dwStyle
|= LVS_AUTOARRANGE
;
551 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
552 m_FolderSettings
.fFlags
|= FWF_NOCLIENTEDGE
| FWF_NOSCROLL
;
554 if (m_FolderSettings
.fFlags
& FWF_SINGLESEL
)
555 dwStyle
|= LVS_SINGLESEL
;
557 if (m_FolderSettings
.fFlags
& FWF_NOCLIENTEDGE
)
558 dwExStyle
&= ~WS_EX_CLIENTEDGE
;
560 RECT rcListView
= {0,0,0,0};
561 m_ListView
.Create(m_hWnd
, rcListView
, NULL
,dwStyle
, dwExStyle
, ID_LISTVIEW
);
566 m_sortInfo
.bIsAscending
= TRUE
;
567 m_sortInfo
.nHeaderID
= -1;
568 m_sortInfo
.nLastHeaderID
= -1;
572 /* UpdateShellSettings(); */
576 void CDefView::UpdateListColors()
578 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
580 /* Check if drop shadows option is enabled */
581 BOOL bDropShadow
= FALSE
;
582 DWORD cbDropShadow
= sizeof(bDropShadow
);
583 WCHAR wszBuf
[16] = L
"";
585 RegGetValueW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
586 L
"ListviewShadow", RRF_RT_DWORD
, NULL
, &bDropShadow
, &cbDropShadow
);
587 if (bDropShadow
&& SystemParametersInfoW(SPI_GETDESKWALLPAPER
, _countof(wszBuf
), wszBuf
, 0) && wszBuf
[0])
589 m_ListView
.SetTextBkColor(CLR_NONE
);
590 m_ListView
.SetBkColor(CLR_NONE
);
591 m_ListView
.SetTextColor(RGB(255, 255, 255));
592 m_ListView
.SetExtendedListViewStyle(LVS_EX_TRANSPARENTSHADOWTEXT
, LVS_EX_TRANSPARENTSHADOWTEXT
);
596 COLORREF crDesktop
= GetSysColor(COLOR_DESKTOP
);
597 m_ListView
.SetTextBkColor(crDesktop
);
598 m_ListView
.SetBkColor(crDesktop
);
599 if (GetRValue(crDesktop
) + GetGValue(crDesktop
) + GetBValue(crDesktop
) > 128 * 3)
600 m_ListView
.SetTextColor(RGB(0, 0, 0));
602 m_ListView
.SetTextColor(RGB(255, 255, 255));
603 m_ListView
.SetExtendedListViewStyle(LVS_EX_TRANSPARENTSHADOWTEXT
);
608 /**********************************************************
609 * ShellView_InitList()
611 * - adds all needed columns to the shellview
613 BOOL
CDefView::InitList()
617 HIMAGELIST big_icons
, small_icons
;
621 m_ListView
.DeleteAllItems();
625 for (int i
= 0; 1; i
++)
627 if (FAILED(m_pSF2Parent
->GetDetailsOf(NULL
, i
, &sd
)))
629 StrRetToStrNW( szTemp
, 50, &sd
.str
, NULL
);
630 m_ListView
.InsertColumn(i
, szTemp
, sd
.fmt
, sd
.cxChar
* 8);
639 Shell_GetImageLists(&big_icons
, &small_icons
);
640 m_ListView
.SetImageList(big_icons
, LVSIL_NORMAL
);
641 m_ListView
.SetImageList(small_icons
, LVSIL_SMALL
);
646 /*************************************************************************
647 * ShellView_ListViewCompareItems
649 * Compare Function for the Listview (FileOpen Dialog)
652 * lParam1 [I] the first ItemIdList to compare with
653 * lParam2 [I] the second ItemIdList to compare with
654 * lpData [I] The column ID for the header Ctrl to process
657 * A negative value if the first item should precede the second,
658 * a positive value if the first item should follow the second,
659 * or zero if the two items are equivalent
661 INT CALLBACK
CDefView::ListViewCompareItems(LPARAM lParam1
, LPARAM lParam2
, LPARAM lpData
)
663 PCUIDLIST_RELATIVE pidl1
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam1
);
664 PCUIDLIST_RELATIVE pidl2
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam2
);
665 CDefView
*pThis
= reinterpret_cast<CDefView
*>(lpData
);
667 HRESULT hres
= pThis
->m_pSFParent
->CompareIDs(pThis
->m_sortInfo
.nHeaderID
, pidl1
, pidl2
);
668 if (FAILED_UNEXPECTEDLY(hres
))
671 SHORT nDiff
= HRESULT_CODE(hres
);
672 if (!pThis
->m_sortInfo
.bIsAscending
)
677 PCUITEMID_CHILD
CDefView::_PidlByItem(int i
)
679 return reinterpret_cast<PCUITEMID_CHILD
>(m_ListView
.GetItemData(i
));
682 PCUITEMID_CHILD
CDefView::_PidlByItem(LVITEM
& lvItem
)
684 return reinterpret_cast<PCUITEMID_CHILD
>(lvItem
.lParam
);
687 /**********************************************************
688 * LV_FindItemByPidl()
690 int CDefView::LV_FindItemByPidl(PCUITEMID_CHILD pidl
)
692 int cItems
= m_ListView
.GetItemCount();
694 for (int i
= 0; i
<cItems
; i
++)
696 PCUITEMID_CHILD currentpidl
= _PidlByItem(i
);
697 HRESULT hr
= m_pSFParent
->CompareIDs(0, pidl
, currentpidl
);
699 if (SUCCEEDED(hr
) && !HRESULT_CODE(hr
))
707 /**********************************************************
710 BOOLEAN
CDefView::LV_AddItem(PCUITEMID_CHILD pidl
)
714 TRACE("(%p)(pidl=%p)\n", this, pidl
);
716 lvItem
.mask
= LVIF_TEXT
| LVIF_IMAGE
| LVIF_PARAM
; /*set the mask*/
717 lvItem
.iItem
= m_ListView
.GetItemCount(); /*add the item to the end of the list*/
719 lvItem
.lParam
= reinterpret_cast<LPARAM
>(ILClone(pidl
)); /*set the item's data*/
720 lvItem
.pszText
= LPSTR_TEXTCALLBACKW
; /*get text on a callback basis*/
721 lvItem
.iImage
= I_IMAGECALLBACK
; /*get the image on a callback basis*/
722 lvItem
.stateMask
= LVIS_CUT
;
724 if (m_ListView
.InsertItem(&lvItem
) == -1)
730 /**********************************************************
733 BOOLEAN
CDefView::LV_DeleteItem(PCUITEMID_CHILD pidl
)
737 TRACE("(%p)(pidl=%p)\n", this, pidl
);
739 nIndex
= LV_FindItemByPidl(pidl
);
741 return (-1 == m_ListView
.DeleteItem(nIndex
)) ? FALSE
: TRUE
;
744 /**********************************************************
747 BOOLEAN
CDefView::LV_RenameItem(PCUITEMID_CHILD pidlOld
, PCUITEMID_CHILD pidlNew
)
752 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", this, pidlOld
, pidlNew
);
754 nItem
= LV_FindItemByPidl(pidlOld
);
758 lvItem
.mask
= LVIF_PARAM
; /* only the pidl */
759 lvItem
.iItem
= nItem
;
761 m_ListView
.GetItem(&lvItem
);
763 SHFree(reinterpret_cast<LPVOID
>(lvItem
.lParam
));
764 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
765 lvItem
.iItem
= nItem
;
767 lvItem
.lParam
= reinterpret_cast<LPARAM
>(ILClone(pidlNew
)); /* set the item's data */
768 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
769 m_ListView
.SetItem(&lvItem
);
770 m_ListView
.Update(nItem
);
771 return TRUE
; /* FIXME: better handling */
777 /**********************************************************
780 BOOLEAN
CDefView::LV_ProdItem(PCUITEMID_CHILD pidl
)
785 TRACE("(%p)(pidl=%p)\n", this, pidl
);
787 nItem
= LV_FindItemByPidl(pidl
);
791 lvItem
.mask
= LVIF_IMAGE
;
792 lvItem
.iItem
= nItem
;
794 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
795 m_ListView
.SetItem(&lvItem
);
796 m_ListView
.Update(nItem
);
803 /**********************************************************
804 * ShellView_FillList()
806 * - gets the objectlist from the shellfolder
808 * - fills the list into the view
810 INT CALLBACK
CDefView::fill_list( LPVOID ptr
, LPVOID arg
)
812 PITEMID_CHILD pidl
= static_cast<PITEMID_CHILD
>(ptr
);
813 CDefView
*pThis
= static_cast<CDefView
*>(arg
);
815 /* in a commdlg This works as a filemask*/
816 if (pThis
->IncludeObject(pidl
) == S_OK
)
817 pThis
->LV_AddItem(pidl
);
823 HRESULT
CDefView::FillList()
825 CComPtr
<IEnumIDList
> pEnumIDList
;
831 DWORD dFlags
= SHCONTF_NONFOLDERS
| SHCONTF_FOLDERS
;
835 /* determine if there is a setting to show all the hidden files/folders */
836 if (RegOpenKeyExW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", 0, KEY_QUERY_VALUE
, &hKey
) == ERROR_SUCCESS
)
838 DWORD dataLength
, flagVal
;
840 dataLength
= sizeof(flagVal
);
841 if (RegQueryValueExW(hKey
, L
"Hidden", NULL
, NULL
, (LPBYTE
)&flagVal
, &dataLength
) == ERROR_SUCCESS
)
843 /* if the value is 1, then show all hidden files/folders */
846 dFlags
|= SHCONTF_INCLUDEHIDDEN
;
847 m_ListView
.SendMessageW(LVM_SETCALLBACKMASK
, LVIS_CUT
, 0);
855 /* get the itemlist from the shfolder */
856 hRes
= m_pSFParent
->EnumObjects(m_hWnd
, dFlags
, &pEnumIDList
);
864 /* create a pointer array */
865 hdpa
= DPA_Create(16);
868 return(E_OUTOFMEMORY
);
871 /* copy the items into the array*/
872 while((S_OK
== pEnumIDList
->Next(1, &pidl
, &dwFetched
)) && dwFetched
)
874 if (DPA_InsertPtr(hdpa
, 0x7fff, pidl
) == -1)
880 /*turn the listview's redrawing off*/
881 m_ListView
.SetRedraw(FALSE
);
883 DPA_DestroyCallback( hdpa
, fill_list
, this);
886 m_pSF2Parent
->GetDefaultColumn(NULL
, (ULONG
*)&m_sortInfo
.nHeaderID
, NULL
);
887 m_sortInfo
.bIsAscending
= TRUE
;
888 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
889 m_ListView
.SortItems(ListViewCompareItems
, this);
891 /*turn the listview's redrawing back on and force it to draw*/
892 m_ListView
.SetRedraw(TRUE
);
897 LRESULT
CDefView::OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
899 m_ListView
.UpdateWindow();
904 LRESULT
CDefView::OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
906 return m_ListView
.SendMessageW(uMsg
, 0, 0);
909 LRESULT
CDefView::OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
916 DestroyMenu(m_hMenu
);
919 RevokeDragDrop(m_hWnd
);
920 SHChangeNotifyDeregister(m_hNotify
);
922 SHFree(m_pidlParent
);
929 LRESULT
CDefView::OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
931 /* redirect to parent */
932 if (m_FolderSettings
.fFlags
& (FWF_DESKTOP
| FWF_TRANSPARENT
))
933 return SendMessageW(GetParent(), WM_ERASEBKGND
, wParam
, lParam
);
939 LRESULT
CDefView::OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
941 /* Update desktop labels color */
944 /* Forward WM_SYSCOLORCHANGE to common controls */
945 return m_ListView
.SendMessageW(uMsg
, 0, 0);
948 LRESULT
CDefView::OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
950 return reinterpret_cast<LRESULT
>(m_pShellBrowser
.p
);
953 LRESULT
CDefView::OnNCCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
960 LRESULT
CDefView::OnNCDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
967 /**********************************************************
968 * ShellView_OnCreate()
970 LRESULT
CDefView::OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
972 CComPtr
<IDropTarget
> pdt
;
973 SHChangeNotifyEntry ntreg
;
974 CComPtr
<IPersistFolder2
> ppf2
;
986 if (SUCCEEDED(QueryInterface(IID_PPV_ARG(IDropTarget
, &pdt
))))
988 if (FAILED(RegisterDragDrop(m_hWnd
, pdt
)))
989 ERR("Registering Drag Drop Failed");
992 /* register for receiving notifications */
993 m_pSFParent
->QueryInterface(IID_PPV_ARG(IPersistFolder2
, &ppf2
));
996 ppf2
->GetCurFolder(&m_pidlParent
);
997 ntreg
.fRecursive
= TRUE
;
998 ntreg
.pidl
= m_pidlParent
;
999 m_hNotify
= SHChangeNotifyRegister(m_hWnd
, SHCNRF_InterruptLevel
| SHCNRF_ShellLevel
, SHCNE_ALLEVENTS
, SHV_CHANGE_NOTIFY
, 1, &ntreg
);
1002 m_hAccel
= LoadAcceleratorsW(shell32_hInstance
, MAKEINTRESOURCEW(IDA_SHELLVIEW
));
1009 /**********************************************************
1010 * #### Handling of the menus ####
1013 HMENU
CDefView::BuildFileMenu()
1016 CComPtr
<IContextMenu
> cm
;
1020 hr
= m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, IID_NULL_PPV_ARG(IContextMenu
, &cm
));
1024 HMENU hmenu
= CreatePopupMenu();
1026 //FIXME: get proper numbers ?
1027 const UINT first
= 0x7800;
1028 const UINT last
= 0x7A00;
1029 hr
= cm
->QueryContextMenu(hmenu
, 0, first
, last
, 0);
1033 // TODO: filter or something
1038 void CDefView::PrepareShowFileMenu(HMENU hSubMenu
)
1040 TRACE("(%p)->(submenu=%p) stub\n", this, hSubMenu
);
1045 /* Cleanup the items added previously */
1046 for (int i
= 0; i
< GetMenuItemCount(hSubMenu
); )
1049 mii
.cbSize
= sizeof(mii
);
1050 mii
.fMask
= MIIM_ID
;
1051 GetMenuItemInfoW(hSubMenu
, i
, TRUE
, &mii
);
1053 if (mii
.wID
< 0x8000)
1055 DeleteMenu(hSubMenu
, i
, MF_BYPOSITION
);
1064 /* FIXME/TODO: Reenable when they implemented AND localizable (not hardcoded). */
1065 /* Insert This item at the beginning of the menu. */
1066 _InsertMenuItemW(hSubMenu
, 0, TRUE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1067 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
+ 4, MFT_STRING
, L
"Properties", MFS_DISABLED
);
1068 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
+ 3, MFT_STRING
, L
"Rename", MFS_DISABLED
);
1069 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
+ 2, MFT_STRING
, L
"Delete", MFS_DISABLED
);
1070 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
+ 1, MFT_STRING
, L
"Create Shortcut", MFS_DISABLED
);
1071 _InsertMenuItemW(hSubMenu
, 0, TRUE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1072 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
, MFT_STRING
, L
"New", MFS_ENABLED
);
1075 HMENU menubase
= BuildFileMenu();
1078 int count
= ::GetMenuItemCount(menubase
);
1079 int count2
= ::GetMenuItemCount(hSubMenu
);
1081 if (count2
> 0 && count
> 0)
1083 _InsertMenuItemW(hSubMenu
, 0, TRUE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1086 for (int i
= count
-1; i
>= 0; i
--)
1090 MENUITEMINFOW mii
= { 0 };
1091 mii
.cbSize
= sizeof(mii
);
1092 mii
.fMask
= MIIM_STATE
| MIIM_ID
| MIIM_SUBMENU
| MIIM_CHECKMARKS
| MIIM_DATA
| MIIM_STRING
| MIIM_BITMAP
| MIIM_FTYPE
;
1093 mii
.dwTypeData
= label
;
1094 mii
.cch
= _countof(label
);
1095 ::GetMenuItemInfoW(menubase
, i
, TRUE
, &mii
);
1097 TRACE("Adding item %d label %S type %d\n", mii
.wID
, mii
.dwTypeData
, mii
.fType
);
1099 mii
.fType
|= MFT_RADIOCHECK
;
1101 ::InsertMenuItemW(hSubMenu
, 0, TRUE
, &mii
);
1105 ::DestroyMenu(menubase
);
1110 void CDefView::PrepareShowViewMenu(HMENU hSubMenu
)
1112 TRACE("(%p)->(submenu=%p)\n", this, hSubMenu
);
1117 if (m_FolderSettings
.ViewMode
>= FVM_FIRST
&& m_FolderSettings
.ViewMode
<= FVM_LAST
)
1119 UINT iItemFirst
= FCIDM_SHVIEW_BIGICON
;
1120 UINT iItemLast
= iItemFirst
+ FVM_LAST
- FVM_FIRST
;
1121 UINT iItem
= iItemFirst
+ m_FolderSettings
.ViewMode
- FVM_FIRST
;
1122 CheckMenuRadioItem(hSubMenu
, iItemFirst
, iItemLast
, iItem
, MF_BYCOMMAND
);
1126 /**********************************************************
1127 * ShellView_GetSelections()
1129 * - fills the m_apidl list with the selected objects
1132 * number of selected items
1134 UINT
CDefView::GetSelections()
1138 m_cidl
= m_ListView
.GetSelectedCount();
1139 m_apidl
= static_cast<PCUITEMID_CHILD
*>(SHAlloc(m_cidl
* sizeof(PCUITEMID_CHILD
)));
1146 TRACE("-- Items selected =%u\n", m_cidl
);
1150 while ((lvIndex
= m_ListView
.GetNextItem(lvIndex
, LVNI_SELECTED
)) > -1)
1152 m_apidl
[i
] = _PidlByItem(lvIndex
);
1156 TRACE("-- selected Item found\n");
1162 HRESULT
CDefView::InvokeContextMenuCommand(UINT uCommand
)
1164 CMINVOKECOMMANDINFO cmi
;
1166 ZeroMemory(&cmi
, sizeof(cmi
));
1167 cmi
.cbSize
= sizeof(cmi
);
1168 cmi
.lpVerb
= MAKEINTRESOURCEA(uCommand
);
1171 if (GetKeyState(VK_SHIFT
) & 0x8000)
1172 cmi
.fMask
|= CMIC_MASK_SHIFT_DOWN
;
1174 if (GetKeyState(VK_CONTROL
) & 0x8000)
1175 cmi
.fMask
|= CMIC_MASK_CONTROL_DOWN
;
1177 return m_pCM
->InvokeCommand(&cmi
);
1180 /**********************************************************
1181 * ShellView_OpenSelectedItems()
1183 HRESULT
CDefView::OpenSelectedItems()
1189 m_cidl
= m_ListView
.GetSelectedCount();
1193 hResult
= OnDefaultCommand();
1194 if (hResult
== S_OK
)
1197 hMenu
= CreatePopupMenu();
1201 hResult
= GetItemObject(SVGIO_SELECTION
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1202 if (FAILED(hResult
))
1205 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, 0x20, 0x7fff, CMF_DEFAULTONLY
);
1206 if (FAILED(hResult
))
1209 uCommand
= GetMenuDefaultItem(hMenu
, FALSE
, 0);
1210 if (uCommand
== (UINT
)-1)
1216 InvokeContextMenuCommand(uCommand
);
1229 /**********************************************************
1230 * ShellView_DoContextMenu()
1232 LRESULT
CDefView::OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1240 // for some reason I haven't figured out, we sometimes recurse into this method
1247 TRACE("(%p)->(0x%08x 0x%08x) stub\n", this, x
, y
);
1249 hMenu
= CreatePopupMenu();
1253 m_cidl
= m_ListView
.GetSelectedCount();
1255 hResult
= GetItemObject( m_cidl
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1256 if (FAILED( hResult
))
1259 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1260 if (FAILED( hResult
))
1263 uCommand
= TrackPopupMenu(hMenu
,
1264 TPM_LEFTALIGN
| TPM_RETURNCMD
| TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
,
1265 x
, y
, 0, m_hWnd
, NULL
);
1269 if (uCommand
== FCIDM_SHVIEW_OPEN
&& OnDefaultCommand() == S_OK
)
1272 InvokeContextMenuCommand(uCommand
);
1284 LRESULT
CDefView::OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
)
1289 hMenu
= CreatePopupMenu();
1293 hResult
= GetItemObject( bUseSelection
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1294 if (FAILED( hResult
))
1297 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1298 if (FAILED( hResult
))
1301 InvokeContextMenuCommand(uCommand
);
1313 /**********************************************************
1314 * ##### message handling #####
1317 /**********************************************************
1318 * ShellView_OnSize()
1320 LRESULT
CDefView::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1325 wWidth
= LOWORD(lParam
);
1326 wHeight
= HIWORD(lParam
);
1328 TRACE("%p width=%u height=%u\n", this, wWidth
, wHeight
);
1330 /*resize the ListView to fit our window*/
1333 ::MoveWindow(m_ListView
, 0, 0, wWidth
, wHeight
, TRUE
);
1339 /**********************************************************
1340 * ShellView_OnDeactivate()
1345 void CDefView::OnDeactivate()
1347 TRACE("%p\n", this);
1349 if (m_uState
!= SVUIA_DEACTIVATE
)
1351 // TODO: cleanup menu after deactivation
1353 m_uState
= SVUIA_DEACTIVATE
;
1357 void CDefView::DoActivate(UINT uState
)
1359 TRACE("%p uState=%x\n", this, uState
);
1361 /*don't do anything if the state isn't really changing */
1362 if (m_uState
== uState
)
1367 if (uState
== SVUIA_DEACTIVATE
)
1377 MENUITEMINFOW mii
= { 0 };
1379 /* initialize EDIT menu */
1380 mii
.cbSize
= sizeof(mii
);
1381 mii
.fMask
= MIIM_SUBMENU
;
1382 if (::GetMenuItemInfoW(m_hMenu
, FCIDM_MENU_EDIT
, FALSE
, &mii
))
1384 HMENU hSubMenu
= mii
.hSubMenu
;
1386 HMENU menubase
= ::LoadMenuW(shell32_hInstance
, L
"MENU_003");
1388 int count
= ::GetMenuItemCount(menubase
);
1389 for (int i
= 0; i
< count
; i
++)
1393 ZeroMemory(&mii
, sizeof(mii
));
1394 mii
.cbSize
= sizeof(mii
);
1395 mii
.fMask
= MIIM_STATE
| MIIM_ID
| MIIM_SUBMENU
| MIIM_CHECKMARKS
| MIIM_DATA
| MIIM_STRING
| MIIM_BITMAP
| MIIM_FTYPE
;
1396 mii
.dwTypeData
= label
;
1397 mii
.cch
= _countof(label
);
1398 ::GetMenuItemInfoW(menubase
, i
, TRUE
, &mii
);
1400 TRACE("Adding item %d label %S type %d\n", mii
.wID
, mii
.dwTypeData
, mii
.fType
);
1402 mii
.fType
|= MFT_RADIOCHECK
;
1404 ::InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, &mii
);
1407 ::DestroyMenu(menubase
);
1410 /* initialize VIEW menu */
1412 mii
.cbSize
= sizeof(mii
);
1413 mii
.fMask
= MIIM_SUBMENU
;
1414 if (::GetMenuItemInfoW(m_hMenu
, FCIDM_MENU_VIEW
, FALSE
, &mii
))
1416 HMENU menubase
= ::LoadMenuW(shell32_hInstance
, L
"MENU_001");
1418 HMENU hSubMenu
= mii
.hSubMenu
;
1420 m_hView
= CreatePopupMenu();
1422 _InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1424 int count
= ::GetMenuItemCount(menubase
);
1425 for (int i
= 0; i
< count
; i
++)
1429 ZeroMemory(&mii
, sizeof(mii
));
1430 mii
.cbSize
= sizeof(mii
);
1431 mii
.fMask
= MIIM_STATE
| MIIM_ID
| MIIM_SUBMENU
| MIIM_CHECKMARKS
| MIIM_DATA
| MIIM_STRING
| MIIM_BITMAP
| MIIM_FTYPE
;
1432 mii
.dwTypeData
= label
;
1433 mii
.cch
= _countof(label
);
1434 ::GetMenuItemInfoW(menubase
, i
, TRUE
, &mii
);
1436 ::AppendMenuW(m_hView
, mii
.fType
, mii
.wID
, mii
.dwTypeData
);
1438 TRACE("Adding item %d label %S type %d\n", mii
.wID
, mii
.dwTypeData
, mii
.fType
);
1440 mii
.fType
|= MFT_RADIOCHECK
;
1442 ::InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, &mii
);
1445 ::DestroyMenu(menubase
);
1449 TRACE("-- before fnSetMenuSB\n");
1450 m_pShellBrowser
->SetMenuSB(m_hMenu
, 0, m_hWnd
);
1452 m_menusLoaded
= TRUE
;
1456 if (SVUIA_ACTIVATE_FOCUS
== uState
)
1458 m_ListView
.SetFocus();
1466 /**********************************************************
1467 * ShellView_OnActivate()
1469 LRESULT
CDefView::OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1471 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1475 /**********************************************************
1476 * ShellView_OnSetFocus()
1479 LRESULT
CDefView::OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1481 TRACE("%p\n", this);
1483 /* Tell the browser one of our windows has received the focus. This
1484 should always be done before merging menus (OnActivate merges the
1485 menus) if one of our windows has the focus.*/
1487 m_pShellBrowser
->OnViewWindowActive(this);
1488 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1490 /* Set the focus to the listview */
1491 m_ListView
.SetFocus();
1493 /* Notify the ICommDlgBrowser interface */
1494 OnStateChange(CDBOSC_SETFOCUS
);
1499 /**********************************************************
1500 * ShellView_OnKillFocus()
1502 LRESULT
CDefView::OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1504 TRACE("(%p) stub\n", this);
1506 DoActivate(SVUIA_ACTIVATE_NOFOCUS
);
1507 /* Notify the ICommDlgBrowser */
1508 OnStateChange(CDBOSC_KILLFOCUS
);
1513 /**********************************************************
1514 * ShellView_OnCommand()
1517 * the CmdID's are the ones from the context menu
1519 LRESULT
CDefView::OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1526 dwCmdID
= GET_WM_COMMAND_ID(wParam
, lParam
);
1527 dwCmd
= GET_WM_COMMAND_CMD(wParam
, lParam
);
1528 hwndCmd
= GET_WM_COMMAND_HWND(wParam
, lParam
);
1530 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n", this, dwCmdID
, dwCmd
, hwndCmd
);
1534 case FCIDM_SHVIEW_SMALLICON
:
1535 m_FolderSettings
.ViewMode
= FVM_SMALLICON
;
1536 SetStyle (LVS_SMALLICON
, LVS_TYPEMASK
);
1540 case FCIDM_SHVIEW_BIGICON
:
1541 m_FolderSettings
.ViewMode
= FVM_ICON
;
1542 SetStyle (LVS_ICON
, LVS_TYPEMASK
);
1546 case FCIDM_SHVIEW_LISTVIEW
:
1547 m_FolderSettings
.ViewMode
= FVM_LIST
;
1548 SetStyle (LVS_LIST
, LVS_TYPEMASK
);
1552 case FCIDM_SHVIEW_REPORTVIEW
:
1553 m_FolderSettings
.ViewMode
= FVM_DETAILS
;
1554 SetStyle (LVS_REPORT
, LVS_TYPEMASK
);
1558 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1563 m_sortInfo
.nHeaderID
= dwCmdID
- 0x30;
1564 m_sortInfo
.bIsAscending
= TRUE
;
1565 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
1566 m_ListView
.SortItems(ListViewCompareItems
, this);
1569 case FCIDM_SHVIEW_SELECTALL
:
1570 m_ListView
.SetItemState(-1, LVIS_SELECTED
, LVIS_SELECTED
);
1573 case FCIDM_SHVIEW_INVERTSELECTION
:
1574 nCount
= m_ListView
.GetItemCount();
1575 for (int i
=0; i
< nCount
; i
++)
1576 m_ListView
.SetItemState(i
, m_ListView
.GetItemState(i
, LVIS_SELECTED
) ? 0 : LVIS_SELECTED
, LVIS_SELECTED
);
1579 case FCIDM_SHVIEW_REFRESH
:
1583 case FCIDM_SHVIEW_DELETE
:
1584 case FCIDM_SHVIEW_CUT
:
1585 case FCIDM_SHVIEW_COPY
:
1586 case FCIDM_SHVIEW_RENAME
:
1587 return OnExplorerCommand(dwCmdID
, TRUE
);
1589 case FCIDM_SHVIEW_INSERT
:
1590 case FCIDM_SHVIEW_UNDO
:
1591 case FCIDM_SHVIEW_INSERTLINK
:
1592 case FCIDM_SHVIEW_NEWFOLDER
:
1593 return OnExplorerCommand(dwCmdID
, FALSE
);
1595 TRACE("-- COMMAND 0x%04x unhandled\n", dwCmdID
);
1601 /**********************************************************
1602 * ShellView_OnNotify()
1605 LRESULT
CDefView::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1609 LPNMLISTVIEW lpnmlv
;
1610 NMLVDISPINFOW
*lpdi
;
1611 PCUITEMID_CHILD pidl
;
1615 lpnmh
= (LPNMHDR
)lParam
;
1616 lpnmlv
= (LPNMLISTVIEW
)lpnmh
;
1617 lpdi
= (NMLVDISPINFOW
*)lpnmh
;
1619 TRACE("%p CtlID=%u lpnmh->code=%x\n", this, CtlID
, lpnmh
->code
);
1621 switch (lpnmh
->code
)
1624 TRACE("-- NM_SETFOCUS %p\n", this);
1625 OnSetFocus(0, 0, 0, unused
);
1629 TRACE("-- NM_KILLFOCUS %p\n", this);
1631 /* Notify the ICommDlgBrowser interface */
1632 OnStateChange(CDBOSC_KILLFOCUS
);
1636 TRACE("-- NM_CUSTOMDRAW %p\n", this);
1637 return CDRF_DODEFAULT
;
1639 case NM_RELEASEDCAPTURE
:
1640 TRACE("-- NM_RELEASEDCAPTURE %p\n", this);
1644 TRACE("-- NM_CLICK %p\n", this);
1648 TRACE("-- NM_RCLICK %p\n", this);
1652 TRACE("-- NM_DBLCLK %p\n", this);
1653 OpenSelectedItems();
1657 TRACE("-- NM_RETURN %p\n", this);
1658 OpenSelectedItems();
1662 TRACE("-- HDN_ENDTRACKW %p\n", this);
1663 /*nColumn1 = m_ListView.GetColumnWidth(0);
1664 nColumn2 = m_ListView.GetColumnWidth(1);*/
1667 case LVN_DELETEITEM
:
1668 TRACE("-- LVN_DELETEITEM %p\n", this);
1670 /*delete the pidl because we made a copy of it*/
1671 SHFree(reinterpret_cast<LPVOID
>(lpnmlv
->lParam
));
1675 case LVN_DELETEALLITEMS
:
1676 TRACE("-- LVN_DELETEALLITEMS %p\n", this);
1679 case LVN_INSERTITEM
:
1680 TRACE("-- LVN_INSERTITEM (STUB)%p\n", this);
1683 case LVN_ITEMACTIVATE
:
1684 TRACE("-- LVN_ITEMACTIVATE %p\n", this);
1685 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1688 case LVN_COLUMNCLICK
:
1689 m_sortInfo
.nHeaderID
= lpnmlv
->iSubItem
;
1690 if (m_sortInfo
.nLastHeaderID
== m_sortInfo
.nHeaderID
)
1691 m_sortInfo
.bIsAscending
= !m_sortInfo
.bIsAscending
;
1693 m_sortInfo
.bIsAscending
= TRUE
;
1694 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
1696 m_ListView
.SortItems(ListViewCompareItems
, this);
1699 case LVN_GETDISPINFOA
:
1700 case LVN_GETDISPINFOW
:
1701 TRACE("-- LVN_GETDISPINFO %p\n", this);
1702 pidl
= _PidlByItem(lpdi
->item
);
1704 if (lpdi
->item
.mask
& LVIF_TEXT
) /* text requested */
1709 if (FAILED(m_pSF2Parent
->GetDetailsOf(pidl
, lpdi
->item
.iSubItem
, &sd
)))
1711 FIXME("failed to get details\n");
1715 if (lpnmh
->code
== LVN_GETDISPINFOA
)
1717 /* shouldn't happen */
1718 NMLVDISPINFOA
*lpdiA
= (NMLVDISPINFOA
*)lpnmh
;
1719 StrRetToStrNA( lpdiA
->item
.pszText
, lpdiA
->item
.cchTextMax
, &sd
.str
, NULL
);
1720 TRACE("-- text=%s\n", lpdiA
->item
.pszText
);
1722 else /* LVN_GETDISPINFOW */
1724 StrRetToStrNW( lpdi
->item
.pszText
, lpdi
->item
.cchTextMax
, &sd
.str
, NULL
);
1725 TRACE("-- text=%s\n", debugstr_w(lpdi
->item
.pszText
));
1733 if(lpdi
->item
.mask
& LVIF_IMAGE
) /* image requested */
1735 lpdi
->item
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
1737 if(lpdi
->item
.mask
& LVIF_STATE
)
1739 ULONG attributes
= SFGAO_HIDDEN
;
1740 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(1, &pidl
, &attributes
)))
1742 if (attributes
& SFGAO_HIDDEN
)
1744 lpdi
->item
.state
|= LVIS_CUT
;
1748 lpdi
->item
.mask
|= LVIF_DI_SETITEM
;
1751 case LVN_ITEMCHANGED
:
1752 TRACE("-- LVN_ITEMCHANGED %p\n", this);
1753 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1758 case LVN_BEGINRDRAG
:
1759 TRACE("-- LVN_BEGINDRAG\n");
1761 if (GetSelections())
1763 CComPtr
<IDataObject
> pda
;
1764 DWORD dwAttributes
= SFGAO_CANLINK
;
1765 DWORD dwEffect
= DROPEFFECT_COPY
| DROPEFFECT_MOVE
;
1767 if (SUCCEEDED(m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, IID_NULL_PPV_ARG(IDataObject
, &pda
))))
1769 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(m_cidl
, m_apidl
, &dwAttributes
)))
1771 if (dwAttributes
& SFGAO_CANLINK
)
1773 dwEffect
|= DROPEFFECT_LINK
;
1777 CComPtr
<IAsyncOperation
> piaso
;
1778 if (SUCCEEDED(pda
->QueryInterface(IID_PPV_ARG(IAsyncOperation
, &piaso
))))
1780 piaso
->SetAsyncMode(TRUE
);
1784 DoDragDrop(pda
, this, dwEffect
, &dwEffect2
);
1789 case LVN_BEGINLABELEDITW
:
1791 DWORD dwAttr
= SFGAO_CANRENAME
;
1792 pidl
= _PidlByItem(lpdi
->item
);
1794 TRACE("-- LVN_BEGINLABELEDITW %p\n", this);
1796 m_pSFParent
->GetAttributesOf(1, &pidl
, &dwAttr
);
1797 if (SFGAO_CANRENAME
& dwAttr
)
1805 case LVN_ENDLABELEDITW
:
1807 TRACE("-- LVN_ENDLABELEDITW %p\n", this);
1809 m_isEditing
= FALSE
;
1811 if (lpdi
->item
.pszText
)
1816 pidl
= _PidlByItem(lpdi
->item
);
1817 PITEMID_CHILD pidlNew
;
1818 hr
= m_pSFParent
->SetNameOf(0, pidl
, lpdi
->item
.pszText
, SHGDN_INFOLDER
, &pidlNew
);
1820 if (SUCCEEDED(hr
) && pidlNew
)
1822 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
1823 lvItem
.iItem
= lpdi
->item
.iItem
;
1824 lvItem
.iSubItem
= 0;
1825 lvItem
.lParam
= reinterpret_cast<LPARAM
>(pidlNew
);
1826 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
1827 m_ListView
.SetItem(&lvItem
);
1828 m_ListView
.Update(lpdi
->item
.iItem
);
1837 TRACE("-- %p WM_COMMAND %x unhandled\n", this, lpnmh
->code
);
1845 * This is just a quick hack to make the desktop work correctly.
1846 * ITranslateShellChangeNotify's IsChildID is undocumented, but most likely the way that
1847 * a folder should know if it should update upon a change notification.
1848 * It is exported by merged folders at a minimum.
1850 static BOOL
ILIsParentOrSpecialParent(PCIDLIST_ABSOLUTE pidl1
, PCIDLIST_ABSOLUTE pidl2
)
1852 if (!pidl1
|| !pidl2
)
1854 if (ILIsParent(pidl1
, pidl2
, TRUE
))
1857 if (_ILIsDesktop(pidl1
))
1859 PIDLIST_ABSOLUTE deskpidl
;
1860 SHGetFolderLocation(NULL
, CSIDL_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
1861 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
1867 SHGetFolderLocation(NULL
, CSIDL_COMMON_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
1868 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
1878 /**********************************************************
1879 * ShellView_OnChange()
1881 LRESULT
CDefView::OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1883 PCIDLIST_ABSOLUTE
*Pidls
= reinterpret_cast<PCIDLIST_ABSOLUTE
*>(wParam
);
1884 BOOL bParent0
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[0]);
1885 BOOL bParent1
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[1]);
1887 TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls
[0], Pidls
[1], lParam
);
1889 switch (lParam
&~ SHCNE_INTERRUPT
)
1895 if (LV_FindItemByPidl(ILFindLastID(Pidls
[0])) == -1)
1897 LV_AddItem(ILFindLastID(Pidls
[0]));
1901 LV_ProdItem(ILFindLastID(Pidls
[0]));
1909 LV_DeleteItem(ILFindLastID(Pidls
[0]));
1912 case SHCNE_RENAMEFOLDER
:
1913 case SHCNE_RENAMEITEM
:
1914 if (bParent0
&& bParent1
)
1915 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[1]));
1917 LV_DeleteItem(ILFindLastID(Pidls
[0]));
1919 LV_AddItem(ILFindLastID(Pidls
[1]));
1922 case SHCNE_UPDATEITEM
:
1924 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[0]));
1927 case SHCNE_UPDATEDIR
:
1934 /**********************************************************
1935 * CDefView::OnCustomItem
1937 LRESULT
CDefView::OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1942 ERR("no menu!!!\n");
1947 HRESULT hres
= SHForwardContextMenuMsg(m_pCM
, uMsg
, wParam
, lParam
, &result
, TRUE
);
1948 if (SUCCEEDED(hres
))
1954 LRESULT
CDefView::OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1956 /* Wallpaper setting affects drop shadows effect */
1957 if (wParam
== SPI_SETDESKWALLPAPER
|| wParam
== 0)
1963 /**********************************************************
1964 * CDefView::OnInitMenuPopup
1966 LRESULT
CDefView::OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1968 MENUITEMINFOW mii
= { 0 };
1969 HMENU hSubmenu
= (HMENU
) wParam
;
1971 TRACE("OnInitMenuPopup lParam=%d\n", lParam
);
1973 mii
.cbSize
= sizeof(mii
);
1974 mii
.fMask
= MIIM_ID
| MIIM_SUBMENU
;
1976 if (!GetMenuItemInfoW(this->m_hMenu
, lParam
, TRUE
, &mii
))
1978 TRACE("OnInitMenuPopup GetMenuItemInfoW failed!\n");
1982 UINT menuItemId
= mii
.wID
;
1984 if (mii
.hSubMenu
!= hSubmenu
)
1986 TRACE("OnInitMenuPopup submenu does not match!!!!\n");
1990 TRACE("OnInitMenuPopup id=%d\n", menuItemId
);
1994 case FCIDM_MENU_FILE
:
1995 PrepareShowFileMenu(hSubmenu
);
1997 case FCIDM_MENU_EDIT
:
1998 //PrepareShowEditMenu(hSubmenu);
2000 case FCIDM_MENU_VIEW
:
2001 PrepareShowViewMenu(hSubmenu
);
2008 /**********************************************************
2011 * The INTERFACE of the IShellView object
2014 **********************************************************
2017 /**********************************************************
2018 * ShellView_GetWindow
2020 HRESULT WINAPI
CDefView::GetWindow(HWND
*phWnd
)
2022 TRACE("(%p)\n", this);
2029 HRESULT WINAPI
CDefView::ContextSensitiveHelp(BOOL fEnterMode
)
2031 FIXME("(%p) stub\n", this);
2036 /**********************************************************
2037 * IShellView_TranslateAccelerator
2040 * use the accel functions
2042 HRESULT WINAPI
CDefView::TranslateAccelerator(LPMSG lpmsg
)
2047 if (lpmsg
->message
>= WM_KEYFIRST
&& lpmsg
->message
<= WM_KEYLAST
)
2049 if (::TranslateAcceleratorW(m_hWnd
, m_hAccel
, lpmsg
) != 0)
2052 TRACE("-- key=0x04%lx\n", lpmsg
->wParam
) ;
2055 return m_pShellBrowser
->TranslateAcceleratorSB(lpmsg
, 0);
2058 HRESULT WINAPI
CDefView::EnableModeless(BOOL fEnable
)
2060 FIXME("(%p) stub\n", this);
2065 HRESULT WINAPI
CDefView::UIActivate(UINT uState
)
2068 CHAR szName[MAX_PATH];
2071 int nPartArray
[1] = { -1};
2073 TRACE("(%p)->(state=%x) stub\n", this, uState
);
2075 /*don't do anything if the state isn't really changing*/
2076 if (m_uState
== uState
)
2081 /*OnActivate handles the menu merging and internal state*/
2084 /*only do This if we are active*/
2085 if (uState
!= SVUIA_DEACTIVATE
)
2089 GetFolderPath is not a method of IShellFolder
2090 IShellFolder_GetFolderPath( m_pSFParent, szName, sizeof(szName) );
2092 /* set the number of parts */
2093 m_pShellBrowser
->SendControlMsg(FCW_STATUS
, SB_SETPARTS
, 1, (LPARAM
)nPartArray
, &lResult
);
2095 /* set the text for the parts */
2097 m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXTA, 0, (LPARAM)szName, &lResult);
2104 HRESULT WINAPI
CDefView::Refresh()
2106 TRACE("(%p)\n", this);
2108 m_ListView
.DeleteAllItems();
2114 HRESULT WINAPI
CDefView::CreateViewWindow(IShellView
*lpPrevView
, LPCFOLDERSETTINGS lpfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
)
2116 OLEMENUGROUPWIDTHS omw
= { { 0, 0, 0, 0, 0, 0 } };
2120 TRACE("(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n", this, lpPrevView
, lpfs
, psb
, prcView
, phWnd
);
2123 TRACE("-- vmode=%x flags=%x\n", lpfs
->ViewMode
, lpfs
->fFlags
);
2124 if (prcView
!= NULL
)
2125 TRACE("-- left=%i top=%i right=%i bottom=%i\n", prcView
->left
, prcView
->top
, prcView
->right
, prcView
->bottom
);
2127 /* Validate the Shell Browser */
2128 if (psb
== NULL
|| m_hWnd
)
2129 return E_UNEXPECTED
;
2131 /*set up the member variables*/
2132 m_pShellBrowser
= psb
;
2133 m_FolderSettings
= *lpfs
;
2135 /*get our parent window*/
2136 m_pShellBrowser
->GetWindow(&m_hWndParent
);
2138 /* try to get the ICommDlgBrowserInterface, adds a reference !!! */
2139 m_pCommDlgBrowser
= NULL
;
2140 if (SUCCEEDED(m_pShellBrowser
->QueryInterface(IID_PPV_ARG(ICommDlgBrowser
, &m_pCommDlgBrowser
))))
2142 TRACE("-- CommDlgBrowser\n");
2145 Create(m_hWndParent
, prcView
, NULL
, WS_CHILD
| WS_TABSTOP
, 0, 0U);
2156 SetWindowPos(HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_SHOWWINDOW
);
2161 m_hMenu
= CreateMenu();
2162 m_pShellBrowser
->InsertMenusSB(m_hMenu
, &omw
);
2163 TRACE("-- after fnInsertMenusSB\n");
2171 HRESULT WINAPI
CDefView::DestroyViewWindow()
2173 TRACE("(%p)\n", this);
2175 /*Make absolutely sure all our UI is cleaned up.*/
2176 UIActivate(SVUIA_DEACTIVATE
);
2180 // "Accelerator tables loaded from resources are freed automatically when the application terminates." -- MSDN
2186 DestroyMenu(m_hView
);
2192 DestroyMenu(m_hMenu
);
2198 m_ListView
.DestroyWindow();
2206 m_pShellBrowser
.Release();
2207 m_pCommDlgBrowser
.Release();
2212 HRESULT WINAPI
CDefView::GetCurrentInfo(LPFOLDERSETTINGS lpfs
)
2214 TRACE("(%p)->(%p) vmode=%x flags=%x\n", this, lpfs
,
2215 m_FolderSettings
.ViewMode
, m_FolderSettings
.fFlags
);
2218 return E_INVALIDARG
;
2220 *lpfs
= m_FolderSettings
;
2224 HRESULT WINAPI
CDefView::AddPropertySheetPages(DWORD dwReserved
, LPFNADDPROPSHEETPAGE lpfn
, LPARAM lparam
)
2226 FIXME("(%p) stub\n", this);
2231 HRESULT WINAPI
CDefView::SaveViewState()
2233 FIXME("(%p) stub\n", this);
2238 HRESULT WINAPI
CDefView::SelectItem(PCUITEMID_CHILD pidl
, UINT uFlags
)
2242 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n", this, pidl
, uFlags
);
2244 i
= LV_FindItemByPidl(pidl
);
2248 if(uFlags
& SVSI_ENSUREVISIBLE
)
2249 m_ListView
.EnsureVisible(i
, FALSE
);
2251 LVITEMW lvItem
= {0};
2252 lvItem
.mask
= LVIF_STATE
;
2253 lvItem
.stateMask
= LVIS_SELECTED
| LVIS_FOCUSED
;
2255 while (m_ListView
.GetItem(&lvItem
))
2257 if (lvItem
.iItem
== i
)
2259 if (uFlags
& SVSI_SELECT
)
2260 lvItem
.state
|= LVIS_SELECTED
;
2262 lvItem
.state
&= ~LVIS_SELECTED
;
2264 if (uFlags
& SVSI_FOCUSED
)
2265 lvItem
.state
&= ~LVIS_FOCUSED
;
2269 if (uFlags
& SVSI_DESELECTOTHERS
)
2270 lvItem
.state
&= ~LVIS_SELECTED
;
2273 m_ListView
.SetItem(&lvItem
);
2277 if(uFlags
& SVSI_EDIT
)
2278 m_ListView
.EditLabel(i
);
2283 HRESULT WINAPI
CDefView::GetItemObject(UINT uItem
, REFIID riid
, LPVOID
*ppvOut
)
2285 HRESULT hr
= E_NOINTERFACE
;
2287 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n", this, uItem
, debugstr_guid(&riid
), ppvOut
);
2293 case SVGIO_BACKGROUND
:
2294 if (IsEqualIID(riid
, IID_IContextMenu
))
2296 //*ppvOut = ISvBgCm_Constructor(m_pSFParent, FALSE);
2301 hr
= CDefFolderMenu_Create2(NULL
, NULL
, 0, NULL
, m_pSFParent
, NULL
, 0, NULL
, &pcm
);
2306 else if (IsEqualIID(riid
, IID_IDispatch
))
2308 if (m_pShellFolderViewDual
== NULL
)
2309 hr
= CDefViewDual_Constructor(riid
, (LPVOID
*)&m_pShellFolderViewDual
);
2310 hr
= m_pShellFolderViewDual
->QueryInterface(riid
, ppvOut
);
2314 case SVGIO_SELECTION
:
2316 hr
= m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, riid
, 0, ppvOut
);
2320 TRACE("-- (%p)->(interface=%p)\n", this, *ppvOut
);
2325 HRESULT STDMETHODCALLTYPE
CDefView::GetCurrentViewMode(UINT
*pViewMode
)
2327 TRACE("(%p)->(%p), stub\n", this, pViewMode
);
2330 return E_INVALIDARG
;
2332 *pViewMode
= m_FolderSettings
.ViewMode
;
2336 HRESULT STDMETHODCALLTYPE
CDefView::SetCurrentViewMode(UINT ViewMode
)
2339 TRACE("(%p)->(%u), stub\n", this, ViewMode
);
2341 /* It's not redundant to check FVM_AUTO because it's a (UINT)-1 */
2342 if (((INT
)ViewMode
< FVM_FIRST
|| (INT
)ViewMode
> FVM_LAST
) && ((INT
)ViewMode
!= FVM_AUTO
))
2343 return E_INVALIDARG
;
2345 /* Windows before Vista uses LVM_SETVIEW and possibly
2346 LVM_SETEXTENDEDLISTVIEWSTYLE to set the style of the listview,
2347 while later versions seem to accomplish this through other
2355 dwStyle
= LVS_REPORT
;
2358 dwStyle
= LVS_SMALLICON
;
2365 FIXME("ViewMode %d not implemented\n", ViewMode
);
2371 SetStyle(dwStyle
, LVS_TYPEMASK
);
2373 /* This will not necessarily be the actual mode set above.
2374 This mimics the behavior of Windows XP. */
2375 m_FolderSettings
.ViewMode
= ViewMode
;
2380 HRESULT STDMETHODCALLTYPE
CDefView::GetFolder(REFIID riid
, void **ppv
)
2382 if (m_pSFParent
== NULL
)
2385 return m_pSFParent
->QueryInterface(riid
, ppv
);
2388 HRESULT STDMETHODCALLTYPE
CDefView::Item(int iItemIndex
, PITEMID_CHILD
*ppidl
)
2390 PCUITEMID_CHILD pidl
= _PidlByItem(iItemIndex
);
2393 *ppidl
= ILClone(pidl
);
2398 return E_INVALIDARG
;
2401 HRESULT STDMETHODCALLTYPE
CDefView::ItemCount(UINT uFlags
, int *pcItems
)
2403 TRACE("(%p)->(%u %p)\n", this, uFlags
, pcItems
);
2405 if (uFlags
!= SVGIO_ALLVIEW
)
2406 FIXME("some flags unsupported, %x\n", uFlags
& ~SVGIO_ALLVIEW
);
2408 *pcItems
= m_ListView
.GetItemCount();
2413 HRESULT STDMETHODCALLTYPE
CDefView::Items(UINT uFlags
, REFIID riid
, void **ppv
)
2418 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectionMarkedItem(int *piItem
)
2420 TRACE("(%p)->(%p)\n", this, piItem
);
2422 *piItem
= m_ListView
.GetSelectionMark();
2427 HRESULT STDMETHODCALLTYPE
CDefView::GetFocusedItem(int *piItem
)
2429 TRACE("(%p)->(%p)\n", this, piItem
);
2431 *piItem
= m_ListView
.GetNextItem(-1, LVNI_FOCUSED
);
2436 HRESULT STDMETHODCALLTYPE
CDefView::GetItemPosition(PCUITEMID_CHILD pidl
, POINT
*ppt
)
2441 HRESULT STDMETHODCALLTYPE
CDefView::GetSpacing(POINT
*ppt
)
2443 TRACE("(%p)->(%p)\n", this, ppt
);
2451 m_ListView
.GetItemSpacing(spacing
);
2453 ppt
->x
= spacing
.cx
;
2454 ppt
->y
= spacing
.cy
;
2460 HRESULT STDMETHODCALLTYPE
CDefView::GetDefaultSpacing(POINT
*ppt
)
2465 HRESULT STDMETHODCALLTYPE
CDefView::GetAutoArrange()
2470 HRESULT STDMETHODCALLTYPE
CDefView::SelectItem(int iItem
, DWORD dwFlags
)
2474 TRACE("(%p)->(%d, %x)\n", this, iItem
, dwFlags
);
2477 lvItem
.stateMask
= LVIS_SELECTED
;
2479 if (dwFlags
& SVSI_ENSUREVISIBLE
)
2480 m_ListView
.EnsureVisible(iItem
, 0);
2483 if (dwFlags
& SVSI_DESELECTOTHERS
)
2484 m_ListView
.SetItemState(-1, 0, LVIS_SELECTED
);
2487 if (dwFlags
& SVSI_SELECT
)
2488 lvItem
.state
|= LVIS_SELECTED
;
2490 if (dwFlags
& SVSI_FOCUSED
)
2491 lvItem
.stateMask
|= LVIS_FOCUSED
;
2493 m_ListView
.SetItemState(iItem
, lvItem
.state
, lvItem
.stateMask
);
2495 if (dwFlags
& SVSI_EDIT
)
2496 m_ListView
.EditLabel(iItem
);
2501 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItems(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD dwFlags
)
2506 /**********************************************************
2507 * IShellView2 implementation
2510 HRESULT STDMETHODCALLTYPE
CDefView::GetView(SHELLVIEWID
*view_guid
, ULONG view_type
)
2512 FIXME("(%p)->(%p, %lu) stub\n", this, view_guid
, view_type
);
2516 HRESULT STDMETHODCALLTYPE
CDefView::CreateViewWindow2(LPSV2CVW2_PARAMS view_params
)
2518 FIXME("(%p)->(%p) stub\n", this, view_params
);
2522 HRESULT STDMETHODCALLTYPE
CDefView::HandleRename(LPCITEMIDLIST new_pidl
)
2524 FIXME("(%p)->(%p) stub\n", this, new_pidl
);
2528 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItem(LPCITEMIDLIST item
, UINT flags
, POINT
*point
)
2530 FIXME("(%p)->(%p, %u, %p) stub\n", this, item
, flags
, point
);
2534 /**********************************************************
2535 * IShellFolderView implementation
2537 HRESULT STDMETHODCALLTYPE
CDefView::Rearrange(LPARAM sort
)
2539 FIXME("(%p)->(%ld) stub\n", this, sort
);
2543 HRESULT STDMETHODCALLTYPE
CDefView::GetArrangeParam(LPARAM
*sort
)
2545 FIXME("(%p)->(%p) stub\n", this, sort
);
2549 HRESULT STDMETHODCALLTYPE
CDefView::ArrangeGrid()
2551 FIXME("(%p) stub\n", this);
2555 HRESULT STDMETHODCALLTYPE
CDefView::AutoArrange()
2557 FIXME("(%p) stub\n", this);
2561 HRESULT STDMETHODCALLTYPE
CDefView::AddObject(PITEMID_CHILD pidl
, UINT
*item
)
2563 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2567 HRESULT STDMETHODCALLTYPE
CDefView::GetObject(PITEMID_CHILD
*pidl
, UINT item
)
2569 TRACE("(%p)->(%p %d)\n", this, pidl
, item
);
2570 return Item(item
, pidl
);
2573 HRESULT STDMETHODCALLTYPE
CDefView::RemoveObject(PITEMID_CHILD pidl
, UINT
*item
)
2576 TRACE("(%p)->(%p %p)\n", this, pidl
, item
);
2580 *item
= LV_FindItemByPidl(ILFindLastID(pidl
));
2581 m_ListView
.DeleteItem(*item
);
2586 m_ListView
.DeleteAllItems();
2592 HRESULT STDMETHODCALLTYPE
CDefView::GetObjectCount(UINT
*count
)
2594 TRACE("(%p)->(%p)\n", this, count
);
2595 *count
= m_ListView
.GetItemCount();
2599 HRESULT STDMETHODCALLTYPE
CDefView::SetObjectCount(UINT count
, UINT flags
)
2601 FIXME("(%p)->(%d %x) stub\n", this, count
, flags
);
2605 HRESULT STDMETHODCALLTYPE
CDefView::UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
)
2607 FIXME("(%p)->(%p %p %p) stub\n", this, pidl_old
, pidl_new
, item
);
2611 HRESULT STDMETHODCALLTYPE
CDefView::RefreshObject(PITEMID_CHILD pidl
, UINT
*item
)
2613 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2617 HRESULT STDMETHODCALLTYPE
CDefView::SetRedraw(BOOL redraw
)
2619 TRACE("(%p)->(%d)\n", this, redraw
);
2620 m_ListView
.SetRedraw(redraw
);
2624 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedCount(UINT
*count
)
2626 FIXME("(%p)->(%p) stub\n", this, count
);
2630 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
)
2632 TRACE("(%p)->(%p %p)\n", this, pidl
, items
);
2634 *items
= GetSelections();
2638 *pidl
= static_cast<PCUITEMID_CHILD
*>(LocalAlloc(0, *items
* sizeof(PCUITEMID_CHILD
)));
2641 return E_OUTOFMEMORY
;
2644 /* it's documented that caller shouldn't PIDLs, only array itself */
2645 memcpy(*pidl
, m_apidl
, *items
* sizeof(PCUITEMID_CHILD
));
2651 HRESULT STDMETHODCALLTYPE
CDefView::IsDropOnSource(IDropTarget
*drop_target
)
2653 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2657 HRESULT STDMETHODCALLTYPE
CDefView::GetDragPoint(POINT
*pt
)
2659 FIXME("(%p)->(%p) stub\n", this, pt
);
2663 HRESULT STDMETHODCALLTYPE
CDefView::GetDropPoint(POINT
*pt
)
2665 FIXME("(%p)->(%p) stub\n", this, pt
);
2669 HRESULT STDMETHODCALLTYPE
CDefView::MoveIcons(IDataObject
*obj
)
2671 TRACE("(%p)->(%p)\n", this, obj
);
2675 HRESULT STDMETHODCALLTYPE
CDefView::SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
)
2677 FIXME("(%p)->(%p %p) stub\n", this, pidl
, pt
);
2681 HRESULT STDMETHODCALLTYPE
CDefView::IsBkDropTarget(IDropTarget
*drop_target
)
2683 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2687 HRESULT STDMETHODCALLTYPE
CDefView::SetClipboard(BOOL move
)
2689 FIXME("(%p)->(%d) stub\n", this, move
);
2693 HRESULT STDMETHODCALLTYPE
CDefView::SetPoints(IDataObject
*obj
)
2695 FIXME("(%p)->(%p) stub\n", this, obj
);
2699 HRESULT STDMETHODCALLTYPE
CDefView::GetItemSpacing(ITEMSPACING
*spacing
)
2701 FIXME("(%p)->(%p) stub\n", this, spacing
);
2705 HRESULT STDMETHODCALLTYPE
CDefView::SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
)
2707 FIXME("(%p)->(%p %p) stub\n", this, new_cb
, old_cb
);
2711 HRESULT STDMETHODCALLTYPE
CDefView::Select(UINT flags
)
2713 FIXME("(%p)->(%d) stub\n", this, flags
);
2717 HRESULT STDMETHODCALLTYPE
CDefView::QuerySupport(UINT
*support
)
2719 TRACE("(%p)->(%p)\n", this, support
);
2723 HRESULT STDMETHODCALLTYPE
CDefView::SetAutomationObject(IDispatch
*disp
)
2725 FIXME("(%p)->(%p) stub\n", this, disp
);
2729 /**********************************************************
2730 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2732 HRESULT WINAPI
CDefView::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD
*prgCmds
, OLECMDTEXT
*pCmdText
)
2734 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
2735 this, pguidCmdGroup
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
2738 return E_INVALIDARG
;
2740 for (UINT i
= 0; i
< cCmds
; i
++)
2742 FIXME("\tprgCmds[%d].cmdID = %d\n", i
, prgCmds
[i
].cmdID
);
2743 prgCmds
[i
].cmdf
= 0;
2746 return OLECMDERR_E_UNKNOWNGROUP
;
2749 /**********************************************************
2750 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2752 * nCmdID is the OLECMDID_* enumeration
2754 HRESULT WINAPI
CDefView::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
2756 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2757 this, debugstr_guid(pguidCmdGroup
), nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2760 return OLECMDERR_E_UNKNOWNGROUP
;
2762 if (IsEqualCLSID(*pguidCmdGroup
, m_Category
))
2764 if (nCmdID
== FCIDM_SHVIEW_AUTOARRANGE
)
2766 if (V_VT(pvaIn
) != VT_INT_PTR
)
2767 return OLECMDERR_E_NOTSUPPORTED
;
2771 params
.cbSize
= sizeof(params
);
2772 params
.rcExclude
= *(RECT
*) V_INTREF(pvaIn
);
2774 HMENU hView
= m_hView
;
2776 hView
= CreatePopupMenu();
2777 AppendMenuW(hView
, MF_STRING
, FCIDM_SHVIEW_BIGICON
, L
"Big!");
2778 AppendMenuW(hView
, MF_STRING
, FCIDM_SHVIEW_SMALLICON
, L
"Small!");
2779 AppendMenuW(hView
, MF_STRING
, FCIDM_SHVIEW_LISTVIEW
, L
"List!");
2780 AppendMenuW(hView
, MF_STRING
, FCIDM_SHVIEW_REPORTVIEW
, L
"Report!");
2785 PrepareShowViewMenu(hView
);
2787 TrackPopupMenuEx(hView
, TPM_LEFTALIGN
| TPM_TOPALIGN
, params
.rcExclude
.left
, params
.rcExclude
.bottom
, m_hWndParent
, ¶ms
);
2790 // pvaOut is VT_I4 with value 0x403 (cmd id of the new mode maybe?)
2791 V_VT(pvaOut
) = VT_I4
;
2792 V_I4(pvaOut
) = 0x403;
2796 if (IsEqualIID(*pguidCmdGroup
, CGID_Explorer
) &&
2798 (nCmdexecopt
== 4) && pvaOut
)
2801 if (IsEqualIID(*pguidCmdGroup
, CGID_ShellDocView
) &&
2806 return OLECMDERR_E_UNKNOWNGROUP
;
2809 /**********************************************************
2810 * ISVDropTarget implementation
2813 /******************************************************************************
2814 * drag_notify_subitem [Internal]
2816 * Figure out the shellfolder object, which is currently under the mouse cursor
2817 * and notify it via the IDropTarget interface.
2820 #define SCROLLAREAWIDTH 20
2822 HRESULT
CDefView::drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2824 LVHITTESTINFO htinfo
;
2829 /* Map from global to client coordinates and query the index of the listview-item, which is
2830 * currently under the mouse cursor. */
2833 htinfo
.flags
= LVHT_ONITEM
;
2834 ::ScreenToClient(m_ListView
, &htinfo
.pt
);
2835 lResult
= m_ListView
.HitTest(&htinfo
);
2837 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2838 ::GetClientRect(m_ListView
, &clientRect
);
2839 if (htinfo
.pt
.x
== m_ptLastMousePos
.x
&& htinfo
.pt
.y
== m_ptLastMousePos
.y
&&
2840 (htinfo
.pt
.x
< SCROLLAREAWIDTH
|| htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
||
2841 htinfo
.pt
.y
< SCROLLAREAWIDTH
|| htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
))
2843 m_cScrollDelay
= (m_cScrollDelay
+ 1) % 5; /* DragOver is called every 50 ms */
2844 if (m_cScrollDelay
== 0)
2846 /* Mouse did hover another 250 ms over the scroll-area */
2847 if (htinfo
.pt
.x
< SCROLLAREAWIDTH
)
2848 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEUP
, 0);
2850 if (htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
)
2851 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEDOWN
, 0);
2853 if (htinfo
.pt
.y
< SCROLLAREAWIDTH
)
2854 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEUP
, 0);
2856 if (htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
)
2857 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEDOWN
, 0);
2862 m_cScrollDelay
= 0; /* Reset, if the cursor is not over the listview's scroll-area */
2865 m_ptLastMousePos
= htinfo
.pt
;
2867 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2868 if (m_pCurDropTarget
&& lResult
== m_iDragOverItem
)
2869 return m_pCurDropTarget
->DragOver(grfKeyState
, pt
, pdwEffect
);
2871 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2872 if (m_pCurDropTarget
)
2874 m_pCurDropTarget
->DragLeave();
2875 m_pCurDropTarget
.Release();
2878 m_iDragOverItem
= lResult
;
2881 /* We are not above one of the listview's subitems. Bind to the parent folder's
2882 * DropTarget interface. */
2883 hr
= m_pSFParent
->CreateViewObject(NULL
, IID_PPV_ARG(IDropTarget
,&m_pCurDropTarget
));
2887 /* Query the relative PIDL of the shellfolder object represented by the currently
2888 * dragged over listview-item ... */
2889 PCUITEMID_CHILD pidl
= _PidlByItem(lResult
);
2891 /* ... and bind m_pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2892 hr
= m_pSFParent
->GetUIObjectOf(m_ListView
, 1, &pidl
, IID_NULL_PPV_ARG(IDropTarget
, &m_pCurDropTarget
));
2895 /* If anything failed, m_pCurDropTarget should be NULL now, which ought to be a save state. */
2899 /* Notify the item just entered via DragEnter. */
2900 return m_pCurDropTarget
->DragEnter(m_pCurDataObject
, grfKeyState
, pt
, pdwEffect
);
2903 HRESULT WINAPI
CDefView::DragEnter(IDataObject
*pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2905 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2906 m_pCurDataObject
= pDataObject
;
2907 pDataObject
->AddRef();
2909 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2912 HRESULT WINAPI
CDefView::DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2914 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2917 HRESULT WINAPI
CDefView::DragLeave()
2919 if (m_pCurDropTarget
)
2921 m_pCurDropTarget
->DragLeave();
2922 m_pCurDropTarget
.Release();
2925 if (m_pCurDataObject
!= NULL
)
2927 m_pCurDataObject
.Release();
2930 m_iDragOverItem
= 0;
2935 HRESULT WINAPI
CDefView::Drop(IDataObject
* pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2937 if (m_pCurDropTarget
)
2939 m_pCurDropTarget
->Drop(pDataObject
, grfKeyState
, pt
, pdwEffect
);
2940 m_pCurDropTarget
.Release();
2943 m_pCurDataObject
.Release();
2944 m_iDragOverItem
= 0;
2948 /**********************************************************
2949 * ISVDropSource implementation
2952 HRESULT WINAPI
CDefView::QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
)
2954 TRACE("(%p)\n", this);
2957 return DRAGDROP_S_CANCEL
;
2958 else if (!(grfKeyState
& MK_LBUTTON
) && !(grfKeyState
& MK_RBUTTON
))
2959 return DRAGDROP_S_DROP
;
2964 HRESULT WINAPI
CDefView::GiveFeedback(DWORD dwEffect
)
2966 TRACE("(%p)\n", this);
2968 return DRAGDROP_S_USEDEFAULTCURSORS
;
2971 /**********************************************************
2972 * ISVViewObject implementation
2975 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
)
2977 FIXME("Stub: this=%p\n", this);
2982 HRESULT WINAPI
CDefView::GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
, HDC hicTargetDevice
, LOGPALETTE
**ppColorSet
)
2984 FIXME("Stub: this=%p\n", this);
2989 HRESULT WINAPI
CDefView::Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
)
2991 FIXME("Stub: this=%p\n", this);
2996 HRESULT WINAPI
CDefView::Unfreeze(DWORD dwFreeze
)
2998 FIXME("Stub: this=%p\n", this);
3003 HRESULT WINAPI
CDefView::SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
)
3005 FIXME("partial stub: %p %08x %08x %p\n", this, aspects
, advf
, pAdvSink
);
3007 /* FIXME: we set the AdviseSink, but never use it to send any advice */
3008 m_pAdvSink
= pAdvSink
;
3009 m_dwAspects
= aspects
;
3015 HRESULT WINAPI
CDefView::GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
)
3017 TRACE("this=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n", this, pAspects
, pAdvf
, ppAdvSink
);
3021 *ppAdvSink
= m_pAdvSink
;
3022 m_pAdvSink
.p
->AddRef();
3026 *pAspects
= m_dwAspects
;
3034 HRESULT STDMETHODCALLTYPE
CDefView::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
3036 if (IsEqualIID(guidService
, SID_IShellBrowser
))
3037 return m_pShellBrowser
->QueryInterface(riid
, ppvObject
);
3038 else if(IsEqualIID(guidService
, SID_IFolderView
))
3039 return QueryInterface(riid
, ppvObject
);
3041 return E_NOINTERFACE
;
3044 HRESULT
CDefView::_MergeToolbar()
3046 CComPtr
<IExplorerToolbar
> ptb
; // [sp+8h] [bp-4h]@1
3050 hr
= IUnknown_QueryService(m_pShellBrowser
, IID_IExplorerToolbar
, IID_PPV_ARG(IExplorerToolbar
, &ptb
));
3054 m_Category
= CGID_DefViewFrame
;
3056 hr
= ptb
->SetCommandTarget(static_cast<IOleCommandTarget
*>(this), &m_Category
, 0);
3064 hr
= ptb
->AddButtons(&m_Category
, buttonsCount
, buttons
);
3071 /**********************************************************
3072 * IShellView_Constructor
3074 HRESULT WINAPI
IShellView_Constructor(IShellFolder
*pFolder
, IShellView
**newView
)
3076 return ShellObjectCreatorInit
<CDefView
>(pFolder
, IID_IShellView
, newView
);
3079 HRESULT WINAPI
CDefView_Constructor(IShellFolder
*pFolder
, REFIID riid
, LPVOID
* ppvOut
)
3081 return ShellObjectCreatorInit
<CDefView
>(pFolder
, riid
, ppvOut
);