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
55 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
59 static const WCHAR SV_CLASS_NAME
[] = {'S', 'H', 'E', 'L', 'L', 'D', 'L', 'L', '_', 'D', 'e', 'f', 'V', 'i', 'e', 'w', 0};
65 } LISTVIEW_SORT_INFO
, *LPLISTVIEW_SORT_INFO
;
67 #define SHV_CHANGE_NOTIFY WM_USER + 0x1111
70 public CWindowImpl
<CDefView
, CWindow
, CControlWinTraits
>,
71 public CComObjectRootEx
<CComMultiThreadModelNoCS
>,
74 public IShellFolderView
,
75 public IOleCommandTarget
,
79 public IServiceProvider
82 CComPtr
<IShellFolder
> m_pSFParent
;
83 CComPtr
<IShellFolder2
> m_pSF2Parent
;
84 CComPtr
<IShellBrowser
> m_pShellBrowser
;
85 CComPtr
<ICommDlgBrowser
> m_pCommDlgBrowser
;
86 HWND m_hWndList
; /* ListView control */
88 FOLDERSETTINGS m_FolderSettings
;
93 LPITEMIDLIST
*m_apidl
;
94 LISTVIEW_SORT_INFO m_sortInfo
;
95 ULONG m_hNotify
; /* change notification handle */
99 CComPtr
<IAdviseSink
> m_pAdvSink
;
101 CComPtr
<IDropTarget
> m_pCurDropTarget
; /* The sub-item, which is currently dragged over */
102 CComPtr
<IDataObject
> m_pCurDataObject
; /* The dragged data-object */
103 LONG m_iDragOverItem
; /* Dragged over item's index, iff m_pCurDropTarget != NULL */
104 UINT m_cScrollDelay
; /* Send a WM_*SCROLL msg every 250 ms during drag-scroll */
105 POINT m_ptLastMousePos
; /* Mouse position at last DragOver call */
107 CComPtr
<IContextMenu
> m_pCM
;
111 HRESULT WINAPI
Initialize(IShellFolder
*shellFolder
);
112 HRESULT
IncludeObject(LPCITEMIDLIST pidl
);
113 HRESULT
OnDefaultCommand();
114 HRESULT
OnStateChange(UINT uFlags
);
116 void SetStyle(DWORD dwAdd
, DWORD dwRemove
);
118 void UpdateListColors();
120 static INT CALLBACK
CompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
);
121 static INT CALLBACK
ListViewCompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
);
122 int LV_FindItemByPidl(LPCITEMIDLIST pidl
);
123 BOOLEAN
LV_AddItem(LPCITEMIDLIST pidl
);
124 BOOLEAN
LV_DeleteItem(LPCITEMIDLIST pidl
);
125 BOOLEAN
LV_RenameItem(LPCITEMIDLIST pidlOld
, LPCITEMIDLIST pidlNew
);
126 static INT CALLBACK
fill_list(LPVOID ptr
, LPVOID arg
);
128 HMENU
BuildFileMenu();
129 void PrepareShowFileMenu(HMENU hSubMenu
);
130 void PrepareShowViewMenu(HMENU hSubMenu
);
131 UINT
GetSelections();
132 HRESULT
OpenSelectedItems();
134 void DoActivate(UINT uState
);
135 HRESULT
drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
136 LRESULT
OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
);
138 // *** IOleWindow methods ***
139 virtual HRESULT STDMETHODCALLTYPE
GetWindow(HWND
*lphwnd
);
140 virtual HRESULT STDMETHODCALLTYPE
ContextSensitiveHelp(BOOL fEnterMode
);
142 // *** IShellView methods ***
143 virtual HRESULT STDMETHODCALLTYPE
TranslateAccelerator(MSG
*pmsg
);
144 virtual HRESULT STDMETHODCALLTYPE
EnableModeless(BOOL fEnable
);
145 virtual HRESULT STDMETHODCALLTYPE
UIActivate(UINT uState
);
146 virtual HRESULT STDMETHODCALLTYPE
Refresh();
147 virtual HRESULT STDMETHODCALLTYPE
CreateViewWindow(IShellView
*psvPrevious
, LPCFOLDERSETTINGS pfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
);
148 virtual HRESULT STDMETHODCALLTYPE
DestroyViewWindow();
149 virtual HRESULT STDMETHODCALLTYPE
GetCurrentInfo(LPFOLDERSETTINGS pfs
);
150 virtual HRESULT STDMETHODCALLTYPE
AddPropertySheetPages(DWORD dwReserved
, LPFNSVADDPROPSHEETPAGE pfn
, LPARAM lparam
);
151 virtual HRESULT STDMETHODCALLTYPE
SaveViewState();
152 virtual HRESULT STDMETHODCALLTYPE
SelectItem(LPCITEMIDLIST pidlItem
, SVSIF uFlags
);
153 virtual HRESULT STDMETHODCALLTYPE
GetItemObject(UINT uItem
, REFIID riid
, void **ppv
);
155 // *** IFolderView methods ***
156 virtual HRESULT STDMETHODCALLTYPE
GetCurrentViewMode(UINT
*pViewMode
);
157 virtual HRESULT STDMETHODCALLTYPE
SetCurrentViewMode(UINT ViewMode
);
158 virtual HRESULT STDMETHODCALLTYPE
GetFolder(REFIID riid
, void **ppv
);
159 virtual HRESULT STDMETHODCALLTYPE
Item(int iItemIndex
, LPITEMIDLIST
*ppidl
);
160 virtual HRESULT STDMETHODCALLTYPE
ItemCount(UINT uFlags
, int *pcItems
);
161 virtual HRESULT STDMETHODCALLTYPE
Items(UINT uFlags
, REFIID riid
, void **ppv
);
162 virtual HRESULT STDMETHODCALLTYPE
GetSelectionMarkedItem(int *piItem
);
163 virtual HRESULT STDMETHODCALLTYPE
GetFocusedItem(int *piItem
);
164 virtual HRESULT STDMETHODCALLTYPE
GetItemPosition(LPCITEMIDLIST pidl
, POINT
*ppt
);
165 virtual HRESULT STDMETHODCALLTYPE
GetSpacing(POINT
*ppt
);
166 virtual HRESULT STDMETHODCALLTYPE
GetDefaultSpacing(POINT
*ppt
);
167 virtual HRESULT STDMETHODCALLTYPE
GetAutoArrange();
168 virtual HRESULT STDMETHODCALLTYPE
SelectItem(int iItem
, DWORD dwFlags
);
169 virtual HRESULT STDMETHODCALLTYPE
SelectAndPositionItems(UINT cidl
, LPCITEMIDLIST
*apidl
, POINT
*apt
, DWORD dwFlags
);
171 // *** IShellFolderView methods ***
172 virtual HRESULT STDMETHODCALLTYPE
Rearrange(LPARAM sort
);
173 virtual HRESULT STDMETHODCALLTYPE
GetArrangeParam(LPARAM
*sort
);
174 virtual HRESULT STDMETHODCALLTYPE
ArrangeGrid();
175 virtual HRESULT STDMETHODCALLTYPE
AutoArrange();
176 virtual HRESULT STDMETHODCALLTYPE
IShellFolderView_GetAutoArrange();
177 virtual HRESULT STDMETHODCALLTYPE
AddObject(PITEMID_CHILD pidl
, UINT
*item
);
178 virtual HRESULT STDMETHODCALLTYPE
GetObject(PITEMID_CHILD
*pidl
, UINT item
);
179 virtual HRESULT STDMETHODCALLTYPE
RemoveObject(PITEMID_CHILD pidl
, UINT
*item
);
180 virtual HRESULT STDMETHODCALLTYPE
GetObjectCount(UINT
*count
);
181 virtual HRESULT STDMETHODCALLTYPE
SetObjectCount(UINT count
, UINT flags
);
182 virtual HRESULT STDMETHODCALLTYPE
UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
);
183 virtual HRESULT STDMETHODCALLTYPE
RefreshObject(PITEMID_CHILD pidl
, UINT
*item
);
184 virtual HRESULT STDMETHODCALLTYPE
SetRedraw(BOOL redraw
);
185 virtual HRESULT STDMETHODCALLTYPE
GetSelectedCount(UINT
*count
);
186 virtual HRESULT STDMETHODCALLTYPE
GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
);
187 virtual HRESULT STDMETHODCALLTYPE
IsDropOnSource(IDropTarget
*drop_target
);
188 virtual HRESULT STDMETHODCALLTYPE
GetDragPoint(POINT
*pt
);
189 virtual HRESULT STDMETHODCALLTYPE
GetDropPoint(POINT
*pt
);
190 virtual HRESULT STDMETHODCALLTYPE
MoveIcons(IDataObject
*obj
);
191 virtual HRESULT STDMETHODCALLTYPE
SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
);
192 virtual HRESULT STDMETHODCALLTYPE
IsBkDropTarget(IDropTarget
*drop_target
);
193 virtual HRESULT STDMETHODCALLTYPE
SetClipboard(BOOL move
);
194 virtual HRESULT STDMETHODCALLTYPE
SetPoints(IDataObject
*obj
);
195 virtual HRESULT STDMETHODCALLTYPE
GetItemSpacing(ITEMSPACING
*spacing
);
196 virtual HRESULT STDMETHODCALLTYPE
SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
);
197 virtual HRESULT STDMETHODCALLTYPE
Select(UINT flags
);
198 virtual HRESULT STDMETHODCALLTYPE
QuerySupport(UINT
*support
);
199 virtual HRESULT STDMETHODCALLTYPE
SetAutomationObject(IDispatch
*disp
);
201 // *** IOleCommandTarget methods ***
202 virtual HRESULT STDMETHODCALLTYPE
QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
);
203 virtual HRESULT STDMETHODCALLTYPE
Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
);
205 // *** IDropTarget methods ***
206 virtual HRESULT STDMETHODCALLTYPE
DragEnter(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
207 virtual HRESULT STDMETHODCALLTYPE
DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
208 virtual HRESULT STDMETHODCALLTYPE
DragLeave();
209 virtual HRESULT STDMETHODCALLTYPE
Drop(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
211 // *** IDropSource methods ***
212 virtual HRESULT STDMETHODCALLTYPE
QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
);
213 virtual HRESULT STDMETHODCALLTYPE
GiveFeedback(DWORD dwEffect
);
215 // *** IViewObject methods ***
216 virtual HRESULT STDMETHODCALLTYPE
Draw(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
,
217 HDC hdcTargetDev
, HDC hdcDraw
, LPCRECTL lprcBounds
, LPCRECTL lprcWBounds
,
218 BOOL ( STDMETHODCALLTYPE
*pfnContinue
)(ULONG_PTR dwContinue
), ULONG_PTR dwContinue
);
219 virtual HRESULT STDMETHODCALLTYPE
GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
,
220 DVTARGETDEVICE
*ptd
, HDC hicTargetDev
, LOGPALETTE
**ppColorSet
);
221 virtual HRESULT STDMETHODCALLTYPE
Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
);
222 virtual HRESULT STDMETHODCALLTYPE
Unfreeze(DWORD dwFreeze
);
223 virtual HRESULT STDMETHODCALLTYPE
SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
);
224 virtual HRESULT STDMETHODCALLTYPE
GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
);
226 // *** IServiceProvider methods ***
227 virtual HRESULT STDMETHODCALLTYPE
QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
);
230 LRESULT
OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
231 LRESULT
OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
232 LRESULT
OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
233 LRESULT
OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
234 LRESULT
OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
235 LRESULT
OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
236 LRESULT
OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
237 LRESULT
OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
238 LRESULT
OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
239 LRESULT
OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
240 LRESULT
OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
241 LRESULT
OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
242 LRESULT
OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
243 LRESULT
OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
244 LRESULT
OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
245 LRESULT
OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
246 LRESULT
OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
247 LRESULT
OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
249 static ATL::CWndClassInfo
& GetWndClassInfo()
251 static ATL::CWndClassInfo wc
=
253 { sizeof(WNDCLASSEX
), 0, StartWindowProc
,
255 LoadCursor(NULL
, IDC_ARROW
), (HBRUSH
)(COLOR_BACKGROUND
+ 1), NULL
, SV_CLASS_NAME
, NULL
257 NULL
, NULL
, IDC_ARROW
, TRUE
, 0, _T("")
262 virtual WNDPROC
GetWindowProc()
267 static LRESULT CALLBACK
WindowProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
272 // must hold a reference during message handling
273 pThis
= reinterpret_cast<CDefView
*>(hWnd
);
275 result
= CWindowImpl
<CDefView
, CWindow
, CControlWinTraits
>::WindowProc(hWnd
, uMsg
, wParam
, lParam
);
280 BEGIN_MSG_MAP(CDefView
)
281 MESSAGE_HANDLER(WM_SIZE
, OnSize
)
282 MESSAGE_HANDLER(WM_SETFOCUS
, OnSetFocus
)
283 MESSAGE_HANDLER(WM_KILLFOCUS
, OnKillFocus
)
284 MESSAGE_HANDLER(WM_CREATE
, OnCreate
)
285 MESSAGE_HANDLER(WM_ACTIVATE
, OnActivate
)
286 MESSAGE_HANDLER(WM_NOTIFY
, OnNotify
)
287 MESSAGE_HANDLER(WM_COMMAND
, OnCommand
)
288 MESSAGE_HANDLER(SHV_CHANGE_NOTIFY
, OnChangeNotify
)
289 MESSAGE_HANDLER(WM_CONTEXTMENU
, OnContextMenu
)
290 MESSAGE_HANDLER(WM_DRAWITEM
, OnCustomItem
)
291 MESSAGE_HANDLER(WM_MEASUREITEM
, OnCustomItem
)
292 MESSAGE_HANDLER(WM_SHOWWINDOW
, OnShowWindow
)
293 MESSAGE_HANDLER(WM_GETDLGCODE
, OnGetDlgCode
)
294 MESSAGE_HANDLER(WM_DESTROY
, OnDestroy
)
295 MESSAGE_HANDLER(WM_ERASEBKGND
, OnEraseBackground
)
296 MESSAGE_HANDLER(WM_SYSCOLORCHANGE
, OnSysColorChange
)
297 MESSAGE_HANDLER(CWM_GETISHELLBROWSER
, OnGetShellBrowser
)
298 MESSAGE_HANDLER(WM_SETTINGCHANGE
, OnSettingChange
)
299 MESSAGE_HANDLER(WM_INITMENUPOPUP
, OnInitMenuPopup
)
302 BEGIN_COM_MAP(CDefView
)
303 COM_INTERFACE_ENTRY_IID(IID_IOleWindow
, IOleWindow
)
304 COM_INTERFACE_ENTRY_IID(IID_IShellView
, IShellView
)
305 COM_INTERFACE_ENTRY_IID(IID_IFolderView
, IFolderView
)
306 COM_INTERFACE_ENTRY_IID(IID_IShellFolderView
, IShellFolderView
)
307 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget
, IOleCommandTarget
)
308 COM_INTERFACE_ENTRY_IID(IID_IDropTarget
, IDropTarget
)
309 COM_INTERFACE_ENTRY_IID(IID_IDropSource
, IDropSource
)
310 COM_INTERFACE_ENTRY_IID(IID_IViewObject
, IViewObject
)
311 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider
, IServiceProvider
)
315 /* ListView Header ID's */
316 #define LISTVIEW_COLUMN_NAME 0
317 #define LISTVIEW_COLUMN_SIZE 1
318 #define LISTVIEW_COLUMN_TYPE 2
319 #define LISTVIEW_COLUMN_TIME 3
320 #define LISTVIEW_COLUMN_ATTRIB 4
323 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
324 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
325 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
327 #define ID_LISTVIEW 1
330 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
331 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
332 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
335 Items merged into the toolbar and the filemenu
344 } MYTOOLINFO
, *LPMYTOOLINFO
;
346 static const MYTOOLINFO Tools
[] =
348 { FCIDM_SHVIEW_BIGICON
, 0, 0, IDS_VIEW_LARGE
, TBSTATE_ENABLED
, BTNS_BUTTON
},
349 { FCIDM_SHVIEW_SMALLICON
, 0, 0, IDS_VIEW_SMALL
, TBSTATE_ENABLED
, BTNS_BUTTON
},
350 { FCIDM_SHVIEW_LISTVIEW
, 0, 0, IDS_VIEW_LIST
, TBSTATE_ENABLED
, BTNS_BUTTON
},
351 { FCIDM_SHVIEW_REPORTVIEW
, 0, 0, IDS_VIEW_DETAILS
, TBSTATE_ENABLED
, BTNS_BUTTON
},
355 typedef void (CALLBACK
*PFNSHGETSETTINGSPROC
)(LPSHELLFLAGSTATE lpsfs
, DWORD dwMask
);
361 m_FolderSettings
.fFlags
= 0;
362 m_FolderSettings
.ViewMode
= 0;
364 m_menusLoaded
= FALSE
;
368 m_sortInfo
.bIsAscending
= FALSE
;
369 m_sortInfo
.nHeaderID
= 0;
370 m_sortInfo
.nLastHeaderID
= 0;
377 m_ptLastMousePos
.x
= 0;
378 m_ptLastMousePos
.y
= 0;
381 CDefView::~CDefView()
383 TRACE(" destroying IShellView(%p)\n", this);
388 HRESULT WINAPI
CDefView::Initialize(IShellFolder
*shellFolder
)
390 m_pSFParent
= shellFolder
;
391 shellFolder
->QueryInterface(IID_PPV_ARG(IShellFolder2
, &m_pSF2Parent
));
396 /**********************************************************
398 * ##### helperfunctions for communication with ICommDlgBrowser #####
400 HRESULT
CDefView::IncludeObject(LPCITEMIDLIST pidl
)
404 if (m_pCommDlgBrowser
.p
!= NULL
)
406 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl
);
407 ret
= m_pCommDlgBrowser
->IncludeObject((IShellView
*)this, pidl
);
408 TRACE("--0x%08x\n", ret
);
414 HRESULT
CDefView::OnDefaultCommand()
416 HRESULT ret
= S_FALSE
;
418 if (m_pCommDlgBrowser
.p
!= NULL
)
420 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
421 ret
= m_pCommDlgBrowser
->OnDefaultCommand((IShellView
*)this);
422 TRACE("-- returns %08x\n", ret
);
428 HRESULT
CDefView::OnStateChange(UINT uFlags
)
430 HRESULT ret
= S_FALSE
;
432 if (m_pCommDlgBrowser
.p
!= NULL
)
434 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags
);
435 ret
= m_pCommDlgBrowser
->OnStateChange((IShellView
*)this, uFlags
);
441 /**********************************************************
442 * set the toolbar of the filedialog buttons
444 * - activates the buttons from the shellbrowser according to
447 void CDefView::CheckToolbar()
453 if (m_pCommDlgBrowser
!= NULL
)
455 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
456 FCIDM_TB_SMALLICON
, (m_FolderSettings
.ViewMode
== FVM_LIST
) ? TRUE
: FALSE
, &result
);
457 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
458 FCIDM_TB_REPORTVIEW
, (m_FolderSettings
.ViewMode
== FVM_DETAILS
) ? TRUE
: FALSE
, &result
);
459 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
460 FCIDM_TB_SMALLICON
, TRUE
, &result
);
461 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
462 FCIDM_TB_REPORTVIEW
, TRUE
, &result
);
466 /**********************************************************
468 * ##### helperfunctions for initializing the view #####
470 /**********************************************************
471 * change the style of the listview control
473 void CDefView::SetStyle(DWORD dwAdd
, DWORD dwRemove
)
477 TRACE("(%p)\n", this);
479 tmpstyle
= ::GetWindowLongPtrW(m_hWndList
, GWL_STYLE
);
480 ::SetWindowLongPtrW(m_hWndList
, GWL_STYLE
, dwAdd
| (tmpstyle
& ~dwRemove
));
483 /**********************************************************
484 * ShellView_CreateList()
486 * - creates the list view window
488 BOOL
CDefView::CreateList()
489 { DWORD dwStyle
, dwExStyle
;
493 dwStyle
= WS_TABSTOP
| WS_VISIBLE
| WS_CHILDWINDOW
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
|
494 LVS_SHAREIMAGELISTS
| LVS_EDITLABELS
| LVS_AUTOARRANGE
;
495 dwExStyle
= WS_EX_CLIENTEDGE
;
497 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
498 dwStyle
|= LVS_ALIGNLEFT
;
500 dwStyle
|= LVS_ALIGNTOP
;
502 switch (m_FolderSettings
.ViewMode
)
509 dwStyle
|= LVS_REPORT
;
513 dwStyle
|= LVS_SMALLICON
;
525 if (m_FolderSettings
.fFlags
& FWF_AUTOARRANGE
)
526 dwStyle
|= LVS_AUTOARRANGE
;
528 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
529 m_FolderSettings
.fFlags
|= FWF_NOCLIENTEDGE
| FWF_NOSCROLL
;
531 if (m_FolderSettings
.fFlags
& FWF_SINGLESEL
)
532 dwStyle
|= LVS_SINGLESEL
;
534 if (m_FolderSettings
.fFlags
& FWF_NOCLIENTEDGE
)
535 dwExStyle
&= ~WS_EX_CLIENTEDGE
;
537 m_hWndList
= CreateWindowExW( dwExStyle
,
550 m_sortInfo
.bIsAscending
= TRUE
;
551 m_sortInfo
.nHeaderID
= -1;
552 m_sortInfo
.nLastHeaderID
= -1;
556 /* UpdateShellSettings(); */
560 void CDefView::UpdateListColors()
562 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
564 /* Check if drop shadows option is enabled */
565 BOOL bDropShadow
= FALSE
;
566 DWORD cbDropShadow
= sizeof(bDropShadow
);
567 WCHAR wszBuf
[16] = L
"";
569 RegGetValueW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
570 L
"ListviewShadow", RRF_RT_DWORD
, NULL
, &bDropShadow
, &cbDropShadow
);
571 if (bDropShadow
&& SystemParametersInfoW(SPI_GETDESKWALLPAPER
, _countof(wszBuf
), wszBuf
, 0) && wszBuf
[0])
573 SendMessageW(m_hWndList
, LVM_SETTEXTBKCOLOR
, 0, CLR_NONE
);
574 SendMessageW(m_hWndList
, LVM_SETBKCOLOR
, 0, CLR_NONE
);
575 SendMessageW(m_hWndList
, LVM_SETTEXTCOLOR
, 0, RGB(255, 255, 255));
576 SendMessageW(m_hWndList
, LVM_SETEXTENDEDLISTVIEWSTYLE
, LVS_EX_TRANSPARENTSHADOWTEXT
, LVS_EX_TRANSPARENTSHADOWTEXT
);
580 COLORREF crDesktop
= GetSysColor(COLOR_DESKTOP
);
581 SendMessageW(m_hWndList
, LVM_SETTEXTBKCOLOR
, 0, crDesktop
);
582 SendMessageW(m_hWndList
, LVM_SETBKCOLOR
, 0, crDesktop
);
583 if (GetRValue(crDesktop
) + GetGValue(crDesktop
) + GetBValue(crDesktop
) > 128 * 3)
584 SendMessageW(m_hWndList
, LVM_SETTEXTCOLOR
, 0, RGB(0, 0, 0));
586 SendMessageW(m_hWndList
, LVM_SETTEXTCOLOR
, 0, RGB(255, 255, 255));
587 SendMessageW(m_hWndList
, LVM_SETEXTENDEDLISTVIEWSTYLE
, LVS_EX_TRANSPARENTSHADOWTEXT
, 0);
592 /**********************************************************
593 * ShellView_InitList()
595 * - adds all needed columns to the shellview
597 BOOL
CDefView::InitList()
605 SendMessageW(m_hWndList
, LVM_DELETEALLITEMS
, 0, 0);
607 lvColumn
.mask
= LVCF_FMT
| LVCF_WIDTH
| LVCF_TEXT
;
608 lvColumn
.pszText
= szTemp
;
612 for (int i
= 0; 1; i
++)
614 if (FAILED(m_pSF2Parent
->GetDetailsOf(NULL
, i
, &sd
)))
617 lvColumn
.fmt
= sd
.fmt
;
618 lvColumn
.cx
= sd
.cxChar
* 8; /* chars->pixel */
619 StrRetToStrNW( szTemp
, 50, &sd
.str
, NULL
);
620 SendMessageW(m_hWndList
, LVM_INSERTCOLUMNW
, i
, (LPARAM
) &lvColumn
);
628 SendMessageW(m_hWndList
, LVM_SETIMAGELIST
, LVSIL_SMALL
, (LPARAM
)ShellSmallIconList
);
629 SendMessageW(m_hWndList
, LVM_SETIMAGELIST
, LVSIL_NORMAL
, (LPARAM
)ShellBigIconList
);
634 /**********************************************************
635 * ShellView_CompareItems()
638 * internal, CALLBACK for DSA_Sort
640 INT CALLBACK
CDefView::CompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
)
643 TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1
, lParam2
, (LPVOID
) lpData
);
648 ret
= (SHORT
)SCODE_CODE(((IShellFolder
*)lpData
)->CompareIDs(0, (LPITEMIDLIST
)lParam1
, (LPITEMIDLIST
)lParam2
));
649 TRACE("ret=%i\n", ret
);
654 /*************************************************************************
655 * ShellView_ListViewCompareItems
657 * Compare Function for the Listview (FileOpen Dialog)
660 * lParam1 [I] the first ItemIdList to compare with
661 * lParam2 [I] the second ItemIdList to compare with
662 * lpData [I] The column ID for the header Ctrl to process
665 * A negative value if the first item should precede the second,
666 * a positive value if the first item should follow the second,
667 * or zero if the two items are equivalent
670 * FIXME: function does what ShellView_CompareItems is supposed to do.
671 * unify it and figure out how to use the undocumented first parameter
672 * of IShellFolder_CompareIDs to do the job this function does and
673 * move this code to IShellFolder.
674 * make LISTVIEW_SORT_INFO obsolete
675 * the way this function works is only usable if we had only
676 * filesystemfolders (25/10/99 jsch)
678 INT CALLBACK
CDefView::ListViewCompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
)
682 char strName1
[MAX_PATH
], strName2
[MAX_PATH
];
683 BOOL bIsFolder1
, bIsFolder2
, bIsBothFolder
;
684 LPITEMIDLIST pItemIdList1
= (LPITEMIDLIST
) lParam1
;
685 LPITEMIDLIST pItemIdList2
= (LPITEMIDLIST
) lParam2
;
686 LISTVIEW_SORT_INFO
*pSortInfo
= (LPLISTVIEW_SORT_INFO
) lpData
;
689 bIsFolder1
= _ILIsFolder(pItemIdList1
);
690 bIsFolder2
= _ILIsFolder(pItemIdList2
);
691 bIsBothFolder
= bIsFolder1
&& bIsFolder2
;
693 /* When sorting between a File and a Folder, the Folder gets sorted first */
694 if ( (bIsFolder1
|| bIsFolder2
) && !bIsBothFolder
)
696 nDiff
= bIsFolder1
? -1 : 1;
700 /* Sort by Time: Folders or Files can be sorted */
702 if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_TIME
)
704 _ILGetFileDateTime(pItemIdList1
, &fd1
);
705 _ILGetFileDateTime(pItemIdList2
, &fd2
);
706 nDiff
= CompareFileTime(&fd2
, &fd1
);
708 /* Sort by Attribute: Folder or Files can be sorted */
709 else if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_ATTRIB
)
711 _ILGetFileAttributes(pItemIdList1
, strName1
, MAX_PATH
);
712 _ILGetFileAttributes(pItemIdList2
, strName2
, MAX_PATH
);
713 nDiff
= lstrcmpiA(strName1
, strName2
);
715 /* Sort by FileName: Folder or Files can be sorted */
716 else if (pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_NAME
|| bIsBothFolder
)
719 _ILSimpleGetText(pItemIdList1
, strName1
, MAX_PATH
);
720 _ILSimpleGetText(pItemIdList2
, strName2
, MAX_PATH
);
721 nDiff
= lstrcmpiA(strName1
, strName2
);
723 /* Sort by File Size, Only valid for Files */
724 else if (pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_SIZE
)
726 nDiff
= (INT
)(_ILGetFileSize(pItemIdList1
, NULL
, 0) - _ILGetFileSize(pItemIdList2
, NULL
, 0));
728 /* Sort by File Type, Only valid for Files */
729 else if (pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_TYPE
)
732 _ILGetFileType(pItemIdList1
, strName1
, MAX_PATH
);
733 _ILGetFileType(pItemIdList2
, strName2
, MAX_PATH
);
734 nDiff
= lstrcmpiA(strName1
, strName2
);
737 /* If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
741 _ILSimpleGetText(pItemIdList1
, strName1
, MAX_PATH
);
742 _ILSimpleGetText(pItemIdList2
, strName2
, MAX_PATH
);
743 nDiff
= lstrcmpiA(strName1
, strName2
);
746 if (!pSortInfo
->bIsAscending
)
754 /**********************************************************
755 * LV_FindItemByPidl()
757 int CDefView::LV_FindItemByPidl(LPCITEMIDLIST pidl
)
761 lvItem
.mask
= LVIF_PARAM
;
763 for (lvItem
.iItem
= 0;
764 SendMessageW(m_hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
767 LPITEMIDLIST currentpidl
= (LPITEMIDLIST
) lvItem
.lParam
;
768 HRESULT hr
= m_pSFParent
->CompareIDs(0, pidl
, currentpidl
);
770 if (SUCCEEDED(hr
) && !HRESULT_CODE(hr
))
778 /**********************************************************
781 BOOLEAN
CDefView::LV_AddItem(LPCITEMIDLIST pidl
)
785 TRACE("(%p)(pidl=%p)\n", this, pidl
);
787 lvItem
.mask
= LVIF_TEXT
| LVIF_IMAGE
| LVIF_PARAM
; /*set the mask*/
788 lvItem
.iItem
= ListView_GetItemCount(m_hWndList
); /*add the item to the end of the list*/
790 lvItem
.lParam
= (LPARAM
) ILClone(ILFindLastID(pidl
)); /*set the item's data*/
791 lvItem
.pszText
= LPSTR_TEXTCALLBACKW
; /*get text on a callback basis*/
792 lvItem
.iImage
= I_IMAGECALLBACK
; /*get the image on a callback basis*/
794 if (SendMessageW(m_hWndList
, LVM_INSERTITEMW
, 0, (LPARAM
)&lvItem
) == -1)
800 /**********************************************************
803 BOOLEAN
CDefView::LV_DeleteItem(LPCITEMIDLIST pidl
)
807 TRACE("(%p)(pidl=%p)\n", this, pidl
);
809 nIndex
= LV_FindItemByPidl(ILFindLastID(pidl
));
811 return (-1 == ListView_DeleteItem(m_hWndList
, nIndex
)) ? FALSE
: TRUE
;
814 /**********************************************************
817 BOOLEAN
CDefView::LV_RenameItem(LPCITEMIDLIST pidlOld
, LPCITEMIDLIST pidlNew
)
822 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", this, pidlOld
, pidlNew
);
824 nItem
= LV_FindItemByPidl(ILFindLastID(pidlOld
));
828 lvItem
.mask
= LVIF_PARAM
; /* only the pidl */
829 lvItem
.iItem
= nItem
;
830 SendMessageW(m_hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
832 SHFree((LPITEMIDLIST
)lvItem
.lParam
);
833 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
834 lvItem
.iItem
= nItem
;
835 lvItem
.lParam
= (LPARAM
) ILClone(ILFindLastID(pidlNew
)); /* set the item's data */
836 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
837 SendMessageW(m_hWndList
, LVM_SETITEMW
, 0, (LPARAM
) &lvItem
);
838 SendMessageW(m_hWndList
, LVM_UPDATE
, nItem
, 0);
839 return TRUE
; /* FIXME: better handling */
845 /**********************************************************
846 * ShellView_FillList()
848 * - gets the objectlist from the shellfolder
850 * - fills the list into the view
852 INT CALLBACK
CDefView::fill_list( LPVOID ptr
, LPVOID arg
)
854 LPITEMIDLIST pidl
= (LPITEMIDLIST
)ptr
;
855 CDefView
*pThis
= static_cast<CDefView
*>(arg
);
856 /* in a commdlg This works as a filemask*/
857 if (pThis
->IncludeObject(pidl
) == S_OK
)
858 pThis
->LV_AddItem(pidl
);
864 HRESULT
CDefView::FillList()
866 LPENUMIDLIST pEnumIDList
;
874 /* get the itemlist from the shfolder*/
875 hRes
= m_pSFParent
->EnumObjects(m_hWnd
, SHCONTF_NONFOLDERS
| SHCONTF_FOLDERS
, &pEnumIDList
);
883 /* create a pointer array */
884 hdpa
= DPA_Create(16);
887 return(E_OUTOFMEMORY
);
890 /* copy the items into the array*/
891 while((S_OK
== pEnumIDList
->Next(1, &pidl
, &dwFetched
)) && dwFetched
)
893 if (DPA_InsertPtr(hdpa
, 0x7fff, pidl
) == -1)
900 DPA_Sort(hdpa
, CompareItems
, (LPARAM
)m_pSFParent
.p
);
902 /*turn the listview's redrawing off*/
903 SendMessageA(m_hWndList
, WM_SETREDRAW
, FALSE
, 0);
905 DPA_DestroyCallback( hdpa
, fill_list
, (void *)this);
907 /*turn the listview's redrawing back on and force it to draw*/
908 SendMessageA(m_hWndList
, WM_SETREDRAW
, TRUE
, 0);
910 pEnumIDList
->Release(); /* destroy the list*/
915 LRESULT
CDefView::OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
917 ::UpdateWindow(m_hWndList
);
922 LRESULT
CDefView::OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
924 return SendMessageW(m_hWndList
, uMsg
, 0, 0);
927 LRESULT
CDefView::OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
930 DestroyMenu(m_hMenu
);
931 RevokeDragDrop(m_hWnd
);
932 SHChangeNotifyDeregister(m_hNotify
);
937 LRESULT
CDefView::OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
939 if (m_FolderSettings
.fFlags
& (FWF_DESKTOP
| FWF_TRANSPARENT
))
940 return SendMessageW(GetParent(), WM_ERASEBKGND
, wParam
, lParam
); /* redirect to parent */
946 LRESULT
CDefView::OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
948 /* Update desktop labels color */
951 /* Forward WM_SYSCOLORCHANGE to common controls */
952 return SendMessageW(m_hWndList
, uMsg
, 0, 0);
955 LRESULT
CDefView::OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
957 return (LRESULT
)m_pShellBrowser
.p
;
960 /**********************************************************
961 * ShellView_OnCreate()
963 LRESULT
CDefView::OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
965 CComPtr
<IDropTarget
> pdt
;
966 SHChangeNotifyEntry ntreg
;
967 CComPtr
<IPersistFolder2
> ppf2
;
979 if (SUCCEEDED(QueryInterface(IID_PPV_ARG(IDropTarget
, &pdt
))))
981 if (FAILED(RegisterDragDrop(m_hWnd
, pdt
)))
982 ERR("Registering Drag Drop Failed");
985 /* register for receiving notifications */
986 m_pSFParent
->QueryInterface(IID_PPV_ARG(IPersistFolder2
, &ppf2
));
989 ppf2
->GetCurFolder((LPITEMIDLIST
*)&ntreg
.pidl
);
990 ntreg
.fRecursive
= TRUE
;
991 m_hNotify
= SHChangeNotifyRegister(m_hWnd
, SHCNF_IDLIST
, SHCNE_ALLEVENTS
, SHV_CHANGE_NOTIFY
, 1, &ntreg
);
992 SHFree((LPITEMIDLIST
)ntreg
.pidl
);
995 m_hAccel
= LoadAcceleratorsA(shell32_hInstance
, MAKEINTRESOURCEA( IDA_SHELLVIEW
));
1000 /**********************************************************
1001 * #### Handling of the menus ####
1004 HMENU
CDefView::BuildFileMenu()
1007 CComPtr
<IContextMenu
> cm
;
1011 LPCITEMIDLIST
* apidl
= (LPCITEMIDLIST
*)m_apidl
;
1013 hr
= m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, apidl
, IID_NULL_PPV_ARG(IContextMenu
, &cm
));
1017 HMENU hmenu
= CreatePopupMenu();
1019 //FIXME: get proper numbers ?
1020 const UINT first
= 0x7800;
1021 const UINT last
= 0x7A00;
1022 hr
= cm
->QueryContextMenu(hmenu
, 0, first
, last
, 0);
1026 // TODO: filter or something
1031 void CDefView::PrepareShowFileMenu(HMENU hSubMenu
)
1033 TRACE("(%p)->(submenu=%p) stub\n", this, hSubMenu
);
1038 /* Cleanup the items added previously */
1039 for (int i
= 0; i
< GetMenuItemCount(hSubMenu
); )
1042 mii
.cbSize
= sizeof(mii
);
1043 mii
.fMask
= MIIM_ID
;
1044 GetMenuItemInfoW(hSubMenu
, i
, TRUE
, &mii
);
1046 if (mii
.wID
< 0x8000)
1048 DeleteMenu(hSubMenu
, i
, MF_BYPOSITION
);
1056 /* Insert This item at the beginning of the menu. */
1057 _InsertMenuItemW(hSubMenu
, 0, TRUE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1058 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
+ 4, MFT_STRING
, L
"Properties", MFS_DISABLED
);
1059 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
+ 3, MFT_STRING
, L
"Rename", MFS_DISABLED
);
1060 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
+ 2, MFT_STRING
, L
"Delete", MFS_DISABLED
);
1061 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
+ 1, MFT_STRING
, L
"Create Shortcut", MFS_DISABLED
);
1062 _InsertMenuItemW(hSubMenu
, 0, TRUE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1063 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
, MFT_STRING
, L
"New", MFS_ENABLED
);
1065 HMENU menubase
= BuildFileMenu();
1068 int count
= ::GetMenuItemCount(menubase
);
1070 for (int i
= 0; i
< count
; i
++)
1074 MENUITEMINFOW mii
= { 0 };
1075 mii
.cbSize
= sizeof(mii
);
1076 mii
.fMask
= MIIM_STATE
| MIIM_ID
| MIIM_SUBMENU
| MIIM_CHECKMARKS
| MIIM_DATA
| MIIM_STRING
| MIIM_BITMAP
| MIIM_FTYPE
;
1077 mii
.dwTypeData
= label
;
1078 mii
.cch
= _countof(label
);
1079 ::GetMenuItemInfoW(menubase
, i
, TRUE
, &mii
);
1081 DbgPrint("Adding item %d label %S type %d\n", mii
.wID
, mii
.dwTypeData
, mii
.fType
);
1083 mii
.fType
|= MFT_RADIOCHECK
;
1085 ::InsertMenuItemW(hSubMenu
, IDM_MYFILEITEM
, FALSE
, &mii
);
1088 _InsertMenuItemW(hSubMenu
, IDM_MYFILEITEM
, FALSE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1090 ::DestroyMenu(menubase
);
1095 void CDefView::PrepareShowViewMenu(HMENU hSubMenu
)
1097 TRACE("(%p)->(submenu=%p)\n", this, hSubMenu
);
1102 if (m_FolderSettings
.ViewMode
>= FVM_FIRST
&& m_FolderSettings
.ViewMode
<= FVM_LAST
)
1104 UINT iItemFirst
= FCIDM_SHVIEW_BIGICON
;
1105 UINT iItemLast
= iItemFirst
+ FVM_LAST
- FVM_FIRST
;
1106 UINT iItem
= iItemFirst
+ m_FolderSettings
.ViewMode
- FVM_FIRST
;
1107 CheckMenuRadioItem(hSubMenu
, iItemFirst
, iItemLast
, iItem
, MF_BYCOMMAND
);
1111 /**********************************************************
1112 * ShellView_GetSelections()
1114 * - fills the m_apidl list with the selected objects
1117 * number of selected items
1119 UINT
CDefView::GetSelections()
1126 m_cidl
= ListView_GetSelectedCount(m_hWndList
);
1127 m_apidl
= (LPITEMIDLIST
*)SHAlloc(m_cidl
* sizeof(LPITEMIDLIST
));
1129 TRACE("selected=%i\n", m_cidl
);
1133 TRACE("-- Items selected =%u\n", m_cidl
);
1135 lvItem
.mask
= LVIF_STATE
| LVIF_PARAM
;
1136 lvItem
.stateMask
= LVIS_SELECTED
;
1138 lvItem
.iSubItem
= 0;
1141 while(SendMessageW(m_hWndList
, LVM_GETITEMW
, 0, (LPARAM
)&lvItem
) && (i
< m_cidl
))
1143 if(lvItem
.state
& LVIS_SELECTED
)
1145 m_apidl
[i
] = (LPITEMIDLIST
)lvItem
.lParam
;
1149 TRACE("-- selected Item found\n");
1158 /**********************************************************
1159 * ShellView_OpenSelectedItems()
1161 HRESULT
CDefView::OpenSelectedItems()
1164 CMINVOKECOMMANDINFO cmi
;
1168 m_cidl
= ListView_GetSelectedCount(m_hWndList
);
1172 hResult
= OnDefaultCommand();
1173 if (hResult
== S_OK
)
1176 hMenu
= CreatePopupMenu();
1180 hResult
= GetItemObject( SVGIO_SELECTION
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1181 if (FAILED(hResult
))
1184 hResult
= IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1185 //if (FAILED( hResult))
1188 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, 0x20, 0x7fff, CMF_DEFAULTONLY
);
1189 if (FAILED(hResult
))
1192 uCommand
= GetMenuDefaultItem(hMenu
, FALSE
, 0);
1193 if (uCommand
== (UINT
)-1)
1199 ZeroMemory(&cmi
, sizeof(cmi
));
1200 cmi
.cbSize
= sizeof(cmi
);
1201 cmi
.lpVerb
= (LPCSTR
)MAKEINTRESOURCEA(uCommand
);
1204 hResult
= m_pCM
->InvokeCommand(&cmi
);
1213 IUnknown_SetSite(m_pCM
, NULL
);
1220 /**********************************************************
1221 * ShellView_DoContextMenu()
1223 LRESULT
CDefView::OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1229 CMINVOKECOMMANDINFO cmi
;
1232 // for some reason I haven't figured out, we sometimes recurse into this method
1239 TRACE("(%p)->(0x%08x 0x%08x) stub\n", this, x
, y
);
1241 hMenu
= CreatePopupMenu();
1245 m_cidl
= ListView_GetSelectedCount(m_hWndList
);
1247 hResult
= GetItemObject( m_cidl
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1248 if (FAILED( hResult
))
1251 hResult
= IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1252 //if (FAILED( hResult))
1255 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1256 if (FAILED( hResult
))
1259 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
1260 SetMenuDefaultItem(hMenu
, FCIDM_SHVIEW_OPEN
, MF_BYCOMMAND
);
1262 uCommand
= TrackPopupMenu(hMenu
,
1263 TPM_LEFTALIGN
| TPM_RETURNCMD
| TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
,
1264 x
, y
, 0, m_hWnd
, NULL
);
1268 if (uCommand
== FCIDM_SHVIEW_OPEN
&& OnDefaultCommand() == S_OK
)
1271 ZeroMemory(&cmi
, sizeof(cmi
));
1272 cmi
.cbSize
= sizeof(cmi
);
1273 cmi
.lpVerb
= (LPCSTR
)MAKEINTRESOURCEA(uCommand
);
1275 m_pCM
->InvokeCommand(&cmi
);
1281 IUnknown_SetSite(m_pCM
, NULL
);
1291 LRESULT
CDefView::OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
)
1294 CMINVOKECOMMANDINFO cmi
;
1297 hMenu
= CreatePopupMenu();
1301 hResult
= GetItemObject( bUseSelection
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1302 if (FAILED( hResult
))
1305 hResult
= IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1306 //if (FAILED( hResult))
1309 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1310 if (FAILED( hResult
))
1313 ZeroMemory(&cmi
, sizeof(cmi
));
1314 cmi
.cbSize
= sizeof(cmi
);
1315 cmi
.lpVerb
= (LPCSTR
)MAKEINTRESOURCEA(uCommand
);
1317 m_pCM
->InvokeCommand(&cmi
);
1323 IUnknown_SetSite(m_pCM
, NULL
);
1333 /**********************************************************
1334 * ##### message handling #####
1337 /**********************************************************
1338 * ShellView_OnSize()
1340 LRESULT
CDefView::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1345 wWidth
= LOWORD(lParam
);
1346 wHeight
= HIWORD(lParam
);
1348 TRACE("%p width=%u height=%u\n", this, wWidth
, wHeight
);
1350 /*resize the ListView to fit our window*/
1353 ::MoveWindow(m_hWndList
, 0, 0, wWidth
, wHeight
, TRUE
);
1359 /**********************************************************
1360 * ShellView_OnDeactivate()
1365 void CDefView::OnDeactivate()
1367 TRACE("%p\n", this);
1369 if (m_uState
!= SVUIA_DEACTIVATE
)
1371 // TODO: cleanup menu after deactivation
1373 m_uState
= SVUIA_DEACTIVATE
;
1377 void CDefView::DoActivate(UINT uState
)
1379 TRACE("%p uState=%x\n", this, uState
);
1381 /*don't do anything if the state isn't really changing */
1382 if (m_uState
== uState
)
1387 if (uState
== SVUIA_DEACTIVATE
)
1397 MENUITEMINFOW mii
= { 0 };
1399 /* initialize EDIT menu */
1400 mii
.cbSize
= sizeof(mii
);
1401 mii
.fMask
= MIIM_SUBMENU
;
1402 if (::GetMenuItemInfoW(m_hMenu
, FCIDM_MENU_EDIT
, FALSE
, &mii
))
1404 HMENU hSubMenu
= mii
.hSubMenu
;
1406 HMENU menubase
= ::LoadMenuW(shell32_hInstance
, L
"MENU_003");
1408 int count
= ::GetMenuItemCount(menubase
);
1409 for (int i
= 0; i
< count
; i
++)
1413 ZeroMemory(&mii
, sizeof(mii
));
1414 mii
.cbSize
= sizeof(mii
);
1415 mii
.fMask
= MIIM_STATE
| MIIM_ID
| MIIM_SUBMENU
| MIIM_CHECKMARKS
| MIIM_DATA
| MIIM_STRING
| MIIM_BITMAP
| MIIM_FTYPE
;
1416 mii
.dwTypeData
= label
;
1417 mii
.cch
= _countof(label
);
1418 ::GetMenuItemInfoW(menubase
, i
, TRUE
, &mii
);
1420 DbgPrint("Adding item %d label %S type %d\n", mii
.wID
, mii
.dwTypeData
, mii
.fType
);
1422 mii
.fType
|= MFT_RADIOCHECK
;
1424 ::InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, &mii
);
1427 ::DestroyMenu(menubase
);
1430 /* initialize VIEW menu */
1431 mii
.cbSize
= sizeof(mii
);
1432 mii
.fMask
= MIIM_SUBMENU
;
1433 if (::GetMenuItemInfoW(m_hMenu
, FCIDM_MENU_VIEW
, FALSE
, &mii
))
1435 HMENU menubase
= ::LoadMenuW(shell32_hInstance
, L
"MENU_001");
1437 HMENU hSubMenu
= mii
.hSubMenu
;
1439 _InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1441 int count
= ::GetMenuItemCount(menubase
);
1442 for (int i
= 0; i
< count
; i
++)
1446 ZeroMemory(&mii
, sizeof(mii
));
1447 mii
.cbSize
= sizeof(mii
);
1448 mii
.fMask
= MIIM_STATE
| MIIM_ID
| MIIM_SUBMENU
| MIIM_CHECKMARKS
| MIIM_DATA
| MIIM_STRING
| MIIM_BITMAP
| MIIM_FTYPE
;
1449 mii
.dwTypeData
= label
;
1450 mii
.cch
= _countof(label
);
1451 ::GetMenuItemInfoW(menubase
, i
, TRUE
, &mii
);
1453 DbgPrint("Adding item %d label %S type %d\n", mii
.wID
, mii
.dwTypeData
, mii
.fType
);
1455 mii
.fType
|= MFT_RADIOCHECK
;
1457 ::InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, &mii
);
1460 ::DestroyMenu(menubase
);
1464 TRACE("-- before fnSetMenuSB\n");
1465 m_pShellBrowser
->SetMenuSB(m_hMenu
, 0, m_hWnd
);
1467 m_menusLoaded
= TRUE
;
1471 if (SVUIA_ACTIVATE_FOCUS
== uState
)
1473 ::SetFocus(m_hWndList
);
1481 /**********************************************************
1482 * ShellView_OnActivate()
1484 LRESULT
CDefView::OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1486 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1490 /**********************************************************
1491 * ShellView_OnSetFocus()
1494 LRESULT
CDefView::OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1496 TRACE("%p\n", this);
1498 /* Tell the browser one of our windows has received the focus. This
1499 should always be done before merging menus (OnActivate merges the
1500 menus) if one of our windows has the focus.*/
1502 m_pShellBrowser
->OnViewWindowActive((IShellView
*)this);
1503 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1505 /* Set the focus to the listview */
1506 ::SetFocus(m_hWndList
);
1508 /* Notify the ICommDlgBrowser interface */
1509 OnStateChange(CDBOSC_SETFOCUS
);
1514 /**********************************************************
1515 * ShellView_OnKillFocus()
1517 LRESULT
CDefView::OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1519 TRACE("(%p) stub\n", this);
1521 DoActivate(SVUIA_ACTIVATE_NOFOCUS
);
1522 /* Notify the ICommDlgBrowser */
1523 OnStateChange(CDBOSC_KILLFOCUS
);
1528 /**********************************************************
1529 * ShellView_OnCommand()
1532 * the CmdID's are the ones from the context menu
1534 LRESULT
CDefView::OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1540 dwCmdID
= GET_WM_COMMAND_ID(wParam
, lParam
);
1541 dwCmd
= GET_WM_COMMAND_CMD(wParam
, lParam
);
1542 hwndCmd
= GET_WM_COMMAND_HWND(wParam
, lParam
);
1544 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n", this, dwCmdID
, dwCmd
, hwndCmd
);
1548 case FCIDM_SHVIEW_SMALLICON
:
1549 m_FolderSettings
.ViewMode
= FVM_SMALLICON
;
1550 SetStyle (LVS_SMALLICON
, LVS_TYPEMASK
);
1554 case FCIDM_SHVIEW_BIGICON
:
1555 m_FolderSettings
.ViewMode
= FVM_ICON
;
1556 SetStyle (LVS_ICON
, LVS_TYPEMASK
);
1560 case FCIDM_SHVIEW_LISTVIEW
:
1561 m_FolderSettings
.ViewMode
= FVM_LIST
;
1562 SetStyle (LVS_LIST
, LVS_TYPEMASK
);
1566 case FCIDM_SHVIEW_REPORTVIEW
:
1567 m_FolderSettings
.ViewMode
= FVM_DETAILS
;
1568 SetStyle (LVS_REPORT
, LVS_TYPEMASK
);
1572 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1577 m_sortInfo
.nHeaderID
= (LPARAM
) (dwCmdID
- 0x30);
1578 m_sortInfo
.bIsAscending
= TRUE
;
1579 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
1580 SendMessageA(m_hWndList
, LVM_SORTITEMS
, (WPARAM
) &m_sortInfo
, (LPARAM
)ListViewCompareItems
);
1583 case FCIDM_SHVIEW_REFRESH
:
1587 case FCIDM_SHVIEW_DELETE
:
1588 case FCIDM_SHVIEW_CUT
:
1589 case FCIDM_SHVIEW_COPY
:
1590 case FCIDM_SHVIEW_RENAME
:
1591 return OnExplorerCommand(dwCmdID
, TRUE
);
1593 case FCIDM_SHVIEW_INSERT
:
1594 case FCIDM_SHVIEW_UNDO
:
1595 case FCIDM_SHVIEW_INSERTLINK
:
1596 case FCIDM_SHVIEW_NEWFOLDER
:
1597 return OnExplorerCommand(dwCmdID
, FALSE
);
1599 TRACE("-- COMMAND 0x%04x unhandled\n", dwCmdID
);
1605 /**********************************************************
1606 * ShellView_OnNotify()
1609 LRESULT
CDefView::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1613 LPNMLISTVIEW lpnmlv
;
1614 NMLVDISPINFOW
*lpdi
;
1619 lpnmh
= (LPNMHDR
)lParam
;
1620 lpnmlv
= (LPNMLISTVIEW
)lpnmh
;
1621 lpdi
= (NMLVDISPINFOW
*)lpnmh
;
1623 TRACE("%p CtlID=%u lpnmh->code=%x\n", this, CtlID
, lpnmh
->code
);
1625 switch (lpnmh
->code
)
1628 TRACE("-- NM_SETFOCUS %p\n", this);
1629 OnSetFocus(0, 0, 0, unused
);
1633 TRACE("-- NM_KILLFOCUS %p\n", this);
1635 /* Notify the ICommDlgBrowser interface */
1636 OnStateChange(CDBOSC_KILLFOCUS
);
1640 TRACE("-- NM_CUSTOMDRAW %p\n", this);
1641 return CDRF_DODEFAULT
;
1643 case NM_RELEASEDCAPTURE
:
1644 TRACE("-- NM_RELEASEDCAPTURE %p\n", this);
1648 TRACE("-- NM_CLICK %p\n", this);
1652 TRACE("-- NM_RCLICK %p\n", this);
1656 TRACE("-- NM_DBLCLK %p\n", this);
1657 OpenSelectedItems();
1661 TRACE("-- NM_RETURN %p\n", this);
1662 OpenSelectedItems();
1666 TRACE("-- HDN_ENDTRACKW %p\n", this);
1667 /*nColumn1 = ListView_GetColumnWidth(m_hWndList, 0);
1668 nColumn2 = ListView_GetColumnWidth(m_hWndList, 1);*/
1671 case LVN_DELETEITEM
:
1672 TRACE("-- LVN_DELETEITEM %p\n", this);
1673 SHFree((LPITEMIDLIST
)lpnmlv
->lParam
); /*delete the pidl because we made a copy of it*/
1676 case LVN_DELETEALLITEMS
:
1677 TRACE("-- LVN_DELETEALLITEMS %p\n", this);
1680 case LVN_INSERTITEM
:
1681 TRACE("-- LVN_INSERTITEM (STUB)%p\n", this);
1684 case LVN_ITEMACTIVATE
:
1685 TRACE("-- LVN_ITEMACTIVATE %p\n", this);
1686 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1689 case LVN_COLUMNCLICK
:
1690 m_sortInfo
.nHeaderID
= lpnmlv
->iSubItem
;
1691 if (m_sortInfo
.nLastHeaderID
== m_sortInfo
.nHeaderID
)
1693 m_sortInfo
.bIsAscending
= !m_sortInfo
.bIsAscending
;
1697 m_sortInfo
.bIsAscending
= TRUE
;
1699 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
1701 SendMessageW(lpnmlv
->hdr
.hwndFrom
, LVM_SORTITEMS
, (WPARAM
) &m_sortInfo
, (LPARAM
)ListViewCompareItems
);
1704 case LVN_GETDISPINFOA
:
1705 case LVN_GETDISPINFOW
:
1706 TRACE("-- LVN_GETDISPINFO %p\n", this);
1707 pidl
= (LPITEMIDLIST
)lpdi
->item
.lParam
;
1709 if (lpdi
->item
.mask
& LVIF_TEXT
) /* text requested */
1714 if (FAILED(m_pSF2Parent
->GetDetailsOf(pidl
, lpdi
->item
.iSubItem
, &sd
)))
1716 FIXME("failed to get details\n");
1720 if (lpnmh
->code
== LVN_GETDISPINFOA
)
1722 /* shouldn't happen */
1723 NMLVDISPINFOA
*lpdiA
= (NMLVDISPINFOA
*)lpnmh
;
1724 StrRetToStrNA( lpdiA
->item
.pszText
, lpdiA
->item
.cchTextMax
, &sd
.str
, NULL
);
1725 TRACE("-- text=%s\n", lpdiA
->item
.pszText
);
1727 else /* LVN_GETDISPINFOW */
1729 StrRetToStrNW( lpdi
->item
.pszText
, lpdi
->item
.cchTextMax
, &sd
.str
, NULL
);
1730 TRACE("-- text=%s\n", debugstr_w(lpdi
->item
.pszText
));
1738 if(lpdi
->item
.mask
& LVIF_IMAGE
) /* image requested */
1740 lpdi
->item
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
1742 lpdi
->item
.mask
|= LVIF_DI_SETITEM
;
1745 case LVN_ITEMCHANGED
:
1746 TRACE("-- LVN_ITEMCHANGED %p\n", this);
1747 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1751 case LVN_BEGINRDRAG
:
1752 TRACE("-- LVN_BEGINDRAG\n");
1754 if (GetSelections())
1757 DWORD dwAttributes
= SFGAO_CANLINK
;
1758 DWORD dwEffect
= DROPEFFECT_COPY
| DROPEFFECT_MOVE
;
1760 if (SUCCEEDED(m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, (LPCITEMIDLIST
*)m_apidl
, IID_NULL_PPV_ARG(IDataObject
, &pda
))))
1762 IDropSource
* pds
= (IDropSource
*)this; /* own DropSource interface */
1764 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(m_cidl
, (LPCITEMIDLIST
*)m_apidl
, &dwAttributes
)))
1766 if (dwAttributes
& SFGAO_CANLINK
)
1768 dwEffect
|= DROPEFFECT_LINK
;
1772 CComPtr
<IAsyncOperation
> piaso
;
1773 if (SUCCEEDED(pda
->QueryInterface(IID_PPV_ARG(IAsyncOperation
, &piaso
))))
1775 piaso
->SetAsyncMode(TRUE
);
1781 DoDragDrop(pda
, pds
, dwEffect
, &dwEffect2
);
1788 case LVN_BEGINLABELEDITW
:
1790 DWORD dwAttr
= SFGAO_CANRENAME
;
1791 pidl
= (LPITEMIDLIST
)lpdi
->item
.lParam
;
1793 TRACE("-- LVN_BEGINLABELEDITW %p\n", this);
1795 m_pSFParent
->GetAttributesOf(1, (LPCITEMIDLIST
*)&pidl
, &dwAttr
);
1796 if (SFGAO_CANRENAME
& dwAttr
)
1803 case LVN_ENDLABELEDITW
:
1805 TRACE("-- LVN_ENDLABELEDITW %p\n", this);
1806 if (lpdi
->item
.pszText
)
1811 lvItem
.iItem
= lpdi
->item
.iItem
;
1812 lvItem
.iSubItem
= 0;
1813 lvItem
.mask
= LVIF_PARAM
;
1814 SendMessageW(m_hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
1816 pidl
= (LPITEMIDLIST
)lpdi
->item
.lParam
;
1817 hr
= m_pSFParent
->SetNameOf(0, pidl
, lpdi
->item
.pszText
, SHGDN_INFOLDER
, &pidl
);
1819 if (SUCCEEDED(hr
) && pidl
)
1821 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
1822 lvItem
.lParam
= (LPARAM
)pidl
;
1823 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
1824 SendMessageW(m_hWndList
, LVM_SETITEMW
, 0, (LPARAM
) &lvItem
);
1825 SendMessageW(m_hWndList
, LVM_UPDATE
, lpdi
->item
.iItem
, 0);
1835 TRACE("-- %p WM_COMMAND %x unhandled\n", this, lpnmh
->code
);
1842 /**********************************************************
1843 * ShellView_OnChange()
1845 LRESULT
CDefView::OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1847 LPITEMIDLIST
*Pidls
;
1849 Pidls
= (LPITEMIDLIST
*)wParam
;
1851 TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls
[0], Pidls
[1], lParam
);
1857 LV_AddItem(Pidls
[0]);
1862 LV_DeleteItem(Pidls
[0]);
1865 case SHCNE_RENAMEFOLDER
:
1866 case SHCNE_RENAMEITEM
:
1867 LV_RenameItem(Pidls
[0], Pidls
[1]);
1870 case SHCNE_UPDATEITEM
:
1871 LV_RenameItem(Pidls
[0], Pidls
[0]);
1874 case SHCNE_UPDATEDIR
:
1881 /**********************************************************
1882 * CDefView::OnCustomItem
1884 LRESULT
CDefView::OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1889 ERR("no menu!!!\n");
1893 CComPtr
<IContextMenu2
> pCM2
;
1894 HRESULT hres
= m_pCM
.p
->QueryInterface(IID_PPV_ARG(IContextMenu2
, &pCM2
));
1898 if (pCM2
.p
->HandleMenuMsg(uMsg
, (WPARAM
)m_hWnd
, lParam
) == S_OK
)
1904 LRESULT
CDefView::OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1906 /* Wallpaper setting affects drop shadows effect */
1907 if (wParam
== SPI_SETDESKWALLPAPER
|| wParam
== 0)
1913 /**********************************************************
1914 * CDefView::OnInitMenuPopup
1916 LRESULT
CDefView::OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1918 MENUITEMINFOW mii
= { 0 };
1919 HMENU hSubmenu
= (HMENU
) wParam
;
1921 DbgPrint("OnInitMenuPopup lParam=%d\n", lParam
);
1923 mii
.cbSize
= sizeof(mii
);
1924 mii
.fMask
= MIIM_ID
| MIIM_SUBMENU
;
1926 if (!GetMenuItemInfoW(this->m_hMenu
, lParam
, TRUE
, &mii
))
1928 DbgPrint("OnInitMenuPopup GetMenuItemInfoW failed!\n");
1932 UINT menuItemId
= mii
.wID
;
1934 if (mii
.hSubMenu
!= hSubmenu
)
1936 DbgPrint("OnInitMenuPopup submenu does not match!!!!\n");
1940 DbgPrint("OnInitMenuPopup id=%d\n", menuItemId
);
1944 case FCIDM_MENU_FILE
:
1945 PrepareShowFileMenu(hSubmenu
);
1947 case FCIDM_MENU_EDIT
:
1948 //PrepareShowEditMenu(hSubmenu);
1950 case FCIDM_MENU_VIEW
:
1951 PrepareShowViewMenu(hSubmenu
);
1958 /**********************************************************
1961 * The INTERFACE of the IShellView object
1964 **********************************************************
1967 /**********************************************************
1968 * ShellView_GetWindow
1970 HRESULT WINAPI
CDefView::GetWindow(HWND
*phWnd
)
1972 TRACE("(%p)\n", this);
1979 HRESULT WINAPI
CDefView::ContextSensitiveHelp(BOOL fEnterMode
)
1981 FIXME("(%p) stub\n", this);
1986 /**********************************************************
1987 * IShellView_TranslateAccelerator
1990 * use the accel functions
1992 HRESULT WINAPI
CDefView::TranslateAccelerator(LPMSG lpmsg
)
1994 if (lpmsg
->message
>= WM_KEYFIRST
&& lpmsg
->message
<= WM_KEYLAST
)
1996 if (::TranslateAcceleratorW(m_hWnd
, m_hAccel
, lpmsg
) != 0)
1999 TRACE("-- key=0x04%lx\n", lpmsg
->wParam
) ;
2002 return S_FALSE
; /* not handled */
2005 HRESULT WINAPI
CDefView::EnableModeless(BOOL fEnable
)
2007 FIXME("(%p) stub\n", this);
2012 HRESULT WINAPI
CDefView::UIActivate(UINT uState
)
2015 CHAR szName[MAX_PATH];
2018 int nPartArray
[1] = { -1};
2020 TRACE("(%p)->(state=%x) stub\n", this, uState
);
2022 /*don't do anything if the state isn't really changing*/
2023 if (m_uState
== uState
)
2028 /*OnActivate handles the menu merging and internal state*/
2031 /*only do This if we are active*/
2032 if (uState
!= SVUIA_DEACTIVATE
)
2036 GetFolderPath is not a method of IShellFolder
2037 IShellFolder_GetFolderPath( m_pSFParent, szName, sizeof(szName) );
2039 /* set the number of parts */
2040 m_pShellBrowser
->SendControlMsg(FCW_STATUS
, SB_SETPARTS
, 1, (LPARAM
)nPartArray
, &lResult
);
2042 /* set the text for the parts */
2044 m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXTA, 0, (LPARAM)szName, &lResult);
2051 HRESULT WINAPI
CDefView::Refresh()
2053 TRACE("(%p)\n", this);
2055 SendMessageW(m_hWndList
, LVM_DELETEALLITEMS
, 0, 0);
2061 HRESULT WINAPI
CDefView::CreateViewWindow(IShellView
*lpPrevView
, LPCFOLDERSETTINGS lpfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
)
2063 OLEMENUGROUPWIDTHS omw
= { { 0, 0, 0, 0, 0, 0 } };
2067 TRACE("(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n", this, lpPrevView
, lpfs
, psb
, prcView
, phWnd
);
2070 TRACE("-- vmode=%x flags=%x\n", lpfs
->ViewMode
, lpfs
->fFlags
);
2071 if (prcView
!= NULL
)
2072 TRACE("-- left=%i top=%i right=%i bottom=%i\n", prcView
->left
, prcView
->top
, prcView
->right
, prcView
->bottom
);
2074 /* Validate the Shell Browser */
2076 return E_UNEXPECTED
;
2078 /*set up the member variables*/
2079 m_pShellBrowser
= psb
;
2080 m_FolderSettings
= *lpfs
;
2082 /*get our parent window*/
2083 m_pShellBrowser
->GetWindow(&m_hWndParent
);
2085 /* try to get the ICommDlgBrowserInterface, adds a reference !!! */
2086 m_pCommDlgBrowser
= NULL
;
2087 if (SUCCEEDED(m_pShellBrowser
->QueryInterface(IID_PPV_ARG(ICommDlgBrowser
, &m_pCommDlgBrowser
))))
2089 TRACE("-- CommDlgBrowser\n");
2092 Create(m_hWndParent
, prcView
, NULL
, WS_CHILD
| WS_TABSTOP
, 0, 0U);
2103 SetWindowPos(HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_SHOWWINDOW
);
2108 m_hMenu
= CreateMenu();
2109 m_pShellBrowser
->InsertMenusSB(m_hMenu
, &omw
);
2110 TRACE("-- after fnInsertMenusSB\n");
2116 HRESULT WINAPI
CDefView::DestroyViewWindow()
2118 TRACE("(%p)\n", this);
2120 /*Make absolutely sure all our UI is cleaned up.*/
2121 UIActivate(SVUIA_DEACTIVATE
);
2125 DestroyMenu(m_hMenu
);
2129 m_pShellBrowser
.Release();
2130 m_pCommDlgBrowser
.Release();
2135 HRESULT WINAPI
CDefView::GetCurrentInfo(LPFOLDERSETTINGS lpfs
)
2137 TRACE("(%p)->(%p) vmode=%x flags=%x\n", this, lpfs
,
2138 m_FolderSettings
.ViewMode
, m_FolderSettings
.fFlags
);
2141 return E_INVALIDARG
;
2143 *lpfs
= m_FolderSettings
;
2147 HRESULT WINAPI
CDefView::AddPropertySheetPages(DWORD dwReserved
, LPFNADDPROPSHEETPAGE lpfn
, LPARAM lparam
)
2149 FIXME("(%p) stub\n", this);
2154 HRESULT WINAPI
CDefView::SaveViewState()
2156 FIXME("(%p) stub\n", this);
2161 HRESULT WINAPI
CDefView::SelectItem(LPCITEMIDLIST pidl
, UINT uFlags
)
2165 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n", this, pidl
, uFlags
);
2167 i
= LV_FindItemByPidl(pidl
);
2173 if(uFlags
& SVSI_ENSUREVISIBLE
)
2174 SendMessageW(m_hWndList
, LVM_ENSUREVISIBLE
, i
, 0);
2176 lvItem
.mask
= LVIF_STATE
;
2177 lvItem
.stateMask
= LVIS_SELECTED
| LVIS_FOCUSED
;
2179 lvItem
.iSubItem
= 0;
2181 while (SendMessageW(m_hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
))
2183 if (lvItem
.iItem
== i
)
2185 if (uFlags
& SVSI_SELECT
)
2186 lvItem
.state
|= LVIS_SELECTED
;
2188 lvItem
.state
&= ~LVIS_SELECTED
;
2190 if (uFlags
& SVSI_FOCUSED
)
2191 lvItem
.state
&= ~LVIS_FOCUSED
;
2195 if (uFlags
& SVSI_DESELECTOTHERS
)
2196 lvItem
.state
&= ~LVIS_SELECTED
;
2199 SendMessageW(m_hWndList
, LVM_SETITEMW
, 0, (LPARAM
) &lvItem
);
2204 if(uFlags
& SVSI_EDIT
)
2205 SendMessageW(m_hWndList
, LVM_EDITLABELW
, i
, 0);
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);
2225 CDefFolderMenu_Create2(NULL
, NULL
, 0, NULL
, m_pSFParent
, NULL
, 0, NULL
, (IContextMenu
**)ppvOut
);
2233 case SVGIO_SELECTION
:
2235 hr
= m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, (LPCITEMIDLIST
*)m_apidl
, riid
, 0, ppvOut
);
2239 TRACE("-- (%p)->(interface=%p)\n", this, *ppvOut
);
2244 HRESULT STDMETHODCALLTYPE
CDefView::GetCurrentViewMode(UINT
*pViewMode
)
2246 TRACE("(%p)->(%p), stub\n", this, pViewMode
);
2249 return E_INVALIDARG
;
2251 *pViewMode
= m_FolderSettings
.ViewMode
;
2255 HRESULT STDMETHODCALLTYPE
CDefView::SetCurrentViewMode(UINT ViewMode
)
2258 TRACE("(%p)->(%u), stub\n", this, ViewMode
);
2260 /* It's not redundant to check FVM_AUTO because it's a (UINT)-1 */
2261 if ((ViewMode
< FVM_FIRST
|| ViewMode
> FVM_LAST
) && (ViewMode
!= (UINT
)FVM_AUTO
))
2262 return E_INVALIDARG
;
2264 /* Windows before Vista uses LVM_SETVIEW and possibly
2265 LVM_SETEXTENDEDLISTVIEWSTYLE to set the style of the listview,
2266 while later versions seem to accomplish this through other
2274 dwStyle
= LVS_REPORT
;
2277 dwStyle
= LVS_SMALLICON
;
2284 FIXME("ViewMode %d not implemented\n", ViewMode
);
2290 SetStyle(dwStyle
, LVS_TYPEMASK
);
2292 /* This will not necessarily be the actual mode set above.
2293 This mimics the behavior of Windows XP. */
2294 m_FolderSettings
.ViewMode
= ViewMode
;
2299 HRESULT STDMETHODCALLTYPE
CDefView::GetFolder(REFIID riid
, void **ppv
)
2301 if (m_pSFParent
== NULL
)
2304 return m_pSFParent
->QueryInterface(riid
, ppv
);
2307 HRESULT STDMETHODCALLTYPE
CDefView::Item(int iItemIndex
, LPITEMIDLIST
*ppidl
)
2311 TRACE("(%p)->(%d %p)\n", this, iItemIndex
, ppidl
);
2313 item
.mask
= LVIF_PARAM
;
2314 item
.iItem
= iItemIndex
;
2316 if (SendMessageW(m_hWndList
, LVM_GETITEMW
, 0, (LPARAM
)&item
))
2318 *ppidl
= ILClone((PITEMID_CHILD
)item
.lParam
);
2324 return E_INVALIDARG
;
2327 HRESULT STDMETHODCALLTYPE
CDefView::ItemCount(UINT uFlags
, int *pcItems
)
2329 TRACE("(%p)->(%u %p)\n", this, uFlags
, pcItems
);
2331 if (uFlags
!= SVGIO_ALLVIEW
)
2332 FIXME("some flags unsupported, %x\n", uFlags
& ~SVGIO_ALLVIEW
);
2334 *pcItems
= SendMessageW(m_hWndList
, LVM_GETITEMCOUNT
, 0, 0);
2339 HRESULT STDMETHODCALLTYPE
CDefView::Items(UINT uFlags
, REFIID riid
, void **ppv
)
2344 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectionMarkedItem(int *piItem
)
2346 TRACE("(%p)->(%p)\n", this, piItem
);
2348 *piItem
= SendMessageW(m_hWndList
, LVM_GETSELECTIONMARK
, 0, 0);
2353 HRESULT STDMETHODCALLTYPE
CDefView::GetFocusedItem(int *piItem
)
2355 TRACE("(%p)->(%p)\n", this, piItem
);
2357 *piItem
= SendMessageW(m_hWndList
, LVM_GETNEXTITEM
, -1, LVNI_FOCUSED
);
2362 HRESULT STDMETHODCALLTYPE
CDefView::GetItemPosition(LPCITEMIDLIST pidl
, POINT
*ppt
)
2367 HRESULT STDMETHODCALLTYPE
CDefView::GetSpacing(POINT
*ppt
)
2369 TRACE("(%p)->(%p)\n", this, ppt
);
2371 if (NULL
== m_hWndList
) return S_FALSE
;
2375 const DWORD ret
= SendMessageW(m_hWndList
, LVM_GETITEMSPACING
, 0, 0);
2377 ppt
->x
= LOWORD(ret
);
2378 ppt
->y
= HIWORD(ret
);
2384 HRESULT STDMETHODCALLTYPE
CDefView::GetDefaultSpacing(POINT
*ppt
)
2389 HRESULT STDMETHODCALLTYPE
CDefView::GetAutoArrange()
2394 HRESULT STDMETHODCALLTYPE
CDefView::SelectItem(int iItem
, DWORD dwFlags
)
2398 TRACE("(%p)->(%d, %x)\n", this, iItem
, dwFlags
);
2401 lvItem
.stateMask
= LVIS_SELECTED
;
2403 if (dwFlags
& SVSI_ENSUREVISIBLE
)
2404 SendMessageW(m_hWndList
, LVM_ENSUREVISIBLE
, iItem
, 0);
2407 if (dwFlags
& SVSI_DESELECTOTHERS
)
2408 SendMessageW(m_hWndList
, LVM_SETITEMSTATE
, -1, (LPARAM
)&lvItem
);
2411 if (dwFlags
& SVSI_SELECT
)
2412 lvItem
.state
|= LVIS_SELECTED
;
2414 if (dwFlags
& SVSI_FOCUSED
)
2415 lvItem
.stateMask
|= LVIS_FOCUSED
;
2417 SendMessageW(m_hWndList
, LVM_SETITEMSTATE
, iItem
, (LPARAM
)&lvItem
);
2419 if (dwFlags
& SVSI_EDIT
)
2420 SendMessageW(m_hWndList
, LVM_EDITLABELW
, iItem
, 0);
2425 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItems(UINT cidl
, LPCITEMIDLIST
*apidl
, POINT
*apt
, DWORD dwFlags
)
2430 /**********************************************************
2431 * IShellFolderView implementation
2433 HRESULT STDMETHODCALLTYPE
CDefView::Rearrange(LPARAM sort
)
2435 FIXME("(%p)->(%ld) stub\n", this, sort
);
2439 HRESULT STDMETHODCALLTYPE
CDefView::GetArrangeParam(LPARAM
*sort
)
2441 FIXME("(%p)->(%p) stub\n", this, sort
);
2445 HRESULT STDMETHODCALLTYPE
CDefView::ArrangeGrid()
2447 FIXME("(%p) stub\n", this);
2451 HRESULT STDMETHODCALLTYPE
CDefView::AutoArrange()
2453 FIXME("(%p) stub\n", this);
2457 HRESULT STDMETHODCALLTYPE
CDefView::IShellFolderView_GetAutoArrange()
2459 TRACE("(%p)\n", this);
2460 return GetAutoArrange();
2463 HRESULT STDMETHODCALLTYPE
CDefView::AddObject(PITEMID_CHILD pidl
, UINT
*item
)
2465 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2469 HRESULT STDMETHODCALLTYPE
CDefView::GetObject(PITEMID_CHILD
*pidl
, UINT item
)
2471 TRACE("(%p)->(%p %d)\n", this, pidl
, item
);
2472 return Item(item
, pidl
);
2475 HRESULT STDMETHODCALLTYPE
CDefView::RemoveObject(PITEMID_CHILD pidl
, UINT
*item
)
2478 TRACE("(%p)->(%p %p)\n", this, pidl
, item
);
2482 *item
= LV_FindItemByPidl(ILFindLastID(pidl
));
2483 SendMessageW(m_hWndList
, LVM_DELETEITEM
, *item
, 0);
2488 SendMessageW(m_hWndList
, LVM_DELETEALLITEMS
, 0, 0);
2494 HRESULT STDMETHODCALLTYPE
CDefView::GetObjectCount(UINT
*count
)
2496 TRACE("(%p)->(%p)\n", this, count
);
2497 return ItemCount(SVGIO_ALLVIEW
, reinterpret_cast<INT
*>(count
));
2500 HRESULT STDMETHODCALLTYPE
CDefView::SetObjectCount(UINT count
, UINT flags
)
2502 FIXME("(%p)->(%d %x) stub\n", this, count
, flags
);
2506 HRESULT STDMETHODCALLTYPE
CDefView::UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
)
2508 FIXME("(%p)->(%p %p %p) stub\n", this, pidl_old
, pidl_new
, item
);
2512 HRESULT STDMETHODCALLTYPE
CDefView::RefreshObject(PITEMID_CHILD pidl
, UINT
*item
)
2514 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2518 HRESULT STDMETHODCALLTYPE
CDefView::SetRedraw(BOOL redraw
)
2520 TRACE("(%p)->(%d)\n", this, redraw
);
2521 SendMessageW(m_hWndList
, WM_SETREDRAW
, redraw
, 0);
2525 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedCount(UINT
*count
)
2527 FIXME("(%p)->(%p) stub\n", this, count
);
2531 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
)
2533 TRACE("(%p)->(%p %p)\n", this, pidl
, items
);
2535 *items
= GetSelections();
2539 *pidl
= static_cast<PCUITEMID_CHILD
*>(LocalAlloc(0, *items
* sizeof(LPITEMIDLIST
)));
2542 return E_OUTOFMEMORY
;
2545 /* it's documented that caller shouldn't PIDLs, only array itself */
2546 memcpy(static_cast<PCUITEMID_CHILD
*>(*pidl
), m_apidl
, *items
* sizeof(LPITEMIDLIST
));
2552 HRESULT STDMETHODCALLTYPE
CDefView::IsDropOnSource(IDropTarget
*drop_target
)
2554 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2558 HRESULT STDMETHODCALLTYPE
CDefView::GetDragPoint(POINT
*pt
)
2560 FIXME("(%p)->(%p) stub\n", this, pt
);
2564 HRESULT STDMETHODCALLTYPE
CDefView::GetDropPoint(POINT
*pt
)
2566 FIXME("(%p)->(%p) stub\n", this, pt
);
2570 HRESULT STDMETHODCALLTYPE
CDefView::MoveIcons(IDataObject
*obj
)
2572 TRACE("(%p)->(%p)\n", this, obj
);
2576 HRESULT STDMETHODCALLTYPE
CDefView::SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
)
2578 FIXME("(%p)->(%p %p) stub\n", this, pidl
, pt
);
2582 HRESULT STDMETHODCALLTYPE
CDefView::IsBkDropTarget(IDropTarget
*drop_target
)
2584 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2588 HRESULT STDMETHODCALLTYPE
CDefView::SetClipboard(BOOL move
)
2590 FIXME("(%p)->(%d) stub\n", this, move
);
2594 HRESULT STDMETHODCALLTYPE
CDefView::SetPoints(IDataObject
*obj
)
2596 FIXME("(%p)->(%p) stub\n", this, obj
);
2600 HRESULT STDMETHODCALLTYPE
CDefView::GetItemSpacing(ITEMSPACING
*spacing
)
2602 FIXME("(%p)->(%p) stub\n", this, spacing
);
2606 HRESULT STDMETHODCALLTYPE
CDefView::SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
)
2608 FIXME("(%p)->(%p %p) stub\n", this, new_cb
, old_cb
);
2612 HRESULT STDMETHODCALLTYPE
CDefView::Select(UINT flags
)
2614 FIXME("(%p)->(%d) stub\n", this, flags
);
2618 HRESULT STDMETHODCALLTYPE
CDefView::QuerySupport(UINT
*support
)
2620 TRACE("(%p)->(%p)\n", this, support
);
2624 HRESULT STDMETHODCALLTYPE
CDefView::SetAutomationObject(IDispatch
*disp
)
2626 FIXME("(%p)->(%p) stub\n", this, disp
);
2630 /**********************************************************
2631 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2633 HRESULT WINAPI
CDefView::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD
*prgCmds
, OLECMDTEXT
*pCmdText
)
2635 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
2636 this, pguidCmdGroup
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
2639 return E_INVALIDARG
;
2641 for (UINT i
= 0; i
< cCmds
; i
++)
2643 FIXME("\tprgCmds[%d].cmdID = %d\n", i
, prgCmds
[i
].cmdID
);
2644 prgCmds
[i
].cmdf
= 0;
2647 return OLECMDERR_E_UNKNOWNGROUP
;
2650 /**********************************************************
2651 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2653 * nCmdID is the OLECMDID_* enumeration
2655 HRESULT WINAPI
CDefView::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
2657 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2658 this, debugstr_guid(pguidCmdGroup
), nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2661 return OLECMDERR_E_UNKNOWNGROUP
;
2663 if (IsEqualIID(*pguidCmdGroup
, CGID_Explorer
) &&
2665 (nCmdexecopt
== 4) && pvaOut
)
2668 if (IsEqualIID(*pguidCmdGroup
, CGID_ShellDocView
) &&
2673 return OLECMDERR_E_UNKNOWNGROUP
;
2676 /**********************************************************
2677 * ISVDropTarget implementation
2680 /******************************************************************************
2681 * drag_notify_subitem [Internal]
2683 * Figure out the shellfolder object, which is currently under the mouse cursor
2684 * and notify it via the IDropTarget interface.
2687 #define SCROLLAREAWIDTH 20
2689 HRESULT
CDefView::drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2691 LVHITTESTINFO htinfo
;
2697 /* Map from global to client coordinates and query the index of the listview-item, which is
2698 * currently under the mouse cursor. */
2701 htinfo
.flags
= LVHT_ONITEM
;
2702 ::ScreenToClient(m_hWndList
, &htinfo
.pt
);
2703 lResult
= SendMessageW(m_hWndList
, LVM_HITTEST
, 0, (LPARAM
)&htinfo
);
2705 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2706 ::GetClientRect(m_hWndList
, &clientRect
);
2707 if (htinfo
.pt
.x
== m_ptLastMousePos
.x
&& htinfo
.pt
.y
== m_ptLastMousePos
.y
&&
2708 (htinfo
.pt
.x
< SCROLLAREAWIDTH
|| htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
||
2709 htinfo
.pt
.y
< SCROLLAREAWIDTH
|| htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
))
2711 m_cScrollDelay
= (m_cScrollDelay
+ 1) % 5; /* DragOver is called every 50 ms */
2712 if (m_cScrollDelay
== 0)
2714 /* Mouse did hover another 250 ms over the scroll-area */
2715 if (htinfo
.pt
.x
< SCROLLAREAWIDTH
)
2716 SendMessageW(m_hWndList
, WM_HSCROLL
, SB_LINEUP
, 0);
2718 if (htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
)
2719 SendMessageW(m_hWndList
, WM_HSCROLL
, SB_LINEDOWN
, 0);
2721 if (htinfo
.pt
.y
< SCROLLAREAWIDTH
)
2722 SendMessageW(m_hWndList
, WM_VSCROLL
, SB_LINEUP
, 0);
2724 if (htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
)
2725 SendMessageW(m_hWndList
, WM_VSCROLL
, SB_LINEDOWN
, 0);
2730 m_cScrollDelay
= 0; /* Reset, if the cursor is not over the listview's scroll-area */
2733 m_ptLastMousePos
= htinfo
.pt
;
2735 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2736 if (m_pCurDropTarget
&& lResult
== m_iDragOverItem
)
2737 return m_pCurDropTarget
->DragOver(grfKeyState
, pt
, pdwEffect
);
2739 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2740 if (m_pCurDropTarget
)
2742 m_pCurDropTarget
->DragLeave();
2743 m_pCurDropTarget
.Release();
2746 m_iDragOverItem
= lResult
;
2749 /* We are not above one of the listview's subitems. Bind to the parent folder's
2750 * DropTarget interface. */
2751 hr
= m_pSFParent
->QueryInterface(IID_PPV_ARG(IDropTarget
,&m_pCurDropTarget
));
2755 /* Query the relative PIDL of the shellfolder object represented by the currently
2756 * dragged over listview-item ... */
2757 lvItem
.mask
= LVIF_PARAM
;
2758 lvItem
.iItem
= lResult
;
2759 lvItem
.iSubItem
= 0;
2760 SendMessageW(m_hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
2762 /* ... and bind m_pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2763 hr
= m_pSFParent
->GetUIObjectOf(m_hWndList
, 1, (LPCITEMIDLIST
*)&lvItem
.lParam
, IID_NULL_PPV_ARG(IDropTarget
, &m_pCurDropTarget
));
2766 /* If anything failed, m_pCurDropTarget should be NULL now, which ought to be a save state. */
2770 /* Notify the item just entered via DragEnter. */
2771 return m_pCurDropTarget
->DragEnter(m_pCurDataObject
, grfKeyState
, pt
, pdwEffect
);
2774 HRESULT WINAPI
CDefView::DragEnter(IDataObject
*pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2776 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2777 m_pCurDataObject
= pDataObject
;
2778 pDataObject
->AddRef();
2780 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2783 HRESULT WINAPI
CDefView::DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2785 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2788 HRESULT WINAPI
CDefView::DragLeave()
2790 if (m_pCurDropTarget
)
2792 m_pCurDropTarget
->DragLeave();
2793 m_pCurDropTarget
.Release();
2796 if (m_pCurDataObject
!= NULL
)
2798 m_pCurDataObject
.Release();
2801 m_iDragOverItem
= 0;
2806 HRESULT WINAPI
CDefView::Drop(IDataObject
* pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2808 if (m_pCurDropTarget
)
2810 m_pCurDropTarget
->Drop(pDataObject
, grfKeyState
, pt
, pdwEffect
);
2811 m_pCurDropTarget
.Release();
2814 m_pCurDataObject
.Release();
2815 m_iDragOverItem
= 0;
2819 /**********************************************************
2820 * ISVDropSource implementation
2823 HRESULT WINAPI
CDefView::QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
)
2825 TRACE("(%p)\n", this);
2828 return DRAGDROP_S_CANCEL
;
2829 else if (!(grfKeyState
& MK_LBUTTON
) && !(grfKeyState
& MK_RBUTTON
))
2830 return DRAGDROP_S_DROP
;
2835 HRESULT WINAPI
CDefView::GiveFeedback(DWORD dwEffect
)
2837 TRACE("(%p)\n", this);
2839 return DRAGDROP_S_USEDEFAULTCURSORS
;
2842 /**********************************************************
2843 * ISVViewObject implementation
2846 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
)
2848 FIXME("Stub: this=%p\n", this);
2853 HRESULT WINAPI
CDefView::GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
, HDC hicTargetDevice
, LOGPALETTE
**ppColorSet
)
2855 FIXME("Stub: this=%p\n", this);
2860 HRESULT WINAPI
CDefView::Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
)
2862 FIXME("Stub: this=%p\n", this);
2867 HRESULT WINAPI
CDefView::Unfreeze(DWORD dwFreeze
)
2869 FIXME("Stub: this=%p\n", this);
2874 HRESULT WINAPI
CDefView::SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
)
2876 FIXME("partial stub: %p %08x %08x %p\n", this, aspects
, advf
, pAdvSink
);
2878 /* FIXME: we set the AdviseSink, but never use it to send any advice */
2879 m_pAdvSink
= pAdvSink
;
2880 m_dwAspects
= aspects
;
2886 HRESULT WINAPI
CDefView::GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
)
2888 TRACE("this=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n", this, pAspects
, pAdvf
, ppAdvSink
);
2892 *ppAdvSink
= m_pAdvSink
;
2893 m_pAdvSink
.p
->AddRef();
2897 *pAspects
= m_dwAspects
;
2905 HRESULT STDMETHODCALLTYPE
CDefView::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
2907 if (IsEqualIID(guidService
, SID_IShellBrowser
))
2908 return m_pShellBrowser
->QueryInterface(riid
, ppvObject
);
2909 else if(IsEqualIID(guidService
, SID_IFolderView
))
2910 return QueryInterface(riid
, ppvObject
);
2912 return E_NOINTERFACE
;
2915 /**********************************************************
2916 * IShellView_Constructor
2918 HRESULT WINAPI
IShellView_Constructor(IShellFolder
*pFolder
, IShellView
**newView
)
2920 CComObject
<CDefView
> *theView
;
2921 CComPtr
<IShellView
> result
;
2924 if (newView
== NULL
)
2928 ATLTRY (theView
= new CComObject
<CDefView
>);
2930 if (theView
== NULL
)
2931 return E_OUTOFMEMORY
;
2933 hResult
= theView
->QueryInterface(IID_PPV_ARG(IShellView
, &result
));
2934 if (FAILED (hResult
))
2940 hResult
= theView
->Initialize (pFolder
);
2941 if (FAILED (hResult
))
2943 *newView
= result
.Detach ();