Merge the following revisions from kernel-fun branch:
[reactos.git] / reactos / dll / win32 / shell32 / CDefView.cpp
1 /*
2 * ShellView
3 *
4 * Copyright 1998,1999 <juergen.schmied@debitel.net>
5 *
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.
8 *
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.
13 *
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.
18 *
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
22 *
23 * FIXME: The order by part of the background context menu should be
24 * built according to the columns shown.
25 *
26 * FIXME: CheckToolbar: handle the "new folder" and "folder up" button
27 *
28 * FIXME: ShellView_FillList: consider sort orders
29 */
30
31 /*
32 TODO:
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
49 */
50
51 #include "precomp.h"
52
53 #include <atlwin.h>
54 #include <rosctrls.h>
55
56 WINE_DEFAULT_DEBUG_CHANNEL(shell);
57
58 #undef SV_CLASS_NAME
59
60 static const WCHAR SV_CLASS_NAME[] = {'S', 'H', 'E', 'L', 'L', 'D', 'L', 'L', '_', 'D', 'e', 'f', 'V', 'i', 'e', 'w', 0};
61
62 typedef struct
63 {
64 BOOL bIsAscending;
65 INT nHeaderID;
66 INT nLastHeaderID;
67 } LISTVIEW_SORT_INFO, *LPLISTVIEW_SORT_INFO;
68
69 #define SHV_CHANGE_NOTIFY WM_USER + 0x1111
70
71 class CDefView :
72 public CWindowImpl<CDefView, CWindow, CControlWinTraits>,
73 public CComObjectRootEx<CComMultiThreadModelNoCS>,
74 public IShellView,
75 public IFolderView,
76 public IShellFolderView,
77 public IOleCommandTarget,
78 public IDropTarget,
79 public IDropSource,
80 public IViewObject,
81 public IServiceProvider
82 {
83 private:
84 CComPtr<IShellFolder> m_pSFParent;
85 CComPtr<IShellFolder2> m_pSF2Parent;
86 CComPtr<IShellBrowser> m_pShellBrowser;
87 CComPtr<ICommDlgBrowser> m_pCommDlgBrowser;
88 CListView m_ListView;
89 HWND m_hWndParent;
90 FOLDERSETTINGS m_FolderSettings;
91 HMENU m_hMenu;
92 BOOL m_menusLoaded;
93 UINT m_uState;
94 UINT m_cidl;
95 PCUITEMID_CHILD_ARRAY m_apidl;
96 LISTVIEW_SORT_INFO m_sortInfo;
97 ULONG m_hNotify; /* change notification handle */
98 HACCEL m_hAccel;
99 DWORD m_dwAspects;
100 DWORD m_dwAdvf;
101 CComPtr<IAdviseSink> m_pAdvSink;
102 // for drag and drop
103 CComPtr<IDropTarget> m_pCurDropTarget; /* The sub-item, which is currently dragged over */
104 CComPtr<IDataObject> m_pCurDataObject; /* The dragged data-object */
105 LONG m_iDragOverItem; /* Dragged over item's index, iff m_pCurDropTarget != NULL */
106 UINT m_cScrollDelay; /* Send a WM_*SCROLL msg every 250 ms during drag-scroll */
107 POINT m_ptLastMousePos; /* Mouse position at last DragOver call */
108 //
109 CComPtr<IContextMenu> m_pCM;
110
111 BOOL m_isEditing;
112
113 CLSID m_Category;
114 HMENU m_hView;
115 private:
116
117 HRESULT _MergeToolbar();
118
119 public:
120 CDefView();
121 ~CDefView();
122 HRESULT WINAPI Initialize(IShellFolder *shellFolder);
123 HRESULT IncludeObject(PCUITEMID_CHILD pidl);
124 HRESULT OnDefaultCommand();
125 HRESULT OnStateChange(UINT uFlags);
126 void CheckToolbar();
127 void SetStyle(DWORD dwAdd, DWORD dwRemove);
128 BOOL CreateList();
129 void UpdateListColors();
130 BOOL InitList();
131 static INT CALLBACK CompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData);
132 static INT CALLBACK ListViewCompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lpData);
133
134 PCUITEMID_CHILD _PidlByItem(int i);
135 PCUITEMID_CHILD _PidlByItem(LVITEM& lvItem);
136 int LV_FindItemByPidl(PCUITEMID_CHILD pidl);
137 BOOLEAN LV_AddItem(PCUITEMID_CHILD pidl);
138 BOOLEAN LV_DeleteItem(PCUITEMID_CHILD pidl);
139 BOOLEAN LV_RenameItem(PCUITEMID_CHILD pidlOld, PCUITEMID_CHILD pidlNew);
140 static INT CALLBACK fill_list(LPVOID ptr, LPVOID arg);
141 HRESULT FillList();
142 HMENU BuildFileMenu();
143 void PrepareShowFileMenu(HMENU hSubMenu);
144 void PrepareShowViewMenu(HMENU hSubMenu);
145 UINT GetSelections();
146 HRESULT OpenSelectedItems();
147 void OnDeactivate();
148 void DoActivate(UINT uState);
149 HRESULT drag_notify_subitem(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
150 LRESULT OnExplorerCommand(UINT uCommand, BOOL bUseSelection);
151
152 // *** IOleWindow methods ***
153 virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND *lphwnd);
154 virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode);
155
156 // *** IShellView methods ***
157 virtual HRESULT STDMETHODCALLTYPE TranslateAccelerator(MSG *pmsg);
158 virtual HRESULT STDMETHODCALLTYPE EnableModeless(BOOL fEnable);
159 virtual HRESULT STDMETHODCALLTYPE UIActivate(UINT uState);
160 virtual HRESULT STDMETHODCALLTYPE Refresh();
161 virtual HRESULT STDMETHODCALLTYPE CreateViewWindow(IShellView *psvPrevious, LPCFOLDERSETTINGS pfs, IShellBrowser *psb, RECT *prcView, HWND *phWnd);
162 virtual HRESULT STDMETHODCALLTYPE DestroyViewWindow();
163 virtual HRESULT STDMETHODCALLTYPE GetCurrentInfo(LPFOLDERSETTINGS pfs);
164 virtual HRESULT STDMETHODCALLTYPE AddPropertySheetPages(DWORD dwReserved, LPFNSVADDPROPSHEETPAGE pfn, LPARAM lparam);
165 virtual HRESULT STDMETHODCALLTYPE SaveViewState();
166 virtual HRESULT STDMETHODCALLTYPE SelectItem(PCUITEMID_CHILD pidlItem, SVSIF uFlags);
167 virtual HRESULT STDMETHODCALLTYPE GetItemObject(UINT uItem, REFIID riid, void **ppv);
168
169 // *** IFolderView methods ***
170 virtual HRESULT STDMETHODCALLTYPE GetCurrentViewMode(UINT *pViewMode);
171 virtual HRESULT STDMETHODCALLTYPE SetCurrentViewMode(UINT ViewMode);
172 virtual HRESULT STDMETHODCALLTYPE GetFolder(REFIID riid, void **ppv);
173 virtual HRESULT STDMETHODCALLTYPE Item(int iItemIndex, PITEMID_CHILD *ppidl);
174 virtual HRESULT STDMETHODCALLTYPE ItemCount(UINT uFlags, int *pcItems);
175 virtual HRESULT STDMETHODCALLTYPE Items(UINT uFlags, REFIID riid, void **ppv);
176 virtual HRESULT STDMETHODCALLTYPE GetSelectionMarkedItem(int *piItem);
177 virtual HRESULT STDMETHODCALLTYPE GetFocusedItem(int *piItem);
178 virtual HRESULT STDMETHODCALLTYPE GetItemPosition(PCUITEMID_CHILD pidl, POINT *ppt);
179 virtual HRESULT STDMETHODCALLTYPE GetSpacing(POINT *ppt);
180 virtual HRESULT STDMETHODCALLTYPE GetDefaultSpacing(POINT *ppt);
181 virtual HRESULT STDMETHODCALLTYPE GetAutoArrange();
182 virtual HRESULT STDMETHODCALLTYPE SelectItem(int iItem, DWORD dwFlags);
183 virtual HRESULT STDMETHODCALLTYPE SelectAndPositionItems(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, POINT *apt, DWORD dwFlags);
184
185 // *** IShellFolderView methods ***
186 virtual HRESULT STDMETHODCALLTYPE Rearrange(LPARAM sort);
187 virtual HRESULT STDMETHODCALLTYPE GetArrangeParam(LPARAM *sort);
188 virtual HRESULT STDMETHODCALLTYPE ArrangeGrid();
189 virtual HRESULT STDMETHODCALLTYPE AutoArrange();
190 virtual HRESULT STDMETHODCALLTYPE AddObject(PITEMID_CHILD pidl, UINT *item);
191 virtual HRESULT STDMETHODCALLTYPE GetObject(PITEMID_CHILD *pidl, UINT item);
192 virtual HRESULT STDMETHODCALLTYPE RemoveObject(PITEMID_CHILD pidl, UINT *item);
193 virtual HRESULT STDMETHODCALLTYPE GetObjectCount(UINT *count);
194 virtual HRESULT STDMETHODCALLTYPE SetObjectCount(UINT count, UINT flags);
195 virtual HRESULT STDMETHODCALLTYPE UpdateObject(PITEMID_CHILD pidl_old, PITEMID_CHILD pidl_new, UINT *item);
196 virtual HRESULT STDMETHODCALLTYPE RefreshObject(PITEMID_CHILD pidl, UINT *item);
197 virtual HRESULT STDMETHODCALLTYPE SetRedraw(BOOL redraw);
198 virtual HRESULT STDMETHODCALLTYPE GetSelectedCount(UINT *count);
199 virtual HRESULT STDMETHODCALLTYPE GetSelectedObjects(PCUITEMID_CHILD **pidl, UINT *items);
200 virtual HRESULT STDMETHODCALLTYPE IsDropOnSource(IDropTarget *drop_target);
201 virtual HRESULT STDMETHODCALLTYPE GetDragPoint(POINT *pt);
202 virtual HRESULT STDMETHODCALLTYPE GetDropPoint(POINT *pt);
203 virtual HRESULT STDMETHODCALLTYPE MoveIcons(IDataObject *obj);
204 virtual HRESULT STDMETHODCALLTYPE SetItemPos(PCUITEMID_CHILD pidl, POINT *pt);
205 virtual HRESULT STDMETHODCALLTYPE IsBkDropTarget(IDropTarget *drop_target);
206 virtual HRESULT STDMETHODCALLTYPE SetClipboard(BOOL move);
207 virtual HRESULT STDMETHODCALLTYPE SetPoints(IDataObject *obj);
208 virtual HRESULT STDMETHODCALLTYPE GetItemSpacing(ITEMSPACING *spacing);
209 virtual HRESULT STDMETHODCALLTYPE SetCallback(IShellFolderViewCB *new_cb, IShellFolderViewCB **old_cb);
210 virtual HRESULT STDMETHODCALLTYPE Select(UINT flags);
211 virtual HRESULT STDMETHODCALLTYPE QuerySupport(UINT *support);
212 virtual HRESULT STDMETHODCALLTYPE SetAutomationObject(IDispatch *disp);
213
214 // *** IOleCommandTarget methods ***
215 virtual HRESULT STDMETHODCALLTYPE QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[ ], OLECMDTEXT *pCmdText);
216 virtual HRESULT STDMETHODCALLTYPE Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut);
217
218 // *** IDropTarget methods ***
219 virtual HRESULT STDMETHODCALLTYPE DragEnter(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
220 virtual HRESULT STDMETHODCALLTYPE DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
221 virtual HRESULT STDMETHODCALLTYPE DragLeave();
222 virtual HRESULT STDMETHODCALLTYPE Drop(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
223
224 // *** IDropSource methods ***
225 virtual HRESULT STDMETHODCALLTYPE QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState);
226 virtual HRESULT STDMETHODCALLTYPE GiveFeedback(DWORD dwEffect);
227
228 // *** IViewObject methods ***
229 virtual HRESULT STDMETHODCALLTYPE Draw(DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd,
230 HDC hdcTargetDev, HDC hdcDraw, LPCRECTL lprcBounds, LPCRECTL lprcWBounds,
231 BOOL ( STDMETHODCALLTYPE *pfnContinue )(ULONG_PTR dwContinue), ULONG_PTR dwContinue);
232 virtual HRESULT STDMETHODCALLTYPE GetColorSet(DWORD dwDrawAspect, LONG lindex, void *pvAspect,
233 DVTARGETDEVICE *ptd, HDC hicTargetDev, LOGPALETTE **ppColorSet);
234 virtual HRESULT STDMETHODCALLTYPE Freeze(DWORD dwDrawAspect, LONG lindex, void *pvAspect, DWORD *pdwFreeze);
235 virtual HRESULT STDMETHODCALLTYPE Unfreeze(DWORD dwFreeze);
236 virtual HRESULT STDMETHODCALLTYPE SetAdvise(DWORD aspects, DWORD advf, IAdviseSink *pAdvSink);
237 virtual HRESULT STDMETHODCALLTYPE GetAdvise(DWORD *pAspects, DWORD *pAdvf, IAdviseSink **ppAdvSink);
238
239 // *** IServiceProvider methods ***
240 virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID guidService, REFIID riid, void **ppvObject);
241
242 // message handlers
243 LRESULT OnShowWindow(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
244 LRESULT OnGetDlgCode(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
245 LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
246 LRESULT OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
247 LRESULT OnSysColorChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
248 LRESULT OnGetShellBrowser(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
249 LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
250 LRESULT OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
251 LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
252 LRESULT OnActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
253 LRESULT OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
254 LRESULT OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
255 LRESULT OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
256 LRESULT OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
257 LRESULT OnChangeNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
258 LRESULT OnCustomItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
259 LRESULT OnSettingChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
260 LRESULT OnInitMenuPopup(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
261
262 static ATL::CWndClassInfo& GetWndClassInfo()
263 {
264 static ATL::CWndClassInfo wc =
265 {
266 { sizeof(WNDCLASSEX), 0, StartWindowProc,
267 0, 0, NULL, NULL,
268 LoadCursor(NULL, IDC_ARROW), (HBRUSH)(COLOR_BACKGROUND + 1), NULL, SV_CLASS_NAME, NULL
269 },
270 NULL, NULL, IDC_ARROW, TRUE, 0, _T("")
271 };
272 return wc;
273 }
274
275 virtual WNDPROC GetWindowProc()
276 {
277 return WindowProc;
278 }
279
280 static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
281 {
282 CDefView *pThis;
283 LRESULT result;
284
285 // must hold a reference during message handling
286 pThis = reinterpret_cast<CDefView *>(hWnd);
287 pThis->AddRef();
288 result = CWindowImpl<CDefView, CWindow, CControlWinTraits>::WindowProc(hWnd, uMsg, wParam, lParam);
289 pThis->Release();
290 return result;
291 }
292
293 BEGIN_MSG_MAP(CDefView)
294 MESSAGE_HANDLER(WM_SIZE, OnSize)
295 MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
296 MESSAGE_HANDLER(WM_KILLFOCUS, OnKillFocus)
297 MESSAGE_HANDLER(WM_CREATE, OnCreate)
298 MESSAGE_HANDLER(WM_ACTIVATE, OnActivate)
299 MESSAGE_HANDLER(WM_NOTIFY, OnNotify)
300 MESSAGE_HANDLER(WM_COMMAND, OnCommand)
301 MESSAGE_HANDLER(SHV_CHANGE_NOTIFY, OnChangeNotify)
302 MESSAGE_HANDLER(WM_CONTEXTMENU, OnContextMenu)
303 MESSAGE_HANDLER(WM_DRAWITEM, OnCustomItem)
304 MESSAGE_HANDLER(WM_MEASUREITEM, OnCustomItem)
305 MESSAGE_HANDLER(WM_SHOWWINDOW, OnShowWindow)
306 MESSAGE_HANDLER(WM_GETDLGCODE, OnGetDlgCode)
307 MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
308 MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
309 MESSAGE_HANDLER(WM_SYSCOLORCHANGE, OnSysColorChange)
310 MESSAGE_HANDLER(CWM_GETISHELLBROWSER, OnGetShellBrowser)
311 MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange)
312 MESSAGE_HANDLER(WM_INITMENUPOPUP, OnInitMenuPopup)
313 END_MSG_MAP()
314
315 BEGIN_COM_MAP(CDefView)
316 COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
317 COM_INTERFACE_ENTRY_IID(IID_IShellView, IShellView)
318 COM_INTERFACE_ENTRY_IID(IID_IFolderView, IFolderView)
319 COM_INTERFACE_ENTRY_IID(IID_IShellFolderView, IShellFolderView)
320 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget, IOleCommandTarget)
321 COM_INTERFACE_ENTRY_IID(IID_IDropTarget, IDropTarget)
322 COM_INTERFACE_ENTRY_IID(IID_IDropSource, IDropSource)
323 COM_INTERFACE_ENTRY_IID(IID_IViewObject, IViewObject)
324 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider)
325 END_COM_MAP()
326 };
327
328 /* ListView Header ID's */
329 #define LISTVIEW_COLUMN_NAME 0
330 #define LISTVIEW_COLUMN_SIZE 1
331 #define LISTVIEW_COLUMN_TYPE 2
332 #define LISTVIEW_COLUMN_TIME 3
333 #define LISTVIEW_COLUMN_ATTRIB 4
334
335 /*menu items */
336 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
337 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
338 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
339
340 #define ID_LISTVIEW 1
341
342 /*windowsx.h */
343 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
344 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
345 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
346
347 typedef void (CALLBACK *PFNSHGETSETTINGSPROC)(LPSHELLFLAGSTATE lpsfs, DWORD dwMask);
348
349 CDefView::CDefView() :
350 m_ListView(),
351 m_hWndParent(NULL),
352 m_hMenu(NULL),
353 m_menusLoaded(FALSE),
354 m_uState(0),
355 m_cidl(0),
356 m_apidl(NULL),
357 m_hNotify(0),
358 m_hAccel(NULL),
359 m_dwAspects(0),
360 m_dwAdvf(0),
361 m_iDragOverItem(0),
362 m_cScrollDelay(0),
363 m_isEditing(FALSE),
364 m_hView(NULL)
365 {
366 ZeroMemory(&m_FolderSettings, sizeof(m_FolderSettings));
367 ZeroMemory(&m_sortInfo, sizeof(m_sortInfo));
368 ZeroMemory(&m_ptLastMousePos, sizeof(m_ptLastMousePos));
369 ZeroMemory(&m_Category, sizeof(m_Category));
370 }
371
372 CDefView::~CDefView()
373 {
374 TRACE(" destroying IShellView(%p)\n", this);
375
376 if (m_hWnd)
377 {
378 DestroyViewWindow();
379 }
380
381 SHFree(m_apidl);
382 }
383
384 HRESULT WINAPI CDefView::Initialize(IShellFolder *shellFolder)
385 {
386 m_pSFParent = shellFolder;
387 shellFolder->QueryInterface(IID_PPV_ARG(IShellFolder2, &m_pSF2Parent));
388
389 return S_OK;
390 }
391
392 /**********************************************************
393 *
394 * ##### helperfunctions for communication with ICommDlgBrowser #####
395 */
396 HRESULT CDefView::IncludeObject(PCUITEMID_CHILD pidl)
397 {
398 HRESULT ret = S_OK;
399
400 if (m_pCommDlgBrowser.p != NULL)
401 {
402 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl);
403 ret = m_pCommDlgBrowser->IncludeObject(this, pidl);
404 TRACE("--0x%08x\n", ret);
405 }
406
407 return ret;
408 }
409
410 HRESULT CDefView::OnDefaultCommand()
411 {
412 HRESULT ret = S_FALSE;
413
414 if (m_pCommDlgBrowser.p != NULL)
415 {
416 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
417 ret = m_pCommDlgBrowser->OnDefaultCommand(this);
418 TRACE("-- returns %08x\n", ret);
419 }
420
421 return ret;
422 }
423
424 HRESULT CDefView::OnStateChange(UINT uFlags)
425 {
426 HRESULT ret = S_FALSE;
427
428 if (m_pCommDlgBrowser.p != NULL)
429 {
430 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags);
431 ret = m_pCommDlgBrowser->OnStateChange(this, uFlags);
432 TRACE("--\n");
433 }
434
435 return ret;
436 }
437 /**********************************************************
438 * set the toolbar of the filedialog buttons
439 *
440 * - activates the buttons from the shellbrowser according to
441 * the view state
442 */
443 void CDefView::CheckToolbar()
444 {
445 LRESULT result;
446
447 TRACE("\n");
448
449 if (m_pCommDlgBrowser != NULL)
450 {
451 m_pShellBrowser->SendControlMsg(FCW_TOOLBAR, TB_CHECKBUTTON,
452 FCIDM_TB_SMALLICON, (m_FolderSettings.ViewMode == FVM_LIST) ? TRUE : FALSE, &result);
453 m_pShellBrowser->SendControlMsg(FCW_TOOLBAR, TB_CHECKBUTTON,
454 FCIDM_TB_REPORTVIEW, (m_FolderSettings.ViewMode == FVM_DETAILS) ? TRUE : FALSE, &result);
455 m_pShellBrowser->SendControlMsg(FCW_TOOLBAR, TB_ENABLEBUTTON,
456 FCIDM_TB_SMALLICON, TRUE, &result);
457 m_pShellBrowser->SendControlMsg(FCW_TOOLBAR, TB_ENABLEBUTTON,
458 FCIDM_TB_REPORTVIEW, TRUE, &result);
459 }
460 }
461
462 /**********************************************************
463 *
464 * ##### helperfunctions for initializing the view #####
465 */
466 /**********************************************************
467 * change the style of the listview control
468 */
469 void CDefView::SetStyle(DWORD dwAdd, DWORD dwRemove)
470 {
471 DWORD tmpstyle;
472
473 TRACE("(%p)\n", this);
474
475 tmpstyle = ::GetWindowLongPtrW(m_ListView, GWL_STYLE);
476 ::SetWindowLongPtrW(m_ListView, GWL_STYLE, dwAdd | (tmpstyle & ~dwRemove));
477 }
478
479 /**********************************************************
480 * ShellView_CreateList()
481 *
482 * - creates the list view window
483 */
484 BOOL CDefView::CreateList()
485 { DWORD dwStyle, dwExStyle;
486
487 TRACE("%p\n", this);
488
489 dwStyle = WS_TABSTOP | WS_VISIBLE | WS_CHILDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
490 LVS_SHAREIMAGELISTS | LVS_EDITLABELS | LVS_AUTOARRANGE;
491 dwExStyle = WS_EX_CLIENTEDGE;
492
493 if (m_FolderSettings.fFlags & FWF_DESKTOP)
494 dwStyle |= LVS_ALIGNLEFT;
495 else
496 dwStyle |= LVS_ALIGNTOP | LVS_SHOWSELALWAYS;
497
498 switch (m_FolderSettings.ViewMode)
499 {
500 case FVM_ICON:
501 dwStyle |= LVS_ICON;
502 break;
503
504 case FVM_DETAILS:
505 dwStyle |= LVS_REPORT;
506 break;
507
508 case FVM_SMALLICON:
509 dwStyle |= LVS_SMALLICON;
510 break;
511
512 case FVM_LIST:
513 dwStyle |= LVS_LIST;
514 break;
515
516 default:
517 dwStyle |= LVS_LIST;
518 break;
519 }
520
521 if (m_FolderSettings.fFlags & FWF_AUTOARRANGE)
522 dwStyle |= LVS_AUTOARRANGE;
523
524 if (m_FolderSettings.fFlags & FWF_DESKTOP)
525 m_FolderSettings.fFlags |= FWF_NOCLIENTEDGE | FWF_NOSCROLL;
526
527 if (m_FolderSettings.fFlags & FWF_SINGLESEL)
528 dwStyle |= LVS_SINGLESEL;
529
530 if (m_FolderSettings.fFlags & FWF_NOCLIENTEDGE)
531 dwExStyle &= ~WS_EX_CLIENTEDGE;
532
533 RECT rcListView = {0,0,0,0};
534 m_ListView.Create(m_hWnd, rcListView, NULL,dwStyle, dwExStyle, ID_LISTVIEW);
535
536 if (!m_ListView)
537 return FALSE;
538
539 m_sortInfo.bIsAscending = TRUE;
540 m_sortInfo.nHeaderID = -1;
541 m_sortInfo.nLastHeaderID = -1;
542
543 UpdateListColors();
544
545 /* UpdateShellSettings(); */
546 return TRUE;
547 }
548
549 void CDefView::UpdateListColors()
550 {
551 if (m_FolderSettings.fFlags & FWF_DESKTOP)
552 {
553 /* Check if drop shadows option is enabled */
554 BOOL bDropShadow = FALSE;
555 DWORD cbDropShadow = sizeof(bDropShadow);
556 WCHAR wszBuf[16] = L"";
557
558 RegGetValueW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
559 L"ListviewShadow", RRF_RT_DWORD, NULL, &bDropShadow, &cbDropShadow);
560 if (bDropShadow && SystemParametersInfoW(SPI_GETDESKWALLPAPER, _countof(wszBuf), wszBuf, 0) && wszBuf[0])
561 {
562 m_ListView.SetTextBkColor(CLR_NONE);
563 m_ListView.SetBkColor(CLR_NONE);
564 m_ListView.SetTextColor(RGB(255, 255, 255));
565 m_ListView.SetExtendedListViewStyle(LVS_EX_TRANSPARENTSHADOWTEXT, LVS_EX_TRANSPARENTSHADOWTEXT);
566 }
567 else
568 {
569 COLORREF crDesktop = GetSysColor(COLOR_DESKTOP);
570 m_ListView.SetTextBkColor(crDesktop);
571 m_ListView.SetBkColor(crDesktop);
572 if (GetRValue(crDesktop) + GetGValue(crDesktop) + GetBValue(crDesktop) > 128 * 3)
573 m_ListView.SetTextColor(RGB(0, 0, 0));
574 else
575 m_ListView.SetTextColor(RGB(255, 255, 255));
576 m_ListView.SetExtendedListViewStyle(LVS_EX_TRANSPARENTSHADOWTEXT);
577 }
578 }
579 }
580
581 /**********************************************************
582 * ShellView_InitList()
583 *
584 * - adds all needed columns to the shellview
585 */
586 BOOL CDefView::InitList()
587 {
588 SHELLDETAILS sd;
589 WCHAR szTemp[50];
590 HIMAGELIST big_icons, small_icons;
591
592 TRACE("%p\n", this);
593
594 m_ListView.DeleteAllItems();
595
596 if (m_pSF2Parent)
597 {
598 for (int i = 0; 1; i++)
599 {
600 if (FAILED(m_pSF2Parent->GetDetailsOf(NULL, i, &sd)))
601 break;
602 StrRetToStrNW( szTemp, 50, &sd.str, NULL);
603 m_ListView.InsertColumn(i, szTemp, sd.fmt, sd.cxChar * 8);
604
605 }
606 }
607 else
608 {
609 FIXME("no SF2\n");
610 }
611
612 Shell_GetImageLists(&big_icons, &small_icons);
613 m_ListView.SetImageList(big_icons, LVSIL_NORMAL);
614 m_ListView.SetImageList(small_icons, LVSIL_SMALL);
615
616 return TRUE;
617 }
618
619 /**********************************************************
620 * ShellView_CompareItems()
621 *
622 * NOTES
623 * internal, CALLBACK for DSA_Sort
624 */
625 INT CALLBACK CDefView::CompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
626 {
627 int ret;
628 TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1, lParam2, (LPVOID) lpData);
629
630 if (!lpData)
631 return 0;
632
633 IShellFolder* psf = reinterpret_cast<IShellFolder*>(lpData);
634 PCUIDLIST_RELATIVE pidl1 = reinterpret_cast<PCUIDLIST_RELATIVE>(lParam1);
635 PCUIDLIST_RELATIVE pidl2 = reinterpret_cast<PCUIDLIST_RELATIVE>(lParam2);
636
637 ret = (SHORT)SCODE_CODE(psf->CompareIDs(0, pidl1, pidl2));
638 TRACE("ret=%i\n", ret);
639
640 return ret;
641 }
642
643 /*************************************************************************
644 * ShellView_ListViewCompareItems
645 *
646 * Compare Function for the Listview (FileOpen Dialog)
647 *
648 * PARAMS
649 * lParam1 [I] the first ItemIdList to compare with
650 * lParam2 [I] the second ItemIdList to compare with
651 * lpData [I] The column ID for the header Ctrl to process
652 *
653 * RETURNS
654 * A negative value if the first item should precede the second,
655 * a positive value if the first item should follow the second,
656 * or zero if the two items are equivalent
657 *
658 * NOTES
659 * FIXME: function does what ShellView_CompareItems is supposed to do.
660 * unify it and figure out how to use the undocumented first parameter
661 * of IShellFolder_CompareIDs to do the job this function does and
662 * move this code to IShellFolder.
663 * make LISTVIEW_SORT_INFO obsolete
664 * the way this function works is only usable if we had only
665 * filesystemfolders (25/10/99 jsch)
666 */
667 INT CALLBACK CDefView::ListViewCompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lpData)
668 {
669 INT nDiff = 0;
670 FILETIME fd1, fd2;
671 char strName1[MAX_PATH], strName2[MAX_PATH];
672 BOOL bIsFolder1, bIsFolder2, bIsBothFolder;
673 PCUIDLIST_RELATIVE pidl1 = reinterpret_cast<PCUIDLIST_RELATIVE>(lParam1);
674 PCUIDLIST_RELATIVE pidl2 = reinterpret_cast<PCUIDLIST_RELATIVE>(lParam2);
675 LISTVIEW_SORT_INFO *pSortInfo = reinterpret_cast<LPLISTVIEW_SORT_INFO>(lpData);
676
677
678 bIsFolder1 = _ILIsFolder(pidl1);
679 bIsFolder2 = _ILIsFolder(pidl2);
680 bIsBothFolder = bIsFolder1 && bIsFolder2;
681
682 /* When sorting between a File and a Folder, the Folder gets sorted first */
683 if ( (bIsFolder1 || bIsFolder2) && !bIsBothFolder)
684 {
685 nDiff = bIsFolder1 ? -1 : 1;
686 }
687 else
688 {
689 /* Sort by Time: Folders or Files can be sorted */
690
691 if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TIME)
692 {
693 _ILGetFileDateTime(pidl1, &fd1);
694 _ILGetFileDateTime(pidl2, &fd2);
695 nDiff = CompareFileTime(&fd2, &fd1);
696 }
697 /* Sort by Attribute: Folder or Files can be sorted */
698 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_ATTRIB)
699 {
700 _ILGetFileAttributes(pidl1, strName1, MAX_PATH);
701 _ILGetFileAttributes(pidl2, strName2, MAX_PATH);
702 nDiff = lstrcmpiA(strName1, strName2);
703 }
704 /* Sort by FileName: Folder or Files can be sorted */
705 else if (pSortInfo->nHeaderID == LISTVIEW_COLUMN_NAME || bIsBothFolder)
706 {
707 /* Sort by Text */
708 _ILSimpleGetText(pidl1, strName1, MAX_PATH);
709 _ILSimpleGetText(pidl2, strName2, MAX_PATH);
710 nDiff = lstrcmpiA(strName1, strName2);
711 }
712 /* Sort by File Size, Only valid for Files */
713 else if (pSortInfo->nHeaderID == LISTVIEW_COLUMN_SIZE)
714 {
715 nDiff = (INT)(_ILGetFileSize(pidl1, NULL, 0) - _ILGetFileSize(pidl2, NULL, 0));
716 }
717 /* Sort by File Type, Only valid for Files */
718 else if (pSortInfo->nHeaderID == LISTVIEW_COLUMN_TYPE)
719 {
720 /* Sort by Type */
721 _ILGetFileType(pidl1, strName1, MAX_PATH);
722 _ILGetFileType(pidl2, strName2, MAX_PATH);
723 nDiff = lstrcmpiA(strName1, strName2);
724 }
725 }
726 /* If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
727
728 if (nDiff == 0)
729 {
730 _ILSimpleGetText(pidl1, strName1, MAX_PATH);
731 _ILSimpleGetText(pidl2, strName2, MAX_PATH);
732 nDiff = lstrcmpiA(strName1, strName2);
733 }
734
735 if (!pSortInfo->bIsAscending)
736 {
737 nDiff = -nDiff;
738 }
739
740 return nDiff;
741 }
742
743 PCUITEMID_CHILD CDefView::_PidlByItem(int i)
744 {
745 return reinterpret_cast<PCUITEMID_CHILD>(m_ListView.GetItemData(i));
746 }
747
748 PCUITEMID_CHILD CDefView::_PidlByItem(LVITEM& lvItem)
749 {
750 return reinterpret_cast<PCUITEMID_CHILD>(lvItem.lParam);
751 }
752
753 /**********************************************************
754 * LV_FindItemByPidl()
755 */
756 int CDefView::LV_FindItemByPidl(PCUITEMID_CHILD pidl)
757 {
758 int cItems = m_ListView.GetItemCount();
759
760 for (int i = 0; i<cItems; i++)
761 {
762 PCUITEMID_CHILD currentpidl = _PidlByItem(i);
763 HRESULT hr = m_pSFParent->CompareIDs(0, pidl, currentpidl);
764
765 if (SUCCEEDED(hr) && !HRESULT_CODE(hr))
766 {
767 return i;
768 }
769 }
770 return -1;
771 }
772
773 /**********************************************************
774 * LV_AddItem()
775 */
776 BOOLEAN CDefView::LV_AddItem(PCUITEMID_CHILD pidl)
777 {
778 LVITEMW lvItem;
779
780 TRACE("(%p)(pidl=%p)\n", this, pidl);
781
782 lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; /*set the mask*/
783 lvItem.iItem = m_ListView.GetItemCount(); /*add the item to the end of the list*/
784 lvItem.iSubItem = 0;
785 lvItem.lParam = reinterpret_cast<LPARAM>(ILClone(pidl)); /*set the item's data*/
786 lvItem.pszText = LPSTR_TEXTCALLBACKW; /*get text on a callback basis*/
787 lvItem.iImage = I_IMAGECALLBACK; /*get the image on a callback basis*/
788
789 if (m_ListView.InsertItem(&lvItem) == -1)
790 return FALSE;
791 else
792 return TRUE;
793 }
794
795 /**********************************************************
796 * LV_DeleteItem()
797 */
798 BOOLEAN CDefView::LV_DeleteItem(PCUITEMID_CHILD pidl)
799 {
800 int nIndex;
801
802 TRACE("(%p)(pidl=%p)\n", this, pidl);
803
804 nIndex = LV_FindItemByPidl(pidl);
805
806 return (-1 == m_ListView.DeleteItem(nIndex)) ? FALSE : TRUE;
807 }
808
809 /**********************************************************
810 * LV_RenameItem()
811 */
812 BOOLEAN CDefView::LV_RenameItem(PCUITEMID_CHILD pidlOld, PCUITEMID_CHILD pidlNew)
813 {
814 int nItem;
815 LVITEMW lvItem;
816
817 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", this, pidlOld, pidlNew);
818
819 nItem = LV_FindItemByPidl(pidlOld);
820
821 if ( -1 != nItem )
822 {
823 lvItem.mask = LVIF_PARAM; /* only the pidl */
824 lvItem.iItem = nItem;
825 m_ListView.GetItem(&lvItem);
826
827 SHFree(reinterpret_cast<LPVOID>(lvItem.lParam));
828 lvItem.mask = LVIF_PARAM|LVIF_IMAGE;
829 lvItem.iItem = nItem;
830 lvItem.lParam = reinterpret_cast<LPARAM>(ILClone(pidlNew)); /* set the item's data */
831 lvItem.iImage = SHMapPIDLToSystemImageListIndex(m_pSFParent, pidlNew, 0);
832 m_ListView.SetItem(&lvItem);
833 m_ListView.Update(nItem);
834 return TRUE; /* FIXME: better handling */
835 }
836
837 return FALSE;
838 }
839
840 /**********************************************************
841 * ShellView_FillList()
842 *
843 * - gets the objectlist from the shellfolder
844 * - sorts the list
845 * - fills the list into the view
846 */
847 INT CALLBACK CDefView::fill_list( LPVOID ptr, LPVOID arg )
848 {
849 PITEMID_CHILD pidl = static_cast<PITEMID_CHILD>(ptr);
850 CDefView *pThis = static_cast<CDefView *>(arg);
851
852 /* in a commdlg This works as a filemask*/
853 if (pThis->IncludeObject(pidl) == S_OK)
854 pThis->LV_AddItem(pidl);
855
856 SHFree(pidl);
857 return TRUE;
858 }
859
860 HRESULT CDefView::FillList()
861 {
862 CComPtr<IEnumIDList> pEnumIDList;
863 PITEMID_CHILD pidl;
864 DWORD dwFetched;
865 HRESULT hRes;
866 HDPA hdpa;
867 HKEY hKey;
868 DWORD dFlags = SHCONTF_NONFOLDERS | SHCONTF_FOLDERS;
869
870 TRACE("%p\n", this);
871
872 /* determine if there is a setting to show all the hidden files/folders */
873 if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
874 {
875 DWORD dataLength, flagVal;
876
877 dataLength = sizeof(flagVal);
878 if (RegQueryValueExW(hKey, L"Hidden", NULL, NULL, (LPBYTE)&flagVal, &dataLength) == ERROR_SUCCESS)
879 {
880 /* if the value is 1, then show all hidden files/folders */
881 if (flagVal == 1)
882 dFlags |= SHCONTF_INCLUDEHIDDEN;
883 }
884
885 /* close the key */
886 RegCloseKey(hKey);
887 }
888
889 /* get the itemlist from the shfolder */
890 hRes = m_pSFParent->EnumObjects(m_hWnd, dFlags, &pEnumIDList);
891 if (hRes != S_OK)
892 {
893 if (hRes == S_FALSE)
894 return(NOERROR);
895 return(hRes);
896 }
897
898 /* create a pointer array */
899 hdpa = DPA_Create(16);
900 if (!hdpa)
901 {
902 return(E_OUTOFMEMORY);
903 }
904
905 /* copy the items into the array*/
906 while((S_OK == pEnumIDList->Next(1, &pidl, &dwFetched)) && dwFetched)
907 {
908 if (DPA_InsertPtr(hdpa, 0x7fff, pidl) == -1)
909 {
910 SHFree(pidl);
911 }
912 }
913
914 /* sort the array */
915 DPA_Sort(hdpa, CompareItems, reinterpret_cast<LPARAM>(m_pSFParent.p));
916
917 /*turn the listview's redrawing off*/
918 m_ListView.SetRedraw(FALSE);
919
920 DPA_DestroyCallback( hdpa, fill_list, this);
921
922 /*turn the listview's redrawing back on and force it to draw*/
923 m_ListView.SetRedraw(TRUE);
924
925 return S_OK;
926 }
927
928 LRESULT CDefView::OnShowWindow(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
929 {
930 m_ListView.UpdateWindow();
931 bHandled = FALSE;
932 return 0;
933 }
934
935 LRESULT CDefView::OnGetDlgCode(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
936 {
937 return m_ListView.SendMessageW(uMsg, 0, 0);
938 }
939
940 LRESULT CDefView::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
941 {
942 if (m_hMenu)
943 DestroyMenu(m_hMenu);
944 RevokeDragDrop(m_hWnd);
945 SHChangeNotifyDeregister(m_hNotify);
946 bHandled = FALSE;
947 return 0;
948 }
949
950 LRESULT CDefView::OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
951 {
952 /* redirect to parent */
953 if (m_FolderSettings.fFlags & (FWF_DESKTOP | FWF_TRANSPARENT))
954 return SendMessageW(GetParent(), WM_ERASEBKGND, wParam, lParam);
955
956 bHandled = FALSE;
957 return 0;
958 }
959
960 LRESULT CDefView::OnSysColorChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
961 {
962 /* Update desktop labels color */
963 UpdateListColors();
964
965 /* Forward WM_SYSCOLORCHANGE to common controls */
966 return m_ListView.SendMessageW(uMsg, 0, 0);
967 }
968
969 LRESULT CDefView::OnGetShellBrowser(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
970 {
971 return reinterpret_cast<LRESULT>(m_pShellBrowser.p);
972 }
973
974 /**********************************************************
975 * ShellView_OnCreate()
976 */
977 LRESULT CDefView::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
978 {
979 CComPtr<IDropTarget> pdt;
980 SHChangeNotifyEntry ntreg;
981 CComPtr<IPersistFolder2> ppf2;
982
983 TRACE("%p\n", this);
984
985 if(CreateList())
986 {
987 if(InitList())
988 {
989 FillList();
990 }
991 }
992
993 if (SUCCEEDED(QueryInterface(IID_PPV_ARG(IDropTarget, &pdt))))
994 {
995 if (FAILED(RegisterDragDrop(m_hWnd, pdt)))
996 ERR("Registering Drag Drop Failed");
997 }
998
999 /* register for receiving notifications */
1000 m_pSFParent->QueryInterface(IID_PPV_ARG(IPersistFolder2, &ppf2));
1001 if (ppf2)
1002 {
1003 PIDLIST_ABSOLUTE pidlParent;
1004 ppf2->GetCurFolder(&pidlParent);
1005 ntreg.fRecursive = TRUE;
1006 ntreg.pidl = pidlParent;
1007 m_hNotify = SHChangeNotifyRegister(m_hWnd, SHCNF_IDLIST, SHCNE_ALLEVENTS, SHV_CHANGE_NOTIFY, 1, &ntreg);
1008 SHFree(pidlParent);
1009 }
1010
1011 m_hAccel = LoadAcceleratorsW(shell32_hInstance, MAKEINTRESOURCEW(IDA_SHELLVIEW));
1012
1013 return S_OK;
1014 }
1015
1016 /**********************************************************
1017 * #### Handling of the menus ####
1018 */
1019
1020 HMENU CDefView::BuildFileMenu()
1021 {
1022 HRESULT hr;
1023 CComPtr<IContextMenu> cm;
1024
1025 GetSelections();
1026
1027 hr = m_pSFParent->GetUIObjectOf(m_hWnd, m_cidl, m_apidl, IID_NULL_PPV_ARG(IContextMenu, &cm));
1028 if (FAILED(hr))
1029 return NULL;
1030
1031 HMENU hmenu = CreatePopupMenu();
1032
1033 //FIXME: get proper numbers ?
1034 const UINT first = 0x7800;
1035 const UINT last = 0x7A00;
1036 hr = cm->QueryContextMenu(hmenu, 0, first, last, 0);
1037 if (FAILED(hr))
1038 return NULL;
1039
1040 // TODO: filter or something
1041
1042 return hmenu;
1043 }
1044
1045 void CDefView::PrepareShowFileMenu(HMENU hSubMenu)
1046 {
1047 TRACE("(%p)->(submenu=%p) stub\n", this, hSubMenu);
1048
1049 if (!hSubMenu)
1050 return;
1051
1052 /* Cleanup the items added previously */
1053 for (int i = 0; i < GetMenuItemCount(hSubMenu); )
1054 {
1055 MENUITEMINFOW mii;
1056 mii.cbSize = sizeof(mii);
1057 mii.fMask = MIIM_ID;
1058 GetMenuItemInfoW(hSubMenu, i, TRUE, &mii);
1059
1060 if (mii.wID < 0x8000)
1061 {
1062 DeleteMenu(hSubMenu, i, MF_BYPOSITION);
1063 }
1064 else
1065 {
1066 i++;
1067 }
1068 }
1069
1070 #if 0
1071 /* FIXME/TODO: Reenable when they implemented AND localizable (not hardcoded). */
1072 /* Insert This item at the beginning of the menu. */
1073 _InsertMenuItemW(hSubMenu, 0, TRUE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
1074 _InsertMenuItemW(hSubMenu, 0, TRUE, IDM_MYFILEITEM + 4, MFT_STRING, L"Properties", MFS_DISABLED);
1075 _InsertMenuItemW(hSubMenu, 0, TRUE, IDM_MYFILEITEM + 3, MFT_STRING, L"Rename", MFS_DISABLED);
1076 _InsertMenuItemW(hSubMenu, 0, TRUE, IDM_MYFILEITEM + 2, MFT_STRING, L"Delete", MFS_DISABLED);
1077 _InsertMenuItemW(hSubMenu, 0, TRUE, IDM_MYFILEITEM + 1, MFT_STRING, L"Create Shortcut", MFS_DISABLED);
1078 _InsertMenuItemW(hSubMenu, 0, TRUE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
1079 _InsertMenuItemW(hSubMenu, 0, TRUE, IDM_MYFILEITEM, MFT_STRING, L"New", MFS_ENABLED);
1080 #endif
1081
1082 HMENU menubase = BuildFileMenu();
1083 if (menubase)
1084 {
1085 int count = ::GetMenuItemCount(menubase);
1086 int count2 = ::GetMenuItemCount(hSubMenu);
1087
1088 if (count2 > 0 && count > 0)
1089 {
1090 _InsertMenuItemW(hSubMenu, 0, TRUE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
1091 }
1092
1093 for (int i = count-1; i >= 0; i--)
1094 {
1095 WCHAR label[128];
1096
1097 MENUITEMINFOW mii = { 0 };
1098 mii.cbSize = sizeof(mii);
1099 mii.fMask = MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_CHECKMARKS | MIIM_DATA | MIIM_STRING | MIIM_BITMAP | MIIM_FTYPE;
1100 mii.dwTypeData = label;
1101 mii.cch = _countof(label);
1102 ::GetMenuItemInfoW(menubase, i, TRUE, &mii);
1103
1104 TRACE("Adding item %d label %S type %d\n", mii.wID, mii.dwTypeData, mii.fType);
1105
1106 mii.fType |= MFT_RADIOCHECK;
1107
1108 ::InsertMenuItemW(hSubMenu, 0, TRUE, &mii);
1109 }
1110
1111
1112 ::DestroyMenu(menubase);
1113 }
1114 TRACE("--\n");
1115 }
1116
1117 void CDefView::PrepareShowViewMenu(HMENU hSubMenu)
1118 {
1119 TRACE("(%p)->(submenu=%p)\n", this, hSubMenu);
1120
1121 if (!hSubMenu)
1122 return;
1123
1124 if (m_FolderSettings.ViewMode >= FVM_FIRST && m_FolderSettings.ViewMode <= FVM_LAST)
1125 {
1126 UINT iItemFirst = FCIDM_SHVIEW_BIGICON;
1127 UINT iItemLast = iItemFirst + FVM_LAST - FVM_FIRST;
1128 UINT iItem = iItemFirst + m_FolderSettings.ViewMode - FVM_FIRST;
1129 CheckMenuRadioItem(hSubMenu, iItemFirst, iItemLast, iItem, MF_BYCOMMAND);
1130 }
1131 }
1132
1133 /**********************************************************
1134 * ShellView_GetSelections()
1135 *
1136 * - fills the m_apidl list with the selected objects
1137 *
1138 * RETURNS
1139 * number of selected items
1140 */
1141 UINT CDefView::GetSelections()
1142 {
1143 SHFree(m_apidl);
1144
1145 m_cidl = m_ListView.GetSelectedCount();
1146 m_apidl = reinterpret_cast<PCUITEMID_CHILD_ARRAY>(SHAlloc(m_cidl * sizeof(PCUITEMID_CHILD)));
1147 if (!m_apidl)
1148 {
1149 m_cidl = 0;
1150 return 0;
1151 }
1152
1153 TRACE("-- Items selected =%u\n", m_cidl);
1154
1155 UINT i = 0;
1156 int lvIndex = -1;
1157 while ((lvIndex = m_ListView.GetNextItem(lvIndex, LVNI_SELECTED)) > -1)
1158 {
1159 m_apidl[i] = _PidlByItem(lvIndex);
1160 i++;
1161 if (i == m_cidl)
1162 break;
1163 TRACE("-- selected Item found\n");
1164 }
1165
1166 return m_cidl;
1167 }
1168
1169 /**********************************************************
1170 * ShellView_OpenSelectedItems()
1171 */
1172 HRESULT CDefView::OpenSelectedItems()
1173 {
1174 HMENU hMenu;
1175 CMINVOKECOMMANDINFO cmi;
1176 UINT uCommand;
1177 HRESULT hResult;
1178
1179 m_cidl = m_ListView.GetSelectedCount();
1180 if (m_cidl == 0)
1181 return S_OK;
1182
1183 hResult = OnDefaultCommand();
1184 if (hResult == S_OK)
1185 return hResult;
1186
1187 hMenu = CreatePopupMenu();
1188 if (!hMenu)
1189 return E_FAIL;
1190
1191 hResult = GetItemObject(SVGIO_SELECTION, IID_PPV_ARG(IContextMenu, &m_pCM));
1192 if (FAILED(hResult))
1193 goto cleanup;
1194
1195 hResult = IUnknown_SetSite(m_pCM, (IShellView *)this);
1196 //if (FAILED( hResult))
1197 // goto cleanup;
1198
1199 hResult = m_pCM->QueryContextMenu(hMenu, 0, 0x20, 0x7fff, CMF_DEFAULTONLY);
1200 if (FAILED(hResult))
1201 goto cleanup;
1202
1203 uCommand = GetMenuDefaultItem(hMenu, FALSE, 0);
1204 if (uCommand == (UINT)-1)
1205 {
1206 hResult = E_FAIL;
1207 goto cleanup;
1208 }
1209
1210 ZeroMemory(&cmi, sizeof(cmi));
1211 cmi.cbSize = sizeof(cmi);
1212 cmi.lpVerb = (LPCSTR)MAKEINTRESOURCEA(uCommand);
1213 cmi.hwnd = m_hWnd;
1214
1215 hResult = m_pCM->InvokeCommand(&cmi);
1216
1217 cleanup:
1218
1219 if (hMenu)
1220 DestroyMenu(hMenu);
1221
1222 if (m_pCM)
1223 {
1224 IUnknown_SetSite(m_pCM, NULL);
1225 m_pCM.Release();
1226 }
1227
1228 return hResult;
1229 }
1230
1231 /**********************************************************
1232 * ShellView_DoContextMenu()
1233 */
1234 LRESULT CDefView::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1235 {
1236 WORD x;
1237 WORD y;
1238 UINT uCommand;
1239 HMENU hMenu;
1240 CMINVOKECOMMANDINFO cmi;
1241 HRESULT hResult;
1242
1243 // for some reason I haven't figured out, we sometimes recurse into this method
1244 if (m_pCM != NULL)
1245 return 0;
1246
1247 x = LOWORD(lParam);
1248 y = HIWORD(lParam);
1249
1250 TRACE("(%p)->(0x%08x 0x%08x) stub\n", this, x, y);
1251
1252 hMenu = CreatePopupMenu();
1253 if (!hMenu)
1254 return E_FAIL;
1255
1256 m_cidl = m_ListView.GetSelectedCount();
1257
1258 hResult = GetItemObject( m_cidl ? SVGIO_SELECTION : SVGIO_BACKGROUND, IID_PPV_ARG(IContextMenu, &m_pCM));
1259 if (FAILED( hResult))
1260 goto cleanup;
1261
1262 hResult = IUnknown_SetSite(m_pCM, (IShellView *)this);
1263 //if (FAILED( hResult))
1264 // goto cleanup;
1265
1266 hResult = m_pCM->QueryContextMenu(hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, CMF_NORMAL);
1267 if (FAILED( hResult))
1268 goto cleanup;
1269
1270 if (m_FolderSettings.fFlags & FWF_DESKTOP)
1271 SetMenuDefaultItem(hMenu, FCIDM_SHVIEW_OPEN, MF_BYCOMMAND);
1272
1273 uCommand = TrackPopupMenu(hMenu,
1274 TPM_LEFTALIGN | TPM_RETURNCMD | TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
1275 x, y, 0, m_hWnd, NULL);
1276 if (uCommand == 0)
1277 goto cleanup;
1278
1279 if (uCommand == FCIDM_SHVIEW_OPEN && OnDefaultCommand() == S_OK)
1280 goto cleanup;
1281
1282 ZeroMemory(&cmi, sizeof(cmi));
1283 cmi.cbSize = sizeof(cmi);
1284 cmi.lpVerb = MAKEINTRESOURCEA(uCommand);
1285 cmi.hwnd = m_hWnd;
1286 m_pCM->InvokeCommand(&cmi);
1287
1288 cleanup:
1289
1290 if (m_pCM)
1291 {
1292 IUnknown_SetSite(m_pCM, NULL);
1293 m_pCM.Release();
1294 }
1295
1296 if (hMenu)
1297 DestroyMenu(hMenu);
1298
1299 return 0;
1300 }
1301
1302 LRESULT CDefView::OnExplorerCommand(UINT uCommand, BOOL bUseSelection)
1303 {
1304 HRESULT hResult;
1305 CMINVOKECOMMANDINFO cmi;
1306 HMENU hMenu;
1307
1308 hMenu = CreatePopupMenu();
1309 if (!hMenu)
1310 return 0;
1311
1312 hResult = GetItemObject( bUseSelection ? SVGIO_SELECTION : SVGIO_BACKGROUND, IID_PPV_ARG(IContextMenu, &m_pCM));
1313 if (FAILED( hResult))
1314 goto cleanup;
1315
1316 hResult = IUnknown_SetSite(m_pCM, (IShellView *)this);
1317 //if (FAILED( hResult))
1318 // goto cleanup;
1319
1320 hResult = m_pCM->QueryContextMenu(hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, CMF_NORMAL);
1321 if (FAILED( hResult))
1322 goto cleanup;
1323
1324 ZeroMemory(&cmi, sizeof(cmi));
1325 cmi.cbSize = sizeof(cmi);
1326 cmi.lpVerb = MAKEINTRESOURCEA(uCommand);
1327 cmi.hwnd = m_hWnd;
1328 m_pCM->InvokeCommand(&cmi);
1329
1330 cleanup:
1331
1332 if (m_pCM)
1333 {
1334 IUnknown_SetSite(m_pCM, NULL);
1335 m_pCM.Release();
1336 }
1337
1338 if (hMenu)
1339 DestroyMenu(hMenu);
1340
1341 return 0;
1342 }
1343
1344 /**********************************************************
1345 * ##### message handling #####
1346 */
1347
1348 /**********************************************************
1349 * ShellView_OnSize()
1350 */
1351 LRESULT CDefView::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1352 {
1353 WORD wWidth;
1354 WORD wHeight;
1355
1356 wWidth = LOWORD(lParam);
1357 wHeight = HIWORD(lParam);
1358
1359 TRACE("%p width=%u height=%u\n", this, wWidth, wHeight);
1360
1361 /*resize the ListView to fit our window*/
1362 if (m_ListView)
1363 {
1364 ::MoveWindow(m_ListView, 0, 0, wWidth, wHeight, TRUE);
1365 }
1366
1367 return 0;
1368 }
1369
1370 /**********************************************************
1371 * ShellView_OnDeactivate()
1372 *
1373 * NOTES
1374 * internal
1375 */
1376 void CDefView::OnDeactivate()
1377 {
1378 TRACE("%p\n", this);
1379
1380 if (m_uState != SVUIA_DEACTIVATE)
1381 {
1382 // TODO: cleanup menu after deactivation
1383
1384 m_uState = SVUIA_DEACTIVATE;
1385 }
1386 }
1387
1388 void CDefView::DoActivate(UINT uState)
1389 {
1390 TRACE("%p uState=%x\n", this, uState);
1391
1392 /*don't do anything if the state isn't really changing */
1393 if (m_uState == uState)
1394 {
1395 return;
1396 }
1397
1398 if (uState == SVUIA_DEACTIVATE)
1399 {
1400 OnDeactivate();
1401 }
1402 else
1403 {
1404 if(m_hMenu)
1405 {
1406 if (!m_menusLoaded)
1407 {
1408 MENUITEMINFOW mii = { 0 };
1409
1410 /* initialize EDIT menu */
1411 mii.cbSize = sizeof(mii);
1412 mii.fMask = MIIM_SUBMENU;
1413 if (::GetMenuItemInfoW(m_hMenu, FCIDM_MENU_EDIT, FALSE, &mii))
1414 {
1415 HMENU hSubMenu = mii.hSubMenu;
1416
1417 HMENU menubase = ::LoadMenuW(shell32_hInstance, L"MENU_003");
1418
1419 int count = ::GetMenuItemCount(menubase);
1420 for (int i = 0; i < count; i++)
1421 {
1422 WCHAR label[128];
1423
1424 ZeroMemory(&mii, sizeof(mii));
1425 mii.cbSize = sizeof(mii);
1426 mii.fMask = MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_CHECKMARKS | MIIM_DATA | MIIM_STRING | MIIM_BITMAP | MIIM_FTYPE;
1427 mii.dwTypeData = label;
1428 mii.cch = _countof(label);
1429 ::GetMenuItemInfoW(menubase, i, TRUE, &mii);
1430
1431 TRACE("Adding item %d label %S type %d\n", mii.wID, mii.dwTypeData, mii.fType);
1432
1433 mii.fType |= MFT_RADIOCHECK;
1434
1435 ::InsertMenuItemW(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
1436 }
1437
1438 ::DestroyMenu(menubase);
1439 }
1440
1441 /* initialize VIEW menu */
1442
1443 mii.cbSize = sizeof(mii);
1444 mii.fMask = MIIM_SUBMENU;
1445 if (::GetMenuItemInfoW(m_hMenu, FCIDM_MENU_VIEW, FALSE, &mii))
1446 {
1447 HMENU menubase = ::LoadMenuW(shell32_hInstance, L"MENU_001");
1448
1449 HMENU hSubMenu = mii.hSubMenu;
1450
1451 m_hView = CreatePopupMenu();
1452
1453 _InsertMenuItemW(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
1454
1455 int count = ::GetMenuItemCount(menubase);
1456 for (int i = 0; i < count; i++)
1457 {
1458 WCHAR label[128];
1459
1460 ZeroMemory(&mii, sizeof(mii));
1461 mii.cbSize = sizeof(mii);
1462 mii.fMask = MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_CHECKMARKS | MIIM_DATA | MIIM_STRING | MIIM_BITMAP | MIIM_FTYPE;
1463 mii.dwTypeData = label;
1464 mii.cch = _countof(label);
1465 ::GetMenuItemInfoW(menubase, i, TRUE, &mii);
1466
1467 ::AppendMenuW(m_hView, mii.fType, mii.wID, mii.dwTypeData);
1468
1469 TRACE("Adding item %d label %S type %d\n", mii.wID, mii.dwTypeData, mii.fType);
1470
1471 mii.fType |= MFT_RADIOCHECK;
1472
1473 ::InsertMenuItemW(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
1474 }
1475
1476 ::DestroyMenu(menubase);
1477 }
1478
1479
1480 TRACE("-- before fnSetMenuSB\n");
1481 m_pShellBrowser->SetMenuSB(m_hMenu, 0, m_hWnd);
1482
1483 m_menusLoaded = TRUE;
1484 }
1485 }
1486
1487 if (SVUIA_ACTIVATE_FOCUS == uState)
1488 {
1489 m_ListView.SetFocus();
1490 }
1491 }
1492
1493 m_uState = uState;
1494 TRACE("--\n");
1495 }
1496
1497 /**********************************************************
1498 * ShellView_OnActivate()
1499 */
1500 LRESULT CDefView::OnActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1501 {
1502 DoActivate(SVUIA_ACTIVATE_FOCUS);
1503 return 0;
1504 }
1505
1506 /**********************************************************
1507 * ShellView_OnSetFocus()
1508 *
1509 */
1510 LRESULT CDefView::OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1511 {
1512 TRACE("%p\n", this);
1513
1514 /* Tell the browser one of our windows has received the focus. This
1515 should always be done before merging menus (OnActivate merges the
1516 menus) if one of our windows has the focus.*/
1517
1518 m_pShellBrowser->OnViewWindowActive(this);
1519 DoActivate(SVUIA_ACTIVATE_FOCUS);
1520
1521 /* Set the focus to the listview */
1522 m_ListView.SetFocus();
1523
1524 /* Notify the ICommDlgBrowser interface */
1525 OnStateChange(CDBOSC_SETFOCUS);
1526
1527 return 0;
1528 }
1529
1530 /**********************************************************
1531 * ShellView_OnKillFocus()
1532 */
1533 LRESULT CDefView::OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1534 {
1535 TRACE("(%p) stub\n", this);
1536
1537 DoActivate(SVUIA_ACTIVATE_NOFOCUS);
1538 /* Notify the ICommDlgBrowser */
1539 OnStateChange(CDBOSC_KILLFOCUS);
1540
1541 return 0;
1542 }
1543
1544 /**********************************************************
1545 * ShellView_OnCommand()
1546 *
1547 * NOTES
1548 * the CmdID's are the ones from the context menu
1549 */
1550 LRESULT CDefView::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1551 {
1552 DWORD dwCmdID;
1553 DWORD dwCmd;
1554 HWND hwndCmd;
1555
1556 dwCmdID = GET_WM_COMMAND_ID(wParam, lParam);
1557 dwCmd = GET_WM_COMMAND_CMD(wParam, lParam);
1558 hwndCmd = GET_WM_COMMAND_HWND(wParam, lParam);
1559
1560 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n", this, dwCmdID, dwCmd, hwndCmd);
1561
1562 switch (dwCmdID)
1563 {
1564 case FCIDM_SHVIEW_SMALLICON:
1565 m_FolderSettings.ViewMode = FVM_SMALLICON;
1566 SetStyle (LVS_SMALLICON, LVS_TYPEMASK);
1567 CheckToolbar();
1568 break;
1569
1570 case FCIDM_SHVIEW_BIGICON:
1571 m_FolderSettings.ViewMode = FVM_ICON;
1572 SetStyle (LVS_ICON, LVS_TYPEMASK);
1573 CheckToolbar();
1574 break;
1575
1576 case FCIDM_SHVIEW_LISTVIEW:
1577 m_FolderSettings.ViewMode = FVM_LIST;
1578 SetStyle (LVS_LIST, LVS_TYPEMASK);
1579 CheckToolbar();
1580 break;
1581
1582 case FCIDM_SHVIEW_REPORTVIEW:
1583 m_FolderSettings.ViewMode = FVM_DETAILS;
1584 SetStyle (LVS_REPORT, LVS_TYPEMASK);
1585 CheckToolbar();
1586 break;
1587
1588 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1589 case 0x30:
1590 case 0x31:
1591 case 0x32:
1592 case 0x33:
1593 m_sortInfo.nHeaderID = dwCmdID - 0x30;
1594 m_sortInfo.bIsAscending = TRUE;
1595 m_sortInfo.nLastHeaderID = m_sortInfo.nHeaderID;
1596 m_ListView.SortItems(ListViewCompareItems, &m_sortInfo);
1597 break;
1598
1599 case FCIDM_SHVIEW_REFRESH:
1600 Refresh();
1601 break;
1602
1603 case FCIDM_SHVIEW_DELETE:
1604 case FCIDM_SHVIEW_CUT:
1605 case FCIDM_SHVIEW_COPY:
1606 case FCIDM_SHVIEW_RENAME:
1607 return OnExplorerCommand(dwCmdID, TRUE);
1608
1609 case FCIDM_SHVIEW_INSERT:
1610 case FCIDM_SHVIEW_UNDO:
1611 case FCIDM_SHVIEW_INSERTLINK:
1612 case FCIDM_SHVIEW_NEWFOLDER:
1613 return OnExplorerCommand(dwCmdID, FALSE);
1614 default:
1615 TRACE("-- COMMAND 0x%04x unhandled\n", dwCmdID);
1616 }
1617
1618 return 0;
1619 }
1620
1621 /**********************************************************
1622 * ShellView_OnNotify()
1623 */
1624
1625 LRESULT CDefView::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1626 {
1627 UINT CtlID;
1628 LPNMHDR lpnmh;
1629 LPNMLISTVIEW lpnmlv;
1630 NMLVDISPINFOW *lpdi;
1631 PCUITEMID_CHILD pidl;
1632 BOOL unused;
1633
1634 CtlID = wParam;
1635 lpnmh = (LPNMHDR)lParam;
1636 lpnmlv = (LPNMLISTVIEW)lpnmh;
1637 lpdi = (NMLVDISPINFOW *)lpnmh;
1638
1639 TRACE("%p CtlID=%u lpnmh->code=%x\n", this, CtlID, lpnmh->code);
1640
1641 switch (lpnmh->code)
1642 {
1643 case NM_SETFOCUS:
1644 TRACE("-- NM_SETFOCUS %p\n", this);
1645 OnSetFocus(0, 0, 0, unused);
1646 break;
1647
1648 case NM_KILLFOCUS:
1649 TRACE("-- NM_KILLFOCUS %p\n", this);
1650 OnDeactivate();
1651 /* Notify the ICommDlgBrowser interface */
1652 OnStateChange(CDBOSC_KILLFOCUS);
1653 break;
1654
1655 case NM_CUSTOMDRAW:
1656 TRACE("-- NM_CUSTOMDRAW %p\n", this);
1657 return CDRF_DODEFAULT;
1658
1659 case NM_RELEASEDCAPTURE:
1660 TRACE("-- NM_RELEASEDCAPTURE %p\n", this);
1661 break;
1662
1663 case NM_CLICK:
1664 TRACE("-- NM_CLICK %p\n", this);
1665 break;
1666
1667 case NM_RCLICK:
1668 TRACE("-- NM_RCLICK %p\n", this);
1669 break;
1670
1671 case NM_DBLCLK:
1672 TRACE("-- NM_DBLCLK %p\n", this);
1673 OpenSelectedItems();
1674 break;
1675
1676 case NM_RETURN:
1677 TRACE("-- NM_RETURN %p\n", this);
1678 OpenSelectedItems();
1679 break;
1680
1681 case HDN_ENDTRACKW:
1682 TRACE("-- HDN_ENDTRACKW %p\n", this);
1683 /*nColumn1 = m_ListView.GetColumnWidth(0);
1684 nColumn2 = m_ListView.GetColumnWidth(1);*/
1685 break;
1686
1687 case LVN_DELETEITEM:
1688 TRACE("-- LVN_DELETEITEM %p\n", this);
1689
1690 /*delete the pidl because we made a copy of it*/
1691 SHFree(reinterpret_cast<LPVOID>(lpnmlv->lParam));
1692
1693 break;
1694
1695 case LVN_DELETEALLITEMS:
1696 TRACE("-- LVN_DELETEALLITEMS %p\n", this);
1697 return FALSE;
1698
1699 case LVN_INSERTITEM:
1700 TRACE("-- LVN_INSERTITEM (STUB)%p\n", this);
1701 break;
1702
1703 case LVN_ITEMACTIVATE:
1704 TRACE("-- LVN_ITEMACTIVATE %p\n", this);
1705 OnStateChange(CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
1706 break;
1707
1708 case LVN_COLUMNCLICK:
1709 m_sortInfo.nHeaderID = lpnmlv->iSubItem;
1710 if (m_sortInfo.nLastHeaderID == m_sortInfo.nHeaderID)
1711 m_sortInfo.bIsAscending = !m_sortInfo.bIsAscending;
1712 else
1713 m_sortInfo.bIsAscending = TRUE;
1714 m_sortInfo.nLastHeaderID = m_sortInfo.nHeaderID;
1715
1716 m_ListView.SortItems(ListViewCompareItems, &m_sortInfo);
1717 break;
1718
1719 case LVN_GETDISPINFOA:
1720 case LVN_GETDISPINFOW:
1721 TRACE("-- LVN_GETDISPINFO %p\n", this);
1722 pidl = _PidlByItem(lpdi->item);
1723
1724 if (lpdi->item.mask & LVIF_TEXT) /* text requested */
1725 {
1726 if (m_pSF2Parent)
1727 {
1728 SHELLDETAILS sd;
1729 if (FAILED(m_pSF2Parent->GetDetailsOf(pidl, lpdi->item.iSubItem, &sd)))
1730 {
1731 FIXME("failed to get details\n");
1732 break;
1733 }
1734
1735 if (lpnmh->code == LVN_GETDISPINFOA)
1736 {
1737 /* shouldn't happen */
1738 NMLVDISPINFOA *lpdiA = (NMLVDISPINFOA *)lpnmh;
1739 StrRetToStrNA( lpdiA->item.pszText, lpdiA->item.cchTextMax, &sd.str, NULL);
1740 TRACE("-- text=%s\n", lpdiA->item.pszText);
1741 }
1742 else /* LVN_GETDISPINFOW */
1743 {
1744 StrRetToStrNW( lpdi->item.pszText, lpdi->item.cchTextMax, &sd.str, NULL);
1745 TRACE("-- text=%s\n", debugstr_w(lpdi->item.pszText));
1746 }
1747 }
1748 else
1749 {
1750 FIXME("no SF2\n");
1751 }
1752 }
1753 if(lpdi->item.mask & LVIF_IMAGE) /* image requested */
1754 {
1755 lpdi->item.iImage = SHMapPIDLToSystemImageListIndex(m_pSFParent, pidl, 0);
1756 }
1757 lpdi->item.mask |= LVIF_DI_SETITEM;
1758 break;
1759
1760 case LVN_ITEMCHANGED:
1761 TRACE("-- LVN_ITEMCHANGED %p\n", this);
1762 OnStateChange(CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
1763 break;
1764
1765 case LVN_BEGINDRAG:
1766 case LVN_BEGINRDRAG:
1767 TRACE("-- LVN_BEGINDRAG\n");
1768
1769 if (GetSelections())
1770 {
1771 CComPtr<IDataObject> pda;
1772 DWORD dwAttributes = SFGAO_CANLINK;
1773 DWORD dwEffect = DROPEFFECT_COPY | DROPEFFECT_MOVE;
1774
1775 if (SUCCEEDED(m_pSFParent->GetUIObjectOf(m_hWnd, m_cidl, m_apidl, IID_NULL_PPV_ARG(IDataObject, &pda))))
1776 {
1777 if (SUCCEEDED(m_pSFParent->GetAttributesOf(m_cidl, m_apidl, &dwAttributes)))
1778 {
1779 if (dwAttributes & SFGAO_CANLINK)
1780 {
1781 dwEffect |= DROPEFFECT_LINK;
1782 }
1783 }
1784
1785 CComPtr<IAsyncOperation> piaso;
1786 if (SUCCEEDED(pda->QueryInterface(IID_PPV_ARG(IAsyncOperation, &piaso))))
1787 {
1788 piaso->SetAsyncMode(TRUE);
1789 }
1790
1791 DWORD dwEffect2;
1792 DoDragDrop(pda, this, dwEffect, &dwEffect2);
1793 }
1794 }
1795 break;
1796
1797 case LVN_BEGINLABELEDITW:
1798 {
1799 DWORD dwAttr = SFGAO_CANRENAME;
1800 pidl = _PidlByItem(lpdi->item);
1801
1802 TRACE("-- LVN_BEGINLABELEDITW %p\n", this);
1803
1804 m_pSFParent->GetAttributesOf(1, &pidl, &dwAttr);
1805 if (SFGAO_CANRENAME & dwAttr)
1806 {
1807 m_isEditing = TRUE;
1808 return FALSE;
1809 }
1810 return TRUE;
1811 }
1812
1813 case LVN_ENDLABELEDITW:
1814 {
1815 TRACE("-- LVN_ENDLABELEDITW %p\n", this);
1816
1817 m_isEditing = FALSE;
1818
1819 if (lpdi->item.pszText)
1820 {
1821 HRESULT hr;
1822 LVITEMW lvItem;
1823
1824 pidl = _PidlByItem(lpdi->item);
1825 PITEMID_CHILD pidlNew;
1826 hr = m_pSFParent->SetNameOf(0, pidl, lpdi->item.pszText, SHGDN_INFOLDER, &pidlNew);
1827
1828 if (SUCCEEDED(hr) && pidlNew)
1829 {
1830 lvItem.mask = LVIF_PARAM|LVIF_IMAGE;
1831 lvItem.iItem = lpdi->item.iItem;
1832 lvItem.lParam = reinterpret_cast<LPARAM>(pidlNew);
1833 lvItem.iImage = SHMapPIDLToSystemImageListIndex(m_pSFParent, pidlNew, 0);
1834 m_ListView.SetItem(&lvItem);
1835 m_ListView.Update(lpdi->item.iItem);
1836 return TRUE;
1837 }
1838 }
1839
1840 return FALSE;
1841 }
1842
1843 default:
1844 TRACE("-- %p WM_COMMAND %x unhandled\n", this, lpnmh->code);
1845 break;
1846 }
1847
1848 return 0;
1849 }
1850
1851 /**********************************************************
1852 * ShellView_OnChange()
1853 */
1854 LRESULT CDefView::OnChangeNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1855 {
1856 PCIDLIST_ABSOLUTE *Pidls = reinterpret_cast<PCIDLIST_ABSOLUTE*>(wParam);
1857
1858 TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls[0], Pidls[1], lParam);
1859
1860 switch (lParam)
1861 {
1862 case SHCNE_MKDIR:
1863 case SHCNE_CREATE:
1864 LV_AddItem(ILFindLastID(Pidls[0]));
1865 break;
1866
1867 case SHCNE_RMDIR:
1868 case SHCNE_DELETE:
1869 LV_DeleteItem(ILFindLastID(Pidls[0]));
1870 break;
1871
1872 case SHCNE_RENAMEFOLDER:
1873 case SHCNE_RENAMEITEM:
1874 LV_RenameItem(ILFindLastID(Pidls[0]), ILFindLastID(Pidls[1]));
1875 break;
1876
1877 case SHCNE_UPDATEITEM:
1878 LV_RenameItem(ILFindLastID(Pidls[0]), ILFindLastID(Pidls[0]));
1879 break;
1880
1881 case SHCNE_UPDATEDIR:
1882 Refresh();
1883 break;
1884 }
1885 return TRUE;
1886 }
1887
1888 /**********************************************************
1889 * CDefView::OnCustomItem
1890 */
1891 LRESULT CDefView::OnCustomItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1892 {
1893 if (!m_pCM.p)
1894 {
1895 /* no menu */
1896 ERR("no menu!!!\n");
1897 return FALSE;
1898 }
1899
1900 CComPtr<IContextMenu2> pCM2;
1901 HRESULT hres = m_pCM.p->QueryInterface(IID_PPV_ARG(IContextMenu2, &pCM2));
1902 if(FAILED(hres))
1903 return FALSE;
1904
1905 if (pCM2.p->HandleMenuMsg(uMsg, (WPARAM)m_hWnd, lParam) == S_OK)
1906 return TRUE;
1907 else
1908 return FALSE;
1909 }
1910
1911 LRESULT CDefView::OnSettingChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1912 {
1913 /* Wallpaper setting affects drop shadows effect */
1914 if (wParam == SPI_SETDESKWALLPAPER || wParam == 0)
1915 UpdateListColors();
1916
1917 return S_OK;
1918 }
1919
1920 /**********************************************************
1921 * CDefView::OnInitMenuPopup
1922 */
1923 LRESULT CDefView::OnInitMenuPopup(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
1924 {
1925 MENUITEMINFOW mii = { 0 };
1926 HMENU hSubmenu = (HMENU) wParam;
1927
1928 TRACE("OnInitMenuPopup lParam=%d\n", lParam);
1929
1930 mii.cbSize = sizeof(mii);
1931 mii.fMask = MIIM_ID | MIIM_SUBMENU;
1932
1933 if (!GetMenuItemInfoW(this->m_hMenu, lParam, TRUE, &mii))
1934 {
1935 TRACE("OnInitMenuPopup GetMenuItemInfoW failed!\n");
1936 return FALSE;
1937 }
1938
1939 UINT menuItemId = mii.wID;
1940
1941 if (mii.hSubMenu != hSubmenu)
1942 {
1943 TRACE("OnInitMenuPopup submenu does not match!!!!\n");
1944 return FALSE;
1945 }
1946
1947 TRACE("OnInitMenuPopup id=%d\n", menuItemId);
1948
1949 switch (menuItemId)
1950 {
1951 case FCIDM_MENU_FILE:
1952 PrepareShowFileMenu(hSubmenu);
1953 break;
1954 case FCIDM_MENU_EDIT:
1955 //PrepareShowEditMenu(hSubmenu);
1956 break;
1957 case FCIDM_MENU_VIEW:
1958 PrepareShowViewMenu(hSubmenu);
1959 break;
1960 }
1961
1962 return FALSE;
1963 }
1964
1965 /**********************************************************
1966 *
1967 *
1968 * The INTERFACE of the IShellView object
1969 *
1970 *
1971 **********************************************************
1972 */
1973
1974 /**********************************************************
1975 * ShellView_GetWindow
1976 */
1977 HRESULT WINAPI CDefView::GetWindow(HWND *phWnd)
1978 {
1979 TRACE("(%p)\n", this);
1980
1981 *phWnd = m_hWnd;
1982
1983 return S_OK;
1984 }
1985
1986 HRESULT WINAPI CDefView::ContextSensitiveHelp(BOOL fEnterMode)
1987 {
1988 FIXME("(%p) stub\n", this);
1989
1990 return E_NOTIMPL;
1991 }
1992
1993 /**********************************************************
1994 * IShellView_TranslateAccelerator
1995 *
1996 * FIXME:
1997 * use the accel functions
1998 */
1999 HRESULT WINAPI CDefView::TranslateAccelerator(LPMSG lpmsg)
2000 {
2001 if (m_isEditing)
2002 return S_FALSE;
2003
2004 if (lpmsg->message >= WM_KEYFIRST && lpmsg->message <= WM_KEYLAST)
2005 {
2006 if (::TranslateAcceleratorW(m_hWnd, m_hAccel, lpmsg) != 0)
2007 return S_OK;
2008
2009 TRACE("-- key=0x04%lx\n", lpmsg->wParam) ;
2010 }
2011
2012 return m_pShellBrowser->TranslateAcceleratorSB(lpmsg, 0);
2013 }
2014
2015 HRESULT WINAPI CDefView::EnableModeless(BOOL fEnable)
2016 {
2017 FIXME("(%p) stub\n", this);
2018
2019 return E_NOTIMPL;
2020 }
2021
2022 HRESULT WINAPI CDefView::UIActivate(UINT uState)
2023 {
2024 /*
2025 CHAR szName[MAX_PATH];
2026 */
2027 LRESULT lResult;
2028 int nPartArray[1] = { -1};
2029
2030 TRACE("(%p)->(state=%x) stub\n", this, uState);
2031
2032 /*don't do anything if the state isn't really changing*/
2033 if (m_uState == uState)
2034 {
2035 return S_OK;
2036 }
2037
2038 /*OnActivate handles the menu merging and internal state*/
2039 DoActivate(uState);
2040
2041 /*only do This if we are active*/
2042 if (uState != SVUIA_DEACTIVATE)
2043 {
2044
2045 /*
2046 GetFolderPath is not a method of IShellFolder
2047 IShellFolder_GetFolderPath( m_pSFParent, szName, sizeof(szName) );
2048 */
2049 /* set the number of parts */
2050 m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETPARTS, 1, (LPARAM)nPartArray, &lResult);
2051
2052 /* set the text for the parts */
2053 /*
2054 m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXTA, 0, (LPARAM)szName, &lResult);
2055 */
2056 }
2057
2058 return S_OK;
2059 }
2060
2061 HRESULT WINAPI CDefView::Refresh()
2062 {
2063 TRACE("(%p)\n", this);
2064
2065 m_ListView.DeleteAllItems();
2066 FillList();
2067
2068 return S_OK;
2069 }
2070
2071 HRESULT WINAPI CDefView::CreateViewWindow(IShellView *lpPrevView, LPCFOLDERSETTINGS lpfs, IShellBrowser *psb, RECT *prcView, HWND *phWnd)
2072 {
2073 OLEMENUGROUPWIDTHS omw = { { 0, 0, 0, 0, 0, 0 } };
2074
2075 *phWnd = 0;
2076
2077 TRACE("(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n", this, lpPrevView, lpfs, psb, prcView, phWnd);
2078
2079 if (lpfs != NULL)
2080 TRACE("-- vmode=%x flags=%x\n", lpfs->ViewMode, lpfs->fFlags);
2081 if (prcView != NULL)
2082 TRACE("-- left=%i top=%i right=%i bottom=%i\n", prcView->left, prcView->top, prcView->right, prcView->bottom);
2083
2084 /* Validate the Shell Browser */
2085 if (psb == NULL)
2086 return E_UNEXPECTED;
2087
2088 /*set up the member variables*/
2089 m_pShellBrowser = psb;
2090 m_FolderSettings = *lpfs;
2091
2092 /*get our parent window*/
2093 m_pShellBrowser->GetWindow(&m_hWndParent);
2094
2095 /* try to get the ICommDlgBrowserInterface, adds a reference !!! */
2096 m_pCommDlgBrowser = NULL;
2097 if (SUCCEEDED(m_pShellBrowser->QueryInterface(IID_PPV_ARG(ICommDlgBrowser, &m_pCommDlgBrowser))))
2098 {
2099 TRACE("-- CommDlgBrowser\n");
2100 }
2101
2102 Create(m_hWndParent, prcView, NULL, WS_CHILD | WS_TABSTOP, 0, 0U);
2103 if (m_hWnd == NULL)
2104 return E_FAIL;
2105
2106 *phWnd = m_hWnd;
2107
2108 CheckToolbar();
2109
2110 if (!*phWnd)
2111 return E_FAIL;
2112
2113 SetWindowPos(HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
2114 UpdateWindow();
2115
2116 if (!m_hMenu)
2117 {
2118 m_hMenu = CreateMenu();
2119 m_pShellBrowser->InsertMenusSB(m_hMenu, &omw);
2120 TRACE("-- after fnInsertMenusSB\n");
2121 }
2122
2123 _MergeToolbar();
2124
2125 return S_OK;
2126 }
2127
2128 HRESULT WINAPI CDefView::DestroyViewWindow()
2129 {
2130 TRACE("(%p)\n", this);
2131
2132 /*Make absolutely sure all our UI is cleaned up.*/
2133 UIActivate(SVUIA_DEACTIVATE);
2134
2135 if (m_hAccel)
2136 {
2137 // "Accelerator tables loaded from resources are freed automatically when the application terminates." -- MSDN
2138 m_hAccel = NULL;
2139 }
2140
2141 if (m_hView)
2142 {
2143 DestroyMenu(m_hView);
2144 m_hView = NULL;
2145 }
2146
2147 if (m_hMenu)
2148 {
2149 DestroyMenu(m_hMenu);
2150 m_hView = NULL;
2151 }
2152
2153 if (m_ListView)
2154 {
2155 m_ListView.DestroyWindow();
2156 }
2157
2158 if (m_hWnd)
2159 {
2160 DestroyWindow();
2161 }
2162
2163 m_pShellBrowser.Release();
2164 m_pCommDlgBrowser.Release();
2165
2166 return S_OK;
2167 }
2168
2169 HRESULT WINAPI CDefView::GetCurrentInfo(LPFOLDERSETTINGS lpfs)
2170 {
2171 TRACE("(%p)->(%p) vmode=%x flags=%x\n", this, lpfs,
2172 m_FolderSettings.ViewMode, m_FolderSettings.fFlags);
2173
2174 if (!lpfs)
2175 return E_INVALIDARG;
2176
2177 *lpfs = m_FolderSettings;
2178 return S_OK;
2179 }
2180
2181 HRESULT WINAPI CDefView::AddPropertySheetPages(DWORD dwReserved, LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam)
2182 {
2183 FIXME("(%p) stub\n", this);
2184
2185 return E_NOTIMPL;
2186 }
2187
2188 HRESULT WINAPI CDefView::SaveViewState()
2189 {
2190 FIXME("(%p) stub\n", this);
2191
2192 return S_OK;
2193 }
2194
2195 HRESULT WINAPI CDefView::SelectItem(PCUITEMID_CHILD pidl, UINT uFlags)
2196 {
2197 int i;
2198
2199 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n", this, pidl, uFlags);
2200
2201 i = LV_FindItemByPidl(pidl);
2202 if (i == -1)
2203 return S_OK;
2204
2205 if(uFlags & SVSI_ENSUREVISIBLE)
2206 m_ListView.EnsureVisible(i, FALSE);
2207
2208 LVITEMW lvItem = {0};
2209 lvItem.mask = LVIF_STATE;
2210 lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
2211
2212 while (m_ListView.GetItem(&lvItem))
2213 {
2214 if (lvItem.iItem == i)
2215 {
2216 if (uFlags & SVSI_SELECT)
2217 lvItem.state |= LVIS_SELECTED;
2218 else
2219 lvItem.state &= ~LVIS_SELECTED;
2220
2221 if (uFlags & SVSI_FOCUSED)
2222 lvItem.state &= ~LVIS_FOCUSED;
2223 }
2224 else
2225 {
2226 if (uFlags & SVSI_DESELECTOTHERS)
2227 lvItem.state &= ~LVIS_SELECTED;
2228 }
2229
2230 m_ListView.SetItem(&lvItem);
2231 lvItem.iItem++;
2232 }
2233
2234 if(uFlags & SVSI_EDIT)
2235 m_ListView.EditLabel(i);
2236
2237 return S_OK;
2238 }
2239
2240 HRESULT WINAPI CDefView::GetItemObject(UINT uItem, REFIID riid, LPVOID *ppvOut)
2241 {
2242 HRESULT hr = E_NOINTERFACE;
2243
2244 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n", this, uItem, debugstr_guid(&riid), ppvOut);
2245
2246 *ppvOut = NULL;
2247
2248 switch (uItem)
2249 {
2250 case SVGIO_BACKGROUND:
2251 if (IsEqualIID(riid, IID_IContextMenu))
2252 {
2253 //*ppvOut = ISvBgCm_Constructor(m_pSFParent, FALSE);
2254 if (!ppvOut)
2255 hr = E_OUTOFMEMORY;
2256
2257 IContextMenu* pcm;
2258 hr = CDefFolderMenu_Create2(NULL, NULL, 0, NULL, m_pSFParent, NULL, 0, NULL, &pcm);
2259 if (FAILED(hr))
2260 return hr;
2261 *ppvOut = pcm;
2262 }
2263 break;
2264
2265 case SVGIO_SELECTION:
2266 GetSelections();
2267 hr = m_pSFParent->GetUIObjectOf(m_hWnd, m_cidl, m_apidl, riid, 0, ppvOut);
2268 break;
2269 }
2270
2271 TRACE("-- (%p)->(interface=%p)\n", this, *ppvOut);
2272
2273 return hr;
2274 }
2275
2276 HRESULT STDMETHODCALLTYPE CDefView::GetCurrentViewMode(UINT *pViewMode)
2277 {
2278 TRACE("(%p)->(%p), stub\n", this, pViewMode);
2279
2280 if (!pViewMode)
2281 return E_INVALIDARG;
2282
2283 *pViewMode = m_FolderSettings.ViewMode;
2284 return S_OK;
2285 }
2286
2287 HRESULT STDMETHODCALLTYPE CDefView::SetCurrentViewMode(UINT ViewMode)
2288 {
2289 DWORD dwStyle;
2290 TRACE("(%p)->(%u), stub\n", this, ViewMode);
2291
2292 /* It's not redundant to check FVM_AUTO because it's a (UINT)-1 */
2293 if (((INT)ViewMode < FVM_FIRST || (INT)ViewMode > FVM_LAST) && ((INT)ViewMode != FVM_AUTO))
2294 return E_INVALIDARG;
2295
2296 /* Windows before Vista uses LVM_SETVIEW and possibly
2297 LVM_SETEXTENDEDLISTVIEWSTYLE to set the style of the listview,
2298 while later versions seem to accomplish this through other
2299 means. */
2300 switch (ViewMode)
2301 {
2302 case FVM_ICON:
2303 dwStyle = LVS_ICON;
2304 break;
2305 case FVM_DETAILS:
2306 dwStyle = LVS_REPORT;
2307 break;
2308 case FVM_SMALLICON:
2309 dwStyle = LVS_SMALLICON;
2310 break;
2311 case FVM_LIST:
2312 dwStyle = LVS_LIST;
2313 break;
2314 default:
2315 {
2316 FIXME("ViewMode %d not implemented\n", ViewMode);
2317 dwStyle = LVS_LIST;
2318 break;
2319 }
2320 }
2321
2322 SetStyle(dwStyle, LVS_TYPEMASK);
2323
2324 /* This will not necessarily be the actual mode set above.
2325 This mimics the behavior of Windows XP. */
2326 m_FolderSettings.ViewMode = ViewMode;
2327
2328 return S_OK;
2329 }
2330
2331 HRESULT STDMETHODCALLTYPE CDefView::GetFolder(REFIID riid, void **ppv)
2332 {
2333 if (m_pSFParent == NULL)
2334 return E_FAIL;
2335
2336 return m_pSFParent->QueryInterface(riid, ppv);
2337 }
2338
2339 HRESULT STDMETHODCALLTYPE CDefView::Item(int iItemIndex, PITEMID_CHILD *ppidl)
2340 {
2341 PCUITEMID_CHILD pidl = _PidlByItem(iItemIndex);
2342 if (pidl)
2343 {
2344 *ppidl = ILClone(pidl);
2345 return S_OK;
2346 }
2347
2348 *ppidl = 0;
2349 return E_INVALIDARG;
2350 }
2351
2352 HRESULT STDMETHODCALLTYPE CDefView::ItemCount(UINT uFlags, int *pcItems)
2353 {
2354 TRACE("(%p)->(%u %p)\n", this, uFlags, pcItems);
2355
2356 if (uFlags != SVGIO_ALLVIEW)
2357 FIXME("some flags unsupported, %x\n", uFlags & ~SVGIO_ALLVIEW);
2358
2359 *pcItems = m_ListView.GetItemCount();
2360
2361 return S_OK;
2362 }
2363
2364 HRESULT STDMETHODCALLTYPE CDefView::Items(UINT uFlags, REFIID riid, void **ppv)
2365 {
2366 return E_NOTIMPL;
2367 }
2368
2369 HRESULT STDMETHODCALLTYPE CDefView::GetSelectionMarkedItem(int *piItem)
2370 {
2371 TRACE("(%p)->(%p)\n", this, piItem);
2372
2373 *piItem = m_ListView.GetSelectionMark();
2374
2375 return S_OK;
2376 }
2377
2378 HRESULT STDMETHODCALLTYPE CDefView::GetFocusedItem(int *piItem)
2379 {
2380 TRACE("(%p)->(%p)\n", this, piItem);
2381
2382 *piItem = m_ListView.GetNextItem(-1, LVNI_FOCUSED);
2383
2384 return S_OK;
2385 }
2386
2387 HRESULT STDMETHODCALLTYPE CDefView::GetItemPosition(PCUITEMID_CHILD pidl, POINT *ppt)
2388 {
2389 return E_NOTIMPL;
2390 }
2391
2392 HRESULT STDMETHODCALLTYPE CDefView::GetSpacing(POINT *ppt)
2393 {
2394 TRACE("(%p)->(%p)\n", this, ppt);
2395
2396 if (!m_ListView)
2397 return S_FALSE;
2398
2399 if (ppt)
2400 {
2401 SIZE spacing;
2402 m_ListView.GetItemSpacing(spacing);
2403
2404 ppt->x = spacing.cx;
2405 ppt->y = spacing.cy;
2406 }
2407
2408 return S_OK;
2409 }
2410
2411 HRESULT STDMETHODCALLTYPE CDefView::GetDefaultSpacing(POINT *ppt)
2412 {
2413 return E_NOTIMPL;
2414 }
2415
2416 HRESULT STDMETHODCALLTYPE CDefView::GetAutoArrange()
2417 {
2418 return E_NOTIMPL;
2419 }
2420
2421 HRESULT STDMETHODCALLTYPE CDefView::SelectItem(int iItem, DWORD dwFlags)
2422 {
2423 LVITEMW lvItem;
2424
2425 TRACE("(%p)->(%d, %x)\n", this, iItem, dwFlags);
2426
2427 lvItem.state = 0;
2428 lvItem.stateMask = LVIS_SELECTED;
2429
2430 if (dwFlags & SVSI_ENSUREVISIBLE)
2431 m_ListView.EnsureVisible(iItem, 0);
2432
2433 /* all items */
2434 if (dwFlags & SVSI_DESELECTOTHERS)
2435 m_ListView.SetItemState(-1, 0, LVIS_SELECTED);
2436
2437 /* this item */
2438 if (dwFlags & SVSI_SELECT)
2439 lvItem.state |= LVIS_SELECTED;
2440
2441 if (dwFlags & SVSI_FOCUSED)
2442 lvItem.stateMask |= LVIS_FOCUSED;
2443
2444 m_ListView.SetItemState(iItem, lvItem.state, lvItem.stateMask);
2445
2446 if (dwFlags & SVSI_EDIT)
2447 m_ListView.EditLabel(iItem);
2448
2449 return S_OK;
2450 }
2451
2452 HRESULT STDMETHODCALLTYPE CDefView::SelectAndPositionItems(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, POINT *apt, DWORD dwFlags)
2453 {
2454 return E_NOTIMPL;
2455 }
2456
2457 /**********************************************************
2458 * IShellFolderView implementation
2459 */
2460 HRESULT STDMETHODCALLTYPE CDefView::Rearrange(LPARAM sort)
2461 {
2462 FIXME("(%p)->(%ld) stub\n", this, sort);
2463 return E_NOTIMPL;
2464 }
2465
2466 HRESULT STDMETHODCALLTYPE CDefView::GetArrangeParam(LPARAM *sort)
2467 {
2468 FIXME("(%p)->(%p) stub\n", this, sort);
2469 return E_NOTIMPL;
2470 }
2471
2472 HRESULT STDMETHODCALLTYPE CDefView::ArrangeGrid()
2473 {
2474 FIXME("(%p) stub\n", this);
2475 return E_NOTIMPL;
2476 }
2477
2478 HRESULT STDMETHODCALLTYPE CDefView::AutoArrange()
2479 {
2480 FIXME("(%p) stub\n", this);
2481 return E_NOTIMPL;
2482 }
2483
2484 HRESULT STDMETHODCALLTYPE CDefView::AddObject(PITEMID_CHILD pidl, UINT *item)
2485 {
2486 FIXME("(%p)->(%p %p) stub\n", this, pidl, item);
2487 return E_NOTIMPL;
2488 }
2489
2490 HRESULT STDMETHODCALLTYPE CDefView::GetObject(PITEMID_CHILD *pidl, UINT item)
2491 {
2492 TRACE("(%p)->(%p %d)\n", this, pidl, item);
2493 return Item(item, pidl);
2494 }
2495
2496 HRESULT STDMETHODCALLTYPE CDefView::RemoveObject(PITEMID_CHILD pidl, UINT *item)
2497 {
2498
2499 TRACE("(%p)->(%p %p)\n", this, pidl, item);
2500
2501 if (pidl)
2502 {
2503 *item = LV_FindItemByPidl(ILFindLastID(pidl));
2504 m_ListView.DeleteItem(*item);
2505 }
2506 else
2507 {
2508 *item = 0;
2509 m_ListView.DeleteAllItems();
2510 }
2511
2512 return S_OK;
2513 }
2514
2515 HRESULT STDMETHODCALLTYPE CDefView::GetObjectCount(UINT *count)
2516 {
2517 TRACE("(%p)->(%p)\n", this, count);
2518 *count = m_ListView.GetItemCount();
2519 return S_OK;
2520 }
2521
2522 HRESULT STDMETHODCALLTYPE CDefView::SetObjectCount(UINT count, UINT flags)
2523 {
2524 FIXME("(%p)->(%d %x) stub\n", this, count, flags);
2525 return E_NOTIMPL;
2526 }
2527
2528 HRESULT STDMETHODCALLTYPE CDefView::UpdateObject(PITEMID_CHILD pidl_old, PITEMID_CHILD pidl_new, UINT *item)
2529 {
2530 FIXME("(%p)->(%p %p %p) stub\n", this, pidl_old, pidl_new, item);
2531 return E_NOTIMPL;
2532 }
2533
2534 HRESULT STDMETHODCALLTYPE CDefView::RefreshObject(PITEMID_CHILD pidl, UINT *item)
2535 {
2536 FIXME("(%p)->(%p %p) stub\n", this, pidl, item);
2537 return E_NOTIMPL;
2538 }
2539
2540 HRESULT STDMETHODCALLTYPE CDefView::SetRedraw(BOOL redraw)
2541 {
2542 TRACE("(%p)->(%d)\n", this, redraw);
2543 m_ListView.SetRedraw(redraw);
2544 return S_OK;
2545 }
2546
2547 HRESULT STDMETHODCALLTYPE CDefView::GetSelectedCount(UINT *count)
2548 {
2549 FIXME("(%p)->(%p) stub\n", this, count);
2550 return E_NOTIMPL;
2551 }
2552
2553 HRESULT STDMETHODCALLTYPE CDefView::GetSelectedObjects(PCUITEMID_CHILD **pidl, UINT *items)
2554 {
2555 TRACE("(%p)->(%p %p)\n", this, pidl, items);
2556
2557 *items = GetSelections();
2558
2559 if (*items)
2560 {
2561 *pidl = static_cast<PCUITEMID_CHILD *>(LocalAlloc(0, *items * sizeof(PCUITEMID_CHILD)));
2562 if (!*pidl)
2563 {
2564 return E_OUTOFMEMORY;
2565 }
2566
2567 /* it's documented that caller shouldn't PIDLs, only array itself */
2568 memcpy(*pidl, m_apidl, *items * sizeof(PCUITEMID_CHILD));
2569 }
2570
2571 return S_OK;
2572 }
2573
2574 HRESULT STDMETHODCALLTYPE CDefView::IsDropOnSource(IDropTarget *drop_target)
2575 {
2576 FIXME("(%p)->(%p) stub\n", this, drop_target);
2577 return E_NOTIMPL;
2578 }
2579
2580 HRESULT STDMETHODCALLTYPE CDefView::GetDragPoint(POINT *pt)
2581 {
2582 FIXME("(%p)->(%p) stub\n", this, pt);
2583 return E_NOTIMPL;
2584 }
2585
2586 HRESULT STDMETHODCALLTYPE CDefView::GetDropPoint(POINT *pt)
2587 {
2588 FIXME("(%p)->(%p) stub\n", this, pt);
2589 return E_NOTIMPL;
2590 }
2591
2592 HRESULT STDMETHODCALLTYPE CDefView::MoveIcons(IDataObject *obj)
2593 {
2594 TRACE("(%p)->(%p)\n", this, obj);
2595 return E_NOTIMPL;
2596 }
2597
2598 HRESULT STDMETHODCALLTYPE CDefView::SetItemPos(PCUITEMID_CHILD pidl, POINT *pt)
2599 {
2600 FIXME("(%p)->(%p %p) stub\n", this, pidl, pt);
2601 return E_NOTIMPL;
2602 }
2603
2604 HRESULT STDMETHODCALLTYPE CDefView::IsBkDropTarget(IDropTarget *drop_target)
2605 {
2606 FIXME("(%p)->(%p) stub\n", this, drop_target);
2607 return E_NOTIMPL;
2608 }
2609
2610 HRESULT STDMETHODCALLTYPE CDefView::SetClipboard(BOOL move)
2611 {
2612 FIXME("(%p)->(%d) stub\n", this, move);
2613 return E_NOTIMPL;
2614 }
2615
2616 HRESULT STDMETHODCALLTYPE CDefView::SetPoints(IDataObject *obj)
2617 {
2618 FIXME("(%p)->(%p) stub\n", this, obj);
2619 return E_NOTIMPL;
2620 }
2621
2622 HRESULT STDMETHODCALLTYPE CDefView::GetItemSpacing(ITEMSPACING *spacing)
2623 {
2624 FIXME("(%p)->(%p) stub\n", this, spacing);
2625 return E_NOTIMPL;
2626 }
2627
2628 HRESULT STDMETHODCALLTYPE CDefView::SetCallback(IShellFolderViewCB *new_cb, IShellFolderViewCB **old_cb)
2629 {
2630 FIXME("(%p)->(%p %p) stub\n", this, new_cb, old_cb);
2631 return E_NOTIMPL;
2632 }
2633
2634 HRESULT STDMETHODCALLTYPE CDefView::Select(UINT flags)
2635 {
2636 FIXME("(%p)->(%d) stub\n", this, flags);
2637 return E_NOTIMPL;
2638 }
2639
2640 HRESULT STDMETHODCALLTYPE CDefView::QuerySupport(UINT *support)
2641 {
2642 TRACE("(%p)->(%p)\n", this, support);
2643 return S_OK;
2644 }
2645
2646 HRESULT STDMETHODCALLTYPE CDefView::SetAutomationObject(IDispatch *disp)
2647 {
2648 FIXME("(%p)->(%p) stub\n", this, disp);
2649 return E_NOTIMPL;
2650 }
2651
2652 /**********************************************************
2653 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2654 */
2655 HRESULT WINAPI CDefView::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD *prgCmds, OLECMDTEXT *pCmdText)
2656 {
2657 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
2658 this, pguidCmdGroup, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText);
2659
2660 if (!prgCmds)
2661 return E_INVALIDARG;
2662
2663 for (UINT i = 0; i < cCmds; i++)
2664 {
2665 FIXME("\tprgCmds[%d].cmdID = %d\n", i, prgCmds[i].cmdID);
2666 prgCmds[i].cmdf = 0;
2667 }
2668
2669 return OLECMDERR_E_UNKNOWNGROUP;
2670 }
2671
2672 /**********************************************************
2673 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2674 *
2675 * nCmdID is the OLECMDID_* enumeration
2676 */
2677 HRESULT WINAPI CDefView::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
2678 {
2679 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2680 this, debugstr_guid(pguidCmdGroup), nCmdID, nCmdexecopt, pvaIn, pvaOut);
2681
2682 if (!pguidCmdGroup)
2683 return OLECMDERR_E_UNKNOWNGROUP;
2684
2685 if (IsEqualCLSID(*pguidCmdGroup, m_Category))
2686 {
2687 if (nCmdID == FCIDM_SHVIEW_AUTOARRANGE)
2688 {
2689 if (V_VT(pvaIn) != VT_INT_PTR)
2690 return OLECMDERR_E_NOTSUPPORTED;
2691
2692
2693 TPMPARAMS params;
2694 params.cbSize = sizeof(params);
2695 params.rcExclude = *(RECT*) V_INTREF(pvaIn);
2696
2697 HMENU hView = m_hView;
2698 #if 0
2699 hView = CreatePopupMenu();
2700 AppendMenuW(hView, MF_STRING, FCIDM_SHVIEW_BIGICON, L"Big!");
2701 AppendMenuW(hView, MF_STRING, FCIDM_SHVIEW_SMALLICON, L"Small!");
2702 AppendMenuW(hView, MF_STRING, FCIDM_SHVIEW_LISTVIEW, L"List!");
2703 AppendMenuW(hView, MF_STRING, FCIDM_SHVIEW_REPORTVIEW, L"Report!");
2704 #endif
2705
2706 if (hView)
2707 {
2708 PrepareShowViewMenu(hView);
2709
2710 TrackPopupMenuEx(hView, TPM_LEFTALIGN | TPM_TOPALIGN, params.rcExclude.left, params.rcExclude.bottom, m_hWndParent, &params);
2711 }
2712
2713 // pvaOut is VT_I4 with value 0x403 (cmd id of the new mode maybe?)
2714 V_VT(pvaOut) = VT_I4;
2715 V_I4(pvaOut) = 0x403;
2716 }
2717 }
2718
2719 if (IsEqualIID(*pguidCmdGroup, CGID_Explorer) &&
2720 (nCmdID == 0x29) &&
2721 (nCmdexecopt == 4) && pvaOut)
2722 return S_OK;
2723
2724 if (IsEqualIID(*pguidCmdGroup, CGID_ShellDocView) &&
2725 (nCmdID == 9) &&
2726 (nCmdexecopt == 0))
2727 return 1;
2728
2729 return OLECMDERR_E_UNKNOWNGROUP;
2730 }
2731
2732 /**********************************************************
2733 * ISVDropTarget implementation
2734 */
2735
2736 /******************************************************************************
2737 * drag_notify_subitem [Internal]
2738 *
2739 * Figure out the shellfolder object, which is currently under the mouse cursor
2740 * and notify it via the IDropTarget interface.
2741 */
2742
2743 #define SCROLLAREAWIDTH 20
2744
2745 HRESULT CDefView::drag_notify_subitem(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
2746 {
2747 LVHITTESTINFO htinfo;
2748 LONG lResult;
2749 HRESULT hr;
2750 RECT clientRect;
2751
2752 /* Map from global to client coordinates and query the index of the listview-item, which is
2753 * currently under the mouse cursor. */
2754 htinfo.pt.x = pt.x;
2755 htinfo.pt.y = pt.y;
2756 htinfo.flags = LVHT_ONITEM;
2757 ::ScreenToClient(m_ListView, &htinfo.pt);
2758 lResult = m_ListView.HitTest(&htinfo);
2759
2760 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2761 ::GetClientRect(m_ListView, &clientRect);
2762 if (htinfo.pt.x == m_ptLastMousePos.x && htinfo.pt.y == m_ptLastMousePos.y &&
2763 (htinfo.pt.x < SCROLLAREAWIDTH || htinfo.pt.x > clientRect.right - SCROLLAREAWIDTH ||
2764 htinfo.pt.y < SCROLLAREAWIDTH || htinfo.pt.y > clientRect.bottom - SCROLLAREAWIDTH ))
2765 {
2766 m_cScrollDelay = (m_cScrollDelay + 1) % 5; /* DragOver is called every 50 ms */
2767 if (m_cScrollDelay == 0)
2768 {
2769 /* Mouse did hover another 250 ms over the scroll-area */
2770 if (htinfo.pt.x < SCROLLAREAWIDTH)
2771 m_ListView.SendMessageW(WM_HSCROLL, SB_LINEUP, 0);
2772
2773 if (htinfo.pt.x > clientRect.right - SCROLLAREAWIDTH)
2774 m_ListView.SendMessageW(WM_HSCROLL, SB_LINEDOWN, 0);
2775
2776 if (htinfo.pt.y < SCROLLAREAWIDTH)
2777 m_ListView.SendMessageW(WM_VSCROLL, SB_LINEUP, 0);
2778
2779 if (htinfo.pt.y > clientRect.bottom - SCROLLAREAWIDTH)
2780 m_ListView.SendMessageW(WM_VSCROLL, SB_LINEDOWN, 0);
2781 }
2782 }
2783 else
2784 {
2785 m_cScrollDelay = 0; /* Reset, if the cursor is not over the listview's scroll-area */
2786 }
2787
2788 m_ptLastMousePos = htinfo.pt;
2789
2790 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2791 if (m_pCurDropTarget && lResult == m_iDragOverItem)
2792 return m_pCurDropTarget->DragOver(grfKeyState, pt, pdwEffect);
2793
2794 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2795 if (m_pCurDropTarget)
2796 {
2797 m_pCurDropTarget->DragLeave();
2798 m_pCurDropTarget.Release();
2799 }
2800
2801 m_iDragOverItem = lResult;
2802 if (lResult == -1)
2803 {
2804 /* We are not above one of the listview's subitems. Bind to the parent folder's
2805 * DropTarget interface. */
2806 hr = m_pSFParent->QueryInterface(IID_PPV_ARG(IDropTarget,&m_pCurDropTarget));
2807 }
2808 else
2809 {
2810 /* Query the relative PIDL of the shellfolder object represented by the currently
2811 * dragged over listview-item ... */
2812 PCUITEMID_CHILD pidl = _PidlByItem(lResult);
2813
2814 /* ... and bind m_pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2815 hr = m_pSFParent->GetUIObjectOf(m_ListView, 1, &pidl, IID_NULL_PPV_ARG(IDropTarget, &m_pCurDropTarget));
2816 }
2817
2818 /* If anything failed, m_pCurDropTarget should be NULL now, which ought to be a save state. */
2819 if (FAILED(hr))
2820 return hr;
2821
2822 /* Notify the item just entered via DragEnter. */
2823 return m_pCurDropTarget->DragEnter(m_pCurDataObject, grfKeyState, pt, pdwEffect);
2824 }
2825
2826 HRESULT WINAPI CDefView::DragEnter(IDataObject *pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
2827 {
2828 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2829 m_pCurDataObject = pDataObject;
2830 pDataObject->AddRef();
2831
2832 return drag_notify_subitem(grfKeyState, pt, pdwEffect);
2833 }
2834
2835 HRESULT WINAPI CDefView::DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
2836 {
2837 return drag_notify_subitem(grfKeyState, pt, pdwEffect);
2838 }
2839
2840 HRESULT WINAPI CDefView::DragLeave()
2841 {
2842 if (m_pCurDropTarget)
2843 {
2844 m_pCurDropTarget->DragLeave();
2845 m_pCurDropTarget.Release();
2846 }
2847
2848 if (m_pCurDataObject != NULL)
2849 {
2850 m_pCurDataObject.Release();
2851 }
2852
2853 m_iDragOverItem = 0;
2854
2855 return S_OK;
2856 }
2857
2858 HRESULT WINAPI CDefView::Drop(IDataObject* pDataObject, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
2859 {
2860 if (m_pCurDropTarget)
2861 {
2862 m_pCurDropTarget->Drop(pDataObject, grfKeyState, pt, pdwEffect);
2863 m_pCurDropTarget.Release();
2864 }
2865
2866 m_pCurDataObject.Release();
2867 m_iDragOverItem = 0;
2868 return S_OK;
2869 }
2870
2871 /**********************************************************
2872 * ISVDropSource implementation
2873 */
2874
2875 HRESULT WINAPI CDefView::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState)
2876 {
2877 TRACE("(%p)\n", this);
2878
2879 if (fEscapePressed)
2880 return DRAGDROP_S_CANCEL;
2881 else if (!(grfKeyState & MK_LBUTTON) && !(grfKeyState & MK_RBUTTON))
2882 return DRAGDROP_S_DROP;
2883 else
2884 return S_OK;
2885 }
2886
2887 HRESULT WINAPI CDefView::GiveFeedback(DWORD dwEffect)
2888 {
2889 TRACE("(%p)\n", this);
2890
2891 return DRAGDROP_S_USEDEFAULTCURSORS;
2892 }
2893
2894 /**********************************************************
2895 * ISVViewObject implementation
2896 */
2897
2898 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)
2899 {
2900 FIXME("Stub: this=%p\n", this);
2901
2902 return E_NOTIMPL;
2903 }
2904
2905 HRESULT WINAPI CDefView::GetColorSet(DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd, HDC hicTargetDevice, LOGPALETTE **ppColorSet)
2906 {
2907 FIXME("Stub: this=%p\n", this);
2908
2909 return E_NOTIMPL;
2910 }
2911
2912 HRESULT WINAPI CDefView::Freeze(DWORD dwDrawAspect, LONG lindex, void *pvAspect, DWORD *pdwFreeze)
2913 {
2914 FIXME("Stub: this=%p\n", this);
2915
2916 return E_NOTIMPL;
2917 }
2918
2919 HRESULT WINAPI CDefView::Unfreeze(DWORD dwFreeze)
2920 {
2921 FIXME("Stub: this=%p\n", this);
2922
2923 return E_NOTIMPL;
2924 }
2925
2926 HRESULT WINAPI CDefView::SetAdvise(DWORD aspects, DWORD advf, IAdviseSink *pAdvSink)
2927 {
2928 FIXME("partial stub: %p %08x %08x %p\n", this, aspects, advf, pAdvSink);
2929
2930 /* FIXME: we set the AdviseSink, but never use it to send any advice */
2931 m_pAdvSink = pAdvSink;
2932 m_dwAspects = aspects;
2933 m_dwAdvf = advf;
2934
2935 return S_OK;
2936 }
2937
2938 HRESULT WINAPI CDefView::GetAdvise(DWORD *pAspects, DWORD *pAdvf, IAdviseSink **ppAdvSink)
2939 {
2940 TRACE("this=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n", this, pAspects, pAdvf, ppAdvSink);
2941
2942 if (ppAdvSink)
2943 {
2944 *ppAdvSink = m_pAdvSink;
2945 m_pAdvSink.p->AddRef();
2946 }
2947
2948 if (pAspects)
2949 *pAspects = m_dwAspects;
2950
2951 if (pAdvf)
2952 *pAdvf = m_dwAdvf;
2953
2954 return S_OK;
2955 }
2956
2957 HRESULT STDMETHODCALLTYPE CDefView::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
2958 {
2959 if (IsEqualIID(guidService, SID_IShellBrowser))
2960 return m_pShellBrowser->QueryInterface(riid, ppvObject);
2961 else if(IsEqualIID(guidService, SID_IFolderView))
2962 return QueryInterface(riid, ppvObject);
2963
2964 return E_NOINTERFACE;
2965 }
2966
2967 HRESULT CDefView::_MergeToolbar()
2968 {
2969 CComPtr<IExplorerToolbar> ptb; // [sp+8h] [bp-4h]@1
2970
2971 HRESULT hr = S_OK;
2972
2973 hr = IUnknown_QueryService(m_pShellBrowser, IID_IExplorerToolbar, IID_PPV_ARG(IExplorerToolbar, &ptb));
2974 if (FAILED(hr))
2975 return hr;
2976
2977 m_Category = CGID_DefViewFrame;
2978
2979 hr = ptb->SetCommandTarget(static_cast<IOleCommandTarget*>(this), &m_Category, 0);
2980 if (FAILED(hr))
2981 return hr;
2982
2983 if (hr == S_FALSE)
2984 return S_OK;
2985
2986 #if 0
2987 hr = ptb->AddButtons(&m_Category, buttonsCount, buttons);
2988 if (FAILED(hr))
2989 return hr;
2990 #endif
2991
2992 return S_OK;
2993 }
2994 /**********************************************************
2995 * IShellView_Constructor
2996 */
2997 HRESULT WINAPI IShellView_Constructor(IShellFolder *pFolder, IShellView **newView)
2998 {
2999 return ShellObjectCreatorInit<CDefView>(pFolder, IID_IShellView, newView);
3000 }