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
);
115 static INT CALLBACK
CompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
);
116 static INT CALLBACK
ListViewCompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
);
117 int LV_FindItemByPidl(LPCITEMIDLIST pidl
);
118 BOOLEAN
LV_AddItem(LPCITEMIDLIST pidl
);
119 BOOLEAN
LV_DeleteItem(LPCITEMIDLIST pidl
);
120 BOOLEAN
LV_RenameItem(LPCITEMIDLIST pidlOld
, LPCITEMIDLIST pidlNew
);
121 static INT CALLBACK
fill_list(LPVOID ptr
, LPVOID arg
);
123 HMENU
BuildFileMenu();
124 void MergeFileMenu(HMENU hSubMenu
);
125 void MergeViewMenu(HMENU hSubMenu
);
126 UINT
GetSelections();
127 HRESULT
OpenSelectedItems();
129 void DoActivate(UINT uState
);
130 HRESULT
drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
132 // *** IOleWindow methods ***
133 virtual HRESULT STDMETHODCALLTYPE
GetWindow(HWND
*lphwnd
);
134 virtual HRESULT STDMETHODCALLTYPE
ContextSensitiveHelp(BOOL fEnterMode
);
136 // *** IShellView methods ***
137 virtual HRESULT STDMETHODCALLTYPE
TranslateAccelerator(MSG
*pmsg
);
138 virtual HRESULT STDMETHODCALLTYPE
EnableModeless(BOOL fEnable
);
139 virtual HRESULT STDMETHODCALLTYPE
UIActivate(UINT uState
);
140 virtual HRESULT STDMETHODCALLTYPE
Refresh();
141 virtual HRESULT STDMETHODCALLTYPE
CreateViewWindow(IShellView
*psvPrevious
, LPCFOLDERSETTINGS pfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
);
142 virtual HRESULT STDMETHODCALLTYPE
DestroyViewWindow();
143 virtual HRESULT STDMETHODCALLTYPE
GetCurrentInfo(LPFOLDERSETTINGS pfs
);
144 virtual HRESULT STDMETHODCALLTYPE
AddPropertySheetPages(DWORD dwReserved
, LPFNSVADDPROPSHEETPAGE pfn
, LPARAM lparam
);
145 virtual HRESULT STDMETHODCALLTYPE
SaveViewState();
146 virtual HRESULT STDMETHODCALLTYPE
SelectItem(LPCITEMIDLIST pidlItem
, SVSIF uFlags
);
147 virtual HRESULT STDMETHODCALLTYPE
GetItemObject(UINT uItem
, REFIID riid
, void **ppv
);
149 // *** IFolderView methods ***
150 virtual HRESULT STDMETHODCALLTYPE
GetCurrentViewMode(UINT
*pViewMode
);
151 virtual HRESULT STDMETHODCALLTYPE
SetCurrentViewMode(UINT ViewMode
);
152 virtual HRESULT STDMETHODCALLTYPE
GetFolder(REFIID riid
, void **ppv
);
153 virtual HRESULT STDMETHODCALLTYPE
Item(int iItemIndex
, LPITEMIDLIST
*ppidl
);
154 virtual HRESULT STDMETHODCALLTYPE
ItemCount(UINT uFlags
, int *pcItems
);
155 virtual HRESULT STDMETHODCALLTYPE
Items(UINT uFlags
, REFIID riid
, void **ppv
);
156 virtual HRESULT STDMETHODCALLTYPE
GetSelectionMarkedItem(int *piItem
);
157 virtual HRESULT STDMETHODCALLTYPE
GetFocusedItem(int *piItem
);
158 virtual HRESULT STDMETHODCALLTYPE
GetItemPosition(LPCITEMIDLIST pidl
, POINT
*ppt
);
159 virtual HRESULT STDMETHODCALLTYPE
GetSpacing(POINT
*ppt
);
160 virtual HRESULT STDMETHODCALLTYPE
GetDefaultSpacing(POINT
*ppt
);
161 virtual HRESULT STDMETHODCALLTYPE
GetAutoArrange();
162 virtual HRESULT STDMETHODCALLTYPE
SelectItem(int iItem
, DWORD dwFlags
);
163 virtual HRESULT STDMETHODCALLTYPE
SelectAndPositionItems(UINT cidl
, LPCITEMIDLIST
*apidl
, POINT
*apt
, DWORD dwFlags
);
165 // *** IOleCommandTarget methods ***
166 virtual HRESULT STDMETHODCALLTYPE
QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
);
167 virtual HRESULT STDMETHODCALLTYPE
Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
);
169 // *** IDropTarget methods ***
170 virtual HRESULT STDMETHODCALLTYPE
DragEnter(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
171 virtual HRESULT STDMETHODCALLTYPE
DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
172 virtual HRESULT STDMETHODCALLTYPE
DragLeave();
173 virtual HRESULT STDMETHODCALLTYPE
Drop(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
175 // *** IDropSource methods ***
176 virtual HRESULT STDMETHODCALLTYPE
QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
);
177 virtual HRESULT STDMETHODCALLTYPE
GiveFeedback(DWORD dwEffect
);
179 // *** IViewObject methods ***
180 virtual HRESULT STDMETHODCALLTYPE
Draw(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
,
181 HDC hdcTargetDev
, HDC hdcDraw
, LPCRECTL lprcBounds
, LPCRECTL lprcWBounds
,
182 BOOL ( STDMETHODCALLTYPE
*pfnContinue
)(ULONG_PTR dwContinue
), ULONG_PTR dwContinue
);
183 virtual HRESULT STDMETHODCALLTYPE
GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
,
184 DVTARGETDEVICE
*ptd
, HDC hicTargetDev
, LOGPALETTE
**ppColorSet
);
185 virtual HRESULT STDMETHODCALLTYPE
Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
);
186 virtual HRESULT STDMETHODCALLTYPE
Unfreeze(DWORD dwFreeze
);
187 virtual HRESULT STDMETHODCALLTYPE
SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
);
188 virtual HRESULT STDMETHODCALLTYPE
GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
);
190 // *** IServiceProvider methods ***
191 virtual HRESULT STDMETHODCALLTYPE
QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
);
194 LRESULT
OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
195 LRESULT
OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
196 LRESULT
OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
197 LRESULT
OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
198 LRESULT
OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
199 LRESULT
OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
200 LRESULT
OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
201 LRESULT
OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
202 LRESULT
OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
203 LRESULT
OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
204 LRESULT
OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
205 LRESULT
OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
206 LRESULT
OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
207 LRESULT
OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
208 LRESULT
OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
209 LRESULT
OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
211 static ATL::CWndClassInfo
& GetWndClassInfo()
213 static ATL::CWndClassInfo wc
=
215 { sizeof(WNDCLASSEX
), CS_HREDRAW
| CS_VREDRAW
, StartWindowProc
,
217 LoadCursor(NULL
, IDC_ARROW
), (HBRUSH
)(COLOR_BACKGROUND
+ 1), NULL
, SV_CLASS_NAME
, NULL
},
218 NULL
, NULL
, IDC_ARROW
, TRUE
, 0, _T("")
223 virtual WNDPROC
GetWindowProc()
228 static LRESULT CALLBACK
WindowProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
233 // must hold a reference during message handling
234 pThis
= reinterpret_cast<CDefView
*>(hWnd
);
236 result
= CWindowImpl
<CDefView
, CWindow
, CControlWinTraits
>::WindowProc(hWnd
, uMsg
, wParam
, lParam
);
241 BEGIN_MSG_MAP(CDefView
)
242 MESSAGE_HANDLER(WM_SIZE
, OnSize
)
243 MESSAGE_HANDLER(WM_SETFOCUS
, OnSetFocus
)
244 MESSAGE_HANDLER(WM_KILLFOCUS
, OnKillFocus
)
245 MESSAGE_HANDLER(WM_CREATE
, OnCreate
)
246 MESSAGE_HANDLER(WM_ACTIVATE
, OnActivate
)
247 MESSAGE_HANDLER(WM_NOTIFY
, OnNotify
)
248 MESSAGE_HANDLER(WM_COMMAND
, OnCommand
)
249 MESSAGE_HANDLER(SHV_CHANGE_NOTIFY
, OnChangeNotify
)
250 MESSAGE_HANDLER(WM_CONTEXTMENU
, OnContextMenu
)
251 MESSAGE_HANDLER(WM_DRAWITEM
, OnCustomItem
)
252 MESSAGE_HANDLER(WM_MEASUREITEM
, OnCustomItem
)
253 MESSAGE_HANDLER(WM_SHOWWINDOW
, OnShowWindow
)
254 MESSAGE_HANDLER(WM_GETDLGCODE
, OnGetDlgCode
)
255 MESSAGE_HANDLER(WM_DESTROY
, OnDestroy
)
256 MESSAGE_HANDLER(WM_ERASEBKGND
, OnEraseBackground
)
257 MESSAGE_HANDLER(WM_SYSCOLORCHANGE
, OnSysColorChange
)
258 MESSAGE_HANDLER(CWM_GETISHELLBROWSER
, OnGetShellBrowser
)
261 BEGIN_COM_MAP(CDefView
)
262 COM_INTERFACE_ENTRY_IID(IID_IOleWindow
, IOleWindow
)
263 COM_INTERFACE_ENTRY_IID(IID_IShellView
, IShellView
)
264 COM_INTERFACE_ENTRY_IID(IID_IFolderView
, IFolderView
)
265 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget
, IOleCommandTarget
)
266 COM_INTERFACE_ENTRY_IID(IID_IDropTarget
, IDropTarget
)
267 COM_INTERFACE_ENTRY_IID(IID_IDropSource
, IDropSource
)
268 COM_INTERFACE_ENTRY_IID(IID_IViewObject
, IViewObject
)
269 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider
, IServiceProvider
)
273 /* ListView Header ID's */
274 #define LISTVIEW_COLUMN_NAME 0
275 #define LISTVIEW_COLUMN_SIZE 1
276 #define LISTVIEW_COLUMN_TYPE 2
277 #define LISTVIEW_COLUMN_TIME 3
278 #define LISTVIEW_COLUMN_ATTRIB 4
281 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
282 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
283 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
285 #define ID_LISTVIEW 1
288 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
289 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
290 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
293 Items merged into the toolbar and the filemenu
302 } MYTOOLINFO
, *LPMYTOOLINFO
;
304 static const MYTOOLINFO Tools
[] =
306 { FCIDM_SHVIEW_BIGICON
, 0, 0, IDS_VIEW_LARGE
, TBSTATE_ENABLED
, BTNS_BUTTON
},
307 { FCIDM_SHVIEW_SMALLICON
, 0, 0, IDS_VIEW_SMALL
, TBSTATE_ENABLED
, BTNS_BUTTON
},
308 { FCIDM_SHVIEW_LISTVIEW
, 0, 0, IDS_VIEW_LIST
, TBSTATE_ENABLED
, BTNS_BUTTON
},
309 { FCIDM_SHVIEW_REPORTVIEW
, 0, 0, IDS_VIEW_DETAILS
, TBSTATE_ENABLED
, BTNS_BUTTON
},
313 typedef void (CALLBACK
*PFNSHGETSETTINGSPROC
)(LPSHELLFLAGSTATE lpsfs
, DWORD dwMask
);
319 FolderSettings
.fFlags
= 0;
320 FolderSettings
.ViewMode
= 0;
325 ListViewSortInfo
.bIsAscending
= FALSE
;
326 ListViewSortInfo
.nHeaderID
= 0;
327 ListViewSortInfo
.nLastHeaderID
= 0;
334 ptLastMousePos
.x
= 0;
335 ptLastMousePos
.y
= 0;
338 CDefView::~CDefView()
340 TRACE(" destroying IShellView(%p)\n", this);
345 HRESULT WINAPI
CDefView::Initialize(IShellFolder
*shellFolder
)
347 pSFParent
= shellFolder
;
348 shellFolder
->QueryInterface(IID_IShellFolder2
, (LPVOID
*)&pSF2Parent
);
353 /**********************************************************
355 * ##### helperfunctions for communication with ICommDlgBrowser #####
357 HRESULT
CDefView::IncludeObject(LPCITEMIDLIST pidl
)
361 if (pCommDlgBrowser
.p
!= NULL
)
363 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl
);
364 ret
= pCommDlgBrowser
->IncludeObject((IShellView
*)this, pidl
);
365 TRACE("--0x%08x\n", ret
);
371 HRESULT
CDefView::OnDefaultCommand()
373 HRESULT ret
= S_FALSE
;
375 if (pCommDlgBrowser
.p
!= NULL
)
377 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
378 ret
= pCommDlgBrowser
->OnDefaultCommand((IShellView
*)this);
379 TRACE("-- returns %08x\n", ret
);
385 HRESULT
CDefView::OnStateChange(UINT uFlags
)
387 HRESULT ret
= S_FALSE
;
389 if (pCommDlgBrowser
.p
!= NULL
)
391 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags
);
392 ret
= pCommDlgBrowser
->OnStateChange((IShellView
*)this, uFlags
);
398 /**********************************************************
399 * set the toolbar of the filedialog buttons
401 * - activates the buttons from the shellbrowser according to
404 void CDefView::CheckToolbar()
410 if (pCommDlgBrowser
!= NULL
)
412 pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
413 FCIDM_TB_SMALLICON
, (FolderSettings
.ViewMode
==FVM_LIST
)? TRUE
: FALSE
, &result
);
414 pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
415 FCIDM_TB_REPORTVIEW
, (FolderSettings
.ViewMode
==FVM_DETAILS
)? TRUE
: FALSE
, &result
);
416 pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
417 FCIDM_TB_SMALLICON
, TRUE
, &result
);
418 pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
419 FCIDM_TB_REPORTVIEW
, TRUE
, &result
);
423 /**********************************************************
425 * ##### helperfunctions for initializing the view #####
427 /**********************************************************
428 * change the style of the listview control
430 void CDefView::SetStyle(DWORD dwAdd
, DWORD dwRemove
)
434 TRACE("(%p)\n", this);
436 tmpstyle
= ::GetWindowLongPtrW(hWndList
, GWL_STYLE
);
437 ::SetWindowLongPtrW(hWndList
, GWL_STYLE
, dwAdd
| (tmpstyle
& ~dwRemove
));
440 /**********************************************************
441 * ShellView_CreateList()
443 * - creates the list view window
445 BOOL
CDefView::CreateList()
446 { DWORD dwStyle
, dwExStyle
;
450 dwStyle
= WS_TABSTOP
| WS_VISIBLE
| WS_CHILDWINDOW
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
|
451 LVS_SHAREIMAGELISTS
| LVS_EDITLABELS
| LVS_AUTOARRANGE
;
452 dwExStyle
= WS_EX_CLIENTEDGE
;
454 if (FolderSettings
.fFlags
& FWF_DESKTOP
)
455 dwStyle
|= LVS_ALIGNLEFT
;
457 dwStyle
|= LVS_ALIGNTOP
;
459 switch (FolderSettings
.ViewMode
)
466 dwStyle
|= LVS_REPORT
;
470 dwStyle
|= LVS_SMALLICON
;
482 if (FolderSettings
.fFlags
& FWF_AUTOARRANGE
)
483 dwStyle
|= LVS_AUTOARRANGE
;
485 if (FolderSettings
.fFlags
& FWF_DESKTOP
)
486 FolderSettings
.fFlags
|= FWF_NOCLIENTEDGE
| FWF_NOSCROLL
;
488 if (FolderSettings
.fFlags
& FWF_SINGLESEL
)
489 dwStyle
|= LVS_SINGLESEL
;
491 if (FolderSettings
.fFlags
& FWF_NOCLIENTEDGE
)
492 dwExStyle
&= ~WS_EX_CLIENTEDGE
;
494 hWndList
=CreateWindowExW( dwExStyle
,
507 ListViewSortInfo
.bIsAscending
= TRUE
;
508 ListViewSortInfo
.nHeaderID
= -1;
509 ListViewSortInfo
.nLastHeaderID
= -1;
511 if (FolderSettings
.fFlags
& FWF_DESKTOP
)
514 * FIXME: look at the registry value
515 * HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ListviewShadow
516 * and activate drop shadows if necessary
520 SendMessageW(hWndList
, LVM_SETTEXTBKCOLOR
, 0, CLR_NONE
);
521 SendMessageW(hWndList
, LVM_SETBKCOLOR
, 0, CLR_NONE
);
525 SendMessageW(hWndList
, LVM_SETTEXTBKCOLOR
, 0, GetSysColor(COLOR_DESKTOP
));
526 SendMessageW(hWndList
, LVM_SETBKCOLOR
, 0, GetSysColor(COLOR_DESKTOP
));
529 SendMessageW(hWndList
, LVM_SETTEXTCOLOR
, 0, RGB(255,255,255));
532 /* UpdateShellSettings(); */
536 /**********************************************************
537 * ShellView_InitList()
539 * - adds all needed columns to the shellview
541 BOOL
CDefView::InitList()
549 SendMessageW(hWndList
, LVM_DELETEALLITEMS
, 0, 0);
551 lvColumn
.mask
= LVCF_FMT
| LVCF_WIDTH
| LVCF_TEXT
;
552 lvColumn
.pszText
= szTemp
;
556 for (int i
=0; 1; i
++)
558 if (FAILED(pSF2Parent
->GetDetailsOf(NULL
, i
, &sd
)))
561 lvColumn
.fmt
= sd
.fmt
;
562 lvColumn
.cx
= sd
.cxChar
*8; /* chars->pixel */
563 StrRetToStrNW( szTemp
, 50, &sd
.str
, NULL
);
564 SendMessageW(hWndList
, LVM_INSERTCOLUMNW
, i
, (LPARAM
) &lvColumn
);
572 SendMessageW(hWndList
, LVM_SETIMAGELIST
, LVSIL_SMALL
, (LPARAM
)ShellSmallIconList
);
573 SendMessageW(hWndList
, LVM_SETIMAGELIST
, LVSIL_NORMAL
, (LPARAM
)ShellBigIconList
);
578 /**********************************************************
579 * ShellView_CompareItems()
582 * internal, CALLBACK for DSA_Sort
584 INT CALLBACK
CDefView::CompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
)
587 TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1
, lParam2
, (LPVOID
) lpData
);
592 ret
= (SHORT
)SCODE_CODE(((IShellFolder
*)lpData
)->CompareIDs(0, (LPITEMIDLIST
)lParam1
, (LPITEMIDLIST
)lParam2
));
593 TRACE("ret=%i\n",ret
);
598 /*************************************************************************
599 * ShellView_ListViewCompareItems
601 * Compare Function for the Listview (FileOpen Dialog)
604 * lParam1 [I] the first ItemIdList to compare with
605 * lParam2 [I] the second ItemIdList to compare with
606 * lpData [I] The column ID for the header Ctrl to process
609 * A negative value if the first item should precede the second,
610 * a positive value if the first item should follow the second,
611 * or zero if the two items are equivalent
614 * FIXME: function does what ShellView_CompareItems is supposed to do.
615 * unify it and figure out how to use the undocumented first parameter
616 * of IShellFolder_CompareIDs to do the job this function does and
617 * move this code to IShellFolder.
618 * make LISTVIEW_SORT_INFO obsolete
619 * the way this function works is only usable if we had only
620 * filesystemfolders (25/10/99 jsch)
622 INT CALLBACK
CDefView::ListViewCompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
)
626 char strName1
[MAX_PATH
], strName2
[MAX_PATH
];
627 BOOL bIsFolder1
, bIsFolder2
,bIsBothFolder
;
628 LPITEMIDLIST pItemIdList1
= (LPITEMIDLIST
) lParam1
;
629 LPITEMIDLIST pItemIdList2
= (LPITEMIDLIST
) lParam2
;
630 LISTVIEW_SORT_INFO
*pSortInfo
= (LPLISTVIEW_SORT_INFO
) lpData
;
633 bIsFolder1
= _ILIsFolder(pItemIdList1
);
634 bIsFolder2
= _ILIsFolder(pItemIdList2
);
635 bIsBothFolder
= bIsFolder1
&& bIsFolder2
;
637 /* When sorting between a File and a Folder, the Folder gets sorted first */
638 if ( (bIsFolder1
|| bIsFolder2
) && !bIsBothFolder
)
640 nDiff
= bIsFolder1
? -1 : 1;
644 /* Sort by Time: Folders or Files can be sorted */
646 if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_TIME
)
648 _ILGetFileDateTime(pItemIdList1
, &fd1
);
649 _ILGetFileDateTime(pItemIdList2
, &fd2
);
650 nDiff
= CompareFileTime(&fd2
, &fd1
);
652 /* Sort by Attribute: Folder or Files can be sorted */
653 else if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_ATTRIB
)
655 _ILGetFileAttributes(pItemIdList1
, strName1
, MAX_PATH
);
656 _ILGetFileAttributes(pItemIdList2
, strName2
, MAX_PATH
);
657 nDiff
= lstrcmpiA(strName1
, strName2
);
659 /* Sort by FileName: Folder or Files can be sorted */
660 else if (pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_NAME
|| bIsBothFolder
)
663 _ILSimpleGetText(pItemIdList1
, strName1
, MAX_PATH
);
664 _ILSimpleGetText(pItemIdList2
, strName2
, MAX_PATH
);
665 nDiff
= lstrcmpiA(strName1
, strName2
);
667 /* Sort by File Size, Only valid for Files */
668 else if (pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_SIZE
)
670 nDiff
= (INT
)(_ILGetFileSize(pItemIdList1
, NULL
, 0) - _ILGetFileSize(pItemIdList2
, NULL
, 0));
672 /* Sort by File Type, Only valid for Files */
673 else if (pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_TYPE
)
676 _ILGetFileType(pItemIdList1
, strName1
, MAX_PATH
);
677 _ILGetFileType(pItemIdList2
, strName2
, MAX_PATH
);
678 nDiff
= lstrcmpiA(strName1
, strName2
);
681 /* If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
685 _ILSimpleGetText(pItemIdList1
, strName1
, MAX_PATH
);
686 _ILSimpleGetText(pItemIdList2
, strName2
, MAX_PATH
);
687 nDiff
= lstrcmpiA(strName1
, strName2
);
690 if (!pSortInfo
->bIsAscending
)
698 /**********************************************************
699 * LV_FindItemByPidl()
701 int CDefView::LV_FindItemByPidl(LPCITEMIDLIST pidl
)
705 lvItem
.mask
= LVIF_PARAM
;
707 for (lvItem
.iItem
= 0;
708 SendMessageW(hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
711 LPITEMIDLIST currentpidl
= (LPITEMIDLIST
) lvItem
.lParam
;
712 HRESULT hr
= pSFParent
->CompareIDs(0, pidl
, currentpidl
);
714 if (SUCCEEDED(hr
) && !HRESULT_CODE(hr
))
722 /**********************************************************
725 BOOLEAN
CDefView::LV_AddItem(LPCITEMIDLIST pidl
)
729 TRACE("(%p)(pidl=%p)\n", this, pidl
);
731 lvItem
.mask
= LVIF_TEXT
| LVIF_IMAGE
| LVIF_PARAM
; /*set the mask*/
732 lvItem
.iItem
= ListView_GetItemCount(hWndList
); /*add the item to the end of the list*/
734 lvItem
.lParam
= (LPARAM
) ILClone(ILFindLastID(pidl
)); /*set the item's data*/
735 lvItem
.pszText
= LPSTR_TEXTCALLBACKW
; /*get text on a callback basis*/
736 lvItem
.iImage
= I_IMAGECALLBACK
; /*get the image on a callback basis*/
738 if (SendMessageW(hWndList
, LVM_INSERTITEMW
, 0, (LPARAM
)&lvItem
) == -1)
744 /**********************************************************
747 BOOLEAN
CDefView::LV_DeleteItem(LPCITEMIDLIST pidl
)
751 TRACE("(%p)(pidl=%p)\n", this, pidl
);
753 nIndex
= LV_FindItemByPidl(ILFindLastID(pidl
));
755 return (-1 == ListView_DeleteItem(hWndList
, nIndex
)) ? FALSE
: TRUE
;
758 /**********************************************************
761 BOOLEAN
CDefView::LV_RenameItem(LPCITEMIDLIST pidlOld
, LPCITEMIDLIST pidlNew
)
766 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", this, pidlOld
, pidlNew
);
768 nItem
= LV_FindItemByPidl(ILFindLastID(pidlOld
));
772 lvItem
.mask
= LVIF_PARAM
; /* only the pidl */
773 lvItem
.iItem
= nItem
;
774 SendMessageW(hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
776 SHFree((LPITEMIDLIST
)lvItem
.lParam
);
777 lvItem
.mask
= LVIF_PARAM
;
778 lvItem
.iItem
= nItem
;
779 lvItem
.lParam
= (LPARAM
) ILClone(ILFindLastID(pidlNew
)); /* set the item's data */
780 SendMessageW(hWndList
, LVM_SETITEMW
, 0, (LPARAM
) &lvItem
);
781 SendMessageW(hWndList
, LVM_UPDATE
, nItem
, 0);
782 return TRUE
; /* FIXME: better handling */
788 /**********************************************************
789 * ShellView_FillList()
791 * - gets the objectlist from the shellfolder
793 * - fills the list into the view
795 INT CALLBACK
CDefView::fill_list( LPVOID ptr
, LPVOID arg
)
797 LPITEMIDLIST pidl
= (LPITEMIDLIST
)ptr
;
798 CDefView
*pThis
= (CDefView
*)arg
;
799 /* in a commdlg This works as a filemask*/
800 if (pThis
->IncludeObject(pidl
) == S_OK
)
801 pThis
->LV_AddItem(pidl
);
807 HRESULT
CDefView::FillList()
809 LPENUMIDLIST pEnumIDList
;
817 /* get the itemlist from the shfolder*/
818 hRes
= pSFParent
->EnumObjects(m_hWnd
, SHCONTF_NONFOLDERS
| SHCONTF_FOLDERS
, &pEnumIDList
);
826 /* create a pointer array */
827 hdpa
= DPA_Create(16);
830 return(E_OUTOFMEMORY
);
833 /* copy the items into the array*/
834 while((S_OK
== pEnumIDList
->Next(1, &pidl
, &dwFetched
)) && dwFetched
)
836 if (DPA_InsertPtr(hdpa
, 0x7fff, pidl
) == -1)
843 DPA_Sort(hdpa
, CompareItems
, (LPARAM
)pSFParent
.p
);
845 /*turn the listview's redrawing off*/
846 SendMessageA(hWndList
, WM_SETREDRAW
, FALSE
, 0);
848 DPA_DestroyCallback( hdpa
, fill_list
, (void *)this);
850 /*turn the listview's redrawing back on and force it to draw*/
851 SendMessageA(hWndList
, WM_SETREDRAW
, TRUE
, 0);
853 pEnumIDList
->Release(); /* destroy the list*/
858 LRESULT
CDefView::OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
860 ::UpdateWindow(hWndList
);
865 LRESULT
CDefView::OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
867 return SendMessageW(hWndList
, uMsg
, 0, 0);
870 LRESULT
CDefView::OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
872 RevokeDragDrop(m_hWnd
);
873 SHChangeNotifyDeregister(hNotify
);
878 LRESULT
CDefView::OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
880 if (FolderSettings
.fFlags
& (FWF_DESKTOP
| FWF_TRANSPARENT
))
881 return SendMessageW(GetParent(), WM_ERASEBKGND
, wParam
, lParam
); /* redirect to parent */
887 LRESULT
CDefView::OnSysColorChange(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
889 /* Forward WM_SYSCOLORCHANGE to common controls */
890 return SendMessageW(hWndList
, uMsg
, 0, 0);
893 LRESULT
CDefView::OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
895 return (LRESULT
)pShellBrowser
.p
;
898 /**********************************************************
899 * ShellView_OnCreate()
901 LRESULT
CDefView::OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
903 CComPtr
<IDropTarget
> pdt
;
904 SHChangeNotifyEntry ntreg
;
905 CComPtr
<IPersistFolder2
> ppf2
;
909 DbgPrint("[shell32, CDefView::OnCreate] Called\n");
919 if (SUCCEEDED(this->QueryInterface(IID_IDropTarget
, (LPVOID
*)&pdt
)))
920 RegisterDragDrop(m_hWnd
, pdt
);
922 /* register for receiving notifications */
923 pSFParent
->QueryInterface(IID_IPersistFolder2
, (LPVOID
*)&ppf2
);
926 ppf2
->GetCurFolder((LPITEMIDLIST
*)&ntreg
.pidl
);
927 ntreg
.fRecursive
= TRUE
;
928 hNotify
= SHChangeNotifyRegister(m_hWnd
, SHCNF_IDLIST
, SHCNE_ALLEVENTS
, SHV_CHANGE_NOTIFY
, 1, &ntreg
);
929 SHFree((LPITEMIDLIST
)ntreg
.pidl
);
932 hAccel
= LoadAcceleratorsA(shell32_hInstance
, "shv_accel");
937 /**********************************************************
938 * #### Handling of the menus ####
941 /**********************************************************
942 * ShellView_BuildFileMenu()
944 HMENU
CDefView::BuildFileMenu()
945 { WCHAR szText
[MAX_PATH
];
950 TRACE("(%p)\n",this);
952 hSubMenu
= CreatePopupMenu();
955 /*get the number of items in our global array*/
956 for(nTools
= 0; Tools
[nTools
].idCommand
!= -1; nTools
++){}
958 /*add the menu items*/
959 for(i
= 0; i
< nTools
; i
++)
961 LoadStringW(shell32_hInstance
, Tools
[i
].idMenuString
, szText
, MAX_PATH
);
963 ZeroMemory(&mii
, sizeof(mii
));
964 mii
.cbSize
= sizeof(mii
);
965 mii
.fMask
= MIIM_TYPE
| MIIM_ID
| MIIM_STATE
;
967 if(BTNS_SEP
!= Tools
[i
].bStyle
) /* no separator*/
969 mii
.fType
= MFT_STRING
;
970 mii
.fState
= MFS_ENABLED
;
971 mii
.dwTypeData
= szText
;
972 mii
.wID
= Tools
[i
].idCommand
;
976 mii
.fType
= MFT_SEPARATOR
;
978 /* tack This item onto the end of the menu */
979 InsertMenuItemW(hSubMenu
, (UINT
)-1, TRUE
, &mii
);
983 TRACE("-- return (menu=%p)\n",hSubMenu
);
987 /**********************************************************
988 * ShellView_MergeFileMenu()
990 void CDefView::MergeFileMenu(HMENU hSubMenu
)
992 TRACE("(%p)->(submenu=%p) stub\n",this,hSubMenu
);
995 { /*insert This item at the beginning of the menu */
996 _InsertMenuItemW(hSubMenu
, 0, TRUE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
997 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
, MFT_STRING
, L
"dummy45", MFS_ENABLED
);
1003 /**********************************************************
1004 * ShellView_MergeViewMenu()
1006 void CDefView::MergeViewMenu(HMENU hSubMenu
)
1008 TRACE("(%p)->(submenu=%p)\n",this,hSubMenu
);
1012 /*add a separator at the correct position in the menu*/
1014 static WCHAR view
[] = L
"View";
1016 _InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
1018 ZeroMemory(&mii
, sizeof(mii
));
1019 mii
.cbSize
= sizeof(mii
);
1020 mii
.fMask
= MIIM_SUBMENU
| MIIM_TYPE
| MIIM_DATA
;
1021 mii
.fType
= MFT_STRING
;
1022 mii
.dwTypeData
= view
;
1023 mii
.hSubMenu
= LoadMenuW(shell32_hInstance
, L
"MENU_001");
1024 InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, &mii
);
1028 /**********************************************************
1029 * ShellView_GetSelections()
1031 * - fills the this->apidl list with the selected objects
1034 * number of selected items
1036 UINT
CDefView::GetSelections()
1043 cidl
= ListView_GetSelectedCount(hWndList
);
1044 apidl
= (LPITEMIDLIST
*)SHAlloc(cidl
* sizeof(LPITEMIDLIST
));
1046 TRACE("selected=%i\n", cidl
);
1050 TRACE("-- Items selected =%u\n", cidl
);
1052 lvItem
.mask
= LVIF_STATE
| LVIF_PARAM
;
1053 lvItem
.stateMask
= LVIS_SELECTED
;
1055 lvItem
.iSubItem
= 0;
1058 while(SendMessageW(hWndList
, LVM_GETITEMW
, 0, (LPARAM
)&lvItem
) && (i
< cidl
))
1060 if(lvItem
.state
& LVIS_SELECTED
)
1062 apidl
[i
] = (LPITEMIDLIST
)lvItem
.lParam
;
1066 TRACE("-- selected Item found\n");
1075 /**********************************************************
1076 * ShellView_OpenSelectedItems()
1078 HRESULT
CDefView::OpenSelectedItems()
1080 static UINT CF_IDLIST
= 0;
1082 CComPtr
<IDataObject
> selection
;
1083 CComPtr
<IContextMenu
> cm
;
1088 LPCITEMIDLIST parent_pidl
;
1089 WCHAR parent_path
[MAX_PATH
];
1090 LPCWSTR parent_dir
= NULL
;
1093 CMINVOKECOMMANDINFOEX ici
;
1096 if (0 == GetSelections())
1101 hr
= pSFParent
->GetUIObjectOf(m_hWnd
, cidl
,
1102 (LPCITEMIDLIST
*)apidl
, IID_IContextMenu
,
1107 hmenu
= CreatePopupMenu();
1110 hr
= IUnknown_SetSite(cm
, (IShellView
*)this);
1111 if (SUCCEEDED(cm
->QueryContextMenu(hmenu
, 0, 0x20, 0x7fff, CMF_DEFAULTONLY
)))
1113 INT def
= -1, n
= GetMenuItemCount(hmenu
);
1115 for ( i
= 0; i
< n
; i
++ )
1117 memset( &info
, 0, sizeof info
);
1118 info
.cbSize
= sizeof info
;
1119 info
.fMask
= MIIM_FTYPE
| MIIM_STATE
| MIIM_ID
;
1120 if (GetMenuItemInfoW( hmenu
, i
, TRUE
, &info
))
1122 if (info
.fState
& MFS_DEFAULT
)
1131 memset( &ici
, 0, sizeof ici
);
1132 ici
.cbSize
= sizeof ici
;
1133 ici
.lpVerb
= MAKEINTRESOURCEA( def
);
1136 if (cm
->InvokeCommand((LPCMINVOKECOMMANDINFO
) &ici
) == S_OK
)
1138 DestroyMenu( hmenu
);
1139 hr
= IUnknown_SetSite(cm
, NULL
);
1145 DestroyMenu( hmenu
);
1146 hr
= IUnknown_SetSite(cm
, NULL
);
1153 hr
= pSFParent
->GetUIObjectOf(m_hWnd
, cidl
,
1154 (LPCITEMIDLIST
*)apidl
, IID_IDataObject
,
1155 0, (LPVOID
*)&selection
);
1164 CF_IDLIST
= RegisterClipboardFormatW(CFSTR_SHELLIDLIST
);
1167 fetc
.cfFormat
= CF_IDLIST
;
1169 fetc
.dwAspect
= DVASPECT_CONTENT
;
1171 fetc
.tymed
= TYMED_HGLOBAL
;
1173 hr
= selection
->QueryGetData(&fetc
);
1177 hr
= selection
->GetData(&fetc
, &stgm
);
1181 pIDList
= (LPIDA
)GlobalLock(stgm
.hGlobal
);
1183 parent_pidl
= (LPCITEMIDLIST
) ((LPBYTE
)pIDList
+pIDList
->aoffset
[0]);
1184 hr
= pSFParent
->GetAttributesOf(1, &parent_pidl
, &attribs
);
1185 if (SUCCEEDED(hr
) && (attribs
& SFGAO_FILESYSTEM
) &&
1186 SHGetPathFromIDListW(parent_pidl
, parent_path
))
1188 parent_dir
= parent_path
;
1191 for (i
= pIDList
->cidl
; i
> 0; --i
)
1195 pidl
= (LPCITEMIDLIST
)((LPBYTE
)pIDList
+pIDList
->aoffset
[i
]);
1197 attribs
= SFGAO_FOLDER
;
1198 hr
= pSFParent
->GetAttributesOf(1, &pidl
, &attribs
);
1200 if (SUCCEEDED(hr
) && ! (attribs
& SFGAO_FOLDER
))
1202 SHELLEXECUTEINFOW shexinfo
;
1204 shexinfo
.cbSize
= sizeof(SHELLEXECUTEINFOW
);
1205 shexinfo
.fMask
= SEE_MASK_INVOKEIDLIST
; /* SEE_MASK_IDLIST is also possible. */
1206 shexinfo
.hwnd
= NULL
;
1207 shexinfo
.lpVerb
= NULL
;
1208 shexinfo
.lpFile
= NULL
;
1209 shexinfo
.lpParameters
= NULL
;
1210 shexinfo
.lpDirectory
= parent_dir
;
1211 shexinfo
.nShow
= SW_NORMAL
;
1212 shexinfo
.lpIDList
= ILCombine(parent_pidl
, pidl
);
1214 ShellExecuteExW(&shexinfo
); /* Discard error/success info */
1216 ILFree((LPITEMIDLIST
)shexinfo
.lpIDList
);
1220 GlobalUnlock(stgm
.hGlobal
);
1221 ReleaseStgMedium(&stgm
);
1226 /**********************************************************
1227 * ShellView_DoContextMenu()
1229 LRESULT
CDefView::OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1239 CMINVOKECOMMANDINFO cmi
;
1242 // for some reason I haven't figured out, we sometimes recurse into this method
1250 TRACE("(%p)->(0x%08x 0x%08x 0x%08x) stub\n",this, x
, y
, bDefault
);
1255 /* look, what's selected and create a context menu object of it*/
1256 if (GetSelections())
1258 pSFParent
->GetUIObjectOf(hWndParent
, cidl
, (LPCITEMIDLIST
*)apidl
, IID_IContextMenu
, NULL
, (LPVOID
*)&pCM
);
1262 TRACE("-- pContextMenu\n");
1263 hMenu
= CreatePopupMenu();
1267 hResult
= IUnknown_SetSite(pCM
, (IShellView
*)this);
1269 /* See if we are in Explore or Open mode. If the browser's tree is present, we are in Explore mode.*/
1270 if (SUCCEEDED(pShellBrowser
->GetControlWindow(FCW_TREE
, &hwndTree
)) && hwndTree
)
1272 TRACE("-- explore mode\n");
1276 /* build the flags depending on what we can do with the selected item */
1277 wFlags
= CMF_NORMAL
| (cidl
!= 1 ? 0 : CMF_CANRENAME
) | (fExplore
? CMF_EXPLORE
: 0);
1279 /* let the ContextMenu merge its items in */
1280 if (SUCCEEDED(pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, wFlags
)))
1282 if (FolderSettings
.fFlags
& FWF_DESKTOP
)
1283 SetMenuDefaultItem(hMenu
, FCIDM_SHVIEW_OPEN
, MF_BYCOMMAND
);
1287 TRACE("-- get menu default command\n");
1288 uCommand
= GetMenuDefaultItem(hMenu
, FALSE
, GMDI_GOINTOPOPUPS
);
1292 TRACE("-- track popup\n");
1293 uCommand
= TrackPopupMenu( hMenu
,TPM_LEFTALIGN
| TPM_RETURNCMD
,x
,y
,0,m_hWnd
,NULL
);
1298 TRACE("-- uCommand=%u\n", uCommand
);
1300 if (uCommand
==FCIDM_SHVIEW_OPEN
&& pCommDlgBrowser
.p
!= NULL
)
1302 TRACE("-- dlg: OnDefaultCommand\n");
1303 if (OnDefaultCommand() != S_OK
)
1305 OpenSelectedItems();
1310 TRACE("-- explore -- invoke command\n");
1311 ZeroMemory(&cmi
, sizeof(cmi
));
1312 cmi
.cbSize
= sizeof(cmi
);
1313 cmi
.hwnd
= hWndParent
; /* this window has to answer CWM_GETISHELLBROWSER */
1314 cmi
.lpVerb
= (LPCSTR
)MAKEINTRESOURCEA(uCommand
);
1315 pCM
->InvokeCommand(&cmi
);
1319 hResult
= IUnknown_SetSite(pCM
, NULL
);
1326 else /* background context menu */
1328 hMenu
= CreatePopupMenu();
1330 CDefFolderMenu_Create2(NULL
, NULL
, cidl
, (LPCITEMIDLIST
*)apidl
, pSFParent
, NULL
, 0, NULL
, (IContextMenu
**)&pCM
);
1331 pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, 0);
1333 uCommand
= TrackPopupMenu( hMenu
, TPM_LEFTALIGN
| TPM_RETURNCMD
,x
,y
,0,m_hWnd
,NULL
);
1336 TRACE("-- (%p)->(uCommand=0x%08x )\n",this, uCommand
);
1338 ZeroMemory(&cmi
, sizeof(cmi
));
1339 cmi
.cbSize
= sizeof(cmi
);
1340 cmi
.lpVerb
= (LPCSTR
)MAKEINTRESOURCEA(uCommand
);
1341 cmi
.hwnd
= hWndParent
;
1342 pCM
->InvokeCommand(&cmi
);
1350 /**********************************************************
1351 * ##### message handling #####
1354 /**********************************************************
1355 * ShellView_OnSize()
1357 LRESULT
CDefView::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1362 wWidth
= LOWORD(lParam
);
1363 wHeight
= HIWORD(lParam
);
1365 TRACE("%p width=%u height=%u\n", this, wWidth
, wHeight
);
1367 /*resize the ListView to fit our window*/
1370 ::MoveWindow(hWndList
, 0, 0, wWidth
, wHeight
, TRUE
);
1376 /**********************************************************
1377 * ShellView_OnDeactivate()
1382 void CDefView::OnDeactivate()
1386 if (uState
!= SVUIA_DEACTIVATE
)
1390 pShellBrowser
->SetMenuSB(0, 0, 0);
1391 pShellBrowser
->RemoveMenusSB(hMenu
);
1396 uState
= SVUIA_DEACTIVATE
;
1400 void CDefView::DoActivate(UINT uState
)
1402 OLEMENUGROUPWIDTHS omw
= { {0, 0, 0, 0, 0, 0} };
1404 CHAR szText
[MAX_PATH
];
1406 TRACE("%p uState=%x\n", this, uState
);
1408 /*don't do anything if the state isn't really changing */
1409 if (uState
== uState
)
1416 /*only do This if we are active */
1417 if(uState
!= SVUIA_DEACTIVATE
)
1419 /*merge the menus */
1420 hMenu
= CreateMenu();
1424 pShellBrowser
->InsertMenusSB(hMenu
, &omw
);
1425 TRACE("-- after fnInsertMenusSB\n");
1427 /*build the top level menu get the menu item's text*/
1428 strcpy(szText
,"dummy 31");
1430 ZeroMemory(&mii
, sizeof(mii
));
1431 mii
.cbSize
= sizeof(mii
);
1432 mii
.fMask
= MIIM_SUBMENU
| MIIM_TYPE
| MIIM_STATE
;
1433 mii
.fType
= MFT_STRING
;
1434 mii
.fState
= MFS_ENABLED
;
1435 mii
.dwTypeData
= szText
;
1436 mii
.hSubMenu
= BuildFileMenu();
1438 /*insert our menu into the menu bar*/
1441 InsertMenuItemA(hMenu
, FCIDM_MENU_HELP
, FALSE
, &mii
);
1444 /*get the view menu so we can merge with it*/
1445 ZeroMemory(&mii
, sizeof(mii
));
1446 mii
.cbSize
= sizeof(mii
);
1447 mii
.fMask
= MIIM_SUBMENU
;
1449 if (GetMenuItemInfoA(hMenu
, FCIDM_MENU_VIEW
, FALSE
, &mii
))
1451 MergeViewMenu(mii
.hSubMenu
);
1454 /*add the items that should only be added if we have the focus*/
1455 if (SVUIA_ACTIVATE_FOCUS
== uState
)
1457 /*get the file menu so we can merge with it */
1458 ZeroMemory(&mii
, sizeof(mii
));
1459 mii
.cbSize
= sizeof(mii
);
1460 mii
.fMask
= MIIM_SUBMENU
;
1462 if (GetMenuItemInfoA(hMenu
, FCIDM_MENU_FILE
, FALSE
, &mii
))
1464 MergeFileMenu(mii
.hSubMenu
);
1468 TRACE("-- before fnSetMenuSB\n");
1469 pShellBrowser
->SetMenuSB(hMenu
, 0, m_hWnd
);
1476 /**********************************************************
1477 * ShellView_OnActivate()
1479 LRESULT
CDefView::OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1481 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1485 /**********************************************************
1486 * ShellView_OnSetFocus()
1489 LRESULT
CDefView::OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1491 TRACE("%p\n", this);
1493 /* Tell the browser one of our windows has received the focus. This
1494 should always be done before merging menus (OnActivate merges the
1495 menus) if one of our windows has the focus.*/
1497 pShellBrowser
->OnViewWindowActive((IShellView
*)this);
1498 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1500 /* Set the focus to the listview */
1501 ::SetFocus(hWndList
);
1503 /* Notify the ICommDlgBrowser interface */
1504 OnStateChange(CDBOSC_SETFOCUS
);
1509 /**********************************************************
1510 * ShellView_OnKillFocus()
1512 LRESULT
CDefView::OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1514 TRACE("(%p) stub\n", this);
1516 DoActivate(SVUIA_ACTIVATE_NOFOCUS
);
1517 /* Notify the ICommDlgBrowser */
1518 OnStateChange(CDBOSC_KILLFOCUS
);
1523 /**********************************************************
1524 * ShellView_OnCommand()
1527 * the CmdID's are the ones from the context menu
1529 LRESULT
CDefView::OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1535 dwCmdID
= GET_WM_COMMAND_ID(wParam
, lParam
);
1536 dwCmd
= GET_WM_COMMAND_CMD(wParam
, lParam
);
1537 hwndCmd
= GET_WM_COMMAND_HWND(wParam
, lParam
);
1539 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n",this, dwCmdID
, dwCmd
, hwndCmd
);
1543 case FCIDM_SHVIEW_SMALLICON
:
1544 FolderSettings
.ViewMode
= FVM_SMALLICON
;
1545 SetStyle (LVS_SMALLICON
, LVS_TYPEMASK
);
1549 case FCIDM_SHVIEW_BIGICON
:
1550 FolderSettings
.ViewMode
= FVM_ICON
;
1551 SetStyle (LVS_ICON
, LVS_TYPEMASK
);
1555 case FCIDM_SHVIEW_LISTVIEW
:
1556 FolderSettings
.ViewMode
= FVM_LIST
;
1557 SetStyle (LVS_LIST
, LVS_TYPEMASK
);
1561 case FCIDM_SHVIEW_REPORTVIEW
:
1562 FolderSettings
.ViewMode
= FVM_DETAILS
;
1563 SetStyle (LVS_REPORT
, LVS_TYPEMASK
);
1567 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1572 ListViewSortInfo
.nHeaderID
= (LPARAM
) (dwCmdID
- 0x30);
1573 ListViewSortInfo
.bIsAscending
= TRUE
;
1574 ListViewSortInfo
.nLastHeaderID
= ListViewSortInfo
.nHeaderID
;
1575 SendMessageA(hWndList
, LVM_SORTITEMS
, (WPARAM
) &ListViewSortInfo
, (LPARAM
)ListViewCompareItems
);
1579 TRACE("-- COMMAND 0x%04x unhandled\n", dwCmdID
);
1585 /**********************************************************
1586 * ShellView_OnNotify()
1589 LRESULT
CDefView::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1593 LPNMLISTVIEW lpnmlv
;
1594 NMLVDISPINFOW
*lpdi
;
1599 lpnmh
= (LPNMHDR
)lParam
;
1600 lpnmlv
= (LPNMLISTVIEW
)lpnmh
;
1601 lpdi
= (NMLVDISPINFOW
*)lpnmh
;
1603 TRACE("%p CtlID=%u lpnmh->code=%x\n",this,CtlID
,lpnmh
->code
);
1605 switch (lpnmh
->code
)
1608 TRACE("-- NM_SETFOCUS %p\n", this);
1609 OnSetFocus(0, 0, 0, unused
);
1613 TRACE("-- NM_KILLFOCUS %p\n", this);
1615 /* Notify the ICommDlgBrowser interface */
1616 OnStateChange(CDBOSC_KILLFOCUS
);
1620 TRACE("-- NM_CUSTOMDRAW %p\n", this);
1621 return CDRF_DODEFAULT
;
1623 case NM_RELEASEDCAPTURE
:
1624 TRACE("-- NM_RELEASEDCAPTURE %p\n", this);
1628 TRACE("-- NM_CLICK %p\n", this);
1632 TRACE("-- NM_RCLICK %p\n", this);
1636 TRACE("-- NM_DBLCLK %p\n", this);
1637 if (OnDefaultCommand() != S_OK
) OpenSelectedItems();
1641 TRACE("-- NM_RETURN %p\n", this);
1642 if (OnDefaultCommand() != S_OK
) OpenSelectedItems();
1646 TRACE("-- HDN_ENDTRACKW %p\n", this);
1647 /*nColumn1 = ListView_GetColumnWidth(hWndList, 0);
1648 nColumn2 = ListView_GetColumnWidth(hWndList, 1);*/
1651 case LVN_DELETEITEM
:
1652 TRACE("-- LVN_DELETEITEM %p\n", this);
1653 SHFree((LPITEMIDLIST
)lpnmlv
->lParam
); /*delete the pidl because we made a copy of it*/
1656 case LVN_DELETEALLITEMS
:
1657 TRACE("-- LVN_DELETEALLITEMS %p\n", this);
1660 case LVN_INSERTITEM
:
1661 TRACE("-- LVN_INSERTITEM (STUB)%p\n", this);
1664 case LVN_ITEMACTIVATE
:
1665 TRACE("-- LVN_ITEMACTIVATE %p\n", this);
1666 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1669 case LVN_COLUMNCLICK
:
1670 ListViewSortInfo
.nHeaderID
= lpnmlv
->iSubItem
;
1671 if (ListViewSortInfo
.nLastHeaderID
== ListViewSortInfo
.nHeaderID
)
1673 ListViewSortInfo
.bIsAscending
= !ListViewSortInfo
.bIsAscending
;
1677 ListViewSortInfo
.bIsAscending
= TRUE
;
1679 ListViewSortInfo
.nLastHeaderID
= ListViewSortInfo
.nHeaderID
;
1681 SendMessageW(lpnmlv
->hdr
.hwndFrom
, LVM_SORTITEMS
, (WPARAM
) &ListViewSortInfo
, (LPARAM
)ListViewCompareItems
);
1684 case LVN_GETDISPINFOA
:
1685 case LVN_GETDISPINFOW
:
1686 TRACE("-- LVN_GETDISPINFO %p\n", this);
1687 pidl
= (LPITEMIDLIST
)lpdi
->item
.lParam
;
1689 if (lpdi
->item
.mask
& LVIF_TEXT
) /* text requested */
1694 pSF2Parent
->GetDetailsOf(pidl
, lpdi
->item
.iSubItem
, &sd
);
1695 if (lpnmh
->code
== LVN_GETDISPINFOA
)
1697 /* shouldn't happen */
1698 NMLVDISPINFOA
*lpdiA
= (NMLVDISPINFOA
*)lpnmh
;
1699 StrRetToStrNA( lpdiA
->item
.pszText
, lpdiA
->item
.cchTextMax
, &sd
.str
, NULL
);
1700 TRACE("-- text=%s\n",lpdiA
->item
.pszText
);
1702 else /* LVN_GETDISPINFOW */
1704 StrRetToStrNW( lpdi
->item
.pszText
, lpdi
->item
.cchTextMax
, &sd
.str
, NULL
);
1705 TRACE("-- text=%s\n",debugstr_w(lpdi
->item
.pszText
));
1713 if(lpdi
->item
.mask
& LVIF_IMAGE
) /* image requested */
1715 lpdi
->item
.iImage
= SHMapPIDLToSystemImageListIndex(pSFParent
, pidl
, 0);
1717 lpdi
->item
.mask
|= LVIF_DI_SETITEM
;
1720 case LVN_ITEMCHANGED
:
1721 TRACE("-- LVN_ITEMCHANGED %p\n", this);
1722 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1726 case LVN_BEGINRDRAG
:
1727 TRACE("-- LVN_BEGINDRAG\n");
1729 if (GetSelections())
1732 DWORD dwAttributes
= SFGAO_CANLINK
;
1733 DWORD dwEffect
= DROPEFFECT_COPY
| DROPEFFECT_MOVE
;
1735 if (SUCCEEDED(pSFParent
->GetUIObjectOf(m_hWnd
, cidl
, (LPCITEMIDLIST
*)apidl
, IID_IDataObject
,0,(LPVOID
*)&pda
)))
1737 IDropSource
* pds
= (IDropSource
*)this; /* own DropSource interface */
1739 if (SUCCEEDED(pSFParent
->GetAttributesOf(cidl
, (LPCITEMIDLIST
*)apidl
, &dwAttributes
)))
1741 if (dwAttributes
& SFGAO_CANLINK
)
1743 dwEffect
|= DROPEFFECT_LINK
;
1750 DoDragDrop(pda
, pds
, dwEffect
, &dwEffect2
);
1757 case LVN_BEGINLABELEDITW
:
1759 DWORD dwAttr
= SFGAO_CANRENAME
;
1760 pidl
= (LPITEMIDLIST
)lpdi
->item
.lParam
;
1762 TRACE("-- LVN_BEGINLABELEDITW %p\n", this);
1764 pSFParent
->GetAttributesOf(1, (LPCITEMIDLIST
*)&pidl
, &dwAttr
);
1765 if (SFGAO_CANRENAME
& dwAttr
)
1772 case LVN_ENDLABELEDITW
:
1774 TRACE("-- LVN_ENDLABELEDITW %p\n", this);
1775 if (lpdi
->item
.pszText
)
1780 lvItem
.iItem
= lpdi
->item
.iItem
;
1781 lvItem
.iSubItem
= 0;
1782 lvItem
.mask
= LVIF_PARAM
;
1783 SendMessageW(hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
1785 pidl
= (LPITEMIDLIST
)lpdi
->item
.lParam
;
1786 hr
= pSFParent
->SetNameOf(0, pidl
, lpdi
->item
.pszText
, SHGDN_INFOLDER
, &pidl
);
1788 if (SUCCEEDED(hr
) && pidl
)
1790 lvItem
.mask
= LVIF_PARAM
;
1791 lvItem
.lParam
= (LPARAM
)pidl
;
1792 SendMessageW(hWndList
, LVM_SETITEMW
, 0, (LPARAM
) &lvItem
);
1805 msg.message = WM_KEYDOWN;
1806 msg.wParam = plvKeyDown->wVKey;
1811 LPNMLVKEYDOWN plvKeyDown
= (LPNMLVKEYDOWN
) lpnmh
;
1812 SHORT ctrl
= GetKeyState(VK_CONTROL
) & 0x8000;
1814 /* initiate a rename of the selected file or directory */
1815 if (plvKeyDown
->wVKey
== VK_F2
)
1817 /* see how many files are selected */
1818 int i
= ListView_GetSelectedCount(hWndList
);
1820 /* get selected item */
1823 /* get selected item */
1824 i
= ListView_GetNextItem(hWndList
, -1, LVNI_SELECTED
);
1826 SendMessageW(hWndList
, LVM_ENSUREVISIBLE
, i
, 0);
1827 SendMessageW(hWndList
, LVM_EDITLABELW
, i
, 0);
1831 TranslateAccelerator(m_hWnd
, hAccel
, &msg
)
1833 else if(plvKeyDown
->wVKey
== VK_DELETE
)
1838 LPITEMIDLIST
* pItems
;
1841 pSFParent
->QueryInterface(IID_ISFHelper
,
1847 if (!(i
= ListView_GetSelectedCount(hWndList
)))
1850 /* allocate memory for the pidl array */
1851 pItems
= (LPITEMIDLIST
*)HeapAlloc(GetProcessHeap(), 0,
1852 sizeof(LPITEMIDLIST
) * i
);
1854 /* retrieve all selected items */
1857 while (ListView_GetSelectedCount(hWndList
) > i
)
1859 /* get selected item */
1860 item_index
= ListView_GetNextItem(hWndList
,
1861 item_index
, LVNI_SELECTED
);
1862 item
.iItem
= item_index
;
1863 item
.mask
= LVIF_PARAM
;
1864 SendMessageA(hWndList
, LVM_GETITEMA
, 0, (LPARAM
) &item
);
1867 pItems
[i
] = (LPITEMIDLIST
)item
.lParam
;
1872 /* perform the item deletion */
1873 psfhlp
->DeleteItems(i
, (LPCITEMIDLIST
*)pItems
);
1875 /* free pidl array memory */
1876 HeapFree(GetProcessHeap(), 0, pItems
);
1878 /* Initiate a refresh */
1879 else if (plvKeyDown
->wVKey
== VK_F5
)
1883 else if (plvKeyDown
->wVKey
== VK_BACK
)
1885 LPSHELLBROWSER lpSb
;
1886 if ((lpSb
= (LPSHELLBROWSER
)SendMessageW(hWndParent
, CWM_GETISHELLBROWSER
, 0, 0)))
1888 lpSb
->BrowseObject(NULL
, SBSP_PARENT
);
1891 else if (plvKeyDown
->wVKey
== 'C' && ctrl
)
1893 if (GetSelections())
1895 CComPtr
<IDataObject
> pda
;
1897 if (SUCCEEDED(pSFParent
->GetUIObjectOf(m_hWnd
, cidl
, (LPCITEMIDLIST
*)apidl
, IID_IDataObject
, 0, (LPVOID
*)&pda
)))
1899 HRESULT hr
= OleSetClipboard(pda
);
1902 WARN("OleSetClipboard failed");
1908 else if(plvKeyDown
->wVKey
== 'V' && ctrl
)
1910 CComPtr
<IDataObject
> pda
;
1912 FORMATETC formatetc
;
1913 LPITEMIDLIST
* apidl
;
1915 CComPtr
<IShellFolder
> psfFrom
;
1916 CComPtr
<IShellFolder
> psfDesktop
;
1917 CComPtr
<IShellFolder
> psfTarget
;
1919 CComPtr
<ISFHelper
> psfhlpdst
;
1920 CComPtr
<ISFHelper
> psfhlpsrc
;
1923 hr
= OleGetClipboard(&pda
);
1926 ERR("Failed to get clipboard with %lx\n", hr
);
1930 InitFormatEtc(formatetc
, RegisterClipboardFormatW(CFSTR_SHELLIDLIST
), TYMED_HGLOBAL
);
1931 hr
= pda
->GetData(&formatetc
, &medium
);
1935 ERR("Failed to get clipboard data with %lx\n", hr
);
1939 /* lock the handle */
1940 lpcida
= (LPIDA
)GlobalLock(medium
.hGlobal
);
1943 ERR("failed to lock pidl\n");
1944 ReleaseStgMedium(&medium
);
1948 /* convert the data into pidl */
1949 apidl
= _ILCopyCidaToaPidl(&pidl
, lpcida
);
1953 ERR("failed to copy pidl\n");
1957 if (FAILED(SHGetDesktopFolder(&psfDesktop
)))
1959 ERR("failed to get desktop folder\n");
1961 _ILFreeaPidl(apidl
, lpcida
->cidl
);
1962 ReleaseStgMedium(&medium
);
1966 if (_ILIsDesktop(pidl
))
1968 /* use desktop shellfolder */
1969 psfFrom
= psfDesktop
;
1971 else if (FAILED(psfDesktop
->BindToObject(pidl
, NULL
, IID_IShellFolder
, (LPVOID
*)&psfFrom
)))
1973 ERR("no IShellFolder\n");
1976 _ILFreeaPidl(apidl
, lpcida
->cidl
);
1977 ReleaseStgMedium(&medium
);
1982 psfTarget
= pSFParent
;
1985 /* get source and destination shellfolder */
1986 if (FAILED(psfTarget
->QueryInterface(IID_ISFHelper
, (LPVOID
*)&psfhlpdst
)))
1988 ERR("no IID_ISFHelper for destination\n");
1991 _ILFreeaPidl(apidl
, lpcida
->cidl
);
1992 ReleaseStgMedium(&medium
);
1997 if (FAILED(psfFrom
->QueryInterface(IID_ISFHelper
, (LPVOID
*)&psfhlpsrc
)))
1999 ERR("no IID_ISFHelper for source\n");
2002 _ILFreeaPidl(apidl
, lpcida
->cidl
);
2003 ReleaseStgMedium(&medium
);
2008 * do we want to perform a copy or move ???
2010 hr
= psfhlpdst
->CopyItems(psfFrom
, lpcida
->cidl
, (LPCITEMIDLIST
*)apidl
);
2013 _ILFreeaPidl(apidl
, lpcida
->cidl
);
2014 ReleaseStgMedium(&medium
);
2016 TRACE("paste end hr %x\n", hr
);
2020 FIXME("LVN_KEYDOWN key=0x%08x\n",plvKeyDown
->wVKey
);
2025 TRACE("-- %p WM_COMMAND %x unhandled\n", this, lpnmh
->code
);
2032 /**********************************************************
2033 * ShellView_OnChange()
2035 LRESULT
CDefView::OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
2037 LPITEMIDLIST
*Pidls
;
2039 Pidls
= (LPITEMIDLIST
*)wParam
;
2041 TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls
[0], Pidls
[1], lParam
);
2047 LV_AddItem(Pidls
[0]);
2052 LV_DeleteItem(Pidls
[0]);
2055 case SHCNE_RENAMEFOLDER
:
2056 case SHCNE_RENAMEITEM
:
2057 LV_RenameItem(Pidls
[0], Pidls
[1]);
2060 case SHCNE_UPDATEITEM
:
2067 /**********************************************************
2068 * ShellView_DoMeasureItem
2070 LRESULT
CDefView::OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
2075 ERR("no menu!!!\n");
2079 if (pCM
.p
->HandleMenuMsg(uMsg
, (WPARAM
)m_hWnd
, lParam
) == S_OK
)
2085 /**********************************************************
2088 * The INTERFACE of the IShellView object
2091 **********************************************************
2094 /**********************************************************
2095 * ShellView_GetWindow
2097 HRESULT WINAPI
CDefView::GetWindow(HWND
*phWnd
)
2099 TRACE("(%p)\n",this);
2106 HRESULT WINAPI
CDefView::ContextSensitiveHelp(BOOL fEnterMode
)
2108 FIXME("(%p) stub\n",this);
2113 /**********************************************************
2114 * IShellView_TranslateAccelerator
2117 * use the accel functions
2119 HRESULT WINAPI
CDefView::TranslateAccelerator(LPMSG lpmsg
)
2122 FIXME("(%p)->(%p: hwnd=%x msg=%x lp=%x wp=%x) stub\n",this,lpmsg
, lpmsg
->hwnd
, lpmsg
->message
, lpmsg
->lParam
, lpmsg
->wParam
);
2125 if (lpmsg
->message
>= WM_KEYFIRST
&& lpmsg
->message
>= WM_KEYLAST
)
2127 TRACE("-- key=0x04%lx\n",lpmsg
->wParam
) ;
2130 return S_FALSE
; /* not handled */
2133 HRESULT WINAPI
CDefView::EnableModeless(BOOL fEnable
)
2135 FIXME("(%p) stub\n",this);
2140 HRESULT WINAPI
CDefView::UIActivate(UINT uState
)
2143 CHAR szName[MAX_PATH];
2146 int nPartArray
[1] = {-1};
2148 TRACE("(%p)->(state=%x) stub\n",this, uState
);
2150 /*don't do anything if the state isn't really changing*/
2151 if (uState
== uState
)
2156 /*OnActivate handles the menu merging and internal state*/
2159 /*only do This if we are active*/
2160 if (uState
!= SVUIA_DEACTIVATE
)
2164 GetFolderPath is not a method of IShellFolder
2165 IShellFolder_GetFolderPath( pSFParent, szName, sizeof(szName) );
2167 /* set the number of parts */
2168 pShellBrowser
->SendControlMsg(FCW_STATUS
, SB_SETPARTS
, 1, (LPARAM
)nPartArray
, &lResult
);
2170 /* set the text for the parts */
2172 pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXTA, 0, (LPARAM)szName, &lResult);
2179 HRESULT WINAPI
CDefView::Refresh()
2181 TRACE("(%p)\n",this);
2183 SendMessageW(hWndList
, LVM_DELETEALLITEMS
, 0, 0);
2189 HRESULT WINAPI
CDefView::CreateViewWindow(IShellView
*lpPrevView
, LPCFOLDERSETTINGS lpfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
)
2193 TRACE("(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n",this, lpPrevView
,lpfs
, psb
, prcView
, phWnd
);
2195 DbgPrint("[shell32, CDefView::CreateViewWindow] Called lpfs = 0x%x, psb = 0x%x\n", lpfs
, psb
);
2198 TRACE("-- vmode=%x flags=%x\n", lpfs
->ViewMode
, lpfs
->fFlags
);
2199 if (prcView
!= NULL
)
2200 TRACE("-- left=%i top=%i right=%i bottom=%i\n", prcView
->left
, prcView
->top
, prcView
->right
, prcView
->bottom
);
2202 /* Validate the Shell Browser */
2204 return E_UNEXPECTED
;
2206 /*set up the member variables*/
2207 pShellBrowser
= psb
;
2208 FolderSettings
= *lpfs
;
2210 /*get our parent window*/
2211 pShellBrowser
->GetWindow(&hWndParent
);
2213 /* try to get the ICommDlgBrowserInterface, adds a reference !!! */
2214 pCommDlgBrowser
= NULL
;
2215 if (SUCCEEDED(pShellBrowser
->QueryInterface(IID_ICommDlgBrowser
, (LPVOID
*)&pCommDlgBrowser
)))
2217 TRACE("-- CommDlgBrowser\n");
2220 DbgPrint("[shell32, CDefView::CreateViewWindow] About to call the create function\n");
2222 Create(hWndParent
, prcView
, NULL
, WS_CHILD
| WS_TABSTOP
, 0, 0U);
2233 SetWindowPos(HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_SHOWWINDOW
);
2239 HRESULT WINAPI
CDefView::DestroyViewWindow()
2241 TRACE("(%p)\n",this);
2243 /*Make absolutely sure all our UI is cleaned up.*/
2244 UIActivate(SVUIA_DEACTIVATE
);
2252 pShellBrowser
.Release();
2253 pCommDlgBrowser
.Release();
2258 HRESULT WINAPI
CDefView::GetCurrentInfo(LPFOLDERSETTINGS lpfs
)
2260 TRACE("(%p)->(%p) vmode=%x flags=%x\n",this, lpfs
,
2261 FolderSettings
.ViewMode
, FolderSettings
.fFlags
);
2264 return E_INVALIDARG
;
2266 *lpfs
= FolderSettings
;
2270 HRESULT WINAPI
CDefView::AddPropertySheetPages(DWORD dwReserved
,LPFNADDPROPSHEETPAGE lpfn
, LPARAM lparam
)
2272 FIXME("(%p) stub\n",this);
2277 HRESULT WINAPI
CDefView::SaveViewState()
2279 FIXME("(%p) stub\n",this);
2284 HRESULT WINAPI
CDefView::SelectItem(LPCITEMIDLIST pidl
, UINT uFlags
)
2288 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n",this, pidl
, uFlags
);
2290 i
= LV_FindItemByPidl(pidl
);
2296 if(uFlags
& SVSI_ENSUREVISIBLE
)
2297 SendMessageW(hWndList
, LVM_ENSUREVISIBLE
, i
, 0);
2299 lvItem
.mask
= LVIF_STATE
;
2300 lvItem
.stateMask
= LVIS_SELECTED
| LVIS_FOCUSED
;
2302 lvItem
.iSubItem
= 0;
2304 while (SendMessageW(hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
))
2306 if (lvItem
.iItem
== i
)
2308 if (uFlags
& SVSI_SELECT
)
2309 lvItem
.state
|= LVIS_SELECTED
;
2311 lvItem
.state
&= ~LVIS_SELECTED
;
2313 if (uFlags
& SVSI_FOCUSED
)
2314 lvItem
.state
&= ~LVIS_FOCUSED
;
2318 if (uFlags
& SVSI_DESELECTOTHERS
)
2319 lvItem
.state
&= ~LVIS_SELECTED
;
2322 SendMessageW(hWndList
, LVM_SETITEMW
, 0, (LPARAM
) &lvItem
);
2327 if(uFlags
& SVSI_EDIT
)
2328 SendMessageW(hWndList
, LVM_EDITLABELW
, i
, 0);
2334 HRESULT WINAPI
CDefView::GetItemObject(UINT uItem
, REFIID riid
, LPVOID
*ppvOut
)
2336 HRESULT hr
= E_FAIL
;
2338 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n",this, uItem
, debugstr_guid(&riid
), ppvOut
);
2344 case SVGIO_BACKGROUND
:
2345 if (IsEqualIID(riid
, IID_IContextMenu
))
2347 //*ppvOut = ISvBgCm_Constructor(pSFParent, FALSE);
2348 CDefFolderMenu_Create2(NULL
, NULL
, cidl
, (LPCITEMIDLIST
*)apidl
, pSFParent
, NULL
, 0, NULL
, (IContextMenu
**)ppvOut
);
2354 case SVGIO_SELECTION
:
2356 hr
= pSFParent
->GetUIObjectOf(m_hWnd
, cidl
, (LPCITEMIDLIST
*)apidl
, riid
, 0, ppvOut
);
2360 TRACE("-- (%p)->(interface=%p)\n",this, *ppvOut
);
2365 HRESULT STDMETHODCALLTYPE
CDefView::GetCurrentViewMode(UINT
*pViewMode
)
2370 HRESULT STDMETHODCALLTYPE
CDefView::SetCurrentViewMode(UINT ViewMode
)
2375 HRESULT STDMETHODCALLTYPE
CDefView::GetFolder(REFIID riid
, void **ppv
)
2377 if (pSFParent
== NULL
)
2380 return pSFParent
->QueryInterface(riid
, ppv
);
2383 HRESULT STDMETHODCALLTYPE
CDefView::Item(int iItemIndex
, LPITEMIDLIST
*ppidl
)
2388 HRESULT STDMETHODCALLTYPE
CDefView::ItemCount(UINT uFlags
, int *pcItems
)
2393 HRESULT STDMETHODCALLTYPE
CDefView::Items(UINT uFlags
, REFIID riid
, void **ppv
)
2398 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectionMarkedItem(int *piItem
)
2403 HRESULT STDMETHODCALLTYPE
CDefView::GetFocusedItem(int *piItem
)
2408 HRESULT STDMETHODCALLTYPE
CDefView::GetItemPosition(LPCITEMIDLIST pidl
, POINT
*ppt
)
2413 HRESULT STDMETHODCALLTYPE
CDefView::GetSpacing(POINT
*ppt
)
2418 HRESULT STDMETHODCALLTYPE
CDefView::GetDefaultSpacing(POINT
*ppt
)
2423 HRESULT STDMETHODCALLTYPE
CDefView::GetAutoArrange()
2428 HRESULT STDMETHODCALLTYPE
CDefView::SelectItem(int iItem
, DWORD dwFlags
)
2433 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItems(UINT cidl
, LPCITEMIDLIST
*apidl
, POINT
*apt
, DWORD dwFlags
)
2438 /**********************************************************
2439 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2441 HRESULT WINAPI
CDefView::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD
*prgCmds
, OLECMDTEXT
*pCmdText
)
2443 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
2444 this, pguidCmdGroup
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
2449 for (UINT i
=0; i
< cCmds
; i
++)
2451 FIXME("\tprgCmds[%d].cmdID = %d\n", i
, prgCmds
[i
].cmdID
);
2452 prgCmds
[i
].cmdf
= 0;
2455 return OLECMDERR_E_UNKNOWNGROUP
;
2458 /**********************************************************
2459 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2461 * nCmdID is the OLECMDID_* enumeration
2463 HRESULT WINAPI
CDefView::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
2465 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2466 this, debugstr_guid(pguidCmdGroup
), nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2468 if (IsEqualIID(*pguidCmdGroup
, CGID_Explorer
) &&
2470 (nCmdexecopt
== 4) && pvaOut
)
2473 if (IsEqualIID(*pguidCmdGroup
, CGID_ShellDocView
) &&
2478 return OLECMDERR_E_UNKNOWNGROUP
;
2481 /**********************************************************
2482 * ISVDropTarget implementation
2485 /******************************************************************************
2486 * drag_notify_subitem [Internal]
2488 * Figure out the shellfolder object, which is currently under the mouse cursor
2489 * and notify it via the IDropTarget interface.
2492 #define SCROLLAREAWIDTH 20
2494 HRESULT
CDefView::drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2496 LVHITTESTINFO htinfo
;
2502 /* Map from global to client coordinates and query the index of the listview-item, which is
2503 * currently under the mouse cursor. */
2506 htinfo
.flags
= LVHT_ONITEM
;
2507 ::ScreenToClient(hWndList
, &htinfo
.pt
);
2508 lResult
= SendMessageW(hWndList
, LVM_HITTEST
, 0, (LPARAM
)&htinfo
);
2510 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2511 ::GetClientRect(hWndList
, &clientRect
);
2512 if (htinfo
.pt
.x
== ptLastMousePos
.x
&& htinfo
.pt
.y
== ptLastMousePos
.y
&&
2513 (htinfo
.pt
.x
< SCROLLAREAWIDTH
|| htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
||
2514 htinfo
.pt
.y
< SCROLLAREAWIDTH
|| htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
))
2516 cScrollDelay
= (cScrollDelay
+ 1) % 5; /* DragOver is called every 50 ms */
2517 if (cScrollDelay
== 0)
2519 /* Mouse did hover another 250 ms over the scroll-area */
2520 if (htinfo
.pt
.x
< SCROLLAREAWIDTH
)
2521 SendMessageW(hWndList
, WM_HSCROLL
, SB_LINEUP
, 0);
2523 if (htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
)
2524 SendMessageW(hWndList
, WM_HSCROLL
, SB_LINEDOWN
, 0);
2526 if (htinfo
.pt
.y
< SCROLLAREAWIDTH
)
2527 SendMessageW(hWndList
, WM_VSCROLL
, SB_LINEUP
, 0);
2529 if (htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
)
2530 SendMessageW(hWndList
, WM_VSCROLL
, SB_LINEDOWN
, 0);
2535 cScrollDelay
= 0; /* Reset, if the cursor is not over the listview's scroll-area */
2538 ptLastMousePos
= htinfo
.pt
;
2540 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2541 if (pCurDropTarget
&& lResult
== iDragOverItem
)
2542 return pCurDropTarget
->DragOver(grfKeyState
, pt
, pdwEffect
);
2544 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2547 pCurDropTarget
->DragLeave();
2548 pCurDropTarget
.Release();
2551 iDragOverItem
= lResult
;
2554 /* We are not above one of the listview's subitems. Bind to the parent folder's
2555 * DropTarget interface. */
2556 hr
= pSFParent
->QueryInterface(IID_IDropTarget
,
2557 (LPVOID
*)&pCurDropTarget
);
2561 /* Query the relative PIDL of the shellfolder object represented by the currently
2562 * dragged over listview-item ... */
2563 lvItem
.mask
= LVIF_PARAM
;
2564 lvItem
.iItem
= lResult
;
2565 lvItem
.iSubItem
= 0;
2566 SendMessageW(hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
2568 /* ... and bind pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2569 hr
= pSFParent
->GetUIObjectOf(hWndList
, 1,
2570 (LPCITEMIDLIST
*)&lvItem
.lParam
, IID_IDropTarget
, NULL
, (LPVOID
*)&pCurDropTarget
);
2573 /* If anything failed, pCurDropTarget should be NULL now, which ought to be a save state. */
2577 /* Notify the item just entered via DragEnter. */
2578 return pCurDropTarget
->DragEnter(pCurDataObject
, grfKeyState
, pt
, pdwEffect
);
2581 HRESULT WINAPI
CDefView::DragEnter(IDataObject
*pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2583 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2584 pCurDataObject
= pDataObject
;
2585 pDataObject
->AddRef();
2587 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2590 HRESULT WINAPI
CDefView::DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2592 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2595 HRESULT WINAPI
CDefView::DragLeave()
2599 pCurDropTarget
->DragLeave();
2600 pCurDropTarget
.Release();
2603 if (pCurDataObject
!= NULL
)
2605 pCurDataObject
.Release();
2613 HRESULT WINAPI
CDefView::Drop(IDataObject
* pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2617 pCurDropTarget
->Drop(pDataObject
, grfKeyState
, pt
, pdwEffect
);
2618 pCurDropTarget
.Release();
2621 pCurDataObject
.Release();
2627 /**********************************************************
2628 * ISVDropSource implementation
2631 HRESULT WINAPI
CDefView::QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
)
2633 TRACE("(%p)\n",this);
2636 return DRAGDROP_S_CANCEL
;
2637 else if (!(grfKeyState
& MK_LBUTTON
) && !(grfKeyState
& MK_RBUTTON
))
2638 return DRAGDROP_S_DROP
;
2643 HRESULT WINAPI
CDefView::GiveFeedback(DWORD dwEffect
)
2645 TRACE("(%p)\n",this);
2647 return DRAGDROP_S_USEDEFAULTCURSORS
;
2650 /**********************************************************
2651 * ISVViewObject implementation
2654 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
)
2656 FIXME("Stub: this=%p\n",this);
2661 HRESULT WINAPI
CDefView::GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
, HDC hicTargetDevice
, LOGPALETTE
**ppColorSet
)
2663 FIXME("Stub: this=%p\n",this);
2668 HRESULT WINAPI
CDefView::Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
)
2670 FIXME("Stub: this=%p\n",this);
2675 HRESULT WINAPI
CDefView::Unfreeze(DWORD dwFreeze
)
2677 FIXME("Stub: this=%p\n",this);
2682 HRESULT WINAPI
CDefView::SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
)
2684 FIXME("partial stub: %p %08x %08x %p\n", this, aspects
, advf
, pAdvSink
);
2686 /* FIXME: we set the AdviseSink, but never use it to send any advice */
2687 pAdvSink
= pAdvSink
;
2688 dwAspects
= aspects
;
2694 HRESULT WINAPI
CDefView::GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
)
2696 TRACE("this=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n", this, pAspects
, pAdvf
, ppAdvSink
);
2700 *ppAdvSink
= pAdvSink
;
2701 pAdvSink
.p
->AddRef();
2705 *pAspects
= dwAspects
;
2713 HRESULT STDMETHODCALLTYPE
CDefView::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
2715 if (IsEqualIID(guidService
, SID_IShellBrowser
))
2716 return pShellBrowser
->QueryInterface(riid
, ppvObject
);
2717 return E_NOINTERFACE
;
2720 /**********************************************************
2721 * IShellView_Constructor
2723 HRESULT WINAPI
IShellView_Constructor(IShellFolder
*pFolder
, IShellView
**newView
)
2725 CComObject
<CDefView
> *theView
;
2726 CComPtr
<IShellView
> result
;
2729 if (newView
== NULL
)
2733 ATLTRY (theView
= new CComObject
<CDefView
>);
2735 if (theView
== NULL
)
2736 return E_OUTOFMEMORY
;
2738 hResult
= theView
->QueryInterface (IID_IShellView
, (void **)&result
);
2739 if (FAILED (hResult
))
2745 hResult
= theView
->Initialize (pFolder
);
2746 if (FAILED (hResult
))
2748 *newView
= result
.Detach ();