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
28 * FIXME: ShellView_FillList: consider sort orders
33 1. Load/Save the view state from/into the stream provided by the ShellBrowser.
34 2. Let the shell folder sort items.
35 3. Code to merge menus in the shellbrowser is incorrect.
36 4. Move the background context menu creation into shell view. It should store the
37 shell view HWND to send commands.
38 5. Send init, measure, and draw messages to context menu during tracking.
39 6. Shell view should do SetCommandTarget on internet toolbar.
40 7. When editing starts on item, set edit text to for editing value.
41 8. When shell view is called back for item info, let listview save the value.
42 9. Shell view should update status bar.
43 10. Fix shell view to handle view mode popup exec.
44 11. The background context menu should have a pidl just like foreground menus. This
45 causes crashes when dynamic handlers try to use the NULL pidl.
46 12. The SHELLDLL_DefView should not be filled with blue unconditionally. This causes
47 annoying flashing of blue even on XP, and is not correct.
48 13. Reorder of columns doesn't work - might be bug in comctl32
56 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
60 static const WCHAR SV_CLASS_NAME
[] = {'S', 'H', 'E', 'L', 'L', 'D', 'L', 'L', '_', 'D', 'e', 'f', 'V', 'i', 'e', 'w', 0};
67 } LISTVIEW_SORT_INFO
, *LPLISTVIEW_SORT_INFO
;
69 #define SHV_CHANGE_NOTIFY WM_USER + 0x1111
72 public CWindowImpl
<CDefView
, CWindow
, CControlWinTraits
>,
73 public CComObjectRootEx
<CComMultiThreadModelNoCS
>,
76 public IShellFolderView
,
77 public IOleCommandTarget
,
81 public IServiceProvider
84 CComPtr
<IShellFolder
> m_pSFParent
;
85 CComPtr
<IShellFolder2
> m_pSF2Parent
;
86 CComPtr
<IShellBrowser
> m_pShellBrowser
;
87 CComPtr
<ICommDlgBrowser
> m_pCommDlgBrowser
;
90 FOLDERSETTINGS m_FolderSettings
;
95 PCUITEMID_CHILD_ARRAY m_apidl
;
96 LISTVIEW_SORT_INFO m_sortInfo
;
97 ULONG m_hNotify
; /* change notification handle */
101 CComPtr
<IAdviseSink
> m_pAdvSink
;
103 CComPtr
<IDropTarget
> m_pCurDropTarget
; /* The sub-item, which is currently dragged over */
104 CComPtr
<IDataObject
> m_pCurDataObject
; /* The dragged data-object */
105 LONG m_iDragOverItem
; /* Dragged over item's index, iff m_pCurDropTarget != NULL */
106 UINT m_cScrollDelay
; /* Send a WM_*SCROLL msg every 250 ms during drag-scroll */
107 POINT m_ptLastMousePos
; /* Mouse position at last DragOver call */
109 CComPtr
<IContextMenu
> m_pCM
;
117 HRESULT
_MergeToolbar();
122 HRESULT WINAPI
Initialize(IShellFolder
*shellFolder
);
123 HRESULT
IncludeObject(PCUITEMID_CHILD pidl
);
124 HRESULT
OnDefaultCommand();
125 HRESULT
OnStateChange(UINT uFlags
);
127 void SetStyle(DWORD dwAdd
, DWORD dwRemove
);
129 void UpdateListColors();
131 static INT CALLBACK
CompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
);
132 static INT CALLBACK
ListViewCompareItems(LPARAM lParam1
, LPARAM lParam2
, LPARAM lpData
);
134 PCUITEMID_CHILD
_PidlByItem(int i
);
135 PCUITEMID_CHILD
_PidlByItem(LVITEM
& lvItem
);
136 int LV_FindItemByPidl(PCUITEMID_CHILD pidl
);
137 BOOLEAN
LV_AddItem(PCUITEMID_CHILD pidl
);
138 BOOLEAN
LV_DeleteItem(PCUITEMID_CHILD pidl
);
139 BOOLEAN
LV_RenameItem(PCUITEMID_CHILD pidlOld
, PCUITEMID_CHILD pidlNew
);
140 static INT CALLBACK
fill_list(LPVOID ptr
, LPVOID arg
);
142 HMENU
BuildFileMenu();
143 void PrepareShowFileMenu(HMENU hSubMenu
);
144 void PrepareShowViewMenu(HMENU hSubMenu
);
145 UINT
GetSelections();
146 HRESULT
OpenSelectedItems();
148 void DoActivate(UINT uState
);
149 HRESULT
drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
150 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 // *** IFolderView methods ***
170 virtual HRESULT STDMETHODCALLTYPE
GetCurrentViewMode(UINT
*pViewMode
);
171 virtual HRESULT STDMETHODCALLTYPE
SetCurrentViewMode(UINT ViewMode
);
172 virtual HRESULT STDMETHODCALLTYPE
GetFolder(REFIID riid
, void **ppv
);
173 virtual HRESULT STDMETHODCALLTYPE
Item(int iItemIndex
, PITEMID_CHILD
*ppidl
);
174 virtual HRESULT STDMETHODCALLTYPE
ItemCount(UINT uFlags
, int *pcItems
);
175 virtual HRESULT STDMETHODCALLTYPE
Items(UINT uFlags
, REFIID riid
, void **ppv
);
176 virtual HRESULT STDMETHODCALLTYPE
GetSelectionMarkedItem(int *piItem
);
177 virtual HRESULT STDMETHODCALLTYPE
GetFocusedItem(int *piItem
);
178 virtual HRESULT STDMETHODCALLTYPE
GetItemPosition(PCUITEMID_CHILD pidl
, POINT
*ppt
);
179 virtual HRESULT STDMETHODCALLTYPE
GetSpacing(POINT
*ppt
);
180 virtual HRESULT STDMETHODCALLTYPE
GetDefaultSpacing(POINT
*ppt
);
181 virtual HRESULT STDMETHODCALLTYPE
GetAutoArrange();
182 virtual HRESULT STDMETHODCALLTYPE
SelectItem(int iItem
, DWORD dwFlags
);
183 virtual HRESULT STDMETHODCALLTYPE
SelectAndPositionItems(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD dwFlags
);
185 // *** IShellFolderView methods ***
186 virtual HRESULT STDMETHODCALLTYPE
Rearrange(LPARAM sort
);
187 virtual HRESULT STDMETHODCALLTYPE
GetArrangeParam(LPARAM
*sort
);
188 virtual HRESULT STDMETHODCALLTYPE
ArrangeGrid();
189 virtual HRESULT STDMETHODCALLTYPE
AutoArrange();
190 virtual HRESULT STDMETHODCALLTYPE
AddObject(PITEMID_CHILD pidl
, UINT
*item
);
191 virtual HRESULT STDMETHODCALLTYPE
GetObject(PITEMID_CHILD
*pidl
, UINT item
);
192 virtual HRESULT STDMETHODCALLTYPE
RemoveObject(PITEMID_CHILD pidl
, UINT
*item
);
193 virtual HRESULT STDMETHODCALLTYPE
GetObjectCount(UINT
*count
);
194 virtual HRESULT STDMETHODCALLTYPE
SetObjectCount(UINT count
, UINT flags
);
195 virtual HRESULT STDMETHODCALLTYPE
UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
);
196 virtual HRESULT STDMETHODCALLTYPE
RefreshObject(PITEMID_CHILD pidl
, UINT
*item
);
197 virtual HRESULT STDMETHODCALLTYPE
SetRedraw(BOOL redraw
);
198 virtual HRESULT STDMETHODCALLTYPE
GetSelectedCount(UINT
*count
);
199 virtual HRESULT STDMETHODCALLTYPE
GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
);
200 virtual HRESULT STDMETHODCALLTYPE
IsDropOnSource(IDropTarget
*drop_target
);
201 virtual HRESULT STDMETHODCALLTYPE
GetDragPoint(POINT
*pt
);
202 virtual HRESULT STDMETHODCALLTYPE
GetDropPoint(POINT
*pt
);
203 virtual HRESULT STDMETHODCALLTYPE
MoveIcons(IDataObject
*obj
);
204 virtual HRESULT STDMETHODCALLTYPE
SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
);
205 virtual HRESULT STDMETHODCALLTYPE
IsBkDropTarget(IDropTarget
*drop_target
);
206 virtual HRESULT STDMETHODCALLTYPE
SetClipboard(BOOL move
);
207 virtual HRESULT STDMETHODCALLTYPE
SetPoints(IDataObject
*obj
);
208 virtual HRESULT STDMETHODCALLTYPE
GetItemSpacing(ITEMSPACING
*spacing
);
209 virtual HRESULT STDMETHODCALLTYPE
SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
);
210 virtual HRESULT STDMETHODCALLTYPE
Select(UINT flags
);
211 virtual HRESULT STDMETHODCALLTYPE
QuerySupport(UINT
*support
);
212 virtual HRESULT STDMETHODCALLTYPE
SetAutomationObject(IDispatch
*disp
);
214 // *** IOleCommandTarget methods ***
215 virtual HRESULT STDMETHODCALLTYPE
QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
);
216 virtual HRESULT STDMETHODCALLTYPE
Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
);
218 // *** IDropTarget methods ***
219 virtual HRESULT STDMETHODCALLTYPE
DragEnter(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
220 virtual HRESULT STDMETHODCALLTYPE
DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
221 virtual HRESULT STDMETHODCALLTYPE
DragLeave();
222 virtual HRESULT STDMETHODCALLTYPE
Drop(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
224 // *** IDropSource methods ***
225 virtual HRESULT STDMETHODCALLTYPE
QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
);
226 virtual HRESULT STDMETHODCALLTYPE
GiveFeedback(DWORD dwEffect
);
228 // *** IViewObject methods ***
229 virtual HRESULT STDMETHODCALLTYPE
Draw(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
,
230 HDC hdcTargetDev
, HDC hdcDraw
, LPCRECTL lprcBounds
, LPCRECTL lprcWBounds
,
231 BOOL ( STDMETHODCALLTYPE
*pfnContinue
)(ULONG_PTR dwContinue
), ULONG_PTR dwContinue
);
232 virtual HRESULT STDMETHODCALLTYPE
GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
,
233 DVTARGETDEVICE
*ptd
, HDC hicTargetDev
, LOGPALETTE
**ppColorSet
);
234 virtual HRESULT STDMETHODCALLTYPE
Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
);
235 virtual HRESULT STDMETHODCALLTYPE
Unfreeze(DWORD dwFreeze
);
236 virtual HRESULT STDMETHODCALLTYPE
SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
);
237 virtual HRESULT STDMETHODCALLTYPE
GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
);
239 // *** IServiceProvider methods ***
240 virtual HRESULT STDMETHODCALLTYPE
QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
);
243 LRESULT
OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
244 LRESULT
OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
245 LRESULT
OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
246 LRESULT
OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
247 LRESULT
OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
248 LRESULT
OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
249 LRESULT
OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
250 LRESULT
OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
251 LRESULT
OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
252 LRESULT
OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
253 LRESULT
OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
254 LRESULT
OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
255 LRESULT
OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
256 LRESULT
OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
257 LRESULT
OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
258 LRESULT
OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
259 LRESULT
OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
260 LRESULT
OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
262 static ATL::CWndClassInfo
& GetWndClassInfo()
264 static ATL::CWndClassInfo wc
=
266 { sizeof(WNDCLASSEX
), 0, StartWindowProc
,
268 LoadCursor(NULL
, IDC_ARROW
), (HBRUSH
)(COLOR_BACKGROUND
+ 1), NULL
, SV_CLASS_NAME
, NULL
270 NULL
, NULL
, IDC_ARROW
, TRUE
, 0, _T("")
275 virtual WNDPROC
GetWindowProc()
280 static LRESULT CALLBACK
WindowProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
285 // must hold a reference during message handling
286 pThis
= reinterpret_cast<CDefView
*>(hWnd
);
288 result
= CWindowImpl
<CDefView
, CWindow
, CControlWinTraits
>::WindowProc(hWnd
, uMsg
, wParam
, lParam
);
293 BEGIN_MSG_MAP(CDefView
)
294 MESSAGE_HANDLER(WM_SIZE
, OnSize
)
295 MESSAGE_HANDLER(WM_SETFOCUS
, OnSetFocus
)
296 MESSAGE_HANDLER(WM_KILLFOCUS
, OnKillFocus
)
297 MESSAGE_HANDLER(WM_CREATE
, OnCreate
)
298 MESSAGE_HANDLER(WM_ACTIVATE
, OnActivate
)
299 MESSAGE_HANDLER(WM_NOTIFY
, OnNotify
)
300 MESSAGE_HANDLER(WM_COMMAND
, OnCommand
)
301 MESSAGE_HANDLER(SHV_CHANGE_NOTIFY
, OnChangeNotify
)
302 MESSAGE_HANDLER(WM_CONTEXTMENU
, OnContextMenu
)
303 MESSAGE_HANDLER(WM_DRAWITEM
, OnCustomItem
)
304 MESSAGE_HANDLER(WM_MEASUREITEM
, OnCustomItem
)
305 MESSAGE_HANDLER(WM_SHOWWINDOW
, OnShowWindow
)
306 MESSAGE_HANDLER(WM_GETDLGCODE
, OnGetDlgCode
)
307 MESSAGE_HANDLER(WM_DESTROY
, OnDestroy
)
308 MESSAGE_HANDLER(WM_ERASEBKGND
, OnEraseBackground
)
309 MESSAGE_HANDLER(WM_SYSCOLORCHANGE
, OnSysColorChange
)
310 MESSAGE_HANDLER(CWM_GETISHELLBROWSER
, OnGetShellBrowser
)
311 MESSAGE_HANDLER(WM_SETTINGCHANGE
, OnSettingChange
)
312 MESSAGE_HANDLER(WM_INITMENUPOPUP
, OnInitMenuPopup
)
315 BEGIN_COM_MAP(CDefView
)
316 COM_INTERFACE_ENTRY_IID(IID_IOleWindow
, IOleWindow
)
317 COM_INTERFACE_ENTRY_IID(IID_IShellView
, IShellView
)
318 COM_INTERFACE_ENTRY_IID(IID_IFolderView
, IFolderView
)
319 COM_INTERFACE_ENTRY_IID(IID_IShellFolderView
, IShellFolderView
)
320 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget
, IOleCommandTarget
)
321 COM_INTERFACE_ENTRY_IID(IID_IDropTarget
, IDropTarget
)
322 COM_INTERFACE_ENTRY_IID(IID_IDropSource
, IDropSource
)
323 COM_INTERFACE_ENTRY_IID(IID_IViewObject
, IViewObject
)
324 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider
, IServiceProvider
)
328 /* ListView Header ID's */
329 #define LISTVIEW_COLUMN_NAME 0
330 #define LISTVIEW_COLUMN_SIZE 1
331 #define LISTVIEW_COLUMN_TYPE 2
332 #define LISTVIEW_COLUMN_TIME 3
333 #define LISTVIEW_COLUMN_ATTRIB 4
336 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
337 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
338 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
340 #define ID_LISTVIEW 1
343 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
344 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
345 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
347 typedef void (CALLBACK
*PFNSHGETSETTINGSPROC
)(LPSHELLFLAGSTATE lpsfs
, DWORD dwMask
);
349 CDefView::CDefView() :
353 m_menusLoaded(FALSE
),
366 ZeroMemory(&m_FolderSettings
, sizeof(m_FolderSettings
));
367 ZeroMemory(&m_sortInfo
, sizeof(m_sortInfo
));
368 ZeroMemory(&m_ptLastMousePos
, sizeof(m_ptLastMousePos
));
369 ZeroMemory(&m_Category
, sizeof(m_Category
));
372 CDefView::~CDefView()
374 TRACE(" destroying IShellView(%p)\n", this);
384 HRESULT WINAPI
CDefView::Initialize(IShellFolder
*shellFolder
)
386 m_pSFParent
= shellFolder
;
387 shellFolder
->QueryInterface(IID_PPV_ARG(IShellFolder2
, &m_pSF2Parent
));
392 /**********************************************************
394 * ##### helperfunctions for communication with ICommDlgBrowser #####
396 HRESULT
CDefView::IncludeObject(PCUITEMID_CHILD pidl
)
400 if (m_pCommDlgBrowser
.p
!= NULL
)
402 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl
);
403 ret
= m_pCommDlgBrowser
->IncludeObject(this, pidl
);
404 TRACE("--0x%08x\n", ret
);
410 HRESULT
CDefView::OnDefaultCommand()
412 HRESULT ret
= S_FALSE
;
414 if (m_pCommDlgBrowser
.p
!= NULL
)
416 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
417 ret
= m_pCommDlgBrowser
->OnDefaultCommand(this);
418 TRACE("-- returns %08x\n", ret
);
424 HRESULT
CDefView::OnStateChange(UINT uFlags
)
426 HRESULT ret
= S_FALSE
;
428 if (m_pCommDlgBrowser
.p
!= NULL
)
430 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags
);
431 ret
= m_pCommDlgBrowser
->OnStateChange(this, uFlags
);
437 /**********************************************************
438 * set the toolbar of the filedialog buttons
440 * - activates the buttons from the shellbrowser according to
443 void CDefView::CheckToolbar()
449 if (m_pCommDlgBrowser
!= NULL
)
451 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
452 FCIDM_TB_SMALLICON
, (m_FolderSettings
.ViewMode
== FVM_LIST
) ? TRUE
: FALSE
, &result
);
453 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
454 FCIDM_TB_REPORTVIEW
, (m_FolderSettings
.ViewMode
== FVM_DETAILS
) ? TRUE
: FALSE
, &result
);
455 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
456 FCIDM_TB_SMALLICON
, TRUE
, &result
);
457 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
458 FCIDM_TB_REPORTVIEW
, TRUE
, &result
);
462 /**********************************************************
464 * ##### helperfunctions for initializing the view #####
466 /**********************************************************
467 * change the style of the listview control
469 void CDefView::SetStyle(DWORD dwAdd
, DWORD dwRemove
)
473 TRACE("(%p)\n", this);
475 tmpstyle
= ::GetWindowLongPtrW(m_ListView
, GWL_STYLE
);
476 ::SetWindowLongPtrW(m_ListView
, GWL_STYLE
, dwAdd
| (tmpstyle
& ~dwRemove
));
479 /**********************************************************
480 * ShellView_CreateList()
482 * - creates the list view window
484 BOOL
CDefView::CreateList()
485 { DWORD dwStyle
, dwExStyle
;
489 dwStyle
= WS_TABSTOP
| WS_VISIBLE
| WS_CHILDWINDOW
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
|
490 LVS_SHAREIMAGELISTS
| LVS_EDITLABELS
| LVS_AUTOARRANGE
;
491 dwExStyle
= WS_EX_CLIENTEDGE
;
493 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
494 dwStyle
|= LVS_ALIGNLEFT
;
496 dwStyle
|= LVS_ALIGNTOP
| LVS_SHOWSELALWAYS
;
498 switch (m_FolderSettings
.ViewMode
)
505 dwStyle
|= LVS_REPORT
;
509 dwStyle
|= LVS_SMALLICON
;
521 if (m_FolderSettings
.fFlags
& FWF_AUTOARRANGE
)
522 dwStyle
|= LVS_AUTOARRANGE
;
524 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
525 m_FolderSettings
.fFlags
|= FWF_NOCLIENTEDGE
| FWF_NOSCROLL
;
527 if (m_FolderSettings
.fFlags
& FWF_SINGLESEL
)
528 dwStyle
|= LVS_SINGLESEL
;
530 if (m_FolderSettings
.fFlags
& FWF_NOCLIENTEDGE
)
531 dwExStyle
&= ~WS_EX_CLIENTEDGE
;
533 RECT rcListView
= {0,0,0,0};
534 m_ListView
.Create(m_hWnd
, rcListView
, NULL
,dwStyle
, dwExStyle
, ID_LISTVIEW
);
539 m_sortInfo
.bIsAscending
= TRUE
;
540 m_sortInfo
.nHeaderID
= -1;
541 m_sortInfo
.nLastHeaderID
= -1;
545 /* UpdateShellSettings(); */
549 void CDefView::UpdateListColors()
551 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
553 /* Check if drop shadows option is enabled */
554 BOOL bDropShadow
= FALSE
;
555 DWORD cbDropShadow
= sizeof(bDropShadow
);
556 WCHAR wszBuf
[16] = L
"";
558 RegGetValueW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
559 L
"ListviewShadow", RRF_RT_DWORD
, NULL
, &bDropShadow
, &cbDropShadow
);
560 if (bDropShadow
&& SystemParametersInfoW(SPI_GETDESKWALLPAPER
, _countof(wszBuf
), wszBuf
, 0) && wszBuf
[0])
562 m_ListView
.SetTextBkColor(CLR_NONE
);
563 m_ListView
.SetBkColor(CLR_NONE
);
564 m_ListView
.SetTextColor(RGB(255, 255, 255));
565 m_ListView
.SetExtendedListViewStyle(LVS_EX_TRANSPARENTSHADOWTEXT
, LVS_EX_TRANSPARENTSHADOWTEXT
);
569 COLORREF crDesktop
= GetSysColor(COLOR_DESKTOP
);
570 m_ListView
.SetTextBkColor(crDesktop
);
571 m_ListView
.SetBkColor(crDesktop
);
572 if (GetRValue(crDesktop
) + GetGValue(crDesktop
) + GetBValue(crDesktop
) > 128 * 3)
573 m_ListView
.SetTextColor(RGB(0, 0, 0));
575 m_ListView
.SetTextColor(RGB(255, 255, 255));
576 m_ListView
.SetExtendedListViewStyle(LVS_EX_TRANSPARENTSHADOWTEXT
);
581 /**********************************************************
582 * ShellView_InitList()
584 * - adds all needed columns to the shellview
586 BOOL
CDefView::InitList()
593 m_ListView
.DeleteAllItems();
597 for (int i
= 0; 1; i
++)
599 if (FAILED(m_pSF2Parent
->GetDetailsOf(NULL
, i
, &sd
)))
601 StrRetToStrNW( szTemp
, 50, &sd
.str
, NULL
);
602 m_ListView
.InsertColumn(i
, szTemp
, sd
.fmt
, sd
.cxChar
* 8);
611 m_ListView
.SetImageList(ShellBigIconList
, LVSIL_NORMAL
);
612 m_ListView
.SetImageList(ShellSmallIconList
, LVSIL_SMALL
);
617 /**********************************************************
618 * ShellView_CompareItems()
621 * internal, CALLBACK for DSA_Sort
623 INT CALLBACK
CDefView::CompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
)
626 TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1
, lParam2
, (LPVOID
) lpData
);
631 IShellFolder
* psf
= reinterpret_cast<IShellFolder
*>(lpData
);
632 PCUIDLIST_RELATIVE pidl1
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam1
);
633 PCUIDLIST_RELATIVE pidl2
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam2
);
635 ret
= (SHORT
)SCODE_CODE(psf
->CompareIDs(0, pidl1
, pidl2
));
636 TRACE("ret=%i\n", ret
);
641 /*************************************************************************
642 * ShellView_ListViewCompareItems
644 * Compare Function for the Listview (FileOpen Dialog)
647 * lParam1 [I] the first ItemIdList to compare with
648 * lParam2 [I] the second ItemIdList to compare with
649 * lpData [I] The column ID for the header Ctrl to process
652 * A negative value if the first item should precede the second,
653 * a positive value if the first item should follow the second,
654 * or zero if the two items are equivalent
657 * FIXME: function does what ShellView_CompareItems is supposed to do.
658 * unify it and figure out how to use the undocumented first parameter
659 * of IShellFolder_CompareIDs to do the job this function does and
660 * move this code to IShellFolder.
661 * make LISTVIEW_SORT_INFO obsolete
662 * the way this function works is only usable if we had only
663 * filesystemfolders (25/10/99 jsch)
665 INT CALLBACK
CDefView::ListViewCompareItems(LPARAM lParam1
, LPARAM lParam2
, LPARAM lpData
)
669 char strName1
[MAX_PATH
], strName2
[MAX_PATH
];
670 BOOL bIsFolder1
, bIsFolder2
, bIsBothFolder
;
671 PCUIDLIST_RELATIVE pidl1
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam1
);
672 PCUIDLIST_RELATIVE pidl2
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam2
);
673 LISTVIEW_SORT_INFO
*pSortInfo
= reinterpret_cast<LPLISTVIEW_SORT_INFO
>(lpData
);
676 bIsFolder1
= _ILIsFolder(pidl1
);
677 bIsFolder2
= _ILIsFolder(pidl2
);
678 bIsBothFolder
= bIsFolder1
&& bIsFolder2
;
680 /* When sorting between a File and a Folder, the Folder gets sorted first */
681 if ( (bIsFolder1
|| bIsFolder2
) && !bIsBothFolder
)
683 nDiff
= bIsFolder1
? -1 : 1;
687 /* Sort by Time: Folders or Files can be sorted */
689 if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_TIME
)
691 _ILGetFileDateTime(pidl1
, &fd1
);
692 _ILGetFileDateTime(pidl2
, &fd2
);
693 nDiff
= CompareFileTime(&fd2
, &fd1
);
695 /* Sort by Attribute: Folder or Files can be sorted */
696 else if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_ATTRIB
)
698 _ILGetFileAttributes(pidl1
, strName1
, MAX_PATH
);
699 _ILGetFileAttributes(pidl2
, strName2
, MAX_PATH
);
700 nDiff
= lstrcmpiA(strName1
, strName2
);
702 /* Sort by FileName: Folder or Files can be sorted */
703 else if (pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_NAME
|| bIsBothFolder
)
706 _ILSimpleGetText(pidl1
, strName1
, MAX_PATH
);
707 _ILSimpleGetText(pidl2
, strName2
, MAX_PATH
);
708 nDiff
= lstrcmpiA(strName1
, strName2
);
710 /* Sort by File Size, Only valid for Files */
711 else if (pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_SIZE
)
713 nDiff
= (INT
)(_ILGetFileSize(pidl1
, NULL
, 0) - _ILGetFileSize(pidl2
, NULL
, 0));
715 /* Sort by File Type, Only valid for Files */
716 else if (pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_TYPE
)
719 _ILGetFileType(pidl1
, strName1
, MAX_PATH
);
720 _ILGetFileType(pidl2
, strName2
, MAX_PATH
);
721 nDiff
= lstrcmpiA(strName1
, strName2
);
724 /* If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
728 _ILSimpleGetText(pidl1
, strName1
, MAX_PATH
);
729 _ILSimpleGetText(pidl2
, strName2
, MAX_PATH
);
730 nDiff
= lstrcmpiA(strName1
, strName2
);
733 if (!pSortInfo
->bIsAscending
)
741 PCUITEMID_CHILD
CDefView::_PidlByItem(int i
)
743 return reinterpret_cast<PCUITEMID_CHILD
>(m_ListView
.GetItemData(i
));
746 PCUITEMID_CHILD
CDefView::_PidlByItem(LVITEM
& lvItem
)
748 return reinterpret_cast<PCUITEMID_CHILD
>(lvItem
.lParam
);
751 /**********************************************************
752 * LV_FindItemByPidl()
754 int CDefView::LV_FindItemByPidl(PCUITEMID_CHILD pidl
)
756 int cItems
= m_ListView
.GetItemCount();
758 for (int i
= 0; i
<cItems
; i
++)
760 PCUITEMID_CHILD currentpidl
= _PidlByItem(i
);
761 HRESULT hr
= m_pSFParent
->CompareIDs(0, pidl
, currentpidl
);
763 if (SUCCEEDED(hr
) && !HRESULT_CODE(hr
))
771 /**********************************************************
774 BOOLEAN
CDefView::LV_AddItem(PCUITEMID_CHILD pidl
)
778 TRACE("(%p)(pidl=%p)\n", this, pidl
);
780 lvItem
.mask
= LVIF_TEXT
| LVIF_IMAGE
| LVIF_PARAM
; /*set the mask*/
781 lvItem
.iItem
= m_ListView
.GetItemCount(); /*add the item to the end of the list*/
783 lvItem
.lParam
= reinterpret_cast<LPARAM
>(ILClone(pidl
)); /*set the item's data*/
784 lvItem
.pszText
= LPSTR_TEXTCALLBACKW
; /*get text on a callback basis*/
785 lvItem
.iImage
= I_IMAGECALLBACK
; /*get the image on a callback basis*/
787 if (m_ListView
.InsertItem(&lvItem
) == -1)
793 /**********************************************************
796 BOOLEAN
CDefView::LV_DeleteItem(PCUITEMID_CHILD pidl
)
800 TRACE("(%p)(pidl=%p)\n", this, pidl
);
802 nIndex
= LV_FindItemByPidl(pidl
);
804 return (-1 == m_ListView
.DeleteItem(nIndex
)) ? FALSE
: TRUE
;
807 /**********************************************************
810 BOOLEAN
CDefView::LV_RenameItem(PCUITEMID_CHILD pidlOld
, PCUITEMID_CHILD pidlNew
)
815 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", this, pidlOld
, pidlNew
);
817 nItem
= LV_FindItemByPidl(pidlOld
);
821 lvItem
.mask
= LVIF_PARAM
; /* only the pidl */
822 lvItem
.iItem
= nItem
;
823 m_ListView
.GetItem(&lvItem
);
825 SHFree(reinterpret_cast<LPVOID
>(lvItem
.lParam
));
826 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
827 lvItem
.iItem
= nItem
;
828 lvItem
.lParam
= reinterpret_cast<LPARAM
>(ILClone(pidlNew
)); /* set the item's data */
829 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
830 m_ListView
.SetItem(&lvItem
);
831 m_ListView
.Update(nItem
);
832 return TRUE
; /* FIXME: better handling */
838 /**********************************************************
839 * ShellView_FillList()
841 * - gets the objectlist from the shellfolder
843 * - fills the list into the view
845 INT CALLBACK
CDefView::fill_list( LPVOID ptr
, LPVOID arg
)
847 PITEMID_CHILD pidl
= static_cast<PITEMID_CHILD
>(ptr
);
848 CDefView
*pThis
= static_cast<CDefView
*>(arg
);
850 /* in a commdlg This works as a filemask*/
851 if (pThis
->IncludeObject(pidl
) == S_OK
)
852 pThis
->LV_AddItem(pidl
);
858 HRESULT
CDefView::FillList()
860 CComPtr
<IEnumIDList
> pEnumIDList
;
868 /* get the itemlist from the shfolder*/
869 hRes
= m_pSFParent
->EnumObjects(m_hWnd
, SHCONTF_NONFOLDERS
| SHCONTF_FOLDERS
, &pEnumIDList
);
877 /* create a pointer array */
878 hdpa
= DPA_Create(16);
881 return(E_OUTOFMEMORY
);
884 /* copy the items into the array*/
885 while((S_OK
== pEnumIDList
->Next(1, &pidl
, &dwFetched
)) && dwFetched
)
887 if (DPA_InsertPtr(hdpa
, 0x7fff, pidl
) == -1)
894 DPA_Sort(hdpa
, CompareItems
, reinterpret_cast<LPARAM
>(m_pSFParent
.p
));
896 /*turn the listview's redrawing off*/
897 m_ListView
.SetRedraw(FALSE
);
899 DPA_DestroyCallback( hdpa
, fill_list
, this);
901 /*turn the listview's redrawing back on and force it to draw*/
902 m_ListView
.SetRedraw(TRUE
);
907 LRESULT
CDefView::OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
909 m_ListView
.UpdateWindow();
914 LRESULT
CDefView::OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
916 return m_ListView
.SendMessageW(uMsg
, 0, 0);
919 LRESULT
CDefView::OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
922 DestroyMenu(m_hMenu
);
923 RevokeDragDrop(m_hWnd
);
924 SHChangeNotifyDeregister(m_hNotify
);
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 /**********************************************************
954 * ShellView_OnCreate()
956 LRESULT
CDefView::OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
958 CComPtr
<IDropTarget
> pdt
;
959 SHChangeNotifyEntry ntreg
;
960 CComPtr
<IPersistFolder2
> ppf2
;
972 if (SUCCEEDED(QueryInterface(IID_PPV_ARG(IDropTarget
, &pdt
))))
974 if (FAILED(RegisterDragDrop(m_hWnd
, pdt
)))
975 ERR("Registering Drag Drop Failed");
978 /* register for receiving notifications */
979 m_pSFParent
->QueryInterface(IID_PPV_ARG(IPersistFolder2
, &ppf2
));
982 PIDLIST_ABSOLUTE pidlParent
;
983 ppf2
->GetCurFolder(&pidlParent
);
984 ntreg
.fRecursive
= TRUE
;
985 ntreg
.pidl
= pidlParent
;
986 m_hNotify
= SHChangeNotifyRegister(m_hWnd
, SHCNF_IDLIST
, SHCNE_ALLEVENTS
, SHV_CHANGE_NOTIFY
, 1, &ntreg
);
990 m_hAccel
= LoadAcceleratorsW(shell32_hInstance
, MAKEINTRESOURCEW(IDA_SHELLVIEW
));
995 /**********************************************************
996 * #### Handling of the menus ####
999 HMENU
CDefView::BuildFileMenu()
1002 CComPtr
<IContextMenu
> cm
;
1006 hr
= m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, IID_NULL_PPV_ARG(IContextMenu
, &cm
));
1010 HMENU hmenu
= CreatePopupMenu();
1012 //FIXME: get proper numbers ?
1013 const UINT first
= 0x7800;
1014 const UINT last
= 0x7A00;
1015 hr
= cm
->QueryContextMenu(hmenu
, 0, first
, last
, 0);
1019 // TODO: filter or something
1024 void CDefView::PrepareShowFileMenu(HMENU hSubMenu
)
1026 TRACE("(%p)->(submenu=%p) stub\n", this, hSubMenu
);
1031 /* Cleanup the items added previously */
1032 for (int i
= 0; i
< GetMenuItemCount(hSubMenu
); )
1035 mii
.cbSize
= sizeof(mii
);
1036 mii
.fMask
= MIIM_ID
;
1037 GetMenuItemInfoW(hSubMenu
, i
, TRUE
, &mii
);
1039 if (mii
.wID
< 0x8000)
1041 DeleteMenu(hSubMenu
, i
, MF_BYPOSITION
);
1049 /* Insert This item at the beginning of the menu. */
1050 _InsertMenuItemW(hSubMenu
, 0, TRUE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1051 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
+ 4, MFT_STRING
, L
"Properties", MFS_DISABLED
);
1052 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
+ 3, MFT_STRING
, L
"Rename", MFS_DISABLED
);
1053 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
+ 2, MFT_STRING
, L
"Delete", MFS_DISABLED
);
1054 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
+ 1, MFT_STRING
, L
"Create Shortcut", MFS_DISABLED
);
1055 _InsertMenuItemW(hSubMenu
, 0, TRUE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1056 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
, MFT_STRING
, L
"New", MFS_ENABLED
);
1058 HMENU menubase
= BuildFileMenu();
1061 int count
= ::GetMenuItemCount(menubase
);
1063 for (int i
= 0; i
< count
; i
++)
1067 MENUITEMINFOW mii
= { 0 };
1068 mii
.cbSize
= sizeof(mii
);
1069 mii
.fMask
= MIIM_STATE
| MIIM_ID
| MIIM_SUBMENU
| MIIM_CHECKMARKS
| MIIM_DATA
| MIIM_STRING
| MIIM_BITMAP
| MIIM_FTYPE
;
1070 mii
.dwTypeData
= label
;
1071 mii
.cch
= _countof(label
);
1072 ::GetMenuItemInfoW(menubase
, i
, TRUE
, &mii
);
1074 TRACE("Adding item %d label %S type %d\n", mii
.wID
, mii
.dwTypeData
, mii
.fType
);
1076 mii
.fType
|= MFT_RADIOCHECK
;
1078 ::InsertMenuItemW(hSubMenu
, IDM_MYFILEITEM
, FALSE
, &mii
);
1081 _InsertMenuItemW(hSubMenu
, IDM_MYFILEITEM
, FALSE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1083 ::DestroyMenu(menubase
);
1088 void CDefView::PrepareShowViewMenu(HMENU hSubMenu
)
1090 TRACE("(%p)->(submenu=%p)\n", this, hSubMenu
);
1095 if (m_FolderSettings
.ViewMode
>= FVM_FIRST
&& m_FolderSettings
.ViewMode
<= FVM_LAST
)
1097 UINT iItemFirst
= FCIDM_SHVIEW_BIGICON
;
1098 UINT iItemLast
= iItemFirst
+ FVM_LAST
- FVM_FIRST
;
1099 UINT iItem
= iItemFirst
+ m_FolderSettings
.ViewMode
- FVM_FIRST
;
1100 CheckMenuRadioItem(hSubMenu
, iItemFirst
, iItemLast
, iItem
, MF_BYCOMMAND
);
1104 /**********************************************************
1105 * ShellView_GetSelections()
1107 * - fills the m_apidl list with the selected objects
1110 * number of selected items
1112 UINT
CDefView::GetSelections()
1116 m_cidl
= m_ListView
.GetSelectedCount();
1117 m_apidl
= reinterpret_cast<PCUITEMID_CHILD_ARRAY
>(SHAlloc(m_cidl
* sizeof(PCUITEMID_CHILD
)));
1124 TRACE("-- Items selected =%u\n", m_cidl
);
1128 while ((lvIndex
= m_ListView
.GetNextItem(lvIndex
, LVNI_SELECTED
)) > -1)
1130 m_apidl
[i
] = _PidlByItem(lvIndex
);
1134 TRACE("-- selected Item found\n");
1140 /**********************************************************
1141 * ShellView_OpenSelectedItems()
1143 HRESULT
CDefView::OpenSelectedItems()
1146 CMINVOKECOMMANDINFO cmi
;
1150 m_cidl
= m_ListView
.GetSelectedCount();
1154 hResult
= OnDefaultCommand();
1155 if (hResult
== S_OK
)
1158 hMenu
= CreatePopupMenu();
1162 hResult
= GetItemObject(SVGIO_SELECTION
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1163 if (FAILED(hResult
))
1166 hResult
= IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1167 //if (FAILED( hResult))
1170 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, 0x20, 0x7fff, CMF_DEFAULTONLY
);
1171 if (FAILED(hResult
))
1174 uCommand
= GetMenuDefaultItem(hMenu
, FALSE
, 0);
1175 if (uCommand
== (UINT
)-1)
1181 ZeroMemory(&cmi
, sizeof(cmi
));
1182 cmi
.cbSize
= sizeof(cmi
);
1183 cmi
.lpVerb
= (LPCSTR
)MAKEINTRESOURCEA(uCommand
);
1186 hResult
= m_pCM
->InvokeCommand(&cmi
);
1195 IUnknown_SetSite(m_pCM
, NULL
);
1202 /**********************************************************
1203 * ShellView_DoContextMenu()
1205 LRESULT
CDefView::OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1211 CMINVOKECOMMANDINFO cmi
;
1214 // for some reason I haven't figured out, we sometimes recurse into this method
1221 TRACE("(%p)->(0x%08x 0x%08x) stub\n", this, x
, y
);
1223 hMenu
= CreatePopupMenu();
1227 m_cidl
= m_ListView
.GetSelectedCount();
1229 hResult
= GetItemObject( m_cidl
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1230 if (FAILED( hResult
))
1233 hResult
= IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1234 //if (FAILED( hResult))
1237 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1238 if (FAILED( hResult
))
1241 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
1242 SetMenuDefaultItem(hMenu
, FCIDM_SHVIEW_OPEN
, MF_BYCOMMAND
);
1244 uCommand
= TrackPopupMenu(hMenu
,
1245 TPM_LEFTALIGN
| TPM_RETURNCMD
| TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
,
1246 x
, y
, 0, m_hWnd
, NULL
);
1250 if (uCommand
== FCIDM_SHVIEW_OPEN
&& OnDefaultCommand() == S_OK
)
1253 ZeroMemory(&cmi
, sizeof(cmi
));
1254 cmi
.cbSize
= sizeof(cmi
);
1255 cmi
.lpVerb
= MAKEINTRESOURCEA(uCommand
);
1257 m_pCM
->InvokeCommand(&cmi
);
1263 IUnknown_SetSite(m_pCM
, NULL
);
1273 LRESULT
CDefView::OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
)
1276 CMINVOKECOMMANDINFO cmi
;
1279 hMenu
= CreatePopupMenu();
1283 hResult
= GetItemObject( bUseSelection
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1284 if (FAILED( hResult
))
1287 hResult
= IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1288 //if (FAILED( hResult))
1291 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1292 if (FAILED( hResult
))
1295 ZeroMemory(&cmi
, sizeof(cmi
));
1296 cmi
.cbSize
= sizeof(cmi
);
1297 cmi
.lpVerb
= MAKEINTRESOURCEA(uCommand
);
1299 m_pCM
->InvokeCommand(&cmi
);
1305 IUnknown_SetSite(m_pCM
, NULL
);
1315 /**********************************************************
1316 * ##### message handling #####
1319 /**********************************************************
1320 * ShellView_OnSize()
1322 LRESULT
CDefView::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1327 wWidth
= LOWORD(lParam
);
1328 wHeight
= HIWORD(lParam
);
1330 TRACE("%p width=%u height=%u\n", this, wWidth
, wHeight
);
1332 /*resize the ListView to fit our window*/
1335 ::MoveWindow(m_ListView
, 0, 0, wWidth
, wHeight
, TRUE
);
1341 /**********************************************************
1342 * ShellView_OnDeactivate()
1347 void CDefView::OnDeactivate()
1349 TRACE("%p\n", this);
1351 if (m_uState
!= SVUIA_DEACTIVATE
)
1353 // TODO: cleanup menu after deactivation
1355 m_uState
= SVUIA_DEACTIVATE
;
1359 void CDefView::DoActivate(UINT uState
)
1361 TRACE("%p uState=%x\n", this, uState
);
1363 /*don't do anything if the state isn't really changing */
1364 if (m_uState
== uState
)
1369 if (uState
== SVUIA_DEACTIVATE
)
1379 MENUITEMINFOW mii
= { 0 };
1381 /* initialize EDIT menu */
1382 mii
.cbSize
= sizeof(mii
);
1383 mii
.fMask
= MIIM_SUBMENU
;
1384 if (::GetMenuItemInfoW(m_hMenu
, FCIDM_MENU_EDIT
, FALSE
, &mii
))
1386 HMENU hSubMenu
= mii
.hSubMenu
;
1388 HMENU menubase
= ::LoadMenuW(shell32_hInstance
, L
"MENU_003");
1390 int count
= ::GetMenuItemCount(menubase
);
1391 for (int i
= 0; i
< count
; i
++)
1395 ZeroMemory(&mii
, sizeof(mii
));
1396 mii
.cbSize
= sizeof(mii
);
1397 mii
.fMask
= MIIM_STATE
| MIIM_ID
| MIIM_SUBMENU
| MIIM_CHECKMARKS
| MIIM_DATA
| MIIM_STRING
| MIIM_BITMAP
| MIIM_FTYPE
;
1398 mii
.dwTypeData
= label
;
1399 mii
.cch
= _countof(label
);
1400 ::GetMenuItemInfoW(menubase
, i
, TRUE
, &mii
);
1402 TRACE("Adding item %d label %S type %d\n", mii
.wID
, mii
.dwTypeData
, mii
.fType
);
1404 mii
.fType
|= MFT_RADIOCHECK
;
1406 ::InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, &mii
);
1409 ::DestroyMenu(menubase
);
1412 /* initialize VIEW menu */
1414 mii
.cbSize
= sizeof(mii
);
1415 mii
.fMask
= MIIM_SUBMENU
;
1416 if (::GetMenuItemInfoW(m_hMenu
, FCIDM_MENU_VIEW
, FALSE
, &mii
))
1418 HMENU menubase
= ::LoadMenuW(shell32_hInstance
, L
"MENU_001");
1420 HMENU hSubMenu
= mii
.hSubMenu
;
1422 m_hView
= CreatePopupMenu();
1424 _InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1426 int count
= ::GetMenuItemCount(menubase
);
1427 for (int i
= 0; i
< count
; i
++)
1431 ZeroMemory(&mii
, sizeof(mii
));
1432 mii
.cbSize
= sizeof(mii
);
1433 mii
.fMask
= MIIM_STATE
| MIIM_ID
| MIIM_SUBMENU
| MIIM_CHECKMARKS
| MIIM_DATA
| MIIM_STRING
| MIIM_BITMAP
| MIIM_FTYPE
;
1434 mii
.dwTypeData
= label
;
1435 mii
.cch
= _countof(label
);
1436 ::GetMenuItemInfoW(menubase
, i
, TRUE
, &mii
);
1438 ::AppendMenuW(m_hView
, mii
.fType
, mii
.wID
, mii
.dwTypeData
);
1440 TRACE("Adding item %d label %S type %d\n", mii
.wID
, mii
.dwTypeData
, mii
.fType
);
1442 mii
.fType
|= MFT_RADIOCHECK
;
1444 ::InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, &mii
);
1447 ::DestroyMenu(menubase
);
1451 TRACE("-- before fnSetMenuSB\n");
1452 m_pShellBrowser
->SetMenuSB(m_hMenu
, 0, m_hWnd
);
1454 m_menusLoaded
= TRUE
;
1458 if (SVUIA_ACTIVATE_FOCUS
== uState
)
1460 m_ListView
.SetFocus();
1468 /**********************************************************
1469 * ShellView_OnActivate()
1471 LRESULT
CDefView::OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1473 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1477 /**********************************************************
1478 * ShellView_OnSetFocus()
1481 LRESULT
CDefView::OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1483 TRACE("%p\n", this);
1485 /* Tell the browser one of our windows has received the focus. This
1486 should always be done before merging menus (OnActivate merges the
1487 menus) if one of our windows has the focus.*/
1489 m_pShellBrowser
->OnViewWindowActive(this);
1490 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1492 /* Set the focus to the listview */
1493 m_ListView
.SetFocus();
1495 /* Notify the ICommDlgBrowser interface */
1496 OnStateChange(CDBOSC_SETFOCUS
);
1501 /**********************************************************
1502 * ShellView_OnKillFocus()
1504 LRESULT
CDefView::OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1506 TRACE("(%p) stub\n", this);
1508 DoActivate(SVUIA_ACTIVATE_NOFOCUS
);
1509 /* Notify the ICommDlgBrowser */
1510 OnStateChange(CDBOSC_KILLFOCUS
);
1515 /**********************************************************
1516 * ShellView_OnCommand()
1519 * the CmdID's are the ones from the context menu
1521 LRESULT
CDefView::OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1527 dwCmdID
= GET_WM_COMMAND_ID(wParam
, lParam
);
1528 dwCmd
= GET_WM_COMMAND_CMD(wParam
, lParam
);
1529 hwndCmd
= GET_WM_COMMAND_HWND(wParam
, lParam
);
1531 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n", this, dwCmdID
, dwCmd
, hwndCmd
);
1535 case FCIDM_SHVIEW_SMALLICON
:
1536 m_FolderSettings
.ViewMode
= FVM_SMALLICON
;
1537 SetStyle (LVS_SMALLICON
, LVS_TYPEMASK
);
1541 case FCIDM_SHVIEW_BIGICON
:
1542 m_FolderSettings
.ViewMode
= FVM_ICON
;
1543 SetStyle (LVS_ICON
, LVS_TYPEMASK
);
1547 case FCIDM_SHVIEW_LISTVIEW
:
1548 m_FolderSettings
.ViewMode
= FVM_LIST
;
1549 SetStyle (LVS_LIST
, LVS_TYPEMASK
);
1553 case FCIDM_SHVIEW_REPORTVIEW
:
1554 m_FolderSettings
.ViewMode
= FVM_DETAILS
;
1555 SetStyle (LVS_REPORT
, LVS_TYPEMASK
);
1559 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1564 m_sortInfo
.nHeaderID
= dwCmdID
- 0x30;
1565 m_sortInfo
.bIsAscending
= TRUE
;
1566 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
1567 m_ListView
.SortItems(ListViewCompareItems
, &m_sortInfo
);
1570 case FCIDM_SHVIEW_REFRESH
:
1574 case FCIDM_SHVIEW_DELETE
:
1575 case FCIDM_SHVIEW_CUT
:
1576 case FCIDM_SHVIEW_COPY
:
1577 case FCIDM_SHVIEW_RENAME
:
1578 return OnExplorerCommand(dwCmdID
, TRUE
);
1580 case FCIDM_SHVIEW_INSERT
:
1581 case FCIDM_SHVIEW_UNDO
:
1582 case FCIDM_SHVIEW_INSERTLINK
:
1583 case FCIDM_SHVIEW_NEWFOLDER
:
1584 return OnExplorerCommand(dwCmdID
, FALSE
);
1586 TRACE("-- COMMAND 0x%04x unhandled\n", dwCmdID
);
1592 /**********************************************************
1593 * ShellView_OnNotify()
1596 LRESULT
CDefView::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1600 LPNMLISTVIEW lpnmlv
;
1601 NMLVDISPINFOW
*lpdi
;
1602 PCUITEMID_CHILD pidl
;
1606 lpnmh
= (LPNMHDR
)lParam
;
1607 lpnmlv
= (LPNMLISTVIEW
)lpnmh
;
1608 lpdi
= (NMLVDISPINFOW
*)lpnmh
;
1610 TRACE("%p CtlID=%u lpnmh->code=%x\n", this, CtlID
, lpnmh
->code
);
1612 switch (lpnmh
->code
)
1615 TRACE("-- NM_SETFOCUS %p\n", this);
1616 OnSetFocus(0, 0, 0, unused
);
1620 TRACE("-- NM_KILLFOCUS %p\n", this);
1622 /* Notify the ICommDlgBrowser interface */
1623 OnStateChange(CDBOSC_KILLFOCUS
);
1627 TRACE("-- NM_CUSTOMDRAW %p\n", this);
1628 return CDRF_DODEFAULT
;
1630 case NM_RELEASEDCAPTURE
:
1631 TRACE("-- NM_RELEASEDCAPTURE %p\n", this);
1635 TRACE("-- NM_CLICK %p\n", this);
1639 TRACE("-- NM_RCLICK %p\n", this);
1643 TRACE("-- NM_DBLCLK %p\n", this);
1644 OpenSelectedItems();
1648 TRACE("-- NM_RETURN %p\n", this);
1649 OpenSelectedItems();
1653 TRACE("-- HDN_ENDTRACKW %p\n", this);
1654 /*nColumn1 = m_ListView.GetColumnWidth(0);
1655 nColumn2 = m_ListView.GetColumnWidth(1);*/
1658 case LVN_DELETEITEM
:
1659 TRACE("-- LVN_DELETEITEM %p\n", this);
1661 /*delete the pidl because we made a copy of it*/
1662 SHFree(reinterpret_cast<LPVOID
>(lpnmlv
->lParam
));
1666 case LVN_DELETEALLITEMS
:
1667 TRACE("-- LVN_DELETEALLITEMS %p\n", this);
1670 case LVN_INSERTITEM
:
1671 TRACE("-- LVN_INSERTITEM (STUB)%p\n", this);
1674 case LVN_ITEMACTIVATE
:
1675 TRACE("-- LVN_ITEMACTIVATE %p\n", this);
1676 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1679 case LVN_COLUMNCLICK
:
1680 m_sortInfo
.nHeaderID
= lpnmlv
->iSubItem
;
1681 if (m_sortInfo
.nLastHeaderID
== m_sortInfo
.nHeaderID
)
1682 m_sortInfo
.bIsAscending
= !m_sortInfo
.bIsAscending
;
1684 m_sortInfo
.bIsAscending
= TRUE
;
1685 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
1687 m_ListView
.SortItems(ListViewCompareItems
, &m_sortInfo
);
1690 case LVN_GETDISPINFOA
:
1691 case LVN_GETDISPINFOW
:
1692 TRACE("-- LVN_GETDISPINFO %p\n", this);
1693 pidl
= _PidlByItem(lpdi
->item
);
1695 if (lpdi
->item
.mask
& LVIF_TEXT
) /* text requested */
1700 if (FAILED(m_pSF2Parent
->GetDetailsOf(pidl
, lpdi
->item
.iSubItem
, &sd
)))
1702 FIXME("failed to get details\n");
1706 if (lpnmh
->code
== LVN_GETDISPINFOA
)
1708 /* shouldn't happen */
1709 NMLVDISPINFOA
*lpdiA
= (NMLVDISPINFOA
*)lpnmh
;
1710 StrRetToStrNA( lpdiA
->item
.pszText
, lpdiA
->item
.cchTextMax
, &sd
.str
, NULL
);
1711 TRACE("-- text=%s\n", lpdiA
->item
.pszText
);
1713 else /* LVN_GETDISPINFOW */
1715 StrRetToStrNW( lpdi
->item
.pszText
, lpdi
->item
.cchTextMax
, &sd
.str
, NULL
);
1716 TRACE("-- text=%s\n", debugstr_w(lpdi
->item
.pszText
));
1724 if(lpdi
->item
.mask
& LVIF_IMAGE
) /* image requested */
1726 lpdi
->item
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
1728 lpdi
->item
.mask
|= LVIF_DI_SETITEM
;
1731 case LVN_ITEMCHANGED
:
1732 TRACE("-- LVN_ITEMCHANGED %p\n", this);
1733 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1737 case LVN_BEGINRDRAG
:
1738 TRACE("-- LVN_BEGINDRAG\n");
1740 if (GetSelections())
1742 CComPtr
<IDataObject
> pda
;
1743 DWORD dwAttributes
= SFGAO_CANLINK
;
1744 DWORD dwEffect
= DROPEFFECT_COPY
| DROPEFFECT_MOVE
;
1746 if (SUCCEEDED(m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, IID_NULL_PPV_ARG(IDataObject
, &pda
))))
1748 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(m_cidl
, m_apidl
, &dwAttributes
)))
1750 if (dwAttributes
& SFGAO_CANLINK
)
1752 dwEffect
|= DROPEFFECT_LINK
;
1756 CComPtr
<IAsyncOperation
> piaso
;
1757 if (SUCCEEDED(pda
->QueryInterface(IID_PPV_ARG(IAsyncOperation
, &piaso
))))
1759 piaso
->SetAsyncMode(TRUE
);
1763 DoDragDrop(pda
, this, dwEffect
, &dwEffect2
);
1768 case LVN_BEGINLABELEDITW
:
1770 DWORD dwAttr
= SFGAO_CANRENAME
;
1771 pidl
= _PidlByItem(lpdi
->item
);
1773 TRACE("-- LVN_BEGINLABELEDITW %p\n", this);
1775 m_pSFParent
->GetAttributesOf(1, &pidl
, &dwAttr
);
1776 if (SFGAO_CANRENAME
& dwAttr
)
1784 case LVN_ENDLABELEDITW
:
1786 TRACE("-- LVN_ENDLABELEDITW %p\n", this);
1788 m_isEditing
= FALSE
;
1790 if (lpdi
->item
.pszText
)
1795 pidl
= _PidlByItem(lpdi
->item
);
1796 PITEMID_CHILD pidlNew
;
1797 hr
= m_pSFParent
->SetNameOf(0, pidl
, lpdi
->item
.pszText
, SHGDN_INFOLDER
, &pidlNew
);
1799 if (SUCCEEDED(hr
) && pidlNew
)
1801 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
1802 lvItem
.iItem
= lpdi
->item
.iItem
;
1803 lvItem
.lParam
= reinterpret_cast<LPARAM
>(pidlNew
);
1804 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
1805 m_ListView
.SetItem(&lvItem
);
1806 m_ListView
.Update(lpdi
->item
.iItem
);
1815 TRACE("-- %p WM_COMMAND %x unhandled\n", this, lpnmh
->code
);
1822 /**********************************************************
1823 * ShellView_OnChange()
1825 LRESULT
CDefView::OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1827 PCIDLIST_ABSOLUTE
*Pidls
= reinterpret_cast<PCIDLIST_ABSOLUTE
*>(wParam
);
1829 TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls
[0], Pidls
[1], lParam
);
1835 LV_AddItem(ILFindLastID(Pidls
[0]));
1840 LV_DeleteItem(ILFindLastID(Pidls
[0]));
1843 case SHCNE_RENAMEFOLDER
:
1844 case SHCNE_RENAMEITEM
:
1845 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[1]));
1848 case SHCNE_UPDATEITEM
:
1849 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[0]));
1852 case SHCNE_UPDATEDIR
:
1859 /**********************************************************
1860 * CDefView::OnCustomItem
1862 LRESULT
CDefView::OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1867 ERR("no menu!!!\n");
1871 CComPtr
<IContextMenu2
> pCM2
;
1872 HRESULT hres
= m_pCM
.p
->QueryInterface(IID_PPV_ARG(IContextMenu2
, &pCM2
));
1876 if (pCM2
.p
->HandleMenuMsg(uMsg
, (WPARAM
)m_hWnd
, lParam
) == S_OK
)
1882 LRESULT
CDefView::OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1884 /* Wallpaper setting affects drop shadows effect */
1885 if (wParam
== SPI_SETDESKWALLPAPER
|| wParam
== 0)
1891 /**********************************************************
1892 * CDefView::OnInitMenuPopup
1894 LRESULT
CDefView::OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1896 MENUITEMINFOW mii
= { 0 };
1897 HMENU hSubmenu
= (HMENU
) wParam
;
1899 DbgPrint("OnInitMenuPopup lParam=%d\n", lParam
);
1901 mii
.cbSize
= sizeof(mii
);
1902 mii
.fMask
= MIIM_ID
| MIIM_SUBMENU
;
1904 if (!GetMenuItemInfoW(this->m_hMenu
, lParam
, TRUE
, &mii
))
1906 DbgPrint("OnInitMenuPopup GetMenuItemInfoW failed!\n");
1910 UINT menuItemId
= mii
.wID
;
1912 if (mii
.hSubMenu
!= hSubmenu
)
1914 DbgPrint("OnInitMenuPopup submenu does not match!!!!\n");
1918 DbgPrint("OnInitMenuPopup id=%d\n", menuItemId
);
1922 case FCIDM_MENU_FILE
:
1923 PrepareShowFileMenu(hSubmenu
);
1925 case FCIDM_MENU_EDIT
:
1926 //PrepareShowEditMenu(hSubmenu);
1928 case FCIDM_MENU_VIEW
:
1929 PrepareShowViewMenu(hSubmenu
);
1936 /**********************************************************
1939 * The INTERFACE of the IShellView object
1942 **********************************************************
1945 /**********************************************************
1946 * ShellView_GetWindow
1948 HRESULT WINAPI
CDefView::GetWindow(HWND
*phWnd
)
1950 TRACE("(%p)\n", this);
1957 HRESULT WINAPI
CDefView::ContextSensitiveHelp(BOOL fEnterMode
)
1959 FIXME("(%p) stub\n", this);
1964 /**********************************************************
1965 * IShellView_TranslateAccelerator
1968 * use the accel functions
1970 HRESULT WINAPI
CDefView::TranslateAccelerator(LPMSG lpmsg
)
1975 if (lpmsg
->message
>= WM_KEYFIRST
&& lpmsg
->message
<= WM_KEYLAST
)
1977 if (::TranslateAcceleratorW(m_hWnd
, m_hAccel
, lpmsg
) != 0)
1980 TRACE("-- key=0x04%lx\n", lpmsg
->wParam
) ;
1983 return m_pShellBrowser
->TranslateAcceleratorSB(lpmsg
, 0);
1986 HRESULT WINAPI
CDefView::EnableModeless(BOOL fEnable
)
1988 FIXME("(%p) stub\n", this);
1993 HRESULT WINAPI
CDefView::UIActivate(UINT uState
)
1996 CHAR szName[MAX_PATH];
1999 int nPartArray
[1] = { -1};
2001 TRACE("(%p)->(state=%x) stub\n", this, uState
);
2003 /*don't do anything if the state isn't really changing*/
2004 if (m_uState
== uState
)
2009 /*OnActivate handles the menu merging and internal state*/
2012 /*only do This if we are active*/
2013 if (uState
!= SVUIA_DEACTIVATE
)
2017 GetFolderPath is not a method of IShellFolder
2018 IShellFolder_GetFolderPath( m_pSFParent, szName, sizeof(szName) );
2020 /* set the number of parts */
2021 m_pShellBrowser
->SendControlMsg(FCW_STATUS
, SB_SETPARTS
, 1, (LPARAM
)nPartArray
, &lResult
);
2023 /* set the text for the parts */
2025 m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXTA, 0, (LPARAM)szName, &lResult);
2032 HRESULT WINAPI
CDefView::Refresh()
2034 TRACE("(%p)\n", this);
2036 m_ListView
.DeleteAllItems();
2042 HRESULT WINAPI
CDefView::CreateViewWindow(IShellView
*lpPrevView
, LPCFOLDERSETTINGS lpfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
)
2044 OLEMENUGROUPWIDTHS omw
= { { 0, 0, 0, 0, 0, 0 } };
2048 TRACE("(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n", this, lpPrevView
, lpfs
, psb
, prcView
, phWnd
);
2051 TRACE("-- vmode=%x flags=%x\n", lpfs
->ViewMode
, lpfs
->fFlags
);
2052 if (prcView
!= NULL
)
2053 TRACE("-- left=%i top=%i right=%i bottom=%i\n", prcView
->left
, prcView
->top
, prcView
->right
, prcView
->bottom
);
2055 /* Validate the Shell Browser */
2057 return E_UNEXPECTED
;
2059 /*set up the member variables*/
2060 m_pShellBrowser
= psb
;
2061 m_FolderSettings
= *lpfs
;
2063 /*get our parent window*/
2064 m_pShellBrowser
->GetWindow(&m_hWndParent
);
2066 /* try to get the ICommDlgBrowserInterface, adds a reference !!! */
2067 m_pCommDlgBrowser
= NULL
;
2068 if (SUCCEEDED(m_pShellBrowser
->QueryInterface(IID_PPV_ARG(ICommDlgBrowser
, &m_pCommDlgBrowser
))))
2070 TRACE("-- CommDlgBrowser\n");
2073 Create(m_hWndParent
, prcView
, NULL
, WS_CHILD
| WS_TABSTOP
, 0, 0U);
2084 SetWindowPos(HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_SHOWWINDOW
);
2089 m_hMenu
= CreateMenu();
2090 m_pShellBrowser
->InsertMenusSB(m_hMenu
, &omw
);
2091 TRACE("-- after fnInsertMenusSB\n");
2099 HRESULT WINAPI
CDefView::DestroyViewWindow()
2101 TRACE("(%p)\n", this);
2103 /*Make absolutely sure all our UI is cleaned up.*/
2104 UIActivate(SVUIA_DEACTIVATE
);
2108 // "Accelerator tables loaded from resources are freed automatically when the application terminates." -- MSDN
2114 DestroyMenu(m_hView
);
2120 DestroyMenu(m_hMenu
);
2126 m_ListView
.DestroyWindow();
2134 m_pShellBrowser
.Release();
2135 m_pCommDlgBrowser
.Release();
2140 HRESULT WINAPI
CDefView::GetCurrentInfo(LPFOLDERSETTINGS lpfs
)
2142 TRACE("(%p)->(%p) vmode=%x flags=%x\n", this, lpfs
,
2143 m_FolderSettings
.ViewMode
, m_FolderSettings
.fFlags
);
2146 return E_INVALIDARG
;
2148 *lpfs
= m_FolderSettings
;
2152 HRESULT WINAPI
CDefView::AddPropertySheetPages(DWORD dwReserved
, LPFNADDPROPSHEETPAGE lpfn
, LPARAM lparam
)
2154 FIXME("(%p) stub\n", this);
2159 HRESULT WINAPI
CDefView::SaveViewState()
2161 FIXME("(%p) stub\n", this);
2166 HRESULT WINAPI
CDefView::SelectItem(PCUITEMID_CHILD pidl
, UINT uFlags
)
2170 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n", this, pidl
, uFlags
);
2172 i
= LV_FindItemByPidl(pidl
);
2176 if(uFlags
& SVSI_ENSUREVISIBLE
)
2177 m_ListView
.EnsureVisible(i
, FALSE
);
2179 LVITEMW lvItem
= {0};
2180 lvItem
.mask
= LVIF_STATE
;
2181 lvItem
.stateMask
= LVIS_SELECTED
| LVIS_FOCUSED
;
2183 while (m_ListView
.GetItem(&lvItem
))
2185 if (lvItem
.iItem
== i
)
2187 if (uFlags
& SVSI_SELECT
)
2188 lvItem
.state
|= LVIS_SELECTED
;
2190 lvItem
.state
&= ~LVIS_SELECTED
;
2192 if (uFlags
& SVSI_FOCUSED
)
2193 lvItem
.state
&= ~LVIS_FOCUSED
;
2197 if (uFlags
& SVSI_DESELECTOTHERS
)
2198 lvItem
.state
&= ~LVIS_SELECTED
;
2201 m_ListView
.SetItem(&lvItem
);
2205 if(uFlags
& SVSI_EDIT
)
2206 m_ListView
.EditLabel(i
);
2211 HRESULT WINAPI
CDefView::GetItemObject(UINT uItem
, REFIID riid
, LPVOID
*ppvOut
)
2213 HRESULT hr
= E_NOINTERFACE
;
2215 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n", this, uItem
, debugstr_guid(&riid
), ppvOut
);
2221 case SVGIO_BACKGROUND
:
2222 if (IsEqualIID(riid
, IID_IContextMenu
))
2224 //*ppvOut = ISvBgCm_Constructor(m_pSFParent, FALSE);
2229 hr
= CDefFolderMenu_Create2(NULL
, NULL
, 0, NULL
, m_pSFParent
, NULL
, 0, NULL
, &pcm
);
2236 case SVGIO_SELECTION
:
2238 hr
= m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, riid
, 0, ppvOut
);
2242 TRACE("-- (%p)->(interface=%p)\n", this, *ppvOut
);
2247 HRESULT STDMETHODCALLTYPE
CDefView::GetCurrentViewMode(UINT
*pViewMode
)
2249 TRACE("(%p)->(%p), stub\n", this, pViewMode
);
2252 return E_INVALIDARG
;
2254 *pViewMode
= m_FolderSettings
.ViewMode
;
2258 HRESULT STDMETHODCALLTYPE
CDefView::SetCurrentViewMode(UINT ViewMode
)
2261 TRACE("(%p)->(%u), stub\n", this, ViewMode
);
2263 /* It's not redundant to check FVM_AUTO because it's a (UINT)-1 */
2264 if ((ViewMode
< FVM_FIRST
|| ViewMode
> FVM_LAST
) && (ViewMode
!= FVM_AUTO
))
2265 return E_INVALIDARG
;
2267 /* Windows before Vista uses LVM_SETVIEW and possibly
2268 LVM_SETEXTENDEDLISTVIEWSTYLE to set the style of the listview,
2269 while later versions seem to accomplish this through other
2277 dwStyle
= LVS_REPORT
;
2280 dwStyle
= LVS_SMALLICON
;
2287 FIXME("ViewMode %d not implemented\n", ViewMode
);
2293 SetStyle(dwStyle
, LVS_TYPEMASK
);
2295 /* This will not necessarily be the actual mode set above.
2296 This mimics the behavior of Windows XP. */
2297 m_FolderSettings
.ViewMode
= ViewMode
;
2302 HRESULT STDMETHODCALLTYPE
CDefView::GetFolder(REFIID riid
, void **ppv
)
2304 if (m_pSFParent
== NULL
)
2307 return m_pSFParent
->QueryInterface(riid
, ppv
);
2310 HRESULT STDMETHODCALLTYPE
CDefView::Item(int iItemIndex
, PITEMID_CHILD
*ppidl
)
2312 PCUITEMID_CHILD pidl
= _PidlByItem(iItemIndex
);
2315 *ppidl
= ILClone(pidl
);
2320 return E_INVALIDARG
;
2323 HRESULT STDMETHODCALLTYPE
CDefView::ItemCount(UINT uFlags
, int *pcItems
)
2325 TRACE("(%p)->(%u %p)\n", this, uFlags
, pcItems
);
2327 if (uFlags
!= SVGIO_ALLVIEW
)
2328 FIXME("some flags unsupported, %x\n", uFlags
& ~SVGIO_ALLVIEW
);
2330 *pcItems
= m_ListView
.GetItemCount();
2335 HRESULT STDMETHODCALLTYPE
CDefView::Items(UINT uFlags
, REFIID riid
, void **ppv
)
2340 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectionMarkedItem(int *piItem
)
2342 TRACE("(%p)->(%p)\n", this, piItem
);
2344 *piItem
= m_ListView
.GetSelectionMark();
2349 HRESULT STDMETHODCALLTYPE
CDefView::GetFocusedItem(int *piItem
)
2351 TRACE("(%p)->(%p)\n", this, piItem
);
2353 *piItem
= m_ListView
.GetNextItem(-1, LVNI_FOCUSED
);
2358 HRESULT STDMETHODCALLTYPE
CDefView::GetItemPosition(PCUITEMID_CHILD pidl
, POINT
*ppt
)
2363 HRESULT STDMETHODCALLTYPE
CDefView::GetSpacing(POINT
*ppt
)
2365 TRACE("(%p)->(%p)\n", this, ppt
);
2373 m_ListView
.GetItemSpacing(spacing
);
2375 ppt
->x
= spacing
.cx
;
2376 ppt
->y
= spacing
.cy
;
2382 HRESULT STDMETHODCALLTYPE
CDefView::GetDefaultSpacing(POINT
*ppt
)
2387 HRESULT STDMETHODCALLTYPE
CDefView::GetAutoArrange()
2392 HRESULT STDMETHODCALLTYPE
CDefView::SelectItem(int iItem
, DWORD dwFlags
)
2396 TRACE("(%p)->(%d, %x)\n", this, iItem
, dwFlags
);
2399 lvItem
.stateMask
= LVIS_SELECTED
;
2401 if (dwFlags
& SVSI_ENSUREVISIBLE
)
2402 m_ListView
.EnsureVisible(iItem
, 0);
2405 if (dwFlags
& SVSI_DESELECTOTHERS
)
2406 m_ListView
.SetItemState(-1, 0, LVIS_SELECTED
);
2409 if (dwFlags
& SVSI_SELECT
)
2410 lvItem
.state
|= LVIS_SELECTED
;
2412 if (dwFlags
& SVSI_FOCUSED
)
2413 lvItem
.stateMask
|= LVIS_FOCUSED
;
2415 m_ListView
.SetItemState(iItem
, lvItem
.state
, lvItem
.stateMask
);
2417 if (dwFlags
& SVSI_EDIT
)
2418 m_ListView
.EditLabel(iItem
);
2423 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItems(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD dwFlags
)
2428 /**********************************************************
2429 * IShellFolderView implementation
2431 HRESULT STDMETHODCALLTYPE
CDefView::Rearrange(LPARAM sort
)
2433 FIXME("(%p)->(%ld) stub\n", this, sort
);
2437 HRESULT STDMETHODCALLTYPE
CDefView::GetArrangeParam(LPARAM
*sort
)
2439 FIXME("(%p)->(%p) stub\n", this, sort
);
2443 HRESULT STDMETHODCALLTYPE
CDefView::ArrangeGrid()
2445 FIXME("(%p) stub\n", this);
2449 HRESULT STDMETHODCALLTYPE
CDefView::AutoArrange()
2451 FIXME("(%p) stub\n", this);
2455 HRESULT STDMETHODCALLTYPE
CDefView::AddObject(PITEMID_CHILD pidl
, UINT
*item
)
2457 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2461 HRESULT STDMETHODCALLTYPE
CDefView::GetObject(PITEMID_CHILD
*pidl
, UINT item
)
2463 TRACE("(%p)->(%p %d)\n", this, pidl
, item
);
2464 return Item(item
, pidl
);
2467 HRESULT STDMETHODCALLTYPE
CDefView::RemoveObject(PITEMID_CHILD pidl
, UINT
*item
)
2470 TRACE("(%p)->(%p %p)\n", this, pidl
, item
);
2474 *item
= LV_FindItemByPidl(ILFindLastID(pidl
));
2475 m_ListView
.DeleteItem(*item
);
2480 m_ListView
.DeleteAllItems();
2486 HRESULT STDMETHODCALLTYPE
CDefView::GetObjectCount(UINT
*count
)
2488 TRACE("(%p)->(%p)\n", this, count
);
2489 *count
= m_ListView
.GetItemCount();
2493 HRESULT STDMETHODCALLTYPE
CDefView::SetObjectCount(UINT count
, UINT flags
)
2495 FIXME("(%p)->(%d %x) stub\n", this, count
, flags
);
2499 HRESULT STDMETHODCALLTYPE
CDefView::UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
)
2501 FIXME("(%p)->(%p %p %p) stub\n", this, pidl_old
, pidl_new
, item
);
2505 HRESULT STDMETHODCALLTYPE
CDefView::RefreshObject(PITEMID_CHILD pidl
, UINT
*item
)
2507 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2511 HRESULT STDMETHODCALLTYPE
CDefView::SetRedraw(BOOL redraw
)
2513 TRACE("(%p)->(%d)\n", this, redraw
);
2514 m_ListView
.SetRedraw(redraw
);
2518 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedCount(UINT
*count
)
2520 FIXME("(%p)->(%p) stub\n", this, count
);
2524 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
)
2526 TRACE("(%p)->(%p %p)\n", this, pidl
, items
);
2528 *items
= GetSelections();
2532 *pidl
= static_cast<PCUITEMID_CHILD
*>(LocalAlloc(0, *items
* sizeof(PCUITEMID_CHILD
)));
2535 return E_OUTOFMEMORY
;
2538 /* it's documented that caller shouldn't PIDLs, only array itself */
2539 memcpy(*pidl
, m_apidl
, *items
* sizeof(PCUITEMID_CHILD
));
2545 HRESULT STDMETHODCALLTYPE
CDefView::IsDropOnSource(IDropTarget
*drop_target
)
2547 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2551 HRESULT STDMETHODCALLTYPE
CDefView::GetDragPoint(POINT
*pt
)
2553 FIXME("(%p)->(%p) stub\n", this, pt
);
2557 HRESULT STDMETHODCALLTYPE
CDefView::GetDropPoint(POINT
*pt
)
2559 FIXME("(%p)->(%p) stub\n", this, pt
);
2563 HRESULT STDMETHODCALLTYPE
CDefView::MoveIcons(IDataObject
*obj
)
2565 TRACE("(%p)->(%p)\n", this, obj
);
2569 HRESULT STDMETHODCALLTYPE
CDefView::SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
)
2571 FIXME("(%p)->(%p %p) stub\n", this, pidl
, pt
);
2575 HRESULT STDMETHODCALLTYPE
CDefView::IsBkDropTarget(IDropTarget
*drop_target
)
2577 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2581 HRESULT STDMETHODCALLTYPE
CDefView::SetClipboard(BOOL move
)
2583 FIXME("(%p)->(%d) stub\n", this, move
);
2587 HRESULT STDMETHODCALLTYPE
CDefView::SetPoints(IDataObject
*obj
)
2589 FIXME("(%p)->(%p) stub\n", this, obj
);
2593 HRESULT STDMETHODCALLTYPE
CDefView::GetItemSpacing(ITEMSPACING
*spacing
)
2595 FIXME("(%p)->(%p) stub\n", this, spacing
);
2599 HRESULT STDMETHODCALLTYPE
CDefView::SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
)
2601 FIXME("(%p)->(%p %p) stub\n", this, new_cb
, old_cb
);
2605 HRESULT STDMETHODCALLTYPE
CDefView::Select(UINT flags
)
2607 FIXME("(%p)->(%d) stub\n", this, flags
);
2611 HRESULT STDMETHODCALLTYPE
CDefView::QuerySupport(UINT
*support
)
2613 TRACE("(%p)->(%p)\n", this, support
);
2617 HRESULT STDMETHODCALLTYPE
CDefView::SetAutomationObject(IDispatch
*disp
)
2619 FIXME("(%p)->(%p) stub\n", this, disp
);
2623 /**********************************************************
2624 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2626 HRESULT WINAPI
CDefView::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD
*prgCmds
, OLECMDTEXT
*pCmdText
)
2628 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
2629 this, pguidCmdGroup
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
2632 return E_INVALIDARG
;
2634 for (UINT i
= 0; i
< cCmds
; i
++)
2636 FIXME("\tprgCmds[%d].cmdID = %d\n", i
, prgCmds
[i
].cmdID
);
2637 prgCmds
[i
].cmdf
= 0;
2640 return OLECMDERR_E_UNKNOWNGROUP
;
2643 /**********************************************************
2644 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2646 * nCmdID is the OLECMDID_* enumeration
2648 HRESULT WINAPI
CDefView::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
2650 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2651 this, debugstr_guid(pguidCmdGroup
), nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2654 return OLECMDERR_E_UNKNOWNGROUP
;
2656 if (IsEqualCLSID(*pguidCmdGroup
, m_Category
))
2658 if (nCmdID
== FCIDM_SHVIEW_AUTOARRANGE
)
2660 if (V_VT(pvaIn
) != VT_INT_PTR
)
2661 return OLECMDERR_E_NOTSUPPORTED
;
2665 params
.cbSize
= sizeof(params
);
2666 params
.rcExclude
= *(RECT
*) V_INTREF(pvaIn
);
2668 HMENU hView
= m_hView
;
2670 hView
= CreatePopupMenu();
2671 AppendMenuW(hView
, MF_STRING
, FCIDM_SHVIEW_BIGICON
, L
"Big!");
2672 AppendMenuW(hView
, MF_STRING
, FCIDM_SHVIEW_SMALLICON
, L
"Small!");
2673 AppendMenuW(hView
, MF_STRING
, FCIDM_SHVIEW_LISTVIEW
, L
"List!");
2674 AppendMenuW(hView
, MF_STRING
, FCIDM_SHVIEW_REPORTVIEW
, L
"Report!");
2679 PrepareShowViewMenu(hView
);
2681 TrackPopupMenuEx(hView
, TPM_LEFTALIGN
| TPM_TOPALIGN
, params
.rcExclude
.left
, params
.rcExclude
.bottom
, m_hWndParent
, ¶ms
);
2684 // pvaOut is VT_I4 with value 0x403 (cmd id of the new mode maybe?)
2685 V_VT(pvaOut
) = VT_I4
;
2686 V_I4(pvaOut
) = 0x403;
2690 if (IsEqualIID(*pguidCmdGroup
, CGID_Explorer
) &&
2692 (nCmdexecopt
== 4) && pvaOut
)
2695 if (IsEqualIID(*pguidCmdGroup
, CGID_ShellDocView
) &&
2700 return OLECMDERR_E_UNKNOWNGROUP
;
2703 /**********************************************************
2704 * ISVDropTarget implementation
2707 /******************************************************************************
2708 * drag_notify_subitem [Internal]
2710 * Figure out the shellfolder object, which is currently under the mouse cursor
2711 * and notify it via the IDropTarget interface.
2714 #define SCROLLAREAWIDTH 20
2716 HRESULT
CDefView::drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2718 LVHITTESTINFO htinfo
;
2723 /* Map from global to client coordinates and query the index of the listview-item, which is
2724 * currently under the mouse cursor. */
2727 htinfo
.flags
= LVHT_ONITEM
;
2728 ::ScreenToClient(m_ListView
, &htinfo
.pt
);
2729 lResult
= m_ListView
.HitTest(&htinfo
);
2731 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2732 ::GetClientRect(m_ListView
, &clientRect
);
2733 if (htinfo
.pt
.x
== m_ptLastMousePos
.x
&& htinfo
.pt
.y
== m_ptLastMousePos
.y
&&
2734 (htinfo
.pt
.x
< SCROLLAREAWIDTH
|| htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
||
2735 htinfo
.pt
.y
< SCROLLAREAWIDTH
|| htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
))
2737 m_cScrollDelay
= (m_cScrollDelay
+ 1) % 5; /* DragOver is called every 50 ms */
2738 if (m_cScrollDelay
== 0)
2740 /* Mouse did hover another 250 ms over the scroll-area */
2741 if (htinfo
.pt
.x
< SCROLLAREAWIDTH
)
2742 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEUP
, 0);
2744 if (htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
)
2745 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEDOWN
, 0);
2747 if (htinfo
.pt
.y
< SCROLLAREAWIDTH
)
2748 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEUP
, 0);
2750 if (htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
)
2751 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEDOWN
, 0);
2756 m_cScrollDelay
= 0; /* Reset, if the cursor is not over the listview's scroll-area */
2759 m_ptLastMousePos
= htinfo
.pt
;
2761 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2762 if (m_pCurDropTarget
&& lResult
== m_iDragOverItem
)
2763 return m_pCurDropTarget
->DragOver(grfKeyState
, pt
, pdwEffect
);
2765 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2766 if (m_pCurDropTarget
)
2768 m_pCurDropTarget
->DragLeave();
2769 m_pCurDropTarget
.Release();
2772 m_iDragOverItem
= lResult
;
2775 /* We are not above one of the listview's subitems. Bind to the parent folder's
2776 * DropTarget interface. */
2777 hr
= m_pSFParent
->QueryInterface(IID_PPV_ARG(IDropTarget
,&m_pCurDropTarget
));
2781 /* Query the relative PIDL of the shellfolder object represented by the currently
2782 * dragged over listview-item ... */
2783 PCUITEMID_CHILD pidl
= _PidlByItem(lResult
);
2785 /* ... and bind m_pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2786 hr
= m_pSFParent
->GetUIObjectOf(m_ListView
, 1, &pidl
, IID_NULL_PPV_ARG(IDropTarget
, &m_pCurDropTarget
));
2789 /* If anything failed, m_pCurDropTarget should be NULL now, which ought to be a save state. */
2793 /* Notify the item just entered via DragEnter. */
2794 return m_pCurDropTarget
->DragEnter(m_pCurDataObject
, grfKeyState
, pt
, pdwEffect
);
2797 HRESULT WINAPI
CDefView::DragEnter(IDataObject
*pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2799 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2800 m_pCurDataObject
= pDataObject
;
2801 pDataObject
->AddRef();
2803 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2806 HRESULT WINAPI
CDefView::DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2808 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2811 HRESULT WINAPI
CDefView::DragLeave()
2813 if (m_pCurDropTarget
)
2815 m_pCurDropTarget
->DragLeave();
2816 m_pCurDropTarget
.Release();
2819 if (m_pCurDataObject
!= NULL
)
2821 m_pCurDataObject
.Release();
2824 m_iDragOverItem
= 0;
2829 HRESULT WINAPI
CDefView::Drop(IDataObject
* pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2831 if (m_pCurDropTarget
)
2833 m_pCurDropTarget
->Drop(pDataObject
, grfKeyState
, pt
, pdwEffect
);
2834 m_pCurDropTarget
.Release();
2837 m_pCurDataObject
.Release();
2838 m_iDragOverItem
= 0;
2842 /**********************************************************
2843 * ISVDropSource implementation
2846 HRESULT WINAPI
CDefView::QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
)
2848 TRACE("(%p)\n", this);
2851 return DRAGDROP_S_CANCEL
;
2852 else if (!(grfKeyState
& MK_LBUTTON
) && !(grfKeyState
& MK_RBUTTON
))
2853 return DRAGDROP_S_DROP
;
2858 HRESULT WINAPI
CDefView::GiveFeedback(DWORD dwEffect
)
2860 TRACE("(%p)\n", this);
2862 return DRAGDROP_S_USEDEFAULTCURSORS
;
2865 /**********************************************************
2866 * ISVViewObject implementation
2869 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
)
2871 FIXME("Stub: this=%p\n", this);
2876 HRESULT WINAPI
CDefView::GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
, HDC hicTargetDevice
, LOGPALETTE
**ppColorSet
)
2878 FIXME("Stub: this=%p\n", this);
2883 HRESULT WINAPI
CDefView::Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
)
2885 FIXME("Stub: this=%p\n", this);
2890 HRESULT WINAPI
CDefView::Unfreeze(DWORD dwFreeze
)
2892 FIXME("Stub: this=%p\n", this);
2897 HRESULT WINAPI
CDefView::SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
)
2899 FIXME("partial stub: %p %08x %08x %p\n", this, aspects
, advf
, pAdvSink
);
2901 /* FIXME: we set the AdviseSink, but never use it to send any advice */
2902 m_pAdvSink
= pAdvSink
;
2903 m_dwAspects
= aspects
;
2909 HRESULT WINAPI
CDefView::GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
)
2911 TRACE("this=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n", this, pAspects
, pAdvf
, ppAdvSink
);
2915 *ppAdvSink
= m_pAdvSink
;
2916 m_pAdvSink
.p
->AddRef();
2920 *pAspects
= m_dwAspects
;
2928 HRESULT STDMETHODCALLTYPE
CDefView::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
2930 if (IsEqualIID(guidService
, SID_IShellBrowser
))
2931 return m_pShellBrowser
->QueryInterface(riid
, ppvObject
);
2932 else if(IsEqualIID(guidService
, SID_IFolderView
))
2933 return QueryInterface(riid
, ppvObject
);
2935 return E_NOINTERFACE
;
2938 HRESULT
CDefView::_MergeToolbar()
2940 CComPtr
<IExplorerToolbar
> ptb
; // [sp+8h] [bp-4h]@1
2944 hr
= IUnknown_QueryService(m_pShellBrowser
, IID_IExplorerToolbar
, IID_PPV_ARG(IExplorerToolbar
, &ptb
));
2948 m_Category
= CGID_DefViewFrame
;
2950 hr
= ptb
->SetCommandTarget(static_cast<IOleCommandTarget
*>(this), &m_Category
, 0);
2958 hr
= ptb
->AddButtons(&m_Category
, buttonsCount
, buttons
);
2965 /**********************************************************
2966 * IShellView_Constructor
2968 HRESULT WINAPI
IShellView_Constructor(IShellFolder
*pFolder
, IShellView
**newView
)
2970 return ShellObjectCreatorInit
<CDefView
>(pFolder
, IID_IShellView
, newView
);