4 * Copyright 1998,1999 <juergen.schmied@debitel.net>
6 * This is the view visualizing the data provided by the shellfolder.
7 * No direct access to data from pidls should be done from here.
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 * FIXME: The order by part of the background context menu should be
24 * built according to the columns shown.
26 * FIXME: CheckToolbar: handle the "new folder" and "folder up" button
28 * FIXME: ShellView_FillList: consider sort orders
33 1. Load/Save the view state from/into the stream provided by the ShellBrowser.
34 2. Let the shell folder sort items.
35 3. Code to merge menus in the shellbrowser is incorrect.
36 4. Move the background context menu creation into shell view. It should store the
37 shell view HWND to send commands.
38 5. Send init, measure, and draw messages to context menu during tracking.
39 6. Shell view should do SetCommandTarget on internet toolbar.
40 7. When editing starts on item, set edit text to for editing value.
41 8. When shell view is called back for item info, let listview save the value.
42 9. Shell view should update status bar.
43 10. Fix shell view to handle view mode popup exec.
44 11. The background context menu should have a pidl just like foreground menus. This
45 causes crashes when dynamic handlers try to use the NULL pidl.
46 12. The SHELLDLL_DefView should not be filled with blue unconditionally. This causes
47 annoying flashing of blue even on XP, and is not correct.
48 13. Reorder of columns doesn't work - might be bug in comctl32
56 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
60 static const WCHAR SV_CLASS_NAME
[] = {'S', 'H', 'E', 'L', 'L', 'D', 'L', 'L', '_', 'D', 'e', 'f', 'V', 'i', 'e', 'w', 0};
67 } LISTVIEW_SORT_INFO
, *LPLISTVIEW_SORT_INFO
;
69 #define SHV_CHANGE_NOTIFY WM_USER + 0x1111
72 public CWindowImpl
<CDefView
, CWindow
, CControlWinTraits
>,
73 public CComObjectRootEx
<CComMultiThreadModelNoCS
>,
76 public IShellFolderView
,
77 public IOleCommandTarget
,
81 public IServiceProvider
84 CComPtr
<IShellFolder
> m_pSFParent
;
85 CComPtr
<IShellFolder2
> m_pSF2Parent
;
86 CComPtr
<IShellBrowser
> m_pShellBrowser
;
87 CComPtr
<ICommDlgBrowser
> m_pCommDlgBrowser
;
90 FOLDERSETTINGS m_FolderSettings
;
95 PCUITEMID_CHILD_ARRAY m_apidl
;
96 PIDLIST_ABSOLUTE m_pidlParent
;
97 LISTVIEW_SORT_INFO m_sortInfo
;
98 ULONG m_hNotify
; /* change notification handle */
102 CComPtr
<IAdviseSink
> m_pAdvSink
;
104 CComPtr
<IDropTarget
> m_pCurDropTarget
; /* The sub-item, which is currently dragged over */
105 CComPtr
<IDataObject
> m_pCurDataObject
; /* The dragged data-object */
106 LONG m_iDragOverItem
; /* Dragged over item's index, iff m_pCurDropTarget != NULL */
107 UINT m_cScrollDelay
; /* Send a WM_*SCROLL msg every 250 ms during drag-scroll */
108 POINT m_ptLastMousePos
; /* Mouse position at last DragOver call */
110 CComPtr
<IContextMenu
> m_pCM
;
118 HRESULT
_MergeToolbar();
123 HRESULT WINAPI
Initialize(IShellFolder
*shellFolder
);
124 HRESULT
IncludeObject(PCUITEMID_CHILD pidl
);
125 HRESULT
OnDefaultCommand();
126 HRESULT
OnStateChange(UINT uFlags
);
128 void SetStyle(DWORD dwAdd
, DWORD dwRemove
);
130 void UpdateListColors();
132 static INT CALLBACK
CompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
);
133 static INT CALLBACK
ListViewCompareItems(LPARAM lParam1
, LPARAM lParam2
, LPARAM lpData
);
135 PCUITEMID_CHILD
_PidlByItem(int i
);
136 PCUITEMID_CHILD
_PidlByItem(LVITEM
& lvItem
);
137 int LV_FindItemByPidl(PCUITEMID_CHILD pidl
);
138 BOOLEAN
LV_AddItem(PCUITEMID_CHILD pidl
);
139 BOOLEAN
LV_DeleteItem(PCUITEMID_CHILD pidl
);
140 BOOLEAN
LV_RenameItem(PCUITEMID_CHILD pidlOld
, PCUITEMID_CHILD pidlNew
);
141 BOOLEAN
LV_ProdItem(PCUITEMID_CHILD pidl
);
142 static INT CALLBACK
fill_list(LPVOID ptr
, LPVOID arg
);
144 HMENU
BuildFileMenu();
145 void PrepareShowFileMenu(HMENU hSubMenu
);
146 void PrepareShowViewMenu(HMENU hSubMenu
);
147 UINT
GetSelections();
148 HRESULT
OpenSelectedItems();
150 void DoActivate(UINT uState
);
151 HRESULT
drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
152 LRESULT
OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
);
154 // *** IOleWindow methods ***
155 virtual HRESULT STDMETHODCALLTYPE
GetWindow(HWND
*lphwnd
);
156 virtual HRESULT STDMETHODCALLTYPE
ContextSensitiveHelp(BOOL fEnterMode
);
158 // *** IShellView methods ***
159 virtual HRESULT STDMETHODCALLTYPE
TranslateAccelerator(MSG
*pmsg
);
160 virtual HRESULT STDMETHODCALLTYPE
EnableModeless(BOOL fEnable
);
161 virtual HRESULT STDMETHODCALLTYPE
UIActivate(UINT uState
);
162 virtual HRESULT STDMETHODCALLTYPE
Refresh();
163 virtual HRESULT STDMETHODCALLTYPE
CreateViewWindow(IShellView
*psvPrevious
, LPCFOLDERSETTINGS pfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
);
164 virtual HRESULT STDMETHODCALLTYPE
DestroyViewWindow();
165 virtual HRESULT STDMETHODCALLTYPE
GetCurrentInfo(LPFOLDERSETTINGS pfs
);
166 virtual HRESULT STDMETHODCALLTYPE
AddPropertySheetPages(DWORD dwReserved
, LPFNSVADDPROPSHEETPAGE pfn
, LPARAM lparam
);
167 virtual HRESULT STDMETHODCALLTYPE
SaveViewState();
168 virtual HRESULT STDMETHODCALLTYPE
SelectItem(PCUITEMID_CHILD pidlItem
, SVSIF uFlags
);
169 virtual HRESULT STDMETHODCALLTYPE
GetItemObject(UINT uItem
, REFIID riid
, void **ppv
);
171 // *** IFolderView methods ***
172 virtual HRESULT STDMETHODCALLTYPE
GetCurrentViewMode(UINT
*pViewMode
);
173 virtual HRESULT STDMETHODCALLTYPE
SetCurrentViewMode(UINT ViewMode
);
174 virtual HRESULT STDMETHODCALLTYPE
GetFolder(REFIID riid
, void **ppv
);
175 virtual HRESULT STDMETHODCALLTYPE
Item(int iItemIndex
, PITEMID_CHILD
*ppidl
);
176 virtual HRESULT STDMETHODCALLTYPE
ItemCount(UINT uFlags
, int *pcItems
);
177 virtual HRESULT STDMETHODCALLTYPE
Items(UINT uFlags
, REFIID riid
, void **ppv
);
178 virtual HRESULT STDMETHODCALLTYPE
GetSelectionMarkedItem(int *piItem
);
179 virtual HRESULT STDMETHODCALLTYPE
GetFocusedItem(int *piItem
);
180 virtual HRESULT STDMETHODCALLTYPE
GetItemPosition(PCUITEMID_CHILD pidl
, POINT
*ppt
);
181 virtual HRESULT STDMETHODCALLTYPE
GetSpacing(POINT
*ppt
);
182 virtual HRESULT STDMETHODCALLTYPE
GetDefaultSpacing(POINT
*ppt
);
183 virtual HRESULT STDMETHODCALLTYPE
GetAutoArrange();
184 virtual HRESULT STDMETHODCALLTYPE
SelectItem(int iItem
, DWORD dwFlags
);
185 virtual HRESULT STDMETHODCALLTYPE
SelectAndPositionItems(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD dwFlags
);
187 // *** IShellFolderView methods ***
188 virtual HRESULT STDMETHODCALLTYPE
Rearrange(LPARAM sort
);
189 virtual HRESULT STDMETHODCALLTYPE
GetArrangeParam(LPARAM
*sort
);
190 virtual HRESULT STDMETHODCALLTYPE
ArrangeGrid();
191 virtual HRESULT STDMETHODCALLTYPE
AutoArrange();
192 virtual HRESULT STDMETHODCALLTYPE
AddObject(PITEMID_CHILD pidl
, UINT
*item
);
193 virtual HRESULT STDMETHODCALLTYPE
GetObject(PITEMID_CHILD
*pidl
, UINT item
);
194 virtual HRESULT STDMETHODCALLTYPE
RemoveObject(PITEMID_CHILD pidl
, UINT
*item
);
195 virtual HRESULT STDMETHODCALLTYPE
GetObjectCount(UINT
*count
);
196 virtual HRESULT STDMETHODCALLTYPE
SetObjectCount(UINT count
, UINT flags
);
197 virtual HRESULT STDMETHODCALLTYPE
UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
);
198 virtual HRESULT STDMETHODCALLTYPE
RefreshObject(PITEMID_CHILD pidl
, UINT
*item
);
199 virtual HRESULT STDMETHODCALLTYPE
SetRedraw(BOOL redraw
);
200 virtual HRESULT STDMETHODCALLTYPE
GetSelectedCount(UINT
*count
);
201 virtual HRESULT STDMETHODCALLTYPE
GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
);
202 virtual HRESULT STDMETHODCALLTYPE
IsDropOnSource(IDropTarget
*drop_target
);
203 virtual HRESULT STDMETHODCALLTYPE
GetDragPoint(POINT
*pt
);
204 virtual HRESULT STDMETHODCALLTYPE
GetDropPoint(POINT
*pt
);
205 virtual HRESULT STDMETHODCALLTYPE
MoveIcons(IDataObject
*obj
);
206 virtual HRESULT STDMETHODCALLTYPE
SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
);
207 virtual HRESULT STDMETHODCALLTYPE
IsBkDropTarget(IDropTarget
*drop_target
);
208 virtual HRESULT STDMETHODCALLTYPE
SetClipboard(BOOL move
);
209 virtual HRESULT STDMETHODCALLTYPE
SetPoints(IDataObject
*obj
);
210 virtual HRESULT STDMETHODCALLTYPE
GetItemSpacing(ITEMSPACING
*spacing
);
211 virtual HRESULT STDMETHODCALLTYPE
SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
);
212 virtual HRESULT STDMETHODCALLTYPE
Select(UINT flags
);
213 virtual HRESULT STDMETHODCALLTYPE
QuerySupport(UINT
*support
);
214 virtual HRESULT STDMETHODCALLTYPE
SetAutomationObject(IDispatch
*disp
);
216 // *** IOleCommandTarget methods ***
217 virtual HRESULT STDMETHODCALLTYPE
QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
);
218 virtual HRESULT STDMETHODCALLTYPE
Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
);
220 // *** IDropTarget methods ***
221 virtual HRESULT STDMETHODCALLTYPE
DragEnter(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
222 virtual HRESULT STDMETHODCALLTYPE
DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
223 virtual HRESULT STDMETHODCALLTYPE
DragLeave();
224 virtual HRESULT STDMETHODCALLTYPE
Drop(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
226 // *** IDropSource methods ***
227 virtual HRESULT STDMETHODCALLTYPE
QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
);
228 virtual HRESULT STDMETHODCALLTYPE
GiveFeedback(DWORD dwEffect
);
230 // *** IViewObject methods ***
231 virtual HRESULT STDMETHODCALLTYPE
Draw(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
,
232 HDC hdcTargetDev
, HDC hdcDraw
, LPCRECTL lprcBounds
, LPCRECTL lprcWBounds
,
233 BOOL ( STDMETHODCALLTYPE
*pfnContinue
)(ULONG_PTR dwContinue
), ULONG_PTR dwContinue
);
234 virtual HRESULT STDMETHODCALLTYPE
GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
,
235 DVTARGETDEVICE
*ptd
, HDC hicTargetDev
, LOGPALETTE
**ppColorSet
);
236 virtual HRESULT STDMETHODCALLTYPE
Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
);
237 virtual HRESULT STDMETHODCALLTYPE
Unfreeze(DWORD dwFreeze
);
238 virtual HRESULT STDMETHODCALLTYPE
SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
);
239 virtual HRESULT STDMETHODCALLTYPE
GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
);
241 // *** IServiceProvider methods ***
242 virtual HRESULT STDMETHODCALLTYPE
QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
);
245 LRESULT
OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
246 LRESULT
OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
247 LRESULT
OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
248 LRESULT
OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
249 LRESULT
OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
250 LRESULT
OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
251 LRESULT
OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
252 LRESULT
OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
253 LRESULT
OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
254 LRESULT
OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
255 LRESULT
OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
256 LRESULT
OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
257 LRESULT
OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
258 LRESULT
OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
259 LRESULT
OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
260 LRESULT
OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
261 LRESULT
OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
262 LRESULT
OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
264 static ATL::CWndClassInfo
& GetWndClassInfo()
266 static ATL::CWndClassInfo wc
=
268 { sizeof(WNDCLASSEX
), 0, StartWindowProc
,
270 LoadCursor(NULL
, IDC_ARROW
), (HBRUSH
)(COLOR_BACKGROUND
+ 1), NULL
, SV_CLASS_NAME
, NULL
272 NULL
, NULL
, IDC_ARROW
, TRUE
, 0, _T("")
277 virtual WNDPROC
GetWindowProc()
282 static LRESULT CALLBACK
WindowProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
287 // must hold a reference during message handling
288 pThis
= reinterpret_cast<CDefView
*>(hWnd
);
290 result
= CWindowImpl
<CDefView
, CWindow
, CControlWinTraits
>::WindowProc(hWnd
, uMsg
, wParam
, lParam
);
295 BEGIN_MSG_MAP(CDefView
)
296 MESSAGE_HANDLER(WM_SIZE
, OnSize
)
297 MESSAGE_HANDLER(WM_SETFOCUS
, OnSetFocus
)
298 MESSAGE_HANDLER(WM_KILLFOCUS
, OnKillFocus
)
299 MESSAGE_HANDLER(WM_CREATE
, OnCreate
)
300 MESSAGE_HANDLER(WM_ACTIVATE
, OnActivate
)
301 MESSAGE_HANDLER(WM_NOTIFY
, OnNotify
)
302 MESSAGE_HANDLER(WM_COMMAND
, OnCommand
)
303 MESSAGE_HANDLER(SHV_CHANGE_NOTIFY
, OnChangeNotify
)
304 MESSAGE_HANDLER(WM_CONTEXTMENU
, OnContextMenu
)
305 MESSAGE_HANDLER(WM_DRAWITEM
, OnCustomItem
)
306 MESSAGE_HANDLER(WM_MEASUREITEM
, OnCustomItem
)
307 MESSAGE_HANDLER(WM_SHOWWINDOW
, OnShowWindow
)
308 MESSAGE_HANDLER(WM_GETDLGCODE
, OnGetDlgCode
)
309 MESSAGE_HANDLER(WM_DESTROY
, OnDestroy
)
310 MESSAGE_HANDLER(WM_ERASEBKGND
, OnEraseBackground
)
311 MESSAGE_HANDLER(WM_SYSCOLORCHANGE
, OnSysColorChange
)
312 MESSAGE_HANDLER(CWM_GETISHELLBROWSER
, OnGetShellBrowser
)
313 MESSAGE_HANDLER(WM_SETTINGCHANGE
, OnSettingChange
)
314 MESSAGE_HANDLER(WM_INITMENUPOPUP
, OnInitMenuPopup
)
317 BEGIN_COM_MAP(CDefView
)
318 COM_INTERFACE_ENTRY_IID(IID_IOleWindow
, IOleWindow
)
319 COM_INTERFACE_ENTRY_IID(IID_IShellView
, IShellView
)
320 COM_INTERFACE_ENTRY_IID(IID_IFolderView
, IFolderView
)
321 COM_INTERFACE_ENTRY_IID(IID_IShellFolderView
, IShellFolderView
)
322 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget
, IOleCommandTarget
)
323 COM_INTERFACE_ENTRY_IID(IID_IDropTarget
, IDropTarget
)
324 COM_INTERFACE_ENTRY_IID(IID_IDropSource
, IDropSource
)
325 COM_INTERFACE_ENTRY_IID(IID_IViewObject
, IViewObject
)
326 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider
, IServiceProvider
)
330 /* ListView Header ID's */
331 #define LISTVIEW_COLUMN_NAME 0
332 #define LISTVIEW_COLUMN_SIZE 1
333 #define LISTVIEW_COLUMN_TYPE 2
334 #define LISTVIEW_COLUMN_TIME 3
335 #define LISTVIEW_COLUMN_ATTRIB 4
338 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
339 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
340 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
342 #define ID_LISTVIEW 1
345 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
346 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
347 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
349 typedef void (CALLBACK
*PFNSHGETSETTINGSPROC
)(LPSHELLFLAGSTATE lpsfs
, DWORD dwMask
);
351 CDefView::CDefView() :
355 m_menusLoaded(FALSE
),
369 ZeroMemory(&m_FolderSettings
, sizeof(m_FolderSettings
));
370 ZeroMemory(&m_sortInfo
, sizeof(m_sortInfo
));
371 ZeroMemory(&m_ptLastMousePos
, sizeof(m_ptLastMousePos
));
372 ZeroMemory(&m_Category
, sizeof(m_Category
));
375 CDefView::~CDefView()
377 TRACE(" destroying IShellView(%p)\n", this);
387 HRESULT WINAPI
CDefView::Initialize(IShellFolder
*shellFolder
)
389 m_pSFParent
= shellFolder
;
390 shellFolder
->QueryInterface(IID_PPV_ARG(IShellFolder2
, &m_pSF2Parent
));
395 /**********************************************************
397 * ##### helperfunctions for communication with ICommDlgBrowser #####
399 HRESULT
CDefView::IncludeObject(PCUITEMID_CHILD pidl
)
403 if (m_pCommDlgBrowser
.p
!= NULL
)
405 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl
);
406 ret
= m_pCommDlgBrowser
->IncludeObject(this, pidl
);
407 TRACE("--0x%08x\n", ret
);
413 HRESULT
CDefView::OnDefaultCommand()
415 HRESULT ret
= S_FALSE
;
417 if (m_pCommDlgBrowser
.p
!= NULL
)
419 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
420 ret
= m_pCommDlgBrowser
->OnDefaultCommand(this);
421 TRACE("-- returns %08x\n", ret
);
427 HRESULT
CDefView::OnStateChange(UINT uFlags
)
429 HRESULT ret
= S_FALSE
;
431 if (m_pCommDlgBrowser
.p
!= NULL
)
433 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags
);
434 ret
= m_pCommDlgBrowser
->OnStateChange(this, uFlags
);
440 /**********************************************************
441 * set the toolbar of the filedialog buttons
443 * - activates the buttons from the shellbrowser according to
446 void CDefView::CheckToolbar()
452 if (m_pCommDlgBrowser
!= NULL
)
454 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
455 FCIDM_TB_SMALLICON
, (m_FolderSettings
.ViewMode
== FVM_LIST
) ? TRUE
: FALSE
, &result
);
456 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
457 FCIDM_TB_REPORTVIEW
, (m_FolderSettings
.ViewMode
== FVM_DETAILS
) ? TRUE
: FALSE
, &result
);
458 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
459 FCIDM_TB_SMALLICON
, TRUE
, &result
);
460 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
461 FCIDM_TB_REPORTVIEW
, TRUE
, &result
);
465 /**********************************************************
467 * ##### helperfunctions for initializing the view #####
469 /**********************************************************
470 * change the style of the listview control
472 void CDefView::SetStyle(DWORD dwAdd
, DWORD dwRemove
)
476 TRACE("(%p)\n", this);
478 tmpstyle
= ::GetWindowLongPtrW(m_ListView
, GWL_STYLE
);
479 ::SetWindowLongPtrW(m_ListView
, GWL_STYLE
, dwAdd
| (tmpstyle
& ~dwRemove
));
482 /**********************************************************
483 * ShellView_CreateList()
485 * - creates the list view window
487 BOOL
CDefView::CreateList()
488 { DWORD dwStyle
, dwExStyle
;
492 dwStyle
= WS_TABSTOP
| WS_VISIBLE
| WS_CHILDWINDOW
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
|
493 LVS_SHAREIMAGELISTS
| LVS_EDITLABELS
| LVS_AUTOARRANGE
;
494 dwExStyle
= WS_EX_CLIENTEDGE
;
496 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
497 dwStyle
|= LVS_ALIGNLEFT
;
499 dwStyle
|= LVS_ALIGNTOP
| LVS_SHOWSELALWAYS
;
501 switch (m_FolderSettings
.ViewMode
)
508 dwStyle
|= LVS_REPORT
;
512 dwStyle
|= LVS_SMALLICON
;
524 if (m_FolderSettings
.fFlags
& FWF_AUTOARRANGE
)
525 dwStyle
|= LVS_AUTOARRANGE
;
527 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
528 m_FolderSettings
.fFlags
|= FWF_NOCLIENTEDGE
| FWF_NOSCROLL
;
530 if (m_FolderSettings
.fFlags
& FWF_SINGLESEL
)
531 dwStyle
|= LVS_SINGLESEL
;
533 if (m_FolderSettings
.fFlags
& FWF_NOCLIENTEDGE
)
534 dwExStyle
&= ~WS_EX_CLIENTEDGE
;
536 RECT rcListView
= {0,0,0,0};
537 m_ListView
.Create(m_hWnd
, rcListView
, NULL
,dwStyle
, dwExStyle
, ID_LISTVIEW
);
542 m_sortInfo
.bIsAscending
= TRUE
;
543 m_sortInfo
.nHeaderID
= -1;
544 m_sortInfo
.nLastHeaderID
= -1;
548 /* UpdateShellSettings(); */
552 void CDefView::UpdateListColors()
554 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
556 /* Check if drop shadows option is enabled */
557 BOOL bDropShadow
= FALSE
;
558 DWORD cbDropShadow
= sizeof(bDropShadow
);
559 WCHAR wszBuf
[16] = L
"";
561 RegGetValueW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
562 L
"ListviewShadow", RRF_RT_DWORD
, NULL
, &bDropShadow
, &cbDropShadow
);
563 if (bDropShadow
&& SystemParametersInfoW(SPI_GETDESKWALLPAPER
, _countof(wszBuf
), wszBuf
, 0) && wszBuf
[0])
565 m_ListView
.SetTextBkColor(CLR_NONE
);
566 m_ListView
.SetBkColor(CLR_NONE
);
567 m_ListView
.SetTextColor(RGB(255, 255, 255));
568 m_ListView
.SetExtendedListViewStyle(LVS_EX_TRANSPARENTSHADOWTEXT
, LVS_EX_TRANSPARENTSHADOWTEXT
);
572 COLORREF crDesktop
= GetSysColor(COLOR_DESKTOP
);
573 m_ListView
.SetTextBkColor(crDesktop
);
574 m_ListView
.SetBkColor(crDesktop
);
575 if (GetRValue(crDesktop
) + GetGValue(crDesktop
) + GetBValue(crDesktop
) > 128 * 3)
576 m_ListView
.SetTextColor(RGB(0, 0, 0));
578 m_ListView
.SetTextColor(RGB(255, 255, 255));
579 m_ListView
.SetExtendedListViewStyle(LVS_EX_TRANSPARENTSHADOWTEXT
);
584 /**********************************************************
585 * ShellView_InitList()
587 * - adds all needed columns to the shellview
589 BOOL
CDefView::InitList()
593 HIMAGELIST big_icons
, small_icons
;
597 m_ListView
.DeleteAllItems();
601 for (int i
= 0; 1; i
++)
603 if (FAILED(m_pSF2Parent
->GetDetailsOf(NULL
, i
, &sd
)))
605 StrRetToStrNW( szTemp
, 50, &sd
.str
, NULL
);
606 m_ListView
.InsertColumn(i
, szTemp
, sd
.fmt
, sd
.cxChar
* 8);
615 Shell_GetImageLists(&big_icons
, &small_icons
);
616 m_ListView
.SetImageList(big_icons
, LVSIL_NORMAL
);
617 m_ListView
.SetImageList(small_icons
, LVSIL_SMALL
);
622 /**********************************************************
623 * ShellView_CompareItems()
626 * internal, CALLBACK for DSA_Sort
628 INT CALLBACK
CDefView::CompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
)
631 TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1
, lParam2
, (LPVOID
) lpData
);
636 IShellFolder
* psf
= reinterpret_cast<IShellFolder
*>(lpData
);
637 PCUIDLIST_RELATIVE pidl1
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam1
);
638 PCUIDLIST_RELATIVE pidl2
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam2
);
640 ret
= (SHORT
)SCODE_CODE(psf
->CompareIDs(0, pidl1
, pidl2
));
641 TRACE("ret=%i\n", ret
);
646 /*************************************************************************
647 * ShellView_ListViewCompareItems
649 * Compare Function for the Listview (FileOpen Dialog)
652 * lParam1 [I] the first ItemIdList to compare with
653 * lParam2 [I] the second ItemIdList to compare with
654 * lpData [I] The column ID for the header Ctrl to process
657 * A negative value if the first item should precede the second,
658 * a positive value if the first item should follow the second,
659 * or zero if the two items are equivalent
662 * FIXME: function does what ShellView_CompareItems is supposed to do.
663 * unify it and figure out how to use the undocumented first parameter
664 * of IShellFolder_CompareIDs to do the job this function does and
665 * move this code to IShellFolder.
666 * make LISTVIEW_SORT_INFO obsolete
667 * the way this function works is only usable if we had only
668 * filesystemfolders (25/10/99 jsch)
670 INT CALLBACK
CDefView::ListViewCompareItems(LPARAM lParam1
, LPARAM lParam2
, LPARAM lpData
)
674 char strName1
[MAX_PATH
], strName2
[MAX_PATH
];
675 BOOL bIsFolder1
, bIsFolder2
, bIsBothFolder
;
676 PCUIDLIST_RELATIVE pidl1
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam1
);
677 PCUIDLIST_RELATIVE pidl2
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam2
);
678 LISTVIEW_SORT_INFO
*pSortInfo
= reinterpret_cast<LPLISTVIEW_SORT_INFO
>(lpData
);
681 bIsFolder1
= _ILIsFolder(pidl1
);
682 bIsFolder2
= _ILIsFolder(pidl2
);
683 bIsBothFolder
= bIsFolder1
&& bIsFolder2
;
685 /* When sorting between a File and a Folder, the Folder gets sorted first */
686 if ( (bIsFolder1
|| bIsFolder2
) && !bIsBothFolder
)
688 nDiff
= bIsFolder1
? -1 : 1;
692 /* Sort by Time: Folders or Files can be sorted */
694 if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_TIME
)
696 _ILGetFileDateTime(pidl1
, &fd1
);
697 _ILGetFileDateTime(pidl2
, &fd2
);
698 nDiff
= CompareFileTime(&fd2
, &fd1
);
700 /* Sort by Attribute: Folder or Files can be sorted */
701 else if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_ATTRIB
)
703 _ILGetFileAttributes(pidl1
, strName1
, MAX_PATH
);
704 _ILGetFileAttributes(pidl2
, strName2
, MAX_PATH
);
705 nDiff
= lstrcmpiA(strName1
, strName2
);
707 /* Sort by FileName: Folder or Files can be sorted */
708 else if (pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_NAME
|| bIsBothFolder
)
711 _ILSimpleGetText(pidl1
, strName1
, MAX_PATH
);
712 _ILSimpleGetText(pidl2
, strName2
, MAX_PATH
);
713 nDiff
= lstrcmpiA(strName1
, strName2
);
715 /* Sort by File Size, Only valid for Files */
716 else if (pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_SIZE
)
718 nDiff
= (INT
)(_ILGetFileSize(pidl1
, NULL
, 0) - _ILGetFileSize(pidl2
, NULL
, 0));
720 /* Sort by File Type, Only valid for Files */
721 else if (pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_TYPE
)
724 _ILGetFileType(pidl1
, strName1
, MAX_PATH
);
725 _ILGetFileType(pidl2
, strName2
, MAX_PATH
);
726 nDiff
= lstrcmpiA(strName1
, strName2
);
729 /* If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
733 _ILSimpleGetText(pidl1
, strName1
, MAX_PATH
);
734 _ILSimpleGetText(pidl2
, strName2
, MAX_PATH
);
735 nDiff
= lstrcmpiA(strName1
, strName2
);
738 if (!pSortInfo
->bIsAscending
)
746 PCUITEMID_CHILD
CDefView::_PidlByItem(int i
)
748 return reinterpret_cast<PCUITEMID_CHILD
>(m_ListView
.GetItemData(i
));
751 PCUITEMID_CHILD
CDefView::_PidlByItem(LVITEM
& lvItem
)
753 return reinterpret_cast<PCUITEMID_CHILD
>(lvItem
.lParam
);
756 /**********************************************************
757 * LV_FindItemByPidl()
759 int CDefView::LV_FindItemByPidl(PCUITEMID_CHILD pidl
)
761 int cItems
= m_ListView
.GetItemCount();
763 for (int i
= 0; i
<cItems
; i
++)
765 PCUITEMID_CHILD currentpidl
= _PidlByItem(i
);
766 HRESULT hr
= m_pSFParent
->CompareIDs(0, pidl
, currentpidl
);
768 if (SUCCEEDED(hr
) && !HRESULT_CODE(hr
))
776 /**********************************************************
779 BOOLEAN
CDefView::LV_AddItem(PCUITEMID_CHILD pidl
)
783 TRACE("(%p)(pidl=%p)\n", this, pidl
);
785 lvItem
.mask
= LVIF_TEXT
| LVIF_IMAGE
| LVIF_PARAM
; /*set the mask*/
786 lvItem
.iItem
= m_ListView
.GetItemCount(); /*add the item to the end of the list*/
788 lvItem
.lParam
= reinterpret_cast<LPARAM
>(ILClone(pidl
)); /*set the item's data*/
789 lvItem
.pszText
= LPSTR_TEXTCALLBACKW
; /*get text on a callback basis*/
790 lvItem
.iImage
= I_IMAGECALLBACK
; /*get the image on a callback basis*/
791 lvItem
.stateMask
= LVIS_CUT
;
793 if (m_ListView
.InsertItem(&lvItem
) == -1)
799 /**********************************************************
802 BOOLEAN
CDefView::LV_DeleteItem(PCUITEMID_CHILD pidl
)
806 TRACE("(%p)(pidl=%p)\n", this, pidl
);
808 nIndex
= LV_FindItemByPidl(pidl
);
810 return (-1 == m_ListView
.DeleteItem(nIndex
)) ? FALSE
: TRUE
;
813 /**********************************************************
816 BOOLEAN
CDefView::LV_RenameItem(PCUITEMID_CHILD pidlOld
, PCUITEMID_CHILD pidlNew
)
821 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", this, pidlOld
, pidlNew
);
823 nItem
= LV_FindItemByPidl(pidlOld
);
827 lvItem
.mask
= LVIF_PARAM
; /* only the pidl */
828 lvItem
.iItem
= nItem
;
829 m_ListView
.GetItem(&lvItem
);
831 SHFree(reinterpret_cast<LPVOID
>(lvItem
.lParam
));
832 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
833 lvItem
.iItem
= nItem
;
834 lvItem
.lParam
= reinterpret_cast<LPARAM
>(ILClone(pidlNew
)); /* set the item's data */
835 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
836 m_ListView
.SetItem(&lvItem
);
837 m_ListView
.Update(nItem
);
838 return TRUE
; /* FIXME: better handling */
844 /**********************************************************
847 BOOLEAN
CDefView::LV_ProdItem(PCUITEMID_CHILD pidl
)
852 TRACE("(%p)(pidl=%p)\n", this, pidl
);
854 nItem
= LV_FindItemByPidl(pidl
);
858 lvItem
.mask
= LVIF_IMAGE
;
859 lvItem
.iItem
= nItem
;
860 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
861 m_ListView
.SetItem(&lvItem
);
862 m_ListView
.Update(nItem
);
869 /**********************************************************
870 * ShellView_FillList()
872 * - gets the objectlist from the shellfolder
874 * - fills the list into the view
876 INT CALLBACK
CDefView::fill_list( LPVOID ptr
, LPVOID arg
)
878 PITEMID_CHILD pidl
= static_cast<PITEMID_CHILD
>(ptr
);
879 CDefView
*pThis
= static_cast<CDefView
*>(arg
);
881 /* in a commdlg This works as a filemask*/
882 if (pThis
->IncludeObject(pidl
) == S_OK
)
883 pThis
->LV_AddItem(pidl
);
889 HRESULT
CDefView::FillList()
891 CComPtr
<IEnumIDList
> pEnumIDList
;
897 DWORD dFlags
= SHCONTF_NONFOLDERS
| SHCONTF_FOLDERS
;
901 /* determine if there is a setting to show all the hidden files/folders */
902 if (RegOpenKeyExW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", 0, KEY_QUERY_VALUE
, &hKey
) == ERROR_SUCCESS
)
904 DWORD dataLength
, flagVal
;
906 dataLength
= sizeof(flagVal
);
907 if (RegQueryValueExW(hKey
, L
"Hidden", NULL
, NULL
, (LPBYTE
)&flagVal
, &dataLength
) == ERROR_SUCCESS
)
909 /* if the value is 1, then show all hidden files/folders */
912 dFlags
|= SHCONTF_INCLUDEHIDDEN
;
913 m_ListView
.SendMessageW(LVM_SETCALLBACKMASK
, LVIS_CUT
, 0);
921 /* get the itemlist from the shfolder */
922 hRes
= m_pSFParent
->EnumObjects(m_hWnd
, dFlags
, &pEnumIDList
);
930 /* create a pointer array */
931 hdpa
= DPA_Create(16);
934 return(E_OUTOFMEMORY
);
937 /* copy the items into the array*/
938 while((S_OK
== pEnumIDList
->Next(1, &pidl
, &dwFetched
)) && dwFetched
)
940 if (DPA_InsertPtr(hdpa
, 0x7fff, pidl
) == -1)
947 DPA_Sort(hdpa
, CompareItems
, reinterpret_cast<LPARAM
>(m_pSFParent
.p
));
949 /*turn the listview's redrawing off*/
950 m_ListView
.SetRedraw(FALSE
);
952 DPA_DestroyCallback( hdpa
, fill_list
, this);
954 /*turn the listview's redrawing back on and force it to draw*/
955 m_ListView
.SetRedraw(TRUE
);
960 LRESULT
CDefView::OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
962 m_ListView
.UpdateWindow();
967 LRESULT
CDefView::OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
969 return m_ListView
.SendMessageW(uMsg
, 0, 0);
972 LRESULT
CDefView::OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
975 DestroyMenu(m_hMenu
);
976 RevokeDragDrop(m_hWnd
);
977 SHChangeNotifyDeregister(m_hNotify
);
978 SHFree(m_pidlParent
);
983 LRESULT
CDefView::OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
985 /* redirect to parent */
986 if (m_FolderSettings
.fFlags
& (FWF_DESKTOP
| FWF_TRANSPARENT
))
987 return SendMessageW(GetParent(), WM_ERASEBKGND
, wParam
, lParam
);
993 LRESULT
CDefView::OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
995 /* Update desktop labels color */
998 /* Forward WM_SYSCOLORCHANGE to common controls */
999 return m_ListView
.SendMessageW(uMsg
, 0, 0);
1002 LRESULT
CDefView::OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1004 return reinterpret_cast<LRESULT
>(m_pShellBrowser
.p
);
1007 /**********************************************************
1008 * ShellView_OnCreate()
1010 LRESULT
CDefView::OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1012 CComPtr
<IDropTarget
> pdt
;
1013 SHChangeNotifyEntry ntreg
;
1014 CComPtr
<IPersistFolder2
> ppf2
;
1016 TRACE("%p\n", this);
1026 if (SUCCEEDED(QueryInterface(IID_PPV_ARG(IDropTarget
, &pdt
))))
1028 if (FAILED(RegisterDragDrop(m_hWnd
, pdt
)))
1029 ERR("Registering Drag Drop Failed");
1032 /* register for receiving notifications */
1033 m_pSFParent
->QueryInterface(IID_PPV_ARG(IPersistFolder2
, &ppf2
));
1036 ppf2
->GetCurFolder(&m_pidlParent
);
1037 ntreg
.fRecursive
= TRUE
;
1038 ntreg
.pidl
= m_pidlParent
;
1039 m_hNotify
= SHChangeNotifyRegister(m_hWnd
, SHCNRF_InterruptLevel
| SHCNRF_ShellLevel
, SHCNE_ALLEVENTS
, SHV_CHANGE_NOTIFY
, 1, &ntreg
);
1042 m_hAccel
= LoadAcceleratorsW(shell32_hInstance
, MAKEINTRESOURCEW(IDA_SHELLVIEW
));
1047 /**********************************************************
1048 * #### Handling of the menus ####
1051 HMENU
CDefView::BuildFileMenu()
1054 CComPtr
<IContextMenu
> cm
;
1058 hr
= m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, IID_NULL_PPV_ARG(IContextMenu
, &cm
));
1062 HMENU hmenu
= CreatePopupMenu();
1064 //FIXME: get proper numbers ?
1065 const UINT first
= 0x7800;
1066 const UINT last
= 0x7A00;
1067 hr
= cm
->QueryContextMenu(hmenu
, 0, first
, last
, 0);
1071 // TODO: filter or something
1076 void CDefView::PrepareShowFileMenu(HMENU hSubMenu
)
1078 TRACE("(%p)->(submenu=%p) stub\n", this, hSubMenu
);
1083 /* Cleanup the items added previously */
1084 for (int i
= 0; i
< GetMenuItemCount(hSubMenu
); )
1087 mii
.cbSize
= sizeof(mii
);
1088 mii
.fMask
= MIIM_ID
;
1089 GetMenuItemInfoW(hSubMenu
, i
, TRUE
, &mii
);
1091 if (mii
.wID
< 0x8000)
1093 DeleteMenu(hSubMenu
, i
, MF_BYPOSITION
);
1102 /* FIXME/TODO: Reenable when they implemented AND localizable (not hardcoded). */
1103 /* Insert This item at the beginning of the menu. */
1104 _InsertMenuItemW(hSubMenu
, 0, TRUE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1105 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
+ 4, MFT_STRING
, L
"Properties", MFS_DISABLED
);
1106 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
+ 3, MFT_STRING
, L
"Rename", MFS_DISABLED
);
1107 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
+ 2, MFT_STRING
, L
"Delete", MFS_DISABLED
);
1108 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
+ 1, MFT_STRING
, L
"Create Shortcut", MFS_DISABLED
);
1109 _InsertMenuItemW(hSubMenu
, 0, TRUE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1110 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
, MFT_STRING
, L
"New", MFS_ENABLED
);
1113 HMENU menubase
= BuildFileMenu();
1116 int count
= ::GetMenuItemCount(menubase
);
1117 int count2
= ::GetMenuItemCount(hSubMenu
);
1119 if (count2
> 0 && count
> 0)
1121 _InsertMenuItemW(hSubMenu
, 0, TRUE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1124 for (int i
= count
-1; i
>= 0; i
--)
1128 MENUITEMINFOW mii
= { 0 };
1129 mii
.cbSize
= sizeof(mii
);
1130 mii
.fMask
= MIIM_STATE
| MIIM_ID
| MIIM_SUBMENU
| MIIM_CHECKMARKS
| MIIM_DATA
| MIIM_STRING
| MIIM_BITMAP
| MIIM_FTYPE
;
1131 mii
.dwTypeData
= label
;
1132 mii
.cch
= _countof(label
);
1133 ::GetMenuItemInfoW(menubase
, i
, TRUE
, &mii
);
1135 TRACE("Adding item %d label %S type %d\n", mii
.wID
, mii
.dwTypeData
, mii
.fType
);
1137 mii
.fType
|= MFT_RADIOCHECK
;
1139 ::InsertMenuItemW(hSubMenu
, 0, TRUE
, &mii
);
1143 ::DestroyMenu(menubase
);
1148 void CDefView::PrepareShowViewMenu(HMENU hSubMenu
)
1150 TRACE("(%p)->(submenu=%p)\n", this, hSubMenu
);
1155 if (m_FolderSettings
.ViewMode
>= FVM_FIRST
&& m_FolderSettings
.ViewMode
<= FVM_LAST
)
1157 UINT iItemFirst
= FCIDM_SHVIEW_BIGICON
;
1158 UINT iItemLast
= iItemFirst
+ FVM_LAST
- FVM_FIRST
;
1159 UINT iItem
= iItemFirst
+ m_FolderSettings
.ViewMode
- FVM_FIRST
;
1160 CheckMenuRadioItem(hSubMenu
, iItemFirst
, iItemLast
, iItem
, MF_BYCOMMAND
);
1164 /**********************************************************
1165 * ShellView_GetSelections()
1167 * - fills the m_apidl list with the selected objects
1170 * number of selected items
1172 UINT
CDefView::GetSelections()
1176 m_cidl
= m_ListView
.GetSelectedCount();
1177 m_apidl
= reinterpret_cast<PCUITEMID_CHILD_ARRAY
>(SHAlloc(m_cidl
* sizeof(PCUITEMID_CHILD
)));
1184 TRACE("-- Items selected =%u\n", m_cidl
);
1188 while ((lvIndex
= m_ListView
.GetNextItem(lvIndex
, LVNI_SELECTED
)) > -1)
1190 m_apidl
[i
] = _PidlByItem(lvIndex
);
1194 TRACE("-- selected Item found\n");
1200 /**********************************************************
1201 * ShellView_OpenSelectedItems()
1203 HRESULT
CDefView::OpenSelectedItems()
1206 CMINVOKECOMMANDINFO cmi
;
1210 m_cidl
= m_ListView
.GetSelectedCount();
1214 hResult
= OnDefaultCommand();
1215 if (hResult
== S_OK
)
1218 hMenu
= CreatePopupMenu();
1222 hResult
= GetItemObject(SVGIO_SELECTION
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1223 if (FAILED(hResult
))
1226 hResult
= IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1227 //if (FAILED( hResult))
1230 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, 0x20, 0x7fff, CMF_DEFAULTONLY
);
1231 if (FAILED(hResult
))
1234 uCommand
= GetMenuDefaultItem(hMenu
, FALSE
, 0);
1235 if (uCommand
== (UINT
)-1)
1241 ZeroMemory(&cmi
, sizeof(cmi
));
1242 cmi
.cbSize
= sizeof(cmi
);
1243 cmi
.lpVerb
= (LPCSTR
)MAKEINTRESOURCEA(uCommand
);
1246 hResult
= m_pCM
->InvokeCommand(&cmi
);
1255 IUnknown_SetSite(m_pCM
, NULL
);
1262 /**********************************************************
1263 * ShellView_DoContextMenu()
1265 LRESULT
CDefView::OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1271 CMINVOKECOMMANDINFO cmi
;
1274 // for some reason I haven't figured out, we sometimes recurse into this method
1281 TRACE("(%p)->(0x%08x 0x%08x) stub\n", this, x
, y
);
1283 hMenu
= CreatePopupMenu();
1287 m_cidl
= m_ListView
.GetSelectedCount();
1289 hResult
= GetItemObject( m_cidl
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1290 if (FAILED( hResult
))
1293 hResult
= IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1294 //if (FAILED( hResult))
1297 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1298 if (FAILED( hResult
))
1301 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
1302 SetMenuDefaultItem(hMenu
, FCIDM_SHVIEW_OPEN
, MF_BYCOMMAND
);
1304 uCommand
= TrackPopupMenu(hMenu
,
1305 TPM_LEFTALIGN
| TPM_RETURNCMD
| TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
,
1306 x
, y
, 0, m_hWnd
, NULL
);
1310 if (uCommand
== FCIDM_SHVIEW_OPEN
&& OnDefaultCommand() == S_OK
)
1313 ZeroMemory(&cmi
, sizeof(cmi
));
1314 cmi
.cbSize
= sizeof(cmi
);
1315 cmi
.lpVerb
= MAKEINTRESOURCEA(uCommand
);
1317 m_pCM
->InvokeCommand(&cmi
);
1323 IUnknown_SetSite(m_pCM
, NULL
);
1333 LRESULT
CDefView::OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
)
1336 CMINVOKECOMMANDINFO cmi
;
1339 hMenu
= CreatePopupMenu();
1343 hResult
= GetItemObject( bUseSelection
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1344 if (FAILED( hResult
))
1347 hResult
= IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1348 //if (FAILED( hResult))
1351 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1352 if (FAILED( hResult
))
1355 ZeroMemory(&cmi
, sizeof(cmi
));
1356 cmi
.cbSize
= sizeof(cmi
);
1357 cmi
.lpVerb
= MAKEINTRESOURCEA(uCommand
);
1359 m_pCM
->InvokeCommand(&cmi
);
1365 IUnknown_SetSite(m_pCM
, NULL
);
1375 /**********************************************************
1376 * ##### message handling #####
1379 /**********************************************************
1380 * ShellView_OnSize()
1382 LRESULT
CDefView::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1387 wWidth
= LOWORD(lParam
);
1388 wHeight
= HIWORD(lParam
);
1390 TRACE("%p width=%u height=%u\n", this, wWidth
, wHeight
);
1392 /*resize the ListView to fit our window*/
1395 ::MoveWindow(m_ListView
, 0, 0, wWidth
, wHeight
, TRUE
);
1401 /**********************************************************
1402 * ShellView_OnDeactivate()
1407 void CDefView::OnDeactivate()
1409 TRACE("%p\n", this);
1411 if (m_uState
!= SVUIA_DEACTIVATE
)
1413 // TODO: cleanup menu after deactivation
1415 m_uState
= SVUIA_DEACTIVATE
;
1419 void CDefView::DoActivate(UINT uState
)
1421 TRACE("%p uState=%x\n", this, uState
);
1423 /*don't do anything if the state isn't really changing */
1424 if (m_uState
== uState
)
1429 if (uState
== SVUIA_DEACTIVATE
)
1439 MENUITEMINFOW mii
= { 0 };
1441 /* initialize EDIT menu */
1442 mii
.cbSize
= sizeof(mii
);
1443 mii
.fMask
= MIIM_SUBMENU
;
1444 if (::GetMenuItemInfoW(m_hMenu
, FCIDM_MENU_EDIT
, FALSE
, &mii
))
1446 HMENU hSubMenu
= mii
.hSubMenu
;
1448 HMENU menubase
= ::LoadMenuW(shell32_hInstance
, L
"MENU_003");
1450 int count
= ::GetMenuItemCount(menubase
);
1451 for (int i
= 0; i
< count
; i
++)
1455 ZeroMemory(&mii
, sizeof(mii
));
1456 mii
.cbSize
= sizeof(mii
);
1457 mii
.fMask
= MIIM_STATE
| MIIM_ID
| MIIM_SUBMENU
| MIIM_CHECKMARKS
| MIIM_DATA
| MIIM_STRING
| MIIM_BITMAP
| MIIM_FTYPE
;
1458 mii
.dwTypeData
= label
;
1459 mii
.cch
= _countof(label
);
1460 ::GetMenuItemInfoW(menubase
, i
, TRUE
, &mii
);
1462 TRACE("Adding item %d label %S type %d\n", mii
.wID
, mii
.dwTypeData
, mii
.fType
);
1464 mii
.fType
|= MFT_RADIOCHECK
;
1466 ::InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, &mii
);
1469 ::DestroyMenu(menubase
);
1472 /* initialize VIEW menu */
1474 mii
.cbSize
= sizeof(mii
);
1475 mii
.fMask
= MIIM_SUBMENU
;
1476 if (::GetMenuItemInfoW(m_hMenu
, FCIDM_MENU_VIEW
, FALSE
, &mii
))
1478 HMENU menubase
= ::LoadMenuW(shell32_hInstance
, L
"MENU_001");
1480 HMENU hSubMenu
= mii
.hSubMenu
;
1482 m_hView
= CreatePopupMenu();
1484 _InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1486 int count
= ::GetMenuItemCount(menubase
);
1487 for (int i
= 0; i
< count
; i
++)
1491 ZeroMemory(&mii
, sizeof(mii
));
1492 mii
.cbSize
= sizeof(mii
);
1493 mii
.fMask
= MIIM_STATE
| MIIM_ID
| MIIM_SUBMENU
| MIIM_CHECKMARKS
| MIIM_DATA
| MIIM_STRING
| MIIM_BITMAP
| MIIM_FTYPE
;
1494 mii
.dwTypeData
= label
;
1495 mii
.cch
= _countof(label
);
1496 ::GetMenuItemInfoW(menubase
, i
, TRUE
, &mii
);
1498 ::AppendMenuW(m_hView
, mii
.fType
, mii
.wID
, mii
.dwTypeData
);
1500 TRACE("Adding item %d label %S type %d\n", mii
.wID
, mii
.dwTypeData
, mii
.fType
);
1502 mii
.fType
|= MFT_RADIOCHECK
;
1504 ::InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, &mii
);
1507 ::DestroyMenu(menubase
);
1511 TRACE("-- before fnSetMenuSB\n");
1512 m_pShellBrowser
->SetMenuSB(m_hMenu
, 0, m_hWnd
);
1514 m_menusLoaded
= TRUE
;
1518 if (SVUIA_ACTIVATE_FOCUS
== uState
)
1520 m_ListView
.SetFocus();
1528 /**********************************************************
1529 * ShellView_OnActivate()
1531 LRESULT
CDefView::OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1533 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1537 /**********************************************************
1538 * ShellView_OnSetFocus()
1541 LRESULT
CDefView::OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1543 TRACE("%p\n", this);
1545 /* Tell the browser one of our windows has received the focus. This
1546 should always be done before merging menus (OnActivate merges the
1547 menus) if one of our windows has the focus.*/
1549 m_pShellBrowser
->OnViewWindowActive(this);
1550 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1552 /* Set the focus to the listview */
1553 m_ListView
.SetFocus();
1555 /* Notify the ICommDlgBrowser interface */
1556 OnStateChange(CDBOSC_SETFOCUS
);
1561 /**********************************************************
1562 * ShellView_OnKillFocus()
1564 LRESULT
CDefView::OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1566 TRACE("(%p) stub\n", this);
1568 DoActivate(SVUIA_ACTIVATE_NOFOCUS
);
1569 /* Notify the ICommDlgBrowser */
1570 OnStateChange(CDBOSC_KILLFOCUS
);
1575 /**********************************************************
1576 * ShellView_OnCommand()
1579 * the CmdID's are the ones from the context menu
1581 LRESULT
CDefView::OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1588 dwCmdID
= GET_WM_COMMAND_ID(wParam
, lParam
);
1589 dwCmd
= GET_WM_COMMAND_CMD(wParam
, lParam
);
1590 hwndCmd
= GET_WM_COMMAND_HWND(wParam
, lParam
);
1592 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n", this, dwCmdID
, dwCmd
, hwndCmd
);
1596 case FCIDM_SHVIEW_SMALLICON
:
1597 m_FolderSettings
.ViewMode
= FVM_SMALLICON
;
1598 SetStyle (LVS_SMALLICON
, LVS_TYPEMASK
);
1602 case FCIDM_SHVIEW_BIGICON
:
1603 m_FolderSettings
.ViewMode
= FVM_ICON
;
1604 SetStyle (LVS_ICON
, LVS_TYPEMASK
);
1608 case FCIDM_SHVIEW_LISTVIEW
:
1609 m_FolderSettings
.ViewMode
= FVM_LIST
;
1610 SetStyle (LVS_LIST
, LVS_TYPEMASK
);
1614 case FCIDM_SHVIEW_REPORTVIEW
:
1615 m_FolderSettings
.ViewMode
= FVM_DETAILS
;
1616 SetStyle (LVS_REPORT
, LVS_TYPEMASK
);
1620 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1625 m_sortInfo
.nHeaderID
= dwCmdID
- 0x30;
1626 m_sortInfo
.bIsAscending
= TRUE
;
1627 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
1628 m_ListView
.SortItems(ListViewCompareItems
, &m_sortInfo
);
1631 case FCIDM_SHVIEW_SELECTALL
:
1632 m_ListView
.SetItemState(-1, LVIS_SELECTED
, LVIS_SELECTED
);
1635 case FCIDM_SHVIEW_INVERTSELECTION
:
1636 nCount
= m_ListView
.GetItemCount();
1637 for (int i
=0; i
< nCount
; i
++)
1638 m_ListView
.SetItemState(i
, m_ListView
.GetItemState(i
, LVIS_SELECTED
) ? 0 : LVIS_SELECTED
, LVIS_SELECTED
);
1641 case FCIDM_SHVIEW_REFRESH
:
1645 case FCIDM_SHVIEW_DELETE
:
1646 case FCIDM_SHVIEW_CUT
:
1647 case FCIDM_SHVIEW_COPY
:
1648 case FCIDM_SHVIEW_RENAME
:
1649 return OnExplorerCommand(dwCmdID
, TRUE
);
1651 case FCIDM_SHVIEW_INSERT
:
1652 case FCIDM_SHVIEW_UNDO
:
1653 case FCIDM_SHVIEW_INSERTLINK
:
1654 case FCIDM_SHVIEW_NEWFOLDER
:
1655 return OnExplorerCommand(dwCmdID
, FALSE
);
1657 TRACE("-- COMMAND 0x%04x unhandled\n", dwCmdID
);
1663 /**********************************************************
1664 * ShellView_OnNotify()
1667 LRESULT
CDefView::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1671 LPNMLISTVIEW lpnmlv
;
1672 NMLVDISPINFOW
*lpdi
;
1673 PCUITEMID_CHILD pidl
;
1677 lpnmh
= (LPNMHDR
)lParam
;
1678 lpnmlv
= (LPNMLISTVIEW
)lpnmh
;
1679 lpdi
= (NMLVDISPINFOW
*)lpnmh
;
1681 TRACE("%p CtlID=%u lpnmh->code=%x\n", this, CtlID
, lpnmh
->code
);
1683 switch (lpnmh
->code
)
1686 TRACE("-- NM_SETFOCUS %p\n", this);
1687 OnSetFocus(0, 0, 0, unused
);
1691 TRACE("-- NM_KILLFOCUS %p\n", this);
1693 /* Notify the ICommDlgBrowser interface */
1694 OnStateChange(CDBOSC_KILLFOCUS
);
1698 TRACE("-- NM_CUSTOMDRAW %p\n", this);
1699 return CDRF_DODEFAULT
;
1701 case NM_RELEASEDCAPTURE
:
1702 TRACE("-- NM_RELEASEDCAPTURE %p\n", this);
1706 TRACE("-- NM_CLICK %p\n", this);
1710 TRACE("-- NM_RCLICK %p\n", this);
1714 TRACE("-- NM_DBLCLK %p\n", this);
1715 OpenSelectedItems();
1719 TRACE("-- NM_RETURN %p\n", this);
1720 OpenSelectedItems();
1724 TRACE("-- HDN_ENDTRACKW %p\n", this);
1725 /*nColumn1 = m_ListView.GetColumnWidth(0);
1726 nColumn2 = m_ListView.GetColumnWidth(1);*/
1729 case LVN_DELETEITEM
:
1730 TRACE("-- LVN_DELETEITEM %p\n", this);
1732 /*delete the pidl because we made a copy of it*/
1733 SHFree(reinterpret_cast<LPVOID
>(lpnmlv
->lParam
));
1737 case LVN_DELETEALLITEMS
:
1738 TRACE("-- LVN_DELETEALLITEMS %p\n", this);
1741 case LVN_INSERTITEM
:
1742 TRACE("-- LVN_INSERTITEM (STUB)%p\n", this);
1745 case LVN_ITEMACTIVATE
:
1746 TRACE("-- LVN_ITEMACTIVATE %p\n", this);
1747 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1750 case LVN_COLUMNCLICK
:
1751 m_sortInfo
.nHeaderID
= lpnmlv
->iSubItem
;
1752 if (m_sortInfo
.nLastHeaderID
== m_sortInfo
.nHeaderID
)
1753 m_sortInfo
.bIsAscending
= !m_sortInfo
.bIsAscending
;
1755 m_sortInfo
.bIsAscending
= TRUE
;
1756 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
1758 m_ListView
.SortItems(ListViewCompareItems
, &m_sortInfo
);
1761 case LVN_GETDISPINFOA
:
1762 case LVN_GETDISPINFOW
:
1763 TRACE("-- LVN_GETDISPINFO %p\n", this);
1764 pidl
= _PidlByItem(lpdi
->item
);
1766 if (lpdi
->item
.mask
& LVIF_TEXT
) /* text requested */
1771 if (FAILED(m_pSF2Parent
->GetDetailsOf(pidl
, lpdi
->item
.iSubItem
, &sd
)))
1773 FIXME("failed to get details\n");
1777 if (lpnmh
->code
== LVN_GETDISPINFOA
)
1779 /* shouldn't happen */
1780 NMLVDISPINFOA
*lpdiA
= (NMLVDISPINFOA
*)lpnmh
;
1781 StrRetToStrNA( lpdiA
->item
.pszText
, lpdiA
->item
.cchTextMax
, &sd
.str
, NULL
);
1782 TRACE("-- text=%s\n", lpdiA
->item
.pszText
);
1784 else /* LVN_GETDISPINFOW */
1786 StrRetToStrNW( lpdi
->item
.pszText
, lpdi
->item
.cchTextMax
, &sd
.str
, NULL
);
1787 TRACE("-- text=%s\n", debugstr_w(lpdi
->item
.pszText
));
1795 if(lpdi
->item
.mask
& LVIF_IMAGE
) /* image requested */
1797 lpdi
->item
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
1799 if(lpdi
->item
.mask
& LVIF_STATE
)
1801 ULONG attributes
= SFGAO_HIDDEN
;
1802 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(1, &pidl
, &attributes
)))
1804 if (attributes
& SFGAO_HIDDEN
)
1806 lpdi
->item
.state
|= LVIS_CUT
;
1810 lpdi
->item
.mask
|= LVIF_DI_SETITEM
;
1813 case LVN_ITEMCHANGED
:
1814 TRACE("-- LVN_ITEMCHANGED %p\n", this);
1815 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1819 case LVN_BEGINRDRAG
:
1820 TRACE("-- LVN_BEGINDRAG\n");
1822 if (GetSelections())
1824 CComPtr
<IDataObject
> pda
;
1825 DWORD dwAttributes
= SFGAO_CANLINK
;
1826 DWORD dwEffect
= DROPEFFECT_COPY
| DROPEFFECT_MOVE
;
1828 if (SUCCEEDED(m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, IID_NULL_PPV_ARG(IDataObject
, &pda
))))
1830 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(m_cidl
, m_apidl
, &dwAttributes
)))
1832 if (dwAttributes
& SFGAO_CANLINK
)
1834 dwEffect
|= DROPEFFECT_LINK
;
1838 CComPtr
<IAsyncOperation
> piaso
;
1839 if (SUCCEEDED(pda
->QueryInterface(IID_PPV_ARG(IAsyncOperation
, &piaso
))))
1841 piaso
->SetAsyncMode(TRUE
);
1845 DoDragDrop(pda
, this, dwEffect
, &dwEffect2
);
1850 case LVN_BEGINLABELEDITW
:
1852 DWORD dwAttr
= SFGAO_CANRENAME
;
1853 pidl
= _PidlByItem(lpdi
->item
);
1855 TRACE("-- LVN_BEGINLABELEDITW %p\n", this);
1857 m_pSFParent
->GetAttributesOf(1, &pidl
, &dwAttr
);
1858 if (SFGAO_CANRENAME
& dwAttr
)
1866 case LVN_ENDLABELEDITW
:
1868 TRACE("-- LVN_ENDLABELEDITW %p\n", this);
1870 m_isEditing
= FALSE
;
1872 if (lpdi
->item
.pszText
)
1877 pidl
= _PidlByItem(lpdi
->item
);
1878 PITEMID_CHILD pidlNew
;
1879 hr
= m_pSFParent
->SetNameOf(0, pidl
, lpdi
->item
.pszText
, SHGDN_INFOLDER
, &pidlNew
);
1881 if (SUCCEEDED(hr
) && pidlNew
)
1883 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
1884 lvItem
.iItem
= lpdi
->item
.iItem
;
1885 lvItem
.lParam
= reinterpret_cast<LPARAM
>(pidlNew
);
1886 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
1887 m_ListView
.SetItem(&lvItem
);
1888 m_ListView
.Update(lpdi
->item
.iItem
);
1897 TRACE("-- %p WM_COMMAND %x unhandled\n", this, lpnmh
->code
);
1905 * This is just a quick hack to make the desktop work correctly.
1906 * ITranslateShellChangeNotify's IsChildID is undocumented, but most likely the way that
1907 * a folder should know if it should update upon a change notification.
1908 * It is exported by merged folders at a minimum.
1910 static BOOL
ILIsParentOrSpecialParent(PCIDLIST_ABSOLUTE pidl1
, PCIDLIST_ABSOLUTE pidl2
)
1912 if (!pidl1
|| !pidl2
)
1914 if (ILIsParent(pidl1
, pidl2
, TRUE
))
1917 if (_ILIsDesktop(pidl1
))
1919 PIDLIST_ABSOLUTE deskpidl
;
1920 SHGetFolderLocation(NULL
, CSIDL_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
1921 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
1927 SHGetFolderLocation(NULL
, CSIDL_COMMON_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
1928 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
1938 /**********************************************************
1939 * ShellView_OnChange()
1941 LRESULT
CDefView::OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1943 PCIDLIST_ABSOLUTE
*Pidls
= reinterpret_cast<PCIDLIST_ABSOLUTE
*>(wParam
);
1944 BOOL bParent0
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[0]);
1945 BOOL bParent1
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[1]);
1947 TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls
[0], Pidls
[1], lParam
);
1955 if (LV_FindItemByPidl(ILFindLastID(Pidls
[0])) == -1)
1957 LV_AddItem(ILFindLastID(Pidls
[0]));
1961 LV_ProdItem(ILFindLastID(Pidls
[0]));
1969 LV_DeleteItem(ILFindLastID(Pidls
[0]));
1972 case SHCNE_RENAMEFOLDER
:
1973 case SHCNE_RENAMEITEM
:
1974 if (bParent0
&& bParent1
)
1975 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[1]));
1977 LV_DeleteItem(ILFindLastID(Pidls
[0]));
1979 LV_AddItem(ILFindLastID(Pidls
[1]));
1982 case SHCNE_UPDATEITEM
:
1984 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[0]));
1987 case SHCNE_UPDATEDIR
:
1994 /**********************************************************
1995 * CDefView::OnCustomItem
1997 LRESULT
CDefView::OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
2002 ERR("no menu!!!\n");
2007 HRESULT hres
= SHForwardContextMenuMsg(m_pCM
, uMsg
, wParam
, lParam
, &result
, TRUE
);
2008 if (SUCCEEDED(hres
))
2014 LRESULT
CDefView::OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
2016 /* Wallpaper setting affects drop shadows effect */
2017 if (wParam
== SPI_SETDESKWALLPAPER
|| wParam
== 0)
2023 /**********************************************************
2024 * CDefView::OnInitMenuPopup
2026 LRESULT
CDefView::OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
2028 MENUITEMINFOW mii
= { 0 };
2029 HMENU hSubmenu
= (HMENU
) wParam
;
2031 TRACE("OnInitMenuPopup lParam=%d\n", lParam
);
2033 mii
.cbSize
= sizeof(mii
);
2034 mii
.fMask
= MIIM_ID
| MIIM_SUBMENU
;
2036 if (!GetMenuItemInfoW(this->m_hMenu
, lParam
, TRUE
, &mii
))
2038 TRACE("OnInitMenuPopup GetMenuItemInfoW failed!\n");
2042 UINT menuItemId
= mii
.wID
;
2044 if (mii
.hSubMenu
!= hSubmenu
)
2046 TRACE("OnInitMenuPopup submenu does not match!!!!\n");
2050 TRACE("OnInitMenuPopup id=%d\n", menuItemId
);
2054 case FCIDM_MENU_FILE
:
2055 PrepareShowFileMenu(hSubmenu
);
2057 case FCIDM_MENU_EDIT
:
2058 //PrepareShowEditMenu(hSubmenu);
2060 case FCIDM_MENU_VIEW
:
2061 PrepareShowViewMenu(hSubmenu
);
2068 /**********************************************************
2071 * The INTERFACE of the IShellView object
2074 **********************************************************
2077 /**********************************************************
2078 * ShellView_GetWindow
2080 HRESULT WINAPI
CDefView::GetWindow(HWND
*phWnd
)
2082 TRACE("(%p)\n", this);
2089 HRESULT WINAPI
CDefView::ContextSensitiveHelp(BOOL fEnterMode
)
2091 FIXME("(%p) stub\n", this);
2096 /**********************************************************
2097 * IShellView_TranslateAccelerator
2100 * use the accel functions
2102 HRESULT WINAPI
CDefView::TranslateAccelerator(LPMSG lpmsg
)
2107 if (lpmsg
->message
>= WM_KEYFIRST
&& lpmsg
->message
<= WM_KEYLAST
)
2109 if (::TranslateAcceleratorW(m_hWnd
, m_hAccel
, lpmsg
) != 0)
2112 TRACE("-- key=0x04%lx\n", lpmsg
->wParam
) ;
2115 return m_pShellBrowser
->TranslateAcceleratorSB(lpmsg
, 0);
2118 HRESULT WINAPI
CDefView::EnableModeless(BOOL fEnable
)
2120 FIXME("(%p) stub\n", this);
2125 HRESULT WINAPI
CDefView::UIActivate(UINT uState
)
2128 CHAR szName[MAX_PATH];
2131 int nPartArray
[1] = { -1};
2133 TRACE("(%p)->(state=%x) stub\n", this, uState
);
2135 /*don't do anything if the state isn't really changing*/
2136 if (m_uState
== uState
)
2141 /*OnActivate handles the menu merging and internal state*/
2144 /*only do This if we are active*/
2145 if (uState
!= SVUIA_DEACTIVATE
)
2149 GetFolderPath is not a method of IShellFolder
2150 IShellFolder_GetFolderPath( m_pSFParent, szName, sizeof(szName) );
2152 /* set the number of parts */
2153 m_pShellBrowser
->SendControlMsg(FCW_STATUS
, SB_SETPARTS
, 1, (LPARAM
)nPartArray
, &lResult
);
2155 /* set the text for the parts */
2157 m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXTA, 0, (LPARAM)szName, &lResult);
2164 HRESULT WINAPI
CDefView::Refresh()
2166 TRACE("(%p)\n", this);
2168 m_ListView
.DeleteAllItems();
2174 HRESULT WINAPI
CDefView::CreateViewWindow(IShellView
*lpPrevView
, LPCFOLDERSETTINGS lpfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
)
2176 OLEMENUGROUPWIDTHS omw
= { { 0, 0, 0, 0, 0, 0 } };
2180 TRACE("(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n", this, lpPrevView
, lpfs
, psb
, prcView
, phWnd
);
2183 TRACE("-- vmode=%x flags=%x\n", lpfs
->ViewMode
, lpfs
->fFlags
);
2184 if (prcView
!= NULL
)
2185 TRACE("-- left=%i top=%i right=%i bottom=%i\n", prcView
->left
, prcView
->top
, prcView
->right
, prcView
->bottom
);
2187 /* Validate the Shell Browser */
2189 return E_UNEXPECTED
;
2191 /*set up the member variables*/
2192 m_pShellBrowser
= psb
;
2193 m_FolderSettings
= *lpfs
;
2195 /*get our parent window*/
2196 m_pShellBrowser
->GetWindow(&m_hWndParent
);
2198 /* try to get the ICommDlgBrowserInterface, adds a reference !!! */
2199 m_pCommDlgBrowser
= NULL
;
2200 if (SUCCEEDED(m_pShellBrowser
->QueryInterface(IID_PPV_ARG(ICommDlgBrowser
, &m_pCommDlgBrowser
))))
2202 TRACE("-- CommDlgBrowser\n");
2205 Create(m_hWndParent
, prcView
, NULL
, WS_CHILD
| WS_TABSTOP
, 0, 0U);
2216 SetWindowPos(HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_SHOWWINDOW
);
2221 m_hMenu
= CreateMenu();
2222 m_pShellBrowser
->InsertMenusSB(m_hMenu
, &omw
);
2223 TRACE("-- after fnInsertMenusSB\n");
2231 HRESULT WINAPI
CDefView::DestroyViewWindow()
2233 TRACE("(%p)\n", this);
2235 /*Make absolutely sure all our UI is cleaned up.*/
2236 UIActivate(SVUIA_DEACTIVATE
);
2240 // "Accelerator tables loaded from resources are freed automatically when the application terminates." -- MSDN
2246 DestroyMenu(m_hView
);
2252 DestroyMenu(m_hMenu
);
2258 m_ListView
.DestroyWindow();
2266 m_pShellBrowser
.Release();
2267 m_pCommDlgBrowser
.Release();
2272 HRESULT WINAPI
CDefView::GetCurrentInfo(LPFOLDERSETTINGS lpfs
)
2274 TRACE("(%p)->(%p) vmode=%x flags=%x\n", this, lpfs
,
2275 m_FolderSettings
.ViewMode
, m_FolderSettings
.fFlags
);
2278 return E_INVALIDARG
;
2280 *lpfs
= m_FolderSettings
;
2284 HRESULT WINAPI
CDefView::AddPropertySheetPages(DWORD dwReserved
, LPFNADDPROPSHEETPAGE lpfn
, LPARAM lparam
)
2286 FIXME("(%p) stub\n", this);
2291 HRESULT WINAPI
CDefView::SaveViewState()
2293 FIXME("(%p) stub\n", this);
2298 HRESULT WINAPI
CDefView::SelectItem(PCUITEMID_CHILD pidl
, UINT uFlags
)
2302 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n", this, pidl
, uFlags
);
2304 i
= LV_FindItemByPidl(pidl
);
2308 if(uFlags
& SVSI_ENSUREVISIBLE
)
2309 m_ListView
.EnsureVisible(i
, FALSE
);
2311 LVITEMW lvItem
= {0};
2312 lvItem
.mask
= LVIF_STATE
;
2313 lvItem
.stateMask
= LVIS_SELECTED
| LVIS_FOCUSED
;
2315 while (m_ListView
.GetItem(&lvItem
))
2317 if (lvItem
.iItem
== i
)
2319 if (uFlags
& SVSI_SELECT
)
2320 lvItem
.state
|= LVIS_SELECTED
;
2322 lvItem
.state
&= ~LVIS_SELECTED
;
2324 if (uFlags
& SVSI_FOCUSED
)
2325 lvItem
.state
&= ~LVIS_FOCUSED
;
2329 if (uFlags
& SVSI_DESELECTOTHERS
)
2330 lvItem
.state
&= ~LVIS_SELECTED
;
2333 m_ListView
.SetItem(&lvItem
);
2337 if(uFlags
& SVSI_EDIT
)
2338 m_ListView
.EditLabel(i
);
2343 HRESULT WINAPI
CDefView::GetItemObject(UINT uItem
, REFIID riid
, LPVOID
*ppvOut
)
2345 HRESULT hr
= E_NOINTERFACE
;
2347 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n", this, uItem
, debugstr_guid(&riid
), ppvOut
);
2353 case SVGIO_BACKGROUND
:
2354 if (IsEqualIID(riid
, IID_IContextMenu
))
2356 //*ppvOut = ISvBgCm_Constructor(m_pSFParent, FALSE);
2361 hr
= CDefFolderMenu_Create2(NULL
, NULL
, 0, NULL
, m_pSFParent
, NULL
, 0, NULL
, &pcm
);
2368 case SVGIO_SELECTION
:
2370 hr
= m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, riid
, 0, ppvOut
);
2374 TRACE("-- (%p)->(interface=%p)\n", this, *ppvOut
);
2379 HRESULT STDMETHODCALLTYPE
CDefView::GetCurrentViewMode(UINT
*pViewMode
)
2381 TRACE("(%p)->(%p), stub\n", this, pViewMode
);
2384 return E_INVALIDARG
;
2386 *pViewMode
= m_FolderSettings
.ViewMode
;
2390 HRESULT STDMETHODCALLTYPE
CDefView::SetCurrentViewMode(UINT ViewMode
)
2393 TRACE("(%p)->(%u), stub\n", this, ViewMode
);
2395 /* It's not redundant to check FVM_AUTO because it's a (UINT)-1 */
2396 if (((INT
)ViewMode
< FVM_FIRST
|| (INT
)ViewMode
> FVM_LAST
) && ((INT
)ViewMode
!= FVM_AUTO
))
2397 return E_INVALIDARG
;
2399 /* Windows before Vista uses LVM_SETVIEW and possibly
2400 LVM_SETEXTENDEDLISTVIEWSTYLE to set the style of the listview,
2401 while later versions seem to accomplish this through other
2409 dwStyle
= LVS_REPORT
;
2412 dwStyle
= LVS_SMALLICON
;
2419 FIXME("ViewMode %d not implemented\n", ViewMode
);
2425 SetStyle(dwStyle
, LVS_TYPEMASK
);
2427 /* This will not necessarily be the actual mode set above.
2428 This mimics the behavior of Windows XP. */
2429 m_FolderSettings
.ViewMode
= ViewMode
;
2434 HRESULT STDMETHODCALLTYPE
CDefView::GetFolder(REFIID riid
, void **ppv
)
2436 if (m_pSFParent
== NULL
)
2439 return m_pSFParent
->QueryInterface(riid
, ppv
);
2442 HRESULT STDMETHODCALLTYPE
CDefView::Item(int iItemIndex
, PITEMID_CHILD
*ppidl
)
2444 PCUITEMID_CHILD pidl
= _PidlByItem(iItemIndex
);
2447 *ppidl
= ILClone(pidl
);
2452 return E_INVALIDARG
;
2455 HRESULT STDMETHODCALLTYPE
CDefView::ItemCount(UINT uFlags
, int *pcItems
)
2457 TRACE("(%p)->(%u %p)\n", this, uFlags
, pcItems
);
2459 if (uFlags
!= SVGIO_ALLVIEW
)
2460 FIXME("some flags unsupported, %x\n", uFlags
& ~SVGIO_ALLVIEW
);
2462 *pcItems
= m_ListView
.GetItemCount();
2467 HRESULT STDMETHODCALLTYPE
CDefView::Items(UINT uFlags
, REFIID riid
, void **ppv
)
2472 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectionMarkedItem(int *piItem
)
2474 TRACE("(%p)->(%p)\n", this, piItem
);
2476 *piItem
= m_ListView
.GetSelectionMark();
2481 HRESULT STDMETHODCALLTYPE
CDefView::GetFocusedItem(int *piItem
)
2483 TRACE("(%p)->(%p)\n", this, piItem
);
2485 *piItem
= m_ListView
.GetNextItem(-1, LVNI_FOCUSED
);
2490 HRESULT STDMETHODCALLTYPE
CDefView::GetItemPosition(PCUITEMID_CHILD pidl
, POINT
*ppt
)
2495 HRESULT STDMETHODCALLTYPE
CDefView::GetSpacing(POINT
*ppt
)
2497 TRACE("(%p)->(%p)\n", this, ppt
);
2505 m_ListView
.GetItemSpacing(spacing
);
2507 ppt
->x
= spacing
.cx
;
2508 ppt
->y
= spacing
.cy
;
2514 HRESULT STDMETHODCALLTYPE
CDefView::GetDefaultSpacing(POINT
*ppt
)
2519 HRESULT STDMETHODCALLTYPE
CDefView::GetAutoArrange()
2524 HRESULT STDMETHODCALLTYPE
CDefView::SelectItem(int iItem
, DWORD dwFlags
)
2528 TRACE("(%p)->(%d, %x)\n", this, iItem
, dwFlags
);
2531 lvItem
.stateMask
= LVIS_SELECTED
;
2533 if (dwFlags
& SVSI_ENSUREVISIBLE
)
2534 m_ListView
.EnsureVisible(iItem
, 0);
2537 if (dwFlags
& SVSI_DESELECTOTHERS
)
2538 m_ListView
.SetItemState(-1, 0, LVIS_SELECTED
);
2541 if (dwFlags
& SVSI_SELECT
)
2542 lvItem
.state
|= LVIS_SELECTED
;
2544 if (dwFlags
& SVSI_FOCUSED
)
2545 lvItem
.stateMask
|= LVIS_FOCUSED
;
2547 m_ListView
.SetItemState(iItem
, lvItem
.state
, lvItem
.stateMask
);
2549 if (dwFlags
& SVSI_EDIT
)
2550 m_ListView
.EditLabel(iItem
);
2555 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItems(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD dwFlags
)
2560 /**********************************************************
2561 * IShellFolderView implementation
2563 HRESULT STDMETHODCALLTYPE
CDefView::Rearrange(LPARAM sort
)
2565 FIXME("(%p)->(%ld) stub\n", this, sort
);
2569 HRESULT STDMETHODCALLTYPE
CDefView::GetArrangeParam(LPARAM
*sort
)
2571 FIXME("(%p)->(%p) stub\n", this, sort
);
2575 HRESULT STDMETHODCALLTYPE
CDefView::ArrangeGrid()
2577 FIXME("(%p) stub\n", this);
2581 HRESULT STDMETHODCALLTYPE
CDefView::AutoArrange()
2583 FIXME("(%p) stub\n", this);
2587 HRESULT STDMETHODCALLTYPE
CDefView::AddObject(PITEMID_CHILD pidl
, UINT
*item
)
2589 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2593 HRESULT STDMETHODCALLTYPE
CDefView::GetObject(PITEMID_CHILD
*pidl
, UINT item
)
2595 TRACE("(%p)->(%p %d)\n", this, pidl
, item
);
2596 return Item(item
, pidl
);
2599 HRESULT STDMETHODCALLTYPE
CDefView::RemoveObject(PITEMID_CHILD pidl
, UINT
*item
)
2602 TRACE("(%p)->(%p %p)\n", this, pidl
, item
);
2606 *item
= LV_FindItemByPidl(ILFindLastID(pidl
));
2607 m_ListView
.DeleteItem(*item
);
2612 m_ListView
.DeleteAllItems();
2618 HRESULT STDMETHODCALLTYPE
CDefView::GetObjectCount(UINT
*count
)
2620 TRACE("(%p)->(%p)\n", this, count
);
2621 *count
= m_ListView
.GetItemCount();
2625 HRESULT STDMETHODCALLTYPE
CDefView::SetObjectCount(UINT count
, UINT flags
)
2627 FIXME("(%p)->(%d %x) stub\n", this, count
, flags
);
2631 HRESULT STDMETHODCALLTYPE
CDefView::UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
)
2633 FIXME("(%p)->(%p %p %p) stub\n", this, pidl_old
, pidl_new
, item
);
2637 HRESULT STDMETHODCALLTYPE
CDefView::RefreshObject(PITEMID_CHILD pidl
, UINT
*item
)
2639 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2643 HRESULT STDMETHODCALLTYPE
CDefView::SetRedraw(BOOL redraw
)
2645 TRACE("(%p)->(%d)\n", this, redraw
);
2646 m_ListView
.SetRedraw(redraw
);
2650 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedCount(UINT
*count
)
2652 FIXME("(%p)->(%p) stub\n", this, count
);
2656 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
)
2658 TRACE("(%p)->(%p %p)\n", this, pidl
, items
);
2660 *items
= GetSelections();
2664 *pidl
= static_cast<PCUITEMID_CHILD
*>(LocalAlloc(0, *items
* sizeof(PCUITEMID_CHILD
)));
2667 return E_OUTOFMEMORY
;
2670 /* it's documented that caller shouldn't PIDLs, only array itself */
2671 memcpy(*pidl
, m_apidl
, *items
* sizeof(PCUITEMID_CHILD
));
2677 HRESULT STDMETHODCALLTYPE
CDefView::IsDropOnSource(IDropTarget
*drop_target
)
2679 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2683 HRESULT STDMETHODCALLTYPE
CDefView::GetDragPoint(POINT
*pt
)
2685 FIXME("(%p)->(%p) stub\n", this, pt
);
2689 HRESULT STDMETHODCALLTYPE
CDefView::GetDropPoint(POINT
*pt
)
2691 FIXME("(%p)->(%p) stub\n", this, pt
);
2695 HRESULT STDMETHODCALLTYPE
CDefView::MoveIcons(IDataObject
*obj
)
2697 TRACE("(%p)->(%p)\n", this, obj
);
2701 HRESULT STDMETHODCALLTYPE
CDefView::SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
)
2703 FIXME("(%p)->(%p %p) stub\n", this, pidl
, pt
);
2707 HRESULT STDMETHODCALLTYPE
CDefView::IsBkDropTarget(IDropTarget
*drop_target
)
2709 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2713 HRESULT STDMETHODCALLTYPE
CDefView::SetClipboard(BOOL move
)
2715 FIXME("(%p)->(%d) stub\n", this, move
);
2719 HRESULT STDMETHODCALLTYPE
CDefView::SetPoints(IDataObject
*obj
)
2721 FIXME("(%p)->(%p) stub\n", this, obj
);
2725 HRESULT STDMETHODCALLTYPE
CDefView::GetItemSpacing(ITEMSPACING
*spacing
)
2727 FIXME("(%p)->(%p) stub\n", this, spacing
);
2731 HRESULT STDMETHODCALLTYPE
CDefView::SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
)
2733 FIXME("(%p)->(%p %p) stub\n", this, new_cb
, old_cb
);
2737 HRESULT STDMETHODCALLTYPE
CDefView::Select(UINT flags
)
2739 FIXME("(%p)->(%d) stub\n", this, flags
);
2743 HRESULT STDMETHODCALLTYPE
CDefView::QuerySupport(UINT
*support
)
2745 TRACE("(%p)->(%p)\n", this, support
);
2749 HRESULT STDMETHODCALLTYPE
CDefView::SetAutomationObject(IDispatch
*disp
)
2751 FIXME("(%p)->(%p) stub\n", this, disp
);
2755 /**********************************************************
2756 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2758 HRESULT WINAPI
CDefView::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD
*prgCmds
, OLECMDTEXT
*pCmdText
)
2760 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
2761 this, pguidCmdGroup
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
2764 return E_INVALIDARG
;
2766 for (UINT i
= 0; i
< cCmds
; i
++)
2768 FIXME("\tprgCmds[%d].cmdID = %d\n", i
, prgCmds
[i
].cmdID
);
2769 prgCmds
[i
].cmdf
= 0;
2772 return OLECMDERR_E_UNKNOWNGROUP
;
2775 /**********************************************************
2776 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2778 * nCmdID is the OLECMDID_* enumeration
2780 HRESULT WINAPI
CDefView::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
2782 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2783 this, debugstr_guid(pguidCmdGroup
), nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2786 return OLECMDERR_E_UNKNOWNGROUP
;
2788 if (IsEqualCLSID(*pguidCmdGroup
, m_Category
))
2790 if (nCmdID
== FCIDM_SHVIEW_AUTOARRANGE
)
2792 if (V_VT(pvaIn
) != VT_INT_PTR
)
2793 return OLECMDERR_E_NOTSUPPORTED
;
2797 params
.cbSize
= sizeof(params
);
2798 params
.rcExclude
= *(RECT
*) V_INTREF(pvaIn
);
2800 HMENU hView
= m_hView
;
2802 hView
= CreatePopupMenu();
2803 AppendMenuW(hView
, MF_STRING
, FCIDM_SHVIEW_BIGICON
, L
"Big!");
2804 AppendMenuW(hView
, MF_STRING
, FCIDM_SHVIEW_SMALLICON
, L
"Small!");
2805 AppendMenuW(hView
, MF_STRING
, FCIDM_SHVIEW_LISTVIEW
, L
"List!");
2806 AppendMenuW(hView
, MF_STRING
, FCIDM_SHVIEW_REPORTVIEW
, L
"Report!");
2811 PrepareShowViewMenu(hView
);
2813 TrackPopupMenuEx(hView
, TPM_LEFTALIGN
| TPM_TOPALIGN
, params
.rcExclude
.left
, params
.rcExclude
.bottom
, m_hWndParent
, ¶ms
);
2816 // pvaOut is VT_I4 with value 0x403 (cmd id of the new mode maybe?)
2817 V_VT(pvaOut
) = VT_I4
;
2818 V_I4(pvaOut
) = 0x403;
2822 if (IsEqualIID(*pguidCmdGroup
, CGID_Explorer
) &&
2824 (nCmdexecopt
== 4) && pvaOut
)
2827 if (IsEqualIID(*pguidCmdGroup
, CGID_ShellDocView
) &&
2832 return OLECMDERR_E_UNKNOWNGROUP
;
2835 /**********************************************************
2836 * ISVDropTarget implementation
2839 /******************************************************************************
2840 * drag_notify_subitem [Internal]
2842 * Figure out the shellfolder object, which is currently under the mouse cursor
2843 * and notify it via the IDropTarget interface.
2846 #define SCROLLAREAWIDTH 20
2848 HRESULT
CDefView::drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2850 LVHITTESTINFO htinfo
;
2855 /* Map from global to client coordinates and query the index of the listview-item, which is
2856 * currently under the mouse cursor. */
2859 htinfo
.flags
= LVHT_ONITEM
;
2860 ::ScreenToClient(m_ListView
, &htinfo
.pt
);
2861 lResult
= m_ListView
.HitTest(&htinfo
);
2863 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2864 ::GetClientRect(m_ListView
, &clientRect
);
2865 if (htinfo
.pt
.x
== m_ptLastMousePos
.x
&& htinfo
.pt
.y
== m_ptLastMousePos
.y
&&
2866 (htinfo
.pt
.x
< SCROLLAREAWIDTH
|| htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
||
2867 htinfo
.pt
.y
< SCROLLAREAWIDTH
|| htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
))
2869 m_cScrollDelay
= (m_cScrollDelay
+ 1) % 5; /* DragOver is called every 50 ms */
2870 if (m_cScrollDelay
== 0)
2872 /* Mouse did hover another 250 ms over the scroll-area */
2873 if (htinfo
.pt
.x
< SCROLLAREAWIDTH
)
2874 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEUP
, 0);
2876 if (htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
)
2877 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEDOWN
, 0);
2879 if (htinfo
.pt
.y
< SCROLLAREAWIDTH
)
2880 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEUP
, 0);
2882 if (htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
)
2883 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEDOWN
, 0);
2888 m_cScrollDelay
= 0; /* Reset, if the cursor is not over the listview's scroll-area */
2891 m_ptLastMousePos
= htinfo
.pt
;
2893 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2894 if (m_pCurDropTarget
&& lResult
== m_iDragOverItem
)
2895 return m_pCurDropTarget
->DragOver(grfKeyState
, pt
, pdwEffect
);
2897 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2898 if (m_pCurDropTarget
)
2900 m_pCurDropTarget
->DragLeave();
2901 m_pCurDropTarget
.Release();
2904 m_iDragOverItem
= lResult
;
2907 /* We are not above one of the listview's subitems. Bind to the parent folder's
2908 * DropTarget interface. */
2909 hr
= m_pSFParent
->QueryInterface(IID_PPV_ARG(IDropTarget
,&m_pCurDropTarget
));
2913 /* Query the relative PIDL of the shellfolder object represented by the currently
2914 * dragged over listview-item ... */
2915 PCUITEMID_CHILD pidl
= _PidlByItem(lResult
);
2917 /* ... and bind m_pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2918 hr
= m_pSFParent
->GetUIObjectOf(m_ListView
, 1, &pidl
, IID_NULL_PPV_ARG(IDropTarget
, &m_pCurDropTarget
));
2921 /* If anything failed, m_pCurDropTarget should be NULL now, which ought to be a save state. */
2925 /* Notify the item just entered via DragEnter. */
2926 return m_pCurDropTarget
->DragEnter(m_pCurDataObject
, grfKeyState
, pt
, pdwEffect
);
2929 HRESULT WINAPI
CDefView::DragEnter(IDataObject
*pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2931 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2932 m_pCurDataObject
= pDataObject
;
2933 pDataObject
->AddRef();
2935 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2938 HRESULT WINAPI
CDefView::DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2940 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2943 HRESULT WINAPI
CDefView::DragLeave()
2945 if (m_pCurDropTarget
)
2947 m_pCurDropTarget
->DragLeave();
2948 m_pCurDropTarget
.Release();
2951 if (m_pCurDataObject
!= NULL
)
2953 m_pCurDataObject
.Release();
2956 m_iDragOverItem
= 0;
2961 HRESULT WINAPI
CDefView::Drop(IDataObject
* pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2963 if (m_pCurDropTarget
)
2965 m_pCurDropTarget
->Drop(pDataObject
, grfKeyState
, pt
, pdwEffect
);
2966 m_pCurDropTarget
.Release();
2969 m_pCurDataObject
.Release();
2970 m_iDragOverItem
= 0;
2974 /**********************************************************
2975 * ISVDropSource implementation
2978 HRESULT WINAPI
CDefView::QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
)
2980 TRACE("(%p)\n", this);
2983 return DRAGDROP_S_CANCEL
;
2984 else if (!(grfKeyState
& MK_LBUTTON
) && !(grfKeyState
& MK_RBUTTON
))
2985 return DRAGDROP_S_DROP
;
2990 HRESULT WINAPI
CDefView::GiveFeedback(DWORD dwEffect
)
2992 TRACE("(%p)\n", this);
2994 return DRAGDROP_S_USEDEFAULTCURSORS
;
2997 /**********************************************************
2998 * ISVViewObject implementation
3001 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
)
3003 FIXME("Stub: this=%p\n", this);
3008 HRESULT WINAPI
CDefView::GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
, HDC hicTargetDevice
, LOGPALETTE
**ppColorSet
)
3010 FIXME("Stub: this=%p\n", this);
3015 HRESULT WINAPI
CDefView::Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
)
3017 FIXME("Stub: this=%p\n", this);
3022 HRESULT WINAPI
CDefView::Unfreeze(DWORD dwFreeze
)
3024 FIXME("Stub: this=%p\n", this);
3029 HRESULT WINAPI
CDefView::SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
)
3031 FIXME("partial stub: %p %08x %08x %p\n", this, aspects
, advf
, pAdvSink
);
3033 /* FIXME: we set the AdviseSink, but never use it to send any advice */
3034 m_pAdvSink
= pAdvSink
;
3035 m_dwAspects
= aspects
;
3041 HRESULT WINAPI
CDefView::GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
)
3043 TRACE("this=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n", this, pAspects
, pAdvf
, ppAdvSink
);
3047 *ppAdvSink
= m_pAdvSink
;
3048 m_pAdvSink
.p
->AddRef();
3052 *pAspects
= m_dwAspects
;
3060 HRESULT STDMETHODCALLTYPE
CDefView::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
3062 if (IsEqualIID(guidService
, SID_IShellBrowser
))
3063 return m_pShellBrowser
->QueryInterface(riid
, ppvObject
);
3064 else if(IsEqualIID(guidService
, SID_IFolderView
))
3065 return QueryInterface(riid
, ppvObject
);
3067 return E_NOINTERFACE
;
3070 HRESULT
CDefView::_MergeToolbar()
3072 CComPtr
<IExplorerToolbar
> ptb
; // [sp+8h] [bp-4h]@1
3076 hr
= IUnknown_QueryService(m_pShellBrowser
, IID_IExplorerToolbar
, IID_PPV_ARG(IExplorerToolbar
, &ptb
));
3080 m_Category
= CGID_DefViewFrame
;
3082 hr
= ptb
->SetCommandTarget(static_cast<IOleCommandTarget
*>(this), &m_Category
, 0);
3090 hr
= ptb
->AddButtons(&m_Category
, buttonsCount
, buttons
);
3097 /**********************************************************
3098 * IShellView_Constructor
3100 HRESULT WINAPI
IShellView_Constructor(IShellFolder
*pFolder
, IShellView
**newView
)
3102 return ShellObjectCreatorInit
<CDefView
>(pFolder
, IID_IShellView
, newView
);