4 * Copyright 1998,1999 <juergen.schmied@debitel.net>
6 * This is the view visualizing the data provided by the shellfolder.
7 * No direct access to data from pidls should be done from here.
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 * FIXME: The order by part of the background context menu should be
24 * built according to the columns shown.
26 * FIXME: CheckToolbar: handle the "new folder" and "folder up" button
28 * FIXME: ShellView_FillList: consider sort orders
33 1. Load/Save the view state from/into the stream provided by the ShellBrowser.
34 2. Let the shell folder sort items.
35 3. Code to merge menus in the shellbrowser is incorrect.
36 4. Move the background context menu creation into shell view. It should store the
37 shell view HWND to send commands.
38 5. Send init, measure, and draw messages to context menu during tracking.
39 6. Shell view should do SetCommandTarget on internet toolbar.
40 7. When editing starts on item, set edit text to for editing value.
41 8. When shell view is called back for item info, let listview save the value.
42 9. Shell view should update status bar.
43 10. Fix shell view to handle view mode popup exec.
44 11. The background context menu should have a pidl just like foreground menus. This
45 causes crashes when dynamic handlers try to use the NULL pidl.
46 12. The SHELLDLL_DefView should not be filled with blue unconditionally. This causes
47 annoying flashing of blue even on XP, and is not correct.
48 13. Reorder of columns doesn't work - might be bug in comctl32
53 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
57 static const WCHAR SV_CLASS_NAME
[] = {'S', 'H', 'E', 'L', 'L', 'D', 'L', 'L', '_', 'D', 'e', 'f', 'V', 'i', 'e', 'w', 0};
63 } LISTVIEW_SORT_INFO
, *LPLISTVIEW_SORT_INFO
;
65 #define SHV_CHANGE_NOTIFY WM_USER + 0x1111
68 public CWindowImpl
<CDefView
, CWindow
, CControlWinTraits
>,
69 public CComObjectRootEx
<CComMultiThreadModelNoCS
>,
72 public IOleCommandTarget
,
76 public IServiceProvider
79 CComPtr
<IShellFolder
> pSFParent
;
80 CComPtr
<IShellFolder2
> pSF2Parent
;
81 CComPtr
<IShellBrowser
> pShellBrowser
;
82 CComPtr
<ICommDlgBrowser
> pCommDlgBrowser
;
83 HWND hWndList
; /* ListView control */
85 FOLDERSETTINGS FolderSettings
;
90 LISTVIEW_SORT_INFO ListViewSortInfo
;
91 ULONG hNotify
; /* change notification handle */
95 CComPtr
<IAdviseSink
> pAdvSink
;
97 CComPtr
<IDropTarget
> pCurDropTarget
; /* The sub-item, which is currently dragged over */
98 CComPtr
<IDataObject
> pCurDataObject
; /* The dragged data-object */
99 LONG iDragOverItem
; /* Dragged over item's index, iff pCurDropTarget != NULL */
100 UINT cScrollDelay
; /* Send a WM_*SCROLL msg every 250 ms during drag-scroll */
101 POINT ptLastMousePos
; /* Mouse position at last DragOver call */
103 CComPtr
<IContextMenu2
> pCM
;
107 HRESULT WINAPI
Initialize(IShellFolder
*shellFolder
);
108 HRESULT
IncludeObject(LPCITEMIDLIST pidl
);
109 HRESULT
OnDefaultCommand();
110 HRESULT
OnStateChange(UINT uFlags
);
112 void SetStyle(DWORD dwAdd
, DWORD dwRemove
);
114 void UpdateListColors();
116 static INT CALLBACK
CompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
);
117 static INT CALLBACK
ListViewCompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
);
118 int LV_FindItemByPidl(LPCITEMIDLIST pidl
);
119 BOOLEAN
LV_AddItem(LPCITEMIDLIST pidl
);
120 BOOLEAN
LV_DeleteItem(LPCITEMIDLIST pidl
);
121 BOOLEAN
LV_RenameItem(LPCITEMIDLIST pidlOld
, LPCITEMIDLIST pidlNew
);
122 static INT CALLBACK
fill_list(LPVOID ptr
, LPVOID arg
);
124 HMENU
BuildFileMenu();
125 void MergeFileMenu(HMENU hSubMenu
);
126 void MergeViewMenu(HMENU hSubMenu
);
127 UINT
GetSelections();
128 HRESULT
OpenSelectedItems();
130 void DoActivate(UINT uState
);
131 HRESULT
drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
132 LRESULT
OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
);
134 // *** IOleWindow methods ***
135 virtual HRESULT STDMETHODCALLTYPE
GetWindow(HWND
*lphwnd
);
136 virtual HRESULT STDMETHODCALLTYPE
ContextSensitiveHelp(BOOL fEnterMode
);
138 // *** IShellView methods ***
139 virtual HRESULT STDMETHODCALLTYPE
TranslateAccelerator(MSG
*pmsg
);
140 virtual HRESULT STDMETHODCALLTYPE
EnableModeless(BOOL fEnable
);
141 virtual HRESULT STDMETHODCALLTYPE
UIActivate(UINT uState
);
142 virtual HRESULT STDMETHODCALLTYPE
Refresh();
143 virtual HRESULT STDMETHODCALLTYPE
CreateViewWindow(IShellView
*psvPrevious
, LPCFOLDERSETTINGS pfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
);
144 virtual HRESULT STDMETHODCALLTYPE
DestroyViewWindow();
145 virtual HRESULT STDMETHODCALLTYPE
GetCurrentInfo(LPFOLDERSETTINGS pfs
);
146 virtual HRESULT STDMETHODCALLTYPE
AddPropertySheetPages(DWORD dwReserved
, LPFNSVADDPROPSHEETPAGE pfn
, LPARAM lparam
);
147 virtual HRESULT STDMETHODCALLTYPE
SaveViewState();
148 virtual HRESULT STDMETHODCALLTYPE
SelectItem(LPCITEMIDLIST pidlItem
, SVSIF uFlags
);
149 virtual HRESULT STDMETHODCALLTYPE
GetItemObject(UINT uItem
, REFIID riid
, void **ppv
);
151 // *** IFolderView methods ***
152 virtual HRESULT STDMETHODCALLTYPE
GetCurrentViewMode(UINT
*pViewMode
);
153 virtual HRESULT STDMETHODCALLTYPE
SetCurrentViewMode(UINT ViewMode
);
154 virtual HRESULT STDMETHODCALLTYPE
GetFolder(REFIID riid
, void **ppv
);
155 virtual HRESULT STDMETHODCALLTYPE
Item(int iItemIndex
, LPITEMIDLIST
*ppidl
);
156 virtual HRESULT STDMETHODCALLTYPE
ItemCount(UINT uFlags
, int *pcItems
);
157 virtual HRESULT STDMETHODCALLTYPE
Items(UINT uFlags
, REFIID riid
, void **ppv
);
158 virtual HRESULT STDMETHODCALLTYPE
GetSelectionMarkedItem(int *piItem
);
159 virtual HRESULT STDMETHODCALLTYPE
GetFocusedItem(int *piItem
);
160 virtual HRESULT STDMETHODCALLTYPE
GetItemPosition(LPCITEMIDLIST pidl
, POINT
*ppt
);
161 virtual HRESULT STDMETHODCALLTYPE
GetSpacing(POINT
*ppt
);
162 virtual HRESULT STDMETHODCALLTYPE
GetDefaultSpacing(POINT
*ppt
);
163 virtual HRESULT STDMETHODCALLTYPE
GetAutoArrange();
164 virtual HRESULT STDMETHODCALLTYPE
SelectItem(int iItem
, DWORD dwFlags
);
165 virtual HRESULT STDMETHODCALLTYPE
SelectAndPositionItems(UINT cidl
, LPCITEMIDLIST
*apidl
, POINT
*apt
, DWORD dwFlags
);
167 // *** IOleCommandTarget methods ***
168 virtual HRESULT STDMETHODCALLTYPE
QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
);
169 virtual HRESULT STDMETHODCALLTYPE
Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
);
171 // *** IDropTarget methods ***
172 virtual HRESULT STDMETHODCALLTYPE
DragEnter(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
173 virtual HRESULT STDMETHODCALLTYPE
DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
174 virtual HRESULT STDMETHODCALLTYPE
DragLeave();
175 virtual HRESULT STDMETHODCALLTYPE
Drop(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
177 // *** IDropSource methods ***
178 virtual HRESULT STDMETHODCALLTYPE
QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
);
179 virtual HRESULT STDMETHODCALLTYPE
GiveFeedback(DWORD dwEffect
);
181 // *** IViewObject methods ***
182 virtual HRESULT STDMETHODCALLTYPE
Draw(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
,
183 HDC hdcTargetDev
, HDC hdcDraw
, LPCRECTL lprcBounds
, LPCRECTL lprcWBounds
,
184 BOOL ( STDMETHODCALLTYPE
*pfnContinue
)(ULONG_PTR dwContinue
), ULONG_PTR dwContinue
);
185 virtual HRESULT STDMETHODCALLTYPE
GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
,
186 DVTARGETDEVICE
*ptd
, HDC hicTargetDev
, LOGPALETTE
**ppColorSet
);
187 virtual HRESULT STDMETHODCALLTYPE
Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
);
188 virtual HRESULT STDMETHODCALLTYPE
Unfreeze(DWORD dwFreeze
);
189 virtual HRESULT STDMETHODCALLTYPE
SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
);
190 virtual HRESULT STDMETHODCALLTYPE
GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
);
192 // *** IServiceProvider methods ***
193 virtual HRESULT STDMETHODCALLTYPE
QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
);
196 LRESULT
OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
197 LRESULT
OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
198 LRESULT
OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
199 LRESULT
OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
200 LRESULT
OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
201 LRESULT
OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
202 LRESULT
OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
203 LRESULT
OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
204 LRESULT
OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
205 LRESULT
OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
206 LRESULT
OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
207 LRESULT
OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
208 LRESULT
OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
209 LRESULT
OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
210 LRESULT
OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
211 LRESULT
OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
212 LRESULT
OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
214 static ATL::CWndClassInfo
& GetWndClassInfo()
216 static ATL::CWndClassInfo wc
=
218 { sizeof(WNDCLASSEX
), 0, StartWindowProc
,
220 LoadCursor(NULL
, IDC_ARROW
), (HBRUSH
)(COLOR_BACKGROUND
+ 1), NULL
, SV_CLASS_NAME
, NULL
222 NULL
, NULL
, IDC_ARROW
, TRUE
, 0, _T("")
227 virtual WNDPROC
GetWindowProc()
232 static LRESULT CALLBACK
WindowProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
237 // must hold a reference during message handling
238 pThis
= reinterpret_cast<CDefView
*>(hWnd
);
240 result
= CWindowImpl
<CDefView
, CWindow
, CControlWinTraits
>::WindowProc(hWnd
, uMsg
, wParam
, lParam
);
245 BEGIN_MSG_MAP(CDefView
)
246 MESSAGE_HANDLER(WM_SIZE
, OnSize
)
247 MESSAGE_HANDLER(WM_SETFOCUS
, OnSetFocus
)
248 MESSAGE_HANDLER(WM_KILLFOCUS
, OnKillFocus
)
249 MESSAGE_HANDLER(WM_CREATE
, OnCreate
)
250 MESSAGE_HANDLER(WM_ACTIVATE
, OnActivate
)
251 MESSAGE_HANDLER(WM_NOTIFY
, OnNotify
)
252 MESSAGE_HANDLER(WM_COMMAND
, OnCommand
)
253 MESSAGE_HANDLER(SHV_CHANGE_NOTIFY
, OnChangeNotify
)
254 MESSAGE_HANDLER(WM_CONTEXTMENU
, OnContextMenu
)
255 MESSAGE_HANDLER(WM_DRAWITEM
, OnCustomItem
)
256 MESSAGE_HANDLER(WM_MEASUREITEM
, OnCustomItem
)
257 MESSAGE_HANDLER(WM_SHOWWINDOW
, OnShowWindow
)
258 MESSAGE_HANDLER(WM_GETDLGCODE
, OnGetDlgCode
)
259 MESSAGE_HANDLER(WM_DESTROY
, OnDestroy
)
260 MESSAGE_HANDLER(WM_ERASEBKGND
, OnEraseBackground
)
261 MESSAGE_HANDLER(WM_SYSCOLORCHANGE
, OnSysColorChange
)
262 MESSAGE_HANDLER(CWM_GETISHELLBROWSER
, OnGetShellBrowser
)
263 MESSAGE_HANDLER(WM_SETTINGCHANGE
, OnSettingChange
)
266 BEGIN_COM_MAP(CDefView
)
267 COM_INTERFACE_ENTRY_IID(IID_IOleWindow
, IOleWindow
)
268 COM_INTERFACE_ENTRY_IID(IID_IShellView
, IShellView
)
269 COM_INTERFACE_ENTRY_IID(IID_IFolderView
, IFolderView
)
270 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget
, IOleCommandTarget
)
271 COM_INTERFACE_ENTRY_IID(IID_IDropTarget
, IDropTarget
)
272 COM_INTERFACE_ENTRY_IID(IID_IDropSource
, IDropSource
)
273 COM_INTERFACE_ENTRY_IID(IID_IViewObject
, IViewObject
)
274 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider
, IServiceProvider
)
278 /* ListView Header ID's */
279 #define LISTVIEW_COLUMN_NAME 0
280 #define LISTVIEW_COLUMN_SIZE 1
281 #define LISTVIEW_COLUMN_TYPE 2
282 #define LISTVIEW_COLUMN_TIME 3
283 #define LISTVIEW_COLUMN_ATTRIB 4
286 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
287 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
288 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
290 #define ID_LISTVIEW 1
293 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
294 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
295 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
298 Items merged into the toolbar and the filemenu
307 } MYTOOLINFO
, *LPMYTOOLINFO
;
309 static const MYTOOLINFO Tools
[] =
311 { FCIDM_SHVIEW_BIGICON
, 0, 0, IDS_VIEW_LARGE
, TBSTATE_ENABLED
, BTNS_BUTTON
},
312 { FCIDM_SHVIEW_SMALLICON
, 0, 0, IDS_VIEW_SMALL
, TBSTATE_ENABLED
, BTNS_BUTTON
},
313 { FCIDM_SHVIEW_LISTVIEW
, 0, 0, IDS_VIEW_LIST
, TBSTATE_ENABLED
, BTNS_BUTTON
},
314 { FCIDM_SHVIEW_REPORTVIEW
, 0, 0, IDS_VIEW_DETAILS
, TBSTATE_ENABLED
, BTNS_BUTTON
},
318 typedef void (CALLBACK
*PFNSHGETSETTINGSPROC
)(LPSHELLFLAGSTATE lpsfs
, DWORD dwMask
);
324 FolderSettings
.fFlags
= 0;
325 FolderSettings
.ViewMode
= 0;
330 ListViewSortInfo
.bIsAscending
= FALSE
;
331 ListViewSortInfo
.nHeaderID
= 0;
332 ListViewSortInfo
.nLastHeaderID
= 0;
339 ptLastMousePos
.x
= 0;
340 ptLastMousePos
.y
= 0;
343 CDefView::~CDefView()
345 TRACE(" destroying IShellView(%p)\n", this);
350 HRESULT WINAPI
CDefView::Initialize(IShellFolder
*shellFolder
)
352 pSFParent
= shellFolder
;
353 shellFolder
->QueryInterface(IID_PPV_ARG(IShellFolder2
, &pSF2Parent
));
358 /**********************************************************
360 * ##### helperfunctions for communication with ICommDlgBrowser #####
362 HRESULT
CDefView::IncludeObject(LPCITEMIDLIST pidl
)
366 if (pCommDlgBrowser
.p
!= NULL
)
368 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl
);
369 ret
= pCommDlgBrowser
->IncludeObject((IShellView
*)this, pidl
);
370 TRACE("--0x%08x\n", ret
);
376 HRESULT
CDefView::OnDefaultCommand()
378 HRESULT ret
= S_FALSE
;
380 if (pCommDlgBrowser
.p
!= NULL
)
382 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
383 ret
= pCommDlgBrowser
->OnDefaultCommand((IShellView
*)this);
384 TRACE("-- returns %08x\n", ret
);
390 HRESULT
CDefView::OnStateChange(UINT uFlags
)
392 HRESULT ret
= S_FALSE
;
394 if (pCommDlgBrowser
.p
!= NULL
)
396 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags
);
397 ret
= pCommDlgBrowser
->OnStateChange((IShellView
*)this, uFlags
);
403 /**********************************************************
404 * set the toolbar of the filedialog buttons
406 * - activates the buttons from the shellbrowser according to
409 void CDefView::CheckToolbar()
415 if (pCommDlgBrowser
!= NULL
)
417 pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
418 FCIDM_TB_SMALLICON
, (FolderSettings
.ViewMode
== FVM_LIST
) ? TRUE
: FALSE
, &result
);
419 pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
420 FCIDM_TB_REPORTVIEW
, (FolderSettings
.ViewMode
== FVM_DETAILS
) ? TRUE
: FALSE
, &result
);
421 pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
422 FCIDM_TB_SMALLICON
, TRUE
, &result
);
423 pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
424 FCIDM_TB_REPORTVIEW
, TRUE
, &result
);
428 /**********************************************************
430 * ##### helperfunctions for initializing the view #####
432 /**********************************************************
433 * change the style of the listview control
435 void CDefView::SetStyle(DWORD dwAdd
, DWORD dwRemove
)
439 TRACE("(%p)\n", this);
441 tmpstyle
= ::GetWindowLongPtrW(hWndList
, GWL_STYLE
);
442 ::SetWindowLongPtrW(hWndList
, GWL_STYLE
, dwAdd
| (tmpstyle
& ~dwRemove
));
445 /**********************************************************
446 * ShellView_CreateList()
448 * - creates the list view window
450 BOOL
CDefView::CreateList()
451 { DWORD dwStyle
, dwExStyle
;
455 dwStyle
= WS_TABSTOP
| WS_VISIBLE
| WS_CHILDWINDOW
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
|
456 LVS_SHAREIMAGELISTS
| LVS_EDITLABELS
| LVS_AUTOARRANGE
;
457 dwExStyle
= WS_EX_CLIENTEDGE
;
459 if (FolderSettings
.fFlags
& FWF_DESKTOP
)
460 dwStyle
|= LVS_ALIGNLEFT
;
462 dwStyle
|= LVS_ALIGNTOP
;
464 switch (FolderSettings
.ViewMode
)
471 dwStyle
|= LVS_REPORT
;
475 dwStyle
|= LVS_SMALLICON
;
487 if (FolderSettings
.fFlags
& FWF_AUTOARRANGE
)
488 dwStyle
|= LVS_AUTOARRANGE
;
490 if (FolderSettings
.fFlags
& FWF_DESKTOP
)
491 FolderSettings
.fFlags
|= FWF_NOCLIENTEDGE
| FWF_NOSCROLL
;
493 if (FolderSettings
.fFlags
& FWF_SINGLESEL
)
494 dwStyle
|= LVS_SINGLESEL
;
496 if (FolderSettings
.fFlags
& FWF_NOCLIENTEDGE
)
497 dwExStyle
&= ~WS_EX_CLIENTEDGE
;
499 hWndList
= CreateWindowExW( dwExStyle
,
512 ListViewSortInfo
.bIsAscending
= TRUE
;
513 ListViewSortInfo
.nHeaderID
= -1;
514 ListViewSortInfo
.nLastHeaderID
= -1;
518 /* UpdateShellSettings(); */
522 void CDefView::UpdateListColors()
524 if (FolderSettings
.fFlags
& FWF_DESKTOP
)
526 /* Check if drop shadows option is enabled */
527 BOOL bDropShadow
= FALSE
;
528 DWORD cbDropShadow
= sizeof(bDropShadow
);
529 WCHAR wszBuf
[16] = L
"";
531 RegGetValueW(HKEY_CURRENT_USER
, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
532 L
"ListviewShadow", RRF_RT_DWORD
, NULL
, &bDropShadow
, &cbDropShadow
);
533 if (bDropShadow
&& SystemParametersInfoW(SPI_GETDESKWALLPAPER
, _countof(wszBuf
), wszBuf
, 0) && wszBuf
[0])
535 SendMessageW(hWndList
, LVM_SETTEXTBKCOLOR
, 0, CLR_NONE
);
536 SendMessageW(hWndList
, LVM_SETBKCOLOR
, 0, CLR_NONE
);
537 SendMessageW(hWndList
, LVM_SETTEXTCOLOR
, 0, RGB(255, 255, 255));
538 SendMessageW(hWndList
, LVM_SETEXTENDEDLISTVIEWSTYLE
, LVS_EX_TRANSPARENTSHADOWTEXT
, LVS_EX_TRANSPARENTSHADOWTEXT
);
542 COLORREF crDesktop
= GetSysColor(COLOR_DESKTOP
);
543 SendMessageW(hWndList
, LVM_SETTEXTBKCOLOR
, 0, crDesktop
);
544 SendMessageW(hWndList
, LVM_SETBKCOLOR
, 0, crDesktop
);
545 if (GetRValue(crDesktop
) + GetGValue(crDesktop
) + GetBValue(crDesktop
) > 128 * 3)
546 SendMessageW(hWndList
, LVM_SETTEXTCOLOR
, 0, RGB(0, 0, 0));
548 SendMessageW(hWndList
, LVM_SETTEXTCOLOR
, 0, RGB(255, 255, 255));
549 SendMessageW(hWndList
, LVM_SETEXTENDEDLISTVIEWSTYLE
, LVS_EX_TRANSPARENTSHADOWTEXT
, 0);
554 /**********************************************************
555 * ShellView_InitList()
557 * - adds all needed columns to the shellview
559 BOOL
CDefView::InitList()
567 SendMessageW(hWndList
, LVM_DELETEALLITEMS
, 0, 0);
569 lvColumn
.mask
= LVCF_FMT
| LVCF_WIDTH
| LVCF_TEXT
;
570 lvColumn
.pszText
= szTemp
;
574 for (int i
= 0; 1; i
++)
576 if (FAILED(pSF2Parent
->GetDetailsOf(NULL
, i
, &sd
)))
579 lvColumn
.fmt
= sd
.fmt
;
580 lvColumn
.cx
= sd
.cxChar
* 8; /* chars->pixel */
581 StrRetToStrNW( szTemp
, 50, &sd
.str
, NULL
);
582 SendMessageW(hWndList
, LVM_INSERTCOLUMNW
, i
, (LPARAM
) &lvColumn
);
590 SendMessageW(hWndList
, LVM_SETIMAGELIST
, LVSIL_SMALL
, (LPARAM
)ShellSmallIconList
);
591 SendMessageW(hWndList
, LVM_SETIMAGELIST
, LVSIL_NORMAL
, (LPARAM
)ShellBigIconList
);
596 /**********************************************************
597 * ShellView_CompareItems()
600 * internal, CALLBACK for DSA_Sort
602 INT CALLBACK
CDefView::CompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
)
605 TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1
, lParam2
, (LPVOID
) lpData
);
610 ret
= (SHORT
)SCODE_CODE(((IShellFolder
*)lpData
)->CompareIDs(0, (LPITEMIDLIST
)lParam1
, (LPITEMIDLIST
)lParam2
));
611 TRACE("ret=%i\n", ret
);
616 /*************************************************************************
617 * ShellView_ListViewCompareItems
619 * Compare Function for the Listview (FileOpen Dialog)
622 * lParam1 [I] the first ItemIdList to compare with
623 * lParam2 [I] the second ItemIdList to compare with
624 * lpData [I] The column ID for the header Ctrl to process
627 * A negative value if the first item should precede the second,
628 * a positive value if the first item should follow the second,
629 * or zero if the two items are equivalent
632 * FIXME: function does what ShellView_CompareItems is supposed to do.
633 * unify it and figure out how to use the undocumented first parameter
634 * of IShellFolder_CompareIDs to do the job this function does and
635 * move this code to IShellFolder.
636 * make LISTVIEW_SORT_INFO obsolete
637 * the way this function works is only usable if we had only
638 * filesystemfolders (25/10/99 jsch)
640 INT CALLBACK
CDefView::ListViewCompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
)
644 char strName1
[MAX_PATH
], strName2
[MAX_PATH
];
645 BOOL bIsFolder1
, bIsFolder2
, bIsBothFolder
;
646 LPITEMIDLIST pItemIdList1
= (LPITEMIDLIST
) lParam1
;
647 LPITEMIDLIST pItemIdList2
= (LPITEMIDLIST
) lParam2
;
648 LISTVIEW_SORT_INFO
*pSortInfo
= (LPLISTVIEW_SORT_INFO
) lpData
;
651 bIsFolder1
= _ILIsFolder(pItemIdList1
);
652 bIsFolder2
= _ILIsFolder(pItemIdList2
);
653 bIsBothFolder
= bIsFolder1
&& bIsFolder2
;
655 /* When sorting between a File and a Folder, the Folder gets sorted first */
656 if ( (bIsFolder1
|| bIsFolder2
) && !bIsBothFolder
)
658 nDiff
= bIsFolder1
? -1 : 1;
662 /* Sort by Time: Folders or Files can be sorted */
664 if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_TIME
)
666 _ILGetFileDateTime(pItemIdList1
, &fd1
);
667 _ILGetFileDateTime(pItemIdList2
, &fd2
);
668 nDiff
= CompareFileTime(&fd2
, &fd1
);
670 /* Sort by Attribute: Folder or Files can be sorted */
671 else if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_ATTRIB
)
673 _ILGetFileAttributes(pItemIdList1
, strName1
, MAX_PATH
);
674 _ILGetFileAttributes(pItemIdList2
, strName2
, MAX_PATH
);
675 nDiff
= lstrcmpiA(strName1
, strName2
);
677 /* Sort by FileName: Folder or Files can be sorted */
678 else if (pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_NAME
|| bIsBothFolder
)
681 _ILSimpleGetText(pItemIdList1
, strName1
, MAX_PATH
);
682 _ILSimpleGetText(pItemIdList2
, strName2
, MAX_PATH
);
683 nDiff
= lstrcmpiA(strName1
, strName2
);
685 /* Sort by File Size, Only valid for Files */
686 else if (pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_SIZE
)
688 nDiff
= (INT
)(_ILGetFileSize(pItemIdList1
, NULL
, 0) - _ILGetFileSize(pItemIdList2
, NULL
, 0));
690 /* Sort by File Type, Only valid for Files */
691 else if (pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_TYPE
)
694 _ILGetFileType(pItemIdList1
, strName1
, MAX_PATH
);
695 _ILGetFileType(pItemIdList2
, strName2
, MAX_PATH
);
696 nDiff
= lstrcmpiA(strName1
, strName2
);
699 /* If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
703 _ILSimpleGetText(pItemIdList1
, strName1
, MAX_PATH
);
704 _ILSimpleGetText(pItemIdList2
, strName2
, MAX_PATH
);
705 nDiff
= lstrcmpiA(strName1
, strName2
);
708 if (!pSortInfo
->bIsAscending
)
716 /**********************************************************
717 * LV_FindItemByPidl()
719 int CDefView::LV_FindItemByPidl(LPCITEMIDLIST pidl
)
723 lvItem
.mask
= LVIF_PARAM
;
725 for (lvItem
.iItem
= 0;
726 SendMessageW(hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
729 LPITEMIDLIST currentpidl
= (LPITEMIDLIST
) lvItem
.lParam
;
730 HRESULT hr
= pSFParent
->CompareIDs(0, pidl
, currentpidl
);
732 if (SUCCEEDED(hr
) && !HRESULT_CODE(hr
))
740 /**********************************************************
743 BOOLEAN
CDefView::LV_AddItem(LPCITEMIDLIST pidl
)
747 TRACE("(%p)(pidl=%p)\n", this, pidl
);
749 lvItem
.mask
= LVIF_TEXT
| LVIF_IMAGE
| LVIF_PARAM
; /*set the mask*/
750 lvItem
.iItem
= ListView_GetItemCount(hWndList
); /*add the item to the end of the list*/
752 lvItem
.lParam
= (LPARAM
) ILClone(ILFindLastID(pidl
)); /*set the item's data*/
753 lvItem
.pszText
= LPSTR_TEXTCALLBACKW
; /*get text on a callback basis*/
754 lvItem
.iImage
= I_IMAGECALLBACK
; /*get the image on a callback basis*/
756 if (SendMessageW(hWndList
, LVM_INSERTITEMW
, 0, (LPARAM
)&lvItem
) == -1)
762 /**********************************************************
765 BOOLEAN
CDefView::LV_DeleteItem(LPCITEMIDLIST pidl
)
769 TRACE("(%p)(pidl=%p)\n", this, pidl
);
771 nIndex
= LV_FindItemByPidl(ILFindLastID(pidl
));
773 return (-1 == ListView_DeleteItem(hWndList
, nIndex
)) ? FALSE
: TRUE
;
776 /**********************************************************
779 BOOLEAN
CDefView::LV_RenameItem(LPCITEMIDLIST pidlOld
, LPCITEMIDLIST pidlNew
)
784 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", this, pidlOld
, pidlNew
);
786 nItem
= LV_FindItemByPidl(ILFindLastID(pidlOld
));
790 lvItem
.mask
= LVIF_PARAM
; /* only the pidl */
791 lvItem
.iItem
= nItem
;
792 SendMessageW(hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
794 SHFree((LPITEMIDLIST
)lvItem
.lParam
);
795 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
796 lvItem
.iItem
= nItem
;
797 lvItem
.lParam
= (LPARAM
) ILClone(ILFindLastID(pidlNew
)); /* set the item's data */
798 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(pSFParent
, pidlNew
, 0);
799 SendMessageW(hWndList
, LVM_SETITEMW
, 0, (LPARAM
) &lvItem
);
800 SendMessageW(hWndList
, LVM_UPDATE
, nItem
, 0);
801 return TRUE
; /* FIXME: better handling */
807 /**********************************************************
808 * ShellView_FillList()
810 * - gets the objectlist from the shellfolder
812 * - fills the list into the view
814 INT CALLBACK
CDefView::fill_list( LPVOID ptr
, LPVOID arg
)
816 LPITEMIDLIST pidl
= (LPITEMIDLIST
)ptr
;
817 CDefView
*pThis
= (CDefView
*)arg
;
818 /* in a commdlg This works as a filemask*/
819 if (pThis
->IncludeObject(pidl
) == S_OK
)
820 pThis
->LV_AddItem(pidl
);
826 HRESULT
CDefView::FillList()
828 LPENUMIDLIST pEnumIDList
;
836 /* get the itemlist from the shfolder*/
837 hRes
= pSFParent
->EnumObjects(m_hWnd
, SHCONTF_NONFOLDERS
| SHCONTF_FOLDERS
, &pEnumIDList
);
845 /* create a pointer array */
846 hdpa
= DPA_Create(16);
849 return(E_OUTOFMEMORY
);
852 /* copy the items into the array*/
853 while((S_OK
== pEnumIDList
->Next(1, &pidl
, &dwFetched
)) && dwFetched
)
855 if (DPA_InsertPtr(hdpa
, 0x7fff, pidl
) == -1)
862 DPA_Sort(hdpa
, CompareItems
, (LPARAM
)pSFParent
.p
);
864 /*turn the listview's redrawing off*/
865 SendMessageA(hWndList
, WM_SETREDRAW
, FALSE
, 0);
867 DPA_DestroyCallback( hdpa
, fill_list
, (void *)this);
869 /*turn the listview's redrawing back on and force it to draw*/
870 SendMessageA(hWndList
, WM_SETREDRAW
, TRUE
, 0);
872 pEnumIDList
->Release(); /* destroy the list*/
877 LRESULT
CDefView::OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
879 ::UpdateWindow(hWndList
);
884 LRESULT
CDefView::OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
886 return SendMessageW(hWndList
, uMsg
, 0, 0);
889 LRESULT
CDefView::OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
891 RevokeDragDrop(m_hWnd
);
892 SHChangeNotifyDeregister(hNotify
);
897 LRESULT
CDefView::OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
899 if (FolderSettings
.fFlags
& (FWF_DESKTOP
| FWF_TRANSPARENT
))
900 return SendMessageW(GetParent(), WM_ERASEBKGND
, wParam
, lParam
); /* redirect to parent */
906 LRESULT
CDefView::OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
908 /* Update desktop labels color */
911 /* Forward WM_SYSCOLORCHANGE to common controls */
912 return SendMessageW(hWndList
, uMsg
, 0, 0);
915 LRESULT
CDefView::OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
917 return (LRESULT
)pShellBrowser
.p
;
920 /**********************************************************
921 * ShellView_OnCreate()
923 LRESULT
CDefView::OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
925 CComPtr
<IDropTarget
> pdt
;
926 SHChangeNotifyEntry ntreg
;
927 CComPtr
<IPersistFolder2
> ppf2
;
939 if (SUCCEEDED(QueryInterface(IID_PPV_ARG(IDropTarget
, &pdt
))))
940 RegisterDragDrop(m_hWnd
, pdt
);
942 /* register for receiving notifications */
943 pSFParent
->QueryInterface(IID_PPV_ARG(IPersistFolder2
, &ppf2
));
946 ppf2
->GetCurFolder((LPITEMIDLIST
*)&ntreg
.pidl
);
947 ntreg
.fRecursive
= TRUE
;
948 hNotify
= SHChangeNotifyRegister(m_hWnd
, SHCNF_IDLIST
, SHCNE_ALLEVENTS
, SHV_CHANGE_NOTIFY
, 1, &ntreg
);
949 SHFree((LPITEMIDLIST
)ntreg
.pidl
);
952 hAccel
= LoadAcceleratorsA(shell32_hInstance
, MAKEINTRESOURCEA( IDA_SHELLVIEW
));
957 /**********************************************************
958 * #### Handling of the menus ####
961 /**********************************************************
962 * ShellView_BuildFileMenu()
964 HMENU
CDefView::BuildFileMenu()
965 { WCHAR szText
[MAX_PATH
];
970 TRACE("(%p)\n", this);
972 hSubMenu
= CreatePopupMenu();
975 /*get the number of items in our global array*/
976 for(nTools
= 0; Tools
[nTools
].idCommand
!= -1; nTools
++) {}
978 /*add the menu items*/
979 for(i
= 0; i
< nTools
; i
++)
981 LoadStringW(shell32_hInstance
, Tools
[i
].idMenuString
, szText
, MAX_PATH
);
983 ZeroMemory(&mii
, sizeof(mii
));
984 mii
.cbSize
= sizeof(mii
);
985 mii
.fMask
= MIIM_TYPE
| MIIM_ID
| MIIM_STATE
;
987 if(BTNS_SEP
!= Tools
[i
].bStyle
) /* no separator*/
989 mii
.fType
= MFT_STRING
;
990 mii
.fState
= MFS_ENABLED
;
991 mii
.dwTypeData
= szText
;
992 mii
.wID
= Tools
[i
].idCommand
;
996 mii
.fType
= MFT_SEPARATOR
;
998 /* tack This item onto the end of the menu */
999 InsertMenuItemW(hSubMenu
, (UINT
) - 1, TRUE
, &mii
);
1003 TRACE("-- return (menu=%p)\n", hSubMenu
);
1007 /**********************************************************
1008 * ShellView_MergeFileMenu()
1010 void CDefView::MergeFileMenu(HMENU hSubMenu
)
1012 TRACE("(%p)->(submenu=%p) stub\n", this, hSubMenu
);
1015 { /*insert This item at the beginning of the menu */
1016 _InsertMenuItemW(hSubMenu
, 0, TRUE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1017 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
, MFT_STRING
, L
"dummy45", MFS_ENABLED
);
1023 /**********************************************************
1024 * ShellView_MergeViewMenu()
1026 void CDefView::MergeViewMenu(HMENU hSubMenu
)
1028 TRACE("(%p)->(submenu=%p)\n", this, hSubMenu
);
1032 /*add a separator at the correct position in the menu*/
1034 static WCHAR view
[] = L
"View";
1036 _InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1038 ZeroMemory(&mii
, sizeof(mii
));
1039 mii
.cbSize
= sizeof(mii
);
1040 mii
.fMask
= MIIM_SUBMENU
| MIIM_TYPE
| MIIM_DATA
;
1041 mii
.fType
= MFT_STRING
;
1042 mii
.dwTypeData
= view
;
1043 mii
.hSubMenu
= LoadMenuW(shell32_hInstance
, L
"MENU_001");
1044 InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, &mii
);
1048 /**********************************************************
1049 * ShellView_GetSelections()
1051 * - fills the this->apidl list with the selected objects
1054 * number of selected items
1056 UINT
CDefView::GetSelections()
1063 cidl
= ListView_GetSelectedCount(hWndList
);
1064 apidl
= (LPITEMIDLIST
*)SHAlloc(cidl
* sizeof(LPITEMIDLIST
));
1066 TRACE("selected=%i\n", cidl
);
1070 TRACE("-- Items selected =%u\n", cidl
);
1072 lvItem
.mask
= LVIF_STATE
| LVIF_PARAM
;
1073 lvItem
.stateMask
= LVIS_SELECTED
;
1075 lvItem
.iSubItem
= 0;
1078 while(SendMessageW(hWndList
, LVM_GETITEMW
, 0, (LPARAM
)&lvItem
) && (i
< cidl
))
1080 if(lvItem
.state
& LVIS_SELECTED
)
1082 apidl
[i
] = (LPITEMIDLIST
)lvItem
.lParam
;
1086 TRACE("-- selected Item found\n");
1095 /**********************************************************
1096 * ShellView_OpenSelectedItems()
1098 HRESULT
CDefView::OpenSelectedItems()
1101 CMINVOKECOMMANDINFO cmi
;
1105 cidl
= ListView_GetSelectedCount(hWndList
);
1109 hResult
= OnDefaultCommand();
1110 if (hResult
== S_OK
)
1113 hMenu
= CreatePopupMenu();
1117 hResult
= GetItemObject( SVGIO_SELECTION
, IID_PPV_ARG(IContextMenu2
, &pCM
));
1118 if (FAILED(hResult
))
1121 hResult
= IUnknown_SetSite(pCM
, (IShellView
*)this);
1122 //if (FAILED( hResult))
1125 hResult
= pCM
->QueryContextMenu(hMenu
, 0, 0x20, 0x7fff, CMF_DEFAULTONLY
);
1126 if (FAILED(hResult
))
1129 uCommand
= GetMenuDefaultItem(hMenu
, FALSE
, 0);
1130 if (uCommand
== (UINT
)-1)
1136 ZeroMemory(&cmi
, sizeof(cmi
));
1137 cmi
.cbSize
= sizeof(cmi
);
1138 cmi
.lpVerb
= (LPCSTR
)MAKEINTRESOURCEA(uCommand
);
1141 hResult
= pCM
->InvokeCommand(&cmi
);
1150 IUnknown_SetSite(pCM
, NULL
);
1157 /**********************************************************
1158 * ShellView_DoContextMenu()
1160 LRESULT
CDefView::OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1166 CMINVOKECOMMANDINFO cmi
;
1169 // for some reason I haven't figured out, we sometimes recurse into this method
1176 TRACE("(%p)->(0x%08x 0x%08x) stub\n", this, x
, y
);
1178 hMenu
= CreatePopupMenu();
1182 cidl
= ListView_GetSelectedCount(hWndList
);
1184 hResult
= GetItemObject( cidl
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu2
, &pCM
));
1185 if (FAILED( hResult
))
1188 hResult
= IUnknown_SetSite(pCM
, (IShellView
*)this);
1189 //if (FAILED( hResult))
1192 hResult
= pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1193 if (FAILED( hResult
))
1196 if (FolderSettings
.fFlags
& FWF_DESKTOP
)
1197 SetMenuDefaultItem(hMenu
, FCIDM_SHVIEW_OPEN
, MF_BYCOMMAND
);
1199 uCommand
= TrackPopupMenu(hMenu
,
1200 TPM_LEFTALIGN
| TPM_RETURNCMD
| TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
,
1201 x
, y
, 0, m_hWnd
, NULL
);
1205 if (uCommand
== FCIDM_SHVIEW_OPEN
&& OnDefaultCommand() == S_OK
)
1208 ZeroMemory(&cmi
, sizeof(cmi
));
1209 cmi
.cbSize
= sizeof(cmi
);
1210 cmi
.lpVerb
= (LPCSTR
)MAKEINTRESOURCEA(uCommand
);
1212 pCM
->InvokeCommand(&cmi
);
1218 IUnknown_SetSite(pCM
, NULL
);
1228 LRESULT
CDefView::OnExplorerCommand(UINT uCommand
, BOOL bUseSelection
)
1231 CMINVOKECOMMANDINFO cmi
;
1234 hMenu
= CreatePopupMenu();
1238 hResult
= GetItemObject( bUseSelection
? SVGIO_SELECTION
: SVGIO_BACKGROUND
, IID_PPV_ARG(IContextMenu2
, &pCM
));
1239 if (FAILED( hResult
))
1242 hResult
= IUnknown_SetSite(pCM
, (IShellView
*)this);
1243 //if (FAILED( hResult))
1246 hResult
= pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, CMF_NORMAL
);
1247 if (FAILED( hResult
))
1250 ZeroMemory(&cmi
, sizeof(cmi
));
1251 cmi
.cbSize
= sizeof(cmi
);
1252 cmi
.lpVerb
= (LPCSTR
)MAKEINTRESOURCEA(uCommand
);
1254 pCM
->InvokeCommand(&cmi
);
1260 IUnknown_SetSite(pCM
, NULL
);
1270 /**********************************************************
1271 * ##### message handling #####
1274 /**********************************************************
1275 * ShellView_OnSize()
1277 LRESULT
CDefView::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1282 wWidth
= LOWORD(lParam
);
1283 wHeight
= HIWORD(lParam
);
1285 TRACE("%p width=%u height=%u\n", this, wWidth
, wHeight
);
1287 /*resize the ListView to fit our window*/
1290 ::MoveWindow(hWndList
, 0, 0, wWidth
, wHeight
, TRUE
);
1296 /**********************************************************
1297 * ShellView_OnDeactivate()
1302 void CDefView::OnDeactivate()
1304 TRACE("%p\n", this);
1306 if (uState
!= SVUIA_DEACTIVATE
)
1310 pShellBrowser
->SetMenuSB(0, 0, 0);
1311 pShellBrowser
->RemoveMenusSB(hMenu
);
1316 uState
= SVUIA_DEACTIVATE
;
1320 void CDefView::DoActivate(UINT uState
)
1322 OLEMENUGROUPWIDTHS omw
= { {0, 0, 0, 0, 0, 0} };
1324 CHAR szText
[MAX_PATH
];
1326 TRACE("%p uState=%x\n", this, uState
);
1328 /*don't do anything if the state isn't really changing */
1329 if (this->uState
== uState
)
1336 /*only do This if we are active */
1337 if(uState
!= SVUIA_DEACTIVATE
)
1339 /*merge the menus */
1340 hMenu
= CreateMenu();
1344 pShellBrowser
->InsertMenusSB(hMenu
, &omw
);
1345 TRACE("-- after fnInsertMenusSB\n");
1347 /*build the top level menu get the menu item's text*/
1348 strcpy(szText
, "dummy 31");
1350 ZeroMemory(&mii
, sizeof(mii
));
1351 mii
.cbSize
= sizeof(mii
);
1352 mii
.fMask
= MIIM_SUBMENU
| MIIM_TYPE
| MIIM_STATE
;
1353 mii
.fType
= MFT_STRING
;
1354 mii
.fState
= MFS_ENABLED
;
1355 mii
.dwTypeData
= szText
;
1356 mii
.hSubMenu
= BuildFileMenu();
1358 /*insert our menu into the menu bar*/
1361 InsertMenuItemA(hMenu
, FCIDM_MENU_HELP
, FALSE
, &mii
);
1364 /*get the view menu so we can merge with it*/
1365 ZeroMemory(&mii
, sizeof(mii
));
1366 mii
.cbSize
= sizeof(mii
);
1367 mii
.fMask
= MIIM_SUBMENU
;
1369 if (GetMenuItemInfoA(hMenu
, FCIDM_MENU_VIEW
, FALSE
, &mii
))
1371 MergeViewMenu(mii
.hSubMenu
);
1374 /*add the items that should only be added if we have the focus*/
1375 if (SVUIA_ACTIVATE_FOCUS
== uState
)
1377 /*get the file menu so we can merge with it */
1378 ZeroMemory(&mii
, sizeof(mii
));
1379 mii
.cbSize
= sizeof(mii
);
1380 mii
.fMask
= MIIM_SUBMENU
;
1382 if (GetMenuItemInfoA(hMenu
, FCIDM_MENU_FILE
, FALSE
, &mii
))
1384 MergeFileMenu(mii
.hSubMenu
);
1388 TRACE("-- before fnSetMenuSB\n");
1389 pShellBrowser
->SetMenuSB(hMenu
, 0, m_hWnd
);
1392 this->uState
= uState
;
1396 /**********************************************************
1397 * ShellView_OnActivate()
1399 LRESULT
CDefView::OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1401 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1405 /**********************************************************
1406 * ShellView_OnSetFocus()
1409 LRESULT
CDefView::OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1411 TRACE("%p\n", this);
1413 /* Tell the browser one of our windows has received the focus. This
1414 should always be done before merging menus (OnActivate merges the
1415 menus) if one of our windows has the focus.*/
1417 pShellBrowser
->OnViewWindowActive((IShellView
*)this);
1418 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1420 /* Set the focus to the listview */
1421 ::SetFocus(hWndList
);
1423 /* Notify the ICommDlgBrowser interface */
1424 OnStateChange(CDBOSC_SETFOCUS
);
1429 /**********************************************************
1430 * ShellView_OnKillFocus()
1432 LRESULT
CDefView::OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1434 TRACE("(%p) stub\n", this);
1436 DoActivate(SVUIA_ACTIVATE_NOFOCUS
);
1437 /* Notify the ICommDlgBrowser */
1438 OnStateChange(CDBOSC_KILLFOCUS
);
1443 /**********************************************************
1444 * ShellView_OnCommand()
1447 * the CmdID's are the ones from the context menu
1449 LRESULT
CDefView::OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1455 dwCmdID
= GET_WM_COMMAND_ID(wParam
, lParam
);
1456 dwCmd
= GET_WM_COMMAND_CMD(wParam
, lParam
);
1457 hwndCmd
= GET_WM_COMMAND_HWND(wParam
, lParam
);
1459 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n", this, dwCmdID
, dwCmd
, hwndCmd
);
1463 case FCIDM_SHVIEW_SMALLICON
:
1464 FolderSettings
.ViewMode
= FVM_SMALLICON
;
1465 SetStyle (LVS_SMALLICON
, LVS_TYPEMASK
);
1469 case FCIDM_SHVIEW_BIGICON
:
1470 FolderSettings
.ViewMode
= FVM_ICON
;
1471 SetStyle (LVS_ICON
, LVS_TYPEMASK
);
1475 case FCIDM_SHVIEW_LISTVIEW
:
1476 FolderSettings
.ViewMode
= FVM_LIST
;
1477 SetStyle (LVS_LIST
, LVS_TYPEMASK
);
1481 case FCIDM_SHVIEW_REPORTVIEW
:
1482 FolderSettings
.ViewMode
= FVM_DETAILS
;
1483 SetStyle (LVS_REPORT
, LVS_TYPEMASK
);
1487 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1492 ListViewSortInfo
.nHeaderID
= (LPARAM
) (dwCmdID
- 0x30);
1493 ListViewSortInfo
.bIsAscending
= TRUE
;
1494 ListViewSortInfo
.nLastHeaderID
= ListViewSortInfo
.nHeaderID
;
1495 SendMessageA(hWndList
, LVM_SORTITEMS
, (WPARAM
) &ListViewSortInfo
, (LPARAM
)ListViewCompareItems
);
1498 case FCIDM_SHVIEW_REFRESH
:
1502 case FCIDM_SHVIEW_DELETE
:
1503 case FCIDM_SHVIEW_CUT
:
1504 case FCIDM_SHVIEW_COPY
:
1505 case FCIDM_SHVIEW_RENAME
:
1506 return OnExplorerCommand(dwCmdID
, TRUE
);
1508 case FCIDM_SHVIEW_INSERT
:
1509 case FCIDM_SHVIEW_UNDO
:
1510 case FCIDM_SHVIEW_INSERTLINK
:
1511 case FCIDM_SHVIEW_NEWFOLDER
:
1512 return OnExplorerCommand(dwCmdID
, FALSE
);
1514 TRACE("-- COMMAND 0x%04x unhandled\n", dwCmdID
);
1520 /**********************************************************
1521 * ShellView_OnNotify()
1524 LRESULT
CDefView::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1528 LPNMLISTVIEW lpnmlv
;
1529 NMLVDISPINFOW
*lpdi
;
1534 lpnmh
= (LPNMHDR
)lParam
;
1535 lpnmlv
= (LPNMLISTVIEW
)lpnmh
;
1536 lpdi
= (NMLVDISPINFOW
*)lpnmh
;
1538 TRACE("%p CtlID=%u lpnmh->code=%x\n", this, CtlID
, lpnmh
->code
);
1540 switch (lpnmh
->code
)
1543 TRACE("-- NM_SETFOCUS %p\n", this);
1544 OnSetFocus(0, 0, 0, unused
);
1548 TRACE("-- NM_KILLFOCUS %p\n", this);
1550 /* Notify the ICommDlgBrowser interface */
1551 OnStateChange(CDBOSC_KILLFOCUS
);
1555 TRACE("-- NM_CUSTOMDRAW %p\n", this);
1556 return CDRF_DODEFAULT
;
1558 case NM_RELEASEDCAPTURE
:
1559 TRACE("-- NM_RELEASEDCAPTURE %p\n", this);
1563 TRACE("-- NM_CLICK %p\n", this);
1567 TRACE("-- NM_RCLICK %p\n", this);
1571 TRACE("-- NM_DBLCLK %p\n", this);
1572 OpenSelectedItems();
1576 TRACE("-- NM_RETURN %p\n", this);
1577 OpenSelectedItems();
1581 TRACE("-- HDN_ENDTRACKW %p\n", this);
1582 /*nColumn1 = ListView_GetColumnWidth(hWndList, 0);
1583 nColumn2 = ListView_GetColumnWidth(hWndList, 1);*/
1586 case LVN_DELETEITEM
:
1587 TRACE("-- LVN_DELETEITEM %p\n", this);
1588 SHFree((LPITEMIDLIST
)lpnmlv
->lParam
); /*delete the pidl because we made a copy of it*/
1591 case LVN_DELETEALLITEMS
:
1592 TRACE("-- LVN_DELETEALLITEMS %p\n", this);
1595 case LVN_INSERTITEM
:
1596 TRACE("-- LVN_INSERTITEM (STUB)%p\n", this);
1599 case LVN_ITEMACTIVATE
:
1600 TRACE("-- LVN_ITEMACTIVATE %p\n", this);
1601 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1604 case LVN_COLUMNCLICK
:
1605 ListViewSortInfo
.nHeaderID
= lpnmlv
->iSubItem
;
1606 if (ListViewSortInfo
.nLastHeaderID
== ListViewSortInfo
.nHeaderID
)
1608 ListViewSortInfo
.bIsAscending
= !ListViewSortInfo
.bIsAscending
;
1612 ListViewSortInfo
.bIsAscending
= TRUE
;
1614 ListViewSortInfo
.nLastHeaderID
= ListViewSortInfo
.nHeaderID
;
1616 SendMessageW(lpnmlv
->hdr
.hwndFrom
, LVM_SORTITEMS
, (WPARAM
) &ListViewSortInfo
, (LPARAM
)ListViewCompareItems
);
1619 case LVN_GETDISPINFOA
:
1620 case LVN_GETDISPINFOW
:
1621 TRACE("-- LVN_GETDISPINFO %p\n", this);
1622 pidl
= (LPITEMIDLIST
)lpdi
->item
.lParam
;
1624 if (lpdi
->item
.mask
& LVIF_TEXT
) /* text requested */
1629 if (FAILED(pSF2Parent
->GetDetailsOf(pidl
, lpdi
->item
.iSubItem
, &sd
)))
1631 FIXME("failed to get details\n");
1635 if (lpnmh
->code
== LVN_GETDISPINFOA
)
1637 /* shouldn't happen */
1638 NMLVDISPINFOA
*lpdiA
= (NMLVDISPINFOA
*)lpnmh
;
1639 StrRetToStrNA( lpdiA
->item
.pszText
, lpdiA
->item
.cchTextMax
, &sd
.str
, NULL
);
1640 TRACE("-- text=%s\n", lpdiA
->item
.pszText
);
1642 else /* LVN_GETDISPINFOW */
1644 StrRetToStrNW( lpdi
->item
.pszText
, lpdi
->item
.cchTextMax
, &sd
.str
, NULL
);
1645 TRACE("-- text=%s\n", debugstr_w(lpdi
->item
.pszText
));
1653 if(lpdi
->item
.mask
& LVIF_IMAGE
) /* image requested */
1655 lpdi
->item
.iImage
= SHMapPIDLToSystemImageListIndex(pSFParent
, pidl
, 0);
1657 lpdi
->item
.mask
|= LVIF_DI_SETITEM
;
1660 case LVN_ITEMCHANGED
:
1661 TRACE("-- LVN_ITEMCHANGED %p\n", this);
1662 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1666 case LVN_BEGINRDRAG
:
1667 TRACE("-- LVN_BEGINDRAG\n");
1669 if (GetSelections())
1672 DWORD dwAttributes
= SFGAO_CANLINK
;
1673 DWORD dwEffect
= DROPEFFECT_COPY
| DROPEFFECT_MOVE
;
1675 if (SUCCEEDED(pSFParent
->GetUIObjectOf(m_hWnd
, cidl
, (LPCITEMIDLIST
*)apidl
, IID_IDataObject
, 0, (LPVOID
*)&pda
)))
1677 IDropSource
* pds
= (IDropSource
*)this; /* own DropSource interface */
1679 if (SUCCEEDED(pSFParent
->GetAttributesOf(cidl
, (LPCITEMIDLIST
*)apidl
, &dwAttributes
)))
1681 if (dwAttributes
& SFGAO_CANLINK
)
1683 dwEffect
|= DROPEFFECT_LINK
;
1690 DoDragDrop(pda
, pds
, dwEffect
, &dwEffect2
);
1697 case LVN_BEGINLABELEDITW
:
1699 DWORD dwAttr
= SFGAO_CANRENAME
;
1700 pidl
= (LPITEMIDLIST
)lpdi
->item
.lParam
;
1702 TRACE("-- LVN_BEGINLABELEDITW %p\n", this);
1704 pSFParent
->GetAttributesOf(1, (LPCITEMIDLIST
*)&pidl
, &dwAttr
);
1705 if (SFGAO_CANRENAME
& dwAttr
)
1712 case LVN_ENDLABELEDITW
:
1714 TRACE("-- LVN_ENDLABELEDITW %p\n", this);
1715 if (lpdi
->item
.pszText
)
1720 lvItem
.iItem
= lpdi
->item
.iItem
;
1721 lvItem
.iSubItem
= 0;
1722 lvItem
.mask
= LVIF_PARAM
;
1723 SendMessageW(hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
1725 pidl
= (LPITEMIDLIST
)lpdi
->item
.lParam
;
1726 hr
= pSFParent
->SetNameOf(0, pidl
, lpdi
->item
.pszText
, SHGDN_INFOLDER
, &pidl
);
1728 if (SUCCEEDED(hr
) && pidl
)
1730 lvItem
.mask
= LVIF_PARAM
|LVIF_IMAGE
;
1731 lvItem
.lParam
= (LPARAM
)pidl
;
1732 lvItem
.iImage
= SHMapPIDLToSystemImageListIndex(pSFParent
, pidl
, 0);
1733 SendMessageW(hWndList
, LVM_SETITEMW
, 0, (LPARAM
) &lvItem
);
1734 SendMessageW(hWndList
, LVM_UPDATE
, lpdi
->item
.iItem
, 0);
1745 LPNMLVKEYDOWN plvKeyDown
= (LPNMLVKEYDOWN
) lpnmh
;
1747 /* initiate a rename of the selected file or directory */
1748 if (plvKeyDown
->wVKey
== VK_BACK
)
1750 LPSHELLBROWSER lpSb
;
1751 if ((lpSb
= (LPSHELLBROWSER
)SendMessageW(hWndParent
, CWM_GETISHELLBROWSER
, 0, 0)))
1753 lpSb
->BrowseObject(NULL
, SBSP_PARENT
);
1758 FIXME("LVN_KEYDOWN key=0x%08x\n", plvKeyDown
->wVKey
);
1763 TRACE("-- %p WM_COMMAND %x unhandled\n", this, lpnmh
->code
);
1770 /**********************************************************
1771 * ShellView_OnChange()
1773 LRESULT
CDefView::OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1775 LPITEMIDLIST
*Pidls
;
1777 Pidls
= (LPITEMIDLIST
*)wParam
;
1779 TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls
[0], Pidls
[1], lParam
);
1785 LV_AddItem(Pidls
[0]);
1790 LV_DeleteItem(Pidls
[0]);
1793 case SHCNE_RENAMEFOLDER
:
1794 case SHCNE_RENAMEITEM
:
1795 LV_RenameItem(Pidls
[0], Pidls
[1]);
1798 case SHCNE_UPDATEITEM
:
1805 /**********************************************************
1806 * CDefView::OnCustomItem
1808 LRESULT
CDefView::OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1813 ERR("no menu!!!\n");
1817 if (pCM
.p
->HandleMenuMsg(uMsg
, (WPARAM
)m_hWnd
, lParam
) == S_OK
)
1823 LRESULT
CDefView::OnSettingChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1825 /* Wallpaper setting affects drop shadows effect */
1826 if (wParam
== SPI_SETDESKWALLPAPER
|| wParam
== 0)
1832 /**********************************************************
1835 * The INTERFACE of the IShellView object
1838 **********************************************************
1841 /**********************************************************
1842 * ShellView_GetWindow
1844 HRESULT WINAPI
CDefView::GetWindow(HWND
*phWnd
)
1846 TRACE("(%p)\n", this);
1853 HRESULT WINAPI
CDefView::ContextSensitiveHelp(BOOL fEnterMode
)
1855 FIXME("(%p) stub\n", this);
1860 /**********************************************************
1861 * IShellView_TranslateAccelerator
1864 * use the accel functions
1866 HRESULT WINAPI
CDefView::TranslateAccelerator(LPMSG lpmsg
)
1868 if (lpmsg
->message
>= WM_KEYFIRST
&& lpmsg
->message
<= WM_KEYLAST
)
1870 if (::TranslateAcceleratorW(m_hWnd
, hAccel
, lpmsg
) != 0)
1873 /* FIXME: should call TranslateAcceleratorSB */
1875 TRACE("-- key=0x04%lx\n", lpmsg
->wParam
) ;
1878 return S_FALSE
; /* not handled */
1881 HRESULT WINAPI
CDefView::EnableModeless(BOOL fEnable
)
1883 FIXME("(%p) stub\n", this);
1888 HRESULT WINAPI
CDefView::UIActivate(UINT uState
)
1891 CHAR szName[MAX_PATH];
1894 int nPartArray
[1] = { -1};
1896 TRACE("(%p)->(state=%x) stub\n", this, uState
);
1898 /*don't do anything if the state isn't really changing*/
1899 if (this->uState
== uState
)
1904 /*OnActivate handles the menu merging and internal state*/
1907 /*only do This if we are active*/
1908 if (uState
!= SVUIA_DEACTIVATE
)
1912 GetFolderPath is not a method of IShellFolder
1913 IShellFolder_GetFolderPath( pSFParent, szName, sizeof(szName) );
1915 /* set the number of parts */
1916 pShellBrowser
->SendControlMsg(FCW_STATUS
, SB_SETPARTS
, 1, (LPARAM
)nPartArray
, &lResult
);
1918 /* set the text for the parts */
1920 pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXTA, 0, (LPARAM)szName, &lResult);
1927 HRESULT WINAPI
CDefView::Refresh()
1929 TRACE("(%p)\n", this);
1931 SendMessageW(hWndList
, LVM_DELETEALLITEMS
, 0, 0);
1937 HRESULT WINAPI
CDefView::CreateViewWindow(IShellView
*lpPrevView
, LPCFOLDERSETTINGS lpfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
)
1941 TRACE("(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n", this, lpPrevView
, lpfs
, psb
, prcView
, phWnd
);
1944 TRACE("-- vmode=%x flags=%x\n", lpfs
->ViewMode
, lpfs
->fFlags
);
1945 if (prcView
!= NULL
)
1946 TRACE("-- left=%i top=%i right=%i bottom=%i\n", prcView
->left
, prcView
->top
, prcView
->right
, prcView
->bottom
);
1948 /* Validate the Shell Browser */
1950 return E_UNEXPECTED
;
1952 /*set up the member variables*/
1953 pShellBrowser
= psb
;
1954 FolderSettings
= *lpfs
;
1956 /*get our parent window*/
1957 pShellBrowser
->GetWindow(&hWndParent
);
1959 /* try to get the ICommDlgBrowserInterface, adds a reference !!! */
1960 pCommDlgBrowser
= NULL
;
1961 if (SUCCEEDED(pShellBrowser
->QueryInterface(IID_PPV_ARG(ICommDlgBrowser
, &pCommDlgBrowser
))))
1963 TRACE("-- CommDlgBrowser\n");
1966 Create(hWndParent
, prcView
, NULL
, WS_CHILD
| WS_TABSTOP
, 0, 0U);
1977 SetWindowPos(HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_SHOWWINDOW
);
1983 HRESULT WINAPI
CDefView::DestroyViewWindow()
1985 TRACE("(%p)\n", this);
1987 /*Make absolutely sure all our UI is cleaned up.*/
1988 UIActivate(SVUIA_DEACTIVATE
);
1996 pShellBrowser
.Release();
1997 pCommDlgBrowser
.Release();
2002 HRESULT WINAPI
CDefView::GetCurrentInfo(LPFOLDERSETTINGS lpfs
)
2004 TRACE("(%p)->(%p) vmode=%x flags=%x\n", this, lpfs
,
2005 FolderSettings
.ViewMode
, FolderSettings
.fFlags
);
2008 return E_INVALIDARG
;
2010 *lpfs
= FolderSettings
;
2014 HRESULT WINAPI
CDefView::AddPropertySheetPages(DWORD dwReserved
, LPFNADDPROPSHEETPAGE lpfn
, LPARAM lparam
)
2016 FIXME("(%p) stub\n", this);
2021 HRESULT WINAPI
CDefView::SaveViewState()
2023 FIXME("(%p) stub\n", this);
2028 HRESULT WINAPI
CDefView::SelectItem(LPCITEMIDLIST pidl
, UINT uFlags
)
2032 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n", this, pidl
, uFlags
);
2034 i
= LV_FindItemByPidl(pidl
);
2040 if(uFlags
& SVSI_ENSUREVISIBLE
)
2041 SendMessageW(hWndList
, LVM_ENSUREVISIBLE
, i
, 0);
2043 lvItem
.mask
= LVIF_STATE
;
2044 lvItem
.stateMask
= LVIS_SELECTED
| LVIS_FOCUSED
;
2046 lvItem
.iSubItem
= 0;
2048 while (SendMessageW(hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
))
2050 if (lvItem
.iItem
== i
)
2052 if (uFlags
& SVSI_SELECT
)
2053 lvItem
.state
|= LVIS_SELECTED
;
2055 lvItem
.state
&= ~LVIS_SELECTED
;
2057 if (uFlags
& SVSI_FOCUSED
)
2058 lvItem
.state
&= ~LVIS_FOCUSED
;
2062 if (uFlags
& SVSI_DESELECTOTHERS
)
2063 lvItem
.state
&= ~LVIS_SELECTED
;
2066 SendMessageW(hWndList
, LVM_SETITEMW
, 0, (LPARAM
) &lvItem
);
2071 if(uFlags
& SVSI_EDIT
)
2072 SendMessageW(hWndList
, LVM_EDITLABELW
, i
, 0);
2078 HRESULT WINAPI
CDefView::GetItemObject(UINT uItem
, REFIID riid
, LPVOID
*ppvOut
)
2080 HRESULT hr
= E_NOINTERFACE
;
2082 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n", this, uItem
, debugstr_guid(&riid
), ppvOut
);
2088 case SVGIO_BACKGROUND
:
2089 if (IsEqualIID(riid
, IID_IContextMenu
))
2091 //*ppvOut = ISvBgCm_Constructor(pSFParent, FALSE);
2092 CDefFolderMenu_Create2(NULL
, NULL
, 0, NULL
, pSFParent
, NULL
, 0, NULL
, (IContextMenu
**)ppvOut
);
2100 case SVGIO_SELECTION
:
2102 hr
= pSFParent
->GetUIObjectOf(m_hWnd
, cidl
, (LPCITEMIDLIST
*)apidl
, riid
, 0, ppvOut
);
2106 TRACE("-- (%p)->(interface=%p)\n", this, *ppvOut
);
2111 HRESULT STDMETHODCALLTYPE
CDefView::GetCurrentViewMode(UINT
*pViewMode
)
2113 TRACE("(%p)->(%p), stub\n", this, pViewMode
);
2116 return E_INVALIDARG
;
2118 *pViewMode
= this->FolderSettings
.ViewMode
;
2122 HRESULT STDMETHODCALLTYPE
CDefView::SetCurrentViewMode(UINT ViewMode
)
2125 TRACE("(%p)->(%u), stub\n", this, ViewMode
);
2127 /* It's not redundant to check FVM_AUTO because it's a (UINT)-1 */
2128 if ((ViewMode
< FVM_FIRST
|| ViewMode
> FVM_LAST
) && (ViewMode
!= (UINT
)FVM_AUTO
))
2129 return E_INVALIDARG
;
2131 /* Windows before Vista uses LVM_SETVIEW and possibly
2132 LVM_SETEXTENDEDLISTVIEWSTYLE to set the style of the listview,
2133 while later versions seem to accomplish this through other
2141 dwStyle
= LVS_REPORT
;
2144 dwStyle
= LVS_SMALLICON
;
2151 FIXME("ViewMode %d not implemented\n", ViewMode
);
2157 SetStyle(dwStyle
, LVS_TYPEMASK
);
2159 /* This will not necessarily be the actual mode set above.
2160 This mimics the behavior of Windows XP. */
2161 this->FolderSettings
.ViewMode
= ViewMode
;
2166 HRESULT STDMETHODCALLTYPE
CDefView::GetFolder(REFIID riid
, void **ppv
)
2168 if (pSFParent
== NULL
)
2171 return pSFParent
->QueryInterface(riid
, ppv
);
2174 HRESULT STDMETHODCALLTYPE
CDefView::Item(int iItemIndex
, LPITEMIDLIST
*ppidl
)
2178 TRACE("(%p)->(%d %p)\n", this, iItemIndex
, ppidl
);
2180 item
.mask
= LVIF_PARAM
;
2181 item
.iItem
= iItemIndex
;
2183 if (SendMessageW(this->hWndList
, LVM_GETITEMW
, 0, (LPARAM
)&item
))
2185 *ppidl
= ILClone((PITEMID_CHILD
)item
.lParam
);
2191 return E_INVALIDARG
;
2194 HRESULT STDMETHODCALLTYPE
CDefView::ItemCount(UINT uFlags
, int *pcItems
)
2196 TRACE("(%p)->(%u %p)\n", this, uFlags
, pcItems
);
2198 if (uFlags
!= SVGIO_ALLVIEW
)
2199 FIXME("some flags unsupported, %x\n", uFlags
& ~SVGIO_ALLVIEW
);
2201 *pcItems
= SendMessageW(this->hWndList
, LVM_GETITEMCOUNT
, 0, 0);
2206 HRESULT STDMETHODCALLTYPE
CDefView::Items(UINT uFlags
, REFIID riid
, void **ppv
)
2211 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectionMarkedItem(int *piItem
)
2213 TRACE("(%p)->(%p)\n", this, piItem
);
2215 *piItem
= SendMessageW(this->hWndList
, LVM_GETSELECTIONMARK
, 0, 0);
2220 HRESULT STDMETHODCALLTYPE
CDefView::GetFocusedItem(int *piItem
)
2222 TRACE("(%p)->(%p)\n", this, piItem
);
2224 *piItem
= SendMessageW(this->hWndList
, LVM_GETNEXTITEM
, -1, LVNI_FOCUSED
);
2229 HRESULT STDMETHODCALLTYPE
CDefView::GetItemPosition(LPCITEMIDLIST pidl
, POINT
*ppt
)
2234 HRESULT STDMETHODCALLTYPE
CDefView::GetSpacing(POINT
*ppt
)
2236 TRACE("(%p)->(%p)\n", this, ppt
);
2238 if (NULL
== this->hWndList
) return S_FALSE
;
2242 const DWORD ret
= SendMessageW(this->hWndList
, LVM_GETITEMSPACING
, 0, 0);
2244 ppt
->x
= LOWORD(ret
);
2245 ppt
->y
= HIWORD(ret
);
2251 HRESULT STDMETHODCALLTYPE
CDefView::GetDefaultSpacing(POINT
*ppt
)
2256 HRESULT STDMETHODCALLTYPE
CDefView::GetAutoArrange()
2261 HRESULT STDMETHODCALLTYPE
CDefView::SelectItem(int iItem
, DWORD dwFlags
)
2265 TRACE("(%p)->(%d, %x)\n", this, iItem
, dwFlags
);
2268 lvItem
.stateMask
= LVIS_SELECTED
;
2270 if (dwFlags
& SVSI_ENSUREVISIBLE
)
2271 SendMessageW(this->hWndList
, LVM_ENSUREVISIBLE
, iItem
, 0);
2274 if (dwFlags
& SVSI_DESELECTOTHERS
)
2275 SendMessageW(this->hWndList
, LVM_SETITEMSTATE
, -1, (LPARAM
)&lvItem
);
2278 if (dwFlags
& SVSI_SELECT
)
2279 lvItem
.state
|= LVIS_SELECTED
;
2281 if (dwFlags
& SVSI_FOCUSED
)
2282 lvItem
.stateMask
|= LVIS_FOCUSED
;
2284 SendMessageW(this->hWndList
, LVM_SETITEMSTATE
, iItem
, (LPARAM
)&lvItem
);
2286 if (dwFlags
& SVSI_EDIT
)
2287 SendMessageW(this->hWndList
, LVM_EDITLABELW
, iItem
, 0);
2292 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItems(UINT cidl
, LPCITEMIDLIST
*apidl
, POINT
*apt
, DWORD dwFlags
)
2297 /**********************************************************
2298 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2300 HRESULT WINAPI
CDefView::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD
*prgCmds
, OLECMDTEXT
*pCmdText
)
2302 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
2303 this, pguidCmdGroup
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
2306 return E_INVALIDARG
;
2308 for (UINT i
= 0; i
< cCmds
; i
++)
2310 FIXME("\tprgCmds[%d].cmdID = %d\n", i
, prgCmds
[i
].cmdID
);
2311 prgCmds
[i
].cmdf
= 0;
2314 return OLECMDERR_E_UNKNOWNGROUP
;
2317 /**********************************************************
2318 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2320 * nCmdID is the OLECMDID_* enumeration
2322 HRESULT WINAPI
CDefView::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
2324 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2325 this, debugstr_guid(pguidCmdGroup
), nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2328 return OLECMDERR_E_UNKNOWNGROUP
;
2330 if (IsEqualIID(*pguidCmdGroup
, CGID_Explorer
) &&
2332 (nCmdexecopt
== 4) && pvaOut
)
2335 if (IsEqualIID(*pguidCmdGroup
, CGID_ShellDocView
) &&
2340 return OLECMDERR_E_UNKNOWNGROUP
;
2343 /**********************************************************
2344 * ISVDropTarget implementation
2347 /******************************************************************************
2348 * drag_notify_subitem [Internal]
2350 * Figure out the shellfolder object, which is currently under the mouse cursor
2351 * and notify it via the IDropTarget interface.
2354 #define SCROLLAREAWIDTH 20
2356 HRESULT
CDefView::drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2358 LVHITTESTINFO htinfo
;
2364 /* Map from global to client coordinates and query the index of the listview-item, which is
2365 * currently under the mouse cursor. */
2368 htinfo
.flags
= LVHT_ONITEM
;
2369 ::ScreenToClient(hWndList
, &htinfo
.pt
);
2370 lResult
= SendMessageW(hWndList
, LVM_HITTEST
, 0, (LPARAM
)&htinfo
);
2372 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2373 ::GetClientRect(hWndList
, &clientRect
);
2374 if (htinfo
.pt
.x
== ptLastMousePos
.x
&& htinfo
.pt
.y
== ptLastMousePos
.y
&&
2375 (htinfo
.pt
.x
< SCROLLAREAWIDTH
|| htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
||
2376 htinfo
.pt
.y
< SCROLLAREAWIDTH
|| htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
))
2378 cScrollDelay
= (cScrollDelay
+ 1) % 5; /* DragOver is called every 50 ms */
2379 if (cScrollDelay
== 0)
2381 /* Mouse did hover another 250 ms over the scroll-area */
2382 if (htinfo
.pt
.x
< SCROLLAREAWIDTH
)
2383 SendMessageW(hWndList
, WM_HSCROLL
, SB_LINEUP
, 0);
2385 if (htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
)
2386 SendMessageW(hWndList
, WM_HSCROLL
, SB_LINEDOWN
, 0);
2388 if (htinfo
.pt
.y
< SCROLLAREAWIDTH
)
2389 SendMessageW(hWndList
, WM_VSCROLL
, SB_LINEUP
, 0);
2391 if (htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
)
2392 SendMessageW(hWndList
, WM_VSCROLL
, SB_LINEDOWN
, 0);
2397 cScrollDelay
= 0; /* Reset, if the cursor is not over the listview's scroll-area */
2400 ptLastMousePos
= htinfo
.pt
;
2402 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2403 if (pCurDropTarget
&& lResult
== iDragOverItem
)
2404 return pCurDropTarget
->DragOver(grfKeyState
, pt
, pdwEffect
);
2406 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2409 pCurDropTarget
->DragLeave();
2410 pCurDropTarget
.Release();
2413 iDragOverItem
= lResult
;
2416 /* We are not above one of the listview's subitems. Bind to the parent folder's
2417 * DropTarget interface. */
2418 hr
= pSFParent
->QueryInterface(IID_PPV_ARG(IDropTarget
,&pCurDropTarget
));
2422 /* Query the relative PIDL of the shellfolder object represented by the currently
2423 * dragged over listview-item ... */
2424 lvItem
.mask
= LVIF_PARAM
;
2425 lvItem
.iItem
= lResult
;
2426 lvItem
.iSubItem
= 0;
2427 SendMessageW(hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
2429 /* ... and bind pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2430 hr
= pSFParent
->GetUIObjectOf(hWndList
, 1,
2431 (LPCITEMIDLIST
*)&lvItem
.lParam
, IID_IDropTarget
, NULL
, (LPVOID
*)&pCurDropTarget
);
2434 /* If anything failed, pCurDropTarget should be NULL now, which ought to be a save state. */
2438 /* Notify the item just entered via DragEnter. */
2439 return pCurDropTarget
->DragEnter(pCurDataObject
, grfKeyState
, pt
, pdwEffect
);
2442 HRESULT WINAPI
CDefView::DragEnter(IDataObject
*pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2444 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2445 pCurDataObject
= pDataObject
;
2446 pDataObject
->AddRef();
2448 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2451 HRESULT WINAPI
CDefView::DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2453 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2456 HRESULT WINAPI
CDefView::DragLeave()
2460 pCurDropTarget
->DragLeave();
2461 pCurDropTarget
.Release();
2464 if (pCurDataObject
!= NULL
)
2466 pCurDataObject
.Release();
2474 HRESULT WINAPI
CDefView::Drop(IDataObject
* pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2478 pCurDropTarget
->Drop(pDataObject
, grfKeyState
, pt
, pdwEffect
);
2479 pCurDropTarget
.Release();
2482 pCurDataObject
.Release();
2488 /**********************************************************
2489 * ISVDropSource implementation
2492 HRESULT WINAPI
CDefView::QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
)
2494 TRACE("(%p)\n", this);
2497 return DRAGDROP_S_CANCEL
;
2498 else if (!(grfKeyState
& MK_LBUTTON
) && !(grfKeyState
& MK_RBUTTON
))
2499 return DRAGDROP_S_DROP
;
2504 HRESULT WINAPI
CDefView::GiveFeedback(DWORD dwEffect
)
2506 TRACE("(%p)\n", this);
2508 return DRAGDROP_S_USEDEFAULTCURSORS
;
2511 /**********************************************************
2512 * ISVViewObject implementation
2515 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
)
2517 FIXME("Stub: this=%p\n", this);
2522 HRESULT WINAPI
CDefView::GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
, HDC hicTargetDevice
, LOGPALETTE
**ppColorSet
)
2524 FIXME("Stub: this=%p\n", this);
2529 HRESULT WINAPI
CDefView::Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
)
2531 FIXME("Stub: this=%p\n", this);
2536 HRESULT WINAPI
CDefView::Unfreeze(DWORD dwFreeze
)
2538 FIXME("Stub: this=%p\n", this);
2543 HRESULT WINAPI
CDefView::SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
)
2545 FIXME("partial stub: %p %08x %08x %p\n", this, aspects
, advf
, pAdvSink
);
2547 /* FIXME: we set the AdviseSink, but never use it to send any advice */
2548 this->pAdvSink
= pAdvSink
;
2549 dwAspects
= aspects
;
2555 HRESULT WINAPI
CDefView::GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
)
2557 TRACE("this=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n", this, pAspects
, pAdvf
, ppAdvSink
);
2561 *ppAdvSink
= pAdvSink
;
2562 pAdvSink
.p
->AddRef();
2566 *pAspects
= dwAspects
;
2574 HRESULT STDMETHODCALLTYPE
CDefView::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
2576 if (IsEqualIID(guidService
, SID_IShellBrowser
))
2577 return pShellBrowser
->QueryInterface(riid
, ppvObject
);
2578 else if(IsEqualIID(guidService
, SID_IFolderView
))
2579 return QueryInterface(riid
, ppvObject
);
2581 return E_NOINTERFACE
;
2584 /**********************************************************
2585 * IShellView_Constructor
2587 HRESULT WINAPI
IShellView_Constructor(IShellFolder
*pFolder
, IShellView
**newView
)
2589 CComObject
<CDefView
> *theView
;
2590 CComPtr
<IShellView
> result
;
2593 if (newView
== NULL
)
2597 ATLTRY (theView
= new CComObject
<CDefView
>);
2599 if (theView
== NULL
)
2600 return E_OUTOFMEMORY
;
2602 hResult
= theView
->QueryInterface(IID_PPV_ARG(IShellView
, &result
));
2603 if (FAILED (hResult
))
2609 hResult
= theView
->Initialize (pFolder
);
2610 if (FAILED (hResult
))
2612 *newView
= result
.Detach ();