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_AUTOARRANGE
;
451 dwExStyle
= WS_EX_CLIENTEDGE
;
453 if (FolderSettings
.fFlags
& FWF_DESKTOP
)
454 dwStyle
|= LVS_ALIGNLEFT
;
456 dwStyle
|= LVS_ALIGNTOP
;
458 switch (FolderSettings
.ViewMode
)
460 case FVM_ICON
: dwStyle
|= LVS_ICON
; break;
461 case FVM_DETAILS
: dwStyle
|= LVS_REPORT
; break;
462 case FVM_SMALLICON
: dwStyle
|= LVS_SMALLICON
; break;
463 case FVM_LIST
: dwStyle
|= LVS_LIST
; break;
464 default: dwStyle
|= LVS_LIST
; break;
467 if (FolderSettings
.fFlags
& FWF_AUTOARRANGE
) dwStyle
|= LVS_AUTOARRANGE
;
468 if (FolderSettings
.fFlags
& FWF_DESKTOP
)
469 FolderSettings
.fFlags
|= FWF_NOCLIENTEDGE
| FWF_NOSCROLL
;
470 if (FolderSettings
.fFlags
& FWF_SINGLESEL
) dwStyle
|= LVS_SINGLESEL
;
471 if (FolderSettings
.fFlags
& FWF_NOCLIENTEDGE
)
472 dwExStyle
&= ~WS_EX_CLIENTEDGE
;
474 hWndList
=CreateWindowExW( dwExStyle
,
487 ListViewSortInfo
.bIsAscending
= TRUE
;
488 ListViewSortInfo
.nHeaderID
= -1;
489 ListViewSortInfo
.nLastHeaderID
= -1;
491 if (FolderSettings
.fFlags
& FWF_DESKTOP
) {
493 * FIXME: look at the registry value
494 * HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ListviewShadow
495 * and activate drop shadows if necessary
499 SendMessageW(hWndList
, LVM_SETTEXTBKCOLOR
, 0, CLR_NONE
);
500 SendMessageW(hWndList
, LVM_SETBKCOLOR
, 0, CLR_NONE
);
504 SendMessageW(hWndList
, LVM_SETTEXTBKCOLOR
, 0, GetSysColor(COLOR_DESKTOP
));
505 SendMessageW(hWndList
, LVM_SETBKCOLOR
, 0, GetSysColor(COLOR_DESKTOP
));
508 SendMessageW(hWndList
, LVM_SETTEXTCOLOR
, 0, RGB(255,255,255));
511 /* UpdateShellSettings(); */
515 /**********************************************************
516 * ShellView_InitList()
518 * - adds all needed columns to the shellview
520 BOOL
CDefView::InitList()
529 SendMessageW(hWndList
, LVM_DELETEALLITEMS
, 0, 0);
531 lvColumn
.mask
= LVCF_FMT
| LVCF_WIDTH
| LVCF_TEXT
;
532 lvColumn
.pszText
= szTemp
;
538 if (FAILED(pSF2Parent
->GetDetailsOf(NULL
, i
, &sd
)))
540 lvColumn
.fmt
= sd
.fmt
;
541 lvColumn
.cx
= sd
.cxChar
*8; /* chars->pixel */
542 StrRetToStrNW( szTemp
, 50, &sd
.str
, NULL
);
543 SendMessageW(hWndList
, LVM_INSERTCOLUMNW
, i
, (LPARAM
) &lvColumn
);
551 SendMessageW(hWndList
, LVM_SETIMAGELIST
, LVSIL_SMALL
, (LPARAM
)ShellSmallIconList
);
552 SendMessageW(hWndList
, LVM_SETIMAGELIST
, LVSIL_NORMAL
, (LPARAM
)ShellBigIconList
);
557 /**********************************************************
558 * ShellView_CompareItems()
561 * internal, CALLBACK for DSA_Sort
563 INT CALLBACK
CDefView::CompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
)
566 TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1
, lParam2
, (LPVOID
) lpData
);
568 if(!lpData
) return 0;
570 ret
= (SHORT
)SCODE_CODE(((IShellFolder
*)lpData
)->CompareIDs(0, (LPITEMIDLIST
)lParam1
, (LPITEMIDLIST
)lParam2
));
571 TRACE("ret=%i\n",ret
);
575 /*************************************************************************
576 * ShellView_ListViewCompareItems
578 * Compare Function for the Listview (FileOpen Dialog)
581 * lParam1 [I] the first ItemIdList to compare with
582 * lParam2 [I] the second ItemIdList to compare with
583 * lpData [I] The column ID for the header Ctrl to process
586 * A negative value if the first item should precede the second,
587 * a positive value if the first item should follow the second,
588 * or zero if the two items are equivalent
591 * FIXME: function does what ShellView_CompareItems is supposed to do.
592 * unify it and figure out how to use the undocumented first parameter
593 * of IShellFolder_CompareIDs to do the job this function does and
594 * move this code to IShellFolder.
595 * make LISTVIEW_SORT_INFO obsolete
596 * the way this function works is only usable if we had only
597 * filesystemfolders (25/10/99 jsch)
599 INT CALLBACK
CDefView::ListViewCompareItems(LPVOID lParam1
, LPVOID lParam2
, LPARAM lpData
)
603 char strName1
[MAX_PATH
], strName2
[MAX_PATH
];
604 BOOL bIsFolder1
, bIsFolder2
,bIsBothFolder
;
605 LPITEMIDLIST pItemIdList1
= (LPITEMIDLIST
) lParam1
;
606 LPITEMIDLIST pItemIdList2
= (LPITEMIDLIST
) lParam2
;
607 LISTVIEW_SORT_INFO
*pSortInfo
= (LPLISTVIEW_SORT_INFO
) lpData
;
610 bIsFolder1
= _ILIsFolder(pItemIdList1
);
611 bIsFolder2
= _ILIsFolder(pItemIdList2
);
612 bIsBothFolder
= bIsFolder1
&& bIsFolder2
;
614 /* When sorting between a File and a Folder, the Folder gets sorted first */
615 if( (bIsFolder1
|| bIsFolder2
) && !bIsBothFolder
)
617 nDiff
= bIsFolder1
? -1 : 1;
621 /* Sort by Time: Folders or Files can be sorted */
623 if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_TIME
)
625 _ILGetFileDateTime(pItemIdList1
, &fd1
);
626 _ILGetFileDateTime(pItemIdList2
, &fd2
);
627 nDiff
= CompareFileTime(&fd2
, &fd1
);
629 /* Sort by Attribute: Folder or Files can be sorted */
630 else if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_ATTRIB
)
632 _ILGetFileAttributes(pItemIdList1
, strName1
, MAX_PATH
);
633 _ILGetFileAttributes(pItemIdList2
, strName2
, MAX_PATH
);
634 nDiff
= lstrcmpiA(strName1
, strName2
);
636 /* Sort by FileName: Folder or Files can be sorted */
637 else if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_NAME
|| bIsBothFolder
)
640 _ILSimpleGetText(pItemIdList1
, strName1
, MAX_PATH
);
641 _ILSimpleGetText(pItemIdList2
, strName2
, MAX_PATH
);
642 nDiff
= lstrcmpiA(strName1
, strName2
);
644 /* Sort by File Size, Only valid for Files */
645 else if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_SIZE
)
647 nDiff
= (INT
)(_ILGetFileSize(pItemIdList1
, NULL
, 0) - _ILGetFileSize(pItemIdList2
, NULL
, 0));
649 /* Sort by File Type, Only valid for Files */
650 else if(pSortInfo
->nHeaderID
== LISTVIEW_COLUMN_TYPE
)
653 _ILGetFileType(pItemIdList1
, strName1
, MAX_PATH
);
654 _ILGetFileType(pItemIdList2
, strName2
, MAX_PATH
);
655 nDiff
= lstrcmpiA(strName1
, strName2
);
658 /* If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
662 _ILSimpleGetText(pItemIdList1
, strName1
, MAX_PATH
);
663 _ILSimpleGetText(pItemIdList2
, strName2
, MAX_PATH
);
664 nDiff
= lstrcmpiA(strName1
, strName2
);
667 if(!pSortInfo
->bIsAscending
)
676 /**********************************************************
677 * LV_FindItemByPidl()
679 int CDefView::LV_FindItemByPidl(LPCITEMIDLIST pidl
)
683 lvItem
.mask
= LVIF_PARAM
;
684 for(lvItem
.iItem
= 0;
685 SendMessageW(hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
688 LPITEMIDLIST currentpidl
= (LPITEMIDLIST
) lvItem
.lParam
;
689 HRESULT hr
= pSFParent
->CompareIDs(0, pidl
, currentpidl
);
690 if(SUCCEEDED(hr
) && !HRESULT_CODE(hr
))
698 /**********************************************************
701 BOOLEAN
CDefView::LV_AddItem(LPCITEMIDLIST pidl
)
705 TRACE("(%p)(pidl=%p)\n", this, pidl
);
707 lvItem
.mask
= LVIF_TEXT
| LVIF_IMAGE
| LVIF_PARAM
; /*set the mask*/
708 lvItem
.iItem
= ListView_GetItemCount(hWndList
); /*add the item to the end of the list*/
710 lvItem
.lParam
= (LPARAM
) ILClone(ILFindLastID(pidl
)); /*set the item's data*/
711 lvItem
.pszText
= LPSTR_TEXTCALLBACKW
; /*get text on a callback basis*/
712 lvItem
.iImage
= I_IMAGECALLBACK
; /*get the image on a callback basis*/
713 if (SendMessageW(hWndList
, LVM_INSERTITEMW
, 0, (LPARAM
)&lvItem
) == -1)
719 /**********************************************************
722 BOOLEAN
CDefView::LV_DeleteItem(LPCITEMIDLIST pidl
)
726 TRACE("(%p)(pidl=%p)\n", this, pidl
);
728 nIndex
= LV_FindItemByPidl(ILFindLastID(pidl
));
729 return (-1 == ListView_DeleteItem(hWndList
, nIndex
)) ? FALSE
: TRUE
;
732 /**********************************************************
735 BOOLEAN
CDefView::LV_RenameItem(LPCITEMIDLIST pidlOld
, LPCITEMIDLIST pidlNew
)
740 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", this, pidlOld
, pidlNew
);
742 nItem
= LV_FindItemByPidl(ILFindLastID(pidlOld
));
745 lvItem
.mask
= LVIF_PARAM
; /* only the pidl */
746 lvItem
.iItem
= nItem
;
747 SendMessageW(hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
749 SHFree((LPITEMIDLIST
)lvItem
.lParam
);
750 lvItem
.mask
= LVIF_PARAM
;
751 lvItem
.iItem
= nItem
;
752 lvItem
.lParam
= (LPARAM
) ILClone(ILFindLastID(pidlNew
)); /* set the item's data */
753 SendMessageW(hWndList
, LVM_SETITEMW
, 0, (LPARAM
) &lvItem
);
754 SendMessageW(hWndList
, LVM_UPDATE
, nItem
, 0);
755 return TRUE
; /* FIXME: better handling */
760 /**********************************************************
761 * ShellView_FillList()
763 * - gets the objectlist from the shellfolder
765 * - fills the list into the view
767 INT CALLBACK
CDefView::fill_list( LPVOID ptr
, LPVOID arg
)
769 LPITEMIDLIST pidl
= (LPITEMIDLIST
)ptr
;
770 CDefView
*pThis
= (CDefView
*)arg
;
771 /* in a commdlg This works as a filemask*/
772 if ( pThis
->IncludeObject(pidl
)==S_OK
) pThis
->LV_AddItem(pidl
);
777 HRESULT
CDefView::FillList()
779 LPENUMIDLIST pEnumIDList
;
787 /* get the itemlist from the shfolder*/
788 hRes
= pSFParent
->EnumObjects(m_hWnd
, SHCONTF_NONFOLDERS
| SHCONTF_FOLDERS
, &pEnumIDList
);
796 /* create a pointer array */
797 hdpa
= DPA_Create(16);
800 return(E_OUTOFMEMORY
);
803 /* copy the items into the array*/
804 while((S_OK
== pEnumIDList
->Next(1, &pidl
, &dwFetched
)) && dwFetched
)
806 if (DPA_InsertPtr(hdpa
, 0x7fff, pidl
) == -1)
813 DPA_Sort(hdpa
, CompareItems
, (LPARAM
)pSFParent
.p
);
815 /*turn the listview's redrawing off*/
816 SendMessageA(hWndList
, WM_SETREDRAW
, FALSE
, 0);
818 DPA_DestroyCallback( hdpa
, fill_list
, (void *)this);
820 /*turn the listview's redrawing back on and force it to draw*/
821 SendMessageA(hWndList
, WM_SETREDRAW
, TRUE
, 0);
823 pEnumIDList
->Release(); /* destroy the list*/
828 LRESULT
CDefView::OnShowWindow(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
830 ::UpdateWindow(hWndList
);
835 LRESULT
CDefView::OnGetDlgCode(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
837 return SendMessageW(hWndList
, uMsg
, 0, 0);
840 LRESULT
CDefView::OnDestroy(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
842 RevokeDragDrop(m_hWnd
);
843 SHChangeNotifyDeregister(hNotify
);
848 LRESULT
CDefView::OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
850 if (FolderSettings
.fFlags
& (FWF_DESKTOP
| FWF_TRANSPARENT
))
851 return SendMessageW(GetParent(), WM_ERASEBKGND
, wParam
, lParam
); /* redirect to parent */
857 LRESULT
CDefView::OnGetShellBrowser(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
859 return (LRESULT
)pShellBrowser
.p
;
862 /**********************************************************
863 * ShellView_OnCreate()
865 LRESULT
CDefView::OnCreate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
867 CComPtr
<IDropTarget
> pdt
;
868 SHChangeNotifyEntry ntreg
;
869 CComPtr
<IPersistFolder2
> ppf2
;
881 if (SUCCEEDED(this->QueryInterface(IID_IDropTarget
, (LPVOID
*)&pdt
)))
882 RegisterDragDrop(m_hWnd
, pdt
);
884 /* register for receiving notifications */
885 pSFParent
->QueryInterface(IID_IPersistFolder2
, (LPVOID
*)&ppf2
);
888 ppf2
->GetCurFolder((LPITEMIDLIST
*)&ntreg
.pidl
);
889 ntreg
.fRecursive
= TRUE
;
890 hNotify
= SHChangeNotifyRegister(m_hWnd
, SHCNF_IDLIST
, SHCNE_ALLEVENTS
, SHV_CHANGE_NOTIFY
, 1, &ntreg
);
891 SHFree((LPITEMIDLIST
)ntreg
.pidl
);
894 hAccel
= LoadAcceleratorsA(shell32_hInstance
, "shv_accel");
899 /**********************************************************
900 * #### Handling of the menus ####
903 /**********************************************************
904 * ShellView_BuildFileMenu()
906 HMENU
CDefView::BuildFileMenu()
907 { WCHAR szText
[MAX_PATH
];
912 TRACE("(%p)\n",this);
914 hSubMenu
= CreatePopupMenu();
916 { /*get the number of items in our global array*/
917 for(nTools
= 0; Tools
[nTools
].idCommand
!= -1; nTools
++){}
919 /*add the menu items*/
920 for(i
= 0; i
< nTools
; i
++)
922 LoadStringW(shell32_hInstance
, Tools
[i
].idMenuString
, szText
, MAX_PATH
);
924 ZeroMemory(&mii
, sizeof(mii
));
925 mii
.cbSize
= sizeof(mii
);
926 mii
.fMask
= MIIM_TYPE
| MIIM_ID
| MIIM_STATE
;
928 if(BTNS_SEP
!= Tools
[i
].bStyle
) /* no separator*/
930 mii
.fType
= MFT_STRING
;
931 mii
.fState
= MFS_ENABLED
;
932 mii
.dwTypeData
= szText
;
933 mii
.wID
= Tools
[i
].idCommand
;
937 mii
.fType
= MFT_SEPARATOR
;
939 /* tack This item onto the end of the menu */
940 InsertMenuItemW(hSubMenu
, (UINT
)-1, TRUE
, &mii
);
943 TRACE("-- return (menu=%p)\n",hSubMenu
);
947 /**********************************************************
948 * ShellView_MergeFileMenu()
950 void CDefView::MergeFileMenu(HMENU hSubMenu
)
951 { TRACE("(%p)->(submenu=%p) stub\n",this,hSubMenu
);
954 { /*insert This item at the beginning of the menu */
955 _InsertMenuItemW(hSubMenu
, 0, TRUE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
956 _InsertMenuItemW(hSubMenu
, 0, TRUE
, IDM_MYFILEITEM
, MFT_STRING
, L
"dummy45", MFS_ENABLED
);
962 /**********************************************************
963 * ShellView_MergeViewMenu()
965 void CDefView::MergeViewMenu(HMENU hSubMenu
)
967 TRACE("(%p)->(submenu=%p)\n",this,hSubMenu
);
970 { /*add a separator at the correct position in the menu*/
972 static WCHAR view
[] = L
"View";
974 _InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, 0, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
976 ZeroMemory(&mii
, sizeof(mii
));
977 mii
.cbSize
= sizeof(mii
);
978 mii
.fMask
= MIIM_SUBMENU
| MIIM_TYPE
| MIIM_DATA
;
979 mii
.fType
= MFT_STRING
;
980 mii
.dwTypeData
= view
;
981 mii
.hSubMenu
= LoadMenuW(shell32_hInstance
, L
"MENU_001");
982 InsertMenuItemW(hSubMenu
, FCIDM_MENU_VIEW_SEP_OPTIONS
, FALSE
, &mii
);
986 /**********************************************************
987 * ShellView_GetSelections()
989 * - fills the this->apidl list with the selected objects
992 * number of selected items
994 UINT
CDefView::GetSelections()
1001 cidl
= ListView_GetSelectedCount(hWndList
);
1002 apidl
= (LPITEMIDLIST
*)SHAlloc(cidl
* sizeof(LPITEMIDLIST
));
1004 TRACE("selected=%i\n", cidl
);
1008 TRACE("-- Items selected =%u\n", cidl
);
1010 lvItem
.mask
= LVIF_STATE
| LVIF_PARAM
;
1011 lvItem
.stateMask
= LVIS_SELECTED
;
1013 lvItem
.iSubItem
= 0;
1015 while(SendMessageW(hWndList
, LVM_GETITEMW
, 0, (LPARAM
)&lvItem
) && (i
< cidl
))
1017 if(lvItem
.state
& LVIS_SELECTED
)
1019 apidl
[i
] = (LPITEMIDLIST
)lvItem
.lParam
;
1023 TRACE("-- selected Item found\n");
1032 /**********************************************************
1033 * ShellView_OpenSelectedItems()
1035 HRESULT
CDefView::OpenSelectedItems()
1037 static UINT CF_IDLIST
= 0;
1039 CComPtr
<IDataObject
> selection
;
1040 CComPtr
<IContextMenu
> cm
;
1045 LPCITEMIDLIST parent_pidl
;
1046 WCHAR parent_path
[MAX_PATH
];
1047 LPCWSTR parent_dir
= NULL
;
1050 CMINVOKECOMMANDINFOEX ici
;
1053 if (0 == GetSelections())
1058 hr
= pSFParent
->GetUIObjectOf(m_hWnd
, cidl
,
1059 (LPCITEMIDLIST
*)apidl
, IID_IContextMenu
,
1064 hmenu
= CreatePopupMenu();
1067 hr
= IUnknown_SetSite(cm
, (IShellView
*)this);
1068 if (SUCCEEDED(cm
->QueryContextMenu(hmenu
, 0, 0x20, 0x7fff, CMF_DEFAULTONLY
)))
1070 INT def
= -1, n
= GetMenuItemCount(hmenu
);
1072 for ( i
= 0; i
< n
; i
++ )
1074 memset( &info
, 0, sizeof info
);
1075 info
.cbSize
= sizeof info
;
1076 info
.fMask
= MIIM_FTYPE
| MIIM_STATE
| MIIM_ID
;
1077 if (GetMenuItemInfoW( hmenu
, i
, TRUE
, &info
))
1079 if (info
.fState
& MFS_DEFAULT
)
1088 memset( &ici
, 0, sizeof ici
);
1089 ici
.cbSize
= sizeof ici
;
1090 ici
.lpVerb
= MAKEINTRESOURCEA( def
);
1093 if (cm
->InvokeCommand((LPCMINVOKECOMMANDINFO
) &ici
) == S_OK
)
1095 DestroyMenu( hmenu
);
1096 hr
= IUnknown_SetSite(cm
, NULL
);
1102 DestroyMenu( hmenu
);
1103 hr
= IUnknown_SetSite(cm
, NULL
);
1110 hr
= pSFParent
->GetUIObjectOf(m_hWnd
, cidl
,
1111 (LPCITEMIDLIST
*)apidl
, IID_IDataObject
,
1112 0, (LPVOID
*)&selection
);
1121 CF_IDLIST
= RegisterClipboardFormatW(CFSTR_SHELLIDLIST
);
1123 fetc
.cfFormat
= CF_IDLIST
;
1125 fetc
.dwAspect
= DVASPECT_CONTENT
;
1127 fetc
.tymed
= TYMED_HGLOBAL
;
1129 hr
= selection
->QueryGetData(&fetc
);
1133 hr
= selection
->GetData(&fetc
, &stgm
);
1137 pIDList
= (LPIDA
)GlobalLock(stgm
.hGlobal
);
1139 parent_pidl
= (LPCITEMIDLIST
) ((LPBYTE
)pIDList
+pIDList
->aoffset
[0]);
1140 hr
= pSFParent
->GetAttributesOf(1, &parent_pidl
, &attribs
);
1141 if (SUCCEEDED(hr
) && (attribs
& SFGAO_FILESYSTEM
) &&
1142 SHGetPathFromIDListW(parent_pidl
, parent_path
))
1144 parent_dir
= parent_path
;
1147 for (i
= pIDList
->cidl
; i
> 0; --i
)
1151 pidl
= (LPCITEMIDLIST
)((LPBYTE
)pIDList
+pIDList
->aoffset
[i
]);
1153 attribs
= SFGAO_FOLDER
;
1154 hr
= pSFParent
->GetAttributesOf(1, &pidl
, &attribs
);
1156 if (SUCCEEDED(hr
) && ! (attribs
& SFGAO_FOLDER
))
1158 SHELLEXECUTEINFOW shexinfo
;
1160 shexinfo
.cbSize
= sizeof(SHELLEXECUTEINFOW
);
1161 shexinfo
.fMask
= SEE_MASK_INVOKEIDLIST
; /* SEE_MASK_IDLIST is also possible. */
1162 shexinfo
.hwnd
= NULL
;
1163 shexinfo
.lpVerb
= NULL
;
1164 shexinfo
.lpFile
= NULL
;
1165 shexinfo
.lpParameters
= NULL
;
1166 shexinfo
.lpDirectory
= parent_dir
;
1167 shexinfo
.nShow
= SW_NORMAL
;
1168 shexinfo
.lpIDList
= ILCombine(parent_pidl
, pidl
);
1170 ShellExecuteExW(&shexinfo
); /* Discard error/success info */
1172 ILFree((LPITEMIDLIST
)shexinfo
.lpIDList
);
1176 GlobalUnlock(stgm
.hGlobal
);
1177 ReleaseStgMedium(&stgm
);
1182 /**********************************************************
1183 * ShellView_DoContextMenu()
1185 LRESULT
CDefView::OnContextMenu(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1195 CMINVOKECOMMANDINFO cmi
;
1198 // for some reason I haven't figured out, we sometimes recurse into this method
1206 TRACE("(%p)->(0x%08x 0x%08x 0x%08x) stub\n",this, x
, y
, bDefault
);
1211 /* look, what's selected and create a context menu object of it*/
1212 if (GetSelections())
1214 pSFParent
->GetUIObjectOf(hWndParent
, cidl
, (LPCITEMIDLIST
*)apidl
, IID_IContextMenu
, NULL
, (LPVOID
*)&pCM
);
1218 TRACE("-- pContextMenu\n");
1219 hMenu
= CreatePopupMenu();
1223 hResult
= IUnknown_SetSite(pCM
, (IShellView
*)this);
1224 /* See if we are in Explore or Open mode. If the browser's tree is present, we are in Explore mode.*/
1225 if(SUCCEEDED(pShellBrowser
->GetControlWindow(FCW_TREE
, &hwndTree
)) && hwndTree
)
1227 TRACE("-- explore mode\n");
1231 /* build the flags depending on what we can do with the selected item */
1232 wFlags
= CMF_NORMAL
| (cidl
!= 1 ? 0 : CMF_CANRENAME
) | (fExplore
? CMF_EXPLORE
: 0);
1234 /* let the ContextMenu merge its items in */
1235 if (SUCCEEDED(pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, wFlags
)))
1237 if (FolderSettings
.fFlags
& FWF_DESKTOP
)
1238 SetMenuDefaultItem(hMenu
, FCIDM_SHVIEW_OPEN
, MF_BYCOMMAND
);
1242 TRACE("-- get menu default command\n");
1243 uCommand
= GetMenuDefaultItem(hMenu
, FALSE
, GMDI_GOINTOPOPUPS
);
1247 TRACE("-- track popup\n");
1248 uCommand
= TrackPopupMenu( hMenu
,TPM_LEFTALIGN
| TPM_RETURNCMD
,x
,y
,0,m_hWnd
,NULL
);
1253 TRACE("-- uCommand=%u\n", uCommand
);
1254 if (uCommand
==FCIDM_SHVIEW_OPEN
&& pCommDlgBrowser
.p
!= NULL
)
1256 TRACE("-- dlg: OnDefaultCommand\n");
1257 if (OnDefaultCommand() != S_OK
)
1259 OpenSelectedItems();
1264 TRACE("-- explore -- invoke command\n");
1265 ZeroMemory(&cmi
, sizeof(cmi
));
1266 cmi
.cbSize
= sizeof(cmi
);
1267 cmi
.hwnd
= hWndParent
; /* this window has to answer CWM_GETISHELLBROWSER */
1268 cmi
.lpVerb
= (LPCSTR
)MAKEINTRESOURCEA(uCommand
);
1269 pCM
->InvokeCommand(&cmi
);
1272 hResult
= IUnknown_SetSite(pCM
, NULL
);
1279 else /* background context menu */
1281 hMenu
= CreatePopupMenu();
1283 CDefFolderMenu_Create2(NULL
, NULL
, cidl
, (LPCITEMIDLIST
*)apidl
, pSFParent
, NULL
, 0, NULL
, (IContextMenu
**)&pCM
);
1284 pCM
->QueryContextMenu(hMenu
, 0, FCIDM_SHVIEWFIRST
, FCIDM_SHVIEWLAST
, 0);
1286 uCommand
= TrackPopupMenu( hMenu
, TPM_LEFTALIGN
| TPM_RETURNCMD
,x
,y
,0,m_hWnd
,NULL
);
1289 TRACE("-- (%p)->(uCommand=0x%08x )\n",this, uCommand
);
1291 ZeroMemory(&cmi
, sizeof(cmi
));
1292 cmi
.cbSize
= sizeof(cmi
);
1293 cmi
.lpVerb
= (LPCSTR
)MAKEINTRESOURCEA(uCommand
);
1294 cmi
.hwnd
= hWndParent
;
1295 pCM
->InvokeCommand(&cmi
);
1302 /**********************************************************
1303 * ##### message handling #####
1306 /**********************************************************
1307 * ShellView_OnSize()
1309 LRESULT
CDefView::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1314 wWidth
= LOWORD(lParam
);
1315 wHeight
= HIWORD(lParam
);
1317 TRACE("%p width=%u height=%u\n", this, wWidth
, wHeight
);
1319 /*resize the ListView to fit our window*/
1322 ::MoveWindow(hWndList
, 0, 0, wWidth
, wHeight
, TRUE
);
1328 /**********************************************************
1329 * ShellView_OnDeactivate()
1334 void CDefView::OnDeactivate()
1338 if(uState
!= SVUIA_DEACTIVATE
)
1342 pShellBrowser
->SetMenuSB(0, 0, 0);
1343 pShellBrowser
->RemoveMenusSB(hMenu
);
1348 uState
= SVUIA_DEACTIVATE
;
1352 void CDefView::DoActivate(UINT uState
)
1354 OLEMENUGROUPWIDTHS omw
= { {0, 0, 0, 0, 0, 0} };
1356 CHAR szText
[MAX_PATH
];
1358 TRACE("%p uState=%x\n", this, uState
);
1360 /*don't do anything if the state isn't really changing */
1361 if(uState
== uState
)
1368 /*only do This if we are active */
1369 if(uState
!= SVUIA_DEACTIVATE
)
1371 /*merge the menus */
1372 hMenu
= CreateMenu();
1376 pShellBrowser
->InsertMenusSB(hMenu
, &omw
);
1377 TRACE("-- after fnInsertMenusSB\n");
1379 /*build the top level menu get the menu item's text*/
1380 strcpy(szText
,"dummy 31");
1382 ZeroMemory(&mii
, sizeof(mii
));
1383 mii
.cbSize
= sizeof(mii
);
1384 mii
.fMask
= MIIM_SUBMENU
| MIIM_TYPE
| MIIM_STATE
;
1385 mii
.fType
= MFT_STRING
;
1386 mii
.fState
= MFS_ENABLED
;
1387 mii
.dwTypeData
= szText
;
1388 mii
.hSubMenu
= BuildFileMenu();
1390 /*insert our menu into the menu bar*/
1393 InsertMenuItemA(hMenu
, FCIDM_MENU_HELP
, FALSE
, &mii
);
1396 /*get the view menu so we can merge with it*/
1397 ZeroMemory(&mii
, sizeof(mii
));
1398 mii
.cbSize
= sizeof(mii
);
1399 mii
.fMask
= MIIM_SUBMENU
;
1401 if(GetMenuItemInfoA(hMenu
, FCIDM_MENU_VIEW
, FALSE
, &mii
))
1403 MergeViewMenu(mii
.hSubMenu
);
1406 /*add the items that should only be added if we have the focus*/
1407 if(SVUIA_ACTIVATE_FOCUS
== uState
)
1409 /*get the file menu so we can merge with it */
1410 ZeroMemory(&mii
, sizeof(mii
));
1411 mii
.cbSize
= sizeof(mii
);
1412 mii
.fMask
= MIIM_SUBMENU
;
1414 if(GetMenuItemInfoA(hMenu
, FCIDM_MENU_FILE
, FALSE
, &mii
))
1416 MergeFileMenu(mii
.hSubMenu
);
1419 TRACE("-- before fnSetMenuSB\n");
1420 pShellBrowser
->SetMenuSB(hMenu
, 0, m_hWnd
);
1427 /**********************************************************
1428 * ShellView_OnActivate()
1430 LRESULT
CDefView::OnActivate(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1432 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1436 /**********************************************************
1437 * ShellView_OnSetFocus()
1440 LRESULT
CDefView::OnSetFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1442 TRACE("%p\n", this);
1444 /* Tell the browser one of our windows has received the focus. This
1445 should always be done before merging menus (OnActivate merges the
1446 menus) if one of our windows has the focus.*/
1448 pShellBrowser
->OnViewWindowActive((IShellView
*)this);
1449 DoActivate(SVUIA_ACTIVATE_FOCUS
);
1451 /* Set the focus to the listview */
1452 ::SetFocus(hWndList
);
1454 /* Notify the ICommDlgBrowser interface */
1455 OnStateChange(CDBOSC_SETFOCUS
);
1460 /**********************************************************
1461 * ShellView_OnKillFocus()
1463 LRESULT
CDefView::OnKillFocus(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1465 TRACE("(%p) stub\n", this);
1467 DoActivate(SVUIA_ACTIVATE_NOFOCUS
);
1468 /* Notify the ICommDlgBrowser */
1469 OnStateChange(CDBOSC_KILLFOCUS
);
1474 /**********************************************************
1475 * ShellView_OnCommand()
1478 * the CmdID's are the ones from the context menu
1480 LRESULT
CDefView::OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1486 dwCmdID
= GET_WM_COMMAND_ID(wParam
, lParam
);
1487 dwCmd
= GET_WM_COMMAND_CMD(wParam
, lParam
);
1488 hwndCmd
= GET_WM_COMMAND_HWND(wParam
, lParam
);
1490 TRACE("(%p)->(0x%08x 0x%08x %p) stub\n",this, dwCmdID
, dwCmd
, hwndCmd
);
1494 case FCIDM_SHVIEW_SMALLICON
:
1495 FolderSettings
.ViewMode
= FVM_SMALLICON
;
1496 SetStyle (LVS_SMALLICON
, LVS_TYPEMASK
);
1500 case FCIDM_SHVIEW_BIGICON
:
1501 FolderSettings
.ViewMode
= FVM_ICON
;
1502 SetStyle (LVS_ICON
, LVS_TYPEMASK
);
1506 case FCIDM_SHVIEW_LISTVIEW
:
1507 FolderSettings
.ViewMode
= FVM_LIST
;
1508 SetStyle (LVS_LIST
, LVS_TYPEMASK
);
1512 case FCIDM_SHVIEW_REPORTVIEW
:
1513 FolderSettings
.ViewMode
= FVM_DETAILS
;
1514 SetStyle (LVS_REPORT
, LVS_TYPEMASK
);
1518 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1523 ListViewSortInfo
.nHeaderID
= (LPARAM
) (dwCmdID
- 0x30);
1524 ListViewSortInfo
.bIsAscending
= TRUE
;
1525 ListViewSortInfo
.nLastHeaderID
= ListViewSortInfo
.nHeaderID
;
1526 SendMessageA(hWndList
, LVM_SORTITEMS
, (WPARAM
) &ListViewSortInfo
, (LPARAM
)ListViewCompareItems
);
1530 TRACE("-- COMMAND 0x%04x unhandled\n", dwCmdID
);
1535 /**********************************************************
1536 * ShellView_OnNotify()
1539 LRESULT
CDefView::OnNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1543 LPNMLISTVIEW lpnmlv
;
1544 NMLVDISPINFOW
*lpdi
;
1549 lpnmh
= (LPNMHDR
)lParam
;
1550 lpnmlv
= (LPNMLISTVIEW
)lpnmh
;
1551 lpdi
= (NMLVDISPINFOW
*)lpnmh
;
1553 TRACE("%p CtlID=%u lpnmh->code=%x\n",this,CtlID
,lpnmh
->code
);
1558 TRACE("-- NM_SETFOCUS %p\n", this);
1559 OnSetFocus(0, 0, 0, unused
);
1563 TRACE("-- NM_KILLFOCUS %p\n", this);
1565 /* Notify the ICommDlgBrowser interface */
1566 OnStateChange(CDBOSC_KILLFOCUS
);
1570 TRACE("-- NM_CUSTOMDRAW %p\n", this);
1571 return CDRF_DODEFAULT
;
1573 case NM_RELEASEDCAPTURE
:
1574 TRACE("-- NM_RELEASEDCAPTURE %p\n", this);
1578 TRACE("-- NM_CLICK %p\n", this);
1582 TRACE("-- NM_RCLICK %p\n", this);
1586 TRACE("-- NM_DBLCLK %p\n", this);
1587 if (OnDefaultCommand() != S_OK
) OpenSelectedItems();
1591 TRACE("-- NM_RETURN %p\n", this);
1592 if (OnDefaultCommand() != S_OK
) OpenSelectedItems();
1596 TRACE("-- HDN_ENDTRACKW %p\n", this);
1597 /*nColumn1 = ListView_GetColumnWidth(hWndList, 0);
1598 nColumn2 = ListView_GetColumnWidth(hWndList, 1);*/
1601 case LVN_DELETEITEM
:
1602 TRACE("-- LVN_DELETEITEM %p\n", this);
1603 SHFree((LPITEMIDLIST
)lpnmlv
->lParam
); /*delete the pidl because we made a copy of it*/
1606 case LVN_DELETEALLITEMS
:
1607 TRACE("-- LVN_DELETEALLITEMS %p\n", this);
1610 case LVN_INSERTITEM
:
1611 TRACE("-- LVN_INSERTITEM (STUB)%p\n", this);
1614 case LVN_ITEMACTIVATE
:
1615 TRACE("-- LVN_ITEMACTIVATE %p\n", this);
1616 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1619 case LVN_COLUMNCLICK
:
1620 ListViewSortInfo
.nHeaderID
= lpnmlv
->iSubItem
;
1621 if(ListViewSortInfo
.nLastHeaderID
== ListViewSortInfo
.nHeaderID
)
1623 ListViewSortInfo
.bIsAscending
= !ListViewSortInfo
.bIsAscending
;
1627 ListViewSortInfo
.bIsAscending
= TRUE
;
1629 ListViewSortInfo
.nLastHeaderID
= ListViewSortInfo
.nHeaderID
;
1631 SendMessageW(lpnmlv
->hdr
.hwndFrom
, LVM_SORTITEMS
, (WPARAM
) &ListViewSortInfo
, (LPARAM
)ListViewCompareItems
);
1634 case LVN_GETDISPINFOA
:
1635 case LVN_GETDISPINFOW
:
1636 TRACE("-- LVN_GETDISPINFO %p\n", this);
1637 pidl
= (LPITEMIDLIST
)lpdi
->item
.lParam
;
1639 if(lpdi
->item
.mask
& LVIF_TEXT
) /* text requested */
1644 pSF2Parent
->GetDetailsOf(pidl
, lpdi
->item
.iSubItem
, &sd
);
1645 if (lpnmh
->code
== LVN_GETDISPINFOA
)
1647 /* shouldn't happen */
1648 NMLVDISPINFOA
*lpdiA
= (NMLVDISPINFOA
*)lpnmh
;
1649 StrRetToStrNA( lpdiA
->item
.pszText
, lpdiA
->item
.cchTextMax
, &sd
.str
, NULL
);
1650 TRACE("-- text=%s\n",lpdiA
->item
.pszText
);
1652 else /* LVN_GETDISPINFOW */
1654 StrRetToStrNW( lpdi
->item
.pszText
, lpdi
->item
.cchTextMax
, &sd
.str
, NULL
);
1655 TRACE("-- text=%s\n",debugstr_w(lpdi
->item
.pszText
));
1663 if(lpdi
->item
.mask
& LVIF_IMAGE
) /* image requested */
1665 lpdi
->item
.iImage
= SHMapPIDLToSystemImageListIndex(pSFParent
, pidl
, 0);
1667 lpdi
->item
.mask
|= LVIF_DI_SETITEM
;
1670 case LVN_ITEMCHANGED
:
1671 TRACE("-- LVN_ITEMCHANGED %p\n", this);
1672 OnStateChange(CDBOSC_SELCHANGE
); /* the browser will get the IDataObject now */
1676 case LVN_BEGINRDRAG
:
1677 TRACE("-- LVN_BEGINDRAG\n");
1679 if (GetSelections())
1682 DWORD dwAttributes
= SFGAO_CANLINK
;
1683 DWORD dwEffect
= DROPEFFECT_COPY
| DROPEFFECT_MOVE
;
1685 if (SUCCEEDED(pSFParent
->GetUIObjectOf(m_hWnd
, cidl
, (LPCITEMIDLIST
*)apidl
, IID_IDataObject
,0,(LPVOID
*)&pda
)))
1687 IDropSource
* pds
= (IDropSource
*)this; /* own DropSource interface */
1689 if (SUCCEEDED(pSFParent
->GetAttributesOf(cidl
, (LPCITEMIDLIST
*)apidl
, &dwAttributes
)))
1691 if (dwAttributes
& SFGAO_CANLINK
)
1693 dwEffect
|= DROPEFFECT_LINK
;
1700 DoDragDrop(pda
, pds
, dwEffect
, &dwEffect2
);
1707 case LVN_BEGINLABELEDITW
:
1709 DWORD dwAttr
= SFGAO_CANRENAME
;
1710 pidl
= (LPITEMIDLIST
)lpdi
->item
.lParam
;
1712 TRACE("-- LVN_BEGINLABELEDITW %p\n", this);
1714 pSFParent
->GetAttributesOf(1, (LPCITEMIDLIST
*)&pidl
, &dwAttr
);
1715 if (SFGAO_CANRENAME
& dwAttr
)
1722 case LVN_ENDLABELEDITW
:
1724 TRACE("-- LVN_ENDLABELEDITW %p\n", this);
1725 if (lpdi
->item
.pszText
)
1730 lvItem
.iItem
= lpdi
->item
.iItem
;
1731 lvItem
.iSubItem
= 0;
1732 lvItem
.mask
= LVIF_PARAM
;
1733 SendMessageW(hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
1735 pidl
= (LPITEMIDLIST
)lpdi
->item
.lParam
;
1736 hr
= pSFParent
->SetNameOf(0, pidl
, lpdi
->item
.pszText
, SHGDN_INFOLDER
, &pidl
);
1738 if(SUCCEEDED(hr
) && pidl
)
1740 lvItem
.mask
= LVIF_PARAM
;
1741 lvItem
.lParam
= (LPARAM
)pidl
;
1742 SendMessageW(hWndList
, LVM_SETITEMW
, 0, (LPARAM
) &lvItem
);
1753 msg.message = WM_KEYDOWN;
1754 msg.wParam = plvKeyDown->wVKey;
1759 LPNMLVKEYDOWN plvKeyDown
= (LPNMLVKEYDOWN
) lpnmh
;
1760 SHORT ctrl
= GetKeyState(VK_CONTROL
) & 0x8000;
1762 /* initiate a rename of the selected file or directory */
1763 if(plvKeyDown
->wVKey
== VK_F2
)
1765 /* see how many files are selected */
1766 int i
= ListView_GetSelectedCount(hWndList
);
1768 /* get selected item */
1771 /* get selected item */
1772 i
= ListView_GetNextItem(hWndList
, -1,
1775 SendMessageW(hWndList
, LVM_ENSUREVISIBLE
, i
, 0);
1776 SendMessageW(hWndList
, LVM_EDITLABELW
, i
, 0);
1780 TranslateAccelerator(m_hWnd
, hAccel
, &msg
)
1782 else if(plvKeyDown
->wVKey
== VK_DELETE
)
1787 LPITEMIDLIST
* pItems
;
1790 pSFParent
->QueryInterface(IID_ISFHelper
,
1796 if(!(i
= ListView_GetSelectedCount(hWndList
)))
1799 /* allocate memory for the pidl array */
1800 pItems
= (LPITEMIDLIST
*)HeapAlloc(GetProcessHeap(), 0,
1801 sizeof(LPITEMIDLIST
) * i
);
1803 /* retrieve all selected items */
1806 while(ListView_GetSelectedCount(hWndList
) > i
)
1808 /* get selected item */
1809 item_index
= ListView_GetNextItem(hWndList
,
1810 item_index
, LVNI_SELECTED
);
1811 item
.iItem
= item_index
;
1812 item
.mask
= LVIF_PARAM
;
1813 SendMessageA(hWndList
, LVM_GETITEMA
, 0, (LPARAM
) &item
);
1816 pItems
[i
] = (LPITEMIDLIST
)item
.lParam
;
1821 /* perform the item deletion */
1822 psfhlp
->DeleteItems(i
, (LPCITEMIDLIST
*)pItems
);
1824 /* free pidl array memory */
1825 HeapFree(GetProcessHeap(), 0, pItems
);
1828 /* Initiate a refresh */
1829 else if(plvKeyDown
->wVKey
== VK_F5
)
1833 else if(plvKeyDown
->wVKey
== VK_BACK
)
1835 LPSHELLBROWSER lpSb
;
1836 if((lpSb
= (LPSHELLBROWSER
)SendMessageW(hWndParent
, CWM_GETISHELLBROWSER
, 0, 0)))
1838 lpSb
->BrowseObject(NULL
, SBSP_PARENT
);
1841 else if(plvKeyDown
->wVKey
== 'C' && ctrl
)
1843 if (GetSelections())
1845 CComPtr
<IDataObject
> pda
;
1847 if (SUCCEEDED(pSFParent
->GetUIObjectOf(m_hWnd
, cidl
, (LPCITEMIDLIST
*)apidl
, IID_IDataObject
, 0, (LPVOID
*)&pda
)))
1849 HRESULT hr
= OleSetClipboard(pda
);
1852 WARN("OleSetClipboard failed");
1858 else if(plvKeyDown
->wVKey
== 'V' && ctrl
)
1860 CComPtr
<IDataObject
> pda
;
1862 FORMATETC formatetc
;
1863 LPITEMIDLIST
* apidl
;
1865 CComPtr
<IShellFolder
> psfFrom
;
1866 CComPtr
<IShellFolder
> psfDesktop
;
1867 CComPtr
<IShellFolder
> psfTarget
;
1869 CComPtr
<ISFHelper
> psfhlpdst
;
1870 CComPtr
<ISFHelper
> psfhlpsrc
;
1873 hr
= OleGetClipboard(&pda
);
1876 ERR("Failed to get clipboard with %lx\n", hr
);
1880 InitFormatEtc(formatetc
, RegisterClipboardFormatW(CFSTR_SHELLIDLIST
), TYMED_HGLOBAL
);
1881 hr
= pda
->GetData(&formatetc
, &medium
);
1885 ERR("Failed to get clipboard data with %lx\n", hr
);
1889 /* lock the handle */
1890 lpcida
= (LPIDA
)GlobalLock(medium
.hGlobal
);
1893 ERR("failed to lock pidl\n");
1894 ReleaseStgMedium(&medium
);
1898 /* convert the data into pidl */
1899 apidl
= _ILCopyCidaToaPidl(&pidl
, lpcida
);
1903 ERR("failed to copy pidl\n");
1907 if (FAILED(SHGetDesktopFolder(&psfDesktop
)))
1909 ERR("failed to get desktop folder\n");
1911 _ILFreeaPidl(apidl
, lpcida
->cidl
);
1912 ReleaseStgMedium(&medium
);
1916 if (_ILIsDesktop(pidl
))
1918 /* use desktop shellfolder */
1919 psfFrom
= psfDesktop
;
1921 else if (FAILED(psfDesktop
->BindToObject(pidl
, NULL
, IID_IShellFolder
, (LPVOID
*)&psfFrom
)))
1923 ERR("no IShellFolder\n");
1926 _ILFreeaPidl(apidl
, lpcida
->cidl
);
1927 ReleaseStgMedium(&medium
);
1932 psfTarget
= pSFParent
;
1935 /* get source and destination shellfolder */
1936 if (FAILED(psfTarget
->QueryInterface(IID_ISFHelper
, (LPVOID
*)&psfhlpdst
)))
1938 ERR("no IID_ISFHelper for destination\n");
1941 _ILFreeaPidl(apidl
, lpcida
->cidl
);
1942 ReleaseStgMedium(&medium
);
1947 if (FAILED(psfFrom
->QueryInterface(IID_ISFHelper
, (LPVOID
*)&psfhlpsrc
)))
1949 ERR("no IID_ISFHelper for source\n");
1952 _ILFreeaPidl(apidl
, lpcida
->cidl
);
1953 ReleaseStgMedium(&medium
);
1958 * do we want to perform a copy or move ???
1960 hr
= psfhlpdst
->CopyItems(psfFrom
, lpcida
->cidl
, (LPCITEMIDLIST
*)apidl
);
1963 _ILFreeaPidl(apidl
, lpcida
->cidl
);
1964 ReleaseStgMedium(&medium
);
1966 TRACE("paste end hr %x\n", hr
);
1970 FIXME("LVN_KEYDOWN key=0x%08x\n",plvKeyDown
->wVKey
);
1975 TRACE("-- %p WM_COMMAND %x unhandled\n", this, lpnmh
->code
);
1981 /**********************************************************
1982 * ShellView_OnChange()
1984 LRESULT
CDefView::OnChangeNotify(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
1986 LPITEMIDLIST
*Pidls
;
1988 Pidls
= (LPITEMIDLIST
*)wParam
;
1990 TRACE("(%p)(%p,%p,0x%08x)\n", this, Pidls
[0], Pidls
[1], lParam
);
1996 LV_AddItem(Pidls
[0]);
2000 LV_DeleteItem(Pidls
[0]);
2002 case SHCNE_RENAMEFOLDER
:
2003 case SHCNE_RENAMEITEM
:
2004 LV_RenameItem(Pidls
[0], Pidls
[1]);
2006 case SHCNE_UPDATEITEM
:
2012 /**********************************************************
2013 * ShellView_DoMeasureItem
2015 LRESULT
CDefView::OnCustomItem(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
2020 ERR("no menu!!!\n");
2024 if (pCM
.p
->HandleMenuMsg(uMsg
, (WPARAM
)m_hWnd
, lParam
) == S_OK
)
2030 /**********************************************************
2033 * The INTERFACE of the IShellView object
2036 **********************************************************
2039 /**********************************************************
2040 * ShellView_GetWindow
2042 HRESULT WINAPI
CDefView::GetWindow(HWND
*phWnd
)
2044 TRACE("(%p)\n",this);
2051 HRESULT WINAPI
CDefView::ContextSensitiveHelp(BOOL fEnterMode
)
2053 FIXME("(%p) stub\n",this);
2058 /**********************************************************
2059 * IShellView_TranslateAccelerator
2062 * use the accel functions
2064 HRESULT WINAPI
CDefView::TranslateAccelerator(LPMSG lpmsg
)
2067 FIXME("(%p)->(%p: hwnd=%x msg=%x lp=%x wp=%x) stub\n",this,lpmsg
, lpmsg
->hwnd
, lpmsg
->message
, lpmsg
->lParam
, lpmsg
->wParam
);
2070 if (lpmsg
->message
>= WM_KEYFIRST
&& lpmsg
->message
>= WM_KEYLAST
)
2072 TRACE("-- key=0x04%lx\n",lpmsg
->wParam
) ;
2074 return S_FALSE
; /* not handled */
2077 HRESULT WINAPI
CDefView::EnableModeless(BOOL fEnable
)
2079 FIXME("(%p) stub\n",this);
2084 HRESULT WINAPI
CDefView::UIActivate(UINT uState
)
2087 CHAR szName[MAX_PATH];
2090 int nPartArray
[1] = {-1};
2092 TRACE("(%p)->(state=%x) stub\n",this, uState
);
2094 /*don't do anything if the state isn't really changing*/
2095 if(uState
== uState
)
2100 /*OnActivate handles the menu merging and internal state*/
2103 /*only do This if we are active*/
2104 if(uState
!= SVUIA_DEACTIVATE
)
2108 GetFolderPath is not a method of IShellFolder
2109 IShellFolder_GetFolderPath( pSFParent, szName, sizeof(szName) );
2111 /* set the number of parts */
2112 pShellBrowser
->SendControlMsg(FCW_STATUS
, SB_SETPARTS
, 1, (LPARAM
)nPartArray
, &lResult
);
2114 /* set the text for the parts */
2116 pShellBrowser->SendControlMsg(FCW_STATUS, SB_SETTEXTA, 0, (LPARAM)szName, &lResult);
2123 HRESULT WINAPI
CDefView::Refresh()
2125 TRACE("(%p)\n",this);
2127 SendMessageW(hWndList
, LVM_DELETEALLITEMS
, 0, 0);
2133 HRESULT WINAPI
CDefView::CreateViewWindow(IShellView
*lpPrevView
, LPCFOLDERSETTINGS lpfs
, IShellBrowser
*psb
, RECT
*prcView
, HWND
*phWnd
)
2137 TRACE("(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n",this, lpPrevView
,lpfs
, psb
, prcView
, phWnd
);
2140 TRACE("-- vmode=%x flags=%x\n", lpfs
->ViewMode
, lpfs
->fFlags
);
2141 if (prcView
!= NULL
)
2142 TRACE("-- left=%i top=%i right=%i bottom=%i\n", prcView
->left
, prcView
->top
, prcView
->right
, prcView
->bottom
);
2144 /* Validate the Shell Browser */
2146 return E_UNEXPECTED
;
2148 /*set up the member variables*/
2149 pShellBrowser
= psb
;
2150 FolderSettings
= *lpfs
;
2152 /*get our parent window*/
2153 pShellBrowser
->GetWindow(&hWndParent
);
2155 /* try to get the ICommDlgBrowserInterface, adds a reference !!! */
2156 pCommDlgBrowser
= NULL
;
2157 if (SUCCEEDED(pShellBrowser
->QueryInterface(IID_ICommDlgBrowser
, (LPVOID
*)&pCommDlgBrowser
)))
2159 TRACE("-- CommDlgBrowser\n");
2162 Create(hWndParent
, prcView
, NULL
, WS_CHILD
| WS_TABSTOP
, 0, 0U);
2173 SetWindowPos(HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
| SWP_SHOWWINDOW
);
2179 HRESULT WINAPI
CDefView::DestroyViewWindow()
2181 TRACE("(%p)\n",this);
2183 /*Make absolutely sure all our UI is cleaned up.*/
2184 UIActivate(SVUIA_DEACTIVATE
);
2192 pShellBrowser
.Release();
2193 pCommDlgBrowser
.Release();
2198 HRESULT WINAPI
CDefView::GetCurrentInfo(LPFOLDERSETTINGS lpfs
)
2200 TRACE("(%p)->(%p) vmode=%x flags=%x\n",this, lpfs
,
2201 FolderSettings
.ViewMode
, FolderSettings
.fFlags
);
2203 if (!lpfs
) return E_INVALIDARG
;
2205 *lpfs
= FolderSettings
;
2209 HRESULT WINAPI
CDefView::AddPropertySheetPages(DWORD dwReserved
,LPFNADDPROPSHEETPAGE lpfn
, LPARAM lparam
)
2211 FIXME("(%p) stub\n",this);
2216 HRESULT WINAPI
CDefView::SaveViewState()
2218 FIXME("(%p) stub\n",this);
2223 HRESULT WINAPI
CDefView::SelectItem(LPCITEMIDLIST pidl
, UINT uFlags
)
2227 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n",this, pidl
, uFlags
);
2229 i
= LV_FindItemByPidl(pidl
);
2235 if(uFlags
& SVSI_ENSUREVISIBLE
)
2236 SendMessageW(hWndList
, LVM_ENSUREVISIBLE
, i
, 0);
2238 lvItem
.mask
= LVIF_STATE
;
2239 lvItem
.stateMask
= LVIS_SELECTED
| LVIS_FOCUSED
;
2241 lvItem
.iSubItem
= 0;
2243 while(SendMessageW(hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
))
2245 if (lvItem
.iItem
== i
)
2247 if (uFlags
& SVSI_SELECT
)
2248 lvItem
.state
|= LVIS_SELECTED
;
2250 lvItem
.state
&= ~LVIS_SELECTED
;
2252 if(uFlags
& SVSI_FOCUSED
)
2253 lvItem
.state
&= ~LVIS_FOCUSED
;
2257 if (uFlags
& SVSI_DESELECTOTHERS
)
2258 lvItem
.state
&= ~LVIS_SELECTED
;
2260 SendMessageW(hWndList
, LVM_SETITEMW
, 0, (LPARAM
) &lvItem
);
2265 if(uFlags
& SVSI_EDIT
)
2266 SendMessageW(hWndList
, LVM_EDITLABELW
, i
, 0);
2272 HRESULT WINAPI
CDefView::GetItemObject(UINT uItem
, REFIID riid
, LPVOID
*ppvOut
)
2274 HRESULT hr
= E_FAIL
;
2276 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n",this, uItem
, debugstr_guid(&riid
), ppvOut
);
2282 case SVGIO_BACKGROUND
:
2283 if (IsEqualIID(riid
, IID_IContextMenu
))
2285 //*ppvOut = ISvBgCm_Constructor(pSFParent, FALSE);
2286 CDefFolderMenu_Create2(NULL
, NULL
, cidl
, (LPCITEMIDLIST
*)apidl
, pSFParent
, NULL
, 0, NULL
, (IContextMenu
**)ppvOut
);
2292 case SVGIO_SELECTION
:
2294 hr
= pSFParent
->GetUIObjectOf(m_hWnd
, cidl
, (LPCITEMIDLIST
*)apidl
, riid
, 0, ppvOut
);
2297 TRACE("-- (%p)->(interface=%p)\n",this, *ppvOut
);
2302 HRESULT STDMETHODCALLTYPE
CDefView::GetCurrentViewMode(UINT
*pViewMode
)
2307 HRESULT STDMETHODCALLTYPE
CDefView::SetCurrentViewMode(UINT ViewMode
)
2312 HRESULT STDMETHODCALLTYPE
CDefView::GetFolder(REFIID riid
, void **ppv
)
2314 if (pSFParent
== NULL
)
2316 return pSFParent
->QueryInterface(riid
, ppv
);
2319 HRESULT STDMETHODCALLTYPE
CDefView::Item(int iItemIndex
, LPITEMIDLIST
*ppidl
)
2324 HRESULT STDMETHODCALLTYPE
CDefView::ItemCount(UINT uFlags
, int *pcItems
)
2329 HRESULT STDMETHODCALLTYPE
CDefView::Items(UINT uFlags
, REFIID riid
, void **ppv
)
2334 HRESULT STDMETHODCALLTYPE
CDefView::GetSelectionMarkedItem(int *piItem
)
2339 HRESULT STDMETHODCALLTYPE
CDefView::GetFocusedItem(int *piItem
)
2344 HRESULT STDMETHODCALLTYPE
CDefView::GetItemPosition(LPCITEMIDLIST pidl
, POINT
*ppt
)
2349 HRESULT STDMETHODCALLTYPE
CDefView::GetSpacing(POINT
*ppt
)
2354 HRESULT STDMETHODCALLTYPE
CDefView::GetDefaultSpacing(POINT
*ppt
)
2359 HRESULT STDMETHODCALLTYPE
CDefView::GetAutoArrange()
2364 HRESULT STDMETHODCALLTYPE
CDefView::SelectItem(int iItem
, DWORD dwFlags
)
2369 HRESULT STDMETHODCALLTYPE
CDefView::SelectAndPositionItems(UINT cidl
, LPCITEMIDLIST
*apidl
, POINT
*apt
, DWORD dwFlags
)
2374 /**********************************************************
2375 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2377 HRESULT WINAPI
CDefView::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD
*prgCmds
, OLECMDTEXT
*pCmdText
)
2381 FIXME("(%p)->(%p(%s) 0x%08x %p %p\n",
2382 this, pguidCmdGroup
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
2386 for (i
= 0; i
< cCmds
; i
++)
2388 FIXME("\tprgCmds[%d].cmdID = %d\n", i
, prgCmds
[i
].cmdID
);
2389 prgCmds
[i
].cmdf
= 0;
2391 return OLECMDERR_E_UNKNOWNGROUP
;
2394 /**********************************************************
2395 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2397 * nCmdID is the OLECMDID_* enumeration
2399 HRESULT WINAPI
CDefView::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
2401 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08x Opt:0x%08x %p %p)\n",
2402 this, debugstr_guid(pguidCmdGroup
), nCmdID
, nCmdexecopt
, pvaIn
, pvaOut
);
2404 if (IsEqualIID(*pguidCmdGroup
, CGID_Explorer
) &&
2406 (nCmdexecopt
== 4) && pvaOut
)
2408 if (IsEqualIID(*pguidCmdGroup
, CGID_ShellDocView
) &&
2413 return OLECMDERR_E_UNKNOWNGROUP
;
2416 /**********************************************************
2417 * ISVDropTarget implementation
2420 /******************************************************************************
2421 * drag_notify_subitem [Internal]
2423 * Figure out the shellfolder object, which is currently under the mouse cursor
2424 * and notify it via the IDropTarget interface.
2427 #define SCROLLAREAWIDTH 20
2429 HRESULT
CDefView::drag_notify_subitem(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2431 LVHITTESTINFO htinfo
;
2437 /* Map from global to client coordinates and query the index of the listview-item, which is
2438 * currently under the mouse cursor. */
2441 htinfo
.flags
= LVHT_ONITEM
;
2442 ::ScreenToClient(hWndList
, &htinfo
.pt
);
2443 lResult
= SendMessageW(hWndList
, LVM_HITTEST
, 0, (LPARAM
)&htinfo
);
2445 /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */
2446 ::GetClientRect(hWndList
, &clientRect
);
2447 if (htinfo
.pt
.x
== ptLastMousePos
.x
&& htinfo
.pt
.y
== ptLastMousePos
.y
&&
2448 (htinfo
.pt
.x
< SCROLLAREAWIDTH
|| htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
||
2449 htinfo
.pt
.y
< SCROLLAREAWIDTH
|| htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
))
2451 cScrollDelay
= (cScrollDelay
+ 1) % 5; /* DragOver is called every 50 ms */
2452 if (cScrollDelay
== 0) { /* Mouse did hover another 250 ms over the scroll-area */
2453 if (htinfo
.pt
.x
< SCROLLAREAWIDTH
)
2454 SendMessageW(hWndList
, WM_HSCROLL
, SB_LINEUP
, 0);
2455 if (htinfo
.pt
.x
> clientRect
.right
- SCROLLAREAWIDTH
)
2456 SendMessageW(hWndList
, WM_HSCROLL
, SB_LINEDOWN
, 0);
2457 if (htinfo
.pt
.y
< SCROLLAREAWIDTH
)
2458 SendMessageW(hWndList
, WM_VSCROLL
, SB_LINEUP
, 0);
2459 if (htinfo
.pt
.y
> clientRect
.bottom
- SCROLLAREAWIDTH
)
2460 SendMessageW(hWndList
, WM_VSCROLL
, SB_LINEDOWN
, 0);
2463 cScrollDelay
= 0; /* Reset, if the cursor is not over the listview's scroll-area */
2465 ptLastMousePos
= htinfo
.pt
;
2467 /* If we are still over the previous sub-item, notify it via DragOver and return. */
2468 if (pCurDropTarget
&& lResult
== iDragOverItem
)
2469 return pCurDropTarget
->DragOver(grfKeyState
, pt
, pdwEffect
);
2471 /* We've left the previous sub-item, notify it via DragLeave and Release it. */
2472 if (pCurDropTarget
) {
2473 pCurDropTarget
->DragLeave();
2474 pCurDropTarget
.Release();
2477 iDragOverItem
= lResult
;
2478 if (lResult
== -1) {
2479 /* We are not above one of the listview's subitems. Bind to the parent folder's
2480 * DropTarget interface. */
2481 hr
= pSFParent
->QueryInterface(IID_IDropTarget
,
2482 (LPVOID
*)&pCurDropTarget
);
2484 /* Query the relative PIDL of the shellfolder object represented by the currently
2485 * dragged over listview-item ... */
2486 lvItem
.mask
= LVIF_PARAM
;
2487 lvItem
.iItem
= lResult
;
2488 lvItem
.iSubItem
= 0;
2489 SendMessageW(hWndList
, LVM_GETITEMW
, 0, (LPARAM
) &lvItem
);
2491 /* ... and bind pCurDropTarget to the IDropTarget interface of an UIObject of this object */
2492 hr
= pSFParent
->GetUIObjectOf(hWndList
, 1,
2493 (LPCITEMIDLIST
*)&lvItem
.lParam
, IID_IDropTarget
, NULL
, (LPVOID
*)&pCurDropTarget
);
2496 /* If anything failed, pCurDropTarget should be NULL now, which ought to be a save state. */
2500 /* Notify the item just entered via DragEnter. */
2501 return pCurDropTarget
->DragEnter(pCurDataObject
, grfKeyState
, pt
, pdwEffect
);
2504 HRESULT WINAPI
CDefView::DragEnter(IDataObject
*pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2506 /* Get a hold on the data object for later calls to DragEnter on the sub-folders */
2507 pCurDataObject
= pDataObject
;
2508 pDataObject
->AddRef();
2510 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2513 HRESULT WINAPI
CDefView::DragOver(DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2515 return drag_notify_subitem(grfKeyState
, pt
, pdwEffect
);
2518 HRESULT WINAPI
CDefView::DragLeave()
2522 pCurDropTarget
->DragLeave();
2523 pCurDropTarget
.Release();
2526 if (pCurDataObject
!= NULL
)
2528 pCurDataObject
.Release();
2536 HRESULT WINAPI
CDefView::Drop(IDataObject
* pDataObject
, DWORD grfKeyState
, POINTL pt
, DWORD
*pdwEffect
)
2540 pCurDropTarget
->Drop(pDataObject
, grfKeyState
, pt
, pdwEffect
);
2541 pCurDropTarget
.Release();
2544 pCurDataObject
.Release();
2550 /**********************************************************
2551 * ISVDropSource implementation
2554 HRESULT WINAPI
CDefView::QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
)
2556 TRACE("(%p)\n",this);
2559 return DRAGDROP_S_CANCEL
;
2560 else if (!(grfKeyState
& MK_LBUTTON
) && !(grfKeyState
& MK_RBUTTON
))
2561 return DRAGDROP_S_DROP
;
2566 HRESULT WINAPI
CDefView::GiveFeedback(DWORD dwEffect
)
2568 TRACE("(%p)\n",this);
2570 return DRAGDROP_S_USEDEFAULTCURSORS
;
2573 /**********************************************************
2574 * ISVViewObject implementation
2577 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
)
2579 FIXME("Stub: this=%p\n",this);
2584 HRESULT WINAPI
CDefView::GetColorSet(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DVTARGETDEVICE
*ptd
, HDC hicTargetDevice
, LOGPALETTE
**ppColorSet
)
2586 FIXME("Stub: this=%p\n",this);
2591 HRESULT WINAPI
CDefView::Freeze(DWORD dwDrawAspect
, LONG lindex
, void *pvAspect
, DWORD
*pdwFreeze
)
2593 FIXME("Stub: this=%p\n",this);
2598 HRESULT WINAPI
CDefView::Unfreeze(DWORD dwFreeze
)
2600 FIXME("Stub: this=%p\n",this);
2605 HRESULT WINAPI
CDefView::SetAdvise(DWORD aspects
, DWORD advf
, IAdviseSink
*pAdvSink
)
2607 FIXME("partial stub: %p %08x %08x %p\n", this, aspects
, advf
, pAdvSink
);
2609 /* FIXME: we set the AdviseSink, but never use it to send any advice */
2610 pAdvSink
= pAdvSink
;
2611 dwAspects
= aspects
;
2617 HRESULT WINAPI
CDefView::GetAdvise(DWORD
*pAspects
, DWORD
*pAdvf
, IAdviseSink
**ppAdvSink
)
2619 TRACE("this=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n", this, pAspects
, pAdvf
, ppAdvSink
);
2623 *ppAdvSink
= pAdvSink
;
2624 pAdvSink
.p
->AddRef();
2627 *pAspects
= dwAspects
;
2634 HRESULT STDMETHODCALLTYPE
CDefView::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
2636 if (IsEqualIID(guidService
, SID_IShellBrowser
))
2637 return pShellBrowser
->QueryInterface(riid
, ppvObject
);
2638 return E_NOINTERFACE
;
2641 /**********************************************************
2642 * IShellView_Constructor
2644 HRESULT WINAPI
IShellView_Constructor(IShellFolder
*pFolder
, IShellView
**newView
)
2646 CComObject
<CDefView
> *theView
;
2647 CComPtr
<IShellView
> result
;
2650 if (newView
== NULL
)
2653 ATLTRY (theView
= new CComObject
<CDefView
>);
2654 if (theView
== NULL
)
2655 return E_OUTOFMEMORY
;
2656 hResult
= theView
->QueryInterface (IID_IShellView
, (void **)&result
);
2657 if (FAILED (hResult
))
2662 hResult
= theView
->Initialize (pFolder
);
2663 if (FAILED (hResult
))
2665 *newView
= result
.Detach ();