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 * FIXME: The order by part of the background context menu should be
10 * buily according to the columns shown.
12 * FIXME: Load/Save the view state from/into the stream provied by
15 * FIXME: CheckToolbar: handle the "new folder" and "folder up" button
17 * FIXME: ShellView_FillList: consider sort orders
19 * FIXME: implement the drag and drop in the old (msg-based) way
21 * FIXME: when the ShellView_WndProc gets a WM_NCDESTROY should we do a
34 #include "undocshell.h"
36 #include "debugtools.h"
40 #include "shell32_main.h"
41 #include "shellfolder.h"
43 DEFAULT_DEBUG_CHANNEL(shell);
49 }LISTVIEW_SORT_INFO, *LPLISTVIEW_SORT_INFO;
52 { ICOM_VFIELD(IShellView);
54 ICOM_VTABLE(IOleCommandTarget)* lpvtblOleCommandTarget;
55 ICOM_VTABLE(IDropTarget)* lpvtblDropTarget;
56 ICOM_VTABLE(IDropSource)* lpvtblDropSource;
57 ICOM_VTABLE(IViewObject)* lpvtblViewObject;
58 IShellFolder* pSFParent;
59 IShellFolder2* pSF2Parent;
60 IShellBrowser* pShellBrowser;
61 ICommDlgBrowser* pCommDlgBrowser;
62 HWND hWnd; /* SHELLDLL_DefView */
63 HWND hWndList; /* ListView control */
65 FOLDERSETTINGS FolderSettings;
70 LISTVIEW_SORT_INFO ListViewSortInfo;
71 HANDLE hNotify; /* change notification handle */
75 static struct ICOM_VTABLE(IShellView) svvt;
77 static struct ICOM_VTABLE(IOleCommandTarget) ctvt;
78 #define _IOleCommandTarget_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblOleCommandTarget)))
79 #define _ICOM_THIS_From_IOleCommandTarget(class, name) class* This = (class*)(((char*)name)-_IOleCommandTarget_Offset);
81 static struct ICOM_VTABLE(IDropTarget) dtvt;
82 #define _IDropTarget_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblDropTarget)))
83 #define _ICOM_THIS_From_IDropTarget(class, name) class* This = (class*)(((char*)name)-_IDropTarget_Offset);
85 static struct ICOM_VTABLE(IDropSource) dsvt;
86 #define _IDropSource_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblDropSource)))
87 #define _ICOM_THIS_From_IDropSource(class, name) class* This = (class*)(((char*)name)-_IDropSource_Offset);
89 static struct ICOM_VTABLE(IViewObject) vovt;
90 #define _IViewObject_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblViewObject)))
91 #define _ICOM_THIS_From_IViewObject(class, name) class* This = (class*)(((char*)name)-_IViewObject_Offset);
93 /* ListView Header ID's */
94 #define LISTVIEW_COLUMN_NAME 0
95 #define LISTVIEW_COLUMN_SIZE 1
96 #define LISTVIEW_COLUMN_TYPE 2
97 #define LISTVIEW_COLUMN_TIME 3
98 #define LISTVIEW_COLUMN_ATTRIB 4
101 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
102 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
103 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
105 #define ID_LISTVIEW 2000
107 #define SHV_CHANGE_NOTIFY WM_USER + 0x1111
110 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
111 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
112 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
114 extern void WINAPI _InsertMenuItem (HMENU hmenu, UINT indexMenu, BOOL fByPosition,
115 UINT wID, UINT fType, LPSTR dwTypeData, UINT fState);
118 Items merged into the toolbar and and the filemenu
127 } MYTOOLINFO, *LPMYTOOLINFO;
131 { FCIDM_SHVIEW_BIGICON, 0, 0, IDS_VIEW_LARGE, TBSTATE_ENABLED, TBSTYLE_BUTTON },
132 { FCIDM_SHVIEW_SMALLICON, 0, 0, IDS_VIEW_SMALL, TBSTATE_ENABLED, TBSTYLE_BUTTON },
133 { FCIDM_SHVIEW_LISTVIEW, 0, 0, IDS_VIEW_LIST, TBSTATE_ENABLED, TBSTYLE_BUTTON },
134 { FCIDM_SHVIEW_REPORTVIEW, 0, 0, IDS_VIEW_DETAILS, TBSTATE_ENABLED, TBSTYLE_BUTTON },
138 typedef void (CALLBACK *PFNSHGETSETTINGSPROC)(LPSHELLFLAGSTATE lpsfs, DWORD dwMask);
140 /**********************************************************
141 * IShellView_Constructor
143 IShellView * IShellView_Constructor( IShellFolder * pFolder)
144 { IShellViewImpl * sv;
145 sv=(IShellViewImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IShellViewImpl));
148 sv->lpvtblOleCommandTarget=&ctvt;
149 sv->lpvtblDropTarget=&dtvt;
150 sv->lpvtblDropSource=&dsvt;
151 sv->lpvtblViewObject=&vovt;
153 sv->pSFParent = pFolder;
154 if(pFolder) IShellFolder_AddRef(pFolder);
155 IShellFolder_QueryInterface(sv->pSFParent, &IID_IShellFolder2, (LPVOID*)&sv->pSF2Parent);
157 TRACE("(%p)->(%p)\n",sv, pFolder);
159 return (IShellView *) sv;
162 /**********************************************************
164 * ##### helperfunctions for communication with ICommDlgBrowser #####
166 static BOOL IsInCommDlg(IShellViewImpl * This)
167 { return(This->pCommDlgBrowser != NULL);
170 static HRESULT IncludeObject(IShellViewImpl * This, LPCITEMIDLIST pidl)
174 if ( IsInCommDlg(This) )
176 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl);
177 ret = ICommDlgBrowser_IncludeObject(This->pCommDlgBrowser, (IShellView*)This, pidl);
178 TRACE("--0x%08lx\n", ret);
183 static HRESULT OnDefaultCommand(IShellViewImpl * This)
185 HRESULT ret = S_FALSE;
187 if (IsInCommDlg(This))
189 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
190 ret = ICommDlgBrowser_OnDefaultCommand(This->pCommDlgBrowser, (IShellView*)This);
196 static HRESULT OnStateChange(IShellViewImpl * This, UINT uFlags)
198 HRESULT ret = S_FALSE;
200 if (IsInCommDlg(This))
202 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags);
203 ret = ICommDlgBrowser_OnStateChange(This->pCommDlgBrowser, (IShellView*)This, uFlags);
208 /**********************************************************
209 * set the toolbar of the filedialog buttons
211 * - activates the buttons from the shellbrowser according to
214 static void CheckToolbar(IShellViewImpl * This)
220 if (IsInCommDlg(This))
222 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
223 FCIDM_TB_SMALLICON, (This->FolderSettings.ViewMode==FVM_LIST)? TRUE : FALSE, &result);
224 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
225 FCIDM_TB_REPORTVIEW, (This->FolderSettings.ViewMode==FVM_DETAILS)? TRUE : FALSE, &result);
226 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
227 FCIDM_TB_SMALLICON, TRUE, &result);
228 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
229 FCIDM_TB_REPORTVIEW, TRUE, &result);
233 /**********************************************************
235 * ##### helperfunctions for initializing the view #####
237 /**********************************************************
238 * change the style of the listview control
240 static void SetStyle(IShellViewImpl * This, DWORD dwAdd, DWORD dwRemove)
244 TRACE("(%p)\n", This);
246 tmpstyle = GetWindowLongA(This->hWndList, GWL_STYLE);
247 SetWindowLongA(This->hWndList, GWL_STYLE, dwAdd | (tmpstyle & ~dwRemove));
250 /**********************************************************
251 * ShellView_CreateList()
253 * - creates the list view window
255 static BOOL ShellView_CreateList (IShellViewImpl * This)
260 dwStyle = WS_TABSTOP | WS_VISIBLE | WS_CHILDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
261 LVS_SHAREIMAGELISTS | LVS_EDITLABELS | LVS_ALIGNLEFT | LVS_AUTOARRANGE;
263 switch (This->FolderSettings.ViewMode)
265 case FVM_ICON: dwStyle |= LVS_ICON; break;
266 case FVM_DETAILS: dwStyle |= LVS_REPORT; break;
267 case FVM_SMALLICON: dwStyle |= LVS_SMALLICON; break;
268 case FVM_LIST: dwStyle |= LVS_LIST; break;
269 default: dwStyle |= LVS_LIST; break;
272 if (This->FolderSettings.fFlags & FWF_AUTOARRANGE) dwStyle |= LVS_AUTOARRANGE;
273 /*if (This->FolderSettings.fFlags && FWF_DESKTOP); used from explorer*/
274 if (This->FolderSettings.fFlags & FWF_SINGLESEL) dwStyle |= LVS_SINGLESEL;
276 This->hWndList=CreateWindowExA( WS_EX_CLIENTEDGE,
289 This->ListViewSortInfo.bIsAscending = TRUE;
290 This->ListViewSortInfo.nHeaderID = -1;
291 This->ListViewSortInfo.nLastHeaderID = -1;
293 /* UpdateShellSettings(); */
297 /**********************************************************
298 * ShellView_InitList()
300 * - adds all needed columns to the shellview
302 static BOOL ShellView_InitList(IShellViewImpl * This)
311 ListView_DeleteAllItems(This->hWndList);
313 lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT;
314 lvColumn.pszText = szTemp;
316 if (This->pSF2Parent)
320 if (!SUCCEEDED(IShellFolder2_GetDetailsOf(This->pSF2Parent, NULL, i, &sd)))
322 lvColumn.fmt = sd.fmt;
323 lvColumn.cx = sd.cxChar*8; /* chars->pixel */
324 StrRetToStrNA( szTemp, 50, &sd.str, NULL);
325 ListView_InsertColumnA(This->hWndList, i, &lvColumn);
333 ListView_SetImageList(This->hWndList, ShellSmallIconList, LVSIL_SMALL);
334 ListView_SetImageList(This->hWndList, ShellBigIconList, LVSIL_NORMAL);
338 /**********************************************************
339 * ShellView_CompareItems()
342 * internal, CALLBACK for DSA_Sort
344 static INT CALLBACK ShellView_CompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
347 TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1, lParam2, (LPVOID) lpData);
349 if(!lpData) return 0;
351 ret = (SHORT) SCODE_CODE(IShellFolder_CompareIDs((LPSHELLFOLDER)lpData, 0, (LPITEMIDLIST)lParam1, (LPITEMIDLIST)lParam2));
352 TRACE("ret=%i\n",ret);
356 /*************************************************************************
357 * ShellView_ListViewCompareItems
359 * Compare Function for the Listview (FileOpen Dialog)
362 * lParam1 [I] the first ItemIdList to compare with
363 * lParam2 [I] the second ItemIdList to compare with
364 * lpData [I] The column ID for the header Ctrl to process
367 * A negative value if the first item should precede the second,
368 * a positive value if the first item should follow the second,
369 * or zero if the two items are equivalent
372 * FIXME: function does what ShellView_CompareItems is supposed to do.
373 * unify it and figure out how to use the undocumented first parameter
374 * of IShellFolder_CompareIDs to do the job this function does and
375 * move this code to IShellFolder.
376 * make LISTVIEW_SORT_INFO obsolete
377 * the way this function works is only usable if we had only
378 * filesystemfolders (25/10/99 jsch)
380 static INT CALLBACK ShellView_ListViewCompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
384 char strName1[MAX_PATH], strName2[MAX_PATH];
385 BOOL bIsFolder1, bIsFolder2,bIsBothFolder;
386 LPITEMIDLIST pItemIdList1 = (LPITEMIDLIST) lParam1;
387 LPITEMIDLIST pItemIdList2 = (LPITEMIDLIST) lParam2;
388 LISTVIEW_SORT_INFO *pSortInfo = (LPLISTVIEW_SORT_INFO) lpData;
391 bIsFolder1 = _ILIsFolder(pItemIdList1);
392 bIsFolder2 = _ILIsFolder(pItemIdList2);
393 bIsBothFolder = bIsFolder1 && bIsFolder2;
395 /* When sorting between a File and a Folder, the Folder gets sorted first */
396 if( (bIsFolder1 || bIsFolder2) && !bIsBothFolder)
398 nDiff = bIsFolder1 ? -1 : 1;
402 /* Sort by Time: Folders or Files can be sorted */
404 if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TIME)
406 _ILGetFileDateTime(pItemIdList1, &fd1);
407 _ILGetFileDateTime(pItemIdList2, &fd2);
408 nDiff = CompareFileTime(&fd2, &fd1);
410 /* Sort by Attribute: Folder or Files can be sorted */
411 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_ATTRIB)
413 _ILGetFileAttributes(pItemIdList1, strName1, MAX_PATH);
414 _ILGetFileAttributes(pItemIdList2, strName2, MAX_PATH);
415 nDiff = strcasecmp(strName1, strName2);
417 /* Sort by FileName: Folder or Files can be sorted */
418 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_NAME || bIsBothFolder)
421 _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
422 _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
423 nDiff = strcasecmp(strName1, strName2);
425 /* Sort by File Size, Only valid for Files */
426 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_SIZE)
428 nDiff = (INT)(_ILGetFileSize(pItemIdList1, NULL, 0) - _ILGetFileSize(pItemIdList2, NULL, 0));
430 /* Sort by File Type, Only valid for Files */
431 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TYPE)
434 _ILGetFileType(pItemIdList1, strName1, MAX_PATH);
435 _ILGetFileType(pItemIdList2, strName2, MAX_PATH);
436 nDiff = strcasecmp(strName1, strName2);
439 /* If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
443 _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
444 _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
445 nDiff = strcasecmp(strName1, strName2);
448 if(!pSortInfo->bIsAscending)
457 /**********************************************************
458 * LV_FindItemByPidl()
460 static int LV_FindItemByPidl(
461 IShellViewImpl * This,
465 ZeroMemory(&lvItem, sizeof(LVITEMA));
466 lvItem.mask = LVIF_PARAM;
467 for(lvItem.iItem = 0; ListView_GetItemA(This->hWndList, &lvItem); lvItem.iItem++)
469 LPITEMIDLIST currentpidl = (LPITEMIDLIST) lvItem.lParam;
470 HRESULT hr = IShellFolder_CompareIDs(This->pSFParent, 0, pidl, currentpidl);
471 if(SUCCEEDED(hr) && !HRESULT_CODE(hr))
479 /**********************************************************
482 static BOOLEAN LV_AddItem(IShellViewImpl * This, LPCITEMIDLIST pidl)
486 TRACE("(%p)(pidl=%p)\n", This, pidl);
488 ZeroMemory(&lvItem, sizeof(lvItem)); /* create the listview item*/
489 lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; /*set the mask*/
490 lvItem.iItem = ListView_GetItemCount(This->hWndList); /*add the item to the end of the list*/
491 lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidl)); /*set the item's data*/
492 lvItem.pszText = LPSTR_TEXTCALLBACKA; /*get text on a callback basis*/
493 lvItem.iImage = I_IMAGECALLBACK; /*get the image on a callback basis*/
494 return (-1==ListView_InsertItemA(This->hWndList, &lvItem))? FALSE: TRUE;
497 /**********************************************************
500 static BOOLEAN LV_DeleteItem(IShellViewImpl * This, LPCITEMIDLIST pidl)
504 TRACE("(%p)(pidl=%p)\n", This, pidl);
506 nIndex = LV_FindItemByPidl(This, ILFindLastID(pidl));
507 return (-1==ListView_DeleteItem(This->hWndList, nIndex))? FALSE: TRUE;
510 /**********************************************************
513 static BOOLEAN LV_RenameItem(IShellViewImpl * This, LPCITEMIDLIST pidlOld, LPCITEMIDLIST pidlNew )
518 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", This, pidlOld, pidlNew);
520 nItem = LV_FindItemByPidl(This, ILFindLastID(pidlOld));
523 ZeroMemory(&lvItem, sizeof(lvItem)); /* create the listview item*/
524 lvItem.mask = LVIF_PARAM; /* only the pidl */
525 lvItem.iItem = nItem;
526 ListView_GetItemA(This->hWndList, &lvItem);
528 SHFree((LPITEMIDLIST)lvItem.lParam);
529 lvItem.mask = LVIF_PARAM;
530 lvItem.iItem = nItem;
531 lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidlNew)); /* set the item's data */
532 ListView_SetItemA(This->hWndList, &lvItem);
533 ListView_Update(This->hWndList, nItem);
534 return TRUE; /* FIXME: better handling */
538 /**********************************************************
539 * ShellView_FillList()
541 * - gets the objectlist from the shellfolder
543 * - fills the list into the view
546 static HRESULT ShellView_FillList(IShellViewImpl * This)
548 LPENUMIDLIST pEnumIDList;
557 /* get the itemlist from the shfolder*/
558 hRes = IShellFolder_EnumObjects(This->pSFParent,This->hWnd, SHCONTF_NONFOLDERS | SHCONTF_FOLDERS, &pEnumIDList);
566 /* create a pointer array */
567 hdpa = pDPA_Create(16);
570 return(E_OUTOFMEMORY);
573 /* copy the items into the array*/
574 while((S_OK == IEnumIDList_Next(pEnumIDList,1, &pidl, &dwFetched)) && dwFetched)
576 if (pDPA_InsertPtr(hdpa, 0x7fff, pidl) == -1)
583 pDPA_Sort(hdpa, ShellView_CompareItems, (LPARAM)This->pSFParent);
585 /*turn the listview's redrawing off*/
586 SendMessageA(This->hWndList, WM_SETREDRAW, FALSE, 0);
588 for (i=0; i < DPA_GetPtrCount(hdpa); ++i) /* DPA_GetPtrCount is a macro*/
590 pidl = (LPITEMIDLIST)pDPA_GetPtr(hdpa, i);
592 /* in a commdlg This works as a filemask*/
593 if ( IncludeObject(This, pidl)==S_OK )
594 LV_AddItem(This, pidl);
598 /*turn the listview's redrawing back on and force it to draw*/
599 SendMessageA(This->hWndList, WM_SETREDRAW, TRUE, 0);
601 IEnumIDList_Release(pEnumIDList); /* destroy the list*/
607 /**********************************************************
608 * ShellView_OnCreate()
610 static LRESULT ShellView_OnCreate(IShellViewImpl * This)
613 NOTIFYREGISTER ntreg;
614 IPersistFolder2 * ppf2 = NULL;
618 if(ShellView_CreateList(This))
620 if(ShellView_InitList(This))
622 ShellView_FillList(This);
628 if (SUCCEEDED(IShellFolder_CreateViewObject(This->pSFParent, This->hWnd, &IID_IDropTarget, (LPVOID*)&pdt)))
630 pRegisterDragDrop(This->hWnd, pdt);
631 IDropTarget_Release(pdt);
635 /* register for receiving notifications */
636 IShellFolder_QueryInterface(This->pSFParent, &IID_IPersistFolder2, (LPVOID*)&ppf2);
639 IPersistFolder2_GetCurFolder(ppf2, &ntreg.pidlPath);
640 ntreg.bWatchSubtree = FALSE;
641 This->hNotify = SHChangeNotifyRegister(This->hWnd, SHCNF_IDLIST, SHCNE_ALLEVENTS, SHV_CHANGE_NOTIFY, 1, &ntreg);
642 SHFree(ntreg.pidlPath);
643 IPersistFolder2_Release(ppf2);
646 This->hAccel = LoadAcceleratorsA(shell32_hInstance, "shv_accel");
651 /**********************************************************
652 * #### Handling of the menus ####
655 /**********************************************************
656 * ShellView_BuildFileMenu()
658 static HMENU ShellView_BuildFileMenu(IShellViewImpl * This)
659 { CHAR szText[MAX_PATH];
664 TRACE("(%p)\n",This);
666 hSubMenu = CreatePopupMenu();
668 { /*get the number of items in our global array*/
669 for(nTools = 0; Tools[nTools].idCommand != -1; nTools++){}
671 /*add the menu items*/
672 for(i = 0; i < nTools; i++)
674 LoadStringA(shell32_hInstance, Tools[i].idMenuString, szText, MAX_PATH);
676 ZeroMemory(&mii, sizeof(mii));
677 mii.cbSize = sizeof(mii);
678 mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
680 if(TBSTYLE_SEP != Tools[i].bStyle) /* no seperator*/
682 mii.fType = MFT_STRING;
683 mii.fState = MFS_ENABLED;
684 mii.dwTypeData = szText;
685 mii.wID = Tools[i].idCommand;
689 mii.fType = MFT_SEPARATOR;
691 /* tack This item onto the end of the menu */
692 InsertMenuItemA(hSubMenu, (UINT)-1, TRUE, &mii);
695 TRACE("-- return (menu=0x%x)\n",hSubMenu);
698 /**********************************************************
699 * ShellView_MergeFileMenu()
701 static void ShellView_MergeFileMenu(IShellViewImpl * This, HMENU hSubMenu)
702 { TRACE("(%p)->(submenu=0x%08x) stub\n",This,hSubMenu);
705 { /*insert This item at the beginning of the menu */
706 _InsertMenuItem(hSubMenu, 0, TRUE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
707 _InsertMenuItem(hSubMenu, 0, TRUE, IDM_MYFILEITEM, MFT_STRING, "dummy45", MFS_ENABLED);
713 /**********************************************************
714 * ShellView_MergeViewMenu()
717 static void ShellView_MergeViewMenu(IShellViewImpl * This, HMENU hSubMenu)
720 TRACE("(%p)->(submenu=0x%08x)\n",This,hSubMenu);
723 { /*add a separator at the correct position in the menu*/
724 _InsertMenuItem(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
726 ZeroMemory(&mii, sizeof(mii));
727 mii.cbSize = sizeof(mii);
728 mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_DATA;;
729 mii.fType = MFT_STRING;
730 mii.dwTypeData = "View";
731 mii.hSubMenu = LoadMenuA(shell32_hInstance, "MENU_001");
732 InsertMenuItemA(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
736 /**********************************************************
737 * ShellView_GetSelections()
739 * - fills the this->apidl list with the selected objects
742 * number of selected items
744 static UINT ShellView_GetSelections(IShellViewImpl * This)
754 This->cidl = ListView_GetSelectedCount(This->hWndList);
755 This->apidl = (LPITEMIDLIST*)SHAlloc(This->cidl * sizeof(LPITEMIDLIST));
757 TRACE("selected=%i\n", This->cidl);
761 TRACE("-- Items selected =%u\n", This->cidl);
763 ZeroMemory(&lvItem, sizeof(lvItem));
764 lvItem.mask = LVIF_STATE | LVIF_PARAM;
765 lvItem.stateMask = LVIS_SELECTED;
767 while(ListView_GetItemA(This->hWndList, &lvItem) && (i < This->cidl))
769 if(lvItem.state & LVIS_SELECTED)
771 This->apidl[i] = (LPITEMIDLIST)lvItem.lParam;
773 TRACE("-- selected Item found\n");
781 /**********************************************************
782 * ShellView_DoContextMenu()
784 static void ShellView_DoContextMenu(IShellViewImpl * This, WORD x, WORD y, BOOL bDefault)
788 BOOL fExplore = FALSE;
790 LPCONTEXTMENU pContextMenu = NULL;
791 IContextMenu * pCM = NULL;
792 CMINVOKECOMMANDINFO cmi;
794 TRACE("(%p)->(0x%08x 0x%08x 0x%08x) stub\n",This, x, y, bDefault);
796 /* look, what's selected and create a context menu object of it*/
797 if( ShellView_GetSelections(This) )
799 IShellFolder_GetUIObjectOf( This->pSFParent, This->hWndParent, This->cidl, This->apidl,
800 (REFIID)&IID_IContextMenu, NULL, (LPVOID *)&pContextMenu);
804 TRACE("-- pContextMenu\n");
805 hMenu = CreatePopupMenu();
809 /* See if we are in Explore or Open mode. If the browser's tree is present, we are in Explore mode.*/
810 if(SUCCEEDED(IShellBrowser_GetControlWindow(This->pShellBrowser,FCW_TREE, &hwndTree)) && hwndTree)
812 TRACE("-- explore mode\n");
816 /* build the flags depending on what we can do with the selected item */
817 wFlags = CMF_NORMAL | (This->cidl != 1 ? 0 : CMF_CANRENAME) | (fExplore ? CMF_EXPLORE : 0);
819 /* let the ContextMenu merge its items in */
820 if (SUCCEEDED(IContextMenu_QueryContextMenu( pContextMenu, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, wFlags )))
824 TRACE("-- get menu default command\n");
825 uCommand = GetMenuDefaultItem(hMenu, FALSE, GMDI_GOINTOPOPUPS);
829 TRACE("-- track popup\n");
830 uCommand = TrackPopupMenu( hMenu,TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
835 TRACE("-- uCommand=%u\n", uCommand);
836 if (IsInCommDlg(This) && ((uCommand==FCIDM_SHVIEW_EXPLORE) || (uCommand==FCIDM_SHVIEW_OPEN)))
838 TRACE("-- dlg: OnDefaultCommand\n");
839 OnDefaultCommand(This);
843 TRACE("-- explore -- invoke command\n");
844 ZeroMemory(&cmi, sizeof(cmi));
845 cmi.cbSize = sizeof(cmi);
846 cmi.hwnd = This->hWndParent; /* this window has to answer CWM_GETISHELLBROWSER */
847 cmi.lpVerb = (LPCSTR)MAKEINTRESOURCEA(uCommand);
848 IContextMenu_InvokeCommand(pContextMenu, &cmi);
855 IContextMenu_Release(pContextMenu);
858 else /* background context menu */
860 hMenu = CreatePopupMenu();
862 pCM = ISvBgCm_Constructor(This->pSFParent);
863 IContextMenu_QueryContextMenu(pCM, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, 0);
865 uCommand = TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
868 TRACE("-- (%p)->(uCommand=0x%08x )\n",This, uCommand);
870 ZeroMemory(&cmi, sizeof(cmi));
871 cmi.cbSize = sizeof(cmi);
872 cmi.lpVerb = (LPCSTR)MAKEINTRESOURCEA(uCommand);
873 cmi.hwnd = This->hWndParent;
874 IContextMenu_InvokeCommand(pCM, &cmi);
876 IContextMenu_Release(pCM);
880 /**********************************************************
881 * ##### message handling #####
884 /**********************************************************
887 static LRESULT ShellView_OnSize(IShellViewImpl * This, WORD wWidth, WORD wHeight)
889 TRACE("%p width=%u height=%u\n",This, wWidth,wHeight);
891 /*resize the ListView to fit our window*/
894 MoveWindow(This->hWndList, 0, 0, wWidth, wHeight, TRUE);
899 /**********************************************************
900 * ShellView_OnDeactivate()
905 static void ShellView_OnDeactivate(IShellViewImpl * This)
909 if(This->uState != SVUIA_DEACTIVATE)
913 IShellBrowser_SetMenuSB(This->pShellBrowser,0, 0, 0);
914 IShellBrowser_RemoveMenusSB(This->pShellBrowser,This->hMenu);
915 DestroyMenu(This->hMenu);
919 This->uState = SVUIA_DEACTIVATE;
923 /**********************************************************
924 * ShellView_OnActivate()
926 static LRESULT ShellView_OnActivate(IShellViewImpl * This, UINT uState)
927 { OLEMENUGROUPWIDTHS omw = { {0, 0, 0, 0, 0, 0} };
929 CHAR szText[MAX_PATH];
931 TRACE("%p uState=%x\n",This,uState);
933 /*don't do anything if the state isn't really changing */
934 if(This->uState == uState)
939 ShellView_OnDeactivate(This);
941 /*only do This if we are active */
942 if(uState != SVUIA_DEACTIVATE)
945 This->hMenu = CreateMenu();
949 IShellBrowser_InsertMenusSB(This->pShellBrowser, This->hMenu, &omw);
950 TRACE("-- after fnInsertMenusSB\n");
952 /*build the top level menu get the menu item's text*/
953 strcpy(szText,"dummy 31");
955 ZeroMemory(&mii, sizeof(mii));
956 mii.cbSize = sizeof(mii);
957 mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_STATE;
958 mii.fType = MFT_STRING;
959 mii.fState = MFS_ENABLED;
960 mii.dwTypeData = szText;
961 mii.hSubMenu = ShellView_BuildFileMenu(This);
963 /*insert our menu into the menu bar*/
966 InsertMenuItemA(This->hMenu, FCIDM_MENU_HELP, FALSE, &mii);
969 /*get the view menu so we can merge with it*/
970 ZeroMemory(&mii, sizeof(mii));
971 mii.cbSize = sizeof(mii);
972 mii.fMask = MIIM_SUBMENU;
974 if(GetMenuItemInfoA(This->hMenu, FCIDM_MENU_VIEW, FALSE, &mii))
976 ShellView_MergeViewMenu(This, mii.hSubMenu);
979 /*add the items that should only be added if we have the focus*/
980 if(SVUIA_ACTIVATE_FOCUS == uState)
982 /*get the file menu so we can merge with it */
983 ZeroMemory(&mii, sizeof(mii));
984 mii.cbSize = sizeof(mii);
985 mii.fMask = MIIM_SUBMENU;
987 if(GetMenuItemInfoA(This->hMenu, FCIDM_MENU_FILE, FALSE, &mii))
989 ShellView_MergeFileMenu(This, mii.hSubMenu);
992 TRACE("-- before fnSetMenuSB\n");
993 IShellBrowser_SetMenuSB(This->pShellBrowser, This->hMenu, 0, This->hWnd);
996 This->uState = uState;
1001 /**********************************************************
1002 * ShellView_OnSetFocus()
1005 static LRESULT ShellView_OnSetFocus(IShellViewImpl * This)
1009 /* Tell the browser one of our windows has received the focus. This
1010 should always be done before merging menus (OnActivate merges the
1011 menus) if one of our windows has the focus.*/
1013 IShellBrowser_OnViewWindowActive(This->pShellBrowser,(IShellView*) This);
1014 ShellView_OnActivate(This, SVUIA_ACTIVATE_FOCUS);
1016 /* Set the focus to the listview */
1017 SetFocus(This->hWndList);
1019 /* Notify the ICommDlgBrowser interface */
1020 OnStateChange(This,CDBOSC_SETFOCUS);
1025 /**********************************************************
1026 * ShellView_OnKillFocus()
1028 static LRESULT ShellView_OnKillFocus(IShellViewImpl * This)
1030 TRACE("(%p) stub\n",This);
1032 ShellView_OnActivate(This, SVUIA_ACTIVATE_NOFOCUS);
1033 /* Notify the ICommDlgBrowser */
1034 OnStateChange(This,CDBOSC_KILLFOCUS);
1039 /**********************************************************
1040 * ShellView_OnCommand()
1043 * the CmdID's are the ones from the context menu
1045 static LRESULT ShellView_OnCommand(IShellViewImpl * This,DWORD dwCmdID, DWORD dwCmd, HWND hwndCmd)
1047 TRACE("(%p)->(0x%08lx 0x%08lx 0x%08x) stub\n",This, dwCmdID, dwCmd, hwndCmd);
1051 case FCIDM_SHVIEW_SMALLICON:
1052 This->FolderSettings.ViewMode = FVM_SMALLICON;
1053 SetStyle (This, LVS_SMALLICON, LVS_TYPEMASK);
1057 case FCIDM_SHVIEW_BIGICON:
1058 This->FolderSettings.ViewMode = FVM_ICON;
1059 SetStyle (This, LVS_ICON, LVS_TYPEMASK);
1063 case FCIDM_SHVIEW_LISTVIEW:
1064 This->FolderSettings.ViewMode = FVM_LIST;
1065 SetStyle (This, LVS_LIST, LVS_TYPEMASK);
1069 case FCIDM_SHVIEW_REPORTVIEW:
1070 This->FolderSettings.ViewMode = FVM_DETAILS;
1071 SetStyle (This, LVS_REPORT, LVS_TYPEMASK);
1075 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1080 This->ListViewSortInfo.nHeaderID = (LPARAM) (dwCmdID - 0x30);
1081 This->ListViewSortInfo.bIsAscending = TRUE;
1082 This->ListViewSortInfo.nLastHeaderID = This->ListViewSortInfo.nHeaderID;
1083 ListView_SortItems(This->hWndList, ShellView_ListViewCompareItems, (LPARAM) (&(This->ListViewSortInfo)));
1087 TRACE("-- COMMAND 0x%04lx unhandled\n", dwCmdID);
1092 /**********************************************************
1093 * ShellView_OnNotify()
1096 static LRESULT ShellView_OnNotify(IShellViewImpl * This, UINT CtlID, LPNMHDR lpnmh)
1097 { LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)lpnmh;
1098 NMLVDISPINFOA *lpdi = (NMLVDISPINFOA *)lpnmh;
1101 TRACE("%p CtlID=%u lpnmh->code=%x\n",This,CtlID,lpnmh->code);
1106 TRACE("-- NM_SETFOCUS %p\n",This);
1107 ShellView_OnSetFocus(This);
1111 TRACE("-- NM_KILLFOCUS %p\n",This);
1112 ShellView_OnDeactivate(This);
1113 /* Notify the ICommDlgBrowser interface */
1114 OnStateChange(This,CDBOSC_KILLFOCUS);
1118 TRACE("-- HDN_ENDTRACKA %p\n",This);
1119 /*nColumn1 = ListView_GetColumnWidth(This->hWndList, 0);
1120 nColumn2 = ListView_GetColumnWidth(This->hWndList, 1);*/
1123 case LVN_DELETEITEM:
1124 TRACE("-- LVN_DELETEITEM %p\n",This);
1125 SHFree((LPITEMIDLIST)lpnmlv->lParam); /*delete the pidl because we made a copy of it*/
1128 case LVN_ITEMACTIVATE:
1129 TRACE("-- LVN_ITEMACTIVATE %p\n",This);
1130 OnStateChange(This, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
1131 ShellView_DoContextMenu(This, 0, 0, TRUE);
1134 case LVN_COLUMNCLICK:
1135 This->ListViewSortInfo.nHeaderID = lpnmlv->iSubItem;
1136 if(This->ListViewSortInfo.nLastHeaderID == This->ListViewSortInfo.nHeaderID)
1138 This->ListViewSortInfo.bIsAscending = !This->ListViewSortInfo.bIsAscending;
1142 This->ListViewSortInfo.bIsAscending = TRUE;
1144 This->ListViewSortInfo.nLastHeaderID = This->ListViewSortInfo.nHeaderID;
1146 ListView_SortItems(lpnmlv->hdr.hwndFrom, ShellView_ListViewCompareItems, (LPARAM) (&(This->ListViewSortInfo)));
1149 case LVN_GETDISPINFOA:
1150 case LVN_GETDISPINFOW:
1151 TRACE("-- LVN_GETDISPINFO %p\n",This);
1152 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1154 if(lpdi->item.mask & LVIF_TEXT) /* text requested */
1156 if (This->pSF2Parent)
1159 IShellFolder2_GetDetailsOf(This->pSF2Parent, pidl, lpdi->item.iSubItem, &sd);
1160 if (lpnmh->code == LVN_GETDISPINFOA)
1162 StrRetToStrNA( lpdi->item.pszText, lpdi->item.cchTextMax, &sd.str, NULL);
1163 TRACE("-- text=%s\n",lpdi->item.pszText);
1165 else /* LVN_GETDISPINFOW */
1167 StrRetToStrNW( lpdi->item.pszText, lpdi->item.cchTextMax, &sd.str, NULL);
1168 TRACE("-- text=%s\n",debugstr_w((WCHAR*)(lpdi->item.pszText)));
1176 if(lpdi->item.mask & LVIF_IMAGE) /* image requested */
1178 lpdi->item.iImage = SHMapPIDLToSystemImageListIndex(This->pSFParent, pidl, 0);
1182 case LVN_ITEMCHANGED:
1183 TRACE("-- LVN_ITEMCHANGED %p\n",This);
1184 OnStateChange(This, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
1188 case LVN_BEGINRDRAG:
1189 TRACE("-- LVN_BEGINDRAG\n");
1191 if (ShellView_GetSelections(This))
1194 DWORD dwAttributes = SFGAO_CANLINK;
1195 DWORD dwEffect = DROPEFFECT_COPY | DROPEFFECT_MOVE;
1199 if (SUCCEEDED(IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, This->apidl, &IID_IDataObject,0,(LPVOID *)&pda)))
1201 IDropSource * pds = (IDropSource*)&(This->lpvtblDropSource); /* own DropSource interface */
1203 if (SUCCEEDED(IShellFolder_GetAttributesOf(This->pSFParent, This->cidl, This->apidl, &dwAttributes)))
1205 if (dwAttributes & SFGAO_CANLINK)
1207 dwEffect |= DROPEFFECT_LINK;
1214 pDoDragDrop(pda, pds, dwEffect, &dwEffect);
1216 IDataObject_Release(pda);
1222 case LVN_BEGINLABELEDITA:
1224 DWORD dwAttr = SFGAO_CANRENAME;
1225 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1227 TRACE("-- LVN_BEGINLABELEDITA %p\n",This);
1229 IShellFolder_GetAttributesOf(This->pSFParent, 1, &pidl, &dwAttr);
1230 if (SFGAO_CANRENAME & dwAttr)
1238 case LVN_ENDLABELEDITA:
1240 TRACE("-- LVN_ENDLABELEDITA %p\n",This);
1241 if (lpdi->item.pszText)
1244 WCHAR wszNewName[MAX_PATH];
1247 ZeroMemory(&lvItem, sizeof(LVITEMA));
1248 lvItem.iItem = lpdi->item.iItem;
1249 lvItem.mask = LVIF_PARAM;
1250 ListView_GetItemA(This->hWndList, &lvItem);
1252 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1253 if (!MultiByteToWideChar( CP_ACP, 0, lpdi->item.pszText, -1, wszNewName, MAX_PATH ))
1254 wszNewName[MAX_PATH-1] = 0;
1255 hr = IShellFolder_SetNameOf(This->pSFParent, 0, pidl, wszNewName, SHGDN_INFOLDER, &pidl);
1257 if(SUCCEEDED(hr) && pidl)
1259 lvItem.mask = LVIF_PARAM;
1260 lvItem.lParam = (LPARAM)pidl;
1261 ListView_SetItemA(This->hWndList, &lvItem);
1272 msg.hwnd = This->hWnd;
1273 msg.message = WM_KEYDOWN;
1274 msg.wParam = plvKeyDown->wVKey;
1279 LPNMLVKEYDOWN plvKeyDown = (LPNMLVKEYDOWN) lpnmh;
1281 /* initiate a rename of the selected file or directory */
1282 if(plvKeyDown->wVKey == VK_F2)
1284 /* see how many files are selected */
1285 int i = ListView_GetSelectedCount(This->hWndList);
1287 /* get selected item */
1290 /* get selected item */
1291 i = ListView_GetNextItem(This->hWndList, -1,
1294 ListView_EnsureVisible(This->hWndList, i, 0);
1295 ListView_EditLabelA(This->hWndList, i);
1299 TranslateAccelerator(This->hWnd, This->hAccel, &msg)
1301 else if(plvKeyDown->wVKey == VK_DELETE)
1305 LPITEMIDLIST* pItems;
1308 IShellFolder_QueryInterface(This->pSFParent, &IID_ISFHelper,
1311 if(!(i = ListView_GetSelectedCount(This->hWndList)))
1314 /* allocate memory for the pidl array */
1315 pItems = HeapAlloc(GetProcessHeap(), 0,
1316 sizeof(LPITEMIDLIST) * i);
1318 /* retrieve all selected items */
1321 while(ListView_GetSelectedCount(This->hWndList) > i)
1323 /* get selected item */
1324 item_index = ListView_GetNextItem(This->hWndList,
1325 item_index, LVNI_SELECTED);
1326 item.iItem = item_index;
1327 ListView_GetItemA(This->hWndList, &item);
1330 pItems[i] = (LPITEMIDLIST)item.lParam;
1335 /* perform the item deletion */
1336 ISFHelper_DeleteItems(psfhlp, i, pItems);
1338 /* free pidl array memory */
1339 HeapFree(GetProcessHeap(), 0, pItems);
1342 FIXME("LVN_KEYDOWN key=0x%08x\n",plvKeyDown->wVKey);
1347 TRACE("-- %p WM_COMMAND %x unhandled\n", This, lpnmh->code);
1353 /**********************************************************
1354 * ShellView_OnChange()
1357 static LRESULT ShellView_OnChange(IShellViewImpl * This, LPITEMIDLIST * Pidls, LONG wEventId)
1360 TRACE("(%p)(%p,%p,0x%08lx)\n", This, Pidls[0], Pidls[1], wEventId);
1365 LV_AddItem(This, Pidls[0]);
1369 LV_DeleteItem(This, Pidls[0]);
1371 case SHCNE_RENAMEFOLDER:
1372 case SHCNE_RENAMEITEM:
1373 LV_RenameItem(This, Pidls[0], Pidls[1]);
1375 case SHCNE_UPDATEITEM:
1380 /**********************************************************
1384 static LRESULT CALLBACK ShellView_WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
1386 IShellViewImpl * pThis = (IShellViewImpl*)GetWindowLongA(hWnd, GWL_USERDATA);
1387 LPCREATESTRUCTA lpcs;
1389 TRACE("(hwnd=%x msg=%x wparm=%x lparm=%lx)\n",hWnd, uMessage, wParam, lParam);
1394 lpcs = (LPCREATESTRUCTA)lParam;
1395 pThis = (IShellViewImpl*)(lpcs->lpCreateParams);
1396 SetWindowLongA(hWnd, GWL_USERDATA, (LONG)pThis);
1397 pThis->hWnd = hWnd; /*set the window handle*/
1400 case WM_SIZE: return ShellView_OnSize(pThis,LOWORD(lParam), HIWORD(lParam));
1401 case WM_SETFOCUS: return ShellView_OnSetFocus(pThis);
1402 case WM_KILLFOCUS: return ShellView_OnKillFocus(pThis);
1403 case WM_CREATE: return ShellView_OnCreate(pThis);
1404 case WM_ACTIVATE: return ShellView_OnActivate(pThis, SVUIA_ACTIVATE_FOCUS);
1405 case WM_NOTIFY: return ShellView_OnNotify(pThis,(UINT)wParam, (LPNMHDR)lParam);
1406 case WM_COMMAND: return ShellView_OnCommand(pThis,
1407 GET_WM_COMMAND_ID(wParam, lParam),
1408 GET_WM_COMMAND_CMD(wParam, lParam),
1409 GET_WM_COMMAND_HWND(wParam, lParam));
1410 case SHV_CHANGE_NOTIFY: return ShellView_OnChange(pThis, (LPITEMIDLIST*)wParam, (LONG)lParam);
1412 case WM_CONTEXTMENU: ShellView_DoContextMenu(pThis, LOWORD(lParam), HIWORD(lParam), FALSE);
1415 case WM_SHOWWINDOW: UpdateWindow(pThis->hWndList);
1418 case WM_GETDLGCODE: return SendMessageA(pThis->hWndList,uMessage,0,0);
1420 case WM_DESTROY: if(GetShellOle())
1422 pRevokeDragDrop(pThis->hWnd);
1424 SHChangeNotifyDeregister(pThis->hNotify);
1428 return DefWindowProcA (hWnd, uMessage, wParam, lParam);
1430 /**********************************************************
1433 * The INTERFACE of the IShellView object
1436 **********************************************************
1437 * IShellView_QueryInterface
1439 static HRESULT WINAPI IShellView_fnQueryInterface(IShellView * iface,REFIID riid, LPVOID *ppvObj)
1441 ICOM_THIS(IShellViewImpl, iface);
1443 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1447 if(IsEqualIID(riid, &IID_IUnknown))
1451 else if(IsEqualIID(riid, &IID_IShellView))
1453 *ppvObj = (IShellView*)This;
1455 else if(IsEqualIID(riid, &IID_IOleCommandTarget))
1457 *ppvObj = (IOleCommandTarget*)&(This->lpvtblOleCommandTarget);
1459 else if(IsEqualIID(riid, &IID_IDropTarget))
1461 *ppvObj = (IDropTarget*)&(This->lpvtblDropTarget);
1463 else if(IsEqualIID(riid, &IID_IDropSource))
1465 *ppvObj = (IDropSource*)&(This->lpvtblDropSource);
1467 else if(IsEqualIID(riid, &IID_IViewObject))
1469 *ppvObj = (IViewObject*)&(This->lpvtblViewObject);
1474 IUnknown_AddRef( (IUnknown*)*ppvObj );
1475 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1478 TRACE("-- Interface: E_NOINTERFACE\n");
1479 return E_NOINTERFACE;
1482 /**********************************************************
1485 static ULONG WINAPI IShellView_fnAddRef(IShellView * iface)
1487 ICOM_THIS(IShellViewImpl, iface);
1489 TRACE("(%p)->(count=%lu)\n",This,This->ref);
1492 return ++(This->ref);
1494 /**********************************************************
1495 * IShellView_Release
1497 static ULONG WINAPI IShellView_fnRelease(IShellView * iface)
1499 ICOM_THIS(IShellViewImpl, iface);
1501 TRACE("(%p)->()\n",This);
1507 TRACE(" destroying IShellView(%p)\n",This);
1510 IShellFolder_Release(This->pSFParent);
1512 if(This->pSF2Parent)
1513 IShellFolder2_Release(This->pSF2Parent);
1516 SHFree(This->apidl);
1518 if (This->pCommDlgBrowser)
1519 ICommDlgBrowser_Release(This->pCommDlgBrowser);
1521 HeapFree(GetProcessHeap(),0,This);
1527 /**********************************************************
1528 * ShellView_GetWindow
1530 static HRESULT WINAPI IShellView_fnGetWindow(IShellView * iface,HWND * phWnd)
1532 ICOM_THIS(IShellViewImpl, iface);
1534 TRACE("(%p)\n",This);
1536 *phWnd = This->hWnd;
1541 static HRESULT WINAPI IShellView_fnContextSensitiveHelp(IShellView * iface,BOOL fEnterMode)
1543 ICOM_THIS(IShellViewImpl, iface);
1545 FIXME("(%p) stub\n",This);
1550 /**********************************************************
1551 * IShellView_TranslateAccelerator
1554 * use the accel functions
1556 static HRESULT WINAPI IShellView_fnTranslateAccelerator(IShellView * iface,LPMSG lpmsg)
1559 ICOM_THIS(IShellViewImpl, iface);
1561 FIXME("(%p)->(%p: hwnd=%x msg=%x lp=%lx wp=%x) stub\n",This,lpmsg, lpmsg->hwnd, lpmsg->message, lpmsg->lParam, lpmsg->wParam);
1564 if ((lpmsg->message>=WM_KEYFIRST) && (lpmsg->message>=WM_KEYLAST))
1566 TRACE("-- key=0x04%x\n",lpmsg->wParam) ;
1568 return S_FALSE; /* not handled */
1571 static HRESULT WINAPI IShellView_fnEnableModeless(IShellView * iface,BOOL fEnable)
1573 ICOM_THIS(IShellViewImpl, iface);
1575 FIXME("(%p) stub\n",This);
1580 static HRESULT WINAPI IShellView_fnUIActivate(IShellView * iface,UINT uState)
1582 ICOM_THIS(IShellViewImpl, iface);
1585 CHAR szName[MAX_PATH];
1588 int nPartArray[1] = {-1};
1590 TRACE("(%p)->(state=%x) stub\n",This, uState);
1592 /*don't do anything if the state isn't really changing*/
1593 if(This->uState == uState)
1598 /*OnActivate handles the menu merging and internal state*/
1599 ShellView_OnActivate(This, uState);
1601 /*only do This if we are active*/
1602 if(uState != SVUIA_DEACTIVATE)
1606 GetFolderPath is not a method of IShellFolder
1607 IShellFolder_GetFolderPath( This->pSFParent, szName, sizeof(szName) );
1609 /* set the number of parts */
1610 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETPARTS, 1,
1611 (LPARAM)nPartArray, &lResult);
1613 /* set the text for the parts */
1615 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETTEXTA,
1616 0, (LPARAM)szName, &lResult);
1623 static HRESULT WINAPI IShellView_fnRefresh(IShellView * iface)
1625 ICOM_THIS(IShellViewImpl, iface);
1627 TRACE("(%p)\n",This);
1629 ListView_DeleteAllItems(This->hWndList);
1630 ShellView_FillList(This);
1635 static HRESULT WINAPI IShellView_fnCreateViewWindow(
1637 IShellView *lpPrevView,
1638 LPCFOLDERSETTINGS lpfs,
1639 IShellBrowser * psb,
1643 ICOM_THIS(IShellViewImpl, iface);
1649 TRACE("(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n",This, lpPrevView,lpfs, psb, prcView, phWnd);
1650 TRACE("-- vmode=%x flags=%x left=%i top=%i right=%i bottom=%i\n",lpfs->ViewMode, lpfs->fFlags ,prcView->left,prcView->top, prcView->right, prcView->bottom);
1652 /*set up the member variables*/
1653 This->pShellBrowser = psb;
1654 This->FolderSettings = *lpfs;
1656 /*get our parent window*/
1657 IShellBrowser_AddRef(This->pShellBrowser);
1658 IShellBrowser_GetWindow(This->pShellBrowser, &(This->hWndParent));
1660 /* try to get the ICommDlgBrowserInterface, adds a reference !!! */
1661 This->pCommDlgBrowser=NULL;
1662 if ( SUCCEEDED (IShellBrowser_QueryInterface( This->pShellBrowser,
1663 (REFIID)&IID_ICommDlgBrowser, (LPVOID*) &This->pCommDlgBrowser)))
1665 TRACE("-- CommDlgBrowser\n");
1668 /*if our window class has not been registered, then do so*/
1669 if(!GetClassInfoA(shell32_hInstance, SV_CLASS_NAME, &wc))
1671 ZeroMemory(&wc, sizeof(wc));
1672 wc.style = CS_HREDRAW | CS_VREDRAW;
1673 wc.lpfnWndProc = (WNDPROC) ShellView_WndProc;
1676 wc.hInstance = shell32_hInstance;
1678 wc.hCursor = LoadCursorA (0, IDC_ARROWA);
1679 wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
1680 wc.lpszMenuName = NULL;
1681 wc.lpszClassName = SV_CLASS_NAME;
1683 if(!RegisterClassA(&wc))
1687 *phWnd = CreateWindowExA(0,
1690 WS_CHILD | WS_VISIBLE | WS_TABSTOP,
1693 prcView->right - prcView->left,
1694 prcView->bottom - prcView->top,
1702 if(!*phWnd) return E_FAIL;
1707 static HRESULT WINAPI IShellView_fnDestroyViewWindow(IShellView * iface)
1709 ICOM_THIS(IShellViewImpl, iface);
1711 TRACE("(%p)\n",This);
1713 /*Make absolutely sure all our UI is cleaned up.*/
1714 IShellView_UIActivate((IShellView*)This, SVUIA_DEACTIVATE);
1718 DestroyMenu(This->hMenu);
1721 DestroyWindow(This->hWnd);
1722 IShellBrowser_Release(This->pShellBrowser);
1727 static HRESULT WINAPI IShellView_fnGetCurrentInfo(IShellView * iface, LPFOLDERSETTINGS lpfs)
1729 ICOM_THIS(IShellViewImpl, iface);
1731 TRACE("(%p)->(%p) vmode=%x flags=%x\n",This, lpfs,
1732 This->FolderSettings.ViewMode, This->FolderSettings.fFlags);
1734 if (!lpfs) return E_INVALIDARG;
1736 *lpfs = This->FolderSettings;
1740 static HRESULT WINAPI IShellView_fnAddPropertySheetPages(IShellView * iface, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam)
1742 ICOM_THIS(IShellViewImpl, iface);
1744 FIXME("(%p) stub\n",This);
1749 static HRESULT WINAPI IShellView_fnSaveViewState(IShellView * iface)
1751 ICOM_THIS(IShellViewImpl, iface);
1753 FIXME("(%p) stub\n",This);
1758 static HRESULT WINAPI IShellView_fnSelectItem(
1763 ICOM_THIS(IShellViewImpl, iface);
1766 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n",This, pidl, uFlags);
1768 i = LV_FindItemByPidl(This, pidl);
1774 if(uFlags & SVSI_ENSUREVISIBLE)
1775 ListView_EnsureVisible(This->hWndList, i, 0);
1777 ZeroMemory(&lvItem, sizeof(LVITEMA));
1778 lvItem.mask = LVIF_STATE;
1781 while(ListView_GetItemA(This->hWndList, &lvItem))
1783 if (lvItem.iItem == i)
1785 if (uFlags & SVSI_SELECT)
1786 lvItem.state |= LVIS_SELECTED;
1788 lvItem.state &= ~LVIS_SELECTED;
1790 if(uFlags & SVSI_FOCUSED)
1791 lvItem.state &= ~LVIS_FOCUSED;
1795 if (uFlags & SVSI_DESELECTOTHERS)
1796 lvItem.state &= ~LVIS_SELECTED;
1798 ListView_SetItemA(This->hWndList, &lvItem);
1803 if(uFlags & SVSI_EDIT)
1804 ListView_EditLabelA(This->hWndList, i);
1810 static HRESULT WINAPI IShellView_fnGetItemObject(IShellView * iface, UINT uItem, REFIID riid, LPVOID *ppvOut)
1812 ICOM_THIS(IShellViewImpl, iface);
1814 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n",This, uItem, debugstr_guid(riid), ppvOut);
1820 case SVGIO_BACKGROUND:
1821 *ppvOut = ISvBgCm_Constructor(This->pSFParent);
1824 case SVGIO_SELECTION:
1825 ShellView_GetSelections(This);
1826 IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, This->apidl, riid, 0, ppvOut);
1829 TRACE("-- (%p)->(interface=%p)\n",This, *ppvOut);
1831 if(!*ppvOut) return E_OUTOFMEMORY;
1836 static HRESULT WINAPI IShellView_fnEditItem(
1840 ICOM_THIS(IShellViewImpl, iface);
1843 TRACE("(%p)->(pidl=%p)\n",This, pidl);
1845 i = LV_FindItemByPidl(This, pidl);
1848 SetFocus(This->hWndList);
1849 ListView_EditLabelA(This->hWndList, i);
1854 static struct ICOM_VTABLE(IShellView) svvt =
1856 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1857 IShellView_fnQueryInterface,
1858 IShellView_fnAddRef,
1859 IShellView_fnRelease,
1860 IShellView_fnGetWindow,
1861 IShellView_fnContextSensitiveHelp,
1862 IShellView_fnTranslateAccelerator,
1863 IShellView_fnEnableModeless,
1864 IShellView_fnUIActivate,
1865 IShellView_fnRefresh,
1866 IShellView_fnCreateViewWindow,
1867 IShellView_fnDestroyViewWindow,
1868 IShellView_fnGetCurrentInfo,
1869 IShellView_fnAddPropertySheetPages,
1870 IShellView_fnSaveViewState,
1871 IShellView_fnSelectItem,
1872 IShellView_fnGetItemObject,
1873 IShellView_fnEditItem
1877 /**********************************************************
1878 * ISVOleCmdTarget_QueryInterface (IUnknown)
1880 static HRESULT WINAPI ISVOleCmdTarget_QueryInterface(
1881 IOleCommandTarget * iface,
1885 _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
1887 return IShellFolder_QueryInterface((IShellFolder*)This, iid, ppvObj);
1890 /**********************************************************
1891 * ISVOleCmdTarget_AddRef (IUnknown)
1893 static ULONG WINAPI ISVOleCmdTarget_AddRef(
1894 IOleCommandTarget * iface)
1896 _ICOM_THIS_From_IOleCommandTarget(IShellFolder, iface);
1898 return IShellFolder_AddRef((IShellFolder*)This);
1901 /**********************************************************
1902 * ISVOleCmdTarget_Release (IUnknown)
1904 static ULONG WINAPI ISVOleCmdTarget_Release(
1905 IOleCommandTarget * iface)
1907 _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
1909 return IShellFolder_Release((IShellFolder*)This);
1912 /**********************************************************
1913 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
1915 static HRESULT WINAPI ISVOleCmdTarget_QueryStatus(
1916 IOleCommandTarget *iface,
1917 const GUID* pguidCmdGroup,
1920 OLECMDTEXT* pCmdText)
1922 _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
1924 FIXME("(%p)->(%p(%s) 0x%08lx %p %p\n",
1925 This, pguidCmdGroup, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText);
1929 /**********************************************************
1930 * ISVOleCmdTarget_Exec (IOleCommandTarget)
1932 * nCmdID is the OLECMDID_* enumeration
1934 static HRESULT WINAPI ISVOleCmdTarget_Exec(
1935 IOleCommandTarget *iface,
1936 const GUID* pguidCmdGroup,
1942 _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
1944 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08lx Opt:0x%08lx %p %p)\n",
1945 This, debugstr_guid(pguidCmdGroup), nCmdID, nCmdexecopt, pvaIn, pvaOut);
1949 static ICOM_VTABLE(IOleCommandTarget) ctvt =
1951 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1952 ISVOleCmdTarget_QueryInterface,
1953 ISVOleCmdTarget_AddRef,
1954 ISVOleCmdTarget_Release,
1955 ISVOleCmdTarget_QueryStatus,
1956 ISVOleCmdTarget_Exec
1959 /**********************************************************
1960 * ISVDropTarget implementation
1963 static HRESULT WINAPI ISVDropTarget_QueryInterface(
1968 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
1970 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1972 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
1975 static ULONG WINAPI ISVDropTarget_AddRef( IDropTarget *iface)
1977 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
1979 TRACE("(%p)->(count=%lu)\n",This,This->ref);
1981 return IShellFolder_AddRef((IShellFolder*)This);
1984 static ULONG WINAPI ISVDropTarget_Release( IDropTarget *iface)
1986 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
1988 TRACE("(%p)->(count=%lu)\n",This,This->ref);
1990 return IShellFolder_Release((IShellFolder*)This);
1993 static HRESULT WINAPI ISVDropTarget_DragEnter(
1995 IDataObject *pDataObject,
2001 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2003 FIXME("Stub: This=%p, DataObject=%p\n",This,pDataObject);
2008 static HRESULT WINAPI ISVDropTarget_DragOver(
2014 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2016 FIXME("Stub: This=%p\n",This);
2021 static HRESULT WINAPI ISVDropTarget_DragLeave(
2024 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2026 FIXME("Stub: This=%p\n",This);
2031 static HRESULT WINAPI ISVDropTarget_Drop(
2033 IDataObject* pDataObject,
2038 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2040 FIXME("Stub: This=%p\n",This);
2045 static struct ICOM_VTABLE(IDropTarget) dtvt =
2047 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2048 ISVDropTarget_QueryInterface,
2049 ISVDropTarget_AddRef,
2050 ISVDropTarget_Release,
2051 ISVDropTarget_DragEnter,
2052 ISVDropTarget_DragOver,
2053 ISVDropTarget_DragLeave,
2057 /**********************************************************
2058 * ISVDropSource implementation
2061 static HRESULT WINAPI ISVDropSource_QueryInterface(
2066 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2068 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2070 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2073 static ULONG WINAPI ISVDropSource_AddRef( IDropSource *iface)
2075 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2077 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2079 return IShellFolder_AddRef((IShellFolder*)This);
2082 static ULONG WINAPI ISVDropSource_Release( IDropSource *iface)
2084 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2086 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2088 return IShellFolder_Release((IShellFolder*)This);
2090 static HRESULT WINAPI ISVDropSource_QueryContinueDrag(
2092 BOOL fEscapePressed,
2095 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2096 TRACE("(%p)\n",This);
2099 return DRAGDROP_S_CANCEL;
2100 else if (!(grfKeyState & MK_LBUTTON) && !(grfKeyState & MK_RBUTTON))
2101 return DRAGDROP_S_DROP;
2106 static HRESULT WINAPI ISVDropSource_GiveFeedback(
2110 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2111 TRACE("(%p)\n",This);
2113 return DRAGDROP_S_USEDEFAULTCURSORS;
2116 static struct ICOM_VTABLE(IDropSource) dsvt =
2118 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2119 ISVDropSource_QueryInterface,
2120 ISVDropSource_AddRef,
2121 ISVDropSource_Release,
2122 ISVDropSource_QueryContinueDrag,
2123 ISVDropSource_GiveFeedback
2125 /**********************************************************
2126 * ISVViewObject implementation
2129 static HRESULT WINAPI ISVViewObject_QueryInterface(
2134 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2136 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2138 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2141 static ULONG WINAPI ISVViewObject_AddRef( IViewObject *iface)
2143 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2145 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2147 return IShellFolder_AddRef((IShellFolder*)This);
2150 static ULONG WINAPI ISVViewObject_Release( IViewObject *iface)
2152 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2154 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2156 return IShellFolder_Release((IShellFolder*)This);
2159 static HRESULT WINAPI ISVViewObject_Draw(
2164 DVTARGETDEVICE* ptd,
2167 LPCRECTL lprcBounds,
2168 LPCRECTL lprcWBounds,
2169 IVO_ContCallback pfnContinue,
2173 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2175 FIXME("Stub: This=%p\n",This);
2179 static HRESULT WINAPI ISVViewObject_GetColorSet(
2184 DVTARGETDEVICE* ptd,
2185 HDC hicTargetDevice,
2186 LOGPALETTE** ppColorSet)
2189 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2191 FIXME("Stub: This=%p\n",This);
2195 static HRESULT WINAPI ISVViewObject_Freeze(
2203 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2205 FIXME("Stub: This=%p\n",This);
2209 static HRESULT WINAPI ISVViewObject_Unfreeze(
2214 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2216 FIXME("Stub: This=%p\n",This);
2220 static HRESULT WINAPI ISVViewObject_SetAdvise(
2224 IAdviseSink* pAdvSink)
2227 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2229 FIXME("Stub: This=%p\n",This);
2233 static HRESULT WINAPI ISVViewObject_GetAdvise(
2237 IAdviseSink** ppAdvSink)
2240 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2242 FIXME("Stub: This=%p\n",This);
2248 static struct ICOM_VTABLE(IViewObject) vovt =
2250 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2251 ISVViewObject_QueryInterface,
2252 ISVViewObject_AddRef,
2253 ISVViewObject_Release,
2255 ISVViewObject_GetColorSet,
2256 ISVViewObject_Freeze,
2257 ISVViewObject_Unfreeze,
2258 ISVViewObject_SetAdvise,
2259 ISVViewObject_GetAdvise