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
55 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
59 static const WCHAR SV_CLASS_NAME
[] = {'S', 'H', 'E', 'L', 'L', 'D', 'L', 'L', '_', 'D', 'e', 'f', 'V', 'i', 'e', 'w', 0};
65 } LISTVIEW_SORT_INFO
, *LPLISTVIEW_SORT_INFO
;
67 #define SHV_CHANGE_NOTIFY WM_USER + 0x1111
70 public CWindowImpl
<CDefView
, CWindow
, CControlWinTraits
>,
71 public CComObjectRootEx
<CComMultiThreadModelNoCS
>,
74 public IOleCommandTarget
,
78 public IServiceProvider
81 CComPtr
<IShellFolder
> m_pSFParent
;
82 CComPtr
<IShellFolder2
> m_pSF2Parent
;
83 CComPtr
<IShellBrowser
> m_pShellBrowser
;
84 CComPtr
<ICommDlgBrowser
> m_pCommDlgBrowser
;
85 HWND m_hWndList
; /* ListView control */
87 FOLDERSETTINGS m_FolderSettings
;
91 LPITEMIDLIST
*m_apidl
;
92 LISTVIEW_SORT_INFO m_sortInfo
;
93 ULONG m_hNotify
; /* change notification handle */
97 CComPtr
<IAdviseSink
> m_pAdvSink
;
99 CComPtr
<IDropTarget
> m_pCurDropTarget
; /* The sub-item, which is currently dragged over */
100 CComPtr
<IDataObject
> m_pCurDataObject
; /* The dragged data-object */
101 LONG m_iDragOverItem
; /* Dragged over item's index, iff m_pCurDropTarget != NULL */
102 UINT m_cScrollDelay
; /* Send a WM_*SCROLL msg every 250 ms during drag-scroll */
103 POINT m_ptLastMousePos
; /* Mouse position at last DragOver call */
105 CComPtr
<IContextMenu
> m_pCM
;
109 HRESULT WINAPI
Initialize(IShellFolder
*shellFolder
);
110 HRESULT
IncludeObject(LPCITEMIDLIST pidl
);
111 HRESULT
OnDefaultCommand();
112 HRESULT
OnStateChange(UINT uFlags
);
114 void SetStyle(DWORD dwAdd
, DWORD dwRemove
);
116 void UpdateListColors();
118 static INT CALLBACK
CompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
);
119 static INT CALLBACK
ListViewCompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
);
120 int LV_FindItemByPidl(LPCITEMIDLIST pidl
);
121 BOOLEAN
LV_AddItem(LPCITEMIDLIST pidl
);
122 BOOLEAN
LV_DeleteItem(LPCITEMIDLIST pidl
);
123 BOOLEAN
LV_RenameItem(LPCITEMIDLIST pidlOld
, LPCITEMIDLIST pidlNew
);
124 static INT CALLBACK
fill_list(LPVOID ptr
, LPVOID arg
);
126 HMENU
BuildFileMenu();
127 void MergeFileMenu(HMENU hSubMenu
);
128 void MergeViewMenu(HMENU hSubMenu
);
129 UINT
GetSelections();
130 HRESULT
OpenSelectedItems();
132 void DoActivate(UINT uState
);
133 HRESULT
drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
134 LRESULT
OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
);
136 // *** IOleWindow methods ***
137 virtual HRESULT STDMETHODCALLTYPE
GetWindow(HWND
*lphwnd
);
138 virtual HRESULT STDMETHODCALLTYPE
ContextSensitiveHelp(BOOL fEnterMode
);
140 // *** IShellView methods ***
141 virtual HRESULT STDMETHODCALLTYPE
TranslateAccelerator(MSG
*pmsg
);
142 virtual HRESULT STDMETHODCALLTYPE
EnableModeless(BOOL fEnable
);
143 virtual HRESULT STDMETHODCALLTYPE
UIActivate(UINT uState
);
144 virtual HRESULT STDMETHODCALLTYPE
Refresh();
145 virtual HRESULT STDMETHODCALLTYPE
CreateViewWindow(IShellView
*psvPrevious
, LPCFOLDERSETTINGS pfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
);
146 virtual HRESULT STDMETHODCALLTYPE
DestroyViewWindow();
147 virtual HRESULT STDMETHODCALLTYPE
GetCurrentInfo(LPFOLDERSETTINGS pfs
);
148 virtual HRESULT STDMETHODCALLTYPE
AddPropertySheetPages(DWORD dwReserved
, LPFNSVADDPROPSHEETPAGE pfn
, LPARAM lparam
);
149 virtual HRESULT STDMETHODCALLTYPE
SaveViewState();
150 virtual HRESULT STDMETHODCALLTYPE
SelectItem(LPCITEMIDLIST pidlItem
, SVSIF uFlags
);
151 virtual HRESULT STDMETHODCALLTYPE
GetItemObject(UINT uItem
, REFIID riid
, void **ppv
);
153 // *** IFolderView methods ***
154 virtual HRESULT STDMETHODCALLTYPE
GetCurrentViewMode(UINT
*pViewMode
);
155 virtual HRESULT STDMETHODCALLTYPE
SetCurrentViewMode(UINT ViewMode
);
156 virtual HRESULT STDMETHODCALLTYPE
GetFolder(REFIID riid
, void **ppv
);
157 virtual HRESULT STDMETHODCALLTYPE
Item(int iItemIndex
, LPITEMIDLIST
*ppidl
);
158 virtual HRESULT STDMETHODCALLTYPE
ItemCount(UINT uFlags
, int *pcItems
);
159 virtual HRESULT STDMETHODCALLTYPE
Items(UINT uFlags
, REFIID riid
, void **ppv
);
160 virtual HRESULT STDMETHODCALLTYPE
GetSelectionMarkedItem(int *piItem
);
161 virtual HRESULT STDMETHODCALLTYPE
GetFocusedItem(int *piItem
);
162 virtual HRESULT STDMETHODCALLTYPE
GetItemPosition(LPCITEMIDLIST pidl
, POINT
*ppt
);
163 virtual HRESULT STDMETHODCALLTYPE
GetSpacing(POINT
*ppt
);
164 virtual HRESULT STDMETHODCALLTYPE
GetDefaultSpacing(POINT
*ppt
);
165 virtual HRESULT STDMETHODCALLTYPE
GetAutoArrange();
166 virtual HRESULT STDMETHODCALLTYPE
SelectItem(int iItem
, DWORD dwFlags
);
167 virtual HRESULT STDMETHODCALLTYPE
SelectAndPositionItems(UINT cidl
, LPCITEMIDLIST
*apidl
, POINT
*apt
, DWORD dwFlags
);
169 // *** IOleCommandTarget methods ***
170 virtual HRESULT STDMETHODCALLTYPE
QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
);
171 virtual HRESULT STDMETHODCALLTYPE
Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
);
173 // *** IDropTarget methods ***
174 virtual HRESULT STDMETHODCALLTYPE
DragEnter(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
175 virtual HRESULT STDMETHODCALLTYPE
DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
176 virtual HRESULT STDMETHODCALLTYPE
DragLeave();
177 virtual HRESULT STDMETHODCALLTYPE
Drop(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
179 // *** IDropSource methods ***
180 virtual HRESULT STDMETHODCALLTYPE
QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
);
181 virtual HRESULT STDMETHODCALLTYPE
GiveFeedback(DWORD dwEffect
);
183 // *** IViewObject methods ***
184 virtual HRESULT STDMETHODCALLTYPE
Draw(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
,
185 HDC hdcTargetDev
, HDC hdcDraw
, LPCRECTL lprcBounds
, LPCRECTL lprcWBounds
,
186 BOOL ( STDMETHODCALLTYPE
*pfnContinue
)(ULONG_PTR dwContinue
), ULONG_PTR dwContinue
);
187 virtual HRESULT STDMETHODCALLTYPE
GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
,
188 DVTARGETDEVICE
*ptd
, HDC hicTargetDev
, LOGPALETTE
**ppColorSet
);
189 virtual HRESULT STDMETHODCALLTYPE
Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
);
190 virtual HRESULT STDMETHODCALLTYPE
Unfreeze(DWORD dwFreeze
);
191 virtual HRESULT STDMETHODCALLTYPE
SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
);
192 virtual HRESULT STDMETHODCALLTYPE
GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
);
194 // *** IServiceProvider methods ***
195 virtual HRESULT STDMETHODCALLTYPE
QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
);
198 LRESULT
OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
199 LRESULT
OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
200 LRESULT
OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
201 LRESULT
OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
202 LRESULT
OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
203 LRESULT
OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
204 LRESULT
OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
205 LRESULT
OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
206 LRESULT
OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
207 LRESULT
OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
208 LRESULT
OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
209 LRESULT
OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
210 LRESULT
OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
211 LRESULT
OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
212 LRESULT
OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
213 LRESULT
OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
214 LRESULT
OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
216 static ATL::CWndClassInfo
& GetWndClassInfo()
218 static ATL::CWndClassInfo wc
=
220 { sizeof(WNDCLASSEX
), 0, StartWindowProc
,
222 LoadCursor(NULL
, IDC_ARROW
), (HBRUSH
)(COLOR_BACKGROUND
+ 1), NULL
, SV_CLASS_NAME
, NULL
224 NULL
, NULL
, IDC_ARROW
, TRUE
, 0, _T("")
229 virtual WNDPROC
GetWindowProc()
234 static LRESULT CALLBACK
WindowProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
239 // must hold a reference during message handling
240 pThis
= reinterpret_cast<CDefView
*>(hWnd
);
242 result
= CWindowImpl
<CDefView
, CWindow
, CControlWinTraits
>::WindowProc(hWnd
, uMsg
, wParam
, lParam
);
247 BEGIN_MSG_MAP(CDefView
)
248 MESSAGE_HANDLER(WM_SIZE
, OnSize
)
249 MESSAGE_HANDLER(WM_SETFOCUS
, OnSetFocus
)
250 MESSAGE_HANDLER(WM_KILLFOCUS
, OnKillFocus
)
251 MESSAGE_HANDLER(WM_CREATE
, OnCreate
)
252 MESSAGE_HANDLER(WM_ACTIVATE
, OnActivate
)
253 MESSAGE_HANDLER(WM_NOTIFY
, OnNotify
)
254 MESSAGE_HANDLER(WM_COMMAND
, OnCommand
)
255 MESSAGE_HANDLER(SHV_CHANGE_NOTIFY
, OnChangeNotify
)
256 MESSAGE_HANDLER(WM_CONTEXTMENU
, OnContextMenu
)
257 MESSAGE_HANDLER(WM_DRAWITEM
, OnCustomItem
)
258 MESSAGE_HANDLER(WM_MEASUREITEM
, OnCustomItem
)
259 MESSAGE_HANDLER(WM_SHOWWINDOW
, OnShowWindow
)
260 MESSAGE_HANDLER(WM_GETDLGCODE
, OnGetDlgCode
)
261 MESSAGE_HANDLER(WM_DESTROY
, OnDestroy
)
262 MESSAGE_HANDLER(WM_ERASEBKGND
, OnEraseBackground
)
263 MESSAGE_HANDLER(WM_SYSCOLORCHANGE
, OnSysColorChange
)
264 MESSAGE_HANDLER(CWM_GETISHELLBROWSER
, OnGetShellBrowser
)
265 MESSAGE_HANDLER(WM_SETTINGCHANGE
, OnSettingChange
)
268 BEGIN_COM_MAP(CDefView
)
269 COM_INTERFACE_ENTRY_IID(IID_IOleWindow
, IOleWindow
)
270 COM_INTERFACE_ENTRY_IID(IID_IShellView
, IShellView
)
271 COM_INTERFACE_ENTRY_IID(IID_IFolderView
, IFolderView
)
272 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget
, IOleCommandTarget
)
273 COM_INTERFACE_ENTRY_IID(IID_IDropTarget
, IDropTarget
)
274 COM_INTERFACE_ENTRY_IID(IID_IDropSource
, IDropSource
)
275 COM_INTERFACE_ENTRY_IID(IID_IViewObject
, IViewObject
)
276 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider
, IServiceProvider
)
280 /* ListView Header ID's */
281 #define LISTVIEW_COLUMN_NAME 0
282 #define LISTVIEW_COLUMN_SIZE 1
283 #define LISTVIEW_COLUMN_TYPE 2
284 #define LISTVIEW_COLUMN_TIME 3
285 #define LISTVIEW_COLUMN_ATTRIB 4
288 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
289 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
290 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
292 #define ID_LISTVIEW 1
295 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
296 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
297 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
300 Items merged into the toolbar and the filemenu
309 } MYTOOLINFO
, *LPMYTOOLINFO
;
311 static const MYTOOLINFO Tools
[] =
313 { FCIDM_SHVIEW_BIGICON
, 0, 0, IDS_VIEW_LARGE
, TBSTATE_ENABLED
, BTNS_BUTTON
},
314 { FCIDM_SHVIEW_SMALLICON
, 0, 0, IDS_VIEW_SMALL
, TBSTATE_ENABLED
, BTNS_BUTTON
},
315 { FCIDM_SHVIEW_LISTVIEW
, 0, 0, IDS_VIEW_LIST
, TBSTATE_ENABLED
, BTNS_BUTTON
},
316 { FCIDM_SHVIEW_REPORTVIEW
, 0, 0, IDS_VIEW_DETAILS
, TBSTATE_ENABLED
, BTNS_BUTTON
},
320 typedef void (CALLBACK
*PFNSHGETSETTINGSPROC
)(LPSHELLFLAGSTATE lpsfs
, DWORD dwMask
);
326 m_FolderSettings
.fFlags
= 0;
327 m_FolderSettings
.ViewMode
= 0;
332 m_sortInfo
.bIsAscending
= FALSE
;
333 m_sortInfo
.nHeaderID
= 0;
334 m_sortInfo
.nLastHeaderID
= 0;
341 m_ptLastMousePos
.x
= 0;
342 m_ptLastMousePos
.y
= 0;
345 CDefView::~CDefView()
347 TRACE(" destroying IShellView(%p)\n", this);
352 HRESULT WINAPI
CDefView::Initialize(IShellFolder
*shellFolder
)
354 m_pSFParent
= shellFolder
;
355 shellFolder
->QueryInterface(IID_PPV_ARG(IShellFolder2
, &m_pSF2Parent
));
360 /**********************************************************
362 * ##### helperfunctions for communication with ICommDlgBrowser #####
364 HRESULT
CDefView::IncludeObject(LPCITEMIDLIST pidl
)
368 if (m_pCommDlgBrowser
.p
!= NULL
)
370 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl
);
371 ret
= m_pCommDlgBrowser
->IncludeObject((IShellView
*)this, pidl
);
372 TRACE("--0x%08x\n", ret
);
378 HRESULT
CDefView::OnDefaultCommand()
380 HRESULT ret
= S_FALSE
;
382 if (m_pCommDlgBrowser
.p
!= NULL
)
384 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
385 ret
= m_pCommDlgBrowser
->OnDefaultCommand((IShellView
*)this);
386 TRACE("-- returns %08x\n", ret
);
392 HRESULT
CDefView::OnStateChange(UINT uFlags
)
394 HRESULT ret
= S_FALSE
;
396 if (m_pCommDlgBrowser
.p
!= NULL
)
398 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags
);
399 ret
= m_pCommDlgBrowser
->OnStateChange((IShellView
*)this, uFlags
);
405 /**********************************************************
406 * set the toolbar of the filedialog buttons
408 * - activates the buttons from the shellbrowser according to
411 void CDefView::CheckToolbar()
417 if (m_pCommDlgBrowser
!= NULL
)
419 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
420 FCIDM_TB_SMALLICON
, (m_FolderSettings
.ViewMode
== FVM_LIST
) ? TRUE
: FALSE
, &result
);
421 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
422 FCIDM_TB_REPORTVIEW
, (m_FolderSettings
.ViewMode
== FVM_DETAILS
) ? TRUE
: FALSE
, &result
);
423 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
424 FCIDM_TB_SMALLICON
, TRUE
, &result
);
425 m_pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
426 FCIDM_TB_REPORTVIEW
, TRUE
, &result
);
430 /**********************************************************
432 * ##### helperfunctions for initializing the view #####
434 /**********************************************************
435 * change the style of the listview control
437 void CDefView::SetStyle(DWORD dwAdd
, DWORD dwRemove
)
441 TRACE("(%p)\n", this);
443 tmpstyle
= ::GetWindowLongPtrW(m_hWndList
, GWL_STYLE
);
444 ::SetWindowLongPtrW(m_hWndList
, GWL_STYLE
, dwAdd
| (tmpstyle
& ~dwRemove
));
447 /**********************************************************
448 * ShellView_CreateList()
450 * - creates the list view window
452 BOOL
CDefView::CreateList()
453 { DWORD dwStyle
, dwExStyle
;
457 dwStyle
= WS_TABSTOP
| WS_VISIBLE
| WS_CHILDWINDOW
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
|
458 LVS_SHAREIMAGELISTS
| LVS_EDITLABELS
| LVS_AUTOARRANGE
;
459 dwExStyle
= WS_EX_CLIENTEDGE
;
461 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
462 dwStyle
|= LVS_ALIGNLEFT
;
464 dwStyle
|= LVS_ALIGNTOP
;
466 switch (m_FolderSettings
.ViewMode
)
473 dwStyle
|= LVS_REPORT
;
477 dwStyle
|= LVS_SMALLICON
;
489 if (m_FolderSettings
.fFlags
& FWF_AUTOARRANGE
)
490 dwStyle
|= LVS_AUTOARRANGE
;
492 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
493 m_FolderSettings
.fFlags
|= FWF_NOCLIENTEDGE
| FWF_NOSCROLL
;
495 if (m_FolderSettings
.fFlags
& FWF_SINGLESEL
)
496 dwStyle
|= LVS_SINGLESEL
;
498 if (m_FolderSettings
.fFlags
& FWF_NOCLIENTEDGE
)
499 dwExStyle
&= ~WS_EX_CLIENTEDGE
;
501 m_hWndList
= CreateWindowExW( dwExStyle
,
514 m_sortInfo
.bIsAscending
= TRUE
;
515 m_sortInfo
.nHeaderID
= -1;
516 m_sortInfo
.nLastHeaderID
= -1;
520 /* UpdateShellSettings(); */
524 void CDefView::UpdateListColors()
526 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
528 /* Check if drop shadows option is enabled */
529 BOOL bDropShadow
= FALSE
;
530 DWORD cbDropShadow
= sizeof(bDropShadow
);
531 WCHAR wszBuf
[16] = L
"";
533 RegGetValueW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
534 L
"ListviewShadow", RRF_RT_DWORD
, NULL
, &bDropShadow
, &cbDropShadow
);
535 if (bDropShadow
&& SystemParametersInfoW(SPI_GETDESKWALLPAPER
, _countof(wszBuf
), wszBuf
, 0) && wszBuf
[0])
537 SendMessageW(m_hWndList
, LVM_SETTEXTBKCOLOR
, 0, CLR_NONE
);
538 SendMessageW(m_hWndList
, LVM_SETBKCOLOR
, 0, CLR_NONE
);
539 SendMessageW(m_hWndList
, LVM_SETTEXTCOLOR
, 0, RGB(255, 255, 255));
540 SendMessageW(m_hWndList
, LVM_SETEXTENDEDLISTVIEWSTYLE
, LVS_EX_TRANSPARENTSHADOWTEXT
, LVS_EX_TRANSPARENTSHADOWTEXT
);
544 COLORREF crDesktop
= GetSysColor(COLOR_DESKTOP
);
545 SendMessageW(m_hWndList
, LVM_SETTEXTBKCOLOR
, 0, crDesktop
);
546 SendMessageW(m_hWndList
, LVM_SETBKCOLOR
, 0, crDesktop
);
547 if (GetRValue(crDesktop
) + GetGValue(crDesktop
) + GetBValue(crDesktop
) > 128 * 3)
548 SendMessageW(m_hWndList
, LVM_SETTEXTCOLOR
, 0, RGB(0, 0, 0));
550 SendMessageW(m_hWndList
, LVM_SETTEXTCOLOR
, 0, RGB(255, 255, 255));
551 SendMessageW(m_hWndList
, LVM_SETEXTENDEDLISTVIEWSTYLE
, LVS_EX_TRANSPARENTSHADOWTEXT
, 0);
556 /**********************************************************
557 * ShellView_InitList()
559 * - adds all needed columns to the shellview
561 BOOL
CDefView::InitList()
569 SendMessageW(m_hWndList
, LVM_DELETEALLITEMS
, 0, 0);
571 lvColumn
.mask
= LVCF_FMT
| LVCF_WIDTH
| LVCF_TEXT
;
572 lvColumn
.pszText
= szTemp
;
576 for (int i
= 0; 1; i
++)
578 if (FAILED(m_pSF2Parent
->GetDetailsOf(NULL
, i
, &sd
)))
581 lvColumn
.fmt
= sd
.fmt
;
582 lvColumn
.cx
= sd
.cxChar
* 8; /* chars->pixel */
583 StrRetToStrNW( szTemp
, 50, &sd
.str
, NULL
);
584 SendMessageW(m_hWndList
, LVM_INSERTCOLUMNW
, i
, (LPARAM
) &lvColumn
);
592 SendMessageW(m_hWndList
, LVM_SETIMAGELIST
, LVSIL_SMALL
, (LPARAM
)ShellSmallIconList
);
593 SendMessageW(m_hWndList
, LVM_SETIMAGELIST
, LVSIL_NORMAL
, (LPARAM
)ShellBigIconList
);
598 /**********************************************************
599 * ShellView_CompareItems()
602 * internal, CALLBACK for DSA_Sort
604 INT CALLBACK
CDefView::CompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
)
607 TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1
, lParam2
, (LPVOID
) lpData
);
612 ret
= (SHORT
)SCODE_CODE(((IShellFolder
*)lpData
)->CompareIDs(0, (LPITEMIDLIST
)lParam1
, (LPITEMIDLIST
)lParam2
));
613 TRACE("ret=%i\n", ret
);
618 /*************************************************************************
619 * ShellView_ListViewCompareItems
621 * Compare Function for the Listview (FileOpen Dialog)
624 * lParam1 [I] the first ItemIdList to compare with
625 * lParam2 [I] the second ItemIdList to compare with
626 * lpData [I] The column ID for the header Ctrl to process
629 * A negative value if the first item should precede the second,
630 * a positive value if the first item should follow the second,
631 * or zero if the two items are equivalent
634 * FIXME: function does what ShellView_CompareItems is supposed to do.
635 * unify it and figure out how to use the undocumented first parameter
636 * of IShellFolder_CompareIDs to do the job this function does and
637 * move this code to IShellFolder.
638 * make LISTVIEW_SORT_INFO obsolete
639 * the way this function works is only usable if we had only
640 * filesystemfolders (25/10/99 jsch)
642 INT CALLBACK
CDefView::ListViewCompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
)
646 char strName1
[MAX_PATH
], strName2
[MAX_PATH
];
647 BOOL bIsFolder1
, bIsFolder2
, bIsBothFolder
;
648 LPITEMIDLIST pItemIdList1
= (LPITEMIDLIST
) lParam1
;
649 LPITEMIDLIST pItemIdList2
= (LPITEMIDLIST
) lParam2
;
650 LISTVIEW_SORT_INFO
*pSortInfo
= (LPLISTVIEW_SORT_INFO
) lpData
;
653 bIsFolder1
= _ILIsFolder(pItemIdList1
);
654 bIsFolder2
= _ILIsFolder(pItemIdList2
);
655 bIsBothFolder
= bIsFolder1
&& bIsFolder2
;
657 /* When sorting between a File and a Folder, the Folder gets sorted first */
658 if ( (bIsFolder1
|| bIsFolder2
) && !bIsBothFolder
)
660 nDiff
= bIsFolder1
? -1 : 1;
664 /* Sort by Time: Folders or Files can be sorted */
666 if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_TIME
)
668 _ILGetFileDateTime(pItemIdList1
, &fd1
);
669 _ILGetFileDateTime(pItemIdList2
, &fd2
);
670 nDiff
= CompareFileTime(&fd2
, &fd1
);
672 /* Sort by Attribute: Folder or Files can be sorted */
673 else if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_ATTRIB
)
675 _ILGetFileAttributes(pItemIdList1
, strName1
, MAX_PATH
);
676 _ILGetFileAttributes(pItemIdList2
, strName2
, MAX_PATH
);
677 nDiff
= lstrcmpiA(strName1
, strName2
);
679 /* Sort by FileName: Folder or Files can be sorted */
680 else if (pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_NAME
|| bIsBothFolder
)
683 _ILSimpleGetText(pItemIdList1
, strName1
, MAX_PATH
);
684 _ILSimpleGetText(pItemIdList2
, strName2
, MAX_PATH
);
685 nDiff
= lstrcmpiA(strName1
, strName2
);
687 /* Sort by File Size, Only valid for Files */
688 else if (pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_SIZE
)
690 nDiff
= (INT
)(_ILGetFileSize(pItemIdList1
, NULL
, 0) - _ILGetFileSize(pItemIdList2
, NULL
, 0));
692 /* Sort by File Type, Only valid for Files */
693 else if (pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_TYPE
)
696 _ILGetFileType(pItemIdList1
, strName1
, MAX_PATH
);
697 _ILGetFileType(pItemIdList2
, strName2
, MAX_PATH
);
698 nDiff
= lstrcmpiA(strName1
, strName2
);
701 /* If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
705 _ILSimpleGetText(pItemIdList1
, strName1
, MAX_PATH
);
706 _ILSimpleGetText(pItemIdList2
, strName2
, MAX_PATH
);
707 nDiff
= lstrcmpiA(strName1
, strName2
);
710 if (!pSortInfo
->bIsAscending
)
718 /**********************************************************
719 * LV_FindItemByPidl()
721 int CDefView::LV_FindItemByPidl(LPCITEMIDLIST pidl
)
725 lvItem
.mask
= LVIF_PARAM
;
727 for (lvItem
.iItem
= 0;
728 SendMessageW(m_hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
731 LPITEMIDLIST currentpidl
= (LPITEMIDLIST
) lvItem
.lParam
;
732 HRESULT hr
= m_pSFParent
->CompareIDs(0, pidl
, currentpidl
);
734 if (SUCCEEDED(hr
) && !HRESULT_CODE(hr
))
742 /**********************************************************
745 BOOLEAN
CDefView::LV_AddItem(LPCITEMIDLIST pidl
)
749 TRACE("(%p)(pidl=%p)\n", this, pidl
);
751 lvItem
.mask
= LVIF_TEXT
| LVIF_IMAGE
| LVIF_PARAM
; /*set the mask*/
752 lvItem
.iItem
= ListView_GetItemCount(m_hWndList
); /*add the item to the end of the list*/
754 lvItem
.lParam
= (LPARAM
) ILClone(ILFindLastID(pidl
)); /*set the item's data*/
755 lvItem
.pszText
= LPSTR_TEXTCALLBACKW
; /*get text on a callback basis*/
756 lvItem
.iImage
= I_IMAGECALLBACK
; /*get the image on a callback basis*/
758 if (SendMessageW(m_hWndList
, LVM_INSERTITEMW
, 0, (LPARAM
)&lvItem
) == -1)
764 /**********************************************************
767 BOOLEAN
CDefView::LV_DeleteItem(LPCITEMIDLIST pidl
)
771 TRACE("(%p)(pidl=%p)\n", this, pidl
);
773 nIndex
= LV_FindItemByPidl(ILFindLastID(pidl
));
775 return (-1 == ListView_DeleteItem(m_hWndList
, nIndex
)) ? FALSE
: TRUE
;
778 /**********************************************************
781 BOOLEAN
CDefView::LV_RenameItem(LPCITEMIDLIST pidlOld
, LPCITEMIDLIST pidlNew
)
786 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", this, pidlOld
, pidlNew
);
788 nItem
= LV_FindItemByPidl(ILFindLastID(pidlOld
));
792 lvItem
.mask
= LVIF_PARAM
; /* only the pidl */
793 lvItem
.iItem
= nItem
;
794 SendMessageW(m_hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
796 SHFree((LPITEMIDLIST
)lvItem
.lParam
);
797 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
798 lvItem
.iItem
= nItem
;
799 lvItem
.lParam
= (LPARAM
) ILClone(ILFindLastID(pidlNew
)); /* set the item's data */
800 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidlNew
, 0);
801 SendMessageW(m_hWndList
, LVM_SETITEMW
, 0, (LPARAM
) &lvItem
);
802 SendMessageW(m_hWndList
, LVM_UPDATE
, nItem
, 0);
803 return TRUE
; /* FIXME: better handling */
809 /**********************************************************
810 * ShellView_FillList()
812 * - gets the objectlist from the shellfolder
814 * - fills the list into the view
816 INT CALLBACK
CDefView::fill_list( LPVOID ptr
, LPVOID arg
)
818 LPITEMIDLIST pidl
= (LPITEMIDLIST
)ptr
;
819 CDefView
*pThis
= (CDefView
*)arg
;
820 /* in a commdlg This works as a filemask*/
821 if (pThis
->IncludeObject(pidl
) == S_OK
)
822 pThis
->LV_AddItem(pidl
);
828 HRESULT
CDefView::FillList()
830 LPENUMIDLIST pEnumIDList
;
838 /* get the itemlist from the shfolder*/
839 hRes
= m_pSFParent
->EnumObjects(m_hWnd
, SHCONTF_NONFOLDERS
| SHCONTF_FOLDERS
, &pEnumIDList
);
847 /* create a pointer array */
848 hdpa
= DPA_Create(16);
851 return(E_OUTOFMEMORY
);
854 /* copy the items into the array*/
855 while((S_OK
== pEnumIDList
->Next(1, &pidl
, &dwFetched
)) && dwFetched
)
857 if (DPA_InsertPtr(hdpa
, 0x7fff, pidl
) == -1)
864 DPA_Sort(hdpa
, CompareItems
, (LPARAM
)m_pSFParent
.p
);
866 /*turn the listview's redrawing off*/
867 SendMessageA(m_hWndList
, WM_SETREDRAW
, FALSE
, 0);
869 DPA_DestroyCallback( hdpa
, fill_list
, (void *)this);
871 /*turn the listview's redrawing back on and force it to draw*/
872 SendMessageA(m_hWndList
, WM_SETREDRAW
, TRUE
, 0);
874 pEnumIDList
->Release(); /* destroy the list*/
879 LRESULT
CDefView::OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
881 ::UpdateWindow(m_hWndList
);
886 LRESULT
CDefView::OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
888 return SendMessageW(m_hWndList
, uMsg
, 0, 0);
891 LRESULT
CDefView::OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
893 RevokeDragDrop(m_hWnd
);
894 SHChangeNotifyDeregister(m_hNotify
);
899 LRESULT
CDefView::OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
901 if (m_FolderSettings
.fFlags
& (FWF_DESKTOP
| FWF_TRANSPARENT
))
902 return SendMessageW(GetParent(), WM_ERASEBKGND
, wParam
, lParam
); /* redirect to parent */
908 LRESULT
CDefView::OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
910 /* Update desktop labels color */
913 /* Forward WM_SYSCOLORCHANGE to common controls */
914 return SendMessageW(m_hWndList
, uMsg
, 0, 0);
917 LRESULT
CDefView::OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
919 return (LRESULT
)m_pShellBrowser
.p
;
922 /**********************************************************
923 * ShellView_OnCreate()
925 LRESULT
CDefView::OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
927 CComPtr
<IDropTarget
> pdt
;
928 SHChangeNotifyEntry ntreg
;
929 CComPtr
<IPersistFolder2
> ppf2
;
941 if (SUCCEEDED(QueryInterface(IID_PPV_ARG(IDropTarget
, &pdt
))))
943 if (FAILED(RegisterDragDrop(m_hWnd
, pdt
)))
944 ERR("Registering Drag Drop Failed");
947 /* register for receiving notifications */
948 m_pSFParent
->QueryInterface(IID_PPV_ARG(IPersistFolder2
, &ppf2
));
951 ppf2
->GetCurFolder((LPITEMIDLIST
*)&ntreg
.pidl
);
952 ntreg
.fRecursive
= TRUE
;
953 m_hNotify
= SHChangeNotifyRegister(m_hWnd
, SHCNF_IDLIST
, SHCNE_ALLEVENTS
, SHV_CHANGE_NOTIFY
, 1, &ntreg
);
954 SHFree((LPITEMIDLIST
)ntreg
.pidl
);
957 m_hAccel
= LoadAcceleratorsA(shell32_hInstance
, MAKEINTRESOURCEA( IDA_SHELLVIEW
));
962 /**********************************************************
963 * #### Handling of the menus ####
966 /**********************************************************
967 * ShellView_BuildFileMenu()
969 HMENU
CDefView::BuildFileMenu()
970 { WCHAR szText
[MAX_PATH
];
975 TRACE("(%p)\n", this);
977 hSubMenu
= CreatePopupMenu();
980 /*get the number of items in our global array*/
981 for(nTools
= 0; Tools
[nTools
].idCommand
!= -1; nTools
++) {}
983 /*add the menu items*/
984 for(i
= 0; i
< nTools
; i
++)
986 LoadStringW(shell32_hInstance
, Tools
[i
].idMenuString
, szText
, MAX_PATH
);
988 ZeroMemory(&mii
, sizeof(mii
));
989 mii
.cbSize
= sizeof(mii
);
990 mii
.fMask
= MIIM_TYPE
| MIIM_ID
| MIIM_STATE
;
992 if(BTNS_SEP
!= Tools
[i
].bStyle
) /* no separator*/
994 mii
.fType
= MFT_STRING
;
995 mii
.fState
= MFS_ENABLED
;
996 mii
.dwTypeData
= szText
;
997 mii
.wID
= Tools
[i
].idCommand
;
1001 mii
.fType
= MFT_SEPARATOR
;
1003 /* tack This item onto the end of the menu */
1004 InsertMenuItemW(hSubMenu
, (UINT
) - 1, TRUE
, &mii
);
1008 TRACE("-- return (menu=%p)\n", hSubMenu
);
1012 /**********************************************************
1013 * ShellView_MergeFileMenu()
1015 void CDefView::MergeFileMenu(HMENU hSubMenu
)
1017 TRACE("(%p)->(submenu=%p) stub\n", this, hSubMenu
);
1020 { /*insert This item at the beginning of the menu */
1021 _InsertMenuItemW(hSubMenu
, 0, TRUE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1022 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
, MFT_STRING
, L
"dummy45", MFS_ENABLED
);
1028 /**********************************************************
1029 * ShellView_MergeViewMenu()
1031 void CDefView::MergeViewMenu(HMENU hSubMenu
)
1033 TRACE("(%p)->(submenu=%p)\n", this, hSubMenu
);
1037 /*add a separator at the correct position in the menu*/
1039 static WCHAR view
[] = L
"View";
1041 _InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1043 ZeroMemory(&mii
, sizeof(mii
));
1044 mii
.cbSize
= sizeof(mii
);
1045 mii
.fMask
= MIIM_SUBMENU
| MIIM_TYPE
| MIIM_DATA
;
1046 mii
.fType
= MFT_STRING
;
1047 mii
.dwTypeData
= view
;
1048 mii
.hSubMenu
= LoadMenuW(shell32_hInstance
, L
"MENU_001");
1049 InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, &mii
);
1053 /**********************************************************
1054 * ShellView_GetSelections()
1056 * - fills the m_apidl list with the selected objects
1059 * number of selected items
1061 UINT
CDefView::GetSelections()
1068 m_cidl
= ListView_GetSelectedCount(m_hWndList
);
1069 m_apidl
= (LPITEMIDLIST
*)SHAlloc(m_cidl
* sizeof(LPITEMIDLIST
));
1071 TRACE("selected=%i\n", m_cidl
);
1075 TRACE("-- Items selected =%u\n", m_cidl
);
1077 lvItem
.mask
= LVIF_STATE
| LVIF_PARAM
;
1078 lvItem
.stateMask
= LVIS_SELECTED
;
1080 lvItem
.iSubItem
= 0;
1083 while(SendMessageW(m_hWndList
, LVM_GETITEMW
, 0, (LPARAM
)&lvItem
) && (i
< m_cidl
))
1085 if(lvItem
.state
& LVIS_SELECTED
)
1087 m_apidl
[i
] = (LPITEMIDLIST
)lvItem
.lParam
;
1091 TRACE("-- selected Item found\n");
1100 /**********************************************************
1101 * ShellView_OpenSelectedItems()
1103 HRESULT
CDefView::OpenSelectedItems()
1106 CMINVOKECOMMANDINFO cmi
;
1110 m_cidl
= ListView_GetSelectedCount(m_hWndList
);
1114 hResult
= OnDefaultCommand();
1115 if (hResult
== S_OK
)
1118 hMenu
= CreatePopupMenu();
1122 hResult
= GetItemObject( SVGIO_SELECTION
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1123 if (FAILED(hResult
))
1126 hResult
= IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1127 //if (FAILED( hResult))
1130 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, 0x20, 0x7fff, CMF_DEFAULTONLY
);
1131 if (FAILED(hResult
))
1134 uCommand
= GetMenuDefaultItem(hMenu
, FALSE
, 0);
1135 if (uCommand
== (UINT
)-1)
1141 ZeroMemory(&cmi
, sizeof(cmi
));
1142 cmi
.cbSize
= sizeof(cmi
);
1143 cmi
.lpVerb
= (LPCSTR
)MAKEINTRESOURCEA(uCommand
);
1146 hResult
= m_pCM
->InvokeCommand(&cmi
);
1155 IUnknown_SetSite(m_pCM
, NULL
);
1162 /**********************************************************
1163 * ShellView_DoContextMenu()
1165 LRESULT
CDefView::OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1171 CMINVOKECOMMANDINFO cmi
;
1174 // for some reason I haven't figured out, we sometimes recurse into this method
1181 TRACE("(%p)->(0x%08x 0x%08x) stub\n", this, x
, y
);
1183 hMenu
= CreatePopupMenu();
1187 m_cidl
= ListView_GetSelectedCount(m_hWndList
);
1189 hResult
= GetItemObject( m_cidl
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1190 if (FAILED( hResult
))
1193 hResult
= IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1194 //if (FAILED( hResult))
1197 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1198 if (FAILED( hResult
))
1201 if (m_FolderSettings
.fFlags
& FWF_DESKTOP
)
1202 SetMenuDefaultItem(hMenu
, FCIDM_SHVIEW_OPEN
, MF_BYCOMMAND
);
1204 uCommand
= TrackPopupMenu(hMenu
,
1205 TPM_LEFTALIGN
| TPM_RETURNCMD
| TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
,
1206 x
, y
, 0, m_hWnd
, NULL
);
1210 if (uCommand
== FCIDM_SHVIEW_OPEN
&& OnDefaultCommand() == S_OK
)
1213 ZeroMemory(&cmi
, sizeof(cmi
));
1214 cmi
.cbSize
= sizeof(cmi
);
1215 cmi
.lpVerb
= (LPCSTR
)MAKEINTRESOURCEA(uCommand
);
1217 m_pCM
->InvokeCommand(&cmi
);
1223 IUnknown_SetSite(m_pCM
, NULL
);
1233 LRESULT
CDefView::OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
)
1236 CMINVOKECOMMANDINFO cmi
;
1239 hMenu
= CreatePopupMenu();
1243 hResult
= GetItemObject( bUseSelection
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu
, &m_pCM
));
1244 if (FAILED( hResult
))
1247 hResult
= IUnknown_SetSite(m_pCM
, (IShellView
*)this);
1248 //if (FAILED( hResult))
1251 hResult
= m_pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1252 if (FAILED( hResult
))
1255 ZeroMemory(&cmi
, sizeof(cmi
));
1256 cmi
.cbSize
= sizeof(cmi
);
1257 cmi
.lpVerb
= (LPCSTR
)MAKEINTRESOURCEA(uCommand
);
1259 m_pCM
->InvokeCommand(&cmi
);
1265 IUnknown_SetSite(m_pCM
, NULL
);
1275 /**********************************************************
1276 * ##### message handling #####
1279 /**********************************************************
1280 * ShellView_OnSize()
1282 LRESULT
CDefView::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1287 wWidth
= LOWORD(lParam
);
1288 wHeight
= HIWORD(lParam
);
1290 TRACE("%p width=%u height=%u\n", this, wWidth
, wHeight
);
1292 /*resize the ListView to fit our window*/
1295 ::MoveWindow(m_hWndList
, 0, 0, wWidth
, wHeight
, TRUE
);
1301 /**********************************************************
1302 * ShellView_OnDeactivate()
1307 void CDefView::OnDeactivate()
1309 TRACE("%p\n", this);
1311 if (m_uState
!= SVUIA_DEACTIVATE
)
1315 m_pShellBrowser
->SetMenuSB(0, 0, 0);
1316 m_pShellBrowser
->RemoveMenusSB(m_hMenu
);
1317 DestroyMenu(m_hMenu
);
1321 m_uState
= SVUIA_DEACTIVATE
;
1325 void CDefView::DoActivate(UINT uState
)
1327 OLEMENUGROUPWIDTHS omw
= { {0, 0, 0, 0, 0, 0} };
1329 CHAR szText
[MAX_PATH
];
1331 TRACE("%p uState=%x\n", this, uState
);
1333 /*don't do anything if the state isn't really changing */
1334 if (m_uState
== uState
)
1341 /*only do This if we are active */
1342 if(uState
!= SVUIA_DEACTIVATE
)
1344 /*merge the menus */
1345 m_hMenu
= CreateMenu();
1349 m_pShellBrowser
->InsertMenusSB(m_hMenu
, &omw
);
1350 TRACE("-- after fnInsertMenusSB\n");
1352 /*build the top level menu get the menu item's text*/
1353 strcpy(szText
, "dummy 31");
1355 ZeroMemory(&mii
, sizeof(mii
));
1356 mii
.cbSize
= sizeof(mii
);
1357 mii
.fMask
= MIIM_SUBMENU
| MIIM_TYPE
| MIIM_STATE
;
1358 mii
.fType
= MFT_STRING
;
1359 mii
.fState
= MFS_ENABLED
;
1360 mii
.dwTypeData
= szText
;
1361 mii
.hSubMenu
= BuildFileMenu();
1363 /*insert our menu into the menu bar*/
1366 InsertMenuItemA(m_hMenu
, FCIDM_MENU_HELP
, FALSE
, &mii
);
1369 /*get the view menu so we can merge with it*/
1370 ZeroMemory(&mii
, sizeof(mii
));
1371 mii
.cbSize
= sizeof(mii
);
1372 mii
.fMask
= MIIM_SUBMENU
;
1374 if (GetMenuItemInfoA(m_hMenu
, FCIDM_MENU_VIEW
, FALSE
, &mii
))
1376 MergeViewMenu(mii
.hSubMenu
);
1379 /*add the items that should only be added if we have the focus*/
1380 if (SVUIA_ACTIVATE_FOCUS
== uState
)
1382 /*get the file menu so we can merge with it */
1383 ZeroMemory(&mii
, sizeof(mii
));
1384 mii
.cbSize
= sizeof(mii
);
1385 mii
.fMask
= MIIM_SUBMENU
;
1387 if (GetMenuItemInfoA(m_hMenu
, FCIDM_MENU_FILE
, FALSE
, &mii
))
1389 MergeFileMenu(mii
.hSubMenu
);
1393 TRACE("-- before fnSetMenuSB\n");
1394 m_pShellBrowser
->SetMenuSB(m_hMenu
, 0, m_hWnd
);
1401 /**********************************************************
1402 * ShellView_OnActivate()
1404 LRESULT
CDefView::OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1406 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1410 /**********************************************************
1411 * ShellView_OnSetFocus()
1414 LRESULT
CDefView::OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1416 TRACE("%p\n", this);
1418 /* Tell the browser one of our windows has received the focus. This
1419 should always be done before merging menus (OnActivate merges the
1420 menus) if one of our windows has the focus.*/
1422 m_pShellBrowser
->OnViewWindowActive((IShellView
*)this);
1423 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1425 /* Set the focus to the listview */
1426 ::SetFocus(m_hWndList
);
1428 /* Notify the ICommDlgBrowser interface */
1429 OnStateChange(CDBOSC_SETFOCUS
);
1434 /**********************************************************
1435 * ShellView_OnKillFocus()
1437 LRESULT
CDefView::OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1439 TRACE("(%p) stub\n", this);
1441 DoActivate(SVUIA_ACTIVATE_NOFOCUS
);
1442 /* Notify the ICommDlgBrowser */
1443 OnStateChange(CDBOSC_KILLFOCUS
);
1448 /**********************************************************
1449 * ShellView_OnCommand()
1452 * the CmdID's are the ones from the context menu
1454 LRESULT
CDefView::OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1460 dwCmdID
= GET_WM_COMMAND_ID(wParam
, lParam
);
1461 dwCmd
= GET_WM_COMMAND_CMD(wParam
, lParam
);
1462 hwndCmd
= GET_WM_COMMAND_HWND(wParam
, lParam
);
1464 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n", this, dwCmdID
, dwCmd
, hwndCmd
);
1468 case FCIDM_SHVIEW_SMALLICON
:
1469 m_FolderSettings
.ViewMode
= FVM_SMALLICON
;
1470 SetStyle (LVS_SMALLICON
, LVS_TYPEMASK
);
1474 case FCIDM_SHVIEW_BIGICON
:
1475 m_FolderSettings
.ViewMode
= FVM_ICON
;
1476 SetStyle (LVS_ICON
, LVS_TYPEMASK
);
1480 case FCIDM_SHVIEW_LISTVIEW
:
1481 m_FolderSettings
.ViewMode
= FVM_LIST
;
1482 SetStyle (LVS_LIST
, LVS_TYPEMASK
);
1486 case FCIDM_SHVIEW_REPORTVIEW
:
1487 m_FolderSettings
.ViewMode
= FVM_DETAILS
;
1488 SetStyle (LVS_REPORT
, LVS_TYPEMASK
);
1492 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1497 m_sortInfo
.nHeaderID
= (LPARAM
) (dwCmdID
- 0x30);
1498 m_sortInfo
.bIsAscending
= TRUE
;
1499 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
1500 SendMessageA(m_hWndList
, LVM_SORTITEMS
, (WPARAM
) &m_sortInfo
, (LPARAM
)ListViewCompareItems
);
1503 case FCIDM_SHVIEW_REFRESH
:
1507 case FCIDM_SHVIEW_DELETE
:
1508 case FCIDM_SHVIEW_CUT
:
1509 case FCIDM_SHVIEW_COPY
:
1510 case FCIDM_SHVIEW_RENAME
:
1511 return OnExplorerCommand(dwCmdID
, TRUE
);
1513 case FCIDM_SHVIEW_INSERT
:
1514 case FCIDM_SHVIEW_UNDO
:
1515 case FCIDM_SHVIEW_INSERTLINK
:
1516 case FCIDM_SHVIEW_NEWFOLDER
:
1517 return OnExplorerCommand(dwCmdID
, FALSE
);
1519 TRACE("-- COMMAND 0x%04x unhandled\n", dwCmdID
);
1525 /**********************************************************
1526 * ShellView_OnNotify()
1529 LRESULT
CDefView::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1533 LPNMLISTVIEW lpnmlv
;
1534 NMLVDISPINFOW
*lpdi
;
1539 lpnmh
= (LPNMHDR
)lParam
;
1540 lpnmlv
= (LPNMLISTVIEW
)lpnmh
;
1541 lpdi
= (NMLVDISPINFOW
*)lpnmh
;
1543 TRACE("%p CtlID=%u lpnmh->code=%x\n", this, CtlID
, lpnmh
->code
);
1545 switch (lpnmh
->code
)
1548 TRACE("-- NM_SETFOCUS %p\n", this);
1549 OnSetFocus(0, 0, 0, unused
);
1553 TRACE("-- NM_KILLFOCUS %p\n", this);
1555 /* Notify the ICommDlgBrowser interface */
1556 OnStateChange(CDBOSC_KILLFOCUS
);
1560 TRACE("-- NM_CUSTOMDRAW %p\n", this);
1561 return CDRF_DODEFAULT
;
1563 case NM_RELEASEDCAPTURE
:
1564 TRACE("-- NM_RELEASEDCAPTURE %p\n", this);
1568 TRACE("-- NM_CLICK %p\n", this);
1572 TRACE("-- NM_RCLICK %p\n", this);
1576 TRACE("-- NM_DBLCLK %p\n", this);
1577 OpenSelectedItems();
1581 TRACE("-- NM_RETURN %p\n", this);
1582 OpenSelectedItems();
1586 TRACE("-- HDN_ENDTRACKW %p\n", this);
1587 /*nColumn1 = ListView_GetColumnWidth(m_hWndList, 0);
1588 nColumn2 = ListView_GetColumnWidth(m_hWndList, 1);*/
1591 case LVN_DELETEITEM
:
1592 TRACE("-- LVN_DELETEITEM %p\n", this);
1593 SHFree((LPITEMIDLIST
)lpnmlv
->lParam
); /*delete the pidl because we made a copy of it*/
1596 case LVN_DELETEALLITEMS
:
1597 TRACE("-- LVN_DELETEALLITEMS %p\n", this);
1600 case LVN_INSERTITEM
:
1601 TRACE("-- LVN_INSERTITEM (STUB)%p\n", this);
1604 case LVN_ITEMACTIVATE
:
1605 TRACE("-- LVN_ITEMACTIVATE %p\n", this);
1606 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1609 case LVN_COLUMNCLICK
:
1610 m_sortInfo
.nHeaderID
= lpnmlv
->iSubItem
;
1611 if (m_sortInfo
.nLastHeaderID
== m_sortInfo
.nHeaderID
)
1613 m_sortInfo
.bIsAscending
= !m_sortInfo
.bIsAscending
;
1617 m_sortInfo
.bIsAscending
= TRUE
;
1619 m_sortInfo
.nLastHeaderID
= m_sortInfo
.nHeaderID
;
1621 SendMessageW(lpnmlv
->hdr
.hwndFrom
, LVM_SORTITEMS
, (WPARAM
) &m_sortInfo
, (LPARAM
)ListViewCompareItems
);
1624 case LVN_GETDISPINFOA
:
1625 case LVN_GETDISPINFOW
:
1626 TRACE("-- LVN_GETDISPINFO %p\n", this);
1627 pidl
= (LPITEMIDLIST
)lpdi
->item
.lParam
;
1629 if (lpdi
->item
.mask
& LVIF_TEXT
) /* text requested */
1634 if (FAILED(m_pSF2Parent
->GetDetailsOf(pidl
, lpdi
->item
.iSubItem
, &sd
)))
1636 FIXME("failed to get details\n");
1640 if (lpnmh
->code
== LVN_GETDISPINFOA
)
1642 /* shouldn't happen */
1643 NMLVDISPINFOA
*lpdiA
= (NMLVDISPINFOA
*)lpnmh
;
1644 StrRetToStrNA( lpdiA
->item
.pszText
, lpdiA
->item
.cchTextMax
, &sd
.str
, NULL
);
1645 TRACE("-- text=%s\n", lpdiA
->item
.pszText
);
1647 else /* LVN_GETDISPINFOW */
1649 StrRetToStrNW( lpdi
->item
.pszText
, lpdi
->item
.cchTextMax
, &sd
.str
, NULL
);
1650 TRACE("-- text=%s\n", debugstr_w(lpdi
->item
.pszText
));
1658 if(lpdi
->item
.mask
& LVIF_IMAGE
) /* image requested */
1660 lpdi
->item
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
1662 lpdi
->item
.mask
|= LVIF_DI_SETITEM
;
1665 case LVN_ITEMCHANGED
:
1666 TRACE("-- LVN_ITEMCHANGED %p\n", this);
1667 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1671 case LVN_BEGINRDRAG
:
1672 TRACE("-- LVN_BEGINDRAG\n");
1674 if (GetSelections())
1677 DWORD dwAttributes
= SFGAO_CANLINK
;
1678 DWORD dwEffect
= DROPEFFECT_COPY
| DROPEFFECT_MOVE
;
1680 if (SUCCEEDED(m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, (LPCITEMIDLIST
*)m_apidl
, IID_IDataObject
, 0, (LPVOID
*)&pda
)))
1682 IDropSource
* pds
= (IDropSource
*)this; /* own DropSource interface */
1684 if (SUCCEEDED(m_pSFParent
->GetAttributesOf(m_cidl
, (LPCITEMIDLIST
*)m_apidl
, &dwAttributes
)))
1686 if (dwAttributes
& SFGAO_CANLINK
)
1688 dwEffect
|= DROPEFFECT_LINK
;
1692 CComPtr
<IAsyncOperation
> piaso
;
1693 if (SUCCEEDED(pda
->QueryInterface(IID_PPV_ARG(IAsyncOperation
, &piaso
))))
1695 piaso
->SetAsyncMode(TRUE
);
1701 DoDragDrop(pda
, pds
, dwEffect
, &dwEffect2
);
1708 case LVN_BEGINLABELEDITW
:
1710 DWORD dwAttr
= SFGAO_CANRENAME
;
1711 pidl
= (LPITEMIDLIST
)lpdi
->item
.lParam
;
1713 TRACE("-- LVN_BEGINLABELEDITW %p\n", this);
1715 m_pSFParent
->GetAttributesOf(1, (LPCITEMIDLIST
*)&pidl
, &dwAttr
);
1716 if (SFGAO_CANRENAME
& dwAttr
)
1723 case LVN_ENDLABELEDITW
:
1725 TRACE("-- LVN_ENDLABELEDITW %p\n", this);
1726 if (lpdi
->item
.pszText
)
1731 lvItem
.iItem
= lpdi
->item
.iItem
;
1732 lvItem
.iSubItem
= 0;
1733 lvItem
.mask
= LVIF_PARAM
;
1734 SendMessageW(m_hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
1736 pidl
= (LPITEMIDLIST
)lpdi
->item
.lParam
;
1737 hr
= m_pSFParent
->SetNameOf(0, pidl
, lpdi
->item
.pszText
, SHGDN_INFOLDER
, &pidl
);
1739 if (SUCCEEDED(hr
) && pidl
)
1741 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
1742 lvItem
.lParam
= (LPARAM
)pidl
;
1743 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(m_pSFParent
, pidl
, 0);
1744 SendMessageW(m_hWndList
, LVM_SETITEMW
, 0, (LPARAM
) &lvItem
);
1745 SendMessageW(m_hWndList
, LVM_UPDATE
, lpdi
->item
.iItem
, 0);
1756 LPNMLVKEYDOWN plvKeyDown
= (LPNMLVKEYDOWN
) lpnmh
;
1758 /* initiate a rename of the selected file or directory */
1759 if (plvKeyDown
->wVKey
== VK_BACK
)
1761 LPSHELLBROWSER lpSb
;
1762 if ((lpSb
= (LPSHELLBROWSER
)SendMessageW(m_hWndParent
, CWM_GETISHELLBROWSER
, 0, 0)))
1764 lpSb
->BrowseObject(NULL
, SBSP_PARENT
);
1769 FIXME("LVN_KEYDOWN key=0x%08x\n", plvKeyDown
->wVKey
);
1774 TRACE("-- %p WM_COMMAND %x unhandled\n", this, lpnmh
->code
);
1781 /**********************************************************
1782 * ShellView_OnChange()
1784 LRESULT
CDefView::OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1786 LPITEMIDLIST
*Pidls
;
1788 Pidls
= (LPITEMIDLIST
*)wParam
;
1790 TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls
[0], Pidls
[1], lParam
);
1796 LV_AddItem(Pidls
[0]);
1801 LV_DeleteItem(Pidls
[0]);
1804 case SHCNE_RENAMEFOLDER
:
1805 case SHCNE_RENAMEITEM
:
1806 LV_RenameItem(Pidls
[0], Pidls
[1]);
1809 case SHCNE_UPDATEITEM
:
1816 /**********************************************************
1817 * CDefView::OnCustomItem
1819 LRESULT
CDefView::OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1824 ERR("no menu!!!\n");
1828 CComPtr
<IContextMenu2
> pCM2
;
1829 HRESULT hres
= m_pCM
.p
->QueryInterface(IID_PPV_ARG(IContextMenu2
, &pCM2
));
1833 if (pCM2
.p
->HandleMenuMsg(uMsg
, (WPARAM
)m_hWnd
, lParam
) == S_OK
)
1839 LRESULT
CDefView::OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1841 /* Wallpaper setting affects drop shadows effect */
1842 if (wParam
== SPI_SETDESKWALLPAPER
|| wParam
== 0)
1848 /**********************************************************
1851 * The INTERFACE of the IShellView object
1854 **********************************************************
1857 /**********************************************************
1858 * ShellView_GetWindow
1860 HRESULT WINAPI
CDefView::GetWindow(HWND
*phWnd
)
1862 TRACE("(%p)\n", this);
1869 HRESULT WINAPI
CDefView::ContextSensitiveHelp(BOOL fEnterMode
)
1871 FIXME("(%p) stub\n", this);
1876 /**********************************************************
1877 * IShellView_TranslateAccelerator
1880 * use the accel functions
1882 HRESULT WINAPI
CDefView::TranslateAccelerator(LPMSG lpmsg
)
1884 if (lpmsg
->message
>= WM_KEYFIRST
&& lpmsg
->message
<= WM_KEYLAST
)
1886 if (::TranslateAcceleratorW(m_hWnd
, m_hAccel
, lpmsg
) != 0)
1889 /* FIXME: should call TranslateAcceleratorSB */
1891 TRACE("-- key=0x04%lx\n", lpmsg
->wParam
) ;
1894 return S_FALSE
; /* not handled */
1897 HRESULT WINAPI
CDefView::EnableModeless(BOOL fEnable
)
1899 FIXME("(%p) stub\n", this);
1904 HRESULT WINAPI
CDefView::UIActivate(UINT uState
)
1907 CHAR szName[MAX_PATH];
1910 int nPartArray
[1] = { -1};
1912 TRACE("(%p)->(state=%x) stub\n", this, uState
);
1914 /*don't do anything if the state isn't really changing*/
1915 if (m_uState
== uState
)
1920 /*OnActivate handles the menu merging and internal state*/
1923 /*only do This if we are active*/
1924 if (uState
!= SVUIA_DEACTIVATE
)
1928 GetFolderPath is not a method of IShellFolder
1929 IShellFolder_GetFolderPath( m_pSFParent, szName, sizeof(szName) );
1931 /* set the number of parts */
1932 m_pShellBrowser
->SendControlMsg(FCW_STATUS
, SB_SETPARTS
, 1, (LPARAM
)nPartArray
, &lResult
);
1934 /* set the text for the parts */
1936 m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXTA, 0, (LPARAM)szName, &lResult);
1943 HRESULT WINAPI
CDefView::Refresh()
1945 TRACE("(%p)\n", this);
1947 SendMessageW(m_hWndList
, LVM_DELETEALLITEMS
, 0, 0);
1953 HRESULT WINAPI
CDefView::CreateViewWindow(IShellView
*lpPrevView
, LPCFOLDERSETTINGS lpfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
)
1957 TRACE("(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n", this, lpPrevView
, lpfs
, psb
, prcView
, phWnd
);
1960 TRACE("-- vmode=%x flags=%x\n", lpfs
->ViewMode
, lpfs
->fFlags
);
1961 if (prcView
!= NULL
)
1962 TRACE("-- left=%i top=%i right=%i bottom=%i\n", prcView
->left
, prcView
->top
, prcView
->right
, prcView
->bottom
);
1964 /* Validate the Shell Browser */
1966 return E_UNEXPECTED
;
1968 /*set up the member variables*/
1969 m_pShellBrowser
= psb
;
1970 m_FolderSettings
= *lpfs
;
1972 /*get our parent window*/
1973 m_pShellBrowser
->GetWindow(&m_hWndParent
);
1975 /* try to get the ICommDlgBrowserInterface, adds a reference !!! */
1976 m_pCommDlgBrowser
= NULL
;
1977 if (SUCCEEDED(m_pShellBrowser
->QueryInterface(IID_PPV_ARG(ICommDlgBrowser
, &m_pCommDlgBrowser
))))
1979 TRACE("-- CommDlgBrowser\n");
1982 Create(m_hWndParent
, prcView
, NULL
, WS_CHILD
| WS_TABSTOP
, 0, 0U);
1993 SetWindowPos(HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_SHOWWINDOW
);
1999 HRESULT WINAPI
CDefView::DestroyViewWindow()
2001 TRACE("(%p)\n", this);
2003 /*Make absolutely sure all our UI is cleaned up.*/
2004 UIActivate(SVUIA_DEACTIVATE
);
2008 DestroyMenu(m_hMenu
);
2012 m_pShellBrowser
.Release();
2013 m_pCommDlgBrowser
.Release();
2018 HRESULT WINAPI
CDefView::GetCurrentInfo(LPFOLDERSETTINGS lpfs
)
2020 TRACE("(%p)->(%p) vmode=%x flags=%x\n", this, lpfs
,
2021 m_FolderSettings
.ViewMode
, m_FolderSettings
.fFlags
);
2024 return E_INVALIDARG
;
2026 *lpfs
= m_FolderSettings
;
2030 HRESULT WINAPI
CDefView::AddPropertySheetPages(DWORD dwReserved
, LPFNADDPROPSHEETPAGE lpfn
, LPARAM lparam
)
2032 FIXME("(%p) stub\n", this);
2037 HRESULT WINAPI
CDefView::SaveViewState()
2039 FIXME("(%p) stub\n", this);
2044 HRESULT WINAPI
CDefView::SelectItem(LPCITEMIDLIST pidl
, UINT uFlags
)
2048 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n", this, pidl
, uFlags
);
2050 i
= LV_FindItemByPidl(pidl
);
2056 if(uFlags
& SVSI_ENSUREVISIBLE
)
2057 SendMessageW(m_hWndList
, LVM_ENSUREVISIBLE
, i
, 0);
2059 lvItem
.mask
= LVIF_STATE
;
2060 lvItem
.stateMask
= LVIS_SELECTED
| LVIS_FOCUSED
;
2062 lvItem
.iSubItem
= 0;
2064 while (SendMessageW(m_hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
))
2066 if (lvItem
.iItem
== i
)
2068 if (uFlags
& SVSI_SELECT
)
2069 lvItem
.state
|= LVIS_SELECTED
;
2071 lvItem
.state
&= ~LVIS_SELECTED
;
2073 if (uFlags
& SVSI_FOCUSED
)
2074 lvItem
.state
&= ~LVIS_FOCUSED
;
2078 if (uFlags
& SVSI_DESELECTOTHERS
)
2079 lvItem
.state
&= ~LVIS_SELECTED
;
2082 SendMessageW(m_hWndList
, LVM_SETITEMW
, 0, (LPARAM
) &lvItem
);
2087 if(uFlags
& SVSI_EDIT
)
2088 SendMessageW(m_hWndList
, LVM_EDITLABELW
, i
, 0);
2094 HRESULT WINAPI
CDefView::GetItemObject(UINT uItem
, REFIID riid
, LPVOID
*ppvOut
)
2096 HRESULT hr
= E_NOINTERFACE
;
2098 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n", this, uItem
, debugstr_guid(&riid
), ppvOut
);
2104 case SVGIO_BACKGROUND
:
2105 if (IsEqualIID(riid
, IID_IContextMenu
))
2107 //*ppvOut = ISvBgCm_Constructor(m_pSFParent, FALSE);
2108 CDefFolderMenu_Create2(NULL
, NULL
, 0, NULL
, m_pSFParent
, NULL
, 0, NULL
, (IContextMenu
**)ppvOut
);
2116 case SVGIO_SELECTION
:
2118 hr
= m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, (LPCITEMIDLIST
*)m_apidl
, riid
, 0, ppvOut
);
2122 TRACE("-- (%p)->(interface=%p)\n", this, *ppvOut
);
2127 HRESULT STDMETHODCALLTYPE
CDefView::GetCurrentViewMode(UINT
*pViewMode
)
2129 TRACE("(%p)->(%p), stub\n", this, pViewMode
);
2132 return E_INVALIDARG
;
2134 *pViewMode
= m_FolderSettings
.ViewMode
;
2138 HRESULT STDMETHODCALLTYPE
CDefView::SetCurrentViewMode(UINT ViewMode
)
2141 TRACE("(%p)->(%u), stub\n", this, ViewMode
);
2143 /* It's not redundant to check FVM_AUTO because it's a (UINT)-1 */
2144 if ((ViewMode
< FVM_FIRST
|| ViewMode
> FVM_LAST
) && (ViewMode
!= (UINT
)FVM_AUTO
))
2145 return E_INVALIDARG
;
2147 /* Windows before Vista uses LVM_SETVIEW and possibly
2148 LVM_SETEXTENDEDLISTVIEWSTYLE to set the style of the listview,
2149 while later versions seem to accomplish this through other
2157 dwStyle
= LVS_REPORT
;
2160 dwStyle
= LVS_SMALLICON
;
2167 FIXME("ViewMode %d not implemented\n", ViewMode
);
2173 SetStyle(dwStyle
, LVS_TYPEMASK
);
2175 /* This will not necessarily be the actual mode set above.
2176 This mimics the behavior of Windows XP. */
2177 m_FolderSettings
.ViewMode
= ViewMode
;
2182 HRESULT STDMETHODCALLTYPE
CDefView::GetFolder(REFIID riid
, void **ppv
)
2184 if (m_pSFParent
== NULL
)
2187 return m_pSFParent
->QueryInterface(riid
, ppv
);
2190 HRESULT STDMETHODCALLTYPE
CDefView::Item(int iItemIndex
, LPITEMIDLIST
*ppidl
)
2194 TRACE("(%p)->(%d %p)\n", this, iItemIndex
, ppidl
);
2196 item
.mask
= LVIF_PARAM
;
2197 item
.iItem
= iItemIndex
;
2199 if (SendMessageW(m_hWndList
, LVM_GETITEMW
, 0, (LPARAM
)&item
))
2201 *ppidl
= ILClone((PITEMID_CHILD
)item
.lParam
);
2207 return E_INVALIDARG
;
2210 HRESULT STDMETHODCALLTYPE
CDefView::ItemCount(UINT uFlags
, int *pcItems
)
2212 TRACE("(%p)->(%u %p)\n", this, uFlags
, pcItems
);
2214 if (uFlags
!= SVGIO_ALLVIEW
)
2215 FIXME("some flags unsupported, %x\n", uFlags
& ~SVGIO_ALLVIEW
);
2217 *pcItems
= SendMessageW(m_hWndList
, LVM_GETITEMCOUNT
, 0, 0);
2222 HRESULT STDMETHODCALLTYPE
CDefView::Items(UINT uFlags
, REFIID riid
, void **ppv
)
2227 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectionMarkedItem(int *piItem
)
2229 TRACE("(%p)->(%p)\n", this, piItem
);
2231 *piItem
= SendMessageW(m_hWndList
, LVM_GETSELECTIONMARK
, 0, 0);
2236 HRESULT STDMETHODCALLTYPE
CDefView::GetFocusedItem(int *piItem
)
2238 TRACE("(%p)->(%p)\n", this, piItem
);
2240 *piItem
= SendMessageW(m_hWndList
, LVM_GETNEXTITEM
, -1, LVNI_FOCUSED
);
2245 HRESULT STDMETHODCALLTYPE
CDefView::GetItemPosition(LPCITEMIDLIST pidl
, POINT
*ppt
)
2250 HRESULT STDMETHODCALLTYPE
CDefView::GetSpacing(POINT
*ppt
)
2252 TRACE("(%p)->(%p)\n", this, ppt
);
2254 if (NULL
== m_hWndList
) return S_FALSE
;
2258 const DWORD ret
= SendMessageW(m_hWndList
, LVM_GETITEMSPACING
, 0, 0);
2260 ppt
->x
= LOWORD(ret
);
2261 ppt
->y
= HIWORD(ret
);
2267 HRESULT STDMETHODCALLTYPE
CDefView::GetDefaultSpacing(POINT
*ppt
)
2272 HRESULT STDMETHODCALLTYPE
CDefView::GetAutoArrange()
2277 HRESULT STDMETHODCALLTYPE
CDefView::SelectItem(int iItem
, DWORD dwFlags
)
2281 TRACE("(%p)->(%d, %x)\n", this, iItem
, dwFlags
);
2284 lvItem
.stateMask
= LVIS_SELECTED
;
2286 if (dwFlags
& SVSI_ENSUREVISIBLE
)
2287 SendMessageW(m_hWndList
, LVM_ENSUREVISIBLE
, iItem
, 0);
2290 if (dwFlags
& SVSI_DESELECTOTHERS
)
2291 SendMessageW(m_hWndList
, LVM_SETITEMSTATE
, -1, (LPARAM
)&lvItem
);
2294 if (dwFlags
& SVSI_SELECT
)
2295 lvItem
.state
|= LVIS_SELECTED
;
2297 if (dwFlags
& SVSI_FOCUSED
)
2298 lvItem
.stateMask
|= LVIS_FOCUSED
;
2300 SendMessageW(m_hWndList
, LVM_SETITEMSTATE
, iItem
, (LPARAM
)&lvItem
);
2302 if (dwFlags
& SVSI_EDIT
)
2303 SendMessageW(m_hWndList
, LVM_EDITLABELW
, iItem
, 0);
2308 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItems(UINT cidl
, LPCITEMIDLIST
*apidl
, POINT
*apt
, DWORD dwFlags
)
2313 /**********************************************************
2314 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2316 HRESULT WINAPI
CDefView::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD
*prgCmds
, OLECMDTEXT
*pCmdText
)
2318 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
2319 this, pguidCmdGroup
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
2322 return E_INVALIDARG
;
2324 for (UINT i
= 0; i
< cCmds
; i
++)
2326 FIXME("\tprgCmds[%d].cmdID = %d\n", i
, prgCmds
[i
].cmdID
);
2327 prgCmds
[i
].cmdf
= 0;
2330 return OLECMDERR_E_UNKNOWNGROUP
;
2333 /**********************************************************
2334 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2336 * nCmdID is the OLECMDID_* enumeration
2338 HRESULT WINAPI
CDefView::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
2340 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2341 this, debugstr_guid(pguidCmdGroup
), nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2344 return OLECMDERR_E_UNKNOWNGROUP
;
2346 if (IsEqualIID(*pguidCmdGroup
, CGID_Explorer
) &&
2348 (nCmdexecopt
== 4) && pvaOut
)
2351 if (IsEqualIID(*pguidCmdGroup
, CGID_ShellDocView
) &&
2356 return OLECMDERR_E_UNKNOWNGROUP
;
2359 /**********************************************************
2360 * ISVDropTarget implementation
2363 /******************************************************************************
2364 * drag_notify_subitem [Internal]
2366 * Figure out the shellfolder object, which is currently under the mouse cursor
2367 * and notify it via the IDropTarget interface.
2370 #define SCROLLAREAWIDTH 20
2372 HRESULT
CDefView::drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2374 LVHITTESTINFO htinfo
;
2380 /* Map from global to client coordinates and query the index of the listview-item, which is
2381 * currently under the mouse cursor. */
2384 htinfo
.flags
= LVHT_ONITEM
;
2385 ::ScreenToClient(m_hWndList
, &htinfo
.pt
);
2386 lResult
= SendMessageW(m_hWndList
, LVM_HITTEST
, 0, (LPARAM
)&htinfo
);
2388 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2389 ::GetClientRect(m_hWndList
, &clientRect
);
2390 if (htinfo
.pt
.x
== m_ptLastMousePos
.x
&& htinfo
.pt
.y
== m_ptLastMousePos
.y
&&
2391 (htinfo
.pt
.x
< SCROLLAREAWIDTH
|| htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
||
2392 htinfo
.pt
.y
< SCROLLAREAWIDTH
|| htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
))
2394 m_cScrollDelay
= (m_cScrollDelay
+ 1) % 5; /* DragOver is called every 50 ms */
2395 if (m_cScrollDelay
== 0)
2397 /* Mouse did hover another 250 ms over the scroll-area */
2398 if (htinfo
.pt
.x
< SCROLLAREAWIDTH
)
2399 SendMessageW(m_hWndList
, WM_HSCROLL
, SB_LINEUP
, 0);
2401 if (htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
)
2402 SendMessageW(m_hWndList
, WM_HSCROLL
, SB_LINEDOWN
, 0);
2404 if (htinfo
.pt
.y
< SCROLLAREAWIDTH
)
2405 SendMessageW(m_hWndList
, WM_VSCROLL
, SB_LINEUP
, 0);
2407 if (htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
)
2408 SendMessageW(m_hWndList
, WM_VSCROLL
, SB_LINEDOWN
, 0);
2413 m_cScrollDelay
= 0; /* Reset, if the cursor is not over the listview's scroll-area */
2416 m_ptLastMousePos
= htinfo
.pt
;
2418 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2419 if (m_pCurDropTarget
&& lResult
== m_iDragOverItem
)
2420 return m_pCurDropTarget
->DragOver(grfKeyState
, pt
, pdwEffect
);
2422 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2423 if (m_pCurDropTarget
)
2425 m_pCurDropTarget
->DragLeave();
2426 m_pCurDropTarget
.Release();
2429 m_iDragOverItem
= lResult
;
2432 /* We are not above one of the listview's subitems. Bind to the parent folder's
2433 * DropTarget interface. */
2434 hr
= m_pSFParent
->QueryInterface(IID_PPV_ARG(IDropTarget
,&m_pCurDropTarget
));
2438 /* Query the relative PIDL of the shellfolder object represented by the currently
2439 * dragged over listview-item ... */
2440 lvItem
.mask
= LVIF_PARAM
;
2441 lvItem
.iItem
= lResult
;
2442 lvItem
.iSubItem
= 0;
2443 SendMessageW(m_hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
2445 /* ... and bind m_pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2446 hr
= m_pSFParent
->GetUIObjectOf(m_hWndList
, 1,
2447 (LPCITEMIDLIST
*)&lvItem
.lParam
, IID_IDropTarget
, NULL
, (LPVOID
*)&m_pCurDropTarget
);
2450 /* If anything failed, m_pCurDropTarget should be NULL now, which ought to be a save state. */
2454 /* Notify the item just entered via DragEnter. */
2455 return m_pCurDropTarget
->DragEnter(m_pCurDataObject
, grfKeyState
, pt
, pdwEffect
);
2458 HRESULT WINAPI
CDefView::DragEnter(IDataObject
*pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2460 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2461 m_pCurDataObject
= pDataObject
;
2462 pDataObject
->AddRef();
2464 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2467 HRESULT WINAPI
CDefView::DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2469 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2472 HRESULT WINAPI
CDefView::DragLeave()
2474 if (m_pCurDropTarget
)
2476 m_pCurDropTarget
->DragLeave();
2477 m_pCurDropTarget
.Release();
2480 if (m_pCurDataObject
!= NULL
)
2482 m_pCurDataObject
.Release();
2485 m_iDragOverItem
= 0;
2490 HRESULT WINAPI
CDefView::Drop(IDataObject
* pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2492 if (m_pCurDropTarget
)
2494 m_pCurDropTarget
->Drop(pDataObject
, grfKeyState
, pt
, pdwEffect
);
2495 m_pCurDropTarget
.Release();
2500 m_pCurDataObject
.Release(); m_iDragOverItem
= 0;
2505 /**********************************************************
2506 * ISVDropSource implementation
2509 HRESULT WINAPI
CDefView::QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
)
2511 TRACE("(%p)\n", this);
2514 return DRAGDROP_S_CANCEL
;
2515 else if (!(grfKeyState
& MK_LBUTTON
) && !(grfKeyState
& MK_RBUTTON
))
2516 return DRAGDROP_S_DROP
;
2521 HRESULT WINAPI
CDefView::GiveFeedback(DWORD dwEffect
)
2523 TRACE("(%p)\n", this);
2525 return DRAGDROP_S_USEDEFAULTCURSORS
;
2528 /**********************************************************
2529 * ISVViewObject implementation
2532 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
)
2534 FIXME("Stub: this=%p\n", this);
2539 HRESULT WINAPI
CDefView::GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
, HDC hicTargetDevice
, LOGPALETTE
**ppColorSet
)
2541 FIXME("Stub: this=%p\n", this);
2546 HRESULT WINAPI
CDefView::Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
)
2548 FIXME("Stub: this=%p\n", this);
2553 HRESULT WINAPI
CDefView::Unfreeze(DWORD dwFreeze
)
2555 FIXME("Stub: this=%p\n", this);
2560 HRESULT WINAPI
CDefView::SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
)
2562 FIXME("partial stub: %p %08x %08x %p\n", this, aspects
, advf
, pAdvSink
);
2564 /* FIXME: we set the AdviseSink, but never use it to send any advice */
2565 m_pAdvSink
= pAdvSink
;
2566 m_dwAspects
= aspects
;
2572 HRESULT WINAPI
CDefView::GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
)
2574 TRACE("this=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n", this, pAspects
, pAdvf
, ppAdvSink
);
2578 *ppAdvSink
= m_pAdvSink
;
2579 m_pAdvSink
.p
->AddRef();
2583 *pAspects
= m_dwAspects
;
2591 HRESULT STDMETHODCALLTYPE
CDefView::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
2593 if (IsEqualIID(guidService
, SID_IShellBrowser
))
2594 return m_pShellBrowser
->QueryInterface(riid
, ppvObject
);
2595 else if(IsEqualIID(guidService
, SID_IFolderView
))
2596 return QueryInterface(riid
, ppvObject
);
2598 return E_NOINTERFACE
;
2601 /**********************************************************
2602 * IShellView_Constructor
2604 HRESULT WINAPI
IShellView_Constructor(IShellFolder
*pFolder
, IShellView
**newView
)
2606 CComObject
<CDefView
> *theView
;
2607 CComPtr
<IShellView
> result
;
2610 if (newView
== NULL
)
2614 ATLTRY (theView
= new CComObject
<CDefView
>);
2616 if (theView
== NULL
)
2617 return E_OUTOFMEMORY
;
2619 hResult
= theView
->QueryInterface(IID_PPV_ARG(IShellView
, &result
));
2620 if (FAILED (hResult
))
2626 hResult
= theView
->Initialize (pFolder
);
2627 if (FAILED (hResult
))
2629 *newView
= result
.Detach ();