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
53 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
57 static const WCHAR SV_CLASS_NAME
[] = {'S', 'H', 'E', 'L', 'L', 'D', 'L', 'L', '_', 'D', 'e', 'f', 'V', 'i', 'e', 'w', 0};
63 } LISTVIEW_SORT_INFO
, *LPLISTVIEW_SORT_INFO
;
65 #define SHV_CHANGE_NOTIFY WM_USER + 0x1111
68 public CWindowImpl
<CDefView
, CWindow
, CControlWinTraits
>,
69 public CComObjectRootEx
<CComMultiThreadModelNoCS
>,
72 public IOleCommandTarget
,
76 public IServiceProvider
79 CComPtr
<IShellFolder
> m_pSFParent
;
80 CComPtr
<IShellFolder2
> m_pSF2Parent
;
81 CComPtr
<IShellBrowser
> m_pShellBrowser
;
82 CComPtr
<ICommDlgBrowser
> m_pCommDlgBrowser
;
83 HWND m_hWndList
; /* ListView control */
85 FOLDERSETTINGS m_FolderSettings
;
89 LPITEMIDLIST
*m_apidl
;
90 LISTVIEW_SORT_INFO m_sortInfo
;
91 ULONG m_hNotify
; /* change notification handle */
95 CComPtr
<IAdviseSink
> m_pAdvSink
;
97 CComPtr
<IDropTarget
> m_pCurDropTarget
; /* The sub-item, which is currently dragged over */
98 CComPtr
<IDataObject
> m_pCurDataObject
; /* The dragged data-object */
99 LONG m_iDragOverItem
; /* Dragged over item's index, iff m_pCurDropTarget != NULL */
100 UINT m_cScrollDelay
; /* Send a WM_*SCROLL msg every 250 ms during drag-scroll */
101 POINT m_ptLastMousePos
; /* Mouse position at last DragOver call */
103 CComPtr
<IContextMenu
> m_pCM
;
107 HRESULT WINAPI
Initialize(IShellFolder
*shellFolder
);
108 HRESULT
IncludeObject(LPCITEMIDLIST pidl
);
109 HRESULT
OnDefaultCommand();
110 HRESULT
OnStateChange(UINT uFlags
);
112 void SetStyle(DWORD dwAdd
, DWORD dwRemove
);
114 void UpdateListColors();
116 static INT CALLBACK
CompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
);
117 static INT CALLBACK
ListViewCompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
);
118 int LV_FindItemByPidl(LPCITEMIDLIST pidl
);
119 BOOLEAN
LV_AddItem(LPCITEMIDLIST pidl
);
120 BOOLEAN
LV_DeleteItem(LPCITEMIDLIST pidl
);
121 BOOLEAN
LV_RenameItem(LPCITEMIDLIST pidlOld
, LPCITEMIDLIST pidlNew
);
122 static INT CALLBACK
fill_list(LPVOID ptr
, LPVOID arg
);
124 HMENU
BuildFileMenu();
125 void MergeFileMenu(HMENU hSubMenu
);
126 void MergeViewMenu(HMENU hSubMenu
);
127 UINT
GetSelections();
128 HRESULT
OpenSelectedItems();
130 void DoActivate(UINT uState
);
131 HRESULT
drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
132 LRESULT
OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
);
134 // *** IOleWindow methods ***
135 virtual HRESULT STDMETHODCALLTYPE
GetWindow(HWND
*lphwnd
);
136 virtual HRESULT STDMETHODCALLTYPE
ContextSensitiveHelp(BOOL fEnterMode
);
138 // *** IShellView methods ***
139 virtual HRESULT STDMETHODCALLTYPE
TranslateAccelerator(MSG
*pmsg
);
140 virtual HRESULT STDMETHODCALLTYPE
EnableModeless(BOOL fEnable
);
141 virtual HRESULT STDMETHODCALLTYPE
UIActivate(UINT uState
);
142 virtual HRESULT STDMETHODCALLTYPE
Refresh();
143 virtual HRESULT STDMETHODCALLTYPE
CreateViewWindow(IShellView
*psvPrevious
, LPCFOLDERSETTINGS pfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
);
144 virtual HRESULT STDMETHODCALLTYPE
DestroyViewWindow();
145 virtual HRESULT STDMETHODCALLTYPE
GetCurrentInfo(LPFOLDERSETTINGS pfs
);
146 virtual HRESULT STDMETHODCALLTYPE
AddPropertySheetPages(DWORD dwReserved
, LPFNSVADDPROPSHEETPAGE pfn
, LPARAM lparam
);
147 virtual HRESULT STDMETHODCALLTYPE
SaveViewState();
148 virtual HRESULT STDMETHODCALLTYPE
SelectItem(LPCITEMIDLIST pidlItem
, SVSIF uFlags
);
149 virtual HRESULT STDMETHODCALLTYPE
GetItemObject(UINT uItem
, REFIID riid
, void **ppv
);
151 // *** IFolderView methods ***
152 virtual HRESULT STDMETHODCALLTYPE
GetCurrentViewMode(UINT
*pViewMode
);
153 virtual HRESULT STDMETHODCALLTYPE
SetCurrentViewMode(UINT ViewMode
);
154 virtual HRESULT STDMETHODCALLTYPE
GetFolder(REFIID riid
, void **ppv
);
155 virtual HRESULT STDMETHODCALLTYPE
Item(int iItemIndex
, LPITEMIDLIST
*ppidl
);
156 virtual HRESULT STDMETHODCALLTYPE
ItemCount(UINT uFlags
, int *pcItems
);
157 virtual HRESULT STDMETHODCALLTYPE
Items(UINT uFlags
, REFIID riid
, void **ppv
);
158 virtual HRESULT STDMETHODCALLTYPE
GetSelectionMarkedItem(int *piItem
);
159 virtual HRESULT STDMETHODCALLTYPE
GetFocusedItem(int *piItem
);
160 virtual HRESULT STDMETHODCALLTYPE
GetItemPosition(LPCITEMIDLIST pidl
, POINT
*ppt
);
161 virtual HRESULT STDMETHODCALLTYPE
GetSpacing(POINT
*ppt
);
162 virtual HRESULT STDMETHODCALLTYPE
GetDefaultSpacing(POINT
*ppt
);
163 virtual HRESULT STDMETHODCALLTYPE
GetAutoArrange();
164 virtual HRESULT STDMETHODCALLTYPE
SelectItem(int iItem
, DWORD dwFlags
);
165 virtual HRESULT STDMETHODCALLTYPE
SelectAndPositionItems(UINT cidl
, LPCITEMIDLIST
*apidl
, POINT
*apt
, DWORD dwFlags
);
167 // *** IOleCommandTarget methods ***
168 virtual HRESULT STDMETHODCALLTYPE
QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
);
169 virtual HRESULT STDMETHODCALLTYPE
Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
);
171 // *** IDropTarget methods ***
172 virtual HRESULT STDMETHODCALLTYPE
DragEnter(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
173 virtual HRESULT STDMETHODCALLTYPE
DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
174 virtual HRESULT STDMETHODCALLTYPE
DragLeave();
175 virtual HRESULT STDMETHODCALLTYPE
Drop(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
177 // *** IDropSource methods ***
178 virtual HRESULT STDMETHODCALLTYPE
QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
);
179 virtual HRESULT STDMETHODCALLTYPE
GiveFeedback(DWORD dwEffect
);
181 // *** IViewObject methods ***
182 virtual HRESULT STDMETHODCALLTYPE
Draw(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
,
183 HDC hdcTargetDev
, HDC hdcDraw
, LPCRECTL lprcBounds
, LPCRECTL lprcWBounds
,
184 BOOL ( STDMETHODCALLTYPE
*pfnContinue
)(ULONG_PTR dwContinue
), ULONG_PTR dwContinue
);
185 virtual HRESULT STDMETHODCALLTYPE
GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
,
186 DVTARGETDEVICE
*ptd
, HDC hicTargetDev
, LOGPALETTE
**ppColorSet
);
187 virtual HRESULT STDMETHODCALLTYPE
Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
);
188 virtual HRESULT STDMETHODCALLTYPE
Unfreeze(DWORD dwFreeze
);
189 virtual HRESULT STDMETHODCALLTYPE
SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
);
190 virtual HRESULT STDMETHODCALLTYPE
GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
);
192 // *** IServiceProvider methods ***
193 virtual HRESULT STDMETHODCALLTYPE
QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
);
196 LRESULT
OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
197 LRESULT
OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
198 LRESULT
OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
199 LRESULT
OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
200 LRESULT
OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
201 LRESULT
OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
202 LRESULT
OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
203 LRESULT
OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
204 LRESULT
OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
205 LRESULT
OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
206 LRESULT
OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
207 LRESULT
OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
208 LRESULT
OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
209 LRESULT
OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
210 LRESULT
OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
211 LRESULT
OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
212 LRESULT
OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
214 static ATL::CWndClassInfo
& GetWndClassInfo()
216 static ATL::CWndClassInfo wc
=
218 { sizeof(WNDCLASSEX
), 0, StartWindowProc
,
220 LoadCursor(NULL
, IDC_ARROW
), (HBRUSH
)(COLOR_BACKGROUND
+ 1), NULL
, SV_CLASS_NAME
, NULL
222 NULL
, NULL
, IDC_ARROW
, TRUE
, 0, _T("")
227 virtual WNDPROC
GetWindowProc()
232 static LRESULT CALLBACK
WindowProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
237 // must hold a reference during message handling
238 pThis
= reinterpret_cast<CDefView
*>(hWnd
);
240 result
= CWindowImpl
<CDefView
, CWindow
, CControlWinTraits
>::WindowProc(hWnd
, uMsg
, wParam
, lParam
);
245 BEGIN_MSG_MAP(CDefView
)
246 MESSAGE_HANDLER(WM_SIZE
, OnSize
)
247 MESSAGE_HANDLER(WM_SETFOCUS
, OnSetFocus
)
248 MESSAGE_HANDLER(WM_KILLFOCUS
, OnKillFocus
)
249 MESSAGE_HANDLER(WM_CREATE
, OnCreate
)
250 MESSAGE_HANDLER(WM_ACTIVATE
, OnActivate
)
251 MESSAGE_HANDLER(WM_NOTIFY
, OnNotify
)
252 MESSAGE_HANDLER(WM_COMMAND
, OnCommand
)
253 MESSAGE_HANDLER(SHV_CHANGE_NOTIFY
, OnChangeNotify
)
254 MESSAGE_HANDLER(WM_CONTEXTMENU
, OnContextMenu
)
255 MESSAGE_HANDLER(WM_DRAWITEM
, OnCustomItem
)
256 MESSAGE_HANDLER(WM_MEASUREITEM
, OnCustomItem
)
257 MESSAGE_HANDLER(WM_SHOWWINDOW
, OnShowWindow
)
258 MESSAGE_HANDLER(WM_GETDLGCODE
, OnGetDlgCode
)
259 MESSAGE_HANDLER(WM_DESTROY
, OnDestroy
)
260 MESSAGE_HANDLER(WM_ERASEBKGND
, OnEraseBackground
)
261 MESSAGE_HANDLER(WM_SYSCOLORCHANGE
, OnSysColorChange
)
262 MESSAGE_HANDLER(CWM_GETISHELLBROWSER
, OnGetShellBrowser
)
263 MESSAGE_HANDLER(WM_SETTINGCHANGE
, OnSettingChange
)
266 BEGIN_COM_MAP(CDefView
)
267 COM_INTERFACE_ENTRY_IID(IID_IOleWindow
, IOleWindow
)
268 COM_INTERFACE_ENTRY_IID(IID_IShellView
, IShellView
)
269 COM_INTERFACE_ENTRY_IID(IID_IFolderView
, IFolderView
)
270 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget
, IOleCommandTarget
)
271 COM_INTERFACE_ENTRY_IID(IID_IDropTarget
, IDropTarget
)
272 COM_INTERFACE_ENTRY_IID(IID_IDropSource
, IDropSource
)
273 COM_INTERFACE_ENTRY_IID(IID_IViewObject
, IViewObject
)
274 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider
, IServiceProvider
)
278 /* ListView Header ID's */
279 #define LISTVIEW_COLUMN_NAME 0
280 #define LISTVIEW_COLUMN_SIZE 1
281 #define LISTVIEW_COLUMN_TYPE 2
282 #define LISTVIEW_COLUMN_TIME 3
283 #define LISTVIEW_COLUMN_ATTRIB 4
286 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
287 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
288 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
290 #define ID_LISTVIEW 1
293 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
294 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
295 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
298 Items merged into the toolbar and the filemenu
307 } MYTOOLINFO
, *LPMYTOOLINFO
;
309 static const MYTOOLINFO Tools
[] =
311 { FCIDM_SHVIEW_BIGICON
, 0, 0, IDS_VIEW_LARGE
, TBSTATE_ENABLED
, BTNS_BUTTON
},
312 { FCIDM_SHVIEW_SMALLICON
, 0, 0, IDS_VIEW_SMALL
, TBSTATE_ENABLED
, BTNS_BUTTON
},
313 { FCIDM_SHVIEW_LISTVIEW
, 0, 0, IDS_VIEW_LIST
, TBSTATE_ENABLED
, BTNS_BUTTON
},
314 { FCIDM_SHVIEW_REPORTVIEW
, 0, 0, IDS_VIEW_DETAILS
, TBSTATE_ENABLED
, BTNS_BUTTON
},
318 typedef void (CALLBACK
*PFNSHGETSETTINGSPROC
)(LPSHELLFLAGSTATE lpsfs
, DWORD dwMask
);
324 m_FolderSettings
.fFlags
= 0;
325 m_FolderSettings
.ViewMode
= 0;
330 m_sortInfo
.bIsAscending
= FALSE
;
331 m_sortInfo
.nHeaderID
= 0;
332 m_sortInfo
.nLastHeaderID
= 0;
339 m_ptLastMousePos
.x
= 0;
340 m_ptLastMousePos
.y
= 0;
343 CDefView::~CDefView()
345 TRACE(" destroying IShellView(%p)\n", this);
350 HRESULT WINAPI
CDefView::Initialize(IShellFolder
*shellFolder
)
352 m_pSFParent
= shellFolder
;
353 shellFolder
->QueryInterface(IID_PPV_ARG(IShellFolder2
, &m_pSF2Parent
));
358 /**********************************************************
360 * ##### helperfunctions for communication with ICommDlgBrowser #####
362 HRESULT
CDefView::IncludeObject(LPCITEMIDLIST pidl
)
366 if (m_pCommDlgBrowser
.p
!= NULL
)
368 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl
);
369 ret
= m_pCommDlgBrowser
->IncludeObject((IShellView
*)this, pidl
);
370 TRACE("--0x%08x\n", ret
);
376 HRESULT
CDefView::OnDefaultCommand()
378 HRESULT ret
= S_FALSE
;
380 if (m_pCommDlgBrowser
.p
!= NULL
)
382 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
383 ret
= m_pCommDlgBrowser
->OnDefaultCommand((IShellView
*)this);
384 TRACE("-- returns %08x\n", ret
);
390 HRESULT
CDefView::OnStateChange(UINT uFlags
)
392 HRESULT ret
= S_FALSE
;
394 if (m_pCommDlgBrowser
.p
!= NULL
)
396 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags
);
397 ret
= m_pCommDlgBrowser
->OnStateChange((IShellView
*)this, uFlags
);
403 /**********************************************************
404 * set the toolbar of the filedialog buttons
406 * - activates the buttons from the shellbrowser according to
409 void CDefView::CheckToolbar()
415 if (m_pCommDlgBrowser
!= NULL
)
417 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
418 FCIDM_TB_SMALLICON
, (m_FolderSettings
.ViewMode
== FVM_LIST
) ? TRUE
: FALSE
, &result
);
419 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
420 FCIDM_TB_REPORTVIEW
, (m_FolderSettings
.ViewMode
== FVM_DETAILS
) ? TRUE
: FALSE
, &result
);
421 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
422 FCIDM_TB_SMALLICON
, TRUE
, &result
);
423 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
424 FCIDM_TB_REPORTVIEW
, TRUE
, &result
);
428 /**********************************************************
430 * ##### helperfunctions for initializing the view #####
432 /**********************************************************
433 * change the style of the listview control
435 void CDefView::SetStyle(DWORD dwAdd
, DWORD dwRemove
)
439 TRACE("(%p)\n", this);
441 tmpstyle
= ::GetWindowLongPtrW(m_hWndList
, GWL_STYLE
);
442 ::SetWindowLongPtrW(m_hWndList
, GWL_STYLE
, dwAdd
| (tmpstyle
& ~dwRemove
));
445 /**********************************************************
446 * ShellView_CreateList()
448 * - creates the list view window
450 BOOL
CDefView::CreateList()
451 { DWORD dwStyle
, dwExStyle
;
455 dwStyle
= WS_TABSTOP
| WS_VISIBLE
| WS_CHILDWINDOW
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
|
456 LVS_SHAREIMAGELISTS
| LVS_EDITLABELS
| LVS_AUTOARRANGE
;
457 dwExStyle
= WS_EX_CLIENTEDGE
;
459 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
460 dwStyle
|= LVS_ALIGNLEFT
;
462 dwStyle
|= LVS_ALIGNTOP
;
464 switch (m_FolderSettings
.ViewMode
)
471 dwStyle
|= LVS_REPORT
;
475 dwStyle
|= LVS_SMALLICON
;
487 if (m_FolderSettings
.fFlags
& FWF_AUTOARRANGE
)
488 dwStyle
|= LVS_AUTOARRANGE
;
490 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
491 m_FolderSettings
.fFlags
|= FWF_NOCLIENTEDGE
| FWF_NOSCROLL
;
493 if (m_FolderSettings
.fFlags
& FWF_SINGLESEL
)
494 dwStyle
|= LVS_SINGLESEL
;
496 if (m_FolderSettings
.fFlags
& FWF_NOCLIENTEDGE
)
497 dwExStyle
&= ~WS_EX_CLIENTEDGE
;
499 m_hWndList
= CreateWindowExW( dwExStyle
,
512 m_sortInfo
.bIsAscending
= TRUE
;
513 m_sortInfo
.nHeaderID
= -1;
514 m_sortInfo
.nLastHeaderID
= -1;
518 /* UpdateShellSettings(); */
522 void CDefView::UpdateListColors()
524 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
526 /* Check if drop shadows option is enabled */
527 BOOL bDropShadow
= FALSE
;
528 DWORD cbDropShadow
= sizeof(bDropShadow
);
529 WCHAR wszBuf
[16] = L
"";
531 RegGetValueW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
532 L
"ListviewShadow", RRF_RT_DWORD
, NULL
, &bDropShadow
, &cbDropShadow
);
533 if (bDropShadow
&& SystemParametersInfoW(SPI_GETDESKWALLPAPER
, _countof(wszBuf
), wszBuf
, 0) && wszBuf
[0])
535 SendMessageW(m_hWndList
, LVM_SETTEXTBKCOLOR
, 0, CLR_NONE
);
536 SendMessageW(m_hWndList
, LVM_SETBKCOLOR
, 0, CLR_NONE
);
537 SendMessageW(m_hWndList
, LVM_SETTEXTCOLOR
, 0, RGB(255, 255, 255));
538 SendMessageW(m_hWndList
, LVM_SETEXTENDEDLISTVIEWSTYLE
, LVS_EX_TRANSPARENTSHADOWTEXT
, LVS_EX_TRANSPARENTSHADOWTEXT
);
542 COLORREF crDesktop
= GetSysColor(COLOR_DESKTOP
);
543 SendMessageW(m_hWndList
, LVM_SETTEXTBKCOLOR
, 0, crDesktop
);
544 SendMessageW(m_hWndList
, LVM_SETBKCOLOR
, 0, crDesktop
);
545 if (GetRValue(crDesktop
) + GetGValue(crDesktop
) + GetBValue(crDesktop
) > 128 * 3)
546 SendMessageW(m_hWndList
, LVM_SETTEXTCOLOR
, 0, RGB(0, 0, 0));
548 SendMessageW(m_hWndList
, LVM_SETTEXTCOLOR
, 0, RGB(255, 255, 255));
549 SendMessageW(m_hWndList
, LVM_SETEXTENDEDLISTVIEWSTYLE
, LVS_EX_TRANSPARENTSHADOWTEXT
, 0);
554 /**********************************************************
555 * ShellView_InitList()
557 * - adds all needed columns to the shellview
559 BOOL
CDefView::InitList()
567 SendMessageW(m_hWndList
, LVM_DELETEALLITEMS
, 0, 0);
569 lvColumn
.mask
= LVCF_FMT
| LVCF_WIDTH
| LVCF_TEXT
;
570 lvColumn
.pszText
= szTemp
;
574 for (int i
= 0; 1; i
++)
576 if (FAILED(m_pSF2Parent
->GetDetailsOf(NULL
, i
, &sd
)))
579 lvColumn
.fmt
= sd
.fmt
;
580 lvColumn
.cx
= sd
.cxChar
* 8; /* chars->pixel */
581 StrRetToStrNW( szTemp
, 50, &sd
.str
, NULL
);
582 SendMessageW(m_hWndList
, LVM_INSERTCOLUMNW
, i
, (LPARAM
) &lvColumn
);
590 SendMessageW(m_hWndList
, LVM_SETIMAGELIST
, LVSIL_SMALL
, (LPARAM
)ShellSmallIconList
);
591 SendMessageW(m_hWndList
, LVM_SETIMAGELIST
, LVSIL_NORMAL
, (LPARAM
)ShellBigIconList
);
596 /**********************************************************
597 * ShellView_CompareItems()
600 * internal, CALLBACK for DSA_Sort
602 INT CALLBACK
CDefView::CompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
)
605 TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1
, lParam2
, (LPVOID
) lpData
);
610 ret
= (SHORT
)SCODE_CODE(((IShellFolder
*)lpData
)->CompareIDs(0, (LPITEMIDLIST
)lParam1
, (LPITEMIDLIST
)lParam2
));
611 TRACE("ret=%i\n", ret
);
616 /*************************************************************************
617 * ShellView_ListViewCompareItems
619 * Compare Function for the Listview (FileOpen Dialog)
622 * lParam1 [I] the first ItemIdList to compare with
623 * lParam2 [I] the second ItemIdList to compare with
624 * lpData [I] The column ID for the header Ctrl to process
627 * A negative value if the first item should precede the second,
628 * a positive value if the first item should follow the second,
629 * or zero if the two items are equivalent
632 * FIXME: function does what ShellView_CompareItems is supposed to do.
633 * unify it and figure out how to use the undocumented first parameter
634 * of IShellFolder_CompareIDs to do the job this function does and
635 * move this code to IShellFolder.
636 * make LISTVIEW_SORT_INFO obsolete
637 * the way this function works is only usable if we had only
638 * filesystemfolders (25/10/99 jsch)
640 INT CALLBACK
CDefView::ListViewCompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
)
644 char strName1
[MAX_PATH
], strName2
[MAX_PATH
];
645 BOOL bIsFolder1
, bIsFolder2
, bIsBothFolder
;
646 LPITEMIDLIST pItemIdList1
= (LPITEMIDLIST
) lParam1
;
647 LPITEMIDLIST pItemIdList2
= (LPITEMIDLIST
) lParam2
;
648 LISTVIEW_SORT_INFO
*pSortInfo
= (LPLISTVIEW_SORT_INFO
) lpData
;
651 bIsFolder1
= _ILIsFolder(pItemIdList1
);
652 bIsFolder2
= _ILIsFolder(pItemIdList2
);
653 bIsBothFolder
= bIsFolder1
&& bIsFolder2
;
655 /* When sorting between a File and a Folder, the Folder gets sorted first */
656 if ( (bIsFolder1
|| bIsFolder2
) && !bIsBothFolder
)
658 nDiff
= bIsFolder1
? -1 : 1;
662 /* Sort by Time: Folders or Files can be sorted */
664 if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_TIME
)
666 _ILGetFileDateTime(pItemIdList1
, &fd1
);
667 _ILGetFileDateTime(pItemIdList2
, &fd2
);
668 nDiff
= CompareFileTime(&fd2
, &fd1
);
670 /* Sort by Attribute: Folder or Files can be sorted */
671 else if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_ATTRIB
)
673 _ILGetFileAttributes(pItemIdList1
, strName1
, MAX_PATH
);
674 _ILGetFileAttributes(pItemIdList2
, strName2
, MAX_PATH
);
675 nDiff
= lstrcmpiA(strName1
, strName2
);
677 /* Sort by FileName: Folder or Files can be sorted */
678 else if (pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_NAME
|| bIsBothFolder
)
681 _ILSimpleGetText(pItemIdList1
, strName1
, MAX_PATH
);
682 _ILSimpleGetText(pItemIdList2
, strName2
, MAX_PATH
);
683 nDiff
= lstrcmpiA(strName1
, strName2
);
685 /* Sort by File Size, Only valid for Files */
686 else if (pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_SIZE
)
688 nDiff
= (INT
)(_ILGetFileSize(pItemIdList1
, NULL
, 0) - _ILGetFileSize(pItemIdList2
, NULL
, 0));
690 /* Sort by File Type, Only valid for Files */
691 else if (pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_TYPE
)
694 _ILGetFileType(pItemIdList1
, strName1
, MAX_PATH
);
695 _ILGetFileType(pItemIdList2
, strName2
, MAX_PATH
);
696 nDiff
= lstrcmpiA(strName1
, strName2
);
699 /* If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
703 _ILSimpleGetText(pItemIdList1
, strName1
, MAX_PATH
);
704 _ILSimpleGetText(pItemIdList2
, strName2
, MAX_PATH
);
705 nDiff
= lstrcmpiA(strName1
, strName2
);
708 if (!pSortInfo
->bIsAscending
)
716 /**********************************************************
717 * LV_FindItemByPidl()
719 int CDefView::LV_FindItemByPidl(LPCITEMIDLIST pidl
)
723 lvItem
.mask
= LVIF_PARAM
;
725 for (lvItem
.iItem
= 0;
726 SendMessageW(m_hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
729 LPITEMIDLIST currentpidl
= (LPITEMIDLIST
) lvItem
.lParam
;
730 HRESULT hr
= m_pSFParent
->CompareIDs(0, pidl
, currentpidl
);
732 if (SUCCEEDED(hr
) && !HRESULT_CODE(hr
))
740 /**********************************************************
743 BOOLEAN
CDefView::LV_AddItem(LPCITEMIDLIST pidl
)
747 TRACE("(%p)(pidl=%p)\n", this, pidl
);
749 lvItem
.mask
= LVIF_TEXT
| LVIF_IMAGE
| LVIF_PARAM
; /*set the mask*/
750 lvItem
.iItem
= ListView_GetItemCount(m_hWndList
); /*add the item to the end of the list*/
752 lvItem
.lParam
= (LPARAM
) ILClone(ILFindLastID(pidl
)); /*set the item's data*/
753 lvItem
.pszText
= LPSTR_TEXTCALLBACKW
; /*get text on a callback basis*/
754 lvItem
.iImage
= I_IMAGECALLBACK
; /*get the image on a callback basis*/
756 if (SendMessageW(m_hWndList
, LVM_INSERTITEMW
, 0, (LPARAM
)&lvItem
) == -1)
762 /**********************************************************
765 BOOLEAN
CDefView::LV_DeleteItem(LPCITEMIDLIST pidl
)
769 TRACE("(%p)(pidl=%p)\n", this, pidl
);
771 nIndex
= LV_FindItemByPidl(ILFindLastID(pidl
));
773 return (-1 == ListView_DeleteItem(m_hWndList
, nIndex
)) ? FALSE
: TRUE
;
776 /**********************************************************
779 BOOLEAN
CDefView::LV_RenameItem(LPCITEMIDLIST pidlOld
, LPCITEMIDLIST pidlNew
)
784 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", this, pidlOld
, pidlNew
);
786 nItem
= LV_FindItemByPidl(ILFindLastID(pidlOld
));
790 lvItem
.mask
= LVIF_PARAM
; /* only the pidl */
791 lvItem
.iItem
= nItem
;
792 SendMessageW(m_hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
794 SHFree((LPITEMIDLIST
)lvItem
.lParam
);
795 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
796 lvItem
.iItem
= nItem
;
797 lvItem
.lParam
= (LPARAM
) ILClone(ILFindLastID(pidlNew
)); /* set the item's data */
798 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
799 SendMessageW(m_hWndList
, LVM_SETITEMW
, 0, (LPARAM
) &lvItem
);
800 SendMessageW(m_hWndList
, LVM_UPDATE
, nItem
, 0);
801 return TRUE
; /* FIXME: better handling */
807 /**********************************************************
808 * ShellView_FillList()
810 * - gets the objectlist from the shellfolder
812 * - fills the list into the view
814 INT CALLBACK
CDefView::fill_list( LPVOID ptr
, LPVOID arg
)
816 LPITEMIDLIST pidl
= (LPITEMIDLIST
)ptr
;
817 CDefView
*pThis
= (CDefView
*)arg
;
818 /* in a commdlg This works as a filemask*/
819 if (pThis
->IncludeObject(pidl
) == S_OK
)
820 pThis
->LV_AddItem(pidl
);
826 HRESULT
CDefView::FillList()
828 LPENUMIDLIST pEnumIDList
;
836 /* get the itemlist from the shfolder*/
837 hRes
= m_pSFParent
->EnumObjects(m_hWnd
, SHCONTF_NONFOLDERS
| SHCONTF_FOLDERS
, &pEnumIDList
);
845 /* create a pointer array */
846 hdpa
= DPA_Create(16);
849 return(E_OUTOFMEMORY
);
852 /* copy the items into the array*/
853 while((S_OK
== pEnumIDList
->Next(1, &pidl
, &dwFetched
)) && dwFetched
)
855 if (DPA_InsertPtr(hdpa
, 0x7fff, pidl
) == -1)
862 DPA_Sort(hdpa
, CompareItems
, (LPARAM
)m_pSFParent
.p
);
864 /*turn the listview's redrawing off*/
865 SendMessageA(m_hWndList
, WM_SETREDRAW
, FALSE
, 0);
867 DPA_DestroyCallback( hdpa
, fill_list
, (void *)this);
869 /*turn the listview's redrawing back on and force it to draw*/
870 SendMessageA(m_hWndList
, WM_SETREDRAW
, TRUE
, 0);
872 pEnumIDList
->Release(); /* destroy the list*/
877 LRESULT
CDefView::OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
879 ::UpdateWindow(m_hWndList
);
884 LRESULT
CDefView::OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
886 return SendMessageW(m_hWndList
, uMsg
, 0, 0);
889 LRESULT
CDefView::OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
891 RevokeDragDrop(m_hWnd
);
892 SHChangeNotifyDeregister(m_hNotify
);
897 LRESULT
CDefView::OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
899 if (m_FolderSettings
.fFlags
& (FWF_DESKTOP
| FWF_TRANSPARENT
))
900 return SendMessageW(GetParent(), WM_ERASEBKGND
, wParam
, lParam
); /* redirect to parent */
906 LRESULT
CDefView::OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
908 /* Update desktop labels color */
911 /* Forward WM_SYSCOLORCHANGE to common controls */
912 return SendMessageW(m_hWndList
, uMsg
, 0, 0);
915 LRESULT
CDefView::OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
917 return (LRESULT
)m_pShellBrowser
.p
;
920 /**********************************************************
921 * ShellView_OnCreate()
923 LRESULT
CDefView::OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
925 CComPtr
<IDropTarget
> pdt
;
926 SHChangeNotifyEntry ntreg
;
927 CComPtr
<IPersistFolder2
> ppf2
;
939 if (SUCCEEDED(QueryInterface(IID_PPV_ARG(IDropTarget
, &pdt
))))
940 RegisterDragDrop(m_hWnd
, pdt
);
942 /* register for receiving notifications */
943 m_pSFParent
->QueryInterface(IID_PPV_ARG(IPersistFolder2
, &ppf2
));
946 ppf2
->GetCurFolder((LPITEMIDLIST
*)&ntreg
.pidl
);
947 ntreg
.fRecursive
= TRUE
;
948 m_hNotify
= SHChangeNotifyRegister(m_hWnd
, SHCNF_IDLIST
, SHCNE_ALLEVENTS
, SHV_CHANGE_NOTIFY
, 1, &ntreg
);
949 SHFree((LPITEMIDLIST
)ntreg
.pidl
);
952 m_hAccel
= LoadAcceleratorsA(shell32_hInstance
, MAKEINTRESOURCEA( IDA_SHELLVIEW
));
957 /**********************************************************
958 * #### Handling of the menus ####
961 /**********************************************************
962 * ShellView_BuildFileMenu()
964 HMENU
CDefView::BuildFileMenu()
965 { WCHAR szText
[MAX_PATH
];
970 TRACE("(%p)\n", this);
972 hSubMenu
= CreatePopupMenu();
975 /*get the number of items in our global array*/
976 for(nTools
= 0; Tools
[nTools
].idCommand
!= -1; nTools
++) {}
978 /*add the menu items*/
979 for(i
= 0; i
< nTools
; i
++)
981 LoadStringW(shell32_hInstance
, Tools
[i
].idMenuString
, szText
, MAX_PATH
);
983 ZeroMemory(&mii
, sizeof(mii
));
984 mii
.cbSize
= sizeof(mii
);
985 mii
.fMask
= MIIM_TYPE
| MIIM_ID
| MIIM_STATE
;
987 if(BTNS_SEP
!= Tools
[i
].bStyle
) /* no separator*/
989 mii
.fType
= MFT_STRING
;
990 mii
.fState
= MFS_ENABLED
;
991 mii
.dwTypeData
= szText
;
992 mii
.wID
= Tools
[i
].idCommand
;
996 mii
.fType
= MFT_SEPARATOR
;
998 /* tack This item onto the end of the menu */
999 InsertMenuItemW(hSubMenu
, (UINT
) - 1, TRUE
, &mii
);
1003 TRACE("-- return (menu=%p)\n", hSubMenu
);
1007 /**********************************************************
1008 * ShellView_MergeFileMenu()
1010 void CDefView::MergeFileMenu(HMENU hSubMenu
)
1012 TRACE("(%p)->(submenu=%p) stub\n", this, hSubMenu
);
1015 { /*insert This item at the beginning of the menu */
1016 _InsertMenuItemW(hSubMenu
, 0, TRUE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1017 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
, MFT_STRING
, L
"dummy45", MFS_ENABLED
);
1023 /**********************************************************
1024 * ShellView_MergeViewMenu()
1026 void CDefView::MergeViewMenu(HMENU hSubMenu
)
1028 TRACE("(%p)->(submenu=%p)\n", this, hSubMenu
);
1032 /*add a separator at the correct position in the menu*/
1034 static WCHAR view
[] = L
"View";
1036 _InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1038 ZeroMemory(&mii
, sizeof(mii
));
1039 mii
.cbSize
= sizeof(mii
);
1040 mii
.fMask
= MIIM_SUBMENU
| MIIM_TYPE
| MIIM_DATA
;
1041 mii
.fType
= MFT_STRING
;
1042 mii
.dwTypeData
= view
;
1043 mii
.hSubMenu
= LoadMenuW(shell32_hInstance
, L
"MENU_001");
1044 InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, &mii
);
1048 /**********************************************************
1049 * ShellView_GetSelections()
1051 * - fills the m_apidl list with the selected objects
1054 * number of selected items
1056 UINT
CDefView::GetSelections()
1063 m_cidl
= ListView_GetSelectedCount(m_hWndList
);
1064 m_apidl
= (LPITEMIDLIST
*)SHAlloc(m_cidl
* sizeof(LPITEMIDLIST
));
1066 TRACE("selected=%i\n", m_cidl
);
1070 TRACE("-- Items selected =%u\n", m_cidl
);
1072 lvItem
.mask
= LVIF_STATE
| LVIF_PARAM
;
1073 lvItem
.stateMask
= LVIS_SELECTED
;
1075 lvItem
.iSubItem
= 0;
1078 while(SendMessageW(m_hWndList
, LVM_GETITEMW
, 0, (LPARAM
)&lvItem
) && (i
< m_cidl
))
1080 if(lvItem
.state
& LVIS_SELECTED
)
1082 m_apidl
[i
] = (LPITEMIDLIST
)lvItem
.lParam
;
1086 TRACE("-- selected Item found\n");
1095 /**********************************************************
1096 * ShellView_OpenSelectedItems()
1098 HRESULT
CDefView::OpenSelectedItems()
1101 CMINVOKECOMMANDINFO cmi
;
1105 m_cidl
= ListView_GetSelectedCount(m_hWndList
);
1109 hResult
= OnDefaultCommand();
1110 if (hResult
== S_OK
)
1113 hMenu
= CreatePopupMenu();
1117 hResult
= GetItemObject( SVGIO_SELECTION
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1118 if (FAILED(hResult
))
1121 hResult
= IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1122 //if (FAILED( hResult))
1125 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, 0x20, 0x7fff, CMF_DEFAULTONLY
);
1126 if (FAILED(hResult
))
1129 uCommand
= GetMenuDefaultItem(hMenu
, FALSE
, 0);
1130 if (uCommand
== (UINT
)-1)
1136 ZeroMemory(&cmi
, sizeof(cmi
));
1137 cmi
.cbSize
= sizeof(cmi
);
1138 cmi
.lpVerb
= (LPCSTR
)MAKEINTRESOURCEA(uCommand
);
1141 hResult
= m_pCM
->InvokeCommand(&cmi
);
1150 IUnknown_SetSite(m_pCM
, NULL
);
1157 /**********************************************************
1158 * ShellView_DoContextMenu()
1160 LRESULT
CDefView::OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1166 CMINVOKECOMMANDINFO cmi
;
1169 // for some reason I haven't figured out, we sometimes recurse into this method
1176 TRACE("(%p)->(0x%08x 0x%08x) stub\n", this, x
, y
);
1178 hMenu
= CreatePopupMenu();
1182 m_cidl
= ListView_GetSelectedCount(m_hWndList
);
1184 hResult
= GetItemObject( m_cidl
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1185 if (FAILED( hResult
))
1188 hResult
= IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1189 //if (FAILED( hResult))
1192 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1193 if (FAILED( hResult
))
1196 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
1197 SetMenuDefaultItem(hMenu
, FCIDM_SHVIEW_OPEN
, MF_BYCOMMAND
);
1199 uCommand
= TrackPopupMenu(hMenu
,
1200 TPM_LEFTALIGN
| TPM_RETURNCMD
| TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
,
1201 x
, y
, 0, m_hWnd
, NULL
);
1205 if (uCommand
== FCIDM_SHVIEW_OPEN
&& OnDefaultCommand() == S_OK
)
1208 ZeroMemory(&cmi
, sizeof(cmi
));
1209 cmi
.cbSize
= sizeof(cmi
);
1210 cmi
.lpVerb
= (LPCSTR
)MAKEINTRESOURCEA(uCommand
);
1212 m_pCM
->InvokeCommand(&cmi
);
1218 IUnknown_SetSite(m_pCM
, NULL
);
1228 LRESULT
CDefView::OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
)
1231 CMINVOKECOMMANDINFO cmi
;
1234 hMenu
= CreatePopupMenu();
1238 hResult
= GetItemObject( bUseSelection
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1239 if (FAILED( hResult
))
1242 hResult
= IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1243 //if (FAILED( hResult))
1246 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1247 if (FAILED( hResult
))
1250 ZeroMemory(&cmi
, sizeof(cmi
));
1251 cmi
.cbSize
= sizeof(cmi
);
1252 cmi
.lpVerb
= (LPCSTR
)MAKEINTRESOURCEA(uCommand
);
1254 m_pCM
->InvokeCommand(&cmi
);
1260 IUnknown_SetSite(m_pCM
, NULL
);
1270 /**********************************************************
1271 * ##### message handling #####
1274 /**********************************************************
1275 * ShellView_OnSize()
1277 LRESULT
CDefView::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1282 wWidth
= LOWORD(lParam
);
1283 wHeight
= HIWORD(lParam
);
1285 TRACE("%p width=%u height=%u\n", this, wWidth
, wHeight
);
1287 /*resize the ListView to fit our window*/
1290 ::MoveWindow(m_hWndList
, 0, 0, wWidth
, wHeight
, TRUE
);
1296 /**********************************************************
1297 * ShellView_OnDeactivate()
1302 void CDefView::OnDeactivate()
1304 TRACE("%p\n", this);
1306 if (m_uState
!= SVUIA_DEACTIVATE
)
1310 m_pShellBrowser
->SetMenuSB(0, 0, 0);
1311 m_pShellBrowser
->RemoveMenusSB(m_hMenu
);
1312 DestroyMenu(m_hMenu
);
1316 m_uState
= SVUIA_DEACTIVATE
;
1320 void CDefView::DoActivate(UINT uState
)
1322 OLEMENUGROUPWIDTHS omw
= { {0, 0, 0, 0, 0, 0} };
1324 CHAR szText
[MAX_PATH
];
1326 TRACE("%p uState=%x\n", this, uState
);
1328 /*don't do anything if the state isn't really changing */
1329 if (m_uState
== uState
)
1336 /*only do This if we are active */
1337 if(uState
!= SVUIA_DEACTIVATE
)
1339 /*merge the menus */
1340 m_hMenu
= CreateMenu();
1344 m_pShellBrowser
->InsertMenusSB(m_hMenu
, &omw
);
1345 TRACE("-- after fnInsertMenusSB\n");
1347 /*build the top level menu get the menu item's text*/
1348 strcpy(szText
, "dummy 31");
1350 ZeroMemory(&mii
, sizeof(mii
));
1351 mii
.cbSize
= sizeof(mii
);
1352 mii
.fMask
= MIIM_SUBMENU
| MIIM_TYPE
| MIIM_STATE
;
1353 mii
.fType
= MFT_STRING
;
1354 mii
.fState
= MFS_ENABLED
;
1355 mii
.dwTypeData
= szText
;
1356 mii
.hSubMenu
= BuildFileMenu();
1358 /*insert our menu into the menu bar*/
1361 InsertMenuItemA(m_hMenu
, FCIDM_MENU_HELP
, FALSE
, &mii
);
1364 /*get the view menu so we can merge with it*/
1365 ZeroMemory(&mii
, sizeof(mii
));
1366 mii
.cbSize
= sizeof(mii
);
1367 mii
.fMask
= MIIM_SUBMENU
;
1369 if (GetMenuItemInfoA(m_hMenu
, FCIDM_MENU_VIEW
, FALSE
, &mii
))
1371 MergeViewMenu(mii
.hSubMenu
);
1374 /*add the items that should only be added if we have the focus*/
1375 if (SVUIA_ACTIVATE_FOCUS
== uState
)
1377 /*get the file menu so we can merge with it */
1378 ZeroMemory(&mii
, sizeof(mii
));
1379 mii
.cbSize
= sizeof(mii
);
1380 mii
.fMask
= MIIM_SUBMENU
;
1382 if (GetMenuItemInfoA(m_hMenu
, FCIDM_MENU_FILE
, FALSE
, &mii
))
1384 MergeFileMenu(mii
.hSubMenu
);
1388 TRACE("-- before fnSetMenuSB\n");
1389 m_pShellBrowser
->SetMenuSB(m_hMenu
, 0, m_hWnd
);
1396 /**********************************************************
1397 * ShellView_OnActivate()
1399 LRESULT
CDefView::OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1401 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1405 /**********************************************************
1406 * ShellView_OnSetFocus()
1409 LRESULT
CDefView::OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1411 TRACE("%p\n", this);
1413 /* Tell the browser one of our windows has received the focus. This
1414 should always be done before merging menus (OnActivate merges the
1415 menus) if one of our windows has the focus.*/
1417 m_pShellBrowser
->OnViewWindowActive((IShellView
*)this);
1418 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1420 /* Set the focus to the listview */
1421 ::SetFocus(m_hWndList
);
1423 /* Notify the ICommDlgBrowser interface */
1424 OnStateChange(CDBOSC_SETFOCUS
);
1429 /**********************************************************
1430 * ShellView_OnKillFocus()
1432 LRESULT
CDefView::OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1434 TRACE("(%p) stub\n", this);
1436 DoActivate(SVUIA_ACTIVATE_NOFOCUS
);
1437 /* Notify the ICommDlgBrowser */
1438 OnStateChange(CDBOSC_KILLFOCUS
);
1443 /**********************************************************
1444 * ShellView_OnCommand()
1447 * the CmdID's are the ones from the context menu
1449 LRESULT
CDefView::OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1455 dwCmdID
= GET_WM_COMMAND_ID(wParam
, lParam
);
1456 dwCmd
= GET_WM_COMMAND_CMD(wParam
, lParam
);
1457 hwndCmd
= GET_WM_COMMAND_HWND(wParam
, lParam
);
1459 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n", this, dwCmdID
, dwCmd
, hwndCmd
);
1463 case FCIDM_SHVIEW_SMALLICON
:
1464 m_FolderSettings
.ViewMode
= FVM_SMALLICON
;
1465 SetStyle (LVS_SMALLICON
, LVS_TYPEMASK
);
1469 case FCIDM_SHVIEW_BIGICON
:
1470 m_FolderSettings
.ViewMode
= FVM_ICON
;
1471 SetStyle (LVS_ICON
, LVS_TYPEMASK
);
1475 case FCIDM_SHVIEW_LISTVIEW
:
1476 m_FolderSettings
.ViewMode
= FVM_LIST
;
1477 SetStyle (LVS_LIST
, LVS_TYPEMASK
);
1481 case FCIDM_SHVIEW_REPORTVIEW
:
1482 m_FolderSettings
.ViewMode
= FVM_DETAILS
;
1483 SetStyle (LVS_REPORT
, LVS_TYPEMASK
);
1487 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1492 m_sortInfo
.nHeaderID
= (LPARAM
) (dwCmdID
- 0x30);
1493 m_sortInfo
.bIsAscending
= TRUE
;
1494 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
1495 SendMessageA(m_hWndList
, LVM_SORTITEMS
, (WPARAM
) &m_sortInfo
, (LPARAM
)ListViewCompareItems
);
1498 case FCIDM_SHVIEW_REFRESH
:
1502 case FCIDM_SHVIEW_DELETE
:
1503 case FCIDM_SHVIEW_CUT
:
1504 case FCIDM_SHVIEW_COPY
:
1505 case FCIDM_SHVIEW_RENAME
:
1506 return OnExplorerCommand(dwCmdID
, TRUE
);
1508 case FCIDM_SHVIEW_INSERT
:
1509 case FCIDM_SHVIEW_UNDO
:
1510 case FCIDM_SHVIEW_INSERTLINK
:
1511 case FCIDM_SHVIEW_NEWFOLDER
:
1512 return OnExplorerCommand(dwCmdID
, FALSE
);
1514 TRACE("-- COMMAND 0x%04x unhandled\n", dwCmdID
);
1520 /**********************************************************
1521 * ShellView_OnNotify()
1524 LRESULT
CDefView::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1528 LPNMLISTVIEW lpnmlv
;
1529 NMLVDISPINFOW
*lpdi
;
1534 lpnmh
= (LPNMHDR
)lParam
;
1535 lpnmlv
= (LPNMLISTVIEW
)lpnmh
;
1536 lpdi
= (NMLVDISPINFOW
*)lpnmh
;
1538 TRACE("%p CtlID=%u lpnmh->code=%x\n", this, CtlID
, lpnmh
->code
);
1540 switch (lpnmh
->code
)
1543 TRACE("-- NM_SETFOCUS %p\n", this);
1544 OnSetFocus(0, 0, 0, unused
);
1548 TRACE("-- NM_KILLFOCUS %p\n", this);
1550 /* Notify the ICommDlgBrowser interface */
1551 OnStateChange(CDBOSC_KILLFOCUS
);
1555 TRACE("-- NM_CUSTOMDRAW %p\n", this);
1556 return CDRF_DODEFAULT
;
1558 case NM_RELEASEDCAPTURE
:
1559 TRACE("-- NM_RELEASEDCAPTURE %p\n", this);
1563 TRACE("-- NM_CLICK %p\n", this);
1567 TRACE("-- NM_RCLICK %p\n", this);
1571 TRACE("-- NM_DBLCLK %p\n", this);
1572 OpenSelectedItems();
1576 TRACE("-- NM_RETURN %p\n", this);
1577 OpenSelectedItems();
1581 TRACE("-- HDN_ENDTRACKW %p\n", this);
1582 /*nColumn1 = ListView_GetColumnWidth(m_hWndList, 0);
1583 nColumn2 = ListView_GetColumnWidth(m_hWndList, 1);*/
1586 case LVN_DELETEITEM
:
1587 TRACE("-- LVN_DELETEITEM %p\n", this);
1588 SHFree((LPITEMIDLIST
)lpnmlv
->lParam
); /*delete the pidl because we made a copy of it*/
1591 case LVN_DELETEALLITEMS
:
1592 TRACE("-- LVN_DELETEALLITEMS %p\n", this);
1595 case LVN_INSERTITEM
:
1596 TRACE("-- LVN_INSERTITEM (STUB)%p\n", this);
1599 case LVN_ITEMACTIVATE
:
1600 TRACE("-- LVN_ITEMACTIVATE %p\n", this);
1601 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1604 case LVN_COLUMNCLICK
:
1605 m_sortInfo
.nHeaderID
= lpnmlv
->iSubItem
;
1606 if (m_sortInfo
.nLastHeaderID
== m_sortInfo
.nHeaderID
)
1608 m_sortInfo
.bIsAscending
= !m_sortInfo
.bIsAscending
;
1612 m_sortInfo
.bIsAscending
= TRUE
;
1614 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
1616 SendMessageW(lpnmlv
->hdr
.hwndFrom
, LVM_SORTITEMS
, (WPARAM
) &m_sortInfo
, (LPARAM
)ListViewCompareItems
);
1619 case LVN_GETDISPINFOA
:
1620 case LVN_GETDISPINFOW
:
1621 TRACE("-- LVN_GETDISPINFO %p\n", this);
1622 pidl
= (LPITEMIDLIST
)lpdi
->item
.lParam
;
1624 if (lpdi
->item
.mask
& LVIF_TEXT
) /* text requested */
1629 if (FAILED(m_pSF2Parent
->GetDetailsOf(pidl
, lpdi
->item
.iSubItem
, &sd
)))
1631 FIXME("failed to get details\n");
1635 if (lpnmh
->code
== LVN_GETDISPINFOA
)
1637 /* shouldn't happen */
1638 NMLVDISPINFOA
*lpdiA
= (NMLVDISPINFOA
*)lpnmh
;
1639 StrRetToStrNA( lpdiA
->item
.pszText
, lpdiA
->item
.cchTextMax
, &sd
.str
, NULL
);
1640 TRACE("-- text=%s\n", lpdiA
->item
.pszText
);
1642 else /* LVN_GETDISPINFOW */
1644 StrRetToStrNW( lpdi
->item
.pszText
, lpdi
->item
.cchTextMax
, &sd
.str
, NULL
);
1645 TRACE("-- text=%s\n", debugstr_w(lpdi
->item
.pszText
));
1653 if(lpdi
->item
.mask
& LVIF_IMAGE
) /* image requested */
1655 lpdi
->item
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
1657 lpdi
->item
.mask
|= LVIF_DI_SETITEM
;
1660 case LVN_ITEMCHANGED
:
1661 TRACE("-- LVN_ITEMCHANGED %p\n", this);
1662 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1666 case LVN_BEGINRDRAG
:
1667 TRACE("-- LVN_BEGINDRAG\n");
1669 if (GetSelections())
1672 DWORD dwAttributes
= SFGAO_CANLINK
;
1673 DWORD dwEffect
= DROPEFFECT_COPY
| DROPEFFECT_MOVE
;
1675 if (SUCCEEDED(m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, (LPCITEMIDLIST
*)m_apidl
, IID_IDataObject
, 0, (LPVOID
*)&pda
)))
1677 IDropSource
* pds
= (IDropSource
*)this; /* own DropSource interface */
1679 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(m_cidl
, (LPCITEMIDLIST
*)m_apidl
, &dwAttributes
)))
1681 if (dwAttributes
& SFGAO_CANLINK
)
1683 dwEffect
|= DROPEFFECT_LINK
;
1690 DoDragDrop(pda
, pds
, dwEffect
, &dwEffect2
);
1697 case LVN_BEGINLABELEDITW
:
1699 DWORD dwAttr
= SFGAO_CANRENAME
;
1700 pidl
= (LPITEMIDLIST
)lpdi
->item
.lParam
;
1702 TRACE("-- LVN_BEGINLABELEDITW %p\n", this);
1704 m_pSFParent
->GetAttributesOf(1, (LPCITEMIDLIST
*)&pidl
, &dwAttr
);
1705 if (SFGAO_CANRENAME
& dwAttr
)
1712 case LVN_ENDLABELEDITW
:
1714 TRACE("-- LVN_ENDLABELEDITW %p\n", this);
1715 if (lpdi
->item
.pszText
)
1720 lvItem
.iItem
= lpdi
->item
.iItem
;
1721 lvItem
.iSubItem
= 0;
1722 lvItem
.mask
= LVIF_PARAM
;
1723 SendMessageW(m_hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
1725 pidl
= (LPITEMIDLIST
)lpdi
->item
.lParam
;
1726 hr
= m_pSFParent
->SetNameOf(0, pidl
, lpdi
->item
.pszText
, SHGDN_INFOLDER
, &pidl
);
1728 if (SUCCEEDED(hr
) && pidl
)
1730 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
1731 lvItem
.lParam
= (LPARAM
)pidl
;
1732 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
1733 SendMessageW(m_hWndList
, LVM_SETITEMW
, 0, (LPARAM
) &lvItem
);
1734 SendMessageW(m_hWndList
, LVM_UPDATE
, lpdi
->item
.iItem
, 0);
1745 LPNMLVKEYDOWN plvKeyDown
= (LPNMLVKEYDOWN
) lpnmh
;
1747 /* initiate a rename of the selected file or directory */
1748 if (plvKeyDown
->wVKey
== VK_BACK
)
1750 LPSHELLBROWSER lpSb
;
1751 if ((lpSb
= (LPSHELLBROWSER
)SendMessageW(m_hWndParent
, CWM_GETISHELLBROWSER
, 0, 0)))
1753 lpSb
->BrowseObject(NULL
, SBSP_PARENT
);
1758 FIXME("LVN_KEYDOWN key=0x%08x\n", plvKeyDown
->wVKey
);
1763 TRACE("-- %p WM_COMMAND %x unhandled\n", this, lpnmh
->code
);
1770 /**********************************************************
1771 * ShellView_OnChange()
1773 LRESULT
CDefView::OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1775 LPITEMIDLIST
*Pidls
;
1777 Pidls
= (LPITEMIDLIST
*)wParam
;
1779 TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls
[0], Pidls
[1], lParam
);
1785 LV_AddItem(Pidls
[0]);
1790 LV_DeleteItem(Pidls
[0]);
1793 case SHCNE_RENAMEFOLDER
:
1794 case SHCNE_RENAMEITEM
:
1795 LV_RenameItem(Pidls
[0], Pidls
[1]);
1798 case SHCNE_UPDATEITEM
:
1805 /**********************************************************
1806 * CDefView::OnCustomItem
1808 LRESULT
CDefView::OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1813 ERR("no menu!!!\n");
1817 CComPtr
<IContextMenu2
> pCM2
;
1818 HRESULT hres
= m_pCM
.p
->QueryInterface(IID_PPV_ARG(IContextMenu2
, &pCM2
));
1822 if (pCM2
.p
->HandleMenuMsg(uMsg
, (WPARAM
)m_hWnd
, lParam
) == S_OK
)
1828 LRESULT
CDefView::OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1830 /* Wallpaper setting affects drop shadows effect */
1831 if (wParam
== SPI_SETDESKWALLPAPER
|| wParam
== 0)
1837 /**********************************************************
1840 * The INTERFACE of the IShellView object
1843 **********************************************************
1846 /**********************************************************
1847 * ShellView_GetWindow
1849 HRESULT WINAPI
CDefView::GetWindow(HWND
*phWnd
)
1851 TRACE("(%p)\n", this);
1858 HRESULT WINAPI
CDefView::ContextSensitiveHelp(BOOL fEnterMode
)
1860 FIXME("(%p) stub\n", this);
1865 /**********************************************************
1866 * IShellView_TranslateAccelerator
1869 * use the accel functions
1871 HRESULT WINAPI
CDefView::TranslateAccelerator(LPMSG lpmsg
)
1873 if (lpmsg
->message
>= WM_KEYFIRST
&& lpmsg
->message
<= WM_KEYLAST
)
1875 if (::TranslateAcceleratorW(m_hWnd
, m_hAccel
, lpmsg
) != 0)
1878 /* FIXME: should call TranslateAcceleratorSB */
1880 TRACE("-- key=0x04%lx\n", lpmsg
->wParam
) ;
1883 return S_FALSE
; /* not handled */
1886 HRESULT WINAPI
CDefView::EnableModeless(BOOL fEnable
)
1888 FIXME("(%p) stub\n", this);
1893 HRESULT WINAPI
CDefView::UIActivate(UINT uState
)
1896 CHAR szName[MAX_PATH];
1899 int nPartArray
[1] = { -1};
1901 TRACE("(%p)->(state=%x) stub\n", this, uState
);
1903 /*don't do anything if the state isn't really changing*/
1904 if (m_uState
== uState
)
1909 /*OnActivate handles the menu merging and internal state*/
1912 /*only do This if we are active*/
1913 if (uState
!= SVUIA_DEACTIVATE
)
1917 GetFolderPath is not a method of IShellFolder
1918 IShellFolder_GetFolderPath( m_pSFParent, szName, sizeof(szName) );
1920 /* set the number of parts */
1921 m_pShellBrowser
->SendControlMsg(FCW_STATUS
, SB_SETPARTS
, 1, (LPARAM
)nPartArray
, &lResult
);
1923 /* set the text for the parts */
1925 m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXTA, 0, (LPARAM)szName, &lResult);
1932 HRESULT WINAPI
CDefView::Refresh()
1934 TRACE("(%p)\n", this);
1936 SendMessageW(m_hWndList
, LVM_DELETEALLITEMS
, 0, 0);
1942 HRESULT WINAPI
CDefView::CreateViewWindow(IShellView
*lpPrevView
, LPCFOLDERSETTINGS lpfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
)
1946 TRACE("(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n", this, lpPrevView
, lpfs
, psb
, prcView
, phWnd
);
1949 TRACE("-- vmode=%x flags=%x\n", lpfs
->ViewMode
, lpfs
->fFlags
);
1950 if (prcView
!= NULL
)
1951 TRACE("-- left=%i top=%i right=%i bottom=%i\n", prcView
->left
, prcView
->top
, prcView
->right
, prcView
->bottom
);
1953 /* Validate the Shell Browser */
1955 return E_UNEXPECTED
;
1957 /*set up the member variables*/
1958 m_pShellBrowser
= psb
;
1959 m_FolderSettings
= *lpfs
;
1961 /*get our parent window*/
1962 m_pShellBrowser
->GetWindow(&m_hWndParent
);
1964 /* try to get the ICommDlgBrowserInterface, adds a reference !!! */
1965 m_pCommDlgBrowser
= NULL
;
1966 if (SUCCEEDED(m_pShellBrowser
->QueryInterface(IID_PPV_ARG(ICommDlgBrowser
, &m_pCommDlgBrowser
))))
1968 TRACE("-- CommDlgBrowser\n");
1971 Create(m_hWndParent
, prcView
, NULL
, WS_CHILD
| WS_TABSTOP
, 0, 0U);
1982 SetWindowPos(HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_SHOWWINDOW
);
1988 HRESULT WINAPI
CDefView::DestroyViewWindow()
1990 TRACE("(%p)\n", this);
1992 /*Make absolutely sure all our UI is cleaned up.*/
1993 UIActivate(SVUIA_DEACTIVATE
);
1997 DestroyMenu(m_hMenu
);
2001 m_pShellBrowser
.Release();
2002 m_pCommDlgBrowser
.Release();
2007 HRESULT WINAPI
CDefView::GetCurrentInfo(LPFOLDERSETTINGS lpfs
)
2009 TRACE("(%p)->(%p) vmode=%x flags=%x\n", this, lpfs
,
2010 m_FolderSettings
.ViewMode
, m_FolderSettings
.fFlags
);
2013 return E_INVALIDARG
;
2015 *lpfs
= m_FolderSettings
;
2019 HRESULT WINAPI
CDefView::AddPropertySheetPages(DWORD dwReserved
, LPFNADDPROPSHEETPAGE lpfn
, LPARAM lparam
)
2021 FIXME("(%p) stub\n", this);
2026 HRESULT WINAPI
CDefView::SaveViewState()
2028 FIXME("(%p) stub\n", this);
2033 HRESULT WINAPI
CDefView::SelectItem(LPCITEMIDLIST pidl
, UINT uFlags
)
2037 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n", this, pidl
, uFlags
);
2039 i
= LV_FindItemByPidl(pidl
);
2045 if(uFlags
& SVSI_ENSUREVISIBLE
)
2046 SendMessageW(m_hWndList
, LVM_ENSUREVISIBLE
, i
, 0);
2048 lvItem
.mask
= LVIF_STATE
;
2049 lvItem
.stateMask
= LVIS_SELECTED
| LVIS_FOCUSED
;
2051 lvItem
.iSubItem
= 0;
2053 while (SendMessageW(m_hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
))
2055 if (lvItem
.iItem
== i
)
2057 if (uFlags
& SVSI_SELECT
)
2058 lvItem
.state
|= LVIS_SELECTED
;
2060 lvItem
.state
&= ~LVIS_SELECTED
;
2062 if (uFlags
& SVSI_FOCUSED
)
2063 lvItem
.state
&= ~LVIS_FOCUSED
;
2067 if (uFlags
& SVSI_DESELECTOTHERS
)
2068 lvItem
.state
&= ~LVIS_SELECTED
;
2071 SendMessageW(m_hWndList
, LVM_SETITEMW
, 0, (LPARAM
) &lvItem
);
2076 if(uFlags
& SVSI_EDIT
)
2077 SendMessageW(m_hWndList
, LVM_EDITLABELW
, i
, 0);
2083 HRESULT WINAPI
CDefView::GetItemObject(UINT uItem
, REFIID riid
, LPVOID
*ppvOut
)
2085 HRESULT hr
= E_NOINTERFACE
;
2087 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n", this, uItem
, debugstr_guid(&riid
), ppvOut
);
2093 case SVGIO_BACKGROUND
:
2094 if (IsEqualIID(riid
, IID_IContextMenu
))
2096 //*ppvOut = ISvBgCm_Constructor(m_pSFParent, FALSE);
2097 CDefFolderMenu_Create2(NULL
, NULL
, 0, NULL
, m_pSFParent
, NULL
, 0, NULL
, (IContextMenu
**)ppvOut
);
2105 case SVGIO_SELECTION
:
2107 hr
= m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, (LPCITEMIDLIST
*)m_apidl
, riid
, 0, ppvOut
);
2111 TRACE("-- (%p)->(interface=%p)\n", this, *ppvOut
);
2116 HRESULT STDMETHODCALLTYPE
CDefView::GetCurrentViewMode(UINT
*pViewMode
)
2118 TRACE("(%p)->(%p), stub\n", this, pViewMode
);
2121 return E_INVALIDARG
;
2123 *pViewMode
= m_FolderSettings
.ViewMode
;
2127 HRESULT STDMETHODCALLTYPE
CDefView::SetCurrentViewMode(UINT ViewMode
)
2130 TRACE("(%p)->(%u), stub\n", this, ViewMode
);
2132 /* It's not redundant to check FVM_AUTO because it's a (UINT)-1 */
2133 if ((ViewMode
< FVM_FIRST
|| ViewMode
> FVM_LAST
) && (ViewMode
!= (UINT
)FVM_AUTO
))
2134 return E_INVALIDARG
;
2136 /* Windows before Vista uses LVM_SETVIEW and possibly
2137 LVM_SETEXTENDEDLISTVIEWSTYLE to set the style of the listview,
2138 while later versions seem to accomplish this through other
2146 dwStyle
= LVS_REPORT
;
2149 dwStyle
= LVS_SMALLICON
;
2156 FIXME("ViewMode %d not implemented\n", ViewMode
);
2162 SetStyle(dwStyle
, LVS_TYPEMASK
);
2164 /* This will not necessarily be the actual mode set above.
2165 This mimics the behavior of Windows XP. */
2166 m_FolderSettings
.ViewMode
= ViewMode
;
2171 HRESULT STDMETHODCALLTYPE
CDefView::GetFolder(REFIID riid
, void **ppv
)
2173 if (m_pSFParent
== NULL
)
2176 return m_pSFParent
->QueryInterface(riid
, ppv
);
2179 HRESULT STDMETHODCALLTYPE
CDefView::Item(int iItemIndex
, LPITEMIDLIST
*ppidl
)
2183 TRACE("(%p)->(%d %p)\n", this, iItemIndex
, ppidl
);
2185 item
.mask
= LVIF_PARAM
;
2186 item
.iItem
= iItemIndex
;
2188 if (SendMessageW(m_hWndList
, LVM_GETITEMW
, 0, (LPARAM
)&item
))
2190 *ppidl
= ILClone((PITEMID_CHILD
)item
.lParam
);
2196 return E_INVALIDARG
;
2199 HRESULT STDMETHODCALLTYPE
CDefView::ItemCount(UINT uFlags
, int *pcItems
)
2201 TRACE("(%p)->(%u %p)\n", this, uFlags
, pcItems
);
2203 if (uFlags
!= SVGIO_ALLVIEW
)
2204 FIXME("some flags unsupported, %x\n", uFlags
& ~SVGIO_ALLVIEW
);
2206 *pcItems
= SendMessageW(m_hWndList
, LVM_GETITEMCOUNT
, 0, 0);
2211 HRESULT STDMETHODCALLTYPE
CDefView::Items(UINT uFlags
, REFIID riid
, void **ppv
)
2216 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectionMarkedItem(int *piItem
)
2218 TRACE("(%p)->(%p)\n", this, piItem
);
2220 *piItem
= SendMessageW(m_hWndList
, LVM_GETSELECTIONMARK
, 0, 0);
2225 HRESULT STDMETHODCALLTYPE
CDefView::GetFocusedItem(int *piItem
)
2227 TRACE("(%p)->(%p)\n", this, piItem
);
2229 *piItem
= SendMessageW(m_hWndList
, LVM_GETNEXTITEM
, -1, LVNI_FOCUSED
);
2234 HRESULT STDMETHODCALLTYPE
CDefView::GetItemPosition(LPCITEMIDLIST pidl
, POINT
*ppt
)
2239 HRESULT STDMETHODCALLTYPE
CDefView::GetSpacing(POINT
*ppt
)
2241 TRACE("(%p)->(%p)\n", this, ppt
);
2243 if (NULL
== m_hWndList
) return S_FALSE
;
2247 const DWORD ret
= SendMessageW(m_hWndList
, LVM_GETITEMSPACING
, 0, 0);
2249 ppt
->x
= LOWORD(ret
);
2250 ppt
->y
= HIWORD(ret
);
2256 HRESULT STDMETHODCALLTYPE
CDefView::GetDefaultSpacing(POINT
*ppt
)
2261 HRESULT STDMETHODCALLTYPE
CDefView::GetAutoArrange()
2266 HRESULT STDMETHODCALLTYPE
CDefView::SelectItem(int iItem
, DWORD dwFlags
)
2270 TRACE("(%p)->(%d, %x)\n", this, iItem
, dwFlags
);
2273 lvItem
.stateMask
= LVIS_SELECTED
;
2275 if (dwFlags
& SVSI_ENSUREVISIBLE
)
2276 SendMessageW(m_hWndList
, LVM_ENSUREVISIBLE
, iItem
, 0);
2279 if (dwFlags
& SVSI_DESELECTOTHERS
)
2280 SendMessageW(m_hWndList
, LVM_SETITEMSTATE
, -1, (LPARAM
)&lvItem
);
2283 if (dwFlags
& SVSI_SELECT
)
2284 lvItem
.state
|= LVIS_SELECTED
;
2286 if (dwFlags
& SVSI_FOCUSED
)
2287 lvItem
.stateMask
|= LVIS_FOCUSED
;
2289 SendMessageW(m_hWndList
, LVM_SETITEMSTATE
, iItem
, (LPARAM
)&lvItem
);
2291 if (dwFlags
& SVSI_EDIT
)
2292 SendMessageW(m_hWndList
, LVM_EDITLABELW
, iItem
, 0);
2297 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItems(UINT cidl
, LPCITEMIDLIST
*apidl
, POINT
*apt
, DWORD dwFlags
)
2302 /**********************************************************
2303 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2305 HRESULT WINAPI
CDefView::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD
*prgCmds
, OLECMDTEXT
*pCmdText
)
2307 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
2308 this, pguidCmdGroup
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
2311 return E_INVALIDARG
;
2313 for (UINT i
= 0; i
< cCmds
; i
++)
2315 FIXME("\tprgCmds[%d].cmdID = %d\n", i
, prgCmds
[i
].cmdID
);
2316 prgCmds
[i
].cmdf
= 0;
2319 return OLECMDERR_E_UNKNOWNGROUP
;
2322 /**********************************************************
2323 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2325 * nCmdID is the OLECMDID_* enumeration
2327 HRESULT WINAPI
CDefView::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
2329 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2330 this, debugstr_guid(pguidCmdGroup
), nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2333 return OLECMDERR_E_UNKNOWNGROUP
;
2335 if (IsEqualIID(*pguidCmdGroup
, CGID_Explorer
) &&
2337 (nCmdexecopt
== 4) && pvaOut
)
2340 if (IsEqualIID(*pguidCmdGroup
, CGID_ShellDocView
) &&
2345 return OLECMDERR_E_UNKNOWNGROUP
;
2348 /**********************************************************
2349 * ISVDropTarget implementation
2352 /******************************************************************************
2353 * drag_notify_subitem [Internal]
2355 * Figure out the shellfolder object, which is currently under the mouse cursor
2356 * and notify it via the IDropTarget interface.
2359 #define SCROLLAREAWIDTH 20
2361 HRESULT
CDefView::drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2363 LVHITTESTINFO htinfo
;
2369 /* Map from global to client coordinates and query the index of the listview-item, which is
2370 * currently under the mouse cursor. */
2373 htinfo
.flags
= LVHT_ONITEM
;
2374 ::ScreenToClient(m_hWndList
, &htinfo
.pt
);
2375 lResult
= SendMessageW(m_hWndList
, LVM_HITTEST
, 0, (LPARAM
)&htinfo
);
2377 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2378 ::GetClientRect(m_hWndList
, &clientRect
);
2379 if (htinfo
.pt
.x
== m_ptLastMousePos
.x
&& htinfo
.pt
.y
== m_ptLastMousePos
.y
&&
2380 (htinfo
.pt
.x
< SCROLLAREAWIDTH
|| htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
||
2381 htinfo
.pt
.y
< SCROLLAREAWIDTH
|| htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
))
2383 m_cScrollDelay
= (m_cScrollDelay
+ 1) % 5; /* DragOver is called every 50 ms */
2384 if (m_cScrollDelay
== 0)
2386 /* Mouse did hover another 250 ms over the scroll-area */
2387 if (htinfo
.pt
.x
< SCROLLAREAWIDTH
)
2388 SendMessageW(m_hWndList
, WM_HSCROLL
, SB_LINEUP
, 0);
2390 if (htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
)
2391 SendMessageW(m_hWndList
, WM_HSCROLL
, SB_LINEDOWN
, 0);
2393 if (htinfo
.pt
.y
< SCROLLAREAWIDTH
)
2394 SendMessageW(m_hWndList
, WM_VSCROLL
, SB_LINEUP
, 0);
2396 if (htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
)
2397 SendMessageW(m_hWndList
, WM_VSCROLL
, SB_LINEDOWN
, 0);
2402 m_cScrollDelay
= 0; /* Reset, if the cursor is not over the listview's scroll-area */
2405 m_ptLastMousePos
= htinfo
.pt
;
2407 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2408 if (m_pCurDropTarget
&& lResult
== m_iDragOverItem
)
2409 return m_pCurDropTarget
->DragOver(grfKeyState
, pt
, pdwEffect
);
2411 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2412 if (m_pCurDropTarget
)
2414 m_pCurDropTarget
->DragLeave();
2415 m_pCurDropTarget
.Release();
2418 m_iDragOverItem
= lResult
;
2421 /* We are not above one of the listview's subitems. Bind to the parent folder's
2422 * DropTarget interface. */
2423 hr
= m_pSFParent
->QueryInterface(IID_PPV_ARG(IDropTarget
,&m_pCurDropTarget
));
2427 /* Query the relative PIDL of the shellfolder object represented by the currently
2428 * dragged over listview-item ... */
2429 lvItem
.mask
= LVIF_PARAM
;
2430 lvItem
.iItem
= lResult
;
2431 lvItem
.iSubItem
= 0;
2432 SendMessageW(m_hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
2434 /* ... and bind m_pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2435 hr
= m_pSFParent
->GetUIObjectOf(m_hWndList
, 1,
2436 (LPCITEMIDLIST
*)&lvItem
.lParam
, IID_IDropTarget
, NULL
, (LPVOID
*)&m_pCurDropTarget
);
2439 /* If anything failed, m_pCurDropTarget should be NULL now, which ought to be a save state. */
2443 /* Notify the item just entered via DragEnter. */
2444 return m_pCurDropTarget
->DragEnter(m_pCurDataObject
, grfKeyState
, pt
, pdwEffect
);
2447 HRESULT WINAPI
CDefView::DragEnter(IDataObject
*pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2449 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2450 m_pCurDataObject
= pDataObject
;
2451 pDataObject
->AddRef();
2453 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2456 HRESULT WINAPI
CDefView::DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2458 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2461 HRESULT WINAPI
CDefView::DragLeave()
2463 if (m_pCurDropTarget
)
2465 m_pCurDropTarget
->DragLeave();
2466 m_pCurDropTarget
.Release();
2469 if (m_pCurDataObject
!= NULL
)
2471 m_pCurDataObject
.Release();
2474 m_iDragOverItem
= 0;
2479 HRESULT WINAPI
CDefView::Drop(IDataObject
* pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2481 if (m_pCurDropTarget
)
2483 m_pCurDropTarget
->Drop(pDataObject
, grfKeyState
, pt
, pdwEffect
);
2484 m_pCurDropTarget
.Release();
2487 m_pCurDataObject
.Release();
2488 m_iDragOverItem
= 0;
2493 /**********************************************************
2494 * ISVDropSource implementation
2497 HRESULT WINAPI
CDefView::QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
)
2499 TRACE("(%p)\n", this);
2502 return DRAGDROP_S_CANCEL
;
2503 else if (!(grfKeyState
& MK_LBUTTON
) && !(grfKeyState
& MK_RBUTTON
))
2504 return DRAGDROP_S_DROP
;
2509 HRESULT WINAPI
CDefView::GiveFeedback(DWORD dwEffect
)
2511 TRACE("(%p)\n", this);
2513 return DRAGDROP_S_USEDEFAULTCURSORS
;
2516 /**********************************************************
2517 * ISVViewObject implementation
2520 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
)
2522 FIXME("Stub: this=%p\n", this);
2527 HRESULT WINAPI
CDefView::GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
, HDC hicTargetDevice
, LOGPALETTE
**ppColorSet
)
2529 FIXME("Stub: this=%p\n", this);
2534 HRESULT WINAPI
CDefView::Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
)
2536 FIXME("Stub: this=%p\n", this);
2541 HRESULT WINAPI
CDefView::Unfreeze(DWORD dwFreeze
)
2543 FIXME("Stub: this=%p\n", this);
2548 HRESULT WINAPI
CDefView::SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
)
2550 FIXME("partial stub: %p %08x %08x %p\n", this, aspects
, advf
, pAdvSink
);
2552 /* FIXME: we set the AdviseSink, but never use it to send any advice */
2553 m_pAdvSink
= pAdvSink
;
2554 m_dwAspects
= aspects
;
2560 HRESULT WINAPI
CDefView::GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
)
2562 TRACE("this=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n", this, pAspects
, pAdvf
, ppAdvSink
);
2566 *ppAdvSink
= m_pAdvSink
;
2567 m_pAdvSink
.p
->AddRef();
2571 *pAspects
= m_dwAspects
;
2579 HRESULT STDMETHODCALLTYPE
CDefView::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
2581 if (IsEqualIID(guidService
, SID_IShellBrowser
))
2582 return m_pShellBrowser
->QueryInterface(riid
, ppvObject
);
2583 else if(IsEqualIID(guidService
, SID_IFolderView
))
2584 return QueryInterface(riid
, ppvObject
);
2586 return E_NOINTERFACE
;
2589 /**********************************************************
2590 * IShellView_Constructor
2592 HRESULT WINAPI
IShellView_Constructor(IShellFolder
*pFolder
, IShellView
**newView
)
2594 CComObject
<CDefView
> *theView
;
2595 CComPtr
<IShellView
> result
;
2598 if (newView
== NULL
)
2602 ATLTRY (theView
= new CComObject
<CDefView
>);
2604 if (theView
== NULL
)
2605 return E_OUTOFMEMORY
;
2607 hResult
= theView
->QueryInterface(IID_PPV_ARG(IShellView
, &result
));
2608 if (FAILED (hResult
))
2614 hResult
= theView
->Initialize (pFolder
);
2615 if (FAILED (hResult
))
2617 *newView
= result
.Detach ();