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
))))
941 if (FAILED(RegisterDragDrop(m_hWnd
, pdt
)))
942 ERR("Registering Drag Drop Failed");
945 /* register for receiving notifications */
946 m_pSFParent
->QueryInterface(IID_PPV_ARG(IPersistFolder2
, &ppf2
));
949 ppf2
->GetCurFolder((LPITEMIDLIST
*)&ntreg
.pidl
);
950 ntreg
.fRecursive
= TRUE
;
951 m_hNotify
= SHChangeNotifyRegister(m_hWnd
, SHCNF_IDLIST
, SHCNE_ALLEVENTS
, SHV_CHANGE_NOTIFY
, 1, &ntreg
);
952 SHFree((LPITEMIDLIST
)ntreg
.pidl
);
955 m_hAccel
= LoadAcceleratorsA(shell32_hInstance
, MAKEINTRESOURCEA( IDA_SHELLVIEW
));
960 /**********************************************************
961 * #### Handling of the menus ####
964 /**********************************************************
965 * ShellView_BuildFileMenu()
967 HMENU
CDefView::BuildFileMenu()
968 { WCHAR szText
[MAX_PATH
];
973 TRACE("(%p)\n", this);
975 hSubMenu
= CreatePopupMenu();
978 /*get the number of items in our global array*/
979 for(nTools
= 0; Tools
[nTools
].idCommand
!= -1; nTools
++) {}
981 /*add the menu items*/
982 for(i
= 0; i
< nTools
; i
++)
984 LoadStringW(shell32_hInstance
, Tools
[i
].idMenuString
, szText
, MAX_PATH
);
986 ZeroMemory(&mii
, sizeof(mii
));
987 mii
.cbSize
= sizeof(mii
);
988 mii
.fMask
= MIIM_TYPE
| MIIM_ID
| MIIM_STATE
;
990 if(BTNS_SEP
!= Tools
[i
].bStyle
) /* no separator*/
992 mii
.fType
= MFT_STRING
;
993 mii
.fState
= MFS_ENABLED
;
994 mii
.dwTypeData
= szText
;
995 mii
.wID
= Tools
[i
].idCommand
;
999 mii
.fType
= MFT_SEPARATOR
;
1001 /* tack This item onto the end of the menu */
1002 InsertMenuItemW(hSubMenu
, (UINT
) - 1, TRUE
, &mii
);
1006 TRACE("-- return (menu=%p)\n", hSubMenu
);
1010 /**********************************************************
1011 * ShellView_MergeFileMenu()
1013 void CDefView::MergeFileMenu(HMENU hSubMenu
)
1015 TRACE("(%p)->(submenu=%p) stub\n", this, hSubMenu
);
1018 { /*insert This item at the beginning of the menu */
1019 _InsertMenuItemW(hSubMenu
, 0, TRUE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1020 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
, MFT_STRING
, L
"dummy45", MFS_ENABLED
);
1026 /**********************************************************
1027 * ShellView_MergeViewMenu()
1029 void CDefView::MergeViewMenu(HMENU hSubMenu
)
1031 TRACE("(%p)->(submenu=%p)\n", this, hSubMenu
);
1035 /*add a separator at the correct position in the menu*/
1037 static WCHAR view
[] = L
"View";
1039 _InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1041 ZeroMemory(&mii
, sizeof(mii
));
1042 mii
.cbSize
= sizeof(mii
);
1043 mii
.fMask
= MIIM_SUBMENU
| MIIM_TYPE
| MIIM_DATA
;
1044 mii
.fType
= MFT_STRING
;
1045 mii
.dwTypeData
= view
;
1046 mii
.hSubMenu
= LoadMenuW(shell32_hInstance
, L
"MENU_001");
1047 InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, &mii
);
1051 /**********************************************************
1052 * ShellView_GetSelections()
1054 * - fills the m_apidl list with the selected objects
1057 * number of selected items
1059 UINT
CDefView::GetSelections()
1066 m_cidl
= ListView_GetSelectedCount(m_hWndList
);
1067 m_apidl
= (LPITEMIDLIST
*)SHAlloc(m_cidl
* sizeof(LPITEMIDLIST
));
1069 TRACE("selected=%i\n", m_cidl
);
1073 TRACE("-- Items selected =%u\n", m_cidl
);
1075 lvItem
.mask
= LVIF_STATE
| LVIF_PARAM
;
1076 lvItem
.stateMask
= LVIS_SELECTED
;
1078 lvItem
.iSubItem
= 0;
1081 while(SendMessageW(m_hWndList
, LVM_GETITEMW
, 0, (LPARAM
)&lvItem
) && (i
< m_cidl
))
1083 if(lvItem
.state
& LVIS_SELECTED
)
1085 m_apidl
[i
] = (LPITEMIDLIST
)lvItem
.lParam
;
1089 TRACE("-- selected Item found\n");
1098 /**********************************************************
1099 * ShellView_OpenSelectedItems()
1101 HRESULT
CDefView::OpenSelectedItems()
1104 CMINVOKECOMMANDINFO cmi
;
1108 m_cidl
= ListView_GetSelectedCount(m_hWndList
);
1112 hResult
= OnDefaultCommand();
1113 if (hResult
== S_OK
)
1116 hMenu
= CreatePopupMenu();
1120 hResult
= GetItemObject( SVGIO_SELECTION
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1121 if (FAILED(hResult
))
1124 hResult
= IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1125 //if (FAILED( hResult))
1128 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, 0x20, 0x7fff, CMF_DEFAULTONLY
);
1129 if (FAILED(hResult
))
1132 uCommand
= GetMenuDefaultItem(hMenu
, FALSE
, 0);
1133 if (uCommand
== (UINT
)-1)
1139 ZeroMemory(&cmi
, sizeof(cmi
));
1140 cmi
.cbSize
= sizeof(cmi
);
1141 cmi
.lpVerb
= (LPCSTR
)MAKEINTRESOURCEA(uCommand
);
1144 hResult
= m_pCM
->InvokeCommand(&cmi
);
1153 IUnknown_SetSite(m_pCM
, NULL
);
1160 /**********************************************************
1161 * ShellView_DoContextMenu()
1163 LRESULT
CDefView::OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1169 CMINVOKECOMMANDINFO cmi
;
1172 // for some reason I haven't figured out, we sometimes recurse into this method
1179 TRACE("(%p)->(0x%08x 0x%08x) stub\n", this, x
, y
);
1181 hMenu
= CreatePopupMenu();
1185 m_cidl
= ListView_GetSelectedCount(m_hWndList
);
1187 hResult
= GetItemObject( m_cidl
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1188 if (FAILED( hResult
))
1191 hResult
= IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1192 //if (FAILED( hResult))
1195 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1196 if (FAILED( hResult
))
1199 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
1200 SetMenuDefaultItem(hMenu
, FCIDM_SHVIEW_OPEN
, MF_BYCOMMAND
);
1202 uCommand
= TrackPopupMenu(hMenu
,
1203 TPM_LEFTALIGN
| TPM_RETURNCMD
| TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
,
1204 x
, y
, 0, m_hWnd
, NULL
);
1208 if (uCommand
== FCIDM_SHVIEW_OPEN
&& OnDefaultCommand() == S_OK
)
1211 ZeroMemory(&cmi
, sizeof(cmi
));
1212 cmi
.cbSize
= sizeof(cmi
);
1213 cmi
.lpVerb
= (LPCSTR
)MAKEINTRESOURCEA(uCommand
);
1215 m_pCM
->InvokeCommand(&cmi
);
1221 IUnknown_SetSite(m_pCM
, NULL
);
1231 LRESULT
CDefView::OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
)
1234 CMINVOKECOMMANDINFO cmi
;
1237 hMenu
= CreatePopupMenu();
1241 hResult
= GetItemObject( bUseSelection
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1242 if (FAILED( hResult
))
1245 hResult
= IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1246 //if (FAILED( hResult))
1249 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1250 if (FAILED( hResult
))
1253 ZeroMemory(&cmi
, sizeof(cmi
));
1254 cmi
.cbSize
= sizeof(cmi
);
1255 cmi
.lpVerb
= (LPCSTR
)MAKEINTRESOURCEA(uCommand
);
1257 m_pCM
->InvokeCommand(&cmi
);
1263 IUnknown_SetSite(m_pCM
, NULL
);
1273 /**********************************************************
1274 * ##### message handling #####
1277 /**********************************************************
1278 * ShellView_OnSize()
1280 LRESULT
CDefView::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1285 wWidth
= LOWORD(lParam
);
1286 wHeight
= HIWORD(lParam
);
1288 TRACE("%p width=%u height=%u\n", this, wWidth
, wHeight
);
1290 /*resize the ListView to fit our window*/
1293 ::MoveWindow(m_hWndList
, 0, 0, wWidth
, wHeight
, TRUE
);
1299 /**********************************************************
1300 * ShellView_OnDeactivate()
1305 void CDefView::OnDeactivate()
1307 TRACE("%p\n", this);
1309 if (m_uState
!= SVUIA_DEACTIVATE
)
1313 m_pShellBrowser
->SetMenuSB(0, 0, 0);
1314 m_pShellBrowser
->RemoveMenusSB(m_hMenu
);
1315 DestroyMenu(m_hMenu
);
1319 m_uState
= SVUIA_DEACTIVATE
;
1323 void CDefView::DoActivate(UINT uState
)
1325 OLEMENUGROUPWIDTHS omw
= { {0, 0, 0, 0, 0, 0} };
1327 CHAR szText
[MAX_PATH
];
1329 TRACE("%p uState=%x\n", this, uState
);
1331 /*don't do anything if the state isn't really changing */
1332 if (m_uState
== uState
)
1339 /*only do This if we are active */
1340 if(uState
!= SVUIA_DEACTIVATE
)
1342 /*merge the menus */
1343 m_hMenu
= CreateMenu();
1347 m_pShellBrowser
->InsertMenusSB(m_hMenu
, &omw
);
1348 TRACE("-- after fnInsertMenusSB\n");
1350 /*build the top level menu get the menu item's text*/
1351 strcpy(szText
, "dummy 31");
1353 ZeroMemory(&mii
, sizeof(mii
));
1354 mii
.cbSize
= sizeof(mii
);
1355 mii
.fMask
= MIIM_SUBMENU
| MIIM_TYPE
| MIIM_STATE
;
1356 mii
.fType
= MFT_STRING
;
1357 mii
.fState
= MFS_ENABLED
;
1358 mii
.dwTypeData
= szText
;
1359 mii
.hSubMenu
= BuildFileMenu();
1361 /*insert our menu into the menu bar*/
1364 InsertMenuItemA(m_hMenu
, FCIDM_MENU_HELP
, FALSE
, &mii
);
1367 /*get the view menu so we can merge with it*/
1368 ZeroMemory(&mii
, sizeof(mii
));
1369 mii
.cbSize
= sizeof(mii
);
1370 mii
.fMask
= MIIM_SUBMENU
;
1372 if (GetMenuItemInfoA(m_hMenu
, FCIDM_MENU_VIEW
, FALSE
, &mii
))
1374 MergeViewMenu(mii
.hSubMenu
);
1377 /*add the items that should only be added if we have the focus*/
1378 if (SVUIA_ACTIVATE_FOCUS
== uState
)
1380 /*get the file menu so we can merge with it */
1381 ZeroMemory(&mii
, sizeof(mii
));
1382 mii
.cbSize
= sizeof(mii
);
1383 mii
.fMask
= MIIM_SUBMENU
;
1385 if (GetMenuItemInfoA(m_hMenu
, FCIDM_MENU_FILE
, FALSE
, &mii
))
1387 MergeFileMenu(mii
.hSubMenu
);
1391 TRACE("-- before fnSetMenuSB\n");
1392 m_pShellBrowser
->SetMenuSB(m_hMenu
, 0, m_hWnd
);
1399 /**********************************************************
1400 * ShellView_OnActivate()
1402 LRESULT
CDefView::OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1404 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1408 /**********************************************************
1409 * ShellView_OnSetFocus()
1412 LRESULT
CDefView::OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1414 TRACE("%p\n", this);
1416 /* Tell the browser one of our windows has received the focus. This
1417 should always be done before merging menus (OnActivate merges the
1418 menus) if one of our windows has the focus.*/
1420 m_pShellBrowser
->OnViewWindowActive((IShellView
*)this);
1421 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1423 /* Set the focus to the listview */
1424 ::SetFocus(m_hWndList
);
1426 /* Notify the ICommDlgBrowser interface */
1427 OnStateChange(CDBOSC_SETFOCUS
);
1432 /**********************************************************
1433 * ShellView_OnKillFocus()
1435 LRESULT
CDefView::OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1437 TRACE("(%p) stub\n", this);
1439 DoActivate(SVUIA_ACTIVATE_NOFOCUS
);
1440 /* Notify the ICommDlgBrowser */
1441 OnStateChange(CDBOSC_KILLFOCUS
);
1446 /**********************************************************
1447 * ShellView_OnCommand()
1450 * the CmdID's are the ones from the context menu
1452 LRESULT
CDefView::OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1458 dwCmdID
= GET_WM_COMMAND_ID(wParam
, lParam
);
1459 dwCmd
= GET_WM_COMMAND_CMD(wParam
, lParam
);
1460 hwndCmd
= GET_WM_COMMAND_HWND(wParam
, lParam
);
1462 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n", this, dwCmdID
, dwCmd
, hwndCmd
);
1466 case FCIDM_SHVIEW_SMALLICON
:
1467 m_FolderSettings
.ViewMode
= FVM_SMALLICON
;
1468 SetStyle (LVS_SMALLICON
, LVS_TYPEMASK
);
1472 case FCIDM_SHVIEW_BIGICON
:
1473 m_FolderSettings
.ViewMode
= FVM_ICON
;
1474 SetStyle (LVS_ICON
, LVS_TYPEMASK
);
1478 case FCIDM_SHVIEW_LISTVIEW
:
1479 m_FolderSettings
.ViewMode
= FVM_LIST
;
1480 SetStyle (LVS_LIST
, LVS_TYPEMASK
);
1484 case FCIDM_SHVIEW_REPORTVIEW
:
1485 m_FolderSettings
.ViewMode
= FVM_DETAILS
;
1486 SetStyle (LVS_REPORT
, LVS_TYPEMASK
);
1490 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1495 m_sortInfo
.nHeaderID
= (LPARAM
) (dwCmdID
- 0x30);
1496 m_sortInfo
.bIsAscending
= TRUE
;
1497 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
1498 SendMessageA(m_hWndList
, LVM_SORTITEMS
, (WPARAM
) &m_sortInfo
, (LPARAM
)ListViewCompareItems
);
1501 case FCIDM_SHVIEW_REFRESH
:
1505 case FCIDM_SHVIEW_DELETE
:
1506 case FCIDM_SHVIEW_CUT
:
1507 case FCIDM_SHVIEW_COPY
:
1508 case FCIDM_SHVIEW_RENAME
:
1509 return OnExplorerCommand(dwCmdID
, TRUE
);
1511 case FCIDM_SHVIEW_INSERT
:
1512 case FCIDM_SHVIEW_UNDO
:
1513 case FCIDM_SHVIEW_INSERTLINK
:
1514 case FCIDM_SHVIEW_NEWFOLDER
:
1515 return OnExplorerCommand(dwCmdID
, FALSE
);
1517 TRACE("-- COMMAND 0x%04x unhandled\n", dwCmdID
);
1523 /**********************************************************
1524 * ShellView_OnNotify()
1527 LRESULT
CDefView::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1531 LPNMLISTVIEW lpnmlv
;
1532 NMLVDISPINFOW
*lpdi
;
1537 lpnmh
= (LPNMHDR
)lParam
;
1538 lpnmlv
= (LPNMLISTVIEW
)lpnmh
;
1539 lpdi
= (NMLVDISPINFOW
*)lpnmh
;
1541 TRACE("%p CtlID=%u lpnmh->code=%x\n", this, CtlID
, lpnmh
->code
);
1543 switch (lpnmh
->code
)
1546 TRACE("-- NM_SETFOCUS %p\n", this);
1547 OnSetFocus(0, 0, 0, unused
);
1551 TRACE("-- NM_KILLFOCUS %p\n", this);
1553 /* Notify the ICommDlgBrowser interface */
1554 OnStateChange(CDBOSC_KILLFOCUS
);
1558 TRACE("-- NM_CUSTOMDRAW %p\n", this);
1559 return CDRF_DODEFAULT
;
1561 case NM_RELEASEDCAPTURE
:
1562 TRACE("-- NM_RELEASEDCAPTURE %p\n", this);
1566 TRACE("-- NM_CLICK %p\n", this);
1570 TRACE("-- NM_RCLICK %p\n", this);
1574 TRACE("-- NM_DBLCLK %p\n", this);
1575 OpenSelectedItems();
1579 TRACE("-- NM_RETURN %p\n", this);
1580 OpenSelectedItems();
1584 TRACE("-- HDN_ENDTRACKW %p\n", this);
1585 /*nColumn1 = ListView_GetColumnWidth(m_hWndList, 0);
1586 nColumn2 = ListView_GetColumnWidth(m_hWndList, 1);*/
1589 case LVN_DELETEITEM
:
1590 TRACE("-- LVN_DELETEITEM %p\n", this);
1591 SHFree((LPITEMIDLIST
)lpnmlv
->lParam
); /*delete the pidl because we made a copy of it*/
1594 case LVN_DELETEALLITEMS
:
1595 TRACE("-- LVN_DELETEALLITEMS %p\n", this);
1598 case LVN_INSERTITEM
:
1599 TRACE("-- LVN_INSERTITEM (STUB)%p\n", this);
1602 case LVN_ITEMACTIVATE
:
1603 TRACE("-- LVN_ITEMACTIVATE %p\n", this);
1604 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1607 case LVN_COLUMNCLICK
:
1608 m_sortInfo
.nHeaderID
= lpnmlv
->iSubItem
;
1609 if (m_sortInfo
.nLastHeaderID
== m_sortInfo
.nHeaderID
)
1611 m_sortInfo
.bIsAscending
= !m_sortInfo
.bIsAscending
;
1615 m_sortInfo
.bIsAscending
= TRUE
;
1617 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
1619 SendMessageW(lpnmlv
->hdr
.hwndFrom
, LVM_SORTITEMS
, (WPARAM
) &m_sortInfo
, (LPARAM
)ListViewCompareItems
);
1622 case LVN_GETDISPINFOA
:
1623 case LVN_GETDISPINFOW
:
1624 TRACE("-- LVN_GETDISPINFO %p\n", this);
1625 pidl
= (LPITEMIDLIST
)lpdi
->item
.lParam
;
1627 if (lpdi
->item
.mask
& LVIF_TEXT
) /* text requested */
1632 if (FAILED(m_pSF2Parent
->GetDetailsOf(pidl
, lpdi
->item
.iSubItem
, &sd
)))
1634 FIXME("failed to get details\n");
1638 if (lpnmh
->code
== LVN_GETDISPINFOA
)
1640 /* shouldn't happen */
1641 NMLVDISPINFOA
*lpdiA
= (NMLVDISPINFOA
*)lpnmh
;
1642 StrRetToStrNA( lpdiA
->item
.pszText
, lpdiA
->item
.cchTextMax
, &sd
.str
, NULL
);
1643 TRACE("-- text=%s\n", lpdiA
->item
.pszText
);
1645 else /* LVN_GETDISPINFOW */
1647 StrRetToStrNW( lpdi
->item
.pszText
, lpdi
->item
.cchTextMax
, &sd
.str
, NULL
);
1648 TRACE("-- text=%s\n", debugstr_w(lpdi
->item
.pszText
));
1656 if(lpdi
->item
.mask
& LVIF_IMAGE
) /* image requested */
1658 lpdi
->item
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
1660 lpdi
->item
.mask
|= LVIF_DI_SETITEM
;
1663 case LVN_ITEMCHANGED
:
1664 TRACE("-- LVN_ITEMCHANGED %p\n", this);
1665 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1669 case LVN_BEGINRDRAG
:
1670 TRACE("-- LVN_BEGINDRAG\n");
1672 if (GetSelections())
1675 DWORD dwAttributes
= SFGAO_CANLINK
;
1676 DWORD dwEffect
= DROPEFFECT_COPY
| DROPEFFECT_MOVE
;
1678 if (SUCCEEDED(m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, (LPCITEMIDLIST
*)m_apidl
, IID_IDataObject
, 0, (LPVOID
*)&pda
)))
1680 IDropSource
* pds
= (IDropSource
*)this; /* own DropSource interface */
1682 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(m_cidl
, (LPCITEMIDLIST
*)m_apidl
, &dwAttributes
)))
1684 if (dwAttributes
& SFGAO_CANLINK
)
1686 dwEffect
|= DROPEFFECT_LINK
;
1690 CComPtr
<IAsyncOperation
> piaso
;
1691 if (SUCCEEDED(pda
->QueryInterface(IID_PPV_ARG(IAsyncOperation
, &piaso
))))
1693 piaso
->SetAsyncMode(TRUE
);
1699 DoDragDrop(pda
, pds
, dwEffect
, &dwEffect2
);
1706 case LVN_BEGINLABELEDITW
:
1708 DWORD dwAttr
= SFGAO_CANRENAME
;
1709 pidl
= (LPITEMIDLIST
)lpdi
->item
.lParam
;
1711 TRACE("-- LVN_BEGINLABELEDITW %p\n", this);
1713 m_pSFParent
->GetAttributesOf(1, (LPCITEMIDLIST
*)&pidl
, &dwAttr
);
1714 if (SFGAO_CANRENAME
& dwAttr
)
1721 case LVN_ENDLABELEDITW
:
1723 TRACE("-- LVN_ENDLABELEDITW %p\n", this);
1724 if (lpdi
->item
.pszText
)
1729 lvItem
.iItem
= lpdi
->item
.iItem
;
1730 lvItem
.iSubItem
= 0;
1731 lvItem
.mask
= LVIF_PARAM
;
1732 SendMessageW(m_hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
1734 pidl
= (LPITEMIDLIST
)lpdi
->item
.lParam
;
1735 hr
= m_pSFParent
->SetNameOf(0, pidl
, lpdi
->item
.pszText
, SHGDN_INFOLDER
, &pidl
);
1737 if (SUCCEEDED(hr
) && pidl
)
1739 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
1740 lvItem
.lParam
= (LPARAM
)pidl
;
1741 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
1742 SendMessageW(m_hWndList
, LVM_SETITEMW
, 0, (LPARAM
) &lvItem
);
1743 SendMessageW(m_hWndList
, LVM_UPDATE
, lpdi
->item
.iItem
, 0);
1754 LPNMLVKEYDOWN plvKeyDown
= (LPNMLVKEYDOWN
) lpnmh
;
1756 /* initiate a rename of the selected file or directory */
1757 if (plvKeyDown
->wVKey
== VK_BACK
)
1759 LPSHELLBROWSER lpSb
;
1760 if ((lpSb
= (LPSHELLBROWSER
)SendMessageW(m_hWndParent
, CWM_GETISHELLBROWSER
, 0, 0)))
1762 lpSb
->BrowseObject(NULL
, SBSP_PARENT
);
1767 FIXME("LVN_KEYDOWN key=0x%08x\n", plvKeyDown
->wVKey
);
1772 TRACE("-- %p WM_COMMAND %x unhandled\n", this, lpnmh
->code
);
1779 /**********************************************************
1780 * ShellView_OnChange()
1782 LRESULT
CDefView::OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1784 LPITEMIDLIST
*Pidls
;
1786 Pidls
= (LPITEMIDLIST
*)wParam
;
1788 TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls
[0], Pidls
[1], lParam
);
1794 LV_AddItem(Pidls
[0]);
1799 LV_DeleteItem(Pidls
[0]);
1802 case SHCNE_RENAMEFOLDER
:
1803 case SHCNE_RENAMEITEM
:
1804 LV_RenameItem(Pidls
[0], Pidls
[1]);
1807 case SHCNE_UPDATEITEM
:
1814 /**********************************************************
1815 * CDefView::OnCustomItem
1817 LRESULT
CDefView::OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1822 ERR("no menu!!!\n");
1826 CComPtr
<IContextMenu2
> pCM2
;
1827 HRESULT hres
= m_pCM
.p
->QueryInterface(IID_PPV_ARG(IContextMenu2
, &pCM2
));
1831 if (pCM2
.p
->HandleMenuMsg(uMsg
, (WPARAM
)m_hWnd
, lParam
) == S_OK
)
1837 LRESULT
CDefView::OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1839 /* Wallpaper setting affects drop shadows effect */
1840 if (wParam
== SPI_SETDESKWALLPAPER
|| wParam
== 0)
1846 /**********************************************************
1849 * The INTERFACE of the IShellView object
1852 **********************************************************
1855 /**********************************************************
1856 * ShellView_GetWindow
1858 HRESULT WINAPI
CDefView::GetWindow(HWND
*phWnd
)
1860 TRACE("(%p)\n", this);
1867 HRESULT WINAPI
CDefView::ContextSensitiveHelp(BOOL fEnterMode
)
1869 FIXME("(%p) stub\n", this);
1874 /**********************************************************
1875 * IShellView_TranslateAccelerator
1878 * use the accel functions
1880 HRESULT WINAPI
CDefView::TranslateAccelerator(LPMSG lpmsg
)
1882 if (lpmsg
->message
>= WM_KEYFIRST
&& lpmsg
->message
<= WM_KEYLAST
)
1884 if (::TranslateAcceleratorW(m_hWnd
, m_hAccel
, lpmsg
) != 0)
1887 /* FIXME: should call TranslateAcceleratorSB */
1889 TRACE("-- key=0x04%lx\n", lpmsg
->wParam
) ;
1892 return S_FALSE
; /* not handled */
1895 HRESULT WINAPI
CDefView::EnableModeless(BOOL fEnable
)
1897 FIXME("(%p) stub\n", this);
1902 HRESULT WINAPI
CDefView::UIActivate(UINT uState
)
1905 CHAR szName[MAX_PATH];
1908 int nPartArray
[1] = { -1};
1910 TRACE("(%p)->(state=%x) stub\n", this, uState
);
1912 /*don't do anything if the state isn't really changing*/
1913 if (m_uState
== uState
)
1918 /*OnActivate handles the menu merging and internal state*/
1921 /*only do This if we are active*/
1922 if (uState
!= SVUIA_DEACTIVATE
)
1926 GetFolderPath is not a method of IShellFolder
1927 IShellFolder_GetFolderPath( m_pSFParent, szName, sizeof(szName) );
1929 /* set the number of parts */
1930 m_pShellBrowser
->SendControlMsg(FCW_STATUS
, SB_SETPARTS
, 1, (LPARAM
)nPartArray
, &lResult
);
1932 /* set the text for the parts */
1934 m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXTA, 0, (LPARAM)szName, &lResult);
1941 HRESULT WINAPI
CDefView::Refresh()
1943 TRACE("(%p)\n", this);
1945 SendMessageW(m_hWndList
, LVM_DELETEALLITEMS
, 0, 0);
1951 HRESULT WINAPI
CDefView::CreateViewWindow(IShellView
*lpPrevView
, LPCFOLDERSETTINGS lpfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
)
1955 TRACE("(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n", this, lpPrevView
, lpfs
, psb
, prcView
, phWnd
);
1958 TRACE("-- vmode=%x flags=%x\n", lpfs
->ViewMode
, lpfs
->fFlags
);
1959 if (prcView
!= NULL
)
1960 TRACE("-- left=%i top=%i right=%i bottom=%i\n", prcView
->left
, prcView
->top
, prcView
->right
, prcView
->bottom
);
1962 /* Validate the Shell Browser */
1964 return E_UNEXPECTED
;
1966 /*set up the member variables*/
1967 m_pShellBrowser
= psb
;
1968 m_FolderSettings
= *lpfs
;
1970 /*get our parent window*/
1971 m_pShellBrowser
->GetWindow(&m_hWndParent
);
1973 /* try to get the ICommDlgBrowserInterface, adds a reference !!! */
1974 m_pCommDlgBrowser
= NULL
;
1975 if (SUCCEEDED(m_pShellBrowser
->QueryInterface(IID_PPV_ARG(ICommDlgBrowser
, &m_pCommDlgBrowser
))))
1977 TRACE("-- CommDlgBrowser\n");
1980 Create(m_hWndParent
, prcView
, NULL
, WS_CHILD
| WS_TABSTOP
, 0, 0U);
1991 SetWindowPos(HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_SHOWWINDOW
);
1997 HRESULT WINAPI
CDefView::DestroyViewWindow()
1999 TRACE("(%p)\n", this);
2001 /*Make absolutely sure all our UI is cleaned up.*/
2002 UIActivate(SVUIA_DEACTIVATE
);
2006 DestroyMenu(m_hMenu
);
2010 m_pShellBrowser
.Release();
2011 m_pCommDlgBrowser
.Release();
2016 HRESULT WINAPI
CDefView::GetCurrentInfo(LPFOLDERSETTINGS lpfs
)
2018 TRACE("(%p)->(%p) vmode=%x flags=%x\n", this, lpfs
,
2019 m_FolderSettings
.ViewMode
, m_FolderSettings
.fFlags
);
2022 return E_INVALIDARG
;
2024 *lpfs
= m_FolderSettings
;
2028 HRESULT WINAPI
CDefView::AddPropertySheetPages(DWORD dwReserved
, LPFNADDPROPSHEETPAGE lpfn
, LPARAM lparam
)
2030 FIXME("(%p) stub\n", this);
2035 HRESULT WINAPI
CDefView::SaveViewState()
2037 FIXME("(%p) stub\n", this);
2042 HRESULT WINAPI
CDefView::SelectItem(LPCITEMIDLIST pidl
, UINT uFlags
)
2046 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n", this, pidl
, uFlags
);
2048 i
= LV_FindItemByPidl(pidl
);
2054 if(uFlags
& SVSI_ENSUREVISIBLE
)
2055 SendMessageW(m_hWndList
, LVM_ENSUREVISIBLE
, i
, 0);
2057 lvItem
.mask
= LVIF_STATE
;
2058 lvItem
.stateMask
= LVIS_SELECTED
| LVIS_FOCUSED
;
2060 lvItem
.iSubItem
= 0;
2062 while (SendMessageW(m_hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
))
2064 if (lvItem
.iItem
== i
)
2066 if (uFlags
& SVSI_SELECT
)
2067 lvItem
.state
|= LVIS_SELECTED
;
2069 lvItem
.state
&= ~LVIS_SELECTED
;
2071 if (uFlags
& SVSI_FOCUSED
)
2072 lvItem
.state
&= ~LVIS_FOCUSED
;
2076 if (uFlags
& SVSI_DESELECTOTHERS
)
2077 lvItem
.state
&= ~LVIS_SELECTED
;
2080 SendMessageW(m_hWndList
, LVM_SETITEMW
, 0, (LPARAM
) &lvItem
);
2085 if(uFlags
& SVSI_EDIT
)
2086 SendMessageW(m_hWndList
, LVM_EDITLABELW
, i
, 0);
2092 HRESULT WINAPI
CDefView::GetItemObject(UINT uItem
, REFIID riid
, LPVOID
*ppvOut
)
2094 HRESULT hr
= E_NOINTERFACE
;
2096 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n", this, uItem
, debugstr_guid(&riid
), ppvOut
);
2102 case SVGIO_BACKGROUND
:
2103 if (IsEqualIID(riid
, IID_IContextMenu
))
2105 //*ppvOut = ISvBgCm_Constructor(m_pSFParent, FALSE);
2106 CDefFolderMenu_Create2(NULL
, NULL
, 0, NULL
, m_pSFParent
, NULL
, 0, NULL
, (IContextMenu
**)ppvOut
);
2114 case SVGIO_SELECTION
:
2116 hr
= m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, (LPCITEMIDLIST
*)m_apidl
, riid
, 0, ppvOut
);
2120 TRACE("-- (%p)->(interface=%p)\n", this, *ppvOut
);
2125 HRESULT STDMETHODCALLTYPE
CDefView::GetCurrentViewMode(UINT
*pViewMode
)
2127 TRACE("(%p)->(%p), stub\n", this, pViewMode
);
2130 return E_INVALIDARG
;
2132 *pViewMode
= m_FolderSettings
.ViewMode
;
2136 HRESULT STDMETHODCALLTYPE
CDefView::SetCurrentViewMode(UINT ViewMode
)
2139 TRACE("(%p)->(%u), stub\n", this, ViewMode
);
2141 /* It's not redundant to check FVM_AUTO because it's a (UINT)-1 */
2142 if ((ViewMode
< FVM_FIRST
|| ViewMode
> FVM_LAST
) && (ViewMode
!= (UINT
)FVM_AUTO
))
2143 return E_INVALIDARG
;
2145 /* Windows before Vista uses LVM_SETVIEW and possibly
2146 LVM_SETEXTENDEDLISTVIEWSTYLE to set the style of the listview,
2147 while later versions seem to accomplish this through other
2155 dwStyle
= LVS_REPORT
;
2158 dwStyle
= LVS_SMALLICON
;
2165 FIXME("ViewMode %d not implemented\n", ViewMode
);
2171 SetStyle(dwStyle
, LVS_TYPEMASK
);
2173 /* This will not necessarily be the actual mode set above.
2174 This mimics the behavior of Windows XP. */
2175 m_FolderSettings
.ViewMode
= ViewMode
;
2180 HRESULT STDMETHODCALLTYPE
CDefView::GetFolder(REFIID riid
, void **ppv
)
2182 if (m_pSFParent
== NULL
)
2185 return m_pSFParent
->QueryInterface(riid
, ppv
);
2188 HRESULT STDMETHODCALLTYPE
CDefView::Item(int iItemIndex
, LPITEMIDLIST
*ppidl
)
2192 TRACE("(%p)->(%d %p)\n", this, iItemIndex
, ppidl
);
2194 item
.mask
= LVIF_PARAM
;
2195 item
.iItem
= iItemIndex
;
2197 if (SendMessageW(m_hWndList
, LVM_GETITEMW
, 0, (LPARAM
)&item
))
2199 *ppidl
= ILClone((PITEMID_CHILD
)item
.lParam
);
2205 return E_INVALIDARG
;
2208 HRESULT STDMETHODCALLTYPE
CDefView::ItemCount(UINT uFlags
, int *pcItems
)
2210 TRACE("(%p)->(%u %p)\n", this, uFlags
, pcItems
);
2212 if (uFlags
!= SVGIO_ALLVIEW
)
2213 FIXME("some flags unsupported, %x\n", uFlags
& ~SVGIO_ALLVIEW
);
2215 *pcItems
= SendMessageW(m_hWndList
, LVM_GETITEMCOUNT
, 0, 0);
2220 HRESULT STDMETHODCALLTYPE
CDefView::Items(UINT uFlags
, REFIID riid
, void **ppv
)
2225 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectionMarkedItem(int *piItem
)
2227 TRACE("(%p)->(%p)\n", this, piItem
);
2229 *piItem
= SendMessageW(m_hWndList
, LVM_GETSELECTIONMARK
, 0, 0);
2234 HRESULT STDMETHODCALLTYPE
CDefView::GetFocusedItem(int *piItem
)
2236 TRACE("(%p)->(%p)\n", this, piItem
);
2238 *piItem
= SendMessageW(m_hWndList
, LVM_GETNEXTITEM
, -1, LVNI_FOCUSED
);
2243 HRESULT STDMETHODCALLTYPE
CDefView::GetItemPosition(LPCITEMIDLIST pidl
, POINT
*ppt
)
2248 HRESULT STDMETHODCALLTYPE
CDefView::GetSpacing(POINT
*ppt
)
2250 TRACE("(%p)->(%p)\n", this, ppt
);
2252 if (NULL
== m_hWndList
) return S_FALSE
;
2256 const DWORD ret
= SendMessageW(m_hWndList
, LVM_GETITEMSPACING
, 0, 0);
2258 ppt
->x
= LOWORD(ret
);
2259 ppt
->y
= HIWORD(ret
);
2265 HRESULT STDMETHODCALLTYPE
CDefView::GetDefaultSpacing(POINT
*ppt
)
2270 HRESULT STDMETHODCALLTYPE
CDefView::GetAutoArrange()
2275 HRESULT STDMETHODCALLTYPE
CDefView::SelectItem(int iItem
, DWORD dwFlags
)
2279 TRACE("(%p)->(%d, %x)\n", this, iItem
, dwFlags
);
2282 lvItem
.stateMask
= LVIS_SELECTED
;
2284 if (dwFlags
& SVSI_ENSUREVISIBLE
)
2285 SendMessageW(m_hWndList
, LVM_ENSUREVISIBLE
, iItem
, 0);
2288 if (dwFlags
& SVSI_DESELECTOTHERS
)
2289 SendMessageW(m_hWndList
, LVM_SETITEMSTATE
, -1, (LPARAM
)&lvItem
);
2292 if (dwFlags
& SVSI_SELECT
)
2293 lvItem
.state
|= LVIS_SELECTED
;
2295 if (dwFlags
& SVSI_FOCUSED
)
2296 lvItem
.stateMask
|= LVIS_FOCUSED
;
2298 SendMessageW(m_hWndList
, LVM_SETITEMSTATE
, iItem
, (LPARAM
)&lvItem
);
2300 if (dwFlags
& SVSI_EDIT
)
2301 SendMessageW(m_hWndList
, LVM_EDITLABELW
, iItem
, 0);
2306 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItems(UINT cidl
, LPCITEMIDLIST
*apidl
, POINT
*apt
, DWORD dwFlags
)
2311 /**********************************************************
2312 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2314 HRESULT WINAPI
CDefView::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD
*prgCmds
, OLECMDTEXT
*pCmdText
)
2316 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
2317 this, pguidCmdGroup
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
2320 return E_INVALIDARG
;
2322 for (UINT i
= 0; i
< cCmds
; i
++)
2324 FIXME("\tprgCmds[%d].cmdID = %d\n", i
, prgCmds
[i
].cmdID
);
2325 prgCmds
[i
].cmdf
= 0;
2328 return OLECMDERR_E_UNKNOWNGROUP
;
2331 /**********************************************************
2332 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2334 * nCmdID is the OLECMDID_* enumeration
2336 HRESULT WINAPI
CDefView::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
2338 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2339 this, debugstr_guid(pguidCmdGroup
), nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2342 return OLECMDERR_E_UNKNOWNGROUP
;
2344 if (IsEqualIID(*pguidCmdGroup
, CGID_Explorer
) &&
2346 (nCmdexecopt
== 4) && pvaOut
)
2349 if (IsEqualIID(*pguidCmdGroup
, CGID_ShellDocView
) &&
2354 return OLECMDERR_E_UNKNOWNGROUP
;
2357 /**********************************************************
2358 * ISVDropTarget implementation
2361 /******************************************************************************
2362 * drag_notify_subitem [Internal]
2364 * Figure out the shellfolder object, which is currently under the mouse cursor
2365 * and notify it via the IDropTarget interface.
2368 #define SCROLLAREAWIDTH 20
2370 HRESULT
CDefView::drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2372 LVHITTESTINFO htinfo
;
2378 /* Map from global to client coordinates and query the index of the listview-item, which is
2379 * currently under the mouse cursor. */
2382 htinfo
.flags
= LVHT_ONITEM
;
2383 ::ScreenToClient(m_hWndList
, &htinfo
.pt
);
2384 lResult
= SendMessageW(m_hWndList
, LVM_HITTEST
, 0, (LPARAM
)&htinfo
);
2386 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2387 ::GetClientRect(m_hWndList
, &clientRect
);
2388 if (htinfo
.pt
.x
== m_ptLastMousePos
.x
&& htinfo
.pt
.y
== m_ptLastMousePos
.y
&&
2389 (htinfo
.pt
.x
< SCROLLAREAWIDTH
|| htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
||
2390 htinfo
.pt
.y
< SCROLLAREAWIDTH
|| htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
))
2392 m_cScrollDelay
= (m_cScrollDelay
+ 1) % 5; /* DragOver is called every 50 ms */
2393 if (m_cScrollDelay
== 0)
2395 /* Mouse did hover another 250 ms over the scroll-area */
2396 if (htinfo
.pt
.x
< SCROLLAREAWIDTH
)
2397 SendMessageW(m_hWndList
, WM_HSCROLL
, SB_LINEUP
, 0);
2399 if (htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
)
2400 SendMessageW(m_hWndList
, WM_HSCROLL
, SB_LINEDOWN
, 0);
2402 if (htinfo
.pt
.y
< SCROLLAREAWIDTH
)
2403 SendMessageW(m_hWndList
, WM_VSCROLL
, SB_LINEUP
, 0);
2405 if (htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
)
2406 SendMessageW(m_hWndList
, WM_VSCROLL
, SB_LINEDOWN
, 0);
2411 m_cScrollDelay
= 0; /* Reset, if the cursor is not over the listview's scroll-area */
2414 m_ptLastMousePos
= htinfo
.pt
;
2416 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2417 if (m_pCurDropTarget
&& lResult
== m_iDragOverItem
)
2418 return m_pCurDropTarget
->DragOver(grfKeyState
, pt
, pdwEffect
);
2420 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2421 if (m_pCurDropTarget
)
2423 m_pCurDropTarget
->DragLeave();
2424 m_pCurDropTarget
.Release();
2427 m_iDragOverItem
= lResult
;
2430 /* We are not above one of the listview's subitems. Bind to the parent folder's
2431 * DropTarget interface. */
2432 hr
= m_pSFParent
->QueryInterface(IID_PPV_ARG(IDropTarget
,&m_pCurDropTarget
));
2436 /* Query the relative PIDL of the shellfolder object represented by the currently
2437 * dragged over listview-item ... */
2438 lvItem
.mask
= LVIF_PARAM
;
2439 lvItem
.iItem
= lResult
;
2440 lvItem
.iSubItem
= 0;
2441 SendMessageW(m_hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
2443 /* ... and bind m_pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2444 hr
= m_pSFParent
->GetUIObjectOf(m_hWndList
, 1,
2445 (LPCITEMIDLIST
*)&lvItem
.lParam
, IID_IDropTarget
, NULL
, (LPVOID
*)&m_pCurDropTarget
);
2448 /* If anything failed, m_pCurDropTarget should be NULL now, which ought to be a save state. */
2452 /* Notify the item just entered via DragEnter. */
2453 return m_pCurDropTarget
->DragEnter(m_pCurDataObject
, grfKeyState
, pt
, pdwEffect
);
2456 HRESULT WINAPI
CDefView::DragEnter(IDataObject
*pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2458 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2459 m_pCurDataObject
= pDataObject
;
2460 pDataObject
->AddRef();
2462 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2465 HRESULT WINAPI
CDefView::DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2467 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2470 HRESULT WINAPI
CDefView::DragLeave()
2472 if (m_pCurDropTarget
)
2474 m_pCurDropTarget
->DragLeave();
2475 m_pCurDropTarget
.Release();
2478 if (m_pCurDataObject
!= NULL
)
2480 m_pCurDataObject
.Release();
2483 m_iDragOverItem
= 0;
2488 HRESULT WINAPI
CDefView::Drop(IDataObject
* pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2490 if (m_pCurDropTarget
)
2492 m_pCurDropTarget
->Drop(pDataObject
, grfKeyState
, pt
, pdwEffect
);
2493 m_pCurDropTarget
.Release();
2498 m_pCurDataObject
.Release(); m_iDragOverItem
= 0;
2503 /**********************************************************
2504 * ISVDropSource implementation
2507 HRESULT WINAPI
CDefView::QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
)
2509 TRACE("(%p)\n", this);
2512 return DRAGDROP_S_CANCEL
;
2513 else if (!(grfKeyState
& MK_LBUTTON
) && !(grfKeyState
& MK_RBUTTON
))
2514 return DRAGDROP_S_DROP
;
2519 HRESULT WINAPI
CDefView::GiveFeedback(DWORD dwEffect
)
2521 TRACE("(%p)\n", this);
2523 return DRAGDROP_S_USEDEFAULTCURSORS
;
2526 /**********************************************************
2527 * ISVViewObject implementation
2530 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
)
2532 FIXME("Stub: this=%p\n", this);
2537 HRESULT WINAPI
CDefView::GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
, HDC hicTargetDevice
, LOGPALETTE
**ppColorSet
)
2539 FIXME("Stub: this=%p\n", this);
2544 HRESULT WINAPI
CDefView::Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
)
2546 FIXME("Stub: this=%p\n", this);
2551 HRESULT WINAPI
CDefView::Unfreeze(DWORD dwFreeze
)
2553 FIXME("Stub: this=%p\n", this);
2558 HRESULT WINAPI
CDefView::SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
)
2560 FIXME("partial stub: %p %08x %08x %p\n", this, aspects
, advf
, pAdvSink
);
2562 /* FIXME: we set the AdviseSink, but never use it to send any advice */
2563 m_pAdvSink
= pAdvSink
;
2564 m_dwAspects
= aspects
;
2570 HRESULT WINAPI
CDefView::GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
)
2572 TRACE("this=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n", this, pAspects
, pAdvf
, ppAdvSink
);
2576 *ppAdvSink
= m_pAdvSink
;
2577 m_pAdvSink
.p
->AddRef();
2581 *pAspects
= m_dwAspects
;
2589 HRESULT STDMETHODCALLTYPE
CDefView::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
2591 if (IsEqualIID(guidService
, SID_IShellBrowser
))
2592 return m_pShellBrowser
->QueryInterface(riid
, ppvObject
);
2593 else if(IsEqualIID(guidService
, SID_IFolderView
))
2594 return QueryInterface(riid
, ppvObject
);
2596 return E_NOINTERFACE
;
2599 /**********************************************************
2600 * IShellView_Constructor
2602 HRESULT WINAPI
IShellView_Constructor(IShellFolder
*pFolder
, IShellView
**newView
)
2604 CComObject
<CDefView
> *theView
;
2605 CComPtr
<IShellView
> result
;
2608 if (newView
== NULL
)
2612 ATLTRY (theView
= new CComObject
<CDefView
>);
2614 if (theView
== NULL
)
2615 return E_OUTOFMEMORY
;
2617 hResult
= theView
->QueryInterface(IID_PPV_ARG(IShellView
, &result
));
2618 if (FAILED (hResult
))
2624 hResult
= theView
->Initialize (pFolder
);
2625 if (FAILED (hResult
))
2627 *newView
= result
.Detach ();