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
= static_cast<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
:
1810 LV_RenameItem(Pidls
[0], Pidls
[0]);
1813 case SHCNE_UPDATEDIR
:
1820 /**********************************************************
1821 * CDefView::OnCustomItem
1823 LRESULT
CDefView::OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1828 ERR("no menu!!!\n");
1832 CComPtr
<IContextMenu2
> pCM2
;
1833 HRESULT hres
= m_pCM
.p
->QueryInterface(IID_PPV_ARG(IContextMenu2
, &pCM2
));
1837 if (pCM2
.p
->HandleMenuMsg(uMsg
, (WPARAM
)m_hWnd
, lParam
) == S_OK
)
1843 LRESULT
CDefView::OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1845 /* Wallpaper setting affects drop shadows effect */
1846 if (wParam
== SPI_SETDESKWALLPAPER
|| wParam
== 0)
1852 /**********************************************************
1855 * The INTERFACE of the IShellView object
1858 **********************************************************
1861 /**********************************************************
1862 * ShellView_GetWindow
1864 HRESULT WINAPI
CDefView::GetWindow(HWND
*phWnd
)
1866 TRACE("(%p)\n", this);
1873 HRESULT WINAPI
CDefView::ContextSensitiveHelp(BOOL fEnterMode
)
1875 FIXME("(%p) stub\n", this);
1880 /**********************************************************
1881 * IShellView_TranslateAccelerator
1884 * use the accel functions
1886 HRESULT WINAPI
CDefView::TranslateAccelerator(LPMSG lpmsg
)
1888 if (lpmsg
->message
>= WM_KEYFIRST
&& lpmsg
->message
<= WM_KEYLAST
)
1890 if (::TranslateAcceleratorW(m_hWnd
, m_hAccel
, lpmsg
) != 0)
1893 /* FIXME: should call TranslateAcceleratorSB */
1895 TRACE("-- key=0x04%lx\n", lpmsg
->wParam
) ;
1898 return S_FALSE
; /* not handled */
1901 HRESULT WINAPI
CDefView::EnableModeless(BOOL fEnable
)
1903 FIXME("(%p) stub\n", this);
1908 HRESULT WINAPI
CDefView::UIActivate(UINT uState
)
1911 CHAR szName[MAX_PATH];
1914 int nPartArray
[1] = { -1};
1916 TRACE("(%p)->(state=%x) stub\n", this, uState
);
1918 /*don't do anything if the state isn't really changing*/
1919 if (m_uState
== uState
)
1924 /*OnActivate handles the menu merging and internal state*/
1927 /*only do This if we are active*/
1928 if (uState
!= SVUIA_DEACTIVATE
)
1932 GetFolderPath is not a method of IShellFolder
1933 IShellFolder_GetFolderPath( m_pSFParent, szName, sizeof(szName) );
1935 /* set the number of parts */
1936 m_pShellBrowser
->SendControlMsg(FCW_STATUS
, SB_SETPARTS
, 1, (LPARAM
)nPartArray
, &lResult
);
1938 /* set the text for the parts */
1940 m_pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXTA, 0, (LPARAM)szName, &lResult);
1947 HRESULT WINAPI
CDefView::Refresh()
1949 TRACE("(%p)\n", this);
1951 SendMessageW(m_hWndList
, LVM_DELETEALLITEMS
, 0, 0);
1957 HRESULT WINAPI
CDefView::CreateViewWindow(IShellView
*lpPrevView
, LPCFOLDERSETTINGS lpfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
)
1961 TRACE("(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n", this, lpPrevView
, lpfs
, psb
, prcView
, phWnd
);
1964 TRACE("-- vmode=%x flags=%x\n", lpfs
->ViewMode
, lpfs
->fFlags
);
1965 if (prcView
!= NULL
)
1966 TRACE("-- left=%i top=%i right=%i bottom=%i\n", prcView
->left
, prcView
->top
, prcView
->right
, prcView
->bottom
);
1968 /* Validate the Shell Browser */
1970 return E_UNEXPECTED
;
1972 /*set up the member variables*/
1973 m_pShellBrowser
= psb
;
1974 m_FolderSettings
= *lpfs
;
1976 /*get our parent window*/
1977 m_pShellBrowser
->GetWindow(&m_hWndParent
);
1979 /* try to get the ICommDlgBrowserInterface, adds a reference !!! */
1980 m_pCommDlgBrowser
= NULL
;
1981 if (SUCCEEDED(m_pShellBrowser
->QueryInterface(IID_PPV_ARG(ICommDlgBrowser
, &m_pCommDlgBrowser
))))
1983 TRACE("-- CommDlgBrowser\n");
1986 Create(m_hWndParent
, prcView
, NULL
, WS_CHILD
| WS_TABSTOP
, 0, 0U);
1997 SetWindowPos(HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_SHOWWINDOW
);
2003 HRESULT WINAPI
CDefView::DestroyViewWindow()
2005 TRACE("(%p)\n", this);
2007 /*Make absolutely sure all our UI is cleaned up.*/
2008 UIActivate(SVUIA_DEACTIVATE
);
2012 DestroyMenu(m_hMenu
);
2016 m_pShellBrowser
.Release();
2017 m_pCommDlgBrowser
.Release();
2022 HRESULT WINAPI
CDefView::GetCurrentInfo(LPFOLDERSETTINGS lpfs
)
2024 TRACE("(%p)->(%p) vmode=%x flags=%x\n", this, lpfs
,
2025 m_FolderSettings
.ViewMode
, m_FolderSettings
.fFlags
);
2028 return E_INVALIDARG
;
2030 *lpfs
= m_FolderSettings
;
2034 HRESULT WINAPI
CDefView::AddPropertySheetPages(DWORD dwReserved
, LPFNADDPROPSHEETPAGE lpfn
, LPARAM lparam
)
2036 FIXME("(%p) stub\n", this);
2041 HRESULT WINAPI
CDefView::SaveViewState()
2043 FIXME("(%p) stub\n", this);
2048 HRESULT WINAPI
CDefView::SelectItem(LPCITEMIDLIST pidl
, UINT uFlags
)
2052 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n", this, pidl
, uFlags
);
2054 i
= LV_FindItemByPidl(pidl
);
2060 if(uFlags
& SVSI_ENSUREVISIBLE
)
2061 SendMessageW(m_hWndList
, LVM_ENSUREVISIBLE
, i
, 0);
2063 lvItem
.mask
= LVIF_STATE
;
2064 lvItem
.stateMask
= LVIS_SELECTED
| LVIS_FOCUSED
;
2066 lvItem
.iSubItem
= 0;
2068 while (SendMessageW(m_hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
))
2070 if (lvItem
.iItem
== i
)
2072 if (uFlags
& SVSI_SELECT
)
2073 lvItem
.state
|= LVIS_SELECTED
;
2075 lvItem
.state
&= ~LVIS_SELECTED
;
2077 if (uFlags
& SVSI_FOCUSED
)
2078 lvItem
.state
&= ~LVIS_FOCUSED
;
2082 if (uFlags
& SVSI_DESELECTOTHERS
)
2083 lvItem
.state
&= ~LVIS_SELECTED
;
2086 SendMessageW(m_hWndList
, LVM_SETITEMW
, 0, (LPARAM
) &lvItem
);
2091 if(uFlags
& SVSI_EDIT
)
2092 SendMessageW(m_hWndList
, LVM_EDITLABELW
, i
, 0);
2098 HRESULT WINAPI
CDefView::GetItemObject(UINT uItem
, REFIID riid
, LPVOID
*ppvOut
)
2100 HRESULT hr
= E_NOINTERFACE
;
2102 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n", this, uItem
, debugstr_guid(&riid
), ppvOut
);
2108 case SVGIO_BACKGROUND
:
2109 if (IsEqualIID(riid
, IID_IContextMenu
))
2111 //*ppvOut = ISvBgCm_Constructor(m_pSFParent, FALSE);
2112 CDefFolderMenu_Create2(NULL
, NULL
, 0, NULL
, m_pSFParent
, NULL
, 0, NULL
, (IContextMenu
**)ppvOut
);
2120 case SVGIO_SELECTION
:
2122 hr
= m_pSFParent
->GetUIObjectOf(m_hWnd
, m_cidl
, (LPCITEMIDLIST
*)m_apidl
, riid
, 0, ppvOut
);
2126 TRACE("-- (%p)->(interface=%p)\n", this, *ppvOut
);
2131 HRESULT STDMETHODCALLTYPE
CDefView::GetCurrentViewMode(UINT
*pViewMode
)
2133 TRACE("(%p)->(%p), stub\n", this, pViewMode
);
2136 return E_INVALIDARG
;
2138 *pViewMode
= m_FolderSettings
.ViewMode
;
2142 HRESULT STDMETHODCALLTYPE
CDefView::SetCurrentViewMode(UINT ViewMode
)
2145 TRACE("(%p)->(%u), stub\n", this, ViewMode
);
2147 /* It's not redundant to check FVM_AUTO because it's a (UINT)-1 */
2148 if ((ViewMode
< FVM_FIRST
|| ViewMode
> FVM_LAST
) && (ViewMode
!= (UINT
)FVM_AUTO
))
2149 return E_INVALIDARG
;
2151 /* Windows before Vista uses LVM_SETVIEW and possibly
2152 LVM_SETEXTENDEDLISTVIEWSTYLE to set the style of the listview,
2153 while later versions seem to accomplish this through other
2161 dwStyle
= LVS_REPORT
;
2164 dwStyle
= LVS_SMALLICON
;
2171 FIXME("ViewMode %d not implemented\n", ViewMode
);
2177 SetStyle(dwStyle
, LVS_TYPEMASK
);
2179 /* This will not necessarily be the actual mode set above.
2180 This mimics the behavior of Windows XP. */
2181 m_FolderSettings
.ViewMode
= ViewMode
;
2186 HRESULT STDMETHODCALLTYPE
CDefView::GetFolder(REFIID riid
, void **ppv
)
2188 if (m_pSFParent
== NULL
)
2191 return m_pSFParent
->QueryInterface(riid
, ppv
);
2194 HRESULT STDMETHODCALLTYPE
CDefView::Item(int iItemIndex
, LPITEMIDLIST
*ppidl
)
2198 TRACE("(%p)->(%d %p)\n", this, iItemIndex
, ppidl
);
2200 item
.mask
= LVIF_PARAM
;
2201 item
.iItem
= iItemIndex
;
2203 if (SendMessageW(m_hWndList
, LVM_GETITEMW
, 0, (LPARAM
)&item
))
2205 *ppidl
= ILClone((PITEMID_CHILD
)item
.lParam
);
2211 return E_INVALIDARG
;
2214 HRESULT STDMETHODCALLTYPE
CDefView::ItemCount(UINT uFlags
, int *pcItems
)
2216 TRACE("(%p)->(%u %p)\n", this, uFlags
, pcItems
);
2218 if (uFlags
!= SVGIO_ALLVIEW
)
2219 FIXME("some flags unsupported, %x\n", uFlags
& ~SVGIO_ALLVIEW
);
2221 *pcItems
= SendMessageW(m_hWndList
, LVM_GETITEMCOUNT
, 0, 0);
2226 HRESULT STDMETHODCALLTYPE
CDefView::Items(UINT uFlags
, REFIID riid
, void **ppv
)
2231 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectionMarkedItem(int *piItem
)
2233 TRACE("(%p)->(%p)\n", this, piItem
);
2235 *piItem
= SendMessageW(m_hWndList
, LVM_GETSELECTIONMARK
, 0, 0);
2240 HRESULT STDMETHODCALLTYPE
CDefView::GetFocusedItem(int *piItem
)
2242 TRACE("(%p)->(%p)\n", this, piItem
);
2244 *piItem
= SendMessageW(m_hWndList
, LVM_GETNEXTITEM
, -1, LVNI_FOCUSED
);
2249 HRESULT STDMETHODCALLTYPE
CDefView::GetItemPosition(LPCITEMIDLIST pidl
, POINT
*ppt
)
2254 HRESULT STDMETHODCALLTYPE
CDefView::GetSpacing(POINT
*ppt
)
2256 TRACE("(%p)->(%p)\n", this, ppt
);
2258 if (NULL
== m_hWndList
) return S_FALSE
;
2262 const DWORD ret
= SendMessageW(m_hWndList
, LVM_GETITEMSPACING
, 0, 0);
2264 ppt
->x
= LOWORD(ret
);
2265 ppt
->y
= HIWORD(ret
);
2271 HRESULT STDMETHODCALLTYPE
CDefView::GetDefaultSpacing(POINT
*ppt
)
2276 HRESULT STDMETHODCALLTYPE
CDefView::GetAutoArrange()
2281 HRESULT STDMETHODCALLTYPE
CDefView::SelectItem(int iItem
, DWORD dwFlags
)
2285 TRACE("(%p)->(%d, %x)\n", this, iItem
, dwFlags
);
2288 lvItem
.stateMask
= LVIS_SELECTED
;
2290 if (dwFlags
& SVSI_ENSUREVISIBLE
)
2291 SendMessageW(m_hWndList
, LVM_ENSUREVISIBLE
, iItem
, 0);
2294 if (dwFlags
& SVSI_DESELECTOTHERS
)
2295 SendMessageW(m_hWndList
, LVM_SETITEMSTATE
, -1, (LPARAM
)&lvItem
);
2298 if (dwFlags
& SVSI_SELECT
)
2299 lvItem
.state
|= LVIS_SELECTED
;
2301 if (dwFlags
& SVSI_FOCUSED
)
2302 lvItem
.stateMask
|= LVIS_FOCUSED
;
2304 SendMessageW(m_hWndList
, LVM_SETITEMSTATE
, iItem
, (LPARAM
)&lvItem
);
2306 if (dwFlags
& SVSI_EDIT
)
2307 SendMessageW(m_hWndList
, LVM_EDITLABELW
, iItem
, 0);
2312 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItems(UINT cidl
, LPCITEMIDLIST
*apidl
, POINT
*apt
, DWORD dwFlags
)
2317 /**********************************************************
2318 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2320 HRESULT WINAPI
CDefView::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD
*prgCmds
, OLECMDTEXT
*pCmdText
)
2322 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
2323 this, pguidCmdGroup
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
2326 return E_INVALIDARG
;
2328 for (UINT i
= 0; i
< cCmds
; i
++)
2330 FIXME("\tprgCmds[%d].cmdID = %d\n", i
, prgCmds
[i
].cmdID
);
2331 prgCmds
[i
].cmdf
= 0;
2334 return OLECMDERR_E_UNKNOWNGROUP
;
2337 /**********************************************************
2338 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2340 * nCmdID is the OLECMDID_* enumeration
2342 HRESULT WINAPI
CDefView::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
2344 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2345 this, debugstr_guid(pguidCmdGroup
), nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2348 return OLECMDERR_E_UNKNOWNGROUP
;
2350 if (IsEqualIID(*pguidCmdGroup
, CGID_Explorer
) &&
2352 (nCmdexecopt
== 4) && pvaOut
)
2355 if (IsEqualIID(*pguidCmdGroup
, CGID_ShellDocView
) &&
2360 return OLECMDERR_E_UNKNOWNGROUP
;
2363 /**********************************************************
2364 * ISVDropTarget implementation
2367 /******************************************************************************
2368 * drag_notify_subitem [Internal]
2370 * Figure out the shellfolder object, which is currently under the mouse cursor
2371 * and notify it via the IDropTarget interface.
2374 #define SCROLLAREAWIDTH 20
2376 HRESULT
CDefView::drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2378 LVHITTESTINFO htinfo
;
2384 /* Map from global to client coordinates and query the index of the listview-item, which is
2385 * currently under the mouse cursor. */
2388 htinfo
.flags
= LVHT_ONITEM
;
2389 ::ScreenToClient(m_hWndList
, &htinfo
.pt
);
2390 lResult
= SendMessageW(m_hWndList
, LVM_HITTEST
, 0, (LPARAM
)&htinfo
);
2392 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2393 ::GetClientRect(m_hWndList
, &clientRect
);
2394 if (htinfo
.pt
.x
== m_ptLastMousePos
.x
&& htinfo
.pt
.y
== m_ptLastMousePos
.y
&&
2395 (htinfo
.pt
.x
< SCROLLAREAWIDTH
|| htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
||
2396 htinfo
.pt
.y
< SCROLLAREAWIDTH
|| htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
))
2398 m_cScrollDelay
= (m_cScrollDelay
+ 1) % 5; /* DragOver is called every 50 ms */
2399 if (m_cScrollDelay
== 0)
2401 /* Mouse did hover another 250 ms over the scroll-area */
2402 if (htinfo
.pt
.x
< SCROLLAREAWIDTH
)
2403 SendMessageW(m_hWndList
, WM_HSCROLL
, SB_LINEUP
, 0);
2405 if (htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
)
2406 SendMessageW(m_hWndList
, WM_HSCROLL
, SB_LINEDOWN
, 0);
2408 if (htinfo
.pt
.y
< SCROLLAREAWIDTH
)
2409 SendMessageW(m_hWndList
, WM_VSCROLL
, SB_LINEUP
, 0);
2411 if (htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
)
2412 SendMessageW(m_hWndList
, WM_VSCROLL
, SB_LINEDOWN
, 0);
2417 m_cScrollDelay
= 0; /* Reset, if the cursor is not over the listview's scroll-area */
2420 m_ptLastMousePos
= htinfo
.pt
;
2422 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2423 if (m_pCurDropTarget
&& lResult
== m_iDragOverItem
)
2424 return m_pCurDropTarget
->DragOver(grfKeyState
, pt
, pdwEffect
);
2426 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2427 if (m_pCurDropTarget
)
2429 m_pCurDropTarget
->DragLeave();
2430 m_pCurDropTarget
.Release();
2433 m_iDragOverItem
= lResult
;
2436 /* We are not above one of the listview's subitems. Bind to the parent folder's
2437 * DropTarget interface. */
2438 hr
= m_pSFParent
->QueryInterface(IID_PPV_ARG(IDropTarget
,&m_pCurDropTarget
));
2442 /* Query the relative PIDL of the shellfolder object represented by the currently
2443 * dragged over listview-item ... */
2444 lvItem
.mask
= LVIF_PARAM
;
2445 lvItem
.iItem
= lResult
;
2446 lvItem
.iSubItem
= 0;
2447 SendMessageW(m_hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
2449 /* ... and bind m_pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2450 hr
= m_pSFParent
->GetUIObjectOf(m_hWndList
, 1,
2451 (LPCITEMIDLIST
*)&lvItem
.lParam
, IID_IDropTarget
, NULL
, (LPVOID
*)&m_pCurDropTarget
);
2454 /* If anything failed, m_pCurDropTarget should be NULL now, which ought to be a save state. */
2458 /* Notify the item just entered via DragEnter. */
2459 return m_pCurDropTarget
->DragEnter(m_pCurDataObject
, grfKeyState
, pt
, pdwEffect
);
2462 HRESULT WINAPI
CDefView::DragEnter(IDataObject
*pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2464 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2465 m_pCurDataObject
= pDataObject
;
2466 pDataObject
->AddRef();
2468 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2471 HRESULT WINAPI
CDefView::DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2473 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2476 HRESULT WINAPI
CDefView::DragLeave()
2478 if (m_pCurDropTarget
)
2480 m_pCurDropTarget
->DragLeave();
2481 m_pCurDropTarget
.Release();
2484 if (m_pCurDataObject
!= NULL
)
2486 m_pCurDataObject
.Release();
2489 m_iDragOverItem
= 0;
2494 HRESULT WINAPI
CDefView::Drop(IDataObject
* pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2496 if (m_pCurDropTarget
)
2498 m_pCurDropTarget
->Drop(pDataObject
, grfKeyState
, pt
, pdwEffect
);
2499 m_pCurDropTarget
.Release();
2502 m_pCurDataObject
.Release();
2503 m_iDragOverItem
= 0;
2507 /**********************************************************
2508 * ISVDropSource implementation
2511 HRESULT WINAPI
CDefView::QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
)
2513 TRACE("(%p)\n", this);
2516 return DRAGDROP_S_CANCEL
;
2517 else if (!(grfKeyState
& MK_LBUTTON
) && !(grfKeyState
& MK_RBUTTON
))
2518 return DRAGDROP_S_DROP
;
2523 HRESULT WINAPI
CDefView::GiveFeedback(DWORD dwEffect
)
2525 TRACE("(%p)\n", this);
2527 return DRAGDROP_S_USEDEFAULTCURSORS
;
2530 /**********************************************************
2531 * ISVViewObject implementation
2534 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
)
2536 FIXME("Stub: this=%p\n", this);
2541 HRESULT WINAPI
CDefView::GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
, HDC hicTargetDevice
, LOGPALETTE
**ppColorSet
)
2543 FIXME("Stub: this=%p\n", this);
2548 HRESULT WINAPI
CDefView::Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
)
2550 FIXME("Stub: this=%p\n", this);
2555 HRESULT WINAPI
CDefView::Unfreeze(DWORD dwFreeze
)
2557 FIXME("Stub: this=%p\n", this);
2562 HRESULT WINAPI
CDefView::SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
)
2564 FIXME("partial stub: %p %08x %08x %p\n", this, aspects
, advf
, pAdvSink
);
2566 /* FIXME: we set the AdviseSink, but never use it to send any advice */
2567 m_pAdvSink
= pAdvSink
;
2568 m_dwAspects
= aspects
;
2574 HRESULT WINAPI
CDefView::GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
)
2576 TRACE("this=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n", this, pAspects
, pAdvf
, ppAdvSink
);
2580 *ppAdvSink
= m_pAdvSink
;
2581 m_pAdvSink
.p
->AddRef();
2585 *pAspects
= m_dwAspects
;
2593 HRESULT STDMETHODCALLTYPE
CDefView::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
2595 if (IsEqualIID(guidService
, SID_IShellBrowser
))
2596 return m_pShellBrowser
->QueryInterface(riid
, ppvObject
);
2597 else if(IsEqualIID(guidService
, SID_IFolderView
))
2598 return QueryInterface(riid
, ppvObject
);
2600 return E_NOINTERFACE
;
2603 /**********************************************************
2604 * IShellView_Constructor
2606 HRESULT WINAPI
IShellView_Constructor(IShellFolder
*pFolder
, IShellView
**newView
)
2608 CComObject
<CDefView
> *theView
;
2609 CComPtr
<IShellView
> result
;
2612 if (newView
== NULL
)
2616 ATLTRY (theView
= new CComObject
<CDefView
>);
2618 if (theView
== NULL
)
2619 return E_OUTOFMEMORY
;
2621 hResult
= theView
->QueryInterface(IID_PPV_ARG(IShellView
, &result
));
2622 if (FAILED (hResult
))
2628 hResult
= theView
->Initialize (pFolder
);
2629 if (FAILED (hResult
))
2631 *newView
= result
.Detach ();