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
);
128 void UpdateStatusbar();
130 void SetStyle(DWORD dwAdd
, DWORD dwRemove
);
132 void UpdateListColors();
134 static INT CALLBACK
CompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
);
135 static INT CALLBACK
ListViewCompareItems(LPARAM lParam1
, LPARAM lParam2
, LPARAM lpData
);
137 PCUITEMID_CHILD
_PidlByItem(int i
);
138 PCUITEMID_CHILD
_PidlByItem(LVITEM
& lvItem
);
139 int LV_FindItemByPidl(PCUITEMID_CHILD pidl
);
140 BOOLEAN
LV_AddItem(PCUITEMID_CHILD pidl
);
141 BOOLEAN
LV_DeleteItem(PCUITEMID_CHILD pidl
);
142 BOOLEAN
LV_RenameItem(PCUITEMID_CHILD pidlOld
, PCUITEMID_CHILD pidlNew
);
143 BOOLEAN
LV_ProdItem(PCUITEMID_CHILD pidl
);
144 static INT CALLBACK
fill_list(LPVOID ptr
, LPVOID arg
);
146 HMENU
BuildFileMenu();
147 void PrepareShowFileMenu(HMENU hSubMenu
);
148 void PrepareShowViewMenu(HMENU hSubMenu
);
149 UINT
GetSelections();
150 HRESULT
OpenSelectedItems();
152 void DoActivate(UINT uState
);
153 HRESULT
drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
154 LRESULT
OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
);
156 // *** IOleWindow methods ***
157 virtual HRESULT STDMETHODCALLTYPE
GetWindow(HWND
*lphwnd
);
158 virtual HRESULT STDMETHODCALLTYPE
ContextSensitiveHelp(BOOL fEnterMode
);
160 // *** IShellView methods ***
161 virtual HRESULT STDMETHODCALLTYPE
TranslateAccelerator(MSG
*pmsg
);
162 virtual HRESULT STDMETHODCALLTYPE
EnableModeless(BOOL fEnable
);
163 virtual HRESULT STDMETHODCALLTYPE
UIActivate(UINT uState
);
164 virtual HRESULT STDMETHODCALLTYPE
Refresh();
165 virtual HRESULT STDMETHODCALLTYPE
CreateViewWindow(IShellView
*psvPrevious
, LPCFOLDERSETTINGS pfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
);
166 virtual HRESULT STDMETHODCALLTYPE
DestroyViewWindow();
167 virtual HRESULT STDMETHODCALLTYPE
GetCurrentInfo(LPFOLDERSETTINGS pfs
);
168 virtual HRESULT STDMETHODCALLTYPE
AddPropertySheetPages(DWORD dwReserved
, LPFNSVADDPROPSHEETPAGE pfn
, LPARAM lparam
);
169 virtual HRESULT STDMETHODCALLTYPE
SaveViewState();
170 virtual HRESULT STDMETHODCALLTYPE
SelectItem(PCUITEMID_CHILD pidlItem
, SVSIF uFlags
);
171 virtual HRESULT STDMETHODCALLTYPE
GetItemObject(UINT uItem
, REFIID riid
, void **ppv
);
173 // *** IFolderView methods ***
174 virtual HRESULT STDMETHODCALLTYPE
GetCurrentViewMode(UINT
*pViewMode
);
175 virtual HRESULT STDMETHODCALLTYPE
SetCurrentViewMode(UINT ViewMode
);
176 virtual HRESULT STDMETHODCALLTYPE
GetFolder(REFIID riid
, void **ppv
);
177 virtual HRESULT STDMETHODCALLTYPE
Item(int iItemIndex
, PITEMID_CHILD
*ppidl
);
178 virtual HRESULT STDMETHODCALLTYPE
ItemCount(UINT uFlags
, int *pcItems
);
179 virtual HRESULT STDMETHODCALLTYPE
Items(UINT uFlags
, REFIID riid
, void **ppv
);
180 virtual HRESULT STDMETHODCALLTYPE
GetSelectionMarkedItem(int *piItem
);
181 virtual HRESULT STDMETHODCALLTYPE
GetFocusedItem(int *piItem
);
182 virtual HRESULT STDMETHODCALLTYPE
GetItemPosition(PCUITEMID_CHILD pidl
, POINT
*ppt
);
183 virtual HRESULT STDMETHODCALLTYPE
GetSpacing(POINT
*ppt
);
184 virtual HRESULT STDMETHODCALLTYPE
GetDefaultSpacing(POINT
*ppt
);
185 virtual HRESULT STDMETHODCALLTYPE
GetAutoArrange();
186 virtual HRESULT STDMETHODCALLTYPE
SelectItem(int iItem
, DWORD dwFlags
);
187 virtual HRESULT STDMETHODCALLTYPE
SelectAndPositionItems(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD dwFlags
);
189 // *** IShellFolderView methods ***
190 virtual HRESULT STDMETHODCALLTYPE
Rearrange(LPARAM sort
);
191 virtual HRESULT STDMETHODCALLTYPE
GetArrangeParam(LPARAM
*sort
);
192 virtual HRESULT STDMETHODCALLTYPE
ArrangeGrid();
193 virtual HRESULT STDMETHODCALLTYPE
AutoArrange();
194 virtual HRESULT STDMETHODCALLTYPE
AddObject(PITEMID_CHILD pidl
, UINT
*item
);
195 virtual HRESULT STDMETHODCALLTYPE
GetObject(PITEMID_CHILD
*pidl
, UINT item
);
196 virtual HRESULT STDMETHODCALLTYPE
RemoveObject(PITEMID_CHILD pidl
, UINT
*item
);
197 virtual HRESULT STDMETHODCALLTYPE
GetObjectCount(UINT
*count
);
198 virtual HRESULT STDMETHODCALLTYPE
SetObjectCount(UINT count
, UINT flags
);
199 virtual HRESULT STDMETHODCALLTYPE
UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
);
200 virtual HRESULT STDMETHODCALLTYPE
RefreshObject(PITEMID_CHILD pidl
, UINT
*item
);
201 virtual HRESULT STDMETHODCALLTYPE
SetRedraw(BOOL redraw
);
202 virtual HRESULT STDMETHODCALLTYPE
GetSelectedCount(UINT
*count
);
203 virtual HRESULT STDMETHODCALLTYPE
GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
);
204 virtual HRESULT STDMETHODCALLTYPE
IsDropOnSource(IDropTarget
*drop_target
);
205 virtual HRESULT STDMETHODCALLTYPE
GetDragPoint(POINT
*pt
);
206 virtual HRESULT STDMETHODCALLTYPE
GetDropPoint(POINT
*pt
);
207 virtual HRESULT STDMETHODCALLTYPE
MoveIcons(IDataObject
*obj
);
208 virtual HRESULT STDMETHODCALLTYPE
SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
);
209 virtual HRESULT STDMETHODCALLTYPE
IsBkDropTarget(IDropTarget
*drop_target
);
210 virtual HRESULT STDMETHODCALLTYPE
SetClipboard(BOOL move
);
211 virtual HRESULT STDMETHODCALLTYPE
SetPoints(IDataObject
*obj
);
212 virtual HRESULT STDMETHODCALLTYPE
GetItemSpacing(ITEMSPACING
*spacing
);
213 virtual HRESULT STDMETHODCALLTYPE
SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
);
214 virtual HRESULT STDMETHODCALLTYPE
Select(UINT flags
);
215 virtual HRESULT STDMETHODCALLTYPE
QuerySupport(UINT
*support
);
216 virtual HRESULT STDMETHODCALLTYPE
SetAutomationObject(IDispatch
*disp
);
218 // *** IOleCommandTarget methods ***
219 virtual HRESULT STDMETHODCALLTYPE
QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
);
220 virtual HRESULT STDMETHODCALLTYPE
Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
);
222 // *** IDropTarget methods ***
223 virtual HRESULT STDMETHODCALLTYPE
DragEnter(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
224 virtual HRESULT STDMETHODCALLTYPE
DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
225 virtual HRESULT STDMETHODCALLTYPE
DragLeave();
226 virtual HRESULT STDMETHODCALLTYPE
Drop(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
228 // *** IDropSource methods ***
229 virtual HRESULT STDMETHODCALLTYPE
QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
);
230 virtual HRESULT STDMETHODCALLTYPE
GiveFeedback(DWORD dwEffect
);
232 // *** IViewObject methods ***
233 virtual HRESULT STDMETHODCALLTYPE
Draw(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
,
234 HDC hdcTargetDev
, HDC hdcDraw
, LPCRECTL lprcBounds
, LPCRECTL lprcWBounds
,
235 BOOL ( STDMETHODCALLTYPE
*pfnContinue
)(ULONG_PTR dwContinue
), ULONG_PTR dwContinue
);
236 virtual HRESULT STDMETHODCALLTYPE
GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
,
237 DVTARGETDEVICE
*ptd
, HDC hicTargetDev
, LOGPALETTE
**ppColorSet
);
238 virtual HRESULT STDMETHODCALLTYPE
Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
);
239 virtual HRESULT STDMETHODCALLTYPE
Unfreeze(DWORD dwFreeze
);
240 virtual HRESULT STDMETHODCALLTYPE
SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
);
241 virtual HRESULT STDMETHODCALLTYPE
GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
);
243 // *** IServiceProvider methods ***
244 virtual HRESULT STDMETHODCALLTYPE
QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
);
247 LRESULT
OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
248 LRESULT
OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
249 LRESULT
OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
250 LRESULT
OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
251 LRESULT
OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
252 LRESULT
OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
253 LRESULT
OnNCCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
254 LRESULT
OnNCDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
255 LRESULT
OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
256 LRESULT
OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
257 LRESULT
OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
258 LRESULT
OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
259 LRESULT
OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
260 LRESULT
OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
261 LRESULT
OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
262 LRESULT
OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
263 LRESULT
OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
264 LRESULT
OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
265 LRESULT
OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
266 LRESULT
OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
268 static ATL::CWndClassInfo
& GetWndClassInfo()
270 static ATL::CWndClassInfo wc
=
272 { sizeof(WNDCLASSEX
), 0, StartWindowProc
,
274 LoadCursor(NULL
, IDC_ARROW
), (HBRUSH
)(COLOR_BACKGROUND
+ 1), NULL
, SV_CLASS_NAME
, NULL
276 NULL
, NULL
, IDC_ARROW
, TRUE
, 0, _T("")
281 virtual WNDPROC
GetWindowProc()
286 static LRESULT CALLBACK
WindowProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
291 // must hold a reference during message handling
292 pThis
= reinterpret_cast<CDefView
*>(hWnd
);
294 result
= CWindowImpl
<CDefView
, CWindow
, CControlWinTraits
>::WindowProc(hWnd
, uMsg
, wParam
, lParam
);
299 BEGIN_MSG_MAP(CDefView
)
300 MESSAGE_HANDLER(WM_SIZE
, OnSize
)
301 MESSAGE_HANDLER(WM_SETFOCUS
, OnSetFocus
)
302 MESSAGE_HANDLER(WM_KILLFOCUS
, OnKillFocus
)
303 MESSAGE_HANDLER(WM_NCCREATE
, OnNCCreate
)
304 MESSAGE_HANDLER(WM_NCDESTROY
, OnNCDestroy
)
305 MESSAGE_HANDLER(WM_CREATE
, OnCreate
)
306 MESSAGE_HANDLER(WM_ACTIVATE
, OnActivate
)
307 MESSAGE_HANDLER(WM_NOTIFY
, OnNotify
)
308 MESSAGE_HANDLER(WM_COMMAND
, OnCommand
)
309 MESSAGE_HANDLER(SHV_CHANGE_NOTIFY
, OnChangeNotify
)
310 MESSAGE_HANDLER(WM_CONTEXTMENU
, OnContextMenu
)
311 MESSAGE_HANDLER(WM_DRAWITEM
, OnCustomItem
)
312 MESSAGE_HANDLER(WM_MEASUREITEM
, OnCustomItem
)
313 MESSAGE_HANDLER(WM_SHOWWINDOW
, OnShowWindow
)
314 MESSAGE_HANDLER(WM_GETDLGCODE
, OnGetDlgCode
)
315 MESSAGE_HANDLER(WM_DESTROY
, OnDestroy
)
316 MESSAGE_HANDLER(WM_ERASEBKGND
, OnEraseBackground
)
317 MESSAGE_HANDLER(WM_SYSCOLORCHANGE
, OnSysColorChange
)
318 MESSAGE_HANDLER(CWM_GETISHELLBROWSER
, OnGetShellBrowser
)
319 MESSAGE_HANDLER(WM_SETTINGCHANGE
, OnSettingChange
)
320 MESSAGE_HANDLER(WM_INITMENUPOPUP
, OnInitMenuPopup
)
323 BEGIN_COM_MAP(CDefView
)
324 // Windows returns E_NOINTERFACE for IOleWindow
325 // COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
326 COM_INTERFACE_ENTRY_IID(IID_IShellView
, IShellView
)
327 COM_INTERFACE_ENTRY_IID(IID_IFolderView
, IFolderView
)
328 COM_INTERFACE_ENTRY_IID(IID_IShellFolderView
, IShellFolderView
)
329 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget
, IOleCommandTarget
)
330 COM_INTERFACE_ENTRY_IID(IID_IDropTarget
, IDropTarget
)
331 COM_INTERFACE_ENTRY_IID(IID_IDropSource
, IDropSource
)
332 COM_INTERFACE_ENTRY_IID(IID_IViewObject
, IViewObject
)
333 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider
, IServiceProvider
)
337 /* ListView Header ID's */
338 #define LISTVIEW_COLUMN_NAME 0
339 #define LISTVIEW_COLUMN_SIZE 1
340 #define LISTVIEW_COLUMN_TYPE 2
341 #define LISTVIEW_COLUMN_TIME 3
342 #define LISTVIEW_COLUMN_ATTRIB 4
345 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
346 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
347 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
349 #define ID_LISTVIEW 1
352 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
353 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
354 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
356 typedef void (CALLBACK
*PFNSHGETSETTINGSPROC
)(LPSHELLFLAGSTATE lpsfs
, DWORD dwMask
);
358 CDefView::CDefView() :
362 m_menusLoaded(FALSE
),
377 ZeroMemory(&m_FolderSettings
, sizeof(m_FolderSettings
));
378 ZeroMemory(&m_sortInfo
, sizeof(m_sortInfo
));
379 ZeroMemory(&m_ptLastMousePos
, sizeof(m_ptLastMousePos
));
380 ZeroMemory(&m_Category
, sizeof(m_Category
));
383 CDefView::~CDefView()
385 TRACE(" destroying IShellView(%p)\n", this);
395 HRESULT WINAPI
CDefView::Initialize(IShellFolder
*shellFolder
)
397 m_pSFParent
= shellFolder
;
398 shellFolder
->QueryInterface(IID_PPV_ARG(IShellFolder2
, &m_pSF2Parent
));
403 /**********************************************************
405 * ##### helperfunctions for communication with ICommDlgBrowser #####
407 HRESULT
CDefView::IncludeObject(PCUITEMID_CHILD pidl
)
411 if (m_pCommDlgBrowser
.p
!= NULL
)
413 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl
);
414 ret
= m_pCommDlgBrowser
->IncludeObject(this, pidl
);
415 TRACE("--0x%08x\n", ret
);
421 HRESULT
CDefView::OnDefaultCommand()
423 HRESULT ret
= S_FALSE
;
425 if (m_pCommDlgBrowser
.p
!= NULL
)
427 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
428 ret
= m_pCommDlgBrowser
->OnDefaultCommand(this);
429 TRACE("-- returns %08x\n", ret
);
435 HRESULT
CDefView::OnStateChange(UINT uFlags
)
437 HRESULT ret
= S_FALSE
;
439 if (m_pCommDlgBrowser
.p
!= NULL
)
441 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags
);
442 ret
= m_pCommDlgBrowser
->OnStateChange(this, uFlags
);
448 /**********************************************************
449 * set the toolbar of the filedialog buttons
451 * - activates the buttons from the shellbrowser according to
454 void CDefView::CheckToolbar()
460 if (m_pCommDlgBrowser
!= NULL
)
462 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
463 FCIDM_TB_SMALLICON
, (m_FolderSettings
.ViewMode
== FVM_LIST
) ? TRUE
: FALSE
, &result
);
464 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
465 FCIDM_TB_REPORTVIEW
, (m_FolderSettings
.ViewMode
== FVM_DETAILS
) ? TRUE
: FALSE
, &result
);
466 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
467 FCIDM_TB_SMALLICON
, TRUE
, &result
);
468 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
469 FCIDM_TB_REPORTVIEW
, TRUE
, &result
);
473 void CDefView::UpdateStatusbar()
475 WCHAR szFormat
[MAX_PATH
] = {0};
476 WCHAR szObjects
[MAX_PATH
] = {0};
479 cSelectedItems
= m_ListView
.GetSelectedCount();
482 LoadStringW(shell32_hInstance
, IDS_OBJECTS_SELECTED
, szFormat
, _countof(szFormat
));
483 StringCchPrintfW(szObjects
, MAX_PATH
, szFormat
, cSelectedItems
);
487 LoadStringW(shell32_hInstance
, IDS_OBJECTS
, szFormat
, _countof(szFormat
));
488 StringCchPrintfW(szObjects
, MAX_PATH
, szFormat
, m_ListView
.GetItemCount());
490 m_pShellBrowser
->SetStatusTextSB(szObjects
);
493 /**********************************************************
495 * ##### helperfunctions for initializing the view #####
497 /**********************************************************
498 * change the style of the listview control
500 void CDefView::SetStyle(DWORD dwAdd
, DWORD dwRemove
)
504 TRACE("(%p)\n", this);
506 tmpstyle
= ::GetWindowLongPtrW(m_ListView
, GWL_STYLE
);
507 ::SetWindowLongPtrW(m_ListView
, GWL_STYLE
, dwAdd
| (tmpstyle
& ~dwRemove
));
510 /**********************************************************
511 * ShellView_CreateList()
513 * - creates the list view window
515 BOOL
CDefView::CreateList()
516 { DWORD dwStyle
, dwExStyle
;
520 dwStyle
= WS_TABSTOP
| WS_VISIBLE
| WS_CHILDWINDOW
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
|
521 LVS_SHAREIMAGELISTS
| LVS_EDITLABELS
| LVS_AUTOARRANGE
;
522 dwExStyle
= WS_EX_CLIENTEDGE
;
524 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
525 dwStyle
|= LVS_ALIGNLEFT
;
527 dwStyle
|= LVS_ALIGNTOP
| LVS_SHOWSELALWAYS
;
529 switch (m_FolderSettings
.ViewMode
)
536 dwStyle
|= LVS_REPORT
;
540 dwStyle
|= LVS_SMALLICON
;
552 if (m_FolderSettings
.fFlags
& FWF_AUTOARRANGE
)
553 dwStyle
|= LVS_AUTOARRANGE
;
555 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
556 m_FolderSettings
.fFlags
|= FWF_NOCLIENTEDGE
| FWF_NOSCROLL
;
558 if (m_FolderSettings
.fFlags
& FWF_SINGLESEL
)
559 dwStyle
|= LVS_SINGLESEL
;
561 if (m_FolderSettings
.fFlags
& FWF_NOCLIENTEDGE
)
562 dwExStyle
&= ~WS_EX_CLIENTEDGE
;
564 RECT rcListView
= {0,0,0,0};
565 m_ListView
.Create(m_hWnd
, rcListView
, NULL
,dwStyle
, dwExStyle
, ID_LISTVIEW
);
570 m_sortInfo
.bIsAscending
= TRUE
;
571 m_sortInfo
.nHeaderID
= -1;
572 m_sortInfo
.nLastHeaderID
= -1;
576 /* UpdateShellSettings(); */
580 void CDefView::UpdateListColors()
582 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
584 /* Check if drop shadows option is enabled */
585 BOOL bDropShadow
= FALSE
;
586 DWORD cbDropShadow
= sizeof(bDropShadow
);
587 WCHAR wszBuf
[16] = L
"";
589 RegGetValueW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
590 L
"ListviewShadow", RRF_RT_DWORD
, NULL
, &bDropShadow
, &cbDropShadow
);
591 if (bDropShadow
&& SystemParametersInfoW(SPI_GETDESKWALLPAPER
, _countof(wszBuf
), wszBuf
, 0) && wszBuf
[0])
593 m_ListView
.SetTextBkColor(CLR_NONE
);
594 m_ListView
.SetBkColor(CLR_NONE
);
595 m_ListView
.SetTextColor(RGB(255, 255, 255));
596 m_ListView
.SetExtendedListViewStyle(LVS_EX_TRANSPARENTSHADOWTEXT
, LVS_EX_TRANSPARENTSHADOWTEXT
);
600 COLORREF crDesktop
= GetSysColor(COLOR_DESKTOP
);
601 m_ListView
.SetTextBkColor(crDesktop
);
602 m_ListView
.SetBkColor(crDesktop
);
603 if (GetRValue(crDesktop
) + GetGValue(crDesktop
) + GetBValue(crDesktop
) > 128 * 3)
604 m_ListView
.SetTextColor(RGB(0, 0, 0));
606 m_ListView
.SetTextColor(RGB(255, 255, 255));
607 m_ListView
.SetExtendedListViewStyle(LVS_EX_TRANSPARENTSHADOWTEXT
);
612 /**********************************************************
613 * ShellView_InitList()
615 * - adds all needed columns to the shellview
617 BOOL
CDefView::InitList()
621 HIMAGELIST big_icons
, small_icons
;
625 m_ListView
.DeleteAllItems();
629 for (int i
= 0; 1; i
++)
631 if (FAILED(m_pSF2Parent
->GetDetailsOf(NULL
, i
, &sd
)))
633 StrRetToStrNW( szTemp
, 50, &sd
.str
, NULL
);
634 m_ListView
.InsertColumn(i
, szTemp
, sd
.fmt
, sd
.cxChar
* 8);
643 Shell_GetImageLists(&big_icons
, &small_icons
);
644 m_ListView
.SetImageList(big_icons
, LVSIL_NORMAL
);
645 m_ListView
.SetImageList(small_icons
, LVSIL_SMALL
);
650 /**********************************************************
651 * ShellView_CompareItems()
654 * internal, CALLBACK for DSA_Sort
656 INT CALLBACK
CDefView::CompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
)
659 TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1
, lParam2
, (LPVOID
) lpData
);
664 IShellFolder
* psf
= reinterpret_cast<IShellFolder
*>(lpData
);
665 PCUIDLIST_RELATIVE pidl1
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam1
);
666 PCUIDLIST_RELATIVE pidl2
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam2
);
668 ret
= (SHORT
)SCODE_CODE(psf
->CompareIDs(0, pidl1
, pidl2
));
669 TRACE("ret=%i\n", ret
);
674 /*************************************************************************
675 * ShellView_ListViewCompareItems
677 * Compare Function for the Listview (FileOpen Dialog)
680 * lParam1 [I] the first ItemIdList to compare with
681 * lParam2 [I] the second ItemIdList to compare with
682 * lpData [I] The column ID for the header Ctrl to process
685 * A negative value if the first item should precede the second,
686 * a positive value if the first item should follow the second,
687 * or zero if the two items are equivalent
690 * FIXME: function does what ShellView_CompareItems is supposed to do.
691 * unify it and figure out how to use the undocumented first parameter
692 * of IShellFolder_CompareIDs to do the job this function does and
693 * move this code to IShellFolder.
694 * make LISTVIEW_SORT_INFO obsolete
695 * the way this function works is only usable if we had only
696 * filesystemfolders (25/10/99 jsch)
698 INT CALLBACK
CDefView::ListViewCompareItems(LPARAM lParam1
, LPARAM lParam2
, LPARAM lpData
)
702 char strName1
[MAX_PATH
], strName2
[MAX_PATH
];
703 BOOL bIsFolder1
, bIsFolder2
, bIsBothFolder
;
704 PCUIDLIST_RELATIVE pidl1
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam1
);
705 PCUIDLIST_RELATIVE pidl2
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam2
);
706 LISTVIEW_SORT_INFO
*pSortInfo
= reinterpret_cast<LPLISTVIEW_SORT_INFO
>(lpData
);
709 bIsFolder1
= _ILIsFolder(pidl1
);
710 bIsFolder2
= _ILIsFolder(pidl2
);
711 bIsBothFolder
= bIsFolder1
&& bIsFolder2
;
713 /* When sorting between a File and a Folder, the Folder gets sorted first */
714 if ( (bIsFolder1
|| bIsFolder2
) && !bIsBothFolder
)
716 nDiff
= bIsFolder1
? -1 : 1;
720 /* Sort by Time: Folders or Files can be sorted */
722 if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_TIME
)
724 _ILGetFileDateTime(pidl1
, &fd1
);
725 _ILGetFileDateTime(pidl2
, &fd2
);
726 nDiff
= CompareFileTime(&fd2
, &fd1
);
728 /* Sort by Attribute: Folder or Files can be sorted */
729 else if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_ATTRIB
)
731 _ILGetFileAttributes(pidl1
, strName1
, MAX_PATH
);
732 _ILGetFileAttributes(pidl2
, strName2
, MAX_PATH
);
733 nDiff
= lstrcmpiA(strName1
, strName2
);
735 /* Sort by FileName: Folder or Files can be sorted */
736 else if (pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_NAME
|| bIsBothFolder
)
739 _ILSimpleGetText(pidl1
, strName1
, MAX_PATH
);
740 _ILSimpleGetText(pidl2
, strName2
, MAX_PATH
);
741 nDiff
= lstrcmpiA(strName1
, strName2
);
743 /* Sort by File Size, Only valid for Files */
744 else if (pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_SIZE
)
746 nDiff
= (INT
)(_ILGetFileSize(pidl1
, NULL
, 0) - _ILGetFileSize(pidl2
, NULL
, 0));
748 /* Sort by File Type, Only valid for Files */
749 else if (pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_TYPE
)
752 _ILGetFileType(pidl1
, strName1
, MAX_PATH
);
753 _ILGetFileType(pidl2
, strName2
, MAX_PATH
);
754 nDiff
= lstrcmpiA(strName1
, strName2
);
757 /* If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
761 _ILSimpleGetText(pidl1
, strName1
, MAX_PATH
);
762 _ILSimpleGetText(pidl2
, strName2
, MAX_PATH
);
763 nDiff
= lstrcmpiA(strName1
, strName2
);
766 if (!pSortInfo
->bIsAscending
)
774 PCUITEMID_CHILD
CDefView::_PidlByItem(int i
)
776 return reinterpret_cast<PCUITEMID_CHILD
>(m_ListView
.GetItemData(i
));
779 PCUITEMID_CHILD
CDefView::_PidlByItem(LVITEM
& lvItem
)
781 return reinterpret_cast<PCUITEMID_CHILD
>(lvItem
.lParam
);
784 /**********************************************************
785 * LV_FindItemByPidl()
787 int CDefView::LV_FindItemByPidl(PCUITEMID_CHILD pidl
)
789 int cItems
= m_ListView
.GetItemCount();
791 for (int i
= 0; i
<cItems
; i
++)
793 PCUITEMID_CHILD currentpidl
= _PidlByItem(i
);
794 HRESULT hr
= m_pSFParent
->CompareIDs(0, pidl
, currentpidl
);
796 if (SUCCEEDED(hr
) && !HRESULT_CODE(hr
))
804 /**********************************************************
807 BOOLEAN
CDefView::LV_AddItem(PCUITEMID_CHILD pidl
)
811 TRACE("(%p)(pidl=%p)\n", this, pidl
);
813 lvItem
.mask
= LVIF_TEXT
| LVIF_IMAGE
| LVIF_PARAM
; /*set the mask*/
814 lvItem
.iItem
= m_ListView
.GetItemCount(); /*add the item to the end of the list*/
816 lvItem
.lParam
= reinterpret_cast<LPARAM
>(ILClone(pidl
)); /*set the item's data*/
817 lvItem
.pszText
= LPSTR_TEXTCALLBACKW
; /*get text on a callback basis*/
818 lvItem
.iImage
= I_IMAGECALLBACK
; /*get the image on a callback basis*/
819 lvItem
.stateMask
= LVIS_CUT
;
821 if (m_ListView
.InsertItem(&lvItem
) == -1)
827 /**********************************************************
830 BOOLEAN
CDefView::LV_DeleteItem(PCUITEMID_CHILD pidl
)
834 TRACE("(%p)(pidl=%p)\n", this, pidl
);
836 nIndex
= LV_FindItemByPidl(pidl
);
838 return (-1 == m_ListView
.DeleteItem(nIndex
)) ? FALSE
: TRUE
;
841 /**********************************************************
844 BOOLEAN
CDefView::LV_RenameItem(PCUITEMID_CHILD pidlOld
, PCUITEMID_CHILD pidlNew
)
849 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", this, pidlOld
, pidlNew
);
851 nItem
= LV_FindItemByPidl(pidlOld
);
855 lvItem
.mask
= LVIF_PARAM
; /* only the pidl */
856 lvItem
.iItem
= nItem
;
857 m_ListView
.GetItem(&lvItem
);
859 SHFree(reinterpret_cast<LPVOID
>(lvItem
.lParam
));
860 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
861 lvItem
.iItem
= nItem
;
862 lvItem
.lParam
= reinterpret_cast<LPARAM
>(ILClone(pidlNew
)); /* set the item's data */
863 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
864 m_ListView
.SetItem(&lvItem
);
865 m_ListView
.Update(nItem
);
866 return TRUE
; /* FIXME: better handling */
872 /**********************************************************
875 BOOLEAN
CDefView::LV_ProdItem(PCUITEMID_CHILD pidl
)
880 TRACE("(%p)(pidl=%p)\n", this, pidl
);
882 nItem
= LV_FindItemByPidl(pidl
);
886 lvItem
.mask
= LVIF_IMAGE
;
887 lvItem
.iItem
= nItem
;
888 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
889 m_ListView
.SetItem(&lvItem
);
890 m_ListView
.Update(nItem
);
897 /**********************************************************
898 * ShellView_FillList()
900 * - gets the objectlist from the shellfolder
902 * - fills the list into the view
904 INT CALLBACK
CDefView::fill_list( LPVOID ptr
, LPVOID arg
)
906 PITEMID_CHILD pidl
= static_cast<PITEMID_CHILD
>(ptr
);
907 CDefView
*pThis
= static_cast<CDefView
*>(arg
);
909 /* in a commdlg This works as a filemask*/
910 if (pThis
->IncludeObject(pidl
) == S_OK
)
911 pThis
->LV_AddItem(pidl
);
917 HRESULT
CDefView::FillList()
919 CComPtr
<IEnumIDList
> pEnumIDList
;
925 DWORD dFlags
= SHCONTF_NONFOLDERS
| SHCONTF_FOLDERS
;
929 /* determine if there is a setting to show all the hidden files/folders */
930 if (RegOpenKeyExW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", 0, KEY_QUERY_VALUE
, &hKey
) == ERROR_SUCCESS
)
932 DWORD dataLength
, flagVal
;
934 dataLength
= sizeof(flagVal
);
935 if (RegQueryValueExW(hKey
, L
"Hidden", NULL
, NULL
, (LPBYTE
)&flagVal
, &dataLength
) == ERROR_SUCCESS
)
937 /* if the value is 1, then show all hidden files/folders */
940 dFlags
|= SHCONTF_INCLUDEHIDDEN
;
941 m_ListView
.SendMessageW(LVM_SETCALLBACKMASK
, LVIS_CUT
, 0);
949 /* get the itemlist from the shfolder */
950 hRes
= m_pSFParent
->EnumObjects(m_hWnd
, dFlags
, &pEnumIDList
);
958 /* create a pointer array */
959 hdpa
= DPA_Create(16);
962 return(E_OUTOFMEMORY
);
965 /* copy the items into the array*/
966 while((S_OK
== pEnumIDList
->Next(1, &pidl
, &dwFetched
)) && dwFetched
)
968 if (DPA_InsertPtr(hdpa
, 0x7fff, pidl
) == -1)
975 DPA_Sort(hdpa
, CompareItems
, reinterpret_cast<LPARAM
>(m_pSFParent
.p
));
977 /*turn the listview's redrawing off*/
978 m_ListView
.SetRedraw(FALSE
);
980 DPA_DestroyCallback( hdpa
, fill_list
, this);
982 /*turn the listview's redrawing back on and force it to draw*/
983 m_ListView
.SetRedraw(TRUE
);
988 LRESULT
CDefView::OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
990 m_ListView
.UpdateWindow();
995 LRESULT
CDefView::OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
997 return m_ListView
.SendMessageW(uMsg
, 0, 0);
1000 LRESULT
CDefView::OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1007 DestroyMenu(m_hMenu
);
1010 RevokeDragDrop(m_hWnd
);
1011 SHChangeNotifyDeregister(m_hNotify
);
1013 SHFree(m_pidlParent
);
1014 m_pidlParent
= NULL
;
1020 LRESULT
CDefView::OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1022 /* redirect to parent */
1023 if (m_FolderSettings
.fFlags
& (FWF_DESKTOP
| FWF_TRANSPARENT
))
1024 return SendMessageW(GetParent(), WM_ERASEBKGND
, wParam
, lParam
);
1030 LRESULT
CDefView::OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1032 /* Update desktop labels color */
1035 /* Forward WM_SYSCOLORCHANGE to common controls */
1036 return m_ListView
.SendMessageW(uMsg
, 0, 0);
1039 LRESULT
CDefView::OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1041 return reinterpret_cast<LRESULT
>(m_pShellBrowser
.p
);
1044 LRESULT
CDefView::OnNCCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1051 LRESULT
CDefView::OnNCDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1058 /**********************************************************
1059 * ShellView_OnCreate()
1061 LRESULT
CDefView::OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1063 CComPtr
<IDropTarget
> pdt
;
1064 SHChangeNotifyEntry ntreg
;
1065 CComPtr
<IPersistFolder2
> ppf2
;
1067 TRACE("%p\n", this);
1077 if (SUCCEEDED(QueryInterface(IID_PPV_ARG(IDropTarget
, &pdt
))))
1079 if (FAILED(RegisterDragDrop(m_hWnd
, pdt
)))
1080 ERR("Registering Drag Drop Failed");
1083 /* register for receiving notifications */
1084 m_pSFParent
->QueryInterface(IID_PPV_ARG(IPersistFolder2
, &ppf2
));
1087 ppf2
->GetCurFolder(&m_pidlParent
);
1088 ntreg
.fRecursive
= TRUE
;
1089 ntreg
.pidl
= m_pidlParent
;
1090 m_hNotify
= SHChangeNotifyRegister(m_hWnd
, SHCNRF_InterruptLevel
| SHCNRF_ShellLevel
, SHCNE_ALLEVENTS
, SHV_CHANGE_NOTIFY
, 1, &ntreg
);
1093 m_hAccel
= LoadAcceleratorsW(shell32_hInstance
, MAKEINTRESOURCEW(IDA_SHELLVIEW
));
1100 /**********************************************************
1101 * #### Handling of the menus ####
1104 HMENU
CDefView::BuildFileMenu()
1107 CComPtr
<IContextMenu
> cm
;
1111 hr
= m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, IID_NULL_PPV_ARG(IContextMenu
, &cm
));
1115 HMENU hmenu
= CreatePopupMenu();
1117 //FIXME: get proper numbers ?
1118 const UINT first
= 0x7800;
1119 const UINT last
= 0x7A00;
1120 hr
= cm
->QueryContextMenu(hmenu
, 0, first
, last
, 0);
1124 // TODO: filter or something
1129 void CDefView::PrepareShowFileMenu(HMENU hSubMenu
)
1131 TRACE("(%p)->(submenu=%p) stub\n", this, hSubMenu
);
1136 /* Cleanup the items added previously */
1137 for (int i
= 0; i
< GetMenuItemCount(hSubMenu
); )
1140 mii
.cbSize
= sizeof(mii
);
1141 mii
.fMask
= MIIM_ID
;
1142 GetMenuItemInfoW(hSubMenu
, i
, TRUE
, &mii
);
1144 if (mii
.wID
< 0x8000)
1146 DeleteMenu(hSubMenu
, i
, MF_BYPOSITION
);
1155 /* FIXME/TODO: Reenable when they implemented AND localizable (not hardcoded). */
1156 /* Insert This item at the beginning of the menu. */
1157 _InsertMenuItemW(hSubMenu
, 0, TRUE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1158 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
+ 4, MFT_STRING
, L
"Properties", MFS_DISABLED
);
1159 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
+ 3, MFT_STRING
, L
"Rename", MFS_DISABLED
);
1160 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
+ 2, MFT_STRING
, L
"Delete", MFS_DISABLED
);
1161 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
+ 1, MFT_STRING
, L
"Create Shortcut", MFS_DISABLED
);
1162 _InsertMenuItemW(hSubMenu
, 0, TRUE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1163 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
, MFT_STRING
, L
"New", MFS_ENABLED
);
1166 HMENU menubase
= BuildFileMenu();
1169 int count
= ::GetMenuItemCount(menubase
);
1170 int count2
= ::GetMenuItemCount(hSubMenu
);
1172 if (count2
> 0 && count
> 0)
1174 _InsertMenuItemW(hSubMenu
, 0, TRUE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1177 for (int i
= count
-1; i
>= 0; i
--)
1181 MENUITEMINFOW mii
= { 0 };
1182 mii
.cbSize
= sizeof(mii
);
1183 mii
.fMask
= MIIM_STATE
| MIIM_ID
| MIIM_SUBMENU
| MIIM_CHECKMARKS
| MIIM_DATA
| MIIM_STRING
| MIIM_BITMAP
| MIIM_FTYPE
;
1184 mii
.dwTypeData
= label
;
1185 mii
.cch
= _countof(label
);
1186 ::GetMenuItemInfoW(menubase
, i
, TRUE
, &mii
);
1188 TRACE("Adding item %d label %S type %d\n", mii
.wID
, mii
.dwTypeData
, mii
.fType
);
1190 mii
.fType
|= MFT_RADIOCHECK
;
1192 ::InsertMenuItemW(hSubMenu
, 0, TRUE
, &mii
);
1196 ::DestroyMenu(menubase
);
1201 void CDefView::PrepareShowViewMenu(HMENU hSubMenu
)
1203 TRACE("(%p)->(submenu=%p)\n", this, hSubMenu
);
1208 if (m_FolderSettings
.ViewMode
>= FVM_FIRST
&& m_FolderSettings
.ViewMode
<= FVM_LAST
)
1210 UINT iItemFirst
= FCIDM_SHVIEW_BIGICON
;
1211 UINT iItemLast
= iItemFirst
+ FVM_LAST
- FVM_FIRST
;
1212 UINT iItem
= iItemFirst
+ m_FolderSettings
.ViewMode
- FVM_FIRST
;
1213 CheckMenuRadioItem(hSubMenu
, iItemFirst
, iItemLast
, iItem
, MF_BYCOMMAND
);
1217 /**********************************************************
1218 * ShellView_GetSelections()
1220 * - fills the m_apidl list with the selected objects
1223 * number of selected items
1225 UINT
CDefView::GetSelections()
1229 m_cidl
= m_ListView
.GetSelectedCount();
1230 m_apidl
= reinterpret_cast<PCUITEMID_CHILD_ARRAY
>(SHAlloc(m_cidl
* sizeof(PCUITEMID_CHILD
)));
1237 TRACE("-- Items selected =%u\n", m_cidl
);
1241 while ((lvIndex
= m_ListView
.GetNextItem(lvIndex
, LVNI_SELECTED
)) > -1)
1243 m_apidl
[i
] = _PidlByItem(lvIndex
);
1247 TRACE("-- selected Item found\n");
1253 /**********************************************************
1254 * ShellView_OpenSelectedItems()
1256 HRESULT
CDefView::OpenSelectedItems()
1259 CMINVOKECOMMANDINFO cmi
;
1263 m_cidl
= m_ListView
.GetSelectedCount();
1267 hResult
= OnDefaultCommand();
1268 if (hResult
== S_OK
)
1271 hMenu
= CreatePopupMenu();
1275 hResult
= GetItemObject(SVGIO_SELECTION
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1276 if (FAILED(hResult
))
1279 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, 0x20, 0x7fff, CMF_DEFAULTONLY
);
1280 if (FAILED(hResult
))
1283 uCommand
= GetMenuDefaultItem(hMenu
, FALSE
, 0);
1284 if (uCommand
== (UINT
)-1)
1290 ZeroMemory(&cmi
, sizeof(cmi
));
1291 cmi
.cbSize
= sizeof(cmi
);
1292 cmi
.lpVerb
= (LPCSTR
)MAKEINTRESOURCEA(uCommand
);
1295 hResult
= m_pCM
->InvokeCommand(&cmi
);
1308 /**********************************************************
1309 * ShellView_DoContextMenu()
1311 LRESULT
CDefView::OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1317 CMINVOKECOMMANDINFO cmi
;
1320 // for some reason I haven't figured out, we sometimes recurse into this method
1327 TRACE("(%p)->(0x%08x 0x%08x) stub\n", this, x
, y
);
1329 hMenu
= CreatePopupMenu();
1333 m_cidl
= m_ListView
.GetSelectedCount();
1335 hResult
= GetItemObject( m_cidl
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1336 if (FAILED( hResult
))
1339 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1340 if (FAILED( hResult
))
1343 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
1344 SetMenuDefaultItem(hMenu
, FCIDM_SHVIEW_OPEN
, MF_BYCOMMAND
);
1346 uCommand
= TrackPopupMenu(hMenu
,
1347 TPM_LEFTALIGN
| TPM_RETURNCMD
| TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
,
1348 x
, y
, 0, m_hWnd
, NULL
);
1352 if (uCommand
== FCIDM_SHVIEW_OPEN
&& OnDefaultCommand() == S_OK
)
1355 ZeroMemory(&cmi
, sizeof(cmi
));
1356 cmi
.cbSize
= sizeof(cmi
);
1357 cmi
.lpVerb
= MAKEINTRESOURCEA(uCommand
);
1359 m_pCM
->InvokeCommand(&cmi
);
1372 LRESULT
CDefView::OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
)
1375 CMINVOKECOMMANDINFO cmi
;
1378 hMenu
= CreatePopupMenu();
1382 hResult
= GetItemObject( bUseSelection
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1383 if (FAILED( hResult
))
1386 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1387 if (FAILED( hResult
))
1390 ZeroMemory(&cmi
, sizeof(cmi
));
1391 cmi
.cbSize
= sizeof(cmi
);
1392 cmi
.lpVerb
= MAKEINTRESOURCEA(uCommand
);
1394 m_pCM
->InvokeCommand(&cmi
);
1407 /**********************************************************
1408 * ##### message handling #####
1411 /**********************************************************
1412 * ShellView_OnSize()
1414 LRESULT
CDefView::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1419 wWidth
= LOWORD(lParam
);
1420 wHeight
= HIWORD(lParam
);
1422 TRACE("%p width=%u height=%u\n", this, wWidth
, wHeight
);
1424 /*resize the ListView to fit our window*/
1427 ::MoveWindow(m_ListView
, 0, 0, wWidth
, wHeight
, TRUE
);
1433 /**********************************************************
1434 * ShellView_OnDeactivate()
1439 void CDefView::OnDeactivate()
1441 TRACE("%p\n", this);
1443 if (m_uState
!= SVUIA_DEACTIVATE
)
1445 // TODO: cleanup menu after deactivation
1447 m_uState
= SVUIA_DEACTIVATE
;
1451 void CDefView::DoActivate(UINT uState
)
1453 TRACE("%p uState=%x\n", this, uState
);
1455 /*don't do anything if the state isn't really changing */
1456 if (m_uState
== uState
)
1461 if (uState
== SVUIA_DEACTIVATE
)
1471 MENUITEMINFOW mii
= { 0 };
1473 /* initialize EDIT menu */
1474 mii
.cbSize
= sizeof(mii
);
1475 mii
.fMask
= MIIM_SUBMENU
;
1476 if (::GetMenuItemInfoW(m_hMenu
, FCIDM_MENU_EDIT
, FALSE
, &mii
))
1478 HMENU hSubMenu
= mii
.hSubMenu
;
1480 HMENU menubase
= ::LoadMenuW(shell32_hInstance
, L
"MENU_003");
1482 int count
= ::GetMenuItemCount(menubase
);
1483 for (int i
= 0; i
< count
; i
++)
1487 ZeroMemory(&mii
, sizeof(mii
));
1488 mii
.cbSize
= sizeof(mii
);
1489 mii
.fMask
= MIIM_STATE
| MIIM_ID
| MIIM_SUBMENU
| MIIM_CHECKMARKS
| MIIM_DATA
| MIIM_STRING
| MIIM_BITMAP
| MIIM_FTYPE
;
1490 mii
.dwTypeData
= label
;
1491 mii
.cch
= _countof(label
);
1492 ::GetMenuItemInfoW(menubase
, i
, TRUE
, &mii
);
1494 TRACE("Adding item %d label %S type %d\n", mii
.wID
, mii
.dwTypeData
, mii
.fType
);
1496 mii
.fType
|= MFT_RADIOCHECK
;
1498 ::InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, &mii
);
1501 ::DestroyMenu(menubase
);
1504 /* initialize VIEW menu */
1506 mii
.cbSize
= sizeof(mii
);
1507 mii
.fMask
= MIIM_SUBMENU
;
1508 if (::GetMenuItemInfoW(m_hMenu
, FCIDM_MENU_VIEW
, FALSE
, &mii
))
1510 HMENU menubase
= ::LoadMenuW(shell32_hInstance
, L
"MENU_001");
1512 HMENU hSubMenu
= mii
.hSubMenu
;
1514 m_hView
= CreatePopupMenu();
1516 _InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1518 int count
= ::GetMenuItemCount(menubase
);
1519 for (int i
= 0; i
< count
; i
++)
1523 ZeroMemory(&mii
, sizeof(mii
));
1524 mii
.cbSize
= sizeof(mii
);
1525 mii
.fMask
= MIIM_STATE
| MIIM_ID
| MIIM_SUBMENU
| MIIM_CHECKMARKS
| MIIM_DATA
| MIIM_STRING
| MIIM_BITMAP
| MIIM_FTYPE
;
1526 mii
.dwTypeData
= label
;
1527 mii
.cch
= _countof(label
);
1528 ::GetMenuItemInfoW(menubase
, i
, TRUE
, &mii
);
1530 ::AppendMenuW(m_hView
, mii
.fType
, mii
.wID
, mii
.dwTypeData
);
1532 TRACE("Adding item %d label %S type %d\n", mii
.wID
, mii
.dwTypeData
, mii
.fType
);
1534 mii
.fType
|= MFT_RADIOCHECK
;
1536 ::InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, &mii
);
1539 ::DestroyMenu(menubase
);
1543 TRACE("-- before fnSetMenuSB\n");
1544 m_pShellBrowser
->SetMenuSB(m_hMenu
, 0, m_hWnd
);
1546 m_menusLoaded
= TRUE
;
1550 if (SVUIA_ACTIVATE_FOCUS
== uState
)
1552 m_ListView
.SetFocus();
1560 /**********************************************************
1561 * ShellView_OnActivate()
1563 LRESULT
CDefView::OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1565 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1569 /**********************************************************
1570 * ShellView_OnSetFocus()
1573 LRESULT
CDefView::OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1575 TRACE("%p\n", this);
1577 /* Tell the browser one of our windows has received the focus. This
1578 should always be done before merging menus (OnActivate merges the
1579 menus) if one of our windows has the focus.*/
1581 m_pShellBrowser
->OnViewWindowActive(this);
1582 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1584 /* Set the focus to the listview */
1585 m_ListView
.SetFocus();
1587 /* Notify the ICommDlgBrowser interface */
1588 OnStateChange(CDBOSC_SETFOCUS
);
1593 /**********************************************************
1594 * ShellView_OnKillFocus()
1596 LRESULT
CDefView::OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1598 TRACE("(%p) stub\n", this);
1600 DoActivate(SVUIA_ACTIVATE_NOFOCUS
);
1601 /* Notify the ICommDlgBrowser */
1602 OnStateChange(CDBOSC_KILLFOCUS
);
1607 /**********************************************************
1608 * ShellView_OnCommand()
1611 * the CmdID's are the ones from the context menu
1613 LRESULT
CDefView::OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1620 dwCmdID
= GET_WM_COMMAND_ID(wParam
, lParam
);
1621 dwCmd
= GET_WM_COMMAND_CMD(wParam
, lParam
);
1622 hwndCmd
= GET_WM_COMMAND_HWND(wParam
, lParam
);
1624 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n", this, dwCmdID
, dwCmd
, hwndCmd
);
1628 case FCIDM_SHVIEW_SMALLICON
:
1629 m_FolderSettings
.ViewMode
= FVM_SMALLICON
;
1630 SetStyle (LVS_SMALLICON
, LVS_TYPEMASK
);
1634 case FCIDM_SHVIEW_BIGICON
:
1635 m_FolderSettings
.ViewMode
= FVM_ICON
;
1636 SetStyle (LVS_ICON
, LVS_TYPEMASK
);
1640 case FCIDM_SHVIEW_LISTVIEW
:
1641 m_FolderSettings
.ViewMode
= FVM_LIST
;
1642 SetStyle (LVS_LIST
, LVS_TYPEMASK
);
1646 case FCIDM_SHVIEW_REPORTVIEW
:
1647 m_FolderSettings
.ViewMode
= FVM_DETAILS
;
1648 SetStyle (LVS_REPORT
, LVS_TYPEMASK
);
1652 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1657 m_sortInfo
.nHeaderID
= dwCmdID
- 0x30;
1658 m_sortInfo
.bIsAscending
= TRUE
;
1659 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
1660 m_ListView
.SortItems(ListViewCompareItems
, &m_sortInfo
);
1663 case FCIDM_SHVIEW_SELECTALL
:
1664 m_ListView
.SetItemState(-1, LVIS_SELECTED
, LVIS_SELECTED
);
1667 case FCIDM_SHVIEW_INVERTSELECTION
:
1668 nCount
= m_ListView
.GetItemCount();
1669 for (int i
=0; i
< nCount
; i
++)
1670 m_ListView
.SetItemState(i
, m_ListView
.GetItemState(i
, LVIS_SELECTED
) ? 0 : LVIS_SELECTED
, LVIS_SELECTED
);
1673 case FCIDM_SHVIEW_REFRESH
:
1677 case FCIDM_SHVIEW_DELETE
:
1678 case FCIDM_SHVIEW_CUT
:
1679 case FCIDM_SHVIEW_COPY
:
1680 case FCIDM_SHVIEW_RENAME
:
1681 return OnExplorerCommand(dwCmdID
, TRUE
);
1683 case FCIDM_SHVIEW_INSERT
:
1684 case FCIDM_SHVIEW_UNDO
:
1685 case FCIDM_SHVIEW_INSERTLINK
:
1686 case FCIDM_SHVIEW_NEWFOLDER
:
1687 return OnExplorerCommand(dwCmdID
, FALSE
);
1689 TRACE("-- COMMAND 0x%04x unhandled\n", dwCmdID
);
1695 /**********************************************************
1696 * ShellView_OnNotify()
1699 LRESULT
CDefView::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1703 LPNMLISTVIEW lpnmlv
;
1704 NMLVDISPINFOW
*lpdi
;
1705 PCUITEMID_CHILD pidl
;
1709 lpnmh
= (LPNMHDR
)lParam
;
1710 lpnmlv
= (LPNMLISTVIEW
)lpnmh
;
1711 lpdi
= (NMLVDISPINFOW
*)lpnmh
;
1713 TRACE("%p CtlID=%u lpnmh->code=%x\n", this, CtlID
, lpnmh
->code
);
1715 switch (lpnmh
->code
)
1718 TRACE("-- NM_SETFOCUS %p\n", this);
1719 OnSetFocus(0, 0, 0, unused
);
1723 TRACE("-- NM_KILLFOCUS %p\n", this);
1725 /* Notify the ICommDlgBrowser interface */
1726 OnStateChange(CDBOSC_KILLFOCUS
);
1730 TRACE("-- NM_CUSTOMDRAW %p\n", this);
1731 return CDRF_DODEFAULT
;
1733 case NM_RELEASEDCAPTURE
:
1734 TRACE("-- NM_RELEASEDCAPTURE %p\n", this);
1738 TRACE("-- NM_CLICK %p\n", this);
1742 TRACE("-- NM_RCLICK %p\n", this);
1746 TRACE("-- NM_DBLCLK %p\n", this);
1747 OpenSelectedItems();
1751 TRACE("-- NM_RETURN %p\n", this);
1752 OpenSelectedItems();
1756 TRACE("-- HDN_ENDTRACKW %p\n", this);
1757 /*nColumn1 = m_ListView.GetColumnWidth(0);
1758 nColumn2 = m_ListView.GetColumnWidth(1);*/
1761 case LVN_DELETEITEM
:
1762 TRACE("-- LVN_DELETEITEM %p\n", this);
1764 /*delete the pidl because we made a copy of it*/
1765 SHFree(reinterpret_cast<LPVOID
>(lpnmlv
->lParam
));
1769 case LVN_DELETEALLITEMS
:
1770 TRACE("-- LVN_DELETEALLITEMS %p\n", this);
1773 case LVN_INSERTITEM
:
1774 TRACE("-- LVN_INSERTITEM (STUB)%p\n", this);
1777 case LVN_ITEMACTIVATE
:
1778 TRACE("-- LVN_ITEMACTIVATE %p\n", this);
1779 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1782 case LVN_COLUMNCLICK
:
1783 m_sortInfo
.nHeaderID
= lpnmlv
->iSubItem
;
1784 if (m_sortInfo
.nLastHeaderID
== m_sortInfo
.nHeaderID
)
1785 m_sortInfo
.bIsAscending
= !m_sortInfo
.bIsAscending
;
1787 m_sortInfo
.bIsAscending
= TRUE
;
1788 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
1790 m_ListView
.SortItems(ListViewCompareItems
, &m_sortInfo
);
1793 case LVN_GETDISPINFOA
:
1794 case LVN_GETDISPINFOW
:
1795 TRACE("-- LVN_GETDISPINFO %p\n", this);
1796 pidl
= _PidlByItem(lpdi
->item
);
1798 if (lpdi
->item
.mask
& LVIF_TEXT
) /* text requested */
1803 if (FAILED(m_pSF2Parent
->GetDetailsOf(pidl
, lpdi
->item
.iSubItem
, &sd
)))
1805 FIXME("failed to get details\n");
1809 if (lpnmh
->code
== LVN_GETDISPINFOA
)
1811 /* shouldn't happen */
1812 NMLVDISPINFOA
*lpdiA
= (NMLVDISPINFOA
*)lpnmh
;
1813 StrRetToStrNA( lpdiA
->item
.pszText
, lpdiA
->item
.cchTextMax
, &sd
.str
, NULL
);
1814 TRACE("-- text=%s\n", lpdiA
->item
.pszText
);
1816 else /* LVN_GETDISPINFOW */
1818 StrRetToStrNW( lpdi
->item
.pszText
, lpdi
->item
.cchTextMax
, &sd
.str
, NULL
);
1819 TRACE("-- text=%s\n", debugstr_w(lpdi
->item
.pszText
));
1827 if(lpdi
->item
.mask
& LVIF_IMAGE
) /* image requested */
1829 lpdi
->item
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
1831 if(lpdi
->item
.mask
& LVIF_STATE
)
1833 ULONG attributes
= SFGAO_HIDDEN
;
1834 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(1, &pidl
, &attributes
)))
1836 if (attributes
& SFGAO_HIDDEN
)
1838 lpdi
->item
.state
|= LVIS_CUT
;
1842 lpdi
->item
.mask
|= LVIF_DI_SETITEM
;
1845 case LVN_ITEMCHANGED
:
1846 TRACE("-- LVN_ITEMCHANGED %p\n", this);
1847 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1852 case LVN_BEGINRDRAG
:
1853 TRACE("-- LVN_BEGINDRAG\n");
1855 if (GetSelections())
1857 CComPtr
<IDataObject
> pda
;
1858 DWORD dwAttributes
= SFGAO_CANLINK
;
1859 DWORD dwEffect
= DROPEFFECT_COPY
| DROPEFFECT_MOVE
;
1861 if (SUCCEEDED(m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, IID_NULL_PPV_ARG(IDataObject
, &pda
))))
1863 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(m_cidl
, m_apidl
, &dwAttributes
)))
1865 if (dwAttributes
& SFGAO_CANLINK
)
1867 dwEffect
|= DROPEFFECT_LINK
;
1871 CComPtr
<IAsyncOperation
> piaso
;
1872 if (SUCCEEDED(pda
->QueryInterface(IID_PPV_ARG(IAsyncOperation
, &piaso
))))
1874 piaso
->SetAsyncMode(TRUE
);
1878 DoDragDrop(pda
, this, dwEffect
, &dwEffect2
);
1883 case LVN_BEGINLABELEDITW
:
1885 DWORD dwAttr
= SFGAO_CANRENAME
;
1886 pidl
= _PidlByItem(lpdi
->item
);
1888 TRACE("-- LVN_BEGINLABELEDITW %p\n", this);
1890 m_pSFParent
->GetAttributesOf(1, &pidl
, &dwAttr
);
1891 if (SFGAO_CANRENAME
& dwAttr
)
1899 case LVN_ENDLABELEDITW
:
1901 TRACE("-- LVN_ENDLABELEDITW %p\n", this);
1903 m_isEditing
= FALSE
;
1905 if (lpdi
->item
.pszText
)
1910 pidl
= _PidlByItem(lpdi
->item
);
1911 PITEMID_CHILD pidlNew
;
1912 hr
= m_pSFParent
->SetNameOf(0, pidl
, lpdi
->item
.pszText
, SHGDN_INFOLDER
, &pidlNew
);
1914 if (SUCCEEDED(hr
) && pidlNew
)
1916 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
1917 lvItem
.iItem
= lpdi
->item
.iItem
;
1918 lvItem
.lParam
= reinterpret_cast<LPARAM
>(pidlNew
);
1919 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
1920 m_ListView
.SetItem(&lvItem
);
1921 m_ListView
.Update(lpdi
->item
.iItem
);
1930 TRACE("-- %p WM_COMMAND %x unhandled\n", this, lpnmh
->code
);
1938 * This is just a quick hack to make the desktop work correctly.
1939 * ITranslateShellChangeNotify's IsChildID is undocumented, but most likely the way that
1940 * a folder should know if it should update upon a change notification.
1941 * It is exported by merged folders at a minimum.
1943 static BOOL
ILIsParentOrSpecialParent(PCIDLIST_ABSOLUTE pidl1
, PCIDLIST_ABSOLUTE pidl2
)
1945 if (!pidl1
|| !pidl2
)
1947 if (ILIsParent(pidl1
, pidl2
, TRUE
))
1950 if (_ILIsDesktop(pidl1
))
1952 PIDLIST_ABSOLUTE deskpidl
;
1953 SHGetFolderLocation(NULL
, CSIDL_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
1954 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
1960 SHGetFolderLocation(NULL
, CSIDL_COMMON_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
1961 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
1971 /**********************************************************
1972 * ShellView_OnChange()
1974 LRESULT
CDefView::OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1976 PCIDLIST_ABSOLUTE
*Pidls
= reinterpret_cast<PCIDLIST_ABSOLUTE
*>(wParam
);
1977 BOOL bParent0
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[0]);
1978 BOOL bParent1
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[1]);
1980 TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls
[0], Pidls
[1], lParam
);
1988 if (LV_FindItemByPidl(ILFindLastID(Pidls
[0])) == -1)
1990 LV_AddItem(ILFindLastID(Pidls
[0]));
1994 LV_ProdItem(ILFindLastID(Pidls
[0]));
2002 LV_DeleteItem(ILFindLastID(Pidls
[0]));
2005 case SHCNE_RENAMEFOLDER
:
2006 case SHCNE_RENAMEITEM
:
2007 if (bParent0
&& bParent1
)
2008 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[1]));
2010 LV_DeleteItem(ILFindLastID(Pidls
[0]));
2012 LV_AddItem(ILFindLastID(Pidls
[1]));
2015 case SHCNE_UPDATEITEM
:
2017 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[0]));
2020 case SHCNE_UPDATEDIR
:
2027 /**********************************************************
2028 * CDefView::OnCustomItem
2030 LRESULT
CDefView::OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
2035 ERR("no menu!!!\n");
2040 HRESULT hres
= SHForwardContextMenuMsg(m_pCM
, uMsg
, wParam
, lParam
, &result
, TRUE
);
2041 if (SUCCEEDED(hres
))
2047 LRESULT
CDefView::OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
2049 /* Wallpaper setting affects drop shadows effect */
2050 if (wParam
== SPI_SETDESKWALLPAPER
|| wParam
== 0)
2056 /**********************************************************
2057 * CDefView::OnInitMenuPopup
2059 LRESULT
CDefView::OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
2061 MENUITEMINFOW mii
= { 0 };
2062 HMENU hSubmenu
= (HMENU
) wParam
;
2064 TRACE("OnInitMenuPopup lParam=%d\n", lParam
);
2066 mii
.cbSize
= sizeof(mii
);
2067 mii
.fMask
= MIIM_ID
| MIIM_SUBMENU
;
2069 if (!GetMenuItemInfoW(this->m_hMenu
, lParam
, TRUE
, &mii
))
2071 TRACE("OnInitMenuPopup GetMenuItemInfoW failed!\n");
2075 UINT menuItemId
= mii
.wID
;
2077 if (mii
.hSubMenu
!= hSubmenu
)
2079 TRACE("OnInitMenuPopup submenu does not match!!!!\n");
2083 TRACE("OnInitMenuPopup id=%d\n", menuItemId
);
2087 case FCIDM_MENU_FILE
:
2088 PrepareShowFileMenu(hSubmenu
);
2090 case FCIDM_MENU_EDIT
:
2091 //PrepareShowEditMenu(hSubmenu);
2093 case FCIDM_MENU_VIEW
:
2094 PrepareShowViewMenu(hSubmenu
);
2101 /**********************************************************
2104 * The INTERFACE of the IShellView object
2107 **********************************************************
2110 /**********************************************************
2111 * ShellView_GetWindow
2113 HRESULT WINAPI
CDefView::GetWindow(HWND
*phWnd
)
2115 TRACE("(%p)\n", this);
2122 HRESULT WINAPI
CDefView::ContextSensitiveHelp(BOOL fEnterMode
)
2124 FIXME("(%p) stub\n", this);
2129 /**********************************************************
2130 * IShellView_TranslateAccelerator
2133 * use the accel functions
2135 HRESULT WINAPI
CDefView::TranslateAccelerator(LPMSG lpmsg
)
2140 if (lpmsg
->message
>= WM_KEYFIRST
&& lpmsg
->message
<= WM_KEYLAST
)
2142 if (::TranslateAcceleratorW(m_hWnd
, m_hAccel
, lpmsg
) != 0)
2145 TRACE("-- key=0x04%lx\n", lpmsg
->wParam
) ;
2148 return m_pShellBrowser
->TranslateAcceleratorSB(lpmsg
, 0);
2151 HRESULT WINAPI
CDefView::EnableModeless(BOOL fEnable
)
2153 FIXME("(%p) stub\n", this);
2158 HRESULT WINAPI
CDefView::UIActivate(UINT uState
)
2161 CHAR szName[MAX_PATH];
2164 int nPartArray
[1] = { -1};
2166 TRACE("(%p)->(state=%x) stub\n", this, uState
);
2168 /*don't do anything if the state isn't really changing*/
2169 if (m_uState
== uState
)
2174 /*OnActivate handles the menu merging and internal state*/
2177 /*only do This if we are active*/
2178 if (uState
!= SVUIA_DEACTIVATE
)
2182 GetFolderPath is not a method of IShellFolder
2183 IShellFolder_GetFolderPath( m_pSFParent, szName, sizeof(szName) );
2185 /* set the number of parts */
2186 m_pShellBrowser
->SendControlMsg(FCW_STATUS
, SB_SETPARTS
, 1, (LPARAM
)nPartArray
, &lResult
);
2188 /* set the text for the parts */
2190 m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXTA, 0, (LPARAM)szName, &lResult);
2197 HRESULT WINAPI
CDefView::Refresh()
2199 TRACE("(%p)\n", this);
2201 m_ListView
.DeleteAllItems();
2207 HRESULT WINAPI
CDefView::CreateViewWindow(IShellView
*lpPrevView
, LPCFOLDERSETTINGS lpfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
)
2209 OLEMENUGROUPWIDTHS omw
= { { 0, 0, 0, 0, 0, 0 } };
2213 TRACE("(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n", this, lpPrevView
, lpfs
, psb
, prcView
, phWnd
);
2216 TRACE("-- vmode=%x flags=%x\n", lpfs
->ViewMode
, lpfs
->fFlags
);
2217 if (prcView
!= NULL
)
2218 TRACE("-- left=%i top=%i right=%i bottom=%i\n", prcView
->left
, prcView
->top
, prcView
->right
, prcView
->bottom
);
2220 /* Validate the Shell Browser */
2221 if (psb
== NULL
|| m_hWnd
)
2222 return E_UNEXPECTED
;
2224 /*set up the member variables*/
2225 m_pShellBrowser
= psb
;
2226 m_FolderSettings
= *lpfs
;
2228 /*get our parent window*/
2229 m_pShellBrowser
->GetWindow(&m_hWndParent
);
2231 /* try to get the ICommDlgBrowserInterface, adds a reference !!! */
2232 m_pCommDlgBrowser
= NULL
;
2233 if (SUCCEEDED(m_pShellBrowser
->QueryInterface(IID_PPV_ARG(ICommDlgBrowser
, &m_pCommDlgBrowser
))))
2235 TRACE("-- CommDlgBrowser\n");
2238 Create(m_hWndParent
, prcView
, NULL
, WS_CHILD
| WS_TABSTOP
, 0, 0U);
2249 SetWindowPos(HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_SHOWWINDOW
);
2254 m_hMenu
= CreateMenu();
2255 m_pShellBrowser
->InsertMenusSB(m_hMenu
, &omw
);
2256 TRACE("-- after fnInsertMenusSB\n");
2264 HRESULT WINAPI
CDefView::DestroyViewWindow()
2266 TRACE("(%p)\n", this);
2268 /*Make absolutely sure all our UI is cleaned up.*/
2269 UIActivate(SVUIA_DEACTIVATE
);
2273 // "Accelerator tables loaded from resources are freed automatically when the application terminates." -- MSDN
2279 DestroyMenu(m_hView
);
2285 DestroyMenu(m_hMenu
);
2291 m_ListView
.DestroyWindow();
2299 m_pShellBrowser
.Release();
2300 m_pCommDlgBrowser
.Release();
2305 HRESULT WINAPI
CDefView::GetCurrentInfo(LPFOLDERSETTINGS lpfs
)
2307 TRACE("(%p)->(%p) vmode=%x flags=%x\n", this, lpfs
,
2308 m_FolderSettings
.ViewMode
, m_FolderSettings
.fFlags
);
2311 return E_INVALIDARG
;
2313 *lpfs
= m_FolderSettings
;
2317 HRESULT WINAPI
CDefView::AddPropertySheetPages(DWORD dwReserved
, LPFNADDPROPSHEETPAGE lpfn
, LPARAM lparam
)
2319 FIXME("(%p) stub\n", this);
2324 HRESULT WINAPI
CDefView::SaveViewState()
2326 FIXME("(%p) stub\n", this);
2331 HRESULT WINAPI
CDefView::SelectItem(PCUITEMID_CHILD pidl
, UINT uFlags
)
2335 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n", this, pidl
, uFlags
);
2337 i
= LV_FindItemByPidl(pidl
);
2341 if(uFlags
& SVSI_ENSUREVISIBLE
)
2342 m_ListView
.EnsureVisible(i
, FALSE
);
2344 LVITEMW lvItem
= {0};
2345 lvItem
.mask
= LVIF_STATE
;
2346 lvItem
.stateMask
= LVIS_SELECTED
| LVIS_FOCUSED
;
2348 while (m_ListView
.GetItem(&lvItem
))
2350 if (lvItem
.iItem
== i
)
2352 if (uFlags
& SVSI_SELECT
)
2353 lvItem
.state
|= LVIS_SELECTED
;
2355 lvItem
.state
&= ~LVIS_SELECTED
;
2357 if (uFlags
& SVSI_FOCUSED
)
2358 lvItem
.state
&= ~LVIS_FOCUSED
;
2362 if (uFlags
& SVSI_DESELECTOTHERS
)
2363 lvItem
.state
&= ~LVIS_SELECTED
;
2366 m_ListView
.SetItem(&lvItem
);
2370 if(uFlags
& SVSI_EDIT
)
2371 m_ListView
.EditLabel(i
);
2376 HRESULT WINAPI
CDefView::GetItemObject(UINT uItem
, REFIID riid
, LPVOID
*ppvOut
)
2378 HRESULT hr
= E_NOINTERFACE
;
2380 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n", this, uItem
, debugstr_guid(&riid
), ppvOut
);
2386 case SVGIO_BACKGROUND
:
2387 if (IsEqualIID(riid
, IID_IContextMenu
))
2389 //*ppvOut = ISvBgCm_Constructor(m_pSFParent, FALSE);
2394 hr
= CDefFolderMenu_Create2(NULL
, NULL
, 0, NULL
, m_pSFParent
, NULL
, 0, NULL
, &pcm
);
2401 case SVGIO_SELECTION
:
2403 hr
= m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, riid
, 0, ppvOut
);
2407 TRACE("-- (%p)->(interface=%p)\n", this, *ppvOut
);
2412 HRESULT STDMETHODCALLTYPE
CDefView::GetCurrentViewMode(UINT
*pViewMode
)
2414 TRACE("(%p)->(%p), stub\n", this, pViewMode
);
2417 return E_INVALIDARG
;
2419 *pViewMode
= m_FolderSettings
.ViewMode
;
2423 HRESULT STDMETHODCALLTYPE
CDefView::SetCurrentViewMode(UINT ViewMode
)
2426 TRACE("(%p)->(%u), stub\n", this, ViewMode
);
2428 /* It's not redundant to check FVM_AUTO because it's a (UINT)-1 */
2429 if (((INT
)ViewMode
< FVM_FIRST
|| (INT
)ViewMode
> FVM_LAST
) && ((INT
)ViewMode
!= FVM_AUTO
))
2430 return E_INVALIDARG
;
2432 /* Windows before Vista uses LVM_SETVIEW and possibly
2433 LVM_SETEXTENDEDLISTVIEWSTYLE to set the style of the listview,
2434 while later versions seem to accomplish this through other
2442 dwStyle
= LVS_REPORT
;
2445 dwStyle
= LVS_SMALLICON
;
2452 FIXME("ViewMode %d not implemented\n", ViewMode
);
2458 SetStyle(dwStyle
, LVS_TYPEMASK
);
2460 /* This will not necessarily be the actual mode set above.
2461 This mimics the behavior of Windows XP. */
2462 m_FolderSettings
.ViewMode
= ViewMode
;
2467 HRESULT STDMETHODCALLTYPE
CDefView::GetFolder(REFIID riid
, void **ppv
)
2469 if (m_pSFParent
== NULL
)
2472 return m_pSFParent
->QueryInterface(riid
, ppv
);
2475 HRESULT STDMETHODCALLTYPE
CDefView::Item(int iItemIndex
, PITEMID_CHILD
*ppidl
)
2477 PCUITEMID_CHILD pidl
= _PidlByItem(iItemIndex
);
2480 *ppidl
= ILClone(pidl
);
2485 return E_INVALIDARG
;
2488 HRESULT STDMETHODCALLTYPE
CDefView::ItemCount(UINT uFlags
, int *pcItems
)
2490 TRACE("(%p)->(%u %p)\n", this, uFlags
, pcItems
);
2492 if (uFlags
!= SVGIO_ALLVIEW
)
2493 FIXME("some flags unsupported, %x\n", uFlags
& ~SVGIO_ALLVIEW
);
2495 *pcItems
= m_ListView
.GetItemCount();
2500 HRESULT STDMETHODCALLTYPE
CDefView::Items(UINT uFlags
, REFIID riid
, void **ppv
)
2505 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectionMarkedItem(int *piItem
)
2507 TRACE("(%p)->(%p)\n", this, piItem
);
2509 *piItem
= m_ListView
.GetSelectionMark();
2514 HRESULT STDMETHODCALLTYPE
CDefView::GetFocusedItem(int *piItem
)
2516 TRACE("(%p)->(%p)\n", this, piItem
);
2518 *piItem
= m_ListView
.GetNextItem(-1, LVNI_FOCUSED
);
2523 HRESULT STDMETHODCALLTYPE
CDefView::GetItemPosition(PCUITEMID_CHILD pidl
, POINT
*ppt
)
2528 HRESULT STDMETHODCALLTYPE
CDefView::GetSpacing(POINT
*ppt
)
2530 TRACE("(%p)->(%p)\n", this, ppt
);
2538 m_ListView
.GetItemSpacing(spacing
);
2540 ppt
->x
= spacing
.cx
;
2541 ppt
->y
= spacing
.cy
;
2547 HRESULT STDMETHODCALLTYPE
CDefView::GetDefaultSpacing(POINT
*ppt
)
2552 HRESULT STDMETHODCALLTYPE
CDefView::GetAutoArrange()
2557 HRESULT STDMETHODCALLTYPE
CDefView::SelectItem(int iItem
, DWORD dwFlags
)
2561 TRACE("(%p)->(%d, %x)\n", this, iItem
, dwFlags
);
2564 lvItem
.stateMask
= LVIS_SELECTED
;
2566 if (dwFlags
& SVSI_ENSUREVISIBLE
)
2567 m_ListView
.EnsureVisible(iItem
, 0);
2570 if (dwFlags
& SVSI_DESELECTOTHERS
)
2571 m_ListView
.SetItemState(-1, 0, LVIS_SELECTED
);
2574 if (dwFlags
& SVSI_SELECT
)
2575 lvItem
.state
|= LVIS_SELECTED
;
2577 if (dwFlags
& SVSI_FOCUSED
)
2578 lvItem
.stateMask
|= LVIS_FOCUSED
;
2580 m_ListView
.SetItemState(iItem
, lvItem
.state
, lvItem
.stateMask
);
2582 if (dwFlags
& SVSI_EDIT
)
2583 m_ListView
.EditLabel(iItem
);
2588 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItems(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD dwFlags
)
2593 /**********************************************************
2594 * IShellFolderView implementation
2596 HRESULT STDMETHODCALLTYPE
CDefView::Rearrange(LPARAM sort
)
2598 FIXME("(%p)->(%ld) stub\n", this, sort
);
2602 HRESULT STDMETHODCALLTYPE
CDefView::GetArrangeParam(LPARAM
*sort
)
2604 FIXME("(%p)->(%p) stub\n", this, sort
);
2608 HRESULT STDMETHODCALLTYPE
CDefView::ArrangeGrid()
2610 FIXME("(%p) stub\n", this);
2614 HRESULT STDMETHODCALLTYPE
CDefView::AutoArrange()
2616 FIXME("(%p) stub\n", this);
2620 HRESULT STDMETHODCALLTYPE
CDefView::AddObject(PITEMID_CHILD pidl
, UINT
*item
)
2622 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2626 HRESULT STDMETHODCALLTYPE
CDefView::GetObject(PITEMID_CHILD
*pidl
, UINT item
)
2628 TRACE("(%p)->(%p %d)\n", this, pidl
, item
);
2629 return Item(item
, pidl
);
2632 HRESULT STDMETHODCALLTYPE
CDefView::RemoveObject(PITEMID_CHILD pidl
, UINT
*item
)
2635 TRACE("(%p)->(%p %p)\n", this, pidl
, item
);
2639 *item
= LV_FindItemByPidl(ILFindLastID(pidl
));
2640 m_ListView
.DeleteItem(*item
);
2645 m_ListView
.DeleteAllItems();
2651 HRESULT STDMETHODCALLTYPE
CDefView::GetObjectCount(UINT
*count
)
2653 TRACE("(%p)->(%p)\n", this, count
);
2654 *count
= m_ListView
.GetItemCount();
2658 HRESULT STDMETHODCALLTYPE
CDefView::SetObjectCount(UINT count
, UINT flags
)
2660 FIXME("(%p)->(%d %x) stub\n", this, count
, flags
);
2664 HRESULT STDMETHODCALLTYPE
CDefView::UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
)
2666 FIXME("(%p)->(%p %p %p) stub\n", this, pidl_old
, pidl_new
, item
);
2670 HRESULT STDMETHODCALLTYPE
CDefView::RefreshObject(PITEMID_CHILD pidl
, UINT
*item
)
2672 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2676 HRESULT STDMETHODCALLTYPE
CDefView::SetRedraw(BOOL redraw
)
2678 TRACE("(%p)->(%d)\n", this, redraw
);
2679 m_ListView
.SetRedraw(redraw
);
2683 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedCount(UINT
*count
)
2685 FIXME("(%p)->(%p) stub\n", this, count
);
2689 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
)
2691 TRACE("(%p)->(%p %p)\n", this, pidl
, items
);
2693 *items
= GetSelections();
2697 *pidl
= static_cast<PCUITEMID_CHILD
*>(LocalAlloc(0, *items
* sizeof(PCUITEMID_CHILD
)));
2700 return E_OUTOFMEMORY
;
2703 /* it's documented that caller shouldn't PIDLs, only array itself */
2704 memcpy(*pidl
, m_apidl
, *items
* sizeof(PCUITEMID_CHILD
));
2710 HRESULT STDMETHODCALLTYPE
CDefView::IsDropOnSource(IDropTarget
*drop_target
)
2712 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2716 HRESULT STDMETHODCALLTYPE
CDefView::GetDragPoint(POINT
*pt
)
2718 FIXME("(%p)->(%p) stub\n", this, pt
);
2722 HRESULT STDMETHODCALLTYPE
CDefView::GetDropPoint(POINT
*pt
)
2724 FIXME("(%p)->(%p) stub\n", this, pt
);
2728 HRESULT STDMETHODCALLTYPE
CDefView::MoveIcons(IDataObject
*obj
)
2730 TRACE("(%p)->(%p)\n", this, obj
);
2734 HRESULT STDMETHODCALLTYPE
CDefView::SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
)
2736 FIXME("(%p)->(%p %p) stub\n", this, pidl
, pt
);
2740 HRESULT STDMETHODCALLTYPE
CDefView::IsBkDropTarget(IDropTarget
*drop_target
)
2742 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2746 HRESULT STDMETHODCALLTYPE
CDefView::SetClipboard(BOOL move
)
2748 FIXME("(%p)->(%d) stub\n", this, move
);
2752 HRESULT STDMETHODCALLTYPE
CDefView::SetPoints(IDataObject
*obj
)
2754 FIXME("(%p)->(%p) stub\n", this, obj
);
2758 HRESULT STDMETHODCALLTYPE
CDefView::GetItemSpacing(ITEMSPACING
*spacing
)
2760 FIXME("(%p)->(%p) stub\n", this, spacing
);
2764 HRESULT STDMETHODCALLTYPE
CDefView::SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
)
2766 FIXME("(%p)->(%p %p) stub\n", this, new_cb
, old_cb
);
2770 HRESULT STDMETHODCALLTYPE
CDefView::Select(UINT flags
)
2772 FIXME("(%p)->(%d) stub\n", this, flags
);
2776 HRESULT STDMETHODCALLTYPE
CDefView::QuerySupport(UINT
*support
)
2778 TRACE("(%p)->(%p)\n", this, support
);
2782 HRESULT STDMETHODCALLTYPE
CDefView::SetAutomationObject(IDispatch
*disp
)
2784 FIXME("(%p)->(%p) stub\n", this, disp
);
2788 /**********************************************************
2789 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2791 HRESULT WINAPI
CDefView::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD
*prgCmds
, OLECMDTEXT
*pCmdText
)
2793 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
2794 this, pguidCmdGroup
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
2797 return E_INVALIDARG
;
2799 for (UINT i
= 0; i
< cCmds
; i
++)
2801 FIXME("\tprgCmds[%d].cmdID = %d\n", i
, prgCmds
[i
].cmdID
);
2802 prgCmds
[i
].cmdf
= 0;
2805 return OLECMDERR_E_UNKNOWNGROUP
;
2808 /**********************************************************
2809 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2811 * nCmdID is the OLECMDID_* enumeration
2813 HRESULT WINAPI
CDefView::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
2815 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2816 this, debugstr_guid(pguidCmdGroup
), nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2819 return OLECMDERR_E_UNKNOWNGROUP
;
2821 if (IsEqualCLSID(*pguidCmdGroup
, m_Category
))
2823 if (nCmdID
== FCIDM_SHVIEW_AUTOARRANGE
)
2825 if (V_VT(pvaIn
) != VT_INT_PTR
)
2826 return OLECMDERR_E_NOTSUPPORTED
;
2830 params
.cbSize
= sizeof(params
);
2831 params
.rcExclude
= *(RECT
*) V_INTREF(pvaIn
);
2833 HMENU hView
= m_hView
;
2835 hView
= CreatePopupMenu();
2836 AppendMenuW(hView
, MF_STRING
, FCIDM_SHVIEW_BIGICON
, L
"Big!");
2837 AppendMenuW(hView
, MF_STRING
, FCIDM_SHVIEW_SMALLICON
, L
"Small!");
2838 AppendMenuW(hView
, MF_STRING
, FCIDM_SHVIEW_LISTVIEW
, L
"List!");
2839 AppendMenuW(hView
, MF_STRING
, FCIDM_SHVIEW_REPORTVIEW
, L
"Report!");
2844 PrepareShowViewMenu(hView
);
2846 TrackPopupMenuEx(hView
, TPM_LEFTALIGN
| TPM_TOPALIGN
, params
.rcExclude
.left
, params
.rcExclude
.bottom
, m_hWndParent
, ¶ms
);
2849 // pvaOut is VT_I4 with value 0x403 (cmd id of the new mode maybe?)
2850 V_VT(pvaOut
) = VT_I4
;
2851 V_I4(pvaOut
) = 0x403;
2855 if (IsEqualIID(*pguidCmdGroup
, CGID_Explorer
) &&
2857 (nCmdexecopt
== 4) && pvaOut
)
2860 if (IsEqualIID(*pguidCmdGroup
, CGID_ShellDocView
) &&
2865 return OLECMDERR_E_UNKNOWNGROUP
;
2868 /**********************************************************
2869 * ISVDropTarget implementation
2872 /******************************************************************************
2873 * drag_notify_subitem [Internal]
2875 * Figure out the shellfolder object, which is currently under the mouse cursor
2876 * and notify it via the IDropTarget interface.
2879 #define SCROLLAREAWIDTH 20
2881 HRESULT
CDefView::drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2883 LVHITTESTINFO htinfo
;
2888 /* Map from global to client coordinates and query the index of the listview-item, which is
2889 * currently under the mouse cursor. */
2892 htinfo
.flags
= LVHT_ONITEM
;
2893 ::ScreenToClient(m_ListView
, &htinfo
.pt
);
2894 lResult
= m_ListView
.HitTest(&htinfo
);
2896 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2897 ::GetClientRect(m_ListView
, &clientRect
);
2898 if (htinfo
.pt
.x
== m_ptLastMousePos
.x
&& htinfo
.pt
.y
== m_ptLastMousePos
.y
&&
2899 (htinfo
.pt
.x
< SCROLLAREAWIDTH
|| htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
||
2900 htinfo
.pt
.y
< SCROLLAREAWIDTH
|| htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
))
2902 m_cScrollDelay
= (m_cScrollDelay
+ 1) % 5; /* DragOver is called every 50 ms */
2903 if (m_cScrollDelay
== 0)
2905 /* Mouse did hover another 250 ms over the scroll-area */
2906 if (htinfo
.pt
.x
< SCROLLAREAWIDTH
)
2907 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEUP
, 0);
2909 if (htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
)
2910 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEDOWN
, 0);
2912 if (htinfo
.pt
.y
< SCROLLAREAWIDTH
)
2913 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEUP
, 0);
2915 if (htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
)
2916 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEDOWN
, 0);
2921 m_cScrollDelay
= 0; /* Reset, if the cursor is not over the listview's scroll-area */
2924 m_ptLastMousePos
= htinfo
.pt
;
2926 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2927 if (m_pCurDropTarget
&& lResult
== m_iDragOverItem
)
2928 return m_pCurDropTarget
->DragOver(grfKeyState
, pt
, pdwEffect
);
2930 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2931 if (m_pCurDropTarget
)
2933 m_pCurDropTarget
->DragLeave();
2934 m_pCurDropTarget
.Release();
2937 m_iDragOverItem
= lResult
;
2940 /* We are not above one of the listview's subitems. Bind to the parent folder's
2941 * DropTarget interface. */
2942 hr
= m_pSFParent
->CreateViewObject(NULL
, IID_PPV_ARG(IDropTarget
,&m_pCurDropTarget
));
2946 /* Query the relative PIDL of the shellfolder object represented by the currently
2947 * dragged over listview-item ... */
2948 PCUITEMID_CHILD pidl
= _PidlByItem(lResult
);
2950 /* ... and bind m_pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2951 hr
= m_pSFParent
->GetUIObjectOf(m_ListView
, 1, &pidl
, IID_NULL_PPV_ARG(IDropTarget
, &m_pCurDropTarget
));
2954 /* If anything failed, m_pCurDropTarget should be NULL now, which ought to be a save state. */
2958 /* Notify the item just entered via DragEnter. */
2959 return m_pCurDropTarget
->DragEnter(m_pCurDataObject
, grfKeyState
, pt
, pdwEffect
);
2962 HRESULT WINAPI
CDefView::DragEnter(IDataObject
*pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2964 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2965 m_pCurDataObject
= pDataObject
;
2966 pDataObject
->AddRef();
2968 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2971 HRESULT WINAPI
CDefView::DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2973 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2976 HRESULT WINAPI
CDefView::DragLeave()
2978 if (m_pCurDropTarget
)
2980 m_pCurDropTarget
->DragLeave();
2981 m_pCurDropTarget
.Release();
2984 if (m_pCurDataObject
!= NULL
)
2986 m_pCurDataObject
.Release();
2989 m_iDragOverItem
= 0;
2994 HRESULT WINAPI
CDefView::Drop(IDataObject
* pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2996 if (m_pCurDropTarget
)
2998 m_pCurDropTarget
->Drop(pDataObject
, grfKeyState
, pt
, pdwEffect
);
2999 m_pCurDropTarget
.Release();
3002 m_pCurDataObject
.Release();
3003 m_iDragOverItem
= 0;
3007 /**********************************************************
3008 * ISVDropSource implementation
3011 HRESULT WINAPI
CDefView::QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
)
3013 TRACE("(%p)\n", this);
3016 return DRAGDROP_S_CANCEL
;
3017 else if (!(grfKeyState
& MK_LBUTTON
) && !(grfKeyState
& MK_RBUTTON
))
3018 return DRAGDROP_S_DROP
;
3023 HRESULT WINAPI
CDefView::GiveFeedback(DWORD dwEffect
)
3025 TRACE("(%p)\n", this);
3027 return DRAGDROP_S_USEDEFAULTCURSORS
;
3030 /**********************************************************
3031 * ISVViewObject implementation
3034 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
)
3036 FIXME("Stub: this=%p\n", this);
3041 HRESULT WINAPI
CDefView::GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
, HDC hicTargetDevice
, LOGPALETTE
**ppColorSet
)
3043 FIXME("Stub: this=%p\n", this);
3048 HRESULT WINAPI
CDefView::Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
)
3050 FIXME("Stub: this=%p\n", this);
3055 HRESULT WINAPI
CDefView::Unfreeze(DWORD dwFreeze
)
3057 FIXME("Stub: this=%p\n", this);
3062 HRESULT WINAPI
CDefView::SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
)
3064 FIXME("partial stub: %p %08x %08x %p\n", this, aspects
, advf
, pAdvSink
);
3066 /* FIXME: we set the AdviseSink, but never use it to send any advice */
3067 m_pAdvSink
= pAdvSink
;
3068 m_dwAspects
= aspects
;
3074 HRESULT WINAPI
CDefView::GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
)
3076 TRACE("this=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n", this, pAspects
, pAdvf
, ppAdvSink
);
3080 *ppAdvSink
= m_pAdvSink
;
3081 m_pAdvSink
.p
->AddRef();
3085 *pAspects
= m_dwAspects
;
3093 HRESULT STDMETHODCALLTYPE
CDefView::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
3095 if (IsEqualIID(guidService
, SID_IShellBrowser
))
3096 return m_pShellBrowser
->QueryInterface(riid
, ppvObject
);
3097 else if(IsEqualIID(guidService
, SID_IFolderView
))
3098 return QueryInterface(riid
, ppvObject
);
3100 return E_NOINTERFACE
;
3103 HRESULT
CDefView::_MergeToolbar()
3105 CComPtr
<IExplorerToolbar
> ptb
; // [sp+8h] [bp-4h]@1
3109 hr
= IUnknown_QueryService(m_pShellBrowser
, IID_IExplorerToolbar
, IID_PPV_ARG(IExplorerToolbar
, &ptb
));
3113 m_Category
= CGID_DefViewFrame
;
3115 hr
= ptb
->SetCommandTarget(static_cast<IOleCommandTarget
*>(this), &m_Category
, 0);
3123 hr
= ptb
->AddButtons(&m_Category
, buttonsCount
, buttons
);
3130 /**********************************************************
3131 * IShellView_Constructor
3133 HRESULT WINAPI
IShellView_Constructor(IShellFolder
*pFolder
, IShellView
**newView
)
3135 return ShellObjectCreatorInit
<CDefView
>(pFolder
, IID_IShellView
, newView
);
3138 HRESULT WINAPI
CDefView_Constructor(IShellFolder
*pFolder
, REFIID riid
, LPVOID
* ppvOut
)
3140 return ShellObjectCreatorInit
<CDefView
>(pFolder
, riid
, ppvOut
);