Use the LVCFMT_{LEFT,RIGHT,CENTER} enumeration flags properly.
[wine/dcerpc.git] / dlls / shell32 / shlview.c
blobc9181e7d501219a4b81c5ba5650e5af4f2bbd338
1 /*
2 * ShellView
4 * Copyright 1998,1999 <juergen.schmied@debitel.net>
6 * This is the view visualizing the data provied 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 * FIXME: The order by part of the background context menu should be
24 * buily according to the columns shown.
26 * FIXME: Load/Save the view state from/into the stream provied by
27 * the ShellBrowser
29 * FIXME: CheckToolbar: handle the "new folder" and "folder up" button
31 * FIXME: ShellView_FillList: consider sort orders
33 * FIXME: implement the drag and drop in the old (msg-based) way
35 * FIXME: when the ShellView_WndProc gets a WM_NCDESTROY should we do a
36 * Release() ???
39 #include "config.h"
40 #include "wine/port.h"
42 #include <stdarg.h>
43 #include <stdlib.h>
44 #include <string.h>
46 #define COBJMACROS
47 #define NONAMELESSUNION
48 #define NONAMELESSSTRUCT
50 #include "windef.h"
51 #include "winerror.h"
52 #include "winbase.h"
53 #include "winnls.h"
54 #include "objbase.h"
55 #include "servprov.h"
56 #include "shlguid.h"
57 #include "wingdi.h"
58 #include "winuser.h"
59 #include "shlobj.h"
60 #include "undocshell.h"
61 #include "shresdef.h"
62 #include "wine/debug.h"
64 #include "docobj.h"
65 #include "pidl.h"
66 #include "shell32_main.h"
67 #include "shellfolder.h"
69 WINE_DEFAULT_DEBUG_CHANNEL(shell);
71 typedef struct
72 { BOOL bIsAscending;
73 INT nHeaderID;
74 INT nLastHeaderID;
75 }LISTVIEW_SORT_INFO, *LPLISTVIEW_SORT_INFO;
77 typedef struct
79 IShellViewVtbl* lpVtbl;
80 DWORD ref;
81 IOleCommandTargetVtbl* lpvtblOleCommandTarget;
82 IDropTargetVtbl* lpvtblDropTarget;
83 IDropSourceVtbl* lpvtblDropSource;
84 IViewObjectVtbl* lpvtblViewObject;
85 IShellFolder* pSFParent;
86 IShellFolder2* pSF2Parent;
87 IShellBrowser* pShellBrowser;
88 ICommDlgBrowser* pCommDlgBrowser;
89 HWND hWnd; /* SHELLDLL_DefView */
90 HWND hWndList; /* ListView control */
91 HWND hWndParent;
92 FOLDERSETTINGS FolderSettings;
93 HMENU hMenu;
94 UINT uState;
95 UINT cidl;
96 LPITEMIDLIST *apidl;
97 LISTVIEW_SORT_INFO ListViewSortInfo;
98 ULONG hNotify; /* change notification handle */
99 HANDLE hAccel;
100 } IShellViewImpl;
102 static struct IShellViewVtbl svvt;
104 static struct IOleCommandTargetVtbl ctvt;
105 #define _IOleCommandTarget_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblOleCommandTarget)))
106 #define _ICOM_THIS_From_IOleCommandTarget(class, name) class* This = (class*)(((char*)name)-_IOleCommandTarget_Offset);
108 static struct IDropTargetVtbl dtvt;
109 #define _IDropTarget_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblDropTarget)))
110 #define _ICOM_THIS_From_IDropTarget(class, name) class* This = (class*)(((char*)name)-_IDropTarget_Offset);
112 static struct IDropSourceVtbl dsvt;
113 #define _IDropSource_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblDropSource)))
114 #define _ICOM_THIS_From_IDropSource(class, name) class* This = (class*)(((char*)name)-_IDropSource_Offset);
116 static struct IViewObjectVtbl vovt;
117 #define _IViewObject_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblViewObject)))
118 #define _ICOM_THIS_From_IViewObject(class, name) class* This = (class*)(((char*)name)-_IViewObject_Offset);
120 /* ListView Header ID's */
121 #define LISTVIEW_COLUMN_NAME 0
122 #define LISTVIEW_COLUMN_SIZE 1
123 #define LISTVIEW_COLUMN_TYPE 2
124 #define LISTVIEW_COLUMN_TIME 3
125 #define LISTVIEW_COLUMN_ATTRIB 4
127 /*menu items */
128 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
129 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
130 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
132 #define ID_LISTVIEW 2000
134 #define SHV_CHANGE_NOTIFY WM_USER + 0x1111
136 /*windowsx.h */
137 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
138 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
139 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
141 extern void WINAPI _InsertMenuItem (HMENU hmenu, UINT indexMenu, BOOL fByPosition,
142 UINT wID, UINT fType, LPSTR dwTypeData, UINT fState);
145 Items merged into the toolbar and and the filemenu
147 typedef struct
148 { int idCommand;
149 int iImage;
150 int idButtonString;
151 int idMenuString;
152 BYTE bState;
153 BYTE bStyle;
154 } MYTOOLINFO, *LPMYTOOLINFO;
156 MYTOOLINFO Tools[] =
158 { FCIDM_SHVIEW_BIGICON, 0, 0, IDS_VIEW_LARGE, TBSTATE_ENABLED, BTNS_BUTTON },
159 { FCIDM_SHVIEW_SMALLICON, 0, 0, IDS_VIEW_SMALL, TBSTATE_ENABLED, BTNS_BUTTON },
160 { FCIDM_SHVIEW_LISTVIEW, 0, 0, IDS_VIEW_LIST, TBSTATE_ENABLED, BTNS_BUTTON },
161 { FCIDM_SHVIEW_REPORTVIEW, 0, 0, IDS_VIEW_DETAILS, TBSTATE_ENABLED, BTNS_BUTTON },
162 { -1, 0, 0, 0, 0, 0}
165 typedef void (CALLBACK *PFNSHGETSETTINGSPROC)(LPSHELLFLAGSTATE lpsfs, DWORD dwMask);
167 /**********************************************************
168 * IShellView_Constructor
170 IShellView * IShellView_Constructor( IShellFolder * pFolder)
171 { IShellViewImpl * sv;
172 sv=(IShellViewImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IShellViewImpl));
173 sv->ref=1;
174 sv->lpVtbl=&svvt;
175 sv->lpvtblOleCommandTarget=&ctvt;
176 sv->lpvtblDropTarget=&dtvt;
177 sv->lpvtblDropSource=&dsvt;
178 sv->lpvtblViewObject=&vovt;
180 sv->pSFParent = pFolder;
181 if(pFolder) IShellFolder_AddRef(pFolder);
182 IShellFolder_QueryInterface(sv->pSFParent, &IID_IShellFolder2, (LPVOID*)&sv->pSF2Parent);
184 TRACE("(%p)->(%p)\n",sv, pFolder);
185 return (IShellView *) sv;
188 /**********************************************************
190 * ##### helperfunctions for communication with ICommDlgBrowser #####
192 static BOOL IsInCommDlg(IShellViewImpl * This)
193 { return(This->pCommDlgBrowser != NULL);
196 static HRESULT IncludeObject(IShellViewImpl * This, LPCITEMIDLIST pidl)
198 HRESULT ret = S_OK;
200 if ( IsInCommDlg(This) )
202 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl);
203 ret = ICommDlgBrowser_IncludeObject(This->pCommDlgBrowser, (IShellView*)This, pidl);
204 TRACE("--0x%08lx\n", ret);
206 return ret;
209 static HRESULT OnDefaultCommand(IShellViewImpl * This)
211 HRESULT ret = S_FALSE;
213 if (IsInCommDlg(This))
215 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
216 ret = ICommDlgBrowser_OnDefaultCommand(This->pCommDlgBrowser, (IShellView*)This);
217 TRACE("--\n");
219 return ret;
222 static HRESULT OnStateChange(IShellViewImpl * This, UINT uFlags)
224 HRESULT ret = S_FALSE;
226 if (IsInCommDlg(This))
228 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags);
229 ret = ICommDlgBrowser_OnStateChange(This->pCommDlgBrowser, (IShellView*)This, uFlags);
230 TRACE("--\n");
232 return ret;
234 /**********************************************************
235 * set the toolbar of the filedialog buttons
237 * - activates the buttons from the shellbrowser according to
238 * the view state
240 static void CheckToolbar(IShellViewImpl * This)
242 LRESULT result;
244 TRACE("\n");
246 if (IsInCommDlg(This))
248 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
249 FCIDM_TB_SMALLICON, (This->FolderSettings.ViewMode==FVM_LIST)? TRUE : FALSE, &result);
250 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
251 FCIDM_TB_REPORTVIEW, (This->FolderSettings.ViewMode==FVM_DETAILS)? TRUE : FALSE, &result);
252 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
253 FCIDM_TB_SMALLICON, TRUE, &result);
254 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
255 FCIDM_TB_REPORTVIEW, TRUE, &result);
259 /**********************************************************
261 * ##### helperfunctions for initializing the view #####
263 /**********************************************************
264 * change the style of the listview control
266 static void SetStyle(IShellViewImpl * This, DWORD dwAdd, DWORD dwRemove)
268 DWORD tmpstyle;
270 TRACE("(%p)\n", This);
272 tmpstyle = GetWindowLongA(This->hWndList, GWL_STYLE);
273 SetWindowLongA(This->hWndList, GWL_STYLE, dwAdd | (tmpstyle & ~dwRemove));
276 /**********************************************************
277 * ShellView_CreateList()
279 * - creates the list view window
281 static BOOL ShellView_CreateList (IShellViewImpl * This)
282 { DWORD dwStyle, dwExStyle;
284 TRACE("%p\n",This);
286 dwStyle = WS_TABSTOP | WS_VISIBLE | WS_CHILDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
287 LVS_SHAREIMAGELISTS | LVS_EDITLABELS | LVS_ALIGNLEFT | LVS_AUTOARRANGE;
288 dwExStyle = WS_EX_CLIENTEDGE;
290 switch (This->FolderSettings.ViewMode)
292 case FVM_ICON: dwStyle |= LVS_ICON; break;
293 case FVM_DETAILS: dwStyle |= LVS_REPORT; break;
294 case FVM_SMALLICON: dwStyle |= LVS_SMALLICON; break;
295 case FVM_LIST: dwStyle |= LVS_LIST; break;
296 default: dwStyle |= LVS_LIST; break;
299 if (This->FolderSettings.fFlags & FWF_AUTOARRANGE) dwStyle |= LVS_AUTOARRANGE;
300 if (This->FolderSettings.fFlags & FWF_DESKTOP)
301 This->FolderSettings.fFlags |= FWF_NOCLIENTEDGE | FWF_NOSCROLL;
302 if (This->FolderSettings.fFlags & FWF_SINGLESEL) dwStyle |= LVS_SINGLESEL;
303 if (This->FolderSettings.fFlags & FWF_NOCLIENTEDGE)
304 dwExStyle &= ~WS_EX_CLIENTEDGE;
306 This->hWndList=CreateWindowExA( dwExStyle,
307 WC_LISTVIEWA,
308 NULL,
309 dwStyle,
310 0,0,0,0,
311 This->hWnd,
312 (HMENU)ID_LISTVIEW,
313 shell32_hInstance,
314 NULL);
316 if(!This->hWndList)
317 return FALSE;
319 This->ListViewSortInfo.bIsAscending = TRUE;
320 This->ListViewSortInfo.nHeaderID = -1;
321 This->ListViewSortInfo.nLastHeaderID = -1;
323 if (This->FolderSettings.fFlags & FWF_DESKTOP) {
324 if (0) /* FIXME: look into registry vale HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ListviewShadow and activate drop shadows */
325 ListView_SetTextBkColor(This->hWndList, CLR_NONE);
326 else
327 ListView_SetTextBkColor(This->hWndList, GetSysColor(COLOR_DESKTOP));
329 ListView_SetTextColor(This->hWndList, RGB(255,255,255));
332 /* UpdateShellSettings(); */
333 return TRUE;
336 /**********************************************************
337 * ShellView_InitList()
339 * - adds all needed columns to the shellview
341 static BOOL ShellView_InitList(IShellViewImpl * This)
343 LVCOLUMNA lvColumn;
344 SHELLDETAILS sd;
345 int i;
346 char szTemp[50];
348 TRACE("%p\n",This);
350 ListView_DeleteAllItems(This->hWndList);
352 lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT;
353 lvColumn.pszText = szTemp;
355 if (This->pSF2Parent)
357 for (i=0; 1; i++)
359 if (!SUCCEEDED(IShellFolder2_GetDetailsOf(This->pSF2Parent, NULL, i, &sd)))
360 break;
361 lvColumn.fmt = sd.fmt;
362 lvColumn.cx = sd.cxChar*8; /* chars->pixel */
363 StrRetToStrNA( szTemp, 50, &sd.str, NULL);
364 ListView_InsertColumnA(This->hWndList, i, &lvColumn);
367 else
369 FIXME("no SF2\n");
372 ListView_SetImageList(This->hWndList, ShellSmallIconList, LVSIL_SMALL);
373 ListView_SetImageList(This->hWndList, ShellBigIconList, LVSIL_NORMAL);
375 return TRUE;
377 /**********************************************************
378 * ShellView_CompareItems()
380 * NOTES
381 * internal, CALLBACK for DSA_Sort
383 static INT CALLBACK ShellView_CompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
385 int ret;
386 TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1, lParam2, (LPVOID) lpData);
388 if(!lpData) return 0;
390 ret = (SHORT) SCODE_CODE(IShellFolder_CompareIDs((LPSHELLFOLDER)lpData, 0, (LPITEMIDLIST)lParam1, (LPITEMIDLIST)lParam2));
391 TRACE("ret=%i\n",ret);
392 return ret;
395 /*************************************************************************
396 * ShellView_ListViewCompareItems
398 * Compare Function for the Listview (FileOpen Dialog)
400 * PARAMS
401 * lParam1 [I] the first ItemIdList to compare with
402 * lParam2 [I] the second ItemIdList to compare with
403 * lpData [I] The column ID for the header Ctrl to process
405 * RETURNS
406 * A negative value if the first item should precede the second,
407 * a positive value if the first item should follow the second,
408 * or zero if the two items are equivalent
410 * NOTES
411 * FIXME: function does what ShellView_CompareItems is supposed to do.
412 * unify it and figure out how to use the undocumented first parameter
413 * of IShellFolder_CompareIDs to do the job this function does and
414 * move this code to IShellFolder.
415 * make LISTVIEW_SORT_INFO obsolete
416 * the way this function works is only usable if we had only
417 * filesystemfolders (25/10/99 jsch)
419 static INT CALLBACK ShellView_ListViewCompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
421 INT nDiff=0;
422 FILETIME fd1, fd2;
423 char strName1[MAX_PATH], strName2[MAX_PATH];
424 BOOL bIsFolder1, bIsFolder2,bIsBothFolder;
425 LPITEMIDLIST pItemIdList1 = (LPITEMIDLIST) lParam1;
426 LPITEMIDLIST pItemIdList2 = (LPITEMIDLIST) lParam2;
427 LISTVIEW_SORT_INFO *pSortInfo = (LPLISTVIEW_SORT_INFO) lpData;
430 bIsFolder1 = _ILIsFolder(pItemIdList1);
431 bIsFolder2 = _ILIsFolder(pItemIdList2);
432 bIsBothFolder = bIsFolder1 && bIsFolder2;
434 /* When sorting between a File and a Folder, the Folder gets sorted first */
435 if( (bIsFolder1 || bIsFolder2) && !bIsBothFolder)
437 nDiff = bIsFolder1 ? -1 : 1;
439 else
441 /* Sort by Time: Folders or Files can be sorted */
443 if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TIME)
445 _ILGetFileDateTime(pItemIdList1, &fd1);
446 _ILGetFileDateTime(pItemIdList2, &fd2);
447 nDiff = CompareFileTime(&fd2, &fd1);
449 /* Sort by Attribute: Folder or Files can be sorted */
450 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_ATTRIB)
452 _ILGetFileAttributes(pItemIdList1, strName1, MAX_PATH);
453 _ILGetFileAttributes(pItemIdList2, strName2, MAX_PATH);
454 nDiff = strcasecmp(strName1, strName2);
456 /* Sort by FileName: Folder or Files can be sorted */
457 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_NAME || bIsBothFolder)
459 /* Sort by Text */
460 _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
461 _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
462 nDiff = strcasecmp(strName1, strName2);
464 /* Sort by File Size, Only valid for Files */
465 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_SIZE)
467 nDiff = (INT)(_ILGetFileSize(pItemIdList1, NULL, 0) - _ILGetFileSize(pItemIdList2, NULL, 0));
469 /* Sort by File Type, Only valid for Files */
470 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TYPE)
472 /* Sort by Type */
473 _ILGetFileType(pItemIdList1, strName1, MAX_PATH);
474 _ILGetFileType(pItemIdList2, strName2, MAX_PATH);
475 nDiff = strcasecmp(strName1, strName2);
478 /* If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
480 if(nDiff == 0)
482 _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
483 _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
484 nDiff = strcasecmp(strName1, strName2);
487 if(!pSortInfo->bIsAscending)
489 nDiff = -nDiff;
492 return nDiff;
496 /**********************************************************
497 * LV_FindItemByPidl()
499 static int LV_FindItemByPidl(
500 IShellViewImpl * This,
501 LPCITEMIDLIST pidl)
503 LVITEMA lvItem;
504 ZeroMemory(&lvItem, sizeof(LVITEMA));
505 lvItem.mask = LVIF_PARAM;
506 for(lvItem.iItem = 0; ListView_GetItemA(This->hWndList, &lvItem); lvItem.iItem++)
508 LPITEMIDLIST currentpidl = (LPITEMIDLIST) lvItem.lParam;
509 HRESULT hr = IShellFolder_CompareIDs(This->pSFParent, 0, pidl, currentpidl);
510 if(SUCCEEDED(hr) && !HRESULT_CODE(hr))
512 return lvItem.iItem;
515 return -1;
518 /**********************************************************
519 * LV_AddItem()
521 static BOOLEAN LV_AddItem(IShellViewImpl * This, LPCITEMIDLIST pidl)
523 LVITEMA lvItem;
525 TRACE("(%p)(pidl=%p)\n", This, pidl);
527 ZeroMemory(&lvItem, sizeof(lvItem)); /* create the listview item*/
528 lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; /*set the mask*/
529 lvItem.iItem = ListView_GetItemCount(This->hWndList); /*add the item to the end of the list*/
530 lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidl)); /*set the item's data*/
531 lvItem.pszText = LPSTR_TEXTCALLBACKA; /*get text on a callback basis*/
532 lvItem.iImage = I_IMAGECALLBACK; /*get the image on a callback basis*/
533 return (-1==ListView_InsertItemA(This->hWndList, &lvItem))? FALSE: TRUE;
536 /**********************************************************
537 * LV_DeleteItem()
539 static BOOLEAN LV_DeleteItem(IShellViewImpl * This, LPCITEMIDLIST pidl)
541 int nIndex;
543 TRACE("(%p)(pidl=%p)\n", This, pidl);
545 nIndex = LV_FindItemByPidl(This, ILFindLastID(pidl));
546 return (-1==ListView_DeleteItem(This->hWndList, nIndex))? FALSE: TRUE;
549 /**********************************************************
550 * LV_RenameItem()
552 static BOOLEAN LV_RenameItem(IShellViewImpl * This, LPCITEMIDLIST pidlOld, LPCITEMIDLIST pidlNew )
554 int nItem;
555 LVITEMA lvItem;
557 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", This, pidlOld, pidlNew);
559 nItem = LV_FindItemByPidl(This, ILFindLastID(pidlOld));
560 if ( -1 != nItem )
562 ZeroMemory(&lvItem, sizeof(lvItem)); /* create the listview item*/
563 lvItem.mask = LVIF_PARAM; /* only the pidl */
564 lvItem.iItem = nItem;
565 ListView_GetItemA(This->hWndList, &lvItem);
567 SHFree((LPITEMIDLIST)lvItem.lParam);
568 lvItem.mask = LVIF_PARAM;
569 lvItem.iItem = nItem;
570 lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidlNew)); /* set the item's data */
571 ListView_SetItemA(This->hWndList, &lvItem);
572 ListView_Update(This->hWndList, nItem);
573 return TRUE; /* FIXME: better handling */
575 return FALSE;
577 /**********************************************************
578 * ShellView_FillList()
580 * - gets the objectlist from the shellfolder
581 * - sorts the list
582 * - fills the list into the view
585 static INT CALLBACK fill_list( LPVOID ptr, LPVOID arg )
587 LPITEMIDLIST pidl = ptr;
588 IShellViewImpl *This = arg;
589 /* in a commdlg This works as a filemask*/
590 if ( IncludeObject(This, pidl)==S_OK ) LV_AddItem(This, pidl);
591 SHFree(pidl);
592 return TRUE;
595 static HRESULT ShellView_FillList(IShellViewImpl * This)
597 LPENUMIDLIST pEnumIDList;
598 LPITEMIDLIST pidl;
599 DWORD dwFetched;
600 HRESULT hRes;
601 HDPA hdpa;
603 TRACE("%p\n",This);
605 /* get the itemlist from the shfolder*/
606 hRes = IShellFolder_EnumObjects(This->pSFParent,This->hWnd, SHCONTF_NONFOLDERS | SHCONTF_FOLDERS, &pEnumIDList);
607 if (hRes != S_OK)
609 if (hRes==S_FALSE)
610 return(NOERROR);
611 return(hRes);
614 /* create a pointer array */
615 hdpa = DPA_Create(16);
616 if (!hdpa)
618 return(E_OUTOFMEMORY);
621 /* copy the items into the array*/
622 while((S_OK == IEnumIDList_Next(pEnumIDList,1, &pidl, &dwFetched)) && dwFetched)
624 if (DPA_InsertPtr(hdpa, 0x7fff, pidl) == -1)
626 SHFree(pidl);
630 /* sort the array */
631 DPA_Sort(hdpa, ShellView_CompareItems, (LPARAM)This->pSFParent);
633 /*turn the listview's redrawing off*/
634 SendMessageA(This->hWndList, WM_SETREDRAW, FALSE, 0);
636 DPA_DestroyCallback( hdpa, fill_list, This );
638 /*turn the listview's redrawing back on and force it to draw*/
639 SendMessageA(This->hWndList, WM_SETREDRAW, TRUE, 0);
641 IEnumIDList_Release(pEnumIDList); /* destroy the list*/
643 return S_OK;
646 /**********************************************************
647 * ShellView_OnCreate()
649 static LRESULT ShellView_OnCreate(IShellViewImpl * This)
651 IDropTarget* pdt;
652 SHChangeNotifyEntry ntreg;
653 IPersistFolder2 * ppf2 = NULL;
655 TRACE("%p\n",This);
657 if(ShellView_CreateList(This))
659 if(ShellView_InitList(This))
661 ShellView_FillList(This);
665 if (SUCCEEDED(IShellFolder_CreateViewObject(This->pSFParent, This->hWnd, &IID_IDropTarget, (LPVOID*)&pdt)))
667 RegisterDragDrop(This->hWnd, pdt);
668 IDropTarget_Release(pdt);
671 /* register for receiving notifications */
672 IShellFolder_QueryInterface(This->pSFParent, &IID_IPersistFolder2, (LPVOID*)&ppf2);
673 if (ppf2)
675 IPersistFolder2_GetCurFolder(ppf2, (LPITEMIDLIST*)&ntreg.pidl);
676 ntreg.fRecursive = TRUE;
677 This->hNotify = SHChangeNotifyRegister(This->hWnd, SHCNF_IDLIST, SHCNE_ALLEVENTS, SHV_CHANGE_NOTIFY, 1, &ntreg);
678 SHFree((LPITEMIDLIST)ntreg.pidl);
679 IPersistFolder2_Release(ppf2);
682 This->hAccel = LoadAcceleratorsA(shell32_hInstance, "shv_accel");
684 return S_OK;
687 /**********************************************************
688 * #### Handling of the menus ####
691 /**********************************************************
692 * ShellView_BuildFileMenu()
694 static HMENU ShellView_BuildFileMenu(IShellViewImpl * This)
695 { CHAR szText[MAX_PATH];
696 MENUITEMINFOA mii;
697 int nTools,i;
698 HMENU hSubMenu;
700 TRACE("(%p)\n",This);
702 hSubMenu = CreatePopupMenu();
703 if(hSubMenu)
704 { /*get the number of items in our global array*/
705 for(nTools = 0; Tools[nTools].idCommand != -1; nTools++){}
707 /*add the menu items*/
708 for(i = 0; i < nTools; i++)
710 LoadStringA(shell32_hInstance, Tools[i].idMenuString, szText, MAX_PATH);
712 ZeroMemory(&mii, sizeof(mii));
713 mii.cbSize = sizeof(mii);
714 mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
716 if(BTNS_SEP != Tools[i].bStyle) /* no separator*/
718 mii.fType = MFT_STRING;
719 mii.fState = MFS_ENABLED;
720 mii.dwTypeData = szText;
721 mii.wID = Tools[i].idCommand;
723 else
725 mii.fType = MFT_SEPARATOR;
727 /* tack This item onto the end of the menu */
728 InsertMenuItemA(hSubMenu, (UINT)-1, TRUE, &mii);
731 TRACE("-- return (menu=%p)\n",hSubMenu);
732 return hSubMenu;
734 /**********************************************************
735 * ShellView_MergeFileMenu()
737 static void ShellView_MergeFileMenu(IShellViewImpl * This, HMENU hSubMenu)
738 { TRACE("(%p)->(submenu=%p) stub\n",This,hSubMenu);
740 if(hSubMenu)
741 { /*insert This item at the beginning of the menu */
742 _InsertMenuItem(hSubMenu, 0, TRUE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
743 _InsertMenuItem(hSubMenu, 0, TRUE, IDM_MYFILEITEM, MFT_STRING, "dummy45", MFS_ENABLED);
746 TRACE("--\n");
749 /**********************************************************
750 * ShellView_MergeViewMenu()
753 static void ShellView_MergeViewMenu(IShellViewImpl * This, HMENU hSubMenu)
754 { MENUITEMINFOA mii;
756 TRACE("(%p)->(submenu=%p)\n",This,hSubMenu);
758 if(hSubMenu)
759 { /*add a separator at the correct position in the menu*/
760 _InsertMenuItem(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
762 ZeroMemory(&mii, sizeof(mii));
763 mii.cbSize = sizeof(mii);
764 mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_DATA;
765 mii.fType = MFT_STRING;
766 mii.dwTypeData = "View";
767 mii.hSubMenu = LoadMenuA(shell32_hInstance, "MENU_001");
768 InsertMenuItemA(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
772 /**********************************************************
773 * ShellView_GetSelections()
775 * - fills the this->apidl list with the selected objects
777 * RETURNS
778 * number of selected items
780 static UINT ShellView_GetSelections(IShellViewImpl * This)
782 LVITEMA lvItem;
783 UINT i = 0;
785 if (This->apidl)
787 SHFree(This->apidl);
790 This->cidl = ListView_GetSelectedCount(This->hWndList);
791 This->apidl = (LPITEMIDLIST*)SHAlloc(This->cidl * sizeof(LPITEMIDLIST));
793 TRACE("selected=%i\n", This->cidl);
795 if(This->apidl)
797 TRACE("-- Items selected =%u\n", This->cidl);
799 ZeroMemory(&lvItem, sizeof(lvItem));
800 lvItem.mask = LVIF_STATE | LVIF_PARAM;
801 lvItem.stateMask = LVIS_SELECTED;
803 while(ListView_GetItemA(This->hWndList, &lvItem) && (i < This->cidl))
805 if(lvItem.state & LVIS_SELECTED)
807 This->apidl[i] = (LPITEMIDLIST)lvItem.lParam;
808 i++;
809 TRACE("-- selected Item found\n");
811 lvItem.iItem++;
814 return This->cidl;
818 /**********************************************************
819 * ShellView_OpenSelectedItems()
821 static HRESULT ShellView_OpenSelectedItems(IShellViewImpl * This)
823 static UINT CF_IDLIST = 0;
824 HRESULT hr;
825 IDataObject* selection;
826 FORMATETC fetc;
827 STGMEDIUM stgm;
828 LPIDA pIDList;
829 LPCITEMIDLIST parent_pidl;
830 int i;
832 if (0 == ShellView_GetSelections(This))
834 return S_OK;
836 hr = IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl,
837 (LPCITEMIDLIST*)This->apidl, &IID_IDataObject,
838 0, (LPVOID *)&selection);
839 if (FAILED(hr))
840 return hr;
842 if (0 == CF_IDLIST)
844 CF_IDLIST = RegisterClipboardFormatA(CFSTR_SHELLIDLIST);
846 fetc.cfFormat = CF_IDLIST;
847 fetc.ptd = NULL;
848 fetc.dwAspect = DVASPECT_CONTENT;
849 fetc.lindex = -1;
850 fetc.tymed = TYMED_HGLOBAL;
852 hr = IDataObject_QueryGetData(selection, &fetc);
853 if (FAILED(hr))
854 return hr;
856 hr = IDataObject_GetData(selection, &fetc, &stgm);
857 if (FAILED(hr))
858 return hr;
860 pIDList = GlobalLock(stgm.u.hGlobal);
862 parent_pidl = (LPCITEMIDLIST) ((LPBYTE)pIDList+pIDList->aoffset[0]);
863 for (i = pIDList->cidl; i > 0; --i)
865 LPCITEMIDLIST pidl;
866 SFGAOF attribs;
868 pidl = (LPCITEMIDLIST)((LPBYTE)pIDList+pIDList->aoffset[i]);
870 attribs = SFGAO_FOLDER;
871 hr = IShellFolder_GetAttributesOf(This->pSFParent, 1, &pidl, &attribs);
873 if (SUCCEEDED(hr) && ! (attribs & SFGAO_FOLDER))
875 SHELLEXECUTEINFOA shexinfo;
877 shexinfo.cbSize = sizeof(SHELLEXECUTEINFOA);
878 shexinfo.fMask = SEE_MASK_INVOKEIDLIST; /* SEE_MASK_IDLIST is also possible. */
879 shexinfo.hwnd = NULL;
880 shexinfo.lpVerb = NULL;
881 shexinfo.lpFile = NULL;
882 shexinfo.lpParameters = NULL;
883 shexinfo.lpDirectory = NULL;
884 shexinfo.nShow = SW_NORMAL;
885 shexinfo.lpIDList = ILCombine(parent_pidl, pidl);
887 ShellExecuteExA(&shexinfo); /* Discard error/success info */
889 ILFree((LPITEMIDLIST)shexinfo.lpIDList);
893 GlobalUnlock(stgm.u.hGlobal);
894 ReleaseStgMedium(&stgm);
896 IDataObject_Release(selection);
898 return S_OK;
901 /**********************************************************
902 * ShellView_DoContextMenu()
904 static void ShellView_DoContextMenu(IShellViewImpl * This, WORD x, WORD y, BOOL bDefault)
905 { UINT uCommand;
906 DWORD wFlags;
907 HMENU hMenu;
908 BOOL fExplore = FALSE;
909 HWND hwndTree = 0;
910 LPCONTEXTMENU pContextMenu = NULL;
911 IContextMenu2 *pCM = NULL;
912 CMINVOKECOMMANDINFO cmi;
914 TRACE("(%p)->(0x%08x 0x%08x 0x%08x) stub\n",This, x, y, bDefault);
916 /* look, what's selected and create a context menu object of it*/
917 if( ShellView_GetSelections(This) )
919 IShellFolder_GetUIObjectOf( This->pSFParent, This->hWndParent, This->cidl, (LPCITEMIDLIST*)This->apidl,
920 (REFIID)&IID_IContextMenu, NULL, (LPVOID *)&pContextMenu);
922 if(pContextMenu)
924 TRACE("-- pContextMenu\n");
925 hMenu = CreatePopupMenu();
927 if( hMenu )
929 /* See if we are in Explore or Open mode. If the browser's tree is present, we are in Explore mode.*/
930 if(SUCCEEDED(IShellBrowser_GetControlWindow(This->pShellBrowser,FCW_TREE, &hwndTree)) && hwndTree)
932 TRACE("-- explore mode\n");
933 fExplore = TRUE;
936 /* build the flags depending on what we can do with the selected item */
937 wFlags = CMF_NORMAL | (This->cidl != 1 ? 0 : CMF_CANRENAME) | (fExplore ? CMF_EXPLORE : 0);
939 /* let the ContextMenu merge its items in */
940 if (SUCCEEDED(IContextMenu_QueryContextMenu( pContextMenu, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, wFlags )))
942 if (This->FolderSettings.fFlags & FWF_DESKTOP)
943 SetMenuDefaultItem(hMenu, FCIDM_SHVIEW_OPEN, MF_BYCOMMAND);
945 if( bDefault )
947 TRACE("-- get menu default command\n");
948 uCommand = GetMenuDefaultItem(hMenu, FALSE, GMDI_GOINTOPOPUPS);
950 else
952 TRACE("-- track popup\n");
953 uCommand = TrackPopupMenu( hMenu,TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
956 if(uCommand > 0)
958 TRACE("-- uCommand=%u\n", uCommand);
959 if (uCommand==FCIDM_SHVIEW_OPEN && IsInCommDlg(This))
961 TRACE("-- dlg: OnDefaultCommand\n");
962 if (FAILED(OnDefaultCommand(This)))
964 ShellView_OpenSelectedItems(This);
967 else
969 TRACE("-- explore -- invoke command\n");
970 ZeroMemory(&cmi, sizeof(cmi));
971 cmi.cbSize = sizeof(cmi);
972 cmi.hwnd = This->hWndParent; /* this window has to answer CWM_GETISHELLBROWSER */
973 cmi.lpVerb = (LPCSTR)MAKEINTRESOURCEA(uCommand);
974 IContextMenu_InvokeCommand(pContextMenu, &cmi);
977 DestroyMenu(hMenu);
980 if (pContextMenu)
981 IContextMenu_Release(pContextMenu);
984 else /* background context menu */
986 hMenu = CreatePopupMenu();
988 pCM = ISvBgCm_Constructor(This->pSFParent);
989 IContextMenu2_QueryContextMenu(pCM, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, 0);
991 uCommand = TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
992 DestroyMenu(hMenu);
994 TRACE("-- (%p)->(uCommand=0x%08x )\n",This, uCommand);
996 ZeroMemory(&cmi, sizeof(cmi));
997 cmi.cbSize = sizeof(cmi);
998 cmi.lpVerb = (LPCSTR)MAKEINTRESOURCEA(uCommand);
999 cmi.hwnd = This->hWndParent;
1000 IContextMenu2_InvokeCommand(pCM, &cmi);
1002 IContextMenu2_Release(pCM);
1006 /**********************************************************
1007 * ##### message handling #####
1010 /**********************************************************
1011 * ShellView_OnSize()
1013 static LRESULT ShellView_OnSize(IShellViewImpl * This, WORD wWidth, WORD wHeight)
1015 TRACE("%p width=%u height=%u\n",This, wWidth,wHeight);
1017 /*resize the ListView to fit our window*/
1018 if(This->hWndList)
1020 MoveWindow(This->hWndList, 0, 0, wWidth, wHeight, TRUE);
1023 return S_OK;
1025 /**********************************************************
1026 * ShellView_OnDeactivate()
1028 * NOTES
1029 * internal
1031 static void ShellView_OnDeactivate(IShellViewImpl * This)
1033 TRACE("%p\n",This);
1035 if(This->uState != SVUIA_DEACTIVATE)
1037 if(This->hMenu)
1039 IShellBrowser_SetMenuSB(This->pShellBrowser,0, 0, 0);
1040 IShellBrowser_RemoveMenusSB(This->pShellBrowser,This->hMenu);
1041 DestroyMenu(This->hMenu);
1042 This->hMenu = 0;
1045 This->uState = SVUIA_DEACTIVATE;
1049 /**********************************************************
1050 * ShellView_OnActivate()
1052 static LRESULT ShellView_OnActivate(IShellViewImpl * This, UINT uState)
1053 { OLEMENUGROUPWIDTHS omw = { {0, 0, 0, 0, 0, 0} };
1054 MENUITEMINFOA mii;
1055 CHAR szText[MAX_PATH];
1057 TRACE("%p uState=%x\n",This,uState);
1059 /*don't do anything if the state isn't really changing */
1060 if(This->uState == uState)
1062 return S_OK;
1065 ShellView_OnDeactivate(This);
1067 /*only do This if we are active */
1068 if(uState != SVUIA_DEACTIVATE)
1070 /*merge the menus */
1071 This->hMenu = CreateMenu();
1073 if(This->hMenu)
1075 IShellBrowser_InsertMenusSB(This->pShellBrowser, This->hMenu, &omw);
1076 TRACE("-- after fnInsertMenusSB\n");
1078 /*build the top level menu get the menu item's text*/
1079 strcpy(szText,"dummy 31");
1081 ZeroMemory(&mii, sizeof(mii));
1082 mii.cbSize = sizeof(mii);
1083 mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_STATE;
1084 mii.fType = MFT_STRING;
1085 mii.fState = MFS_ENABLED;
1086 mii.dwTypeData = szText;
1087 mii.hSubMenu = ShellView_BuildFileMenu(This);
1089 /*insert our menu into the menu bar*/
1090 if(mii.hSubMenu)
1092 InsertMenuItemA(This->hMenu, FCIDM_MENU_HELP, FALSE, &mii);
1095 /*get the view menu so we can merge with it*/
1096 ZeroMemory(&mii, sizeof(mii));
1097 mii.cbSize = sizeof(mii);
1098 mii.fMask = MIIM_SUBMENU;
1100 if(GetMenuItemInfoA(This->hMenu, FCIDM_MENU_VIEW, FALSE, &mii))
1102 ShellView_MergeViewMenu(This, mii.hSubMenu);
1105 /*add the items that should only be added if we have the focus*/
1106 if(SVUIA_ACTIVATE_FOCUS == uState)
1108 /*get the file menu so we can merge with it */
1109 ZeroMemory(&mii, sizeof(mii));
1110 mii.cbSize = sizeof(mii);
1111 mii.fMask = MIIM_SUBMENU;
1113 if(GetMenuItemInfoA(This->hMenu, FCIDM_MENU_FILE, FALSE, &mii))
1115 ShellView_MergeFileMenu(This, mii.hSubMenu);
1118 TRACE("-- before fnSetMenuSB\n");
1119 IShellBrowser_SetMenuSB(This->pShellBrowser, This->hMenu, 0, This->hWnd);
1122 This->uState = uState;
1123 TRACE("--\n");
1124 return S_OK;
1127 /**********************************************************
1128 * ShellView_OnSetFocus()
1131 static LRESULT ShellView_OnSetFocus(IShellViewImpl * This)
1133 TRACE("%p\n",This);
1135 /* Tell the browser one of our windows has received the focus. This
1136 should always be done before merging menus (OnActivate merges the
1137 menus) if one of our windows has the focus.*/
1139 IShellBrowser_OnViewWindowActive(This->pShellBrowser,(IShellView*) This);
1140 ShellView_OnActivate(This, SVUIA_ACTIVATE_FOCUS);
1142 /* Set the focus to the listview */
1143 SetFocus(This->hWndList);
1145 /* Notify the ICommDlgBrowser interface */
1146 OnStateChange(This,CDBOSC_SETFOCUS);
1148 return 0;
1151 /**********************************************************
1152 * ShellView_OnKillFocus()
1154 static LRESULT ShellView_OnKillFocus(IShellViewImpl * This)
1156 TRACE("(%p) stub\n",This);
1158 ShellView_OnActivate(This, SVUIA_ACTIVATE_NOFOCUS);
1159 /* Notify the ICommDlgBrowser */
1160 OnStateChange(This,CDBOSC_KILLFOCUS);
1162 return 0;
1165 /**********************************************************
1166 * ShellView_OnCommand()
1168 * NOTES
1169 * the CmdID's are the ones from the context menu
1171 static LRESULT ShellView_OnCommand(IShellViewImpl * This,DWORD dwCmdID, DWORD dwCmd, HWND hwndCmd)
1173 TRACE("(%p)->(0x%08lx 0x%08lx %p) stub\n",This, dwCmdID, dwCmd, hwndCmd);
1175 switch(dwCmdID)
1177 case FCIDM_SHVIEW_SMALLICON:
1178 This->FolderSettings.ViewMode = FVM_SMALLICON;
1179 SetStyle (This, LVS_SMALLICON, LVS_TYPEMASK);
1180 CheckToolbar(This);
1181 break;
1183 case FCIDM_SHVIEW_BIGICON:
1184 This->FolderSettings.ViewMode = FVM_ICON;
1185 SetStyle (This, LVS_ICON, LVS_TYPEMASK);
1186 CheckToolbar(This);
1187 break;
1189 case FCIDM_SHVIEW_LISTVIEW:
1190 This->FolderSettings.ViewMode = FVM_LIST;
1191 SetStyle (This, LVS_LIST, LVS_TYPEMASK);
1192 CheckToolbar(This);
1193 break;
1195 case FCIDM_SHVIEW_REPORTVIEW:
1196 This->FolderSettings.ViewMode = FVM_DETAILS;
1197 SetStyle (This, LVS_REPORT, LVS_TYPEMASK);
1198 CheckToolbar(This);
1199 break;
1201 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1202 case 0x30:
1203 case 0x31:
1204 case 0x32:
1205 case 0x33:
1206 This->ListViewSortInfo.nHeaderID = (LPARAM) (dwCmdID - 0x30);
1207 This->ListViewSortInfo.bIsAscending = TRUE;
1208 This->ListViewSortInfo.nLastHeaderID = This->ListViewSortInfo.nHeaderID;
1209 ListView_SortItems(This->hWndList, ShellView_ListViewCompareItems, (LPARAM) (&(This->ListViewSortInfo)));
1210 break;
1212 default:
1213 TRACE("-- COMMAND 0x%04lx unhandled\n", dwCmdID);
1215 return 0;
1218 /**********************************************************
1219 * ShellView_OnNotify()
1222 static LRESULT ShellView_OnNotify(IShellViewImpl * This, UINT CtlID, LPNMHDR lpnmh)
1223 { LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)lpnmh;
1224 NMLVDISPINFOA *lpdi = (NMLVDISPINFOA *)lpnmh;
1225 LPITEMIDLIST pidl;
1227 TRACE("%p CtlID=%u lpnmh->code=%x\n",This,CtlID,lpnmh->code);
1229 switch(lpnmh->code)
1231 case NM_SETFOCUS:
1232 TRACE("-- NM_SETFOCUS %p\n",This);
1233 ShellView_OnSetFocus(This);
1234 break;
1236 case NM_KILLFOCUS:
1237 TRACE("-- NM_KILLFOCUS %p\n",This);
1238 ShellView_OnDeactivate(This);
1239 /* Notify the ICommDlgBrowser interface */
1240 OnStateChange(This,CDBOSC_KILLFOCUS);
1241 break;
1243 case NM_CUSTOMDRAW:
1244 TRACE("-- NM_CUSTOMDRAW %p\n",This);
1245 return CDRF_DODEFAULT;
1247 case NM_RELEASEDCAPTURE:
1248 TRACE("-- NM_RELEASEDCAPTURE %p\n",This);
1249 break;
1251 case NM_CLICK:
1252 TRACE("-- NM_CLICK %p\n",This);
1253 break;
1255 case NM_RCLICK:
1256 TRACE("-- NM_RCLICK %p\n",This);
1257 break;
1259 case HDN_ENDTRACKA:
1260 TRACE("-- HDN_ENDTRACKA %p\n",This);
1261 /*nColumn1 = ListView_GetColumnWidth(This->hWndList, 0);
1262 nColumn2 = ListView_GetColumnWidth(This->hWndList, 1);*/
1263 break;
1265 case LVN_DELETEITEM:
1266 TRACE("-- LVN_DELETEITEM %p\n",This);
1267 SHFree((LPITEMIDLIST)lpnmlv->lParam); /*delete the pidl because we made a copy of it*/
1268 break;
1270 case LVN_DELETEALLITEMS:
1271 TRACE("-- LVN_DELETEALLITEMS %p\n",This);
1272 return FALSE;
1274 case LVN_INSERTITEM:
1275 TRACE("-- LVN_INSERTITEM (STUB)%p\n",This);
1276 break;
1278 case LVN_ITEMACTIVATE:
1279 TRACE("-- LVN_ITEMACTIVATE %p\n",This);
1280 OnStateChange(This, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
1281 ShellView_DoContextMenu(This, 0, 0, TRUE);
1282 break;
1284 case LVN_COLUMNCLICK:
1285 This->ListViewSortInfo.nHeaderID = lpnmlv->iSubItem;
1286 if(This->ListViewSortInfo.nLastHeaderID == This->ListViewSortInfo.nHeaderID)
1288 This->ListViewSortInfo.bIsAscending = !This->ListViewSortInfo.bIsAscending;
1290 else
1292 This->ListViewSortInfo.bIsAscending = TRUE;
1294 This->ListViewSortInfo.nLastHeaderID = This->ListViewSortInfo.nHeaderID;
1296 ListView_SortItems(lpnmlv->hdr.hwndFrom, ShellView_ListViewCompareItems, (LPARAM) (&(This->ListViewSortInfo)));
1297 break;
1299 case LVN_GETDISPINFOA:
1300 case LVN_GETDISPINFOW:
1301 TRACE("-- LVN_GETDISPINFO %p\n",This);
1302 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1304 if(lpdi->item.mask & LVIF_TEXT) /* text requested */
1306 if (This->pSF2Parent)
1308 SHELLDETAILS sd;
1309 IShellFolder2_GetDetailsOf(This->pSF2Parent, pidl, lpdi->item.iSubItem, &sd);
1310 if (lpnmh->code == LVN_GETDISPINFOA)
1312 StrRetToStrNA( lpdi->item.pszText, lpdi->item.cchTextMax, &sd.str, NULL);
1313 TRACE("-- text=%s\n",lpdi->item.pszText);
1315 else /* LVN_GETDISPINFOW */
1317 StrRetToStrNW( ((NMLVDISPINFOW *)lpdi)->item.pszText, lpdi->item.cchTextMax, &sd.str, NULL);
1318 TRACE("-- text=%s\n",debugstr_w((WCHAR*)(lpdi->item.pszText)));
1321 else
1323 FIXME("no SF2\n");
1326 if(lpdi->item.mask & LVIF_IMAGE) /* image requested */
1328 lpdi->item.iImage = SHMapPIDLToSystemImageListIndex(This->pSFParent, pidl, 0);
1330 break;
1332 case LVN_ITEMCHANGED:
1333 TRACE("-- LVN_ITEMCHANGED %p\n",This);
1334 OnStateChange(This, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
1335 break;
1337 case LVN_BEGINDRAG:
1338 case LVN_BEGINRDRAG:
1339 TRACE("-- LVN_BEGINDRAG\n");
1341 if (ShellView_GetSelections(This))
1343 IDataObject * pda;
1344 DWORD dwAttributes = SFGAO_CANLINK;
1345 DWORD dwEffect = DROPEFFECT_COPY | DROPEFFECT_MOVE;
1347 if (SUCCEEDED(IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, (LPCITEMIDLIST*)This->apidl, &IID_IDataObject,0,(LPVOID *)&pda)))
1349 IDropSource * pds = (IDropSource*)&(This->lpvtblDropSource); /* own DropSource interface */
1351 if (SUCCEEDED(IShellFolder_GetAttributesOf(This->pSFParent, This->cidl, (LPCITEMIDLIST*)This->apidl, &dwAttributes)))
1353 if (dwAttributes & SFGAO_CANLINK)
1355 dwEffect |= DROPEFFECT_LINK;
1359 if (pds)
1361 DWORD dwEffect;
1362 DoDragDrop(pda, pds, dwEffect, &dwEffect);
1364 IDataObject_Release(pda);
1367 break;
1369 case LVN_BEGINLABELEDITA:
1371 DWORD dwAttr = SFGAO_CANRENAME;
1372 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1374 TRACE("-- LVN_BEGINLABELEDITA %p\n",This);
1376 IShellFolder_GetAttributesOf(This->pSFParent, 1, (LPCITEMIDLIST*)&pidl, &dwAttr);
1377 if (SFGAO_CANRENAME & dwAttr)
1379 return FALSE;
1381 return TRUE;
1384 case LVN_ENDLABELEDITA:
1386 TRACE("-- LVN_ENDLABELEDITA %p\n",This);
1387 if (lpdi->item.pszText)
1389 HRESULT hr;
1390 WCHAR wszNewName[MAX_PATH];
1391 LVITEMA lvItem;
1393 ZeroMemory(&lvItem, sizeof(LVITEMA));
1394 lvItem.iItem = lpdi->item.iItem;
1395 lvItem.mask = LVIF_PARAM;
1396 ListView_GetItemA(This->hWndList, &lvItem);
1398 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1399 if (!MultiByteToWideChar( CP_ACP, 0, lpdi->item.pszText, -1, wszNewName, MAX_PATH ))
1400 wszNewName[MAX_PATH-1] = 0;
1401 hr = IShellFolder_SetNameOf(This->pSFParent, 0, pidl, wszNewName, SHGDN_INFOLDER, &pidl);
1403 if(SUCCEEDED(hr) && pidl)
1405 lvItem.mask = LVIF_PARAM;
1406 lvItem.lParam = (LPARAM)pidl;
1407 ListView_SetItemA(This->hWndList, &lvItem);
1408 return TRUE;
1411 return FALSE;
1414 case LVN_KEYDOWN:
1416 /* MSG msg;
1417 msg.hwnd = This->hWnd;
1418 msg.message = WM_KEYDOWN;
1419 msg.wParam = plvKeyDown->wVKey;
1420 msg.lParam = 0;
1421 msg.time = 0;
1422 msg.pt = 0;*/
1424 LPNMLVKEYDOWN plvKeyDown = (LPNMLVKEYDOWN) lpnmh;
1426 /* initiate a rename of the selected file or directory */
1427 if(plvKeyDown->wVKey == VK_F2)
1429 /* see how many files are selected */
1430 int i = ListView_GetSelectedCount(This->hWndList);
1432 /* get selected item */
1433 if(i == 1)
1435 /* get selected item */
1436 i = ListView_GetNextItem(This->hWndList, -1,
1437 LVNI_SELECTED);
1439 ListView_EnsureVisible(This->hWndList, i, 0);
1440 ListView_EditLabelA(This->hWndList, i);
1443 #if 0
1444 TranslateAccelerator(This->hWnd, This->hAccel, &msg)
1445 #endif
1446 else if(plvKeyDown->wVKey == VK_DELETE)
1448 UINT i;
1449 int item_index;
1450 LVITEMA item;
1451 LPITEMIDLIST* pItems;
1452 ISFHelper *psfhlp;
1454 IShellFolder_QueryInterface(This->pSFParent, &IID_ISFHelper,
1455 (LPVOID*)&psfhlp);
1457 if(!(i = ListView_GetSelectedCount(This->hWndList)))
1458 break;
1460 /* allocate memory for the pidl array */
1461 pItems = HeapAlloc(GetProcessHeap(), 0,
1462 sizeof(LPITEMIDLIST) * i);
1464 /* retrieve all selected items */
1465 i = 0;
1466 item_index = -1;
1467 while(ListView_GetSelectedCount(This->hWndList) > i)
1469 /* get selected item */
1470 item_index = ListView_GetNextItem(This->hWndList,
1471 item_index, LVNI_SELECTED);
1472 item.iItem = item_index;
1473 item.mask |= LVIF_PARAM;
1474 ListView_GetItemA(This->hWndList, &item);
1476 /* get item pidl */
1477 pItems[i] = (LPITEMIDLIST)item.lParam;
1479 i++;
1482 /* perform the item deletion */
1483 ISFHelper_DeleteItems(psfhlp, i, (LPCITEMIDLIST*)pItems);
1485 /* free pidl array memory */
1486 HeapFree(GetProcessHeap(), 0, pItems);
1488 else
1489 FIXME("LVN_KEYDOWN key=0x%08x\n",plvKeyDown->wVKey);
1491 break;
1493 default:
1494 TRACE("-- %p WM_COMMAND %x unhandled\n", This, lpnmh->code);
1495 break;
1497 return 0;
1500 /**********************************************************
1501 * ShellView_OnChange()
1504 static LRESULT ShellView_OnChange(IShellViewImpl * This, LPITEMIDLIST * Pidls, LONG wEventId)
1507 TRACE("(%p)(%p,%p,0x%08lx)\n", This, Pidls[0], Pidls[1], wEventId);
1508 switch(wEventId)
1510 case SHCNE_MKDIR:
1511 case SHCNE_CREATE:
1512 LV_AddItem(This, Pidls[0]);
1513 break;
1514 case SHCNE_RMDIR:
1515 case SHCNE_DELETE:
1516 LV_DeleteItem(This, Pidls[0]);
1517 break;
1518 case SHCNE_RENAMEFOLDER:
1519 case SHCNE_RENAMEITEM:
1520 LV_RenameItem(This, Pidls[0], Pidls[1]);
1521 break;
1522 case SHCNE_UPDATEITEM:
1523 break;
1525 return TRUE;
1527 /**********************************************************
1528 * ShellView_WndProc
1531 static LRESULT CALLBACK ShellView_WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
1533 IShellViewImpl * pThis = (IShellViewImpl*)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
1534 LPCREATESTRUCTA lpcs;
1536 TRACE("(hwnd=%p msg=%x wparm=%x lparm=%lx)\n",hWnd, uMessage, wParam, lParam);
1538 switch (uMessage)
1540 case WM_NCCREATE:
1541 lpcs = (LPCREATESTRUCTA)lParam;
1542 pThis = (IShellViewImpl*)(lpcs->lpCreateParams);
1543 SetWindowLongPtrW(hWnd, GWLP_USERDATA, (ULONG_PTR)pThis);
1544 pThis->hWnd = hWnd; /*set the window handle*/
1545 break;
1547 case WM_SIZE: return ShellView_OnSize(pThis,LOWORD(lParam), HIWORD(lParam));
1548 case WM_SETFOCUS: return ShellView_OnSetFocus(pThis);
1549 case WM_KILLFOCUS: return ShellView_OnKillFocus(pThis);
1550 case WM_CREATE: return ShellView_OnCreate(pThis);
1551 case WM_ACTIVATE: return ShellView_OnActivate(pThis, SVUIA_ACTIVATE_FOCUS);
1552 case WM_NOTIFY: return ShellView_OnNotify(pThis,(UINT)wParam, (LPNMHDR)lParam);
1553 case WM_COMMAND: return ShellView_OnCommand(pThis,
1554 GET_WM_COMMAND_ID(wParam, lParam),
1555 GET_WM_COMMAND_CMD(wParam, lParam),
1556 GET_WM_COMMAND_HWND(wParam, lParam));
1557 case SHV_CHANGE_NOTIFY: return ShellView_OnChange(pThis, (LPITEMIDLIST*)wParam, (LONG)lParam);
1559 case WM_CONTEXTMENU: ShellView_DoContextMenu(pThis, LOWORD(lParam), HIWORD(lParam), FALSE);
1560 return 0;
1562 case WM_SHOWWINDOW: UpdateWindow(pThis->hWndList);
1563 break;
1565 case WM_GETDLGCODE: return SendMessageA(pThis->hWndList,uMessage,0,0);
1567 case WM_DESTROY:
1568 RevokeDragDrop(pThis->hWnd);
1569 SHChangeNotifyDeregister(pThis->hNotify);
1570 break;
1572 case WM_ERASEBKGND:
1573 if ((pThis->FolderSettings.fFlags & FWF_DESKTOP) ||
1574 (pThis->FolderSettings.fFlags & FWF_TRANSPARENT))
1575 return 1;
1576 break;
1579 return DefWindowProcA (hWnd, uMessage, wParam, lParam);
1581 /**********************************************************
1584 * The INTERFACE of the IShellView object
1587 **********************************************************
1588 * IShellView_QueryInterface
1590 static HRESULT WINAPI IShellView_fnQueryInterface(IShellView * iface,REFIID riid, LPVOID *ppvObj)
1592 IShellViewImpl *This = (IShellViewImpl *)iface;
1594 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1596 *ppvObj = NULL;
1598 if(IsEqualIID(riid, &IID_IUnknown))
1600 *ppvObj = This;
1602 else if(IsEqualIID(riid, &IID_IShellView))
1604 *ppvObj = (IShellView*)This;
1606 else if(IsEqualIID(riid, &IID_IOleCommandTarget))
1608 *ppvObj = (IOleCommandTarget*)&(This->lpvtblOleCommandTarget);
1610 else if(IsEqualIID(riid, &IID_IDropTarget))
1612 *ppvObj = (IDropTarget*)&(This->lpvtblDropTarget);
1614 else if(IsEqualIID(riid, &IID_IDropSource))
1616 *ppvObj = (IDropSource*)&(This->lpvtblDropSource);
1618 else if(IsEqualIID(riid, &IID_IViewObject))
1620 *ppvObj = (IViewObject*)&(This->lpvtblViewObject);
1623 if(*ppvObj)
1625 IUnknown_AddRef( (IUnknown*)*ppvObj );
1626 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1627 return S_OK;
1629 TRACE("-- Interface: E_NOINTERFACE\n");
1630 return E_NOINTERFACE;
1633 /**********************************************************
1634 * IShellView_AddRef
1636 static ULONG WINAPI IShellView_fnAddRef(IShellView * iface)
1638 IShellViewImpl *This = (IShellViewImpl *)iface;
1639 ULONG refCount = InterlockedIncrement(&This->ref);
1641 TRACE("(%p)->(count=%lu)\n", This, refCount - 1);
1643 return refCount;
1645 /**********************************************************
1646 * IShellView_Release
1648 static ULONG WINAPI IShellView_fnRelease(IShellView * iface)
1650 IShellViewImpl *This = (IShellViewImpl *)iface;
1651 ULONG refCount = InterlockedDecrement(&This->ref);
1653 TRACE("(%p)->(count=%li)\n", This, refCount + 1);
1655 if (!refCount)
1657 TRACE(" destroying IShellView(%p)\n",This);
1659 DestroyWindow(This->hWndList);
1661 if(This->pSFParent)
1662 IShellFolder_Release(This->pSFParent);
1664 if(This->pSF2Parent)
1665 IShellFolder2_Release(This->pSF2Parent);
1667 if (This->apidl)
1668 SHFree(This->apidl);
1670 HeapFree(GetProcessHeap(),0,This);
1672 return refCount;
1675 /**********************************************************
1676 * ShellView_GetWindow
1678 static HRESULT WINAPI IShellView_fnGetWindow(IShellView * iface,HWND * phWnd)
1680 IShellViewImpl *This = (IShellViewImpl *)iface;
1682 TRACE("(%p)\n",This);
1684 *phWnd = This->hWnd;
1686 return S_OK;
1689 static HRESULT WINAPI IShellView_fnContextSensitiveHelp(IShellView * iface,BOOL fEnterMode)
1691 IShellViewImpl *This = (IShellViewImpl *)iface;
1693 FIXME("(%p) stub\n",This);
1695 return E_NOTIMPL;
1698 /**********************************************************
1699 * IShellView_TranslateAccelerator
1701 * FIXME:
1702 * use the accel functions
1704 static HRESULT WINAPI IShellView_fnTranslateAccelerator(IShellView * iface,LPMSG lpmsg)
1706 #if 0
1707 IShellViewImpl *This = (IShellViewImpl *)iface;
1709 FIXME("(%p)->(%p: hwnd=%x msg=%x lp=%lx wp=%x) stub\n",This,lpmsg, lpmsg->hwnd, lpmsg->message, lpmsg->lParam, lpmsg->wParam);
1710 #endif
1712 if ((lpmsg->message>=WM_KEYFIRST) && (lpmsg->message>=WM_KEYLAST))
1714 TRACE("-- key=0x04%x\n",lpmsg->wParam) ;
1716 return S_FALSE; /* not handled */
1719 static HRESULT WINAPI IShellView_fnEnableModeless(IShellView * iface,BOOL fEnable)
1721 IShellViewImpl *This = (IShellViewImpl *)iface;
1723 FIXME("(%p) stub\n",This);
1725 return E_NOTIMPL;
1728 static HRESULT WINAPI IShellView_fnUIActivate(IShellView * iface,UINT uState)
1730 IShellViewImpl *This = (IShellViewImpl *)iface;
1733 CHAR szName[MAX_PATH];
1735 LRESULT lResult;
1736 int nPartArray[1] = {-1};
1738 TRACE("(%p)->(state=%x) stub\n",This, uState);
1740 /*don't do anything if the state isn't really changing*/
1741 if(This->uState == uState)
1743 return S_OK;
1746 /*OnActivate handles the menu merging and internal state*/
1747 ShellView_OnActivate(This, uState);
1749 /*only do This if we are active*/
1750 if(uState != SVUIA_DEACTIVATE)
1754 GetFolderPath is not a method of IShellFolder
1755 IShellFolder_GetFolderPath( This->pSFParent, szName, sizeof(szName) );
1757 /* set the number of parts */
1758 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETPARTS, 1,
1759 (LPARAM)nPartArray, &lResult);
1761 /* set the text for the parts */
1763 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETTEXTA,
1764 0, (LPARAM)szName, &lResult);
1768 return S_OK;
1771 static HRESULT WINAPI IShellView_fnRefresh(IShellView * iface)
1773 IShellViewImpl *This = (IShellViewImpl *)iface;
1775 TRACE("(%p)\n",This);
1777 ListView_DeleteAllItems(This->hWndList);
1778 ShellView_FillList(This);
1780 return S_OK;
1783 static HRESULT WINAPI IShellView_fnCreateViewWindow(
1784 IShellView * iface,
1785 IShellView *lpPrevView,
1786 LPCFOLDERSETTINGS lpfs,
1787 IShellBrowser * psb,
1788 RECT * prcView,
1789 HWND *phWnd)
1791 IShellViewImpl *This = (IShellViewImpl *)iface;
1793 WNDCLASSA wc;
1794 *phWnd = 0;
1797 TRACE("(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n",This, lpPrevView,lpfs, psb, prcView, phWnd);
1798 TRACE("-- vmode=%x flags=%x left=%li top=%li right=%li bottom=%li\n",lpfs->ViewMode, lpfs->fFlags ,prcView->left,prcView->top, prcView->right, prcView->bottom);
1800 /*set up the member variables*/
1801 This->pShellBrowser = psb;
1802 This->FolderSettings = *lpfs;
1804 /*get our parent window*/
1805 IShellBrowser_AddRef(This->pShellBrowser);
1806 IShellBrowser_GetWindow(This->pShellBrowser, &(This->hWndParent));
1808 /* try to get the ICommDlgBrowserInterface, adds a reference !!! */
1809 This->pCommDlgBrowser=NULL;
1810 if ( SUCCEEDED (IShellBrowser_QueryInterface( This->pShellBrowser,
1811 (REFIID)&IID_ICommDlgBrowser, (LPVOID*) &This->pCommDlgBrowser)))
1813 TRACE("-- CommDlgBrowser\n");
1816 /*if our window class has not been registered, then do so*/
1817 if(!GetClassInfoA(shell32_hInstance, SV_CLASS_NAME, &wc))
1819 ZeroMemory(&wc, sizeof(wc));
1820 wc.style = CS_HREDRAW | CS_VREDRAW;
1821 wc.lpfnWndProc = ShellView_WndProc;
1822 wc.cbClsExtra = 0;
1823 wc.cbWndExtra = 0;
1824 wc.hInstance = shell32_hInstance;
1825 wc.hIcon = 0;
1826 wc.hCursor = LoadCursorA (0, (LPSTR)IDC_ARROW);
1827 wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
1828 wc.lpszMenuName = NULL;
1829 wc.lpszClassName = SV_CLASS_NAME;
1831 if(!RegisterClassA(&wc))
1832 return E_FAIL;
1835 *phWnd = CreateWindowExA(0,
1836 SV_CLASS_NAME,
1837 NULL,
1838 WS_CHILD | WS_VISIBLE | WS_TABSTOP,
1839 prcView->left,
1840 prcView->top,
1841 prcView->right - prcView->left,
1842 prcView->bottom - prcView->top,
1843 This->hWndParent,
1845 shell32_hInstance,
1846 (LPVOID)This);
1848 CheckToolbar(This);
1850 if(!*phWnd) return E_FAIL;
1852 return S_OK;
1855 static HRESULT WINAPI IShellView_fnDestroyViewWindow(IShellView * iface)
1857 IShellViewImpl *This = (IShellViewImpl *)iface;
1859 TRACE("(%p)\n",This);
1861 /*Make absolutely sure all our UI is cleaned up.*/
1862 IShellView_UIActivate((IShellView*)This, SVUIA_DEACTIVATE);
1864 if(This->hMenu)
1866 DestroyMenu(This->hMenu);
1869 DestroyWindow(This->hWnd);
1870 if(This->pShellBrowser) IShellBrowser_Release(This->pShellBrowser);
1871 if(This->pCommDlgBrowser) ICommDlgBrowser_Release(This->pCommDlgBrowser);
1874 return S_OK;
1877 static HRESULT WINAPI IShellView_fnGetCurrentInfo(IShellView * iface, LPFOLDERSETTINGS lpfs)
1879 IShellViewImpl *This = (IShellViewImpl *)iface;
1881 TRACE("(%p)->(%p) vmode=%x flags=%x\n",This, lpfs,
1882 This->FolderSettings.ViewMode, This->FolderSettings.fFlags);
1884 if (!lpfs) return E_INVALIDARG;
1886 *lpfs = This->FolderSettings;
1887 return NOERROR;
1890 static HRESULT WINAPI IShellView_fnAddPropertySheetPages(IShellView * iface, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam)
1892 IShellViewImpl *This = (IShellViewImpl *)iface;
1894 FIXME("(%p) stub\n",This);
1896 return E_NOTIMPL;
1899 static HRESULT WINAPI IShellView_fnSaveViewState(IShellView * iface)
1901 IShellViewImpl *This = (IShellViewImpl *)iface;
1903 FIXME("(%p) stub\n",This);
1905 return S_OK;
1908 static HRESULT WINAPI IShellView_fnSelectItem(
1909 IShellView * iface,
1910 LPCITEMIDLIST pidl,
1911 UINT uFlags)
1913 IShellViewImpl *This = (IShellViewImpl *)iface;
1914 int i;
1916 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n",This, pidl, uFlags);
1918 i = LV_FindItemByPidl(This, pidl);
1920 if (i != -1)
1922 LVITEMA lvItem;
1924 if(uFlags & SVSI_ENSUREVISIBLE)
1925 ListView_EnsureVisible(This->hWndList, i, 0);
1927 ZeroMemory(&lvItem, sizeof(LVITEMA));
1928 lvItem.mask = LVIF_STATE;
1929 lvItem.iItem = 0;
1931 while(ListView_GetItemA(This->hWndList, &lvItem))
1933 if (lvItem.iItem == i)
1935 if (uFlags & SVSI_SELECT)
1936 lvItem.state |= LVIS_SELECTED;
1937 else
1938 lvItem.state &= ~LVIS_SELECTED;
1940 if(uFlags & SVSI_FOCUSED)
1941 lvItem.state &= ~LVIS_FOCUSED;
1943 else
1945 if (uFlags & SVSI_DESELECTOTHERS)
1946 lvItem.state &= ~LVIS_SELECTED;
1948 ListView_SetItemA(This->hWndList, &lvItem);
1949 lvItem.iItem++;
1953 if(uFlags & SVSI_EDIT)
1954 ListView_EditLabelA(This->hWndList, i);
1957 return S_OK;
1960 static HRESULT WINAPI IShellView_fnGetItemObject(IShellView * iface, UINT uItem, REFIID riid, LPVOID *ppvOut)
1962 IShellViewImpl *This = (IShellViewImpl *)iface;
1964 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n",This, uItem, debugstr_guid(riid), ppvOut);
1966 *ppvOut = NULL;
1968 switch(uItem)
1970 case SVGIO_BACKGROUND:
1971 *ppvOut = ISvBgCm_Constructor(This->pSFParent);
1972 break;
1974 case SVGIO_SELECTION:
1975 ShellView_GetSelections(This);
1976 IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, (LPCITEMIDLIST*)This->apidl, riid, 0, ppvOut);
1977 break;
1979 TRACE("-- (%p)->(interface=%p)\n",This, *ppvOut);
1981 if(!*ppvOut) return E_OUTOFMEMORY;
1983 return S_OK;
1986 static struct IShellViewVtbl svvt =
1988 IShellView_fnQueryInterface,
1989 IShellView_fnAddRef,
1990 IShellView_fnRelease,
1991 IShellView_fnGetWindow,
1992 IShellView_fnContextSensitiveHelp,
1993 IShellView_fnTranslateAccelerator,
1994 IShellView_fnEnableModeless,
1995 IShellView_fnUIActivate,
1996 IShellView_fnRefresh,
1997 IShellView_fnCreateViewWindow,
1998 IShellView_fnDestroyViewWindow,
1999 IShellView_fnGetCurrentInfo,
2000 IShellView_fnAddPropertySheetPages,
2001 IShellView_fnSaveViewState,
2002 IShellView_fnSelectItem,
2003 IShellView_fnGetItemObject
2007 /**********************************************************
2008 * ISVOleCmdTarget_QueryInterface (IUnknown)
2010 static HRESULT WINAPI ISVOleCmdTarget_QueryInterface(
2011 IOleCommandTarget * iface,
2012 REFIID iid,
2013 LPVOID* ppvObj)
2015 _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
2017 return IShellFolder_QueryInterface((IShellFolder*)This, iid, ppvObj);
2020 /**********************************************************
2021 * ISVOleCmdTarget_AddRef (IUnknown)
2023 static ULONG WINAPI ISVOleCmdTarget_AddRef(
2024 IOleCommandTarget * iface)
2026 _ICOM_THIS_From_IOleCommandTarget(IShellFolder, iface);
2028 return IShellFolder_AddRef((IShellFolder*)This);
2031 /**********************************************************
2032 * ISVOleCmdTarget_Release (IUnknown)
2034 static ULONG WINAPI ISVOleCmdTarget_Release(
2035 IOleCommandTarget * iface)
2037 _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
2039 return IShellFolder_Release((IShellFolder*)This);
2042 /**********************************************************
2043 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
2045 static HRESULT WINAPI ISVOleCmdTarget_QueryStatus(
2046 IOleCommandTarget *iface,
2047 const GUID* pguidCmdGroup,
2048 ULONG cCmds,
2049 OLECMD * prgCmds,
2050 OLECMDTEXT* pCmdText)
2052 UINT i;
2053 _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
2055 FIXME("(%p)->(%p(%s) 0x%08lx %p %p\n",
2056 This, pguidCmdGroup, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText);
2058 if (!prgCmds)
2059 return E_POINTER;
2060 for (i = 0; i < cCmds; i++)
2062 FIXME("\tprgCmds[%d].cmdID = %ld\n", i, prgCmds[i].cmdID);
2063 prgCmds[i].cmdf = 0;
2065 return OLECMDERR_E_UNKNOWNGROUP;
2068 /**********************************************************
2069 * ISVOleCmdTarget_Exec (IOleCommandTarget)
2071 * nCmdID is the OLECMDID_* enumeration
2073 static HRESULT WINAPI ISVOleCmdTarget_Exec(
2074 IOleCommandTarget *iface,
2075 const GUID* pguidCmdGroup,
2076 DWORD nCmdID,
2077 DWORD nCmdexecopt,
2078 VARIANT* pvaIn,
2079 VARIANT* pvaOut)
2081 _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
2083 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08lx Opt:0x%08lx %p %p)\n",
2084 This, debugstr_guid(pguidCmdGroup), nCmdID, nCmdexecopt, pvaIn, pvaOut);
2086 if (IsEqualIID(pguidCmdGroup, &CGID_Explorer) &&
2087 (nCmdID == 0x29) &&
2088 (nCmdexecopt == 4) && pvaOut)
2089 return S_OK;
2090 if (IsEqualIID(pguidCmdGroup, &CGID_ShellDocView) &&
2091 (nCmdID == 9) &&
2092 (nCmdexecopt == 0))
2093 return 1;
2095 return OLECMDERR_E_UNKNOWNGROUP;
2098 static IOleCommandTargetVtbl ctvt =
2100 ISVOleCmdTarget_QueryInterface,
2101 ISVOleCmdTarget_AddRef,
2102 ISVOleCmdTarget_Release,
2103 ISVOleCmdTarget_QueryStatus,
2104 ISVOleCmdTarget_Exec
2107 /**********************************************************
2108 * ISVDropTarget implementation
2111 static HRESULT WINAPI ISVDropTarget_QueryInterface(
2112 IDropTarget *iface,
2113 REFIID riid,
2114 LPVOID *ppvObj)
2116 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2118 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2120 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2123 static ULONG WINAPI ISVDropTarget_AddRef( IDropTarget *iface)
2125 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2127 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2129 return IShellFolder_AddRef((IShellFolder*)This);
2132 static ULONG WINAPI ISVDropTarget_Release( IDropTarget *iface)
2134 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2136 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2138 return IShellFolder_Release((IShellFolder*)This);
2141 static HRESULT WINAPI ISVDropTarget_DragEnter(
2142 IDropTarget *iface,
2143 IDataObject *pDataObject,
2144 DWORD grfKeyState,
2145 POINTL pt,
2146 DWORD *pdwEffect)
2149 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2151 FIXME("Stub: This=%p, DataObject=%p\n",This,pDataObject);
2153 return E_NOTIMPL;
2156 static HRESULT WINAPI ISVDropTarget_DragOver(
2157 IDropTarget *iface,
2158 DWORD grfKeyState,
2159 POINTL pt,
2160 DWORD *pdwEffect)
2162 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2164 FIXME("Stub: This=%p\n",This);
2166 return E_NOTIMPL;
2169 static HRESULT WINAPI ISVDropTarget_DragLeave(
2170 IDropTarget *iface)
2172 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2174 FIXME("Stub: This=%p\n",This);
2176 return E_NOTIMPL;
2179 static HRESULT WINAPI ISVDropTarget_Drop(
2180 IDropTarget *iface,
2181 IDataObject* pDataObject,
2182 DWORD grfKeyState,
2183 POINTL pt,
2184 DWORD *pdwEffect)
2186 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2188 FIXME("Stub: This=%p\n",This);
2190 return E_NOTIMPL;
2193 static struct IDropTargetVtbl dtvt =
2195 ISVDropTarget_QueryInterface,
2196 ISVDropTarget_AddRef,
2197 ISVDropTarget_Release,
2198 ISVDropTarget_DragEnter,
2199 ISVDropTarget_DragOver,
2200 ISVDropTarget_DragLeave,
2201 ISVDropTarget_Drop
2204 /**********************************************************
2205 * ISVDropSource implementation
2208 static HRESULT WINAPI ISVDropSource_QueryInterface(
2209 IDropSource *iface,
2210 REFIID riid,
2211 LPVOID *ppvObj)
2213 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2215 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2217 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2220 static ULONG WINAPI ISVDropSource_AddRef( IDropSource *iface)
2222 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2224 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2226 return IShellFolder_AddRef((IShellFolder*)This);
2229 static ULONG WINAPI ISVDropSource_Release( IDropSource *iface)
2231 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2233 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2235 return IShellFolder_Release((IShellFolder*)This);
2237 static HRESULT WINAPI ISVDropSource_QueryContinueDrag(
2238 IDropSource *iface,
2239 BOOL fEscapePressed,
2240 DWORD grfKeyState)
2242 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2243 TRACE("(%p)\n",This);
2245 if (fEscapePressed)
2246 return DRAGDROP_S_CANCEL;
2247 else if (!(grfKeyState & MK_LBUTTON) && !(grfKeyState & MK_RBUTTON))
2248 return DRAGDROP_S_DROP;
2249 else
2250 return NOERROR;
2253 static HRESULT WINAPI ISVDropSource_GiveFeedback(
2254 IDropSource *iface,
2255 DWORD dwEffect)
2257 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2258 TRACE("(%p)\n",This);
2260 return DRAGDROP_S_USEDEFAULTCURSORS;
2263 static struct IDropSourceVtbl dsvt =
2265 ISVDropSource_QueryInterface,
2266 ISVDropSource_AddRef,
2267 ISVDropSource_Release,
2268 ISVDropSource_QueryContinueDrag,
2269 ISVDropSource_GiveFeedback
2271 /**********************************************************
2272 * ISVViewObject implementation
2275 static HRESULT WINAPI ISVViewObject_QueryInterface(
2276 IViewObject *iface,
2277 REFIID riid,
2278 LPVOID *ppvObj)
2280 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2282 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2284 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2287 static ULONG WINAPI ISVViewObject_AddRef( IViewObject *iface)
2289 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2291 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2293 return IShellFolder_AddRef((IShellFolder*)This);
2296 static ULONG WINAPI ISVViewObject_Release( IViewObject *iface)
2298 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2300 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2302 return IShellFolder_Release((IShellFolder*)This);
2305 static HRESULT WINAPI ISVViewObject_Draw(
2306 IViewObject *iface,
2307 DWORD dwDrawAspect,
2308 LONG lindex,
2309 void* pvAspect,
2310 DVTARGETDEVICE* ptd,
2311 HDC hdcTargetDev,
2312 HDC hdcDraw,
2313 LPCRECTL lprcBounds,
2314 LPCRECTL lprcWBounds,
2315 BOOL (CALLBACK *pfnContinue)(ULONG_PTR dwContinue),
2316 ULONG_PTR dwContinue)
2319 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2321 FIXME("Stub: This=%p\n",This);
2323 return E_NOTIMPL;
2325 static HRESULT WINAPI ISVViewObject_GetColorSet(
2326 IViewObject *iface,
2327 DWORD dwDrawAspect,
2328 LONG lindex,
2329 void *pvAspect,
2330 DVTARGETDEVICE* ptd,
2331 HDC hicTargetDevice,
2332 LOGPALETTE** ppColorSet)
2335 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2337 FIXME("Stub: This=%p\n",This);
2339 return E_NOTIMPL;
2341 static HRESULT WINAPI ISVViewObject_Freeze(
2342 IViewObject *iface,
2343 DWORD dwDrawAspect,
2344 LONG lindex,
2345 void* pvAspect,
2346 DWORD* pdwFreeze)
2349 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2351 FIXME("Stub: This=%p\n",This);
2353 return E_NOTIMPL;
2355 static HRESULT WINAPI ISVViewObject_Unfreeze(
2356 IViewObject *iface,
2357 DWORD dwFreeze)
2360 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2362 FIXME("Stub: This=%p\n",This);
2364 return E_NOTIMPL;
2366 static HRESULT WINAPI ISVViewObject_SetAdvise(
2367 IViewObject *iface,
2368 DWORD aspects,
2369 DWORD advf,
2370 IAdviseSink* pAdvSink)
2373 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2375 FIXME("Stub: This=%p\n",This);
2377 return E_NOTIMPL;
2379 static HRESULT WINAPI ISVViewObject_GetAdvise(
2380 IViewObject *iface,
2381 DWORD* pAspects,
2382 DWORD* pAdvf,
2383 IAdviseSink** ppAdvSink)
2386 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2388 FIXME("Stub: This=%p\n",This);
2390 return E_NOTIMPL;
2394 static struct IViewObjectVtbl vovt =
2396 ISVViewObject_QueryInterface,
2397 ISVViewObject_AddRef,
2398 ISVViewObject_Release,
2399 ISVViewObject_Draw,
2400 ISVViewObject_GetColorSet,
2401 ISVViewObject_Freeze,
2402 ISVViewObject_Unfreeze,
2403 ISVViewObject_SetAdvise,
2404 ISVViewObject_GetAdvise