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 PIDLIST_ABSOLUTE m_pidlParent
;
97 LISTVIEW_SORT_INFO m_sortInfo
;
98 ULONG m_hNotify
; /* change notification handle */
102 CComPtr
<IAdviseSink
> m_pAdvSink
;
104 CComPtr
<IDropTarget
> m_pCurDropTarget
; /* The sub-item, which is currently dragged over */
105 CComPtr
<IDataObject
> m_pCurDataObject
; /* The dragged data-object */
106 LONG m_iDragOverItem
; /* Dragged over item's index, iff m_pCurDropTarget != NULL */
107 UINT m_cScrollDelay
; /* Send a WM_*SCROLL msg every 250 ms during drag-scroll */
108 POINT m_ptLastMousePos
; /* Mouse position at last DragOver call */
110 CComPtr
<IContextMenu
> m_pCM
;
119 HRESULT
_MergeToolbar();
124 HRESULT WINAPI
Initialize(IShellFolder
*shellFolder
);
125 HRESULT
IncludeObject(PCUITEMID_CHILD pidl
);
126 HRESULT
OnDefaultCommand();
127 HRESULT
OnStateChange(UINT uFlags
);
129 void SetStyle(DWORD dwAdd
, DWORD dwRemove
);
131 void UpdateListColors();
133 static INT CALLBACK
CompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
);
134 static INT CALLBACK
ListViewCompareItems(LPARAM lParam1
, LPARAM lParam2
, LPARAM lpData
);
136 PCUITEMID_CHILD
_PidlByItem(int i
);
137 PCUITEMID_CHILD
_PidlByItem(LVITEM
& lvItem
);
138 int LV_FindItemByPidl(PCUITEMID_CHILD pidl
);
139 BOOLEAN
LV_AddItem(PCUITEMID_CHILD pidl
);
140 BOOLEAN
LV_DeleteItem(PCUITEMID_CHILD pidl
);
141 BOOLEAN
LV_RenameItem(PCUITEMID_CHILD pidlOld
, PCUITEMID_CHILD pidlNew
);
142 BOOLEAN
LV_ProdItem(PCUITEMID_CHILD pidl
);
143 static INT CALLBACK
fill_list(LPVOID ptr
, LPVOID arg
);
145 HMENU
BuildFileMenu();
146 void PrepareShowFileMenu(HMENU hSubMenu
);
147 void PrepareShowViewMenu(HMENU hSubMenu
);
148 UINT
GetSelections();
149 HRESULT
OpenSelectedItems();
151 void DoActivate(UINT uState
);
152 HRESULT
drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
153 LRESULT
OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
);
155 // *** IOleWindow methods ***
156 virtual HRESULT STDMETHODCALLTYPE
GetWindow(HWND
*lphwnd
);
157 virtual HRESULT STDMETHODCALLTYPE
ContextSensitiveHelp(BOOL fEnterMode
);
159 // *** IShellView methods ***
160 virtual HRESULT STDMETHODCALLTYPE
TranslateAccelerator(MSG
*pmsg
);
161 virtual HRESULT STDMETHODCALLTYPE
EnableModeless(BOOL fEnable
);
162 virtual HRESULT STDMETHODCALLTYPE
UIActivate(UINT uState
);
163 virtual HRESULT STDMETHODCALLTYPE
Refresh();
164 virtual HRESULT STDMETHODCALLTYPE
CreateViewWindow(IShellView
*psvPrevious
, LPCFOLDERSETTINGS pfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
);
165 virtual HRESULT STDMETHODCALLTYPE
DestroyViewWindow();
166 virtual HRESULT STDMETHODCALLTYPE
GetCurrentInfo(LPFOLDERSETTINGS pfs
);
167 virtual HRESULT STDMETHODCALLTYPE
AddPropertySheetPages(DWORD dwReserved
, LPFNSVADDPROPSHEETPAGE pfn
, LPARAM lparam
);
168 virtual HRESULT STDMETHODCALLTYPE
SaveViewState();
169 virtual HRESULT STDMETHODCALLTYPE
SelectItem(PCUITEMID_CHILD pidlItem
, SVSIF uFlags
);
170 virtual HRESULT STDMETHODCALLTYPE
GetItemObject(UINT uItem
, REFIID riid
, void **ppv
);
172 // *** IFolderView methods ***
173 virtual HRESULT STDMETHODCALLTYPE
GetCurrentViewMode(UINT
*pViewMode
);
174 virtual HRESULT STDMETHODCALLTYPE
SetCurrentViewMode(UINT ViewMode
);
175 virtual HRESULT STDMETHODCALLTYPE
GetFolder(REFIID riid
, void **ppv
);
176 virtual HRESULT STDMETHODCALLTYPE
Item(int iItemIndex
, PITEMID_CHILD
*ppidl
);
177 virtual HRESULT STDMETHODCALLTYPE
ItemCount(UINT uFlags
, int *pcItems
);
178 virtual HRESULT STDMETHODCALLTYPE
Items(UINT uFlags
, REFIID riid
, void **ppv
);
179 virtual HRESULT STDMETHODCALLTYPE
GetSelectionMarkedItem(int *piItem
);
180 virtual HRESULT STDMETHODCALLTYPE
GetFocusedItem(int *piItem
);
181 virtual HRESULT STDMETHODCALLTYPE
GetItemPosition(PCUITEMID_CHILD pidl
, POINT
*ppt
);
182 virtual HRESULT STDMETHODCALLTYPE
GetSpacing(POINT
*ppt
);
183 virtual HRESULT STDMETHODCALLTYPE
GetDefaultSpacing(POINT
*ppt
);
184 virtual HRESULT STDMETHODCALLTYPE
GetAutoArrange();
185 virtual HRESULT STDMETHODCALLTYPE
SelectItem(int iItem
, DWORD dwFlags
);
186 virtual HRESULT STDMETHODCALLTYPE
SelectAndPositionItems(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD dwFlags
);
188 // *** IShellFolderView methods ***
189 virtual HRESULT STDMETHODCALLTYPE
Rearrange(LPARAM sort
);
190 virtual HRESULT STDMETHODCALLTYPE
GetArrangeParam(LPARAM
*sort
);
191 virtual HRESULT STDMETHODCALLTYPE
ArrangeGrid();
192 virtual HRESULT STDMETHODCALLTYPE
AutoArrange();
193 virtual HRESULT STDMETHODCALLTYPE
AddObject(PITEMID_CHILD pidl
, UINT
*item
);
194 virtual HRESULT STDMETHODCALLTYPE
GetObject(PITEMID_CHILD
*pidl
, UINT item
);
195 virtual HRESULT STDMETHODCALLTYPE
RemoveObject(PITEMID_CHILD pidl
, UINT
*item
);
196 virtual HRESULT STDMETHODCALLTYPE
GetObjectCount(UINT
*count
);
197 virtual HRESULT STDMETHODCALLTYPE
SetObjectCount(UINT count
, UINT flags
);
198 virtual HRESULT STDMETHODCALLTYPE
UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
);
199 virtual HRESULT STDMETHODCALLTYPE
RefreshObject(PITEMID_CHILD pidl
, UINT
*item
);
200 virtual HRESULT STDMETHODCALLTYPE
SetRedraw(BOOL redraw
);
201 virtual HRESULT STDMETHODCALLTYPE
GetSelectedCount(UINT
*count
);
202 virtual HRESULT STDMETHODCALLTYPE
GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
);
203 virtual HRESULT STDMETHODCALLTYPE
IsDropOnSource(IDropTarget
*drop_target
);
204 virtual HRESULT STDMETHODCALLTYPE
GetDragPoint(POINT
*pt
);
205 virtual HRESULT STDMETHODCALLTYPE
GetDropPoint(POINT
*pt
);
206 virtual HRESULT STDMETHODCALLTYPE
MoveIcons(IDataObject
*obj
);
207 virtual HRESULT STDMETHODCALLTYPE
SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
);
208 virtual HRESULT STDMETHODCALLTYPE
IsBkDropTarget(IDropTarget
*drop_target
);
209 virtual HRESULT STDMETHODCALLTYPE
SetClipboard(BOOL move
);
210 virtual HRESULT STDMETHODCALLTYPE
SetPoints(IDataObject
*obj
);
211 virtual HRESULT STDMETHODCALLTYPE
GetItemSpacing(ITEMSPACING
*spacing
);
212 virtual HRESULT STDMETHODCALLTYPE
SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
);
213 virtual HRESULT STDMETHODCALLTYPE
Select(UINT flags
);
214 virtual HRESULT STDMETHODCALLTYPE
QuerySupport(UINT
*support
);
215 virtual HRESULT STDMETHODCALLTYPE
SetAutomationObject(IDispatch
*disp
);
217 // *** IOleCommandTarget methods ***
218 virtual HRESULT STDMETHODCALLTYPE
QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
);
219 virtual HRESULT STDMETHODCALLTYPE
Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
);
221 // *** IDropTarget methods ***
222 virtual HRESULT STDMETHODCALLTYPE
DragEnter(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
223 virtual HRESULT STDMETHODCALLTYPE
DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
224 virtual HRESULT STDMETHODCALLTYPE
DragLeave();
225 virtual HRESULT STDMETHODCALLTYPE
Drop(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
227 // *** IDropSource methods ***
228 virtual HRESULT STDMETHODCALLTYPE
QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
);
229 virtual HRESULT STDMETHODCALLTYPE
GiveFeedback(DWORD dwEffect
);
231 // *** IViewObject methods ***
232 virtual HRESULT STDMETHODCALLTYPE
Draw(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
,
233 HDC hdcTargetDev
, HDC hdcDraw
, LPCRECTL lprcBounds
, LPCRECTL lprcWBounds
,
234 BOOL ( STDMETHODCALLTYPE
*pfnContinue
)(ULONG_PTR dwContinue
), ULONG_PTR dwContinue
);
235 virtual HRESULT STDMETHODCALLTYPE
GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
,
236 DVTARGETDEVICE
*ptd
, HDC hicTargetDev
, LOGPALETTE
**ppColorSet
);
237 virtual HRESULT STDMETHODCALLTYPE
Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
);
238 virtual HRESULT STDMETHODCALLTYPE
Unfreeze(DWORD dwFreeze
);
239 virtual HRESULT STDMETHODCALLTYPE
SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
);
240 virtual HRESULT STDMETHODCALLTYPE
GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
);
242 // *** IServiceProvider methods ***
243 virtual HRESULT STDMETHODCALLTYPE
QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
);
246 LRESULT
OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
247 LRESULT
OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
248 LRESULT
OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
249 LRESULT
OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
250 LRESULT
OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
251 LRESULT
OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
252 LRESULT
OnNCCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
253 LRESULT
OnNCDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
254 LRESULT
OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
255 LRESULT
OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
256 LRESULT
OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
257 LRESULT
OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
258 LRESULT
OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
259 LRESULT
OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
260 LRESULT
OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
261 LRESULT
OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
262 LRESULT
OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
263 LRESULT
OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
264 LRESULT
OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
265 LRESULT
OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
267 static ATL::CWndClassInfo
& GetWndClassInfo()
269 static ATL::CWndClassInfo wc
=
271 { sizeof(WNDCLASSEX
), 0, StartWindowProc
,
273 LoadCursor(NULL
, IDC_ARROW
), (HBRUSH
)(COLOR_BACKGROUND
+ 1), NULL
, SV_CLASS_NAME
, NULL
275 NULL
, NULL
, IDC_ARROW
, TRUE
, 0, _T("")
280 virtual WNDPROC
GetWindowProc()
285 static LRESULT CALLBACK
WindowProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
290 // must hold a reference during message handling
291 pThis
= reinterpret_cast<CDefView
*>(hWnd
);
293 result
= CWindowImpl
<CDefView
, CWindow
, CControlWinTraits
>::WindowProc(hWnd
, uMsg
, wParam
, lParam
);
298 BEGIN_MSG_MAP(CDefView
)
299 MESSAGE_HANDLER(WM_SIZE
, OnSize
)
300 MESSAGE_HANDLER(WM_SETFOCUS
, OnSetFocus
)
301 MESSAGE_HANDLER(WM_KILLFOCUS
, OnKillFocus
)
302 MESSAGE_HANDLER(WM_NCCREATE
, OnNCCreate
)
303 MESSAGE_HANDLER(WM_NCDESTROY
, OnNCDestroy
)
304 MESSAGE_HANDLER(WM_CREATE
, OnCreate
)
305 MESSAGE_HANDLER(WM_ACTIVATE
, OnActivate
)
306 MESSAGE_HANDLER(WM_NOTIFY
, OnNotify
)
307 MESSAGE_HANDLER(WM_COMMAND
, OnCommand
)
308 MESSAGE_HANDLER(SHV_CHANGE_NOTIFY
, OnChangeNotify
)
309 MESSAGE_HANDLER(WM_CONTEXTMENU
, OnContextMenu
)
310 MESSAGE_HANDLER(WM_DRAWITEM
, OnCustomItem
)
311 MESSAGE_HANDLER(WM_MEASUREITEM
, OnCustomItem
)
312 MESSAGE_HANDLER(WM_SHOWWINDOW
, OnShowWindow
)
313 MESSAGE_HANDLER(WM_GETDLGCODE
, OnGetDlgCode
)
314 MESSAGE_HANDLER(WM_DESTROY
, OnDestroy
)
315 MESSAGE_HANDLER(WM_ERASEBKGND
, OnEraseBackground
)
316 MESSAGE_HANDLER(WM_SYSCOLORCHANGE
, OnSysColorChange
)
317 MESSAGE_HANDLER(CWM_GETISHELLBROWSER
, OnGetShellBrowser
)
318 MESSAGE_HANDLER(WM_SETTINGCHANGE
, OnSettingChange
)
319 MESSAGE_HANDLER(WM_INITMENUPOPUP
, OnInitMenuPopup
)
322 BEGIN_COM_MAP(CDefView
)
323 // Windows returns E_NOINTERFACE for IOleWindow
324 // COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
325 COM_INTERFACE_ENTRY_IID(IID_IShellView
, IShellView
)
326 COM_INTERFACE_ENTRY_IID(IID_IFolderView
, IFolderView
)
327 COM_INTERFACE_ENTRY_IID(IID_IShellFolderView
, IShellFolderView
)
328 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget
, IOleCommandTarget
)
329 COM_INTERFACE_ENTRY_IID(IID_IDropTarget
, IDropTarget
)
330 COM_INTERFACE_ENTRY_IID(IID_IDropSource
, IDropSource
)
331 COM_INTERFACE_ENTRY_IID(IID_IViewObject
, IViewObject
)
332 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider
, IServiceProvider
)
336 /* ListView Header ID's */
337 #define LISTVIEW_COLUMN_NAME 0
338 #define LISTVIEW_COLUMN_SIZE 1
339 #define LISTVIEW_COLUMN_TYPE 2
340 #define LISTVIEW_COLUMN_TIME 3
341 #define LISTVIEW_COLUMN_ATTRIB 4
344 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
345 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
346 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
348 #define ID_LISTVIEW 1
351 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
352 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
353 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
355 typedef void (CALLBACK
*PFNSHGETSETTINGSPROC
)(LPSHELLFLAGSTATE lpsfs
, DWORD dwMask
);
357 CDefView::CDefView() :
361 m_menusLoaded(FALSE
),
376 ZeroMemory(&m_FolderSettings
, sizeof(m_FolderSettings
));
377 ZeroMemory(&m_sortInfo
, sizeof(m_sortInfo
));
378 ZeroMemory(&m_ptLastMousePos
, sizeof(m_ptLastMousePos
));
379 ZeroMemory(&m_Category
, sizeof(m_Category
));
382 CDefView::~CDefView()
384 TRACE(" destroying IShellView(%p)\n", this);
394 HRESULT WINAPI
CDefView::Initialize(IShellFolder
*shellFolder
)
396 m_pSFParent
= shellFolder
;
397 shellFolder
->QueryInterface(IID_PPV_ARG(IShellFolder2
, &m_pSF2Parent
));
402 /**********************************************************
404 * ##### helperfunctions for communication with ICommDlgBrowser #####
406 HRESULT
CDefView::IncludeObject(PCUITEMID_CHILD pidl
)
410 if (m_pCommDlgBrowser
.p
!= NULL
)
412 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl
);
413 ret
= m_pCommDlgBrowser
->IncludeObject(this, pidl
);
414 TRACE("--0x%08x\n", ret
);
420 HRESULT
CDefView::OnDefaultCommand()
422 HRESULT ret
= S_FALSE
;
424 if (m_pCommDlgBrowser
.p
!= NULL
)
426 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
427 ret
= m_pCommDlgBrowser
->OnDefaultCommand(this);
428 TRACE("-- returns %08x\n", ret
);
434 HRESULT
CDefView::OnStateChange(UINT uFlags
)
436 HRESULT ret
= S_FALSE
;
438 if (m_pCommDlgBrowser
.p
!= NULL
)
440 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags
);
441 ret
= m_pCommDlgBrowser
->OnStateChange(this, uFlags
);
447 /**********************************************************
448 * set the toolbar of the filedialog buttons
450 * - activates the buttons from the shellbrowser according to
453 void CDefView::CheckToolbar()
459 if (m_pCommDlgBrowser
!= NULL
)
461 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
462 FCIDM_TB_SMALLICON
, (m_FolderSettings
.ViewMode
== FVM_LIST
) ? TRUE
: FALSE
, &result
);
463 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
464 FCIDM_TB_REPORTVIEW
, (m_FolderSettings
.ViewMode
== FVM_DETAILS
) ? TRUE
: FALSE
, &result
);
465 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
466 FCIDM_TB_SMALLICON
, TRUE
, &result
);
467 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
468 FCIDM_TB_REPORTVIEW
, TRUE
, &result
);
472 /**********************************************************
474 * ##### helperfunctions for initializing the view #####
476 /**********************************************************
477 * change the style of the listview control
479 void CDefView::SetStyle(DWORD dwAdd
, DWORD dwRemove
)
483 TRACE("(%p)\n", this);
485 tmpstyle
= ::GetWindowLongPtrW(m_ListView
, GWL_STYLE
);
486 ::SetWindowLongPtrW(m_ListView
, GWL_STYLE
, dwAdd
| (tmpstyle
& ~dwRemove
));
489 /**********************************************************
490 * ShellView_CreateList()
492 * - creates the list view window
494 BOOL
CDefView::CreateList()
495 { DWORD dwStyle
, dwExStyle
;
499 dwStyle
= WS_TABSTOP
| WS_VISIBLE
| WS_CHILDWINDOW
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
|
500 LVS_SHAREIMAGELISTS
| LVS_EDITLABELS
| LVS_AUTOARRANGE
;
501 dwExStyle
= WS_EX_CLIENTEDGE
;
503 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
504 dwStyle
|= LVS_ALIGNLEFT
;
506 dwStyle
|= LVS_ALIGNTOP
| LVS_SHOWSELALWAYS
;
508 switch (m_FolderSettings
.ViewMode
)
515 dwStyle
|= LVS_REPORT
;
519 dwStyle
|= LVS_SMALLICON
;
531 if (m_FolderSettings
.fFlags
& FWF_AUTOARRANGE
)
532 dwStyle
|= LVS_AUTOARRANGE
;
534 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
535 m_FolderSettings
.fFlags
|= FWF_NOCLIENTEDGE
| FWF_NOSCROLL
;
537 if (m_FolderSettings
.fFlags
& FWF_SINGLESEL
)
538 dwStyle
|= LVS_SINGLESEL
;
540 if (m_FolderSettings
.fFlags
& FWF_NOCLIENTEDGE
)
541 dwExStyle
&= ~WS_EX_CLIENTEDGE
;
543 RECT rcListView
= {0,0,0,0};
544 m_ListView
.Create(m_hWnd
, rcListView
, NULL
,dwStyle
, dwExStyle
, ID_LISTVIEW
);
549 m_sortInfo
.bIsAscending
= TRUE
;
550 m_sortInfo
.nHeaderID
= -1;
551 m_sortInfo
.nLastHeaderID
= -1;
555 /* UpdateShellSettings(); */
559 void CDefView::UpdateListColors()
561 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
563 /* Check if drop shadows option is enabled */
564 BOOL bDropShadow
= FALSE
;
565 DWORD cbDropShadow
= sizeof(bDropShadow
);
566 WCHAR wszBuf
[16] = L
"";
568 RegGetValueW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
569 L
"ListviewShadow", RRF_RT_DWORD
, NULL
, &bDropShadow
, &cbDropShadow
);
570 if (bDropShadow
&& SystemParametersInfoW(SPI_GETDESKWALLPAPER
, _countof(wszBuf
), wszBuf
, 0) && wszBuf
[0])
572 m_ListView
.SetTextBkColor(CLR_NONE
);
573 m_ListView
.SetBkColor(CLR_NONE
);
574 m_ListView
.SetTextColor(RGB(255, 255, 255));
575 m_ListView
.SetExtendedListViewStyle(LVS_EX_TRANSPARENTSHADOWTEXT
, LVS_EX_TRANSPARENTSHADOWTEXT
);
579 COLORREF crDesktop
= GetSysColor(COLOR_DESKTOP
);
580 m_ListView
.SetTextBkColor(crDesktop
);
581 m_ListView
.SetBkColor(crDesktop
);
582 if (GetRValue(crDesktop
) + GetGValue(crDesktop
) + GetBValue(crDesktop
) > 128 * 3)
583 m_ListView
.SetTextColor(RGB(0, 0, 0));
585 m_ListView
.SetTextColor(RGB(255, 255, 255));
586 m_ListView
.SetExtendedListViewStyle(LVS_EX_TRANSPARENTSHADOWTEXT
);
591 /**********************************************************
592 * ShellView_InitList()
594 * - adds all needed columns to the shellview
596 BOOL
CDefView::InitList()
600 HIMAGELIST big_icons
, small_icons
;
604 m_ListView
.DeleteAllItems();
608 for (int i
= 0; 1; i
++)
610 if (FAILED(m_pSF2Parent
->GetDetailsOf(NULL
, i
, &sd
)))
612 StrRetToStrNW( szTemp
, 50, &sd
.str
, NULL
);
613 m_ListView
.InsertColumn(i
, szTemp
, sd
.fmt
, sd
.cxChar
* 8);
622 Shell_GetImageLists(&big_icons
, &small_icons
);
623 m_ListView
.SetImageList(big_icons
, LVSIL_NORMAL
);
624 m_ListView
.SetImageList(small_icons
, LVSIL_SMALL
);
629 /**********************************************************
630 * ShellView_CompareItems()
633 * internal, CALLBACK for DSA_Sort
635 INT CALLBACK
CDefView::CompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
)
638 TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1
, lParam2
, (LPVOID
) lpData
);
643 IShellFolder
* psf
= reinterpret_cast<IShellFolder
*>(lpData
);
644 PCUIDLIST_RELATIVE pidl1
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam1
);
645 PCUIDLIST_RELATIVE pidl2
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam2
);
647 ret
= (SHORT
)SCODE_CODE(psf
->CompareIDs(0, pidl1
, pidl2
));
648 TRACE("ret=%i\n", ret
);
653 /*************************************************************************
654 * ShellView_ListViewCompareItems
656 * Compare Function for the Listview (FileOpen Dialog)
659 * lParam1 [I] the first ItemIdList to compare with
660 * lParam2 [I] the second ItemIdList to compare with
661 * lpData [I] The column ID for the header Ctrl to process
664 * A negative value if the first item should precede the second,
665 * a positive value if the first item should follow the second,
666 * or zero if the two items are equivalent
669 * FIXME: function does what ShellView_CompareItems is supposed to do.
670 * unify it and figure out how to use the undocumented first parameter
671 * of IShellFolder_CompareIDs to do the job this function does and
672 * move this code to IShellFolder.
673 * make LISTVIEW_SORT_INFO obsolete
674 * the way this function works is only usable if we had only
675 * filesystemfolders (25/10/99 jsch)
677 INT CALLBACK
CDefView::ListViewCompareItems(LPARAM lParam1
, LPARAM lParam2
, LPARAM lpData
)
681 char strName1
[MAX_PATH
], strName2
[MAX_PATH
];
682 BOOL bIsFolder1
, bIsFolder2
, bIsBothFolder
;
683 PCUIDLIST_RELATIVE pidl1
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam1
);
684 PCUIDLIST_RELATIVE pidl2
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam2
);
685 LISTVIEW_SORT_INFO
*pSortInfo
= reinterpret_cast<LPLISTVIEW_SORT_INFO
>(lpData
);
688 bIsFolder1
= _ILIsFolder(pidl1
);
689 bIsFolder2
= _ILIsFolder(pidl2
);
690 bIsBothFolder
= bIsFolder1
&& bIsFolder2
;
692 /* When sorting between a File and a Folder, the Folder gets sorted first */
693 if ( (bIsFolder1
|| bIsFolder2
) && !bIsBothFolder
)
695 nDiff
= bIsFolder1
? -1 : 1;
699 /* Sort by Time: Folders or Files can be sorted */
701 if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_TIME
)
703 _ILGetFileDateTime(pidl1
, &fd1
);
704 _ILGetFileDateTime(pidl2
, &fd2
);
705 nDiff
= CompareFileTime(&fd2
, &fd1
);
707 /* Sort by Attribute: Folder or Files can be sorted */
708 else if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_ATTRIB
)
710 _ILGetFileAttributes(pidl1
, strName1
, MAX_PATH
);
711 _ILGetFileAttributes(pidl2
, strName2
, MAX_PATH
);
712 nDiff
= lstrcmpiA(strName1
, strName2
);
714 /* Sort by FileName: Folder or Files can be sorted */
715 else if (pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_NAME
|| bIsBothFolder
)
718 _ILSimpleGetText(pidl1
, strName1
, MAX_PATH
);
719 _ILSimpleGetText(pidl2
, strName2
, MAX_PATH
);
720 nDiff
= lstrcmpiA(strName1
, strName2
);
722 /* Sort by File Size, Only valid for Files */
723 else if (pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_SIZE
)
725 nDiff
= (INT
)(_ILGetFileSize(pidl1
, NULL
, 0) - _ILGetFileSize(pidl2
, NULL
, 0));
727 /* Sort by File Type, Only valid for Files */
728 else if (pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_TYPE
)
731 _ILGetFileType(pidl1
, strName1
, MAX_PATH
);
732 _ILGetFileType(pidl2
, strName2
, MAX_PATH
);
733 nDiff
= lstrcmpiA(strName1
, strName2
);
736 /* If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
740 _ILSimpleGetText(pidl1
, strName1
, MAX_PATH
);
741 _ILSimpleGetText(pidl2
, strName2
, MAX_PATH
);
742 nDiff
= lstrcmpiA(strName1
, strName2
);
745 if (!pSortInfo
->bIsAscending
)
753 PCUITEMID_CHILD
CDefView::_PidlByItem(int i
)
755 return reinterpret_cast<PCUITEMID_CHILD
>(m_ListView
.GetItemData(i
));
758 PCUITEMID_CHILD
CDefView::_PidlByItem(LVITEM
& lvItem
)
760 return reinterpret_cast<PCUITEMID_CHILD
>(lvItem
.lParam
);
763 /**********************************************************
764 * LV_FindItemByPidl()
766 int CDefView::LV_FindItemByPidl(PCUITEMID_CHILD pidl
)
768 int cItems
= m_ListView
.GetItemCount();
770 for (int i
= 0; i
<cItems
; i
++)
772 PCUITEMID_CHILD currentpidl
= _PidlByItem(i
);
773 HRESULT hr
= m_pSFParent
->CompareIDs(0, pidl
, currentpidl
);
775 if (SUCCEEDED(hr
) && !HRESULT_CODE(hr
))
783 /**********************************************************
786 BOOLEAN
CDefView::LV_AddItem(PCUITEMID_CHILD pidl
)
790 TRACE("(%p)(pidl=%p)\n", this, pidl
);
792 lvItem
.mask
= LVIF_TEXT
| LVIF_IMAGE
| LVIF_PARAM
; /*set the mask*/
793 lvItem
.iItem
= m_ListView
.GetItemCount(); /*add the item to the end of the list*/
795 lvItem
.lParam
= reinterpret_cast<LPARAM
>(ILClone(pidl
)); /*set the item's data*/
796 lvItem
.pszText
= LPSTR_TEXTCALLBACKW
; /*get text on a callback basis*/
797 lvItem
.iImage
= I_IMAGECALLBACK
; /*get the image on a callback basis*/
798 lvItem
.stateMask
= LVIS_CUT
;
800 if (m_ListView
.InsertItem(&lvItem
) == -1)
806 /**********************************************************
809 BOOLEAN
CDefView::LV_DeleteItem(PCUITEMID_CHILD pidl
)
813 TRACE("(%p)(pidl=%p)\n", this, pidl
);
815 nIndex
= LV_FindItemByPidl(pidl
);
817 return (-1 == m_ListView
.DeleteItem(nIndex
)) ? FALSE
: TRUE
;
820 /**********************************************************
823 BOOLEAN
CDefView::LV_RenameItem(PCUITEMID_CHILD pidlOld
, PCUITEMID_CHILD pidlNew
)
828 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", this, pidlOld
, pidlNew
);
830 nItem
= LV_FindItemByPidl(pidlOld
);
834 lvItem
.mask
= LVIF_PARAM
; /* only the pidl */
835 lvItem
.iItem
= nItem
;
836 m_ListView
.GetItem(&lvItem
);
838 SHFree(reinterpret_cast<LPVOID
>(lvItem
.lParam
));
839 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
840 lvItem
.iItem
= nItem
;
841 lvItem
.lParam
= reinterpret_cast<LPARAM
>(ILClone(pidlNew
)); /* set the item's data */
842 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
843 m_ListView
.SetItem(&lvItem
);
844 m_ListView
.Update(nItem
);
845 return TRUE
; /* FIXME: better handling */
851 /**********************************************************
854 BOOLEAN
CDefView::LV_ProdItem(PCUITEMID_CHILD pidl
)
859 TRACE("(%p)(pidl=%p)\n", this, pidl
);
861 nItem
= LV_FindItemByPidl(pidl
);
865 lvItem
.mask
= LVIF_IMAGE
;
866 lvItem
.iItem
= nItem
;
867 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
868 m_ListView
.SetItem(&lvItem
);
869 m_ListView
.Update(nItem
);
876 /**********************************************************
877 * ShellView_FillList()
879 * - gets the objectlist from the shellfolder
881 * - fills the list into the view
883 INT CALLBACK
CDefView::fill_list( LPVOID ptr
, LPVOID arg
)
885 PITEMID_CHILD pidl
= static_cast<PITEMID_CHILD
>(ptr
);
886 CDefView
*pThis
= static_cast<CDefView
*>(arg
);
888 /* in a commdlg This works as a filemask*/
889 if (pThis
->IncludeObject(pidl
) == S_OK
)
890 pThis
->LV_AddItem(pidl
);
896 HRESULT
CDefView::FillList()
898 CComPtr
<IEnumIDList
> pEnumIDList
;
904 DWORD dFlags
= SHCONTF_NONFOLDERS
| SHCONTF_FOLDERS
;
908 /* determine if there is a setting to show all the hidden files/folders */
909 if (RegOpenKeyExW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", 0, KEY_QUERY_VALUE
, &hKey
) == ERROR_SUCCESS
)
911 DWORD dataLength
, flagVal
;
913 dataLength
= sizeof(flagVal
);
914 if (RegQueryValueExW(hKey
, L
"Hidden", NULL
, NULL
, (LPBYTE
)&flagVal
, &dataLength
) == ERROR_SUCCESS
)
916 /* if the value is 1, then show all hidden files/folders */
919 dFlags
|= SHCONTF_INCLUDEHIDDEN
;
920 m_ListView
.SendMessageW(LVM_SETCALLBACKMASK
, LVIS_CUT
, 0);
928 /* get the itemlist from the shfolder */
929 hRes
= m_pSFParent
->EnumObjects(m_hWnd
, dFlags
, &pEnumIDList
);
937 /* create a pointer array */
938 hdpa
= DPA_Create(16);
941 return(E_OUTOFMEMORY
);
944 /* copy the items into the array*/
945 while((S_OK
== pEnumIDList
->Next(1, &pidl
, &dwFetched
)) && dwFetched
)
947 if (DPA_InsertPtr(hdpa
, 0x7fff, pidl
) == -1)
954 DPA_Sort(hdpa
, CompareItems
, reinterpret_cast<LPARAM
>(m_pSFParent
.p
));
956 /*turn the listview's redrawing off*/
957 m_ListView
.SetRedraw(FALSE
);
959 DPA_DestroyCallback( hdpa
, fill_list
, this);
961 /*turn the listview's redrawing back on and force it to draw*/
962 m_ListView
.SetRedraw(TRUE
);
967 LRESULT
CDefView::OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
969 m_ListView
.UpdateWindow();
974 LRESULT
CDefView::OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
976 return m_ListView
.SendMessageW(uMsg
, 0, 0);
979 LRESULT
CDefView::OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
986 DestroyMenu(m_hMenu
);
989 RevokeDragDrop(m_hWnd
);
990 SHChangeNotifyDeregister(m_hNotify
);
992 SHFree(m_pidlParent
);
999 LRESULT
CDefView::OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1001 /* redirect to parent */
1002 if (m_FolderSettings
.fFlags
& (FWF_DESKTOP
| FWF_TRANSPARENT
))
1003 return SendMessageW(GetParent(), WM_ERASEBKGND
, wParam
, lParam
);
1009 LRESULT
CDefView::OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1011 /* Update desktop labels color */
1014 /* Forward WM_SYSCOLORCHANGE to common controls */
1015 return m_ListView
.SendMessageW(uMsg
, 0, 0);
1018 LRESULT
CDefView::OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1020 return reinterpret_cast<LRESULT
>(m_pShellBrowser
.p
);
1023 LRESULT
CDefView::OnNCCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1030 LRESULT
CDefView::OnNCDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1037 /**********************************************************
1038 * ShellView_OnCreate()
1040 LRESULT
CDefView::OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1042 CComPtr
<IDropTarget
> pdt
;
1043 SHChangeNotifyEntry ntreg
;
1044 CComPtr
<IPersistFolder2
> ppf2
;
1046 TRACE("%p\n", this);
1056 if (SUCCEEDED(QueryInterface(IID_PPV_ARG(IDropTarget
, &pdt
))))
1058 if (FAILED(RegisterDragDrop(m_hWnd
, pdt
)))
1059 ERR("Registering Drag Drop Failed");
1062 /* register for receiving notifications */
1063 m_pSFParent
->QueryInterface(IID_PPV_ARG(IPersistFolder2
, &ppf2
));
1066 ppf2
->GetCurFolder(&m_pidlParent
);
1067 ntreg
.fRecursive
= TRUE
;
1068 ntreg
.pidl
= m_pidlParent
;
1069 m_hNotify
= SHChangeNotifyRegister(m_hWnd
, SHCNRF_InterruptLevel
| SHCNRF_ShellLevel
, SHCNE_ALLEVENTS
, SHV_CHANGE_NOTIFY
, 1, &ntreg
);
1072 m_hAccel
= LoadAcceleratorsW(shell32_hInstance
, MAKEINTRESOURCEW(IDA_SHELLVIEW
));
1077 /**********************************************************
1078 * #### Handling of the menus ####
1081 HMENU
CDefView::BuildFileMenu()
1084 CComPtr
<IContextMenu
> cm
;
1088 hr
= m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, IID_NULL_PPV_ARG(IContextMenu
, &cm
));
1092 HMENU hmenu
= CreatePopupMenu();
1094 //FIXME: get proper numbers ?
1095 const UINT first
= 0x7800;
1096 const UINT last
= 0x7A00;
1097 hr
= cm
->QueryContextMenu(hmenu
, 0, first
, last
, 0);
1101 // TODO: filter or something
1106 void CDefView::PrepareShowFileMenu(HMENU hSubMenu
)
1108 TRACE("(%p)->(submenu=%p) stub\n", this, hSubMenu
);
1113 /* Cleanup the items added previously */
1114 for (int i
= 0; i
< GetMenuItemCount(hSubMenu
); )
1117 mii
.cbSize
= sizeof(mii
);
1118 mii
.fMask
= MIIM_ID
;
1119 GetMenuItemInfoW(hSubMenu
, i
, TRUE
, &mii
);
1121 if (mii
.wID
< 0x8000)
1123 DeleteMenu(hSubMenu
, i
, MF_BYPOSITION
);
1132 /* FIXME/TODO: Reenable when they implemented AND localizable (not hardcoded). */
1133 /* Insert This item at the beginning of the menu. */
1134 _InsertMenuItemW(hSubMenu
, 0, TRUE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1135 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
+ 4, MFT_STRING
, L
"Properties", MFS_DISABLED
);
1136 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
+ 3, MFT_STRING
, L
"Rename", MFS_DISABLED
);
1137 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
+ 2, MFT_STRING
, L
"Delete", MFS_DISABLED
);
1138 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
+ 1, MFT_STRING
, L
"Create Shortcut", MFS_DISABLED
);
1139 _InsertMenuItemW(hSubMenu
, 0, TRUE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1140 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
, MFT_STRING
, L
"New", MFS_ENABLED
);
1143 HMENU menubase
= BuildFileMenu();
1146 int count
= ::GetMenuItemCount(menubase
);
1147 int count2
= ::GetMenuItemCount(hSubMenu
);
1149 if (count2
> 0 && count
> 0)
1151 _InsertMenuItemW(hSubMenu
, 0, TRUE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1154 for (int i
= count
-1; i
>= 0; i
--)
1158 MENUITEMINFOW mii
= { 0 };
1159 mii
.cbSize
= sizeof(mii
);
1160 mii
.fMask
= MIIM_STATE
| MIIM_ID
| MIIM_SUBMENU
| MIIM_CHECKMARKS
| MIIM_DATA
| MIIM_STRING
| MIIM_BITMAP
| MIIM_FTYPE
;
1161 mii
.dwTypeData
= label
;
1162 mii
.cch
= _countof(label
);
1163 ::GetMenuItemInfoW(menubase
, i
, TRUE
, &mii
);
1165 TRACE("Adding item %d label %S type %d\n", mii
.wID
, mii
.dwTypeData
, mii
.fType
);
1167 mii
.fType
|= MFT_RADIOCHECK
;
1169 ::InsertMenuItemW(hSubMenu
, 0, TRUE
, &mii
);
1173 ::DestroyMenu(menubase
);
1178 void CDefView::PrepareShowViewMenu(HMENU hSubMenu
)
1180 TRACE("(%p)->(submenu=%p)\n", this, hSubMenu
);
1185 if (m_FolderSettings
.ViewMode
>= FVM_FIRST
&& m_FolderSettings
.ViewMode
<= FVM_LAST
)
1187 UINT iItemFirst
= FCIDM_SHVIEW_BIGICON
;
1188 UINT iItemLast
= iItemFirst
+ FVM_LAST
- FVM_FIRST
;
1189 UINT iItem
= iItemFirst
+ m_FolderSettings
.ViewMode
- FVM_FIRST
;
1190 CheckMenuRadioItem(hSubMenu
, iItemFirst
, iItemLast
, iItem
, MF_BYCOMMAND
);
1194 /**********************************************************
1195 * ShellView_GetSelections()
1197 * - fills the m_apidl list with the selected objects
1200 * number of selected items
1202 UINT
CDefView::GetSelections()
1206 m_cidl
= m_ListView
.GetSelectedCount();
1207 m_apidl
= reinterpret_cast<PCUITEMID_CHILD_ARRAY
>(SHAlloc(m_cidl
* sizeof(PCUITEMID_CHILD
)));
1214 TRACE("-- Items selected =%u\n", m_cidl
);
1218 while ((lvIndex
= m_ListView
.GetNextItem(lvIndex
, LVNI_SELECTED
)) > -1)
1220 m_apidl
[i
] = _PidlByItem(lvIndex
);
1224 TRACE("-- selected Item found\n");
1230 /**********************************************************
1231 * ShellView_OpenSelectedItems()
1233 HRESULT
CDefView::OpenSelectedItems()
1236 CMINVOKECOMMANDINFO cmi
;
1240 m_cidl
= m_ListView
.GetSelectedCount();
1244 hResult
= OnDefaultCommand();
1245 if (hResult
== S_OK
)
1248 hMenu
= CreatePopupMenu();
1252 hResult
= GetItemObject(SVGIO_SELECTION
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1253 if (FAILED(hResult
))
1256 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, 0x20, 0x7fff, CMF_DEFAULTONLY
);
1257 if (FAILED(hResult
))
1260 uCommand
= GetMenuDefaultItem(hMenu
, FALSE
, 0);
1261 if (uCommand
== (UINT
)-1)
1267 ZeroMemory(&cmi
, sizeof(cmi
));
1268 cmi
.cbSize
= sizeof(cmi
);
1269 cmi
.lpVerb
= (LPCSTR
)MAKEINTRESOURCEA(uCommand
);
1272 hResult
= m_pCM
->InvokeCommand(&cmi
);
1285 /**********************************************************
1286 * ShellView_DoContextMenu()
1288 LRESULT
CDefView::OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1294 CMINVOKECOMMANDINFO cmi
;
1297 // for some reason I haven't figured out, we sometimes recurse into this method
1304 TRACE("(%p)->(0x%08x 0x%08x) stub\n", this, x
, y
);
1306 hMenu
= CreatePopupMenu();
1310 m_cidl
= m_ListView
.GetSelectedCount();
1312 hResult
= GetItemObject( m_cidl
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1313 if (FAILED( hResult
))
1316 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1317 if (FAILED( hResult
))
1320 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
1321 SetMenuDefaultItem(hMenu
, FCIDM_SHVIEW_OPEN
, MF_BYCOMMAND
);
1323 uCommand
= TrackPopupMenu(hMenu
,
1324 TPM_LEFTALIGN
| TPM_RETURNCMD
| TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
,
1325 x
, y
, 0, m_hWnd
, NULL
);
1329 if (uCommand
== FCIDM_SHVIEW_OPEN
&& OnDefaultCommand() == S_OK
)
1332 ZeroMemory(&cmi
, sizeof(cmi
));
1333 cmi
.cbSize
= sizeof(cmi
);
1334 cmi
.lpVerb
= MAKEINTRESOURCEA(uCommand
);
1336 m_pCM
->InvokeCommand(&cmi
);
1349 LRESULT
CDefView::OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
)
1352 CMINVOKECOMMANDINFO cmi
;
1355 hMenu
= CreatePopupMenu();
1359 hResult
= GetItemObject( bUseSelection
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1360 if (FAILED( hResult
))
1363 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1364 if (FAILED( hResult
))
1367 ZeroMemory(&cmi
, sizeof(cmi
));
1368 cmi
.cbSize
= sizeof(cmi
);
1369 cmi
.lpVerb
= MAKEINTRESOURCEA(uCommand
);
1371 m_pCM
->InvokeCommand(&cmi
);
1384 /**********************************************************
1385 * ##### message handling #####
1388 /**********************************************************
1389 * ShellView_OnSize()
1391 LRESULT
CDefView::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1396 wWidth
= LOWORD(lParam
);
1397 wHeight
= HIWORD(lParam
);
1399 TRACE("%p width=%u height=%u\n", this, wWidth
, wHeight
);
1401 /*resize the ListView to fit our window*/
1404 ::MoveWindow(m_ListView
, 0, 0, wWidth
, wHeight
, TRUE
);
1410 /**********************************************************
1411 * ShellView_OnDeactivate()
1416 void CDefView::OnDeactivate()
1418 TRACE("%p\n", this);
1420 if (m_uState
!= SVUIA_DEACTIVATE
)
1422 // TODO: cleanup menu after deactivation
1424 m_uState
= SVUIA_DEACTIVATE
;
1428 void CDefView::DoActivate(UINT uState
)
1430 TRACE("%p uState=%x\n", this, uState
);
1432 /*don't do anything if the state isn't really changing */
1433 if (m_uState
== uState
)
1438 if (uState
== SVUIA_DEACTIVATE
)
1448 MENUITEMINFOW mii
= { 0 };
1450 /* initialize EDIT menu */
1451 mii
.cbSize
= sizeof(mii
);
1452 mii
.fMask
= MIIM_SUBMENU
;
1453 if (::GetMenuItemInfoW(m_hMenu
, FCIDM_MENU_EDIT
, FALSE
, &mii
))
1455 HMENU hSubMenu
= mii
.hSubMenu
;
1457 HMENU menubase
= ::LoadMenuW(shell32_hInstance
, L
"MENU_003");
1459 int count
= ::GetMenuItemCount(menubase
);
1460 for (int i
= 0; i
< count
; i
++)
1464 ZeroMemory(&mii
, sizeof(mii
));
1465 mii
.cbSize
= sizeof(mii
);
1466 mii
.fMask
= MIIM_STATE
| MIIM_ID
| MIIM_SUBMENU
| MIIM_CHECKMARKS
| MIIM_DATA
| MIIM_STRING
| MIIM_BITMAP
| MIIM_FTYPE
;
1467 mii
.dwTypeData
= label
;
1468 mii
.cch
= _countof(label
);
1469 ::GetMenuItemInfoW(menubase
, i
, TRUE
, &mii
);
1471 TRACE("Adding item %d label %S type %d\n", mii
.wID
, mii
.dwTypeData
, mii
.fType
);
1473 mii
.fType
|= MFT_RADIOCHECK
;
1475 ::InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, &mii
);
1478 ::DestroyMenu(menubase
);
1481 /* initialize VIEW menu */
1483 mii
.cbSize
= sizeof(mii
);
1484 mii
.fMask
= MIIM_SUBMENU
;
1485 if (::GetMenuItemInfoW(m_hMenu
, FCIDM_MENU_VIEW
, FALSE
, &mii
))
1487 HMENU menubase
= ::LoadMenuW(shell32_hInstance
, L
"MENU_001");
1489 HMENU hSubMenu
= mii
.hSubMenu
;
1491 m_hView
= CreatePopupMenu();
1493 _InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1495 int count
= ::GetMenuItemCount(menubase
);
1496 for (int i
= 0; i
< count
; i
++)
1500 ZeroMemory(&mii
, sizeof(mii
));
1501 mii
.cbSize
= sizeof(mii
);
1502 mii
.fMask
= MIIM_STATE
| MIIM_ID
| MIIM_SUBMENU
| MIIM_CHECKMARKS
| MIIM_DATA
| MIIM_STRING
| MIIM_BITMAP
| MIIM_FTYPE
;
1503 mii
.dwTypeData
= label
;
1504 mii
.cch
= _countof(label
);
1505 ::GetMenuItemInfoW(menubase
, i
, TRUE
, &mii
);
1507 ::AppendMenuW(m_hView
, mii
.fType
, mii
.wID
, mii
.dwTypeData
);
1509 TRACE("Adding item %d label %S type %d\n", mii
.wID
, mii
.dwTypeData
, mii
.fType
);
1511 mii
.fType
|= MFT_RADIOCHECK
;
1513 ::InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, &mii
);
1516 ::DestroyMenu(menubase
);
1520 TRACE("-- before fnSetMenuSB\n");
1521 m_pShellBrowser
->SetMenuSB(m_hMenu
, 0, m_hWnd
);
1523 m_menusLoaded
= TRUE
;
1527 if (SVUIA_ACTIVATE_FOCUS
== uState
)
1529 m_ListView
.SetFocus();
1537 /**********************************************************
1538 * ShellView_OnActivate()
1540 LRESULT
CDefView::OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1542 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1546 /**********************************************************
1547 * ShellView_OnSetFocus()
1550 LRESULT
CDefView::OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1552 TRACE("%p\n", this);
1554 /* Tell the browser one of our windows has received the focus. This
1555 should always be done before merging menus (OnActivate merges the
1556 menus) if one of our windows has the focus.*/
1558 m_pShellBrowser
->OnViewWindowActive(this);
1559 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1561 /* Set the focus to the listview */
1562 m_ListView
.SetFocus();
1564 /* Notify the ICommDlgBrowser interface */
1565 OnStateChange(CDBOSC_SETFOCUS
);
1570 /**********************************************************
1571 * ShellView_OnKillFocus()
1573 LRESULT
CDefView::OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1575 TRACE("(%p) stub\n", this);
1577 DoActivate(SVUIA_ACTIVATE_NOFOCUS
);
1578 /* Notify the ICommDlgBrowser */
1579 OnStateChange(CDBOSC_KILLFOCUS
);
1584 /**********************************************************
1585 * ShellView_OnCommand()
1588 * the CmdID's are the ones from the context menu
1590 LRESULT
CDefView::OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1597 dwCmdID
= GET_WM_COMMAND_ID(wParam
, lParam
);
1598 dwCmd
= GET_WM_COMMAND_CMD(wParam
, lParam
);
1599 hwndCmd
= GET_WM_COMMAND_HWND(wParam
, lParam
);
1601 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n", this, dwCmdID
, dwCmd
, hwndCmd
);
1605 case FCIDM_SHVIEW_SMALLICON
:
1606 m_FolderSettings
.ViewMode
= FVM_SMALLICON
;
1607 SetStyle (LVS_SMALLICON
, LVS_TYPEMASK
);
1611 case FCIDM_SHVIEW_BIGICON
:
1612 m_FolderSettings
.ViewMode
= FVM_ICON
;
1613 SetStyle (LVS_ICON
, LVS_TYPEMASK
);
1617 case FCIDM_SHVIEW_LISTVIEW
:
1618 m_FolderSettings
.ViewMode
= FVM_LIST
;
1619 SetStyle (LVS_LIST
, LVS_TYPEMASK
);
1623 case FCIDM_SHVIEW_REPORTVIEW
:
1624 m_FolderSettings
.ViewMode
= FVM_DETAILS
;
1625 SetStyle (LVS_REPORT
, LVS_TYPEMASK
);
1629 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1634 m_sortInfo
.nHeaderID
= dwCmdID
- 0x30;
1635 m_sortInfo
.bIsAscending
= TRUE
;
1636 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
1637 m_ListView
.SortItems(ListViewCompareItems
, &m_sortInfo
);
1640 case FCIDM_SHVIEW_SELECTALL
:
1641 m_ListView
.SetItemState(-1, LVIS_SELECTED
, LVIS_SELECTED
);
1644 case FCIDM_SHVIEW_INVERTSELECTION
:
1645 nCount
= m_ListView
.GetItemCount();
1646 for (int i
=0; i
< nCount
; i
++)
1647 m_ListView
.SetItemState(i
, m_ListView
.GetItemState(i
, LVIS_SELECTED
) ? 0 : LVIS_SELECTED
, LVIS_SELECTED
);
1650 case FCIDM_SHVIEW_REFRESH
:
1654 case FCIDM_SHVIEW_DELETE
:
1655 case FCIDM_SHVIEW_CUT
:
1656 case FCIDM_SHVIEW_COPY
:
1657 case FCIDM_SHVIEW_RENAME
:
1658 return OnExplorerCommand(dwCmdID
, TRUE
);
1660 case FCIDM_SHVIEW_INSERT
:
1661 case FCIDM_SHVIEW_UNDO
:
1662 case FCIDM_SHVIEW_INSERTLINK
:
1663 case FCIDM_SHVIEW_NEWFOLDER
:
1664 return OnExplorerCommand(dwCmdID
, FALSE
);
1666 TRACE("-- COMMAND 0x%04x unhandled\n", dwCmdID
);
1672 /**********************************************************
1673 * ShellView_OnNotify()
1676 LRESULT
CDefView::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1680 LPNMLISTVIEW lpnmlv
;
1681 NMLVDISPINFOW
*lpdi
;
1682 PCUITEMID_CHILD pidl
;
1686 lpnmh
= (LPNMHDR
)lParam
;
1687 lpnmlv
= (LPNMLISTVIEW
)lpnmh
;
1688 lpdi
= (NMLVDISPINFOW
*)lpnmh
;
1690 TRACE("%p CtlID=%u lpnmh->code=%x\n", this, CtlID
, lpnmh
->code
);
1692 switch (lpnmh
->code
)
1695 TRACE("-- NM_SETFOCUS %p\n", this);
1696 OnSetFocus(0, 0, 0, unused
);
1700 TRACE("-- NM_KILLFOCUS %p\n", this);
1702 /* Notify the ICommDlgBrowser interface */
1703 OnStateChange(CDBOSC_KILLFOCUS
);
1707 TRACE("-- NM_CUSTOMDRAW %p\n", this);
1708 return CDRF_DODEFAULT
;
1710 case NM_RELEASEDCAPTURE
:
1711 TRACE("-- NM_RELEASEDCAPTURE %p\n", this);
1715 TRACE("-- NM_CLICK %p\n", this);
1719 TRACE("-- NM_RCLICK %p\n", this);
1723 TRACE("-- NM_DBLCLK %p\n", this);
1724 OpenSelectedItems();
1728 TRACE("-- NM_RETURN %p\n", this);
1729 OpenSelectedItems();
1733 TRACE("-- HDN_ENDTRACKW %p\n", this);
1734 /*nColumn1 = m_ListView.GetColumnWidth(0);
1735 nColumn2 = m_ListView.GetColumnWidth(1);*/
1738 case LVN_DELETEITEM
:
1739 TRACE("-- LVN_DELETEITEM %p\n", this);
1741 /*delete the pidl because we made a copy of it*/
1742 SHFree(reinterpret_cast<LPVOID
>(lpnmlv
->lParam
));
1746 case LVN_DELETEALLITEMS
:
1747 TRACE("-- LVN_DELETEALLITEMS %p\n", this);
1750 case LVN_INSERTITEM
:
1751 TRACE("-- LVN_INSERTITEM (STUB)%p\n", this);
1754 case LVN_ITEMACTIVATE
:
1755 TRACE("-- LVN_ITEMACTIVATE %p\n", this);
1756 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1759 case LVN_COLUMNCLICK
:
1760 m_sortInfo
.nHeaderID
= lpnmlv
->iSubItem
;
1761 if (m_sortInfo
.nLastHeaderID
== m_sortInfo
.nHeaderID
)
1762 m_sortInfo
.bIsAscending
= !m_sortInfo
.bIsAscending
;
1764 m_sortInfo
.bIsAscending
= TRUE
;
1765 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
1767 m_ListView
.SortItems(ListViewCompareItems
, &m_sortInfo
);
1770 case LVN_GETDISPINFOA
:
1771 case LVN_GETDISPINFOW
:
1772 TRACE("-- LVN_GETDISPINFO %p\n", this);
1773 pidl
= _PidlByItem(lpdi
->item
);
1775 if (lpdi
->item
.mask
& LVIF_TEXT
) /* text requested */
1780 if (FAILED(m_pSF2Parent
->GetDetailsOf(pidl
, lpdi
->item
.iSubItem
, &sd
)))
1782 FIXME("failed to get details\n");
1786 if (lpnmh
->code
== LVN_GETDISPINFOA
)
1788 /* shouldn't happen */
1789 NMLVDISPINFOA
*lpdiA
= (NMLVDISPINFOA
*)lpnmh
;
1790 StrRetToStrNA( lpdiA
->item
.pszText
, lpdiA
->item
.cchTextMax
, &sd
.str
, NULL
);
1791 TRACE("-- text=%s\n", lpdiA
->item
.pszText
);
1793 else /* LVN_GETDISPINFOW */
1795 StrRetToStrNW( lpdi
->item
.pszText
, lpdi
->item
.cchTextMax
, &sd
.str
, NULL
);
1796 TRACE("-- text=%s\n", debugstr_w(lpdi
->item
.pszText
));
1804 if(lpdi
->item
.mask
& LVIF_IMAGE
) /* image requested */
1806 lpdi
->item
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
1808 if(lpdi
->item
.mask
& LVIF_STATE
)
1810 ULONG attributes
= SFGAO_HIDDEN
;
1811 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(1, &pidl
, &attributes
)))
1813 if (attributes
& SFGAO_HIDDEN
)
1815 lpdi
->item
.state
|= LVIS_CUT
;
1819 lpdi
->item
.mask
|= LVIF_DI_SETITEM
;
1822 case LVN_ITEMCHANGED
:
1823 TRACE("-- LVN_ITEMCHANGED %p\n", this);
1824 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1828 case LVN_BEGINRDRAG
:
1829 TRACE("-- LVN_BEGINDRAG\n");
1831 if (GetSelections())
1833 CComPtr
<IDataObject
> pda
;
1834 DWORD dwAttributes
= SFGAO_CANLINK
;
1835 DWORD dwEffect
= DROPEFFECT_COPY
| DROPEFFECT_MOVE
;
1837 if (SUCCEEDED(m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, IID_NULL_PPV_ARG(IDataObject
, &pda
))))
1839 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(m_cidl
, m_apidl
, &dwAttributes
)))
1841 if (dwAttributes
& SFGAO_CANLINK
)
1843 dwEffect
|= DROPEFFECT_LINK
;
1847 CComPtr
<IAsyncOperation
> piaso
;
1848 if (SUCCEEDED(pda
->QueryInterface(IID_PPV_ARG(IAsyncOperation
, &piaso
))))
1850 piaso
->SetAsyncMode(TRUE
);
1854 DoDragDrop(pda
, this, dwEffect
, &dwEffect2
);
1859 case LVN_BEGINLABELEDITW
:
1861 DWORD dwAttr
= SFGAO_CANRENAME
;
1862 pidl
= _PidlByItem(lpdi
->item
);
1864 TRACE("-- LVN_BEGINLABELEDITW %p\n", this);
1866 m_pSFParent
->GetAttributesOf(1, &pidl
, &dwAttr
);
1867 if (SFGAO_CANRENAME
& dwAttr
)
1875 case LVN_ENDLABELEDITW
:
1877 TRACE("-- LVN_ENDLABELEDITW %p\n", this);
1879 m_isEditing
= FALSE
;
1881 if (lpdi
->item
.pszText
)
1886 pidl
= _PidlByItem(lpdi
->item
);
1887 PITEMID_CHILD pidlNew
;
1888 hr
= m_pSFParent
->SetNameOf(0, pidl
, lpdi
->item
.pszText
, SHGDN_INFOLDER
, &pidlNew
);
1890 if (SUCCEEDED(hr
) && pidlNew
)
1892 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
1893 lvItem
.iItem
= lpdi
->item
.iItem
;
1894 lvItem
.lParam
= reinterpret_cast<LPARAM
>(pidlNew
);
1895 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
1896 m_ListView
.SetItem(&lvItem
);
1897 m_ListView
.Update(lpdi
->item
.iItem
);
1906 TRACE("-- %p WM_COMMAND %x unhandled\n", this, lpnmh
->code
);
1914 * This is just a quick hack to make the desktop work correctly.
1915 * ITranslateShellChangeNotify's IsChildID is undocumented, but most likely the way that
1916 * a folder should know if it should update upon a change notification.
1917 * It is exported by merged folders at a minimum.
1919 static BOOL
ILIsParentOrSpecialParent(PCIDLIST_ABSOLUTE pidl1
, PCIDLIST_ABSOLUTE pidl2
)
1921 if (!pidl1
|| !pidl2
)
1923 if (ILIsParent(pidl1
, pidl2
, TRUE
))
1926 if (_ILIsDesktop(pidl1
))
1928 PIDLIST_ABSOLUTE deskpidl
;
1929 SHGetFolderLocation(NULL
, CSIDL_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
1930 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
1936 SHGetFolderLocation(NULL
, CSIDL_COMMON_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
1937 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
1947 /**********************************************************
1948 * ShellView_OnChange()
1950 LRESULT
CDefView::OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1952 PCIDLIST_ABSOLUTE
*Pidls
= reinterpret_cast<PCIDLIST_ABSOLUTE
*>(wParam
);
1953 BOOL bParent0
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[0]);
1954 BOOL bParent1
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[1]);
1956 TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls
[0], Pidls
[1], lParam
);
1964 if (LV_FindItemByPidl(ILFindLastID(Pidls
[0])) == -1)
1966 LV_AddItem(ILFindLastID(Pidls
[0]));
1970 LV_ProdItem(ILFindLastID(Pidls
[0]));
1978 LV_DeleteItem(ILFindLastID(Pidls
[0]));
1981 case SHCNE_RENAMEFOLDER
:
1982 case SHCNE_RENAMEITEM
:
1983 if (bParent0
&& bParent1
)
1984 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[1]));
1986 LV_DeleteItem(ILFindLastID(Pidls
[0]));
1988 LV_AddItem(ILFindLastID(Pidls
[1]));
1991 case SHCNE_UPDATEITEM
:
1993 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[0]));
1996 case SHCNE_UPDATEDIR
:
2003 /**********************************************************
2004 * CDefView::OnCustomItem
2006 LRESULT
CDefView::OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
2011 ERR("no menu!!!\n");
2016 HRESULT hres
= SHForwardContextMenuMsg(m_pCM
, uMsg
, wParam
, lParam
, &result
, TRUE
);
2017 if (SUCCEEDED(hres
))
2023 LRESULT
CDefView::OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
2025 /* Wallpaper setting affects drop shadows effect */
2026 if (wParam
== SPI_SETDESKWALLPAPER
|| wParam
== 0)
2032 /**********************************************************
2033 * CDefView::OnInitMenuPopup
2035 LRESULT
CDefView::OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
2037 MENUITEMINFOW mii
= { 0 };
2038 HMENU hSubmenu
= (HMENU
) wParam
;
2040 TRACE("OnInitMenuPopup lParam=%d\n", lParam
);
2042 mii
.cbSize
= sizeof(mii
);
2043 mii
.fMask
= MIIM_ID
| MIIM_SUBMENU
;
2045 if (!GetMenuItemInfoW(this->m_hMenu
, lParam
, TRUE
, &mii
))
2047 TRACE("OnInitMenuPopup GetMenuItemInfoW failed!\n");
2051 UINT menuItemId
= mii
.wID
;
2053 if (mii
.hSubMenu
!= hSubmenu
)
2055 TRACE("OnInitMenuPopup submenu does not match!!!!\n");
2059 TRACE("OnInitMenuPopup id=%d\n", menuItemId
);
2063 case FCIDM_MENU_FILE
:
2064 PrepareShowFileMenu(hSubmenu
);
2066 case FCIDM_MENU_EDIT
:
2067 //PrepareShowEditMenu(hSubmenu);
2069 case FCIDM_MENU_VIEW
:
2070 PrepareShowViewMenu(hSubmenu
);
2077 /**********************************************************
2080 * The INTERFACE of the IShellView object
2083 **********************************************************
2086 /**********************************************************
2087 * ShellView_GetWindow
2089 HRESULT WINAPI
CDefView::GetWindow(HWND
*phWnd
)
2091 TRACE("(%p)\n", this);
2098 HRESULT WINAPI
CDefView::ContextSensitiveHelp(BOOL fEnterMode
)
2100 FIXME("(%p) stub\n", this);
2105 /**********************************************************
2106 * IShellView_TranslateAccelerator
2109 * use the accel functions
2111 HRESULT WINAPI
CDefView::TranslateAccelerator(LPMSG lpmsg
)
2116 if (lpmsg
->message
>= WM_KEYFIRST
&& lpmsg
->message
<= WM_KEYLAST
)
2118 if (::TranslateAcceleratorW(m_hWnd
, m_hAccel
, lpmsg
) != 0)
2121 TRACE("-- key=0x04%lx\n", lpmsg
->wParam
) ;
2124 return m_pShellBrowser
->TranslateAcceleratorSB(lpmsg
, 0);
2127 HRESULT WINAPI
CDefView::EnableModeless(BOOL fEnable
)
2129 FIXME("(%p) stub\n", this);
2134 HRESULT WINAPI
CDefView::UIActivate(UINT uState
)
2137 CHAR szName[MAX_PATH];
2140 int nPartArray
[1] = { -1};
2142 TRACE("(%p)->(state=%x) stub\n", this, uState
);
2144 /*don't do anything if the state isn't really changing*/
2145 if (m_uState
== uState
)
2150 /*OnActivate handles the menu merging and internal state*/
2153 /*only do This if we are active*/
2154 if (uState
!= SVUIA_DEACTIVATE
)
2158 GetFolderPath is not a method of IShellFolder
2159 IShellFolder_GetFolderPath( m_pSFParent, szName, sizeof(szName) );
2161 /* set the number of parts */
2162 m_pShellBrowser
->SendControlMsg(FCW_STATUS
, SB_SETPARTS
, 1, (LPARAM
)nPartArray
, &lResult
);
2164 /* set the text for the parts */
2166 m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXTA, 0, (LPARAM)szName, &lResult);
2173 HRESULT WINAPI
CDefView::Refresh()
2175 TRACE("(%p)\n", this);
2177 m_ListView
.DeleteAllItems();
2183 HRESULT WINAPI
CDefView::CreateViewWindow(IShellView
*lpPrevView
, LPCFOLDERSETTINGS lpfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
)
2185 OLEMENUGROUPWIDTHS omw
= { { 0, 0, 0, 0, 0, 0 } };
2189 TRACE("(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n", this, lpPrevView
, lpfs
, psb
, prcView
, phWnd
);
2192 TRACE("-- vmode=%x flags=%x\n", lpfs
->ViewMode
, lpfs
->fFlags
);
2193 if (prcView
!= NULL
)
2194 TRACE("-- left=%i top=%i right=%i bottom=%i\n", prcView
->left
, prcView
->top
, prcView
->right
, prcView
->bottom
);
2196 /* Validate the Shell Browser */
2197 if (psb
== NULL
|| m_hWnd
)
2198 return E_UNEXPECTED
;
2200 /*set up the member variables*/
2201 m_pShellBrowser
= psb
;
2202 m_FolderSettings
= *lpfs
;
2204 /*get our parent window*/
2205 m_pShellBrowser
->GetWindow(&m_hWndParent
);
2207 /* try to get the ICommDlgBrowserInterface, adds a reference !!! */
2208 m_pCommDlgBrowser
= NULL
;
2209 if (SUCCEEDED(m_pShellBrowser
->QueryInterface(IID_PPV_ARG(ICommDlgBrowser
, &m_pCommDlgBrowser
))))
2211 TRACE("-- CommDlgBrowser\n");
2214 Create(m_hWndParent
, prcView
, NULL
, WS_CHILD
| WS_TABSTOP
, 0, 0U);
2225 SetWindowPos(HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_SHOWWINDOW
);
2230 m_hMenu
= CreateMenu();
2231 m_pShellBrowser
->InsertMenusSB(m_hMenu
, &omw
);
2232 TRACE("-- after fnInsertMenusSB\n");
2240 HRESULT WINAPI
CDefView::DestroyViewWindow()
2242 TRACE("(%p)\n", this);
2244 /*Make absolutely sure all our UI is cleaned up.*/
2245 UIActivate(SVUIA_DEACTIVATE
);
2249 // "Accelerator tables loaded from resources are freed automatically when the application terminates." -- MSDN
2255 DestroyMenu(m_hView
);
2261 DestroyMenu(m_hMenu
);
2267 m_ListView
.DestroyWindow();
2275 m_pShellBrowser
.Release();
2276 m_pCommDlgBrowser
.Release();
2281 HRESULT WINAPI
CDefView::GetCurrentInfo(LPFOLDERSETTINGS lpfs
)
2283 TRACE("(%p)->(%p) vmode=%x flags=%x\n", this, lpfs
,
2284 m_FolderSettings
.ViewMode
, m_FolderSettings
.fFlags
);
2287 return E_INVALIDARG
;
2289 *lpfs
= m_FolderSettings
;
2293 HRESULT WINAPI
CDefView::AddPropertySheetPages(DWORD dwReserved
, LPFNADDPROPSHEETPAGE lpfn
, LPARAM lparam
)
2295 FIXME("(%p) stub\n", this);
2300 HRESULT WINAPI
CDefView::SaveViewState()
2302 FIXME("(%p) stub\n", this);
2307 HRESULT WINAPI
CDefView::SelectItem(PCUITEMID_CHILD pidl
, UINT uFlags
)
2311 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n", this, pidl
, uFlags
);
2313 i
= LV_FindItemByPidl(pidl
);
2317 if(uFlags
& SVSI_ENSUREVISIBLE
)
2318 m_ListView
.EnsureVisible(i
, FALSE
);
2320 LVITEMW lvItem
= {0};
2321 lvItem
.mask
= LVIF_STATE
;
2322 lvItem
.stateMask
= LVIS_SELECTED
| LVIS_FOCUSED
;
2324 while (m_ListView
.GetItem(&lvItem
))
2326 if (lvItem
.iItem
== i
)
2328 if (uFlags
& SVSI_SELECT
)
2329 lvItem
.state
|= LVIS_SELECTED
;
2331 lvItem
.state
&= ~LVIS_SELECTED
;
2333 if (uFlags
& SVSI_FOCUSED
)
2334 lvItem
.state
&= ~LVIS_FOCUSED
;
2338 if (uFlags
& SVSI_DESELECTOTHERS
)
2339 lvItem
.state
&= ~LVIS_SELECTED
;
2342 m_ListView
.SetItem(&lvItem
);
2346 if(uFlags
& SVSI_EDIT
)
2347 m_ListView
.EditLabel(i
);
2352 HRESULT WINAPI
CDefView::GetItemObject(UINT uItem
, REFIID riid
, LPVOID
*ppvOut
)
2354 HRESULT hr
= E_NOINTERFACE
;
2356 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n", this, uItem
, debugstr_guid(&riid
), ppvOut
);
2362 case SVGIO_BACKGROUND
:
2363 if (IsEqualIID(riid
, IID_IContextMenu
))
2365 //*ppvOut = ISvBgCm_Constructor(m_pSFParent, FALSE);
2370 hr
= CDefFolderMenu_Create2(NULL
, NULL
, 0, NULL
, m_pSFParent
, NULL
, 0, NULL
, &pcm
);
2377 case SVGIO_SELECTION
:
2379 hr
= m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, riid
, 0, ppvOut
);
2383 TRACE("-- (%p)->(interface=%p)\n", this, *ppvOut
);
2388 HRESULT STDMETHODCALLTYPE
CDefView::GetCurrentViewMode(UINT
*pViewMode
)
2390 TRACE("(%p)->(%p), stub\n", this, pViewMode
);
2393 return E_INVALIDARG
;
2395 *pViewMode
= m_FolderSettings
.ViewMode
;
2399 HRESULT STDMETHODCALLTYPE
CDefView::SetCurrentViewMode(UINT ViewMode
)
2402 TRACE("(%p)->(%u), stub\n", this, ViewMode
);
2404 /* It's not redundant to check FVM_AUTO because it's a (UINT)-1 */
2405 if (((INT
)ViewMode
< FVM_FIRST
|| (INT
)ViewMode
> FVM_LAST
) && ((INT
)ViewMode
!= FVM_AUTO
))
2406 return E_INVALIDARG
;
2408 /* Windows before Vista uses LVM_SETVIEW and possibly
2409 LVM_SETEXTENDEDLISTVIEWSTYLE to set the style of the listview,
2410 while later versions seem to accomplish this through other
2418 dwStyle
= LVS_REPORT
;
2421 dwStyle
= LVS_SMALLICON
;
2428 FIXME("ViewMode %d not implemented\n", ViewMode
);
2434 SetStyle(dwStyle
, LVS_TYPEMASK
);
2436 /* This will not necessarily be the actual mode set above.
2437 This mimics the behavior of Windows XP. */
2438 m_FolderSettings
.ViewMode
= ViewMode
;
2443 HRESULT STDMETHODCALLTYPE
CDefView::GetFolder(REFIID riid
, void **ppv
)
2445 if (m_pSFParent
== NULL
)
2448 return m_pSFParent
->QueryInterface(riid
, ppv
);
2451 HRESULT STDMETHODCALLTYPE
CDefView::Item(int iItemIndex
, PITEMID_CHILD
*ppidl
)
2453 PCUITEMID_CHILD pidl
= _PidlByItem(iItemIndex
);
2456 *ppidl
= ILClone(pidl
);
2461 return E_INVALIDARG
;
2464 HRESULT STDMETHODCALLTYPE
CDefView::ItemCount(UINT uFlags
, int *pcItems
)
2466 TRACE("(%p)->(%u %p)\n", this, uFlags
, pcItems
);
2468 if (uFlags
!= SVGIO_ALLVIEW
)
2469 FIXME("some flags unsupported, %x\n", uFlags
& ~SVGIO_ALLVIEW
);
2471 *pcItems
= m_ListView
.GetItemCount();
2476 HRESULT STDMETHODCALLTYPE
CDefView::Items(UINT uFlags
, REFIID riid
, void **ppv
)
2481 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectionMarkedItem(int *piItem
)
2483 TRACE("(%p)->(%p)\n", this, piItem
);
2485 *piItem
= m_ListView
.GetSelectionMark();
2490 HRESULT STDMETHODCALLTYPE
CDefView::GetFocusedItem(int *piItem
)
2492 TRACE("(%p)->(%p)\n", this, piItem
);
2494 *piItem
= m_ListView
.GetNextItem(-1, LVNI_FOCUSED
);
2499 HRESULT STDMETHODCALLTYPE
CDefView::GetItemPosition(PCUITEMID_CHILD pidl
, POINT
*ppt
)
2504 HRESULT STDMETHODCALLTYPE
CDefView::GetSpacing(POINT
*ppt
)
2506 TRACE("(%p)->(%p)\n", this, ppt
);
2514 m_ListView
.GetItemSpacing(spacing
);
2516 ppt
->x
= spacing
.cx
;
2517 ppt
->y
= spacing
.cy
;
2523 HRESULT STDMETHODCALLTYPE
CDefView::GetDefaultSpacing(POINT
*ppt
)
2528 HRESULT STDMETHODCALLTYPE
CDefView::GetAutoArrange()
2533 HRESULT STDMETHODCALLTYPE
CDefView::SelectItem(int iItem
, DWORD dwFlags
)
2537 TRACE("(%p)->(%d, %x)\n", this, iItem
, dwFlags
);
2540 lvItem
.stateMask
= LVIS_SELECTED
;
2542 if (dwFlags
& SVSI_ENSUREVISIBLE
)
2543 m_ListView
.EnsureVisible(iItem
, 0);
2546 if (dwFlags
& SVSI_DESELECTOTHERS
)
2547 m_ListView
.SetItemState(-1, 0, LVIS_SELECTED
);
2550 if (dwFlags
& SVSI_SELECT
)
2551 lvItem
.state
|= LVIS_SELECTED
;
2553 if (dwFlags
& SVSI_FOCUSED
)
2554 lvItem
.stateMask
|= LVIS_FOCUSED
;
2556 m_ListView
.SetItemState(iItem
, lvItem
.state
, lvItem
.stateMask
);
2558 if (dwFlags
& SVSI_EDIT
)
2559 m_ListView
.EditLabel(iItem
);
2564 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItems(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD dwFlags
)
2569 /**********************************************************
2570 * IShellFolderView implementation
2572 HRESULT STDMETHODCALLTYPE
CDefView::Rearrange(LPARAM sort
)
2574 FIXME("(%p)->(%ld) stub\n", this, sort
);
2578 HRESULT STDMETHODCALLTYPE
CDefView::GetArrangeParam(LPARAM
*sort
)
2580 FIXME("(%p)->(%p) stub\n", this, sort
);
2584 HRESULT STDMETHODCALLTYPE
CDefView::ArrangeGrid()
2586 FIXME("(%p) stub\n", this);
2590 HRESULT STDMETHODCALLTYPE
CDefView::AutoArrange()
2592 FIXME("(%p) stub\n", this);
2596 HRESULT STDMETHODCALLTYPE
CDefView::AddObject(PITEMID_CHILD pidl
, UINT
*item
)
2598 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2602 HRESULT STDMETHODCALLTYPE
CDefView::GetObject(PITEMID_CHILD
*pidl
, UINT item
)
2604 TRACE("(%p)->(%p %d)\n", this, pidl
, item
);
2605 return Item(item
, pidl
);
2608 HRESULT STDMETHODCALLTYPE
CDefView::RemoveObject(PITEMID_CHILD pidl
, UINT
*item
)
2611 TRACE("(%p)->(%p %p)\n", this, pidl
, item
);
2615 *item
= LV_FindItemByPidl(ILFindLastID(pidl
));
2616 m_ListView
.DeleteItem(*item
);
2621 m_ListView
.DeleteAllItems();
2627 HRESULT STDMETHODCALLTYPE
CDefView::GetObjectCount(UINT
*count
)
2629 TRACE("(%p)->(%p)\n", this, count
);
2630 *count
= m_ListView
.GetItemCount();
2634 HRESULT STDMETHODCALLTYPE
CDefView::SetObjectCount(UINT count
, UINT flags
)
2636 FIXME("(%p)->(%d %x) stub\n", this, count
, flags
);
2640 HRESULT STDMETHODCALLTYPE
CDefView::UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
)
2642 FIXME("(%p)->(%p %p %p) stub\n", this, pidl_old
, pidl_new
, item
);
2646 HRESULT STDMETHODCALLTYPE
CDefView::RefreshObject(PITEMID_CHILD pidl
, UINT
*item
)
2648 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2652 HRESULT STDMETHODCALLTYPE
CDefView::SetRedraw(BOOL redraw
)
2654 TRACE("(%p)->(%d)\n", this, redraw
);
2655 m_ListView
.SetRedraw(redraw
);
2659 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedCount(UINT
*count
)
2661 FIXME("(%p)->(%p) stub\n", this, count
);
2665 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
)
2667 TRACE("(%p)->(%p %p)\n", this, pidl
, items
);
2669 *items
= GetSelections();
2673 *pidl
= static_cast<PCUITEMID_CHILD
*>(LocalAlloc(0, *items
* sizeof(PCUITEMID_CHILD
)));
2676 return E_OUTOFMEMORY
;
2679 /* it's documented that caller shouldn't PIDLs, only array itself */
2680 memcpy(*pidl
, m_apidl
, *items
* sizeof(PCUITEMID_CHILD
));
2686 HRESULT STDMETHODCALLTYPE
CDefView::IsDropOnSource(IDropTarget
*drop_target
)
2688 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2692 HRESULT STDMETHODCALLTYPE
CDefView::GetDragPoint(POINT
*pt
)
2694 FIXME("(%p)->(%p) stub\n", this, pt
);
2698 HRESULT STDMETHODCALLTYPE
CDefView::GetDropPoint(POINT
*pt
)
2700 FIXME("(%p)->(%p) stub\n", this, pt
);
2704 HRESULT STDMETHODCALLTYPE
CDefView::MoveIcons(IDataObject
*obj
)
2706 TRACE("(%p)->(%p)\n", this, obj
);
2710 HRESULT STDMETHODCALLTYPE
CDefView::SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
)
2712 FIXME("(%p)->(%p %p) stub\n", this, pidl
, pt
);
2716 HRESULT STDMETHODCALLTYPE
CDefView::IsBkDropTarget(IDropTarget
*drop_target
)
2718 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2722 HRESULT STDMETHODCALLTYPE
CDefView::SetClipboard(BOOL move
)
2724 FIXME("(%p)->(%d) stub\n", this, move
);
2728 HRESULT STDMETHODCALLTYPE
CDefView::SetPoints(IDataObject
*obj
)
2730 FIXME("(%p)->(%p) stub\n", this, obj
);
2734 HRESULT STDMETHODCALLTYPE
CDefView::GetItemSpacing(ITEMSPACING
*spacing
)
2736 FIXME("(%p)->(%p) stub\n", this, spacing
);
2740 HRESULT STDMETHODCALLTYPE
CDefView::SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
)
2742 FIXME("(%p)->(%p %p) stub\n", this, new_cb
, old_cb
);
2746 HRESULT STDMETHODCALLTYPE
CDefView::Select(UINT flags
)
2748 FIXME("(%p)->(%d) stub\n", this, flags
);
2752 HRESULT STDMETHODCALLTYPE
CDefView::QuerySupport(UINT
*support
)
2754 TRACE("(%p)->(%p)\n", this, support
);
2758 HRESULT STDMETHODCALLTYPE
CDefView::SetAutomationObject(IDispatch
*disp
)
2760 FIXME("(%p)->(%p) stub\n", this, disp
);
2764 /**********************************************************
2765 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2767 HRESULT WINAPI
CDefView::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD
*prgCmds
, OLECMDTEXT
*pCmdText
)
2769 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
2770 this, pguidCmdGroup
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
2773 return E_INVALIDARG
;
2775 for (UINT i
= 0; i
< cCmds
; i
++)
2777 FIXME("\tprgCmds[%d].cmdID = %d\n", i
, prgCmds
[i
].cmdID
);
2778 prgCmds
[i
].cmdf
= 0;
2781 return OLECMDERR_E_UNKNOWNGROUP
;
2784 /**********************************************************
2785 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2787 * nCmdID is the OLECMDID_* enumeration
2789 HRESULT WINAPI
CDefView::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
2791 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2792 this, debugstr_guid(pguidCmdGroup
), nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2795 return OLECMDERR_E_UNKNOWNGROUP
;
2797 if (IsEqualCLSID(*pguidCmdGroup
, m_Category
))
2799 if (nCmdID
== FCIDM_SHVIEW_AUTOARRANGE
)
2801 if (V_VT(pvaIn
) != VT_INT_PTR
)
2802 return OLECMDERR_E_NOTSUPPORTED
;
2806 params
.cbSize
= sizeof(params
);
2807 params
.rcExclude
= *(RECT
*) V_INTREF(pvaIn
);
2809 HMENU hView
= m_hView
;
2811 hView
= CreatePopupMenu();
2812 AppendMenuW(hView
, MF_STRING
, FCIDM_SHVIEW_BIGICON
, L
"Big!");
2813 AppendMenuW(hView
, MF_STRING
, FCIDM_SHVIEW_SMALLICON
, L
"Small!");
2814 AppendMenuW(hView
, MF_STRING
, FCIDM_SHVIEW_LISTVIEW
, L
"List!");
2815 AppendMenuW(hView
, MF_STRING
, FCIDM_SHVIEW_REPORTVIEW
, L
"Report!");
2820 PrepareShowViewMenu(hView
);
2822 TrackPopupMenuEx(hView
, TPM_LEFTALIGN
| TPM_TOPALIGN
, params
.rcExclude
.left
, params
.rcExclude
.bottom
, m_hWndParent
, ¶ms
);
2825 // pvaOut is VT_I4 with value 0x403 (cmd id of the new mode maybe?)
2826 V_VT(pvaOut
) = VT_I4
;
2827 V_I4(pvaOut
) = 0x403;
2831 if (IsEqualIID(*pguidCmdGroup
, CGID_Explorer
) &&
2833 (nCmdexecopt
== 4) && pvaOut
)
2836 if (IsEqualIID(*pguidCmdGroup
, CGID_ShellDocView
) &&
2841 return OLECMDERR_E_UNKNOWNGROUP
;
2844 /**********************************************************
2845 * ISVDropTarget implementation
2848 /******************************************************************************
2849 * drag_notify_subitem [Internal]
2851 * Figure out the shellfolder object, which is currently under the mouse cursor
2852 * and notify it via the IDropTarget interface.
2855 #define SCROLLAREAWIDTH 20
2857 HRESULT
CDefView::drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2859 LVHITTESTINFO htinfo
;
2864 /* Map from global to client coordinates and query the index of the listview-item, which is
2865 * currently under the mouse cursor. */
2868 htinfo
.flags
= LVHT_ONITEM
;
2869 ::ScreenToClient(m_ListView
, &htinfo
.pt
);
2870 lResult
= m_ListView
.HitTest(&htinfo
);
2872 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2873 ::GetClientRect(m_ListView
, &clientRect
);
2874 if (htinfo
.pt
.x
== m_ptLastMousePos
.x
&& htinfo
.pt
.y
== m_ptLastMousePos
.y
&&
2875 (htinfo
.pt
.x
< SCROLLAREAWIDTH
|| htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
||
2876 htinfo
.pt
.y
< SCROLLAREAWIDTH
|| htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
))
2878 m_cScrollDelay
= (m_cScrollDelay
+ 1) % 5; /* DragOver is called every 50 ms */
2879 if (m_cScrollDelay
== 0)
2881 /* Mouse did hover another 250 ms over the scroll-area */
2882 if (htinfo
.pt
.x
< SCROLLAREAWIDTH
)
2883 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEUP
, 0);
2885 if (htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
)
2886 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEDOWN
, 0);
2888 if (htinfo
.pt
.y
< SCROLLAREAWIDTH
)
2889 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEUP
, 0);
2891 if (htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
)
2892 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEDOWN
, 0);
2897 m_cScrollDelay
= 0; /* Reset, if the cursor is not over the listview's scroll-area */
2900 m_ptLastMousePos
= htinfo
.pt
;
2902 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2903 if (m_pCurDropTarget
&& lResult
== m_iDragOverItem
)
2904 return m_pCurDropTarget
->DragOver(grfKeyState
, pt
, pdwEffect
);
2906 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2907 if (m_pCurDropTarget
)
2909 m_pCurDropTarget
->DragLeave();
2910 m_pCurDropTarget
.Release();
2913 m_iDragOverItem
= lResult
;
2916 /* We are not above one of the listview's subitems. Bind to the parent folder's
2917 * DropTarget interface. */
2918 hr
= m_pSFParent
->CreateViewObject(NULL
, IID_PPV_ARG(IDropTarget
,&m_pCurDropTarget
));
2922 /* Query the relative PIDL of the shellfolder object represented by the currently
2923 * dragged over listview-item ... */
2924 PCUITEMID_CHILD pidl
= _PidlByItem(lResult
);
2926 /* ... and bind m_pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2927 hr
= m_pSFParent
->GetUIObjectOf(m_ListView
, 1, &pidl
, IID_NULL_PPV_ARG(IDropTarget
, &m_pCurDropTarget
));
2930 /* If anything failed, m_pCurDropTarget should be NULL now, which ought to be a save state. */
2934 /* Notify the item just entered via DragEnter. */
2935 return m_pCurDropTarget
->DragEnter(m_pCurDataObject
, grfKeyState
, pt
, pdwEffect
);
2938 HRESULT WINAPI
CDefView::DragEnter(IDataObject
*pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2940 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2941 m_pCurDataObject
= pDataObject
;
2942 pDataObject
->AddRef();
2944 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2947 HRESULT WINAPI
CDefView::DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2949 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2952 HRESULT WINAPI
CDefView::DragLeave()
2954 if (m_pCurDropTarget
)
2956 m_pCurDropTarget
->DragLeave();
2957 m_pCurDropTarget
.Release();
2960 if (m_pCurDataObject
!= NULL
)
2962 m_pCurDataObject
.Release();
2965 m_iDragOverItem
= 0;
2970 HRESULT WINAPI
CDefView::Drop(IDataObject
* pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2972 if (m_pCurDropTarget
)
2974 m_pCurDropTarget
->Drop(pDataObject
, grfKeyState
, pt
, pdwEffect
);
2975 m_pCurDropTarget
.Release();
2978 m_pCurDataObject
.Release();
2979 m_iDragOverItem
= 0;
2983 /**********************************************************
2984 * ISVDropSource implementation
2987 HRESULT WINAPI
CDefView::QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
)
2989 TRACE("(%p)\n", this);
2992 return DRAGDROP_S_CANCEL
;
2993 else if (!(grfKeyState
& MK_LBUTTON
) && !(grfKeyState
& MK_RBUTTON
))
2994 return DRAGDROP_S_DROP
;
2999 HRESULT WINAPI
CDefView::GiveFeedback(DWORD dwEffect
)
3001 TRACE("(%p)\n", this);
3003 return DRAGDROP_S_USEDEFAULTCURSORS
;
3006 /**********************************************************
3007 * ISVViewObject implementation
3010 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
)
3012 FIXME("Stub: this=%p\n", this);
3017 HRESULT WINAPI
CDefView::GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
, HDC hicTargetDevice
, LOGPALETTE
**ppColorSet
)
3019 FIXME("Stub: this=%p\n", this);
3024 HRESULT WINAPI
CDefView::Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
)
3026 FIXME("Stub: this=%p\n", this);
3031 HRESULT WINAPI
CDefView::Unfreeze(DWORD dwFreeze
)
3033 FIXME("Stub: this=%p\n", this);
3038 HRESULT WINAPI
CDefView::SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
)
3040 FIXME("partial stub: %p %08x %08x %p\n", this, aspects
, advf
, pAdvSink
);
3042 /* FIXME: we set the AdviseSink, but never use it to send any advice */
3043 m_pAdvSink
= pAdvSink
;
3044 m_dwAspects
= aspects
;
3050 HRESULT WINAPI
CDefView::GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
)
3052 TRACE("this=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n", this, pAspects
, pAdvf
, ppAdvSink
);
3056 *ppAdvSink
= m_pAdvSink
;
3057 m_pAdvSink
.p
->AddRef();
3061 *pAspects
= m_dwAspects
;
3069 HRESULT STDMETHODCALLTYPE
CDefView::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
3071 if (IsEqualIID(guidService
, SID_IShellBrowser
))
3072 return m_pShellBrowser
->QueryInterface(riid
, ppvObject
);
3073 else if(IsEqualIID(guidService
, SID_IFolderView
))
3074 return QueryInterface(riid
, ppvObject
);
3076 return E_NOINTERFACE
;
3079 HRESULT
CDefView::_MergeToolbar()
3081 CComPtr
<IExplorerToolbar
> ptb
; // [sp+8h] [bp-4h]@1
3085 hr
= IUnknown_QueryService(m_pShellBrowser
, IID_IExplorerToolbar
, IID_PPV_ARG(IExplorerToolbar
, &ptb
));
3089 m_Category
= CGID_DefViewFrame
;
3091 hr
= ptb
->SetCommandTarget(static_cast<IOleCommandTarget
*>(this), &m_Category
, 0);
3099 hr
= ptb
->AddButtons(&m_Category
, buttonsCount
, buttons
);
3106 /**********************************************************
3107 * IShellView_Constructor
3109 HRESULT WINAPI
IShellView_Constructor(IShellFolder
*pFolder
, IShellView
**newView
)
3111 return ShellObjectCreatorInit
<CDefView
>(pFolder
, IID_IShellView
, newView
);
3114 HRESULT WINAPI
CDefView_Constructor(IShellFolder
*pFolder
, REFIID riid
, LPVOID
* ppvOut
)
3116 return ShellObjectCreatorInit
<CDefView
>(pFolder
, riid
, ppvOut
);