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, TBSTYLE_BUTTON },
153 { FCIDM_SHVIEW_SMALLICON, 0, 0, IDS_VIEW_SMALL, TBSTATE_ENABLED, TBSTYLE_BUTTON },
154 { FCIDM_SHVIEW_LISTVIEW, 0, 0, IDS_VIEW_LIST, TBSTATE_ENABLED, TBSTYLE_BUTTON },
155 { FCIDM_SHVIEW_REPORTVIEW, 0, 0, IDS_VIEW_DETAILS, TBSTATE_ENABLED, TBSTYLE_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 = FALSE;
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(TBSTYLE_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( 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 ListView_GetItemA(This->hWndList, &item);
1368 pItems[i] = (LPITEMIDLIST)item.lParam;
1373 /* perform the item deletion */
1374 ISFHelper_DeleteItems(psfhlp, i, (LPCITEMIDLIST*)pItems);
1376 /* free pidl array memory */
1377 HeapFree(GetProcessHeap(), 0, pItems);
1380 FIXME("LVN_KEYDOWN key=0x%08x\n",plvKeyDown->wVKey);
1385 FIXME("-- %p WM_COMMAND %x unhandled\n", This, lpnmh->code);
1391 /**********************************************************
1392 * ShellView_OnChange()
1395 static LRESULT ShellView_OnChange(IShellViewImpl * This, LPITEMIDLIST * Pidls, LONG wEventId)
1398 TRACE("(%p)(%p,%p,0x%08lx)\n", This, Pidls[0], Pidls[1], wEventId);
1403 LV_AddItem(This, Pidls[0]);
1407 LV_DeleteItem(This, Pidls[0]);
1409 case SHCNE_RENAMEFOLDER:
1410 case SHCNE_RENAMEITEM:
1411 LV_RenameItem(This, Pidls[0], Pidls[1]);
1413 case SHCNE_UPDATEITEM:
1418 /**********************************************************
1422 static LRESULT CALLBACK ShellView_WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
1424 IShellViewImpl * pThis = (IShellViewImpl*)GetWindowLongA(hWnd, GWL_USERDATA);
1425 LPCREATESTRUCTA lpcs;
1427 TRACE("(hwnd=%p msg=%x wparm=%x lparm=%lx)\n",hWnd, uMessage, wParam, lParam);
1432 lpcs = (LPCREATESTRUCTA)lParam;
1433 pThis = (IShellViewImpl*)(lpcs->lpCreateParams);
1434 SetWindowLongA(hWnd, GWL_USERDATA, (LONG)pThis);
1435 pThis->hWnd = hWnd; /*set the window handle*/
1438 case WM_SIZE: return ShellView_OnSize(pThis,LOWORD(lParam), HIWORD(lParam));
1439 case WM_SETFOCUS: return ShellView_OnSetFocus(pThis);
1440 case WM_KILLFOCUS: return ShellView_OnKillFocus(pThis);
1441 case WM_CREATE: return ShellView_OnCreate(pThis);
1442 case WM_ACTIVATE: return ShellView_OnActivate(pThis, SVUIA_ACTIVATE_FOCUS);
1443 case WM_NOTIFY: return ShellView_OnNotify(pThis,(UINT)wParam, (LPNMHDR)lParam);
1444 case WM_COMMAND: return ShellView_OnCommand(pThis,
1445 GET_WM_COMMAND_ID(wParam, lParam),
1446 GET_WM_COMMAND_CMD(wParam, lParam),
1447 GET_WM_COMMAND_HWND(wParam, lParam));
1448 case SHV_CHANGE_NOTIFY: return ShellView_OnChange(pThis, (LPITEMIDLIST*)wParam, (LONG)lParam);
1450 case WM_CONTEXTMENU: ShellView_DoContextMenu(pThis, LOWORD(lParam), HIWORD(lParam), FALSE);
1453 case WM_SHOWWINDOW: UpdateWindow(pThis->hWndList);
1456 case WM_GETDLGCODE: return SendMessageA(pThis->hWndList,uMessage,0,0);
1458 case WM_DESTROY: if(GetShellOle() && pRevokeDragDrop)
1460 pRevokeDragDrop(pThis->hWnd);
1462 SHChangeNotifyDeregister(pThis->hNotify);
1466 if ((pThis->FolderSettings.fFlags & FWF_DESKTOP) ||
1467 (pThis->FolderSettings.fFlags & FWF_TRANSPARENT))
1472 return DefWindowProcA (hWnd, uMessage, wParam, lParam);
1474 /**********************************************************
1477 * The INTERFACE of the IShellView object
1480 **********************************************************
1481 * IShellView_QueryInterface
1483 static HRESULT WINAPI IShellView_fnQueryInterface(IShellView * iface,REFIID riid, LPVOID *ppvObj)
1485 ICOM_THIS(IShellViewImpl, iface);
1487 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
1491 if(IsEqualIID(riid, &IID_IUnknown))
1495 else if(IsEqualIID(riid, &IID_IShellView))
1497 *ppvObj = (IShellView*)This;
1499 else if(IsEqualIID(riid, &IID_IOleCommandTarget))
1501 *ppvObj = (IOleCommandTarget*)&(This->lpvtblOleCommandTarget);
1503 else if(IsEqualIID(riid, &IID_IDropTarget))
1505 *ppvObj = (IDropTarget*)&(This->lpvtblDropTarget);
1507 else if(IsEqualIID(riid, &IID_IDropSource))
1509 *ppvObj = (IDropSource*)&(This->lpvtblDropSource);
1511 else if(IsEqualIID(riid, &IID_IViewObject))
1513 *ppvObj = (IViewObject*)&(This->lpvtblViewObject);
1518 IUnknown_AddRef( (IUnknown*)*ppvObj );
1519 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
1522 TRACE("-- Interface: E_NOINTERFACE\n");
1523 return E_NOINTERFACE;
1526 /**********************************************************
1529 static ULONG WINAPI IShellView_fnAddRef(IShellView * iface)
1531 ICOM_THIS(IShellViewImpl, iface);
1533 TRACE("(%p)->(count=%lu)\n",This,This->ref);
1535 return ++(This->ref);
1537 /**********************************************************
1538 * IShellView_Release
1540 static ULONG WINAPI IShellView_fnRelease(IShellView * iface)
1542 ICOM_THIS(IShellViewImpl, iface);
1544 TRACE("(%p)->()\n",This);
1548 TRACE(" destroying IShellView(%p)\n",This);
1551 IShellFolder_Release(This->pSFParent);
1553 if(This->pSF2Parent)
1554 IShellFolder2_Release(This->pSF2Parent);
1557 SHFree(This->apidl);
1559 HeapFree(GetProcessHeap(),0,This);
1565 /**********************************************************
1566 * ShellView_GetWindow
1568 static HRESULT WINAPI IShellView_fnGetWindow(IShellView * iface,HWND * phWnd)
1570 ICOM_THIS(IShellViewImpl, iface);
1572 TRACE("(%p)\n",This);
1574 *phWnd = This->hWnd;
1579 static HRESULT WINAPI IShellView_fnContextSensitiveHelp(IShellView * iface,BOOL fEnterMode)
1581 ICOM_THIS(IShellViewImpl, iface);
1583 FIXME("(%p) stub\n",This);
1588 /**********************************************************
1589 * IShellView_TranslateAccelerator
1592 * use the accel functions
1594 static HRESULT WINAPI IShellView_fnTranslateAccelerator(IShellView * iface,LPMSG lpmsg)
1597 ICOM_THIS(IShellViewImpl, iface);
1599 FIXME("(%p)->(%p: hwnd=%x msg=%x lp=%lx wp=%x) stub\n",This,lpmsg, lpmsg->hwnd, lpmsg->message, lpmsg->lParam, lpmsg->wParam);
1602 if ((lpmsg->message>=WM_KEYFIRST) && (lpmsg->message>=WM_KEYLAST))
1604 TRACE("-- key=0x04%x\n",lpmsg->wParam) ;
1606 return S_FALSE; /* not handled */
1609 static HRESULT WINAPI IShellView_fnEnableModeless(IShellView * iface,BOOL fEnable)
1611 ICOM_THIS(IShellViewImpl, iface);
1613 FIXME("(%p) stub\n",This);
1618 static HRESULT WINAPI IShellView_fnUIActivate(IShellView * iface,UINT uState)
1620 ICOM_THIS(IShellViewImpl, iface);
1623 CHAR szName[MAX_PATH];
1626 int nPartArray[1] = {-1};
1628 TRACE("(%p)->(state=%x) stub\n",This, uState);
1630 /*don't do anything if the state isn't really changing*/
1631 if(This->uState == uState)
1636 /*OnActivate handles the menu merging and internal state*/
1637 ShellView_OnActivate(This, uState);
1639 /*only do This if we are active*/
1640 if(uState != SVUIA_DEACTIVATE)
1644 GetFolderPath is not a method of IShellFolder
1645 IShellFolder_GetFolderPath( This->pSFParent, szName, sizeof(szName) );
1647 /* set the number of parts */
1648 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETPARTS, 1,
1649 (LPARAM)nPartArray, &lResult);
1651 /* set the text for the parts */
1653 IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETTEXTA,
1654 0, (LPARAM)szName, &lResult);
1661 static HRESULT WINAPI IShellView_fnRefresh(IShellView * iface)
1663 ICOM_THIS(IShellViewImpl, iface);
1665 TRACE("(%p)\n",This);
1667 ListView_DeleteAllItems(This->hWndList);
1668 ShellView_FillList(This);
1673 static HRESULT WINAPI IShellView_fnCreateViewWindow(
1675 IShellView *lpPrevView,
1676 LPCFOLDERSETTINGS lpfs,
1677 IShellBrowser * psb,
1681 ICOM_THIS(IShellViewImpl, iface);
1687 TRACE("(%p)->(shlview=%p set=%p shlbrs=%p rec=%p hwnd=%p) incomplete\n",This, lpPrevView,lpfs, psb, prcView, phWnd);
1688 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);
1690 /*set up the member variables*/
1691 This->pShellBrowser = psb;
1692 This->FolderSettings = *lpfs;
1694 /*get our parent window*/
1695 IShellBrowser_AddRef(This->pShellBrowser);
1696 IShellBrowser_GetWindow(This->pShellBrowser, &(This->hWndParent));
1698 /* try to get the ICommDlgBrowserInterface, adds a reference !!! */
1699 This->pCommDlgBrowser=NULL;
1700 if ( SUCCEEDED (IShellBrowser_QueryInterface( This->pShellBrowser,
1701 (REFIID)&IID_ICommDlgBrowser, (LPVOID*) &This->pCommDlgBrowser)))
1703 TRACE("-- CommDlgBrowser\n");
1706 /*if our window class has not been registered, then do so*/
1707 if(!GetClassInfoA(shell32_hInstance, SV_CLASS_NAME, &wc))
1709 ZeroMemory(&wc, sizeof(wc));
1710 wc.style = CS_HREDRAW | CS_VREDRAW;
1711 wc.lpfnWndProc = (WNDPROC) ShellView_WndProc;
1714 wc.hInstance = shell32_hInstance;
1716 wc.hCursor = LoadCursorA (0, (LPSTR)IDC_ARROW);
1717 wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
1718 wc.lpszMenuName = NULL;
1719 wc.lpszClassName = SV_CLASS_NAME;
1721 if(!RegisterClassA(&wc))
1725 *phWnd = CreateWindowExA(0,
1728 WS_CHILD | WS_VISIBLE | WS_TABSTOP,
1731 prcView->right - prcView->left,
1732 prcView->bottom - prcView->top,
1740 if(!*phWnd) return E_FAIL;
1745 static HRESULT WINAPI IShellView_fnDestroyViewWindow(IShellView * iface)
1747 ICOM_THIS(IShellViewImpl, iface);
1749 TRACE("(%p)\n",This);
1751 /*Make absolutely sure all our UI is cleaned up.*/
1752 IShellView_UIActivate((IShellView*)This, SVUIA_DEACTIVATE);
1756 DestroyMenu(This->hMenu);
1759 DestroyWindow(This->hWnd);
1760 if(This->pShellBrowser) IShellBrowser_Release(This->pShellBrowser);
1761 if(This->pCommDlgBrowser) ICommDlgBrowser_Release(This->pCommDlgBrowser);
1767 static HRESULT WINAPI IShellView_fnGetCurrentInfo(IShellView * iface, LPFOLDERSETTINGS lpfs)
1769 ICOM_THIS(IShellViewImpl, iface);
1771 TRACE("(%p)->(%p) vmode=%x flags=%x\n",This, lpfs,
1772 This->FolderSettings.ViewMode, This->FolderSettings.fFlags);
1774 if (!lpfs) return E_INVALIDARG;
1776 *lpfs = This->FolderSettings;
1780 static HRESULT WINAPI IShellView_fnAddPropertySheetPages(IShellView * iface, DWORD dwReserved,LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam)
1782 ICOM_THIS(IShellViewImpl, iface);
1784 FIXME("(%p) stub\n",This);
1789 static HRESULT WINAPI IShellView_fnSaveViewState(IShellView * iface)
1791 ICOM_THIS(IShellViewImpl, iface);
1793 FIXME("(%p) stub\n",This);
1798 static HRESULT WINAPI IShellView_fnSelectItem(
1803 ICOM_THIS(IShellViewImpl, iface);
1806 TRACE("(%p)->(pidl=%p, 0x%08x) stub\n",This, pidl, uFlags);
1808 i = LV_FindItemByPidl(This, pidl);
1814 if(uFlags & SVSI_ENSUREVISIBLE)
1815 ListView_EnsureVisible(This->hWndList, i, 0);
1817 ZeroMemory(&lvItem, sizeof(LVITEMA));
1818 lvItem.mask = LVIF_STATE;
1821 while(ListView_GetItemA(This->hWndList, &lvItem))
1823 if (lvItem.iItem == i)
1825 if (uFlags & SVSI_SELECT)
1826 lvItem.state |= LVIS_SELECTED;
1828 lvItem.state &= ~LVIS_SELECTED;
1830 if(uFlags & SVSI_FOCUSED)
1831 lvItem.state &= ~LVIS_FOCUSED;
1835 if (uFlags & SVSI_DESELECTOTHERS)
1836 lvItem.state &= ~LVIS_SELECTED;
1838 ListView_SetItemA(This->hWndList, &lvItem);
1843 if(uFlags & SVSI_EDIT)
1844 ListView_EditLabelA(This->hWndList, i);
1850 static HRESULT WINAPI IShellView_fnGetItemObject(IShellView * iface, UINT uItem, REFIID riid, LPVOID *ppvOut)
1852 ICOM_THIS(IShellViewImpl, iface);
1854 TRACE("(%p)->(uItem=0x%08x,\n\tIID=%s, ppv=%p)\n",This, uItem, debugstr_guid(riid), ppvOut);
1860 case SVGIO_BACKGROUND:
1861 *ppvOut = ISvBgCm_Constructor(This->pSFParent);
1864 case SVGIO_SELECTION:
1865 ShellView_GetSelections(This);
1866 IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, (LPCITEMIDLIST*)This->apidl, riid, 0, ppvOut);
1869 TRACE("-- (%p)->(interface=%p)\n",This, *ppvOut);
1871 if(!*ppvOut) return E_OUTOFMEMORY;
1876 static struct ICOM_VTABLE(IShellView) svvt =
1878 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1879 IShellView_fnQueryInterface,
1880 IShellView_fnAddRef,
1881 IShellView_fnRelease,
1882 IShellView_fnGetWindow,
1883 IShellView_fnContextSensitiveHelp,
1884 IShellView_fnTranslateAccelerator,
1885 IShellView_fnEnableModeless,
1886 IShellView_fnUIActivate,
1887 IShellView_fnRefresh,
1888 IShellView_fnCreateViewWindow,
1889 IShellView_fnDestroyViewWindow,
1890 IShellView_fnGetCurrentInfo,
1891 IShellView_fnAddPropertySheetPages,
1892 IShellView_fnSaveViewState,
1893 IShellView_fnSelectItem,
1894 IShellView_fnGetItemObject
1898 /**********************************************************
1899 * ISVOleCmdTarget_QueryInterface (IUnknown)
1901 static HRESULT WINAPI ISVOleCmdTarget_QueryInterface(
1902 IOleCommandTarget * iface,
1906 _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
1908 return IShellFolder_QueryInterface((IShellFolder*)This, iid, ppvObj);
1911 /**********************************************************
1912 * ISVOleCmdTarget_AddRef (IUnknown)
1914 static ULONG WINAPI ISVOleCmdTarget_AddRef(
1915 IOleCommandTarget * iface)
1917 _ICOM_THIS_From_IOleCommandTarget(IShellFolder, iface);
1919 return IShellFolder_AddRef((IShellFolder*)This);
1922 /**********************************************************
1923 * ISVOleCmdTarget_Release (IUnknown)
1925 static ULONG WINAPI ISVOleCmdTarget_Release(
1926 IOleCommandTarget * iface)
1928 _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
1930 return IShellFolder_Release((IShellFolder*)This);
1933 /**********************************************************
1934 * ISVOleCmdTarget_QueryStatus (IOleCommandTarget)
1936 static HRESULT WINAPI ISVOleCmdTarget_QueryStatus(
1937 IOleCommandTarget *iface,
1938 const GUID* pguidCmdGroup,
1941 OLECMDTEXT* pCmdText)
1944 _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
1946 FIXME("(%p)->(%p(%s) 0x%08lx %p %p\n",
1947 This, pguidCmdGroup, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText);
1951 for (i = 0; i < cCmds; i++)
1953 FIXME("\tprgCmds[%d].cmdID = %ld\n", i, prgCmds[i].cmdID);
1954 prgCmds[i].cmdf = 0;
1956 return OLECMDERR_E_UNKNOWNGROUP;
1959 /**********************************************************
1960 * ISVOleCmdTarget_Exec (IOleCommandTarget)
1962 * nCmdID is the OLECMDID_* enumeration
1964 static HRESULT WINAPI ISVOleCmdTarget_Exec(
1965 IOleCommandTarget *iface,
1966 const GUID* pguidCmdGroup,
1972 _ICOM_THIS_From_IOleCommandTarget(IShellViewImpl, iface);
1974 FIXME("(%p)->(\n\tTarget GUID:%s Command:0x%08lx Opt:0x%08lx %p %p)\n",
1975 This, debugstr_guid(pguidCmdGroup), nCmdID, nCmdexecopt, pvaIn, pvaOut);
1977 if (IsEqualIID(pguidCmdGroup, &CGID_Explorer) &&
1979 (nCmdexecopt == 4) && pvaOut)
1981 if (IsEqualIID(pguidCmdGroup, &CGID_ShellDocView) &&
1986 return OLECMDERR_E_UNKNOWNGROUP;
1989 static ICOM_VTABLE(IOleCommandTarget) ctvt =
1991 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1992 ISVOleCmdTarget_QueryInterface,
1993 ISVOleCmdTarget_AddRef,
1994 ISVOleCmdTarget_Release,
1995 ISVOleCmdTarget_QueryStatus,
1996 ISVOleCmdTarget_Exec
1999 /**********************************************************
2000 * ISVDropTarget implementation
2003 static HRESULT WINAPI ISVDropTarget_QueryInterface(
2008 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2010 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2012 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2015 static ULONG WINAPI ISVDropTarget_AddRef( IDropTarget *iface)
2017 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2019 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2021 return IShellFolder_AddRef((IShellFolder*)This);
2024 static ULONG WINAPI ISVDropTarget_Release( IDropTarget *iface)
2026 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2028 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2030 return IShellFolder_Release((IShellFolder*)This);
2033 static HRESULT WINAPI ISVDropTarget_DragEnter(
2035 IDataObject *pDataObject,
2041 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2043 FIXME("Stub: This=%p, DataObject=%p\n",This,pDataObject);
2048 static HRESULT WINAPI ISVDropTarget_DragOver(
2054 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2056 FIXME("Stub: This=%p\n",This);
2061 static HRESULT WINAPI ISVDropTarget_DragLeave(
2064 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2066 FIXME("Stub: This=%p\n",This);
2071 static HRESULT WINAPI ISVDropTarget_Drop(
2073 IDataObject* pDataObject,
2078 _ICOM_THIS_From_IDropTarget(IShellViewImpl, iface);
2080 FIXME("Stub: This=%p\n",This);
2085 static struct ICOM_VTABLE(IDropTarget) dtvt =
2087 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2088 ISVDropTarget_QueryInterface,
2089 ISVDropTarget_AddRef,
2090 ISVDropTarget_Release,
2091 ISVDropTarget_DragEnter,
2092 ISVDropTarget_DragOver,
2093 ISVDropTarget_DragLeave,
2097 /**********************************************************
2098 * ISVDropSource implementation
2101 static HRESULT WINAPI ISVDropSource_QueryInterface(
2106 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2108 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2110 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2113 static ULONG WINAPI ISVDropSource_AddRef( IDropSource *iface)
2115 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2117 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2119 return IShellFolder_AddRef((IShellFolder*)This);
2122 static ULONG WINAPI ISVDropSource_Release( IDropSource *iface)
2124 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2126 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2128 return IShellFolder_Release((IShellFolder*)This);
2130 static HRESULT WINAPI ISVDropSource_QueryContinueDrag(
2132 BOOL fEscapePressed,
2135 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2136 TRACE("(%p)\n",This);
2139 return DRAGDROP_S_CANCEL;
2140 else if (!(grfKeyState & MK_LBUTTON) && !(grfKeyState & MK_RBUTTON))
2141 return DRAGDROP_S_DROP;
2146 static HRESULT WINAPI ISVDropSource_GiveFeedback(
2150 _ICOM_THIS_From_IDropSource(IShellViewImpl, iface);
2151 TRACE("(%p)\n",This);
2153 return DRAGDROP_S_USEDEFAULTCURSORS;
2156 static struct ICOM_VTABLE(IDropSource) dsvt =
2158 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2159 ISVDropSource_QueryInterface,
2160 ISVDropSource_AddRef,
2161 ISVDropSource_Release,
2162 ISVDropSource_QueryContinueDrag,
2163 ISVDropSource_GiveFeedback
2165 /**********************************************************
2166 * ISVViewObject implementation
2169 static HRESULT WINAPI ISVViewObject_QueryInterface(
2174 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2176 TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
2178 return IShellFolder_QueryInterface((IShellFolder*)This, riid, ppvObj);
2181 static ULONG WINAPI ISVViewObject_AddRef( IViewObject *iface)
2183 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2185 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2187 return IShellFolder_AddRef((IShellFolder*)This);
2190 static ULONG WINAPI ISVViewObject_Release( IViewObject *iface)
2192 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2194 TRACE("(%p)->(count=%lu)\n",This,This->ref);
2196 return IShellFolder_Release((IShellFolder*)This);
2199 static HRESULT WINAPI ISVViewObject_Draw(
2204 DVTARGETDEVICE* ptd,
2207 LPCRECTL lprcBounds,
2208 LPCRECTL lprcWBounds,
2209 BOOL (CALLBACK *pfnContinue)(ULONG_PTR dwContinue),
2213 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2215 FIXME("Stub: This=%p\n",This);
2219 static HRESULT WINAPI ISVViewObject_GetColorSet(
2224 DVTARGETDEVICE* ptd,
2225 HDC hicTargetDevice,
2226 LOGPALETTE** ppColorSet)
2229 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2231 FIXME("Stub: This=%p\n",This);
2235 static HRESULT WINAPI ISVViewObject_Freeze(
2243 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2245 FIXME("Stub: This=%p\n",This);
2249 static HRESULT WINAPI ISVViewObject_Unfreeze(
2254 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2256 FIXME("Stub: This=%p\n",This);
2260 static HRESULT WINAPI ISVViewObject_SetAdvise(
2264 IAdviseSink* pAdvSink)
2267 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2269 FIXME("Stub: This=%p\n",This);
2273 static HRESULT WINAPI ISVViewObject_GetAdvise(
2277 IAdviseSink** ppAdvSink)
2280 _ICOM_THIS_From_IViewObject(IShellViewImpl, iface);
2282 FIXME("Stub: This=%p\n",This);
2288 static struct ICOM_VTABLE(IViewObject) vovt =
2290 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2291 ISVViewObject_QueryInterface,
2292 ISVViewObject_AddRef,
2293 ISVViewObject_Release,
2295 ISVViewObject_GetColorSet,
2296 ISVViewObject_Freeze,
2297 ISVViewObject_Unfreeze,
2298 ISVViewObject_SetAdvise,
2299 ISVViewObject_GetAdvise