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
;
87 HMENU m_hMenu
; /* Handle to the menu bar of the browser */
88 HMENU m_hMenuArrangeModes
; /* Handle to the popup menu with the arrange modes */
89 HMENU m_hMenuViewModes
; /* Handle to the popup menu with the view modes */
90 HMENU m_hContextMenu
; /* Handle to the open context menu */
91 BOOL m_bmenuBarInitialized
;
94 PCUITEMID_CHILD
*m_apidl
;
95 PIDLIST_ABSOLUTE m_pidlParent
;
96 LISTVIEW_SORT_INFO m_sortInfo
;
97 ULONG m_hNotify
; /* Change notification handle */
101 CComPtr
<IAdviseSink
> m_pAdvSink
;
103 CComPtr
<IDataObject
> m_pSourceDataObject
;
104 CComPtr
<IDropTarget
> m_pCurDropTarget
; /* The sub-item, which is currently dragged over */
105 CComPtr
<IDataObject
> m_pCurDataObject
; /* The dragged data-object */
106 LONG m_iDragOverItem
; /* Dragged over item's index, iff m_pCurDropTarget != NULL */
107 UINT m_cScrollDelay
; /* Send a WM_*SCROLL msg every 250 ms during drag-scroll */
108 POINT m_ptLastMousePos
; /* Mouse position at last DragOver call */
110 CComPtr
<IContextMenu
> m_pCM
;
118 HRESULT
_MergeToolbar();
123 HRESULT WINAPI
Initialize(IShellFolder
*shellFolder
);
124 HRESULT
IncludeObject(PCUITEMID_CHILD pidl
);
125 HRESULT
OnDefaultCommand();
126 HRESULT
OnStateChange(UINT uFlags
);
127 void UpdateStatusbar();
129 void SetStyle(DWORD dwAdd
, DWORD dwRemove
);
131 void UpdateListColors();
133 static INT CALLBACK
ListViewCompareItems(LPARAM lParam1
, LPARAM lParam2
, LPARAM lpData
);
135 PCUITEMID_CHILD
_PidlByItem(int i
);
136 PCUITEMID_CHILD
_PidlByItem(LVITEM
& lvItem
);
137 int LV_FindItemByPidl(PCUITEMID_CHILD pidl
);
138 BOOLEAN
LV_AddItem(PCUITEMID_CHILD pidl
);
139 BOOLEAN
LV_DeleteItem(PCUITEMID_CHILD pidl
);
140 BOOLEAN
LV_RenameItem(PCUITEMID_CHILD pidlOld
, PCUITEMID_CHILD pidlNew
);
141 BOOLEAN
LV_ProdItem(PCUITEMID_CHILD pidl
);
142 static INT CALLBACK
fill_list(LPVOID ptr
, LPVOID arg
);
144 HRESULT
FillFileMenu();
145 HRESULT
FillEditMenu();
146 HRESULT
FillViewMenu();
147 HRESULT
FillArrangeAsMenu(HMENU hmenuArrange
);
148 HRESULT
CheckViewMode(HMENU hmenuView
);
149 UINT
GetSelections();
150 HRESULT
OpenSelectedItems();
152 void DoActivate(UINT uState
);
153 HRESULT
drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
154 HRESULT
InvokeContextMenuCommand(UINT uCommand
);
155 LRESULT
OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
);
157 // *** IOleWindow methods ***
158 virtual HRESULT STDMETHODCALLTYPE
GetWindow(HWND
*lphwnd
);
159 virtual HRESULT STDMETHODCALLTYPE
ContextSensitiveHelp(BOOL fEnterMode
);
161 // *** IShellView methods ***
162 virtual HRESULT STDMETHODCALLTYPE
TranslateAccelerator(MSG
*pmsg
);
163 virtual HRESULT STDMETHODCALLTYPE
EnableModeless(BOOL fEnable
);
164 virtual HRESULT STDMETHODCALLTYPE
UIActivate(UINT uState
);
165 virtual HRESULT STDMETHODCALLTYPE
Refresh();
166 virtual HRESULT STDMETHODCALLTYPE
CreateViewWindow(IShellView
*psvPrevious
, LPCFOLDERSETTINGS pfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
);
167 virtual HRESULT STDMETHODCALLTYPE
DestroyViewWindow();
168 virtual HRESULT STDMETHODCALLTYPE
GetCurrentInfo(LPFOLDERSETTINGS pfs
);
169 virtual HRESULT STDMETHODCALLTYPE
AddPropertySheetPages(DWORD dwReserved
, LPFNSVADDPROPSHEETPAGE pfn
, LPARAM lparam
);
170 virtual HRESULT STDMETHODCALLTYPE
SaveViewState();
171 virtual HRESULT STDMETHODCALLTYPE
SelectItem(PCUITEMID_CHILD pidlItem
, SVSIF uFlags
);
172 virtual HRESULT STDMETHODCALLTYPE
GetItemObject(UINT uItem
, REFIID riid
, void **ppv
);
174 // *** IShellView2 methods ***
175 virtual HRESULT STDMETHODCALLTYPE
GetView(SHELLVIEWID
*view_guid
, ULONG view_type
);
176 virtual HRESULT STDMETHODCALLTYPE
CreateViewWindow2(LPSV2CVW2_PARAMS view_params
);
177 virtual HRESULT STDMETHODCALLTYPE
HandleRename(LPCITEMIDLIST new_pidl
);
178 virtual HRESULT STDMETHODCALLTYPE
SelectAndPositionItem(LPCITEMIDLIST item
, UINT flags
, POINT
*point
);
180 // *** IShellView3 methods ***
181 virtual HRESULT STDMETHODCALLTYPE
CreateViewWindow3(IShellBrowser
*psb
, IShellView
*psvPrevious
, SV3CVW3_FLAGS view_flags
, FOLDERFLAGS mask
, FOLDERFLAGS flags
, FOLDERVIEWMODE mode
, const SHELLVIEWID
*view_id
, RECT
*prcView
, HWND
*hwnd
);
183 // *** IFolderView methods ***
184 virtual HRESULT STDMETHODCALLTYPE
GetCurrentViewMode(UINT
*pViewMode
);
185 virtual HRESULT STDMETHODCALLTYPE
SetCurrentViewMode(UINT ViewMode
);
186 virtual HRESULT STDMETHODCALLTYPE
GetFolder(REFIID riid
, void **ppv
);
187 virtual HRESULT STDMETHODCALLTYPE
Item(int iItemIndex
, PITEMID_CHILD
*ppidl
);
188 virtual HRESULT STDMETHODCALLTYPE
ItemCount(UINT uFlags
, int *pcItems
);
189 virtual HRESULT STDMETHODCALLTYPE
Items(UINT uFlags
, REFIID riid
, void **ppv
);
190 virtual HRESULT STDMETHODCALLTYPE
GetSelectionMarkedItem(int *piItem
);
191 virtual HRESULT STDMETHODCALLTYPE
GetFocusedItem(int *piItem
);
192 virtual HRESULT STDMETHODCALLTYPE
GetItemPosition(PCUITEMID_CHILD pidl
, POINT
*ppt
);
193 virtual HRESULT STDMETHODCALLTYPE
GetSpacing(POINT
*ppt
);
194 virtual HRESULT STDMETHODCALLTYPE
GetDefaultSpacing(POINT
*ppt
);
195 virtual HRESULT STDMETHODCALLTYPE
GetAutoArrange();
196 virtual HRESULT STDMETHODCALLTYPE
SelectItem(int iItem
, DWORD dwFlags
);
197 virtual HRESULT STDMETHODCALLTYPE
SelectAndPositionItems(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD dwFlags
);
199 // *** IShellFolderView methods ***
200 virtual HRESULT STDMETHODCALLTYPE
Rearrange(LPARAM sort
);
201 virtual HRESULT STDMETHODCALLTYPE
GetArrangeParam(LPARAM
*sort
);
202 virtual HRESULT STDMETHODCALLTYPE
ArrangeGrid();
203 virtual HRESULT STDMETHODCALLTYPE
AutoArrange();
204 virtual HRESULT STDMETHODCALLTYPE
AddObject(PITEMID_CHILD pidl
, UINT
*item
);
205 virtual HRESULT STDMETHODCALLTYPE
GetObject(PITEMID_CHILD
*pidl
, UINT item
);
206 virtual HRESULT STDMETHODCALLTYPE
RemoveObject(PITEMID_CHILD pidl
, UINT
*item
);
207 virtual HRESULT STDMETHODCALLTYPE
GetObjectCount(UINT
*count
);
208 virtual HRESULT STDMETHODCALLTYPE
SetObjectCount(UINT count
, UINT flags
);
209 virtual HRESULT STDMETHODCALLTYPE
UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
);
210 virtual HRESULT STDMETHODCALLTYPE
RefreshObject(PITEMID_CHILD pidl
, UINT
*item
);
211 virtual HRESULT STDMETHODCALLTYPE
SetRedraw(BOOL redraw
);
212 virtual HRESULT STDMETHODCALLTYPE
GetSelectedCount(UINT
*count
);
213 virtual HRESULT STDMETHODCALLTYPE
GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
);
214 virtual HRESULT STDMETHODCALLTYPE
IsDropOnSource(IDropTarget
*drop_target
);
215 virtual HRESULT STDMETHODCALLTYPE
GetDragPoint(POINT
*pt
);
216 virtual HRESULT STDMETHODCALLTYPE
GetDropPoint(POINT
*pt
);
217 virtual HRESULT STDMETHODCALLTYPE
MoveIcons(IDataObject
*obj
);
218 virtual HRESULT STDMETHODCALLTYPE
SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
);
219 virtual HRESULT STDMETHODCALLTYPE
IsBkDropTarget(IDropTarget
*drop_target
);
220 virtual HRESULT STDMETHODCALLTYPE
SetClipboard(BOOL move
);
221 virtual HRESULT STDMETHODCALLTYPE
SetPoints(IDataObject
*obj
);
222 virtual HRESULT STDMETHODCALLTYPE
GetItemSpacing(ITEMSPACING
*spacing
);
223 virtual HRESULT STDMETHODCALLTYPE
SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
);
224 virtual HRESULT STDMETHODCALLTYPE
Select(UINT flags
);
225 virtual HRESULT STDMETHODCALLTYPE
QuerySupport(UINT
*support
);
226 virtual HRESULT STDMETHODCALLTYPE
SetAutomationObject(IDispatch
*disp
);
228 // *** IOleCommandTarget methods ***
229 virtual HRESULT STDMETHODCALLTYPE
QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
);
230 virtual HRESULT STDMETHODCALLTYPE
Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
);
232 // *** IDropTarget methods ***
233 virtual HRESULT STDMETHODCALLTYPE
DragEnter(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
234 virtual HRESULT STDMETHODCALLTYPE
DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
235 virtual HRESULT STDMETHODCALLTYPE
DragLeave();
236 virtual HRESULT STDMETHODCALLTYPE
Drop(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
238 // *** IDropSource methods ***
239 virtual HRESULT STDMETHODCALLTYPE
QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
);
240 virtual HRESULT STDMETHODCALLTYPE
GiveFeedback(DWORD dwEffect
);
242 // *** IViewObject methods ***
243 virtual HRESULT STDMETHODCALLTYPE
Draw(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
,
244 HDC hdcTargetDev
, HDC hdcDraw
, LPCRECTL lprcBounds
, LPCRECTL lprcWBounds
,
245 BOOL ( STDMETHODCALLTYPE
*pfnContinue
)(ULONG_PTR dwContinue
), ULONG_PTR dwContinue
);
246 virtual HRESULT STDMETHODCALLTYPE
GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
,
247 DVTARGETDEVICE
*ptd
, HDC hicTargetDev
, LOGPALETTE
**ppColorSet
);
248 virtual HRESULT STDMETHODCALLTYPE
Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
);
249 virtual HRESULT STDMETHODCALLTYPE
Unfreeze(DWORD dwFreeze
);
250 virtual HRESULT STDMETHODCALLTYPE
SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
);
251 virtual HRESULT STDMETHODCALLTYPE
GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
);
253 // *** IServiceProvider methods ***
254 virtual HRESULT STDMETHODCALLTYPE
QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
);
257 LRESULT
OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
258 LRESULT
OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
259 LRESULT
OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
260 LRESULT
OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
261 LRESULT
OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
262 LRESULT
OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
263 LRESULT
OnNCCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
264 LRESULT
OnNCDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
265 LRESULT
OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
266 LRESULT
OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
267 LRESULT
OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
268 LRESULT
OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
269 LRESULT
OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
270 LRESULT
OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
271 LRESULT
OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
272 LRESULT
OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
273 LRESULT
OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
274 LRESULT
OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
275 LRESULT
OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
276 LRESULT
OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
278 static ATL::CWndClassInfo
& GetWndClassInfo()
280 static ATL::CWndClassInfo wc
=
282 { sizeof(WNDCLASSEX
), CS_PARENTDC
, StartWindowProc
,
284 LoadCursor(NULL
, IDC_ARROW
), (HBRUSH
)(COLOR_WINDOW
+ 1), NULL
, SV_CLASS_NAME
, NULL
286 NULL
, NULL
, IDC_ARROW
, TRUE
, 0, _T("")
291 virtual WNDPROC
GetWindowProc()
296 static LRESULT CALLBACK
WindowProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
301 // Must hold a reference during message handling
302 pThis
= reinterpret_cast<CDefView
*>(hWnd
);
304 result
= CWindowImpl
<CDefView
, CWindow
, CControlWinTraits
>::WindowProc(hWnd
, uMsg
, wParam
, lParam
);
309 BEGIN_MSG_MAP(CDefView
)
310 MESSAGE_HANDLER(WM_SIZE
, OnSize
)
311 MESSAGE_HANDLER(WM_SETFOCUS
, OnSetFocus
)
312 MESSAGE_HANDLER(WM_KILLFOCUS
, OnKillFocus
)
313 MESSAGE_HANDLER(WM_NCCREATE
, OnNCCreate
)
314 MESSAGE_HANDLER(WM_NCDESTROY
, OnNCDestroy
)
315 MESSAGE_HANDLER(WM_CREATE
, OnCreate
)
316 MESSAGE_HANDLER(WM_ACTIVATE
, OnActivate
)
317 MESSAGE_HANDLER(WM_NOTIFY
, OnNotify
)
318 MESSAGE_HANDLER(WM_COMMAND
, OnCommand
)
319 MESSAGE_HANDLER(SHV_CHANGE_NOTIFY
, OnChangeNotify
)
320 MESSAGE_HANDLER(WM_CONTEXTMENU
, OnContextMenu
)
321 MESSAGE_HANDLER(WM_DRAWITEM
, OnCustomItem
)
322 MESSAGE_HANDLER(WM_MEASUREITEM
, OnCustomItem
)
323 MESSAGE_HANDLER(WM_SHOWWINDOW
, OnShowWindow
)
324 MESSAGE_HANDLER(WM_GETDLGCODE
, OnGetDlgCode
)
325 MESSAGE_HANDLER(WM_DESTROY
, OnDestroy
)
326 MESSAGE_HANDLER(WM_ERASEBKGND
, OnEraseBackground
)
327 MESSAGE_HANDLER(WM_SYSCOLORCHANGE
, OnSysColorChange
)
328 MESSAGE_HANDLER(CWM_GETISHELLBROWSER
, OnGetShellBrowser
)
329 MESSAGE_HANDLER(WM_SETTINGCHANGE
, OnSettingChange
)
330 MESSAGE_HANDLER(WM_INITMENUPOPUP
, OnInitMenuPopup
)
333 BEGIN_COM_MAP(CDefView
)
334 // Windows returns E_NOINTERFACE for IOleWindow
335 // COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
336 COM_INTERFACE_ENTRY_IID(IID_IShellView
, IShellView
)
337 COM_INTERFACE_ENTRY_IID(IID_IShellView2
, IShellView2
)
338 COM_INTERFACE_ENTRY_IID(IID_IFolderView
, IFolderView
)
339 COM_INTERFACE_ENTRY_IID(IID_IShellFolderView
, IShellFolderView
)
340 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget
, IOleCommandTarget
)
341 COM_INTERFACE_ENTRY_IID(IID_IDropTarget
, IDropTarget
)
342 COM_INTERFACE_ENTRY_IID(IID_IDropSource
, IDropSource
)
343 COM_INTERFACE_ENTRY_IID(IID_IViewObject
, IViewObject
)
344 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider
, IServiceProvider
)
349 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
350 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
351 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
353 #define ID_LISTVIEW 1
356 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
357 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
358 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
360 typedef void (CALLBACK
*PFNSHGETSETTINGSPROC
)(LPSHELLFLAGSTATE lpsfs
, DWORD dwMask
);
362 CDefView::CDefView() :
366 m_hMenuArrangeModes(NULL
),
367 m_hMenuViewModes(NULL
),
368 m_hContextMenu(NULL
),
369 m_bmenuBarInitialized(FALSE
),
383 ZeroMemory(&m_FolderSettings
, sizeof(m_FolderSettings
));
384 ZeroMemory(&m_sortInfo
, sizeof(m_sortInfo
));
385 ZeroMemory(&m_ptLastMousePos
, sizeof(m_ptLastMousePos
));
386 ZeroMemory(&m_Category
, sizeof(m_Category
));
389 CDefView::~CDefView()
391 TRACE(" destroying IShellView(%p)\n", this);
401 HRESULT WINAPI
CDefView::Initialize(IShellFolder
*shellFolder
)
403 m_pSFParent
= shellFolder
;
404 shellFolder
->QueryInterface(IID_PPV_ARG(IShellFolder2
, &m_pSF2Parent
));
409 /**********************************************************
411 * ##### helperfunctions for communication with ICommDlgBrowser #####
413 HRESULT
CDefView::IncludeObject(PCUITEMID_CHILD pidl
)
417 if (m_pCommDlgBrowser
.p
!= NULL
)
419 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl
);
420 ret
= m_pCommDlgBrowser
->IncludeObject(this, pidl
);
421 TRACE("--0x%08x\n", ret
);
427 HRESULT
CDefView::OnDefaultCommand()
429 HRESULT ret
= S_FALSE
;
431 if (m_pCommDlgBrowser
.p
!= NULL
)
433 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
434 ret
= m_pCommDlgBrowser
->OnDefaultCommand(this);
435 TRACE("-- returns %08x\n", ret
);
441 HRESULT
CDefView::OnStateChange(UINT uFlags
)
443 HRESULT ret
= S_FALSE
;
445 if (m_pCommDlgBrowser
.p
!= NULL
)
447 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags
);
448 ret
= m_pCommDlgBrowser
->OnStateChange(this, uFlags
);
454 /**********************************************************
455 * set the toolbar of the filedialog buttons
457 * - activates the buttons from the shellbrowser according to
460 void CDefView::CheckToolbar()
466 if (m_pCommDlgBrowser
!= NULL
)
468 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
469 FCIDM_TB_SMALLICON
, (m_FolderSettings
.ViewMode
== FVM_LIST
) ? TRUE
: FALSE
, &result
);
470 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
471 FCIDM_TB_REPORTVIEW
, (m_FolderSettings
.ViewMode
== FVM_DETAILS
) ? TRUE
: FALSE
, &result
);
472 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
473 FCIDM_TB_SMALLICON
, TRUE
, &result
);
474 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
475 FCIDM_TB_REPORTVIEW
, TRUE
, &result
);
479 void CDefView::UpdateStatusbar()
481 WCHAR szFormat
[MAX_PATH
] = {0};
482 WCHAR szObjects
[MAX_PATH
] = {0};
485 cSelectedItems
= m_ListView
.GetSelectedCount();
488 LoadStringW(shell32_hInstance
, IDS_OBJECTS_SELECTED
, szFormat
, _countof(szFormat
));
489 StringCchPrintfW(szObjects
, MAX_PATH
, szFormat
, cSelectedItems
);
493 LoadStringW(shell32_hInstance
, IDS_OBJECTS
, szFormat
, _countof(szFormat
));
494 StringCchPrintfW(szObjects
, MAX_PATH
, szFormat
, m_ListView
.GetItemCount());
496 m_pShellBrowser
->SetStatusTextSB(szObjects
);
499 /**********************************************************
501 * ##### helperfunctions for initializing the view #####
503 /**********************************************************
504 * change the style of the listview control
506 void CDefView::SetStyle(DWORD dwAdd
, DWORD dwRemove
)
510 TRACE("(%p)\n", this);
512 tmpstyle
= ::GetWindowLongPtrW(m_ListView
, GWL_STYLE
);
513 ::SetWindowLongPtrW(m_ListView
, GWL_STYLE
, dwAdd
| (tmpstyle
& ~dwRemove
));
516 /**********************************************************
517 * ShellView_CreateList()
519 * - creates the list view window
521 BOOL
CDefView::CreateList()
523 DWORD dwStyle
, dwExStyle
;
527 dwStyle
= WS_TABSTOP
| WS_VISIBLE
| WS_CHILDWINDOW
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
|
528 LVS_SHAREIMAGELISTS
| LVS_EDITLABELS
| LVS_AUTOARRANGE
;
529 dwExStyle
= WS_EX_CLIENTEDGE
;
531 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
532 dwStyle
|= LVS_ALIGNLEFT
;
534 dwStyle
|= LVS_ALIGNTOP
| LVS_SHOWSELALWAYS
;
536 switch (m_FolderSettings
.ViewMode
)
543 dwStyle
|= LVS_REPORT
;
547 dwStyle
|= LVS_SMALLICON
;
559 if (m_FolderSettings
.fFlags
& FWF_AUTOARRANGE
)
560 dwStyle
|= LVS_AUTOARRANGE
;
562 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
563 m_FolderSettings
.fFlags
|= FWF_NOCLIENTEDGE
| FWF_NOSCROLL
;
565 if (m_FolderSettings
.fFlags
& FWF_SINGLESEL
)
566 dwStyle
|= LVS_SINGLESEL
;
568 if (m_FolderSettings
.fFlags
& FWF_NOCLIENTEDGE
)
569 dwExStyle
&= ~WS_EX_CLIENTEDGE
;
571 RECT rcListView
= {0,0,0,0};
572 m_ListView
.Create(m_hWnd
, rcListView
, L
"FolderView", dwStyle
, dwExStyle
, ID_LISTVIEW
);
577 m_sortInfo
.bIsAscending
= TRUE
;
578 m_sortInfo
.nHeaderID
= -1;
579 m_sortInfo
.nLastHeaderID
= -1;
583 /* UpdateShellSettings(); */
587 void CDefView::UpdateListColors()
589 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
591 /* Check if drop shadows option is enabled */
592 BOOL bDropShadow
= FALSE
;
593 DWORD cbDropShadow
= sizeof(bDropShadow
);
596 * The desktop ListView always take the default desktop colours, by
597 * remaining transparent and letting user32/win32k paint itself the
598 * desktop background color, if any.
600 m_ListView
.SetBkColor(CLR_NONE
);
602 SHGetValueW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
603 L
"ListviewShadow", NULL
, &bDropShadow
, &cbDropShadow
);
606 /* Set the icon background transparent */
607 m_ListView
.SetTextBkColor(CLR_NONE
);
608 m_ListView
.SetTextColor(RGB(255, 255, 255));
609 m_ListView
.SetExtendedListViewStyle(LVS_EX_TRANSPARENTSHADOWTEXT
, LVS_EX_TRANSPARENTSHADOWTEXT
);
613 /* Set the icon background as the same colour as the desktop */
614 COLORREF crDesktop
= GetSysColor(COLOR_DESKTOP
);
615 m_ListView
.SetTextBkColor(crDesktop
);
616 if (GetRValue(crDesktop
) + GetGValue(crDesktop
) + GetBValue(crDesktop
) > 128 * 3)
617 m_ListView
.SetTextColor(RGB(0, 0, 0));
619 m_ListView
.SetTextColor(RGB(255, 255, 255));
620 m_ListView
.SetExtendedListViewStyle(0, LVS_EX_TRANSPARENTSHADOWTEXT
);
625 /**********************************************************
626 * ShellView_InitList()
628 * - adds all needed columns to the shellview
630 BOOL
CDefView::InitList()
634 HIMAGELIST big_icons
, small_icons
;
638 m_ListView
.DeleteAllItems();
640 m_hMenuArrangeModes
= CreateMenu();
644 for (int i
= 0; 1; i
++)
646 if (FAILED(m_pSF2Parent
->GetDetailsOf(NULL
, i
, &sd
)))
648 StrRetToStrNW( szTemp
, 50, &sd
.str
, NULL
);
649 m_ListView
.InsertColumn(i
, szTemp
, sd
.fmt
, sd
.cxChar
* 8);
651 InsertMenuW(m_hMenuArrangeModes
, -1, MF_STRING
, 0x30 + i
, szTemp
);
654 InsertMenuW(m_hMenuArrangeModes
, -1, MF_BYPOSITION
| MF_SEPARATOR
, 0, 0);
658 FIXME("no m_pSF2Parent\n");
661 Shell_GetImageLists(&big_icons
, &small_icons
);
662 m_ListView
.SetImageList(big_icons
, LVSIL_NORMAL
);
663 m_ListView
.SetImageList(small_icons
, LVSIL_SMALL
);
668 /*************************************************************************
669 * ShellView_ListViewCompareItems
671 * Compare Function for the Listview (FileOpen Dialog)
674 * lParam1 [I] the first ItemIdList to compare with
675 * lParam2 [I] the second ItemIdList to compare with
676 * lpData [I] The column ID for the header Ctrl to process
679 * A negative value if the first item should precede the second,
680 * a positive value if the first item should follow the second,
681 * or zero if the two items are equivalent
683 INT CALLBACK
CDefView::ListViewCompareItems(LPARAM lParam1
, LPARAM lParam2
, LPARAM lpData
)
685 PCUIDLIST_RELATIVE pidl1
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam1
);
686 PCUIDLIST_RELATIVE pidl2
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam2
);
687 CDefView
*pThis
= reinterpret_cast<CDefView
*>(lpData
);
689 HRESULT hres
= pThis
->m_pSFParent
->CompareIDs(pThis
->m_sortInfo
.nHeaderID
, pidl1
, pidl2
);
690 if (FAILED_UNEXPECTEDLY(hres
))
693 SHORT nDiff
= HRESULT_CODE(hres
);
694 if (!pThis
->m_sortInfo
.bIsAscending
)
699 PCUITEMID_CHILD
CDefView::_PidlByItem(int i
)
701 return reinterpret_cast<PCUITEMID_CHILD
>(m_ListView
.GetItemData(i
));
704 PCUITEMID_CHILD
CDefView::_PidlByItem(LVITEM
& lvItem
)
706 return reinterpret_cast<PCUITEMID_CHILD
>(lvItem
.lParam
);
709 /**********************************************************
710 * LV_FindItemByPidl()
712 int CDefView::LV_FindItemByPidl(PCUITEMID_CHILD pidl
)
714 int cItems
= m_ListView
.GetItemCount();
716 for (int i
= 0; i
<cItems
; i
++)
718 PCUITEMID_CHILD currentpidl
= _PidlByItem(i
);
719 HRESULT hr
= m_pSFParent
->CompareIDs(0, pidl
, currentpidl
);
721 if (SUCCEEDED(hr
) && !HRESULT_CODE(hr
))
729 /**********************************************************
732 BOOLEAN
CDefView::LV_AddItem(PCUITEMID_CHILD pidl
)
736 TRACE("(%p)(pidl=%p)\n", this, pidl
);
738 lvItem
.mask
= LVIF_TEXT
| LVIF_IMAGE
| LVIF_PARAM
; /*set the mask*/
739 lvItem
.iItem
= m_ListView
.GetItemCount(); /*add the item to the end of the list*/
741 lvItem
.lParam
= reinterpret_cast<LPARAM
>(ILClone(pidl
)); /*set the item's data*/
742 lvItem
.pszText
= LPSTR_TEXTCALLBACKW
; /*get text on a callback basis*/
743 lvItem
.iImage
= I_IMAGECALLBACK
; /*get the image on a callback basis*/
744 lvItem
.stateMask
= LVIS_CUT
;
746 if (m_ListView
.InsertItem(&lvItem
) == -1)
752 /**********************************************************
755 BOOLEAN
CDefView::LV_DeleteItem(PCUITEMID_CHILD pidl
)
759 TRACE("(%p)(pidl=%p)\n", this, pidl
);
761 nIndex
= LV_FindItemByPidl(pidl
);
763 return (-1 == m_ListView
.DeleteItem(nIndex
)) ? FALSE
: TRUE
;
766 /**********************************************************
769 BOOLEAN
CDefView::LV_RenameItem(PCUITEMID_CHILD pidlOld
, PCUITEMID_CHILD pidlNew
)
774 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", this, pidlOld
, pidlNew
);
776 nItem
= LV_FindItemByPidl(pidlOld
);
780 lvItem
.mask
= LVIF_PARAM
; /* only the pidl */
781 lvItem
.iItem
= nItem
;
783 m_ListView
.GetItem(&lvItem
);
785 SHFree(reinterpret_cast<LPVOID
>(lvItem
.lParam
));
786 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
787 lvItem
.iItem
= nItem
;
789 lvItem
.lParam
= reinterpret_cast<LPARAM
>(ILClone(pidlNew
)); /* set the item's data */
790 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
791 m_ListView
.SetItem(&lvItem
);
792 m_ListView
.Update(nItem
);
793 return TRUE
; /* FIXME: better handling */
799 /**********************************************************
802 BOOLEAN
CDefView::LV_ProdItem(PCUITEMID_CHILD pidl
)
807 TRACE("(%p)(pidl=%p)\n", this, pidl
);
809 nItem
= LV_FindItemByPidl(pidl
);
813 lvItem
.mask
= LVIF_IMAGE
;
814 lvItem
.iItem
= nItem
;
816 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
817 m_ListView
.SetItem(&lvItem
);
818 m_ListView
.Update(nItem
);
825 /**********************************************************
826 * ShellView_FillList()
828 * - gets the objectlist from the shellfolder
830 * - fills the list into the view
832 INT CALLBACK
CDefView::fill_list(LPVOID ptr
, LPVOID arg
)
834 PITEMID_CHILD pidl
= static_cast<PITEMID_CHILD
>(ptr
);
835 CDefView
*pThis
= static_cast<CDefView
*>(arg
);
837 /* in a commdlg This works as a filemask*/
838 if (pThis
->IncludeObject(pidl
) == S_OK
)
839 pThis
->LV_AddItem(pidl
);
845 HRESULT
CDefView::FillList()
847 CComPtr
<IEnumIDList
> pEnumIDList
;
853 DWORD dFlags
= SHCONTF_NONFOLDERS
| SHCONTF_FOLDERS
;
857 /* determine if there is a setting to show all the hidden files/folders */
858 if (RegOpenKeyExW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", 0, KEY_QUERY_VALUE
, &hKey
) == ERROR_SUCCESS
)
860 DWORD dataLength
, flagVal
;
862 dataLength
= sizeof(flagVal
);
863 if (RegQueryValueExW(hKey
, L
"Hidden", NULL
, NULL
, (LPBYTE
)&flagVal
, &dataLength
) == ERROR_SUCCESS
)
865 /* if the value is 1, then show all hidden files/folders */
868 dFlags
|= SHCONTF_INCLUDEHIDDEN
;
869 m_ListView
.SendMessageW(LVM_SETCALLBACKMASK
, LVIS_CUT
, 0);
877 /* get the itemlist from the shfolder */
878 hRes
= m_pSFParent
->EnumObjects(m_hWnd
, dFlags
, &pEnumIDList
);
886 /* create a pointer array */
887 hdpa
= DPA_Create(16);
890 return(E_OUTOFMEMORY
);
893 /* copy the items into the array*/
894 while((S_OK
== pEnumIDList
->Next(1, &pidl
, &dwFetched
)) && dwFetched
)
896 if (DPA_InsertPtr(hdpa
, 0x7fff, pidl
) == -1)
902 /*turn the listview's redrawing off*/
903 m_ListView
.SetRedraw(FALSE
);
905 DPA_DestroyCallback( hdpa
, fill_list
, this);
910 m_pSF2Parent
->GetDefaultColumn(NULL
, (ULONG
*)&m_sortInfo
.nHeaderID
, NULL
);
914 FIXME("no m_pSF2Parent\n");
916 m_sortInfo
.bIsAscending
= TRUE
;
917 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
918 m_ListView
.SortItems(ListViewCompareItems
, this);
920 /*turn the listview's redrawing back on and force it to draw*/
921 m_ListView
.SetRedraw(TRUE
);
926 LRESULT
CDefView::OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
928 m_ListView
.UpdateWindow();
933 LRESULT
CDefView::OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
935 return m_ListView
.SendMessageW(uMsg
, 0, 0);
938 LRESULT
CDefView::OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
945 DestroyMenu(m_hMenu
);
948 RevokeDragDrop(m_hWnd
);
949 SHChangeNotifyDeregister(m_hNotify
);
951 SHFree(m_pidlParent
);
958 LRESULT
CDefView::OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
960 /* redirect to parent */
961 if (m_FolderSettings
.fFlags
& (FWF_DESKTOP
| FWF_TRANSPARENT
))
962 return SendMessageW(GetParent(), WM_ERASEBKGND
, wParam
, lParam
);
968 LRESULT
CDefView::OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
970 /* Update desktop labels color */
973 /* Forward WM_SYSCOLORCHANGE to common controls */
974 return m_ListView
.SendMessageW(uMsg
, 0, 0);
977 LRESULT
CDefView::OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
979 return reinterpret_cast<LRESULT
>(m_pShellBrowser
.p
);
982 LRESULT
CDefView::OnNCCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
989 LRESULT
CDefView::OnNCDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
996 /**********************************************************
997 * ShellView_OnCreate()
999 LRESULT
CDefView::OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1001 CComPtr
<IDropTarget
> pdt
;
1002 SHChangeNotifyEntry ntreg
;
1003 CComPtr
<IPersistFolder2
> ppf2
;
1005 TRACE("%p\n", this);
1015 if (SUCCEEDED(QueryInterface(IID_PPV_ARG(IDropTarget
, &pdt
))))
1017 if (FAILED(RegisterDragDrop(m_hWnd
, pdt
)))
1018 ERR("Registering Drag Drop Failed");
1021 /* register for receiving notifications */
1022 m_pSFParent
->QueryInterface(IID_PPV_ARG(IPersistFolder2
, &ppf2
));
1025 ppf2
->GetCurFolder(&m_pidlParent
);
1026 ntreg
.fRecursive
= TRUE
;
1027 ntreg
.pidl
= m_pidlParent
;
1028 m_hNotify
= SHChangeNotifyRegister(m_hWnd
, SHCNRF_InterruptLevel
| SHCNRF_ShellLevel
, SHCNE_ALLEVENTS
, SHV_CHANGE_NOTIFY
, 1, &ntreg
);
1031 m_hAccel
= LoadAcceleratorsW(shell32_hInstance
, MAKEINTRESOURCEW(IDA_SHELLVIEW
));
1038 /**********************************************************
1039 * #### Handling of the menus ####
1042 extern "C" DWORD WINAPI
SHMenuIndexFromID(HMENU hMenu
, UINT uID
);
1044 HMENU
GetSubmenuByID(HMENU hmenu
, UINT id
)
1046 MENUITEMINFOW mii
= {sizeof(mii
), MIIM_SUBMENU
};
1047 if (::GetMenuItemInfoW(hmenu
, id
, FALSE
, &mii
))
1048 return mii
.hSubMenu
;
1053 /* ReallyGetMenuItemID returns the id of an item even if it opens a submenu,
1054 GetMenuItemID returns -1 if the specified item opens a submenu */
1055 UINT
ReallyGetMenuItemID(HMENU hmenu
, int i
)
1057 MENUITEMINFOW mii
= {sizeof(mii
), MIIM_ID
};
1058 if (::GetMenuItemInfoW(hmenu
, i
, TRUE
, &mii
))
1064 HRESULT
CDefView::FillFileMenu()
1066 HMENU hFileMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_FILE
);
1070 /* Cleanup the items added previously */
1071 for (int i
= GetMenuItemCount(hFileMenu
) - 1; i
>= 0; i
--)
1073 UINT id
= GetMenuItemID(hFileMenu
, i
);
1074 if (id
< FCIDM_BROWSERFIRST
|| id
> FCIDM_BROWSERLAST
)
1075 DeleteMenu(hFileMenu
, i
, MF_BYPOSITION
);
1078 /* Store the context menu in m_pCM and keep it in order to invoke the selected command later on */
1079 HRESULT hr
= GetItemObject(SVGIO_SELECTION
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1080 if (FAILED_UNEXPECTEDLY(hr
))
1083 IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1085 HMENU hmenu
= CreatePopupMenu();
1087 hr
= m_pCM
->QueryContextMenu(hmenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, 0);
1088 if (FAILED_UNEXPECTEDLY(hr
))
1091 // TODO: filter or something
1093 Shell_MergeMenus(hFileMenu
, hmenu
, 0, 0, 0xFFFF, MM_ADDSEPARATOR
| MM_SUBMENUSHAVEIDS
);
1095 ::DestroyMenu(hmenu
);
1100 HRESULT
CDefView::FillEditMenu()
1102 HMENU hEditMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_EDIT
);
1106 HMENU hmenuContents
= ::LoadMenuW(shell32_hInstance
, L
"MENU_003");
1110 Shell_MergeMenus(hEditMenu
, hmenuContents
, 0, 0, 0xFFFF, 0);
1112 ::DestroyMenu(hmenuContents
);
1117 HRESULT
CDefView::FillViewMenu()
1119 HMENU hViewMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_VIEW
);
1123 m_hMenuViewModes
= ::LoadMenuW(shell32_hInstance
, L
"MENU_001");
1124 if (!m_hMenuViewModes
)
1127 UINT i
= SHMenuIndexFromID(hViewMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
);
1128 Shell_MergeMenus(hViewMenu
, m_hMenuViewModes
, i
, 0, 0xFFFF, MM_ADDSEPARATOR
| MM_DONTREMOVESEPS
| MM_SUBMENUSHAVEIDS
);
1133 HRESULT
CDefView::FillArrangeAsMenu(HMENU hmenuArrange
)
1135 /* We only need to fill this once */
1136 if (GetMenuItemID(hmenuArrange
, 0) == FCIDM_SHVIEW_AUTOARRANGE
)
1138 Shell_MergeMenus(hmenuArrange
, m_hMenuArrangeModes
, 0, 0, 0xFFFF,0);
1141 /* Also check the menu item according to which we sort */
1142 CheckMenuRadioItem(hmenuArrange
,
1145 m_sortInfo
.nHeaderID
+ 0x30,
1151 HRESULT
CDefView::CheckViewMode(HMENU hmenuView
)
1153 if (m_FolderSettings
.ViewMode
>= FVM_FIRST
&& m_FolderSettings
.ViewMode
<= FVM_LAST
)
1155 UINT iItemFirst
= FCIDM_SHVIEW_BIGICON
;
1156 UINT iItemLast
= iItemFirst
+ FVM_LAST
- FVM_FIRST
;
1157 UINT iItem
= iItemFirst
+ m_FolderSettings
.ViewMode
- FVM_FIRST
;
1158 CheckMenuRadioItem(hmenuView
, iItemFirst
, iItemLast
, iItem
, MF_BYCOMMAND
);
1164 /**********************************************************
1165 * ShellView_GetSelections()
1167 * - fills the m_apidl list with the selected objects
1170 * number of selected items
1172 UINT
CDefView::GetSelections()
1176 m_cidl
= m_ListView
.GetSelectedCount();
1177 m_apidl
= static_cast<PCUITEMID_CHILD
*>(SHAlloc(m_cidl
* sizeof(PCUITEMID_CHILD
)));
1184 TRACE("-- Items selected =%u\n", m_cidl
);
1188 while ((lvIndex
= m_ListView
.GetNextItem(lvIndex
, LVNI_SELECTED
)) > -1)
1190 m_apidl
[i
] = _PidlByItem(lvIndex
);
1194 TRACE("-- selected Item found\n");
1200 HRESULT
CDefView::InvokeContextMenuCommand(UINT uCommand
)
1202 CMINVOKECOMMANDINFO cmi
;
1204 ZeroMemory(&cmi
, sizeof(cmi
));
1205 cmi
.cbSize
= sizeof(cmi
);
1206 cmi
.lpVerb
= MAKEINTRESOURCEA(uCommand
);
1209 if (GetKeyState(VK_SHIFT
) & 0x8000)
1210 cmi
.fMask
|= CMIC_MASK_SHIFT_DOWN
;
1212 if (GetKeyState(VK_CONTROL
) & 0x8000)
1213 cmi
.fMask
|= CMIC_MASK_CONTROL_DOWN
;
1215 HRESULT hr
= m_pCM
->InvokeCommand(&cmi
);
1216 if (FAILED_UNEXPECTEDLY(hr
))
1222 /**********************************************************
1223 * ShellView_OpenSelectedItems()
1225 HRESULT
CDefView::OpenSelectedItems()
1231 m_cidl
= m_ListView
.GetSelectedCount();
1235 hResult
= OnDefaultCommand();
1236 if (hResult
== S_OK
)
1239 hMenu
= CreatePopupMenu();
1243 hResult
= GetItemObject(SVGIO_SELECTION
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1244 if (FAILED_UNEXPECTEDLY(hResult
))
1247 IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1249 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, 0x20, 0x7fff, CMF_DEFAULTONLY
);
1250 if (FAILED_UNEXPECTEDLY(hResult
))
1253 uCommand
= GetMenuDefaultItem(hMenu
, FALSE
, 0);
1254 if (uCommand
== (UINT
)-1)
1260 InvokeContextMenuCommand(uCommand
);
1269 IUnknown_SetSite(m_pCM
, NULL
);
1276 /**********************************************************
1277 * ShellView_DoContextMenu()
1279 LRESULT
CDefView::OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1288 TRACE("(%p)->(0x%08x 0x%08x) stub\n", this, x
, y
);
1290 m_hContextMenu
= CreatePopupMenu();
1291 if (!m_hContextMenu
)
1294 m_cidl
= m_ListView
.GetSelectedCount();
1296 hResult
= GetItemObject( m_cidl
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1297 if (FAILED_UNEXPECTEDLY(hResult
))
1300 IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1302 hResult
= m_pCM
->QueryContextMenu(m_hContextMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1303 if (FAILED_UNEXPECTEDLY(hResult
))
1306 uCommand
= TrackPopupMenu(m_hContextMenu
,
1307 TPM_LEFTALIGN
| TPM_RETURNCMD
| TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
,
1308 x
, y
, 0, m_hWnd
, NULL
);
1312 if (uCommand
== FCIDM_SHVIEW_OPEN
&& OnDefaultCommand() == S_OK
)
1315 InvokeContextMenuCommand(uCommand
);
1320 IUnknown_SetSite(m_pCM
, NULL
);
1326 DestroyMenu(m_hContextMenu
);
1327 m_hContextMenu
= NULL
;
1333 LRESULT
CDefView::OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
)
1338 hMenu
= CreatePopupMenu();
1342 hResult
= GetItemObject( bUseSelection
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1343 if (FAILED_UNEXPECTEDLY( hResult
))
1346 IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1348 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1349 if (FAILED_UNEXPECTEDLY( hResult
))
1352 InvokeContextMenuCommand(uCommand
);
1357 IUnknown_SetSite(m_pCM
, NULL
);
1367 /**********************************************************
1368 * ##### message handling #####
1371 /**********************************************************
1372 * ShellView_OnSize()
1374 LRESULT
CDefView::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1376 WORD wWidth
, wHeight
;
1378 wWidth
= LOWORD(lParam
);
1379 wHeight
= HIWORD(lParam
);
1381 TRACE("%p width=%u height=%u\n", this, wWidth
, wHeight
);
1383 /* Resize the ListView to fit our window */
1386 ::MoveWindow(m_ListView
, 0, 0, wWidth
, wHeight
, TRUE
);
1392 /**********************************************************
1393 * ShellView_OnDeactivate()
1398 void CDefView::OnDeactivate()
1400 TRACE("%p\n", this);
1402 if (m_uState
!= SVUIA_DEACTIVATE
)
1404 // TODO: cleanup menu after deactivation
1406 m_uState
= SVUIA_DEACTIVATE
;
1410 void CDefView::DoActivate(UINT uState
)
1412 TRACE("%p uState=%x\n", this, uState
);
1414 /*don't do anything if the state isn't really changing */
1415 if (m_uState
== uState
)
1420 if (uState
== SVUIA_DEACTIVATE
)
1426 if(m_hMenu
&& !m_bmenuBarInitialized
)
1430 m_pShellBrowser
->SetMenuSB(m_hMenu
, 0, m_hWnd
);
1431 m_bmenuBarInitialized
= TRUE
;
1434 if (SVUIA_ACTIVATE_FOCUS
== uState
)
1436 m_ListView
.SetFocus();
1444 /**********************************************************
1445 * ShellView_OnActivate()
1447 LRESULT
CDefView::OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1449 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1453 /**********************************************************
1454 * ShellView_OnSetFocus()
1457 LRESULT
CDefView::OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1459 TRACE("%p\n", this);
1461 /* Tell the browser one of our windows has received the focus. This
1462 should always be done before merging menus (OnActivate merges the
1463 menus) if one of our windows has the focus.*/
1465 m_pShellBrowser
->OnViewWindowActive(this);
1466 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1468 /* Set the focus to the listview */
1469 m_ListView
.SetFocus();
1471 /* Notify the ICommDlgBrowser interface */
1472 OnStateChange(CDBOSC_SETFOCUS
);
1477 /**********************************************************
1478 * ShellView_OnKillFocus()
1480 LRESULT
CDefView::OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1482 TRACE("(%p) stub\n", this);
1484 DoActivate(SVUIA_ACTIVATE_NOFOCUS
);
1485 /* Notify the ICommDlgBrowser */
1486 OnStateChange(CDBOSC_KILLFOCUS
);
1491 /**********************************************************
1492 * ShellView_OnCommand()
1495 * the CmdID's are the ones from the context menu
1497 LRESULT
CDefView::OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1504 dwCmdID
= GET_WM_COMMAND_ID(wParam
, lParam
);
1505 dwCmd
= GET_WM_COMMAND_CMD(wParam
, lParam
);
1506 hwndCmd
= GET_WM_COMMAND_HWND(wParam
, lParam
);
1508 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n", this, dwCmdID
, dwCmd
, hwndCmd
);
1512 case FCIDM_SHVIEW_SMALLICON
:
1513 m_FolderSettings
.ViewMode
= FVM_SMALLICON
;
1514 SetStyle (LVS_SMALLICON
, LVS_TYPEMASK
);
1518 case FCIDM_SHVIEW_BIGICON
:
1519 m_FolderSettings
.ViewMode
= FVM_ICON
;
1520 SetStyle (LVS_ICON
, LVS_TYPEMASK
);
1524 case FCIDM_SHVIEW_LISTVIEW
:
1525 m_FolderSettings
.ViewMode
= FVM_LIST
;
1526 SetStyle (LVS_LIST
, LVS_TYPEMASK
);
1530 case FCIDM_SHVIEW_REPORTVIEW
:
1531 m_FolderSettings
.ViewMode
= FVM_DETAILS
;
1532 SetStyle (LVS_REPORT
, LVS_TYPEMASK
);
1536 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1541 m_sortInfo
.nHeaderID
= dwCmdID
- 0x30;
1542 m_sortInfo
.bIsAscending
= TRUE
;
1543 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
1544 m_ListView
.SortItems(ListViewCompareItems
, this);
1547 case FCIDM_SHVIEW_SNAPTOGRID
:
1548 case FCIDM_SHVIEW_AUTOARRANGE
:
1551 case FCIDM_SHVIEW_SELECTALL
:
1552 m_ListView
.SetItemState(-1, LVIS_SELECTED
, LVIS_SELECTED
);
1555 case FCIDM_SHVIEW_INVERTSELECTION
:
1556 nCount
= m_ListView
.GetItemCount();
1557 for (int i
=0; i
< nCount
; i
++)
1558 m_ListView
.SetItemState(i
, m_ListView
.GetItemState(i
, LVIS_SELECTED
) ? 0 : LVIS_SELECTED
, LVIS_SELECTED
);
1561 case FCIDM_SHVIEW_REFRESH
:
1565 case FCIDM_SHVIEW_DELETE
:
1566 case FCIDM_SHVIEW_CUT
:
1567 case FCIDM_SHVIEW_COPY
:
1568 case FCIDM_SHVIEW_RENAME
:
1569 return OnExplorerCommand(dwCmdID
, TRUE
);
1571 case FCIDM_SHVIEW_INSERT
:
1572 case FCIDM_SHVIEW_UNDO
:
1573 case FCIDM_SHVIEW_INSERTLINK
:
1574 case FCIDM_SHVIEW_NEWFOLDER
:
1575 return OnExplorerCommand(dwCmdID
, FALSE
);
1577 /* WM_COMMAND messages from the file menu are routed to the CDefView so as to let m_pCM handle the command */
1580 InvokeContextMenuCommand(dwCmdID
);
1587 /**********************************************************
1588 * ShellView_OnNotify()
1591 LRESULT
CDefView::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1595 LPNMLISTVIEW lpnmlv
;
1596 NMLVDISPINFOW
*lpdi
;
1597 PCUITEMID_CHILD pidl
;
1601 lpnmh
= (LPNMHDR
)lParam
;
1602 lpnmlv
= (LPNMLISTVIEW
)lpnmh
;
1603 lpdi
= (NMLVDISPINFOW
*)lpnmh
;
1605 TRACE("%p CtlID=%u lpnmh->code=%x\n", this, CtlID
, lpnmh
->code
);
1607 switch (lpnmh
->code
)
1610 TRACE("-- NM_SETFOCUS %p\n", this);
1611 OnSetFocus(0, 0, 0, unused
);
1615 TRACE("-- NM_KILLFOCUS %p\n", this);
1617 /* Notify the ICommDlgBrowser interface */
1618 OnStateChange(CDBOSC_KILLFOCUS
);
1622 TRACE("-- NM_CUSTOMDRAW %p\n", this);
1623 return CDRF_DODEFAULT
;
1625 case NM_RELEASEDCAPTURE
:
1626 TRACE("-- NM_RELEASEDCAPTURE %p\n", this);
1630 TRACE("-- NM_CLICK %p\n", this);
1634 TRACE("-- NM_RCLICK %p\n", this);
1638 TRACE("-- NM_DBLCLK %p\n", this);
1639 OpenSelectedItems();
1643 TRACE("-- NM_RETURN %p\n", this);
1644 OpenSelectedItems();
1648 TRACE("-- HDN_ENDTRACKW %p\n", this);
1649 /*nColumn1 = m_ListView.GetColumnWidth(0);
1650 nColumn2 = m_ListView.GetColumnWidth(1);*/
1653 case LVN_DELETEITEM
:
1654 TRACE("-- LVN_DELETEITEM %p\n", this);
1656 /*delete the pidl because we made a copy of it*/
1657 SHFree(reinterpret_cast<LPVOID
>(lpnmlv
->lParam
));
1661 case LVN_DELETEALLITEMS
:
1662 TRACE("-- LVN_DELETEALLITEMS %p\n", this);
1665 case LVN_INSERTITEM
:
1666 TRACE("-- LVN_INSERTITEM (STUB)%p\n", this);
1669 case LVN_ITEMACTIVATE
:
1670 TRACE("-- LVN_ITEMACTIVATE %p\n", this);
1671 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1674 case LVN_COLUMNCLICK
:
1675 m_sortInfo
.nHeaderID
= lpnmlv
->iSubItem
;
1676 if (m_sortInfo
.nLastHeaderID
== m_sortInfo
.nHeaderID
)
1677 m_sortInfo
.bIsAscending
= !m_sortInfo
.bIsAscending
;
1679 m_sortInfo
.bIsAscending
= TRUE
;
1680 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
1682 m_ListView
.SortItems(ListViewCompareItems
, this);
1685 case LVN_GETDISPINFOA
:
1686 case LVN_GETDISPINFOW
:
1687 TRACE("-- LVN_GETDISPINFO %p\n", this);
1688 pidl
= _PidlByItem(lpdi
->item
);
1690 if (lpdi
->item
.mask
& LVIF_TEXT
) /* text requested */
1695 if (FAILED_UNEXPECTEDLY(m_pSF2Parent
->GetDetailsOf(pidl
, lpdi
->item
.iSubItem
, &sd
)))
1698 if (lpnmh
->code
== LVN_GETDISPINFOA
)
1700 /* shouldn't happen */
1701 NMLVDISPINFOA
*lpdiA
= (NMLVDISPINFOA
*)lpnmh
;
1702 StrRetToStrNA( lpdiA
->item
.pszText
, lpdiA
->item
.cchTextMax
, &sd
.str
, NULL
);
1703 TRACE("-- text=%s\n", lpdiA
->item
.pszText
);
1705 else /* LVN_GETDISPINFOW */
1707 StrRetToStrNW( lpdi
->item
.pszText
, lpdi
->item
.cchTextMax
, &sd
.str
, NULL
);
1708 TRACE("-- text=%s\n", debugstr_w(lpdi
->item
.pszText
));
1713 FIXME("no m_pSF2Parent\n");
1716 if(lpdi
->item
.mask
& LVIF_IMAGE
) /* image requested */
1718 lpdi
->item
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
1720 if(lpdi
->item
.mask
& LVIF_STATE
)
1722 ULONG attributes
= SFGAO_HIDDEN
;
1723 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(1, &pidl
, &attributes
)))
1725 if (attributes
& SFGAO_HIDDEN
)
1727 lpdi
->item
.state
|= LVIS_CUT
;
1731 lpdi
->item
.mask
|= LVIF_DI_SETITEM
;
1734 case LVN_ITEMCHANGED
:
1735 TRACE("-- LVN_ITEMCHANGED %p\n", this);
1736 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1741 case LVN_BEGINRDRAG
:
1742 TRACE("-- LVN_BEGINDRAG\n");
1744 if (GetSelections())
1746 CComPtr
<IDataObject
> pda
;
1747 DWORD dwAttributes
= SFGAO_CANLINK
;
1748 DWORD dwEffect
= DROPEFFECT_COPY
| DROPEFFECT_MOVE
;
1750 if (SUCCEEDED(m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, IID_NULL_PPV_ARG(IDataObject
, &pda
))))
1752 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(m_cidl
, m_apidl
, &dwAttributes
)))
1754 if (dwAttributes
& SFGAO_CANLINK
)
1756 dwEffect
|= DROPEFFECT_LINK
;
1760 CComPtr
<IAsyncOperation
> piaso
;
1761 if (SUCCEEDED(pda
->QueryInterface(IID_PPV_ARG(IAsyncOperation
, &piaso
))))
1763 piaso
->SetAsyncMode(TRUE
);
1768 m_pSourceDataObject
= pda
;
1770 DoDragDrop(pda
, this, dwEffect
, &dwEffect2
);
1772 m_pSourceDataObject
.Release();
1777 case LVN_BEGINLABELEDITW
:
1779 DWORD dwAttr
= SFGAO_CANRENAME
;
1780 pidl
= _PidlByItem(lpdi
->item
);
1782 TRACE("-- LVN_BEGINLABELEDITW %p\n", this);
1784 m_pSFParent
->GetAttributesOf(1, &pidl
, &dwAttr
);
1785 if (SFGAO_CANRENAME
& dwAttr
)
1793 case LVN_ENDLABELEDITW
:
1795 TRACE("-- LVN_ENDLABELEDITW %p\n", this);
1797 m_isEditing
= FALSE
;
1799 if (lpdi
->item
.pszText
)
1804 pidl
= _PidlByItem(lpdi
->item
);
1805 PITEMID_CHILD pidlNew
;
1806 hr
= m_pSFParent
->SetNameOf(0, pidl
, lpdi
->item
.pszText
, SHGDN_INFOLDER
, &pidlNew
);
1808 if (SUCCEEDED(hr
) && pidlNew
)
1810 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
1811 lvItem
.iItem
= lpdi
->item
.iItem
;
1812 lvItem
.iSubItem
= 0;
1813 lvItem
.lParam
= reinterpret_cast<LPARAM
>(pidlNew
);
1814 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
1815 m_ListView
.SetItem(&lvItem
);
1816 m_ListView
.Update(lpdi
->item
.iItem
);
1825 TRACE("-- %p WM_COMMAND %x unhandled\n", this, lpnmh
->code
);
1833 * This is just a quick hack to make the desktop work correctly.
1834 * ITranslateShellChangeNotify's IsChildID is undocumented, but most likely the way that
1835 * a folder should know if it should update upon a change notification.
1836 * It is exported by merged folders at a minimum.
1838 static BOOL
ILIsParentOrSpecialParent(PCIDLIST_ABSOLUTE pidl1
, PCIDLIST_ABSOLUTE pidl2
)
1840 if (!pidl1
|| !pidl2
)
1842 if (ILIsParent(pidl1
, pidl2
, TRUE
))
1845 if (_ILIsDesktop(pidl1
))
1847 PIDLIST_ABSOLUTE deskpidl
;
1848 SHGetFolderLocation(NULL
, CSIDL_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
1849 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
1855 SHGetFolderLocation(NULL
, CSIDL_COMMON_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
1856 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
1866 /**********************************************************
1867 * ShellView_OnChange()
1869 LRESULT
CDefView::OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1871 PCIDLIST_ABSOLUTE
*Pidls
= reinterpret_cast<PCIDLIST_ABSOLUTE
*>(wParam
);
1872 BOOL bParent0
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[0]);
1873 BOOL bParent1
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[1]);
1875 TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls
[0], Pidls
[1], lParam
);
1877 switch (lParam
&~ SHCNE_INTERRUPT
)
1883 if (LV_FindItemByPidl(ILFindLastID(Pidls
[0])) == -1)
1885 LV_AddItem(ILFindLastID(Pidls
[0]));
1889 LV_ProdItem(ILFindLastID(Pidls
[0]));
1897 LV_DeleteItem(ILFindLastID(Pidls
[0]));
1900 case SHCNE_RENAMEFOLDER
:
1901 case SHCNE_RENAMEITEM
:
1902 if (bParent0
&& bParent1
)
1903 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[1]));
1905 LV_DeleteItem(ILFindLastID(Pidls
[0]));
1907 LV_AddItem(ILFindLastID(Pidls
[1]));
1910 case SHCNE_UPDATEITEM
:
1912 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[0]));
1915 case SHCNE_UPDATEDIR
:
1922 /**********************************************************
1923 * CDefView::OnCustomItem
1925 LRESULT
CDefView::OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1930 ERR("no menu!!!\n");
1935 HRESULT hres
= SHForwardContextMenuMsg(m_pCM
, uMsg
, wParam
, lParam
, &result
, TRUE
);
1936 if (SUCCEEDED(hres
))
1942 LRESULT
CDefView::OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1944 /* Wallpaper setting affects drop shadows effect */
1945 if (wParam
== SPI_SETDESKWALLPAPER
|| wParam
== 0)
1951 /**********************************************************
1952 * CDefView::OnInitMenuPopup
1954 LRESULT
CDefView::OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1956 HMENU hmenu
= (HMENU
) wParam
;
1957 int nPos
= LOWORD(lParam
);
1960 OnCustomItem(uMsg
, wParam
, lParam
, bHandled
);
1962 HMENU hViewMenu
= GetSubmenuByID(m_hMenu
, FCIDM_MENU_VIEW
);
1964 /* Lets try to find out what the hell wParam is */
1965 if (hmenu
== GetSubMenu(m_hMenu
, nPos
))
1966 menuItemId
= ReallyGetMenuItemID(m_hMenu
, nPos
);
1967 else if (hViewMenu
&& hmenu
== GetSubMenu(hViewMenu
, nPos
))
1968 menuItemId
= ReallyGetMenuItemID(hViewMenu
, nPos
);
1969 else if (m_hContextMenu
&& hmenu
== GetSubMenu(m_hContextMenu
, nPos
))
1970 menuItemId
= ReallyGetMenuItemID(m_hContextMenu
, nPos
);
1976 case FCIDM_MENU_FILE
:
1979 case FCIDM_MENU_VIEW
:
1980 case FCIDM_SHVIEW_VIEW
:
1981 CheckViewMode(hmenu
);
1983 case FCIDM_SHVIEW_ARRANGE
:
1984 FillArrangeAsMenu(hmenu
);
1991 /**********************************************************
1994 * The INTERFACE of the IShellView object
1997 **********************************************************
2000 /**********************************************************
2001 * ShellView_GetWindow
2003 HRESULT WINAPI
CDefView::GetWindow(HWND
*phWnd
)
2005 TRACE("(%p)\n", this);
2012 HRESULT WINAPI
CDefView::ContextSensitiveHelp(BOOL fEnterMode
)
2014 FIXME("(%p) stub\n", this);
2019 /**********************************************************
2020 * IShellView_TranslateAccelerator
2023 * use the accel functions
2025 HRESULT WINAPI
CDefView::TranslateAccelerator(LPMSG lpmsg
)
2030 if (lpmsg
->message
>= WM_KEYFIRST
&& lpmsg
->message
<= WM_KEYLAST
)
2032 if (::TranslateAcceleratorW(m_hWnd
, m_hAccel
, lpmsg
) != 0)
2035 TRACE("-- key=0x04%lx\n", lpmsg
->wParam
) ;
2038 return m_pShellBrowser
->TranslateAcceleratorSB(lpmsg
, 0);
2041 HRESULT WINAPI
CDefView::EnableModeless(BOOL fEnable
)
2043 FIXME("(%p) stub\n", this);
2048 HRESULT WINAPI
CDefView::UIActivate(UINT uState
)
2050 // CHAR szName[MAX_PATH];
2052 int nPartArray
[1] = { -1};
2054 TRACE("(%p)->(state=%x) stub\n", this, uState
);
2056 /* don't do anything if the state isn't really changing */
2057 if (m_uState
== uState
)
2062 /* OnActivate handles the menu merging and internal state */
2065 /* only do This if we are active */
2066 if (uState
!= SVUIA_DEACTIVATE
)
2070 GetFolderPath is not a method of IShellFolder
2071 IShellFolder_GetFolderPath( m_pSFParent, szName, sizeof(szName) );
2073 /* set the number of parts */
2074 m_pShellBrowser
->SendControlMsg(FCW_STATUS
, SB_SETPARTS
, 1, (LPARAM
)nPartArray
, &lResult
);
2076 /* set the text for the parts */
2078 m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXTA, 0, (LPARAM)szName, &lResult);
2085 HRESULT WINAPI
CDefView::Refresh()
2087 TRACE("(%p)\n", this);
2089 m_ListView
.DeleteAllItems();
2095 HRESULT WINAPI
CDefView::CreateViewWindow(IShellView
*lpPrevView
, LPCFOLDERSETTINGS lpfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
)
2097 return CreateViewWindow3(psb
, lpPrevView
, SV3CVW3_DEFAULT
,
2098 (FOLDERFLAGS
)lpfs
->fFlags
, (FOLDERFLAGS
)lpfs
->fFlags
, (FOLDERVIEWMODE
)lpfs
->ViewMode
, NULL
, prcView
, phWnd
);
2101 HRESULT WINAPI
CDefView::DestroyViewWindow()
2103 TRACE("(%p)\n", this);
2105 /* Make absolutely sure all our UI is cleaned up */
2106 UIActivate(SVUIA_DEACTIVATE
);
2110 // "Accelerator tables loaded from resources are freed automatically when the application terminates." -- MSDN
2114 if (m_hMenuViewModes
)
2116 DestroyMenu(m_hMenuViewModes
);
2117 m_hMenuViewModes
= NULL
;
2122 DestroyMenu(m_hMenu
);
2128 m_ListView
.DestroyWindow();
2136 m_pShellBrowser
.Release();
2137 m_pCommDlgBrowser
.Release();
2142 HRESULT WINAPI
CDefView::GetCurrentInfo(LPFOLDERSETTINGS lpfs
)
2144 TRACE("(%p)->(%p) vmode=%x flags=%x\n", this, lpfs
,
2145 m_FolderSettings
.ViewMode
, m_FolderSettings
.fFlags
);
2148 return E_INVALIDARG
;
2150 *lpfs
= m_FolderSettings
;
2154 HRESULT WINAPI
CDefView::AddPropertySheetPages(DWORD dwReserved
, LPFNADDPROPSHEETPAGE lpfn
, LPARAM lparam
)
2156 FIXME("(%p) stub\n", this);
2161 HRESULT WINAPI
CDefView::SaveViewState()
2163 FIXME("(%p) stub\n", this);
2168 HRESULT WINAPI
CDefView::SelectItem(PCUITEMID_CHILD pidl
, UINT uFlags
)
2172 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n", this, pidl
, uFlags
);
2174 i
= LV_FindItemByPidl(pidl
);
2178 if(uFlags
& SVSI_ENSUREVISIBLE
)
2179 m_ListView
.EnsureVisible(i
, FALSE
);
2181 LVITEMW lvItem
= {0};
2182 lvItem
.mask
= LVIF_STATE
;
2183 lvItem
.stateMask
= LVIS_SELECTED
| LVIS_FOCUSED
;
2185 while (m_ListView
.GetItem(&lvItem
))
2187 if (lvItem
.iItem
== i
)
2189 if (uFlags
& SVSI_SELECT
)
2190 lvItem
.state
|= LVIS_SELECTED
;
2192 lvItem
.state
&= ~LVIS_SELECTED
;
2194 if (uFlags
& SVSI_FOCUSED
)
2195 lvItem
.state
&= ~LVIS_FOCUSED
;
2199 if (uFlags
& SVSI_DESELECTOTHERS
)
2200 lvItem
.state
&= ~LVIS_SELECTED
;
2203 m_ListView
.SetItem(&lvItem
);
2207 if((uFlags
& SVSI_EDIT
) == SVSI_EDIT
)
2208 m_ListView
.EditLabel(i
);
2213 HRESULT WINAPI
CDefView::GetItemObject(UINT uItem
, REFIID riid
, LPVOID
*ppvOut
)
2215 HRESULT hr
= E_NOINTERFACE
;
2217 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n", this, uItem
, debugstr_guid(&riid
), ppvOut
);
2223 case SVGIO_BACKGROUND
:
2224 if (IsEqualIID(riid
, IID_IContextMenu
))
2226 //*ppvOut = ISvBgCm_Constructor(m_pSFParent, FALSE);
2231 hr
= CDefFolderMenu_Create2(NULL
, NULL
, 0, NULL
, m_pSFParent
, NULL
, 0, NULL
, &pcm
);
2232 if (FAILED_UNEXPECTEDLY(hr
))
2236 else if (IsEqualIID(riid
, IID_IDispatch
))
2238 if (m_pShellFolderViewDual
== NULL
)
2240 hr
= CDefViewDual_Constructor(riid
, (LPVOID
*)&m_pShellFolderViewDual
);
2241 if (FAILED_UNEXPECTEDLY(hr
))
2244 hr
= m_pShellFolderViewDual
->QueryInterface(riid
, ppvOut
);
2248 case SVGIO_SELECTION
:
2250 hr
= m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, riid
, 0, ppvOut
);
2251 if (FAILED_UNEXPECTEDLY(hr
))
2256 TRACE("-- (%p)->(interface=%p)\n", this, *ppvOut
);
2261 HRESULT STDMETHODCALLTYPE
CDefView::GetCurrentViewMode(UINT
*pViewMode
)
2263 TRACE("(%p)->(%p), stub\n", this, pViewMode
);
2266 return E_INVALIDARG
;
2268 *pViewMode
= m_FolderSettings
.ViewMode
;
2272 HRESULT STDMETHODCALLTYPE
CDefView::SetCurrentViewMode(UINT ViewMode
)
2275 TRACE("(%p)->(%u), stub\n", this, ViewMode
);
2277 /* It's not redundant to check FVM_AUTO because it's a (UINT)-1 */
2278 if (((INT
)ViewMode
< FVM_FIRST
|| (INT
)ViewMode
> FVM_LAST
) && ((INT
)ViewMode
!= FVM_AUTO
))
2279 return E_INVALIDARG
;
2281 /* Windows before Vista uses LVM_SETVIEW and possibly
2282 LVM_SETEXTENDEDLISTVIEWSTYLE to set the style of the listview,
2283 while later versions seem to accomplish this through other
2291 dwStyle
= LVS_REPORT
;
2294 dwStyle
= LVS_SMALLICON
;
2301 FIXME("ViewMode %d not implemented\n", ViewMode
);
2307 SetStyle(dwStyle
, LVS_TYPEMASK
);
2309 /* This will not necessarily be the actual mode set above.
2310 This mimics the behavior of Windows XP. */
2311 m_FolderSettings
.ViewMode
= ViewMode
;
2316 HRESULT STDMETHODCALLTYPE
CDefView::GetFolder(REFIID riid
, void **ppv
)
2318 if (m_pSFParent
== NULL
)
2321 return m_pSFParent
->QueryInterface(riid
, ppv
);
2324 HRESULT STDMETHODCALLTYPE
CDefView::Item(int iItemIndex
, PITEMID_CHILD
*ppidl
)
2326 PCUITEMID_CHILD pidl
= _PidlByItem(iItemIndex
);
2329 *ppidl
= ILClone(pidl
);
2334 return E_INVALIDARG
;
2337 HRESULT STDMETHODCALLTYPE
CDefView::ItemCount(UINT uFlags
, int *pcItems
)
2339 TRACE("(%p)->(%u %p)\n", this, uFlags
, pcItems
);
2341 if (uFlags
!= SVGIO_ALLVIEW
)
2342 FIXME("some flags unsupported, %x\n", uFlags
& ~SVGIO_ALLVIEW
);
2344 *pcItems
= m_ListView
.GetItemCount();
2349 HRESULT STDMETHODCALLTYPE
CDefView::Items(UINT uFlags
, REFIID riid
, void **ppv
)
2354 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectionMarkedItem(int *piItem
)
2356 TRACE("(%p)->(%p)\n", this, piItem
);
2358 *piItem
= m_ListView
.GetSelectionMark();
2363 HRESULT STDMETHODCALLTYPE
CDefView::GetFocusedItem(int *piItem
)
2365 TRACE("(%p)->(%p)\n", this, piItem
);
2367 *piItem
= m_ListView
.GetNextItem(-1, LVNI_FOCUSED
);
2372 HRESULT STDMETHODCALLTYPE
CDefView::GetItemPosition(PCUITEMID_CHILD pidl
, POINT
*ppt
)
2377 HRESULT STDMETHODCALLTYPE
CDefView::GetSpacing(POINT
*ppt
)
2379 TRACE("(%p)->(%p)\n", this, ppt
);
2387 m_ListView
.GetItemSpacing(spacing
);
2389 ppt
->x
= spacing
.cx
;
2390 ppt
->y
= spacing
.cy
;
2396 HRESULT STDMETHODCALLTYPE
CDefView::GetDefaultSpacing(POINT
*ppt
)
2401 HRESULT STDMETHODCALLTYPE
CDefView::GetAutoArrange()
2406 HRESULT STDMETHODCALLTYPE
CDefView::SelectItem(int iItem
, DWORD dwFlags
)
2410 TRACE("(%p)->(%d, %x)\n", this, iItem
, dwFlags
);
2413 lvItem
.stateMask
= LVIS_SELECTED
;
2415 if (dwFlags
& SVSI_ENSUREVISIBLE
)
2416 m_ListView
.EnsureVisible(iItem
, 0);
2419 if (dwFlags
& SVSI_DESELECTOTHERS
)
2420 m_ListView
.SetItemState(-1, 0, LVIS_SELECTED
);
2423 if (dwFlags
& SVSI_SELECT
)
2424 lvItem
.state
|= LVIS_SELECTED
;
2426 if (dwFlags
& SVSI_FOCUSED
)
2427 lvItem
.stateMask
|= LVIS_FOCUSED
;
2429 m_ListView
.SetItemState(iItem
, lvItem
.state
, lvItem
.stateMask
);
2431 if (dwFlags
& SVSI_EDIT
)
2432 m_ListView
.EditLabel(iItem
);
2437 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItems(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD dwFlags
)
2442 /**********************************************************
2443 * IShellView2 implementation
2446 HRESULT STDMETHODCALLTYPE
CDefView::GetView(SHELLVIEWID
*view_guid
, ULONG view_type
)
2448 FIXME("(%p)->(%p, %lu) stub\n", this, view_guid
, view_type
);
2452 HRESULT STDMETHODCALLTYPE
CDefView::CreateViewWindow2(LPSV2CVW2_PARAMS view_params
)
2454 return CreateViewWindow3(view_params
->psbOwner
, view_params
->psvPrev
,
2455 SV3CVW3_DEFAULT
, (FOLDERFLAGS
)view_params
->pfs
->fFlags
, (FOLDERFLAGS
)view_params
->pfs
->fFlags
,
2456 (FOLDERVIEWMODE
)view_params
->pfs
->ViewMode
, view_params
->pvid
, view_params
->prcView
, &view_params
->hwndView
);
2459 HRESULT STDMETHODCALLTYPE
CDefView::CreateViewWindow3(IShellBrowser
*psb
, IShellView
*psvPrevious
, SV3CVW3_FLAGS view_flags
, FOLDERFLAGS mask
, FOLDERFLAGS flags
, FOLDERVIEWMODE mode
, const SHELLVIEWID
*view_id
, RECT
*prcView
, HWND
*hwnd
)
2461 OLEMENUGROUPWIDTHS omw
= { { 0, 0, 0, 0, 0, 0 } };
2465 TRACE("(%p)->(shlview=%p shlbrs=%p rec=%p hwnd=%p vmode=%x flags=%x)\n", this, psvPrevious
, psb
, prcView
, hwnd
, mode
, flags
);
2466 if (prcView
!= NULL
)
2467 TRACE("-- left=%i top=%i right=%i bottom=%i\n", prcView
->left
, prcView
->top
, prcView
->right
, prcView
->bottom
);
2469 /* Validate the Shell Browser */
2470 if (psb
== NULL
|| m_hWnd
)
2471 return E_UNEXPECTED
;
2473 if (view_flags
!= SV3CVW3_DEFAULT
)
2474 FIXME("unsupported view flags 0x%08x\n", view_flags
);
2476 /* Set up the member variables */
2477 m_pShellBrowser
= psb
;
2478 m_FolderSettings
.ViewMode
= mode
;
2479 m_FolderSettings
.fFlags
= mask
& flags
;
2483 if (IsEqualIID(*view_id
, VID_LargeIcons
))
2484 m_FolderSettings
.ViewMode
= FVM_ICON
;
2485 else if (IsEqualIID(*view_id
, VID_SmallIcons
))
2486 m_FolderSettings
.ViewMode
= FVM_SMALLICON
;
2487 else if (IsEqualIID(*view_id
, VID_List
))
2488 m_FolderSettings
.ViewMode
= FVM_LIST
;
2489 else if (IsEqualIID(*view_id
, VID_Details
))
2490 m_FolderSettings
.ViewMode
= FVM_DETAILS
;
2491 else if (IsEqualIID(*view_id
, VID_Thumbnails
))
2492 m_FolderSettings
.ViewMode
= FVM_THUMBNAIL
;
2493 else if (IsEqualIID(*view_id
, VID_Tile
))
2494 m_FolderSettings
.ViewMode
= FVM_TILE
;
2495 else if (IsEqualIID(*view_id
, VID_ThumbStrip
))
2496 m_FolderSettings
.ViewMode
= FVM_THUMBSTRIP
;
2498 FIXME("Ignoring unrecognized VID %s\n", debugstr_guid(view_id
));
2501 /* Get our parent window */
2502 m_pShellBrowser
->GetWindow(&m_hWndParent
);
2504 /* Try to get the ICommDlgBrowserInterface, adds a reference !!! */
2505 m_pCommDlgBrowser
= NULL
;
2506 if (SUCCEEDED(m_pShellBrowser
->QueryInterface(IID_PPV_ARG(ICommDlgBrowser
, &m_pCommDlgBrowser
))))
2508 TRACE("-- CommDlgBrowser\n");
2511 Create(m_hWndParent
, prcView
, NULL
, WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
| WS_TABSTOP
, 0, 0U);
2522 SetWindowPos(HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_SHOWWINDOW
);
2527 m_hMenu
= CreateMenu();
2528 m_pShellBrowser
->InsertMenusSB(m_hMenu
, &omw
);
2529 TRACE("-- after fnInsertMenusSB\n");
2537 HRESULT STDMETHODCALLTYPE
CDefView::HandleRename(LPCITEMIDLIST new_pidl
)
2539 FIXME("(%p)->(%p) stub\n", this, new_pidl
);
2543 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItem(LPCITEMIDLIST item
, UINT flags
, POINT
*point
)
2545 FIXME("(%p)->(%p, %u, %p) stub\n", this, item
, flags
, point
);
2549 /**********************************************************
2550 * IShellFolderView implementation
2552 HRESULT STDMETHODCALLTYPE
CDefView::Rearrange(LPARAM sort
)
2554 FIXME("(%p)->(%ld) stub\n", this, sort
);
2558 HRESULT STDMETHODCALLTYPE
CDefView::GetArrangeParam(LPARAM
*sort
)
2560 FIXME("(%p)->(%p) stub\n", this, sort
);
2564 HRESULT STDMETHODCALLTYPE
CDefView::ArrangeGrid()
2566 FIXME("(%p) stub\n", this);
2570 HRESULT STDMETHODCALLTYPE
CDefView::AutoArrange()
2572 FIXME("(%p) stub\n", this);
2576 HRESULT STDMETHODCALLTYPE
CDefView::AddObject(PITEMID_CHILD pidl
, UINT
*item
)
2578 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2582 HRESULT STDMETHODCALLTYPE
CDefView::GetObject(PITEMID_CHILD
*pidl
, UINT item
)
2584 TRACE("(%p)->(%p %d)\n", this, pidl
, item
);
2585 return Item(item
, pidl
);
2588 HRESULT STDMETHODCALLTYPE
CDefView::RemoveObject(PITEMID_CHILD pidl
, UINT
*item
)
2591 TRACE("(%p)->(%p %p)\n", this, pidl
, item
);
2595 *item
= LV_FindItemByPidl(ILFindLastID(pidl
));
2596 m_ListView
.DeleteItem(*item
);
2601 m_ListView
.DeleteAllItems();
2607 HRESULT STDMETHODCALLTYPE
CDefView::GetObjectCount(UINT
*count
)
2609 TRACE("(%p)->(%p)\n", this, count
);
2610 *count
= m_ListView
.GetItemCount();
2614 HRESULT STDMETHODCALLTYPE
CDefView::SetObjectCount(UINT count
, UINT flags
)
2616 FIXME("(%p)->(%d %x) stub\n", this, count
, flags
);
2620 HRESULT STDMETHODCALLTYPE
CDefView::UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
)
2622 FIXME("(%p)->(%p %p %p) stub\n", this, pidl_old
, pidl_new
, item
);
2626 HRESULT STDMETHODCALLTYPE
CDefView::RefreshObject(PITEMID_CHILD pidl
, UINT
*item
)
2628 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2632 HRESULT STDMETHODCALLTYPE
CDefView::SetRedraw(BOOL redraw
)
2634 TRACE("(%p)->(%d)\n", this, redraw
);
2635 m_ListView
.SetRedraw(redraw
);
2639 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedCount(UINT
*count
)
2641 FIXME("(%p)->(%p) stub\n", this, count
);
2645 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
)
2647 TRACE("(%p)->(%p %p)\n", this, pidl
, items
);
2649 *items
= GetSelections();
2653 *pidl
= static_cast<PCUITEMID_CHILD
*>(LocalAlloc(0, *items
* sizeof(PCUITEMID_CHILD
)));
2656 return E_OUTOFMEMORY
;
2659 /* it's documented that caller shouldn't PIDLs, only array itself */
2660 memcpy(*pidl
, m_apidl
, *items
* sizeof(PCUITEMID_CHILD
));
2666 HRESULT STDMETHODCALLTYPE
CDefView::IsDropOnSource(IDropTarget
*drop_target
)
2668 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2672 HRESULT STDMETHODCALLTYPE
CDefView::GetDragPoint(POINT
*pt
)
2674 FIXME("(%p)->(%p) stub\n", this, pt
);
2678 HRESULT STDMETHODCALLTYPE
CDefView::GetDropPoint(POINT
*pt
)
2680 FIXME("(%p)->(%p) stub\n", this, pt
);
2684 HRESULT STDMETHODCALLTYPE
CDefView::MoveIcons(IDataObject
*obj
)
2686 TRACE("(%p)->(%p)\n", this, obj
);
2690 HRESULT STDMETHODCALLTYPE
CDefView::SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
)
2692 FIXME("(%p)->(%p %p) stub\n", this, pidl
, pt
);
2696 HRESULT STDMETHODCALLTYPE
CDefView::IsBkDropTarget(IDropTarget
*drop_target
)
2698 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2702 HRESULT STDMETHODCALLTYPE
CDefView::SetClipboard(BOOL move
)
2704 FIXME("(%p)->(%d) stub\n", this, move
);
2708 HRESULT STDMETHODCALLTYPE
CDefView::SetPoints(IDataObject
*obj
)
2710 FIXME("(%p)->(%p) stub\n", this, obj
);
2714 HRESULT STDMETHODCALLTYPE
CDefView::GetItemSpacing(ITEMSPACING
*spacing
)
2716 FIXME("(%p)->(%p) stub\n", this, spacing
);
2720 HRESULT STDMETHODCALLTYPE
CDefView::SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
)
2722 FIXME("(%p)->(%p %p) stub\n", this, new_cb
, old_cb
);
2726 HRESULT STDMETHODCALLTYPE
CDefView::Select(UINT flags
)
2728 FIXME("(%p)->(%d) stub\n", this, flags
);
2732 HRESULT STDMETHODCALLTYPE
CDefView::QuerySupport(UINT
*support
)
2734 TRACE("(%p)->(%p)\n", this, support
);
2738 HRESULT STDMETHODCALLTYPE
CDefView::SetAutomationObject(IDispatch
*disp
)
2740 FIXME("(%p)->(%p) stub\n", this, disp
);
2744 /**********************************************************
2745 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2747 HRESULT WINAPI
CDefView::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD
*prgCmds
, OLECMDTEXT
*pCmdText
)
2749 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
2750 this, pguidCmdGroup
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
2753 return E_INVALIDARG
;
2755 for (UINT i
= 0; i
< cCmds
; i
++)
2757 FIXME("\tprgCmds[%d].cmdID = %d\n", i
, prgCmds
[i
].cmdID
);
2758 prgCmds
[i
].cmdf
= 0;
2761 return OLECMDERR_E_UNKNOWNGROUP
;
2764 /**********************************************************
2765 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2767 * nCmdID is the OLECMDID_* enumeration
2769 HRESULT WINAPI
CDefView::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
2771 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2772 this, debugstr_guid(pguidCmdGroup
), nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2775 return OLECMDERR_E_UNKNOWNGROUP
;
2777 if (IsEqualCLSID(*pguidCmdGroup
, m_Category
))
2779 if (nCmdID
== FCIDM_SHVIEW_AUTOARRANGE
)
2781 if (V_VT(pvaIn
) != VT_INT_PTR
)
2782 return OLECMDERR_E_NOTSUPPORTED
;
2785 params
.cbSize
= sizeof(params
);
2786 params
.rcExclude
= *(RECT
*) V_INTREF(pvaIn
);
2788 if (m_hMenuViewModes
)
2790 /* Duplicate all but the last two items of the view modes menu */
2791 HMENU hmenuViewPopup
= CreatePopupMenu();
2792 Shell_MergeMenus(hmenuViewPopup
, m_hMenuViewModes
, 0, 0, 0xFFFF, 0);
2793 DeleteMenu(hmenuViewPopup
, GetMenuItemCount(hmenuViewPopup
) - 1, MF_BYPOSITION
);
2794 DeleteMenu(hmenuViewPopup
, GetMenuItemCount(hmenuViewPopup
) - 1, MF_BYPOSITION
);
2795 CheckViewMode(hmenuViewPopup
);
2796 TrackPopupMenuEx(hmenuViewPopup
, TPM_LEFTALIGN
| TPM_TOPALIGN
, params
.rcExclude
.left
, params
.rcExclude
.bottom
, m_hWndParent
, ¶ms
);
2797 ::DestroyMenu(hmenuViewPopup
);
2800 // pvaOut is VT_I4 with value 0x403 (cmd id of the new mode maybe?)
2801 V_VT(pvaOut
) = VT_I4
;
2802 V_I4(pvaOut
) = 0x403;
2806 if (IsEqualIID(*pguidCmdGroup
, CGID_Explorer
) &&
2808 (nCmdexecopt
== 4) && pvaOut
)
2811 if (IsEqualIID(*pguidCmdGroup
, CGID_ShellDocView
) &&
2816 return OLECMDERR_E_UNKNOWNGROUP
;
2819 /**********************************************************
2820 * ISVDropTarget implementation
2823 /******************************************************************************
2824 * drag_notify_subitem [Internal]
2826 * Figure out the shellfolder object, which is currently under the mouse cursor
2827 * and notify it via the IDropTarget interface.
2830 #define SCROLLAREAWIDTH 20
2832 HRESULT
CDefView::drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2834 LVHITTESTINFO htinfo
;
2839 /* Map from global to client coordinates and query the index of the listview-item, which is
2840 * currently under the mouse cursor. */
2843 htinfo
.flags
= LVHT_ONITEM
;
2844 ::ScreenToClient(m_ListView
, &htinfo
.pt
);
2845 lResult
= m_ListView
.HitTest(&htinfo
);
2847 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2848 ::GetClientRect(m_ListView
, &clientRect
);
2849 if (htinfo
.pt
.x
== m_ptLastMousePos
.x
&& htinfo
.pt
.y
== m_ptLastMousePos
.y
&&
2850 (htinfo
.pt
.x
< SCROLLAREAWIDTH
|| htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
||
2851 htinfo
.pt
.y
< SCROLLAREAWIDTH
|| htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
))
2853 m_cScrollDelay
= (m_cScrollDelay
+ 1) % 5; /* DragOver is called every 50 ms */
2854 if (m_cScrollDelay
== 0)
2856 /* Mouse did hover another 250 ms over the scroll-area */
2857 if (htinfo
.pt
.x
< SCROLLAREAWIDTH
)
2858 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEUP
, 0);
2860 if (htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
)
2861 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEDOWN
, 0);
2863 if (htinfo
.pt
.y
< SCROLLAREAWIDTH
)
2864 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEUP
, 0);
2866 if (htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
)
2867 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEDOWN
, 0);
2872 m_cScrollDelay
= 0; /* Reset, if the cursor is not over the listview's scroll-area */
2875 m_ptLastMousePos
= htinfo
.pt
;
2877 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2878 if (m_pCurDropTarget
&& lResult
== m_iDragOverItem
)
2879 return m_pCurDropTarget
->DragOver(grfKeyState
, pt
, pdwEffect
);
2881 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2882 if (m_pCurDropTarget
)
2884 m_pCurDropTarget
->DragLeave();
2885 m_pCurDropTarget
.Release();
2888 m_iDragOverItem
= lResult
;
2891 /* We are not above one of the listview's subitems. Bind to the parent folder's
2892 * DropTarget interface. */
2893 hr
= m_pSFParent
->CreateViewObject(NULL
, IID_PPV_ARG(IDropTarget
,&m_pCurDropTarget
));
2897 /* Query the relative PIDL of the shellfolder object represented by the currently
2898 * dragged over listview-item ... */
2899 PCUITEMID_CHILD pidl
= _PidlByItem(lResult
);
2901 /* ... and bind m_pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2902 hr
= m_pSFParent
->GetUIObjectOf(m_ListView
, 1, &pidl
, IID_NULL_PPV_ARG(IDropTarget
, &m_pCurDropTarget
));
2905 /* If anything failed, m_pCurDropTarget should be NULL now, which ought to be a save state. */
2909 /* Notify the item just entered via DragEnter. */
2910 return m_pCurDropTarget
->DragEnter(m_pCurDataObject
, grfKeyState
, pt
, pdwEffect
);
2913 HRESULT WINAPI
CDefView::DragEnter(IDataObject
*pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2915 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2916 m_pCurDataObject
= pDataObject
;
2917 pDataObject
->AddRef();
2919 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2922 HRESULT WINAPI
CDefView::DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2924 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2927 HRESULT WINAPI
CDefView::DragLeave()
2929 if (m_pCurDropTarget
)
2931 m_pCurDropTarget
->DragLeave();
2932 m_pCurDropTarget
.Release();
2935 if (m_pCurDataObject
!= NULL
)
2937 m_pCurDataObject
.Release();
2940 m_iDragOverItem
= 0;
2945 HRESULT WINAPI
CDefView::Drop(IDataObject
* pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2947 ERR("GetKeyState(VK_LBUTTON): %d\n", GetKeyState(VK_LBUTTON
));
2949 if ((m_iDragOverItem
== -1) &&
2950 (*pdwEffect
& DROPEFFECT_MOVE
) &&
2951 (GetKeyState(VK_LBUTTON
) != 0) &&
2952 (m_pSourceDataObject
.p
) &&
2953 (SHIsSameObject(pDataObject
, m_pSourceDataObject
)))
2955 ERR("Should implement moving items here!\n");
2957 if (m_pCurDropTarget
)
2959 m_pCurDropTarget
->DragLeave();
2960 m_pCurDropTarget
.Release();
2963 else if (m_pCurDropTarget
)
2965 m_pCurDropTarget
->Drop(pDataObject
, grfKeyState
, pt
, pdwEffect
);
2966 m_pCurDropTarget
.Release();
2969 m_pCurDataObject
.Release();
2970 m_iDragOverItem
= 0;
2974 /**********************************************************
2975 * ISVDropSource implementation
2978 HRESULT WINAPI
CDefView::QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
)
2980 TRACE("(%p)\n", this);
2983 return DRAGDROP_S_CANCEL
;
2984 else if (!(grfKeyState
& MK_LBUTTON
) && !(grfKeyState
& MK_RBUTTON
))
2985 return DRAGDROP_S_DROP
;
2990 HRESULT WINAPI
CDefView::GiveFeedback(DWORD dwEffect
)
2992 TRACE("(%p)\n", this);
2994 return DRAGDROP_S_USEDEFAULTCURSORS
;
2997 /**********************************************************
2998 * ISVViewObject implementation
3001 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
)
3003 FIXME("Stub: this=%p\n", this);
3008 HRESULT WINAPI
CDefView::GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
, HDC hicTargetDevice
, LOGPALETTE
**ppColorSet
)
3010 FIXME("Stub: this=%p\n", this);
3015 HRESULT WINAPI
CDefView::Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
)
3017 FIXME("Stub: this=%p\n", this);
3022 HRESULT WINAPI
CDefView::Unfreeze(DWORD dwFreeze
)
3024 FIXME("Stub: this=%p\n", this);
3029 HRESULT WINAPI
CDefView::SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
)
3031 FIXME("partial stub: %p %08x %08x %p\n", this, aspects
, advf
, pAdvSink
);
3033 /* FIXME: we set the AdviseSink, but never use it to send any advice */
3034 m_pAdvSink
= pAdvSink
;
3035 m_dwAspects
= aspects
;
3041 HRESULT WINAPI
CDefView::GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
)
3043 TRACE("this=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n", this, pAspects
, pAdvf
, ppAdvSink
);
3047 *ppAdvSink
= m_pAdvSink
;
3048 m_pAdvSink
.p
->AddRef();
3052 *pAspects
= m_dwAspects
;
3060 HRESULT STDMETHODCALLTYPE
CDefView::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
3062 if (IsEqualIID(guidService
, SID_IShellBrowser
))
3063 return m_pShellBrowser
->QueryInterface(riid
, ppvObject
);
3064 else if(IsEqualIID(guidService
, SID_IFolderView
))
3065 return QueryInterface(riid
, ppvObject
);
3067 return E_NOINTERFACE
;
3070 HRESULT
CDefView::_MergeToolbar()
3072 CComPtr
<IExplorerToolbar
> ptb
;
3075 hr
= IUnknown_QueryService(m_pShellBrowser
, IID_IExplorerToolbar
, IID_PPV_ARG(IExplorerToolbar
, &ptb
));
3079 m_Category
= CGID_DefViewFrame
;
3081 hr
= ptb
->SetCommandTarget(static_cast<IOleCommandTarget
*>(this), &m_Category
, 0);
3089 hr
= ptb
->AddButtons(&m_Category
, buttonsCount
, buttons
);
3096 /**********************************************************
3097 * IShellView_Constructor
3099 HRESULT WINAPI
IShellView_Constructor(IShellFolder
*pFolder
, IShellView
**newView
)
3101 return ShellObjectCreatorInit
<CDefView
>(pFolder
, IID_IShellView
, newView
);
3104 HRESULT WINAPI
CDefView_Constructor(IShellFolder
*pFolder
, REFIID riid
, LPVOID
* ppvOut
)
3106 return ShellObjectCreatorInit
<CDefView
>(pFolder
, riid
, ppvOut
);