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
*m_apidl
;
96 PIDLIST_ABSOLUTE m_pidlParent
;
97 LISTVIEW_SORT_INFO m_sortInfo
;
98 ULONG m_hNotify
; /* change notification handle */
102 CComPtr
<IAdviseSink
> m_pAdvSink
;
104 CComPtr
<IDropTarget
> m_pCurDropTarget
; /* The sub-item, which is currently dragged over */
105 CComPtr
<IDataObject
> m_pCurDataObject
; /* The dragged data-object */
106 LONG m_iDragOverItem
; /* Dragged over item's index, iff m_pCurDropTarget != NULL */
107 UINT m_cScrollDelay
; /* Send a WM_*SCROLL msg every 250 ms during drag-scroll */
108 POINT m_ptLastMousePos
; /* Mouse position at last DragOver call */
110 CComPtr
<IContextMenu
> m_pCM
;
119 HRESULT
_MergeToolbar();
124 HRESULT WINAPI
Initialize(IShellFolder
*shellFolder
);
125 HRESULT
IncludeObject(PCUITEMID_CHILD pidl
);
126 HRESULT
OnDefaultCommand();
127 HRESULT
OnStateChange(UINT uFlags
);
128 void UpdateStatusbar();
130 void SetStyle(DWORD dwAdd
, DWORD dwRemove
);
132 void UpdateListColors();
134 static INT CALLBACK
CompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
);
135 static INT CALLBACK
ListViewCompareItems(LPARAM lParam1
, LPARAM lParam2
, LPARAM lpData
);
137 PCUITEMID_CHILD
_PidlByItem(int i
);
138 PCUITEMID_CHILD
_PidlByItem(LVITEM
& lvItem
);
139 int LV_FindItemByPidl(PCUITEMID_CHILD pidl
);
140 BOOLEAN
LV_AddItem(PCUITEMID_CHILD pidl
);
141 BOOLEAN
LV_DeleteItem(PCUITEMID_CHILD pidl
);
142 BOOLEAN
LV_RenameItem(PCUITEMID_CHILD pidlOld
, PCUITEMID_CHILD pidlNew
);
143 BOOLEAN
LV_ProdItem(PCUITEMID_CHILD pidl
);
144 static INT CALLBACK
fill_list(LPVOID ptr
, LPVOID arg
);
146 HMENU
BuildFileMenu();
147 void PrepareShowFileMenu(HMENU hSubMenu
);
148 void PrepareShowViewMenu(HMENU hSubMenu
);
149 UINT
GetSelections();
150 HRESULT
OpenSelectedItems();
152 void DoActivate(UINT uState
);
153 HRESULT
drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
154 HRESULT
InvokeContextMenuCommand(UINT uCommand
);
155 LRESULT
OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
);
157 // *** IOleWindow methods ***
158 virtual HRESULT STDMETHODCALLTYPE
GetWindow(HWND
*lphwnd
);
159 virtual HRESULT STDMETHODCALLTYPE
ContextSensitiveHelp(BOOL fEnterMode
);
161 // *** IShellView methods ***
162 virtual HRESULT STDMETHODCALLTYPE
TranslateAccelerator(MSG
*pmsg
);
163 virtual HRESULT STDMETHODCALLTYPE
EnableModeless(BOOL fEnable
);
164 virtual HRESULT STDMETHODCALLTYPE
UIActivate(UINT uState
);
165 virtual HRESULT STDMETHODCALLTYPE
Refresh();
166 virtual HRESULT STDMETHODCALLTYPE
CreateViewWindow(IShellView
*psvPrevious
, LPCFOLDERSETTINGS pfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
);
167 virtual HRESULT STDMETHODCALLTYPE
DestroyViewWindow();
168 virtual HRESULT STDMETHODCALLTYPE
GetCurrentInfo(LPFOLDERSETTINGS pfs
);
169 virtual HRESULT STDMETHODCALLTYPE
AddPropertySheetPages(DWORD dwReserved
, LPFNSVADDPROPSHEETPAGE pfn
, LPARAM lparam
);
170 virtual HRESULT STDMETHODCALLTYPE
SaveViewState();
171 virtual HRESULT STDMETHODCALLTYPE
SelectItem(PCUITEMID_CHILD pidlItem
, SVSIF uFlags
);
172 virtual HRESULT STDMETHODCALLTYPE
GetItemObject(UINT uItem
, REFIID riid
, void **ppv
);
174 // *** IFolderView methods ***
175 virtual HRESULT STDMETHODCALLTYPE
GetCurrentViewMode(UINT
*pViewMode
);
176 virtual HRESULT STDMETHODCALLTYPE
SetCurrentViewMode(UINT ViewMode
);
177 virtual HRESULT STDMETHODCALLTYPE
GetFolder(REFIID riid
, void **ppv
);
178 virtual HRESULT STDMETHODCALLTYPE
Item(int iItemIndex
, PITEMID_CHILD
*ppidl
);
179 virtual HRESULT STDMETHODCALLTYPE
ItemCount(UINT uFlags
, int *pcItems
);
180 virtual HRESULT STDMETHODCALLTYPE
Items(UINT uFlags
, REFIID riid
, void **ppv
);
181 virtual HRESULT STDMETHODCALLTYPE
GetSelectionMarkedItem(int *piItem
);
182 virtual HRESULT STDMETHODCALLTYPE
GetFocusedItem(int *piItem
);
183 virtual HRESULT STDMETHODCALLTYPE
GetItemPosition(PCUITEMID_CHILD pidl
, POINT
*ppt
);
184 virtual HRESULT STDMETHODCALLTYPE
GetSpacing(POINT
*ppt
);
185 virtual HRESULT STDMETHODCALLTYPE
GetDefaultSpacing(POINT
*ppt
);
186 virtual HRESULT STDMETHODCALLTYPE
GetAutoArrange();
187 virtual HRESULT STDMETHODCALLTYPE
SelectItem(int iItem
, DWORD dwFlags
);
188 virtual HRESULT STDMETHODCALLTYPE
SelectAndPositionItems(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD dwFlags
);
190 // *** IShellFolderView methods ***
191 virtual HRESULT STDMETHODCALLTYPE
Rearrange(LPARAM sort
);
192 virtual HRESULT STDMETHODCALLTYPE
GetArrangeParam(LPARAM
*sort
);
193 virtual HRESULT STDMETHODCALLTYPE
ArrangeGrid();
194 virtual HRESULT STDMETHODCALLTYPE
AutoArrange();
195 virtual HRESULT STDMETHODCALLTYPE
AddObject(PITEMID_CHILD pidl
, UINT
*item
);
196 virtual HRESULT STDMETHODCALLTYPE
GetObject(PITEMID_CHILD
*pidl
, UINT item
);
197 virtual HRESULT STDMETHODCALLTYPE
RemoveObject(PITEMID_CHILD pidl
, UINT
*item
);
198 virtual HRESULT STDMETHODCALLTYPE
GetObjectCount(UINT
*count
);
199 virtual HRESULT STDMETHODCALLTYPE
SetObjectCount(UINT count
, UINT flags
);
200 virtual HRESULT STDMETHODCALLTYPE
UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
);
201 virtual HRESULT STDMETHODCALLTYPE
RefreshObject(PITEMID_CHILD pidl
, UINT
*item
);
202 virtual HRESULT STDMETHODCALLTYPE
SetRedraw(BOOL redraw
);
203 virtual HRESULT STDMETHODCALLTYPE
GetSelectedCount(UINT
*count
);
204 virtual HRESULT STDMETHODCALLTYPE
GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
);
205 virtual HRESULT STDMETHODCALLTYPE
IsDropOnSource(IDropTarget
*drop_target
);
206 virtual HRESULT STDMETHODCALLTYPE
GetDragPoint(POINT
*pt
);
207 virtual HRESULT STDMETHODCALLTYPE
GetDropPoint(POINT
*pt
);
208 virtual HRESULT STDMETHODCALLTYPE
MoveIcons(IDataObject
*obj
);
209 virtual HRESULT STDMETHODCALLTYPE
SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
);
210 virtual HRESULT STDMETHODCALLTYPE
IsBkDropTarget(IDropTarget
*drop_target
);
211 virtual HRESULT STDMETHODCALLTYPE
SetClipboard(BOOL move
);
212 virtual HRESULT STDMETHODCALLTYPE
SetPoints(IDataObject
*obj
);
213 virtual HRESULT STDMETHODCALLTYPE
GetItemSpacing(ITEMSPACING
*spacing
);
214 virtual HRESULT STDMETHODCALLTYPE
SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
);
215 virtual HRESULT STDMETHODCALLTYPE
Select(UINT flags
);
216 virtual HRESULT STDMETHODCALLTYPE
QuerySupport(UINT
*support
);
217 virtual HRESULT STDMETHODCALLTYPE
SetAutomationObject(IDispatch
*disp
);
219 // *** IOleCommandTarget methods ***
220 virtual HRESULT STDMETHODCALLTYPE
QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
);
221 virtual HRESULT STDMETHODCALLTYPE
Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
);
223 // *** IDropTarget methods ***
224 virtual HRESULT STDMETHODCALLTYPE
DragEnter(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
225 virtual HRESULT STDMETHODCALLTYPE
DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
226 virtual HRESULT STDMETHODCALLTYPE
DragLeave();
227 virtual HRESULT STDMETHODCALLTYPE
Drop(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
229 // *** IDropSource methods ***
230 virtual HRESULT STDMETHODCALLTYPE
QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
);
231 virtual HRESULT STDMETHODCALLTYPE
GiveFeedback(DWORD dwEffect
);
233 // *** IViewObject methods ***
234 virtual HRESULT STDMETHODCALLTYPE
Draw(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
,
235 HDC hdcTargetDev
, HDC hdcDraw
, LPCRECTL lprcBounds
, LPCRECTL lprcWBounds
,
236 BOOL ( STDMETHODCALLTYPE
*pfnContinue
)(ULONG_PTR dwContinue
), ULONG_PTR dwContinue
);
237 virtual HRESULT STDMETHODCALLTYPE
GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
,
238 DVTARGETDEVICE
*ptd
, HDC hicTargetDev
, LOGPALETTE
**ppColorSet
);
239 virtual HRESULT STDMETHODCALLTYPE
Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
);
240 virtual HRESULT STDMETHODCALLTYPE
Unfreeze(DWORD dwFreeze
);
241 virtual HRESULT STDMETHODCALLTYPE
SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
);
242 virtual HRESULT STDMETHODCALLTYPE
GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
);
244 // *** IServiceProvider methods ***
245 virtual HRESULT STDMETHODCALLTYPE
QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
);
248 LRESULT
OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
249 LRESULT
OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
250 LRESULT
OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
251 LRESULT
OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
252 LRESULT
OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
253 LRESULT
OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
254 LRESULT
OnNCCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
255 LRESULT
OnNCDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
256 LRESULT
OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
257 LRESULT
OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
258 LRESULT
OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
259 LRESULT
OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
260 LRESULT
OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
261 LRESULT
OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
262 LRESULT
OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
263 LRESULT
OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
264 LRESULT
OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
265 LRESULT
OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
266 LRESULT
OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
267 LRESULT
OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
269 static ATL::CWndClassInfo
& GetWndClassInfo()
271 static ATL::CWndClassInfo wc
=
273 { sizeof(WNDCLASSEX
), 0, StartWindowProc
,
275 LoadCursor(NULL
, IDC_ARROW
), (HBRUSH
)(COLOR_BACKGROUND
+ 1), NULL
, SV_CLASS_NAME
, NULL
277 NULL
, NULL
, IDC_ARROW
, TRUE
, 0, _T("")
282 virtual WNDPROC
GetWindowProc()
287 static LRESULT CALLBACK
WindowProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
292 // must hold a reference during message handling
293 pThis
= reinterpret_cast<CDefView
*>(hWnd
);
295 result
= CWindowImpl
<CDefView
, CWindow
, CControlWinTraits
>::WindowProc(hWnd
, uMsg
, wParam
, lParam
);
300 BEGIN_MSG_MAP(CDefView
)
301 MESSAGE_HANDLER(WM_SIZE
, OnSize
)
302 MESSAGE_HANDLER(WM_SETFOCUS
, OnSetFocus
)
303 MESSAGE_HANDLER(WM_KILLFOCUS
, OnKillFocus
)
304 MESSAGE_HANDLER(WM_NCCREATE
, OnNCCreate
)
305 MESSAGE_HANDLER(WM_NCDESTROY
, OnNCDestroy
)
306 MESSAGE_HANDLER(WM_CREATE
, OnCreate
)
307 MESSAGE_HANDLER(WM_ACTIVATE
, OnActivate
)
308 MESSAGE_HANDLER(WM_NOTIFY
, OnNotify
)
309 MESSAGE_HANDLER(WM_COMMAND
, OnCommand
)
310 MESSAGE_HANDLER(SHV_CHANGE_NOTIFY
, OnChangeNotify
)
311 MESSAGE_HANDLER(WM_CONTEXTMENU
, OnContextMenu
)
312 MESSAGE_HANDLER(WM_DRAWITEM
, OnCustomItem
)
313 MESSAGE_HANDLER(WM_MEASUREITEM
, OnCustomItem
)
314 MESSAGE_HANDLER(WM_SHOWWINDOW
, OnShowWindow
)
315 MESSAGE_HANDLER(WM_GETDLGCODE
, OnGetDlgCode
)
316 MESSAGE_HANDLER(WM_DESTROY
, OnDestroy
)
317 MESSAGE_HANDLER(WM_ERASEBKGND
, OnEraseBackground
)
318 MESSAGE_HANDLER(WM_SYSCOLORCHANGE
, OnSysColorChange
)
319 MESSAGE_HANDLER(CWM_GETISHELLBROWSER
, OnGetShellBrowser
)
320 MESSAGE_HANDLER(WM_SETTINGCHANGE
, OnSettingChange
)
321 MESSAGE_HANDLER(WM_INITMENUPOPUP
, OnInitMenuPopup
)
324 BEGIN_COM_MAP(CDefView
)
325 // Windows returns E_NOINTERFACE for IOleWindow
326 // COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IOleWindow)
327 COM_INTERFACE_ENTRY_IID(IID_IShellView
, IShellView
)
328 COM_INTERFACE_ENTRY_IID(IID_IFolderView
, IFolderView
)
329 COM_INTERFACE_ENTRY_IID(IID_IShellFolderView
, IShellFolderView
)
330 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget
, IOleCommandTarget
)
331 COM_INTERFACE_ENTRY_IID(IID_IDropTarget
, IDropTarget
)
332 COM_INTERFACE_ENTRY_IID(IID_IDropSource
, IDropSource
)
333 COM_INTERFACE_ENTRY_IID(IID_IViewObject
, IViewObject
)
334 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider
, IServiceProvider
)
338 /* ListView Header ID's */
339 #define LISTVIEW_COLUMN_NAME 0
340 #define LISTVIEW_COLUMN_SIZE 1
341 #define LISTVIEW_COLUMN_TYPE 2
342 #define LISTVIEW_COLUMN_TIME 3
343 #define LISTVIEW_COLUMN_ATTRIB 4
346 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
347 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
348 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
350 #define ID_LISTVIEW 1
353 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
354 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
355 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
357 typedef void (CALLBACK
*PFNSHGETSETTINGSPROC
)(LPSHELLFLAGSTATE lpsfs
, DWORD dwMask
);
359 CDefView::CDefView() :
363 m_menusLoaded(FALSE
),
378 ZeroMemory(&m_FolderSettings
, sizeof(m_FolderSettings
));
379 ZeroMemory(&m_sortInfo
, sizeof(m_sortInfo
));
380 ZeroMemory(&m_ptLastMousePos
, sizeof(m_ptLastMousePos
));
381 ZeroMemory(&m_Category
, sizeof(m_Category
));
384 CDefView::~CDefView()
386 TRACE(" destroying IShellView(%p)\n", this);
396 HRESULT WINAPI
CDefView::Initialize(IShellFolder
*shellFolder
)
398 m_pSFParent
= shellFolder
;
399 shellFolder
->QueryInterface(IID_PPV_ARG(IShellFolder2
, &m_pSF2Parent
));
404 /**********************************************************
406 * ##### helperfunctions for communication with ICommDlgBrowser #####
408 HRESULT
CDefView::IncludeObject(PCUITEMID_CHILD pidl
)
412 if (m_pCommDlgBrowser
.p
!= NULL
)
414 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl
);
415 ret
= m_pCommDlgBrowser
->IncludeObject(this, pidl
);
416 TRACE("--0x%08x\n", ret
);
422 HRESULT
CDefView::OnDefaultCommand()
424 HRESULT ret
= S_FALSE
;
426 if (m_pCommDlgBrowser
.p
!= NULL
)
428 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
429 ret
= m_pCommDlgBrowser
->OnDefaultCommand(this);
430 TRACE("-- returns %08x\n", ret
);
436 HRESULT
CDefView::OnStateChange(UINT uFlags
)
438 HRESULT ret
= S_FALSE
;
440 if (m_pCommDlgBrowser
.p
!= NULL
)
442 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags
);
443 ret
= m_pCommDlgBrowser
->OnStateChange(this, uFlags
);
449 /**********************************************************
450 * set the toolbar of the filedialog buttons
452 * - activates the buttons from the shellbrowser according to
455 void CDefView::CheckToolbar()
461 if (m_pCommDlgBrowser
!= NULL
)
463 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
464 FCIDM_TB_SMALLICON
, (m_FolderSettings
.ViewMode
== FVM_LIST
) ? TRUE
: FALSE
, &result
);
465 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
466 FCIDM_TB_REPORTVIEW
, (m_FolderSettings
.ViewMode
== FVM_DETAILS
) ? TRUE
: FALSE
, &result
);
467 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
468 FCIDM_TB_SMALLICON
, TRUE
, &result
);
469 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
470 FCIDM_TB_REPORTVIEW
, TRUE
, &result
);
474 void CDefView::UpdateStatusbar()
476 WCHAR szFormat
[MAX_PATH
] = {0};
477 WCHAR szObjects
[MAX_PATH
] = {0};
480 cSelectedItems
= m_ListView
.GetSelectedCount();
483 LoadStringW(shell32_hInstance
, IDS_OBJECTS_SELECTED
, szFormat
, _countof(szFormat
));
484 StringCchPrintfW(szObjects
, MAX_PATH
, szFormat
, cSelectedItems
);
488 LoadStringW(shell32_hInstance
, IDS_OBJECTS
, szFormat
, _countof(szFormat
));
489 StringCchPrintfW(szObjects
, MAX_PATH
, szFormat
, m_ListView
.GetItemCount());
491 m_pShellBrowser
->SetStatusTextSB(szObjects
);
494 /**********************************************************
496 * ##### helperfunctions for initializing the view #####
498 /**********************************************************
499 * change the style of the listview control
501 void CDefView::SetStyle(DWORD dwAdd
, DWORD dwRemove
)
505 TRACE("(%p)\n", this);
507 tmpstyle
= ::GetWindowLongPtrW(m_ListView
, GWL_STYLE
);
508 ::SetWindowLongPtrW(m_ListView
, GWL_STYLE
, dwAdd
| (tmpstyle
& ~dwRemove
));
511 /**********************************************************
512 * ShellView_CreateList()
514 * - creates the list view window
516 BOOL
CDefView::CreateList()
517 { DWORD dwStyle
, dwExStyle
;
521 dwStyle
= WS_TABSTOP
| WS_VISIBLE
| WS_CHILDWINDOW
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
|
522 LVS_SHAREIMAGELISTS
| LVS_EDITLABELS
| LVS_AUTOARRANGE
;
523 dwExStyle
= WS_EX_CLIENTEDGE
;
525 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
526 dwStyle
|= LVS_ALIGNLEFT
;
528 dwStyle
|= LVS_ALIGNTOP
| LVS_SHOWSELALWAYS
;
530 switch (m_FolderSettings
.ViewMode
)
537 dwStyle
|= LVS_REPORT
;
541 dwStyle
|= LVS_SMALLICON
;
553 if (m_FolderSettings
.fFlags
& FWF_AUTOARRANGE
)
554 dwStyle
|= LVS_AUTOARRANGE
;
556 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
557 m_FolderSettings
.fFlags
|= FWF_NOCLIENTEDGE
| FWF_NOSCROLL
;
559 if (m_FolderSettings
.fFlags
& FWF_SINGLESEL
)
560 dwStyle
|= LVS_SINGLESEL
;
562 if (m_FolderSettings
.fFlags
& FWF_NOCLIENTEDGE
)
563 dwExStyle
&= ~WS_EX_CLIENTEDGE
;
565 RECT rcListView
= {0,0,0,0};
566 m_ListView
.Create(m_hWnd
, rcListView
, NULL
,dwStyle
, dwExStyle
, ID_LISTVIEW
);
571 m_sortInfo
.bIsAscending
= TRUE
;
572 m_sortInfo
.nHeaderID
= -1;
573 m_sortInfo
.nLastHeaderID
= -1;
577 /* UpdateShellSettings(); */
581 void CDefView::UpdateListColors()
583 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
585 /* Check if drop shadows option is enabled */
586 BOOL bDropShadow
= FALSE
;
587 DWORD cbDropShadow
= sizeof(bDropShadow
);
588 WCHAR wszBuf
[16] = L
"";
590 RegGetValueW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
591 L
"ListviewShadow", RRF_RT_DWORD
, NULL
, &bDropShadow
, &cbDropShadow
);
592 if (bDropShadow
&& SystemParametersInfoW(SPI_GETDESKWALLPAPER
, _countof(wszBuf
), wszBuf
, 0) && wszBuf
[0])
594 m_ListView
.SetTextBkColor(CLR_NONE
);
595 m_ListView
.SetBkColor(CLR_NONE
);
596 m_ListView
.SetTextColor(RGB(255, 255, 255));
597 m_ListView
.SetExtendedListViewStyle(LVS_EX_TRANSPARENTSHADOWTEXT
, LVS_EX_TRANSPARENTSHADOWTEXT
);
601 COLORREF crDesktop
= GetSysColor(COLOR_DESKTOP
);
602 m_ListView
.SetTextBkColor(crDesktop
);
603 m_ListView
.SetBkColor(crDesktop
);
604 if (GetRValue(crDesktop
) + GetGValue(crDesktop
) + GetBValue(crDesktop
) > 128 * 3)
605 m_ListView
.SetTextColor(RGB(0, 0, 0));
607 m_ListView
.SetTextColor(RGB(255, 255, 255));
608 m_ListView
.SetExtendedListViewStyle(LVS_EX_TRANSPARENTSHADOWTEXT
);
613 /**********************************************************
614 * ShellView_InitList()
616 * - adds all needed columns to the shellview
618 BOOL
CDefView::InitList()
622 HIMAGELIST big_icons
, small_icons
;
626 m_ListView
.DeleteAllItems();
630 for (int i
= 0; 1; i
++)
632 if (FAILED(m_pSF2Parent
->GetDetailsOf(NULL
, i
, &sd
)))
634 StrRetToStrNW( szTemp
, 50, &sd
.str
, NULL
);
635 m_ListView
.InsertColumn(i
, szTemp
, sd
.fmt
, sd
.cxChar
* 8);
644 Shell_GetImageLists(&big_icons
, &small_icons
);
645 m_ListView
.SetImageList(big_icons
, LVSIL_NORMAL
);
646 m_ListView
.SetImageList(small_icons
, LVSIL_SMALL
);
651 /**********************************************************
652 * ShellView_CompareItems()
655 * internal, CALLBACK for DSA_Sort
657 INT CALLBACK
CDefView::CompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
)
660 TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1
, lParam2
, (LPVOID
) lpData
);
665 IShellFolder
* psf
= reinterpret_cast<IShellFolder
*>(lpData
);
666 PCUIDLIST_RELATIVE pidl1
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam1
);
667 PCUIDLIST_RELATIVE pidl2
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam2
);
669 ret
= (SHORT
)SCODE_CODE(psf
->CompareIDs(0, pidl1
, pidl2
));
670 TRACE("ret=%i\n", ret
);
675 /*************************************************************************
676 * ShellView_ListViewCompareItems
678 * Compare Function for the Listview (FileOpen Dialog)
681 * lParam1 [I] the first ItemIdList to compare with
682 * lParam2 [I] the second ItemIdList to compare with
683 * lpData [I] The column ID for the header Ctrl to process
686 * A negative value if the first item should precede the second,
687 * a positive value if the first item should follow the second,
688 * or zero if the two items are equivalent
691 * FIXME: function does what ShellView_CompareItems is supposed to do.
692 * unify it and figure out how to use the undocumented first parameter
693 * of IShellFolder_CompareIDs to do the job this function does and
694 * move this code to IShellFolder.
695 * make LISTVIEW_SORT_INFO obsolete
696 * the way this function works is only usable if we had only
697 * filesystemfolders (25/10/99 jsch)
699 INT CALLBACK
CDefView::ListViewCompareItems(LPARAM lParam1
, LPARAM lParam2
, LPARAM lpData
)
703 char strName1
[MAX_PATH
], strName2
[MAX_PATH
];
704 BOOL bIsFolder1
, bIsFolder2
, bIsBothFolder
;
705 PCUIDLIST_RELATIVE pidl1
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam1
);
706 PCUIDLIST_RELATIVE pidl2
= reinterpret_cast<PCUIDLIST_RELATIVE
>(lParam2
);
707 LISTVIEW_SORT_INFO
*pSortInfo
= reinterpret_cast<LPLISTVIEW_SORT_INFO
>(lpData
);
710 bIsFolder1
= _ILIsFolder(pidl1
);
711 bIsFolder2
= _ILIsFolder(pidl2
);
712 bIsBothFolder
= bIsFolder1
&& bIsFolder2
;
714 /* When sorting between a File and a Folder, the Folder gets sorted first */
715 if ( (bIsFolder1
|| bIsFolder2
) && !bIsBothFolder
)
717 nDiff
= bIsFolder1
? -1 : 1;
721 /* Sort by Time: Folders or Files can be sorted */
723 if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_TIME
)
725 _ILGetFileDateTime(pidl1
, &fd1
);
726 _ILGetFileDateTime(pidl2
, &fd2
);
727 nDiff
= CompareFileTime(&fd2
, &fd1
);
729 /* Sort by Attribute: Folder or Files can be sorted */
730 else if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_ATTRIB
)
732 _ILGetFileAttributes(pidl1
, strName1
, MAX_PATH
);
733 _ILGetFileAttributes(pidl2
, strName2
, MAX_PATH
);
734 nDiff
= lstrcmpiA(strName1
, strName2
);
736 /* Sort by FileName: Folder or Files can be sorted */
737 else if (pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_NAME
|| bIsBothFolder
)
740 _ILSimpleGetText(pidl1
, strName1
, MAX_PATH
);
741 _ILSimpleGetText(pidl2
, strName2
, MAX_PATH
);
742 nDiff
= lstrcmpiA(strName1
, strName2
);
744 /* Sort by File Size, Only valid for Files */
745 else if (pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_SIZE
)
747 nDiff
= (INT
)(_ILGetFileSize(pidl1
, NULL
, 0) - _ILGetFileSize(pidl2
, NULL
, 0));
749 /* Sort by File Type, Only valid for Files */
750 else if (pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_TYPE
)
753 _ILGetFileType(pidl1
, strName1
, MAX_PATH
);
754 _ILGetFileType(pidl2
, strName2
, MAX_PATH
);
755 nDiff
= lstrcmpiA(strName1
, strName2
);
758 /* If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
762 _ILSimpleGetText(pidl1
, strName1
, MAX_PATH
);
763 _ILSimpleGetText(pidl2
, strName2
, MAX_PATH
);
764 nDiff
= lstrcmpiA(strName1
, strName2
);
767 if (!pSortInfo
->bIsAscending
)
775 PCUITEMID_CHILD
CDefView::_PidlByItem(int i
)
777 return reinterpret_cast<PCUITEMID_CHILD
>(m_ListView
.GetItemData(i
));
780 PCUITEMID_CHILD
CDefView::_PidlByItem(LVITEM
& lvItem
)
782 return reinterpret_cast<PCUITEMID_CHILD
>(lvItem
.lParam
);
785 /**********************************************************
786 * LV_FindItemByPidl()
788 int CDefView::LV_FindItemByPidl(PCUITEMID_CHILD pidl
)
790 int cItems
= m_ListView
.GetItemCount();
792 for (int i
= 0; i
<cItems
; i
++)
794 PCUITEMID_CHILD currentpidl
= _PidlByItem(i
);
795 HRESULT hr
= m_pSFParent
->CompareIDs(0, pidl
, currentpidl
);
797 if (SUCCEEDED(hr
) && !HRESULT_CODE(hr
))
805 /**********************************************************
808 BOOLEAN
CDefView::LV_AddItem(PCUITEMID_CHILD pidl
)
812 TRACE("(%p)(pidl=%p)\n", this, pidl
);
814 lvItem
.mask
= LVIF_TEXT
| LVIF_IMAGE
| LVIF_PARAM
; /*set the mask*/
815 lvItem
.iItem
= m_ListView
.GetItemCount(); /*add the item to the end of the list*/
817 lvItem
.lParam
= reinterpret_cast<LPARAM
>(ILClone(pidl
)); /*set the item's data*/
818 lvItem
.pszText
= LPSTR_TEXTCALLBACKW
; /*get text on a callback basis*/
819 lvItem
.iImage
= I_IMAGECALLBACK
; /*get the image on a callback basis*/
820 lvItem
.stateMask
= LVIS_CUT
;
822 if (m_ListView
.InsertItem(&lvItem
) == -1)
828 /**********************************************************
831 BOOLEAN
CDefView::LV_DeleteItem(PCUITEMID_CHILD pidl
)
835 TRACE("(%p)(pidl=%p)\n", this, pidl
);
837 nIndex
= LV_FindItemByPidl(pidl
);
839 return (-1 == m_ListView
.DeleteItem(nIndex
)) ? FALSE
: TRUE
;
842 /**********************************************************
845 BOOLEAN
CDefView::LV_RenameItem(PCUITEMID_CHILD pidlOld
, PCUITEMID_CHILD pidlNew
)
850 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", this, pidlOld
, pidlNew
);
852 nItem
= LV_FindItemByPidl(pidlOld
);
856 lvItem
.mask
= LVIF_PARAM
; /* only the pidl */
857 lvItem
.iItem
= nItem
;
858 m_ListView
.GetItem(&lvItem
);
860 SHFree(reinterpret_cast<LPVOID
>(lvItem
.lParam
));
861 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
862 lvItem
.iItem
= nItem
;
863 lvItem
.lParam
= reinterpret_cast<LPARAM
>(ILClone(pidlNew
)); /* set the item's data */
864 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
865 m_ListView
.SetItem(&lvItem
);
866 m_ListView
.Update(nItem
);
867 return TRUE
; /* FIXME: better handling */
873 /**********************************************************
876 BOOLEAN
CDefView::LV_ProdItem(PCUITEMID_CHILD pidl
)
881 TRACE("(%p)(pidl=%p)\n", this, pidl
);
883 nItem
= LV_FindItemByPidl(pidl
);
887 lvItem
.mask
= LVIF_IMAGE
;
888 lvItem
.iItem
= nItem
;
889 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
890 m_ListView
.SetItem(&lvItem
);
891 m_ListView
.Update(nItem
);
898 /**********************************************************
899 * ShellView_FillList()
901 * - gets the objectlist from the shellfolder
903 * - fills the list into the view
905 INT CALLBACK
CDefView::fill_list( LPVOID ptr
, LPVOID arg
)
907 PITEMID_CHILD pidl
= static_cast<PITEMID_CHILD
>(ptr
);
908 CDefView
*pThis
= static_cast<CDefView
*>(arg
);
910 /* in a commdlg This works as a filemask*/
911 if (pThis
->IncludeObject(pidl
) == S_OK
)
912 pThis
->LV_AddItem(pidl
);
918 HRESULT
CDefView::FillList()
920 CComPtr
<IEnumIDList
> pEnumIDList
;
926 DWORD dFlags
= SHCONTF_NONFOLDERS
| SHCONTF_FOLDERS
;
930 /* determine if there is a setting to show all the hidden files/folders */
931 if (RegOpenKeyExW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", 0, KEY_QUERY_VALUE
, &hKey
) == ERROR_SUCCESS
)
933 DWORD dataLength
, flagVal
;
935 dataLength
= sizeof(flagVal
);
936 if (RegQueryValueExW(hKey
, L
"Hidden", NULL
, NULL
, (LPBYTE
)&flagVal
, &dataLength
) == ERROR_SUCCESS
)
938 /* if the value is 1, then show all hidden files/folders */
941 dFlags
|= SHCONTF_INCLUDEHIDDEN
;
942 m_ListView
.SendMessageW(LVM_SETCALLBACKMASK
, LVIS_CUT
, 0);
950 /* get the itemlist from the shfolder */
951 hRes
= m_pSFParent
->EnumObjects(m_hWnd
, dFlags
, &pEnumIDList
);
959 /* create a pointer array */
960 hdpa
= DPA_Create(16);
963 return(E_OUTOFMEMORY
);
966 /* copy the items into the array*/
967 while((S_OK
== pEnumIDList
->Next(1, &pidl
, &dwFetched
)) && dwFetched
)
969 if (DPA_InsertPtr(hdpa
, 0x7fff, pidl
) == -1)
976 DPA_Sort(hdpa
, CompareItems
, reinterpret_cast<LPARAM
>(m_pSFParent
.p
));
978 /*turn the listview's redrawing off*/
979 m_ListView
.SetRedraw(FALSE
);
981 DPA_DestroyCallback( hdpa
, fill_list
, this);
983 /*turn the listview's redrawing back on and force it to draw*/
984 m_ListView
.SetRedraw(TRUE
);
989 LRESULT
CDefView::OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
991 m_ListView
.UpdateWindow();
996 LRESULT
CDefView::OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
998 return m_ListView
.SendMessageW(uMsg
, 0, 0);
1001 LRESULT
CDefView::OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1008 DestroyMenu(m_hMenu
);
1011 RevokeDragDrop(m_hWnd
);
1012 SHChangeNotifyDeregister(m_hNotify
);
1014 SHFree(m_pidlParent
);
1015 m_pidlParent
= NULL
;
1021 LRESULT
CDefView::OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1023 /* redirect to parent */
1024 if (m_FolderSettings
.fFlags
& (FWF_DESKTOP
| FWF_TRANSPARENT
))
1025 return SendMessageW(GetParent(), WM_ERASEBKGND
, wParam
, lParam
);
1031 LRESULT
CDefView::OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1033 /* Update desktop labels color */
1036 /* Forward WM_SYSCOLORCHANGE to common controls */
1037 return m_ListView
.SendMessageW(uMsg
, 0, 0);
1040 LRESULT
CDefView::OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1042 return reinterpret_cast<LRESULT
>(m_pShellBrowser
.p
);
1045 LRESULT
CDefView::OnNCCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1052 LRESULT
CDefView::OnNCDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1059 /**********************************************************
1060 * ShellView_OnCreate()
1062 LRESULT
CDefView::OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1064 CComPtr
<IDropTarget
> pdt
;
1065 SHChangeNotifyEntry ntreg
;
1066 CComPtr
<IPersistFolder2
> ppf2
;
1068 TRACE("%p\n", this);
1078 if (SUCCEEDED(QueryInterface(IID_PPV_ARG(IDropTarget
, &pdt
))))
1080 if (FAILED(RegisterDragDrop(m_hWnd
, pdt
)))
1081 ERR("Registering Drag Drop Failed");
1084 /* register for receiving notifications */
1085 m_pSFParent
->QueryInterface(IID_PPV_ARG(IPersistFolder2
, &ppf2
));
1088 ppf2
->GetCurFolder(&m_pidlParent
);
1089 ntreg
.fRecursive
= TRUE
;
1090 ntreg
.pidl
= m_pidlParent
;
1091 m_hNotify
= SHChangeNotifyRegister(m_hWnd
, SHCNRF_InterruptLevel
| SHCNRF_ShellLevel
, SHCNE_ALLEVENTS
, SHV_CHANGE_NOTIFY
, 1, &ntreg
);
1094 m_hAccel
= LoadAcceleratorsW(shell32_hInstance
, MAKEINTRESOURCEW(IDA_SHELLVIEW
));
1101 /**********************************************************
1102 * #### Handling of the menus ####
1105 HMENU
CDefView::BuildFileMenu()
1108 CComPtr
<IContextMenu
> cm
;
1112 hr
= m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, IID_NULL_PPV_ARG(IContextMenu
, &cm
));
1116 HMENU hmenu
= CreatePopupMenu();
1118 //FIXME: get proper numbers ?
1119 const UINT first
= 0x7800;
1120 const UINT last
= 0x7A00;
1121 hr
= cm
->QueryContextMenu(hmenu
, 0, first
, last
, 0);
1125 // TODO: filter or something
1130 void CDefView::PrepareShowFileMenu(HMENU hSubMenu
)
1132 TRACE("(%p)->(submenu=%p) stub\n", this, hSubMenu
);
1137 /* Cleanup the items added previously */
1138 for (int i
= 0; i
< GetMenuItemCount(hSubMenu
); )
1141 mii
.cbSize
= sizeof(mii
);
1142 mii
.fMask
= MIIM_ID
;
1143 GetMenuItemInfoW(hSubMenu
, i
, TRUE
, &mii
);
1145 if (mii
.wID
< 0x8000)
1147 DeleteMenu(hSubMenu
, i
, MF_BYPOSITION
);
1156 /* FIXME/TODO: Reenable when they implemented AND localizable (not hardcoded). */
1157 /* Insert This item at the beginning of the menu. */
1158 _InsertMenuItemW(hSubMenu
, 0, TRUE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1159 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
+ 4, MFT_STRING
, L
"Properties", MFS_DISABLED
);
1160 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
+ 3, MFT_STRING
, L
"Rename", MFS_DISABLED
);
1161 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
+ 2, MFT_STRING
, L
"Delete", MFS_DISABLED
);
1162 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
+ 1, MFT_STRING
, L
"Create Shortcut", MFS_DISABLED
);
1163 _InsertMenuItemW(hSubMenu
, 0, TRUE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1164 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
, MFT_STRING
, L
"New", MFS_ENABLED
);
1167 HMENU menubase
= BuildFileMenu();
1170 int count
= ::GetMenuItemCount(menubase
);
1171 int count2
= ::GetMenuItemCount(hSubMenu
);
1173 if (count2
> 0 && count
> 0)
1175 _InsertMenuItemW(hSubMenu
, 0, TRUE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1178 for (int i
= count
-1; i
>= 0; i
--)
1182 MENUITEMINFOW mii
= { 0 };
1183 mii
.cbSize
= sizeof(mii
);
1184 mii
.fMask
= MIIM_STATE
| MIIM_ID
| MIIM_SUBMENU
| MIIM_CHECKMARKS
| MIIM_DATA
| MIIM_STRING
| MIIM_BITMAP
| MIIM_FTYPE
;
1185 mii
.dwTypeData
= label
;
1186 mii
.cch
= _countof(label
);
1187 ::GetMenuItemInfoW(menubase
, i
, TRUE
, &mii
);
1189 TRACE("Adding item %d label %S type %d\n", mii
.wID
, mii
.dwTypeData
, mii
.fType
);
1191 mii
.fType
|= MFT_RADIOCHECK
;
1193 ::InsertMenuItemW(hSubMenu
, 0, TRUE
, &mii
);
1197 ::DestroyMenu(menubase
);
1202 void CDefView::PrepareShowViewMenu(HMENU hSubMenu
)
1204 TRACE("(%p)->(submenu=%p)\n", this, hSubMenu
);
1209 if (m_FolderSettings
.ViewMode
>= FVM_FIRST
&& m_FolderSettings
.ViewMode
<= FVM_LAST
)
1211 UINT iItemFirst
= FCIDM_SHVIEW_BIGICON
;
1212 UINT iItemLast
= iItemFirst
+ FVM_LAST
- FVM_FIRST
;
1213 UINT iItem
= iItemFirst
+ m_FolderSettings
.ViewMode
- FVM_FIRST
;
1214 CheckMenuRadioItem(hSubMenu
, iItemFirst
, iItemLast
, iItem
, MF_BYCOMMAND
);
1218 /**********************************************************
1219 * ShellView_GetSelections()
1221 * - fills the m_apidl list with the selected objects
1224 * number of selected items
1226 UINT
CDefView::GetSelections()
1230 m_cidl
= m_ListView
.GetSelectedCount();
1231 m_apidl
= static_cast<PCUITEMID_CHILD
*>(SHAlloc(m_cidl
* sizeof(PCUITEMID_CHILD
)));
1238 TRACE("-- Items selected =%u\n", m_cidl
);
1242 while ((lvIndex
= m_ListView
.GetNextItem(lvIndex
, LVNI_SELECTED
)) > -1)
1244 m_apidl
[i
] = _PidlByItem(lvIndex
);
1248 TRACE("-- selected Item found\n");
1254 HRESULT
CDefView::InvokeContextMenuCommand(UINT uCommand
)
1256 CMINVOKECOMMANDINFO cmi
;
1258 ZeroMemory(&cmi
, sizeof(cmi
));
1259 cmi
.cbSize
= sizeof(cmi
);
1260 cmi
.lpVerb
= MAKEINTRESOURCEA(uCommand
);
1263 if (GetKeyState(VK_SHIFT
) & 0x8000)
1264 cmi
.fMask
|= CMIC_MASK_SHIFT_DOWN
;
1266 if (GetKeyState(VK_CONTROL
) & 0x8000)
1267 cmi
.fMask
|= CMIC_MASK_CONTROL_DOWN
;
1269 return m_pCM
->InvokeCommand(&cmi
);
1272 /**********************************************************
1273 * ShellView_OpenSelectedItems()
1275 HRESULT
CDefView::OpenSelectedItems()
1281 m_cidl
= m_ListView
.GetSelectedCount();
1285 hResult
= OnDefaultCommand();
1286 if (hResult
== S_OK
)
1289 hMenu
= CreatePopupMenu();
1293 hResult
= GetItemObject(SVGIO_SELECTION
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1294 if (FAILED(hResult
))
1297 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, 0x20, 0x7fff, CMF_DEFAULTONLY
);
1298 if (FAILED(hResult
))
1301 uCommand
= GetMenuDefaultItem(hMenu
, FALSE
, 0);
1302 if (uCommand
== (UINT
)-1)
1308 InvokeContextMenuCommand(uCommand
);
1321 /**********************************************************
1322 * ShellView_DoContextMenu()
1324 LRESULT
CDefView::OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1332 // for some reason I haven't figured out, we sometimes recurse into this method
1339 TRACE("(%p)->(0x%08x 0x%08x) stub\n", this, x
, y
);
1341 hMenu
= CreatePopupMenu();
1345 m_cidl
= m_ListView
.GetSelectedCount();
1347 hResult
= GetItemObject( m_cidl
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1348 if (FAILED( hResult
))
1351 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1352 if (FAILED( hResult
))
1355 uCommand
= TrackPopupMenu(hMenu
,
1356 TPM_LEFTALIGN
| TPM_RETURNCMD
| TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
,
1357 x
, y
, 0, m_hWnd
, NULL
);
1361 if (uCommand
== FCIDM_SHVIEW_OPEN
&& OnDefaultCommand() == S_OK
)
1364 InvokeContextMenuCommand(uCommand
);
1376 LRESULT
CDefView::OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
)
1381 hMenu
= CreatePopupMenu();
1385 hResult
= GetItemObject( bUseSelection
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1386 if (FAILED( hResult
))
1389 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1390 if (FAILED( hResult
))
1393 InvokeContextMenuCommand(uCommand
);
1405 /**********************************************************
1406 * ##### message handling #####
1409 /**********************************************************
1410 * ShellView_OnSize()
1412 LRESULT
CDefView::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1417 wWidth
= LOWORD(lParam
);
1418 wHeight
= HIWORD(lParam
);
1420 TRACE("%p width=%u height=%u\n", this, wWidth
, wHeight
);
1422 /*resize the ListView to fit our window*/
1425 ::MoveWindow(m_ListView
, 0, 0, wWidth
, wHeight
, TRUE
);
1431 /**********************************************************
1432 * ShellView_OnDeactivate()
1437 void CDefView::OnDeactivate()
1439 TRACE("%p\n", this);
1441 if (m_uState
!= SVUIA_DEACTIVATE
)
1443 // TODO: cleanup menu after deactivation
1445 m_uState
= SVUIA_DEACTIVATE
;
1449 void CDefView::DoActivate(UINT uState
)
1451 TRACE("%p uState=%x\n", this, uState
);
1453 /*don't do anything if the state isn't really changing */
1454 if (m_uState
== uState
)
1459 if (uState
== SVUIA_DEACTIVATE
)
1469 MENUITEMINFOW mii
= { 0 };
1471 /* initialize EDIT menu */
1472 mii
.cbSize
= sizeof(mii
);
1473 mii
.fMask
= MIIM_SUBMENU
;
1474 if (::GetMenuItemInfoW(m_hMenu
, FCIDM_MENU_EDIT
, FALSE
, &mii
))
1476 HMENU hSubMenu
= mii
.hSubMenu
;
1478 HMENU menubase
= ::LoadMenuW(shell32_hInstance
, L
"MENU_003");
1480 int count
= ::GetMenuItemCount(menubase
);
1481 for (int i
= 0; i
< count
; i
++)
1485 ZeroMemory(&mii
, sizeof(mii
));
1486 mii
.cbSize
= sizeof(mii
);
1487 mii
.fMask
= MIIM_STATE
| MIIM_ID
| MIIM_SUBMENU
| MIIM_CHECKMARKS
| MIIM_DATA
| MIIM_STRING
| MIIM_BITMAP
| MIIM_FTYPE
;
1488 mii
.dwTypeData
= label
;
1489 mii
.cch
= _countof(label
);
1490 ::GetMenuItemInfoW(menubase
, i
, TRUE
, &mii
);
1492 TRACE("Adding item %d label %S type %d\n", mii
.wID
, mii
.dwTypeData
, mii
.fType
);
1494 mii
.fType
|= MFT_RADIOCHECK
;
1496 ::InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, &mii
);
1499 ::DestroyMenu(menubase
);
1502 /* initialize VIEW menu */
1504 mii
.cbSize
= sizeof(mii
);
1505 mii
.fMask
= MIIM_SUBMENU
;
1506 if (::GetMenuItemInfoW(m_hMenu
, FCIDM_MENU_VIEW
, FALSE
, &mii
))
1508 HMENU menubase
= ::LoadMenuW(shell32_hInstance
, L
"MENU_001");
1510 HMENU hSubMenu
= mii
.hSubMenu
;
1512 m_hView
= CreatePopupMenu();
1514 _InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1516 int count
= ::GetMenuItemCount(menubase
);
1517 for (int i
= 0; i
< count
; i
++)
1521 ZeroMemory(&mii
, sizeof(mii
));
1522 mii
.cbSize
= sizeof(mii
);
1523 mii
.fMask
= MIIM_STATE
| MIIM_ID
| MIIM_SUBMENU
| MIIM_CHECKMARKS
| MIIM_DATA
| MIIM_STRING
| MIIM_BITMAP
| MIIM_FTYPE
;
1524 mii
.dwTypeData
= label
;
1525 mii
.cch
= _countof(label
);
1526 ::GetMenuItemInfoW(menubase
, i
, TRUE
, &mii
);
1528 ::AppendMenuW(m_hView
, mii
.fType
, mii
.wID
, mii
.dwTypeData
);
1530 TRACE("Adding item %d label %S type %d\n", mii
.wID
, mii
.dwTypeData
, mii
.fType
);
1532 mii
.fType
|= MFT_RADIOCHECK
;
1534 ::InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, &mii
);
1537 ::DestroyMenu(menubase
);
1541 TRACE("-- before fnSetMenuSB\n");
1542 m_pShellBrowser
->SetMenuSB(m_hMenu
, 0, m_hWnd
);
1544 m_menusLoaded
= TRUE
;
1548 if (SVUIA_ACTIVATE_FOCUS
== uState
)
1550 m_ListView
.SetFocus();
1558 /**********************************************************
1559 * ShellView_OnActivate()
1561 LRESULT
CDefView::OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1563 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1567 /**********************************************************
1568 * ShellView_OnSetFocus()
1571 LRESULT
CDefView::OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1573 TRACE("%p\n", this);
1575 /* Tell the browser one of our windows has received the focus. This
1576 should always be done before merging menus (OnActivate merges the
1577 menus) if one of our windows has the focus.*/
1579 m_pShellBrowser
->OnViewWindowActive(this);
1580 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1582 /* Set the focus to the listview */
1583 m_ListView
.SetFocus();
1585 /* Notify the ICommDlgBrowser interface */
1586 OnStateChange(CDBOSC_SETFOCUS
);
1591 /**********************************************************
1592 * ShellView_OnKillFocus()
1594 LRESULT
CDefView::OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1596 TRACE("(%p) stub\n", this);
1598 DoActivate(SVUIA_ACTIVATE_NOFOCUS
);
1599 /* Notify the ICommDlgBrowser */
1600 OnStateChange(CDBOSC_KILLFOCUS
);
1605 /**********************************************************
1606 * ShellView_OnCommand()
1609 * the CmdID's are the ones from the context menu
1611 LRESULT
CDefView::OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1618 dwCmdID
= GET_WM_COMMAND_ID(wParam
, lParam
);
1619 dwCmd
= GET_WM_COMMAND_CMD(wParam
, lParam
);
1620 hwndCmd
= GET_WM_COMMAND_HWND(wParam
, lParam
);
1622 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n", this, dwCmdID
, dwCmd
, hwndCmd
);
1626 case FCIDM_SHVIEW_SMALLICON
:
1627 m_FolderSettings
.ViewMode
= FVM_SMALLICON
;
1628 SetStyle (LVS_SMALLICON
, LVS_TYPEMASK
);
1632 case FCIDM_SHVIEW_BIGICON
:
1633 m_FolderSettings
.ViewMode
= FVM_ICON
;
1634 SetStyle (LVS_ICON
, LVS_TYPEMASK
);
1638 case FCIDM_SHVIEW_LISTVIEW
:
1639 m_FolderSettings
.ViewMode
= FVM_LIST
;
1640 SetStyle (LVS_LIST
, LVS_TYPEMASK
);
1644 case FCIDM_SHVIEW_REPORTVIEW
:
1645 m_FolderSettings
.ViewMode
= FVM_DETAILS
;
1646 SetStyle (LVS_REPORT
, LVS_TYPEMASK
);
1650 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1655 m_sortInfo
.nHeaderID
= dwCmdID
- 0x30;
1656 m_sortInfo
.bIsAscending
= TRUE
;
1657 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
1658 m_ListView
.SortItems(ListViewCompareItems
, &m_sortInfo
);
1661 case FCIDM_SHVIEW_SELECTALL
:
1662 m_ListView
.SetItemState(-1, LVIS_SELECTED
, LVIS_SELECTED
);
1665 case FCIDM_SHVIEW_INVERTSELECTION
:
1666 nCount
= m_ListView
.GetItemCount();
1667 for (int i
=0; i
< nCount
; i
++)
1668 m_ListView
.SetItemState(i
, m_ListView
.GetItemState(i
, LVIS_SELECTED
) ? 0 : LVIS_SELECTED
, LVIS_SELECTED
);
1671 case FCIDM_SHVIEW_REFRESH
:
1675 case FCIDM_SHVIEW_DELETE
:
1676 case FCIDM_SHVIEW_CUT
:
1677 case FCIDM_SHVIEW_COPY
:
1678 case FCIDM_SHVIEW_RENAME
:
1679 return OnExplorerCommand(dwCmdID
, TRUE
);
1681 case FCIDM_SHVIEW_INSERT
:
1682 case FCIDM_SHVIEW_UNDO
:
1683 case FCIDM_SHVIEW_INSERTLINK
:
1684 case FCIDM_SHVIEW_NEWFOLDER
:
1685 return OnExplorerCommand(dwCmdID
, FALSE
);
1687 TRACE("-- COMMAND 0x%04x unhandled\n", dwCmdID
);
1693 /**********************************************************
1694 * ShellView_OnNotify()
1697 LRESULT
CDefView::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1701 LPNMLISTVIEW lpnmlv
;
1702 NMLVDISPINFOW
*lpdi
;
1703 PCUITEMID_CHILD pidl
;
1707 lpnmh
= (LPNMHDR
)lParam
;
1708 lpnmlv
= (LPNMLISTVIEW
)lpnmh
;
1709 lpdi
= (NMLVDISPINFOW
*)lpnmh
;
1711 TRACE("%p CtlID=%u lpnmh->code=%x\n", this, CtlID
, lpnmh
->code
);
1713 switch (lpnmh
->code
)
1716 TRACE("-- NM_SETFOCUS %p\n", this);
1717 OnSetFocus(0, 0, 0, unused
);
1721 TRACE("-- NM_KILLFOCUS %p\n", this);
1723 /* Notify the ICommDlgBrowser interface */
1724 OnStateChange(CDBOSC_KILLFOCUS
);
1728 TRACE("-- NM_CUSTOMDRAW %p\n", this);
1729 return CDRF_DODEFAULT
;
1731 case NM_RELEASEDCAPTURE
:
1732 TRACE("-- NM_RELEASEDCAPTURE %p\n", this);
1736 TRACE("-- NM_CLICK %p\n", this);
1740 TRACE("-- NM_RCLICK %p\n", this);
1744 TRACE("-- NM_DBLCLK %p\n", this);
1745 OpenSelectedItems();
1749 TRACE("-- NM_RETURN %p\n", this);
1750 OpenSelectedItems();
1754 TRACE("-- HDN_ENDTRACKW %p\n", this);
1755 /*nColumn1 = m_ListView.GetColumnWidth(0);
1756 nColumn2 = m_ListView.GetColumnWidth(1);*/
1759 case LVN_DELETEITEM
:
1760 TRACE("-- LVN_DELETEITEM %p\n", this);
1762 /*delete the pidl because we made a copy of it*/
1763 SHFree(reinterpret_cast<LPVOID
>(lpnmlv
->lParam
));
1767 case LVN_DELETEALLITEMS
:
1768 TRACE("-- LVN_DELETEALLITEMS %p\n", this);
1771 case LVN_INSERTITEM
:
1772 TRACE("-- LVN_INSERTITEM (STUB)%p\n", this);
1775 case LVN_ITEMACTIVATE
:
1776 TRACE("-- LVN_ITEMACTIVATE %p\n", this);
1777 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1780 case LVN_COLUMNCLICK
:
1781 m_sortInfo
.nHeaderID
= lpnmlv
->iSubItem
;
1782 if (m_sortInfo
.nLastHeaderID
== m_sortInfo
.nHeaderID
)
1783 m_sortInfo
.bIsAscending
= !m_sortInfo
.bIsAscending
;
1785 m_sortInfo
.bIsAscending
= TRUE
;
1786 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
1788 m_ListView
.SortItems(ListViewCompareItems
, &m_sortInfo
);
1791 case LVN_GETDISPINFOA
:
1792 case LVN_GETDISPINFOW
:
1793 TRACE("-- LVN_GETDISPINFO %p\n", this);
1794 pidl
= _PidlByItem(lpdi
->item
);
1796 if (lpdi
->item
.mask
& LVIF_TEXT
) /* text requested */
1801 if (FAILED(m_pSF2Parent
->GetDetailsOf(pidl
, lpdi
->item
.iSubItem
, &sd
)))
1803 FIXME("failed to get details\n");
1807 if (lpnmh
->code
== LVN_GETDISPINFOA
)
1809 /* shouldn't happen */
1810 NMLVDISPINFOA
*lpdiA
= (NMLVDISPINFOA
*)lpnmh
;
1811 StrRetToStrNA( lpdiA
->item
.pszText
, lpdiA
->item
.cchTextMax
, &sd
.str
, NULL
);
1812 TRACE("-- text=%s\n", lpdiA
->item
.pszText
);
1814 else /* LVN_GETDISPINFOW */
1816 StrRetToStrNW( lpdi
->item
.pszText
, lpdi
->item
.cchTextMax
, &sd
.str
, NULL
);
1817 TRACE("-- text=%s\n", debugstr_w(lpdi
->item
.pszText
));
1825 if(lpdi
->item
.mask
& LVIF_IMAGE
) /* image requested */
1827 lpdi
->item
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
1829 if(lpdi
->item
.mask
& LVIF_STATE
)
1831 ULONG attributes
= SFGAO_HIDDEN
;
1832 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(1, &pidl
, &attributes
)))
1834 if (attributes
& SFGAO_HIDDEN
)
1836 lpdi
->item
.state
|= LVIS_CUT
;
1840 lpdi
->item
.mask
|= LVIF_DI_SETITEM
;
1843 case LVN_ITEMCHANGED
:
1844 TRACE("-- LVN_ITEMCHANGED %p\n", this);
1845 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1850 case LVN_BEGINRDRAG
:
1851 TRACE("-- LVN_BEGINDRAG\n");
1853 if (GetSelections())
1855 CComPtr
<IDataObject
> pda
;
1856 DWORD dwAttributes
= SFGAO_CANLINK
;
1857 DWORD dwEffect
= DROPEFFECT_COPY
| DROPEFFECT_MOVE
;
1859 if (SUCCEEDED(m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, IID_NULL_PPV_ARG(IDataObject
, &pda
))))
1861 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(m_cidl
, m_apidl
, &dwAttributes
)))
1863 if (dwAttributes
& SFGAO_CANLINK
)
1865 dwEffect
|= DROPEFFECT_LINK
;
1869 CComPtr
<IAsyncOperation
> piaso
;
1870 if (SUCCEEDED(pda
->QueryInterface(IID_PPV_ARG(IAsyncOperation
, &piaso
))))
1872 piaso
->SetAsyncMode(TRUE
);
1876 DoDragDrop(pda
, this, dwEffect
, &dwEffect2
);
1881 case LVN_BEGINLABELEDITW
:
1883 DWORD dwAttr
= SFGAO_CANRENAME
;
1884 pidl
= _PidlByItem(lpdi
->item
);
1886 TRACE("-- LVN_BEGINLABELEDITW %p\n", this);
1888 m_pSFParent
->GetAttributesOf(1, &pidl
, &dwAttr
);
1889 if (SFGAO_CANRENAME
& dwAttr
)
1897 case LVN_ENDLABELEDITW
:
1899 TRACE("-- LVN_ENDLABELEDITW %p\n", this);
1901 m_isEditing
= FALSE
;
1903 if (lpdi
->item
.pszText
)
1908 pidl
= _PidlByItem(lpdi
->item
);
1909 PITEMID_CHILD pidlNew
;
1910 hr
= m_pSFParent
->SetNameOf(0, pidl
, lpdi
->item
.pszText
, SHGDN_INFOLDER
, &pidlNew
);
1912 if (SUCCEEDED(hr
) && pidlNew
)
1914 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
1915 lvItem
.iItem
= lpdi
->item
.iItem
;
1916 lvItem
.lParam
= reinterpret_cast<LPARAM
>(pidlNew
);
1917 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
1918 m_ListView
.SetItem(&lvItem
);
1919 m_ListView
.Update(lpdi
->item
.iItem
);
1928 TRACE("-- %p WM_COMMAND %x unhandled\n", this, lpnmh
->code
);
1936 * This is just a quick hack to make the desktop work correctly.
1937 * ITranslateShellChangeNotify's IsChildID is undocumented, but most likely the way that
1938 * a folder should know if it should update upon a change notification.
1939 * It is exported by merged folders at a minimum.
1941 static BOOL
ILIsParentOrSpecialParent(PCIDLIST_ABSOLUTE pidl1
, PCIDLIST_ABSOLUTE pidl2
)
1943 if (!pidl1
|| !pidl2
)
1945 if (ILIsParent(pidl1
, pidl2
, TRUE
))
1948 if (_ILIsDesktop(pidl1
))
1950 PIDLIST_ABSOLUTE deskpidl
;
1951 SHGetFolderLocation(NULL
, CSIDL_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
1952 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
1958 SHGetFolderLocation(NULL
, CSIDL_COMMON_DESKTOPDIRECTORY
, NULL
, 0, &deskpidl
);
1959 if (ILIsParent(deskpidl
, pidl2
, TRUE
))
1969 /**********************************************************
1970 * ShellView_OnChange()
1972 LRESULT
CDefView::OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1974 PCIDLIST_ABSOLUTE
*Pidls
= reinterpret_cast<PCIDLIST_ABSOLUTE
*>(wParam
);
1975 BOOL bParent0
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[0]);
1976 BOOL bParent1
= ILIsParentOrSpecialParent(m_pidlParent
, Pidls
[1]);
1978 TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls
[0], Pidls
[1], lParam
);
1980 switch (lParam
&~ SHCNE_INTERRUPT
)
1986 if (LV_FindItemByPidl(ILFindLastID(Pidls
[0])) == -1)
1988 LV_AddItem(ILFindLastID(Pidls
[0]));
1992 LV_ProdItem(ILFindLastID(Pidls
[0]));
2000 LV_DeleteItem(ILFindLastID(Pidls
[0]));
2003 case SHCNE_RENAMEFOLDER
:
2004 case SHCNE_RENAMEITEM
:
2005 if (bParent0
&& bParent1
)
2006 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[1]));
2008 LV_DeleteItem(ILFindLastID(Pidls
[0]));
2010 LV_AddItem(ILFindLastID(Pidls
[1]));
2013 case SHCNE_UPDATEITEM
:
2015 LV_RenameItem(ILFindLastID(Pidls
[0]), ILFindLastID(Pidls
[0]));
2018 case SHCNE_UPDATEDIR
:
2025 /**********************************************************
2026 * CDefView::OnCustomItem
2028 LRESULT
CDefView::OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
2033 ERR("no menu!!!\n");
2038 HRESULT hres
= SHForwardContextMenuMsg(m_pCM
, uMsg
, wParam
, lParam
, &result
, TRUE
);
2039 if (SUCCEEDED(hres
))
2045 LRESULT
CDefView::OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
2047 /* Wallpaper setting affects drop shadows effect */
2048 if (wParam
== SPI_SETDESKWALLPAPER
|| wParam
== 0)
2054 /**********************************************************
2055 * CDefView::OnInitMenuPopup
2057 LRESULT
CDefView::OnInitMenuPopup(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
2059 MENUITEMINFOW mii
= { 0 };
2060 HMENU hSubmenu
= (HMENU
) wParam
;
2062 TRACE("OnInitMenuPopup lParam=%d\n", lParam
);
2064 mii
.cbSize
= sizeof(mii
);
2065 mii
.fMask
= MIIM_ID
| MIIM_SUBMENU
;
2067 if (!GetMenuItemInfoW(this->m_hMenu
, lParam
, TRUE
, &mii
))
2069 TRACE("OnInitMenuPopup GetMenuItemInfoW failed!\n");
2073 UINT menuItemId
= mii
.wID
;
2075 if (mii
.hSubMenu
!= hSubmenu
)
2077 TRACE("OnInitMenuPopup submenu does not match!!!!\n");
2081 TRACE("OnInitMenuPopup id=%d\n", menuItemId
);
2085 case FCIDM_MENU_FILE
:
2086 PrepareShowFileMenu(hSubmenu
);
2088 case FCIDM_MENU_EDIT
:
2089 //PrepareShowEditMenu(hSubmenu);
2091 case FCIDM_MENU_VIEW
:
2092 PrepareShowViewMenu(hSubmenu
);
2099 /**********************************************************
2102 * The INTERFACE of the IShellView object
2105 **********************************************************
2108 /**********************************************************
2109 * ShellView_GetWindow
2111 HRESULT WINAPI
CDefView::GetWindow(HWND
*phWnd
)
2113 TRACE("(%p)\n", this);
2120 HRESULT WINAPI
CDefView::ContextSensitiveHelp(BOOL fEnterMode
)
2122 FIXME("(%p) stub\n", this);
2127 /**********************************************************
2128 * IShellView_TranslateAccelerator
2131 * use the accel functions
2133 HRESULT WINAPI
CDefView::TranslateAccelerator(LPMSG lpmsg
)
2138 if (lpmsg
->message
>= WM_KEYFIRST
&& lpmsg
->message
<= WM_KEYLAST
)
2140 if (::TranslateAcceleratorW(m_hWnd
, m_hAccel
, lpmsg
) != 0)
2143 TRACE("-- key=0x04%lx\n", lpmsg
->wParam
) ;
2146 return m_pShellBrowser
->TranslateAcceleratorSB(lpmsg
, 0);
2149 HRESULT WINAPI
CDefView::EnableModeless(BOOL fEnable
)
2151 FIXME("(%p) stub\n", this);
2156 HRESULT WINAPI
CDefView::UIActivate(UINT uState
)
2159 CHAR szName[MAX_PATH];
2162 int nPartArray
[1] = { -1};
2164 TRACE("(%p)->(state=%x) stub\n", this, uState
);
2166 /*don't do anything if the state isn't really changing*/
2167 if (m_uState
== uState
)
2172 /*OnActivate handles the menu merging and internal state*/
2175 /*only do This if we are active*/
2176 if (uState
!= SVUIA_DEACTIVATE
)
2180 GetFolderPath is not a method of IShellFolder
2181 IShellFolder_GetFolderPath( m_pSFParent, szName, sizeof(szName) );
2183 /* set the number of parts */
2184 m_pShellBrowser
->SendControlMsg(FCW_STATUS
, SB_SETPARTS
, 1, (LPARAM
)nPartArray
, &lResult
);
2186 /* set the text for the parts */
2188 m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXTA, 0, (LPARAM)szName, &lResult);
2195 HRESULT WINAPI
CDefView::Refresh()
2197 TRACE("(%p)\n", this);
2199 m_ListView
.DeleteAllItems();
2205 HRESULT WINAPI
CDefView::CreateViewWindow(IShellView
*lpPrevView
, LPCFOLDERSETTINGS lpfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
)
2207 OLEMENUGROUPWIDTHS omw
= { { 0, 0, 0, 0, 0, 0 } };
2211 TRACE("(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n", this, lpPrevView
, lpfs
, psb
, prcView
, phWnd
);
2214 TRACE("-- vmode=%x flags=%x\n", lpfs
->ViewMode
, lpfs
->fFlags
);
2215 if (prcView
!= NULL
)
2216 TRACE("-- left=%i top=%i right=%i bottom=%i\n", prcView
->left
, prcView
->top
, prcView
->right
, prcView
->bottom
);
2218 /* Validate the Shell Browser */
2219 if (psb
== NULL
|| m_hWnd
)
2220 return E_UNEXPECTED
;
2222 /*set up the member variables*/
2223 m_pShellBrowser
= psb
;
2224 m_FolderSettings
= *lpfs
;
2226 /*get our parent window*/
2227 m_pShellBrowser
->GetWindow(&m_hWndParent
);
2229 /* try to get the ICommDlgBrowserInterface, adds a reference !!! */
2230 m_pCommDlgBrowser
= NULL
;
2231 if (SUCCEEDED(m_pShellBrowser
->QueryInterface(IID_PPV_ARG(ICommDlgBrowser
, &m_pCommDlgBrowser
))))
2233 TRACE("-- CommDlgBrowser\n");
2236 Create(m_hWndParent
, prcView
, NULL
, WS_CHILD
| WS_TABSTOP
, 0, 0U);
2247 SetWindowPos(HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_SHOWWINDOW
);
2252 m_hMenu
= CreateMenu();
2253 m_pShellBrowser
->InsertMenusSB(m_hMenu
, &omw
);
2254 TRACE("-- after fnInsertMenusSB\n");
2262 HRESULT WINAPI
CDefView::DestroyViewWindow()
2264 TRACE("(%p)\n", this);
2266 /*Make absolutely sure all our UI is cleaned up.*/
2267 UIActivate(SVUIA_DEACTIVATE
);
2271 // "Accelerator tables loaded from resources are freed automatically when the application terminates." -- MSDN
2277 DestroyMenu(m_hView
);
2283 DestroyMenu(m_hMenu
);
2289 m_ListView
.DestroyWindow();
2297 m_pShellBrowser
.Release();
2298 m_pCommDlgBrowser
.Release();
2303 HRESULT WINAPI
CDefView::GetCurrentInfo(LPFOLDERSETTINGS lpfs
)
2305 TRACE("(%p)->(%p) vmode=%x flags=%x\n", this, lpfs
,
2306 m_FolderSettings
.ViewMode
, m_FolderSettings
.fFlags
);
2309 return E_INVALIDARG
;
2311 *lpfs
= m_FolderSettings
;
2315 HRESULT WINAPI
CDefView::AddPropertySheetPages(DWORD dwReserved
, LPFNADDPROPSHEETPAGE lpfn
, LPARAM lparam
)
2317 FIXME("(%p) stub\n", this);
2322 HRESULT WINAPI
CDefView::SaveViewState()
2324 FIXME("(%p) stub\n", this);
2329 HRESULT WINAPI
CDefView::SelectItem(PCUITEMID_CHILD pidl
, UINT uFlags
)
2333 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n", this, pidl
, uFlags
);
2335 i
= LV_FindItemByPidl(pidl
);
2339 if(uFlags
& SVSI_ENSUREVISIBLE
)
2340 m_ListView
.EnsureVisible(i
, FALSE
);
2342 LVITEMW lvItem
= {0};
2343 lvItem
.mask
= LVIF_STATE
;
2344 lvItem
.stateMask
= LVIS_SELECTED
| LVIS_FOCUSED
;
2346 while (m_ListView
.GetItem(&lvItem
))
2348 if (lvItem
.iItem
== i
)
2350 if (uFlags
& SVSI_SELECT
)
2351 lvItem
.state
|= LVIS_SELECTED
;
2353 lvItem
.state
&= ~LVIS_SELECTED
;
2355 if (uFlags
& SVSI_FOCUSED
)
2356 lvItem
.state
&= ~LVIS_FOCUSED
;
2360 if (uFlags
& SVSI_DESELECTOTHERS
)
2361 lvItem
.state
&= ~LVIS_SELECTED
;
2364 m_ListView
.SetItem(&lvItem
);
2368 if(uFlags
& SVSI_EDIT
)
2369 m_ListView
.EditLabel(i
);
2374 HRESULT WINAPI
CDefView::GetItemObject(UINT uItem
, REFIID riid
, LPVOID
*ppvOut
)
2376 HRESULT hr
= E_NOINTERFACE
;
2378 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n", this, uItem
, debugstr_guid(&riid
), ppvOut
);
2384 case SVGIO_BACKGROUND
:
2385 if (IsEqualIID(riid
, IID_IContextMenu
))
2387 //*ppvOut = ISvBgCm_Constructor(m_pSFParent, FALSE);
2392 hr
= CDefFolderMenu_Create2(NULL
, NULL
, 0, NULL
, m_pSFParent
, NULL
, 0, NULL
, &pcm
);
2399 case SVGIO_SELECTION
:
2401 hr
= m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, m_apidl
, riid
, 0, ppvOut
);
2405 TRACE("-- (%p)->(interface=%p)\n", this, *ppvOut
);
2410 HRESULT STDMETHODCALLTYPE
CDefView::GetCurrentViewMode(UINT
*pViewMode
)
2412 TRACE("(%p)->(%p), stub\n", this, pViewMode
);
2415 return E_INVALIDARG
;
2417 *pViewMode
= m_FolderSettings
.ViewMode
;
2421 HRESULT STDMETHODCALLTYPE
CDefView::SetCurrentViewMode(UINT ViewMode
)
2424 TRACE("(%p)->(%u), stub\n", this, ViewMode
);
2426 /* It's not redundant to check FVM_AUTO because it's a (UINT)-1 */
2427 if (((INT
)ViewMode
< FVM_FIRST
|| (INT
)ViewMode
> FVM_LAST
) && ((INT
)ViewMode
!= FVM_AUTO
))
2428 return E_INVALIDARG
;
2430 /* Windows before Vista uses LVM_SETVIEW and possibly
2431 LVM_SETEXTENDEDLISTVIEWSTYLE to set the style of the listview,
2432 while later versions seem to accomplish this through other
2440 dwStyle
= LVS_REPORT
;
2443 dwStyle
= LVS_SMALLICON
;
2450 FIXME("ViewMode %d not implemented\n", ViewMode
);
2456 SetStyle(dwStyle
, LVS_TYPEMASK
);
2458 /* This will not necessarily be the actual mode set above.
2459 This mimics the behavior of Windows XP. */
2460 m_FolderSettings
.ViewMode
= ViewMode
;
2465 HRESULT STDMETHODCALLTYPE
CDefView::GetFolder(REFIID riid
, void **ppv
)
2467 if (m_pSFParent
== NULL
)
2470 return m_pSFParent
->QueryInterface(riid
, ppv
);
2473 HRESULT STDMETHODCALLTYPE
CDefView::Item(int iItemIndex
, PITEMID_CHILD
*ppidl
)
2475 PCUITEMID_CHILD pidl
= _PidlByItem(iItemIndex
);
2478 *ppidl
= ILClone(pidl
);
2483 return E_INVALIDARG
;
2486 HRESULT STDMETHODCALLTYPE
CDefView::ItemCount(UINT uFlags
, int *pcItems
)
2488 TRACE("(%p)->(%u %p)\n", this, uFlags
, pcItems
);
2490 if (uFlags
!= SVGIO_ALLVIEW
)
2491 FIXME("some flags unsupported, %x\n", uFlags
& ~SVGIO_ALLVIEW
);
2493 *pcItems
= m_ListView
.GetItemCount();
2498 HRESULT STDMETHODCALLTYPE
CDefView::Items(UINT uFlags
, REFIID riid
, void **ppv
)
2503 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectionMarkedItem(int *piItem
)
2505 TRACE("(%p)->(%p)\n", this, piItem
);
2507 *piItem
= m_ListView
.GetSelectionMark();
2512 HRESULT STDMETHODCALLTYPE
CDefView::GetFocusedItem(int *piItem
)
2514 TRACE("(%p)->(%p)\n", this, piItem
);
2516 *piItem
= m_ListView
.GetNextItem(-1, LVNI_FOCUSED
);
2521 HRESULT STDMETHODCALLTYPE
CDefView::GetItemPosition(PCUITEMID_CHILD pidl
, POINT
*ppt
)
2526 HRESULT STDMETHODCALLTYPE
CDefView::GetSpacing(POINT
*ppt
)
2528 TRACE("(%p)->(%p)\n", this, ppt
);
2536 m_ListView
.GetItemSpacing(spacing
);
2538 ppt
->x
= spacing
.cx
;
2539 ppt
->y
= spacing
.cy
;
2545 HRESULT STDMETHODCALLTYPE
CDefView::GetDefaultSpacing(POINT
*ppt
)
2550 HRESULT STDMETHODCALLTYPE
CDefView::GetAutoArrange()
2555 HRESULT STDMETHODCALLTYPE
CDefView::SelectItem(int iItem
, DWORD dwFlags
)
2559 TRACE("(%p)->(%d, %x)\n", this, iItem
, dwFlags
);
2562 lvItem
.stateMask
= LVIS_SELECTED
;
2564 if (dwFlags
& SVSI_ENSUREVISIBLE
)
2565 m_ListView
.EnsureVisible(iItem
, 0);
2568 if (dwFlags
& SVSI_DESELECTOTHERS
)
2569 m_ListView
.SetItemState(-1, 0, LVIS_SELECTED
);
2572 if (dwFlags
& SVSI_SELECT
)
2573 lvItem
.state
|= LVIS_SELECTED
;
2575 if (dwFlags
& SVSI_FOCUSED
)
2576 lvItem
.stateMask
|= LVIS_FOCUSED
;
2578 m_ListView
.SetItemState(iItem
, lvItem
.state
, lvItem
.stateMask
);
2580 if (dwFlags
& SVSI_EDIT
)
2581 m_ListView
.EditLabel(iItem
);
2586 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItems(UINT cidl
, PCUITEMID_CHILD_ARRAY apidl
, POINT
*apt
, DWORD dwFlags
)
2591 /**********************************************************
2592 * IShellFolderView implementation
2594 HRESULT STDMETHODCALLTYPE
CDefView::Rearrange(LPARAM sort
)
2596 FIXME("(%p)->(%ld) stub\n", this, sort
);
2600 HRESULT STDMETHODCALLTYPE
CDefView::GetArrangeParam(LPARAM
*sort
)
2602 FIXME("(%p)->(%p) stub\n", this, sort
);
2606 HRESULT STDMETHODCALLTYPE
CDefView::ArrangeGrid()
2608 FIXME("(%p) stub\n", this);
2612 HRESULT STDMETHODCALLTYPE
CDefView::AutoArrange()
2614 FIXME("(%p) stub\n", this);
2618 HRESULT STDMETHODCALLTYPE
CDefView::AddObject(PITEMID_CHILD pidl
, UINT
*item
)
2620 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2624 HRESULT STDMETHODCALLTYPE
CDefView::GetObject(PITEMID_CHILD
*pidl
, UINT item
)
2626 TRACE("(%p)->(%p %d)\n", this, pidl
, item
);
2627 return Item(item
, pidl
);
2630 HRESULT STDMETHODCALLTYPE
CDefView::RemoveObject(PITEMID_CHILD pidl
, UINT
*item
)
2633 TRACE("(%p)->(%p %p)\n", this, pidl
, item
);
2637 *item
= LV_FindItemByPidl(ILFindLastID(pidl
));
2638 m_ListView
.DeleteItem(*item
);
2643 m_ListView
.DeleteAllItems();
2649 HRESULT STDMETHODCALLTYPE
CDefView::GetObjectCount(UINT
*count
)
2651 TRACE("(%p)->(%p)\n", this, count
);
2652 *count
= m_ListView
.GetItemCount();
2656 HRESULT STDMETHODCALLTYPE
CDefView::SetObjectCount(UINT count
, UINT flags
)
2658 FIXME("(%p)->(%d %x) stub\n", this, count
, flags
);
2662 HRESULT STDMETHODCALLTYPE
CDefView::UpdateObject(PITEMID_CHILD pidl_old
, PITEMID_CHILD pidl_new
, UINT
*item
)
2664 FIXME("(%p)->(%p %p %p) stub\n", this, pidl_old
, pidl_new
, item
);
2668 HRESULT STDMETHODCALLTYPE
CDefView::RefreshObject(PITEMID_CHILD pidl
, UINT
*item
)
2670 FIXME("(%p)->(%p %p) stub\n", this, pidl
, item
);
2674 HRESULT STDMETHODCALLTYPE
CDefView::SetRedraw(BOOL redraw
)
2676 TRACE("(%p)->(%d)\n", this, redraw
);
2677 m_ListView
.SetRedraw(redraw
);
2681 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedCount(UINT
*count
)
2683 FIXME("(%p)->(%p) stub\n", this, count
);
2687 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectedObjects(PCUITEMID_CHILD
**pidl
, UINT
*items
)
2689 TRACE("(%p)->(%p %p)\n", this, pidl
, items
);
2691 *items
= GetSelections();
2695 *pidl
= static_cast<PCUITEMID_CHILD
*>(LocalAlloc(0, *items
* sizeof(PCUITEMID_CHILD
)));
2698 return E_OUTOFMEMORY
;
2701 /* it's documented that caller shouldn't PIDLs, only array itself */
2702 memcpy(*pidl
, m_apidl
, *items
* sizeof(PCUITEMID_CHILD
));
2708 HRESULT STDMETHODCALLTYPE
CDefView::IsDropOnSource(IDropTarget
*drop_target
)
2710 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2714 HRESULT STDMETHODCALLTYPE
CDefView::GetDragPoint(POINT
*pt
)
2716 FIXME("(%p)->(%p) stub\n", this, pt
);
2720 HRESULT STDMETHODCALLTYPE
CDefView::GetDropPoint(POINT
*pt
)
2722 FIXME("(%p)->(%p) stub\n", this, pt
);
2726 HRESULT STDMETHODCALLTYPE
CDefView::MoveIcons(IDataObject
*obj
)
2728 TRACE("(%p)->(%p)\n", this, obj
);
2732 HRESULT STDMETHODCALLTYPE
CDefView::SetItemPos(PCUITEMID_CHILD pidl
, POINT
*pt
)
2734 FIXME("(%p)->(%p %p) stub\n", this, pidl
, pt
);
2738 HRESULT STDMETHODCALLTYPE
CDefView::IsBkDropTarget(IDropTarget
*drop_target
)
2740 FIXME("(%p)->(%p) stub\n", this, drop_target
);
2744 HRESULT STDMETHODCALLTYPE
CDefView::SetClipboard(BOOL move
)
2746 FIXME("(%p)->(%d) stub\n", this, move
);
2750 HRESULT STDMETHODCALLTYPE
CDefView::SetPoints(IDataObject
*obj
)
2752 FIXME("(%p)->(%p) stub\n", this, obj
);
2756 HRESULT STDMETHODCALLTYPE
CDefView::GetItemSpacing(ITEMSPACING
*spacing
)
2758 FIXME("(%p)->(%p) stub\n", this, spacing
);
2762 HRESULT STDMETHODCALLTYPE
CDefView::SetCallback(IShellFolderViewCB
*new_cb
, IShellFolderViewCB
**old_cb
)
2764 FIXME("(%p)->(%p %p) stub\n", this, new_cb
, old_cb
);
2768 HRESULT STDMETHODCALLTYPE
CDefView::Select(UINT flags
)
2770 FIXME("(%p)->(%d) stub\n", this, flags
);
2774 HRESULT STDMETHODCALLTYPE
CDefView::QuerySupport(UINT
*support
)
2776 TRACE("(%p)->(%p)\n", this, support
);
2780 HRESULT STDMETHODCALLTYPE
CDefView::SetAutomationObject(IDispatch
*disp
)
2782 FIXME("(%p)->(%p) stub\n", this, disp
);
2786 /**********************************************************
2787 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2789 HRESULT WINAPI
CDefView::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD
*prgCmds
, OLECMDTEXT
*pCmdText
)
2791 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
2792 this, pguidCmdGroup
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
2795 return E_INVALIDARG
;
2797 for (UINT i
= 0; i
< cCmds
; i
++)
2799 FIXME("\tprgCmds[%d].cmdID = %d\n", i
, prgCmds
[i
].cmdID
);
2800 prgCmds
[i
].cmdf
= 0;
2803 return OLECMDERR_E_UNKNOWNGROUP
;
2806 /**********************************************************
2807 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2809 * nCmdID is the OLECMDID_* enumeration
2811 HRESULT WINAPI
CDefView::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
2813 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2814 this, debugstr_guid(pguidCmdGroup
), nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2817 return OLECMDERR_E_UNKNOWNGROUP
;
2819 if (IsEqualCLSID(*pguidCmdGroup
, m_Category
))
2821 if (nCmdID
== FCIDM_SHVIEW_AUTOARRANGE
)
2823 if (V_VT(pvaIn
) != VT_INT_PTR
)
2824 return OLECMDERR_E_NOTSUPPORTED
;
2828 params
.cbSize
= sizeof(params
);
2829 params
.rcExclude
= *(RECT
*) V_INTREF(pvaIn
);
2831 HMENU hView
= m_hView
;
2833 hView
= CreatePopupMenu();
2834 AppendMenuW(hView
, MF_STRING
, FCIDM_SHVIEW_BIGICON
, L
"Big!");
2835 AppendMenuW(hView
, MF_STRING
, FCIDM_SHVIEW_SMALLICON
, L
"Small!");
2836 AppendMenuW(hView
, MF_STRING
, FCIDM_SHVIEW_LISTVIEW
, L
"List!");
2837 AppendMenuW(hView
, MF_STRING
, FCIDM_SHVIEW_REPORTVIEW
, L
"Report!");
2842 PrepareShowViewMenu(hView
);
2844 TrackPopupMenuEx(hView
, TPM_LEFTALIGN
| TPM_TOPALIGN
, params
.rcExclude
.left
, params
.rcExclude
.bottom
, m_hWndParent
, ¶ms
);
2847 // pvaOut is VT_I4 with value 0x403 (cmd id of the new mode maybe?)
2848 V_VT(pvaOut
) = VT_I4
;
2849 V_I4(pvaOut
) = 0x403;
2853 if (IsEqualIID(*pguidCmdGroup
, CGID_Explorer
) &&
2855 (nCmdexecopt
== 4) && pvaOut
)
2858 if (IsEqualIID(*pguidCmdGroup
, CGID_ShellDocView
) &&
2863 return OLECMDERR_E_UNKNOWNGROUP
;
2866 /**********************************************************
2867 * ISVDropTarget implementation
2870 /******************************************************************************
2871 * drag_notify_subitem [Internal]
2873 * Figure out the shellfolder object, which is currently under the mouse cursor
2874 * and notify it via the IDropTarget interface.
2877 #define SCROLLAREAWIDTH 20
2879 HRESULT
CDefView::drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2881 LVHITTESTINFO htinfo
;
2886 /* Map from global to client coordinates and query the index of the listview-item, which is
2887 * currently under the mouse cursor. */
2890 htinfo
.flags
= LVHT_ONITEM
;
2891 ::ScreenToClient(m_ListView
, &htinfo
.pt
);
2892 lResult
= m_ListView
.HitTest(&htinfo
);
2894 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2895 ::GetClientRect(m_ListView
, &clientRect
);
2896 if (htinfo
.pt
.x
== m_ptLastMousePos
.x
&& htinfo
.pt
.y
== m_ptLastMousePos
.y
&&
2897 (htinfo
.pt
.x
< SCROLLAREAWIDTH
|| htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
||
2898 htinfo
.pt
.y
< SCROLLAREAWIDTH
|| htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
))
2900 m_cScrollDelay
= (m_cScrollDelay
+ 1) % 5; /* DragOver is called every 50 ms */
2901 if (m_cScrollDelay
== 0)
2903 /* Mouse did hover another 250 ms over the scroll-area */
2904 if (htinfo
.pt
.x
< SCROLLAREAWIDTH
)
2905 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEUP
, 0);
2907 if (htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
)
2908 m_ListView
.SendMessageW(WM_HSCROLL
, SB_LINEDOWN
, 0);
2910 if (htinfo
.pt
.y
< SCROLLAREAWIDTH
)
2911 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEUP
, 0);
2913 if (htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
)
2914 m_ListView
.SendMessageW(WM_VSCROLL
, SB_LINEDOWN
, 0);
2919 m_cScrollDelay
= 0; /* Reset, if the cursor is not over the listview's scroll-area */
2922 m_ptLastMousePos
= htinfo
.pt
;
2924 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2925 if (m_pCurDropTarget
&& lResult
== m_iDragOverItem
)
2926 return m_pCurDropTarget
->DragOver(grfKeyState
, pt
, pdwEffect
);
2928 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2929 if (m_pCurDropTarget
)
2931 m_pCurDropTarget
->DragLeave();
2932 m_pCurDropTarget
.Release();
2935 m_iDragOverItem
= lResult
;
2938 /* We are not above one of the listview's subitems. Bind to the parent folder's
2939 * DropTarget interface. */
2940 hr
= m_pSFParent
->CreateViewObject(NULL
, IID_PPV_ARG(IDropTarget
,&m_pCurDropTarget
));
2944 /* Query the relative PIDL of the shellfolder object represented by the currently
2945 * dragged over listview-item ... */
2946 PCUITEMID_CHILD pidl
= _PidlByItem(lResult
);
2948 /* ... and bind m_pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2949 hr
= m_pSFParent
->GetUIObjectOf(m_ListView
, 1, &pidl
, IID_NULL_PPV_ARG(IDropTarget
, &m_pCurDropTarget
));
2952 /* If anything failed, m_pCurDropTarget should be NULL now, which ought to be a save state. */
2956 /* Notify the item just entered via DragEnter. */
2957 return m_pCurDropTarget
->DragEnter(m_pCurDataObject
, grfKeyState
, pt
, pdwEffect
);
2960 HRESULT WINAPI
CDefView::DragEnter(IDataObject
*pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2962 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2963 m_pCurDataObject
= pDataObject
;
2964 pDataObject
->AddRef();
2966 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2969 HRESULT WINAPI
CDefView::DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2971 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2974 HRESULT WINAPI
CDefView::DragLeave()
2976 if (m_pCurDropTarget
)
2978 m_pCurDropTarget
->DragLeave();
2979 m_pCurDropTarget
.Release();
2982 if (m_pCurDataObject
!= NULL
)
2984 m_pCurDataObject
.Release();
2987 m_iDragOverItem
= 0;
2992 HRESULT WINAPI
CDefView::Drop(IDataObject
* pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2994 if (m_pCurDropTarget
)
2996 m_pCurDropTarget
->Drop(pDataObject
, grfKeyState
, pt
, pdwEffect
);
2997 m_pCurDropTarget
.Release();
3000 m_pCurDataObject
.Release();
3001 m_iDragOverItem
= 0;
3005 /**********************************************************
3006 * ISVDropSource implementation
3009 HRESULT WINAPI
CDefView::QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
)
3011 TRACE("(%p)\n", this);
3014 return DRAGDROP_S_CANCEL
;
3015 else if (!(grfKeyState
& MK_LBUTTON
) && !(grfKeyState
& MK_RBUTTON
))
3016 return DRAGDROP_S_DROP
;
3021 HRESULT WINAPI
CDefView::GiveFeedback(DWORD dwEffect
)
3023 TRACE("(%p)\n", this);
3025 return DRAGDROP_S_USEDEFAULTCURSORS
;
3028 /**********************************************************
3029 * ISVViewObject implementation
3032 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
)
3034 FIXME("Stub: this=%p\n", this);
3039 HRESULT WINAPI
CDefView::GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
, HDC hicTargetDevice
, LOGPALETTE
**ppColorSet
)
3041 FIXME("Stub: this=%p\n", this);
3046 HRESULT WINAPI
CDefView::Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
)
3048 FIXME("Stub: this=%p\n", this);
3053 HRESULT WINAPI
CDefView::Unfreeze(DWORD dwFreeze
)
3055 FIXME("Stub: this=%p\n", this);
3060 HRESULT WINAPI
CDefView::SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
)
3062 FIXME("partial stub: %p %08x %08x %p\n", this, aspects
, advf
, pAdvSink
);
3064 /* FIXME: we set the AdviseSink, but never use it to send any advice */
3065 m_pAdvSink
= pAdvSink
;
3066 m_dwAspects
= aspects
;
3072 HRESULT WINAPI
CDefView::GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
)
3074 TRACE("this=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n", this, pAspects
, pAdvf
, ppAdvSink
);
3078 *ppAdvSink
= m_pAdvSink
;
3079 m_pAdvSink
.p
->AddRef();
3083 *pAspects
= m_dwAspects
;
3091 HRESULT STDMETHODCALLTYPE
CDefView::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
3093 if (IsEqualIID(guidService
, SID_IShellBrowser
))
3094 return m_pShellBrowser
->QueryInterface(riid
, ppvObject
);
3095 else if(IsEqualIID(guidService
, SID_IFolderView
))
3096 return QueryInterface(riid
, ppvObject
);
3098 return E_NOINTERFACE
;
3101 HRESULT
CDefView::_MergeToolbar()
3103 CComPtr
<IExplorerToolbar
> ptb
; // [sp+8h] [bp-4h]@1
3107 hr
= IUnknown_QueryService(m_pShellBrowser
, IID_IExplorerToolbar
, IID_PPV_ARG(IExplorerToolbar
, &ptb
));
3111 m_Category
= CGID_DefViewFrame
;
3113 hr
= ptb
->SetCommandTarget(static_cast<IOleCommandTarget
*>(this), &m_Category
, 0);
3121 hr
= ptb
->AddButtons(&m_Category
, buttonsCount
, buttons
);
3128 /**********************************************************
3129 * IShellView_Constructor
3131 HRESULT WINAPI
IShellView_Constructor(IShellFolder
*pFolder
, IShellView
**newView
)
3133 return ShellObjectCreatorInit
<CDefView
>(pFolder
, IID_IShellView
, newView
);
3136 HRESULT WINAPI
CDefView_Constructor(IShellFolder
*pFolder
, REFIID riid
, LPVOID
* ppvOut
)
3138 return ShellObjectCreatorInit
<CDefView
>(pFolder
, riid
, ppvOut
);