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
56 #include "shlwapi_undoc.h"
58 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
62 static const WCHAR SV_CLASS_NAME
[] = {'S','H','E','L','L','D','L','L','_','D','e','f','V','i','e','w',0};
68 }LISTVIEW_SORT_INFO
, *LPLISTVIEW_SORT_INFO
;
70 #define SHV_CHANGE_NOTIFY WM_USER + 0x1111
73 public CWindowImpl
<CDefView
, CWindow
, CControlWinTraits
>,
74 public CComObjectRootEx
<CComMultiThreadModelNoCS
>,
77 public IOleCommandTarget
,
81 public IServiceProvider
84 CComPtr
<IShellFolder
> pSFParent
;
85 CComPtr
<IShellFolder2
> pSF2Parent
;
86 CComPtr
<IShellBrowser
> pShellBrowser
;
87 CComPtr
<ICommDlgBrowser
> pCommDlgBrowser
;
88 HWND hWndList
; /* ListView control */
90 FOLDERSETTINGS FolderSettings
;
95 LISTVIEW_SORT_INFO ListViewSortInfo
;
96 ULONG hNotify
; /* change notification handle */
100 CComPtr
<IAdviseSink
> pAdvSink
;
102 CComPtr
<IDropTarget
> pCurDropTarget
; /* The sub-item, which is currently dragged over */
103 CComPtr
<IDataObject
> pCurDataObject
; /* The dragged data-object */
104 LONG iDragOverItem
; /* Dragged over item's index, iff pCurDropTarget != NULL */
105 UINT cScrollDelay
; /* Send a WM_*SCROLL msg every 250 ms during drag-scroll */
106 POINT ptLastMousePos
; /* Mouse position at last DragOver call */
108 CComPtr
<IContextMenu2
> pCM
;
112 HRESULT WINAPI
Initialize(IShellFolder
*shellFolder
);
113 HRESULT
IncludeObject(LPCITEMIDLIST pidl
);
114 HRESULT
OnDefaultCommand();
115 HRESULT
OnStateChange(UINT uFlags
);
117 void SetStyle(DWORD dwAdd
, DWORD dwRemove
);
120 static INT CALLBACK
CompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
);
121 static INT CALLBACK
ListViewCompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
);
122 int LV_FindItemByPidl(LPCITEMIDLIST pidl
);
123 BOOLEAN
LV_AddItem(LPCITEMIDLIST pidl
);
124 BOOLEAN
LV_DeleteItem(LPCITEMIDLIST pidl
);
125 BOOLEAN
LV_RenameItem(LPCITEMIDLIST pidlOld
, LPCITEMIDLIST pidlNew
);
126 static INT CALLBACK
fill_list(LPVOID ptr
, LPVOID arg
);
128 HMENU
BuildFileMenu();
129 void MergeFileMenu(HMENU hSubMenu
);
130 void MergeViewMenu(HMENU hSubMenu
);
131 UINT
GetSelections();
132 HRESULT
OpenSelectedItems();
134 void DoActivate(UINT uState
);
135 HRESULT
drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
137 // *** IOleWindow methods ***
138 virtual HRESULT STDMETHODCALLTYPE
GetWindow(HWND
*lphwnd
);
139 virtual HRESULT STDMETHODCALLTYPE
ContextSensitiveHelp(BOOL fEnterMode
);
141 // *** IShellView methods ***
142 virtual HRESULT STDMETHODCALLTYPE
TranslateAccelerator(MSG
*pmsg
);
143 virtual HRESULT STDMETHODCALLTYPE
EnableModeless(BOOL fEnable
);
144 virtual HRESULT STDMETHODCALLTYPE
UIActivate(UINT uState
);
145 virtual HRESULT STDMETHODCALLTYPE
Refresh();
146 virtual HRESULT STDMETHODCALLTYPE
CreateViewWindow(IShellView
*psvPrevious
, LPCFOLDERSETTINGS pfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
);
147 virtual HRESULT STDMETHODCALLTYPE
DestroyViewWindow();
148 virtual HRESULT STDMETHODCALLTYPE
GetCurrentInfo(LPFOLDERSETTINGS pfs
);
149 virtual HRESULT STDMETHODCALLTYPE
AddPropertySheetPages(DWORD dwReserved
, LPFNSVADDPROPSHEETPAGE pfn
, LPARAM lparam
);
150 virtual HRESULT STDMETHODCALLTYPE
SaveViewState();
151 virtual HRESULT STDMETHODCALLTYPE
SelectItem(LPCITEMIDLIST pidlItem
, SVSIF uFlags
);
152 virtual HRESULT STDMETHODCALLTYPE
GetItemObject(UINT uItem
, REFIID riid
, void **ppv
);
154 // *** IFolderView methods ***
155 virtual HRESULT STDMETHODCALLTYPE
GetCurrentViewMode(UINT
*pViewMode
);
156 virtual HRESULT STDMETHODCALLTYPE
SetCurrentViewMode(UINT ViewMode
);
157 virtual HRESULT STDMETHODCALLTYPE
GetFolder(REFIID riid
, void **ppv
);
158 virtual HRESULT STDMETHODCALLTYPE
Item(int iItemIndex
, LPITEMIDLIST
*ppidl
);
159 virtual HRESULT STDMETHODCALLTYPE
ItemCount(UINT uFlags
, int *pcItems
);
160 virtual HRESULT STDMETHODCALLTYPE
Items(UINT uFlags
, REFIID riid
, void **ppv
);
161 virtual HRESULT STDMETHODCALLTYPE
GetSelectionMarkedItem(int *piItem
);
162 virtual HRESULT STDMETHODCALLTYPE
GetFocusedItem(int *piItem
);
163 virtual HRESULT STDMETHODCALLTYPE
GetItemPosition(LPCITEMIDLIST pidl
, POINT
*ppt
);
164 virtual HRESULT STDMETHODCALLTYPE
GetSpacing(POINT
*ppt
);
165 virtual HRESULT STDMETHODCALLTYPE
GetDefaultSpacing(POINT
*ppt
);
166 virtual HRESULT STDMETHODCALLTYPE
GetAutoArrange();
167 virtual HRESULT STDMETHODCALLTYPE
SelectItem(int iItem
, DWORD dwFlags
);
168 virtual HRESULT STDMETHODCALLTYPE
SelectAndPositionItems(UINT cidl
, LPCITEMIDLIST
*apidl
, POINT
*apt
, DWORD dwFlags
);
170 // *** IOleCommandTarget methods ***
171 virtual HRESULT STDMETHODCALLTYPE
QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
);
172 virtual HRESULT STDMETHODCALLTYPE
Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
);
174 // *** IDropTarget methods ***
175 virtual HRESULT STDMETHODCALLTYPE
DragEnter(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
176 virtual HRESULT STDMETHODCALLTYPE
DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
177 virtual HRESULT STDMETHODCALLTYPE
DragLeave();
178 virtual HRESULT STDMETHODCALLTYPE
Drop(IDataObject
*pDataObj
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
);
180 // *** IDropSource methods ***
181 virtual HRESULT STDMETHODCALLTYPE
QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
);
182 virtual HRESULT STDMETHODCALLTYPE
GiveFeedback(DWORD dwEffect
);
184 // *** IViewObject methods ***
185 virtual HRESULT STDMETHODCALLTYPE
Draw(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
,
186 HDC hdcTargetDev
, HDC hdcDraw
, LPCRECTL lprcBounds
, LPCRECTL lprcWBounds
,
187 BOOL ( STDMETHODCALLTYPE
*pfnContinue
)(ULONG_PTR dwContinue
), ULONG_PTR dwContinue
);
188 virtual HRESULT STDMETHODCALLTYPE
GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
,
189 DVTARGETDEVICE
*ptd
, HDC hicTargetDev
, LOGPALETTE
**ppColorSet
);
190 virtual HRESULT STDMETHODCALLTYPE
Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
);
191 virtual HRESULT STDMETHODCALLTYPE
Unfreeze(DWORD dwFreeze
);
192 virtual HRESULT STDMETHODCALLTYPE
SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
);
193 virtual HRESULT STDMETHODCALLTYPE
GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
);
195 // *** IServiceProvider methods ***
196 virtual HRESULT STDMETHODCALLTYPE
QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
);
199 LRESULT
OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
200 LRESULT
OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
201 LRESULT
OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
202 LRESULT
OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
203 LRESULT
OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
204 LRESULT
OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
205 LRESULT
OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
206 LRESULT
OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
207 LRESULT
OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
208 LRESULT
OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
209 LRESULT
OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
210 LRESULT
OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
211 LRESULT
OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
212 LRESULT
OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
213 LRESULT
OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
);
215 static ATL::CWndClassInfo
& GetWndClassInfo()
217 static ATL::CWndClassInfo wc
=
219 { sizeof(WNDCLASSEX
), CS_HREDRAW
| CS_VREDRAW
, StartWindowProc
,
221 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(CWM_GETISHELLBROWSER
, OnGetShellBrowser
)
264 BEGIN_COM_MAP(CDefView
)
265 COM_INTERFACE_ENTRY_IID(IID_IOleWindow
, IOleWindow
)
266 COM_INTERFACE_ENTRY_IID(IID_IShellView
, IShellView
)
267 COM_INTERFACE_ENTRY_IID(IID_IFolderView
, IFolderView
)
268 COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget
, IOleCommandTarget
)
269 COM_INTERFACE_ENTRY_IID(IID_IDropTarget
, IDropTarget
)
270 COM_INTERFACE_ENTRY_IID(IID_IDropSource
, IDropSource
)
271 COM_INTERFACE_ENTRY_IID(IID_IViewObject
, IViewObject
)
272 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider
, IServiceProvider
)
276 /* ListView Header ID's */
277 #define LISTVIEW_COLUMN_NAME 0
278 #define LISTVIEW_COLUMN_SIZE 1
279 #define LISTVIEW_COLUMN_TYPE 2
280 #define LISTVIEW_COLUMN_TIME 3
281 #define LISTVIEW_COLUMN_ATTRIB 4
284 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
285 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
286 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
288 #define ID_LISTVIEW 1
291 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
292 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
293 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
296 Items merged into the toolbar and the filemenu
305 } MYTOOLINFO
, *LPMYTOOLINFO
;
307 static const MYTOOLINFO Tools
[] =
309 { FCIDM_SHVIEW_BIGICON
, 0, 0, IDS_VIEW_LARGE
, TBSTATE_ENABLED
, BTNS_BUTTON
},
310 { FCIDM_SHVIEW_SMALLICON
, 0, 0, IDS_VIEW_SMALL
, TBSTATE_ENABLED
, BTNS_BUTTON
},
311 { FCIDM_SHVIEW_LISTVIEW
, 0, 0, IDS_VIEW_LIST
, TBSTATE_ENABLED
, BTNS_BUTTON
},
312 { FCIDM_SHVIEW_REPORTVIEW
, 0, 0, IDS_VIEW_DETAILS
, TBSTATE_ENABLED
, BTNS_BUTTON
},
316 typedef void (CALLBACK
*PFNSHGETSETTINGSPROC
)(LPSHELLFLAGSTATE lpsfs
, DWORD dwMask
);
322 FolderSettings
.fFlags
= 0;
323 FolderSettings
.ViewMode
= 0;
328 ListViewSortInfo
.bIsAscending
= FALSE
;
329 ListViewSortInfo
.nHeaderID
= 0;
330 ListViewSortInfo
.nLastHeaderID
= 0;
337 ptLastMousePos
.x
= 0;
338 ptLastMousePos
.y
= 0;
341 CDefView::~CDefView()
343 TRACE(" destroying IShellView(%p)\n", this);
348 HRESULT WINAPI
CDefView::Initialize(IShellFolder
*shellFolder
)
350 pSFParent
= shellFolder
;
351 shellFolder
->QueryInterface(IID_IShellFolder2
, (LPVOID
*)&pSF2Parent
);
355 /**********************************************************
357 * ##### helperfunctions for communication with ICommDlgBrowser #####
359 HRESULT
CDefView::IncludeObject(LPCITEMIDLIST pidl
)
363 if (pCommDlgBrowser
.p
!= NULL
)
365 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl
);
366 ret
= pCommDlgBrowser
->IncludeObject((IShellView
*)this, pidl
);
367 TRACE("--0x%08x\n", ret
);
372 HRESULT
CDefView::OnDefaultCommand()
374 HRESULT ret
= S_FALSE
;
376 if (pCommDlgBrowser
.p
!= NULL
)
378 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
379 ret
= pCommDlgBrowser
->OnDefaultCommand((IShellView
*)this);
380 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
);
397 /**********************************************************
398 * set the toolbar of the filedialog buttons
400 * - activates the buttons from the shellbrowser according to
403 void CDefView::CheckToolbar()
409 if (pCommDlgBrowser
!= NULL
)
411 pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
412 FCIDM_TB_SMALLICON
, (FolderSettings
.ViewMode
==FVM_LIST
)? TRUE
: FALSE
, &result
);
413 pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_CHECKBUTTON
,
414 FCIDM_TB_REPORTVIEW
, (FolderSettings
.ViewMode
==FVM_DETAILS
)? TRUE
: FALSE
, &result
);
415 pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
416 FCIDM_TB_SMALLICON
, TRUE
, &result
);
417 pShellBrowser
->SendControlMsg(FCW_TOOLBAR
, TB_ENABLEBUTTON
,
418 FCIDM_TB_REPORTVIEW
, TRUE
, &result
);
422 /**********************************************************
424 * ##### helperfunctions for initializing the view #####
426 /**********************************************************
427 * change the style of the listview control
429 void CDefView::SetStyle(DWORD dwAdd
, DWORD dwRemove
)
433 TRACE("(%p)\n", this);
435 tmpstyle
= ::GetWindowLongPtrW(hWndList
, GWL_STYLE
);
436 ::SetWindowLongPtrW(hWndList
, GWL_STYLE
, dwAdd
| (tmpstyle
& ~dwRemove
));
439 /**********************************************************
440 * ShellView_CreateList()
442 * - creates the list view window
444 BOOL
CDefView::CreateList()
445 { DWORD dwStyle
, dwExStyle
;
449 dwStyle
= WS_TABSTOP
| WS_VISIBLE
| WS_CHILDWINDOW
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
|
450 LVS_SHAREIMAGELISTS
| LVS_EDITLABELS
| LVS_ALIGNLEFT
| LVS_AUTOARRANGE
;
451 dwExStyle
= WS_EX_CLIENTEDGE
;
453 switch (FolderSettings
.ViewMode
)
455 case FVM_ICON
: dwStyle
|= LVS_ICON
; break;
456 case FVM_DETAILS
: dwStyle
|= LVS_REPORT
; break;
457 case FVM_SMALLICON
: dwStyle
|= LVS_SMALLICON
; break;
458 case FVM_LIST
: dwStyle
|= LVS_LIST
; break;
459 default: dwStyle
|= LVS_LIST
; break;
462 if (FolderSettings
.fFlags
& FWF_AUTOARRANGE
) dwStyle
|= LVS_AUTOARRANGE
;
463 if (FolderSettings
.fFlags
& FWF_DESKTOP
)
464 FolderSettings
.fFlags
|= FWF_NOCLIENTEDGE
| FWF_NOSCROLL
;
465 if (FolderSettings
.fFlags
& FWF_SINGLESEL
) dwStyle
|= LVS_SINGLESEL
;
466 if (FolderSettings
.fFlags
& FWF_NOCLIENTEDGE
)
467 dwExStyle
&= ~WS_EX_CLIENTEDGE
;
469 hWndList
=CreateWindowExW( dwExStyle
,
482 ListViewSortInfo
.bIsAscending
= TRUE
;
483 ListViewSortInfo
.nHeaderID
= -1;
484 ListViewSortInfo
.nLastHeaderID
= -1;
486 if (FolderSettings
.fFlags
& FWF_DESKTOP
) {
488 * FIXME: look at the registry value
489 * HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ListviewShadow
490 * and activate drop shadows if necessary
493 SendMessageW(hWndList
, LVM_SETTEXTBKCOLOR
, 0, CLR_NONE
);
496 SendMessageW(hWndList
, LVM_SETTEXTBKCOLOR
, 0, GetSysColor(COLOR_DESKTOP
));
497 SendMessageW(hWndList
, LVM_SETBKCOLOR
, 0, GetSysColor(COLOR_DESKTOP
));
500 SendMessageW(hWndList
, LVM_SETTEXTCOLOR
, 0, RGB(255,255,255));
503 /* UpdateShellSettings(); */
507 /**********************************************************
508 * ShellView_InitList()
510 * - adds all needed columns to the shellview
512 BOOL
CDefView::InitList()
521 SendMessageW(hWndList
, LVM_DELETEALLITEMS
, 0, 0);
523 lvColumn
.mask
= LVCF_FMT
| LVCF_WIDTH
| LVCF_TEXT
;
524 lvColumn
.pszText
= szTemp
;
530 if (FAILED(pSF2Parent
->GetDetailsOf(NULL
, i
, &sd
)))
532 lvColumn
.fmt
= sd
.fmt
;
533 lvColumn
.cx
= sd
.cxChar
*8; /* chars->pixel */
534 StrRetToStrNW( szTemp
, 50, &sd
.str
, NULL
);
535 SendMessageW(hWndList
, LVM_INSERTCOLUMNW
, i
, (LPARAM
) &lvColumn
);
543 SendMessageW(hWndList
, LVM_SETIMAGELIST
, LVSIL_SMALL
, (LPARAM
)ShellSmallIconList
);
544 SendMessageW(hWndList
, LVM_SETIMAGELIST
, LVSIL_NORMAL
, (LPARAM
)ShellBigIconList
);
549 /**********************************************************
550 * ShellView_CompareItems()
553 * internal, CALLBACK for DSA_Sort
555 INT CALLBACK
CDefView::CompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
)
558 TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1
, lParam2
, (LPVOID
) lpData
);
560 if(!lpData
) return 0;
562 ret
= (SHORT
)SCODE_CODE(((IShellFolder
*)lpData
)->CompareIDs(0, (LPITEMIDLIST
)lParam1
, (LPITEMIDLIST
)lParam2
));
563 TRACE("ret=%i\n",ret
);
567 /*************************************************************************
568 * ShellView_ListViewCompareItems
570 * Compare Function for the Listview (FileOpen Dialog)
573 * lParam1 [I] the first ItemIdList to compare with
574 * lParam2 [I] the second ItemIdList to compare with
575 * lpData [I] The column ID for the header Ctrl to process
578 * A negative value if the first item should precede the second,
579 * a positive value if the first item should follow the second,
580 * or zero if the two items are equivalent
583 * FIXME: function does what ShellView_CompareItems is supposed to do.
584 * unify it and figure out how to use the undocumented first parameter
585 * of IShellFolder_CompareIDs to do the job this function does and
586 * move this code to IShellFolder.
587 * make LISTVIEW_SORT_INFO obsolete
588 * the way this function works is only usable if we had only
589 * filesystemfolders (25/10/99 jsch)
591 INT CALLBACK
CDefView::ListViewCompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
)
595 char strName1
[MAX_PATH
], strName2
[MAX_PATH
];
596 BOOL bIsFolder1
, bIsFolder2
,bIsBothFolder
;
597 LPITEMIDLIST pItemIdList1
= (LPITEMIDLIST
) lParam1
;
598 LPITEMIDLIST pItemIdList2
= (LPITEMIDLIST
) lParam2
;
599 LISTVIEW_SORT_INFO
*pSortInfo
= (LPLISTVIEW_SORT_INFO
) lpData
;
602 bIsFolder1
= _ILIsFolder(pItemIdList1
);
603 bIsFolder2
= _ILIsFolder(pItemIdList2
);
604 bIsBothFolder
= bIsFolder1
&& bIsFolder2
;
606 /* When sorting between a File and a Folder, the Folder gets sorted first */
607 if( (bIsFolder1
|| bIsFolder2
) && !bIsBothFolder
)
609 nDiff
= bIsFolder1
? -1 : 1;
613 /* Sort by Time: Folders or Files can be sorted */
615 if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_TIME
)
617 _ILGetFileDateTime(pItemIdList1
, &fd1
);
618 _ILGetFileDateTime(pItemIdList2
, &fd2
);
619 nDiff
= CompareFileTime(&fd2
, &fd1
);
621 /* Sort by Attribute: Folder or Files can be sorted */
622 else if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_ATTRIB
)
624 _ILGetFileAttributes(pItemIdList1
, strName1
, MAX_PATH
);
625 _ILGetFileAttributes(pItemIdList2
, strName2
, MAX_PATH
);
626 nDiff
= lstrcmpiA(strName1
, strName2
);
628 /* Sort by FileName: Folder or Files can be sorted */
629 else if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_NAME
|| bIsBothFolder
)
632 _ILSimpleGetText(pItemIdList1
, strName1
, MAX_PATH
);
633 _ILSimpleGetText(pItemIdList2
, strName2
, MAX_PATH
);
634 nDiff
= lstrcmpiA(strName1
, strName2
);
636 /* Sort by File Size, Only valid for Files */
637 else if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_SIZE
)
639 nDiff
= (INT
)(_ILGetFileSize(pItemIdList1
, NULL
, 0) - _ILGetFileSize(pItemIdList2
, NULL
, 0));
641 /* Sort by File Type, Only valid for Files */
642 else if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_TYPE
)
645 _ILGetFileType(pItemIdList1
, strName1
, MAX_PATH
);
646 _ILGetFileType(pItemIdList2
, strName2
, MAX_PATH
);
647 nDiff
= lstrcmpiA(strName1
, strName2
);
650 /* If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
654 _ILSimpleGetText(pItemIdList1
, strName1
, MAX_PATH
);
655 _ILSimpleGetText(pItemIdList2
, strName2
, MAX_PATH
);
656 nDiff
= lstrcmpiA(strName1
, strName2
);
659 if(!pSortInfo
->bIsAscending
)
668 /**********************************************************
669 * LV_FindItemByPidl()
671 int CDefView::LV_FindItemByPidl(LPCITEMIDLIST pidl
)
675 lvItem
.mask
= LVIF_PARAM
;
676 for(lvItem
.iItem
= 0;
677 SendMessageW(hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
680 LPITEMIDLIST currentpidl
= (LPITEMIDLIST
) lvItem
.lParam
;
681 HRESULT hr
= pSFParent
->CompareIDs(0, pidl
, currentpidl
);
682 if(SUCCEEDED(hr
) && !HRESULT_CODE(hr
))
690 /**********************************************************
693 BOOLEAN
CDefView::LV_AddItem(LPCITEMIDLIST pidl
)
697 TRACE("(%p)(pidl=%p)\n", this, pidl
);
699 lvItem
.mask
= LVIF_TEXT
| LVIF_IMAGE
| LVIF_PARAM
; /*set the mask*/
700 lvItem
.iItem
= ListView_GetItemCount(hWndList
); /*add the item to the end of the list*/
702 lvItem
.lParam
= (LPARAM
) ILClone(ILFindLastID(pidl
)); /*set the item's data*/
703 lvItem
.pszText
= LPSTR_TEXTCALLBACKW
; /*get text on a callback basis*/
704 lvItem
.iImage
= I_IMAGECALLBACK
; /*get the image on a callback basis*/
705 if (SendMessageW(hWndList
, LVM_INSERTITEMW
, 0, (LPARAM
)&lvItem
) == -1)
711 /**********************************************************
714 BOOLEAN
CDefView::LV_DeleteItem(LPCITEMIDLIST pidl
)
718 TRACE("(%p)(pidl=%p)\n", this, pidl
);
720 nIndex
= LV_FindItemByPidl(ILFindLastID(pidl
));
721 return (-1 == ListView_DeleteItem(hWndList
, nIndex
)) ? FALSE
: TRUE
;
724 /**********************************************************
727 BOOLEAN
CDefView::LV_RenameItem(LPCITEMIDLIST pidlOld
, LPCITEMIDLIST pidlNew
)
732 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", this, pidlOld
, pidlNew
);
734 nItem
= LV_FindItemByPidl(ILFindLastID(pidlOld
));
737 lvItem
.mask
= LVIF_PARAM
; /* only the pidl */
738 lvItem
.iItem
= nItem
;
739 SendMessageW(hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
741 SHFree((LPITEMIDLIST
)lvItem
.lParam
);
742 lvItem
.mask
= LVIF_PARAM
;
743 lvItem
.iItem
= nItem
;
744 lvItem
.lParam
= (LPARAM
) ILClone(ILFindLastID(pidlNew
)); /* set the item's data */
745 SendMessageW(hWndList
, LVM_SETITEMW
, 0, (LPARAM
) &lvItem
);
746 SendMessageW(hWndList
, LVM_UPDATE
, nItem
, 0);
747 return TRUE
; /* FIXME: better handling */
752 /**********************************************************
753 * ShellView_FillList()
755 * - gets the objectlist from the shellfolder
757 * - fills the list into the view
759 INT CALLBACK
CDefView::fill_list( LPVOID ptr
, LPVOID arg
)
761 LPITEMIDLIST pidl
= (LPITEMIDLIST
)ptr
;
762 CDefView
*pThis
= (CDefView
*)arg
;
763 /* in a commdlg This works as a filemask*/
764 if ( pThis
->IncludeObject(pidl
)==S_OK
) pThis
->LV_AddItem(pidl
);
769 HRESULT
CDefView::FillList()
771 LPENUMIDLIST pEnumIDList
;
779 /* get the itemlist from the shfolder*/
780 hRes
= pSFParent
->EnumObjects(m_hWnd
, SHCONTF_NONFOLDERS
| SHCONTF_FOLDERS
, &pEnumIDList
);
788 /* create a pointer array */
789 hdpa
= DPA_Create(16);
792 return(E_OUTOFMEMORY
);
795 /* copy the items into the array*/
796 while((S_OK
== pEnumIDList
->Next(1, &pidl
, &dwFetched
)) && dwFetched
)
798 if (DPA_InsertPtr(hdpa
, 0x7fff, pidl
) == -1)
805 DPA_Sort(hdpa
, CompareItems
, (LPARAM
)pSFParent
.p
);
807 /*turn the listview's redrawing off*/
808 SendMessageA(hWndList
, WM_SETREDRAW
, FALSE
, 0);
810 DPA_DestroyCallback( hdpa
, fill_list
, (void *)this);
812 /*turn the listview's redrawing back on and force it to draw*/
813 SendMessageA(hWndList
, WM_SETREDRAW
, TRUE
, 0);
815 pEnumIDList
->Release(); /* destroy the list*/
820 LRESULT
CDefView::OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
822 ::UpdateWindow(hWndList
);
827 LRESULT
CDefView::OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
829 return SendMessageW(hWndList
, uMsg
, 0, 0);
832 LRESULT
CDefView::OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
834 RevokeDragDrop(m_hWnd
);
835 SHChangeNotifyDeregister(hNotify
);
840 LRESULT
CDefView::OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
842 if (FolderSettings
.fFlags
& (FWF_DESKTOP
| FWF_TRANSPARENT
))
848 LRESULT
CDefView::OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
850 return (LRESULT
)pShellBrowser
.p
;
853 /**********************************************************
854 * ShellView_OnCreate()
856 LRESULT
CDefView::OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
858 CComPtr
<IDropTarget
> pdt
;
859 SHChangeNotifyEntry ntreg
;
860 CComPtr
<IPersistFolder2
> ppf2
;
872 if (SUCCEEDED(this->QueryInterface(IID_IDropTarget
, (LPVOID
*)&pdt
)))
873 RegisterDragDrop(m_hWnd
, pdt
);
875 /* register for receiving notifications */
876 pSFParent
->QueryInterface(IID_IPersistFolder2
, (LPVOID
*)&ppf2
);
879 ppf2
->GetCurFolder((LPITEMIDLIST
*)&ntreg
.pidl
);
880 ntreg
.fRecursive
= TRUE
;
881 hNotify
= SHChangeNotifyRegister(m_hWnd
, SHCNF_IDLIST
, SHCNE_ALLEVENTS
, SHV_CHANGE_NOTIFY
, 1, &ntreg
);
882 SHFree((LPITEMIDLIST
)ntreg
.pidl
);
885 hAccel
= LoadAcceleratorsA(shell32_hInstance
, "shv_accel");
890 /**********************************************************
891 * #### Handling of the menus ####
894 /**********************************************************
895 * ShellView_BuildFileMenu()
897 HMENU
CDefView::BuildFileMenu()
898 { WCHAR szText
[MAX_PATH
];
903 TRACE("(%p)\n",this);
905 hSubMenu
= CreatePopupMenu();
907 { /*get the number of items in our global array*/
908 for(nTools
= 0; Tools
[nTools
].idCommand
!= -1; nTools
++){}
910 /*add the menu items*/
911 for(i
= 0; i
< nTools
; i
++)
913 LoadStringW(shell32_hInstance
, Tools
[i
].idMenuString
, szText
, MAX_PATH
);
915 ZeroMemory(&mii
, sizeof(mii
));
916 mii
.cbSize
= sizeof(mii
);
917 mii
.fMask
= MIIM_TYPE
| MIIM_ID
| MIIM_STATE
;
919 if(BTNS_SEP
!= Tools
[i
].bStyle
) /* no separator*/
921 mii
.fType
= MFT_STRING
;
922 mii
.fState
= MFS_ENABLED
;
923 mii
.dwTypeData
= szText
;
924 mii
.wID
= Tools
[i
].idCommand
;
928 mii
.fType
= MFT_SEPARATOR
;
930 /* tack This item onto the end of the menu */
931 InsertMenuItemW(hSubMenu
, (UINT
)-1, TRUE
, &mii
);
934 TRACE("-- return (menu=%p)\n",hSubMenu
);
938 /**********************************************************
939 * ShellView_MergeFileMenu()
941 void CDefView::MergeFileMenu(HMENU hSubMenu
)
942 { TRACE("(%p)->(submenu=%p) stub\n",this,hSubMenu
);
945 { /*insert This item at the beginning of the menu */
946 _InsertMenuItemW(hSubMenu
, 0, TRUE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
947 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
, MFT_STRING
, L
"dummy45", MFS_ENABLED
);
953 /**********************************************************
954 * ShellView_MergeViewMenu()
956 void CDefView::MergeViewMenu(HMENU hSubMenu
)
958 TRACE("(%p)->(submenu=%p)\n",this,hSubMenu
);
961 { /*add a separator at the correct position in the menu*/
963 static WCHAR view
[] = L
"View";
965 _InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
967 ZeroMemory(&mii
, sizeof(mii
));
968 mii
.cbSize
= sizeof(mii
);
969 mii
.fMask
= MIIM_SUBMENU
| MIIM_TYPE
| MIIM_DATA
;
970 mii
.fType
= MFT_STRING
;
971 mii
.dwTypeData
= view
;
972 mii
.hSubMenu
= LoadMenuW(shell32_hInstance
, L
"MENU_001");
973 InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, &mii
);
977 /**********************************************************
978 * ShellView_GetSelections()
980 * - fills the this->apidl list with the selected objects
983 * number of selected items
985 UINT
CDefView::GetSelections()
992 cidl
= ListView_GetSelectedCount(hWndList
);
993 apidl
= (LPITEMIDLIST
*)SHAlloc(cidl
* sizeof(LPITEMIDLIST
));
995 TRACE("selected=%i\n", cidl
);
999 TRACE("-- Items selected =%u\n", cidl
);
1001 lvItem
.mask
= LVIF_STATE
| LVIF_PARAM
;
1002 lvItem
.stateMask
= LVIS_SELECTED
;
1004 lvItem
.iSubItem
= 0;
1006 while(SendMessageW(hWndList
, LVM_GETITEMW
, 0, (LPARAM
)&lvItem
) && (i
< cidl
))
1008 if(lvItem
.state
& LVIS_SELECTED
)
1010 apidl
[i
] = (LPITEMIDLIST
)lvItem
.lParam
;
1014 TRACE("-- selected Item found\n");
1023 /**********************************************************
1024 * ShellView_OpenSelectedItems()
1026 HRESULT
CDefView::OpenSelectedItems()
1028 static UINT CF_IDLIST
= 0;
1030 CComPtr
<IDataObject
> selection
;
1031 CComPtr
<IContextMenu
> cm
;
1036 LPCITEMIDLIST parent_pidl
;
1037 WCHAR parent_path
[MAX_PATH
];
1038 LPCWSTR parent_dir
= NULL
;
1041 CMINVOKECOMMANDINFOEX ici
;
1044 if (0 == GetSelections())
1049 hr
= pSFParent
->GetUIObjectOf(m_hWnd
, cidl
,
1050 (LPCITEMIDLIST
*)apidl
, IID_IContextMenu
,
1055 hmenu
= CreatePopupMenu();
1058 hr
= IUnknown_SetSite(cm
, (IShellView
*)this);
1059 if (SUCCEEDED(cm
->QueryContextMenu(hmenu
, 0, 0x20, 0x7fff, CMF_DEFAULTONLY
)))
1061 INT def
= -1, n
= GetMenuItemCount(hmenu
);
1063 for ( i
= 0; i
< n
; i
++ )
1065 memset( &info
, 0, sizeof info
);
1066 info
.cbSize
= sizeof info
;
1067 info
.fMask
= MIIM_FTYPE
| MIIM_STATE
| MIIM_ID
;
1068 if (GetMenuItemInfoW( hmenu
, i
, TRUE
, &info
))
1070 if (info
.fState
& MFS_DEFAULT
)
1079 memset( &ici
, 0, sizeof ici
);
1080 ici
.cbSize
= sizeof ici
;
1081 ici
.lpVerb
= MAKEINTRESOURCEA( def
);
1084 if (cm
->InvokeCommand((LPCMINVOKECOMMANDINFO
) &ici
) == S_OK
)
1086 DestroyMenu( hmenu
);
1087 hr
= IUnknown_SetSite(cm
, NULL
);
1093 DestroyMenu( hmenu
);
1094 hr
= IUnknown_SetSite(cm
, NULL
);
1101 hr
= pSFParent
->GetUIObjectOf(m_hWnd
, cidl
,
1102 (LPCITEMIDLIST
*)apidl
, IID_IDataObject
,
1103 0, (LPVOID
*)&selection
);
1112 CF_IDLIST
= RegisterClipboardFormatW(CFSTR_SHELLIDLIST
);
1114 fetc
.cfFormat
= CF_IDLIST
;
1116 fetc
.dwAspect
= DVASPECT_CONTENT
;
1118 fetc
.tymed
= TYMED_HGLOBAL
;
1120 hr
= selection
->QueryGetData(&fetc
);
1124 hr
= selection
->GetData(&fetc
, &stgm
);
1128 pIDList
= (LPIDA
)GlobalLock(stgm
.hGlobal
);
1130 parent_pidl
= (LPCITEMIDLIST
) ((LPBYTE
)pIDList
+pIDList
->aoffset
[0]);
1131 hr
= pSFParent
->GetAttributesOf(1, &parent_pidl
, &attribs
);
1132 if (SUCCEEDED(hr
) && (attribs
& SFGAO_FILESYSTEM
) &&
1133 SHGetPathFromIDListW(parent_pidl
, parent_path
))
1135 parent_dir
= parent_path
;
1138 for (i
= pIDList
->cidl
; i
> 0; --i
)
1142 pidl
= (LPCITEMIDLIST
)((LPBYTE
)pIDList
+pIDList
->aoffset
[i
]);
1144 attribs
= SFGAO_FOLDER
;
1145 hr
= pSFParent
->GetAttributesOf(1, &pidl
, &attribs
);
1147 if (SUCCEEDED(hr
) && ! (attribs
& SFGAO_FOLDER
))
1149 SHELLEXECUTEINFOW shexinfo
;
1151 shexinfo
.cbSize
= sizeof(SHELLEXECUTEINFOW
);
1152 shexinfo
.fMask
= SEE_MASK_INVOKEIDLIST
; /* SEE_MASK_IDLIST is also possible. */
1153 shexinfo
.hwnd
= NULL
;
1154 shexinfo
.lpVerb
= NULL
;
1155 shexinfo
.lpFile
= NULL
;
1156 shexinfo
.lpParameters
= NULL
;
1157 shexinfo
.lpDirectory
= parent_dir
;
1158 shexinfo
.nShow
= SW_NORMAL
;
1159 shexinfo
.lpIDList
= ILCombine(parent_pidl
, pidl
);
1161 ShellExecuteExW(&shexinfo
); /* Discard error/success info */
1163 ILFree((LPITEMIDLIST
)shexinfo
.lpIDList
);
1167 GlobalUnlock(stgm
.hGlobal
);
1168 ReleaseStgMedium(&stgm
);
1173 /**********************************************************
1174 * ShellView_DoContextMenu()
1176 LRESULT
CDefView::OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1186 CMINVOKECOMMANDINFO cmi
;
1189 // for some reason I haven't figured out, we sometimes recurse into this method
1197 TRACE("(%p)->(0x%08x 0x%08x 0x%08x) stub\n",this, x
, y
, bDefault
);
1202 /* look, what's selected and create a context menu object of it*/
1203 if (GetSelections())
1205 pSFParent
->GetUIObjectOf(hWndParent
, cidl
, (LPCITEMIDLIST
*)apidl
, IID_IContextMenu
, NULL
, (LPVOID
*)&pCM
);
1209 TRACE("-- pContextMenu\n");
1210 hMenu
= CreatePopupMenu();
1214 hResult
= IUnknown_SetSite(pCM
, (IShellView
*)this);
1215 /* See if we are in Explore or Open mode. If the browser's tree is present, we are in Explore mode.*/
1216 if(SUCCEEDED(pShellBrowser
->GetControlWindow(FCW_TREE
, &hwndTree
)) && hwndTree
)
1218 TRACE("-- explore mode\n");
1222 /* build the flags depending on what we can do with the selected item */
1223 wFlags
= CMF_NORMAL
| (cidl
!= 1 ? 0 : CMF_CANRENAME
) | (fExplore
? CMF_EXPLORE
: 0);
1225 /* let the ContextMenu merge its items in */
1226 if (SUCCEEDED(pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, wFlags
)))
1228 if (FolderSettings
.fFlags
& FWF_DESKTOP
)
1229 SetMenuDefaultItem(hMenu
, FCIDM_SHVIEW_OPEN
, MF_BYCOMMAND
);
1233 TRACE("-- get menu default command\n");
1234 uCommand
= GetMenuDefaultItem(hMenu
, FALSE
, GMDI_GOINTOPOPUPS
);
1238 TRACE("-- track popup\n");
1239 uCommand
= TrackPopupMenu( hMenu
,TPM_LEFTALIGN
| TPM_RETURNCMD
,x
,y
,0,m_hWnd
,NULL
);
1244 TRACE("-- uCommand=%u\n", uCommand
);
1245 if (uCommand
==FCIDM_SHVIEW_OPEN
&& pCommDlgBrowser
.p
!= NULL
)
1247 TRACE("-- dlg: OnDefaultCommand\n");
1248 if (OnDefaultCommand() != S_OK
)
1250 OpenSelectedItems();
1255 TRACE("-- explore -- invoke command\n");
1256 ZeroMemory(&cmi
, sizeof(cmi
));
1257 cmi
.cbSize
= sizeof(cmi
);
1258 cmi
.hwnd
= hWndParent
; /* this window has to answer CWM_GETISHELLBROWSER */
1259 cmi
.lpVerb
= (LPCSTR
)MAKEINTRESOURCEA(uCommand
);
1260 pCM
->InvokeCommand(&cmi
);
1263 hResult
= IUnknown_SetSite(pCM
, NULL
);
1270 else /* background context menu */
1272 hMenu
= CreatePopupMenu();
1274 CDefFolderMenu_Create2(NULL
, NULL
, cidl
, (LPCITEMIDLIST
*)apidl
, pSFParent
, NULL
, 0, NULL
, (IContextMenu
**)&pCM
);
1275 pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, 0);
1277 uCommand
= TrackPopupMenu( hMenu
, TPM_LEFTALIGN
| TPM_RETURNCMD
,x
,y
,0,m_hWnd
,NULL
);
1280 TRACE("-- (%p)->(uCommand=0x%08x )\n",this, uCommand
);
1282 ZeroMemory(&cmi
, sizeof(cmi
));
1283 cmi
.cbSize
= sizeof(cmi
);
1284 cmi
.lpVerb
= (LPCSTR
)MAKEINTRESOURCEA(uCommand
);
1285 cmi
.hwnd
= hWndParent
;
1286 pCM
->InvokeCommand(&cmi
);
1293 /**********************************************************
1294 * ##### message handling #####
1297 /**********************************************************
1298 * ShellView_OnSize()
1300 LRESULT
CDefView::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1305 wWidth
= LOWORD(lParam
);
1306 wHeight
= HIWORD(lParam
);
1308 TRACE("%p width=%u height=%u\n", this, wWidth
, wHeight
);
1310 /*resize the ListView to fit our window*/
1313 ::MoveWindow(hWndList
, 0, 0, wWidth
, wHeight
, TRUE
);
1319 /**********************************************************
1320 * ShellView_OnDeactivate()
1325 void CDefView::OnDeactivate()
1329 if(uState
!= SVUIA_DEACTIVATE
)
1333 pShellBrowser
->SetMenuSB(0, 0, 0);
1334 pShellBrowser
->RemoveMenusSB(hMenu
);
1339 uState
= SVUIA_DEACTIVATE
;
1343 void CDefView::DoActivate(UINT uState
)
1345 OLEMENUGROUPWIDTHS omw
= { {0, 0, 0, 0, 0, 0} };
1347 CHAR szText
[MAX_PATH
];
1349 TRACE("%p uState=%x\n", this, uState
);
1351 /*don't do anything if the state isn't really changing */
1352 if(uState
== uState
)
1359 /*only do This if we are active */
1360 if(uState
!= SVUIA_DEACTIVATE
)
1362 /*merge the menus */
1363 hMenu
= CreateMenu();
1367 pShellBrowser
->InsertMenusSB(hMenu
, &omw
);
1368 TRACE("-- after fnInsertMenusSB\n");
1370 /*build the top level menu get the menu item's text*/
1371 strcpy(szText
,"dummy 31");
1373 ZeroMemory(&mii
, sizeof(mii
));
1374 mii
.cbSize
= sizeof(mii
);
1375 mii
.fMask
= MIIM_SUBMENU
| MIIM_TYPE
| MIIM_STATE
;
1376 mii
.fType
= MFT_STRING
;
1377 mii
.fState
= MFS_ENABLED
;
1378 mii
.dwTypeData
= szText
;
1379 mii
.hSubMenu
= BuildFileMenu();
1381 /*insert our menu into the menu bar*/
1384 InsertMenuItemA(hMenu
, FCIDM_MENU_HELP
, FALSE
, &mii
);
1387 /*get the view menu so we can merge with it*/
1388 ZeroMemory(&mii
, sizeof(mii
));
1389 mii
.cbSize
= sizeof(mii
);
1390 mii
.fMask
= MIIM_SUBMENU
;
1392 if(GetMenuItemInfoA(hMenu
, FCIDM_MENU_VIEW
, FALSE
, &mii
))
1394 MergeViewMenu(mii
.hSubMenu
);
1397 /*add the items that should only be added if we have the focus*/
1398 if(SVUIA_ACTIVATE_FOCUS
== uState
)
1400 /*get the file menu so we can merge with it */
1401 ZeroMemory(&mii
, sizeof(mii
));
1402 mii
.cbSize
= sizeof(mii
);
1403 mii
.fMask
= MIIM_SUBMENU
;
1405 if(GetMenuItemInfoA(hMenu
, FCIDM_MENU_FILE
, FALSE
, &mii
))
1407 MergeFileMenu(mii
.hSubMenu
);
1410 TRACE("-- before fnSetMenuSB\n");
1411 pShellBrowser
->SetMenuSB(hMenu
, 0, m_hWnd
);
1418 /**********************************************************
1419 * ShellView_OnActivate()
1421 LRESULT
CDefView::OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1423 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1427 /**********************************************************
1428 * ShellView_OnSetFocus()
1431 LRESULT
CDefView::OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1433 TRACE("%p\n", this);
1435 /* Tell the browser one of our windows has received the focus. This
1436 should always be done before merging menus (OnActivate merges the
1437 menus) if one of our windows has the focus.*/
1439 pShellBrowser
->OnViewWindowActive((IShellView
*)this);
1440 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1442 /* Set the focus to the listview */
1443 ::SetFocus(hWndList
);
1445 /* Notify the ICommDlgBrowser interface */
1446 OnStateChange(CDBOSC_SETFOCUS
);
1451 /**********************************************************
1452 * ShellView_OnKillFocus()
1454 LRESULT
CDefView::OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1456 TRACE("(%p) stub\n", this);
1458 DoActivate(SVUIA_ACTIVATE_NOFOCUS
);
1459 /* Notify the ICommDlgBrowser */
1460 OnStateChange(CDBOSC_KILLFOCUS
);
1465 /**********************************************************
1466 * ShellView_OnCommand()
1469 * the CmdID's are the ones from the context menu
1471 LRESULT
CDefView::OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1477 dwCmdID
= GET_WM_COMMAND_ID(wParam
, lParam
);
1478 dwCmd
= GET_WM_COMMAND_CMD(wParam
, lParam
);
1479 hwndCmd
= GET_WM_COMMAND_HWND(wParam
, lParam
);
1481 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n",this, dwCmdID
, dwCmd
, hwndCmd
);
1485 case FCIDM_SHVIEW_SMALLICON
:
1486 FolderSettings
.ViewMode
= FVM_SMALLICON
;
1487 SetStyle (LVS_SMALLICON
, LVS_TYPEMASK
);
1491 case FCIDM_SHVIEW_BIGICON
:
1492 FolderSettings
.ViewMode
= FVM_ICON
;
1493 SetStyle (LVS_ICON
, LVS_TYPEMASK
);
1497 case FCIDM_SHVIEW_LISTVIEW
:
1498 FolderSettings
.ViewMode
= FVM_LIST
;
1499 SetStyle (LVS_LIST
, LVS_TYPEMASK
);
1503 case FCIDM_SHVIEW_REPORTVIEW
:
1504 FolderSettings
.ViewMode
= FVM_DETAILS
;
1505 SetStyle (LVS_REPORT
, LVS_TYPEMASK
);
1509 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1514 ListViewSortInfo
.nHeaderID
= (LPARAM
) (dwCmdID
- 0x30);
1515 ListViewSortInfo
.bIsAscending
= TRUE
;
1516 ListViewSortInfo
.nLastHeaderID
= ListViewSortInfo
.nHeaderID
;
1517 SendMessageA(hWndList
, LVM_SORTITEMS
, (WPARAM
) &ListViewSortInfo
, (LPARAM
)ListViewCompareItems
);
1521 TRACE("-- COMMAND 0x%04x unhandled\n", dwCmdID
);
1526 /**********************************************************
1527 * ShellView_OnNotify()
1530 LRESULT
CDefView::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1534 LPNMLISTVIEW lpnmlv
;
1535 NMLVDISPINFOW
*lpdi
;
1540 lpnmh
= (LPNMHDR
)lParam
;
1541 lpnmlv
= (LPNMLISTVIEW
)lpnmh
;
1542 lpdi
= (NMLVDISPINFOW
*)lpnmh
;
1544 TRACE("%p CtlID=%u lpnmh->code=%x\n",this,CtlID
,lpnmh
->code
);
1549 TRACE("-- NM_SETFOCUS %p\n", this);
1550 OnSetFocus(0, 0, 0, unused
);
1554 TRACE("-- NM_KILLFOCUS %p\n", this);
1556 /* Notify the ICommDlgBrowser interface */
1557 OnStateChange(CDBOSC_KILLFOCUS
);
1561 TRACE("-- NM_CUSTOMDRAW %p\n", this);
1562 return CDRF_DODEFAULT
;
1564 case NM_RELEASEDCAPTURE
:
1565 TRACE("-- NM_RELEASEDCAPTURE %p\n", this);
1569 TRACE("-- NM_CLICK %p\n", this);
1573 TRACE("-- NM_RCLICK %p\n", this);
1577 TRACE("-- NM_DBLCLK %p\n", this);
1578 if (OnDefaultCommand() != S_OK
) OpenSelectedItems();
1582 TRACE("-- NM_RETURN %p\n", this);
1583 if (OnDefaultCommand() != S_OK
) OpenSelectedItems();
1587 TRACE("-- HDN_ENDTRACKW %p\n", this);
1588 /*nColumn1 = ListView_GetColumnWidth(hWndList, 0);
1589 nColumn2 = ListView_GetColumnWidth(hWndList, 1);*/
1592 case LVN_DELETEITEM
:
1593 TRACE("-- LVN_DELETEITEM %p\n", this);
1594 SHFree((LPITEMIDLIST
)lpnmlv
->lParam
); /*delete the pidl because we made a copy of it*/
1597 case LVN_DELETEALLITEMS
:
1598 TRACE("-- LVN_DELETEALLITEMS %p\n", this);
1601 case LVN_INSERTITEM
:
1602 TRACE("-- LVN_INSERTITEM (STUB)%p\n", this);
1605 case LVN_ITEMACTIVATE
:
1606 TRACE("-- LVN_ITEMACTIVATE %p\n", this);
1607 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1610 case LVN_COLUMNCLICK
:
1611 ListViewSortInfo
.nHeaderID
= lpnmlv
->iSubItem
;
1612 if(ListViewSortInfo
.nLastHeaderID
== ListViewSortInfo
.nHeaderID
)
1614 ListViewSortInfo
.bIsAscending
= !ListViewSortInfo
.bIsAscending
;
1618 ListViewSortInfo
.bIsAscending
= TRUE
;
1620 ListViewSortInfo
.nLastHeaderID
= ListViewSortInfo
.nHeaderID
;
1622 SendMessageW(lpnmlv
->hdr
.hwndFrom
, LVM_SORTITEMS
, (WPARAM
) &ListViewSortInfo
, (LPARAM
)ListViewCompareItems
);
1625 case LVN_GETDISPINFOA
:
1626 case LVN_GETDISPINFOW
:
1627 TRACE("-- LVN_GETDISPINFO %p\n", this);
1628 pidl
= (LPITEMIDLIST
)lpdi
->item
.lParam
;
1630 if(lpdi
->item
.mask
& LVIF_TEXT
) /* text requested */
1635 pSF2Parent
->GetDetailsOf(pidl
, lpdi
->item
.iSubItem
, &sd
);
1636 if (lpnmh
->code
== LVN_GETDISPINFOA
)
1638 /* shouldn't happen */
1639 NMLVDISPINFOA
*lpdiA
= (NMLVDISPINFOA
*)lpnmh
;
1640 StrRetToStrNA( lpdiA
->item
.pszText
, lpdiA
->item
.cchTextMax
, &sd
.str
, NULL
);
1641 TRACE("-- text=%s\n",lpdiA
->item
.pszText
);
1643 else /* LVN_GETDISPINFOW */
1645 StrRetToStrNW( lpdi
->item
.pszText
, lpdi
->item
.cchTextMax
, &sd
.str
, NULL
);
1646 TRACE("-- text=%s\n",debugstr_w(lpdi
->item
.pszText
));
1654 if(lpdi
->item
.mask
& LVIF_IMAGE
) /* image requested */
1656 lpdi
->item
.iImage
= SHMapPIDLToSystemImageListIndex(pSFParent
, pidl
, 0);
1658 lpdi
->item
.mask
|= LVIF_DI_SETITEM
;
1661 case LVN_ITEMCHANGED
:
1662 TRACE("-- LVN_ITEMCHANGED %p\n", this);
1663 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1667 case LVN_BEGINRDRAG
:
1668 TRACE("-- LVN_BEGINDRAG\n");
1670 if (GetSelections())
1673 DWORD dwAttributes
= SFGAO_CANLINK
;
1674 DWORD dwEffect
= DROPEFFECT_COPY
| DROPEFFECT_MOVE
;
1676 if (SUCCEEDED(pSFParent
->GetUIObjectOf(m_hWnd
, cidl
, (LPCITEMIDLIST
*)apidl
, IID_IDataObject
,0,(LPVOID
*)&pda
)))
1678 IDropSource
* pds
= (IDropSource
*)this; /* own DropSource interface */
1680 if (SUCCEEDED(pSFParent
->GetAttributesOf(cidl
, (LPCITEMIDLIST
*)apidl
, &dwAttributes
)))
1682 if (dwAttributes
& SFGAO_CANLINK
)
1684 dwEffect
|= DROPEFFECT_LINK
;
1691 DoDragDrop(pda
, pds
, dwEffect
, &dwEffect2
);
1698 case LVN_BEGINLABELEDITW
:
1700 DWORD dwAttr
= SFGAO_CANRENAME
;
1701 pidl
= (LPITEMIDLIST
)lpdi
->item
.lParam
;
1703 TRACE("-- LVN_BEGINLABELEDITW %p\n", this);
1705 pSFParent
->GetAttributesOf(1, (LPCITEMIDLIST
*)&pidl
, &dwAttr
);
1706 if (SFGAO_CANRENAME
& dwAttr
)
1713 case LVN_ENDLABELEDITW
:
1715 TRACE("-- LVN_ENDLABELEDITA %p\n", this);
1716 if (lpdi
->item
.pszText
)
1721 lvItem
.iItem
= lpdi
->item
.iItem
;
1722 lvItem
.iSubItem
= 0;
1723 lvItem
.mask
= LVIF_PARAM
;
1724 SendMessageW(hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
1726 pidl
= (LPITEMIDLIST
)lpdi
->item
.lParam
;
1727 hr
= pSFParent
->SetNameOf(0, pidl
, lpdi
->item
.pszText
, SHGDN_INFOLDER
, &pidl
);
1729 if(SUCCEEDED(hr
) && pidl
)
1731 lvItem
.mask
= LVIF_PARAM
;
1732 lvItem
.lParam
= (LPARAM
)pidl
;
1733 SendMessageW(hWndList
, LVM_SETITEMW
, 0, (LPARAM
) &lvItem
);
1744 msg.message = WM_KEYDOWN;
1745 msg.wParam = plvKeyDown->wVKey;
1750 LPNMLVKEYDOWN plvKeyDown
= (LPNMLVKEYDOWN
) lpnmh
;
1751 SHORT ctrl
= GetKeyState(VK_CONTROL
) & 0x8000;
1753 /* initiate a rename of the selected file or directory */
1754 if(plvKeyDown
->wVKey
== VK_F2
)
1756 /* see how many files are selected */
1757 int i
= ListView_GetSelectedCount(hWndList
);
1759 /* get selected item */
1762 /* get selected item */
1763 i
= ListView_GetNextItem(hWndList
, -1,
1766 SendMessageW(hWndList
, LVM_ENSUREVISIBLE
, i
, 0);
1767 SendMessageW(hWndList
, LVM_EDITLABELW
, i
, 0);
1771 TranslateAccelerator(m_hWnd
, hAccel
, &msg
)
1773 else if(plvKeyDown
->wVKey
== VK_DELETE
)
1778 LPITEMIDLIST
* pItems
;
1781 pSFParent
->QueryInterface(IID_ISFHelper
,
1787 if(!(i
= ListView_GetSelectedCount(hWndList
)))
1790 /* allocate memory for the pidl array */
1791 pItems
= (LPITEMIDLIST
*)HeapAlloc(GetProcessHeap(), 0,
1792 sizeof(LPITEMIDLIST
) * i
);
1794 /* retrieve all selected items */
1797 while(ListView_GetSelectedCount(hWndList
) > i
)
1799 /* get selected item */
1800 item_index
= ListView_GetNextItem(hWndList
,
1801 item_index
, LVNI_SELECTED
);
1802 item
.iItem
= item_index
;
1803 item
.mask
= LVIF_PARAM
;
1804 SendMessageA(hWndList
, LVM_GETITEMA
, 0, (LPARAM
) &item
);
1807 pItems
[i
] = (LPITEMIDLIST
)item
.lParam
;
1812 /* perform the item deletion */
1813 psfhlp
->DeleteItems(i
, (LPCITEMIDLIST
*)pItems
);
1815 /* free pidl array memory */
1816 HeapFree(GetProcessHeap(), 0, pItems
);
1819 /* Initiate a refresh */
1820 else if(plvKeyDown
->wVKey
== VK_F5
)
1824 else if(plvKeyDown
->wVKey
== VK_BACK
)
1826 LPSHELLBROWSER lpSb
;
1827 if((lpSb
= (LPSHELLBROWSER
)SendMessageW(hWndParent
, CWM_GETISHELLBROWSER
, 0, 0)))
1829 lpSb
->BrowseObject(NULL
, SBSP_PARENT
);
1832 else if(plvKeyDown
->wVKey
== 'C' && ctrl
)
1834 if (GetSelections())
1836 CComPtr
<IDataObject
> pda
;
1838 if (SUCCEEDED(pSFParent
->GetUIObjectOf(m_hWnd
, cidl
, (LPCITEMIDLIST
*)apidl
, IID_IDataObject
, 0, (LPVOID
*)&pda
)))
1840 HRESULT hr
= OleSetClipboard(pda
);
1843 WARN("OleSetClipboard failed");
1849 else if(plvKeyDown
->wVKey
== 'V' && ctrl
)
1851 CComPtr
<IDataObject
> pda
;
1853 FORMATETC formatetc
;
1854 LPITEMIDLIST
* apidl
;
1856 CComPtr
<IShellFolder
> psfFrom
;
1857 CComPtr
<IShellFolder
> psfDesktop
;
1858 CComPtr
<IShellFolder
> psfTarget
;
1860 CComPtr
<ISFHelper
> psfhlpdst
;
1861 CComPtr
<ISFHelper
> psfhlpsrc
;
1864 hr
= OleGetClipboard(&pda
);
1867 ERR("Failed to get clipboard with %lx\n", hr
);
1871 InitFormatEtc(formatetc
, RegisterClipboardFormatW(CFSTR_SHELLIDLIST
), TYMED_HGLOBAL
);
1872 hr
= pda
->GetData(&formatetc
, &medium
);
1876 ERR("Failed to get clipboard data with %lx\n", hr
);
1880 /* lock the handle */
1881 lpcida
= (LPIDA
)GlobalLock(medium
.hGlobal
);
1884 ERR("failed to lock pidl\n");
1885 ReleaseStgMedium(&medium
);
1889 /* convert the data into pidl */
1890 apidl
= _ILCopyCidaToaPidl(&pidl
, lpcida
);
1894 ERR("failed to copy pidl\n");
1898 if (FAILED(SHGetDesktopFolder(&psfDesktop
)))
1900 ERR("failed to get desktop folder\n");
1902 _ILFreeaPidl(apidl
, lpcida
->cidl
);
1903 ReleaseStgMedium(&medium
);
1907 if (_ILIsDesktop(pidl
))
1909 /* use desktop shellfolder */
1910 psfFrom
= psfDesktop
;
1912 else if (FAILED(psfDesktop
->BindToObject(pidl
, NULL
, IID_IShellFolder
, (LPVOID
*)&psfFrom
)))
1914 ERR("no IShellFolder\n");
1917 _ILFreeaPidl(apidl
, lpcida
->cidl
);
1918 ReleaseStgMedium(&medium
);
1923 psfTarget
= pSFParent
;
1926 /* get source and destination shellfolder */
1927 if (FAILED(psfTarget
->QueryInterface(IID_ISFHelper
, (LPVOID
*)&psfhlpdst
)))
1929 ERR("no IID_ISFHelper for destination\n");
1932 _ILFreeaPidl(apidl
, lpcida
->cidl
);
1933 ReleaseStgMedium(&medium
);
1938 if (FAILED(psfFrom
->QueryInterface(IID_ISFHelper
, (LPVOID
*)&psfhlpsrc
)))
1940 ERR("no IID_ISFHelper for source\n");
1943 _ILFreeaPidl(apidl
, lpcida
->cidl
);
1944 ReleaseStgMedium(&medium
);
1949 * do we want to perform a copy or move ???
1951 hr
= psfhlpdst
->CopyItems(psfFrom
, lpcida
->cidl
, (LPCITEMIDLIST
*)apidl
);
1954 _ILFreeaPidl(apidl
, lpcida
->cidl
);
1955 ReleaseStgMedium(&medium
);
1957 TRACE("paste end hr %x\n", hr
);
1961 FIXME("LVN_KEYDOWN key=0x%08x\n",plvKeyDown
->wVKey
);
1966 TRACE("-- %p WM_COMMAND %x unhandled\n", this, lpnmh
->code
);
1972 /**********************************************************
1973 * ShellView_OnChange()
1975 LRESULT
CDefView::OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1977 LPITEMIDLIST
*Pidls
;
1979 Pidls
= (LPITEMIDLIST
*)wParam
;
1981 TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls
[0], Pidls
[1], lParam
);
1987 LV_AddItem(Pidls
[0]);
1991 LV_DeleteItem(Pidls
[0]);
1993 case SHCNE_RENAMEFOLDER
:
1994 case SHCNE_RENAMEITEM
:
1995 LV_RenameItem(Pidls
[0], Pidls
[1]);
1997 case SHCNE_UPDATEITEM
:
2003 /**********************************************************
2004 * ShellView_DoMeasureItem
2006 LRESULT
CDefView::OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
2011 ERR("no menu!!!\n");
2015 if (pCM
.p
->HandleMenuMsg(uMsg
, (WPARAM
)m_hWnd
, lParam
) == S_OK
)
2021 /**********************************************************
2024 * The INTERFACE of the IShellView object
2027 **********************************************************
2030 /**********************************************************
2031 * ShellView_GetWindow
2033 HRESULT WINAPI
CDefView::GetWindow(HWND
*phWnd
)
2035 TRACE("(%p)\n",this);
2042 HRESULT WINAPI
CDefView::ContextSensitiveHelp(BOOL fEnterMode
)
2044 FIXME("(%p) stub\n",this);
2049 /**********************************************************
2050 * IShellView_TranslateAccelerator
2053 * use the accel functions
2055 HRESULT WINAPI
CDefView::TranslateAccelerator(LPMSG lpmsg
)
2058 FIXME("(%p)->(%p: hwnd=%x msg=%x lp=%x wp=%x) stub\n",this,lpmsg
, lpmsg
->hwnd
, lpmsg
->message
, lpmsg
->lParam
, lpmsg
->wParam
);
2061 if (lpmsg
->message
>= WM_KEYFIRST
&& lpmsg
->message
>= WM_KEYLAST
)
2063 TRACE("-- key=0x04%lx\n",lpmsg
->wParam
) ;
2065 return S_FALSE
; /* not handled */
2068 HRESULT WINAPI
CDefView::EnableModeless(BOOL fEnable
)
2070 FIXME("(%p) stub\n",this);
2075 HRESULT WINAPI
CDefView::UIActivate(UINT uState
)
2078 CHAR szName[MAX_PATH];
2081 int nPartArray
[1] = {-1};
2083 TRACE("(%p)->(state=%x) stub\n",this, uState
);
2085 /*don't do anything if the state isn't really changing*/
2086 if(uState
== uState
)
2091 /*OnActivate handles the menu merging and internal state*/
2094 /*only do This if we are active*/
2095 if(uState
!= SVUIA_DEACTIVATE
)
2099 GetFolderPath is not a method of IShellFolder
2100 IShellFolder_GetFolderPath( pSFParent, szName, sizeof(szName) );
2102 /* set the number of parts */
2103 pShellBrowser
->SendControlMsg(FCW_STATUS
, SB_SETPARTS
, 1, (LPARAM
)nPartArray
, &lResult
);
2105 /* set the text for the parts */
2107 pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXTA, 0, (LPARAM)szName, &lResult);
2114 HRESULT WINAPI
CDefView::Refresh()
2116 TRACE("(%p)\n",this);
2118 SendMessageW(hWndList
, LVM_DELETEALLITEMS
, 0, 0);
2124 HRESULT WINAPI
CDefView::CreateViewWindow(IShellView
*lpPrevView
, LPCFOLDERSETTINGS lpfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
)
2128 TRACE("(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n",this, lpPrevView
,lpfs
, psb
, prcView
, phWnd
);
2131 TRACE("-- vmode=%x flags=%x\n", lpfs
->ViewMode
, lpfs
->fFlags
);
2132 if (prcView
!= NULL
)
2133 TRACE("-- left=%i top=%i right=%i bottom=%i\n", prcView
->left
, prcView
->top
, prcView
->right
, prcView
->bottom
);
2135 /* Validate the Shell Browser */
2137 return E_UNEXPECTED
;
2139 /*set up the member variables*/
2140 pShellBrowser
= psb
;
2141 FolderSettings
= *lpfs
;
2143 /*get our parent window*/
2144 pShellBrowser
->GetWindow(&hWndParent
);
2146 /* try to get the ICommDlgBrowserInterface, adds a reference !!! */
2147 pCommDlgBrowser
= NULL
;
2148 if (SUCCEEDED(pShellBrowser
->QueryInterface(IID_ICommDlgBrowser
, (LPVOID
*)&pCommDlgBrowser
)))
2150 TRACE("-- CommDlgBrowser\n");
2153 Create(hWndParent
, prcView
, NULL
, WS_CHILD
| WS_TABSTOP
, 0, 0U);
2164 SetWindowPos(HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_SHOWWINDOW
);
2170 HRESULT WINAPI
CDefView::DestroyViewWindow()
2172 TRACE("(%p)\n",this);
2174 /*Make absolutely sure all our UI is cleaned up.*/
2175 UIActivate(SVUIA_DEACTIVATE
);
2183 pShellBrowser
.Release();
2184 pCommDlgBrowser
.Release();
2189 HRESULT WINAPI
CDefView::GetCurrentInfo(LPFOLDERSETTINGS lpfs
)
2191 TRACE("(%p)->(%p) vmode=%x flags=%x\n",this, lpfs
,
2192 FolderSettings
.ViewMode
, FolderSettings
.fFlags
);
2194 if (!lpfs
) return E_INVALIDARG
;
2196 *lpfs
= FolderSettings
;
2200 HRESULT WINAPI
CDefView::AddPropertySheetPages(DWORD dwReserved
,LPFNADDPROPSHEETPAGE lpfn
, LPARAM lparam
)
2202 FIXME("(%p) stub\n",this);
2207 HRESULT WINAPI
CDefView::SaveViewState()
2209 FIXME("(%p) stub\n",this);
2214 HRESULT WINAPI
CDefView::SelectItem(LPCITEMIDLIST pidl
, UINT uFlags
)
2218 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n",this, pidl
, uFlags
);
2220 i
= LV_FindItemByPidl(pidl
);
2226 if(uFlags
& SVSI_ENSUREVISIBLE
)
2227 SendMessageW(hWndList
, LVM_ENSUREVISIBLE
, i
, 0);
2229 lvItem
.mask
= LVIF_STATE
;
2230 lvItem
.stateMask
= LVIS_SELECTED
| LVIS_FOCUSED
;
2232 lvItem
.iSubItem
= 0;
2234 while(SendMessageW(hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
))
2236 if (lvItem
.iItem
== i
)
2238 if (uFlags
& SVSI_SELECT
)
2239 lvItem
.state
|= LVIS_SELECTED
;
2241 lvItem
.state
&= ~LVIS_SELECTED
;
2243 if(uFlags
& SVSI_FOCUSED
)
2244 lvItem
.state
&= ~LVIS_FOCUSED
;
2248 if (uFlags
& SVSI_DESELECTOTHERS
)
2249 lvItem
.state
&= ~LVIS_SELECTED
;
2251 SendMessageW(hWndList
, LVM_SETITEMW
, 0, (LPARAM
) &lvItem
);
2256 if(uFlags
& SVSI_EDIT
)
2257 SendMessageW(hWndList
, LVM_EDITLABELW
, i
, 0);
2263 HRESULT WINAPI
CDefView::GetItemObject(UINT uItem
, REFIID riid
, LPVOID
*ppvOut
)
2265 HRESULT hr
= E_FAIL
;
2267 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n",this, uItem
, debugstr_guid(&riid
), ppvOut
);
2273 case SVGIO_BACKGROUND
:
2274 if (IsEqualIID(riid
, IID_IContextMenu
))
2276 //*ppvOut = ISvBgCm_Constructor(pSFParent, FALSE);
2277 CDefFolderMenu_Create2(NULL
, NULL
, cidl
, (LPCITEMIDLIST
*)apidl
, pSFParent
, NULL
, 0, NULL
, (IContextMenu
**)ppvOut
);
2283 case SVGIO_SELECTION
:
2285 hr
= pSFParent
->GetUIObjectOf(m_hWnd
, cidl
, (LPCITEMIDLIST
*)apidl
, riid
, 0, ppvOut
);
2288 TRACE("-- (%p)->(interface=%p)\n",this, *ppvOut
);
2293 HRESULT STDMETHODCALLTYPE
CDefView::GetCurrentViewMode(UINT
*pViewMode
)
2298 HRESULT STDMETHODCALLTYPE
CDefView::SetCurrentViewMode(UINT ViewMode
)
2303 HRESULT STDMETHODCALLTYPE
CDefView::GetFolder(REFIID riid
, void **ppv
)
2305 if (pSFParent
== NULL
)
2307 return pSFParent
->QueryInterface(riid
, ppv
);
2310 HRESULT STDMETHODCALLTYPE
CDefView::Item(int iItemIndex
, LPITEMIDLIST
*ppidl
)
2315 HRESULT STDMETHODCALLTYPE
CDefView::ItemCount(UINT uFlags
, int *pcItems
)
2320 HRESULT STDMETHODCALLTYPE
CDefView::Items(UINT uFlags
, REFIID riid
, void **ppv
)
2325 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectionMarkedItem(int *piItem
)
2330 HRESULT STDMETHODCALLTYPE
CDefView::GetFocusedItem(int *piItem
)
2335 HRESULT STDMETHODCALLTYPE
CDefView::GetItemPosition(LPCITEMIDLIST pidl
, POINT
*ppt
)
2340 HRESULT STDMETHODCALLTYPE
CDefView::GetSpacing(POINT
*ppt
)
2345 HRESULT STDMETHODCALLTYPE
CDefView::GetDefaultSpacing(POINT
*ppt
)
2350 HRESULT STDMETHODCALLTYPE
CDefView::GetAutoArrange()
2355 HRESULT STDMETHODCALLTYPE
CDefView::SelectItem(int iItem
, DWORD dwFlags
)
2360 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItems(UINT cidl
, LPCITEMIDLIST
*apidl
, POINT
*apt
, DWORD dwFlags
)
2365 /**********************************************************
2366 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2368 HRESULT WINAPI
CDefView::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD
*prgCmds
, OLECMDTEXT
*pCmdText
)
2372 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
2373 this, pguidCmdGroup
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
2377 for (i
= 0; i
< cCmds
; i
++)
2379 FIXME("\tprgCmds[%d].cmdID = %d\n", i
, prgCmds
[i
].cmdID
);
2380 prgCmds
[i
].cmdf
= 0;
2382 return OLECMDERR_E_UNKNOWNGROUP
;
2385 /**********************************************************
2386 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2388 * nCmdID is the OLECMDID_* enumeration
2390 HRESULT WINAPI
CDefView::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
2392 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2393 this, debugstr_guid(pguidCmdGroup
), nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2395 if (IsEqualIID(*pguidCmdGroup
, CGID_Explorer
) &&
2397 (nCmdexecopt
== 4) && pvaOut
)
2399 if (IsEqualIID(*pguidCmdGroup
, CGID_ShellDocView
) &&
2404 return OLECMDERR_E_UNKNOWNGROUP
;
2407 /**********************************************************
2408 * ISVDropTarget implementation
2411 /******************************************************************************
2412 * drag_notify_subitem [Internal]
2414 * Figure out the shellfolder object, which is currently under the mouse cursor
2415 * and notify it via the IDropTarget interface.
2418 #define SCROLLAREAWIDTH 20
2420 HRESULT
CDefView::drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2422 LVHITTESTINFO htinfo
;
2428 /* Map from global to client coordinates and query the index of the listview-item, which is
2429 * currently under the mouse cursor. */
2432 htinfo
.flags
= LVHT_ONITEM
;
2433 ::ScreenToClient(hWndList
, &htinfo
.pt
);
2434 lResult
= SendMessageW(hWndList
, LVM_HITTEST
, 0, (LPARAM
)&htinfo
);
2436 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2437 ::GetClientRect(hWndList
, &clientRect
);
2438 if (htinfo
.pt
.x
== ptLastMousePos
.x
&& htinfo
.pt
.y
== ptLastMousePos
.y
&&
2439 (htinfo
.pt
.x
< SCROLLAREAWIDTH
|| htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
||
2440 htinfo
.pt
.y
< SCROLLAREAWIDTH
|| htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
))
2442 cScrollDelay
= (cScrollDelay
+ 1) % 5; /* DragOver is called every 50 ms */
2443 if (cScrollDelay
== 0) { /* Mouse did hover another 250 ms over the scroll-area */
2444 if (htinfo
.pt
.x
< SCROLLAREAWIDTH
)
2445 SendMessageW(hWndList
, WM_HSCROLL
, SB_LINEUP
, 0);
2446 if (htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
)
2447 SendMessageW(hWndList
, WM_HSCROLL
, SB_LINEDOWN
, 0);
2448 if (htinfo
.pt
.y
< SCROLLAREAWIDTH
)
2449 SendMessageW(hWndList
, WM_VSCROLL
, SB_LINEUP
, 0);
2450 if (htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
)
2451 SendMessageW(hWndList
, WM_VSCROLL
, SB_LINEDOWN
, 0);
2454 cScrollDelay
= 0; /* Reset, if the cursor is not over the listview's scroll-area */
2456 ptLastMousePos
= htinfo
.pt
;
2458 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2459 if (pCurDropTarget
&& lResult
== iDragOverItem
)
2460 return pCurDropTarget
->DragOver(grfKeyState
, pt
, pdwEffect
);
2462 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2463 if (pCurDropTarget
) {
2464 pCurDropTarget
->DragLeave();
2465 pCurDropTarget
.Release();
2468 iDragOverItem
= lResult
;
2469 if (lResult
== -1) {
2470 /* We are not above one of the listview's subitems. Bind to the parent folder's
2471 * DropTarget interface. */
2472 hr
= pSFParent
->QueryInterface(IID_IDropTarget
,
2473 (LPVOID
*)&pCurDropTarget
);
2475 /* Query the relative PIDL of the shellfolder object represented by the currently
2476 * dragged over listview-item ... */
2477 lvItem
.mask
= LVIF_PARAM
;
2478 lvItem
.iItem
= lResult
;
2479 lvItem
.iSubItem
= 0;
2480 SendMessageW(hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
2482 /* ... and bind pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2483 hr
= pSFParent
->GetUIObjectOf(hWndList
, 1,
2484 (LPCITEMIDLIST
*)&lvItem
.lParam
, IID_IDropTarget
, NULL
, (LPVOID
*)&pCurDropTarget
);
2487 /* If anything failed, pCurDropTarget should be NULL now, which ought to be a save state. */
2491 /* Notify the item just entered via DragEnter. */
2492 return pCurDropTarget
->DragEnter(pCurDataObject
, grfKeyState
, pt
, pdwEffect
);
2495 HRESULT WINAPI
CDefView::DragEnter(IDataObject
*pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2497 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2498 pCurDataObject
= pDataObject
;
2499 pDataObject
->AddRef();
2501 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2504 HRESULT WINAPI
CDefView::DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2506 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2509 HRESULT WINAPI
CDefView::DragLeave()
2513 pCurDropTarget
->DragLeave();
2514 pCurDropTarget
.Release();
2517 if (pCurDataObject
!= NULL
)
2519 pCurDataObject
.Release();
2527 HRESULT WINAPI
CDefView::Drop(IDataObject
* pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2531 pCurDropTarget
->Drop(pDataObject
, grfKeyState
, pt
, pdwEffect
);
2532 pCurDropTarget
.Release();
2535 pCurDataObject
.Release();
2541 /**********************************************************
2542 * ISVDropSource implementation
2545 HRESULT WINAPI
CDefView::QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
)
2547 TRACE("(%p)\n",this);
2550 return DRAGDROP_S_CANCEL
;
2551 else if (!(grfKeyState
& MK_LBUTTON
) && !(grfKeyState
& MK_RBUTTON
))
2552 return DRAGDROP_S_DROP
;
2557 HRESULT WINAPI
CDefView::GiveFeedback(DWORD dwEffect
)
2559 TRACE("(%p)\n",this);
2561 return DRAGDROP_S_USEDEFAULTCURSORS
;
2564 /**********************************************************
2565 * ISVViewObject implementation
2568 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
)
2570 FIXME("Stub: this=%p\n",this);
2575 HRESULT WINAPI
CDefView::GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
, HDC hicTargetDevice
, LOGPALETTE
**ppColorSet
)
2577 FIXME("Stub: this=%p\n",this);
2582 HRESULT WINAPI
CDefView::Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
)
2584 FIXME("Stub: this=%p\n",this);
2589 HRESULT WINAPI
CDefView::Unfreeze(DWORD dwFreeze
)
2591 FIXME("Stub: this=%p\n",this);
2596 HRESULT WINAPI
CDefView::SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
)
2598 FIXME("partial stub: %p %08x %08x %p\n", this, aspects
, advf
, pAdvSink
);
2600 /* FIXME: we set the AdviseSink, but never use it to send any advice */
2601 pAdvSink
= pAdvSink
;
2602 dwAspects
= aspects
;
2608 HRESULT WINAPI
CDefView::GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
)
2610 TRACE("this=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n", this, pAspects
, pAdvf
, ppAdvSink
);
2614 *ppAdvSink
= pAdvSink
;
2615 pAdvSink
.p
->AddRef();
2618 *pAspects
= dwAspects
;
2625 HRESULT STDMETHODCALLTYPE
CDefView::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
2627 if (IsEqualIID(guidService
, SID_IShellBrowser
))
2628 return pShellBrowser
->QueryInterface(riid
, ppvObject
);
2629 return E_NOINTERFACE
;
2632 /**********************************************************
2633 * IShellView_Constructor
2635 HRESULT WINAPI
IShellView_Constructor(IShellFolder
*pFolder
, IShellView
**newView
)
2637 CComObject
<CDefView
> *theView
;
2638 CComPtr
<IShellView
> result
;
2641 if (newView
== NULL
)
2644 ATLTRY (theView
= new CComObject
<CDefView
>);
2645 if (theView
== NULL
)
2646 return E_OUTOFMEMORY
;
2647 hResult
= theView
->QueryInterface (IID_IShellView
, (void **)&result
);
2648 if (FAILED (hResult
))
2653 hResult
= theView
->Initialize (pFolder
);
2654 if (FAILED (hResult
))
2656 *newView
= result
.Detach ();