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
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
40 #include "wine/port.h"
52 #include "undocshell.h"
54 #include "wine/debug.h"
58 #include "shell32_main.h"
59 #include "shellfolder.h"
61 WINE_DEFAULT_DEBUG_CHANNEL(shell);
67 }LISTVIEW_SORT_INFO, *LPLISTVIEW_SORT_INFO;
70 { ICOM_VFIELD(IShellView);
72 ICOM_VTABLE(IOleCommandTarget)* lpvtblOleCommandTarget;
73 ICOM_VTABLE(IDropTarget)* lpvtblDropTarget;
74 ICOM_VTABLE(IDropSource)* lpvtblDropSource;
75 ICOM_VTABLE(IViewObject)* lpvtblViewObject;
76 IShellFolder* pSFParent;
77 IShellFolder2* pSF2Parent;
78 IShellBrowser* pShellBrowser;
79 ICommDlgBrowser* pCommDlgBrowser;
80 HWND hWnd; /* SHELLDLL_DefView */
81 HWND hWndList; /* ListView control */
83 FOLDERSETTINGS FolderSettings;
88 LISTVIEW_SORT_INFO ListViewSortInfo;
89 HANDLE hNotify; /* change notification handle */
93 static struct ICOM_VTABLE(IShellView) svvt;
95 static struct ICOM_VTABLE(IOleCommandTarget) ctvt;
96 #define _IOleCommandTarget_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblOleCommandTarget)))
97 #define _ICOM_THIS_From_IOleCommandTarget(class, name) class* This = (class*)(((char*)name)-_IOleCommandTarget_Offset);
99 static struct ICOM_VTABLE(IDropTarget) dtvt;
100 #define _IDropTarget_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblDropTarget)))
101 #define _ICOM_THIS_From_IDropTarget(class, name) class* This = (class*)(((char*)name)-_IDropTarget_Offset);
103 static struct ICOM_VTABLE(IDropSource) dsvt;
104 #define _IDropSource_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblDropSource)))
105 #define _ICOM_THIS_From_IDropSource(class, name) class* This = (class*)(((char*)name)-_IDropSource_Offset);
107 static struct ICOM_VTABLE(IViewObject) vovt;
108 #define _IViewObject_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblViewObject)))
109 #define _ICOM_THIS_From_IViewObject(class, name) class* This = (class*)(((char*)name)-_IViewObject_Offset);
111 /* ListView Header ID's */
112 #define LISTVIEW_COLUMN_NAME 0
113 #define LISTVIEW_COLUMN_SIZE 1
114 #define LISTVIEW_COLUMN_TYPE 2
115 #define LISTVIEW_COLUMN_TIME 3
116 #define LISTVIEW_COLUMN_ATTRIB 4
119 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
120 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
121 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
123 #define ID_LISTVIEW 2000
125 #define SHV_CHANGE_NOTIFY WM_USER + 0x1111
128 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
129 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
130 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
132 extern void WINAPI _InsertMenuItem (HMENU hmenu, UINT indexMenu, BOOL fByPosition,
133 UINT wID, UINT fType, LPSTR dwTypeData, UINT fState);
136 Items merged into the toolbar and and the filemenu
145 } MYTOOLINFO, *LPMYTOOLINFO;
149 { FCIDM_SHVIEW_BIGICON, 0, 0, IDS_VIEW_LARGE, TBSTATE_ENABLED, TBSTYLE_BUTTON },
150 { FCIDM_SHVIEW_SMALLICON, 0, 0, IDS_VIEW_SMALL, TBSTATE_ENABLED, TBSTYLE_BUTTON },
151 { FCIDM_SHVIEW_LISTVIEW, 0, 0, IDS_VIEW_LIST, TBSTATE_ENABLED, TBSTYLE_BUTTON },
152 { FCIDM_SHVIEW_REPORTVIEW, 0, 0, IDS_VIEW_DETAILS, TBSTATE_ENABLED, TBSTYLE_BUTTON },
156 typedef void (CALLBACK *PFNSHGETSETTINGSPROC)(LPSHELLFLAGSTATE lpsfs, DWORD dwMask);
158 /**********************************************************
159 * IShellView_Constructor
161 IShellView * IShellView_Constructor( IShellFolder * pFolder)
162 { IShellViewImpl * sv;
163 sv=(IShellViewImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IShellViewImpl));
166 sv->lpvtblOleCommandTarget=&ctvt;
167 sv->lpvtblDropTarget=&dtvt;
168 sv->lpvtblDropSource=&dsvt;
169 sv->lpvtblViewObject=&vovt;
171 sv->pSFParent = pFolder;
172 if(pFolder) IShellFolder_AddRef(pFolder);
173 IShellFolder_QueryInterface(sv->pSFParent, &IID_IShellFolder2, (LPVOID*)&sv->pSF2Parent);
175 TRACE("(%p)->(%p)\n",sv, pFolder);
176 return (IShellView *) sv;
179 /**********************************************************
181 * ##### helperfunctions for communication with ICommDlgBrowser #####
183 static BOOL IsInCommDlg(IShellViewImpl * This)
184 { return(This->pCommDlgBrowser != NULL);
187 static HRESULT IncludeObject(IShellViewImpl * This, LPCITEMIDLIST pidl)
191 if ( IsInCommDlg(This) )
193 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl);
194 ret = ICommDlgBrowser_IncludeObject(This->pCommDlgBrowser, (IShellView*)This, pidl);
195 TRACE("--0x%08lx\n", ret);
200 static HRESULT OnDefaultCommand(IShellViewImpl * This)
202 HRESULT ret = S_FALSE;
204 if (IsInCommDlg(This))
206 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
207 ret = ICommDlgBrowser_OnDefaultCommand(This->pCommDlgBrowser, (IShellView*)This);
213 static HRESULT OnStateChange(IShellViewImpl * This, UINT uFlags)
215 HRESULT ret = S_FALSE;
217 if (IsInCommDlg(This))
219 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags);
220 ret = ICommDlgBrowser_OnStateChange(This->pCommDlgBrowser, (IShellView*)This, uFlags);
225 /**********************************************************
226 * set the toolbar of the filedialog buttons
228 * - activates the buttons from the shellbrowser according to
231 static void CheckToolbar(IShellViewImpl * This)
237 if (IsInCommDlg(This))
239 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
240 FCIDM_TB_SMALLICON, (This->FolderSettings.ViewMode==FVM_LIST)? TRUE : FALSE, &result);
241 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
242 FCIDM_TB_REPORTVIEW, (This->FolderSettings.ViewMode==FVM_DETAILS)? TRUE : FALSE, &result);
243 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
244 FCIDM_TB_SMALLICON, TRUE, &result);
245 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
246 FCIDM_TB_REPORTVIEW, TRUE, &result);
250 /**********************************************************
252 * ##### helperfunctions for initializing the view #####
254 /**********************************************************
255 * change the style of the listview control
257 static void SetStyle(IShellViewImpl * This, DWORD dwAdd, DWORD dwRemove)
261 TRACE("(%p)\n", This);
263 tmpstyle = GetWindowLongA(This->hWndList, GWL_STYLE);
264 SetWindowLongA(This->hWndList, GWL_STYLE, dwAdd | (tmpstyle & ~dwRemove));
267 /**********************************************************
268 * ShellView_CreateList()
270 * - creates the list view window
272 static BOOL ShellView_CreateList (IShellViewImpl * This)
277 dwStyle = WS_TABSTOP | WS_VISIBLE | WS_CHILDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
278 LVS_SHAREIMAGELISTS | LVS_EDITLABELS | LVS_ALIGNLEFT | LVS_AUTOARRANGE;
280 switch (This->FolderSettings.ViewMode)
282 case FVM_ICON: dwStyle |= LVS_ICON; break;
283 case FVM_DETAILS: dwStyle |= LVS_REPORT; break;
284 case FVM_SMALLICON: dwStyle |= LVS_SMALLICON; break;
285 case FVM_LIST: dwStyle |= LVS_LIST; break;
286 default: dwStyle |= LVS_LIST; break;
289 if (This->FolderSettings.fFlags & FWF_AUTOARRANGE) dwStyle |= LVS_AUTOARRANGE;
290 /*if (This->FolderSettings.fFlags && FWF_DESKTOP); used from explorer*/
291 if (This->FolderSettings.fFlags & FWF_SINGLESEL) dwStyle |= LVS_SINGLESEL;
293 This->hWndList=CreateWindowExA( WS_EX_CLIENTEDGE,
306 This->ListViewSortInfo.bIsAscending = TRUE;
307 This->ListViewSortInfo.nHeaderID = -1;
308 This->ListViewSortInfo.nLastHeaderID = -1;
310 /* UpdateShellSettings(); */
314 /**********************************************************
315 * ShellView_InitList()
317 * - adds all needed columns to the shellview
319 static BOOL ShellView_InitList(IShellViewImpl * This)
328 ListView_DeleteAllItems(This->hWndList);
330 lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT;
331 lvColumn.pszText = szTemp;
333 if (This->pSF2Parent)
337 if (!SUCCEEDED(IShellFolder2_GetDetailsOf(This->pSF2Parent, NULL, i, &sd)))
339 lvColumn.fmt = sd.fmt;
340 lvColumn.cx = sd.cxChar*8; /* chars->pixel */
341 StrRetToStrNA( szTemp, 50, &sd.str, NULL);
342 ListView_InsertColumnA(This->hWndList, i, &lvColumn);
350 ListView_SetImageList(This->hWndList, ShellSmallIconList, LVSIL_SMALL);
351 ListView_SetImageList(This->hWndList, ShellBigIconList, LVSIL_NORMAL);
355 /**********************************************************
356 * ShellView_CompareItems()
359 * internal, CALLBACK for DSA_Sort
361 static INT CALLBACK ShellView_CompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
364 TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1, lParam2, (LPVOID) lpData);
366 if(!lpData) return 0;
368 ret = (SHORT) SCODE_CODE(IShellFolder_CompareIDs((LPSHELLFOLDER)lpData, 0, (LPITEMIDLIST)lParam1, (LPITEMIDLIST)lParam2));
369 TRACE("ret=%i\n",ret);
373 /*************************************************************************
374 * ShellView_ListViewCompareItems
376 * Compare Function for the Listview (FileOpen Dialog)
379 * lParam1 [I] the first ItemIdList to compare with
380 * lParam2 [I] the second ItemIdList to compare with
381 * lpData [I] The column ID for the header Ctrl to process
384 * A negative value if the first item should precede the second,
385 * a positive value if the first item should follow the second,
386 * or zero if the two items are equivalent
389 * FIXME: function does what ShellView_CompareItems is supposed to do.
390 * unify it and figure out how to use the undocumented first parameter
391 * of IShellFolder_CompareIDs to do the job this function does and
392 * move this code to IShellFolder.
393 * make LISTVIEW_SORT_INFO obsolete
394 * the way this function works is only usable if we had only
395 * filesystemfolders (25/10/99 jsch)
397 static INT CALLBACK ShellView_ListViewCompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
401 char strName1[MAX_PATH], strName2[MAX_PATH];
402 BOOL bIsFolder1, bIsFolder2,bIsBothFolder;
403 LPITEMIDLIST pItemIdList1 = (LPITEMIDLIST) lParam1;
404 LPITEMIDLIST pItemIdList2 = (LPITEMIDLIST) lParam2;
405 LISTVIEW_SORT_INFO *pSortInfo = (LPLISTVIEW_SORT_INFO) lpData;
408 bIsFolder1 = _ILIsFolder(pItemIdList1);
409 bIsFolder2 = _ILIsFolder(pItemIdList2);
410 bIsBothFolder = bIsFolder1 && bIsFolder2;
412 /* When sorting between a File and a Folder, the Folder gets sorted first */
413 if( (bIsFolder1 || bIsFolder2) && !bIsBothFolder)
415 nDiff = bIsFolder1 ? -1 : 1;
419 /* Sort by Time: Folders or Files can be sorted */
421 if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TIME)
423 _ILGetFileDateTime(pItemIdList1, &fd1);
424 _ILGetFileDateTime(pItemIdList2, &fd2);
425 nDiff = CompareFileTime(&fd2, &fd1);
427 /* Sort by Attribute: Folder or Files can be sorted */
428 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_ATTRIB)
430 _ILGetFileAttributes(pItemIdList1, strName1, MAX_PATH);
431 _ILGetFileAttributes(pItemIdList2, strName2, MAX_PATH);
432 nDiff = strcasecmp(strName1, strName2);
434 /* Sort by FileName: Folder or Files can be sorted */
435 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_NAME || bIsBothFolder)
438 _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
439 _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
440 nDiff = strcasecmp(strName1, strName2);
442 /* Sort by File Size, Only valid for Files */
443 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_SIZE)
445 nDiff = (INT)(_ILGetFileSize(pItemIdList1, NULL, 0) - _ILGetFileSize(pItemIdList2, NULL, 0));
447 /* Sort by File Type, Only valid for Files */
448 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TYPE)
451 _ILGetFileType(pItemIdList1, strName1, MAX_PATH);
452 _ILGetFileType(pItemIdList2, strName2, MAX_PATH);
453 nDiff = strcasecmp(strName1, strName2);
456 /* If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
460 _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
461 _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
462 nDiff = strcasecmp(strName1, strName2);
465 if(!pSortInfo->bIsAscending)
474 /**********************************************************
475 * LV_FindItemByPidl()
477 static int LV_FindItemByPidl(
478 IShellViewImpl * This,
482 ZeroMemory(&lvItem, sizeof(LVITEMA));
483 lvItem.mask = LVIF_PARAM;
484 for(lvItem.iItem = 0; ListView_GetItemA(This->hWndList, &lvItem); lvItem.iItem++)
486 LPITEMIDLIST currentpidl = (LPITEMIDLIST) lvItem.lParam;
487 HRESULT hr = IShellFolder_CompareIDs(This->pSFParent, 0, pidl, currentpidl);
488 if(SUCCEEDED(hr) && !HRESULT_CODE(hr))
496 /**********************************************************
499 static BOOLEAN LV_AddItem(IShellViewImpl * This, LPCITEMIDLIST pidl)
503 TRACE("(%p)(pidl=%p)\n", This, pidl);
505 ZeroMemory(&lvItem, sizeof(lvItem)); /* create the listview item*/
506 lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; /*set the mask*/
507 lvItem.iItem = ListView_GetItemCount(This->hWndList); /*add the item to the end of the list*/
508 lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidl)); /*set the item's data*/
509 lvItem.pszText = LPSTR_TEXTCALLBACKA; /*get text on a callback basis*/
510 lvItem.iImage = I_IMAGECALLBACK; /*get the image on a callback basis*/
511 return (-1==ListView_InsertItemA(This->hWndList, &lvItem))? FALSE: TRUE;
514 /**********************************************************
517 static BOOLEAN LV_DeleteItem(IShellViewImpl * This, LPCITEMIDLIST pidl)
521 TRACE("(%p)(pidl=%p)\n", This, pidl);
523 nIndex = LV_FindItemByPidl(This, ILFindLastID(pidl));
524 return (-1==ListView_DeleteItem(This->hWndList, nIndex))? FALSE: TRUE;
527 /**********************************************************
530 static BOOLEAN LV_RenameItem(IShellViewImpl * This, LPCITEMIDLIST pidlOld, LPCITEMIDLIST pidlNew )
535 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", This, pidlOld, pidlNew);
537 nItem = LV_FindItemByPidl(This, ILFindLastID(pidlOld));
540 ZeroMemory(&lvItem, sizeof(lvItem)); /* create the listview item*/
541 lvItem.mask = LVIF_PARAM; /* only the pidl */
542 lvItem.iItem = nItem;
543 ListView_GetItemA(This->hWndList, &lvItem);
545 SHFree((LPITEMIDLIST)lvItem.lParam);
546 lvItem.mask = LVIF_PARAM;
547 lvItem.iItem = nItem;
548 lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidlNew)); /* set the item's data */
549 ListView_SetItemA(This->hWndList, &lvItem);
550 ListView_Update(This->hWndList, nItem);
551 return TRUE; /* FIXME: better handling */
555 /**********************************************************
556 * ShellView_FillList()
558 * - gets the objectlist from the shellfolder
560 * - fills the list into the view
563 static HRESULT ShellView_FillList(IShellViewImpl * This)
565 LPENUMIDLIST pEnumIDList;
574 /* get the itemlist from the shfolder*/
575 hRes = IShellFolder_EnumObjects(This->pSFParent,This->hWnd, SHCONTF_NONFOLDERS | SHCONTF_FOLDERS, &pEnumIDList);
583 /* create a pointer array */
584 hdpa = DPA_Create(16);
587 return(E_OUTOFMEMORY);
590 /* copy the items into the array*/
591 while((S_OK == IEnumIDList_Next(pEnumIDList,1, &pidl, &dwFetched)) && dwFetched)
593 if (DPA_InsertPtr(hdpa, 0x7fff, pidl) == -1)
600 DPA_Sort(hdpa, ShellView_CompareItems, (LPARAM)This->pSFParent);
602 /*turn the listview's redrawing off*/
603 SendMessageA(This->hWndList, WM_SETREDRAW, FALSE, 0);
605 for (i=0; i < DPA_GetPtrCount(hdpa); ++i) /* DPA_GetPtrCount is a macro*/
607 pidl = (LPITEMIDLIST)DPA_GetPtr(hdpa, i);
609 /* in a commdlg This works as a filemask*/
610 if ( IncludeObject(This, pidl)==S_OK )
611 LV_AddItem(This, pidl);
615 /*turn the listview's redrawing back on and force it to draw*/
616 SendMessageA(This->hWndList, WM_SETREDRAW, TRUE, 0);
618 IEnumIDList_Release(pEnumIDList); /* destroy the list*/
624 /**********************************************************
625 * ShellView_OnCreate()
627 static LRESULT ShellView_OnCreate(IShellViewImpl * This)
630 NOTIFYREGISTER ntreg;
631 IPersistFolder2 * ppf2 = NULL;
635 if(ShellView_CreateList(This))
637 if(ShellView_InitList(This))
639 ShellView_FillList(This);
643 if(GetShellOle() && pRegisterDragDrop)
645 if (SUCCEEDED(IShellFolder_CreateViewObject(This->pSFParent, This->hWnd, &IID_IDropTarget, (LPVOID*)&pdt)))
647 pRegisterDragDrop(This->hWnd, pdt);
648 IDropTarget_Release(pdt);
652 /* register for receiving notifications */
653 IShellFolder_QueryInterface(This->pSFParent, &IID_IPersistFolder2, (LPVOID*)&ppf2);
656 IPersistFolder2_GetCurFolder(ppf2, &ntreg.pidlPath);
657 ntreg.bWatchSubtree = FALSE;
658 This->hNotify = SHChangeNotifyRegister(This->hWnd, SHCNF_IDLIST, SHCNE_ALLEVENTS, SHV_CHANGE_NOTIFY, 1, &ntreg);
659 SHFree(ntreg.pidlPath);
660 IPersistFolder2_Release(ppf2);
663 This->hAccel = LoadAcceleratorsA(shell32_hInstance, "shv_accel");
668 /**********************************************************
669 * #### Handling of the menus ####
672 /**********************************************************
673 * ShellView_BuildFileMenu()
675 static HMENU ShellView_BuildFileMenu(IShellViewImpl * This)
676 { CHAR szText[MAX_PATH];
681 TRACE("(%p)\n",This);
683 hSubMenu = CreatePopupMenu();
685 { /*get the number of items in our global array*/
686 for(nTools = 0; Tools[nTools].idCommand != -1; nTools++){}
688 /*add the menu items*/
689 for(i = 0; i < nTools; i++)
691 LoadStringA(shell32_hInstance, Tools[i].idMenuString, szText, MAX_PATH);
693 ZeroMemory(&mii, sizeof(mii));
694 mii.cbSize = sizeof(mii);
695 mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
697 if(TBSTYLE_SEP != Tools[i].bStyle) /* no separator*/
699 mii.fType = MFT_STRING;
700 mii.fState = MFS_ENABLED;
701 mii.dwTypeData = szText;
702 mii.wID = Tools[i].idCommand;
706 mii.fType = MFT_SEPARATOR;
708 /* tack This item onto the end of the menu */
709 InsertMenuItemA(hSubMenu, (UINT)-1, TRUE, &mii);
712 TRACE("-- return (menu=%p)\n",hSubMenu);
715 /**********************************************************
716 * ShellView_MergeFileMenu()
718 static void ShellView_MergeFileMenu(IShellViewImpl * This, HMENU hSubMenu)
719 { TRACE("(%p)->(submenu=%p) stub\n",This,hSubMenu);
722 { /*insert This item at the beginning of the menu */
723 _InsertMenuItem(hSubMenu, 0, TRUE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
724 _InsertMenuItem(hSubMenu, 0, TRUE, IDM_MYFILEITEM, MFT_STRING, "dummy45", MFS_ENABLED);
730 /**********************************************************
731 * ShellView_MergeViewMenu()
734 static void ShellView_MergeViewMenu(IShellViewImpl * This, HMENU hSubMenu)
737 TRACE("(%p)->(submenu=%p)\n",This,hSubMenu);
740 { /*add a separator at the correct position in the menu*/
741 _InsertMenuItem(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
743 ZeroMemory(&mii, sizeof(mii));
744 mii.cbSize = sizeof(mii);
745 mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_DATA;
746 mii.fType = MFT_STRING;
747 mii.dwTypeData = "View";
748 mii.hSubMenu = LoadMenuA(shell32_hInstance, "MENU_001");
749 InsertMenuItemA(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
753 /**********************************************************
754 * ShellView_GetSelections()
756 * - fills the this->apidl list with the selected objects
759 * number of selected items
761 static UINT ShellView_GetSelections(IShellViewImpl * This)
771 This->cidl = ListView_GetSelectedCount(This->hWndList);
772 This->apidl = (LPITEMIDLIST*)SHAlloc(This->cidl * sizeof(LPITEMIDLIST));
774 TRACE("selected=%i\n", This->cidl);
778 TRACE("-- Items selected =%u\n", This->cidl);
780 ZeroMemory(&lvItem, sizeof(lvItem));
781 lvItem.mask = LVIF_STATE | LVIF_PARAM;
782 lvItem.stateMask = LVIS_SELECTED;
784 while(ListView_GetItemA(This->hWndList, &lvItem) && (i < This->cidl))
786 if(lvItem.state & LVIS_SELECTED)
788 This->apidl[i] = (LPITEMIDLIST)lvItem.lParam;
790 TRACE("-- selected Item found\n");
798 /**********************************************************
799 * ShellView_DoContextMenu()
801 static void ShellView_DoContextMenu(IShellViewImpl * This, WORD x, WORD y, BOOL bDefault)
805 BOOL fExplore = FALSE;
807 LPCONTEXTMENU pContextMenu = NULL;
808 IContextMenu * pCM = NULL;
809 CMINVOKECOMMANDINFO cmi;
811 TRACE("(%p)->(0x%08x 0x%08x 0x%08x) stub\n",This, x, y, bDefault);
813 /* look, what's selected and create a context menu object of it*/
814 if( ShellView_GetSelections(This) )
816 IShellFolder_GetUIObjectOf( This->pSFParent, This->hWndParent, This->cidl, (LPCITEMIDLIST*)This->apidl,
817 (REFIID)&IID_IContextMenu, NULL, (LPVOID *)&pContextMenu);
821 TRACE("-- pContextMenu\n");
822 hMenu = CreatePopupMenu();
826 /* See if we are in Explore or Open mode. If the browser's tree is present, we are in Explore mode.*/
827 if(SUCCEEDED(IShellBrowser_GetControlWindow(This->pShellBrowser,FCW_TREE, &hwndTree)) && hwndTree)
829 TRACE("-- explore mode\n");
833 /* build the flags depending on what we can do with the selected item */
834 wFlags = CMF_NORMAL | (This->cidl != 1 ? 0 : CMF_CANRENAME) | (fExplore ? CMF_EXPLORE : 0);
836 /* let the ContextMenu merge its items in */
837 if (SUCCEEDED(IContextMenu_QueryContextMenu( pContextMenu, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, wFlags )))
841 TRACE("-- get menu default command\n");
842 uCommand = GetMenuDefaultItem(hMenu, FALSE, GMDI_GOINTOPOPUPS);
846 TRACE("-- track popup\n");
847 uCommand = TrackPopupMenu( hMenu,TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
852 TRACE("-- uCommand=%u\n", uCommand);
853 if (IsInCommDlg(This) && ((uCommand==FCIDM_SHVIEW_EXPLORE) || (uCommand==FCIDM_SHVIEW_OPEN)))
855 TRACE("-- dlg: OnDefaultCommand\n");
856 OnDefaultCommand(This);
860 TRACE("-- explore -- invoke command\n");
861 ZeroMemory(&cmi, sizeof(cmi));
862 cmi.cbSize = sizeof(cmi);
863 cmi.hwnd = This->hWndParent; /* this window has to answer CWM_GETISHELLBROWSER */
864 cmi.lpVerb = (LPCSTR)MAKEINTRESOURCEA(uCommand);
865 IContextMenu_InvokeCommand(pContextMenu, &cmi);
872 IContextMenu_Release(pContextMenu);
875 else /* background context menu */
877 hMenu = CreatePopupMenu();
879 pCM = ISvBgCm_Constructor(This->pSFParent);
880 IContextMenu_QueryContextMenu(pCM, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, 0);
882 uCommand = TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
885 TRACE("-- (%p)->(uCommand=0x%08x )\n",This, uCommand);
887 ZeroMemory(&cmi, sizeof(cmi));
888 cmi.cbSize = sizeof(cmi);
889 cmi.lpVerb = (LPCSTR)MAKEINTRESOURCEA(uCommand);
890 cmi.hwnd = This->hWndParent;
891 IContextMenu_InvokeCommand(pCM, &cmi);
893 IContextMenu_Release(pCM);
897 /**********************************************************
898 * ##### message handling #####
901 /**********************************************************
904 static LRESULT ShellView_OnSize(IShellViewImpl * This, WORD wWidth, WORD wHeight)
906 TRACE("%p width=%u height=%u\n",This, wWidth,wHeight);
908 /*resize the ListView to fit our window*/
911 MoveWindow(This->hWndList, 0, 0, wWidth, wHeight, TRUE);
916 /**********************************************************
917 * ShellView_OnDeactivate()
922 static void ShellView_OnDeactivate(IShellViewImpl * This)
926 if(This->uState != SVUIA_DEACTIVATE)
930 IShellBrowser_SetMenuSB(This->pShellBrowser,0, 0, 0);
931 IShellBrowser_RemoveMenusSB(This->pShellBrowser,This->hMenu);
932 DestroyMenu(This->hMenu);
936 This->uState = SVUIA_DEACTIVATE;
940 /**********************************************************
941 * ShellView_OnActivate()
943 static LRESULT ShellView_OnActivate(IShellViewImpl * This, UINT uState)
944 { OLEMENUGROUPWIDTHS omw = { {0, 0, 0, 0, 0, 0} };
946 CHAR szText[MAX_PATH];
948 TRACE("%p uState=%x\n",This,uState);
950 /*don't do anything if the state isn't really changing */
951 if(This->uState == uState)
956 ShellView_OnDeactivate(This);
958 /*only do This if we are active */
959 if(uState != SVUIA_DEACTIVATE)
962 This->hMenu = CreateMenu();
966 IShellBrowser_InsertMenusSB(This->pShellBrowser, This->hMenu, &omw);
967 TRACE("-- after fnInsertMenusSB\n");
969 /*build the top level menu get the menu item's text*/
970 strcpy(szText,"dummy 31");
972 ZeroMemory(&mii, sizeof(mii));
973 mii.cbSize = sizeof(mii);
974 mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_STATE;
975 mii.fType = MFT_STRING;
976 mii.fState = MFS_ENABLED;
977 mii.dwTypeData = szText;
978 mii.hSubMenu = ShellView_BuildFileMenu(This);
980 /*insert our menu into the menu bar*/
983 InsertMenuItemA(This->hMenu, FCIDM_MENU_HELP, FALSE, &mii);
986 /*get the view menu so we can merge with it*/
987 ZeroMemory(&mii, sizeof(mii));
988 mii.cbSize = sizeof(mii);
989 mii.fMask = MIIM_SUBMENU;
991 if(GetMenuItemInfoA(This->hMenu, FCIDM_MENU_VIEW, FALSE, &mii))
993 ShellView_MergeViewMenu(This, mii.hSubMenu);
996 /*add the items that should only be added if we have the focus*/
997 if(SVUIA_ACTIVATE_FOCUS == uState)
999 /*get the file menu so we can merge with it */
1000 ZeroMemory(&mii, sizeof(mii));
1001 mii.cbSize = sizeof(mii);
1002 mii.fMask = MIIM_SUBMENU;
1004 if(GetMenuItemInfoA(This->hMenu, FCIDM_MENU_FILE, FALSE, &mii))
1006 ShellView_MergeFileMenu(This, mii.hSubMenu);
1009 TRACE("-- before fnSetMenuSB\n");
1010 IShellBrowser_SetMenuSB(This->pShellBrowser, This->hMenu, 0, This->hWnd);
1013 This->uState = uState;
1018 /**********************************************************
1019 * ShellView_OnSetFocus()
1022 static LRESULT ShellView_OnSetFocus(IShellViewImpl * This)
1026 /* Tell the browser one of our windows has received the focus. This
1027 should always be done before merging menus (OnActivate merges the
1028 menus) if one of our windows has the focus.*/
1030 IShellBrowser_OnViewWindowActive(This->pShellBrowser,(IShellView*) This);
1031 ShellView_OnActivate(This, SVUIA_ACTIVATE_FOCUS);
1033 /* Set the focus to the listview */
1034 SetFocus(This->hWndList);
1036 /* Notify the ICommDlgBrowser interface */
1037 OnStateChange(This,CDBOSC_SETFOCUS);
1042 /**********************************************************
1043 * ShellView_OnKillFocus()
1045 static LRESULT ShellView_OnKillFocus(IShellViewImpl * This)
1047 TRACE("(%p) stub\n",This);
1049 ShellView_OnActivate(This, SVUIA_ACTIVATE_NOFOCUS);
1050 /* Notify the ICommDlgBrowser */
1051 OnStateChange(This,CDBOSC_KILLFOCUS);
1056 /**********************************************************
1057 * ShellView_OnCommand()
1060 * the CmdID's are the ones from the context menu
1062 static LRESULT ShellView_OnCommand(IShellViewImpl * This,DWORD dwCmdID, DWORD dwCmd, HWND hwndCmd)
1064 TRACE("(%p)->(0x%08lx 0x%08lx %p) stub\n",This, dwCmdID, dwCmd, hwndCmd);
1068 case FCIDM_SHVIEW_SMALLICON:
1069 This->FolderSettings.ViewMode = FVM_SMALLICON;
1070 SetStyle (This, LVS_SMALLICON, LVS_TYPEMASK);
1074 case FCIDM_SHVIEW_BIGICON:
1075 This->FolderSettings.ViewMode = FVM_ICON;
1076 SetStyle (This, LVS_ICON, LVS_TYPEMASK);
1080 case FCIDM_SHVIEW_LISTVIEW:
1081 This->FolderSettings.ViewMode = FVM_LIST;
1082 SetStyle (This, LVS_LIST, LVS_TYPEMASK);
1086 case FCIDM_SHVIEW_REPORTVIEW:
1087 This->FolderSettings.ViewMode = FVM_DETAILS;
1088 SetStyle (This, LVS_REPORT, LVS_TYPEMASK);
1092 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1097 This->ListViewSortInfo.nHeaderID = (LPARAM) (dwCmdID - 0x30);
1098 This->ListViewSortInfo.bIsAscending = TRUE;
1099 This->ListViewSortInfo.nLastHeaderID = This->ListViewSortInfo.nHeaderID;
1100 ListView_SortItems(This->hWndList, ShellView_ListViewCompareItems, (LPARAM) (&(This->ListViewSortInfo)));
1104 TRACE("-- COMMAND 0x%04lx unhandled\n", dwCmdID);
1109 /**********************************************************
1110 * ShellView_OnNotify()
1113 static LRESULT ShellView_OnNotify(IShellViewImpl * This, UINT CtlID, LPNMHDR lpnmh)
1114 { LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)lpnmh;
1115 NMLVDISPINFOA *lpdi = (NMLVDISPINFOA *)lpnmh;
1118 TRACE("%p CtlID=%u lpnmh->code=%x\n",This,CtlID,lpnmh->code);
1123 TRACE("-- NM_SETFOCUS %p\n",This);
1124 ShellView_OnSetFocus(This);
1128 TRACE("-- NM_KILLFOCUS %p\n",This);
1129 ShellView_OnDeactivate(This);
1130 /* Notify the ICommDlgBrowser interface */
1131 OnStateChange(This,CDBOSC_KILLFOCUS);
1135 TRACE("-- HDN_ENDTRACKA %p\n",This);
1136 /*nColumn1 = ListView_GetColumnWidth(This->hWndList, 0);
1137 nColumn2 = ListView_GetColumnWidth(This->hWndList, 1);*/
1140 case LVN_DELETEITEM:
1141 TRACE("-- LVN_DELETEITEM %p\n",This);
1142 SHFree((LPITEMIDLIST)lpnmlv->lParam); /*delete the pidl because we made a copy of it*/
1145 case LVN_INSERTITEM:
1146 TRACE("-- LVN_INSERTITEM (STUB)%p\n",This);
1149 case LVN_ITEMACTIVATE:
1150 TRACE("-- LVN_ITEMACTIVATE %p\n",This);
1151 OnStateChange(This, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
1152 ShellView_DoContextMenu(This, 0, 0, TRUE);
1155 case LVN_COLUMNCLICK:
1156 This->ListViewSortInfo.nHeaderID = lpnmlv->iSubItem;
1157 if(This->ListViewSortInfo.nLastHeaderID == This->ListViewSortInfo.nHeaderID)
1159 This->ListViewSortInfo.bIsAscending = !This->ListViewSortInfo.bIsAscending;
1163 This->ListViewSortInfo.bIsAscending = TRUE;
1165 This->ListViewSortInfo.nLastHeaderID = This->ListViewSortInfo.nHeaderID;
1167 ListView_SortItems(lpnmlv->hdr.hwndFrom, ShellView_ListViewCompareItems, (LPARAM) (&(This->ListViewSortInfo)));
1170 case LVN_GETDISPINFOA:
1171 case LVN_GETDISPINFOW:
1172 TRACE("-- LVN_GETDISPINFO %p\n",This);
1173 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1175 if(lpdi->item.mask & LVIF_TEXT) /* text requested */
1177 if (This->pSF2Parent)
1180 IShellFolder2_GetDetailsOf(This->pSF2Parent, pidl, lpdi->item.iSubItem, &sd);
1181 if (lpnmh->code == LVN_GETDISPINFOA)
1183 StrRetToStrNA( lpdi->item.pszText, lpdi->item.cchTextMax, &sd.str, NULL);
1184 TRACE("-- text=%s\n",lpdi->item.pszText);
1186 else /* LVN_GETDISPINFOW */
1188 StrRetToStrNW( lpdi->item.pszText, lpdi->item.cchTextMax, &sd.str, NULL);
1189 TRACE("-- text=%s\n",debugstr_w((WCHAR*)(lpdi->item.pszText)));
1197 if(lpdi->item.mask & LVIF_IMAGE) /* image requested */
1199 lpdi->item.iImage = SHMapPIDLToSystemImageListIndex(This->pSFParent, pidl, 0);
1203 case LVN_ITEMCHANGED:
1204 TRACE("-- LVN_ITEMCHANGED %p\n",This);
1205 OnStateChange(This, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
1209 case LVN_BEGINRDRAG:
1210 TRACE("-- LVN_BEGINDRAG\n");
1212 if (ShellView_GetSelections(This))
1215 DWORD dwAttributes = SFGAO_CANLINK;
1216 DWORD dwEffect = DROPEFFECT_COPY | DROPEFFECT_MOVE;
1218 if(GetShellOle() && pDoDragDrop)
1220 if (SUCCEEDED(IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, (LPCITEMIDLIST*)This->apidl, &IID_IDataObject,0,(LPVOID *)&pda)))
1222 IDropSource * pds = (IDropSource*)&(This->lpvtblDropSource); /* own DropSource interface */
1224 if (SUCCEEDED(IShellFolder_GetAttributesOf(This->pSFParent, This->cidl, (LPCITEMIDLIST*)This->apidl, &dwAttributes)))
1226 if (dwAttributes & SFGAO_CANLINK)
1228 dwEffect |= DROPEFFECT_LINK;
1235 pDoDragDrop(pda, pds, dwEffect, &dwEffect);
1237 IDataObject_Release(pda);
1243 case LVN_BEGINLABELEDITA:
1245 DWORD dwAttr = SFGAO_CANRENAME;
1246 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1248 TRACE("-- LVN_BEGINLABELEDITA %p\n",This);
1250 IShellFolder_GetAttributesOf(This->pSFParent, 1, (LPCITEMIDLIST*)&pidl, &dwAttr);
1251 if (SFGAO_CANRENAME & dwAttr)
1259 case LVN_ENDLABELEDITA:
1261 TRACE("-- LVN_ENDLABELEDITA %p\n",This);
1262 if (lpdi->item.pszText)
1265 WCHAR wszNewName[MAX_PATH];
1268 ZeroMemory(&lvItem, sizeof(LVITEMA));
1269 lvItem.iItem = lpdi->item.iItem;
1270 lvItem.mask = LVIF_PARAM;
1271 ListView_GetItemA(This->hWndList, &lvItem);
1273 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1274 if (!MultiByteToWideChar( CP_ACP, 0, lpdi->item.pszText, -1, wszNewName, MAX_PATH ))
1275 wszNewName[MAX_PATH-1] = 0;
1276 hr = IShellFolder_SetNameOf(This->pSFParent, 0, pidl, wszNewName, SHGDN_INFOLDER, &pidl);
1278 if(SUCCEEDED(hr) && pidl)
1280 lvItem.mask = LVIF_PARAM;
1281 lvItem.lParam = (LPARAM)pidl;
1282 ListView_SetItemA(This->hWndList, &lvItem);
1293 msg.hwnd = This->hWnd;
1294 msg.message = WM_KEYDOWN;
1295 msg.wParam = plvKeyDown->wVKey;
1300 LPNMLVKEYDOWN plvKeyDown = (LPNMLVKEYDOWN) lpnmh;
1302 /* initiate a rename of the selected file or directory */
1303 if(plvKeyDown->wVKey == VK_F2)
1305 /* see how many files are selected */
1306 int i = ListView_GetSelectedCount(This->hWndList);
1308 /* get selected item */
1311 /* get selected item */
1312 i = ListView_GetNextItem(This->hWndList, -1,
1315 ListView_EnsureVisible(This->hWndList, i, 0);
1316 ListView_EditLabelA(This->hWndList, i);
1320 TranslateAccelerator(This->hWnd, This->hAccel, &msg)
1322 else if(plvKeyDown->wVKey == VK_DELETE)
1327 LPITEMIDLIST* pItems;
1330 IShellFolder_QueryInterface(This->pSFParent, &IID_ISFHelper,
1333 if(!(i = ListView_GetSelectedCount(This->hWndList)))
1336 /* allocate memory for the pidl array */
1337 pItems = HeapAlloc(GetProcessHeap(), 0,
1338 sizeof(LPITEMIDLIST) * i);
1340 /* retrieve all selected items */
1343 while(ListView_GetSelectedCount(This->hWndList) > i)
1345 /* get selected item */
1346 item_index = ListView_GetNextItem(This->hWndList,
1347 item_index, LVNI_SELECTED);
1348 item.iItem = item_index;
1349 ListView_GetItemA(This->hWndList, &item);
1352 pItems[i] = (LPITEMIDLIST)item.lParam;
1357 /* perform the item deletion */
1358 ISFHelper_DeleteItems(psfhlp, i, (LPCITEMIDLIST*)pItems);
1360 /* free pidl array memory */
1361 HeapFree(GetProcessHeap(), 0, pItems);
1364 FIXME("LVN_KEYDOWN key=0x%08x\n",plvKeyDown->wVKey);
1369 FIXME("-- %p WM_COMMAND %x unhandled\n", This, lpnmh->code);
1375 /**********************************************************
1376 * ShellView_OnChange()
1379 static LRESULT ShellView_OnChange(IShellViewImpl * This, LPITEMIDLIST * Pidls, LONG wEventId)
1382 TRACE("(%p)(%p,%p,0x%08lx)\n", This, Pidls[0], Pidls[1], wEventId);
1387 LV_AddItem(This, Pidls[0]);
1391 LV_DeleteItem(This, Pidls[0]);
1393 case SHCNE_RENAMEFOLDER:
1394 case SHCNE_RENAMEITEM:
1395 LV_RenameItem(This, Pidls[0], Pidls[1]);
1397 case SHCNE_UPDATEITEM:
1402 /**********************************************************
1406 static LRESULT CALLBACK ShellView_WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
1408 IShellViewImpl * pThis = (IShellViewImpl*)GetWindowLongA(hWnd, GWL_USERDATA);
1409 LPCREATESTRUCTA lpcs;
1411 TRACE("(hwnd=%p msg=%x wparm=%x lparm=%lx)\n",hWnd, uMessage, wParam, lParam);
1416 lpcs = (LPCREATESTRUCTA)lParam;
1417 pThis = (IShellViewImpl*)(lpcs->lpCreateParams);
1418 SetWindowLongA(hWnd, GWL_USERDATA, (LONG)pThis);
1419 pThis->hWnd = hWnd; /*set the window handle*/
1422 case WM_SIZE: return ShellView_OnSize(pThis,LOWORD(lParam), HIWORD(lParam));
1423 case WM_SETFOCUS: return ShellView_OnSetFocus(pThis);
1424 case WM_KILLFOCUS: return ShellView_OnKillFocus(pThis);
1425 case WM_CREATE: return ShellView_OnCreate(pThis);
1426 case WM_ACTIVATE: return ShellView_OnActivate(pThis, SVUIA_ACTIVATE_FOCUS);
1427 case WM_NOTIFY: return ShellView_OnNotify(pThis,(UINT)wParam, (LPNMHDR)lParam);
1428 case WM_COMMAND: return ShellView_OnCommand(pThis,
1429 GET_WM_COMMAND_ID(wParam, lParam),
1430 GET_WM_COMMAND_CMD(wParam, lParam),
1431 GET_WM_COMMAND_HWND(wParam, lParam));
1432 case SHV_CHANGE_NOTIFY: return ShellView_OnChange(pThis, (LPITEMIDLIST*)wParam, (LONG)lParam);
1434 case WM_CONTEXTMENU: ShellView_DoContextMenu(pThis, LOWORD(lParam), HIWORD(lParam), FALSE);
1437 case WM_SHOWWINDOW: UpdateWindow(pThis->hWndList);
1440 case WM_GETDLGCODE: return SendMessageA(pThis->hWndList,uMessage,0,0);
1442 case WM_DESTROY: if(GetShellOle() && pRevokeDragDrop)
1444 pRevokeDragDrop(pThis->hWnd);
1446 SHChangeNotifyDeregister(pThis->hNotify);
1450 return DefWindowProcA (hWnd, uMessage, wParam, lParam);
1452 /**********************************************************
1455 * The INTERFACE of the IShellView object
1458 **********************************************************
1459 * IShellView_QueryInterface
1461 static HRESULT WINAPI IShellView_fnQueryInterface(IShellView * iface,REFIID riid, LPVOID *ppvObj)
1463 ICOM_THIS(IShellViewImpl, iface);
1465 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1469 if(IsEqualIID(riid, &IID_IUnknown))
1473 else if(IsEqualIID(riid, &IID_IShellView))
1475 *ppvObj = (IShellView*)This;
1477 else if(IsEqualIID(riid, &IID_IOleCommandTarget))
1479 *ppvObj = (IOleCommandTarget*)&(This->lpvtblOleCommandTarget);
1481 else if(IsEqualIID(riid, &IID_IDropTarget))
1483 *ppvObj = (IDropTarget*)&(This->lpvtblDropTarget);
1485 else if(IsEqualIID(riid, &IID_IDropSource))
1487 *ppvObj = (IDropSource*)&(This->lpvtblDropSource);
1489 else if(IsEqualIID(riid, &IID_IViewObject))
1491 *ppvObj = (IViewObject*)&(This->lpvtblViewObject);
1496 IUnknown_AddRef( (IUnknown*)*ppvObj );
1497 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1500 TRACE("-- Interface: E_NOINTERFACE\n");
1501 return E_NOINTERFACE;
1504 /**********************************************************
1507 static ULONG WINAPI IShellView_fnAddRef(IShellView * iface)
1509 ICOM_THIS(IShellViewImpl, iface);
1511 TRACE("(%p)->(count=%lu)\n",This,This->ref);
1513 return ++(This->ref);
1515 /**********************************************************
1516 * IShellView_Release
1518 static ULONG WINAPI IShellView_fnRelease(IShellView * iface)
1520 ICOM_THIS(IShellViewImpl, iface);
1522 TRACE("(%p)->()\n",This);
1526 TRACE(" destroying IShellView(%p)\n",This);
1529 IShellFolder_Release(This->pSFParent);
1531 if(This->pSF2Parent)
1532 IShellFolder2_Release(This->pSF2Parent);
1535 SHFree(This->apidl);
1537 HeapFree(GetProcessHeap(),0,This);
1543 /**********************************************************
1544 * ShellView_GetWindow
1546 static HRESULT WINAPI IShellView_fnGetWindow(IShellView * iface,HWND * phWnd)
1548 ICOM_THIS(IShellViewImpl, iface);
1550 TRACE("(%p)\n",This);
1552 *phWnd = This->hWnd;
1557 static HRESULT WINAPI IShellView_fnContextSensitiveHelp(IShellView * iface,BOOL fEnterMode)
1559 ICOM_THIS(IShellViewImpl, iface);
1561 FIXME("(%p) stub\n",This);
1566 /**********************************************************
1567 * IShellView_TranslateAccelerator
1570 * use the accel functions
1572 static HRESULT WINAPI IShellView_fnTranslateAccelerator(IShellView * iface,LPMSG lpmsg)
1575 ICOM_THIS(IShellViewImpl, iface);
1577 FIXME("(%p)->(%p: hwnd=%x msg=%x lp=%lx wp=%x) stub\n",This,lpmsg, lpmsg->hwnd, lpmsg->message, lpmsg->lParam, lpmsg->wParam);
1580 if ((lpmsg->message>=WM_KEYFIRST) && (lpmsg->message>=WM_KEYLAST))
1582 TRACE("-- key=0x04%x\n",lpmsg->wParam) ;
1584 return S_FALSE; /* not handled */
1587 static HRESULT WINAPI IShellView_fnEnableModeless(IShellView * iface,BOOL fEnable)
1589 ICOM_THIS(IShellViewImpl, iface);
1591 FIXME("(%p) stub\n",This);
1596 static HRESULT WINAPI IShellView_fnUIActivate(IShellView * iface,UINT uState)
1598 ICOM_THIS(IShellViewImpl, iface);
1601 CHAR szName[MAX_PATH];
1604 int nPartArray[1] = {-1};
1606 TRACE("(%p)->(state=%x) stub\n",This, uState);
1608 /*don't do anything if the state isn't really changing*/
1609 if(This->uState == uState)
1614 /*OnActivate handles the menu merging and internal state*/
1615 ShellView_OnActivate(This, uState);
1617 /*only do This if we are active*/
1618 if(uState != SVUIA_DEACTIVATE)
1622 GetFolderPath is not a method of IShellFolder
1623 IShellFolder_GetFolderPath( This->pSFParent, szName, sizeof(szName) );
1625 /* set the number of parts */
1626 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETPARTS, 1,
1627 (LPARAM)nPartArray, &lResult);
1629 /* set the text for the parts */
1631 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETTEXTA,
1632 0, (LPARAM)szName, &lResult);
1639 static HRESULT WINAPI IShellView_fnRefresh(IShellView * iface)
1641 ICOM_THIS(IShellViewImpl, iface);
1643 TRACE("(%p)\n",This);
1645 ListView_DeleteAllItems(This->hWndList);
1646 ShellView_FillList(This);
1651 static HRESULT WINAPI IShellView_fnCreateViewWindow(
1653 IShellView *lpPrevView,
1654 LPCFOLDERSETTINGS lpfs,
1655 IShellBrowser * psb,
1659 ICOM_THIS(IShellViewImpl, iface);
1665 TRACE("(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n",This, lpPrevView,lpfs, psb, prcView, phWnd);
1666 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);
1668 /*set up the member variables*/
1669 This->pShellBrowser = psb;
1670 This->FolderSettings = *lpfs;
1672 /*get our parent window*/
1673 IShellBrowser_AddRef(This->pShellBrowser);
1674 IShellBrowser_GetWindow(This->pShellBrowser, &(This->hWndParent));
1676 /* try to get the ICommDlgBrowserInterface, adds a reference !!! */
1677 This->pCommDlgBrowser=NULL;
1678 if ( SUCCEEDED (IShellBrowser_QueryInterface( This->pShellBrowser,
1679 (REFIID)&IID_ICommDlgBrowser, (LPVOID*) &This->pCommDlgBrowser)))
1681 TRACE("-- CommDlgBrowser\n");
1684 /*if our window class has not been registered, then do so*/
1685 if(!GetClassInfoA(shell32_hInstance, SV_CLASS_NAME, &wc))
1687 ZeroMemory(&wc, sizeof(wc));
1688 wc.style = CS_HREDRAW | CS_VREDRAW;
1689 wc.lpfnWndProc = (WNDPROC) ShellView_WndProc;
1692 wc.hInstance = shell32_hInstance;
1694 wc.hCursor = LoadCursorA (0, IDC_ARROWA);
1695 wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
1696 wc.lpszMenuName = NULL;
1697 wc.lpszClassName = SV_CLASS_NAME;
1699 if(!RegisterClassA(&wc))
1703 *phWnd = CreateWindowExA(0,
1706 WS_CHILD | WS_VISIBLE | WS_TABSTOP,
1709 prcView->right - prcView->left,
1710 prcView->bottom - prcView->top,
1718 if(!*phWnd) return E_FAIL;
1723 static HRESULT WINAPI IShellView_fnDestroyViewWindow(IShellView * iface)
1725 ICOM_THIS(IShellViewImpl, iface);
1727 TRACE("(%p)\n",This);
1729 /*Make absolutely sure all our UI is cleaned up.*/
1730 IShellView_UIActivate((IShellView*)This, SVUIA_DEACTIVATE);
1734 DestroyMenu(This->hMenu);
1737 DestroyWindow(This->hWnd);
1738 if(This->pShellBrowser) IShellBrowser_Release(This->pShellBrowser);
1739 if(This->pCommDlgBrowser) ICommDlgBrowser_Release(This->pCommDlgBrowser);
1745 static HRESULT WINAPI IShellView_fnGetCurrentInfo(IShellView * iface, LPFOLDERSETTINGS lpfs)
1747 ICOM_THIS(IShellViewImpl, iface);
1749 TRACE("(%p)->(%p) vmode=%x flags=%x\n",This, lpfs,
1750 This->FolderSettings.ViewMode, This->FolderSettings.fFlags);
1752 if (!lpfs) return E_INVALIDARG;
1754 *lpfs = This->FolderSettings;
1758 static HRESULT WINAPI IShellView_fnAddPropertySheetPages(IShellView * iface, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam)
1760 ICOM_THIS(IShellViewImpl, iface);
1762 FIXME("(%p) stub\n",This);
1767 static HRESULT WINAPI IShellView_fnSaveViewState(IShellView * iface)
1769 ICOM_THIS(IShellViewImpl, iface);
1771 FIXME("(%p) stub\n",This);
1776 static HRESULT WINAPI IShellView_fnSelectItem(
1781 ICOM_THIS(IShellViewImpl, iface);
1784 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n",This, pidl, uFlags);
1786 i = LV_FindItemByPidl(This, pidl);
1792 if(uFlags & SVSI_ENSUREVISIBLE)
1793 ListView_EnsureVisible(This->hWndList, i, 0);
1795 ZeroMemory(&lvItem, sizeof(LVITEMA));
1796 lvItem.mask = LVIF_STATE;
1799 while(ListView_GetItemA(This->hWndList, &lvItem))
1801 if (lvItem.iItem == i)
1803 if (uFlags & SVSI_SELECT)
1804 lvItem.state |= LVIS_SELECTED;
1806 lvItem.state &= ~LVIS_SELECTED;
1808 if(uFlags & SVSI_FOCUSED)
1809 lvItem.state &= ~LVIS_FOCUSED;
1813 if (uFlags & SVSI_DESELECTOTHERS)
1814 lvItem.state &= ~LVIS_SELECTED;
1816 ListView_SetItemA(This->hWndList, &lvItem);
1821 if(uFlags & SVSI_EDIT)
1822 ListView_EditLabelA(This->hWndList, i);
1828 static HRESULT WINAPI IShellView_fnGetItemObject(IShellView * iface, UINT uItem, REFIID riid, LPVOID *ppvOut)
1830 ICOM_THIS(IShellViewImpl, iface);
1832 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n",This, uItem, debugstr_guid(riid), ppvOut);
1838 case SVGIO_BACKGROUND:
1839 *ppvOut = ISvBgCm_Constructor(This->pSFParent);
1842 case SVGIO_SELECTION:
1843 ShellView_GetSelections(This);
1844 IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, (LPCITEMIDLIST*)This->apidl, riid, 0, ppvOut);
1847 TRACE("-- (%p)->(interface=%p)\n",This, *ppvOut);
1849 if(!*ppvOut) return E_OUTOFMEMORY;
1854 static HRESULT WINAPI IShellView_fnEditItem(
1858 ICOM_THIS(IShellViewImpl, iface);
1861 TRACE("(%p)->(pidl=%p)\n",This, pidl);
1863 i = LV_FindItemByPidl(This, pidl);
1866 SetFocus(This->hWndList);
1867 ListView_EditLabelA(This->hWndList, i);
1872 static struct ICOM_VTABLE(IShellView) svvt =
1874 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1875 IShellView_fnQueryInterface,
1876 IShellView_fnAddRef,
1877 IShellView_fnRelease,
1878 IShellView_fnGetWindow,
1879 IShellView_fnContextSensitiveHelp,
1880 IShellView_fnTranslateAccelerator,
1881 IShellView_fnEnableModeless,
1882 IShellView_fnUIActivate,
1883 IShellView_fnRefresh,
1884 IShellView_fnCreateViewWindow,
1885 IShellView_fnDestroyViewWindow,
1886 IShellView_fnGetCurrentInfo,
1887 IShellView_fnAddPropertySheetPages,
1888 IShellView_fnSaveViewState,
1889 IShellView_fnSelectItem,
1890 IShellView_fnGetItemObject,
1891 IShellView_fnEditItem
1895 /**********************************************************
1896 * ISVOleCmdTarget_QueryInterface (IUnknown)
1898 static HRESULT WINAPI ISVOleCmdTarget_QueryInterface(
1899 IOleCommandTarget * iface,
1903 _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
1905 return IShellFolder_QueryInterface((IShellFolder*)This, iid, ppvObj);
1908 /**********************************************************
1909 * ISVOleCmdTarget_AddRef (IUnknown)
1911 static ULONG WINAPI ISVOleCmdTarget_AddRef(
1912 IOleCommandTarget * iface)
1914 _ICOM_THIS_From_IOleCommandTarget(IShellFolder, iface);
1916 return IShellFolder_AddRef((IShellFolder*)This);
1919 /**********************************************************
1920 * ISVOleCmdTarget_Release (IUnknown)
1922 static ULONG WINAPI ISVOleCmdTarget_Release(
1923 IOleCommandTarget * iface)
1925 _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
1927 return IShellFolder_Release((IShellFolder*)This);
1930 /**********************************************************
1931 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
1933 static HRESULT WINAPI ISVOleCmdTarget_QueryStatus(
1934 IOleCommandTarget *iface,
1935 const GUID* pguidCmdGroup,
1938 OLECMDTEXT* pCmdText)
1941 _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
1943 FIXME("(%p)->(%p(%s) 0x%08lx %p %p\n",
1944 This, pguidCmdGroup, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText);
1948 for (i = 0; i < cCmds; i++)
1950 FIXME("\tprgCmds[%d].cmdID = %ld\n", i, prgCmds[i].cmdID);
1951 prgCmds[i].cmdf = 0;
1953 return OLECMDERR_E_UNKNOWNGROUP;
1956 /**********************************************************
1957 * ISVOleCmdTarget_Exec (IOleCommandTarget)
1959 * nCmdID is the OLECMDID_* enumeration
1961 static HRESULT WINAPI ISVOleCmdTarget_Exec(
1962 IOleCommandTarget *iface,
1963 const GUID* pguidCmdGroup,
1969 _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
1971 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08lx Opt:0x%08lx %p %p)\n",
1972 This, debugstr_guid(pguidCmdGroup), nCmdID, nCmdexecopt, pvaIn, pvaOut);
1974 if (IsEqualIID(pguidCmdGroup, &CGID_Explorer) &&
1976 (nCmdexecopt == 4) && pvaOut)
1978 if (IsEqualIID(pguidCmdGroup, &CGID_ShellDocView) &&
1983 return OLECMDERR_E_UNKNOWNGROUP;
1986 static ICOM_VTABLE(IOleCommandTarget) ctvt =
1988 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1989 ISVOleCmdTarget_QueryInterface,
1990 ISVOleCmdTarget_AddRef,
1991 ISVOleCmdTarget_Release,
1992 ISVOleCmdTarget_QueryStatus,
1993 ISVOleCmdTarget_Exec
1996 /**********************************************************
1997 * ISVDropTarget implementation
2000 static HRESULT WINAPI ISVDropTarget_QueryInterface(
2005 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2007 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2009 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2012 static ULONG WINAPI ISVDropTarget_AddRef( IDropTarget *iface)
2014 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2016 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2018 return IShellFolder_AddRef((IShellFolder*)This);
2021 static ULONG WINAPI ISVDropTarget_Release( IDropTarget *iface)
2023 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2025 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2027 return IShellFolder_Release((IShellFolder*)This);
2030 static HRESULT WINAPI ISVDropTarget_DragEnter(
2032 IDataObject *pDataObject,
2038 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2040 FIXME("Stub: This=%p, DataObject=%p\n",This,pDataObject);
2045 static HRESULT WINAPI ISVDropTarget_DragOver(
2051 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2053 FIXME("Stub: This=%p\n",This);
2058 static HRESULT WINAPI ISVDropTarget_DragLeave(
2061 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2063 FIXME("Stub: This=%p\n",This);
2068 static HRESULT WINAPI ISVDropTarget_Drop(
2070 IDataObject* pDataObject,
2075 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2077 FIXME("Stub: This=%p\n",This);
2082 static struct ICOM_VTABLE(IDropTarget) dtvt =
2084 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2085 ISVDropTarget_QueryInterface,
2086 ISVDropTarget_AddRef,
2087 ISVDropTarget_Release,
2088 ISVDropTarget_DragEnter,
2089 ISVDropTarget_DragOver,
2090 ISVDropTarget_DragLeave,
2094 /**********************************************************
2095 * ISVDropSource implementation
2098 static HRESULT WINAPI ISVDropSource_QueryInterface(
2103 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2105 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2107 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2110 static ULONG WINAPI ISVDropSource_AddRef( IDropSource *iface)
2112 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2114 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2116 return IShellFolder_AddRef((IShellFolder*)This);
2119 static ULONG WINAPI ISVDropSource_Release( IDropSource *iface)
2121 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2123 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2125 return IShellFolder_Release((IShellFolder*)This);
2127 static HRESULT WINAPI ISVDropSource_QueryContinueDrag(
2129 BOOL fEscapePressed,
2132 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2133 TRACE("(%p)\n",This);
2136 return DRAGDROP_S_CANCEL;
2137 else if (!(grfKeyState & MK_LBUTTON) && !(grfKeyState & MK_RBUTTON))
2138 return DRAGDROP_S_DROP;
2143 static HRESULT WINAPI ISVDropSource_GiveFeedback(
2147 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2148 TRACE("(%p)\n",This);
2150 return DRAGDROP_S_USEDEFAULTCURSORS;
2153 static struct ICOM_VTABLE(IDropSource) dsvt =
2155 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2156 ISVDropSource_QueryInterface,
2157 ISVDropSource_AddRef,
2158 ISVDropSource_Release,
2159 ISVDropSource_QueryContinueDrag,
2160 ISVDropSource_GiveFeedback
2162 /**********************************************************
2163 * ISVViewObject implementation
2166 static HRESULT WINAPI ISVViewObject_QueryInterface(
2171 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2173 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2175 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2178 static ULONG WINAPI ISVViewObject_AddRef( IViewObject *iface)
2180 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2182 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2184 return IShellFolder_AddRef((IShellFolder*)This);
2187 static ULONG WINAPI ISVViewObject_Release( IViewObject *iface)
2189 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2191 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2193 return IShellFolder_Release((IShellFolder*)This);
2196 static HRESULT WINAPI ISVViewObject_Draw(
2201 DVTARGETDEVICE* ptd,
2204 LPCRECTL lprcBounds,
2205 LPCRECTL lprcWBounds,
2206 BOOL (CALLBACK *pfnContinue)(ULONG_PTR dwContinue),
2210 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2212 FIXME("Stub: This=%p\n",This);
2216 static HRESULT WINAPI ISVViewObject_GetColorSet(
2221 DVTARGETDEVICE* ptd,
2222 HDC hicTargetDevice,
2223 LOGPALETTE** ppColorSet)
2226 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2228 FIXME("Stub: This=%p\n",This);
2232 static HRESULT WINAPI ISVViewObject_Freeze(
2240 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2242 FIXME("Stub: This=%p\n",This);
2246 static HRESULT WINAPI ISVViewObject_Unfreeze(
2251 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2253 FIXME("Stub: This=%p\n",This);
2257 static HRESULT WINAPI ISVViewObject_SetAdvise(
2261 IAdviseSink* pAdvSink)
2264 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2266 FIXME("Stub: This=%p\n",This);
2270 static HRESULT WINAPI ISVViewObject_GetAdvise(
2274 IAdviseSink** ppAdvSink)
2277 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2279 FIXME("Stub: This=%p\n",This);
2285 static struct ICOM_VTABLE(IViewObject) vovt =
2287 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2288 ISVViewObject_QueryInterface,
2289 ISVViewObject_AddRef,
2290 ISVViewObject_Release,
2292 ISVViewObject_GetColorSet,
2293 ISVViewObject_Freeze,
2294 ISVViewObject_Unfreeze,
2295 ISVViewObject_SetAdvise,
2296 ISVViewObject_GetAdvise