| /* | |
| * ShellView | |
| * | |
| * Copyright 1998,1999 <juergen.schmied@debitel.net> | |
| * | |
| * This is the view visualizing the data provided by the shellfolder. | |
| * No direct access to data from pidls should be done from here. | |
| * | |
| * This library is free software; you can redistribute it and/or | |
| * modify it under the terms of the GNU Lesser General Public | |
| * License as published by the Free Software Foundation; either | |
| * version 2.1 of the License, or (at your option) any later version. | |
| * | |
| * This library is distributed in the hope that it will be useful, | |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| * Lesser General Public License for more details. | |
| * | |
| * You should have received a copy of the GNU Lesser General Public | |
| * License along with this library; if not, write to the Free Software | |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA | |
| * | |
| * FIXME: The order by part of the background context menu should be | |
| * built according to the columns shown. | |
| * | |
| * FIXME: Load/Save the view state from/into the stream provided by | |
| * the ShellBrowser | |
| * | |
| * FIXME: CheckToolbar: handle the "new folder" and "folder up" button | |
| * | |
| * FIXME: ShellView_FillList: consider sort orders | |
| * | |
| * FIXME: implement the drag and drop in the old (msg-based) way | |
| * | |
| * FIXME: when the ShellView_WndProc gets a WM_NCDESTROY should we do a | |
| * Release() ??? | |
| */ | |
| #include "config.h" | |
| #include "wine/port.h" | |
| #include <stdarg.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| #define CINTERFACE | |
| #define COBJMACROS | |
| #define NONAMELESSUNION | |
| #include "windef.h" | |
| #include "winerror.h" | |
| #include "winbase.h" | |
| #include "winnls.h" | |
| #include "objbase.h" | |
| #include "servprov.h" | |
| #include "shlguid.h" | |
| #include "wingdi.h" | |
| #include "winuser.h" | |
| #include "shlobj.h" | |
| #include "shobjidl.h" | |
| #include "undocshell.h" | |
| #include "shresdef.h" | |
| #include "wine/debug.h" | |
| #include "docobj.h" | |
| #include "pidl.h" | |
| #include "shell32_main.h" | |
| #include "shellfolder.h" | |
| WINE_DEFAULT_DEBUG_CHANNEL(shell); | |
| static const WCHAR SV_CLASS_NAME[] = {'S','H','E','L','L','D','L','L','_','D','e','f','V','i','e','w',0}; | |
| typedef struct | |
| { BOOL bIsAscending; | |
| INT nHeaderID; | |
| INT nLastHeaderID; | |
| }LISTVIEW_SORT_INFO, *LPLISTVIEW_SORT_INFO; | |
| typedef struct | |
| { | |
| IShellView3 IShellView3_iface; | |
| IOleCommandTarget IOleCommandTarget_iface; | |
| IDropTarget IDropTarget_iface; | |
| IDropSource IDropSource_iface; | |
| IViewObject IViewObject_iface; | |
| IFolderView2 IFolderView2_iface; | |
| IShellFolderView IShellFolderView_iface; | |
| IShellFolderViewDual3 IShellFolderViewDual3_iface; | |
| LONG ref; | |
| IShellFolder* pSFParent; | |
| IShellFolder2* pSF2Parent; | |
| IShellBrowser* pShellBrowser; | |
| ICommDlgBrowser* pCommDlgBrowser; | |
| HWND hWnd; /* SHELLDLL_DefView */ | |
| HWND hWndList; /* ListView control */ | |
| HWND hWndParent; | |
| FOLDERSETTINGS FolderSettings; | |
| HMENU hMenu; | |
| UINT uState; | |
| UINT cidl; | |
| LPITEMIDLIST *apidl; | |
| LISTVIEW_SORT_INFO ListViewSortInfo; | |
| ULONG hNotify; /* change notification handle */ | |
| HANDLE hAccel; | |
| DWORD dwAspects; | |
| DWORD dwAdvf; | |
| IAdviseSink *pAdvSink; | |
| IDropTarget* pCurDropTarget; /* The sub-item, which is currently dragged over */ | |
| IDataObject* pCurDataObject; /* The dragged data-object */ | |
| LONG iDragOverItem; /* Dragged over item's index, iff pCurDropTarget != NULL */ | |
| UINT cScrollDelay; /* Send a WM_*SCROLL msg every 250 ms during drag-scroll */ | |
| POINT ptLastMousePos; /* Mouse position at last DragOver call */ | |
| UINT columns; /* Number of shell folder columns */ | |
| } IShellViewImpl; | |
| static inline IShellViewImpl *impl_from_IShellView3(IShellView3 *iface) | |
| { | |
| return CONTAINING_RECORD(iface, IShellViewImpl, IShellView3_iface); | |
| } | |
| static inline IShellViewImpl *impl_from_IOleCommandTarget(IOleCommandTarget *iface) | |
| { | |
| return CONTAINING_RECORD(iface, IShellViewImpl, IOleCommandTarget_iface); | |
| } | |
| static inline IShellViewImpl *impl_from_IDropTarget(IDropTarget *iface) | |
| { | |
| return CONTAINING_RECORD(iface, IShellViewImpl, IDropTarget_iface); | |
| } | |
| static inline IShellViewImpl *impl_from_IDropSource(IDropSource *iface) | |
| { | |
| return CONTAINING_RECORD(iface, IShellViewImpl, IDropSource_iface); | |
| } | |
| static inline IShellViewImpl *impl_from_IViewObject(IViewObject *iface) | |
| { | |
| return CONTAINING_RECORD(iface, IShellViewImpl, IViewObject_iface); | |
| } | |
| static inline IShellViewImpl *impl_from_IFolderView2(IFolderView2 *iface) | |
| { | |
| return CONTAINING_RECORD(iface, IShellViewImpl, IFolderView2_iface); | |
| } | |
| static inline IShellViewImpl *impl_from_IShellFolderView(IShellFolderView *iface) | |
| { | |
| return CONTAINING_RECORD(iface, IShellViewImpl, IShellFolderView_iface); | |
| } | |
| static inline IShellViewImpl *impl_from_IShellFolderViewDual3(IShellFolderViewDual3 *iface) | |
| { | |
| return CONTAINING_RECORD(iface, IShellViewImpl, IShellFolderViewDual3_iface); | |
| } | |
| /* ListView Header IDs */ | |
| #define LISTVIEW_COLUMN_NAME 0 | |
| #define LISTVIEW_COLUMN_SIZE 1 | |
| #define LISTVIEW_COLUMN_TYPE 2 | |
| #define LISTVIEW_COLUMN_TIME 3 | |
| #define LISTVIEW_COLUMN_ATTRIB 4 | |
| /*menu items */ | |
| #define IDM_VIEW_FILES (FCIDM_SHVIEWFIRST + 0x500) | |
| #define IDM_VIEW_IDW (FCIDM_SHVIEWFIRST + 0x501) | |
| #define IDM_MYFILEITEM (FCIDM_SHVIEWFIRST + 0x502) | |
| #define ID_LISTVIEW 1 | |
| #define SHV_CHANGE_NOTIFY WM_USER + 0x1111 | |
| /*windowsx.h */ | |
| #define GET_WM_COMMAND_ID(wp, lp) LOWORD(wp) | |
| #define GET_WM_COMMAND_HWND(wp, lp) (HWND)(lp) | |
| #define GET_WM_COMMAND_CMD(wp, lp) HIWORD(wp) | |
| /* | |
| Items merged into the toolbar and the filemenu | |
| */ | |
| typedef struct | |
| { int idCommand; | |
| int iImage; | |
| int idButtonString; | |
| int idMenuString; | |
| BYTE bState; | |
| BYTE bStyle; | |
| } MYTOOLINFO, *LPMYTOOLINFO; | |
| static const MYTOOLINFO Tools[] = | |
| { | |
| { FCIDM_SHVIEW_BIGICON, 0, 0, IDS_VIEW_LARGE, TBSTATE_ENABLED, BTNS_BUTTON }, | |
| { FCIDM_SHVIEW_SMALLICON, 0, 0, IDS_VIEW_SMALL, TBSTATE_ENABLED, BTNS_BUTTON }, | |
| { FCIDM_SHVIEW_LISTVIEW, 0, 0, IDS_VIEW_LIST, TBSTATE_ENABLED, BTNS_BUTTON }, | |
| { FCIDM_SHVIEW_REPORTVIEW, 0, 0, IDS_VIEW_DETAILS, TBSTATE_ENABLED, BTNS_BUTTON }, | |
| { -1, 0, 0, 0, 0, 0} | |
| }; | |
| typedef void (CALLBACK *PFNSHGETSETTINGSPROC)(LPSHELLFLAGSTATE lpsfs, DWORD dwMask); | |
| /********************************************************** | |
| * | |
| * ##### helperfunctions for communication with ICommDlgBrowser ##### | |
| */ | |
| static BOOL IsInCommDlg(IShellViewImpl * This) | |
| { | |
| return This->pCommDlgBrowser != NULL; | |
| } | |
| static HRESULT IncludeObject(IShellViewImpl * This, LPCITEMIDLIST pidl) | |
| { | |
| HRESULT ret = S_OK; | |
| if (IsInCommDlg(This)) | |
| { | |
| TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl); | |
| ret = ICommDlgBrowser_IncludeObject(This->pCommDlgBrowser, (IShellView *)&This->IShellView3_iface, pidl); | |
| TRACE("-- returns 0x%08x\n", ret); | |
| } | |
| return ret; | |
| } | |
| static HRESULT OnDefaultCommand(IShellViewImpl * This) | |
| { | |
| HRESULT ret = S_FALSE; | |
| if (IsInCommDlg(This)) | |
| { | |
| TRACE("ICommDlgBrowser::OnDefaultCommand\n"); | |
| ret = ICommDlgBrowser_OnDefaultCommand(This->pCommDlgBrowser, (IShellView *)&This->IShellView3_iface); | |
| TRACE("-- returns 0x%08x\n", ret); | |
| } | |
| return ret; | |
| } | |
| static HRESULT OnStateChange(IShellViewImpl * This, UINT change) | |
| { | |
| HRESULT ret = S_FALSE; | |
| if (IsInCommDlg(This)) | |
| { | |
| TRACE("ICommDlgBrowser::OnStateChange change=%d\n", change); | |
| ret = ICommDlgBrowser_OnStateChange(This->pCommDlgBrowser, (IShellView *)&This->IShellView3_iface, change); | |
| TRACE("-- returns 0x%08x\n", ret); | |
| } | |
| return ret; | |
| } | |
| /********************************************************** | |
| * set the toolbar of the filedialog buttons | |
| * | |
| * - activates the buttons from the shellbrowser according to | |
| * the view state | |
| */ | |
| static void CheckToolbar(IShellViewImpl * This) | |
| { | |
| LRESULT result; | |
| TRACE("\n"); | |
| if (IsInCommDlg(This)) | |
| { | |
| IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON, | |
| FCIDM_TB_SMALLICON, This->FolderSettings.ViewMode == FVM_LIST, &result); | |
| IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_CHECKBUTTON, | |
| FCIDM_TB_REPORTVIEW, This->FolderSettings.ViewMode == FVM_DETAILS, &result); | |
| IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON, | |
| FCIDM_TB_SMALLICON, TRUE, &result); | |
| IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_TOOLBAR, TB_ENABLEBUTTON, | |
| FCIDM_TB_REPORTVIEW, TRUE, &result); | |
| } | |
| } | |
| /********************************************************** | |
| * | |
| * ##### helperfunctions for initializing the view ##### | |
| */ | |
| /********************************************************** | |
| * change the style of the listview control | |
| */ | |
| static void SetStyle(IShellViewImpl * This, DWORD dwAdd, DWORD dwRemove) | |
| { | |
| DWORD tmpstyle; | |
| TRACE("(%p)\n", This); | |
| tmpstyle = GetWindowLongW(This->hWndList, GWL_STYLE); | |
| SetWindowLongW(This->hWndList, GWL_STYLE, dwAdd | (tmpstyle & ~dwRemove)); | |
| } | |
| static DWORD ViewModeToListStyle(UINT ViewMode) | |
| { | |
| DWORD dwStyle; | |
| TRACE("%d\n", ViewMode); | |
| switch (ViewMode) | |
| { | |
| case FVM_ICON: dwStyle = LVS_ICON; break; | |
| case FVM_DETAILS: dwStyle = LVS_REPORT; break; | |
| case FVM_SMALLICON: dwStyle = LVS_SMALLICON; break; | |
| case FVM_LIST: dwStyle = LVS_LIST; break; | |
| default: | |
| { | |
| FIXME("ViewMode %d not implemented\n", ViewMode); | |
| dwStyle = LVS_LIST; | |
| break; | |
| } | |
| } | |
| return dwStyle; | |
| } | |
| /********************************************************** | |
| * ShellView_CreateList() | |
| * | |
| * - creates the list view window | |
| */ | |
| static BOOL ShellView_CreateList (IShellViewImpl * This) | |
| { DWORD dwStyle, dwExStyle; | |
| TRACE("%p\n",This); | |
| dwStyle = WS_TABSTOP | WS_VISIBLE | WS_CHILDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | | |
| LVS_SHAREIMAGELISTS | LVS_EDITLABELS | LVS_ALIGNLEFT | LVS_AUTOARRANGE; | |
| dwExStyle = WS_EX_CLIENTEDGE; | |
| dwStyle |= ViewModeToListStyle(This->FolderSettings.ViewMode); | |
| if (This->FolderSettings.fFlags & FWF_AUTOARRANGE) dwStyle |= LVS_AUTOARRANGE; | |
| if (This->FolderSettings.fFlags & FWF_DESKTOP) | |
| This->FolderSettings.fFlags |= FWF_NOCLIENTEDGE | FWF_NOSCROLL; | |
| if (This->FolderSettings.fFlags & FWF_SINGLESEL) dwStyle |= LVS_SINGLESEL; | |
| if (This->FolderSettings.fFlags & FWF_NOCLIENTEDGE) | |
| dwExStyle &= ~WS_EX_CLIENTEDGE; | |
| This->hWndList=CreateWindowExW( dwExStyle, | |
| WC_LISTVIEWW, | |
| NULL, | |
| dwStyle, | |
| 0,0,0,0, | |
| This->hWnd, | |
| (HMENU)ID_LISTVIEW, | |
| shell32_hInstance, | |
| NULL); | |
| if(!This->hWndList) | |
| return FALSE; | |
| This->ListViewSortInfo.bIsAscending = TRUE; | |
| This->ListViewSortInfo.nHeaderID = -1; | |
| This->ListViewSortInfo.nLastHeaderID = -1; | |
| if (This->FolderSettings.fFlags & FWF_DESKTOP) { | |
| /* | |
| * FIXME: look at the registry value | |
| * HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ListviewShadow | |
| * and activate drop shadows if necessary | |
| */ | |
| if (0) | |
| SendMessageW(This->hWndList, LVM_SETTEXTBKCOLOR, 0, CLR_NONE); | |
| else | |
| SendMessageW(This->hWndList, LVM_SETTEXTBKCOLOR, 0, GetSysColor(COLOR_DESKTOP)); | |
| SendMessageW(This->hWndList, LVM_SETTEXTCOLOR, 0, RGB(255,255,255)); | |
| } | |
| /* UpdateShellSettings(); */ | |
| return TRUE; | |
| } | |
| /********************************************************** | |
| * ShellView_InitList() | |
| * | |
| * - adds all needed columns to the shellview | |
| */ | |
| static void ShellView_InitList(IShellViewImpl *This) | |
| { | |
| IShellDetails *details = NULL; | |
| HIMAGELIST big_icons, small_icons; | |
| LVCOLUMNW lvColumn; | |
| SHELLDETAILS sd; | |
| WCHAR nameW[50]; | |
| HRESULT hr; | |
| TRACE("(%p)\n", This); | |
| Shell_GetImageLists( &big_icons, &small_icons ); | |
| SendMessageW(This->hWndList, LVM_DELETEALLITEMS, 0, 0); | |
| SendMessageW(This->hWndList, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)small_icons); | |
| SendMessageW(This->hWndList, LVM_SETIMAGELIST, LVSIL_NORMAL, (LPARAM)big_icons); | |
| lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT; | |
| lvColumn.pszText = nameW; | |
| if (!This->pSF2Parent) | |
| { | |
| hr = IShellFolder_QueryInterface(This->pSFParent, &IID_IShellDetails, (void**)&details); | |
| if (hr != S_OK) | |
| { | |
| WARN("IShellFolder2/IShellDetails not supported\n"); | |
| return; | |
| } | |
| } | |
| for (This->columns = 0;; This->columns++) | |
| { | |
| if (This->pSF2Parent) | |
| hr = IShellFolder2_GetDetailsOf(This->pSF2Parent, NULL, This->columns, &sd); | |
| else | |
| hr = IShellDetails_GetDetailsOf(details, NULL, This->columns, &sd); | |
| if (FAILED(hr)) break; | |
| lvColumn.fmt = sd.fmt; | |
| lvColumn.cx = sd.cxChar*8; /* chars->pixel */ | |
| StrRetToStrNW(nameW, sizeof(nameW)/sizeof(WCHAR), &sd.str, NULL); | |
| SendMessageW(This->hWndList, LVM_INSERTCOLUMNW, This->columns, (LPARAM)&lvColumn); | |
| } | |
| if (details) IShellDetails_Release(details); | |
| } | |
| /* LVM_SORTITEMS callback used when initially inserting items */ | |
| static INT CALLBACK ShellView_CompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lpData) | |
| { | |
| LPITEMIDLIST pidl1 = (LPITEMIDLIST)lParam1; | |
| LPITEMIDLIST pidl2 = (LPITEMIDLIST)lParam2; | |
| IShellFolder *folder = (IShellFolder *)lpData; | |
| int ret; | |
| TRACE("pidl1=%p, pidl2=%p, shellfolder=%p\n", pidl1, pidl2, folder); | |
| ret = (SHORT)HRESULT_CODE(IShellFolder_CompareIDs(folder, 0, pidl1, pidl2)); | |
| TRACE("ret=%i\n", ret); | |
| return ret; | |
| } | |
| /************************************************************************* | |
| * ShellView_ListViewCompareItems | |
| * | |
| * Compare Function for the Listview (FileOpen Dialog) | |
| * | |
| * PARAMS | |
| * lParam1 [I] the first ItemIdList to compare with | |
| * lParam2 [I] the second ItemIdList to compare with | |
| * lpData [I] The column ID for the header Ctrl to process | |
| * | |
| * RETURNS | |
| * A negative value if the first item should precede the second, | |
| * a positive value if the first item should follow the second, | |
| * or zero if the two items are equivalent | |
| * | |
| * NOTES | |
| * FIXME: function does what ShellView_CompareItems is supposed to do. | |
| * unify it and figure out how to use the undocumented first parameter | |
| * of IShellFolder_CompareIDs to do the job this function does and | |
| * move this code to IShellFolder. | |
| * make LISTVIEW_SORT_INFO obsolete | |
| * the way this function works is only usable if we had only | |
| * filesystemfolders (25/10/99 jsch) | |
| */ | |
| static INT CALLBACK ShellView_ListViewCompareItems(LPVOID lParam1, LPVOID lParam2, LPARAM lpData) | |
| { | |
| INT nDiff=0; | |
| FILETIME fd1, fd2; | |
| char strName1[MAX_PATH], strName2[MAX_PATH]; | |
| BOOL bIsFolder1, bIsFolder2,bIsBothFolder; | |
| LPITEMIDLIST pItemIdList1 = lParam1; | |
| LPITEMIDLIST pItemIdList2 = lParam2; | |
| LISTVIEW_SORT_INFO *pSortInfo = (LPLISTVIEW_SORT_INFO) lpData; | |
| bIsFolder1 = _ILIsFolder(pItemIdList1); | |
| bIsFolder2 = _ILIsFolder(pItemIdList2); | |
| bIsBothFolder = bIsFolder1 && bIsFolder2; | |
| /* When sorting between a File and a Folder, the Folder gets sorted first */ | |
| if( (bIsFolder1 || bIsFolder2) && !bIsBothFolder) | |
| { | |
| nDiff = bIsFolder1 ? -1 : 1; | |
| } | |
| else | |
| { | |
| /* Sort by Time: Folders or Files can be sorted */ | |
| if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TIME) | |
| { | |
| _ILGetFileDateTime(pItemIdList1, &fd1); | |
| _ILGetFileDateTime(pItemIdList2, &fd2); | |
| nDiff = CompareFileTime(&fd2, &fd1); | |
| } | |
| /* Sort by Attribute: Folder or Files can be sorted */ | |
| else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_ATTRIB) | |
| { | |
| _ILGetFileAttributes(pItemIdList1, strName1, MAX_PATH); | |
| _ILGetFileAttributes(pItemIdList2, strName2, MAX_PATH); | |
| nDiff = lstrcmpiA(strName1, strName2); | |
| } | |
| /* Sort by FileName: Folder or Files can be sorted */ | |
| else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_NAME || bIsBothFolder) | |
| { | |
| /* Sort by Text */ | |
| _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH); | |
| _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH); | |
| nDiff = lstrcmpiA(strName1, strName2); | |
| } | |
| /* Sort by File Size, Only valid for Files */ | |
| else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_SIZE) | |
| { | |
| nDiff = (INT)(_ILGetFileSize(pItemIdList1, NULL, 0) - _ILGetFileSize(pItemIdList2, NULL, 0)); | |
| } | |
| /* Sort by File Type, Only valid for Files */ | |
| else if(pSortInfo->nHeaderID == LISTVIEW_COLUMN_TYPE) | |
| { | |
| /* Sort by Type */ | |
| _ILGetFileType(pItemIdList1, strName1, MAX_PATH); | |
| _ILGetFileType(pItemIdList2, strName2, MAX_PATH); | |
| nDiff = lstrcmpiA(strName1, strName2); | |
| } | |
| } | |
| /* If the Date, FileSize, FileType, Attrib was the same, sort by FileName */ | |
| if(nDiff == 0) | |
| { | |
| _ILSimpleGetText(pItemIdList1, strName1, MAX_PATH); | |
| _ILSimpleGetText(pItemIdList2, strName2, MAX_PATH); | |
| nDiff = lstrcmpiA(strName1, strName2); | |
| } | |
| if(!pSortInfo->bIsAscending) | |
| { | |
| nDiff = -nDiff; | |
| } | |
| return nDiff; | |
| } | |
| /********************************************************** | |
| * LV_FindItemByPidl() | |
| */ | |
| static int LV_FindItemByPidl( | |
| IShellViewImpl * This, | |
| LPCITEMIDLIST pidl) | |
| { | |
| LVITEMW lvItem; | |
| lvItem.iSubItem = 0; | |
| lvItem.mask = LVIF_PARAM; | |
| for(lvItem.iItem = 0; | |
| SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem); | |
| lvItem.iItem++) | |
| { | |
| LPITEMIDLIST currentpidl = (LPITEMIDLIST) lvItem.lParam; | |
| HRESULT hr = IShellFolder_CompareIDs(This->pSFParent, 0, pidl, currentpidl); | |
| if(SUCCEEDED(hr) && !HRESULT_CODE(hr)) | |
| { | |
| return lvItem.iItem; | |
| } | |
| } | |
| return -1; | |
| } | |
| static void shellview_add_item(IShellViewImpl *shellview, LPCITEMIDLIST pidl) | |
| { | |
| LVITEMW item; | |
| UINT i; | |
| TRACE("(%p)(pidl=%p)\n", shellview, pidl); | |
| item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; | |
| item.iItem = 0; | |
| item.iSubItem = 0; | |
| item.lParam = (LPARAM)pidl; | |
| item.pszText = LPSTR_TEXTCALLBACKW; | |
| item.iImage = I_IMAGECALLBACK; | |
| SendMessageW(shellview->hWndList, LVM_INSERTITEMW, 0, (LPARAM)&item); | |
| for (i = 1; i < shellview->columns; i++) | |
| { | |
| item.mask = LVIF_TEXT; | |
| item.iItem = 0; | |
| item.iSubItem = 1; | |
| item.pszText = LPSTR_TEXTCALLBACKW; | |
| SendMessageW(shellview->hWndList, LVM_SETITEMW, 0, (LPARAM)&item); | |
| } | |
| } | |
| /********************************************************** | |
| * LV_RenameItem() | |
| */ | |
| static BOOLEAN LV_RenameItem(IShellViewImpl * This, LPCITEMIDLIST pidlOld, LPCITEMIDLIST pidlNew ) | |
| { | |
| int nItem; | |
| LVITEMW lvItem; | |
| TRACE("(%p)(pidlold=%p pidlnew=%p)\n", This, pidlOld, pidlNew); | |
| nItem = LV_FindItemByPidl(This, ILFindLastID(pidlOld)); | |
| if ( -1 != nItem ) | |
| { | |
| lvItem.mask = LVIF_PARAM; /* only the pidl */ | |
| lvItem.iItem = nItem; | |
| SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem); | |
| SHFree((LPITEMIDLIST)lvItem.lParam); | |
| lvItem.mask = LVIF_PARAM; | |
| lvItem.iItem = nItem; | |
| lvItem.lParam = (LPARAM) ILClone(ILFindLastID(pidlNew)); /* set the item's data */ | |
| SendMessageW(This->hWndList, LVM_SETITEMW, 0, (LPARAM) &lvItem); | |
| SendMessageW(This->hWndList, LVM_UPDATE, nItem, 0); | |
| return TRUE; /* FIXME: better handling */ | |
| } | |
| return FALSE; | |
| } | |
| /********************************************************** | |
| * ShellView_FillList() | |
| * | |
| * - gets the objectlist from the shellfolder | |
| * - sorts the list | |
| * - fills the list into the view | |
| */ | |
| static HRESULT ShellView_FillList(IShellViewImpl *This) | |
| { | |
| IFolderView2 *folderview = &This->IFolderView2_iface; | |
| LPENUMIDLIST pEnumIDList; | |
| LPITEMIDLIST pidl; | |
| DWORD fetched; | |
| HRESULT hr; | |
| TRACE("(%p)\n", This); | |
| /* get the itemlist from the shfolder*/ | |
| hr = IShellFolder_EnumObjects(This->pSFParent, This->hWnd, SHCONTF_NONFOLDERS | SHCONTF_FOLDERS, &pEnumIDList); | |
| if (hr != S_OK) | |
| return hr; | |
| IFolderView2_SetRedraw(folderview, FALSE); | |
| /* copy the items into the array */ | |
| while ((S_OK == IEnumIDList_Next(pEnumIDList, 1, &pidl, &fetched)) && fetched) | |
| { | |
| if (IncludeObject(This, pidl) == S_OK) | |
| shellview_add_item(This, pidl); | |
| } | |
| SendMessageW(This->hWndList, LVM_SORTITEMS, (WPARAM)This->pSFParent, (LPARAM)ShellView_CompareItems); | |
| IFolderView2_SetRedraw(folderview, TRUE); | |
| IEnumIDList_Release(pEnumIDList); | |
| return S_OK; | |
| } | |
| /********************************************************** | |
| * ShellView_OnCreate() | |
| */ | |
| static LRESULT ShellView_OnCreate(IShellViewImpl *This) | |
| { | |
| IShellView3 *iface = &This->IShellView3_iface; | |
| static const WCHAR accel_nameW[] = {'s','h','v','_','a','c','c','e','l',0}; | |
| IPersistFolder2 *ppf2; | |
| IDropTarget* pdt; | |
| HRESULT hr; | |
| TRACE("(%p)\n", This); | |
| if (ShellView_CreateList(This)) | |
| { | |
| ShellView_InitList(This); | |
| ShellView_FillList(This); | |
| } | |
| hr = IShellView3_QueryInterface(iface, &IID_IDropTarget, (void**)&pdt); | |
| if (hr == S_OK) | |
| { | |
| RegisterDragDrop(This->hWnd, pdt); | |
| IDropTarget_Release(pdt); | |
| } | |
| /* register for receiving notifications */ | |
| hr = IShellFolder_QueryInterface(This->pSFParent, &IID_IPersistFolder2, (LPVOID*)&ppf2); | |
| if (hr == S_OK) | |
| { | |
| LPITEMIDLIST raw_pidl; | |
| SHChangeNotifyEntry ntreg; | |
| hr = IPersistFolder2_GetCurFolder(ppf2, &raw_pidl); | |
| if(SUCCEEDED(hr)) | |
| { | |
| LPITEMIDLIST computer_pidl; | |
| SHGetFolderLocation(NULL,CSIDL_DRIVES,NULL,0,&computer_pidl); | |
| if(ILIsParent(computer_pidl,raw_pidl,FALSE)) | |
| { | |
| /* Normalize the pidl to unixfs to workaround an issue with | |
| * sending notifications on dos paths | |
| */ | |
| WCHAR path[MAX_PATH]; | |
| SHGetPathFromIDListW(raw_pidl,path); | |
| SHParseDisplayName(path,NULL,(LPITEMIDLIST*)&ntreg.pidl,0,NULL); | |
| SHFree(raw_pidl); | |
| } | |
| else | |
| ntreg.pidl = raw_pidl; | |
| ntreg.fRecursive = TRUE; | |
| This->hNotify = SHChangeNotifyRegister(This->hWnd, SHCNRF_InterruptLevel, SHCNE_ALLEVENTS, | |
| SHV_CHANGE_NOTIFY, 1, &ntreg); | |
| SHFree((LPITEMIDLIST)ntreg.pidl); | |
| SHFree(computer_pidl); | |
| } | |
| IPersistFolder2_Release(ppf2); | |
| } | |
| This->hAccel = LoadAcceleratorsW(shell32_hInstance, accel_nameW); | |
| return S_OK; | |
| } | |
| /********************************************************** | |
| * #### Handling of the menus #### | |
| */ | |
| /********************************************************** | |
| * ShellView_BuildFileMenu() | |
| */ | |
| static HMENU ShellView_BuildFileMenu(IShellViewImpl * This) | |
| { WCHAR szText[MAX_PATH]; | |
| MENUITEMINFOW mii; | |
| int nTools,i; | |
| HMENU hSubMenu; | |
| TRACE("(%p)\n",This); | |
| hSubMenu = CreatePopupMenu(); | |
| if(hSubMenu) | |
| { /*get the number of items in our global array*/ | |
| for(nTools = 0; Tools[nTools].idCommand != -1; nTools++){} | |
| /*add the menu items*/ | |
| for(i = 0; i < nTools; i++) | |
| { | |
| LoadStringW(shell32_hInstance, Tools[i].idMenuString, szText, MAX_PATH); | |
| ZeroMemory(&mii, sizeof(mii)); | |
| mii.cbSize = sizeof(mii); | |
| mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE; | |
| if(BTNS_SEP != Tools[i].bStyle) /* no separator*/ | |
| { | |
| mii.fType = MFT_STRING; | |
| mii.fState = MFS_ENABLED; | |
| mii.dwTypeData = szText; | |
| mii.wID = Tools[i].idCommand; | |
| } | |
| else | |
| { | |
| mii.fType = MFT_SEPARATOR; | |
| } | |
| /* tack This item onto the end of the menu */ | |
| InsertMenuItemW(hSubMenu, (UINT)-1, TRUE, &mii); | |
| } | |
| } | |
| TRACE("-- return (menu=%p)\n",hSubMenu); | |
| return hSubMenu; | |
| } | |
| /********************************************************** | |
| * ShellView_MergeFileMenu() | |
| */ | |
| static void ShellView_MergeFileMenu(IShellViewImpl *This, HMENU hSubMenu) | |
| { | |
| TRACE("(%p)->(submenu=%p) stub\n",This,hSubMenu); | |
| if (hSubMenu) | |
| { | |
| static const WCHAR dummyW[] = {'d','u','m','m','y','4','5',0}; | |
| MENUITEMINFOW mii; | |
| /* insert This item at the beginning of the menu */ | |
| mii.cbSize = sizeof(mii); | |
| mii.fMask = MIIM_ID | MIIM_TYPE; | |
| mii.wID = 0; | |
| mii.fType = MFT_SEPARATOR; | |
| InsertMenuItemW(hSubMenu, 0, TRUE, &mii); | |
| mii.cbSize = sizeof(mii); | |
| mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE; | |
| mii.dwTypeData = (LPWSTR)dummyW; | |
| mii.fState = MFS_ENABLED; | |
| mii.wID = IDM_MYFILEITEM; | |
| mii.fType = MFT_STRING; | |
| InsertMenuItemW(hSubMenu, 0, TRUE, &mii); | |
| } | |
| TRACE("--\n"); | |
| } | |
| /********************************************************** | |
| * ShellView_MergeViewMenu() | |
| */ | |
| static void ShellView_MergeViewMenu(IShellViewImpl *This, HMENU hSubMenu) | |
| { | |
| TRACE("(%p)->(submenu=%p)\n",This,hSubMenu); | |
| /* add a separator at the correct position in the menu */ | |
| if (hSubMenu) | |
| { | |
| static const WCHAR menuW[] = {'M','E','N','U','_','0','0','1',0}; | |
| static const WCHAR viewW[] = {'V','i','e','w',0}; | |
| MENUITEMINFOW mii; | |
| memset(&mii, 0, sizeof(mii)); | |
| mii.cbSize = sizeof(mii); | |
| mii.fMask = MIIM_ID | MIIM_TYPE; | |
| mii.wID = 0; | |
| mii.fType = MFT_SEPARATOR; | |
| InsertMenuItemW(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii); | |
| mii.cbSize = sizeof(mii); | |
| mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_DATA; | |
| mii.fType = MFT_STRING; | |
| mii.dwTypeData = (LPWSTR)viewW; | |
| mii.hSubMenu = LoadMenuW(shell32_hInstance, menuW); | |
| InsertMenuItemW(hSubMenu, FCIDM_MENU_VIEW_SEP_OPTIONS, FALSE, &mii); | |
| } | |
| } | |
| /********************************************************** | |
| * ShellView_GetSelections() | |
| * | |
| * - fills the this->apidl list with the selected objects | |
| * | |
| * RETURNS | |
| * number of selected items | |
| */ | |
| static UINT ShellView_GetSelections(IShellViewImpl * This) | |
| { | |
| LVITEMW lvItem; | |
| UINT i = 0; | |
| SHFree(This->apidl); | |
| This->cidl = SendMessageW(This->hWndList, LVM_GETSELECTEDCOUNT, 0, 0); | |
| This->apidl = SHAlloc(This->cidl * sizeof(LPITEMIDLIST)); | |
| TRACE("selected=%i\n", This->cidl); | |
| if(This->apidl) | |
| { | |
| TRACE("-- Items selected =%u\n", This->cidl); | |
| lvItem.mask = LVIF_STATE | LVIF_PARAM; | |
| lvItem.stateMask = LVIS_SELECTED; | |
| lvItem.iItem = 0; | |
| lvItem.iSubItem = 0; | |
| while(ListView_GetItemW(This->hWndList, &lvItem) && (i < This->cidl)) | |
| { | |
| if(lvItem.state & LVIS_SELECTED) | |
| { | |
| This->apidl[i] = (LPITEMIDLIST)lvItem.lParam; | |
| i++; | |
| TRACE("-- selected Item found\n"); | |
| } | |
| lvItem.iItem++; | |
| } | |
| } | |
| return This->cidl; | |
| } | |
| /********************************************************** | |
| * ShellView_OpenSelectedItems() | |
| */ | |
| static HRESULT ShellView_OpenSelectedItems(IShellViewImpl * This) | |
| { | |
| static UINT CF_IDLIST = 0; | |
| HRESULT hr; | |
| IDataObject* selection; | |
| FORMATETC fetc; | |
| STGMEDIUM stgm; | |
| LPIDA pIDList; | |
| LPCITEMIDLIST parent_pidl; | |
| WCHAR parent_path[MAX_PATH]; | |
| LPCWSTR parent_dir = NULL; | |
| SFGAOF attribs; | |
| int i; | |
| if (0 == ShellView_GetSelections(This)) | |
| { | |
| return S_OK; | |
| } | |
| hr = IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, | |
| (LPCITEMIDLIST*)This->apidl, &IID_IDataObject, | |
| 0, (LPVOID *)&selection); | |
| if (FAILED(hr)) | |
| return hr; | |
| if (0 == CF_IDLIST) | |
| { | |
| CF_IDLIST = RegisterClipboardFormatW(CFSTR_SHELLIDLISTW); | |
| } | |
| fetc.cfFormat = CF_IDLIST; | |
| fetc.ptd = NULL; | |
| fetc.dwAspect = DVASPECT_CONTENT; | |
| fetc.lindex = -1; | |
| fetc.tymed = TYMED_HGLOBAL; | |
| hr = IDataObject_QueryGetData(selection, &fetc); | |
| if (FAILED(hr)) | |
| return hr; | |
| hr = IDataObject_GetData(selection, &fetc, &stgm); | |
| if (FAILED(hr)) | |
| return hr; | |
| pIDList = GlobalLock(stgm.u.hGlobal); | |
| parent_pidl = (LPCITEMIDLIST) ((LPBYTE)pIDList+pIDList->aoffset[0]); | |
| hr = IShellFolder_GetAttributesOf(This->pSFParent, 1, &parent_pidl, &attribs); | |
| if (SUCCEEDED(hr) && (attribs & SFGAO_FILESYSTEM) && | |
| SHGetPathFromIDListW(parent_pidl, parent_path)) | |
| { | |
| parent_dir = parent_path; | |
| } | |
| for (i = pIDList->cidl; i > 0; --i) | |
| { | |
| LPCITEMIDLIST pidl; | |
| pidl = (LPCITEMIDLIST)((LPBYTE)pIDList+pIDList->aoffset[i]); | |
| attribs = SFGAO_FOLDER; | |
| hr = IShellFolder_GetAttributesOf(This->pSFParent, 1, &pidl, &attribs); | |
| if (SUCCEEDED(hr) && ! (attribs & SFGAO_FOLDER)) | |
| { | |
| SHELLEXECUTEINFOW shexinfo; | |
| shexinfo.cbSize = sizeof(SHELLEXECUTEINFOW); | |
| shexinfo.fMask = SEE_MASK_INVOKEIDLIST; /* SEE_MASK_IDLIST is also possible. */ | |
| shexinfo.hwnd = NULL; | |
| shexinfo.lpVerb = NULL; | |
| shexinfo.lpFile = NULL; | |
| shexinfo.lpParameters = NULL; | |
| shexinfo.lpDirectory = parent_dir; | |
| shexinfo.nShow = SW_NORMAL; | |
| shexinfo.lpIDList = ILCombine(parent_pidl, pidl); | |
| ShellExecuteExW(&shexinfo); /* Discard error/success info */ | |
| ILFree(shexinfo.lpIDList); | |
| } | |
| } | |
| GlobalUnlock(stgm.u.hGlobal); | |
| ReleaseStgMedium(&stgm); | |
| IDataObject_Release(selection); | |
| return S_OK; | |
| } | |
| /********************************************************** | |
| * ShellView_DoContextMenu() | |
| */ | |
| static void ShellView_DoContextMenu(IShellViewImpl * This, WORD x, WORD y, BOOL bDefault) | |
| { UINT uCommand; | |
| DWORD wFlags; | |
| HMENU hMenu; | |
| BOOL fExplore = FALSE; | |
| HWND hwndTree = 0; | |
| LPCONTEXTMENU pContextMenu = NULL; | |
| CMINVOKECOMMANDINFO cmi; | |
| TRACE("(%p)->(0x%08x 0x%08x 0x%08x) stub\n",This, x, y, bDefault); | |
| /* look, what's selected and create a context menu object of it*/ | |
| if( ShellView_GetSelections(This) ) | |
| { | |
| IShellFolder_GetUIObjectOf( This->pSFParent, This->hWndParent, This->cidl, (LPCITEMIDLIST*)This->apidl, | |
| &IID_IContextMenu, NULL, (LPVOID *)&pContextMenu); | |
| if(pContextMenu) | |
| { | |
| TRACE("-- pContextMenu\n"); | |
| hMenu = CreatePopupMenu(); | |
| if( hMenu ) | |
| { | |
| /* See if we are in Explore or Open mode. If the browser's tree is present, we are in Explore mode.*/ | |
| if(SUCCEEDED(IShellBrowser_GetControlWindow(This->pShellBrowser,FCW_TREE, &hwndTree)) && hwndTree) | |
| { | |
| TRACE("-- explore mode\n"); | |
| fExplore = TRUE; | |
| } | |
| /* build the flags depending on what we can do with the selected item */ | |
| wFlags = CMF_NORMAL | (This->cidl != 1 ? 0 : CMF_CANRENAME) | (fExplore ? CMF_EXPLORE : 0); | |
| /* let the ContextMenu merge its items in */ | |
| if (SUCCEEDED(IContextMenu_QueryContextMenu( pContextMenu, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, wFlags ))) | |
| { | |
| if (This->FolderSettings.fFlags & FWF_DESKTOP) | |
| SetMenuDefaultItem(hMenu, FCIDM_SHVIEW_OPEN, MF_BYCOMMAND); | |
| if( bDefault ) | |
| { | |
| TRACE("-- get menu default command\n"); | |
| uCommand = GetMenuDefaultItem(hMenu, FALSE, GMDI_GOINTOPOPUPS); | |
| } | |
| else | |
| { | |
| TRACE("-- track popup\n"); | |
| uCommand = TrackPopupMenu( hMenu,TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL); | |
| } | |
| if(uCommand > 0) | |
| { | |
| TRACE("-- uCommand=%u\n", uCommand); | |
| if (uCommand==FCIDM_SHVIEW_OPEN && IsInCommDlg(This)) | |
| { | |
| TRACE("-- dlg: OnDefaultCommand\n"); | |
| if (OnDefaultCommand(This) != S_OK) | |
| { | |
| ShellView_OpenSelectedItems(This); | |
| } | |
| } | |
| else | |
| { | |
| TRACE("-- explore -- invoke command\n"); | |
| ZeroMemory(&cmi, sizeof(cmi)); | |
| cmi.cbSize = sizeof(cmi); | |
| cmi.hwnd = This->hWndParent; /* this window has to answer CWM_GETISHELLBROWSER */ | |
| cmi.lpVerb = MAKEINTRESOURCEA(uCommand); | |
| IContextMenu_InvokeCommand(pContextMenu, &cmi); | |
| } | |
| } | |
| DestroyMenu(hMenu); | |
| } | |
| } | |
| if (pContextMenu) | |
| IContextMenu_Release(pContextMenu); | |
| } | |
| } | |
| else /* background context menu */ | |
| { | |
| IContextMenu2 *pCM; | |
| hMenu = CreatePopupMenu(); | |
| BackgroundMenu_Constructor(This->pSFParent, FALSE, &IID_IContextMenu2, (void**)&pCM); | |
| IContextMenu2_QueryContextMenu(pCM, hMenu, 0, FCIDM_SHVIEWFIRST, FCIDM_SHVIEWLAST, 0); | |
| uCommand = TrackPopupMenu( hMenu, TPM_LEFTALIGN | TPM_RETURNCMD,x,y,0,This->hWnd,NULL); | |
| DestroyMenu(hMenu); | |
| TRACE("-- (%p)->(uCommand=0x%08x )\n",This, uCommand); | |
| ZeroMemory(&cmi, sizeof(cmi)); | |
| cmi.cbSize = sizeof(cmi); | |
| cmi.lpVerb = MAKEINTRESOURCEA(uCommand); | |
| cmi.hwnd = This->hWndParent; | |
| IContextMenu2_InvokeCommand(pCM, &cmi); | |
| IContextMenu2_Release(pCM); | |
| } | |
| } | |
| /********************************************************** | |
| * ##### message handling ##### | |
| */ | |
| /********************************************************** | |
| * ShellView_OnSize() | |
| */ | |
| static LRESULT ShellView_OnSize(IShellViewImpl * This, WORD wWidth, WORD wHeight) | |
| { | |
| TRACE("%p width=%u height=%u\n",This, wWidth,wHeight); | |
| /*resize the ListView to fit our window*/ | |
| if(This->hWndList) | |
| { | |
| MoveWindow(This->hWndList, 0, 0, wWidth, wHeight, TRUE); | |
| } | |
| return S_OK; | |
| } | |
| /********************************************************** | |
| * ShellView_OnDeactivate() | |
| * | |
| * NOTES | |
| * internal | |
| */ | |
| static void ShellView_OnDeactivate(IShellViewImpl * This) | |
| { | |
| TRACE("%p\n",This); | |
| if(This->uState != SVUIA_DEACTIVATE) | |
| { | |
| if(This->hMenu) | |
| { | |
| IShellBrowser_SetMenuSB(This->pShellBrowser,0, 0, 0); | |
| IShellBrowser_RemoveMenusSB(This->pShellBrowser,This->hMenu); | |
| DestroyMenu(This->hMenu); | |
| This->hMenu = 0; | |
| } | |
| This->uState = SVUIA_DEACTIVATE; | |
| } | |
| } | |
| /********************************************************** | |
| * ShellView_OnActivate() | |
| */ | |
| static LRESULT ShellView_OnActivate(IShellViewImpl *This, UINT uState) | |
| { | |
| OLEMENUGROUPWIDTHS omw = { {0, 0, 0, 0, 0, 0} }; | |
| MENUITEMINFOW mii; | |
| TRACE("(%p) uState=%x\n",This,uState); | |
| /* don't do anything if the state isn't really changing */ | |
| if (This->uState == uState) return S_OK; | |
| ShellView_OnDeactivate(This); | |
| /* only do This if we are active */ | |
| if (uState != SVUIA_DEACTIVATE) | |
| { | |
| /* merge the menus */ | |
| This->hMenu = CreateMenu(); | |
| if (This->hMenu) | |
| { | |
| static const WCHAR dummyW[] = {'d','u','m','m','y',' ','3','1',0}; | |
| IShellBrowser_InsertMenusSB(This->pShellBrowser, This->hMenu, &omw); | |
| TRACE("-- after fnInsertMenusSB\n"); | |
| mii.cbSize = sizeof(mii); | |
| mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_STATE; | |
| mii.fType = MFT_STRING; | |
| mii.fState = MFS_ENABLED; | |
| mii.wID = 0; | |
| mii.hSubMenu = ShellView_BuildFileMenu(This); | |
| mii.hbmpChecked = NULL; | |
| mii.hbmpUnchecked = NULL; | |
| mii.dwItemData = 0; | |
| /* build the top level menu get the menu item's text */ | |
| mii.dwTypeData = (LPWSTR)dummyW; | |
| mii.cch = 0; | |
| mii.hbmpItem = NULL; | |
| /* insert our menu into the menu bar */ | |
| if (mii.hSubMenu) | |
| InsertMenuItemW(This->hMenu, FCIDM_MENU_HELP, FALSE, &mii); | |
| /* get the view menu so we can merge with it */ | |
| memset(&mii, 0, sizeof(mii)); | |
| mii.cbSize = sizeof(mii); | |
| mii.fMask = MIIM_SUBMENU; | |
| if (GetMenuItemInfoW(This->hMenu, FCIDM_MENU_VIEW, FALSE, &mii)) | |
| ShellView_MergeViewMenu(This, mii.hSubMenu); | |
| /* add the items that should only be added if we have the focus */ | |
| if (SVUIA_ACTIVATE_FOCUS == uState) | |
| { | |
| /* get the file menu so we can merge with it */ | |
| memset(&mii, 0, sizeof(mii)); | |
| mii.cbSize = sizeof(mii); | |
| mii.fMask = MIIM_SUBMENU; | |
| if (GetMenuItemInfoW(This->hMenu, FCIDM_MENU_FILE, FALSE, &mii)) | |
| ShellView_MergeFileMenu(This, mii.hSubMenu); | |
| } | |
| TRACE("-- before fnSetMenuSB\n"); | |
| IShellBrowser_SetMenuSB(This->pShellBrowser, This->hMenu, 0, This->hWnd); | |
| } | |
| } | |
| This->uState = uState; | |
| TRACE("--\n"); | |
| return S_OK; | |
| } | |
| /********************************************************** | |
| * ShellView_OnSetFocus() | |
| * | |
| */ | |
| static LRESULT ShellView_OnSetFocus(IShellViewImpl * This) | |
| { | |
| TRACE("%p\n",This); | |
| /* Tell the browser one of our windows has received the focus. This | |
| should always be done before merging menus (OnActivate merges the | |
| menus) if one of our windows has the focus.*/ | |
| IShellBrowser_OnViewWindowActive(This->pShellBrowser, (IShellView *)&This->IShellView3_iface); | |
| ShellView_OnActivate(This, SVUIA_ACTIVATE_FOCUS); | |
| /* Set the focus to the listview */ | |
| SetFocus(This->hWndList); | |
| /* Notify the ICommDlgBrowser interface */ | |
| OnStateChange(This,CDBOSC_SETFOCUS); | |
| return 0; | |
| } | |
| /********************************************************** | |
| * ShellView_OnKillFocus() | |
| */ | |
| static LRESULT ShellView_OnKillFocus(IShellViewImpl * This) | |
| { | |
| TRACE("(%p) stub\n",This); | |
| ShellView_OnActivate(This, SVUIA_ACTIVATE_NOFOCUS); | |
| /* Notify the ICommDlgBrowser */ | |
| OnStateChange(This,CDBOSC_KILLFOCUS); | |
| return 0; | |
| } | |
| /********************************************************** | |
| * ShellView_OnCommand() | |
| * | |
| * NOTES | |
| * the CmdIDs are the ones from the context menu | |
| */ | |
| static LRESULT ShellView_OnCommand(IShellViewImpl * This,DWORD dwCmdID, DWORD dwCmd, HWND hwndCmd) | |
| { | |
| TRACE("(%p)->(0x%08x 0x%08x %p) stub\n",This, dwCmdID, dwCmd, hwndCmd); | |
| switch(dwCmdID) | |
| { | |
| case FCIDM_SHVIEW_SMALLICON: | |
| This->FolderSettings.ViewMode = FVM_SMALLICON; | |
| SetStyle (This, LVS_SMALLICON, LVS_TYPEMASK); | |
| CheckToolbar(This); | |
| break; | |
| case FCIDM_SHVIEW_BIGICON: | |
| This->FolderSettings.ViewMode = FVM_ICON; | |
| SetStyle (This, LVS_ICON, LVS_TYPEMASK); | |
| CheckToolbar(This); | |
| break; | |
| case FCIDM_SHVIEW_LISTVIEW: | |
| This->FolderSettings.ViewMode = FVM_LIST; | |
| SetStyle (This, LVS_LIST, LVS_TYPEMASK); | |
| CheckToolbar(This); | |
| break; | |
| case FCIDM_SHVIEW_REPORTVIEW: | |
| This->FolderSettings.ViewMode = FVM_DETAILS; | |
| SetStyle (This, LVS_REPORT, LVS_TYPEMASK); | |
| CheckToolbar(This); | |
| break; | |
| /* the menu IDs for sorting are 0x30... see shell32.rc */ | |
| case 0x30: | |
| case 0x31: | |
| case 0x32: | |
| case 0x33: | |
| This->ListViewSortInfo.nHeaderID = dwCmdID - 0x30; | |
| This->ListViewSortInfo.bIsAscending = TRUE; | |
| This->ListViewSortInfo.nLastHeaderID = This->ListViewSortInfo.nHeaderID; | |
| SendMessageW(This->hWndList, LVM_SORTITEMS, (WPARAM) &This->ListViewSortInfo, (LPARAM)ShellView_ListViewCompareItems); | |
| break; | |
| default: | |
| TRACE("-- COMMAND 0x%04x unhandled\n", dwCmdID); | |
| } | |
| return 0; | |
| } | |
| /********************************************************** | |
| * ShellView_OnNotify() | |
| */ | |
| static LRESULT ShellView_OnNotify(IShellViewImpl * This, UINT CtlID, LPNMHDR lpnmh) | |
| { LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)lpnmh; | |
| NMLVDISPINFOW *lpdi = (NMLVDISPINFOW *)lpnmh; | |
| LPITEMIDLIST pidl; | |
| TRACE("%p CtlID=%u lpnmh->code=%x\n",This,CtlID,lpnmh->code); | |
| switch(lpnmh->code) | |
| { | |
| case NM_SETFOCUS: | |
| TRACE("-- NM_SETFOCUS %p\n",This); | |
| ShellView_OnSetFocus(This); | |
| break; | |
| case NM_KILLFOCUS: | |
| TRACE("-- NM_KILLFOCUS %p\n",This); | |
| ShellView_OnDeactivate(This); | |
| /* Notify the ICommDlgBrowser interface */ | |
| OnStateChange(This,CDBOSC_KILLFOCUS); | |
| break; | |
| case NM_CUSTOMDRAW: | |
| TRACE("-- NM_CUSTOMDRAW %p\n",This); | |
| return CDRF_DODEFAULT; | |
| case NM_RELEASEDCAPTURE: | |
| TRACE("-- NM_RELEASEDCAPTURE %p\n",This); | |
| break; | |
| case NM_CLICK: | |
| TRACE("-- NM_CLICK %p\n",This); | |
| break; | |
| case NM_RCLICK: | |
| TRACE("-- NM_RCLICK %p\n",This); | |
| break; | |
| case NM_DBLCLK: | |
| TRACE("-- NM_DBLCLK %p\n",This); | |
| if (OnDefaultCommand(This) != S_OK) ShellView_OpenSelectedItems(This); | |
| break; | |
| case NM_RETURN: | |
| TRACE("-- NM_RETURN %p\n",This); | |
| if (OnDefaultCommand(This) != S_OK) ShellView_OpenSelectedItems(This); | |
| break; | |
| case HDN_ENDTRACKW: | |
| TRACE("-- HDN_ENDTRACKW %p\n",This); | |
| /*nColumn1 = ListView_GetColumnWidth(This->hWndList, 0); | |
| nColumn2 = ListView_GetColumnWidth(This->hWndList, 1);*/ | |
| break; | |
| case LVN_DELETEITEM: | |
| TRACE("-- LVN_DELETEITEM %p\n",This); | |
| SHFree((LPITEMIDLIST)lpnmlv->lParam); /*delete the pidl because we made a copy of it*/ | |
| break; | |
| case LVN_DELETEALLITEMS: | |
| TRACE("-- LVN_DELETEALLITEMS %p\n",This); | |
| return FALSE; | |
| case LVN_INSERTITEM: | |
| TRACE("-- LVN_INSERTITEM (STUB)%p\n",This); | |
| break; | |
| case LVN_ITEMACTIVATE: | |
| TRACE("-- LVN_ITEMACTIVATE %p\n",This); | |
| OnStateChange(This, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */ | |
| break; | |
| case LVN_COLUMNCLICK: | |
| This->ListViewSortInfo.nHeaderID = lpnmlv->iSubItem; | |
| if(This->ListViewSortInfo.nLastHeaderID == This->ListViewSortInfo.nHeaderID) | |
| { | |
| This->ListViewSortInfo.bIsAscending = !This->ListViewSortInfo.bIsAscending; | |
| } | |
| else | |
| { | |
| This->ListViewSortInfo.bIsAscending = TRUE; | |
| } | |
| This->ListViewSortInfo.nLastHeaderID = This->ListViewSortInfo.nHeaderID; | |
| SendMessageW(lpnmlv->hdr.hwndFrom, LVM_SORTITEMS, (WPARAM) &This->ListViewSortInfo, (LPARAM)ShellView_ListViewCompareItems); | |
| break; | |
| case LVN_GETDISPINFOA: | |
| case LVN_GETDISPINFOW: | |
| TRACE("-- LVN_GETDISPINFO %p\n",This); | |
| pidl = (LPITEMIDLIST)lpdi->item.lParam; | |
| if(lpdi->item.mask & LVIF_TEXT) /* text requested */ | |
| { | |
| static WCHAR emptyW[] = { 0 }; | |
| SHELLDETAILS sd; | |
| HRESULT hr; | |
| if (This->pSF2Parent) | |
| { | |
| hr = IShellFolder2_GetDetailsOf(This->pSF2Parent, pidl, lpdi->item.iSubItem, &sd); | |
| } | |
| else | |
| { | |
| IShellDetails *details; | |
| hr = IShellFolder_QueryInterface(This->pSFParent, &IID_IShellDetails, (void**)&details); | |
| if (hr == S_OK) | |
| { | |
| hr = IShellDetails_GetDetailsOf(details, pidl, lpdi->item.iSubItem, &sd); | |
| IShellDetails_Release(details); | |
| } | |
| else | |
| WARN("IShellFolder2/IShellDetails not supported\n"); | |
| } | |
| if (hr != S_OK) | |
| { | |
| /* set to empty on failure */ | |
| sd.str.uType = STRRET_WSTR; | |
| sd.str.u.pOleStr = emptyW; | |
| } | |
| if (lpnmh->code == LVN_GETDISPINFOW) | |
| { | |
| StrRetToStrNW( lpdi->item.pszText, lpdi->item.cchTextMax, &sd.str, NULL); | |
| TRACE("-- text=%s\n", debugstr_w(lpdi->item.pszText)); | |
| } | |
| else | |
| { | |
| /* LVN_GETDISPINFOA - shouldn't happen */ | |
| NMLVDISPINFOA *lpdiA = (NMLVDISPINFOA *)lpnmh; | |
| StrRetToStrNA( lpdiA->item.pszText, lpdiA->item.cchTextMax, &sd.str, NULL); | |
| TRACE("-- text=%s\n", lpdiA->item.pszText); | |
| } | |
| } | |
| if(lpdi->item.mask & LVIF_IMAGE) /* image requested */ | |
| { | |
| lpdi->item.iImage = SHMapPIDLToSystemImageListIndex(This->pSFParent, pidl, 0); | |
| } | |
| break; | |
| case LVN_ITEMCHANGED: | |
| TRACE("-- LVN_ITEMCHANGED %p\n",This); | |
| OnStateChange(This, CDBOSC_SELCHANGE); /* the browser will get the IDataObject now */ | |
| break; | |
| case LVN_BEGINDRAG: | |
| case LVN_BEGINRDRAG: | |
| TRACE("-- LVN_BEGINDRAG\n"); | |
| if (ShellView_GetSelections(This)) | |
| { | |
| IDataObject * pda; | |
| DWORD dwAttributes = SFGAO_CANLINK; | |
| DWORD dwEffect = DROPEFFECT_COPY | DROPEFFECT_MOVE; | |
| if (SUCCEEDED(IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, (LPCITEMIDLIST*)This->apidl, &IID_IDataObject,0,(LPVOID *)&pda))) | |
| { | |
| IDropSource *pds = &This->IDropSource_iface; /* own DropSource interface */ | |
| if (SUCCEEDED(IShellFolder_GetAttributesOf(This->pSFParent, This->cidl, (LPCITEMIDLIST*)This->apidl, &dwAttributes))) | |
| { | |
| if (dwAttributes & SFGAO_CANLINK) | |
| { | |
| dwEffect |= DROPEFFECT_LINK; | |
| } | |
| } | |
| if (pds) | |
| { | |
| DWORD dwEffect2; | |
| DoDragDrop(pda, pds, dwEffect, &dwEffect2); | |
| } | |
| IDataObject_Release(pda); | |
| } | |
| } | |
| break; | |
| case LVN_BEGINLABELEDITW: | |
| { | |
| DWORD dwAttr = SFGAO_CANRENAME; | |
| pidl = (LPITEMIDLIST)lpdi->item.lParam; | |
| TRACE("-- LVN_BEGINLABELEDITW %p\n",This); | |
| IShellFolder_GetAttributesOf(This->pSFParent, 1, (LPCITEMIDLIST*)&pidl, &dwAttr); | |
| if (SFGAO_CANRENAME & dwAttr) | |
| { | |
| return FALSE; | |
| } | |
| return TRUE; | |
| } | |
| case LVN_ENDLABELEDITW: | |
| { | |
| TRACE("-- LVN_ENDLABELEDITA %p\n",This); | |
| if (lpdi->item.pszText) | |
| { | |
| HRESULT hr; | |
| LVITEMW lvItem; | |
| lvItem.iItem = lpdi->item.iItem; | |
| lvItem.iSubItem = 0; | |
| lvItem.mask = LVIF_PARAM; | |
| SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem); | |
| pidl = (LPITEMIDLIST)lpdi->item.lParam; | |
| hr = IShellFolder_SetNameOf(This->pSFParent, 0, pidl, lpdi->item.pszText, SHGDN_INFOLDER, &pidl); | |
| if(SUCCEEDED(hr) && pidl) | |
| { | |
| lvItem.mask = LVIF_PARAM; | |
| lvItem.lParam = (LPARAM)pidl; | |
| SendMessageW(This->hWndList, LVM_SETITEMW, 0, (LPARAM) &lvItem); | |
| return TRUE; | |
| } | |
| } | |
| return FALSE; | |
| } | |
| case LVN_KEYDOWN: | |
| { | |
| LPNMLVKEYDOWN plvKeyDown = (LPNMLVKEYDOWN) lpnmh; | |
| /* initiate a rename of the selected file or directory */ | |
| switch (plvKeyDown->wVKey) | |
| { | |
| case VK_F2: | |
| { | |
| INT i = SendMessageW(This->hWndList, LVM_GETSELECTEDCOUNT, 0, 0); | |
| if (i == 1) | |
| { | |
| /* get selected item */ | |
| i = SendMessageW(This->hWndList, LVM_GETNEXTITEM, -1, MAKELPARAM (LVNI_SELECTED, 0)); | |
| SendMessageW(This->hWndList, LVM_ENSUREVISIBLE, i, 0); | |
| SendMessageW(This->hWndList, LVM_EDITLABELW, i, 0); | |
| } | |
| } | |
| break; | |
| case VK_DELETE: | |
| { | |
| UINT i, count; | |
| int item_index; | |
| LVITEMW item; | |
| LPITEMIDLIST* pItems; | |
| ISFHelper *psfhlp; | |
| HRESULT hr; | |
| hr = IShellFolder_QueryInterface(This->pSFParent, &IID_ISFHelper, (void**)&psfhlp); | |
| if (hr != S_OK) return 0; | |
| if(!(count = SendMessageW(This->hWndList, LVM_GETSELECTEDCOUNT, 0, 0))) | |
| { | |
| ISFHelper_Release(psfhlp); | |
| return 0; | |
| } | |
| /* allocate memory for the pidl array */ | |
| pItems = HeapAlloc(GetProcessHeap(), 0, sizeof(LPITEMIDLIST) * count); | |
| /* retrieve all selected items */ | |
| i = 0; | |
| item_index = -1; | |
| while (count > i) | |
| { | |
| /* get selected item */ | |
| item_index = SendMessageW(This->hWndList, LVM_GETNEXTITEM, item_index, | |
| MAKELPARAM (LVNI_SELECTED, 0)); | |
| item.iItem = item_index; | |
| item.mask = LVIF_PARAM; | |
| SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM)&item); | |
| /* get item pidl */ | |
| pItems[i] = (LPITEMIDLIST)item.lParam; | |
| i++; | |
| } | |
| /* perform the item deletion */ | |
| ISFHelper_DeleteItems(psfhlp, i, (LPCITEMIDLIST*)pItems); | |
| ISFHelper_Release(psfhlp); | |
| /* free pidl array memory */ | |
| HeapFree(GetProcessHeap(), 0, pItems); | |
| } | |
| break; | |
| case VK_F5: | |
| /* Initiate a refresh */ | |
| IShellView3_Refresh(&This->IShellView3_iface); | |
| break; | |
| case VK_BACK: | |
| { | |
| LPSHELLBROWSER lpSb; | |
| if((lpSb = (LPSHELLBROWSER)SendMessageW(This->hWndParent, CWM_GETISHELLBROWSER, 0, 0))) | |
| { | |
| IShellBrowser_BrowseObject(lpSb, NULL, SBSP_PARENT); | |
| } | |
| } | |
| break; | |
| default: | |
| FIXME("LVN_KEYDOWN key=0x%08x\n", plvKeyDown->wVKey); | |
| } | |
| } | |
| break; | |
| default: | |
| TRACE("-- %p WM_COMMAND %x unhandled\n", This, lpnmh->code); | |
| break; | |
| } | |
| return 0; | |
| } | |
| /********************************************************** | |
| * ShellView_OnChange() | |
| */ | |
| static LRESULT ShellView_OnChange(IShellViewImpl * This, const LPCITEMIDLIST *pidls, LONG event) | |
| { | |
| LPCITEMIDLIST pidl; | |
| BOOL ret = TRUE; | |
| TRACE("(%p)->(%p, %p, 0x%08x)\n", This, pidls[0], pidls[1], event); | |
| switch (event) | |
| { | |
| case SHCNE_MKDIR: | |
| case SHCNE_CREATE: | |
| pidl = ILClone(ILFindLastID(pidls[0])); | |
| shellview_add_item(This, pidl); | |
| break; | |
| case SHCNE_RMDIR: | |
| case SHCNE_DELETE: | |
| { | |
| INT i = LV_FindItemByPidl(This, ILFindLastID(pidls[0])); | |
| ret = SendMessageW(This->hWndList, LVM_DELETEITEM, i, 0); | |
| break; | |
| } | |
| case SHCNE_RENAMEFOLDER: | |
| case SHCNE_RENAMEITEM: | |
| LV_RenameItem(This, pidls[0], pidls[1]); | |
| break; | |
| case SHCNE_UPDATEITEM: | |
| break; | |
| } | |
| return ret; | |
| } | |
| /********************************************************** | |
| * ShellView_WndProc | |
| */ | |
| static LRESULT CALLBACK ShellView_WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam) | |
| { | |
| IShellViewImpl * pThis = (IShellViewImpl*)GetWindowLongPtrW(hWnd, GWLP_USERDATA); | |
| LPCREATESTRUCTW lpcs; | |
| TRACE("(hwnd=%p msg=%x wparm=%lx lparm=%lx)\n",hWnd, uMessage, wParam, lParam); | |
| switch (uMessage) | |
| { | |
| case WM_NCCREATE: | |
| lpcs = (LPCREATESTRUCTW)lParam; | |
| pThis = lpcs->lpCreateParams; | |
| SetWindowLongPtrW(hWnd, GWLP_USERDATA, (ULONG_PTR)pThis); | |
| pThis->hWnd = hWnd; /*set the window handle*/ | |
| break; | |
| case WM_SIZE: return ShellView_OnSize(pThis,LOWORD(lParam), HIWORD(lParam)); | |
| case WM_SETFOCUS: return ShellView_OnSetFocus(pThis); | |
| case WM_KILLFOCUS: return ShellView_OnKillFocus(pThis); | |
| case WM_CREATE: return ShellView_OnCreate(pThis); | |
| case WM_ACTIVATE: return ShellView_OnActivate(pThis, SVUIA_ACTIVATE_FOCUS); | |
| case WM_NOTIFY: return ShellView_OnNotify(pThis,(UINT)wParam, (LPNMHDR)lParam); | |
| case WM_COMMAND: return ShellView_OnCommand(pThis, | |
| GET_WM_COMMAND_ID(wParam, lParam), | |
| GET_WM_COMMAND_CMD(wParam, lParam), | |
| GET_WM_COMMAND_HWND(wParam, lParam)); | |
| case SHV_CHANGE_NOTIFY: return ShellView_OnChange(pThis, (const LPCITEMIDLIST*)wParam, (LONG)lParam); | |
| case WM_CONTEXTMENU: ShellView_DoContextMenu(pThis, LOWORD(lParam), HIWORD(lParam), FALSE); | |
| return 0; | |
| case WM_SHOWWINDOW: UpdateWindow(pThis->hWndList); | |
| break; | |
| case WM_GETDLGCODE: return SendMessageW(pThis->hWndList, uMessage, 0, 0); | |
| case WM_SETFONT: return SendMessageW(pThis->hWndList, WM_SETFONT, wParam, lParam); | |
| case WM_GETFONT: return SendMessageW(pThis->hWndList, WM_GETFONT, wParam, lParam); | |
| case WM_DESTROY: | |
| RevokeDragDrop(pThis->hWnd); | |
| SHChangeNotifyDeregister(pThis->hNotify); | |
| break; | |
| case WM_ERASEBKGND: | |
| if ((pThis->FolderSettings.fFlags & FWF_DESKTOP) || | |
| (pThis->FolderSettings.fFlags & FWF_TRANSPARENT)) | |
| return 1; | |
| break; | |
| } | |
| return DefWindowProcW(hWnd, uMessage, wParam, lParam); | |
| } | |
| /********************************************************** | |
| * | |
| * | |
| * The INTERFACE of the IShellView object | |
| * | |
| * | |
| ********************************************************** | |
| * IShellView_QueryInterface | |
| */ | |
| static HRESULT WINAPI IShellView_fnQueryInterface(IShellView3 *iface, REFIID riid, void **ppvObj) | |
| { | |
| IShellViewImpl *This = impl_from_IShellView3(iface); | |
| TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppvObj); | |
| *ppvObj = NULL; | |
| if(IsEqualIID(riid, &IID_IUnknown) || | |
| IsEqualIID(riid, &IID_IShellView) || | |
| IsEqualIID(riid, &IID_IShellView2) || | |
| IsEqualIID(riid, &IID_IShellView3) || | |
| IsEqualIID(riid, &IID_CDefView)) | |
| { | |
| *ppvObj = &This->IShellView3_iface; | |
| } | |
| else if(IsEqualIID(riid, &IID_IShellFolderView)) | |
| { | |
| *ppvObj = &This->IShellFolderView_iface; | |
| } | |
| else if(IsEqualIID(riid, &IID_IFolderView) || | |
| IsEqualIID(riid, &IID_IFolderView2)) | |
| { | |
| *ppvObj = &This->IFolderView2_iface; | |
| } | |
| else if(IsEqualIID(riid, &IID_IOleCommandTarget)) | |
| { | |
| *ppvObj = &This->IOleCommandTarget_iface; | |
| } | |
| else if(IsEqualIID(riid, &IID_IDropTarget)) | |
| { | |
| *ppvObj = &This->IDropTarget_iface; | |
| } | |
| else if(IsEqualIID(riid, &IID_IDropSource)) | |
| { | |
| *ppvObj = &This->IDropSource_iface; | |
| } | |
| else if(IsEqualIID(riid, &IID_IViewObject)) | |
| { | |
| *ppvObj = &This->IViewObject_iface; | |
| } | |
| if(*ppvObj) | |
| { | |
| IUnknown_AddRef( (IUnknown*)*ppvObj ); | |
| TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj); | |
| return S_OK; | |
| } | |
| TRACE("-- Interface: E_NOINTERFACE\n"); | |
| return E_NOINTERFACE; | |
| } | |
| /********************************************************** | |
| * IShellView_AddRef | |
| */ | |
| static ULONG WINAPI IShellView_fnAddRef(IShellView3 *iface) | |
| { | |
| IShellViewImpl *This = impl_from_IShellView3(iface); | |
| ULONG refCount = InterlockedIncrement(&This->ref); | |
| TRACE("(%p)->(count=%u)\n", This, refCount - 1); | |
| return refCount; | |
| } | |
| /********************************************************** | |
| * IShellView_Release | |
| */ | |
| static ULONG WINAPI IShellView_fnRelease(IShellView3 *iface) | |
| { | |
| IShellViewImpl *This = impl_from_IShellView3(iface); | |
| ULONG refCount = InterlockedDecrement(&This->ref); | |
| TRACE("(%p)->(count=%i)\n", This, refCount + 1); | |
| if (!refCount) | |
| { | |
| TRACE(" destroying IShellView(%p)\n",This); | |
| DestroyWindow(This->hWndList); | |
| if(This->pSFParent) | |
| IShellFolder_Release(This->pSFParent); | |
| if(This->pSF2Parent) | |
| IShellFolder2_Release(This->pSF2Parent); | |
| SHFree(This->apidl); | |
| if(This->pAdvSink) | |
| IAdviseSink_Release(This->pAdvSink); | |
| HeapFree(GetProcessHeap(),0,This); | |
| } | |
| return refCount; | |
| } | |
| /********************************************************** | |
| * ShellView_GetWindow | |
| */ | |
| static HRESULT WINAPI IShellView_fnGetWindow(IShellView3 *iface, HWND *phWnd) | |
| { | |
| IShellViewImpl *This = impl_from_IShellView3(iface); | |
| TRACE("(%p)\n", This); | |
| *phWnd = This->hWnd; | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI IShellView_fnContextSensitiveHelp(IShellView3 *iface, BOOL mode) | |
| { | |
| IShellViewImpl *This = impl_from_IShellView3(iface); | |
| TRACE("(%p)->(%d)\n", This, mode); | |
| return E_NOTIMPL; | |
| } | |
| /********************************************************** | |
| * IShellView_TranslateAccelerator | |
| * | |
| * FIXME: | |
| * use the accel functions | |
| */ | |
| static HRESULT WINAPI IShellView_fnTranslateAccelerator(IShellView3 *iface, MSG *lpmsg) | |
| { | |
| #if 0 | |
| IShellViewImpl *This = (IShellViewImpl *)iface; | |
| FIXME("(%p)->(%p: hwnd=%x msg=%x lp=%x wp=%x) stub\n",This,lpmsg, lpmsg->hwnd, lpmsg->message, lpmsg->lParam, lpmsg->wParam); | |
| #endif | |
| if ((lpmsg->message>=WM_KEYFIRST) && (lpmsg->message>=WM_KEYLAST)) | |
| { | |
| TRACE("-- key=0x04%lx\n",lpmsg->wParam) ; | |
| } | |
| return S_FALSE; /* not handled */ | |
| } | |
| static HRESULT WINAPI IShellView_fnEnableModeless(IShellView3 *iface, BOOL fEnable) | |
| { | |
| IShellViewImpl *This = impl_from_IShellView3(iface); | |
| FIXME("(%p) stub\n", This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IShellView_fnUIActivate(IShellView3 *iface, UINT uState) | |
| { | |
| IShellViewImpl *This = impl_from_IShellView3(iface); | |
| /* | |
| CHAR szName[MAX_PATH]; | |
| */ | |
| LRESULT lResult; | |
| int nPartArray[1] = {-1}; | |
| TRACE("(%p)->(state=%x) stub\n",This, uState); | |
| /*don't do anything if the state isn't really changing*/ | |
| if(This->uState == uState) | |
| { | |
| return S_OK; | |
| } | |
| /*OnActivate handles the menu merging and internal state*/ | |
| ShellView_OnActivate(This, uState); | |
| /*only do This if we are active*/ | |
| if(uState != SVUIA_DEACTIVATE) | |
| { | |
| /* | |
| GetFolderPath is not a method of IShellFolder | |
| IShellFolder_GetFolderPath( This->pSFParent, szName, sizeof(szName) ); | |
| */ | |
| /* set the number of parts */ | |
| IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETPARTS, 1, | |
| (LPARAM)nPartArray, &lResult); | |
| /* set the text for the parts */ | |
| /* | |
| IShellBrowser_SendControlMsg(This->pShellBrowser, FCW_STATUS, SB_SETTEXTA, | |
| 0, (LPARAM)szName, &lResult); | |
| */ | |
| } | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI IShellView_fnRefresh(IShellView3 *iface) | |
| { | |
| IShellViewImpl *This = impl_from_IShellView3(iface); | |
| TRACE("(%p)\n", This); | |
| SendMessageW(This->hWndList, LVM_DELETEALLITEMS, 0, 0); | |
| ShellView_FillList(This); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI IShellView_fnCreateViewWindow(IShellView3 *iface, IShellView *prev_view, | |
| const FOLDERSETTINGS *settings, IShellBrowser *owner, RECT *rect, HWND *hWnd) | |
| { | |
| IShellViewImpl *This = impl_from_IShellView3(iface); | |
| TRACE("(%p)->(%p %p %p %p %p)\n", This, prev_view, settings, owner, rect, hWnd); | |
| return IShellView3_CreateViewWindow3(iface, owner, prev_view, SV3CVW3_DEFAULT, | |
| settings->fFlags, settings->fFlags, settings->ViewMode, NULL, rect, hWnd); | |
| } | |
| static HRESULT WINAPI IShellView_fnDestroyViewWindow(IShellView3 *iface) | |
| { | |
| IShellViewImpl *This = impl_from_IShellView3(iface); | |
| TRACE("(%p)\n", This); | |
| if (!This->hWnd) | |
| return S_OK; | |
| /* Make absolutely sure all our UI is cleaned up. */ | |
| IShellView3_UIActivate(iface, SVUIA_DEACTIVATE); | |
| if (This->hMenu) | |
| DestroyMenu(This->hMenu); | |
| DestroyWindow(This->hWnd); | |
| if (This->pShellBrowser) IShellBrowser_Release(This->pShellBrowser); | |
| if (This->pCommDlgBrowser) ICommDlgBrowser_Release(This->pCommDlgBrowser); | |
| This->hMenu = NULL; | |
| This->hWnd = NULL; | |
| This->pShellBrowser = NULL; | |
| This->pCommDlgBrowser = NULL; | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI IShellView_fnGetCurrentInfo(IShellView3 *iface, LPFOLDERSETTINGS lpfs) | |
| { | |
| IShellViewImpl *This = impl_from_IShellView3(iface); | |
| TRACE("(%p)->(%p) vmode=%x flags=%x\n", This, lpfs, | |
| This->FolderSettings.ViewMode, This->FolderSettings.fFlags); | |
| if (!lpfs) return E_INVALIDARG; | |
| *lpfs = This->FolderSettings; | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI IShellView_fnAddPropertySheetPages(IShellView3 *iface, DWORD dwReserved, | |
| LPFNADDPROPSHEETPAGE lpfn, LPARAM lparam) | |
| { | |
| IShellViewImpl *This = impl_from_IShellView3(iface); | |
| FIXME("(%p) stub\n", This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IShellView_fnSaveViewState(IShellView3 *iface) | |
| { | |
| IShellViewImpl *This = impl_from_IShellView3(iface); | |
| FIXME("(%p) stub\n", This); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI IShellView_fnSelectItem(IShellView3 *iface, LPCITEMIDLIST pidl, UINT flags) | |
| { | |
| IShellViewImpl *This = impl_from_IShellView3(iface); | |
| int i; | |
| TRACE("(%p)->(pidl=%p, 0x%08x)\n",This, pidl, flags); | |
| i = LV_FindItemByPidl(This, pidl); | |
| if (i == -1) return S_OK; | |
| return IFolderView2_SelectItem(&This->IFolderView2_iface, i, flags); | |
| } | |
| static HRESULT WINAPI IShellView_fnGetItemObject(IShellView3 *iface, UINT uItem, REFIID riid, | |
| void **ppvOut) | |
| { | |
| IShellViewImpl *This = impl_from_IShellView3(iface); | |
| HRESULT hr = E_NOINTERFACE; | |
| TRACE("(%p)->(0x%08x, %s, %p)\n",This, uItem, debugstr_guid(riid), ppvOut); | |
| *ppvOut = NULL; | |
| switch(uItem) | |
| { | |
| case SVGIO_BACKGROUND: | |
| if (IsEqualIID(&IID_IContextMenu, riid)) | |
| return BackgroundMenu_Constructor(This->pSFParent, FALSE, riid, ppvOut); | |
| else if (IsEqualIID(&IID_IDispatch, riid)) { | |
| *ppvOut = &This->IShellFolderViewDual3_iface; | |
| IShellFolderViewDual3_AddRef(&This->IShellFolderViewDual3_iface); | |
| return S_OK; | |
| } | |
| else | |
| FIXME("unsupported interface requested %s\n", debugstr_guid(riid)); | |
| break; | |
| case SVGIO_SELECTION: | |
| ShellView_GetSelections(This); | |
| hr = IShellFolder_GetUIObjectOf(This->pSFParent, This->hWnd, This->cidl, (LPCITEMIDLIST*)This->apidl, riid, 0, ppvOut); | |
| break; | |
| default: | |
| FIXME("unimplemented for uItem = 0x%08x\n", uItem); | |
| } | |
| TRACE("-- (%p)->(interface=%p)\n",This, *ppvOut); | |
| return hr; | |
| } | |
| static HRESULT WINAPI IShellView2_fnGetView(IShellView3 *iface, SHELLVIEWID *view_guid, ULONG view_type) | |
| { | |
| FIXME("(%p)->(%s, %#x) stub!\n", iface, debugstr_guid(view_guid), view_type); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IShellView2_fnCreateViewWindow2(IShellView3 *iface, SV2CVW2_PARAMS *view_params) | |
| { | |
| IShellViewImpl *This = impl_from_IShellView3(iface); | |
| TRACE("(%p)->(%p)\n", This, view_params); | |
| return IShellView3_CreateViewWindow3(iface, view_params->psbOwner, view_params->psvPrev, | |
| SV3CVW3_DEFAULT, view_params->pfs->fFlags, view_params->pfs->fFlags, | |
| view_params->pfs->ViewMode, view_params->pvid, view_params->prcView, &view_params->hwndView); | |
| } | |
| static HRESULT WINAPI IShellView2_fnHandleRename(IShellView3 *iface, LPCITEMIDLIST new_pidl) | |
| { | |
| FIXME("(%p)->(new_pidl %p) stub!\n", iface, new_pidl); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IShellView2_fnSelectAndPositionItem(IShellView3 *iface, LPCITEMIDLIST item, | |
| UINT flags, POINT *point) | |
| { | |
| IShellViewImpl *This = impl_from_IShellView3(iface); | |
| TRACE("(%p)->(item %p, flags %#x, point %p)\n", This, item, flags, point); | |
| return IFolderView2_SelectAndPositionItems(&This->IFolderView2_iface, 1, &item, point, flags); | |
| } | |
| static HRESULT WINAPI IShellView3_fnCreateViewWindow3(IShellView3 *iface, IShellBrowser *owner, | |
| IShellView *prev_view, SV3CVW3_FLAGS view_flags, FOLDERFLAGS mask, FOLDERFLAGS flags, | |
| FOLDERVIEWMODE mode, const SHELLVIEWID *view_id, const RECT *rect, HWND *hwnd) | |
| { | |
| IShellViewImpl *This = impl_from_IShellView3(iface); | |
| INITCOMMONCONTROLSEX icex; | |
| WNDCLASSW wc; | |
| HRESULT hr; | |
| HWND wnd; | |
| TRACE("(%p)->(%p %p 0x%08x 0x%08x 0x%08x %d %s %s %p)\n", This, owner, prev_view, view_flags, | |
| mask, flags, mode, debugstr_guid(view_id), wine_dbgstr_rect(rect), hwnd); | |
| icex.dwSize = sizeof(icex); | |
| icex.dwICC = ICC_LISTVIEW_CLASSES; | |
| InitCommonControlsEx(&icex); | |
| *hwnd = NULL; | |
| if (!owner || This->hWnd) | |
| return E_UNEXPECTED; | |
| if (view_flags != SV3CVW3_DEFAULT) | |
| FIXME("unsupported view flags 0x%08x\n", view_flags); | |
| /* Set up the member variables */ | |
| This->pShellBrowser = owner; | |
| This->FolderSettings.ViewMode = mode; | |
| This->FolderSettings.fFlags = mask & flags; | |
| if (view_id) | |
| { | |
| if (IsEqualGUID(view_id, &VID_LargeIcons)) | |
| This->FolderSettings.ViewMode = FVM_ICON; | |
| else if (IsEqualGUID(view_id, &VID_SmallIcons)) | |
| This->FolderSettings.ViewMode = FVM_SMALLICON; | |
| else if (IsEqualGUID(view_id, &VID_List)) | |
| This->FolderSettings.ViewMode = FVM_LIST; | |
| else if (IsEqualGUID(view_id, &VID_Details)) | |
| This->FolderSettings.ViewMode = FVM_DETAILS; | |
| else if (IsEqualGUID(view_id, &VID_Thumbnails)) | |
| This->FolderSettings.ViewMode = FVM_THUMBNAIL; | |
| else if (IsEqualGUID(view_id, &VID_Tile)) | |
| This->FolderSettings.ViewMode = FVM_TILE; | |
| else if (IsEqualGUID(view_id, &VID_ThumbStrip)) | |
| This->FolderSettings.ViewMode = FVM_THUMBSTRIP; | |
| else | |
| FIXME("Ignoring unrecognized VID %s\n", debugstr_guid(view_id)); | |
| } | |
| /* Get our parent window */ | |
| IShellBrowser_AddRef(This->pShellBrowser); | |
| IShellBrowser_GetWindow(This->pShellBrowser, &This->hWndParent); | |
| /* Try to get the ICommDlgBrowserInterface, adds a reference !!! */ | |
| This->pCommDlgBrowser = NULL; | |
| hr = IShellBrowser_QueryInterface(This->pShellBrowser, &IID_ICommDlgBrowser, (void **)&This->pCommDlgBrowser); | |
| if (hr == S_OK) | |
| TRACE("-- CommDlgBrowser %p\n", This->pCommDlgBrowser); | |
| /* If our window class has not been registered, then do so */ | |
| if (!GetClassInfoW(shell32_hInstance, SV_CLASS_NAME, &wc)) | |
| { | |
| wc.style = CS_HREDRAW | CS_VREDRAW; | |
| wc.lpfnWndProc = ShellView_WndProc; | |
| wc.cbClsExtra = 0; | |
| wc.cbWndExtra = 0; | |
| wc.hInstance = shell32_hInstance; | |
| wc.hIcon = 0; | |
| wc.hCursor = LoadCursorW(0, (LPWSTR)IDC_ARROW); | |
| wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); | |
| wc.lpszMenuName = NULL; | |
| wc.lpszClassName = SV_CLASS_NAME; | |
| if (!RegisterClassW(&wc)) return E_FAIL; | |
| } | |
| wnd = CreateWindowExW(0, SV_CLASS_NAME, NULL, WS_CHILD | WS_TABSTOP, | |
| rect->left, rect->top, | |
| rect->right - rect->left, | |
| rect->bottom - rect->top, | |
| This->hWndParent, 0, shell32_hInstance, This); | |
| CheckToolbar(This); | |
| if (!wnd) | |
| { | |
| IShellBrowser_Release(This->pShellBrowser); | |
| return E_FAIL; | |
| } | |
| SetWindowPos(wnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); | |
| UpdateWindow(wnd); | |
| *hwnd = wnd; | |
| return S_OK; | |
| } | |
| static const IShellView3Vtbl shellviewvtbl = | |
| { | |
| IShellView_fnQueryInterface, | |
| IShellView_fnAddRef, | |
| IShellView_fnRelease, | |
| IShellView_fnGetWindow, | |
| IShellView_fnContextSensitiveHelp, | |
| IShellView_fnTranslateAccelerator, | |
| IShellView_fnEnableModeless, | |
| IShellView_fnUIActivate, | |
| IShellView_fnRefresh, | |
| IShellView_fnCreateViewWindow, | |
| IShellView_fnDestroyViewWindow, | |
| IShellView_fnGetCurrentInfo, | |
| IShellView_fnAddPropertySheetPages, | |
| IShellView_fnSaveViewState, | |
| IShellView_fnSelectItem, | |
| IShellView_fnGetItemObject, | |
| IShellView2_fnGetView, | |
| IShellView2_fnCreateViewWindow2, | |
| IShellView2_fnHandleRename, | |
| IShellView2_fnSelectAndPositionItem, | |
| IShellView3_fnCreateViewWindow3 | |
| }; | |
| /********************************************************** | |
| * ISVOleCmdTarget_QueryInterface (IUnknown) | |
| */ | |
| static HRESULT WINAPI ISVOleCmdTarget_QueryInterface(IOleCommandTarget *iface, REFIID iid, void **ppvObj) | |
| { | |
| IShellViewImpl *This = impl_from_IOleCommandTarget(iface); | |
| return IShellView3_QueryInterface(&This->IShellView3_iface, iid, ppvObj); | |
| } | |
| /********************************************************** | |
| * ISVOleCmdTarget_AddRef (IUnknown) | |
| */ | |
| static ULONG WINAPI ISVOleCmdTarget_AddRef(IOleCommandTarget *iface) | |
| { | |
| IShellViewImpl *This = impl_from_IOleCommandTarget(iface); | |
| return IShellView3_AddRef(&This->IShellView3_iface); | |
| } | |
| /********************************************************** | |
| * ISVOleCmdTarget_Release (IUnknown) | |
| */ | |
| static ULONG WINAPI ISVOleCmdTarget_Release(IOleCommandTarget *iface) | |
| { | |
| IShellViewImpl *This = impl_from_IOleCommandTarget(iface); | |
| return IShellView3_Release(&This->IShellView3_iface); | |
| } | |
| /********************************************************** | |
| * ISVOleCmdTarget_QueryStatus (IOleCommandTarget) | |
| */ | |
| static HRESULT WINAPI ISVOleCmdTarget_QueryStatus( | |
| IOleCommandTarget *iface, | |
| const GUID *pguidCmdGroup, | |
| ULONG cCmds, | |
| OLECMD *prgCmds, | |
| OLECMDTEXT *pCmdText) | |
| { | |
| IShellViewImpl *This = impl_from_IOleCommandTarget(iface); | |
| UINT i; | |
| FIXME("(%p)->(%s %d %p %p)\n", | |
| This, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText); | |
| if (!prgCmds) | |
| return E_INVALIDARG; | |
| for (i = 0; i < cCmds; i++) | |
| { | |
| FIXME("\tprgCmds[%d].cmdID = %d\n", i, prgCmds[i].cmdID); | |
| prgCmds[i].cmdf = 0; | |
| } | |
| return OLECMDERR_E_UNKNOWNGROUP; | |
| } | |
| /********************************************************** | |
| * ISVOleCmdTarget_Exec (IOleCommandTarget) | |
| * | |
| * nCmdID is the OLECMDID_* enumeration | |
| */ | |
| static HRESULT WINAPI ISVOleCmdTarget_Exec( | |
| IOleCommandTarget *iface, | |
| const GUID* pguidCmdGroup, | |
| DWORD nCmdID, | |
| DWORD nCmdexecopt, | |
| VARIANT* pvaIn, | |
| VARIANT* pvaOut) | |
| { | |
| IShellViewImpl *This = impl_from_IOleCommandTarget(iface); | |
| FIXME("(%p)->(%s %d 0x%08x %s %p)\n", | |
| This, debugstr_guid(pguidCmdGroup), nCmdID, nCmdexecopt, debugstr_variant(pvaIn), pvaOut); | |
| if (!pguidCmdGroup) | |
| return OLECMDERR_E_UNKNOWNGROUP; | |
| if (IsEqualIID(pguidCmdGroup, &CGID_Explorer) && | |
| (nCmdID == OLECMDID_SHOWMESSAGE) && | |
| (nCmdexecopt == 4) && pvaOut) | |
| return S_OK; | |
| if (IsEqualIID(pguidCmdGroup, &CGID_ShellDocView) && | |
| (nCmdID == OLECMDID_SPELL) && | |
| (nCmdexecopt == OLECMDEXECOPT_DODEFAULT)) | |
| return S_FALSE; | |
| return OLECMDERR_E_UNKNOWNGROUP; | |
| } | |
| static const IOleCommandTargetVtbl olecommandtargetvtbl = | |
| { | |
| ISVOleCmdTarget_QueryInterface, | |
| ISVOleCmdTarget_AddRef, | |
| ISVOleCmdTarget_Release, | |
| ISVOleCmdTarget_QueryStatus, | |
| ISVOleCmdTarget_Exec | |
| }; | |
| /********************************************************** | |
| * ISVDropTarget implementation | |
| */ | |
| static HRESULT WINAPI ISVDropTarget_QueryInterface(IDropTarget *iface, REFIID riid, void **ppvObj) | |
| { | |
| IShellViewImpl *This = impl_from_IDropTarget(iface); | |
| return IShellView3_QueryInterface(&This->IShellView3_iface, riid, ppvObj); | |
| } | |
| static ULONG WINAPI ISVDropTarget_AddRef(IDropTarget *iface) | |
| { | |
| IShellViewImpl *This = impl_from_IDropTarget(iface); | |
| return IShellView3_AddRef(&This->IShellView3_iface); | |
| } | |
| static ULONG WINAPI ISVDropTarget_Release(IDropTarget *iface) | |
| { | |
| IShellViewImpl *This = impl_from_IDropTarget(iface); | |
| return IShellView3_Release(&This->IShellView3_iface); | |
| } | |
| /****************************************************************************** | |
| * drag_notify_subitem [Internal] | |
| * | |
| * Figure out the shellfolder object, which is currently under the mouse cursor | |
| * and notify it via the IDropTarget interface. | |
| */ | |
| #define SCROLLAREAWIDTH 20 | |
| static HRESULT drag_notify_subitem(IShellViewImpl *This, DWORD grfKeyState, POINTL pt, | |
| DWORD *pdwEffect) | |
| { | |
| LVHITTESTINFO htinfo; | |
| LVITEMW lvItem; | |
| LONG lResult; | |
| HRESULT hr; | |
| RECT clientRect; | |
| /* Map from global to client coordinates and query the index of the listview-item, which is | |
| * currently under the mouse cursor. */ | |
| htinfo.pt.x = pt.x; | |
| htinfo.pt.y = pt.y; | |
| htinfo.flags = LVHT_ONITEM; | |
| ScreenToClient(This->hWndList, &htinfo.pt); | |
| lResult = SendMessageW(This->hWndList, LVM_HITTEST, 0, (LPARAM)&htinfo); | |
| /* Send WM_*SCROLL messages every 250 ms during drag-scrolling */ | |
| GetClientRect(This->hWndList, &clientRect); | |
| if (htinfo.pt.x == This->ptLastMousePos.x && htinfo.pt.y == This->ptLastMousePos.y && | |
| (htinfo.pt.x < SCROLLAREAWIDTH || htinfo.pt.x > clientRect.right - SCROLLAREAWIDTH || | |
| htinfo.pt.y < SCROLLAREAWIDTH || htinfo.pt.y > clientRect.bottom - SCROLLAREAWIDTH )) | |
| { | |
| This->cScrollDelay = (This->cScrollDelay + 1) % 5; /* DragOver is called every 50 ms */ | |
| if (This->cScrollDelay == 0) { /* Mouse did hover another 250 ms over the scroll-area */ | |
| if (htinfo.pt.x < SCROLLAREAWIDTH) | |
| SendMessageW(This->hWndList, WM_HSCROLL, SB_LINEUP, 0); | |
| if (htinfo.pt.x > clientRect.right - SCROLLAREAWIDTH) | |
| SendMessageW(This->hWndList, WM_HSCROLL, SB_LINEDOWN, 0); | |
| if (htinfo.pt.y < SCROLLAREAWIDTH) | |
| SendMessageW(This->hWndList, WM_VSCROLL, SB_LINEUP, 0); | |
| if (htinfo.pt.y > clientRect.bottom - SCROLLAREAWIDTH) | |
| SendMessageW(This->hWndList, WM_VSCROLL, SB_LINEDOWN, 0); | |
| } | |
| } else { | |
| This->cScrollDelay = 0; /* Reset, if the cursor is not over the listview's scroll-area */ | |
| } | |
| This->ptLastMousePos = htinfo.pt; | |
| /* If we are still over the previous sub-item, notify it via DragOver and return. */ | |
| if (This->pCurDropTarget && lResult == This->iDragOverItem) | |
| return IDropTarget_DragOver(This->pCurDropTarget, grfKeyState, pt, pdwEffect); | |
| /* We've left the previous sub-item, notify it via DragLeave and Release it. */ | |
| if (This->pCurDropTarget) { | |
| IDropTarget_DragLeave(This->pCurDropTarget); | |
| IDropTarget_Release(This->pCurDropTarget); | |
| This->pCurDropTarget = NULL; | |
| } | |
| This->iDragOverItem = lResult; | |
| if (lResult == -1) { | |
| /* We are not above one of the listview's subitems. Bind to the parent folder's | |
| * DropTarget interface. */ | |
| hr = IShellFolder_QueryInterface(This->pSFParent, &IID_IDropTarget, | |
| (LPVOID*)&This->pCurDropTarget); | |
| } else { | |
| /* Query the relative PIDL of the shellfolder object represented by the currently | |
| * dragged over listview-item ... */ | |
| lvItem.mask = LVIF_PARAM; | |
| lvItem.iItem = lResult; | |
| lvItem.iSubItem = 0; | |
| SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM) &lvItem); | |
| /* ... and bind pCurDropTarget to the IDropTarget interface of an UIObject of this object */ | |
| hr = IShellFolder_GetUIObjectOf(This->pSFParent, This->hWndList, 1, | |
| (LPCITEMIDLIST*)&lvItem.lParam, &IID_IDropTarget, NULL, (LPVOID*)&This->pCurDropTarget); | |
| } | |
| /* If anything failed, pCurDropTarget should be NULL now, which ought to be a save state. */ | |
| if (FAILED(hr)) | |
| return hr; | |
| /* Notify the item just entered via DragEnter. */ | |
| return IDropTarget_DragEnter(This->pCurDropTarget, This->pCurDataObject, grfKeyState, pt, pdwEffect); | |
| } | |
| static HRESULT WINAPI ISVDropTarget_DragEnter(IDropTarget *iface, IDataObject *pDataObject, | |
| DWORD grfKeyState, POINTL pt, DWORD *pdwEffect) | |
| { | |
| IShellViewImpl *This = impl_from_IDropTarget(iface); | |
| /* Get a hold on the data object for later calls to DragEnter on the sub-folders */ | |
| This->pCurDataObject = pDataObject; | |
| IDataObject_AddRef(pDataObject); | |
| return drag_notify_subitem(This, grfKeyState, pt, pdwEffect); | |
| } | |
| static HRESULT WINAPI ISVDropTarget_DragOver(IDropTarget *iface, DWORD grfKeyState, POINTL pt, | |
| DWORD *pdwEffect) | |
| { | |
| IShellViewImpl *This = impl_from_IDropTarget(iface); | |
| return drag_notify_subitem(This, grfKeyState, pt, pdwEffect); | |
| } | |
| static HRESULT WINAPI ISVDropTarget_DragLeave(IDropTarget *iface) | |
| { | |
| IShellViewImpl *This = impl_from_IDropTarget(iface); | |
| if (This->pCurDropTarget) | |
| { | |
| IDropTarget_DragLeave(This->pCurDropTarget); | |
| IDropTarget_Release(This->pCurDropTarget); | |
| This->pCurDropTarget = NULL; | |
| } | |
| if (This->pCurDataObject) | |
| { | |
| IDataObject_Release(This->pCurDataObject); | |
| This->pCurDataObject = NULL; | |
| } | |
| This->iDragOverItem = 0; | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI ISVDropTarget_Drop(IDropTarget *iface, IDataObject* pDataObject, | |
| DWORD grfKeyState, POINTL pt, DWORD *pdwEffect) | |
| { | |
| IShellViewImpl *This = impl_from_IDropTarget(iface); | |
| if (!This->pCurDropTarget) return DRAGDROP_E_INVALIDHWND; | |
| IDropTarget_Drop(This->pCurDropTarget, pDataObject, grfKeyState, pt, pdwEffect); | |
| IDropTarget_Release(This->pCurDropTarget); | |
| IDataObject_Release(This->pCurDataObject); | |
| This->pCurDataObject = NULL; | |
| This->pCurDropTarget = NULL; | |
| This->iDragOverItem = 0; | |
| return S_OK; | |
| } | |
| static const IDropTargetVtbl droptargetvtbl = | |
| { | |
| ISVDropTarget_QueryInterface, | |
| ISVDropTarget_AddRef, | |
| ISVDropTarget_Release, | |
| ISVDropTarget_DragEnter, | |
| ISVDropTarget_DragOver, | |
| ISVDropTarget_DragLeave, | |
| ISVDropTarget_Drop | |
| }; | |
| /********************************************************** | |
| * ISVDropSource implementation | |
| */ | |
| static HRESULT WINAPI ISVDropSource_QueryInterface(IDropSource *iface, REFIID riid, void **ppvObj) | |
| { | |
| IShellViewImpl *This = impl_from_IDropSource(iface); | |
| return IShellView3_QueryInterface(&This->IShellView3_iface, riid, ppvObj); | |
| } | |
| static ULONG WINAPI ISVDropSource_AddRef(IDropSource *iface) | |
| { | |
| IShellViewImpl *This = impl_from_IDropSource(iface); | |
| return IShellView3_AddRef(&This->IShellView3_iface); | |
| } | |
| static ULONG WINAPI ISVDropSource_Release(IDropSource *iface) | |
| { | |
| IShellViewImpl *This = impl_from_IDropSource(iface); | |
| return IShellView3_Release(&This->IShellView3_iface); | |
| } | |
| static HRESULT WINAPI ISVDropSource_QueryContinueDrag( | |
| IDropSource *iface, | |
| BOOL fEscapePressed, | |
| DWORD grfKeyState) | |
| { | |
| IShellViewImpl *This = impl_from_IDropSource(iface); | |
| TRACE("(%p)\n",This); | |
| if (fEscapePressed) | |
| return DRAGDROP_S_CANCEL; | |
| else if (!(grfKeyState & MK_LBUTTON) && !(grfKeyState & MK_RBUTTON)) | |
| return DRAGDROP_S_DROP; | |
| else | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI ISVDropSource_GiveFeedback( | |
| IDropSource *iface, | |
| DWORD dwEffect) | |
| { | |
| IShellViewImpl *This = impl_from_IDropSource(iface); | |
| TRACE("(%p)\n",This); | |
| return DRAGDROP_S_USEDEFAULTCURSORS; | |
| } | |
| static const IDropSourceVtbl dropsourcevtbl = | |
| { | |
| ISVDropSource_QueryInterface, | |
| ISVDropSource_AddRef, | |
| ISVDropSource_Release, | |
| ISVDropSource_QueryContinueDrag, | |
| ISVDropSource_GiveFeedback | |
| }; | |
| /********************************************************** | |
| * ISVViewObject implementation | |
| */ | |
| static HRESULT WINAPI ISVViewObject_QueryInterface(IViewObject *iface, REFIID riid, void **ppvObj) | |
| { | |
| IShellViewImpl *This = impl_from_IViewObject(iface); | |
| return IShellView3_QueryInterface(&This->IShellView3_iface, riid, ppvObj); | |
| } | |
| static ULONG WINAPI ISVViewObject_AddRef(IViewObject *iface) | |
| { | |
| IShellViewImpl *This = impl_from_IViewObject(iface); | |
| return IShellView3_AddRef(&This->IShellView3_iface); | |
| } | |
| static ULONG WINAPI ISVViewObject_Release(IViewObject *iface) | |
| { | |
| IShellViewImpl *This = impl_from_IViewObject(iface); | |
| return IShellView3_Release(&This->IShellView3_iface); | |
| } | |
| static HRESULT WINAPI ISVViewObject_Draw( | |
| IViewObject *iface, | |
| DWORD dwDrawAspect, | |
| LONG lindex, | |
| void* pvAspect, | |
| DVTARGETDEVICE* ptd, | |
| HDC hdcTargetDev, | |
| HDC hdcDraw, | |
| LPCRECTL lprcBounds, | |
| LPCRECTL lprcWBounds, | |
| BOOL (CALLBACK *pfnContinue)(ULONG_PTR dwContinue), | |
| ULONG_PTR dwContinue) | |
| { | |
| IShellViewImpl *This = impl_from_IViewObject(iface); | |
| FIXME("Stub: This=%p\n",This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ISVViewObject_GetColorSet( | |
| IViewObject *iface, | |
| DWORD dwDrawAspect, | |
| LONG lindex, | |
| void *pvAspect, | |
| DVTARGETDEVICE* ptd, | |
| HDC hicTargetDevice, | |
| LOGPALETTE** ppColorSet) | |
| { | |
| IShellViewImpl *This = impl_from_IViewObject(iface); | |
| FIXME("Stub: This=%p\n",This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ISVViewObject_Freeze( | |
| IViewObject *iface, | |
| DWORD dwDrawAspect, | |
| LONG lindex, | |
| void* pvAspect, | |
| DWORD* pdwFreeze) | |
| { | |
| IShellViewImpl *This = impl_from_IViewObject(iface); | |
| FIXME("Stub: This=%p\n",This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ISVViewObject_Unfreeze( | |
| IViewObject *iface, | |
| DWORD dwFreeze) | |
| { | |
| IShellViewImpl *This = impl_from_IViewObject(iface); | |
| FIXME("Stub: This=%p\n",This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI ISVViewObject_SetAdvise( | |
| IViewObject *iface, | |
| DWORD aspects, | |
| DWORD advf, | |
| IAdviseSink* pAdvSink) | |
| { | |
| IShellViewImpl *This = impl_from_IViewObject(iface); | |
| FIXME("partial stub: %p %08x %08x %p\n", | |
| This, aspects, advf, pAdvSink); | |
| /* FIXME: we set the AdviseSink, but never use it to send any advice */ | |
| This->pAdvSink = pAdvSink; | |
| This->dwAspects = aspects; | |
| This->dwAdvf = advf; | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI ISVViewObject_GetAdvise( | |
| IViewObject *iface, | |
| DWORD* pAspects, | |
| DWORD* pAdvf, | |
| IAdviseSink** ppAdvSink) | |
| { | |
| IShellViewImpl *This = impl_from_IViewObject(iface); | |
| TRACE("This=%p pAspects=%p pAdvf=%p ppAdvSink=%p\n", | |
| This, pAspects, pAdvf, ppAdvSink); | |
| if( ppAdvSink ) | |
| { | |
| IAdviseSink_AddRef( This->pAdvSink ); | |
| *ppAdvSink = This->pAdvSink; | |
| } | |
| if( pAspects ) | |
| *pAspects = This->dwAspects; | |
| if( pAdvf ) | |
| *pAdvf = This->dwAdvf; | |
| return S_OK; | |
| } | |
| static const IViewObjectVtbl viewobjectvtbl = | |
| { | |
| ISVViewObject_QueryInterface, | |
| ISVViewObject_AddRef, | |
| ISVViewObject_Release, | |
| ISVViewObject_Draw, | |
| ISVViewObject_GetColorSet, | |
| ISVViewObject_Freeze, | |
| ISVViewObject_Unfreeze, | |
| ISVViewObject_SetAdvise, | |
| ISVViewObject_GetAdvise | |
| }; | |
| /* IFolderView2 */ | |
| static HRESULT WINAPI FolderView_QueryInterface(IFolderView2 *iface, REFIID riid, void **ppvObj) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| return IShellView3_QueryInterface(&This->IShellView3_iface, riid, ppvObj); | |
| } | |
| static ULONG WINAPI FolderView_AddRef(IFolderView2 *iface) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| return IShellView3_AddRef(&This->IShellView3_iface); | |
| } | |
| static ULONG WINAPI FolderView_Release(IFolderView2 *iface) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| return IShellView3_Release(&This->IShellView3_iface); | |
| } | |
| static HRESULT WINAPI FolderView_GetCurrentViewMode(IFolderView2 *iface, UINT *mode) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| TRACE("(%p)->(%p), stub\n", This, mode); | |
| if(!mode) | |
| return E_INVALIDARG; | |
| *mode = This->FolderSettings.ViewMode; | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI FolderView_SetCurrentViewMode(IFolderView2 *iface, UINT mode) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| DWORD dwStyle; | |
| TRACE("(%p)->(%u), stub\n", This, mode); | |
| if((mode < FVM_FIRST || mode > FVM_LAST) && | |
| (mode != FVM_AUTO)) | |
| return E_INVALIDARG; | |
| /* Windows before Vista uses LVM_SETVIEW and possibly | |
| LVM_SETEXTENDEDLISTVIEWSTYLE to set the style of the listview, | |
| while later versions seem to accomplish this through other | |
| means. */ | |
| dwStyle = ViewModeToListStyle(mode); | |
| SetStyle(This, dwStyle, LVS_TYPEMASK); | |
| /* This will not necessarily be the actual mode set above. | |
| This mimics the behavior of Windows XP. */ | |
| This->FolderSettings.ViewMode = mode; | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI FolderView_GetFolder(IFolderView2 *iface, REFIID riid, void **ppv) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv); | |
| return IShellFolder_QueryInterface(This->pSFParent, riid, ppv); | |
| } | |
| static HRESULT WINAPI FolderView_Item(IFolderView2 *iface, int index, PITEMID_CHILD *ppidl) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| LVITEMW item; | |
| TRACE("(%p)->(%d %p)\n", This, index, ppidl); | |
| item.mask = LVIF_PARAM; | |
| item.iItem = index; | |
| if (SendMessageW(This->hWndList, LVM_GETITEMW, 0, (LPARAM)&item)) | |
| { | |
| *ppidl = ILClone((PITEMID_CHILD)item.lParam); | |
| return S_OK; | |
| } | |
| else | |
| { | |
| *ppidl = 0; | |
| return E_INVALIDARG; | |
| } | |
| } | |
| static HRESULT WINAPI FolderView_ItemCount(IFolderView2 *iface, UINT flags, int *items) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| TRACE("(%p)->(%u %p)\n", This, flags, items); | |
| if (flags != SVGIO_ALLVIEW) | |
| FIXME("some flags unsupported, %x\n", flags & ~SVGIO_ALLVIEW); | |
| *items = SendMessageW(This->hWndList, LVM_GETITEMCOUNT, 0, 0); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI FolderView_Items(IFolderView2 *iface, UINT flags, REFIID riid, void **ppv) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| FIXME("(%p)->(%u %s %p), stub\n", This, flags, debugstr_guid(riid), ppv); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI FolderView_GetSelectionMarkedItem(IFolderView2 *iface, int *item) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| TRACE("(%p)->(%p)\n", This, item); | |
| *item = SendMessageW(This->hWndList, LVM_GETSELECTIONMARK, 0, 0); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI FolderView_GetFocusedItem(IFolderView2 *iface, int *item) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| TRACE("(%p)->(%p)\n", This, item); | |
| *item = SendMessageW(This->hWndList, LVM_GETNEXTITEM, -1, LVNI_FOCUSED); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI FolderView_GetItemPosition(IFolderView2 *iface, PCUITEMID_CHILD pidl, POINT *ppt) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| FIXME("(%p)->(%p %p), stub\n", This, pidl, ppt); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI FolderView_GetSpacing(IFolderView2 *iface, POINT *pt) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| TRACE("(%p)->(%p)\n", This, pt); | |
| if (!This->hWndList) return S_FALSE; | |
| if (pt) | |
| { | |
| DWORD ret; | |
| ret = SendMessageW(This->hWndList, LVM_GETITEMSPACING, 0, 0); | |
| pt->x = LOWORD(ret); | |
| pt->y = HIWORD(ret); | |
| } | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI FolderView_GetDefaultSpacing(IFolderView2 *iface, POINT *pt) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| FIXME("(%p)->(%p), stub\n", This, pt); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI FolderView_GetAutoArrange(IFolderView2 *iface) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| FIXME("(%p), stub\n", This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI FolderView_SelectItem(IFolderView2 *iface, int item, DWORD flags) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| LVITEMW lvItem; | |
| TRACE("(%p)->(%d, %x)\n", This, item, flags); | |
| lvItem.state = 0; | |
| lvItem.stateMask = LVIS_SELECTED; | |
| if (flags & SVSI_ENSUREVISIBLE) | |
| SendMessageW(This->hWndList, LVM_ENSUREVISIBLE, item, 0); | |
| /* all items */ | |
| if (flags & SVSI_DESELECTOTHERS) | |
| SendMessageW(This->hWndList, LVM_SETITEMSTATE, -1, (LPARAM)&lvItem); | |
| /* this item */ | |
| if (flags & SVSI_SELECT) | |
| lvItem.state |= LVIS_SELECTED; | |
| if (flags & SVSI_FOCUSED) | |
| lvItem.stateMask |= LVIS_FOCUSED; | |
| SendMessageW(This->hWndList, LVM_SETITEMSTATE, item, (LPARAM)&lvItem); | |
| if (flags & SVSI_EDIT) | |
| SendMessageW(This->hWndList, LVM_EDITLABELW, item, 0); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI FolderView_SelectAndPositionItems(IFolderView2 *iface, UINT cidl, | |
| PCUITEMID_CHILD_ARRAY apidl, POINT *apt, DWORD flags) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| FIXME("(%p)->(%u %p %p %x), stub\n", This, cidl, apidl, apt, flags); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI FolderView2_SetGroupBy(IFolderView2 *iface, REFPROPERTYKEY key, BOOL ascending) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| FIXME("(%p)->(%p %d), stub\n", This, key, ascending); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI FolderView2_GetGroupBy(IFolderView2 *iface, PROPERTYKEY *pkey, BOOL *ascending) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| FIXME("(%p)->(%p %p), stub\n", This, pkey, ascending); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI FolderView2_SetViewProperty(IFolderView2 *iface, PCUITEMID_CHILD pidl, | |
| REFPROPERTYKEY propkey, REFPROPVARIANT propvar) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| FIXME("(%p)->(%p %p %p), stub\n", This, pidl, propkey, propvar); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI FolderView2_GetViewProperty(IFolderView2 *iface, PCUITEMID_CHILD pidl, | |
| REFPROPERTYKEY propkey, PROPVARIANT *propvar) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| FIXME("(%p)->(%p %p %p), stub\n", This, pidl, propkey, propvar); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI FolderView2_SetTileViewProperties(IFolderView2 *iface, PCUITEMID_CHILD pidl, | |
| LPCWSTR prop_list) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| FIXME("(%p)->(%p %s), stub\n", This, pidl, debugstr_w(prop_list)); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI FolderView2_SetExtendedTileViewProperties(IFolderView2 *iface, PCUITEMID_CHILD pidl, | |
| LPCWSTR prop_list) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| FIXME("(%p)->(%p %s), stub\n", This, pidl, debugstr_w(prop_list)); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI FolderView2_SetText(IFolderView2 *iface, FVTEXTTYPE type, LPCWSTR text) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| FIXME("(%p)->(%d %s), stub\n", This, type, debugstr_w(text)); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI FolderView2_SetCurrentFolderFlags(IFolderView2 *iface, DWORD mask, DWORD flags) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| FIXME("(%p)->(0x%08x 0x%08x), stub\n", This, mask, flags); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI FolderView2_GetCurrentFolderFlags(IFolderView2 *iface, DWORD *flags) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| FIXME("(%p)->(%p), stub\n", This, flags); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI FolderView2_GetSortColumnCount(IFolderView2 *iface, int *columns) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| FIXME("(%p)->(%p), stub\n", This, columns); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI FolderView2_SetSortColumns(IFolderView2 *iface, const SORTCOLUMN *columns, | |
| int count) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| FIXME("(%p)->(%p %d), stub\n", This, columns, count); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI FolderView2_GetSortColumns(IFolderView2 *iface, SORTCOLUMN *columns, | |
| int count) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| FIXME("(%p)->(%p %d), stub\n", This, columns, count); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI FolderView2_GetItem(IFolderView2 *iface, int item, REFIID riid, void **ppv) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| FIXME("(%p)->(%d %s %p), stub\n", This, item, debugstr_guid(riid), ppv); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI FolderView2_GetVisibleItem(IFolderView2 *iface, int start, BOOL previous, | |
| int *item) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| FIXME("(%p)->(%d %d %p), stub\n", This, start, previous, item); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI FolderView2_GetSelectedItem(IFolderView2 *iface, int start, int *item) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| FIXME("(%p)->(%d %p), stub\n", This, start, item); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI FolderView2_GetSelection(IFolderView2 *iface, BOOL none_implies_folder, | |
| IShellItemArray **array) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| FIXME("(%p)->(%d %p), stub\n", This, none_implies_folder, array); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI FolderView2_GetSelectionState(IFolderView2 *iface, PCUITEMID_CHILD pidl, | |
| DWORD *flags) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| FIXME("(%p)->(%p %p), stub\n", This, pidl, flags); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI FolderView2_InvokeVerbOnSelection(IFolderView2 *iface, LPCSTR verb) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| FIXME("(%p)->(%s), stub\n", This, debugstr_a(verb)); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI FolderView2_SetViewModeAndIconSize(IFolderView2 *iface, FOLDERVIEWMODE mode, | |
| int size) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| FIXME("(%p)->(%d %d), stub\n", This, mode, size); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI FolderView2_GetViewModeAndIconSize(IFolderView2 *iface, FOLDERVIEWMODE *mode, | |
| int *size) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| FIXME("(%p)->(%p %p), stub\n", This, mode, size); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI FolderView2_SetGroupSubsetCount(IFolderView2 *iface, UINT visible_rows) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| FIXME("(%p)->(%u), stub\n", This, visible_rows); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI FolderView2_GetGroupSubsetCount(IFolderView2 *iface, UINT *visible_rows) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| FIXME("(%p)->(%p), stub\n", This, visible_rows); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI FolderView2_SetRedraw(IFolderView2 *iface, BOOL redraw) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| TRACE("(%p)->(%d)\n", This, redraw); | |
| SendMessageW(This->hWndList, WM_SETREDRAW, redraw, 0); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI FolderView2_IsMoveInSameFolder(IFolderView2 *iface) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| FIXME("(%p), stub\n", This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI FolderView2_DoRename(IFolderView2 *iface) | |
| { | |
| IShellViewImpl *This = impl_from_IFolderView2(iface); | |
| FIXME("(%p), stub\n", This); | |
| return E_NOTIMPL; | |
| } | |
| static const IFolderView2Vtbl folderviewvtbl = | |
| { | |
| FolderView_QueryInterface, | |
| FolderView_AddRef, | |
| FolderView_Release, | |
| FolderView_GetCurrentViewMode, | |
| FolderView_SetCurrentViewMode, | |
| FolderView_GetFolder, | |
| FolderView_Item, | |
| FolderView_ItemCount, | |
| FolderView_Items, | |
| FolderView_GetSelectionMarkedItem, | |
| FolderView_GetFocusedItem, | |
| FolderView_GetItemPosition, | |
| FolderView_GetSpacing, | |
| FolderView_GetDefaultSpacing, | |
| FolderView_GetAutoArrange, | |
| FolderView_SelectItem, | |
| FolderView_SelectAndPositionItems, | |
| FolderView2_SetGroupBy, | |
| FolderView2_GetGroupBy, | |
| FolderView2_SetViewProperty, | |
| FolderView2_GetViewProperty, | |
| FolderView2_SetTileViewProperties, | |
| FolderView2_SetExtendedTileViewProperties, | |
| FolderView2_SetText, | |
| FolderView2_SetCurrentFolderFlags, | |
| FolderView2_GetCurrentFolderFlags, | |
| FolderView2_GetSortColumnCount, | |
| FolderView2_SetSortColumns, | |
| FolderView2_GetSortColumns, | |
| FolderView2_GetItem, | |
| FolderView2_GetVisibleItem, | |
| FolderView2_GetSelectedItem, | |
| FolderView2_GetSelection, | |
| FolderView2_GetSelectionState, | |
| FolderView2_InvokeVerbOnSelection, | |
| FolderView2_SetViewModeAndIconSize, | |
| FolderView2_GetViewModeAndIconSize, | |
| FolderView2_SetGroupSubsetCount, | |
| FolderView2_GetGroupSubsetCount, | |
| FolderView2_SetRedraw, | |
| FolderView2_IsMoveInSameFolder, | |
| FolderView2_DoRename | |
| }; | |
| /* IShellFolderView */ | |
| static HRESULT WINAPI IShellFolderView_fnQueryInterface(IShellFolderView *iface, REFIID riid, void **ppvObj) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderView(iface); | |
| return IShellView3_QueryInterface(&This->IShellView3_iface, riid, ppvObj); | |
| } | |
| static ULONG WINAPI IShellFolderView_fnAddRef(IShellFolderView *iface) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderView(iface); | |
| return IShellView3_AddRef(&This->IShellView3_iface); | |
| } | |
| static ULONG WINAPI IShellFolderView_fnRelease(IShellFolderView *iface) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderView(iface); | |
| return IShellView3_Release(&This->IShellView3_iface); | |
| } | |
| static HRESULT WINAPI IShellFolderView_fnRearrange(IShellFolderView *iface, LPARAM sort) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderView(iface); | |
| FIXME("(%p)->(%ld) stub\n", This, sort); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IShellFolderView_fnGetArrangeParam(IShellFolderView *iface, LPARAM *sort) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderView(iface); | |
| FIXME("(%p)->(%p) stub\n", This, sort); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IShellFolderView_fnArrangeGrid(IShellFolderView *iface) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderView(iface); | |
| FIXME("(%p) stub\n", This); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IShellFolderView_fnAutoArrange(IShellFolderView *iface) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderView(iface); | |
| TRACE("(%p)\n", This); | |
| return IFolderView2_SetCurrentFolderFlags(&This->IFolderView2_iface, FWF_AUTOARRANGE, FWF_AUTOARRANGE); | |
| } | |
| static HRESULT WINAPI IShellFolderView_fnGetAutoArrange(IShellFolderView *iface) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderView(iface); | |
| TRACE("(%p)\n", This); | |
| return IFolderView2_GetAutoArrange(&This->IFolderView2_iface); | |
| } | |
| static HRESULT WINAPI IShellFolderView_fnAddObject( | |
| IShellFolderView *iface, | |
| PITEMID_CHILD pidl, | |
| UINT *item) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderView(iface); | |
| FIXME("(%p)->(%p %p) stub\n", This, pidl, item); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IShellFolderView_fnGetObject( | |
| IShellFolderView *iface, | |
| PITEMID_CHILD *pidl, | |
| UINT item) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderView(iface); | |
| TRACE("(%p)->(%p %d)\n", This, pidl, item); | |
| return IFolderView2_Item(&This->IFolderView2_iface, item, pidl); | |
| } | |
| static HRESULT WINAPI IShellFolderView_fnRemoveObject( | |
| IShellFolderView *iface, | |
| PITEMID_CHILD pidl, | |
| UINT *item) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderView(iface); | |
| TRACE("(%p)->(%p %p)\n", This, pidl, item); | |
| if (pidl) | |
| { | |
| *item = LV_FindItemByPidl(This, ILFindLastID(pidl)); | |
| SendMessageW(This->hWndList, LVM_DELETEITEM, *item, 0); | |
| } | |
| else | |
| { | |
| *item = 0; | |
| SendMessageW(This->hWndList, LVM_DELETEALLITEMS, 0, 0); | |
| } | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI IShellFolderView_fnGetObjectCount( | |
| IShellFolderView *iface, | |
| UINT *count) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderView(iface); | |
| TRACE("(%p)->(%p)\n", This, count); | |
| return IFolderView2_ItemCount(&This->IFolderView2_iface, SVGIO_ALLVIEW, (INT*)count); | |
| } | |
| static HRESULT WINAPI IShellFolderView_fnSetObjectCount( | |
| IShellFolderView *iface, | |
| UINT count, | |
| UINT flags) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderView(iface); | |
| FIXME("(%p)->(%d %x) stub\n", This, count, flags); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IShellFolderView_fnUpdateObject( | |
| IShellFolderView *iface, | |
| PITEMID_CHILD pidl_old, | |
| PITEMID_CHILD pidl_new, | |
| UINT *item) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderView(iface); | |
| FIXME("(%p)->(%p %p %p) stub\n", This, pidl_old, pidl_new, item); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IShellFolderView_fnRefreshObject( | |
| IShellFolderView *iface, | |
| PITEMID_CHILD pidl, | |
| UINT *item) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderView(iface); | |
| FIXME("(%p)->(%p %p) stub\n", This, pidl, item); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IShellFolderView_fnSetRedraw( | |
| IShellFolderView *iface, | |
| BOOL redraw) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderView(iface); | |
| TRACE("(%p)->(%d)\n", This, redraw); | |
| return IFolderView2_SetRedraw(&This->IFolderView2_iface, redraw); | |
| } | |
| static HRESULT WINAPI IShellFolderView_fnGetSelectedCount( | |
| IShellFolderView *iface, | |
| UINT *count) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderView(iface); | |
| IShellItemArray *selection; | |
| HRESULT hr; | |
| TRACE("(%p)->(%p)\n", This, count); | |
| *count = 0; | |
| hr = IFolderView2_GetSelection(&This->IFolderView2_iface, FALSE, &selection); | |
| if (FAILED(hr)) | |
| return hr; | |
| hr = IShellItemArray_GetCount(selection, count); | |
| IShellItemArray_Release(selection); | |
| return hr; | |
| } | |
| static HRESULT WINAPI IShellFolderView_fnGetSelectedObjects( | |
| IShellFolderView *iface, | |
| PCITEMID_CHILD **pidl, | |
| UINT *items) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderView(iface); | |
| TRACE("(%p)->(%p %p)\n", This, pidl, items); | |
| *items = ShellView_GetSelections( This ); | |
| if (*items) | |
| { | |
| *pidl = LocalAlloc(0, *items*sizeof(LPITEMIDLIST)); | |
| if (!*pidl) return E_OUTOFMEMORY; | |
| /* it's documented that caller shouldn't free PIDLs, only array itself */ | |
| memcpy((PITEMID_CHILD*)*pidl, This->apidl, *items*sizeof(LPITEMIDLIST)); | |
| } | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI IShellFolderView_fnIsDropOnSource( | |
| IShellFolderView *iface, | |
| IDropTarget *drop_target) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderView(iface); | |
| FIXME("(%p)->(%p) stub\n", This, drop_target); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IShellFolderView_fnGetDragPoint( | |
| IShellFolderView *iface, | |
| POINT *pt) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderView(iface); | |
| FIXME("(%p)->(%p) stub\n", This, pt); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IShellFolderView_fnGetDropPoint( | |
| IShellFolderView *iface, | |
| POINT *pt) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderView(iface); | |
| FIXME("(%p)->(%p) stub\n", This, pt); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IShellFolderView_fnMoveIcons( | |
| IShellFolderView *iface, | |
| IDataObject *obj) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderView(iface); | |
| TRACE("(%p)->(%p)\n", This, obj); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IShellFolderView_fnSetItemPos( | |
| IShellFolderView *iface, | |
| PCUITEMID_CHILD pidl, | |
| POINT *pt) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderView(iface); | |
| FIXME("(%p)->(%p %p) stub\n", This, pidl, pt); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IShellFolderView_fnIsBkDropTarget( | |
| IShellFolderView *iface, | |
| IDropTarget *drop_target) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderView(iface); | |
| FIXME("(%p)->(%p) stub\n", This, drop_target); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IShellFolderView_fnSetClipboard( | |
| IShellFolderView *iface, | |
| BOOL move) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderView(iface); | |
| FIXME("(%p)->(%d) stub\n", This, move); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IShellFolderView_fnSetPoints( | |
| IShellFolderView *iface, | |
| IDataObject *obj) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderView(iface); | |
| FIXME("(%p)->(%p) stub\n", This, obj); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IShellFolderView_fnGetItemSpacing( | |
| IShellFolderView *iface, | |
| ITEMSPACING *spacing) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderView(iface); | |
| FIXME("(%p)->(%p) stub\n", This, spacing); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IShellFolderView_fnSetCallback( | |
| IShellFolderView *iface, | |
| IShellFolderViewCB *new_cb, | |
| IShellFolderViewCB **old_cb) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderView(iface); | |
| FIXME("(%p)->(%p %p) stub\n", This, new_cb, old_cb); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IShellFolderView_fnSelect( | |
| IShellFolderView *iface, | |
| UINT flags) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderView(iface); | |
| FIXME("(%p)->(%d) stub\n", This, flags); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI IShellFolderView_fnQuerySupport( | |
| IShellFolderView *iface, | |
| UINT *support) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderView(iface); | |
| TRACE("(%p)->(%p)\n", This, support); | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI IShellFolderView_fnSetAutomationObject( | |
| IShellFolderView *iface, | |
| IDispatch *disp) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderView(iface); | |
| FIXME("(%p)->(%p) stub\n", This, disp); | |
| return E_NOTIMPL; | |
| } | |
| static const IShellFolderViewVtbl shellfolderviewvtbl = | |
| { | |
| IShellFolderView_fnQueryInterface, | |
| IShellFolderView_fnAddRef, | |
| IShellFolderView_fnRelease, | |
| IShellFolderView_fnRearrange, | |
| IShellFolderView_fnGetArrangeParam, | |
| IShellFolderView_fnArrangeGrid, | |
| IShellFolderView_fnAutoArrange, | |
| IShellFolderView_fnGetAutoArrange, | |
| IShellFolderView_fnAddObject, | |
| IShellFolderView_fnGetObject, | |
| IShellFolderView_fnRemoveObject, | |
| IShellFolderView_fnGetObjectCount, | |
| IShellFolderView_fnSetObjectCount, | |
| IShellFolderView_fnUpdateObject, | |
| IShellFolderView_fnRefreshObject, | |
| IShellFolderView_fnSetRedraw, | |
| IShellFolderView_fnGetSelectedCount, | |
| IShellFolderView_fnGetSelectedObjects, | |
| IShellFolderView_fnIsDropOnSource, | |
| IShellFolderView_fnGetDragPoint, | |
| IShellFolderView_fnGetDropPoint, | |
| IShellFolderView_fnMoveIcons, | |
| IShellFolderView_fnSetItemPos, | |
| IShellFolderView_fnIsBkDropTarget, | |
| IShellFolderView_fnSetClipboard, | |
| IShellFolderView_fnSetPoints, | |
| IShellFolderView_fnGetItemSpacing, | |
| IShellFolderView_fnSetCallback, | |
| IShellFolderView_fnSelect, | |
| IShellFolderView_fnQuerySupport, | |
| IShellFolderView_fnSetAutomationObject | |
| }; | |
| static HRESULT WINAPI shellfolderviewdual_QueryInterface(IShellFolderViewDual3 *iface, REFIID riid, void **ppvObj) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderViewDual3(iface); | |
| TRACE("(%p)->(IID:%s,%p)\n", This, debugstr_guid(riid), ppvObj); | |
| if (IsEqualIID(riid, &IID_IShellFolderViewDual3) || | |
| IsEqualIID(riid, &IID_IShellFolderViewDual2) || | |
| IsEqualIID(riid, &IID_IShellFolderViewDual) || | |
| IsEqualIID(riid, &IID_IDispatch) || | |
| IsEqualIID(riid, &IID_IUnknown)) | |
| { | |
| *ppvObj = iface; | |
| IShellFolderViewDual3_AddRef(iface); | |
| return S_OK; | |
| } | |
| WARN("unsupported interface %s\n", debugstr_guid(riid)); | |
| return E_NOINTERFACE; | |
| } | |
| static ULONG WINAPI shellfolderviewdual_AddRef(IShellFolderViewDual3 *iface) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderViewDual3(iface); | |
| return IShellView3_AddRef(&This->IShellView3_iface); | |
| } | |
| static ULONG WINAPI shellfolderviewdual_Release(IShellFolderViewDual3 *iface) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderViewDual3(iface); | |
| return IShellView3_Release(&This->IShellView3_iface); | |
| } | |
| static HRESULT WINAPI shellfolderviewdual_GetTypeInfoCount(IShellFolderViewDual3 *iface, UINT *pctinfo) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderViewDual3(iface); | |
| TRACE("%p %p\n", This, pctinfo); | |
| *pctinfo = 1; | |
| return S_OK; | |
| } | |
| static HRESULT WINAPI shellfolderviewdual_GetTypeInfo(IShellFolderViewDual3 *iface, | |
| UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderViewDual3(iface); | |
| HRESULT hr; | |
| TRACE("(%p,%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo); | |
| hr = get_typeinfo(IShellFolderViewDual3_tid, ppTInfo); | |
| if (SUCCEEDED(hr)) | |
| ITypeInfo_AddRef(*ppTInfo); | |
| return hr; | |
| } | |
| static HRESULT WINAPI shellfolderviewdual_GetIDsOfNames( | |
| IShellFolderViewDual3 *iface, REFIID riid, LPOLESTR *rgszNames, UINT | |
| cNames, LCID lcid, DISPID *rgDispId) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderViewDual3(iface); | |
| ITypeInfo *ti; | |
| HRESULT hr; | |
| TRACE("(%p, %s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames, | |
| cNames, lcid, rgDispId); | |
| hr = get_typeinfo(IShellFolderViewDual3_tid, &ti); | |
| if (SUCCEEDED(hr)) | |
| hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId); | |
| return hr; | |
| } | |
| static HRESULT WINAPI shellfolderviewdual_Invoke(IShellFolderViewDual3 *iface, | |
| DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, | |
| DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, | |
| UINT *puArgErr) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderViewDual3(iface); | |
| ITypeInfo *ti; | |
| HRESULT hr; | |
| TRACE("(%p, %d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, | |
| debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult, | |
| pExcepInfo, puArgErr); | |
| hr = get_typeinfo(IShellFolderViewDual3_tid, &ti); | |
| if (SUCCEEDED(hr)) | |
| hr = ITypeInfo_Invoke(ti, &This->IShellFolderViewDual3_iface, dispIdMember, wFlags, pDispParams, | |
| pVarResult, pExcepInfo, puArgErr); | |
| return hr; | |
| } | |
| static HRESULT WINAPI shellfolderviewdual_get_Application(IShellFolderViewDual3 *iface, | |
| IDispatch **disp) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderViewDual3(iface); | |
| TRACE("%p %p\n", This, disp); | |
| if (!disp) | |
| return E_INVALIDARG; | |
| return IShellDispatch_Constructor(NULL, &IID_IDispatch, (void**)disp); | |
| } | |
| static HRESULT WINAPI shellfolderviewdual_get_Parent(IShellFolderViewDual3 *iface, IDispatch **disp) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderViewDual3(iface); | |
| FIXME("%p %p\n", This, disp); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI shellfolderviewdual_get_Folder(IShellFolderViewDual3 *iface, Folder **folder) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderViewDual3(iface); | |
| FIXME("%p %p\n", This, folder); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI shellfolderviewdual_SelectedItems(IShellFolderViewDual3 *iface, FolderItems **items) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderViewDual3(iface); | |
| FIXME("%p %p\n", This, items); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI shellfolderviewdual_get_FocusedItem(IShellFolderViewDual3 *iface, | |
| FolderItem **item) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderViewDual3(iface); | |
| FIXME("%p %p\n", This, item); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI shellfolderviewdual_SelectItem(IShellFolderViewDual3 *iface, | |
| VARIANT *v, int flags) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderViewDual3(iface); | |
| FIXME("%p %s %x\n", This, debugstr_variant(v), flags); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI shellfolderviewdual_PopupItemMenu(IShellFolderViewDual3 *iface, | |
| FolderItem *item, VARIANT vx, VARIANT vy, BSTR *command) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderViewDual3(iface); | |
| FIXME("%p %p %s %s %p\n", This, item, debugstr_variant(&vx), debugstr_variant(&vy), command); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI shellfolderviewdual_get_Script(IShellFolderViewDual3 *iface, IDispatch **disp) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderViewDual3(iface); | |
| FIXME("%p %p\n", This, disp); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI shellfolderviewdual_get_ViewOptions(IShellFolderViewDual3 *iface, LONG *options) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderViewDual3(iface); | |
| FIXME("%p %p\n", This, options); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI shellfolderviewdual_get_CurrentViewMode(IShellFolderViewDual3 *iface, UINT *mode) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderViewDual3(iface); | |
| FIXME("%p %p\n", This, mode); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI shellfolderviewdual_put_CurrentViewMode(IShellFolderViewDual3 *iface, UINT mode) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderViewDual3(iface); | |
| FIXME("%p %u\n", This, mode); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI shellfolderviewdual_SelectItemRelative(IShellFolderViewDual3 *iface, int relative) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderViewDual3(iface); | |
| FIXME("%p %d\n", This, relative); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI shellfolderviewdual_get_GroupBy(IShellFolderViewDual3 *iface, BSTR *groupby) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderViewDual3(iface); | |
| FIXME("%p %p\n", This, groupby); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI shellfolderviewdual_put_GroupBy(IShellFolderViewDual3 *iface, BSTR groupby) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderViewDual3(iface); | |
| FIXME("%p %s\n", This, debugstr_w(groupby)); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI shellfolderviewdual_get_FolderFlags(IShellFolderViewDual3 *iface, DWORD *flags) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderViewDual3(iface); | |
| FIXME("%p %p\n", This, flags); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI shellfolderviewdual_put_FolderFlags(IShellFolderViewDual3 *iface, DWORD flags) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderViewDual3(iface); | |
| FIXME("%p 0x%08x\n", This, flags); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI shellfolderviewdual_get_SortColumns(IShellFolderViewDual3 *iface, BSTR *sortcolumns) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderViewDual3(iface); | |
| FIXME("%p %p\n", This, sortcolumns); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI shellfolderviewdual_put_SortColumns(IShellFolderViewDual3 *iface, BSTR sortcolumns) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderViewDual3(iface); | |
| FIXME("%p %s\n", This, debugstr_w(sortcolumns)); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI shellfolderviewdual_put_IconSize(IShellFolderViewDual3 *iface, int icon_size) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderViewDual3(iface); | |
| FIXME("%p %d\n", This, icon_size); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI shellfolderviewdual_get_IconSize(IShellFolderViewDual3 *iface, int *icon_size) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderViewDual3(iface); | |
| FIXME("%p %p\n", This, icon_size); | |
| return E_NOTIMPL; | |
| } | |
| static HRESULT WINAPI shellfolderviewdual_FilterView(IShellFolderViewDual3 *iface, BSTR filter_text) | |
| { | |
| IShellViewImpl *This = impl_from_IShellFolderViewDual3(iface); | |
| FIXME("%p %s\n", This, debugstr_w(filter_text)); | |
| return E_NOTIMPL; | |
| } | |
| static const IShellFolderViewDual3Vtbl shellfolderviewdualvtbl = | |
| { | |
| shellfolderviewdual_QueryInterface, | |
| shellfolderviewdual_AddRef, | |
| shellfolderviewdual_Release, | |
| shellfolderviewdual_GetTypeInfoCount, | |
| shellfolderviewdual_GetTypeInfo, | |
| shellfolderviewdual_GetIDsOfNames, | |
| shellfolderviewdual_Invoke, | |
| shellfolderviewdual_get_Application, | |
| shellfolderviewdual_get_Parent, | |
| shellfolderviewdual_get_Folder, | |
| shellfolderviewdual_SelectedItems, | |
| shellfolderviewdual_get_FocusedItem, | |
| shellfolderviewdual_SelectItem, | |
| shellfolderviewdual_PopupItemMenu, | |
| shellfolderviewdual_get_Script, | |
| shellfolderviewdual_get_ViewOptions, | |
| shellfolderviewdual_get_CurrentViewMode, | |
| shellfolderviewdual_put_CurrentViewMode, | |
| shellfolderviewdual_SelectItemRelative, | |
| shellfolderviewdual_get_GroupBy, | |
| shellfolderviewdual_put_GroupBy, | |
| shellfolderviewdual_get_FolderFlags, | |
| shellfolderviewdual_put_FolderFlags, | |
| shellfolderviewdual_get_SortColumns, | |
| shellfolderviewdual_put_SortColumns, | |
| shellfolderviewdual_put_IconSize, | |
| shellfolderviewdual_get_IconSize, | |
| shellfolderviewdual_FilterView | |
| }; | |
| /********************************************************** | |
| * IShellView_Constructor | |
| */ | |
| IShellView *IShellView_Constructor(IShellFolder *folder) | |
| { | |
| IShellViewImpl *sv; | |
| sv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IShellViewImpl)); | |
| if (!sv) | |
| return NULL; | |
| sv->ref = 1; | |
| sv->IShellView3_iface.lpVtbl = &shellviewvtbl; | |
| sv->IOleCommandTarget_iface.lpVtbl = &olecommandtargetvtbl; | |
| sv->IDropTarget_iface.lpVtbl = &droptargetvtbl; | |
| sv->IDropSource_iface.lpVtbl = &dropsourcevtbl; | |
| sv->IViewObject_iface.lpVtbl = &viewobjectvtbl; | |
| sv->IFolderView2_iface.lpVtbl = &folderviewvtbl; | |
| sv->IShellFolderView_iface.lpVtbl = &shellfolderviewvtbl; | |
| sv->IShellFolderViewDual3_iface.lpVtbl = &shellfolderviewdualvtbl; | |
| sv->pSFParent = folder; | |
| if (folder) IShellFolder_AddRef(folder); | |
| IShellFolder_QueryInterface(sv->pSFParent, &IID_IShellFolder2, (void**)&sv->pSF2Parent); | |
| sv->pCurDropTarget = NULL; | |
| sv->pCurDataObject = NULL; | |
| sv->iDragOverItem = 0; | |
| sv->cScrollDelay = 0; | |
| sv->ptLastMousePos.x = 0; | |
| sv->ptLastMousePos.y = 0; | |
| TRACE("(%p)->(%p)\n", sv, folder); | |
| return (IShellView*)&sv->IShellView3_iface; | |
| } | |
| /************************************************************************* | |
| * SHCreateShellFolderView [SHELL32.256] | |
| * | |
| * Create a new instance of the default Shell folder view object. | |
| * | |
| * RETURNS | |
| * Success: S_OK | |
| * Failure: error value | |
| * | |
| * NOTES | |
| * see IShellFolder::CreateViewObject | |
| */ | |
| HRESULT WINAPI SHCreateShellFolderView(const SFV_CREATE *desc, IShellView **shellview) | |
| { | |
| TRACE("(%p, %p)\n", desc, shellview); | |
| *shellview = NULL; | |
| if (!desc || desc->cbSize != sizeof(*desc)) | |
| return E_INVALIDARG; | |
| TRACE("sf=%p outer=%p callback=%p\n", desc->pshf, desc->psvOuter, desc->psfvcb); | |
| if (!desc->pshf) | |
| return E_UNEXPECTED; | |
| *shellview = IShellView_Constructor(desc->pshf); | |
| if (!*shellview) | |
| return E_OUTOFMEMORY; | |
| if (desc->psfvcb) | |
| { | |
| IShellFolderView *view; | |
| IShellView_QueryInterface(*shellview, &IID_IShellFolderView, (void **)&view); | |
| IShellFolderView_SetCallback(view, desc->psfvcb, NULL); | |
| IShellFolderView_Release(view); | |
| } | |
| return S_OK; | |
| } | |
| /************************************************************************* | |
| * SHCreateShellFolderViewEx [SHELL32.174] | |
| * | |
| * Create a new instance of the default Shell folder view object. | |
| * | |
| * RETURNS | |
| * Success: S_OK | |
| * Failure: error value | |
| * | |
| * NOTES | |
| * see IShellFolder::CreateViewObject | |
| */ | |
| HRESULT WINAPI SHCreateShellFolderViewEx(CSFV *desc, IShellView **shellview) | |
| { | |
| TRACE("(%p, %p)\n", desc, shellview); | |
| TRACE("sf=%p pidl=%p cb=%p mode=0x%08x parm=%p\n", desc->pshf, desc->pidl, desc->pfnCallback, | |
| desc->fvm, desc->psvOuter); | |
| if (!desc->pshf) | |
| return E_UNEXPECTED; | |
| *shellview = IShellView_Constructor(desc->pshf); | |
| if (!*shellview) | |
| return E_OUTOFMEMORY; | |
| return S_OK; | |
| } |