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
;
118 HRESULT
_MergeToolbar();
123 HRESULT WINAPI
Initialize(IShellFolder
*shellFolder
);
124 HRESULT
IncludeObject(PCUITEMID_CHILD pidl
);
125 HRESULT
OnDefaultCommand();
126 HRESULT
OnStateChange(UINT uFlags
);
128 void SetStyle(DWORD dwAdd
, DWORD dwRemove
);
130 void UpdateListColors();
132 static INT CALLBACK
CompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
);
133 static INT CALLBACK
ListViewCompareItems(LPARAM lParam1
, LPARAM lParam2
, LPARAM lpData
);
135 PCUITEMID_CHILD
_PidlByItem(int i
);
136 PCUITEMID_CHILD
_PidlByItem(LVITEM
& lvItem
);
137 int LV_FindItemByPidl(PCUITEMID_CHILD pidl
);
138 BOOLEAN
LV_AddItem(PCUITEMID_CHILD pidl
);
139 BOOLEAN
LV_DeleteItem(PCUITEMID_CHILD pidl
);
140 BOOLEAN
LV_RenameItem(PCUITEMID_CHILD pidlOld
, PCUITEMID_CHILD pidlNew
);
141 static INT CALLBACK
fill_list(LPVOID ptr
, LPVOID arg
);
143 HMENU
BuildFileMenu();
144 void PrepareShowFileMenu(HMENU hSubMenu
);
145 void PrepareShowViewMenu(HMENU hSubMenu
);
146 UINT
GetSelections();
147 HRESULT
OpenSelectedItems();
149 void DoActivate(UINT uState
);
150 HRESULT
drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
151 LRESULT
OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
);
153 // *** IOleWindow methods ***
154 virtual HRESULT STDMETHODCALLTYPE
GetWindow(HWND
*lphwnd
);
155 virtual HRESULT STDMETHODCALLTYPE
ContextSensitiveHelp(BOOL fEnterMode
);
157 // *** IShellView methods ***
158 virtual HRESULT STDMETHODCALLTYPE
TranslateAccelerator(MSG
*pmsg
);
159 virtual HRESULT STDMETHODCALLTYPE
EnableModeless(BOOL fEnable
);
160 virtual HRESULT STDMETHODCALLTYPE
UIActivate(UINT uState
);
161 virtual HRESULT STDMETHODCALLTYPE
Refresh();
162 virtual HRESULT STDMETHODCALLTYPE
CreateViewWindow(IShellView
*psvPrevious
, LPCFOLDERSETTINGS pfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
);
163 virtual HRESULT STDMETHODCALLTYPE
DestroyViewWindow();
164 virtual HRESULT STDMETHODCALLTYPE
GetCurrentInfo(LPFOLDERSETTINGS pfs
);
165 virtual HRESULT STDMETHODCALLTYPE
AddPropertySheetPages(DWORD dwReserved
, LPFNSVADDPROPSHEETPAGE pfn
, LPARAM lparam
);
166 virtual HRESULT STDMETHODCALLTYPE
SaveViewState();
167 virtual HRESULT STDMETHODCALLTYPE
SelectItem(PCUITEMID_CHILD pidlItem
, SVSIF uFlags
);
168 virtual HRESULT STDMETHODCALLTYPE
GetItemObject(UINT uItem
, REFIID riid
, void **ppv
);
170 // *** IFolderView methods ***
171 virtual HRESULT STDMETHODCALLTYPE
GetCurrentViewMode(UINT
*pViewMode
);
172 virtual HRESULT STDMETHODCALLTYPE
SetCurrentViewMode(UINT ViewMode
);
173 virtual HRESULT STDMETHODCALLTYPE
GetFolder(REFIID riid
, void **ppv
);
174 virtual HRESULT STDMETHODCALLTYPE
Item(int iItemIndex
, PITEMID_CHILD
*ppidl
);
175 virtual HRESULT STDMETHODCALLTYPE
ItemCount(UINT uFlags
, int *pcItems
);
176 virtual HRESULT STDMETHODCALLTYPE
Items(UINT uFlags
, REFIID riid
, void **ppv
);
177 virtual HRESULT STDMETHODCALLTYPE
GetSelectionMarkedItem(int *piItem
);
178 virtual HRESULT STDMETHODCALLTYPE
GetFocusedItem(int *piItem
);
179 virtual HRESULT STDMETHODCALLTYPE
GetItemPosition(PCUITEMID_CHILD pidl
, POINT
*ppt
);
180 virtual HRESULT STDMETHODCALLTYPE
GetSpacing(POINT
*ppt
);
181 virtual HRESULT STDMETHODCALLTYPE
GetDefaultSpacing(POINT
*ppt
);
182 virtual HRESULT STDMETHODCALLTYPE
GetAutoArrange();
183 virtual HRESULT STDMETHODCALLTYPE
SelectItem(int iItem
, DWORD dwFlags
);
184 virtual HRESULT STDMETHODCALLTYPE
SelectAndPositionItems(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD dwFlags
);
186 // *** IShellFolderView methods ***
187 virtual HRESULT STDMETHODCALLTYPE
Rearrange(LPARAM sort
);
188 virtual HRESULT STDMETHODCALLTYPE
GetArrangeParam(LPARAM
*sort
);
189 virtual HRESULT STDMETHODCALLTYPE
ArrangeGrid();
190 virtual HRESULT STDMETHODCALLTYPE
AutoArrange();
191 virtual HRESULT STDMETHODCALLTYPE
AddObject(PITEMID_CHILD pidl
, UINT
*item
);
192 virtual HRESULT STDMETHODCALLTYPE
GetObject(PITEMID_CHILD
*pidl
, UINT item
);
193 virtual HRESULT STDMETHODCALLTYPE
RemoveObject(PITEMID_CHILD pidl
, UINT
*item
);
194 virtual HRESULT STDMETHODCALLTYPE
GetObjectCount(UINT
*count
);
195 virtual HRESULT STDMETHODCALLTYPE
SetObjectCount(UINT count
, UINT flags
);
196 virtual HRESULT STDMETHODCALLTYPE
UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
);
197 virtual HRESULT STDMETHODCALLTYPE
RefreshObject(PITEMID_CHILD pidl
, UINT
*item
);
198 virtual HRESULT STDMETHODCALLTYPE
SetRedraw(BOOL redraw
);
199 virtual HRESULT STDMETHODCALLTYPE
GetSelectedCount(UINT
*count
);
200 virtual HRESULT STDMETHODCALLTYPE
GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
);
201 virtual HRESULT STDMETHODCALLTYPE
IsDropOnSource(IDropTarget
*drop_target
);
202 virtual HRESULT STDMETHODCALLTYPE
GetDragPoint(POINT
*pt
);
203 virtual HRESULT STDMETHODCALLTYPE
GetDropPoint(POINT
*pt
);
204 virtual HRESULT STDMETHODCALLTYPE
MoveIcons(IDataObject
*obj
);
205 virtual HRESULT STDMETHODCALLTYPE
SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
);
206 virtual HRESULT STDMETHODCALLTYPE
IsBkDropTarget(IDropTarget
*drop_target
);
207 virtual HRESULT STDMETHODCALLTYPE
SetClipboard(BOOL move
);
208 virtual HRESULT STDMETHODCALLTYPE
SetPoints(IDataObject
*obj
);
209 virtual HRESULT STDMETHODCALLTYPE
GetItemSpacing(ITEMSPACING
*spacing
);
210 virtual HRESULT STDMETHODCALLTYPE
SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
);
211 virtual HRESULT STDMETHODCALLTYPE
Select(UINT flags
);
212 virtual HRESULT STDMETHODCALLTYPE
QuerySupport(UINT
*support
);
213 virtual HRESULT STDMETHODCALLTYPE
SetAutomationObject(IDispatch
*disp
);
215 // *** IOleCommandTarget methods ***
216 virtual HRESULT STDMETHODCALLTYPE
QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
);
217 virtual HRESULT STDMETHODCALLTYPE
Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
);
219 // *** IDropTarget methods ***
220 virtual HRESULT STDMETHODCALLTYPE
DragEnter(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
221 virtual HRESULT STDMETHODCALLTYPE
DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
222 virtual HRESULT STDMETHODCALLTYPE
DragLeave();
223 virtual HRESULT STDMETHODCALLTYPE
Drop(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
225 // *** IDropSource methods ***
226 virtual HRESULT STDMETHODCALLTYPE
QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
);
227 virtual HRESULT STDMETHODCALLTYPE
GiveFeedback(DWORD dwEffect
);
229 // *** IViewObject methods ***
230 virtual HRESULT STDMETHODCALLTYPE
Draw(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
,
231 HDC hdcTargetDev
, HDC hdcDraw
, LPCRECTL lprcBounds
, LPCRECTL lprcWBounds
,
232 BOOL ( STDMETHODCALLTYPE
*pfnContinue
)(ULONG_PTR dwContinue
), ULONG_PTR dwContinue
);
233 virtual HRESULT STDMETHODCALLTYPE
GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
,
234 DVTARGETDEVICE
*ptd
, HDC hicTargetDev
, LOGPALETTE
**ppColorSet
);
235 virtual HRESULT STDMETHODCALLTYPE
Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
);
236 virtual HRESULT STDMETHODCALLTYPE
Unfreeze(DWORD dwFreeze
);
237 virtual HRESULT STDMETHODCALLTYPE
SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
);
238 virtual HRESULT STDMETHODCALLTYPE
GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
);
240 // *** IServiceProvider methods ***
241 virtual HRESULT STDMETHODCALLTYPE
QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
);
244 LRESULT
OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
245 LRESULT
OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
246 LRESULT
OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
247 LRESULT
OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
248 LRESULT
OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
249 LRESULT
OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
250 LRESULT
OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
251 LRESULT
OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
252 LRESULT
OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
253 LRESULT
OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
254 LRESULT
OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
255 LRESULT
OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
256 LRESULT
OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
257 LRESULT
OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
258 LRESULT
OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
259 LRESULT
OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
260 LRESULT
OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
261 LRESULT
OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
263 static ATL::CWndClassInfo
& GetWndClassInfo()
265 static ATL::CWndClassInfo wc
=
267 { sizeof(WNDCLASSEX
), 0, StartWindowProc
,
269 LoadCursor(NULL
, IDC_ARROW
), (HBRUSH
)(COLOR_BACKGROUND
+ 1), NULL
, SV_CLASS_NAME
, NULL
271 NULL
, NULL
, IDC_ARROW
, TRUE
, 0, _T("")
276 virtual WNDPROC
GetWindowProc()
281 static LRESULT CALLBACK
WindowProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
286 // must hold a reference during message handling
287 pThis
= reinterpret_cast<CDefView
*>(hWnd
);
289 result
= CWindowImpl
<CDefView
, CWindow
, CControlWinTraits
>::WindowProc(hWnd
, uMsg
, wParam
, lParam
);
294 BEGIN_MSG_MAP(CDefView
)
295 MESSAGE_HANDLER(WM_SIZE
, OnSize
)
296 MESSAGE_HANDLER(WM_SETFOCUS
, OnSetFocus
)
297 MESSAGE_HANDLER(WM_KILLFOCUS
, OnKillFocus
)
298 MESSAGE_HANDLER(WM_CREATE
, OnCreate
)
299 MESSAGE_HANDLER(WM_ACTIVATE
, OnActivate
)
300 MESSAGE_HANDLER(WM_NOTIFY
, OnNotify
)
301 MESSAGE_HANDLER(WM_COMMAND
, OnCommand
)
302 MESSAGE_HANDLER(SHV_CHANGE_NOTIFY
, OnChangeNotify
)
303 MESSAGE_HANDLER(WM_CONTEXTMENU
, OnContextMenu
)
304 MESSAGE_HANDLER(WM_DRAWITEM
, OnCustomItem
)
305 MESSAGE_HANDLER(WM_MEASUREITEM
, OnCustomItem
)
306 MESSAGE_HANDLER(WM_SHOWWINDOW
, OnShowWindow
)
307 MESSAGE_HANDLER(WM_GETDLGCODE
, OnGetDlgCode
)
308 MESSAGE_HANDLER(WM_DESTROY
, OnDestroy
)
309 MESSAGE_HANDLER(WM_ERASEBKGND
, OnEraseBackground
)
310 MESSAGE_HANDLER(WM_SYSCOLORCHANGE
, OnSysColorChange
)
311 MESSAGE_HANDLER(CWM_GETISHELLBROWSER
, OnGetShellBrowser
)
312 MESSAGE_HANDLER(WM_SETTINGCHANGE
, OnSettingChange
)
313 MESSAGE_HANDLER(WM_INITMENUPOPUP
, OnInitMenuPopup
)
316 BEGIN_COM_MAP(CDefView
)
317 COM_INTERFACE_ENTRY_IID(IID_IOleWindow
, IOleWindow
)
318 COM_INTERFACE_ENTRY_IID(IID_IShellView
, IShellView
)
319 COM_INTERFACE_ENTRY_IID(IID_IFolderView
, IFolderView
)
320 COM_INTERFACE_ENTRY_IID(IID_IShellFolderView
, IShellFolderView
)
321 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget
, IOleCommandTarget
)
322 COM_INTERFACE_ENTRY_IID(IID_IDropTarget
, IDropTarget
)
323 COM_INTERFACE_ENTRY_IID(IID_IDropSource
, IDropSource
)
324 COM_INTERFACE_ENTRY_IID(IID_IViewObject
, IViewObject
)
325 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider
, IServiceProvider
)
329 /* ListView Header ID's */
330 #define LISTVIEW_COLUMN_NAME 0
331 #define LISTVIEW_COLUMN_SIZE 1
332 #define LISTVIEW_COLUMN_TYPE 2
333 #define LISTVIEW_COLUMN_TIME 3
334 #define LISTVIEW_COLUMN_ATTRIB 4
337 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
338 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
339 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
341 #define ID_LISTVIEW 1
344 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
345 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
346 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
348 typedef void (CALLBACK
*PFNSHGETSETTINGSPROC
)(LPSHELLFLAGSTATE lpsfs
, DWORD dwMask
);
350 CDefView::CDefView() :
354 m_menusLoaded(FALSE
),
368 ZeroMemory(&m_FolderSettings
, sizeof(m_FolderSettings
));
369 ZeroMemory(&m_sortInfo
, sizeof(m_sortInfo
));
370 ZeroMemory(&m_ptLastMousePos
, sizeof(m_ptLastMousePos
));
371 ZeroMemory(&m_Category
, sizeof(m_Category
));
374 CDefView::~CDefView()
376 TRACE(" destroying IShellView(%p)\n", this);
386 HRESULT WINAPI
CDefView::Initialize(IShellFolder
*shellFolder
)
388 m_pSFParent
= shellFolder
;
389 shellFolder
->QueryInterface(IID_PPV_ARG(IShellFolder2
, &m_pSF2Parent
));
394 /**********************************************************
396 * ##### helperfunctions for communication with ICommDlgBrowser #####
398 HRESULT
CDefView::IncludeObject(PCUITEMID_CHILD pidl
)
402 if (m_pCommDlgBrowser
.p
!= NULL
)
404 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl
);
405 ret
= m_pCommDlgBrowser
->IncludeObject(this, pidl
);
406 TRACE("--0x%08x\n", ret
);
412 HRESULT
CDefView::OnDefaultCommand()
414 HRESULT ret
= S_FALSE
;
416 if (m_pCommDlgBrowser
.p
!= NULL
)
418 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
419 ret
= m_pCommDlgBrowser
->OnDefaultCommand(this);
420 TRACE("-- returns %08x\n", ret
);
426 HRESULT
CDefView::OnStateChange(UINT uFlags
)
428 HRESULT ret
= S_FALSE
;
430 if (m_pCommDlgBrowser
.p
!= NULL
)
432 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags
);
433 ret
= m_pCommDlgBrowser
->OnStateChange(this, uFlags
);
439 /**********************************************************
440 * set the toolbar of the filedialog buttons
442 * - activates the buttons from the shellbrowser according to
445 void CDefView::CheckToolbar()
451 if (m_pCommDlgBrowser
!= NULL
)
453 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
454 FCIDM_TB_SMALLICON
, (m_FolderSettings
.ViewMode
== FVM_LIST
) ? TRUE
: FALSE
, &result
);
455 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
456 FCIDM_TB_REPORTVIEW
, (m_FolderSettings
.ViewMode
== FVM_DETAILS
) ? TRUE
: FALSE
, &result
);
457 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
458 FCIDM_TB_SMALLICON
, TRUE
, &result
);
459 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
460 FCIDM_TB_REPORTVIEW
, TRUE
, &result
);
464 /**********************************************************
466 * ##### helperfunctions for initializing the view #####
468 /**********************************************************
469 * change the style of the listview control
471 void CDefView::SetStyle(DWORD dwAdd
, DWORD dwRemove
)
475 TRACE("(%p)\n", this);
477 tmpstyle
= ::GetWindowLongPtrW(m_ListView
, GWL_STYLE
);
478 ::SetWindowLongPtrW(m_ListView
, GWL_STYLE
, dwAdd
| (tmpstyle
& ~dwRemove
));
481 /**********************************************************
482 * ShellView_CreateList()
484 * - creates the list view window
486 BOOL
CDefView::CreateList()
487 { DWORD dwStyle
, dwExStyle
;
491 dwStyle
= WS_TABSTOP
| WS_VISIBLE
| WS_CHILDWINDOW
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
|
492 LVS_SHAREIMAGELISTS
| LVS_EDITLABELS
| LVS_AUTOARRANGE
;
493 dwExStyle
= WS_EX_CLIENTEDGE
;
495 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
496 dwStyle
|= LVS_ALIGNLEFT
;
498 dwStyle
|= LVS_ALIGNTOP
| LVS_SHOWSELALWAYS
;
500 switch (m_FolderSettings
.ViewMode
)
507 dwStyle
|= LVS_REPORT
;
511 dwStyle
|= LVS_SMALLICON
;
523 if (m_FolderSettings
.fFlags
& FWF_AUTOARRANGE
)
524 dwStyle
|= LVS_AUTOARRANGE
;
526 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
527 m_FolderSettings
.fFlags
|= FWF_NOCLIENTEDGE
| FWF_NOSCROLL
;
529 if (m_FolderSettings
.fFlags
& FWF_SINGLESEL
)
530 dwStyle
|= LVS_SINGLESEL
;
532 if (m_FolderSettings
.fFlags
& FWF_NOCLIENTEDGE
)
533 dwExStyle
&= ~WS_EX_CLIENTEDGE
;
535 RECT rcListView
= {0,0,0,0};
536 m_ListView
.Create(m_hWnd
, rcListView
, NULL
,dwStyle
, dwExStyle
, ID_LISTVIEW
);
541 m_sortInfo
.bIsAscending
= TRUE
;
542 m_sortInfo
.nHeaderID
= -1;
543 m_sortInfo
.nLastHeaderID
= -1;
547 /* UpdateShellSettings(); */
551 void CDefView::UpdateListColors()
553 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
555 /* Check if drop shadows option is enabled */
556 BOOL bDropShadow
= FALSE
;
557 DWORD cbDropShadow
= sizeof(bDropShadow
);
558 WCHAR wszBuf
[16] = L
"";
560 RegGetValueW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
561 L
"ListviewShadow", RRF_RT_DWORD
, NULL
, &bDropShadow
, &cbDropShadow
);
562 if (bDropShadow
&& SystemParametersInfoW(SPI_GETDESKWALLPAPER
, _countof(wszBuf
), wszBuf
, 0) && wszBuf
[0])
564 m_ListView
.SetTextBkColor(CLR_NONE
);
565 m_ListView
.SetBkColor(CLR_NONE
);
566 m_ListView
.SetTextColor(RGB(255, 255, 255));
567 m_ListView
.SetExtendedListViewStyle(LVS_EX_TRANSPARENTSHADOWTEXT
, LVS_EX_TRANSPARENTSHADOWTEXT
);
571 COLORREF crDesktop
= GetSysColor(COLOR_DESKTOP
);
572 m_ListView
.SetTextBkColor(crDesktop
);
573 m_ListView
.SetBkColor(crDesktop
);
574 if (GetRValue(crDesktop
) + GetGValue(crDesktop
) + GetBValue(crDesktop
) > 128 * 3)
575 m_ListView
.SetTextColor(RGB(0, 0, 0));
577 m_ListView
.SetTextColor(RGB(255, 255, 255));
578 m_ListView
.SetExtendedListViewStyle(LVS_EX_TRANSPARENTSHADOWTEXT
);
583 /**********************************************************
584 * ShellView_InitList()
586 * - adds all needed columns to the shellview
588 BOOL
CDefView::InitList()
592 HIMAGELIST big_icons
, small_icons
;
596 m_ListView
.DeleteAllItems();
600 for (int i
= 0; 1; i
++)
602 if (FAILED(m_pSF2Parent
->GetDetailsOf(NULL
, i
, &sd
)))
604 StrRetToStrNW( szTemp
, 50, &sd
.str
, NULL
);
605 m_ListView
.InsertColumn(i
, szTemp
, sd
.fmt
, sd
.cxChar
* 8);
614 Shell_GetImageLists(&big_icons
, &small_icons
);
615 m_ListView
.SetImageList(big_icons
, LVSIL_NORMAL
);
616 m_ListView
.SetImageList(small_icons
, LVSIL_SMALL
);
621 /**********************************************************
622 * ShellView_CompareItems()
625 * internal, CALLBACK for DSA_Sort
627 INT CALLBACK
CDefView::CompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
)
630 TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1
, lParam2
, (LPVOID
) lpData
);
635 IShellFolder
* psf
= reinterpret_cast<IShellFolder
*>(lpData
);
636 PCUIDLIST_RELATIVE pidl1
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam1
);
637 PCUIDLIST_RELATIVE pidl2
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam2
);
639 ret
= (SHORT
)SCODE_CODE(psf
->CompareIDs(0, pidl1
, pidl2
));
640 TRACE("ret=%i\n", ret
);
645 /*************************************************************************
646 * ShellView_ListViewCompareItems
648 * Compare Function for the Listview (FileOpen Dialog)
651 * lParam1 [I] the first ItemIdList to compare with
652 * lParam2 [I] the second ItemIdList to compare with
653 * lpData [I] The column ID for the header Ctrl to process
656 * A negative value if the first item should precede the second,
657 * a positive value if the first item should follow the second,
658 * or zero if the two items are equivalent
661 * FIXME: function does what ShellView_CompareItems is supposed to do.
662 * unify it and figure out how to use the undocumented first parameter
663 * of IShellFolder_CompareIDs to do the job this function does and
664 * move this code to IShellFolder.
665 * make LISTVIEW_SORT_INFO obsolete
666 * the way this function works is only usable if we had only
667 * filesystemfolders (25/10/99 jsch)
669 INT CALLBACK
CDefView::ListViewCompareItems(LPARAM lParam1
, LPARAM lParam2
, LPARAM lpData
)
673 char strName1
[MAX_PATH
], strName2
[MAX_PATH
];
674 BOOL bIsFolder1
, bIsFolder2
, bIsBothFolder
;
675 PCUIDLIST_RELATIVE pidl1
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam1
);
676 PCUIDLIST_RELATIVE pidl2
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam2
);
677 LISTVIEW_SORT_INFO
*pSortInfo
= reinterpret_cast<LPLISTVIEW_SORT_INFO
>(lpData
);
680 bIsFolder1
= _ILIsFolder(pidl1
);
681 bIsFolder2
= _ILIsFolder(pidl2
);
682 bIsBothFolder
= bIsFolder1
&& bIsFolder2
;
684 /* When sorting between a File and a Folder, the Folder gets sorted first */
685 if ( (bIsFolder1
|| bIsFolder2
) && !bIsBothFolder
)
687 nDiff
= bIsFolder1
? -1 : 1;
691 /* Sort by Time: Folders or Files can be sorted */
693 if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_TIME
)
695 _ILGetFileDateTime(pidl1
, &fd1
);
696 _ILGetFileDateTime(pidl2
, &fd2
);
697 nDiff
= CompareFileTime(&fd2
, &fd1
);
699 /* Sort by Attribute: Folder or Files can be sorted */
700 else if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_ATTRIB
)
702 _ILGetFileAttributes(pidl1
, strName1
, MAX_PATH
);
703 _ILGetFileAttributes(pidl2
, strName2
, MAX_PATH
);
704 nDiff
= lstrcmpiA(strName1
, strName2
);
706 /* Sort by FileName: Folder or Files can be sorted */
707 else if (pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_NAME
|| bIsBothFolder
)
710 _ILSimpleGetText(pidl1
, strName1
, MAX_PATH
);
711 _ILSimpleGetText(pidl2
, strName2
, MAX_PATH
);
712 nDiff
= lstrcmpiA(strName1
, strName2
);
714 /* Sort by File Size, Only valid for Files */
715 else if (pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_SIZE
)
717 nDiff
= (INT
)(_ILGetFileSize(pidl1
, NULL
, 0) - _ILGetFileSize(pidl2
, NULL
, 0));
719 /* Sort by File Type, Only valid for Files */
720 else if (pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_TYPE
)
723 _ILGetFileType(pidl1
, strName1
, MAX_PATH
);
724 _ILGetFileType(pidl2
, strName2
, MAX_PATH
);
725 nDiff
= lstrcmpiA(strName1
, strName2
);
728 /* If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
732 _ILSimpleGetText(pidl1
, strName1
, MAX_PATH
);
733 _ILSimpleGetText(pidl2
, strName2
, MAX_PATH
);
734 nDiff
= lstrcmpiA(strName1
, strName2
);
737 if (!pSortInfo
->bIsAscending
)
745 PCUITEMID_CHILD
CDefView::_PidlByItem(int i
)
747 return reinterpret_cast<PCUITEMID_CHILD
>(m_ListView
.GetItemData(i
));
750 PCUITEMID_CHILD
CDefView::_PidlByItem(LVITEM
& lvItem
)
752 return reinterpret_cast<PCUITEMID_CHILD
>(lvItem
.lParam
);
755 /**********************************************************
756 * LV_FindItemByPidl()
758 int CDefView::LV_FindItemByPidl(PCUITEMID_CHILD pidl
)
760 int cItems
= m_ListView
.GetItemCount();
762 for (int i
= 0; i
<cItems
; i
++)
764 PCUITEMID_CHILD currentpidl
= _PidlByItem(i
);
765 HRESULT hr
= m_pSFParent
->CompareIDs(0, pidl
, currentpidl
);
767 if (SUCCEEDED(hr
) && !HRESULT_CODE(hr
))
775 /**********************************************************
778 BOOLEAN
CDefView::LV_AddItem(PCUITEMID_CHILD pidl
)
782 TRACE("(%p)(pidl=%p)\n", this, pidl
);
784 lvItem
.mask
= LVIF_TEXT
| LVIF_IMAGE
| LVIF_PARAM
; /*set the mask*/
785 lvItem
.iItem
= m_ListView
.GetItemCount(); /*add the item to the end of the list*/
787 lvItem
.lParam
= reinterpret_cast<LPARAM
>(ILClone(pidl
)); /*set the item's data*/
788 lvItem
.pszText
= LPSTR_TEXTCALLBACKW
; /*get text on a callback basis*/
789 lvItem
.iImage
= I_IMAGECALLBACK
; /*get the image on a callback basis*/
790 lvItem
.stateMask
= LVIS_CUT
;
792 if (m_ListView
.InsertItem(&lvItem
) == -1)
798 /**********************************************************
801 BOOLEAN
CDefView::LV_DeleteItem(PCUITEMID_CHILD pidl
)
805 TRACE("(%p)(pidl=%p)\n", this, pidl
);
807 nIndex
= LV_FindItemByPidl(pidl
);
809 return (-1 == m_ListView
.DeleteItem(nIndex
)) ? FALSE
: TRUE
;
812 /**********************************************************
815 BOOLEAN
CDefView::LV_RenameItem(PCUITEMID_CHILD pidlOld
, PCUITEMID_CHILD pidlNew
)
820 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", this, pidlOld
, pidlNew
);
822 nItem
= LV_FindItemByPidl(pidlOld
);
826 lvItem
.mask
= LVIF_PARAM
; /* only the pidl */
827 lvItem
.iItem
= nItem
;
828 m_ListView
.GetItem(&lvItem
);
830 SHFree(reinterpret_cast<LPVOID
>(lvItem
.lParam
));
831 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
832 lvItem
.iItem
= nItem
;
833 lvItem
.lParam
= reinterpret_cast<LPARAM
>(ILClone(pidlNew
)); /* set the item's data */
834 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
835 m_ListView
.SetItem(&lvItem
);
836 m_ListView
.Update(nItem
);
837 return TRUE
; /* FIXME: better handling */
843 /**********************************************************
844 * ShellView_FillList()
846 * - gets the objectlist from the shellfolder
848 * - fills the list into the view
850 INT CALLBACK
CDefView::fill_list( LPVOID ptr
, LPVOID arg
)
852 PITEMID_CHILD pidl
= static_cast<PITEMID_CHILD
>(ptr
);
853 CDefView
*pThis
= static_cast<CDefView
*>(arg
);
855 /* in a commdlg This works as a filemask*/
856 if (pThis
->IncludeObject(pidl
) == S_OK
)
857 pThis
->LV_AddItem(pidl
);
863 HRESULT
CDefView::FillList()
865 CComPtr
<IEnumIDList
> pEnumIDList
;
871 DWORD dFlags
= SHCONTF_NONFOLDERS
| SHCONTF_FOLDERS
;
875 /* determine if there is a setting to show all the hidden files/folders */
876 if (RegOpenKeyExW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", 0, KEY_QUERY_VALUE
, &hKey
) == ERROR_SUCCESS
)
878 DWORD dataLength
, flagVal
;
880 dataLength
= sizeof(flagVal
);
881 if (RegQueryValueExW(hKey
, L
"Hidden", NULL
, NULL
, (LPBYTE
)&flagVal
, &dataLength
) == ERROR_SUCCESS
)
883 /* if the value is 1, then show all hidden files/folders */
886 dFlags
|= SHCONTF_INCLUDEHIDDEN
;
887 m_ListView
.SendMessageW(LVM_SETCALLBACKMASK
, LVIS_CUT
, 0);
895 /* get the itemlist from the shfolder */
896 hRes
= m_pSFParent
->EnumObjects(m_hWnd
, dFlags
, &pEnumIDList
);
904 /* create a pointer array */
905 hdpa
= DPA_Create(16);
908 return(E_OUTOFMEMORY
);
911 /* copy the items into the array*/
912 while((S_OK
== pEnumIDList
->Next(1, &pidl
, &dwFetched
)) && dwFetched
)
914 if (DPA_InsertPtr(hdpa
, 0x7fff, pidl
) == -1)
921 DPA_Sort(hdpa
, CompareItems
, reinterpret_cast<LPARAM
>(m_pSFParent
.p
));
923 /*turn the listview's redrawing off*/
924 m_ListView
.SetRedraw(FALSE
);
926 DPA_DestroyCallback( hdpa
, fill_list
, this);
928 /*turn the listview's redrawing back on and force it to draw*/
929 m_ListView
.SetRedraw(TRUE
);
934 LRESULT
CDefView::OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
936 m_ListView
.UpdateWindow();
941 LRESULT
CDefView::OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
943 return m_ListView
.SendMessageW(uMsg
, 0, 0);
946 LRESULT
CDefView::OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
949 DestroyMenu(m_hMenu
);
950 RevokeDragDrop(m_hWnd
);
951 SHChangeNotifyDeregister(m_hNotify
);
952 SHFree(m_pidlParent
);
957 LRESULT
CDefView::OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
959 /* redirect to parent */
960 if (m_FolderSettings
.fFlags
& (FWF_DESKTOP
| FWF_TRANSPARENT
))
961 return SendMessageW(GetParent(), WM_ERASEBKGND
, wParam
, lParam
);
967 LRESULT
CDefView::OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
969 /* Update desktop labels color */
972 /* Forward WM_SYSCOLORCHANGE to common controls */
973 return m_ListView
.SendMessageW(uMsg
, 0, 0);
976 LRESULT
CDefView::OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
978 return reinterpret_cast<LRESULT
>(m_pShellBrowser
.p
);
981 /**********************************************************
982 * ShellView_OnCreate()
984 LRESULT
CDefView::OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
986 CComPtr
<IDropTarget
> pdt
;
987 SHChangeNotifyEntry ntreg
;
988 CComPtr
<IPersistFolder2
> ppf2
;
1000 if (SUCCEEDED(QueryInterface(IID_PPV_ARG(IDropTarget
, &pdt
))))
1002 if (FAILED(RegisterDragDrop(m_hWnd
, pdt
)))
1003 ERR("Registering Drag Drop Failed");
1006 /* register for receiving notifications */
1007 m_pSFParent
->QueryInterface(IID_PPV_ARG(IPersistFolder2
, &ppf2
));
1010 ppf2
->GetCurFolder(&m_pidlParent
);
1011 ntreg
.fRecursive
= TRUE
;
1012 ntreg
.pidl
= m_pidlParent
;
1013 m_hNotify
= SHChangeNotifyRegister(m_hWnd
, SHCNRF_InterruptLevel
| SHCNRF_ShellLevel
, SHCNE_ALLEVENTS
, SHV_CHANGE_NOTIFY
, 1, &ntreg
);
1016 m_hAccel
= LoadAcceleratorsW(shell32_hInstance
, MAKEINTRESOURCEW(IDA_SHELLVIEW
));
1021 /**********************************************************
1022 * #### Handling of the menus ####
1025 HMENU
CDefView::BuildFileMenu()
1028 CComPtr
<IContextMenu
> cm
;
1032 hr
= m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, IID_NULL_PPV_ARG(IContextMenu
, &cm
));
1036 HMENU hmenu
= CreatePopupMenu();
1038 //FIXME: get proper numbers ?
1039 const UINT first
= 0x7800;
1040 const UINT last
= 0x7A00;
1041 hr
= cm
->QueryContextMenu(hmenu
, 0, first
, last
, 0);
1045 // TODO: filter or something
1050 void CDefView::PrepareShowFileMenu(HMENU hSubMenu
)
1052 TRACE("(%p)->(submenu=%p) stub\n", this, hSubMenu
);
1057 /* Cleanup the items added previously */
1058 for (int i
= 0; i
< GetMenuItemCount(hSubMenu
); )
1061 mii
.cbSize
= sizeof(mii
);
1062 mii
.fMask
= MIIM_ID
;
1063 GetMenuItemInfoW(hSubMenu
, i
, TRUE
, &mii
);
1065 if (mii
.wID
< 0x8000)
1067 DeleteMenu(hSubMenu
, i
, MF_BYPOSITION
);
1076 /* FIXME/TODO: Reenable when they implemented AND localizable (not hardcoded). */
1077 /* Insert This item at the beginning of the menu. */
1078 _InsertMenuItemW(hSubMenu
, 0, TRUE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1079 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
+ 4, MFT_STRING
, L
"Properties", MFS_DISABLED
);
1080 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
+ 3, MFT_STRING
, L
"Rename", MFS_DISABLED
);
1081 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
+ 2, MFT_STRING
, L
"Delete", MFS_DISABLED
);
1082 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
+ 1, MFT_STRING
, L
"Create Shortcut", MFS_DISABLED
);
1083 _InsertMenuItemW(hSubMenu
, 0, TRUE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1084 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
, MFT_STRING
, L
"New", MFS_ENABLED
);
1087 HMENU menubase
= BuildFileMenu();
1090 int count
= ::GetMenuItemCount(menubase
);
1091 int count2
= ::GetMenuItemCount(hSubMenu
);
1093 if (count2
> 0 && count
> 0)
1095 _InsertMenuItemW(hSubMenu
, 0, TRUE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1098 for (int i
= count
-1; i
>= 0; i
--)
1102 MENUITEMINFOW mii
= { 0 };
1103 mii
.cbSize
= sizeof(mii
);
1104 mii
.fMask
= MIIM_STATE
| MIIM_ID
| MIIM_SUBMENU
| MIIM_CHECKMARKS
| MIIM_DATA
| MIIM_STRING
| MIIM_BITMAP
| MIIM_FTYPE
;
1105 mii
.dwTypeData
= label
;
1106 mii
.cch
= _countof(label
);
1107 ::GetMenuItemInfoW(menubase
, i
, TRUE
, &mii
);
1109 TRACE("Adding item %d label %S type %d\n", mii
.wID
, mii
.dwTypeData
, mii
.fType
);
1111 mii
.fType
|= MFT_RADIOCHECK
;
1113 ::InsertMenuItemW(hSubMenu
, 0, TRUE
, &mii
);
1117 ::DestroyMenu(menubase
);
1122 void CDefView::PrepareShowViewMenu(HMENU hSubMenu
)
1124 TRACE("(%p)->(submenu=%p)\n", this, hSubMenu
);
1129 if (m_FolderSettings
.ViewMode
>= FVM_FIRST
&& m_FolderSettings
.ViewMode
<= FVM_LAST
)
1131 UINT iItemFirst
= FCIDM_SHVIEW_BIGICON
;
1132 UINT iItemLast
= iItemFirst
+ FVM_LAST
- FVM_FIRST
;
1133 UINT iItem
= iItemFirst
+ m_FolderSettings
.ViewMode
- FVM_FIRST
;
1134 CheckMenuRadioItem(hSubMenu
, iItemFirst
, iItemLast
, iItem
, MF_BYCOMMAND
);
1138 /**********************************************************
1139 * ShellView_GetSelections()
1141 * - fills the m_apidl list with the selected objects
1144 * number of selected items
1146 UINT
CDefView::GetSelections()
1150 m_cidl
= m_ListView
.GetSelectedCount();
1151 m_apidl
= reinterpret_cast<PCUITEMID_CHILD_ARRAY
>(SHAlloc(m_cidl
* sizeof(PCUITEMID_CHILD
)));
1158 TRACE("-- Items selected =%u\n", m_cidl
);
1162 while ((lvIndex
= m_ListView
.GetNextItem(lvIndex
, LVNI_SELECTED
)) > -1)
1164 m_apidl
[i
] = _PidlByItem(lvIndex
);
1168 TRACE("-- selected Item found\n");
1174 /**********************************************************
1175 * ShellView_OpenSelectedItems()
1177 HRESULT
CDefView::OpenSelectedItems()
1180 CMINVOKECOMMANDINFO cmi
;
1184 m_cidl
= m_ListView
.GetSelectedCount();
1188 hResult
= OnDefaultCommand();
1189 if (hResult
== S_OK
)
1192 hMenu
= CreatePopupMenu();
1196 hResult
= GetItemObject(SVGIO_SELECTION
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1197 if (FAILED(hResult
))
1200 hResult
= IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1201 //if (FAILED( hResult))
1204 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, 0x20, 0x7fff, CMF_DEFAULTONLY
);
1205 if (FAILED(hResult
))
1208 uCommand
= GetMenuDefaultItem(hMenu
, FALSE
, 0);
1209 if (uCommand
== (UINT
)-1)
1215 ZeroMemory(&cmi
, sizeof(cmi
));
1216 cmi
.cbSize
= sizeof(cmi
);
1217 cmi
.lpVerb
= (LPCSTR
)MAKEINTRESOURCEA(uCommand
);
1220 hResult
= m_pCM
->InvokeCommand(&cmi
);
1229 IUnknown_SetSite(m_pCM
, NULL
);
1236 /**********************************************************
1237 * ShellView_DoContextMenu()
1239 LRESULT
CDefView::OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1245 CMINVOKECOMMANDINFO cmi
;
1248 // for some reason I haven't figured out, we sometimes recurse into this method
1255 TRACE("(%p)->(0x%08x 0x%08x) stub\n", this, x
, y
);
1257 hMenu
= CreatePopupMenu();
1261 m_cidl
= m_ListView
.GetSelectedCount();
1263 hResult
= GetItemObject( m_cidl
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1264 if (FAILED( hResult
))
1267 hResult
= IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1268 //if (FAILED( hResult))
1271 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1272 if (FAILED( hResult
))
1275 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
1276 SetMenuDefaultItem(hMenu
, FCIDM_SHVIEW_OPEN
, MF_BYCOMMAND
);
1278 uCommand
= TrackPopupMenu(hMenu
,
1279 TPM_LEFTALIGN
| TPM_RETURNCMD
| TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
,
1280 x
, y
, 0, m_hWnd
, NULL
);
1284 if (uCommand
== FCIDM_SHVIEW_OPEN
&& OnDefaultCommand() == S_OK
)
1287 ZeroMemory(&cmi
, sizeof(cmi
));
1288 cmi
.cbSize
= sizeof(cmi
);
1289 cmi
.lpVerb
= MAKEINTRESOURCEA(uCommand
);
1291 m_pCM
->InvokeCommand(&cmi
);
1297 IUnknown_SetSite(m_pCM
, NULL
);
1307 LRESULT
CDefView::OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
)
1310 CMINVOKECOMMANDINFO cmi
;
1313 hMenu
= CreatePopupMenu();
1317 hResult
= GetItemObject( bUseSelection
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1318 if (FAILED( hResult
))
1321 hResult
= IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1322 //if (FAILED( hResult))
1325 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1326 if (FAILED( hResult
))
1329 ZeroMemory(&cmi
, sizeof(cmi
));
1330 cmi
.cbSize
= sizeof(cmi
);
1331 cmi
.lpVerb
= MAKEINTRESOURCEA(uCommand
);
1333 m_pCM
->InvokeCommand(&cmi
);
1339 IUnknown_SetSite(m_pCM
, NULL
);
1349 /**********************************************************
1350 * ##### message handling #####
1353 /**********************************************************
1354 * ShellView_OnSize()
1356 LRESULT
CDefView::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1361 wWidth
= LOWORD(lParam
);
1362 wHeight
= HIWORD(lParam
);
1364 TRACE("%p width=%u height=%u\n", this, wWidth
, wHeight
);
1366 /*resize the ListView to fit our window*/
1369 ::MoveWindow(m_ListView
, 0, 0, wWidth
, wHeight
, TRUE
);
1375 /**********************************************************
1376 * ShellView_OnDeactivate()
1381 void CDefView::OnDeactivate()
1383 TRACE("%p\n", this);
1385 if (m_uState
!= SVUIA_DEACTIVATE
)
1387 // TODO: cleanup menu after deactivation
1389 m_uState
= SVUIA_DEACTIVATE
;
1393 void CDefView::DoActivate(UINT uState
)
1395 TRACE("%p uState=%x\n", this, uState
);
1397 /*don't do anything if the state isn't really changing */
1398 if (m_uState
== uState
)
1403 if (uState
== SVUIA_DEACTIVATE
)
1413 MENUITEMINFOW mii
= { 0 };
1415 /* initialize EDIT menu */
1416 mii
.cbSize
= sizeof(mii
);
1417 mii
.fMask
= MIIM_SUBMENU
;
1418 if (::GetMenuItemInfoW(m_hMenu
, FCIDM_MENU_EDIT
, FALSE
, &mii
))
1420 HMENU hSubMenu
= mii
.hSubMenu
;
1422 HMENU menubase
= ::LoadMenuW(shell32_hInstance
, L
"MENU_003");
1424 int count
= ::GetMenuItemCount(menubase
);
1425 for (int i
= 0; i
< count
; i
++)
1429 ZeroMemory(&mii
, sizeof(mii
));
1430 mii
.cbSize
= sizeof(mii
);
1431 mii
.fMask
= MIIM_STATE
| MIIM_ID
| MIIM_SUBMENU
| MIIM_CHECKMARKS
| MIIM_DATA
| MIIM_STRING
| MIIM_BITMAP
| MIIM_FTYPE
;
1432 mii
.dwTypeData
= label
;
1433 mii
.cch
= _countof(label
);
1434 ::GetMenuItemInfoW(menubase
, i
, TRUE
, &mii
);
1436 TRACE("Adding item %d label %S type %d\n", mii
.wID
, mii
.dwTypeData
, mii
.fType
);
1438 mii
.fType
|= MFT_RADIOCHECK
;
1440 ::InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, &mii
);
1443 ::DestroyMenu(menubase
);
1446 /* initialize VIEW menu */
1448 mii
.cbSize
= sizeof(mii
);
1449 mii
.fMask
= MIIM_SUBMENU
;
1450 if (::GetMenuItemInfoW(m_hMenu
, FCIDM_MENU_VIEW
, FALSE
, &mii
))
1452 HMENU menubase
= ::LoadMenuW(shell32_hInstance
, L
"MENU_001");
1454 HMENU hSubMenu
= mii
.hSubMenu
;
1456 m_hView
= CreatePopupMenu();
1458 _InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1460 int count
= ::GetMenuItemCount(menubase
);
1461 for (int i
= 0; i
< count
; i
++)
1465 ZeroMemory(&mii
, sizeof(mii
));
1466 mii
.cbSize
= sizeof(mii
);
1467 mii
.fMask
= MIIM_STATE
| MIIM_ID
| MIIM_SUBMENU
| MIIM_CHECKMARKS
| MIIM_DATA
| MIIM_STRING
| MIIM_BITMAP
| MIIM_FTYPE
;
1468 mii
.dwTypeData
= label
;
1469 mii
.cch
= _countof(label
);
1470 ::GetMenuItemInfoW(menubase
, i
, TRUE
, &mii
);
1472 ::AppendMenuW(m_hView
, mii
.fType
, mii
.wID
, mii
.dwTypeData
);
1474 TRACE("Adding item %d label %S type %d\n", mii
.wID
, mii
.dwTypeData
, mii
.fType
);
1476 mii
.fType
|= MFT_RADIOCHECK
;
1478 ::InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, &mii
);
1481 ::DestroyMenu(menubase
);
1485 TRACE("-- before fnSetMenuSB\n");
1486 m_pShellBrowser
->SetMenuSB(m_hMenu
, 0, m_hWnd
);
1488 m_menusLoaded
= TRUE
;
1492 if (SVUIA_ACTIVATE_FOCUS
== uState
)
1494 m_ListView
.SetFocus();
1502 /**********************************************************
1503 * ShellView_OnActivate()
1505 LRESULT
CDefView::OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1507 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1511 /**********************************************************
1512 * ShellView_OnSetFocus()
1515 LRESULT
CDefView::OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1517 TRACE("%p\n", this);
1519 /* Tell the browser one of our windows has received the focus. This
1520 should always be done before merging menus (OnActivate merges the
1521 menus) if one of our windows has the focus.*/
1523 m_pShellBrowser
->OnViewWindowActive(this);
1524 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1526 /* Set the focus to the listview */
1527 m_ListView
.SetFocus();
1529 /* Notify the ICommDlgBrowser interface */
1530 OnStateChange(CDBOSC_SETFOCUS
);
1535 /**********************************************************
1536 * ShellView_OnKillFocus()
1538 LRESULT
CDefView::OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1540 TRACE("(%p) stub\n", this);
1542 DoActivate(SVUIA_ACTIVATE_NOFOCUS
);
1543 /* Notify the ICommDlgBrowser */
1544 OnStateChange(CDBOSC_KILLFOCUS
);
1549 /**********************************************************
1550 * ShellView_OnCommand()
1553 * the CmdID's are the ones from the context menu
1555 LRESULT
CDefView::OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1561 dwCmdID
= GET_WM_COMMAND_ID(wParam
, lParam
);
1562 dwCmd
= GET_WM_COMMAND_CMD(wParam
, lParam
);
1563 hwndCmd
= GET_WM_COMMAND_HWND(wParam
, lParam
);
1565 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n", this, dwCmdID
, dwCmd
, hwndCmd
);
1569 case FCIDM_SHVIEW_SMALLICON
:
1570 m_FolderSettings
.ViewMode
= FVM_SMALLICON
;
1571 SetStyle (LVS_SMALLICON
, LVS_TYPEMASK
);
1575 case FCIDM_SHVIEW_BIGICON
:
1576 m_FolderSettings
.ViewMode
= FVM_ICON
;
1577 SetStyle (LVS_ICON
, LVS_TYPEMASK
);
1581 case FCIDM_SHVIEW_LISTVIEW
:
1582 m_FolderSettings
.ViewMode
= FVM_LIST
;
1583 SetStyle (LVS_LIST
, LVS_TYPEMASK
);
1587 case FCIDM_SHVIEW_REPORTVIEW
:
1588 m_FolderSettings
.ViewMode
= FVM_DETAILS
;
1589 SetStyle (LVS_REPORT
, LVS_TYPEMASK
);
1593 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1598 m_sortInfo
.nHeaderID
= dwCmdID
- 0x30;
1599 m_sortInfo
.bIsAscending
= TRUE
;
1600 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
1601 m_ListView
.SortItems(ListViewCompareItems
, &m_sortInfo
);
1604 case FCIDM_SHVIEW_SELECTALL
:
1605 m_ListView
.SetItemState(-1, LVIS_SELECTED
, LVIS_SELECTED
);
1608 case FCIDM_SHVIEW_REFRESH
:
1612 case FCIDM_SHVIEW_DELETE
:
1613 case FCIDM_SHVIEW_CUT
:
1614 case FCIDM_SHVIEW_COPY
:
1615 case FCIDM_SHVIEW_RENAME
:
1616 return OnExplorerCommand(dwCmdID
, TRUE
);
1618 case FCIDM_SHVIEW_INSERT
:
1619 case FCIDM_SHVIEW_UNDO
:
1620 case FCIDM_SHVIEW_INSERTLINK
:
1621 case FCIDM_SHVIEW_NEWFOLDER
:
1622 return OnExplorerCommand(dwCmdID
, FALSE
);
1624 TRACE("-- COMMAND 0x%04x unhandled\n", dwCmdID
);
1630 /**********************************************************
1631 * ShellView_OnNotify()
1634 LRESULT
CDefView::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1638 LPNMLISTVIEW lpnmlv
;
1639 NMLVDISPINFOW
*lpdi
;
1640 PCUITEMID_CHILD pidl
;
1644 lpnmh
= (LPNMHDR
)lParam
;
1645 lpnmlv
= (LPNMLISTVIEW
)lpnmh
;
1646 lpdi
= (NMLVDISPINFOW
*)lpnmh
;
1648 TRACE("%p CtlID=%u lpnmh->code=%x\n", this, CtlID
, lpnmh
->code
);
1650 switch (lpnmh
->code
)
1653 TRACE("-- NM_SETFOCUS %p\n", this);
1654 OnSetFocus(0, 0, 0, unused
);
1658 TRACE("-- NM_KILLFOCUS %p\n", this);
1660 /* Notify the ICommDlgBrowser interface */
1661 OnStateChange(CDBOSC_KILLFOCUS
);
1665 TRACE("-- NM_CUSTOMDRAW %p\n", this);
1666 return CDRF_DODEFAULT
;
1668 case NM_RELEASEDCAPTURE
:
1669 TRACE("-- NM_RELEASEDCAPTURE %p\n", this);
1673 TRACE("-- NM_CLICK %p\n", this);
1677 TRACE("-- NM_RCLICK %p\n", this);
1681 TRACE("-- NM_DBLCLK %p\n", this);
1682 OpenSelectedItems();
1686 TRACE("-- NM_RETURN %p\n", this);
1687 OpenSelectedItems();
1691 TRACE("-- HDN_ENDTRACKW %p\n", this);
1692 /*nColumn1 = m_ListView.GetColumnWidth(0);
1693 nColumn2 = m_ListView.GetColumnWidth(1);*/
1696 case LVN_DELETEITEM
:
1697 TRACE("-- LVN_DELETEITEM %p\n", this);
1699 /*delete the pidl because we made a copy of it*/
1700 SHFree(reinterpret_cast<LPVOID
>(lpnmlv
->lParam
));
1704 case LVN_DELETEALLITEMS
:
1705 TRACE("-- LVN_DELETEALLITEMS %p\n", this);
1708 case LVN_INSERTITEM
:
1709 TRACE("-- LVN_INSERTITEM (STUB)%p\n", this);
1712 case LVN_ITEMACTIVATE
:
1713 TRACE("-- LVN_ITEMACTIVATE %p\n", this);
1714 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1717 case LVN_COLUMNCLICK
:
1718 m_sortInfo
.nHeaderID
= lpnmlv
->iSubItem
;
1719 if (m_sortInfo
.nLastHeaderID
== m_sortInfo
.nHeaderID
)
1720 m_sortInfo
.bIsAscending
= !m_sortInfo
.bIsAscending
;
1722 m_sortInfo
.bIsAscending
= TRUE
;
1723 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
1725 m_ListView
.SortItems(ListViewCompareItems
, &m_sortInfo
);
1728 case LVN_GETDISPINFOA
:
1729 case LVN_GETDISPINFOW
:
1730 TRACE("-- LVN_GETDISPINFO %p\n", this);
1731 pidl
= _PidlByItem(lpdi
->item
);
1733 if (lpdi
->item
.mask
& LVIF_TEXT
) /* text requested */
1738 if (FAILED(m_pSF2Parent
->GetDetailsOf(pidl
, lpdi
->item
.iSubItem
, &sd
)))
1740 FIXME("failed to get details\n");
1744 if (lpnmh
->code
== LVN_GETDISPINFOA
)
1746 /* shouldn't happen */
1747 NMLVDISPINFOA
*lpdiA
= (NMLVDISPINFOA
*)lpnmh
;
1748 StrRetToStrNA( lpdiA
->item
.pszText
, lpdiA
->item
.cchTextMax
, &sd
.str
, NULL
);
1749 TRACE("-- text=%s\n", lpdiA
->item
.pszText
);
1751 else /* LVN_GETDISPINFOW */
1753 StrRetToStrNW( lpdi
->item
.pszText
, lpdi
->item
.cchTextMax
, &sd
.str
, NULL
);
1754 TRACE("-- text=%s\n", debugstr_w(lpdi
->item
.pszText
));
1762 if(lpdi
->item
.mask
& LVIF_IMAGE
) /* image requested */
1764 lpdi
->item
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
1766 if(lpdi
->item
.mask
& LVIF_STATE
)
1768 ULONG attributes
= SFGAO_HIDDEN
;
1769 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(1, &pidl
, &attributes
)))
1771 if (attributes
& SFGAO_HIDDEN
)
1773 lpdi
->item
.state
|= LVIS_CUT
;
1777 lpdi
->item
.mask
|= LVIF_DI_SETITEM
;
1780 case LVN_ITEMCHANGED
:
1781 TRACE("-- LVN_ITEMCHANGED %p\n", this);
1782 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1786 case LVN_BEGINRDRAG
:
1787 TRACE("-- LVN_BEGINDRAG\n");
1789 if (GetSelections())
1791 CComPtr
<IDataObject
> pda
;
1792 DWORD dwAttributes
= SFGAO_CANLINK
;
1793 DWORD dwEffect
= DROPEFFECT_COPY
| DROPEFFECT_MOVE
;
1795 if (SUCCEEDED(m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, IID_NULL_PPV_ARG(IDataObject
, &pda
))))
1797 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(m_cidl
, m_apidl
, &dwAttributes
)))
1799 if (dwAttributes
& SFGAO_CANLINK
)
1801 dwEffect
|= DROPEFFECT_LINK
;
1805 CComPtr
<IAsyncOperation
> piaso
;
1806 if (SUCCEEDED(pda
->QueryInterface(IID_PPV_ARG(IAsyncOperation
, &piaso
))))
1808 piaso
->SetAsyncMode(TRUE
);
1812 DoDragDrop(pda
, this, dwEffect
, &dwEffect2
);
1817 case LVN_BEGINLABELEDITW
:
1819 DWORD dwAttr
= SFGAO_CANRENAME
;
1820 pidl
= _PidlByItem(lpdi
->item
);
1822 TRACE("-- LVN_BEGINLABELEDITW %p\n", this);
1824 m_pSFParent
->GetAttributesOf(1, &pidl
, &dwAttr
);
1825 if (SFGAO_CANRENAME
& dwAttr
)
1833 case LVN_ENDLABELEDITW
:
1835 TRACE("-- LVN_ENDLABELEDITW %p\n", this);
1837 m_isEditing
= FALSE
;
1839 if (lpdi
->item
.pszText
)
1844 pidl
= _PidlByItem(lpdi
->item
);
1845 PITEMID_CHILD pidlNew
;
1846 hr
= m_pSFParent
->SetNameOf(0, pidl
, lpdi
->item
.pszText
, SHGDN_INFOLDER
, &pidlNew
);
1848 if (SUCCEEDED(hr
) && pidlNew
)
1850 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
1851 lvItem
.iItem
= lpdi
->item
.iItem
;
1852 lvItem
.lParam
= reinterpret_cast<LPARAM
>(pidlNew
);
1853 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
1854 m_ListView
.SetItem(&lvItem
);
1855 m_ListView
.Update(lpdi
->item
.iItem
);
1864 TRACE("-- %p WM_COMMAND %x unhandled\n", this, lpnmh
->code
);
1872 * This is just a quick hack to make the desktop work correctly.
1873 * ITranslateShellChangeNotify's IsChildID is undocumented, but most likely the way that
1874 * a folder should know if it should update upon a change notification.
1875 * It is exported by merged folders at a minimum.
1877 static BOOL
ILIsParentOrSpecialParent(PCIDLIST_ABSOLUTE pidl1
, PCIDLIST_ABSOLUTE pidl2
)
1879 if (!pidl1
|| !pidl2
)
1881 if (ILIsParent(pidl1
, pidl2
, TRUE
))
1884 if (_ILIsDesktop(pidl1
))
1886 PIDLIST_ABSOLUTE deskpidl
;
1887 SHGetFolderLocation(NULL
, CSIDL_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
1888 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
1894 SHGetFolderLocation(NULL
, CSIDL_COMMON_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
1895 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
1905 /**********************************************************
1906 * ShellView_OnChange()
1908 LRESULT
CDefView::OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1910 PCIDLIST_ABSOLUTE
*Pidls
= reinterpret_cast<PCIDLIST_ABSOLUTE
*>(wParam
);
1911 BOOL bParent0
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[0]);
1912 BOOL bParent1
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[1]);
1914 TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls
[0], Pidls
[1], lParam
);
1921 LV_AddItem(ILFindLastID(Pidls
[0]));
1927 LV_DeleteItem(ILFindLastID(Pidls
[0]));
1930 case SHCNE_RENAMEFOLDER
:
1931 case SHCNE_RENAMEITEM
:
1932 if (bParent0
&& bParent1
)
1933 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[1]));
1935 LV_DeleteItem(ILFindLastID(Pidls
[0]));
1937 LV_AddItem(ILFindLastID(Pidls
[0]));
1940 case SHCNE_UPDATEITEM
:
1942 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[0]));
1945 case SHCNE_UPDATEDIR
:
1952 /**********************************************************
1953 * CDefView::OnCustomItem
1955 LRESULT
CDefView::OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1960 ERR("no menu!!!\n");
1965 HRESULT hres
= SHForwardContextMenuMsg(m_pCM
, uMsg
, wParam
, lParam
, &result
, TRUE
);
1966 if (SUCCEEDED(hres
))
1972 LRESULT
CDefView::OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1974 /* Wallpaper setting affects drop shadows effect */
1975 if (wParam
== SPI_SETDESKWALLPAPER
|| wParam
== 0)
1981 /**********************************************************
1982 * CDefView::OnInitMenuPopup
1984 LRESULT
CDefView::OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1986 MENUITEMINFOW mii
= { 0 };
1987 HMENU hSubmenu
= (HMENU
) wParam
;
1989 TRACE("OnInitMenuPopup lParam=%d\n", lParam
);
1991 mii
.cbSize
= sizeof(mii
);
1992 mii
.fMask
= MIIM_ID
| MIIM_SUBMENU
;
1994 if (!GetMenuItemInfoW(this->m_hMenu
, lParam
, TRUE
, &mii
))
1996 TRACE("OnInitMenuPopup GetMenuItemInfoW failed!\n");
2000 UINT menuItemId
= mii
.wID
;
2002 if (mii
.hSubMenu
!= hSubmenu
)
2004 TRACE("OnInitMenuPopup submenu does not match!!!!\n");
2008 TRACE("OnInitMenuPopup id=%d\n", menuItemId
);
2012 case FCIDM_MENU_FILE
:
2013 PrepareShowFileMenu(hSubmenu
);
2015 case FCIDM_MENU_EDIT
:
2016 //PrepareShowEditMenu(hSubmenu);
2018 case FCIDM_MENU_VIEW
:
2019 PrepareShowViewMenu(hSubmenu
);
2026 /**********************************************************
2029 * The INTERFACE of the IShellView object
2032 **********************************************************
2035 /**********************************************************
2036 * ShellView_GetWindow
2038 HRESULT WINAPI
CDefView::GetWindow(HWND
*phWnd
)
2040 TRACE("(%p)\n", this);
2047 HRESULT WINAPI
CDefView::ContextSensitiveHelp(BOOL fEnterMode
)
2049 FIXME("(%p) stub\n", this);
2054 /**********************************************************
2055 * IShellView_TranslateAccelerator
2058 * use the accel functions
2060 HRESULT WINAPI
CDefView::TranslateAccelerator(LPMSG lpmsg
)
2065 if (lpmsg
->message
>= WM_KEYFIRST
&& lpmsg
->message
<= WM_KEYLAST
)
2067 if (::TranslateAcceleratorW(m_hWnd
, m_hAccel
, lpmsg
) != 0)
2070 TRACE("-- key=0x04%lx\n", lpmsg
->wParam
) ;
2073 return m_pShellBrowser
->TranslateAcceleratorSB(lpmsg
, 0);
2076 HRESULT WINAPI
CDefView::EnableModeless(BOOL fEnable
)
2078 FIXME("(%p) stub\n", this);
2083 HRESULT WINAPI
CDefView::UIActivate(UINT uState
)
2086 CHAR szName[MAX_PATH];
2089 int nPartArray
[1] = { -1};
2091 TRACE("(%p)->(state=%x) stub\n", this, uState
);
2093 /*don't do anything if the state isn't really changing*/
2094 if (m_uState
== uState
)
2099 /*OnActivate handles the menu merging and internal state*/
2102 /*only do This if we are active*/
2103 if (uState
!= SVUIA_DEACTIVATE
)
2107 GetFolderPath is not a method of IShellFolder
2108 IShellFolder_GetFolderPath( m_pSFParent, szName, sizeof(szName) );
2110 /* set the number of parts */
2111 m_pShellBrowser
->SendControlMsg(FCW_STATUS
, SB_SETPARTS
, 1, (LPARAM
)nPartArray
, &lResult
);
2113 /* set the text for the parts */
2115 m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXTA, 0, (LPARAM)szName, &lResult);
2122 HRESULT WINAPI
CDefView::Refresh()
2124 TRACE("(%p)\n", this);
2126 m_ListView
.DeleteAllItems();
2132 HRESULT WINAPI
CDefView::CreateViewWindow(IShellView
*lpPrevView
, LPCFOLDERSETTINGS lpfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
)
2134 OLEMENUGROUPWIDTHS omw
= { { 0, 0, 0, 0, 0, 0 } };
2138 TRACE("(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n", this, lpPrevView
, lpfs
, psb
, prcView
, phWnd
);
2141 TRACE("-- vmode=%x flags=%x\n", lpfs
->ViewMode
, lpfs
->fFlags
);
2142 if (prcView
!= NULL
)
2143 TRACE("-- left=%i top=%i right=%i bottom=%i\n", prcView
->left
, prcView
->top
, prcView
->right
, prcView
->bottom
);
2145 /* Validate the Shell Browser */
2147 return E_UNEXPECTED
;
2149 /*set up the member variables*/
2150 m_pShellBrowser
= psb
;
2151 m_FolderSettings
= *lpfs
;
2153 /*get our parent window*/
2154 m_pShellBrowser
->GetWindow(&m_hWndParent
);
2156 /* try to get the ICommDlgBrowserInterface, adds a reference !!! */
2157 m_pCommDlgBrowser
= NULL
;
2158 if (SUCCEEDED(m_pShellBrowser
->QueryInterface(IID_PPV_ARG(ICommDlgBrowser
, &m_pCommDlgBrowser
))))
2160 TRACE("-- CommDlgBrowser\n");
2163 Create(m_hWndParent
, prcView
, NULL
, WS_CHILD
| WS_TABSTOP
, 0, 0U);
2174 SetWindowPos(HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_SHOWWINDOW
);
2179 m_hMenu
= CreateMenu();
2180 m_pShellBrowser
->InsertMenusSB(m_hMenu
, &omw
);
2181 TRACE("-- after fnInsertMenusSB\n");
2189 HRESULT WINAPI
CDefView::DestroyViewWindow()
2191 TRACE("(%p)\n", this);
2193 /*Make absolutely sure all our UI is cleaned up.*/
2194 UIActivate(SVUIA_DEACTIVATE
);
2198 // "Accelerator tables loaded from resources are freed automatically when the application terminates." -- MSDN
2204 DestroyMenu(m_hView
);
2210 DestroyMenu(m_hMenu
);
2216 m_ListView
.DestroyWindow();
2224 m_pShellBrowser
.Release();
2225 m_pCommDlgBrowser
.Release();
2230 HRESULT WINAPI
CDefView::GetCurrentInfo(LPFOLDERSETTINGS lpfs
)
2232 TRACE("(%p)->(%p) vmode=%x flags=%x\n", this, lpfs
,
2233 m_FolderSettings
.ViewMode
, m_FolderSettings
.fFlags
);
2236 return E_INVALIDARG
;
2238 *lpfs
= m_FolderSettings
;
2242 HRESULT WINAPI
CDefView::AddPropertySheetPages(DWORD dwReserved
, LPFNADDPROPSHEETPAGE lpfn
, LPARAM lparam
)
2244 FIXME("(%p) stub\n", this);
2249 HRESULT WINAPI
CDefView::SaveViewState()
2251 FIXME("(%p) stub\n", this);
2256 HRESULT WINAPI
CDefView::SelectItem(PCUITEMID_CHILD pidl
, UINT uFlags
)
2260 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n", this, pidl
, uFlags
);
2262 i
= LV_FindItemByPidl(pidl
);
2266 if(uFlags
& SVSI_ENSUREVISIBLE
)
2267 m_ListView
.EnsureVisible(i
, FALSE
);
2269 LVITEMW lvItem
= {0};
2270 lvItem
.mask
= LVIF_STATE
;
2271 lvItem
.stateMask
= LVIS_SELECTED
| LVIS_FOCUSED
;
2273 while (m_ListView
.GetItem(&lvItem
))
2275 if (lvItem
.iItem
== i
)
2277 if (uFlags
& SVSI_SELECT
)
2278 lvItem
.state
|= LVIS_SELECTED
;
2280 lvItem
.state
&= ~LVIS_SELECTED
;
2282 if (uFlags
& SVSI_FOCUSED
)
2283 lvItem
.state
&= ~LVIS_FOCUSED
;
2287 if (uFlags
& SVSI_DESELECTOTHERS
)
2288 lvItem
.state
&= ~LVIS_SELECTED
;
2291 m_ListView
.SetItem(&lvItem
);
2295 if(uFlags
& SVSI_EDIT
)
2296 m_ListView
.EditLabel(i
);
2301 HRESULT WINAPI
CDefView::GetItemObject(UINT uItem
, REFIID riid
, LPVOID
*ppvOut
)
2303 HRESULT hr
= E_NOINTERFACE
;
2305 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n", this, uItem
, debugstr_guid(&riid
), ppvOut
);
2311 case SVGIO_BACKGROUND
:
2312 if (IsEqualIID(riid
, IID_IContextMenu
))
2314 //*ppvOut = ISvBgCm_Constructor(m_pSFParent, FALSE);
2319 hr
= CDefFolderMenu_Create2(NULL
, NULL
, 0, NULL
, m_pSFParent
, NULL
, 0, NULL
, &pcm
);
2326 case SVGIO_SELECTION
:
2328 hr
= m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, riid
, 0, ppvOut
);
2332 TRACE("-- (%p)->(interface=%p)\n", this, *ppvOut
);
2337 HRESULT STDMETHODCALLTYPE
CDefView::GetCurrentViewMode(UINT
*pViewMode
)
2339 TRACE("(%p)->(%p), stub\n", this, pViewMode
);
2342 return E_INVALIDARG
;
2344 *pViewMode
= m_FolderSettings
.ViewMode
;
2348 HRESULT STDMETHODCALLTYPE
CDefView::SetCurrentViewMode(UINT ViewMode
)
2351 TRACE("(%p)->(%u), stub\n", this, ViewMode
);
2353 /* It's not redundant to check FVM_AUTO because it's a (UINT)-1 */
2354 if (((INT
)ViewMode
< FVM_FIRST
|| (INT
)ViewMode
> FVM_LAST
) && ((INT
)ViewMode
!= FVM_AUTO
))
2355 return E_INVALIDARG
;
2357 /* Windows before Vista uses LVM_SETVIEW and possibly
2358 LVM_SETEXTENDEDLISTVIEWSTYLE to set the style of the listview,
2359 while later versions seem to accomplish this through other
2367 dwStyle
= LVS_REPORT
;
2370 dwStyle
= LVS_SMALLICON
;
2377 FIXME("ViewMode %d not implemented\n", ViewMode
);
2383 SetStyle(dwStyle
, LVS_TYPEMASK
);
2385 /* This will not necessarily be the actual mode set above.
2386 This mimics the behavior of Windows XP. */
2387 m_FolderSettings
.ViewMode
= ViewMode
;
2392 HRESULT STDMETHODCALLTYPE
CDefView::GetFolder(REFIID riid
, void **ppv
)
2394 if (m_pSFParent
== NULL
)
2397 return m_pSFParent
->QueryInterface(riid
, ppv
);
2400 HRESULT STDMETHODCALLTYPE
CDefView::Item(int iItemIndex
, PITEMID_CHILD
*ppidl
)
2402 PCUITEMID_CHILD pidl
= _PidlByItem(iItemIndex
);
2405 *ppidl
= ILClone(pidl
);
2410 return E_INVALIDARG
;
2413 HRESULT STDMETHODCALLTYPE
CDefView::ItemCount(UINT uFlags
, int *pcItems
)
2415 TRACE("(%p)->(%u %p)\n", this, uFlags
, pcItems
);
2417 if (uFlags
!= SVGIO_ALLVIEW
)
2418 FIXME("some flags unsupported, %x\n", uFlags
& ~SVGIO_ALLVIEW
);
2420 *pcItems
= m_ListView
.GetItemCount();
2425 HRESULT STDMETHODCALLTYPE
CDefView::Items(UINT uFlags
, REFIID riid
, void **ppv
)
2430 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectionMarkedItem(int *piItem
)
2432 TRACE("(%p)->(%p)\n", this, piItem
);
2434 *piItem
= m_ListView
.GetSelectionMark();
2439 HRESULT STDMETHODCALLTYPE
CDefView::GetFocusedItem(int *piItem
)
2441 TRACE("(%p)->(%p)\n", this, piItem
);
2443 *piItem
= m_ListView
.GetNextItem(-1, LVNI_FOCUSED
);
2448 HRESULT STDMETHODCALLTYPE
CDefView::GetItemPosition(PCUITEMID_CHILD pidl
, POINT
*ppt
)
2453 HRESULT STDMETHODCALLTYPE
CDefView::GetSpacing(POINT
*ppt
)
2455 TRACE("(%p)->(%p)\n", this, ppt
);
2463 m_ListView
.GetItemSpacing(spacing
);
2465 ppt
->x
= spacing
.cx
;
2466 ppt
->y
= spacing
.cy
;
2472 HRESULT STDMETHODCALLTYPE
CDefView::GetDefaultSpacing(POINT
*ppt
)
2477 HRESULT STDMETHODCALLTYPE
CDefView::GetAutoArrange()
2482 HRESULT STDMETHODCALLTYPE
CDefView::SelectItem(int iItem
, DWORD dwFlags
)
2486 TRACE("(%p)->(%d, %x)\n", this, iItem
, dwFlags
);
2489 lvItem
.stateMask
= LVIS_SELECTED
;
2491 if (dwFlags
& SVSI_ENSUREVISIBLE
)
2492 m_ListView
.EnsureVisible(iItem
, 0);
2495 if (dwFlags
& SVSI_DESELECTOTHERS
)
2496 m_ListView
.SetItemState(-1, 0, LVIS_SELECTED
);
2499 if (dwFlags
& SVSI_SELECT
)
2500 lvItem
.state
|= LVIS_SELECTED
;
2502 if (dwFlags
& SVSI_FOCUSED
)
2503 lvItem
.stateMask
|= LVIS_FOCUSED
;
2505 m_ListView
.SetItemState(iItem
, lvItem
.state
, lvItem
.stateMask
);
2507 if (dwFlags
& SVSI_EDIT
)
2508 m_ListView
.EditLabel(iItem
);
2513 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItems(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD dwFlags
)
2518 /**********************************************************
2519 * IShellFolderView implementation
2521 HRESULT STDMETHODCALLTYPE
CDefView::Rearrange(LPARAM sort
)
2523 FIXME("(%p)->(%ld) stub\n", this, sort
);
2527 HRESULT STDMETHODCALLTYPE
CDefView::GetArrangeParam(LPARAM
*sort
)
2529 FIXME("(%p)->(%p) stub\n", this, sort
);
2533 HRESULT STDMETHODCALLTYPE
CDefView::ArrangeGrid()
2535 FIXME("(%p) stub\n", this);
2539 HRESULT STDMETHODCALLTYPE
CDefView::AutoArrange()
2541 FIXME("(%p) stub\n", this);
2545 HRESULT STDMETHODCALLTYPE
CDefView::AddObject(PITEMID_CHILD pidl
, UINT
*item
)
2547 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2551 HRESULT STDMETHODCALLTYPE
CDefView::GetObject(PITEMID_CHILD
*pidl
, UINT item
)
2553 TRACE("(%p)->(%p %d)\n", this, pidl
, item
);
2554 return Item(item
, pidl
);
2557 HRESULT STDMETHODCALLTYPE
CDefView::RemoveObject(PITEMID_CHILD pidl
, UINT
*item
)
2560 TRACE("(%p)->(%p %p)\n", this, pidl
, item
);
2564 *item
= LV_FindItemByPidl(ILFindLastID(pidl
));
2565 m_ListView
.DeleteItem(*item
);
2570 m_ListView
.DeleteAllItems();
2576 HRESULT STDMETHODCALLTYPE
CDefView::GetObjectCount(UINT
*count
)
2578 TRACE("(%p)->(%p)\n", this, count
);
2579 *count
= m_ListView
.GetItemCount();
2583 HRESULT STDMETHODCALLTYPE
CDefView::SetObjectCount(UINT count
, UINT flags
)
2585 FIXME("(%p)->(%d %x) stub\n", this, count
, flags
);
2589 HRESULT STDMETHODCALLTYPE
CDefView::UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
)
2591 FIXME("(%p)->(%p %p %p) stub\n", this, pidl_old
, pidl_new
, item
);
2595 HRESULT STDMETHODCALLTYPE
CDefView::RefreshObject(PITEMID_CHILD pidl
, UINT
*item
)
2597 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2601 HRESULT STDMETHODCALLTYPE
CDefView::SetRedraw(BOOL redraw
)
2603 TRACE("(%p)->(%d)\n", this, redraw
);
2604 m_ListView
.SetRedraw(redraw
);
2608 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedCount(UINT
*count
)
2610 FIXME("(%p)->(%p) stub\n", this, count
);
2614 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
)
2616 TRACE("(%p)->(%p %p)\n", this, pidl
, items
);
2618 *items
= GetSelections();
2622 *pidl
= static_cast<PCUITEMID_CHILD
*>(LocalAlloc(0, *items
* sizeof(PCUITEMID_CHILD
)));
2625 return E_OUTOFMEMORY
;
2628 /* it's documented that caller shouldn't PIDLs, only array itself */
2629 memcpy(*pidl
, m_apidl
, *items
* sizeof(PCUITEMID_CHILD
));
2635 HRESULT STDMETHODCALLTYPE
CDefView::IsDropOnSource(IDropTarget
*drop_target
)
2637 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2641 HRESULT STDMETHODCALLTYPE
CDefView::GetDragPoint(POINT
*pt
)
2643 FIXME("(%p)->(%p) stub\n", this, pt
);
2647 HRESULT STDMETHODCALLTYPE
CDefView::GetDropPoint(POINT
*pt
)
2649 FIXME("(%p)->(%p) stub\n", this, pt
);
2653 HRESULT STDMETHODCALLTYPE
CDefView::MoveIcons(IDataObject
*obj
)
2655 TRACE("(%p)->(%p)\n", this, obj
);
2659 HRESULT STDMETHODCALLTYPE
CDefView::SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
)
2661 FIXME("(%p)->(%p %p) stub\n", this, pidl
, pt
);
2665 HRESULT STDMETHODCALLTYPE
CDefView::IsBkDropTarget(IDropTarget
*drop_target
)
2667 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2671 HRESULT STDMETHODCALLTYPE
CDefView::SetClipboard(BOOL move
)
2673 FIXME("(%p)->(%d) stub\n", this, move
);
2677 HRESULT STDMETHODCALLTYPE
CDefView::SetPoints(IDataObject
*obj
)
2679 FIXME("(%p)->(%p) stub\n", this, obj
);
2683 HRESULT STDMETHODCALLTYPE
CDefView::GetItemSpacing(ITEMSPACING
*spacing
)
2685 FIXME("(%p)->(%p) stub\n", this, spacing
);
2689 HRESULT STDMETHODCALLTYPE
CDefView::SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
)
2691 FIXME("(%p)->(%p %p) stub\n", this, new_cb
, old_cb
);
2695 HRESULT STDMETHODCALLTYPE
CDefView::Select(UINT flags
)
2697 FIXME("(%p)->(%d) stub\n", this, flags
);
2701 HRESULT STDMETHODCALLTYPE
CDefView::QuerySupport(UINT
*support
)
2703 TRACE("(%p)->(%p)\n", this, support
);
2707 HRESULT STDMETHODCALLTYPE
CDefView::SetAutomationObject(IDispatch
*disp
)
2709 FIXME("(%p)->(%p) stub\n", this, disp
);
2713 /**********************************************************
2714 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2716 HRESULT WINAPI
CDefView::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD
*prgCmds
, OLECMDTEXT
*pCmdText
)
2718 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
2719 this, pguidCmdGroup
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
2722 return E_INVALIDARG
;
2724 for (UINT i
= 0; i
< cCmds
; i
++)
2726 FIXME("\tprgCmds[%d].cmdID = %d\n", i
, prgCmds
[i
].cmdID
);
2727 prgCmds
[i
].cmdf
= 0;
2730 return OLECMDERR_E_UNKNOWNGROUP
;
2733 /**********************************************************
2734 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2736 * nCmdID is the OLECMDID_* enumeration
2738 HRESULT WINAPI
CDefView::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
2740 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2741 this, debugstr_guid(pguidCmdGroup
), nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2744 return OLECMDERR_E_UNKNOWNGROUP
;
2746 if (IsEqualCLSID(*pguidCmdGroup
, m_Category
))
2748 if (nCmdID
== FCIDM_SHVIEW_AUTOARRANGE
)
2750 if (V_VT(pvaIn
) != VT_INT_PTR
)
2751 return OLECMDERR_E_NOTSUPPORTED
;
2755 params
.cbSize
= sizeof(params
);
2756 params
.rcExclude
= *(RECT
*) V_INTREF(pvaIn
);
2758 HMENU hView
= m_hView
;
2760 hView
= CreatePopupMenu();
2761 AppendMenuW(hView
, MF_STRING
, FCIDM_SHVIEW_BIGICON
, L
"Big!");
2762 AppendMenuW(hView
, MF_STRING
, FCIDM_SHVIEW_SMALLICON
, L
"Small!");
2763 AppendMenuW(hView
, MF_STRING
, FCIDM_SHVIEW_LISTVIEW
, L
"List!");
2764 AppendMenuW(hView
, MF_STRING
, FCIDM_SHVIEW_REPORTVIEW
, L
"Report!");
2769 PrepareShowViewMenu(hView
);
2771 TrackPopupMenuEx(hView
, TPM_LEFTALIGN
| TPM_TOPALIGN
, params
.rcExclude
.left
, params
.rcExclude
.bottom
, m_hWndParent
, ¶ms
);
2774 // pvaOut is VT_I4 with value 0x403 (cmd id of the new mode maybe?)
2775 V_VT(pvaOut
) = VT_I4
;
2776 V_I4(pvaOut
) = 0x403;
2780 if (IsEqualIID(*pguidCmdGroup
, CGID_Explorer
) &&
2782 (nCmdexecopt
== 4) && pvaOut
)
2785 if (IsEqualIID(*pguidCmdGroup
, CGID_ShellDocView
) &&
2790 return OLECMDERR_E_UNKNOWNGROUP
;
2793 /**********************************************************
2794 * ISVDropTarget implementation
2797 /******************************************************************************
2798 * drag_notify_subitem [Internal]
2800 * Figure out the shellfolder object, which is currently under the mouse cursor
2801 * and notify it via the IDropTarget interface.
2804 #define SCROLLAREAWIDTH 20
2806 HRESULT
CDefView::drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2808 LVHITTESTINFO htinfo
;
2813 /* Map from global to client coordinates and query the index of the listview-item, which is
2814 * currently under the mouse cursor. */
2817 htinfo
.flags
= LVHT_ONITEM
;
2818 ::ScreenToClient(m_ListView
, &htinfo
.pt
);
2819 lResult
= m_ListView
.HitTest(&htinfo
);
2821 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2822 ::GetClientRect(m_ListView
, &clientRect
);
2823 if (htinfo
.pt
.x
== m_ptLastMousePos
.x
&& htinfo
.pt
.y
== m_ptLastMousePos
.y
&&
2824 (htinfo
.pt
.x
< SCROLLAREAWIDTH
|| htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
||
2825 htinfo
.pt
.y
< SCROLLAREAWIDTH
|| htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
))
2827 m_cScrollDelay
= (m_cScrollDelay
+ 1) % 5; /* DragOver is called every 50 ms */
2828 if (m_cScrollDelay
== 0)
2830 /* Mouse did hover another 250 ms over the scroll-area */
2831 if (htinfo
.pt
.x
< SCROLLAREAWIDTH
)
2832 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEUP
, 0);
2834 if (htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
)
2835 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEDOWN
, 0);
2837 if (htinfo
.pt
.y
< SCROLLAREAWIDTH
)
2838 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEUP
, 0);
2840 if (htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
)
2841 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEDOWN
, 0);
2846 m_cScrollDelay
= 0; /* Reset, if the cursor is not over the listview's scroll-area */
2849 m_ptLastMousePos
= htinfo
.pt
;
2851 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2852 if (m_pCurDropTarget
&& lResult
== m_iDragOverItem
)
2853 return m_pCurDropTarget
->DragOver(grfKeyState
, pt
, pdwEffect
);
2855 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2856 if (m_pCurDropTarget
)
2858 m_pCurDropTarget
->DragLeave();
2859 m_pCurDropTarget
.Release();
2862 m_iDragOverItem
= lResult
;
2865 /* We are not above one of the listview's subitems. Bind to the parent folder's
2866 * DropTarget interface. */
2867 hr
= m_pSFParent
->QueryInterface(IID_PPV_ARG(IDropTarget
,&m_pCurDropTarget
));
2871 /* Query the relative PIDL of the shellfolder object represented by the currently
2872 * dragged over listview-item ... */
2873 PCUITEMID_CHILD pidl
= _PidlByItem(lResult
);
2875 /* ... and bind m_pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2876 hr
= m_pSFParent
->GetUIObjectOf(m_ListView
, 1, &pidl
, IID_NULL_PPV_ARG(IDropTarget
, &m_pCurDropTarget
));
2879 /* If anything failed, m_pCurDropTarget should be NULL now, which ought to be a save state. */
2883 /* Notify the item just entered via DragEnter. */
2884 return m_pCurDropTarget
->DragEnter(m_pCurDataObject
, grfKeyState
, pt
, pdwEffect
);
2887 HRESULT WINAPI
CDefView::DragEnter(IDataObject
*pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2889 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2890 m_pCurDataObject
= pDataObject
;
2891 pDataObject
->AddRef();
2893 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2896 HRESULT WINAPI
CDefView::DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2898 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2901 HRESULT WINAPI
CDefView::DragLeave()
2903 if (m_pCurDropTarget
)
2905 m_pCurDropTarget
->DragLeave();
2906 m_pCurDropTarget
.Release();
2909 if (m_pCurDataObject
!= NULL
)
2911 m_pCurDataObject
.Release();
2914 m_iDragOverItem
= 0;
2919 HRESULT WINAPI
CDefView::Drop(IDataObject
* pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2921 if (m_pCurDropTarget
)
2923 m_pCurDropTarget
->Drop(pDataObject
, grfKeyState
, pt
, pdwEffect
);
2924 m_pCurDropTarget
.Release();
2927 m_pCurDataObject
.Release();
2928 m_iDragOverItem
= 0;
2932 /**********************************************************
2933 * ISVDropSource implementation
2936 HRESULT WINAPI
CDefView::QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
)
2938 TRACE("(%p)\n", this);
2941 return DRAGDROP_S_CANCEL
;
2942 else if (!(grfKeyState
& MK_LBUTTON
) && !(grfKeyState
& MK_RBUTTON
))
2943 return DRAGDROP_S_DROP
;
2948 HRESULT WINAPI
CDefView::GiveFeedback(DWORD dwEffect
)
2950 TRACE("(%p)\n", this);
2952 return DRAGDROP_S_USEDEFAULTCURSORS
;
2955 /**********************************************************
2956 * ISVViewObject implementation
2959 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
)
2961 FIXME("Stub: this=%p\n", this);
2966 HRESULT WINAPI
CDefView::GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
, HDC hicTargetDevice
, LOGPALETTE
**ppColorSet
)
2968 FIXME("Stub: this=%p\n", this);
2973 HRESULT WINAPI
CDefView::Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
)
2975 FIXME("Stub: this=%p\n", this);
2980 HRESULT WINAPI
CDefView::Unfreeze(DWORD dwFreeze
)
2982 FIXME("Stub: this=%p\n", this);
2987 HRESULT WINAPI
CDefView::SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
)
2989 FIXME("partial stub: %p %08x %08x %p\n", this, aspects
, advf
, pAdvSink
);
2991 /* FIXME: we set the AdviseSink, but never use it to send any advice */
2992 m_pAdvSink
= pAdvSink
;
2993 m_dwAspects
= aspects
;
2999 HRESULT WINAPI
CDefView::GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
)
3001 TRACE("this=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n", this, pAspects
, pAdvf
, ppAdvSink
);
3005 *ppAdvSink
= m_pAdvSink
;
3006 m_pAdvSink
.p
->AddRef();
3010 *pAspects
= m_dwAspects
;
3018 HRESULT STDMETHODCALLTYPE
CDefView::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
3020 if (IsEqualIID(guidService
, SID_IShellBrowser
))
3021 return m_pShellBrowser
->QueryInterface(riid
, ppvObject
);
3022 else if(IsEqualIID(guidService
, SID_IFolderView
))
3023 return QueryInterface(riid
, ppvObject
);
3025 return E_NOINTERFACE
;
3028 HRESULT
CDefView::_MergeToolbar()
3030 CComPtr
<IExplorerToolbar
> ptb
; // [sp+8h] [bp-4h]@1
3034 hr
= IUnknown_QueryService(m_pShellBrowser
, IID_IExplorerToolbar
, IID_PPV_ARG(IExplorerToolbar
, &ptb
));
3038 m_Category
= CGID_DefViewFrame
;
3040 hr
= ptb
->SetCommandTarget(static_cast<IOleCommandTarget
*>(this), &m_Category
, 0);
3048 hr
= ptb
->AddButtons(&m_Category
, buttonsCount
, buttons
);
3055 /**********************************************************
3056 * IShellView_Constructor
3058 HRESULT WINAPI
IShellView_Constructor(IShellFolder
*pFolder
, IShellView
**newView
)
3060 return ShellObjectCreatorInit
<CDefView
>(pFolder
, IID_IShellView
, newView
);