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"
55 #include "undocshell.h"
57 #include "wine/debug.h"
61 #include "shell32_main.h"
62 #include "shellfolder.h"
64 WINE_DEFAULT_DEBUG_CHANNEL(shell);
70 }LISTVIEW_SORT_INFO, *LPLISTVIEW_SORT_INFO;
73 { ICOM_VFIELD(IShellView);
75 ICOM_VTABLE(IOleCommandTarget)* lpvtblOleCommandTarget;
76 ICOM_VTABLE(IDropTarget)* lpvtblDropTarget;
77 ICOM_VTABLE(IDropSource)* lpvtblDropSource;
78 ICOM_VTABLE(IViewObject)* lpvtblViewObject;
79 IShellFolder* pSFParent;
80 IShellFolder2* pSF2Parent;
81 IShellBrowser* pShellBrowser;
82 ICommDlgBrowser* pCommDlgBrowser;
83 HWND hWnd; /* SHELLDLL_DefView */
84 HWND hWndList; /* ListView control */
86 FOLDERSETTINGS FolderSettings;
91 LISTVIEW_SORT_INFO ListViewSortInfo;
92 ULONG hNotify; /* change notification handle */
96 static struct ICOM_VTABLE(IShellView) svvt;
98 static struct ICOM_VTABLE(IOleCommandTarget) ctvt;
99 #define _IOleCommandTarget_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblOleCommandTarget)))
100 #define _ICOM_THIS_From_IOleCommandTarget(class, name) class* This = (class*)(((char*)name)-_IOleCommandTarget_Offset);
102 static struct ICOM_VTABLE(IDropTarget) dtvt;
103 #define _IDropTarget_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblDropTarget)))
104 #define _ICOM_THIS_From_IDropTarget(class, name) class* This = (class*)(((char*)name)-_IDropTarget_Offset);
106 static struct ICOM_VTABLE(IDropSource) dsvt;
107 #define _IDropSource_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblDropSource)))
108 #define _ICOM_THIS_From_IDropSource(class, name) class* This = (class*)(((char*)name)-_IDropSource_Offset);
110 static struct ICOM_VTABLE(IViewObject) vovt;
111 #define _IViewObject_Offset ((int)(&(((IShellViewImpl*)0)->lpvtblViewObject)))
112 #define _ICOM_THIS_From_IViewObject(class, name) class* This = (class*)(((char*)name)-_IViewObject_Offset);
114 /* ListView Header ID's */
115 #define LISTVIEW_COLUMN_NAME 0
116 #define LISTVIEW_COLUMN_SIZE 1
117 #define LISTVIEW_COLUMN_TYPE 2
118 #define LISTVIEW_COLUMN_TIME 3
119 #define LISTVIEW_COLUMN_ATTRIB 4
122 #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500)
123 #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501)
124 #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502)
126 #define ID_LISTVIEW 2000
128 #define SHV_CHANGE_NOTIFY WM_USER + 0x1111
131 #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp)
132 #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp)
133 #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp)
135 extern void WINAPI _InsertMenuItem (HMENU hmenu, UINT indexMenu, BOOL fByPosition,
136 UINT wID, UINT fType, LPSTR dwTypeData, UINT fState);
139 Items merged into the toolbar and and the filemenu
148 } MYTOOLINFO, *LPMYTOOLINFO;
152 { FCIDM_SHVIEW_BIGICON, 0, 0, IDS_VIEW_LARGE, TBSTATE_ENABLED, BTNS_BUTTON },
153 { FCIDM_SHVIEW_SMALLICON, 0, 0, IDS_VIEW_SMALL, TBSTATE_ENABLED, BTNS_BUTTON },
154 { FCIDM_SHVIEW_LISTVIEW, 0, 0, IDS_VIEW_LIST, TBSTATE_ENABLED, BTNS_BUTTON },
155 { FCIDM_SHVIEW_REPORTVIEW, 0, 0, IDS_VIEW_DETAILS, TBSTATE_ENABLED, BTNS_BUTTON },
159 typedef void (CALLBACK *PFNSHGETSETTINGSPROC)(LPSHELLFLAGSTATE lpsfs, DWORD dwMask);
161 /**********************************************************
162 * IShellView_Constructor
164 IShellView * IShellView_Constructor( IShellFolder * pFolder)
165 { IShellViewImpl * sv;
166 sv=(IShellViewImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IShellViewImpl));
169 sv->lpvtblOleCommandTarget=&ctvt;
170 sv->lpvtblDropTarget=&dtvt;
171 sv->lpvtblDropSource=&dsvt;
172 sv->lpvtblViewObject=&vovt;
174 sv->pSFParent = pFolder;
175 if(pFolder) IShellFolder_AddRef(pFolder);
176 IShellFolder_QueryInterface(sv->pSFParent, &IID_IShellFolder2, (LPVOID*)&sv->pSF2Parent);
178 TRACE("(%p)->(%p)\n",sv, pFolder);
179 return (IShellView *) sv;
182 /**********************************************************
184 * ##### helperfunctions for communication with ICommDlgBrowser #####
186 static BOOL IsInCommDlg(IShellViewImpl * This)
187 { return(This->pCommDlgBrowser != NULL);
190 static HRESULT IncludeObject(IShellViewImpl * This, LPCITEMIDLIST pidl)
194 if ( IsInCommDlg(This) )
196 TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl);
197 ret = ICommDlgBrowser_IncludeObject(This->pCommDlgBrowser, (IShellView*)This, pidl);
198 TRACE("--0x%08lx\n", ret);
203 static HRESULT OnDefaultCommand(IShellViewImpl * This)
205 HRESULT ret = S_FALSE;
207 if (IsInCommDlg(This))
209 TRACE("ICommDlgBrowser::OnDefaultCommand\n");
210 ret = ICommDlgBrowser_OnDefaultCommand(This->pCommDlgBrowser, (IShellView*)This);
216 static HRESULT OnStateChange(IShellViewImpl * This, UINT uFlags)
218 HRESULT ret = S_FALSE;
220 if (IsInCommDlg(This))
222 TRACE("ICommDlgBrowser::OnStateChange flags=%x\n", uFlags);
223 ret = ICommDlgBrowser_OnStateChange(This->pCommDlgBrowser, (IShellView*)This, uFlags);
228 /**********************************************************
229 * set the toolbar of the filedialog buttons
231 * - activates the buttons from the shellbrowser according to
234 static void CheckToolbar(IShellViewImpl * This)
240 if (IsInCommDlg(This))
242 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
243 FCIDM_TB_SMALLICON, (This->FolderSettings.ViewMode==FVM_LIST)? TRUE : FALSE, &result);
244 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON,
245 FCIDM_TB_REPORTVIEW, (This->FolderSettings.ViewMode==FVM_DETAILS)? TRUE : FALSE, &result);
246 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
247 FCIDM_TB_SMALLICON, TRUE, &result);
248 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON,
249 FCIDM_TB_REPORTVIEW, TRUE, &result);
253 /**********************************************************
255 * ##### helperfunctions for initializing the view #####
257 /**********************************************************
258 * change the style of the listview control
260 static void SetStyle(IShellViewImpl * This, DWORD dwAdd, DWORD dwRemove)
264 TRACE("(%p)\n", This);
266 tmpstyle = GetWindowLongA(This->hWndList, GWL_STYLE);
267 SetWindowLongA(This->hWndList, GWL_STYLE, dwAdd | (tmpstyle & ~dwRemove));
270 /**********************************************************
271 * ShellView_CreateList()
273 * - creates the list view window
275 static BOOL ShellView_CreateList (IShellViewImpl * This)
276 { DWORD dwStyle, dwExStyle;
280 dwStyle = WS_TABSTOP | WS_VISIBLE | WS_CHILDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
281 LVS_SHAREIMAGELISTS | LVS_EDITLABELS | LVS_ALIGNLEFT | LVS_AUTOARRANGE;
282 dwExStyle = WS_EX_CLIENTEDGE;
284 switch (This->FolderSettings.ViewMode)
286 case FVM_ICON: dwStyle |= LVS_ICON; break;
287 case FVM_DETAILS: dwStyle |= LVS_REPORT; break;
288 case FVM_SMALLICON: dwStyle |= LVS_SMALLICON; break;
289 case FVM_LIST: dwStyle |= LVS_LIST; break;
290 default: dwStyle |= LVS_LIST; break;
293 if (This->FolderSettings.fFlags & FWF_AUTOARRANGE) dwStyle |= LVS_AUTOARRANGE;
294 if (This->FolderSettings.fFlags & FWF_DESKTOP)
295 This->FolderSettings.fFlags |= FWF_NOCLIENTEDGE | FWF_NOSCROLL;
296 if (This->FolderSettings.fFlags & FWF_SINGLESEL) dwStyle |= LVS_SINGLESEL;
297 if (This->FolderSettings.fFlags & FWF_NOCLIENTEDGE)
298 dwExStyle &= ~WS_EX_CLIENTEDGE;
300 This->hWndList=CreateWindowExA( dwExStyle,
313 This->ListViewSortInfo.bIsAscending = TRUE;
314 This->ListViewSortInfo.nHeaderID = -1;
315 This->ListViewSortInfo.nLastHeaderID = -1;
317 if (This->FolderSettings.fFlags & FWF_DESKTOP) {
318 if (0) /* FIXME: look into registry vale HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ListviewShadow and activate drop shadows */
319 ListView_SetTextBkColor(This->hWndList, CLR_NONE);
321 ListView_SetTextBkColor(This->hWndList, GetSysColor(COLOR_DESKTOP));
323 ListView_SetTextColor(This->hWndList, RGB(255,255,255));
326 /* UpdateShellSettings(); */
330 /**********************************************************
331 * ShellView_InitList()
333 * - adds all needed columns to the shellview
335 static BOOL ShellView_InitList(IShellViewImpl * This)
344 ListView_DeleteAllItems(This->hWndList);
346 lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT;
347 lvColumn.pszText = szTemp;
349 if (This->pSF2Parent)
353 if (!SUCCEEDED(IShellFolder2_GetDetailsOf(This->pSF2Parent, NULL, i, &sd)))
355 lvColumn.fmt = sd.fmt;
356 lvColumn.cx = sd.cxChar*8; /* chars->pixel */
357 StrRetToStrNA( szTemp, 50, &sd.str, NULL);
358 ListView_InsertColumnA(This->hWndList, i, &lvColumn);
366 ListView_SetImageList(This->hWndList, ShellSmallIconList, LVSIL_SMALL);
367 ListView_SetImageList(This->hWndList, ShellBigIconList, LVSIL_NORMAL);
371 /**********************************************************
372 * ShellView_CompareItems()
375 * internal, CALLBACK for DSA_Sort
377 static INT CALLBACK ShellView_CompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
380 TRACE("pidl1=%p pidl2=%p lpsf=%p\n", lParam1, lParam2, (LPVOID) lpData);
382 if(!lpData) return 0;
384 ret = (SHORT) SCODE_CODE(IShellFolder_CompareIDs((LPSHELLFOLDER)lpData, 0, (LPITEMIDLIST)lParam1, (LPITEMIDLIST)lParam2));
385 TRACE("ret=%i\n",ret);
389 /*************************************************************************
390 * ShellView_ListViewCompareItems
392 * Compare Function for the Listview (FileOpen Dialog)
395 * lParam1 [I] the first ItemIdList to compare with
396 * lParam2 [I] the second ItemIdList to compare with
397 * lpData [I] The column ID for the header Ctrl to process
400 * A negative value if the first item should precede the second,
401 * a positive value if the first item should follow the second,
402 * or zero if the two items are equivalent
405 * FIXME: function does what ShellView_CompareItems is supposed to do.
406 * unify it and figure out how to use the undocumented first parameter
407 * of IShellFolder_CompareIDs to do the job this function does and
408 * move this code to IShellFolder.
409 * make LISTVIEW_SORT_INFO obsolete
410 * the way this function works is only usable if we had only
411 * filesystemfolders (25/10/99 jsch)
413 static INT CALLBACK ShellView_ListViewCompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData)
417 char strName1[MAX_PATH], strName2[MAX_PATH];
418 BOOL bIsFolder1, bIsFolder2,bIsBothFolder;
419 LPITEMIDLIST pItemIdList1 = (LPITEMIDLIST) lParam1;
420 LPITEMIDLIST pItemIdList2 = (LPITEMIDLIST) lParam2;
421 LISTVIEW_SORT_INFO *pSortInfo = (LPLISTVIEW_SORT_INFO) lpData;
424 bIsFolder1 = _ILIsFolder(pItemIdList1);
425 bIsFolder2 = _ILIsFolder(pItemIdList2);
426 bIsBothFolder = bIsFolder1 && bIsFolder2;
428 /* When sorting between a File and a Folder, the Folder gets sorted first */
429 if( (bIsFolder1 || bIsFolder2) && !bIsBothFolder)
431 nDiff = bIsFolder1 ? -1 : 1;
435 /* Sort by Time: Folders or Files can be sorted */
437 if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TIME)
439 _ILGetFileDateTime(pItemIdList1, &fd1);
440 _ILGetFileDateTime(pItemIdList2, &fd2);
441 nDiff = CompareFileTime(&fd2, &fd1);
443 /* Sort by Attribute: Folder or Files can be sorted */
444 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_ATTRIB)
446 _ILGetFileAttributes(pItemIdList1, strName1, MAX_PATH);
447 _ILGetFileAttributes(pItemIdList2, strName2, MAX_PATH);
448 nDiff = strcasecmp(strName1, strName2);
450 /* Sort by FileName: Folder or Files can be sorted */
451 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_NAME || bIsBothFolder)
454 _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
455 _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
456 nDiff = strcasecmp(strName1, strName2);
458 /* Sort by File Size, Only valid for Files */
459 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_SIZE)
461 nDiff = (INT)(_ILGetFileSize(pItemIdList1, NULL, 0) - _ILGetFileSize(pItemIdList2, NULL, 0));
463 /* Sort by File Type, Only valid for Files */
464 else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TYPE)
467 _ILGetFileType(pItemIdList1, strName1, MAX_PATH);
468 _ILGetFileType(pItemIdList2, strName2, MAX_PATH);
469 nDiff = strcasecmp(strName1, strName2);
472 /* If the Date, FileSize, FileType, Attrib was the same, sort by FileName */
476 _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH);
477 _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH);
478 nDiff = strcasecmp(strName1, strName2);
481 if(!pSortInfo->bIsAscending)
490 /**********************************************************
491 * LV_FindItemByPidl()
493 static int LV_FindItemByPidl(
494 IShellViewImpl * This,
498 ZeroMemory(&lvItem, sizeof(LVITEMA));
499 lvItem.mask = LVIF_PARAM;
500 for(lvItem.iItem = 0; ListView_GetItemA(This->hWndList, &lvItem); lvItem.iItem++)
502 LPITEMIDLIST currentpidl = (LPITEMIDLIST) lvItem.lParam;
503 HRESULT hr = IShellFolder_CompareIDs(This->pSFParent, 0, pidl, currentpidl);
504 if(SUCCEEDED(hr) && !HRESULT_CODE(hr))
512 /**********************************************************
515 static BOOLEAN LV_AddItem(IShellViewImpl * This, LPCITEMIDLIST pidl)
519 TRACE("(%p)(pidl=%p)\n", This, pidl);
521 ZeroMemory(&lvItem, sizeof(lvItem)); /* create the listview item*/
522 lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; /*set the mask*/
523 lvItem.iItem = ListView_GetItemCount(This->hWndList); /*add the item to the end of the list*/
524 lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidl)); /*set the item's data*/
525 lvItem.pszText = LPSTR_TEXTCALLBACKA; /*get text on a callback basis*/
526 lvItem.iImage = I_IMAGECALLBACK; /*get the image on a callback basis*/
527 return (-1==ListView_InsertItemA(This->hWndList, &lvItem))? FALSE: TRUE;
530 /**********************************************************
533 static BOOLEAN LV_DeleteItem(IShellViewImpl * This, LPCITEMIDLIST pidl)
537 TRACE("(%p)(pidl=%p)\n", This, pidl);
539 nIndex = LV_FindItemByPidl(This, ILFindLastID(pidl));
540 return (-1==ListView_DeleteItem(This->hWndList, nIndex))? FALSE: TRUE;
543 /**********************************************************
546 static BOOLEAN LV_RenameItem(IShellViewImpl * This, LPCITEMIDLIST pidlOld, LPCITEMIDLIST pidlNew )
551 TRACE("(%p)(pidlold=%p pidlnew=%p)\n", This, pidlOld, pidlNew);
553 nItem = LV_FindItemByPidl(This, ILFindLastID(pidlOld));
556 ZeroMemory(&lvItem, sizeof(lvItem)); /* create the listview item*/
557 lvItem.mask = LVIF_PARAM; /* only the pidl */
558 lvItem.iItem = nItem;
559 ListView_GetItemA(This->hWndList, &lvItem);
561 SHFree((LPITEMIDLIST)lvItem.lParam);
562 lvItem.mask = LVIF_PARAM;
563 lvItem.iItem = nItem;
564 lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidlNew)); /* set the item's data */
565 ListView_SetItemA(This->hWndList, &lvItem);
566 ListView_Update(This->hWndList, nItem);
567 return TRUE; /* FIXME: better handling */
571 /**********************************************************
572 * ShellView_FillList()
574 * - gets the objectlist from the shellfolder
576 * - fills the list into the view
579 static INT CALLBACK fill_list( LPVOID ptr, LPVOID arg )
581 LPITEMIDLIST pidl = ptr;
582 IShellViewImpl *This = arg;
583 /* in a commdlg This works as a filemask*/
584 if ( IncludeObject(This, pidl)==S_OK ) LV_AddItem(This, pidl);
589 static HRESULT ShellView_FillList(IShellViewImpl * This)
591 LPENUMIDLIST pEnumIDList;
599 /* get the itemlist from the shfolder*/
600 hRes = IShellFolder_EnumObjects(This->pSFParent,This->hWnd, SHCONTF_NONFOLDERS | SHCONTF_FOLDERS, &pEnumIDList);
608 /* create a pointer array */
609 hdpa = DPA_Create(16);
612 return(E_OUTOFMEMORY);
615 /* copy the items into the array*/
616 while((S_OK == IEnumIDList_Next(pEnumIDList,1, &pidl, &dwFetched)) && dwFetched)
618 if (DPA_InsertPtr(hdpa, 0x7fff, pidl) == -1)
625 DPA_Sort(hdpa, ShellView_CompareItems, (LPARAM)This->pSFParent);
627 /*turn the listview's redrawing off*/
628 SendMessageA(This->hWndList, WM_SETREDRAW, FALSE, 0);
630 DPA_DestroyCallback( hdpa, fill_list, This );
632 /*turn the listview's redrawing back on and force it to draw*/
633 SendMessageA(This->hWndList, WM_SETREDRAW, TRUE, 0);
635 IEnumIDList_Release(pEnumIDList); /* destroy the list*/
640 /**********************************************************
641 * ShellView_OnCreate()
643 static LRESULT ShellView_OnCreate(IShellViewImpl * This)
646 SHChangeNotifyEntry ntreg;
647 IPersistFolder2 * ppf2 = NULL;
651 if(ShellView_CreateList(This))
653 if(ShellView_InitList(This))
655 ShellView_FillList(This);
659 if(GetShellOle() && pRegisterDragDrop)
661 if (SUCCEEDED(IShellFolder_CreateViewObject(This->pSFParent, This->hWnd, &IID_IDropTarget, (LPVOID*)&pdt)))
663 pRegisterDragDrop(This->hWnd, pdt);
664 IDropTarget_Release(pdt);
668 /* register for receiving notifications */
669 IShellFolder_QueryInterface(This->pSFParent, &IID_IPersistFolder2, (LPVOID*)&ppf2);
672 IPersistFolder2_GetCurFolder(ppf2, (LPITEMIDLIST*)&ntreg.pidl);
673 ntreg.fRecursive = TRUE;
674 This->hNotify = SHChangeNotifyRegister(This->hWnd, SHCNF_IDLIST, SHCNE_ALLEVENTS, SHV_CHANGE_NOTIFY, 1, &ntreg);
675 SHFree((LPITEMIDLIST)ntreg.pidl);
676 IPersistFolder2_Release(ppf2);
679 This->hAccel = LoadAcceleratorsA(shell32_hInstance, "shv_accel");
684 /**********************************************************
685 * #### Handling of the menus ####
688 /**********************************************************
689 * ShellView_BuildFileMenu()
691 static HMENU ShellView_BuildFileMenu(IShellViewImpl * This)
692 { CHAR szText[MAX_PATH];
697 TRACE("(%p)\n",This);
699 hSubMenu = CreatePopupMenu();
701 { /*get the number of items in our global array*/
702 for(nTools = 0; Tools[nTools].idCommand != -1; nTools++){}
704 /*add the menu items*/
705 for(i = 0; i < nTools; i++)
707 LoadStringA(shell32_hInstance, Tools[i].idMenuString, szText, MAX_PATH);
709 ZeroMemory(&mii, sizeof(mii));
710 mii.cbSize = sizeof(mii);
711 mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
713 if(BTNS_SEP != Tools[i].bStyle) /* no separator*/
715 mii.fType = MFT_STRING;
716 mii.fState = MFS_ENABLED;
717 mii.dwTypeData = szText;
718 mii.wID = Tools[i].idCommand;
722 mii.fType = MFT_SEPARATOR;
724 /* tack This item onto the end of the menu */
725 InsertMenuItemA(hSubMenu, (UINT)-1, TRUE, &mii);
728 TRACE("-- return (menu=%p)\n",hSubMenu);
731 /**********************************************************
732 * ShellView_MergeFileMenu()
734 static void ShellView_MergeFileMenu(IShellViewImpl * This, HMENU hSubMenu)
735 { TRACE("(%p)->(submenu=%p) stub\n",This,hSubMenu);
738 { /*insert This item at the beginning of the menu */
739 _InsertMenuItem(hSubMenu, 0, TRUE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
740 _InsertMenuItem(hSubMenu, 0, TRUE, IDM_MYFILEITEM, MFT_STRING, "dummy45", MFS_ENABLED);
746 /**********************************************************
747 * ShellView_MergeViewMenu()
750 static void ShellView_MergeViewMenu(IShellViewImpl * This, HMENU hSubMenu)
753 TRACE("(%p)->(submenu=%p)\n",This,hSubMenu);
756 { /*add a separator at the correct position in the menu*/
757 _InsertMenuItem(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED);
759 ZeroMemory(&mii, sizeof(mii));
760 mii.cbSize = sizeof(mii);
761 mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_DATA;
762 mii.fType = MFT_STRING;
763 mii.dwTypeData = "View";
764 mii.hSubMenu = LoadMenuA(shell32_hInstance, "MENU_001");
765 InsertMenuItemA(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii);
769 /**********************************************************
770 * ShellView_GetSelections()
772 * - fills the this->apidl list with the selected objects
775 * number of selected items
777 static UINT ShellView_GetSelections(IShellViewImpl * This)
787 This->cidl = ListView_GetSelectedCount(This->hWndList);
788 This->apidl = (LPITEMIDLIST*)SHAlloc(This->cidl * sizeof(LPITEMIDLIST));
790 TRACE("selected=%i\n", This->cidl);
794 TRACE("-- Items selected =%u\n", This->cidl);
796 ZeroMemory(&lvItem, sizeof(lvItem));
797 lvItem.mask = LVIF_STATE | LVIF_PARAM;
798 lvItem.stateMask = LVIS_SELECTED;
800 while(ListView_GetItemA(This->hWndList, &lvItem) && (i < This->cidl))
802 if(lvItem.state & LVIS_SELECTED)
804 This->apidl[i] = (LPITEMIDLIST)lvItem.lParam;
806 TRACE("-- selected Item found\n");
814 /**********************************************************
815 * ShellView_DoContextMenu()
817 static void ShellView_DoContextMenu(IShellViewImpl * This, WORD x, WORD y, BOOL bDefault)
821 BOOL fExplore = FALSE;
823 LPCONTEXTMENU pContextMenu = NULL;
824 IContextMenu2 *pCM = NULL;
825 CMINVOKECOMMANDINFO cmi;
827 TRACE("(%p)->(0x%08x 0x%08x 0x%08x) stub\n",This, x, y, bDefault);
829 /* look, what's selected and create a context menu object of it*/
830 if( ShellView_GetSelections(This) )
832 IShellFolder_GetUIObjectOf( This->pSFParent, This->hWndParent, This->cidl, (LPCITEMIDLIST*)This->apidl,
833 (REFIID)&IID_IContextMenu, NULL, (LPVOID *)&pContextMenu);
837 TRACE("-- pContextMenu\n");
838 hMenu = CreatePopupMenu();
842 /* See if we are in Explore or Open mode. If the browser's tree is present, we are in Explore mode.*/
843 if(SUCCEEDED(IShellBrowser_GetControlWindow(This->pShellBrowser,FCW_TREE, &hwndTree)) && hwndTree)
845 TRACE("-- explore mode\n");
849 /* build the flags depending on what we can do with the selected item */
850 wFlags = CMF_NORMAL | (This->cidl != 1 ? 0 : CMF_CANRENAME) | (fExplore ? CMF_EXPLORE : 0);
852 /* let the ContextMenu merge its items in */
853 if (SUCCEEDED(IContextMenu_QueryContextMenu( pContextMenu, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, wFlags )))
857 TRACE("-- get menu default command\n");
858 uCommand = GetMenuDefaultItem(hMenu, FALSE, GMDI_GOINTOPOPUPS);
862 TRACE("-- track popup\n");
863 uCommand = TrackPopupMenu( hMenu,TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
868 TRACE("-- uCommand=%u\n", uCommand);
869 if (IsInCommDlg(This) && ((uCommand==FCIDM_SHVIEW_EXPLORE) || (uCommand==FCIDM_SHVIEW_OPEN)))
871 TRACE("-- dlg: OnDefaultCommand\n");
872 OnDefaultCommand(This);
876 TRACE("-- explore -- invoke command\n");
877 ZeroMemory(&cmi, sizeof(cmi));
878 cmi.cbSize = sizeof(cmi);
879 cmi.hwnd = This->hWndParent; /* this window has to answer CWM_GETISHELLBROWSER */
880 cmi.lpVerb = (LPCSTR)MAKEINTRESOURCEA(uCommand);
881 IContextMenu_InvokeCommand(pContextMenu, &cmi);
888 IContextMenu_Release(pContextMenu);
891 else /* background context menu */
893 hMenu = CreatePopupMenu();
895 pCM = ISvBgCm_Constructor(This->pSFParent);
896 IContextMenu2_QueryContextMenu(pCM, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, 0);
898 uCommand = TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL);
901 TRACE("-- (%p)->(uCommand=0x%08x )\n",This, uCommand);
903 ZeroMemory(&cmi, sizeof(cmi));
904 cmi.cbSize = sizeof(cmi);
905 cmi.lpVerb = (LPCSTR)MAKEINTRESOURCEA(uCommand);
906 cmi.hwnd = This->hWndParent;
907 IContextMenu2_InvokeCommand(pCM, &cmi);
909 IContextMenu2_Release(pCM);
913 /**********************************************************
914 * ##### message handling #####
917 /**********************************************************
920 static LRESULT ShellView_OnSize(IShellViewImpl * This, WORD wWidth, WORD wHeight)
922 TRACE("%p width=%u height=%u\n",This, wWidth,wHeight);
924 /*resize the ListView to fit our window*/
927 MoveWindow(This->hWndList, 0, 0, wWidth, wHeight, TRUE);
932 /**********************************************************
933 * ShellView_OnDeactivate()
938 static void ShellView_OnDeactivate(IShellViewImpl * This)
942 if(This->uState != SVUIA_DEACTIVATE)
946 IShellBrowser_SetMenuSB(This->pShellBrowser,0, 0, 0);
947 IShellBrowser_RemoveMenusSB(This->pShellBrowser,This->hMenu);
948 DestroyMenu(This->hMenu);
952 This->uState = SVUIA_DEACTIVATE;
956 /**********************************************************
957 * ShellView_OnActivate()
959 static LRESULT ShellView_OnActivate(IShellViewImpl * This, UINT uState)
960 { OLEMENUGROUPWIDTHS omw = { {0, 0, 0, 0, 0, 0} };
962 CHAR szText[MAX_PATH];
964 TRACE("%p uState=%x\n",This,uState);
966 /*don't do anything if the state isn't really changing */
967 if(This->uState == uState)
972 ShellView_OnDeactivate(This);
974 /*only do This if we are active */
975 if(uState != SVUIA_DEACTIVATE)
978 This->hMenu = CreateMenu();
982 IShellBrowser_InsertMenusSB(This->pShellBrowser, This->hMenu, &omw);
983 TRACE("-- after fnInsertMenusSB\n");
985 /*build the top level menu get the menu item's text*/
986 strcpy(szText,"dummy 31");
988 ZeroMemory(&mii, sizeof(mii));
989 mii.cbSize = sizeof(mii);
990 mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_STATE;
991 mii.fType = MFT_STRING;
992 mii.fState = MFS_ENABLED;
993 mii.dwTypeData = szText;
994 mii.hSubMenu = ShellView_BuildFileMenu(This);
996 /*insert our menu into the menu bar*/
999 InsertMenuItemA(This->hMenu, FCIDM_MENU_HELP, FALSE, &mii);
1002 /*get the view menu so we can merge with it*/
1003 ZeroMemory(&mii, sizeof(mii));
1004 mii.cbSize = sizeof(mii);
1005 mii.fMask = MIIM_SUBMENU;
1007 if(GetMenuItemInfoA(This->hMenu, FCIDM_MENU_VIEW, FALSE, &mii))
1009 ShellView_MergeViewMenu(This, mii.hSubMenu);
1012 /*add the items that should only be added if we have the focus*/
1013 if(SVUIA_ACTIVATE_FOCUS == uState)
1015 /*get the file menu so we can merge with it */
1016 ZeroMemory(&mii, sizeof(mii));
1017 mii.cbSize = sizeof(mii);
1018 mii.fMask = MIIM_SUBMENU;
1020 if(GetMenuItemInfoA(This->hMenu, FCIDM_MENU_FILE, FALSE, &mii))
1022 ShellView_MergeFileMenu(This, mii.hSubMenu);
1025 TRACE("-- before fnSetMenuSB\n");
1026 IShellBrowser_SetMenuSB(This->pShellBrowser, This->hMenu, 0, This->hWnd);
1029 This->uState = uState;
1034 /**********************************************************
1035 * ShellView_OnSetFocus()
1038 static LRESULT ShellView_OnSetFocus(IShellViewImpl * This)
1042 /* Tell the browser one of our windows has received the focus. This
1043 should always be done before merging menus (OnActivate merges the
1044 menus) if one of our windows has the focus.*/
1046 IShellBrowser_OnViewWindowActive(This->pShellBrowser,(IShellView*) This);
1047 ShellView_OnActivate(This, SVUIA_ACTIVATE_FOCUS);
1049 /* Set the focus to the listview */
1050 SetFocus(This->hWndList);
1052 /* Notify the ICommDlgBrowser interface */
1053 OnStateChange(This,CDBOSC_SETFOCUS);
1058 /**********************************************************
1059 * ShellView_OnKillFocus()
1061 static LRESULT ShellView_OnKillFocus(IShellViewImpl * This)
1063 TRACE("(%p) stub\n",This);
1065 ShellView_OnActivate(This, SVUIA_ACTIVATE_NOFOCUS);
1066 /* Notify the ICommDlgBrowser */
1067 OnStateChange(This,CDBOSC_KILLFOCUS);
1072 /**********************************************************
1073 * ShellView_OnCommand()
1076 * the CmdID's are the ones from the context menu
1078 static LRESULT ShellView_OnCommand(IShellViewImpl * This,DWORD dwCmdID, DWORD dwCmd, HWND hwndCmd)
1080 TRACE("(%p)->(0x%08lx 0x%08lx %p) stub\n",This, dwCmdID, dwCmd, hwndCmd);
1084 case FCIDM_SHVIEW_SMALLICON:
1085 This->FolderSettings.ViewMode = FVM_SMALLICON;
1086 SetStyle (This, LVS_SMALLICON, LVS_TYPEMASK);
1090 case FCIDM_SHVIEW_BIGICON:
1091 This->FolderSettings.ViewMode = FVM_ICON;
1092 SetStyle (This, LVS_ICON, LVS_TYPEMASK);
1096 case FCIDM_SHVIEW_LISTVIEW:
1097 This->FolderSettings.ViewMode = FVM_LIST;
1098 SetStyle (This, LVS_LIST, LVS_TYPEMASK);
1102 case FCIDM_SHVIEW_REPORTVIEW:
1103 This->FolderSettings.ViewMode = FVM_DETAILS;
1104 SetStyle (This, LVS_REPORT, LVS_TYPEMASK);
1108 /* the menu-ID's for sorting are 0x30... see shrec.rc */
1113 This->ListViewSortInfo.nHeaderID = (LPARAM) (dwCmdID - 0x30);
1114 This->ListViewSortInfo.bIsAscending = TRUE;
1115 This->ListViewSortInfo.nLastHeaderID = This->ListViewSortInfo.nHeaderID;
1116 ListView_SortItems(This->hWndList, ShellView_ListViewCompareItems, (LPARAM) (&(This->ListViewSortInfo)));
1120 TRACE("-- COMMAND 0x%04lx unhandled\n", dwCmdID);
1125 /**********************************************************
1126 * ShellView_OnNotify()
1129 static LRESULT ShellView_OnNotify(IShellViewImpl * This, UINT CtlID, LPNMHDR lpnmh)
1130 { LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)lpnmh;
1131 NMLVDISPINFOA *lpdi = (NMLVDISPINFOA *)lpnmh;
1134 TRACE("%p CtlID=%u lpnmh->code=%x\n",This,CtlID,lpnmh->code);
1139 TRACE("-- NM_SETFOCUS %p\n",This);
1140 ShellView_OnSetFocus(This);
1144 TRACE("-- NM_KILLFOCUS %p\n",This);
1145 ShellView_OnDeactivate(This);
1146 /* Notify the ICommDlgBrowser interface */
1147 OnStateChange(This,CDBOSC_KILLFOCUS);
1151 TRACE("-- HDN_ENDTRACKA %p\n",This);
1152 /*nColumn1 = ListView_GetColumnWidth(This->hWndList, 0);
1153 nColumn2 = ListView_GetColumnWidth(This->hWndList, 1);*/
1156 case LVN_DELETEITEM:
1157 TRACE("-- LVN_DELETEITEM %p\n",This);
1158 SHFree((LPITEMIDLIST)lpnmlv->lParam); /*delete the pidl because we made a copy of it*/
1161 case LVN_INSERTITEM:
1162 TRACE("-- LVN_INSERTITEM (STUB)%p\n",This);
1165 case LVN_ITEMACTIVATE:
1166 TRACE("-- LVN_ITEMACTIVATE %p\n",This);
1167 OnStateChange(This, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
1168 ShellView_DoContextMenu(This, 0, 0, TRUE);
1171 case LVN_COLUMNCLICK:
1172 This->ListViewSortInfo.nHeaderID = lpnmlv->iSubItem;
1173 if(This->ListViewSortInfo.nLastHeaderID == This->ListViewSortInfo.nHeaderID)
1175 This->ListViewSortInfo.bIsAscending = !This->ListViewSortInfo.bIsAscending;
1179 This->ListViewSortInfo.bIsAscending = TRUE;
1181 This->ListViewSortInfo.nLastHeaderID = This->ListViewSortInfo.nHeaderID;
1183 ListView_SortItems(lpnmlv->hdr.hwndFrom, ShellView_ListViewCompareItems, (LPARAM) (&(This->ListViewSortInfo)));
1186 case LVN_GETDISPINFOA:
1187 case LVN_GETDISPINFOW:
1188 TRACE("-- LVN_GETDISPINFO %p\n",This);
1189 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1191 if(lpdi->item.mask & LVIF_TEXT) /* text requested */
1193 if (This->pSF2Parent)
1196 IShellFolder2_GetDetailsOf(This->pSF2Parent, pidl, lpdi->item.iSubItem, &sd);
1197 if (lpnmh->code == LVN_GETDISPINFOA)
1199 StrRetToStrNA( lpdi->item.pszText, lpdi->item.cchTextMax, &sd.str, NULL);
1200 TRACE("-- text=%s\n",lpdi->item.pszText);
1202 else /* LVN_GETDISPINFOW */
1204 StrRetToStrNW( ((NMLVDISPINFOW *)lpdi)->item.pszText, lpdi->item.cchTextMax, &sd.str, NULL);
1205 TRACE("-- text=%s\n",debugstr_w((WCHAR*)(lpdi->item.pszText)));
1213 if(lpdi->item.mask & LVIF_IMAGE) /* image requested */
1215 lpdi->item.iImage = SHMapPIDLToSystemImageListIndex(This->pSFParent, pidl, 0);
1219 case LVN_ITEMCHANGED:
1220 TRACE("-- LVN_ITEMCHANGED %p\n",This);
1221 OnStateChange(This, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */
1225 case LVN_BEGINRDRAG:
1226 TRACE("-- LVN_BEGINDRAG\n");
1228 if (ShellView_GetSelections(This))
1231 DWORD dwAttributes = SFGAO_CANLINK;
1232 DWORD dwEffect = DROPEFFECT_COPY | DROPEFFECT_MOVE;
1234 if(GetShellOle() && pDoDragDrop)
1236 if (SUCCEEDED(IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, (LPCITEMIDLIST*)This->apidl, &IID_IDataObject,0,(LPVOID *)&pda)))
1238 IDropSource * pds = (IDropSource*)&(This->lpvtblDropSource); /* own DropSource interface */
1240 if (SUCCEEDED(IShellFolder_GetAttributesOf(This->pSFParent, This->cidl, (LPCITEMIDLIST*)This->apidl, &dwAttributes)))
1242 if (dwAttributes & SFGAO_CANLINK)
1244 dwEffect |= DROPEFFECT_LINK;
1251 pDoDragDrop(pda, pds, dwEffect, &dwEffect);
1253 IDataObject_Release(pda);
1259 case LVN_BEGINLABELEDITA:
1261 DWORD dwAttr = SFGAO_CANRENAME;
1262 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1264 TRACE("-- LVN_BEGINLABELEDITA %p\n",This);
1266 IShellFolder_GetAttributesOf(This->pSFParent, 1, (LPCITEMIDLIST*)&pidl, &dwAttr);
1267 if (SFGAO_CANRENAME & dwAttr)
1275 case LVN_ENDLABELEDITA:
1277 TRACE("-- LVN_ENDLABELEDITA %p\n",This);
1278 if (lpdi->item.pszText)
1281 WCHAR wszNewName[MAX_PATH];
1284 ZeroMemory(&lvItem, sizeof(LVITEMA));
1285 lvItem.iItem = lpdi->item.iItem;
1286 lvItem.mask = LVIF_PARAM;
1287 ListView_GetItemA(This->hWndList, &lvItem);
1289 pidl = (LPITEMIDLIST)lpdi->item.lParam;
1290 if (!MultiByteToWideChar( CP_ACP, 0, lpdi->item.pszText, -1, wszNewName, MAX_PATH ))
1291 wszNewName[MAX_PATH-1] = 0;
1292 hr = IShellFolder_SetNameOf(This->pSFParent, 0, pidl, wszNewName, SHGDN_INFOLDER, &pidl);
1294 if(SUCCEEDED(hr) && pidl)
1296 lvItem.mask = LVIF_PARAM;
1297 lvItem.lParam = (LPARAM)pidl;
1298 ListView_SetItemA(This->hWndList, &lvItem);
1309 msg.hwnd = This->hWnd;
1310 msg.message = WM_KEYDOWN;
1311 msg.wParam = plvKeyDown->wVKey;
1316 LPNMLVKEYDOWN plvKeyDown = (LPNMLVKEYDOWN) lpnmh;
1318 /* initiate a rename of the selected file or directory */
1319 if(plvKeyDown->wVKey == VK_F2)
1321 /* see how many files are selected */
1322 int i = ListView_GetSelectedCount(This->hWndList);
1324 /* get selected item */
1327 /* get selected item */
1328 i = ListView_GetNextItem(This->hWndList, -1,
1331 ListView_EnsureVisible(This->hWndList, i, 0);
1332 ListView_EditLabelA(This->hWndList, i);
1336 TranslateAccelerator(This->hWnd, This->hAccel, &msg)
1338 else if(plvKeyDown->wVKey == VK_DELETE)
1343 LPITEMIDLIST* pItems;
1346 IShellFolder_QueryInterface(This->pSFParent, &IID_ISFHelper,
1349 if(!(i = ListView_GetSelectedCount(This->hWndList)))
1352 /* allocate memory for the pidl array */
1353 pItems = HeapAlloc(GetProcessHeap(), 0,
1354 sizeof(LPITEMIDLIST) * i);
1356 /* retrieve all selected items */
1359 while(ListView_GetSelectedCount(This->hWndList) > i)
1361 /* get selected item */
1362 item_index = ListView_GetNextItem(This->hWndList,
1363 item_index, LVNI_SELECTED);
1364 item.iItem = item_index;
1365 item.mask |= LVIF_PARAM;
1366 ListView_GetItemA(This->hWndList, &item);
1369 pItems[i] = (LPITEMIDLIST)item.lParam;
1374 /* perform the item deletion */
1375 ISFHelper_DeleteItems(psfhlp, i, (LPCITEMIDLIST*)pItems);
1377 /* free pidl array memory */
1378 HeapFree(GetProcessHeap(), 0, pItems);
1381 FIXME("LVN_KEYDOWN key=0x%08x\n",plvKeyDown->wVKey);
1386 TRACE("-- %p WM_COMMAND %x unhandled\n", This, lpnmh->code);
1392 /**********************************************************
1393 * ShellView_OnChange()
1396 static LRESULT ShellView_OnChange(IShellViewImpl * This, LPITEMIDLIST * Pidls, LONG wEventId)
1399 TRACE("(%p)(%p,%p,0x%08lx)\n", This, Pidls[0], Pidls[1], wEventId);
1404 LV_AddItem(This, Pidls[0]);
1408 LV_DeleteItem(This, Pidls[0]);
1410 case SHCNE_RENAMEFOLDER:
1411 case SHCNE_RENAMEITEM:
1412 LV_RenameItem(This, Pidls[0], Pidls[1]);
1414 case SHCNE_UPDATEITEM:
1419 /**********************************************************
1423 static LRESULT CALLBACK ShellView_WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
1425 IShellViewImpl * pThis = (IShellViewImpl*)GetWindowLongA(hWnd, GWL_USERDATA);
1426 LPCREATESTRUCTA lpcs;
1428 TRACE("(hwnd=%p msg=%x wparm=%x lparm=%lx)\n",hWnd, uMessage, wParam, lParam);
1433 lpcs = (LPCREATESTRUCTA)lParam;
1434 pThis = (IShellViewImpl*)(lpcs->lpCreateParams);
1435 SetWindowLongA(hWnd, GWL_USERDATA, (LONG)pThis);
1436 pThis->hWnd = hWnd; /*set the window handle*/
1439 case WM_SIZE: return ShellView_OnSize(pThis,LOWORD(lParam), HIWORD(lParam));
1440 case WM_SETFOCUS: return ShellView_OnSetFocus(pThis);
1441 case WM_KILLFOCUS: return ShellView_OnKillFocus(pThis);
1442 case WM_CREATE: return ShellView_OnCreate(pThis);
1443 case WM_ACTIVATE: return ShellView_OnActivate(pThis, SVUIA_ACTIVATE_FOCUS);
1444 case WM_NOTIFY: return ShellView_OnNotify(pThis,(UINT)wParam, (LPNMHDR)lParam);
1445 case WM_COMMAND: return ShellView_OnCommand(pThis,
1446 GET_WM_COMMAND_ID(wParam, lParam),
1447 GET_WM_COMMAND_CMD(wParam, lParam),
1448 GET_WM_COMMAND_HWND(wParam, lParam));
1449 case SHV_CHANGE_NOTIFY: return ShellView_OnChange(pThis, (LPITEMIDLIST*)wParam, (LONG)lParam);
1451 case WM_CONTEXTMENU: ShellView_DoContextMenu(pThis, LOWORD(lParam), HIWORD(lParam), FALSE);
1454 case WM_SHOWWINDOW: UpdateWindow(pThis->hWndList);
1457 case WM_GETDLGCODE: return SendMessageA(pThis->hWndList,uMessage,0,0);
1459 case WM_DESTROY: if(GetShellOle() && pRevokeDragDrop)
1461 pRevokeDragDrop(pThis->hWnd);
1463 SHChangeNotifyDeregister(pThis->hNotify);
1467 if ((pThis->FolderSettings.fFlags & FWF_DESKTOP) ||
1468 (pThis->FolderSettings.fFlags & FWF_TRANSPARENT))
1473 return DefWindowProcA (hWnd, uMessage, wParam, lParam);
1475 /**********************************************************
1478 * The INTERFACE of the IShellView object
1481 **********************************************************
1482 * IShellView_QueryInterface
1484 static HRESULT WINAPI IShellView_fnQueryInterface(IShellView * iface,REFIID riid, LPVOID *ppvObj)
1486 ICOM_THIS(IShellViewImpl, iface);
1488 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1492 if(IsEqualIID(riid, &IID_IUnknown))
1496 else if(IsEqualIID(riid, &IID_IShellView))
1498 *ppvObj = (IShellView*)This;
1500 else if(IsEqualIID(riid, &IID_IOleCommandTarget))
1502 *ppvObj = (IOleCommandTarget*)&(This->lpvtblOleCommandTarget);
1504 else if(IsEqualIID(riid, &IID_IDropTarget))
1506 *ppvObj = (IDropTarget*)&(This->lpvtblDropTarget);
1508 else if(IsEqualIID(riid, &IID_IDropSource))
1510 *ppvObj = (IDropSource*)&(This->lpvtblDropSource);
1512 else if(IsEqualIID(riid, &IID_IViewObject))
1514 *ppvObj = (IViewObject*)&(This->lpvtblViewObject);
1519 IUnknown_AddRef( (IUnknown*)*ppvObj );
1520 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1523 TRACE("-- Interface: E_NOINTERFACE\n");
1524 return E_NOINTERFACE;
1527 /**********************************************************
1530 static ULONG WINAPI IShellView_fnAddRef(IShellView * iface)
1532 ICOM_THIS(IShellViewImpl, iface);
1534 TRACE("(%p)->(count=%lu)\n",This,This->ref);
1536 return ++(This->ref);
1538 /**********************************************************
1539 * IShellView_Release
1541 static ULONG WINAPI IShellView_fnRelease(IShellView * iface)
1543 ICOM_THIS(IShellViewImpl, iface);
1545 TRACE("(%p)->()\n",This);
1549 TRACE(" destroying IShellView(%p)\n",This);
1552 IShellFolder_Release(This->pSFParent);
1554 if(This->pSF2Parent)
1555 IShellFolder2_Release(This->pSF2Parent);
1558 SHFree(This->apidl);
1560 HeapFree(GetProcessHeap(),0,This);
1566 /**********************************************************
1567 * ShellView_GetWindow
1569 static HRESULT WINAPI IShellView_fnGetWindow(IShellView * iface,HWND * phWnd)
1571 ICOM_THIS(IShellViewImpl, iface);
1573 TRACE("(%p)\n",This);
1575 *phWnd = This->hWnd;
1580 static HRESULT WINAPI IShellView_fnContextSensitiveHelp(IShellView * iface,BOOL fEnterMode)
1582 ICOM_THIS(IShellViewImpl, iface);
1584 FIXME("(%p) stub\n",This);
1589 /**********************************************************
1590 * IShellView_TranslateAccelerator
1593 * use the accel functions
1595 static HRESULT WINAPI IShellView_fnTranslateAccelerator(IShellView * iface,LPMSG lpmsg)
1598 ICOM_THIS(IShellViewImpl, iface);
1600 FIXME("(%p)->(%p: hwnd=%x msg=%x lp=%lx wp=%x) stub\n",This,lpmsg, lpmsg->hwnd, lpmsg->message, lpmsg->lParam, lpmsg->wParam);
1603 if ((lpmsg->message>=WM_KEYFIRST) && (lpmsg->message>=WM_KEYLAST))
1605 TRACE("-- key=0x04%x\n",lpmsg->wParam) ;
1607 return S_FALSE; /* not handled */
1610 static HRESULT WINAPI IShellView_fnEnableModeless(IShellView * iface,BOOL fEnable)
1612 ICOM_THIS(IShellViewImpl, iface);
1614 FIXME("(%p) stub\n",This);
1619 static HRESULT WINAPI IShellView_fnUIActivate(IShellView * iface,UINT uState)
1621 ICOM_THIS(IShellViewImpl, iface);
1624 CHAR szName[MAX_PATH];
1627 int nPartArray[1] = {-1};
1629 TRACE("(%p)->(state=%x) stub\n",This, uState);
1631 /*don't do anything if the state isn't really changing*/
1632 if(This->uState == uState)
1637 /*OnActivate handles the menu merging and internal state*/
1638 ShellView_OnActivate(This, uState);
1640 /*only do This if we are active*/
1641 if(uState != SVUIA_DEACTIVATE)
1645 GetFolderPath is not a method of IShellFolder
1646 IShellFolder_GetFolderPath( This->pSFParent, szName, sizeof(szName) );
1648 /* set the number of parts */
1649 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETPARTS, 1,
1650 (LPARAM)nPartArray, &lResult);
1652 /* set the text for the parts */
1654 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETTEXTA,
1655 0, (LPARAM)szName, &lResult);
1662 static HRESULT WINAPI IShellView_fnRefresh(IShellView * iface)
1664 ICOM_THIS(IShellViewImpl, iface);
1666 TRACE("(%p)\n",This);
1668 ListView_DeleteAllItems(This->hWndList);
1669 ShellView_FillList(This);
1674 static HRESULT WINAPI IShellView_fnCreateViewWindow(
1676 IShellView *lpPrevView,
1677 LPCFOLDERSETTINGS lpfs,
1678 IShellBrowser * psb,
1682 ICOM_THIS(IShellViewImpl, iface);
1688 TRACE("(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n",This, lpPrevView,lpfs, psb, prcView, phWnd);
1689 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);
1691 /*set up the member variables*/
1692 This->pShellBrowser = psb;
1693 This->FolderSettings = *lpfs;
1695 /*get our parent window*/
1696 IShellBrowser_AddRef(This->pShellBrowser);
1697 IShellBrowser_GetWindow(This->pShellBrowser, &(This->hWndParent));
1699 /* try to get the ICommDlgBrowserInterface, adds a reference !!! */
1700 This->pCommDlgBrowser=NULL;
1701 if ( SUCCEEDED (IShellBrowser_QueryInterface( This->pShellBrowser,
1702 (REFIID)&IID_ICommDlgBrowser, (LPVOID*) &This->pCommDlgBrowser)))
1704 TRACE("-- CommDlgBrowser\n");
1707 /*if our window class has not been registered, then do so*/
1708 if(!GetClassInfoA(shell32_hInstance, SV_CLASS_NAME, &wc))
1710 ZeroMemory(&wc, sizeof(wc));
1711 wc.style = CS_HREDRAW | CS_VREDRAW;
1712 wc.lpfnWndProc = (WNDPROC) ShellView_WndProc;
1715 wc.hInstance = shell32_hInstance;
1717 wc.hCursor = LoadCursorA (0, (LPSTR)IDC_ARROW);
1718 wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
1719 wc.lpszMenuName = NULL;
1720 wc.lpszClassName = SV_CLASS_NAME;
1722 if(!RegisterClassA(&wc))
1726 *phWnd = CreateWindowExA(0,
1729 WS_CHILD | WS_VISIBLE | WS_TABSTOP,
1732 prcView->right - prcView->left,
1733 prcView->bottom - prcView->top,
1741 if(!*phWnd) return E_FAIL;
1746 static HRESULT WINAPI IShellView_fnDestroyViewWindow(IShellView * iface)
1748 ICOM_THIS(IShellViewImpl, iface);
1750 TRACE("(%p)\n",This);
1752 /*Make absolutely sure all our UI is cleaned up.*/
1753 IShellView_UIActivate((IShellView*)This, SVUIA_DEACTIVATE);
1757 DestroyMenu(This->hMenu);
1760 DestroyWindow(This->hWnd);
1761 if(This->pShellBrowser) IShellBrowser_Release(This->pShellBrowser);
1762 if(This->pCommDlgBrowser) ICommDlgBrowser_Release(This->pCommDlgBrowser);
1768 static HRESULT WINAPI IShellView_fnGetCurrentInfo(IShellView * iface, LPFOLDERSETTINGS lpfs)
1770 ICOM_THIS(IShellViewImpl, iface);
1772 TRACE("(%p)->(%p) vmode=%x flags=%x\n",This, lpfs,
1773 This->FolderSettings.ViewMode, This->FolderSettings.fFlags);
1775 if (!lpfs) return E_INVALIDARG;
1777 *lpfs = This->FolderSettings;
1781 static HRESULT WINAPI IShellView_fnAddPropertySheetPages(IShellView * iface, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam)
1783 ICOM_THIS(IShellViewImpl, iface);
1785 FIXME("(%p) stub\n",This);
1790 static HRESULT WINAPI IShellView_fnSaveViewState(IShellView * iface)
1792 ICOM_THIS(IShellViewImpl, iface);
1794 FIXME("(%p) stub\n",This);
1799 static HRESULT WINAPI IShellView_fnSelectItem(
1804 ICOM_THIS(IShellViewImpl, iface);
1807 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n",This, pidl, uFlags);
1809 i = LV_FindItemByPidl(This, pidl);
1815 if(uFlags & SVSI_ENSUREVISIBLE)
1816 ListView_EnsureVisible(This->hWndList, i, 0);
1818 ZeroMemory(&lvItem, sizeof(LVITEMA));
1819 lvItem.mask = LVIF_STATE;
1822 while(ListView_GetItemA(This->hWndList, &lvItem))
1824 if (lvItem.iItem == i)
1826 if (uFlags & SVSI_SELECT)
1827 lvItem.state |= LVIS_SELECTED;
1829 lvItem.state &= ~LVIS_SELECTED;
1831 if(uFlags & SVSI_FOCUSED)
1832 lvItem.state &= ~LVIS_FOCUSED;
1836 if (uFlags & SVSI_DESELECTOTHERS)
1837 lvItem.state &= ~LVIS_SELECTED;
1839 ListView_SetItemA(This->hWndList, &lvItem);
1844 if(uFlags & SVSI_EDIT)
1845 ListView_EditLabelA(This->hWndList, i);
1851 static HRESULT WINAPI IShellView_fnGetItemObject(IShellView * iface, UINT uItem, REFIID riid, LPVOID *ppvOut)
1853 ICOM_THIS(IShellViewImpl, iface);
1855 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n",This, uItem, debugstr_guid(riid), ppvOut);
1861 case SVGIO_BACKGROUND:
1862 *ppvOut = ISvBgCm_Constructor(This->pSFParent);
1865 case SVGIO_SELECTION:
1866 ShellView_GetSelections(This);
1867 IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, (LPCITEMIDLIST*)This->apidl, riid, 0, ppvOut);
1870 TRACE("-- (%p)->(interface=%p)\n",This, *ppvOut);
1872 if(!*ppvOut) return E_OUTOFMEMORY;
1877 static struct ICOM_VTABLE(IShellView) svvt =
1879 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1880 IShellView_fnQueryInterface,
1881 IShellView_fnAddRef,
1882 IShellView_fnRelease,
1883 IShellView_fnGetWindow,
1884 IShellView_fnContextSensitiveHelp,
1885 IShellView_fnTranslateAccelerator,
1886 IShellView_fnEnableModeless,
1887 IShellView_fnUIActivate,
1888 IShellView_fnRefresh,
1889 IShellView_fnCreateViewWindow,
1890 IShellView_fnDestroyViewWindow,
1891 IShellView_fnGetCurrentInfo,
1892 IShellView_fnAddPropertySheetPages,
1893 IShellView_fnSaveViewState,
1894 IShellView_fnSelectItem,
1895 IShellView_fnGetItemObject
1899 /**********************************************************
1900 * ISVOleCmdTarget_QueryInterface (IUnknown)
1902 static HRESULT WINAPI ISVOleCmdTarget_QueryInterface(
1903 IOleCommandTarget * iface,
1907 _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
1909 return IShellFolder_QueryInterface((IShellFolder*)This, iid, ppvObj);
1912 /**********************************************************
1913 * ISVOleCmdTarget_AddRef (IUnknown)
1915 static ULONG WINAPI ISVOleCmdTarget_AddRef(
1916 IOleCommandTarget * iface)
1918 _ICOM_THIS_From_IOleCommandTarget(IShellFolder, iface);
1920 return IShellFolder_AddRef((IShellFolder*)This);
1923 /**********************************************************
1924 * ISVOleCmdTarget_Release (IUnknown)
1926 static ULONG WINAPI ISVOleCmdTarget_Release(
1927 IOleCommandTarget * iface)
1929 _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
1931 return IShellFolder_Release((IShellFolder*)This);
1934 /**********************************************************
1935 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
1937 static HRESULT WINAPI ISVOleCmdTarget_QueryStatus(
1938 IOleCommandTarget *iface,
1939 const GUID* pguidCmdGroup,
1942 OLECMDTEXT* pCmdText)
1945 _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
1947 FIXME("(%p)->(%p(%s) 0x%08lx %p %p\n",
1948 This, pguidCmdGroup, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText);
1952 for (i = 0; i < cCmds; i++)
1954 FIXME("\tprgCmds[%d].cmdID = %ld\n", i, prgCmds[i].cmdID);
1955 prgCmds[i].cmdf = 0;
1957 return OLECMDERR_E_UNKNOWNGROUP;
1960 /**********************************************************
1961 * ISVOleCmdTarget_Exec (IOleCommandTarget)
1963 * nCmdID is the OLECMDID_* enumeration
1965 static HRESULT WINAPI ISVOleCmdTarget_Exec(
1966 IOleCommandTarget *iface,
1967 const GUID* pguidCmdGroup,
1973 _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
1975 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08lx Opt:0x%08lx %p %p)\n",
1976 This, debugstr_guid(pguidCmdGroup), nCmdID, nCmdexecopt, pvaIn, pvaOut);
1978 if (IsEqualIID(pguidCmdGroup, &CGID_Explorer) &&
1980 (nCmdexecopt == 4) && pvaOut)
1982 if (IsEqualIID(pguidCmdGroup, &CGID_ShellDocView) &&
1987 return OLECMDERR_E_UNKNOWNGROUP;
1990 static ICOM_VTABLE(IOleCommandTarget) ctvt =
1992 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1993 ISVOleCmdTarget_QueryInterface,
1994 ISVOleCmdTarget_AddRef,
1995 ISVOleCmdTarget_Release,
1996 ISVOleCmdTarget_QueryStatus,
1997 ISVOleCmdTarget_Exec
2000 /**********************************************************
2001 * ISVDropTarget implementation
2004 static HRESULT WINAPI ISVDropTarget_QueryInterface(
2009 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2011 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2013 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2016 static ULONG WINAPI ISVDropTarget_AddRef( IDropTarget *iface)
2018 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2020 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2022 return IShellFolder_AddRef((IShellFolder*)This);
2025 static ULONG WINAPI ISVDropTarget_Release( IDropTarget *iface)
2027 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2029 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2031 return IShellFolder_Release((IShellFolder*)This);
2034 static HRESULT WINAPI ISVDropTarget_DragEnter(
2036 IDataObject *pDataObject,
2042 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2044 FIXME("Stub: This=%p, DataObject=%p\n",This,pDataObject);
2049 static HRESULT WINAPI ISVDropTarget_DragOver(
2055 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2057 FIXME("Stub: This=%p\n",This);
2062 static HRESULT WINAPI ISVDropTarget_DragLeave(
2065 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2067 FIXME("Stub: This=%p\n",This);
2072 static HRESULT WINAPI ISVDropTarget_Drop(
2074 IDataObject* pDataObject,
2079 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2081 FIXME("Stub: This=%p\n",This);
2086 static struct ICOM_VTABLE(IDropTarget) dtvt =
2088 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2089 ISVDropTarget_QueryInterface,
2090 ISVDropTarget_AddRef,
2091 ISVDropTarget_Release,
2092 ISVDropTarget_DragEnter,
2093 ISVDropTarget_DragOver,
2094 ISVDropTarget_DragLeave,
2098 /**********************************************************
2099 * ISVDropSource implementation
2102 static HRESULT WINAPI ISVDropSource_QueryInterface(
2107 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2109 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2111 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2114 static ULONG WINAPI ISVDropSource_AddRef( IDropSource *iface)
2116 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2118 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2120 return IShellFolder_AddRef((IShellFolder*)This);
2123 static ULONG WINAPI ISVDropSource_Release( IDropSource *iface)
2125 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2127 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2129 return IShellFolder_Release((IShellFolder*)This);
2131 static HRESULT WINAPI ISVDropSource_QueryContinueDrag(
2133 BOOL fEscapePressed,
2136 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2137 TRACE("(%p)\n",This);
2140 return DRAGDROP_S_CANCEL;
2141 else if (!(grfKeyState & MK_LBUTTON) && !(grfKeyState & MK_RBUTTON))
2142 return DRAGDROP_S_DROP;
2147 static HRESULT WINAPI ISVDropSource_GiveFeedback(
2151 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2152 TRACE("(%p)\n",This);
2154 return DRAGDROP_S_USEDEFAULTCURSORS;
2157 static struct ICOM_VTABLE(IDropSource) dsvt =
2159 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2160 ISVDropSource_QueryInterface,
2161 ISVDropSource_AddRef,
2162 ISVDropSource_Release,
2163 ISVDropSource_QueryContinueDrag,
2164 ISVDropSource_GiveFeedback
2166 /**********************************************************
2167 * ISVViewObject implementation
2170 static HRESULT WINAPI ISVViewObject_QueryInterface(
2175 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2177 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2179 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2182 static ULONG WINAPI ISVViewObject_AddRef( IViewObject *iface)
2184 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2186 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2188 return IShellFolder_AddRef((IShellFolder*)This);
2191 static ULONG WINAPI ISVViewObject_Release( IViewObject *iface)
2193 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2195 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2197 return IShellFolder_Release((IShellFolder*)This);
2200 static HRESULT WINAPI ISVViewObject_Draw(
2205 DVTARGETDEVICE* ptd,
2208 LPCRECTL lprcBounds,
2209 LPCRECTL lprcWBounds,
2210 BOOL (CALLBACK *pfnContinue)(ULONG_PTR dwContinue),
2214 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2216 FIXME("Stub: This=%p\n",This);
2220 static HRESULT WINAPI ISVViewObject_GetColorSet(
2225 DVTARGETDEVICE* ptd,
2226 HDC hicTargetDevice,
2227 LOGPALETTE** ppColorSet)
2230 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2232 FIXME("Stub: This=%p\n",This);
2236 static HRESULT WINAPI ISVViewObject_Freeze(
2244 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2246 FIXME("Stub: This=%p\n",This);
2250 static HRESULT WINAPI ISVViewObject_Unfreeze(
2255 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2257 FIXME("Stub: This=%p\n",This);
2261 static HRESULT WINAPI ISVViewObject_SetAdvise(
2265 IAdviseSink* pAdvSink)
2268 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2270 FIXME("Stub: This=%p\n",This);
2274 static HRESULT WINAPI ISVViewObject_GetAdvise(
2278 IAdviseSink** ppAdvSink)
2281 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2283 FIXME("Stub: This=%p\n",This);
2289 static struct ICOM_VTABLE(IViewObject) vovt =
2291 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2292 ISVViewObject_QueryInterface,
2293 ISVViewObject_AddRef,
2294 ISVViewObject_Release,
2296 ISVViewObject_GetColorSet,
2297 ISVViewObject_Freeze,
2298 ISVViewObject_Unfreeze,
2299 ISVViewObject_SetAdvise,
2300 ISVViewObject_GetAdvise